----
url: https://docs.nestjs.com/v9/openapi/cli-plugin
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [CLI Plugin](https://docs.nestjs.com/v9/openapi/cli-plugin#cli-plugin)
* [Overview](https://docs.nestjs.com/v9/openapi/cli-plugin#overview)
* [Comments introspection](https://docs.nestjs.com/v9/openapi/cli-plugin#comments-introspection)
* [Using the CLI plugin](https://docs.nestjs.com/v9/openapi/cli-plugin#using-the-cli-plugin)
* [Integration with ts-jest (e2e tests)](https://docs.nestjs.com/v9/openapi/cli-plugin#integration-with-ts-jest-e2e-tests)
* [Troubleshooting jest (e2e tests)](https://docs.nestjs.com/v9/openapi/cli-plugin#troubleshooting-jest-e2e-tests)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/openapi/cli-plugin.md "Suggest Edits")

### CLI Plugin

TypeScript's metadata reflection system has several limitations which make it impossible to, for instance, determine what properties a class consists of or recognize whether a given property is optional or required. However, some of these constraints can be addressed at compilation time. Nest provides a plugin that enhances the TypeScript compilation process to reduce the amount of boilerplate code required.

> **Hint** This plugin is **opt-in**. If you prefer, you can declare all decorators manually, or only specific decorators where you need them.

```typescript

export class CreateUserDto {
  @ApiProperty()
  email: string;

  @ApiProperty()
  password: string;

  @ApiProperty({ enum: RoleEnum, default: [], isArray: true })
  roles: RoleEnum[] = [];

  @ApiProperty({ required: false, default: true })
  isEnabled?: boolean = true;
}
```

While not a significant issue with medium-sized projects, it becomes verbose & hard to maintain once you have a large set of classes.

By [enabling the Swagger plugin](/openapi/cli-plugin#using-the-cli-plugin), the above class definition can be declared simply:

```typescript

export class CreateUserDto {
  email: string;
  password: string;
  roles: RoleEnum[] = [];
  isEnabled?: boolean = true;
}
```

> **Hint** When using [mapped types utilities](https://docs.nestjs.com/openapi/mapped-types) (like `PartialType`) in DTOs import them from `@nestjs/swagger` instead of `@nestjs/mapped-types` for the plugin to pick up the schema.

The plugin adds appropriate decorators on the fly based on the **Abstract Syntax Tree**. Thus you won't have to struggle with `@ApiProperty` decorators scattered throughout the code.

> **Hint** The plugin will automatically generate any missing swagger properties, but if you need to override them, you simply set them explicitly via `@ApiProperty()`.

#### Comments introspection[#](/openapi/cli-plugin#comments-introspection)

With the comments introspection feature enabled, CLI plugin will generate descriptions and example values for properties based on comments.

For example, given an example `roles` property:

```typescript

/**
 * A list of user's roles
 * @example ['admin']
 */
@ApiProperty({
  description: `A list of user's roles`,
  example: ['admin'],
})
roles: RoleEnum[] = [];
```

You must duplicate both description and example values. With `introspectComments` enabled, the CLI plugin can extract these comments and automatically provide descriptions (and examples, if defined) for properties. Now, the above property can be declared simply as follows:

```typescript

/**
 * A list of user's roles
 * @example ['admin']
 */
roles: RoleEnum[] = [];
```

There are `dtoKeyOfComment` and `controllerKeyOfComment` plugin options that you can use to customize how the plugin will set the value for `ApiProperty` and `ApiOperation` decorators respectively. Take a look at the following example:

```typescript

export class SomeController {
  /**
   * Create some resource
   */
  @Post()
  create() {}
}
```

By default, these options are set to `"description"`. This means the plugin will assign `"Create some resource"` to `description` key on the `ApiOperation` operator. Like so:

```ts

@ApiOperation({ description: "Create some resource" })
```

> **Hint** For models, the same logic applies but to `ApiProperty` decorator instead.

#### Using the CLI plugin[#](/openapi/cli-plugin#using-the-cli-plugin)

To enable the plugin, open `nest-cli.json` (if you use [Nest CLI](/v9/cli/overview)) and add the following `plugins` configuration:

```javascript

{
  "collection": "@nestjs/schematics",
  "sourceRoot": "src",
  "compilerOptions": {
    "plugins": ["@nestjs/swagger"]
  }
}
```

You can use the `options` property to customize the behavior of the plugin.

```javascript

"plugins": [
  {
    "name": "@nestjs/swagger",
    "options": {
      "classValidatorShim": false,
      "introspectComments": true
    }
  }
]
```

The `options` property has to fulfill the following interface:

```typescript

export interface PluginOptions {
  dtoFileNameSuffix?: string[];
  controllerFileNameSuffix?: string[];
  classValidatorShim?: boolean;
  dtoKeyOfComment?: string;
  controllerKeyOfComment?: string;
  introspectComments?: boolean;
}
```

| Option                     | Default                     | Description                                                                                                                             |
| -------------------------- | --------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| `dtoFileNameSuffix`        | `['.dto.ts', '.entity.ts']` | DTO (Data Transfer Object) files suffix                                                                                                 |
| `controllerFileNameSuffix` | `.controller.ts`            | Controller files suffix                                                                                                                 |
| `classValidatorShim`       | `true`                      | If set to true, the module will reuse `class-validator` validation decorators (e.g. `@Max(10)` will add `max: 10` to schema definition) |
| `dtoKeyOfComment`          | `'description'`             | The property key to set the comment text to on `ApiProperty`.                                                                           |
| `controllerKeyOfComment`   | `'description'`             | The property key to set the comment text to on `ApiOperation`.                                                                          |
| `introspectComments`       | `false`                     | If set to true, plugin will generate descriptions and example values for properties based on comments                                   |

Make sure to delete the `/dist` folder and rebuild your application whenever plugin options are updated. If you don't use the CLI but instead have a custom `webpack` configuration, you can use this plugin in combination with `ts-loader`:

```javascript

getCustomTransformers: (program: any) => ({
  before: [require('@nestjs/swagger/plugin').before({}, program)]
}),
```

#### Integration with `ts-jest` (e2e tests)[#](/openapi/cli-plugin#integration-with-ts-jest-e2e-tests)

To run e2e tests, `ts-jest` compiles your source code files on the fly, in memory. This means, it doesn't use Nest CLI compiler and does not apply any plugins or perform AST transformations.

To enable the plugin, create the following file in your e2e tests directory:

```javascript

const transformer = require('@nestjs/swagger/plugin');

module.exports.name = 'nestjs-swagger-transformer';
// you should change the version number anytime you change the configuration below - otherwise, jest will not detect changes
module.exports.version = 1;

module.exports.factory = (cs) => {
  return transformer.before(
    {
      // @nestjs/swagger/plugin options (can be empty)
    },
    cs.program, // "cs.tsCompiler.program" for older versions of Jest (<= v27)
  );
};
```

With this in place, import AST transformer within your `jest` configuration file. By default (in the starter application), e2e tests configuration file is located under the `test` folder and is named `jest-e2e.json`.

```json

{
  ... // other configuration
  "globals": {
    "ts-jest": {
      "astTransformers": {
        "before": ["<path to the file created above>"]
      }
    }
  }
}
```

If you use `jest@^29`, then use the snippet below, as the previous approach got deprecated.

```json

{
  ... // other configuration
  "transform": {
    "^.+\\.(t|j)s$": [
      "ts-jest",
      {
        "astTransformers": {
          "before": ["<path to the file created above>"]
        }
      }
    ]
  }
}
```

#### Troubleshooting `jest` (e2e tests)[#](/openapi/cli-plugin#troubleshooting-jest-e2e-tests)

In case `jest` does not seem to pick up your configuration changes, it's possible that Jest has already **cached** the build result. To apply the new configuration, you need to clear Jest's cache directory.

To clear the cache directory, run the following command in your NestJS project folder:

```bash

$ npx jest --clearCache
```

In case the automatic cache clearance fails, you can still manually remove the cache folder with the following commands:

```bash

# Find jest cache directory (usually /tmp/jest_rs)
# by running the following command in your NestJS project root
$ npx jest --showConfig | grep cache
# ex result:
#   "cache": true,
#   "cacheDirectory": "/tmp/jest_rs"

# Remove or empty the Jest cache directory
$ rm -rf  <cacheDirectory value>
# ex:
# rm -rf /tmp/jest_rs
```

----
url: https://docs.nestjs.com/v9/openapi/operations
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Operations](https://docs.nestjs.com/v9/openapi/operations#operations)
* [Tags](https://docs.nestjs.com/v9/openapi/operations#tags)
* [Headers](https://docs.nestjs.com/v9/openapi/operations#headers)
* [Responses](https://docs.nestjs.com/v9/openapi/operations#responses)
* [File upload](https://docs.nestjs.com/v9/openapi/operations#file-upload)
* [Extensions](https://docs.nestjs.com/v9/openapi/operations#extensions)
* [Advanced: Generic ApiResponse](https://docs.nestjs.com/v9/openapi/operations#advanced-generic-apiresponse)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/openapi/operations.md "Suggest Edits")

### Operations

In OpenAPI terms, paths are endpoints (resources), such as `/users` or `/reports/summary`, that your API exposes, and operations are the HTTP methods used to manipulate these paths, such as `GET`, `POST` or `DELETE`.

#### Tags[#](/openapi/operations#tags)

To attach a controller to a specific tag, use the `@ApiTags(...tags)` decorator.

```typescript

@ApiTags('cats')
@Controller('cats')
export class CatsController {}
```

#### Headers[#](/openapi/operations#headers)

To define custom headers that are expected as part of the request, use `@ApiHeader()`.

```typescript

@ApiHeader({
  name: 'X-MyHeader',
  description: 'Custom header',
})
@Controller('cats')
export class CatsController {}
```

#### Responses[#](/openapi/operations#responses)

To define a custom HTTP response, use the `@ApiResponse()` decorator.

```typescript

@Post()
@ApiResponse({ status: 201, description: 'The record has been successfully created.'})
@ApiResponse({ status: 403, description: 'Forbidden.'})
async create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

```typescript

@Post()
@ApiCreatedResponse({ description: 'The record has been successfully created.'})
@ApiForbiddenResponse({ description: 'Forbidden.'})
async create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

To specify a return model for a request, we must create a class and annotate all properties with the `@ApiProperty()` decorator.

```typescript

export class Cat {
  @ApiProperty()
  id: number;

  @ApiProperty()
  name: string;

  @ApiProperty()
  age: number;

  @ApiProperty()
  breed: string;
}
```

Then the `Cat` model can be used in combination with the `type` property of the response decorator.

```typescript

@ApiTags('cats')
@Controller('cats')
export class CatsController {
  @Post()
  @ApiCreatedResponse({
    description: 'The record has been successfully created.',
    type: Cat,
  })
  async create(@Body() createCatDto: CreateCatDto): Promise<Cat> {
    return this.catsService.create(createCatDto);
  }
}
```

Let's open the browser and verify the generated `Cat` model:

#### File upload[#](/openapi/operations#file-upload)

You can enable file upload for a specific method with the `@ApiBody` decorator together with `@ApiConsumes()`. Here's a full example using the [File Upload](/v9/techniques/file-upload) technique:

```typescript

@UseInterceptors(FileInterceptor('file'))
@ApiConsumes('multipart/form-data')
@ApiBody({
  description: 'List of cats',
  type: FileUploadDto,
})
uploadFile(@UploadedFile() file) {}
```

Where `FileUploadDto` is defined as follows:

```typescript

class FileUploadDto {
  @ApiProperty({ type: 'string', format: 'binary' })
  file: any;
}
```

To handle multiple files uploading, you can define `FilesUploadDto` as follows:

```typescript

class FilesUploadDto {
  @ApiProperty({ type: 'array', items: { type: 'string', format: 'binary' } })
  files: any[];
}
```

#### Extensions[#](/openapi/operations#extensions)

To add an Extension to a request use the `@ApiExtension()` decorator. The extension name must be prefixed with `x-`.

```typescript

@ApiExtension('x-foo', { hello: 'world' })
```

#### Advanced: Generic `ApiResponse`[#](/openapi/operations#advanced-generic-apiresponse)

With the ability to provide [Raw Definitions](/openapi/types-and-parameters#raw-definitions), we can define Generic schema for Swagger UI. Assume we have the following DTO:

```ts

export class PaginatedDto<TData> {
  @ApiProperty()
  total: number;

  @ApiProperty()
  limit: number;

  @ApiProperty()
  offset: number;

  results: TData[];
}
```

We skip decorating `results` as we will be providing a raw definition for it later. Now, let's define another DTO and name it, for example, `CatDto`, as follows:

```ts

export class CatDto {
  @ApiProperty()
  name: string;

  @ApiProperty()
  age: number;

  @ApiProperty()
  breed: string;
}
```

With this in place, we can define a `PaginatedDto<CatDto>` response, as follows:

```ts

@ApiOkResponse({
  schema: {
    allOf: [
      { $ref: getSchemaPath(PaginatedDto) },
      {
        properties: {
          results: {
            type: 'array',
            items: { $ref: getSchemaPath(CatDto) },
          },
        },
      },
    ],
  },
})
async findAll(): Promise<PaginatedDto<CatDto>> {}
```

In this example, we specify that the response will have allOf `PaginatedDto` and the `results` property will be of type `Array<CatDto>`.

* `getSchemaPath()` function that returns the OpenAPI Schema path from within the OpenAPI Spec File for a given model.
* `allOf` is a concept that OAS 3 provides to cover various Inheritance related use-cases.

Lastly, since `PaginatedDto` is not directly referenced by any controller, the `SwaggerModule` will not be able to generate a corresponding model definition just yet. In this case, we must add it as an [Extra Model](/openapi/types-and-parameters#extra-models). For example, we can use the `@ApiExtraModels()` decorator on the controller level, as follows:

```ts

@Controller('cats')
@ApiExtraModels(PaginatedDto)
export class CatsController {}
```

If you run Swagger now, the generated `swagger.json` for this specific endpoint should have the following response defined:

```json

"responses": {
  "200": {
    "description": "",
    "content": {
      "application/json": {
        "schema": {
          "allOf": [
            {
              "$ref": "#/components/schemas/PaginatedDto"
            },
            {
              "properties": {
                "results": {
                  "$ref": "#/components/schemas/CatDto"
                }
              }
            }
          ]
        }
      }
    }
  }
}
```

To make it reusable, we can create a custom decorator for `PaginatedDto`, as follows:

```ts

export const ApiPaginatedResponse = <TModel extends Type<any>>(
  model: TModel,
) => {
  return applyDecorators(
    ApiOkResponse({
      schema: {
        allOf: [
          { $ref: getSchemaPath(PaginatedDto) },
          {
            properties: {
              results: {
                type: 'array',
                items: { $ref: getSchemaPath(model) },
              },
            },
          },
        ],
      },
    }),
  );
};
```

> **Hint**`Type<any>` interface and `applyDecorators` function are imported from the `@nestjs/common` package.

With this in place, we can use the custom `@ApiPaginatedResponse()` decorator on our endpoint:

```ts

@ApiPaginatedResponse(CatDto)
async findAll(): Promise<PaginatedDto<CatDto>> {}
```

For client generation tools, this approach poses an ambiguity in how the `PaginatedResponse<TModel>` is being generated for the client. The following snippet is an example of a client generator result for the above `GET /` endpoint.

```typescript

// Angular
findAll(): Observable<{ total: number, limit: number, offset: number, results: CatDto[] }>
```

As you can see, the **Return Type** here is ambiguous. To workaround this issue, you can add a `title` property to the `schema` for `ApiPaginatedResponse`:

```typescript

export const ApiPaginatedResponse = <TModel extends Type<any>>(model: TModel) => {
  return applyDecorators(
    ApiOkResponse({
      schema: {
        title: `PaginatedResponseOf${model.name}`
        allOf: [
          // ...
        ],
      },
    }),
  );
};
```

Now the result of the client generator tool will become:

```ts

// Angular
findAll(): Observable<PaginatedResponseOfCatDto>
```

----
url: https://docs.nestjs.com/v10/techniques/cookies
----

* [Cookies](https://docs.nestjs.com/v10/techniques/cookies#cookies)
* [Use with Express (default)](https://docs.nestjs.com/v10/techniques/cookies#use-with-express-default)
* [Use with Fastify](https://docs.nestjs.com/v10/techniques/cookies#use-with-fastify)
* [Creating a custom decorator (cross-platform)](https://docs.nestjs.com/v10/techniques/cookies#creating-a-custom-decorator-cross-platform)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/techniques/cookies.md "Suggest Edits")

### Cookies

An **HTTP cookie** is a small piece of data stored by the user's browser. Cookies were designed to be a reliable mechanism for websites to remember stateful information. When the user visits the website again, the cookie is automatically sent with the request.

#### Use with Express (default)[#](/techniques/cookies#use-with-express-default)

First install the [required package](https://github.com/expressjs/cookie-parser) (and its types for TypeScript users):

```shell

$ npm i cookie-parser
$ npm i -D @types/cookie-parser
```

Once the installation is complete, apply the `cookie-parser` middleware as global middleware (for example, in your `main.ts` file).

```typescript

import * as cookieParser from 'cookie-parser';
// somewhere in your initialization file
app.use(cookieParser());
```

You can pass several options to the `cookieParser` middleware:

* `secret` a string or array used for signing cookies. This is optional and if not specified, will not parse signed cookies. If a string is provided, this is used as the secret. If an array is provided, an attempt will be made to unsign the cookie with each secret in order.
* `options` an object that is passed to `cookie.parse` as the second option. See [cookie](https://www.npmjs.org/package/cookie) for more information.

The middleware will parse the `Cookie` header on the request and expose the cookie data as the property `req.cookies` and, if a secret was provided, as the property `req.signedCookies`. These properties are name value pairs of the cookie name to cookie value.

When a secret is provided, this module will unsign and validate any signed cookie values and move those name value pairs from `req.cookies` into `req.signedCookies`. A signed cookie is a cookie that has a value prefixed with `s:`. Signed cookies that fail signature validation will have the value `false` instead of the tampered value.

With this in place, you can now read cookies from within the route handlers, as follows:

```typescript

@Get()
findAll(@Req() request: Request) {
  console.log(request.cookies); // or "request.cookies['cookieKey']"
  // or console.log(request.signedCookies);
}
```

> **Hint** The `@Req()` decorator is imported from the `@nestjs/common`, while `Request` from the `express` package.

To attach a cookie to an outgoing response, use the `Response#cookie()` method:

```typescript

@Get()
findAll(@Res({ passthrough: true }) response: Response) {
  response.cookie('key', 'value')
}
```

> **Warning** If you want to leave the response handling logic to the framework, remember to set the `passthrough` option to `true`, as shown above. Read more [here](/controllers#library-specific-approach).

> **Hint** The `@Res()` decorator is imported from the `@nestjs/common`, while `Response` from the `express` package.

#### Use with Fastify[#](/techniques/cookies#use-with-fastify)

First install the required package:

```shell

$ npm i @fastify/cookie
```

Once the installation is complete, register the `@fastify/cookie` plugin:

```typescript

import fastifyCookie from '@fastify/cookie';

// somewhere in your initialization file
const app = await NestFactory.create<NestFastifyApplication>(AppModule, new FastifyAdapter());
await app.register(fastifyCookie, {
  secret: 'my-secret', // for cookies signature
});
```

With this in place, you can now read cookies from within the route handlers, as follows:

```typescript

@Get()
findAll(@Req() request: FastifyRequest) {
  console.log(request.cookies); // or "request.cookies['cookieKey']"
}
```

> **Hint** The `@Req()` decorator is imported from the `@nestjs/common`, while `FastifyRequest` from the `fastify` package.

To attach a cookie to an outgoing response, use the `FastifyReply#setCookie()` method:

```typescript

@Get()
findAll(@Res({ passthrough: true }) response: FastifyReply) {
  response.setCookie('key', 'value')
}
```

To read more about `FastifyReply#setCookie()` method, check out this [page](https://github.com/fastify/fastify-cookie#sending).

> **Warning** If you want to leave the response handling logic to the framework, remember to set the `passthrough` option to `true`, as shown above. Read more [here](/controllers#library-specific-approach).

> **Hint** The `@Res()` decorator is imported from the `@nestjs/common`, while `FastifyReply` from the `fastify` package.

#### Creating a custom decorator (cross-platform)[#](/techniques/cookies#creating-a-custom-decorator-cross-platform)

To provide a convenient, declarative way of accessing incoming cookies, we can create a [custom decorator](/v10/custom-decorators).

```typescript

import { createParamDecorator, ExecutionContext } from '@nestjs/common';

export const Cookies = createParamDecorator((data: string, ctx: ExecutionContext) => {
  const request = ctx.switchToHttp().getRequest();
  return data ? request.cookies?.[data] : request.cookies;
});
```

The `@Cookies()` decorator will extract all cookies, or a named cookie from the `req.cookies` object and populate the decorated parameter with that value.

With this in place, we can now use the decorator in a route handler signature, as follows:

```typescript

@Get()
findAll(@Cookies('name') name: string) {}
```

----
url: https://docs.nestjs.com/v10/graphql/mapped-types
----

* [Mapped types](https://docs.nestjs.com/v10/graphql/mapped-types#mapped-types)
* [Partial](https://docs.nestjs.com/v10/graphql/mapped-types#partial)
* [Pick](https://docs.nestjs.com/v10/graphql/mapped-types#pick)
* [Omit](https://docs.nestjs.com/v10/graphql/mapped-types#omit)
* [Intersection](https://docs.nestjs.com/v10/graphql/mapped-types#intersection)
* [Composition](https://docs.nestjs.com/v10/graphql/mapped-types#composition)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/mapped-types.md "Suggest Edits")

### Mapped types

> **Warning** This chapter applies only to the code first approach.

As you build out features like CRUD (Create/Read/Update/Delete) it's often useful to construct variants on a base entity type. Nest provides several utility functions that perform type transformations to make this task more convenient.

#### Partial[#](/graphql/mapped-types#partial)

When building input validation types (also called Data Transfer Objects or DTOs), it's often useful to build **create** and **update** variations on the same type. For example, the **create** variant may require all fields, while the **update** variant may make all fields optional.

Nest provides the `PartialType()` utility function to make this task easier and minimize boilerplate.

The `PartialType()` function returns a type (class) with all the properties of the input type set to optional. For example, suppose we have a **create** type as follows:

```typescript

@InputType()
class CreateUserInput {
  @Field()
  email: string;

  @Field()
  password: string;

  @Field()
  firstName: string;
}
```

By default, all of these fields are required. To create a type with the same fields, but with each one optional, use `PartialType()` passing the class reference (`CreateUserInput`) as an argument:

```typescript

@InputType()
export class UpdateUserInput extends PartialType(CreateUserInput) {}
```

> **Hint** The `PartialType()` function is imported from the `@nestjs/graphql` package.

The `PartialType()` function takes an optional second argument that is a reference to a decorator factory. This argument can be used to change the decorator function applied to the resulting (child) class. If not specified, the child class effectively uses the same decorator as the **parent** class (the class referenced in the first argument). In the example above, we are extending `CreateUserInput` which is annotated with the `@InputType()` decorator. Since we want `UpdateUserInput` to also be treated as if it were decorated with `@InputType()`, we didn't need to pass `InputType` as the second argument. If the parent and child types are different, (e.g., the parent is decorated with `@ObjectType`), we would pass `InputType` as the second argument. For example:

```typescript

@InputType()
export class UpdateUserInput extends PartialType(User, InputType) {}
```

#### Pick[#](/graphql/mapped-types#pick)

The `PickType()` function constructs a new type (class) by picking a set of properties from an input type. For example, suppose we start with a type like:

```typescript

@InputType()
class CreateUserInput {
  @Field()
  email: string;

  @Field()
  password: string;

  @Field()
  firstName: string;
}
```

We can pick a set of properties from this class using the `PickType()` utility function:

```typescript

@InputType()
export class UpdateEmailInput extends PickType(CreateUserInput, [
  'email',
] as const) {}
```

> **Hint** The `PickType()` function is imported from the `@nestjs/graphql` package.

#### Omit[#](/graphql/mapped-types#omit)

The `OmitType()` function constructs a type by picking all properties from an input type and then removing a particular set of keys. For example, suppose we start with a type like:

```typescript

@InputType()
class CreateUserInput {
  @Field()
  email: string;

  @Field()
  password: string;

  @Field()
  firstName: string;
}
```

We can generate a derived type that has every property **except**`email` as shown below. In this construct, the second argument to `OmitType` is an array of property names.

```typescript

@InputType()
export class UpdateUserInput extends OmitType(CreateUserInput, [
  'email',
] as const) {}
```

> **Hint** The `OmitType()` function is imported from the `@nestjs/graphql` package.

#### Intersection[#](/graphql/mapped-types#intersection)

The `IntersectionType()` function combines two types into one new type (class). For example, suppose we start with two types like:

```typescript

@InputType()
class CreateUserInput {
  @Field()
  email: string;

  @Field()
  password: string;
}

@ObjectType()
export class AdditionalUserInfo {
  @Field()
  firstName: string;

  @Field()
  lastName: string;
}
```

We can generate a new type that combines all properties in both types.

```typescript

@InputType()
export class UpdateUserInput extends IntersectionType(
  CreateUserInput,
  AdditionalUserInfo,
) {}
```

> **Hint** The `IntersectionType()` function is imported from the `@nestjs/graphql` package.

#### Composition[#](/graphql/mapped-types#composition)

The type mapping utility functions are composable. For example, the following will produce a type (class) that has all of the properties of the `CreateUserInput` type except for `email`, and those properties will be set to optional:

```typescript

@InputType()
export class UpdateUserInput extends PartialType(
  OmitType(CreateUserInput, ['email'] as const),
) {}
```

----
url: https://docs.nestjs.com/v10/recipes/nest-commander
----

* [Nest Commander](https://docs.nestjs.com/v10/recipes/nest-commander#nest-commander)
* [Installation](https://docs.nestjs.com/v10/recipes/nest-commander#installation)
* [A Command file](https://docs.nestjs.com/v10/recipes/nest-commander#a-command-file)
* [Running the Command](https://docs.nestjs.com/v10/recipes/nest-commander#running-the-command)
* [Testing](https://docs.nestjs.com/v10/recipes/nest-commander#testing)
* [Putting it all together](https://docs.nestjs.com/v10/recipes/nest-commander#putting-it-all-together)
* [More Information](https://docs.nestjs.com/v10/recipes/nest-commander#more-information)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/recipes/nest-commander.md "Suggest Edits")

### Nest Commander

Expanding on the [standalone application](/v10/standalone-applications) docs there's also the [nest-commander](https://jmcdo29.github.io/nest-commander) package for writing command line applications in a structure similar to your typical Nest application.

> **info**`nest-commander` is a third party package and is not managed by the entirety of the NestJS core team. Please, report any issues found with the library in the [appropriate repository](https://github.com/jmcdo29/nest-commander/issues/new/choose)

#### Installation[#](/recipes/nest-commander#installation)

Just like any other package, you've got to install it before you can use it.

```bash

$ npm i nest-commander
```

#### A Command file[#](/recipes/nest-commander#a-command-file)

`nest-commander` makes it easy to write new command-line applications with [decorators](https://www.typescriptlang.org/docs/handbook/decorators.html) via the `@Command()` decorator for classes and the `@Option()` decorator for methods of that class. Every command file should implement the `CommandRunner` abstract class and should be decorated with a `@Command()` decorator.

Every command is seen as an `@Injectable()` by Nest, so your normal Dependency Injection still works as you would expect it to. The only thing to take note of is the abstract class `CommandRunner`, which should be implemented by each command. The `CommandRunner` abstract class ensures that all commands have a `run` method that returns a `Promise<void>` and takes in the parameters `string[], Record<string, any>`. The `run` command is where you can kick all of your logic off from, it will take in whatever parameters did not match option flags and pass them in as an array, just in case you are really meaning to work with multiple parameters. As for the options, the `Record<string, any>`, the names of these properties match the `name` property given to the `@Option()` decorators, while their value matches the return of the option handler. If you'd like better type safety, you are welcome to create an interface for your options as well.

#### Running the Command[#](/recipes/nest-commander#running-the-command)

Similar to how in a NestJS application we can use the `NestFactory` to create a server for us, and run it using `listen`, the `nest-commander` package exposes a simple to use API to run your server. Import the `CommandFactory` and use the `static` method `run` and pass in the root module of your application. This would probably look like below

```ts

import { CommandFactory } from 'nest-commander';
import { AppModule } from './app.module';

async function bootstrap() {
  await CommandFactory.run(AppModule);
}

bootstrap();
```

By default, Nest's logger is disabled when using the `CommandFactory`. It's possible to provide it though, as the second argument to the `run` function. You can either provide a custom NestJS logger, or an array of log levels you want to keep - it might be useful to at least provide `['error']` here, if you only want to print out Nest's error logs.

```ts

import { CommandFactory } from 'nest-commander';
import { AppModule } from './app.module';
import { LogService } './log.service';

async function bootstrap() {
  await CommandFactory.run(AppModule, new LogService());

  // or, if you only want to print Nest's warnings and errors
  await CommandFactory.run(AppModule, ['warn', 'error']);
}

bootstrap();
```

And that's it. Under the hood, `CommandFactory` will worry about calling `NestFactory` for you and calling `app.close()` when necessary, so you shouldn't need to worry about memory leaks there. If you need to add in some error handling, there's always `try/catch` wrapping the `run` command, or you can chain on some `.catch()` method to the `bootstrap()` call.

#### Testing[#](/recipes/nest-commander#testing)

So what's the use of writing a super awesome command line script if you can't test it super easily, right? Fortunately, `nest-commander` has some utilities you can make use of that fits in perfectly with the NestJS ecosystem, it'll feel right at home to any Nestlings out there. Instead of using the `CommandFactory` for building the command in test mode, you can use `CommandTestFactory` and pass in your metadata, very similarly to how `Test.createTestingModule` from `@nestjs/testing` works. In fact, it uses this package under the hood. You're also still able to chain on the `overrideProvider` methods before calling `compile()` so you can swap out DI pieces right in the test.

#### Putting it all together[#](/recipes/nest-commander#putting-it-all-together)

The following class would equate to having a CLI command that can take in the subcommand `basic` or be called directly, with `-n`, `-s`, and `-b` (along with their long flags) all being supported and with custom parsers for each option. The `--help` flag is also supported, as is customary with commander.

```ts

import { Command, CommandRunner, Option } from 'nest-commander';
import { LogService } from './log.service';

interface BasicCommandOptions {
  string?: string;
  boolean?: boolean;
  number?: number;
}

@Command({ name: 'basic', description: 'A parameter parse' })
export class BasicCommand extends CommandRunner {
  constructor(private readonly logService: LogService) {
    super()
  }

  async run(
    passedParam: string[],
    options?: BasicCommandOptions,
  ): Promise<void> {
    if (options?.boolean !== undefined && options?.boolean !== null) {
      this.runWithBoolean(passedParam, options.boolean);
    } else if (options?.number) {
      this.runWithNumber(passedParam, options.number);
    } else if (options?.string) {
      this.runWithString(passedParam, options.string);
    } else {
      this.runWithNone(passedParam);
    }
  }

  @Option({
    flags: '-n, --number [number]',
    description: 'A basic number parser',
  })
  parseNumber(val: string): number {
    return Number(val);
  }

  @Option({
    flags: '-s, --string [string]',
    description: 'A string return',
  })
  parseString(val: string): string {
    return val;
  }

  @Option({
    flags: '-b, --boolean [boolean]',
    description: 'A boolean parser',
  })
  parseBoolean(val: string): boolean {
    return JSON.parse(val);
  }

  runWithString(param: string[], option: string): void {
    this.logService.log({ param, string: option });
  }

  runWithNumber(param: string[], option: number): void {
    this.logService.log({ param, number: option });
  }

  runWithBoolean(param: string[], option: boolean): void {
    this.logService.log({ param, boolean: option });
  }

  runWithNone(param: string[]): void {
    this.logService.log({ param });
  }
}
```

Make sure the command class is added to a module

```ts

@Module({
  providers: [LogService, BasicCommand],
})
export class AppModule {}
```

And now to be able to run the CLI in your main.ts you can do the following

```ts

async function bootstrap() {
  await CommandFactory.run(AppModule);
}

bootstrap();
```

And just like that, you've got a command line application.

#### More Information[#](/recipes/nest-commander#more-information)

Visit the [nest-commander docs site](https://jmcdo29.github.io/nest-commander) for more information, examples, and API documentation.

----
url: https://docs.nestjs.com/v9/fundamentals/circular-dependency
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Circular dependency](https://docs.nestjs.com/v9/fundamentals/circular-dependency#circular-dependency)
* [Forward reference](https://docs.nestjs.com/v9/fundamentals/circular-dependency#forward-reference)
* [ModuleRef class alternative](https://docs.nestjs.com/v9/fundamentals/circular-dependency#moduleref-class-alternative)
* [Module forward reference](https://docs.nestjs.com/v9/fundamentals/circular-dependency#module-forward-reference)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/fundamentals/circular-dependency.md "Suggest Edits")

### Circular dependency

A circular dependency occurs when two classes depend on each other. For example, class A needs class B, and class B also needs class A. Circular dependencies can arise in Nest between modules and between providers.

While circular dependencies should be avoided where possible, you can't always do so. In such cases, Nest enables resolving circular dependencies between providers in two ways. In this chapter, we describe using **forward referencing** as one technique, and using the **ModuleRef** class to retrieve a provider instance from the DI container as another.

We also describe resolving circular dependencies between modules.

> **Warning** A circular dependency might also be caused when using "barrel files"/index.ts files to group imports. Barrel files should be omitted when it comes to module/provider classes. For example, barrel files should not be used when importing files within the same directory as the barrel file, i.e. `cats/cats.controller` should not import `cats` to import the `cats/cats.service` file. For more details please also see [this github issue](https://github.com/nestjs/nest/issues/1181#issuecomment-430197191).

#### Forward reference[#](/fundamentals/circular-dependency#forward-reference)

A **forward reference** allows Nest to reference classes which aren't yet defined using the `forwardRef()` utility function. For example, if `CatsService` and `CommonService` depend on each other, both sides of the relationship can use `@Inject()` and the `forwardRef()` utility to resolve the circular dependency. Otherwise Nest won't instantiate them because all of the essential metadata won't be available. Here's an example:

cats.service.ts

JS TS

```typescript

@Injectable()
export class CatsService {
  constructor(
    @Inject(forwardRef(() => CommonService))
    private commonService: CommonService,
  ) {}
}
```

```typescript

@Injectable()
@Dependencies(forwardRef(() => CommonService))
export class CatsService {
  constructor(commonService) {
    this.commonService = commonService;
  }
}
```

> **Hint** The `forwardRef()` function is imported from the `@nestjs/common` package.

That covers one side of the relationship. Now let's do the same with `CommonService`:

common.service.ts

JS TS

```typescript

@Injectable()
export class CommonService {
  constructor(
    @Inject(forwardRef(() => CatsService))
    private catsService: CatsService,
  ) {}
}
```

```typescript

@Injectable()
@Dependencies(forwardRef(() => CatsService))
export class CommonService {
  constructor(catsService) {
    this.catsService = catsService;
  }
}
```

> **Warning** The order of instantiation is indeterminate. Make sure your code does not depend on which constructor is called first. Having circular dependencies depend on providers with `Scope.REQUEST` can lead to undefined dependencies. More information available [here](https://github.com/nestjs/nest/issues/5778)

#### ModuleRef class alternative[#](/fundamentals/circular-dependency#moduleref-class-alternative)

An alternative to using `forwardRef()` is to refactor your code and use the `ModuleRef` class to retrieve a provider on one side of the (otherwise) circular relationship. Learn more about the `ModuleRef` utility class [here](/v9/fundamentals/module-ref).

#### Module forward reference[#](/fundamentals/circular-dependency#module-forward-reference)

In order to resolve circular dependencies between modules, use the same `forwardRef()` utility function on both sides of the modules association. For example:

common.module.ts

JS TS

```typescript

@Module({
  imports: [forwardRef(() => CatsModule)],
})
export class CommonModule {}
```

That covers one side of the relationship. Now let's do the same with `CatsModule`:

cats.module.ts

JS TS

```typescript

@Module({
  imports: [forwardRef(() => CommonModule)],
})
export class CatsModule {}
```

----
url: https://docs.nestjs.com/v9/techniques/http-module
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [HTTP module](https://docs.nestjs.com/v9/techniques/http-module#http-module)
* [Installation](https://docs.nestjs.com/v9/techniques/http-module#installation)
* [Getting started](https://docs.nestjs.com/v9/techniques/http-module#getting-started)
* [Configuration](https://docs.nestjs.com/v9/techniques/http-module#configuration)
* [Async configuration](https://docs.nestjs.com/v9/techniques/http-module#async-configuration)
* [Using Axios directly](https://docs.nestjs.com/v9/techniques/http-module#using-axios-directly)
* [Full example](https://docs.nestjs.com/v9/techniques/http-module#full-example)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/techniques/http-module.md "Suggest Edits")

### HTTP module

[Axios](https://github.com/axios/axios) is richly featured HTTP client package that is widely used. Nest wraps Axios and exposes it via the built-in `HttpModule`. The `HttpModule` exports the `HttpService` class, which exposes Axios-based methods to perform HTTP requests. The library also transforms the resulting HTTP responses into `Observables`.

> **Hint** You can also use any general purpose Node.js HTTP client library directly, including [got](https://github.com/sindresorhus/got) or [undici](https://github.com/nodejs/undici).

#### Installation[#](/techniques/http-module#installation)

To begin using it, we first install required dependencies.

```bash

$ npm i --save @nestjs/axios axios
```

#### Getting started[#](/techniques/http-module#getting-started)

Once the installation process is complete, to use the `HttpService`, first import `HttpModule`.

```typescript

@Module({
  imports: [HttpModule],
  providers: [CatsService],
})
export class CatsModule {}
```

Next, inject `HttpService` using normal constructor injection.

> **Hint**`HttpModule` and `HttpService` are imported from `@nestjs/axios` package.

JS TS

```typescript

@Injectable()
export class CatsService {
  constructor(private readonly httpService: HttpService) {}

  findAll(): Observable<AxiosResponse<Cat[]>> {
    return this.httpService.get('http://localhost:3000/cats');
  }
}
```

```typescript

@Injectable()
@Dependencies(HttpService)
export class CatsService {
  constructor(httpService) {
    this.httpService = httpService;
  }

  findAll() {
    return this.httpService.get('http://localhost:3000/cats');
  }
}
```

> **Hint**`AxiosResponse` is an interface exported from the `axios` package (`$ npm i axios`).

All `HttpService` methods return an `AxiosResponse` wrapped in an `Observable` object.

#### Configuration[#](/techniques/http-module#configuration)

[Axios](https://github.com/axios/axios) can be configured with a variety of options to customize the behavior of the `HttpService`. Read more about them [here](https://github.com/axios/axios#request-config). To configure the underlying Axios instance, pass an optional options object to the `register()` method of `HttpModule` when importing it. This options object will be passed directly to the underlying Axios constructor.

```typescript

@Module({
  imports: [
    HttpModule.register({
      timeout: 5000,
      maxRedirects: 5,
    }),
  ],
  providers: [CatsService],
})
export class CatsModule {}
```

#### Async configuration[#](/techniques/http-module#async-configuration)

When you need to pass module options asynchronously instead of statically, use the `registerAsync()` method. As with most dynamic modules, Nest provides several techniques to deal with async configuration.

One technique is to use a factory function:

```typescript

HttpModule.registerAsync({
  useFactory: () => ({
    timeout: 5000,
    maxRedirects: 5,
  }),
});
```

Like other factory providers, our factory function can be [async](https://docs.nestjs.com/fundamentals/custom-providers#factory-providers-usefactory) and can inject dependencies through `inject`.

```typescript

HttpModule.registerAsync({
  imports: [ConfigModule],
  useFactory: async (configService: ConfigService) => ({
    timeout: configService.get('HTTP_TIMEOUT'),
    maxRedirects: configService.get('HTTP_MAX_REDIRECTS'),
  }),
  inject: [ConfigService],
});
```

Alternatively, you can configure the `HttpModule` using a class instead of a factory, as shown below.

```typescript

HttpModule.registerAsync({
  useClass: HttpConfigService,
});
```

The construction above instantiates `HttpConfigService` inside `HttpModule`, using it to create an options object. Note that in this example, the `HttpConfigService` has to implement `HttpModuleOptionsFactory` interface as shown below. The `HttpModule` will call the `createHttpOptions()` method on the instantiated object of the supplied class.

```typescript

@Injectable()
class HttpConfigService implements HttpModuleOptionsFactory {
  createHttpOptions(): HttpModuleOptions {
    return {
      timeout: 5000,
      maxRedirects: 5,
    };
  }
}
```

If you want to reuse an existing options provider instead of creating a private copy inside the `HttpModule`, use the `useExisting` syntax.

```typescript

HttpModule.registerAsync({
  imports: [ConfigModule],
  useExisting: HttpConfigService,
});
```

#### Using Axios directly[#](/techniques/http-module#using-axios-directly)

If you think that `HttpModule.register`'s options are not enough for you, or if you just want to access the underlying Axios instance created by `@nestjs/axios`, you can access it via `HttpService#axiosRef` as follows:

```typescript

@Injectable()
export class CatsService {
  constructor(private readonly httpService: HttpService) {}

  findAll(): Promise<AxiosResponse<Cat[]>> {
    return this.httpService.axiosRef.get('http://localhost:3000/cats');
    //                      ^ AxiosInstance interface
  }
}
```

#### Full example[#](/techniques/http-module#full-example)

Since the return value of the `HttpService` methods is an Observable, we can use `rxjs` - `firstValueFrom` or `lastValueFrom` to retrieve the data of the request in the form of a promise.

```typescript

import { catchError, firstValueFrom } from 'rxjs';

@Injectable()
export class CatsService {
  private readonly logger = new Logger(CatsService.name);
  constructor(private readonly httpService: HttpService) {}

  async findAll(): Promise<Cat[]> {
    const { data } = await firstValueFrom(
      this.httpService.get<Cat[]>('http://localhost:3000/cats').pipe(
        catchError((error: AxiosError) => {
          this.logger.error(error.response.data);
          throw 'An error happened!';
        }),
      ),
    );
    return data;
  }
}
```

> **Hint** Visit RxJS's documentation on [`firstValueFrom`](https://rxjs.dev/api/index/function/firstValueFrom) and [`lastValueFrom`](https://rxjs.dev/api/index/function/lastValueFrom) for differences between them.

----
url: https://docs.nestjs.com/v6/fundamentals/circular-dependency
----

* [Circular dependency](https://docs.nestjs.com/v6/fundamentals/circular-dependency#circular-dependency)
* [Forward reference](https://docs.nestjs.com/v6/fundamentals/circular-dependency#forward-reference)
* [ModuleRef class alternative](https://docs.nestjs.com/v6/fundamentals/circular-dependency#moduleref-class-alternative)
* [Module forward reference](https://docs.nestjs.com/v6/fundamentals/circular-dependency#module-forward-reference)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/fundamentals/circular-dependency.md "Suggest Edits")

### Circular dependency

A circular dependency occurs when two classes depend on each other. For example, class A needs class B, and class B also needs class A. Circular dependencies can arise in Nest between modules and between providers.

While circular dependencies should be avoided where possible, you can't always do so. In such cases, Nest enables resolving circular dependencies between providers in two ways. In this chapter, we describe using **forward referencing** as one technique, and using the **ModuleRef** class to retrieve a provider instance from the DI container as another.

We also describe resolving circular dependencies between modules.

#### Forward reference[#](/fundamentals/circular-dependency#forward-reference)

A **forward reference** allows Nest to reference classes which aren't yet defined using the `forwardRef()` utility function. For example, if `CatsService` and `CommonService` depend on each other, both sides of the relationship can use `@Inject()` and the `forwardRef()` utility to resolve the circular dependency. Otherwise Nest won't instantiate them because all of the essential metadata won't be available. Here's an example:

cats.service.ts

JS TS

```typescript

@Injectable()
export class CatsService {
  constructor(
    @Inject(forwardRef(() => CommonService))
    private readonly commonService: CommonService,
  ) {}
}
```

```typescript

@Injectable()
@Dependencies(forwardRef(() => CommonService))
export class CatsService {
  constructor(commonService) {
    this.commonService = commonService;
  }
}
```

> **Hint** The `forwardRef()` function is imported from the `@nestjs/common` package.

That covers one side of the relationship. Now let's do the same with `CommonService`:

common.service.ts

JS TS

```typescript

@Injectable()
export class CommonService {
  constructor(
    @Inject(forwardRef(() => CatsService))
    private readonly catsService: CatsService,
  ) {}
}
```

```typescript

@Injectable()
@Dependencies(forwardRef(() => CatsService))
export class CommonService {
  constructor(catsService) {
    this.catsService = catsService;
  }
}
```

> **Warning** The order of instantiation is indeterminate. Make sure your code does not depend on which constructor is called first.

#### ModuleRef class alternative[#](/fundamentals/circular-dependency#moduleref-class-alternative)

An alternative to using `forwardRef()` is to refactor your code and use the `ModuleRef` class to retrieve a provider on one side of the (otherwise) circular relationship. Learn more about the `ModuleRef` utility class [here](/v6/fundamentals/module-ref).

#### Module forward reference[#](/fundamentals/circular-dependency#module-forward-reference)

In order to resolve circular dependencies between modules, use the same `forwardRef()` utility function on both sides of the modules association. For example:

common.module.ts

JS TS

```typescript

@Module({
  imports: [forwardRef(() => CatsModule)],
})
export class CommonModule {}
```

----
url: https://docs.nestjs.com/security/authentication
----

[Skip to content](#content)

On this page

* [Authentication](https://docs.nestjs.com/security/authentication#authentication)
* [Installation](https://docs.nestjs.com/security/authentication#installation)
* [Register the authentication module](https://docs.nestjs.com/security/authentication#register-the-authentication-module)
* [Add sign-up and sign-in](https://docs.nestjs.com/security/authentication#add-sign-up-and-sign-in)
* [Verify email addresses](https://docs.nestjs.com/security/authentication#verify-email-addresses)
* [Reset forgotten passwords](https://docs.nestjs.com/security/authentication#reset-forgotten-passwords)
* [Read the current user](https://docs.nestjs.com/security/authentication#read-the-current-user)
* [Issue tokens to the mobile app](https://docs.nestjs.com/security/authentication#issue-tokens-to-the-mobile-app)
* [Add two-factor authentication](https://docs.nestjs.com/security/authentication#add-two-factor-authentication)
* [Add "Sign in with Google"](https://docs.nestjs.com/security/authentication#add-sign-in-with-google)
* [Add magic-link sign-in](https://docs.nestjs.com/security/authentication#add-magic-link-sign-in)
* [Let customers manage their sessions](https://docs.nestjs.com/security/authentication#let-customers-manage-their-sessions)
* [Rate-limit sign-in](https://docs.nestjs.com/security/authentication#rate-limit-sign-in)
* [Keep sessions and tokens in your database](https://docs.nestjs.com/security/authentication#keep-sessions-and-tokens-in-your-database)
* [Issue API keys to partners](https://docs.nestjs.com/security/authentication#issue-api-keys-to-partners)
* [Try it](https://docs.nestjs.com/security/authentication#try-it)
* [GraphQL and WebSockets](https://docs.nestjs.com/security/authentication#graphql-and-websockets)
* [Testing](https://docs.nestjs.com/security/authentication#testing)
* [Production checklist](https://docs.nestjs.com/security/authentication#production-checklist)
* [The store contract](https://docs.nestjs.com/security/authentication#the-store-contract)
* [Reference](https://docs.nestjs.com/security/authentication#reference)

### Authentication

`@nestjs/authentication` signs users in and tells the rest of your application who they are. It registers a global guard, gives you decorators and an injectable context to read the current user, and ships the parts every sign-in flow needs: server-side sessions, password hashing, email verification and password reset links, TOTP two-factor authentication, magic links, OpenID Connect, access and refresh tokens, and API keys. All of them are built on Node.js built-ins, and they keep their state in your database through a store you write against documented interfaces, with the package's tests to check it. You write what only your application knows: how to load a user, which routes are public, and the endpoints of your sign-in flows.

In this tutorial, you'll add sign-in to the API of an online store for cat food and supplies. By the end, it will:

* Sign customers in with a password, with Google, or with a link sent by email, and keep the web app signed in with a session cookie.
* Confirm customers' email addresses, and let them reset a forgotten password.
* Give the mobile app short-lived bearer tokens and rotating refresh tokens.
* Offer two-factor authentication with an authenticator app, and require it to change an account's email address.
* Let customers see where they are signed in, and sign out everywhere.
* Limit how fast anyone can guess passwords.
* Keep its sessions, tokens and pending links in PostgreSQL, through Drizzle (or TypeORM).
* Let partners' systems and customers' scripts call the API with keys that customers create and revoke.

These are the endpoints you'll build, and the section that adds each one:

| Endpoint                                                                                                                              | Section                                                                                             |
| ------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------- |
| `POST /auth/sign-up`, `POST /auth/sign-in`                                                                                            | [Add sign-up and sign-in](/security/authentication#add-sign-up-and-sign-in)                         |
| `POST /auth/email/verify`, `POST /auth/email/verification`                                                                            | [Verify email addresses](/security/authentication#verify-email-addresses)                           |
| `POST /auth/password/forgot`, `POST /auth/password/reset`                                                                             | [Reset forgotten passwords](/security/authentication#reset-forgotten-passwords)                     |
| `GET /me`, `GET /orders`, `POST /orders`                                                                                              | [Read the current user](/security/authentication#read-the-current-user)                             |
| `POST /auth/token`, `POST /auth/token/refresh`                                                                                        | [Issue tokens to the mobile app](/security/authentication#issue-tokens-to-the-mobile-app)           |
| `POST /auth/mfa/enroll`, `POST /auth/mfa/replace`, `POST /auth/mfa/confirm`, `POST /auth/mfa/verify`, `PATCH /me/email`               | [Add two-factor authentication](/security/authentication#add-two-factor-authentication)             |
| `GET /auth/oidc/google/login`, `GET /auth/oidc/google/callback`                                                                       | [Add "Sign in with Google"](/security/authentication#add-sign-in-with-google)                       |
| `POST /auth/magic-link`, `POST /auth/magic-link/consume`                                                                              | [Add magic-link sign-in](/security/authentication#add-magic-link-sign-in)                           |
| `GET /auth/sessions`, `DELETE /auth/sessions/:id`, `POST /auth/sign-out`, `POST /auth/sign-out-everywhere`, `POST /auth/token/revoke` | [Let customers manage their sessions](/security/authentication#let-customers-manage-their-sessions) |
| `POST /auth/api-keys`, `GET /auth/api-keys`, `DELETE /auth/api-keys/:id`                                                              | [Issue API keys to partners](/security/authentication#issue-api-keys-to-partners)                   |

#### Installation[#](/security/authentication#installation)

Install the package:

```bash

$ npm i --save @nestjs/authentication
```

Request bodies are validated with whatever your application already uses. Every DTO on this page comes twice, as a class with decorators and as a Zod schema, so pick the style you have and skip the other listing.

The tutorial keeps users in memory, behind a `UsersRepository` class. Replace its method bodies with Prisma, Drizzle, TypeORM, or whatever your application uses; the rest of the code only sees plain `User` objects. The authentication state (sessions, tokens, authenticators, pending links) moves to PostgreSQL in [Keep sessions and tokens in your database](/security/authentication#keep-sessions-and-tokens-in-your-database).

Starting with email verification, the application reads settings and secrets from environment variables. Keep them in a `.env` file during development, and start the application with it:

```bash

$ npm run start:dev -- --env-file .env
```

#### Register the authentication module[#](/security/authentication#register-the-authentication-module)

The package never reads your users table. It asks your code for a user by id, and your code decides what a user is. Here's the store's user. `emailVerified` records whether the customer proved they own the address; email verification sets it, and placing orders, Google sign-in and magic links depend on it:

src/users/user.ts

JS TS

```typescript

export type Role = 'customer' | 'staff' | 'admin';

export interface User {
  id: string;
  email: string;
  /** Whether the owner proved the address to us, e.g. by using a magic link. */
  emailVerified: boolean;
  roles: Role[];
}
```

The repository keeps password hashes to itself. Everything it returns is a `User` without one, so a user can be returned from a route or written to a log without leaking the hash:

src/users/users.repository.ts

JS TS

```typescript

import { randomUUID } from 'node:crypto';
import { Injectable } from '@nestjs/common';
import type { User } from './user.js';

interface UserRow extends User {
  passwordHash: string | null;
}

/**
 * In-memory stand-in for your data layer (Prisma, Drizzle, TypeORM, ...).
 * Only `User` objects leave this class: password hashes stay inside.
 */
@Injectable()
export class UsersRepository {
  private readonly rows = new Map<string, UserRow>();

  async create(
    email: string,
    { passwordHash = null, emailVerified = false }: { passwordHash?: string | null; emailVerified?: boolean } = {},
  ): Promise<User> {
    const row: UserRow = { id: randomUUID(), email: normalize(email), emailVerified, roles: ['customer'], passwordHash };
    this.rows.set(row.id, row);
    return toUser(row);
  }

  async findById(id: string): Promise<User | null> {
    const row = this.rows.get(id);
    return row ? toUser(row) : null;
  }

  async findByEmail(email: string): Promise<User | null> {
    const row = this.findRow(email);
    return row ? toUser(row) : null;
  }

  /** For password sign-in only. */
  async findCredentials(email: string): Promise<{ user: User; passwordHash: string | null } | null> {
    const row = this.findRow(email);
    return row ? { user: toUser(row), passwordHash: row.passwordHash } : null;
  }

  async updatePasswordHash(id: string, passwordHash: string): Promise<void> {
    const row = this.rows.get(id);
    if (row) {
      row.passwordHash = passwordHash;
    }
  }

  async updateEmail(id: string, email: string): Promise<User | null> {
    const row = this.rows.get(id);
    if (!row) {
      return null;
    }
    row.email = normalize(email);
    row.emailVerified = false; // nobody has proven the new address yet
    return toUser(row);
  }

  private findRow(email: string) {
    const normalized = normalize(email);
    return [...this.rows.values()].find((row) => row.email === normalized);
  }
}

// As the package passes addresses to handlers: an accent typed as two code points matches the stored one.
const normalize = (email: string) => email.trim().normalize('NFC').toLowerCase();
const toUser = ({ id, email, emailVerified, roles }: UserRow): User => ({ id, email, emailVerified, roles: [...roles] });
```

src/users/users.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { UsersRepository } from './users.repository.js';

@Module({
  providers: [UsersRepository],
  exports: [UsersRepository],
})
export class UsersModule {}
```

Next comes a **credential provider**. A provider looks at an incoming request and returns the user the request proves, or `null` when the request carries no credentials it understands. `SessionCookieProvider` reads the session cookie, loads the session, and passes it to your `validate()` method, which loads the user:

src/auth/session-auth.provider.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { AuthenticationRegistry, SessionCookieProvider, type SessionRecord } from '@nestjs/authentication';
import type { User } from '../users/user.js';
import { UsersRepository } from '../users/users.repository.js';

@Injectable()
export class SessionAuth extends SessionCookieProvider<User> {
  constructor(
    private readonly usersRepository: UsersRepository,
    registry: AuthenticationRegistry,
  ) {
    super();
    // Adds this provider to the chain the guard runs for every request.
    registry.registerProvider(this);
  }

  // Called for every request with a live session cookie.
  // Returning null (the user was deleted) ends the session.
  validate(session: SessionRecord) {
    return this.usersRepository.findById(session.userId);
  }
}
```

Providers are ordinary `@Injectable()` classes, so they inject whatever they need, and they register themselves: the constructor hands `this` to `AuthenticationRegistry`, the package's list of providers, which the guard consults. The base class receives `SessionService` through property injection, which is why the constructor lists only `UsersRepository` and the registry. Because `validate()` runs on every authenticated request, a deleted user loses access right away, not when the session expires. When the users live in the same database as the sessions, the store can read the user in the same query and hand it to `validate()` as `session.extra`, so a request costs one read instead of two; [Keep sessions and tokens in your database](/security/authentication#keep-sessions-and-tokens-in-your-database) shows how.

Provide it in a module of your own. `AuthModule` will hold everything this tutorial adds under `src/auth`:

src/auth/auth.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { UsersModule } from '../users/users.module.js';
import { SessionAuth } from './session-auth.provider.js';

@Module({
  imports: [UsersModule],
  providers: [SessionAuth],
})
export class AuthModule {}
```

Now register `AuthenticationModule` in the root module, next to `AuthModule`:

src/app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { AuthenticationModule } from '@nestjs/authentication';
import { AuthModule } from './auth/auth.module.js';
import { UsersModule } from './users/users.module.js';

@Module({
  imports: [
    AuthenticationModule.forRoot({
      session: {
        absoluteTtl: '14d', // signed out after 14 days, however active
        idleTtl: '3d', // or after 3 days without a request
      },
    }),
    UsersModule,
    AuthModule,
  ],
})
export class AppModule {}
```

`forRoot()` takes values only: lifetimes, secrets, client ids, the pages your emails link to. No class goes in the options. The credential providers, the handlers that later sections add and the [database store](/security/authentication#keep-sessions-and-tokens-in-your-database) are providers of your own modules, and each registers itself from its constructor, so it lives next to whatever it injects, and the module's options stay plain data. Lifetimes are milliseconds, or strings such as `'15m'` and `'14d'`, up to 100 years. `@nestjs/jwt` counts seconds instead, so a numeric lifetime under a minute logs a warning at startup: `3600` is 3.6 seconds here, not an hour.

At startup, once every provider's constructor has run, the registry locks and logs the chain it will try:

```bash

LOG [AuthenticationModule] AuthenticationRegistry: providers SessionAuth
```

The module also registers a global guard. From now on, **every route requires a signed-in user** and answers `401 Unauthorized` to anyone else. If your application already has routes that must stay open, such as a health check or the product catalog, mark them with `@Public()`, which the next section introduces.

> **Hint** Sessions are stored in memory until a provider registers a store, and with `NODE_ENV` set to `production` the module refuses to start that way. A [later section](/security/authentication#keep-sessions-and-tokens-in-your-database) moves them to your database.

#### Add sign-up and sign-in[#](/security/authentication#add-sign-up-and-sign-in)

Validate the request bodies first. Sign-up enforces a minimum password length; sign-in doesn't, so that a password set under an older rule still works:

src/auth/auth.dto.ts

JS TS

```typescript

import { IsEmail, IsString, MaxLength, MinLength } from 'class-validator';

export class SignUpDto {
  @IsEmail()
  email: string;

  @IsString()
  @MinLength(12)
  @MaxLength(128)
  password: string;
}

export class SignInDto {
  @IsEmail()
  email: string;

  @IsString()
  password: string;
}
```

The same rules as Zod schemas, whose inferred types replace the classes. Nest 12.1 validates any [Standard Schema](https://standardschema.dev/) object, from Zod, Valibot or ArkType, through `StandardSchemaValidationPipe`:

src/auth/auth.schemas.ts

JS TS

```typescript

import { z } from 'zod';

export const signUpSchema = z.object({
  email: z.email(),
  password: z.string().min(12).max(128),
});
export type SignUpDto = z.infer<typeof signUpSchema>;

export const signInSchema = z.object({
  email: z.email(),
  password: z.string(),
});
export type SignInDto = z.infer<typeof signInSchema>;
```

`PasswordHasher` hashes passwords with scrypt (`crypto.scrypt`, on the libuv threadpool, so it doesn't block the event loop), using OWASP's recommended parameters by default. A service wraps the two things the controller needs:

src/auth/credentials.service.ts

JS TS

```typescript

import { ConflictException, Injectable } from '@nestjs/common';
import { PasswordHasher } from '@nestjs/authentication';
import type { User } from '../users/user.js';
import { UsersRepository } from '../users/users.repository.js';

@Injectable()
export class CredentialsService {
  constructor(
    private readonly usersRepository: UsersRepository,
    private readonly passwordHasher: PasswordHasher,
  ) {}

  async register(email: string, password: string): Promise<User> {
    if (await this.usersRepository.findByEmail(email)) {
      throw new ConflictException('Email already registered');
    }
    // The address is unverified: anyone can type any email into a sign-up form.
    return this.usersRepository.create(email, { passwordHash: await this.passwordHasher.hash(password) });
  }

  /** The user, or `null` when the email or the password is wrong. */
  async verify(email: string, password: string): Promise<User | null> {
    const found = await this.usersRepository.findCredentials(email);
    // With no account (or no password), verify() checks a dummy hash, so the
    // response time does not reveal which emails are registered.
    const valid = await this.passwordHasher.verify(password, found?.passwordHash);
    if (!valid || !found?.passwordHash) {
      return null;
    }
    // The cost settings changed since this hash was stored: upgrade it now,
    // while we have the plaintext.
    if (this.passwordHasher.needsRehash(found.passwordHash)) {
      await this.usersRepository.updatePasswordHash(found.user.id, await this.passwordHasher.hash(password));
    }
    return found.user;
  }
}
```

* `verify()` with no stored hash checks the password against a dummy hash. An unknown email and a wrong password take the same time and produce the same answer, so neither reveals which emails have accounts.
* Passwords are hashed with scrypt from `node:crypto`, at the parameters OWASP recommends (N=2^17, r=8, p=1: about 128 MiB of memory per hash), on the libuv thread pool. That's a memory-hard function, which bcrypt isn't, and it needs no native dependency. Every hash records the parameters it was made with (`$scrypt$ln=17,r=8,p=1$...`). When you raise the cost with the `password` option, `needsRehash()` tells you which stored hashes to upgrade, and the only moment you can do that is while the user signs in. The cost has a ceiling of 1 GiB of memory and 16 times the default work per hash, so with `r` at 8, `logN` stops at 20. Parameters beyond it fail at startup, and a stored hash made with them never verifies.
* `register()` leaves the address unverified. Typing an email into a sign-up form doesn't prove you own it.

The controller turns a verified password into a session:

src/auth/auth.controller.ts

JS TS

```typescript

import { Body, Controller, HttpCode, Post, UnauthorizedException } from '@nestjs/common';
import { Public, SignInService } from '@nestjs/authentication';
import { SignInDto, SignUpDto } from './auth.dto.js';
import { CredentialsService } from './credentials.service.js';

@Public()
@Controller('auth')
export class AuthController {
  constructor(
    private readonly credentialsService: CredentialsService,
    private readonly signInService: SignInService,
  ) {}

  @Post('sign-up')
  async signUp(@Body() body: SignUpDto) {
    const user = await this.credentialsService.register(body.email, body.password);
    await this.signInService.signIn(user.id, { method: 'password' });
    return user;
  }

  @Post('sign-in')
  @HttpCode(200)
  async signIn(@Body() body: SignInDto) {
    const user = await this.credentialsService.verify(body.email, body.password);
    if (!user) {
      throw new UnauthorizedException('Invalid email or password');
    }
    const { session } = await this.signInService.signIn(user.id, { method: 'password' });
    return { mfaRequired: session.mfa === 'pending' };
  }
}
```

`@Public()` on the class skips authentication for both routes. `SignInService.signIn()` is the one place where a first factor becomes a session: this step calls it after a password, and the Google and magic-link steps go through it too. It creates the session and sets the session cookie on the response itself, on Express and Fastify alike, so the controller needs neither `@Req()` nor `@Res()`:

* The cookie, `__Host-sid`, holds a random 256-bit token and is `HttpOnly`, `Secure` and `SameSite=Lax`. The `__Host-` prefix tells browsers to accept it only from this host, so a page on another subdomain can't plant a session cookie of its own. Only the token's SHA-256 hash is stored, so a leaked session store can't be replayed as cookies.
* It deletes the session this browser had before, which defends against session fixation.
* It refuses, with a 403, a sign-in posted from another website's page. Otherwise that page could sign the customer's browser in to an account of the attacker's choosing (login CSRF).
* `method` is recorded in the audit trail, which the section on [managing sessions](/security/authentication#let-customers-manage-their-sessions) mentions.
* `mfaRequired` stays `false` until you [add a second factor](/security/authentication#add-two-factor-authentication).

With the Zod schemas, the body parameters declare their schema instead of a class:

src/auth/auth.controller.ts

JS TS

```typescript

import { signInSchema, signUpSchema, type SignInDto, type SignUpDto } from './auth.schemas.js';
// ...
@Post('sign-up')
async signUp(@Body({ schema: signUpSchema }) body: SignUpDto) {
  // ...
}

@Post('sign-in')
@HttpCode(200)
async signIn(@Body({ schema: signInSchema }) body: SignInDto) {
  // ...
}
```

Register the controller in `AuthModule`:

src/auth/auth.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { UsersModule } from '../users/users.module.js';
import { AuthController } from './auth.controller.js';
import { CredentialsService } from './credentials.service.js';
import { SessionAuth } from './session-auth.provider.js';

@Module({
  imports: [UsersModule],
  controllers: [AuthController],
  providers: [SessionAuth, CredentialsService],
})
export class AuthModule {}
```

> **Hint** The DTOs are enforced only by a validation pipe: bind `ValidationPipe` globally, as an `APP_PIPE` provider of `AppModule` or with `useGlobalPipes()` in `main.ts`. With the Zod schemas, bind `StandardSchemaValidationPipe` the same way instead: an application uses one or the other. The [validation](/application/validation) page has the options of each.

> **Hint** Chrome, Firefox and curl treat `http://localhost` as a secure origin and accept `Secure` and `__Host-` cookies from it, so you don't need HTTPS during development. On another host over plain HTTP, such as a LAN address, set `cookie.secure` to `false` in the `session` options there; the cookie is then named `sid`.

The session cookie is also protected against cross-site request forgery. Besides `SameSite=Lax`, the module ignores the cookie on `POST`, `PUT`, `PATCH` and `DELETE` requests, and on WebSocket handshakes, that come from another origin, judged by the `Sec-Fetch-Site`, `Origin` and `Host` headers, so those requests are anonymous. Clients that send neither `Sec-Fetch-Site` nor `Origin`, such as curl and your mobile app, are unaffected. If your web app runs on another origin than the API, list it in `session.trustedOrigins`.

On Nest 12.1 or later, also call `app.enableCsrfProtection()` in `main.ts`. It makes the same decision for every route, with a 403, including the public ones that have no session to protect yet. Pass it the same `trustedOrigins` as the `session` options.

#### Verify email addresses[#](/security/authentication#verify-email-addresses)

Anyone can type any address into the sign-up form. Until the customer proves the address is theirs, by opening a link sent to it, the store treats it as unverified: it won't take orders whose receipts would go there, and it won't let a Google account or a magic link into that account, as later sections show. The package creates and checks the links. Your application sends them, with the mail library of your choice; the store uses `@nestjs/mail`:

```bash

$ npm i --save @nestjs/mail
```

From this step on, the application reads settings from environment variables. Add the application's public URL to `.env`. The links in the emails point to pages of the web app there:

```bash

APP_URL=http://localhost:3000
```

> **Hint** The tutorial reads `process.env` directly, to stay short. In an application, load the environment through [`@nestjs/config`](/application/configuration) with a validation schema, so a missing or malformed variable stops the application at startup rather than at the first request, and read the values from `ConfigService`.

Register `MailModule` in `AppModule`. Both modules now read environment variables, so `AuthenticationModule` switches to `forRootAsync()`: its factory runs at bootstrap, whereas the argument of `forRoot()` is evaluated when the file is imported, which was fine while every value was a literal. With `@nestjs/config`, add `inject: [ConfigService]` and read the values from the injected service instead. In development, `LogMailTransport` prints each email to the application's log, so you can follow the links; set `SMTP_URL` to send real email. `FileTemplateEngine` renders the bodies of the emails from HTML files in `src/mail/templates`, one per email:

src/app.module.ts

JS TS

```typescript

import { FileTemplateEngine, LogMailTransport, MailModule, SmtpTransport } from '@nestjs/mail';
// ...
import { join } from 'node:path';
// ...

@Module({
  imports: [
    MailModule.forRootAsync({
      useFactory: () => ({
        // Your provider in production. In development, each email (links
        // included) is printed to the log.
        transport: process.env.SMTP_URL ? new SmtpTransport({ url: process.env.SMTP_URL }) : new LogMailTransport(),
        // The emails' HTML: the templates in mail/templates, next to this file
        templates: new FileTemplateEngine({ dir: join(import.meta.dirname, 'mail/templates') }),
        from: 'Accounts <accounts@example.com>',
      }),
    }),
    AuthenticationModule.forRootAsync({
      // ...
```

The TypeScript compiler doesn't copy HTML files to `dist`: add the templates to the assets in `nest-cli.json`, as the [Mail](/application/mail#register-the-mail-module) tutorial shows; it covers the template syntax too.

The verification email is a template. The link goes between double braces, which escape it:

src/mail/templates/verify-email.html

JS TS

```html

<p>Confirm the email address of your store account:</p>
<p><a href="{{ url }}">Confirm my address</a></p>
<p>If you didn't create an account, ignore this email.</p>
```

A mail class renders the email from the template, with the link as its context, and an `EmailVerificationHandler` connects the package to it: `send()` delivers a link, and `markVerified()` records a verified address in your users table. Like a credential provider, a handler registers itself, under the name of the feature it serves:

src/auth/email-verification.mailer.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { AuthenticationRegistry, EmailVerificationHandler, type EmailVerificationLink } from '@nestjs/authentication';
import { Mailer, type Mailable } from '@nestjs/mail';
import { UsersRepository } from '../users/users.repository.js';

@Injectable()
export class VerifyEmailMail implements Mailable<EmailVerificationLink> {
  render({ url }: EmailVerificationLink) {
    return {
      subject: 'Confirm your email address',
      template: 'verify-email',
      context: { url },
    };
  }
}

@Injectable()
export class EmailVerificationMailer extends EmailVerificationHandler {
  constructor(
    private readonly usersRepository: UsersRepository,
    private readonly mailer: Mailer,
    registry: AuthenticationRegistry,
  ) {
    super();
    registry.registerHandler('emailVerification', this);
  }

  async send(link: EmailVerificationLink) {
    await this.mailer.send(VerifyEmailMail, { to: link.email, data: link });
  }

  // Runs when the link is used. It verifies nothing if the address changed since.
  markVerified(userId: string, email: string) {
    return this.usersRepository.markEmailVerified(userId, email);
  }
}
```

`markVerified()` marks only the address the link was sent to. If the customer has changed their address since, the link verifies nothing. The repository updates the row only while the address matches, which in SQL is one conditional update (`UPDATE users SET email_verified = true WHERE id = $1 AND email = $2`):

src/users/users.repository.ts

JS TS

```typescript

/** Only if `email` is still the user's address: a link sent to an old one verifies nothing. */
async markEmailVerified(id: string, email: string): Promise<boolean> {
  const row = this.rows.get(id);
  if (!row || row.email !== normalize(email)) {
    return false;
  }
  row.emailVerified = true;
  return true;
}
```

A feature has two halves: its handler, and its option. Provide the handler in `AuthModule`, and configure the page the links open. One half without the other fails at startup, with a message naming the missing one:

src/auth/auth.module.ts

JS TS

```typescript

providers: [
  SessionAuth,
  CredentialsService,
  EmailVerificationMailer,
],
```

src/app.module.ts

JS TS

```typescript

AuthenticationModule.forRootAsync({
  useFactory: () => ({
    session: {
      // ...
    },
    emailVerification: { url: `${process.env.APP_URL}/verify-email` },
  }),
}),
```

Send the link when a customer signs up:

src/auth/auth.controller.ts

JS TS

```typescript

import { EmailVerificationService, Public, SignInService } from '@nestjs/authentication';
// ...
constructor(
  private readonly credentialsService: CredentialsService,
  private readonly signInService: SignInService,
  private readonly emailVerificationService: EmailVerificationService,
) {}

@Post('sign-up')
async signUp(@Body() body: SignUpDto) {
  const user = await this.credentialsService.register(body.email, body.password);
  await this.signInService.signIn(user.id, { method: 'password' });
  // The link in this email proves the customer owns the address.
  await this.emailVerificationService.send(user);
  return user;
}
```

Then add the endpoints. The link opens a page of the web app, which POSTs the token from its URL back to the API: email scanners and link previews follow links in emails with GET requests, and would use it up before the customer clicks.

src/auth/email-verification.controller.ts

JS TS

```typescript

import { BadRequestException, Body, ConflictException, Controller, HttpCode, Post } from '@nestjs/common';
import { CurrentUser, EmailVerificationService, Public } from '@nestjs/authentication';
import type { User } from '../users/user.js';

@Controller('auth/email')
export class EmailVerificationController {
  constructor(private readonly emailVerificationService: EmailVerificationService) {}

  // Called by the page the link opens, which POSTs the token from its URL.
  @Public()
  @Post('verify')
  @HttpCode(200)
  async verify(@Body('token') token: string) {
    const verified = await this.emailVerificationService.verify(token);
    if (!verified) {
      throw new BadRequestException('Invalid or expired link');
    }
    return { email: verified.email, emailVerified: true };
  }

  // "Send the link again", to the signed-in customer's current address.
  @Post('verification')
  @HttpCode(202)
  async resend(@CurrentUser() user: User) {
    if (user.emailVerified) {
      throw new ConflictException('Email address already verified');
    }
    await this.emailVerificationService.send(user);
  }
}
```

* `EmailVerificationService.send()` stores the SHA-256 hash of a random 256-bit token, with the customer's id and the address, and passes the link to your handler. The token itself only exists in the email.
* A link works once, for 24 hours (`emailVerification.ttl`), and only for the address it was sent to. `verify()` returns `null` for an unknown, used or expired token, and for an address that has changed since, and the route answers 400.
* `resend` isn't `@Public()`: only a signed-in customer can ask for a new link, and only to their own address, so the route reveals nothing about other accounts.

Register the controller:

src/auth/auth.module.ts

JS TS

```typescript

controllers: [
  AuthController,
  EmailVerificationController,
],
```

The package can also require a verified address on a route: `@Authenticate()` with `verifiedEmail: true` answers a signed-in customer whose address isn't verified with a 403. [Read the current user](/security/authentication#read-the-current-user) uses it for placing orders.

> **Hint**`LogMailTransport` logs the text of each email at the `debug` level, links included, so never use it where logs are shipped. In production, set `SMTP_URL`, or pass another transport, such as `ResendTransport`. The [Mail](/application/mail) tutorial covers the options.

#### Reset forgotten passwords[#](/security/authentication#reset-forgotten-passwords)

A customer who forgot their password asks for a link, and chooses a new password on the page it opens. The email that sends the link is another template:

src/mail/templates/password-reset.html

JS TS

```html

<p>Someone asked to reset the password of your store account.</p>
<p><a href="{{ url }}">Choose a new password</a></p>
<p>The link works once, for an hour. If it wasn't you, ignore this email: your password stays as it is.</p>
```

The package owns the tokens; a `PasswordResetHandler` finds accounts, sends the email, and stores the new password's hash:

src/auth/password-reset.mailer.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { AuthenticationRegistry, PasswordResetHandler, type PasswordResetLink } from '@nestjs/authentication';
import { Mailer, type Mailable } from '@nestjs/mail';
import { UsersRepository } from '../users/users.repository.js';

@Injectable()
export class PasswordResetMail implements Mailable<PasswordResetLink> {
  render({ url }: PasswordResetLink) {
    return {
      subject: 'Reset your password',
      template: 'password-reset',
      context: { url },
    };
  }
}

@Injectable()
export class PasswordResetMailer extends PasswordResetHandler {
  constructor(
    private readonly usersRepository: UsersRepository,
    private readonly mailer: Mailer,
    registry: AuthenticationRegistry,
  ) {
    super();
    registry.registerHandler('passwordReset', this);
  }

  // The link goes to the address the account has stored, and works only while
  // the account keeps that address and this hash: any change invalidates it.
  async findUser(email: string) {
    const found = await this.usersRepository.findCredentials(email);
    return found && { id: found.user.id, email: found.user.email, passwordHash: found.passwordHash };
  }

  async send(link: PasswordResetLink) {
    await this.mailer.send(PasswordResetMail, { to: link.email, data: link });
  }

  updatePassword(userId: string, passwordHash: string) {
    return this.usersRepository.updatePasswordHash(userId, passwordHash);
  }
}
```

`findUser()` returns the account's id, its stored address and its stored password hash, `null` for an account without a password. The link goes to that stored address, never to the one typed into the form: a lookup that ignores accents or dots, as MySQL's default collation does, would otherwise mail one customer's link to whoever typed a lookalike address. A link works only while the address and the hash are unchanged, so a password change, by any route, invalidates the links sent before it. Leaving the address or the hash out is an error, which the package logs instead of sending the link.

Enable password reset next to email verification, the handler in `AuthModule` and the page in the options:

src/auth/auth.module.ts

JS TS

```typescript

providers: [
  SessionAuth,
  CredentialsService,
  EmailVerificationMailer,
  PasswordResetMailer,
],
```

src/app.module.ts

JS TS

```typescript

AuthenticationModule.forRootAsync({
  useFactory: () => ({
    // ...
    emailVerification: { url: `${process.env.APP_URL}/verify-email` },
    passwordReset: { url: `${process.env.APP_URL}/reset-password` },
  }),
}),
```

One endpoint takes the address, the other the token and the new password, which follows the sign-up rules:

src/auth/auth.dto.ts

JS TS

```typescript

// ...

export class EmailDto {
  @IsEmail()
  email: string;
}

/** The token from the reset link, and the new password, under the sign-up rules. */
export class ResetPasswordDto {
  @IsString()
  token: string;

  @IsString()
  @MinLength(12)
  @MaxLength(128)
  password: string;
}
```

src/auth/auth.schemas.ts

JS TS

```typescript

export const emailSchema = z.object({
  email: z.email(),
});
export type EmailDto = z.infer<typeof emailSchema>;

/** The token from the reset link, and the new password, under the sign-up rules. */
export const resetPasswordSchema = z.object({
  token: z.string(),
  password: z.string().min(12).max(128),
});
export type ResetPasswordDto = z.infer<typeof resetPasswordSchema>;
```

src/auth/password-reset.controller.ts

JS TS

```typescript

import { BadRequestException, Body, Controller, HttpCode, Post } from '@nestjs/common';
import { PasswordResetService, Public } from '@nestjs/authentication';
import { EmailDto, ResetPasswordDto } from './auth.dto.js';

@Public()
@Controller('auth/password')
export class PasswordResetController {
  constructor(private readonly passwordResetService: PasswordResetService) {}

  // The same answer, as fast, whether or not the address has an account:
  // request() returns before it looks the address up.
  @Post('forgot')
  @HttpCode(202)
  forgot(@Body() body: EmailDto) {
    this.passwordResetService.request(body.email);
  }

  // Called by the page the link opens, with the token from its URL and the new password.
  @Post('reset')
  @HttpCode(200)
  async reset(@Body() body: ResetPasswordDto) {
    const result = await this.passwordResetService.reset(body.token, body.password, { signIn: true });
    if (!result) {
      throw new BadRequestException('Invalid or expired link');
    }
    return { mfaRequired: result.signedIn?.session.mfa === 'pending' };
  }
}
```

* `request()` returns before it looks the address up. Finding the account, storing the token and sending the email happen after the response, so a request for an address nobody registered gets the same 202, in the same time, as a customer's: the route can't tell anyone who has an account. That's why `forgot` doesn't `await` anything. A failure after the response, such as a mail server that is down, is logged.
* A link works once, for an hour (`passwordReset.ttl`), and only while the account still has the address and the password it had when the link was sent.
* `reset()` stores the new password's hash, invalidates the customer's other reset links, and ends every session of the account, and every refresh token once the application [issues them](/security/authentication#issue-tokens-to-the-mobile-app), so whoever knew the old password is signed out everywhere. [API keys](/security/authentication#issue-api-keys-to-partners) live in your own table and stay valid: to cut them off too, revoke them on the `password-reset` event. A password that `PasswordHasher` refuses, empty or over 4 KiB, gets `null` without spending the link, so the customer can try again. With `signIn: true`, it then signs the customer in on this browser through `SignInService`, so a customer with [two-factor authentication](/security/authentication#add-two-factor-authentication) still has to enter a code.
* The link proves the address too, so `reset()` marks it verified, through your `markVerified()`. That also rescues an account that someone else signed up for with the customer's address: the reset replaces the stranger's password and signs them out.

With the Zod schemas:

src/auth/password-reset.controller.ts

JS TS

```typescript

import { emailSchema, resetPasswordSchema, type EmailDto, type ResetPasswordDto } from './auth.schemas.js';
// ...
@Post('forgot')
@HttpCode(202)
forgot(@Body({ schema: emailSchema }) body: EmailDto) {
  this.passwordResetService.request(body.email);
}

@Post('reset')
@HttpCode(200)
async reset(@Body({ schema: resetPasswordSchema }) body: ResetPasswordDto) {
  // ...
}
```

Register the controller:

src/auth/auth.module.ts

JS TS

```typescript

controllers: [
  AuthController,
  EmailVerificationController,
  PasswordResetController,
],
```

#### Read the current user[#](/security/authentication#read-the-current-user)

`@CurrentUser()` injects the user that `validate()` loaded:

src/users/me.controller.ts

JS TS

```typescript

import { Controller, Get } from '@nestjs/common';
import { CurrentUser } from '@nestjs/authentication';
import type { User } from './user.js';

@Controller('me')
export class MeController {
  @Get()
  me(@CurrentUser() user: User) {
    return user;
  }
}
```

`@CurrentUser('id')` injects a single property. `@CurrentSession()` injects what the provider considers the session: here, the stored session record.

> **Hint** Optional: tell the package your user type once, and its types follow. Augment the `AuthenticationTypes` interface of `@nestjs/authentication` in a `declare module` block, with `user: User` (the tutorial keeps it in `src/auth/auth-types.ts`). From then on `@CurrentUser('key')` accepts only keys of `User` and is typed to return that property, and `AuthenticationContext.user` and `.session` are typed too. A `sessionExtra` key types `SessionRecord.extra`, what a session store reads along with each session (exported as `SessionExtra`, `unknown` without the key). It doesn't type the parameter itself: a parameter decorator has no say over the annotation, so `user: User` stays on the parameter. And it is one user type for the whole application, so an application with two kinds of principal keeps the annotations instead. The same interface takes `refreshTokens: false` for an application that [turns refresh tokens off](/security/authentication#issue-tokens-to-the-mobile-app).

src/users/users.module.ts

JS TS

```typescript

@Module({
  controllers: [MeController],
  providers: [UsersRepository],
  exports: [UsersRepository],
})
export class UsersModule {}
```

Controllers aren't the only code that needs the user. Orders belong to the customer who placed them, and `OrdersService` reads that customer from `AuthenticationContext`, so the controller doesn't pass the user down:

src/orders/order.ts

JS TS

```typescript

export interface OrderItem {
  productId: string;
  quantity: number;
}

export interface Order {
  id: string;
  userId: string;
  items: OrderItem[];
  /** In cents. */
  total: number;
  status: 'pending' | 'paid' | 'shipped' | 'refunded';
}
```

src/orders/orders.service.ts

JS TS

```typescript

import { randomUUID } from 'node:crypto';
import { BadRequestException, Injectable } from '@nestjs/common';
import { AuthenticationContext } from '@nestjs/authentication';
import type { Order, OrderItem } from './order.js';

// Stand-in for the products table: product id → price in cents.
const PRICES = new Map([
  ['salmon-kibble-2kg', 2499],
  ['clumping-litter-10l', 1599],
]);

@Injectable()
export class OrdersService {
  private readonly orders: Order[] = [];

  constructor(private readonly authenticationContext: AuthenticationContext) {}

  findMine(): Order[] {
    const { id } = this.authenticationContext.requireUser();
    return this.orders.filter((order) => order.userId === id);
  }

  place(items: OrderItem[]): Order {
    const { id: userId } = this.authenticationContext.requireUser();
    const total = items.reduce((sum, item) => sum + this.price(item.productId) * item.quantity, 0);
    const order: Order = { id: randomUUID(), userId, items, total, status: 'pending' };
    this.orders.push(order);
    return order;
  }

  private price(productId: string): number {
    const price = PRICES.get(productId);
    if (price === undefined) {
      throw new BadRequestException(`Unknown product ${productId}`);
    }
    return price;
  }
}
```

src/orders/orders.controller.ts

JS TS

```typescript

import { Body, Controller, Get, Post } from '@nestjs/common';
import { Authenticate } from '@nestjs/authentication';
import type { OrderItem } from './order.js';
import { OrdersService } from './orders.service.js';

@Controller('orders')
export class OrdersController {
  constructor(private readonly ordersService: OrdersService) {}

  @Get()
  findMine() {
    return this.ordersService.findMine();
  }

  // Receipts and shipping updates go to the customer's email address,
  // so it must be one they proved.
  @Authenticate({ verifiedEmail: true })
  @Post()
  place(@Body('items') items: OrderItem[]) {
    return this.ordersService.place(items);
  }
}
```

`@Authenticate()` with `verifiedEmail: true` lets only customers with a verified address place orders. Anyone else signed in gets a 403 whose `error` is `email_unverified`, which tells the web app to ask the customer to open the [verification link](/security/authentication#verify-email-addresses), or to send it again. It's a 403 rather than a 401: signing in again wouldn't help. `GET /orders` has no such requirement. By default the guard reads `emailVerified` from the user that `validate()` loaded; your `EmailVerificationHandler` can override `isVerified(user)` if your user type stores it differently.

src/orders/orders.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { OrdersController } from './orders.controller.js';
import { OrdersService } from './orders.service.js';

@Module({
  controllers: [OrdersController],
  providers: [OrdersService],
})
export class OrdersModule {}
```

Add `OrdersModule` to the `imports` of `AppModule`:

src/app.module.ts

JS TS

```typescript

UsersModule,
AuthModule,
OrdersModule,
```

`AuthenticationContext` is a singleton. It reads the current request's user from an `AsyncLocalStorage` that the module opens around each handler, so it's correct in anything the handler calls or awaits, however many requests run at the same time. `requireUser()` returns the user, or throws an `AuthenticationError`, which the module answers with a 401 on any transport. Outside a request, in a queue consumer or a cron job, `AuthenticationContext` is empty, and its `run()` method runs a function as a given user. It's also empty in middleware, guards and exception filters, which run outside the handler.

#### Issue tokens to the mobile app[#](/security/authentication#issue-tokens-to-the-mobile-app)

The store's mobile app authenticates with bearer tokens rather than cookies. It sends a short-lived JWT access token in the `Authorization` header, and renews it with a long-lived refresh token.

Add a signing secret to `.env`. It must be at least 32 bytes. Without it, the application refuses to start, naming the option: `accessToken.key` is required.

```bash

# Generate with: openssl rand -base64 32
JWT_SECRET=
```

The application both issues and verifies the access tokens, so describe them once, with the `accessToken` options. The key signs them, and the issuer, audience and lifetime go into every token and are checked on every request:

src/app.module.ts

JS TS

```typescript

AuthenticationModule.forRootAsync({
  useFactory: () => ({
    session: {
      // ...
    },
    accessToken: {
      key: process.env.JWT_SECRET!,
      issuer: 'https://api.example.com',
      audience: 'mobile-app',
      ttl: '15m',
    },
  }),
}),
```

With a secret as the key, tokens are signed with HS256. The second credential provider verifies them. `JwtBearerProvider` reads the `Authorization` header, checks the signature against the `accessToken` key, and `exp`, `iss` and `aud`, and passes the verified claims to your `validate()`:

src/auth/jwt-auth.provider.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { AuthenticationRegistry, JwtBearerProvider, type JwtClaims } from '@nestjs/authentication';
import type { User } from '../users/user.js';
import { UsersRepository } from '../users/users.repository.js';

@Injectable()
export class JwtAuth extends JwtBearerProvider<User> {
  constructor(
    private readonly usersRepository: UsersRepository,
    registry: AuthenticationRegistry,
  ) {
    // The key, issuer and audience come from the `accessToken` options.
    super({ realm: 'store' });
    // Second in the chain, after SessionAuth (order 0).
    registry.registerProvider(this, { order: 1 });
  }

  // Called after the signature and claims checked out.
  // Returning null (the user was deleted) rejects the token.
  validate({ sub }: JwtClaims) {
    return sub ? this.usersRepository.findById(sub) : null;
  }
}
```

> **Hint** HS256 with a shared secret suits an API that both issues and verifies its tokens. If other services verify them too, make the `accessToken` key an ES256 private key: `JwtAuth` then verifies with its public half, and so can they. To accept tokens from another issuer instead, pass `super()` its `jwks` URL, which must be https (plain http only on localhost), or its public `key`, with `issuer` and `audience`: both are required, because an identity provider signs every client's tokens with the same keys. For tokens without an audience, pass `audience: false` and check the claim that names your client in `validate()`. Add `clockTolerance: '30s'` for another issuer's clock. Keys are PEM text or a `KeyObject`; import a JWK with `createPublicKey()` from `node:crypto`, passing the JWK as `key` and `'jwk'` as `format`. An empty `key` or `jwks`, such as an unset environment variable, fails at startup instead of falling back to the `accessToken` options. A service that only verifies tokens can leave `accessToken` out entirely and give `super()` what it verifies with: the shared `key`, or the `jwks` with `issuer` and `audience`.

Provide it in `AuthModule`:

src/auth/auth.module.ts

JS TS

```typescript

providers: [
  SessionAuth,
  JwtAuth,
  CredentialsService,
],
```

For each request, the guard asks the providers in ascending `order`, and the first one that returns a user wins. `SessionAuth` registered with the default order, `0`, and `JwtAuth` asked for `1`, so a request with a session cookie is signed in by `SessionAuth`, and a request with a bearer token, which has no cookie, gets `null` from `SessionAuth` and is handled by `JwtAuth`. The order is given at registration rather than left to the order in which Nest constructs the providers: that one follows the module graph, and changes when a provider moves to another module or an import is added. Two providers asking for the same order fail at startup, naming both. A request with neither gets a 401 with `missing_credentials` as its `errorCode`; its `WWW-Authenticate` header lists what the providers accept: `Bearer realm="store"`. A token that fails verification gets a 401 that says why, as RFC 6750 describes, for example `error="invalid_token", error_description="token expired"`. That tells the mobile app to refresh.

Now the endpoints that issue tokens:

src/auth/tokens.controller.ts

JS TS

```typescript

import { Body, Controller, HttpCode, Post, UnauthorizedException } from '@nestjs/common';
import { Public, TokenService } from '@nestjs/authentication';
import { SignInDto } from './auth.dto.js';
import { CredentialsService } from './credentials.service.js';

@Public()
@Controller('auth/token')
export class TokensController {
  constructor(
    private readonly credentialsService: CredentialsService,
    private readonly tokenService: TokenService,
  ) {}

  @Post()
  @HttpCode(200)
  async issue(@Body() body: SignInDto) {
    const user = await this.credentialsService.verify(body.email, body.password);
    if (!user) {
      throw new UnauthorizedException('Invalid email or password');
    }
    return this.tokenService.issue(user.id, {
      method: 'password',
      // `amr` goes into this access token and into every refreshed one.
      claims: { amr: ['pwd'] },
    });
  }

  // An unknown, expired or reused refresh token gets a 401.
  @Post('refresh')
  @HttpCode(200)
  refresh(@Body('refreshToken') refreshToken: string) {
    return this.tokenService.refresh(refreshToken);
  }
}
```

`TokenService.issue()` signs an access token with the `accessToken` options, starts a refresh token, and returns both, with `expiresIn`, the access token's lifetime in seconds. Refresh tokens are opaque, and stored as hashes. Each one works once: `refresh()` spends it and returns its successor, with a new access token. The successors of one sign-in form a family. If a spent token comes back, two parties hold it, a thief and the app, so the service revokes the whole family and both have to sign in again. A refresh token that is unknown, expired or reused throws `RefreshTokenError`, an `AuthenticationError`, which the module answers with a 401, so `refresh` needs no error handling of its own.

The `amr` claim records how the user signed in, and [two-factor authentication](/security/authentication#add-two-factor-authentication) relies on it. `issue()` stores the `claims` with the refresh-token family, and `refresh()` puts them into every access token it mints, so refreshed tokens describe the same sign-in. Keep facts that can change, such as roles, out of `claims`: they would stay in the tokens for as long as the family lives. `validate()` loads the current user on every request instead.

A service that signs short-lived access tokens and has its clients sign in again can turn refresh tokens off. With `refreshToken` set to `false`, `issue()` returns `accessToken` and `expiresIn` alone, and stores nothing, so the application needs no `RefreshTokenStore`. The token endpoint's response has no refresh token: clients sign in again when the access token expires. `refresh()` and `revoke()` throw, saying refresh tokens are disabled, and `revokeAll()` does nothing. The second factor and the `amr` claim work as before. Declare `refreshTokens: false` on `AuthenticationTypes` too, so `issue()` is typed to return an `AccessTokenResult` rather than a `TokenPair`:

src/app.module.ts

JS TS

```typescript

AuthenticationModule.forRootAsync({
  useFactory: () => ({
    accessToken: {
      key: process.env.JWT_SECRET!,
      // ...
    },
    refreshToken: false,
  }),
}),
```

src/auth/auth-types.ts

JS TS

```typescript

declare module '@nestjs/authentication' {
  interface AuthenticationTypes {
    // ...
    refreshTokens: false;
  }
}
```

The option is what runs; the declaration only tells the compiler. An application that sets the option without the declaration gets no refresh token at run time, typed as a string, and `refresh()` throws on it. `refreshToken` set to `false` without `accessToken` changes nothing, and logs a warning at startup.

Register the controller:

src/auth/auth.module.ts

JS TS

```typescript

controllers: [
  AuthController,
  EmailVerificationController,
  PasswordResetController,
  TokensController,
],
```

#### Add two-factor authentication[#](/security/authentication#add-two-factor-authentication)

Customers can protect their accounts with an authenticator app (time-based one-time passwords, or TOTP). Configure `mfa` in `AppModule`:

src/app.module.ts

JS TS

```typescript

AuthenticationModule.forRootAsync({
  useFactory: () => ({
    // ...
    mfa: {
      issuer: 'example.com',
      encryption: { keys: [process.env.TOTP_ENCRYPTION_KEY!] },
    },
  }),
}),
```

The server has to read a TOTP secret back to check codes, so, unlike a password, it can't be hashed. `MfaService` encrypts each secret with AES-256-GCM before it reaches storage, bound to its user, and decrypts it only to verify a code. Anyone holding a copy of your database, but not the key, can't generate codes. The key is required: configuring `mfa` without `encryption` throws at startup. (`encryption: false` stores plaintext on purpose, for tests.) A secret shorter than 128 bits never verifies: `enroll()` makes 160, but secrets imported from another system may be shorter, and their users enroll again.

Add the key to `.env`. A string key must be at least 32 characters of random data:

```bash

# Generate with: openssl rand -base64 32
TOTP_ENCRYPTION_KEY=
```

> **Hint** To rotate the key, put a new one first in `keys` and keep the old one after it. The first key encrypts, every listed key decrypts, and secrets are re-encrypted with the new key as they're used. Remove the old key once nothing uses it. Keys need no names: each encrypted secret records an id derived from its key.

Two-factor authentication is off unless `mfa` is configured. Without it, `MfaService.isEnrolled()` answers `false` without reading the store, so sign-ins never ask for a code, and every other `MfaService` method throws `MFA is not configured` before touching storage. Removing `mfa` from the options turns two-factor authentication off for every customer, including those who already enrolled an authenticator.

The MFA endpoints enroll an authenticator, confirm it, and complete a sign-in:

src/auth/mfa.controller.ts

JS TS

```typescript

import { Body, Controller, HttpCode, Post, UnauthorizedException } from '@nestjs/common';
import { Authenticate, CurrentUser, MfaService, Public, SignInService } from '@nestjs/authentication';
import type { User } from '../users/user.js';

@Controller('auth/mfa')
export class MfaController {
  constructor(
    private readonly mfaService: MfaService,
    private readonly signInService: SignInService,
  ) {}

  // Returns the otpauth:// URI for the web app to show as a QR code,
  // and the secret for people who type it in instead.
  @Post('enroll')
  enroll(@CurrentUser() user: User) {
    return this.mfaService.enroll(user.id, user.email);
  }

  // A new phone. The current authenticator keeps working until /confirm
  // receives a code from the new one.
  @Authenticate({ mfa: true })
  @Post('replace')
  replace(@CurrentUser() user: User) {
    return this.mfaService.enroll(user.id, user.email, { replace: true });
  }

  // The first code proves the authenticator works, and that this browser has
  // it: the session passes the second factor from here on, under a new cookie.
  // Recovery codes are shown once.
  @Post('confirm')
  @HttpCode(200)
  async confirm(@CurrentUser('id') userId: string, @Body('code') code: string) {
    if (!(await this.signInService.confirmMfa(userId, code))) {
      throw new UnauthorizedException('Invalid code');
    }
    return { recoveryCodes: await this.mfaService.generateRecoveryCodes(userId) };
  }

  // Second step of signing in. A pending session counts as signed in
  // nowhere, so the route is public: completeMfa() reads the session cookie.
  @Public()
  @Post('verify')
  @HttpCode(200)
  async verify(@Body('code') code: string | undefined, @Body('recoveryCode') recoveryCode: string | undefined) {
    const issued = await this.signInService.completeMfa({ code, recoveryCode });
    if (!issued) {
      throw new UnauthorizedException('Invalid code');
    }
    return { mfa: issued.session.mfa };
  }
}
```

* `enroll()` stores a new, unconfirmed secret, and returns it with an `otpauth://` URI that the web app shows as a QR code. Once an authenticator is confirmed, `enroll()` refuses to overwrite it and throws `MfaAlreadyEnrolledError`, which the module answers with a 409, `Authenticator already enrolled`. Overwriting it would switch two-factor authentication off until the new one was confirmed.
* `replace` handles a new phone. `enroll()` with `replace: true` stages a second secret, and the current authenticator keeps working until `confirm()` receives a code from the new one. `@Authenticate()` with `mfa: true` makes the route require a verified second factor, so a stolen password alone can't swap in someone else's authenticator.
* `SignInService.confirmMfa()` activates the authenticator once it produces a valid code, so a mistyped secret can't lock anyone out. That code also proves this browser has the authenticator, so the session becomes verified, under a new cookie: the customer can use the routes that require a second factor right away, without signing in again. A confirmation sent with a bearer token, which has no session, only activates the authenticator. The ten recovery codes the route returns are shown only this once, and stored under a slow hash salted with the customer's id, so a copy of the database doesn't reveal them.
* Once an authenticator is confirmed, `SignInService.signIn()` creates **pending** sessions for that user. A pending session isn't signed in anywhere: routes that need a user answer with a 401 and `"errorCode": "mfa_required"`, which tells the web app to ask for a code. That's why `verify` is `@Public()`. `completeMfa()` reads the session from this browser's cookie, checks a code or a recovery code, and rotates the session to a new id with `mfa: 'verified'`, setting the new cookie. A pending session expires after 10 minutes (`mfa.pendingTtl`), not after the 14 days of `session.absoluteTtl`: a pending cookie is half a credential. Verifying the code gives the session its full lifetime.
* `completeMfa()` only acts on the session cookie. A request with a bearer token and no cookie gets a 401.
* Codes are accepted 30 seconds either side of now, and each code works once. After 5 wrong codes in 15 minutes, the account refuses every code, right ones included, until the window passes. Each attempt is counted before it's checked, so sending guesses in parallel doesn't get around the limit.

A verified second factor can also be required for individual routes, which is called step-up authentication. The store requires it to change the email address, since that's how an account is recovered. The new address arrives in the `EmailDto` of [Reset forgotten passwords](/security/authentication#reset-forgotten-passwords). Add the route, with `@Authenticate()`:

src/users/me.controller.ts

JS TS

```typescript

import { Body, ConflictException, Controller, Get, Patch } from '@nestjs/common';
import { Authenticate, CurrentUser, EmailVerificationService } from '@nestjs/authentication';
import { EmailDto } from '../auth/auth.dto.js';
import type { User } from './user.js';
import { UsersRepository } from './users.repository.js';

@Controller('me')
export class MeController {
  constructor(
    private readonly usersRepository: UsersRepository,
    private readonly emailVerificationService: EmailVerificationService,
  ) {}

  @Get()
  me(@CurrentUser() user: User) {
    return user;
  }

  // The email address is how an account is recovered: changing it needs a
  // session (or token) that passed the second factor.
  @Authenticate({ mfa: true })
  @Patch('email')
  async changeEmail(@CurrentUser('id') userId: string, @Body() body: EmailDto) {
    if (await this.usersRepository.findByEmail(body.email)) {
      throw new ConflictException('Email already registered');
    }
    const user = await this.usersRepository.updateEmail(userId, body.email);
    if (user) {
      // The new address is unverified until the customer uses this link.
      await this.emailVerificationService.send(user);
    }
    return user;
  }
}
```

With the Zod schema:

src/users/me.controller.ts

JS TS

```typescript

import { emailSchema, type EmailDto } from '../auth/auth.schemas.js';
// ...
@Authenticate({ mfa: true })
@Patch('email')
async changeEmail(@CurrentUser('id') userId: string, @Body({ schema: emailSchema }) body: EmailDto) {
  // ...
}
```

Every route already requires a signed-in user; `@Authenticate()` adjusts how. With `mfa: true`, a cookie session passes once it's verified. A customer who hasn't enrolled an authenticator can't pass it, so the web app asks them to enroll first.

The new address is unverified, so the route sends a verification link to it, and the customer can't place orders until they use it. The links sent to the old address stop working: they verify only the address they were sent to.

The mobile app must not become a way around the second factor, and it can't be: like `signIn()`, `TokenService.issue()` gives a customer with a confirmed authenticator no tokens without a code. It answers 401 with `"errorCode": "mfa_required"`, which tells the app to ask for one. The app then sends the password again, with the code. Add the code to the body:

src/auth/auth.dto.ts

JS TS

```typescript

import { IsEmail, IsOptional, IsString, MaxLength, MinLength } from 'class-validator';

// ...

/** The mobile app's sign-in: a password, and a code once the customer has an authenticator. */
export class TokenRequestDto extends SignInDto {
  @IsOptional()
  @IsString()
  code?: string;

  @IsOptional()
  @IsString()
  recoveryCode?: string;
}
```

src/auth/auth.schemas.ts

JS TS

```typescript

/** The mobile app's sign-in: a password, and a code once the customer has an authenticator. */
export const tokenRequestSchema = signInSchema.extend({
  code: z.string().optional(),
  recoveryCode: z.string().optional(),
});
export type TokenRequestDto = z.infer<typeof tokenRequestSchema>;
```

And pass it on as the `secondFactor`:

src/auth/tokens.controller.ts

JS TS

```typescript

@Post()
@HttpCode(200)
async issue(@Body() body: TokenRequestDto) {
  const user = await this.credentialsService.verify(body.email, body.password);
  if (!user) {
    throw new UnauthorizedException('Invalid email or password');
  }
  return this.tokenService.issue(user.id, {
    method: 'password',
    // `amr` goes into this access token and into every refreshed one.
    claims: { amr: ['pwd'] },
    // Checked only for customers with an authenticator.
    secondFactor: { code: body.code, recoveryCode: body.recoveryCode },
  });
}
```

src/auth/tokens.controller.ts

JS TS

```typescript

import { tokenRequestSchema, type TokenRequestDto } from './auth.schemas.js';
// ...
@Post()
@HttpCode(200)
async issue(@Body({ schema: tokenRequestSchema }) body: TokenRequestDto) {
  // ...
}
```

A request without a code isn't counted as a failed attempt, so the app can find out whether it needs one. A verified code adds `mfa` to the `amr` claim. `JwtBearerProvider` treats a token whose `amr` contains `mfa`, `otp` or `hwk` as verified, so it passes `mfa: true` routes. Refreshed tokens carry the same `amr` as the sign-in that started their family, so a mobile app that signed in with a code stays verified until its refresh tokens expire or are revoked. `issue()` never takes those three values from your own `claims`: it drops them, with a warning in the log, and adds `mfa` only once it has verified a code, so an application can't mint a verified token by accident.

Register the controller:

src/auth/auth.module.ts

JS TS

```typescript

controllers: [
  // ...
  TokensController,
  MfaController,
],
```

##### Turn off two-factor authentication[#](/security/authentication#turn-off-two-factor-authentication)

`MfaService.disable()` removes the customer's authenticator and their recovery codes, and emits `mfa-disabled`. Add a route to `MfaController`, with `SessionService` and `TokenService` injected into its constructor:

src/auth/mfa.controller.ts

JS TS

```typescript

// Takes a verified session and a fresh code: a session left signed in on a
// shared computer isn't enough.
@Authenticate({ mfa: true })
@Post('disable')
@HttpCode(204)
async disable(
  @CurrentUser('id') userId: string,
  @CurrentSession() current: SessionRecord,
  @Body('code') code: string,
) {
  if (!(await this.mfaService.verifyTotp(userId, code))) {
    throw new UnauthorizedException('Invalid code');
  }
  await this.mfaService.disable(userId);
  // The other sessions and refresh tokens passed the second factor, and still would.
  await this.sessionService.revokeAll(userId, { except: current.id });
  await this.tokenService.revokeAll(userId);
}
```

* `@Authenticate()` with `mfa: true` is the minimum: without it, a stolen password alone could turn the second factor off. An API key never passes it. It doesn't prove the customer is at the keyboard now, though: a session stays verified for its whole lifetime. So the route asks for a code as well. `verifyTotp()` resolves `false` for a wrong code, counts toward the same lockout as signing in, and each code works once.
* `disable()` deletes every recovery code along with the authenticator, and drops a replacement staged by `replace` that was never confirmed. Enrolling again starts from scratch, with a new batch of recovery codes.
* `disable()` leaves sessions and tokens alone. The customer's other verified sessions would keep passing `mfa: true` routes, and so would their refresh-token families, whose `amr` keeps `mfa` on every refresh. The route ends them, keeping this browser's session. Access tokens already issued stay valid until they expire. Sent with a bearer token, the request has no session id to keep: every session ends, and `TokenService.revokeAll()` signs that client out too.
* A session still waiting for its second factor can't complete it, since there's no authenticator left to check a code against. `revokeAll()` ends it with the others.
* A customer whose enrollment was never confirmed has no verified session, so this route refuses them. To cancel such an enrollment, call `disable()` from a route without it while `isEnrolled()` is `false`, or call `enroll()` again.

#### Add "Sign in with Google"[#](/security/authentication#add-sign-in-with-google)

In the Google Cloud console, create an OAuth client ID of type **Web application**, and add this authorized redirect URI (and the production one, when you deploy):

```bash

http://localhost:3000/auth/oidc/google/callback
```

Add the client's credentials to `.env`, next to `APP_URL`:

```bash

GOOGLE_CLIENT_ID=
GOOGLE_CLIENT_SECRET=
```

The first time someone signs in with Google, your application has to decide which local account that Google account belongs to. Store the link as a (provider, subject) pair, where the subject is Google's stable id for the account. Emails change; subjects don't. Add an identities table to the repository:

src/users/users.repository.ts

JS TS

```typescript

@Injectable()
export class UsersRepository {
  private readonly rows = new Map<string, UserRow>();
  /** `provider:subject` → user id, e.g. `google:1098...` */
  private readonly identities = new Map<string, string>();

  // ...

  async findByIdentity(provider: string, subject: string): Promise<User | null> {
    const id = this.identities.get(`${provider}:${subject}`);
    return id ? this.findById(id) : null;
  }

  async linkIdentity(id: string, provider: string, subject: string): Promise<User | null> {
    this.identities.set(`${provider}:${subject}`, id);
    return this.findById(id);
  }
```

The package asks an `OidcAccountResolver` for that decision:

src/auth/account-linker.ts

JS TS

```typescript

import { ConflictException, ForbiddenException, Injectable } from '@nestjs/common';
import {
  AuthenticationRegistry,
  OidcAccountResolver,
  type OAuthTokens,
  type OidcProfile,
  type OidcResolveContext,
} from '@nestjs/authentication';
import { UsersRepository } from '../users/users.repository.js';

@Injectable()
export class AccountLinker extends OidcAccountResolver {
  constructor(
    private readonly usersRepository: UsersRepository,
    registry: AuthenticationRegistry,
  ) {
    super();
    registry.registerHandler('oidc', this);
  }

  async resolveUser(profile: OidcProfile, _tokens: OAuthTokens, { linkTo }: OidcResolveContext) {
    const linked = await this.usersRepository.findByIdentity(profile.provider, profile.subject);

    // "Connect Google" from the account page: link to the signed-in customer.
    if (linkTo) {
      if (linked && linked.id !== linkTo.id) {
        throw new ConflictException('This Google account belongs to another customer');
      }
      return this.usersRepository.linkIdentity(linkTo.id, profile.provider, profile.subject);
    }

    // A returning Google account: sign in the user it is linked to.
    if (linked) {
      return linked;
    }

    // First visit. Trust only an address Google verified, or anyone could
    // claim any account.
    if (!profile.email || !profile.emailVerified) {
      return null; // 403
    }
    const existing = await this.usersRepository.findByEmail(profile.email);
    if (!existing) {
      const user = await this.usersRepository.create(profile.email, { emailVerified: true });
      return this.usersRepository.linkIdentity(user.id, profile.provider, profile.subject);
    }
    // Link by email only if the account's owner proved the address to us too.
    // Otherwise whoever signed up with it, with a password of their choosing,
    // would share the account with the customer.
    if (!existing.emailVerified) {
      throw new ForbiddenException('Sign in with your password, then connect Google from your account');
    }
    return this.usersRepository.linkIdentity(existing.id, profile.provider, profile.subject);
  }
}
```

Linking by email needs both sides to have verified the address:

* **Google must have verified it** (`profile.emailVerified`). Otherwise, anyone could create a Google account with a customer's address and take over their account at the store. Returning `null` refuses the sign-in with a 403.
* **The store account must have verified it too** (`existing.emailVerified`). Otherwise, someone could sign up first with a customer's address and a password of their choosing, and keep access once the customer signs in with Google. This is called account pre-hijacking. An account created with a password is unverified until its owner opens the [verification link](/security/authentication#verify-email-addresses), or [resets the password](/security/authentication#reset-forgotten-passwords). Until then, it gets a 403 that asks the customer to sign in with their password and connect Google from their account.

Connecting Google to an account the customer is signed in to needs no email match at all. The package calls it a link flow: the web app's "Connect Google" button points to `GET /auth/oidc/google/login?link=true`. The package only starts it for a fully signed-in session, and not from another site's page, which gets a 403: a link attaches whatever Google account is signed in on this browser. On the callback it checks that the same session is still live, then calls `resolveUser()` with `linkTo`, the signed-in user. The resolver links the Google account to them, unless it already belongs to another customer. The session stays as it is, and the browser is redirected to `redirectTo`.

Enable OpenID Connect with the `google()` preset and the URL Google sends the browser back to. `:provider` stands for the provider's name, so one callback route serves every provider you add:

src/app.module.ts

JS TS

```typescript

AuthenticationModule.forRootAsync({
  useFactory: () => ({
    // ...
    oidc: {
      // The callback route of OidcController, registered with Google.
      callbackUrl: `${process.env.APP_URL}/auth/oidc/:provider/callback`,
      providers: {
        google: google({
          clientId: process.env.GOOGLE_CLIENT_ID!,
          clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
        }),
      },
    },
  }),
}),
```

The routes are yours, so they sit with your other routes, under your prefixes, versions and throttling. `OidcService.start()` builds the redirect to Google and `finish()` handles the callback; a controller exposes the two:

src/auth/oidc.controller.ts

JS TS

```typescript

import { Controller, Get, Param, Query, Redirect } from '@nestjs/common';
import { OidcService, Public } from '@nestjs/authentication';

@Public()
@Controller('auth/oidc')
export class OidcController {
  constructor(private readonly oidcService: OidcService) {}

  // "Sign in with Google" links here. With ?link=true, "Connect Google"
  // links the Google account to the signed-in customer instead.
  @Get(':provider/login')
  @Redirect()
  login(@Param('provider') provider: string, @Query('redirectTo') redirectTo?: string, @Query('link') link?: string) {
    return this.oidcService.start(provider, { redirectTo, link: link === 'true' });
  }

  // Where Google sends the browser back.
  @Get(':provider/callback')
  @Redirect()
  callback(@Param('provider') provider: string, @Query() query: Record<string, string>) {
    return this.oidcService.finish(provider, query);
  }
}
```

* `GET /auth/oidc/google/login?redirectTo=/orders` redirects the browser to Google. The web app's "Sign in with Google" button is a plain link to it. `start()` uses the authorization code flow with PKCE, a `state` and a `nonce`. The login transaction is stored server-side under `state`, and the browser gets a secret whose SHA-256 hash is the `state`, in an `HttpOnly` cookie named `__Host-oidc_tx`, for 10 minutes.
* `GET /auth/oidc/google/callback` is where Google sends the browser back. `finish()` checks that the `state` in the query is the hash of the secret in the browser's cookie (so nobody can finish a login they didn't start in this browser, even with a callback URL read from a log or a browser's history), exchanges the code, verifies the ID token's signature against Google's published keys, and checks its issuer, audience, expiry and nonce. If Google can't be reached, or answers with an endpoint that isn't https, the answer is a 502, not a 401. It then calls `resolveUser()`, signs the user in through `SignInService` (so a customer with an authenticator gets a pending session), and returns the redirect to `redirectTo`, or to `/`. Only relative paths are accepted as `redirectTo`, so the login can't be turned into an open redirect.
* Both read the request and set their cookies through Nest's HTTP adapter, and return what `@Redirect()` expects, so the controller works on Express and Fastify alike, without `@Req()` or `@Res()`.

Register the controller and the resolver in `AuthModule`:

src/auth/auth.module.ts

JS TS

```typescript

controllers: [
  // ...
  MfaController,
  OidcController,
],
providers: [
  // ...
  PasswordResetMailer,
  AccountLinker,
],
```

The `github()` preset works the same way. `microsoft()` also takes your directory's tenant id as its `tenant` option, next to `clientId` and `clientSecret`: a GUID from the Overview page of the Microsoft Entra admin center, such as `process.env.ENTRA_TENANT_ID`. A domain, or the multi-tenant `common`, `organizations` and `consumers`, fails at startup: for those, Microsoft publishes another issuer than the one asked for, and every sign-in would fail. Add them next to `google` in `providers`, and register the callback URL with each of them, with its name in place of `google`.

An application served under several domains, such as one domain per customer, can't name a single callback URL: a login started on one domain must come back to that domain. Pass a function of the request as `callbackUrl` instead. `start()` calls it on the login, and `finish()` calls it again on the callback, so it must return the same URL for both. Compare the host with your own list of domains rather than trusting the header, and register every URL it can return with each provider:

src/app.module.ts

JS TS

```typescript

oidc: {
  callbackUrl: ({ headers }) => {
    const host = CUSTOMER_DOMAINS.find((domain) => domain === headers.host);
    if (!host) {
      throw new NotFoundException();
    }
    return `https://${host}/auth/oidc/:provider/callback`;
  },
  providers: {
    // ...
  },
},
```

The function can also be `async`, to look the domains up in your database. Whatever it throws is the login's answer, like the 404 above for a domain the application doesn't serve, and a URL that isn't absolute fails the login with an error that names the function. The `__Host-oidc_tx` cookie belongs to the domain that set it, so a login finishes on the domain where it started. If the function ever returned another URL on the callback, the provider would refuse the code, and the callback would get a 401. Behind a proxy that rewrites the host, read the header it forwards instead, such as `X-Forwarded-Host`, and only from a proxy you trust.

#### Add magic-link sign-in[#](/security/authentication#add-magic-link-sign-in)

A magic link signs a customer in from their inbox, without a password. The package creates and checks the links; delivering them is up to you, through a `MagicLinkHandler`. The store emails them like the verification links, with a template and a mail class of their own:

src/mail/templates/magic-link.html

JS TS

```html

<p><a href="{{ url }}">Sign in to the store</a></p>
<p>The link works once, for 15 minutes. If you didn't ask for it, ignore this email.</p>
```

src/auth/magic-link.mailer.ts

JS TS

```typescript

import { ForbiddenException, Injectable } from '@nestjs/common';
import { AuthenticationRegistry, MagicLinkHandler, type MagicLink } from '@nestjs/authentication';
import { Mailer, type Mailable } from '@nestjs/mail';
import { UsersRepository } from '../users/users.repository.js';

@Injectable()
export class MagicLinkMail implements Mailable<MagicLink> {
  render({ url }: MagicLink) {
    return {
      subject: 'Your sign-in link',
      template: 'magic-link',
      context: { url },
    };
  }
}

@Injectable()
export class MagicLinkMailer extends MagicLinkHandler {
  constructor(
    private readonly usersRepository: UsersRepository,
    private readonly mailer: Mailer,
    registry: AuthenticationRegistry,
  ) {
    super();
    registry.registerHandler('magicLink', this);
  }

  async send(link: MagicLink) {
    await this.mailer.send(MagicLinkMail, { to: link.email, data: link });
  }

  // Runs when the link is used, which proves the address. The account returned
  // carries its stored `email`, and signs in only if the link went to that address.
  async resolveUser(email: string) {
    const user = await this.usersRepository.findByEmail(email);
    if (!user) {
      // Passwordless sign-up. Return null instead to refuse unknown addresses.
      return this.usersRepository.create(email, { emailVerified: true });
    }
    // A password account whose address nobody confirmed: whoever chose that
    // password may not own the address. Resetting the password proves both.
    if (!user.emailVerified) {
      throw new ForbiddenException('Sign in with your password, or reset it');
    }
    return user;
  }
}
```

Enable magic links: the handler in `AuthModule`, and the URL the links point to in the options:

src/auth/auth.module.ts

JS TS

```typescript

providers: [
  // ...
  AccountLinker,
  MagicLinkMailer,
],
```

src/app.module.ts

JS TS

```typescript

AuthenticationModule.forRootAsync({
  useFactory: () => ({
    // ...
    magicLink: { url: `${process.env.APP_URL}/sign-in/magic` },
  }),
}),
```

`MagicLinkService.create()` makes a random 256-bit token, valid for 15 minutes and usable once, and passes the link to your handler. It stores the SHA-256 hash of the token combined with a secret that only this browser's transaction cookie holds (see below), so a link read from a log, or forwarded, finds nothing, even with a forged cookie. With `bindToBrowser: false`, it stores the hash of the token alone. The token is added to the URL as a `token` query parameter, and your code never sees it otherwise.

Point the link at a page of your web app, not at the API. The page reads the token from its URL and POSTs it back. Email scanners and link previews follow links in emails with GET requests, and would use up the token before the customer clicks. The page must be on the same site as the API: requesting a link sets a cookie that the browser sends back with the token.

src/auth/magic-link.controller.ts

JS TS

```typescript

import { Body, Controller, HttpCode, Post, UnauthorizedException } from '@nestjs/common';
import { MagicLinkService, Public } from '@nestjs/authentication';
import { EmailDto } from './auth.dto.js';

@Public()
@Controller('auth/magic-link')
export class MagicLinkController {
  constructor(private readonly magicLinkService: MagicLinkService) {}

  @Post()
  @HttpCode(202)
  async request(@Body() body: EmailDto, @Body('redirectTo') redirectTo?: string) {
    await this.magicLinkService.create(body.email, { redirectTo });
  }

  // Called by the page the link opens, which POSTs the token from its URL.
  @Post('consume')
  @HttpCode(200)
  async consume(@Body('token') token: string) {
    // A link opened in another browser throws MagicLinkError, which the module
    // answers: a 401 telling the customer to open it where they asked for it.
    const result = await this.magicLinkService.consume(token);
    if (!result) {
      throw new UnauthorizedException('Invalid or expired link');
    }
    return { redirectTo: result.redirectTo ?? '/', mfaRequired: result.session.mfa === 'pending' };
  }
}
```

* The request route answers 202 whether or not the address has an account, and the account is only created once the link is used. A request posted from another site's page gets a 403, as a sign-in does: that page could otherwise set this browser's transaction cookie for a link to its author's address, then get the customer to open it (login CSRF).
* `consume()` burns the token, calls `resolveUser()`, and signs the user in through `SignInService`, which sets the cookie, so two-factor authentication still applies. `resolveUser()` returns the account with its stored `email`, and the link signs the account in only if that is the address the link was sent to, compared trimmed, lowercased and in Unicode NFC. A lookup that ignores accents or dots, as MySQL's default collation does, can't hand one mailbox another customer's account: `consume()` returns `null` instead.
* A link works only in the browser that asked for it. `create()` sets a transaction cookie, `__Host-magic_link_tx`, and `consume()` refuses the token without it, before looking anything up: it throws a `MagicLinkError`, and the module answers it with a 401 whose `error` is `not_this_browser` and whose message tells the customer to open the latest link in the browser they requested it from, or to request a new one here. Otherwise anyone could request a link for their own address and get a customer to open it, which would sign the customer's browser in to the attacker's account (login CSRF). The refused link stays valid in the browser that requested it, and the answer reveals nothing about the token, since a made-up one gets it too. The cookie keeps the last five links the browser requested, so a customer who clicks "Resend" and then opens the first email is still signed in; a link older than those five gets the same 401. So a customer who asks for a link on the laptop and opens the email on the phone is told to open it on the laptop, or to ask for a new link on the phone, which then works there; an application that would rather let the link itself work on the phone sets `bindToBrowser: false` in the `magicLink` options. Unknown, used and expired links, and addresses the handler refuses, get the controller's one generic answer: `consume()` returns `null` for all of them, and only the `magic-link-refused` event says which it was.
* Using the link proves the address, so accounts created by a link are verified. An account created with a password is different while its address is unverified: the link proves who owns the address now, not who chose the password, so the handler refuses it with a 403 rather than handing a pre-hijacked account to its owner. Once the owner has used the [verification link](/security/authentication#verify-email-addresses), or [reset the password](/security/authentication#reset-forgotten-passwords), magic links work for that account too.
* `redirectTo` survives the round trip only if it's a relative path, such as `/orders`.

With the Zod schema:

src/auth/magic-link.controller.ts

JS TS

```typescript

import { emailSchema, type EmailDto } from './auth.schemas.js';
// ...
@Post()
@HttpCode(202)
async request(@Body({ schema: emailSchema }) body: EmailDto, @Body('redirectTo') redirectTo?: string) {
  // ...
}
```

Register the controller:

src/auth/auth.module.ts

JS TS

```typescript

controllers: [
  // ...
  OidcController,
  MagicLinkController,
],
```

#### Let customers manage their sessions[#](/security/authentication#let-customers-manage-their-sessions)

Sessions live on the server, so customers can see where they're signed in and end any of those sessions. To tell those sessions apart, record the browser each one belongs to. `session.metadata` runs whenever a customer signs in, with a password, with Google or with a magic link, and what it returns is stored with the new session:

src/app.module.ts

JS TS

```typescript

AuthenticationModule.forRootAsync({
  useFactory: () => ({
    session: {
      absoluteTtl: '14d', // signed out after 14 days, however active
      idleTtl: '3d', // or after 3 days without a request
      // Stored with every new session, whichever way the customer signed in.
      metadata: (request) => ({ userAgent: request.headers['user-agent'] }),
    },
    // ...
  }),
}),
```

Then list the sessions, and end them:

src/auth/sessions.controller.ts

JS TS

```typescript

import { Controller, Delete, Get, HttpCode, NotFoundException, Param, Post, UnauthorizedException } from '@nestjs/common';
import {
  CurrentSession,
  CurrentUser,
  Public,
  SessionService,
  SignInService,
  type SessionRecord,
} from '@nestjs/authentication';

@Controller('auth')
export class SessionsController {
  constructor(
    private readonly sessionService: SessionService,
    private readonly signInService: SignInService,
  ) {}

  @Get('sessions')
  async list(@CurrentUser('id') userId: string, @CurrentSession() current: SessionRecord) {
    const sessions = await this.sessionService.list(userId);
    return sessions.map(({ id, createdAt, lastActiveAt, metadata }) => ({
      id,
      createdAt,
      lastActiveAt,
      userAgent: metadata?.userAgent ?? null,
      current: id === current.id,
    }));
  }

  // revoke() only ends a session of this user: another customer's id is a 404.
  @Delete('sessions/:id')
  @HttpCode(204)
  async revoke(@CurrentUser('id') userId: string, @Param('id') id: string) {
    if (!(await this.sessionService.revoke(id, { userId }))) {
      throw new NotFoundException();
    }
  }

  // Public, so that a session still waiting for its second factor can sign
  // out too. signOut() ends the session in this browser's cookie.
  @Public()
  @Post('sign-out')
  @HttpCode(204)
  async signOut() {
    if (!(await this.signInService.signOut())) {
      throw new UnauthorizedException(); // no session cookie, e.g. a bearer token
    }
  }

  @Post('sign-out-everywhere')
  @HttpCode(204)
  async signOutEverywhere(@CurrentUser('id') userId: string) {
    await this.signInService.signOutEverywhere(userId);
  }
}
```

* Session ids are SHA-256 hashes of the cookie tokens. Showing them to their owner is safe, since a cookie can't be derived from one. `revoke()` takes the user as well as the id, and only ends a session that belongs to them, so an id from the URL can't end another customer's session.
* `sign-out` is `@Public()`, like `verify` in [two-factor authentication](/security/authentication#add-two-factor-authentication), so a customer who never finishes the second factor can still sign out. `signOut()` ends the session in this browser's cookie and clears the cookie. It returns `false` when there was no session, and the route answers 401: a bearer token here signs nothing out.
* `signOutEverywhere()` ends every session and, when the application issues them, every refresh token of the user, and clears this browser's cookie. Access tokens that were already issued stay valid until they expire, which is why they only last 15 minutes.

The mobile app signs out of one device by revoking its refresh token. Add a route to `TokensController`. `TokenService.revoke()` ends the token's family: the token, its predecessors and its successors:

src/auth/tokens.controller.ts

JS TS

```typescript

// Signs the mobile app out on this device. Unknown tokens get the same
// answer, as in RFC 7009.
@Post('revoke')
@HttpCode(204)
async revoke(@Body('refreshToken') refreshToken: string) {
  await this.tokenService.revoke(refreshToken);
}
```

Register the controller. This is the finished module, with every credential provider and handler of the tutorial:

src/auth/auth.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { UsersModule } from '../users/users.module.js';
import { AccountLinker } from './account-linker.js';
import { AuthController } from './auth.controller.js';
import { CredentialsService } from './credentials.service.js';
import { EmailVerificationController } from './email-verification.controller.js';
import { EmailVerificationMailer } from './email-verification.mailer.js';
import { JwtAuth } from './jwt-auth.provider.js';
import { MagicLinkController } from './magic-link.controller.js';
import { MagicLinkMailer } from './magic-link.mailer.js';
import { MfaController } from './mfa.controller.js';
import { OidcController } from './oidc.controller.js';
import { PasswordResetController } from './password-reset.controller.js';
import { PasswordResetMailer } from './password-reset.mailer.js';
import { SessionAuth } from './session-auth.provider.js';
import { SessionsController } from './sessions.controller.js';
import { TokensController } from './tokens.controller.js';

@Module({
  imports: [UsersModule],
  controllers: [
    AuthController,
    EmailVerificationController,
    PasswordResetController,
    TokensController,
    MfaController,
    OidcController,
    MagicLinkController,
    SessionsController,
  ],
  providers: [
    SessionAuth,
    JwtAuth,
    CredentialsService,
    EmailVerificationMailer,
    PasswordResetMailer,
    AccountLinker,
    MagicLinkMailer,
  ],
})
export class AuthModule {}
```

Rotate the session whenever privileges change, for example after a password change or when a customer becomes staff: `SignInService.rotateSession()` gives this browser's session a new id, and sets the new cookie; `completeMfa()` already does this. It resolves `null`, and sets no cookie, when the browser has no session or lost it meanwhile: a sign-out everywhere, a password reset, or another request that rotated it first.

#### Rate-limit sign-in[#](/security/authentication#rate-limit-sign-in)

`@nestjs/authentication` doesn't limit request rates. That's the job of `@nestjs/throttler`, a separate package:

```bash

$ npm i --save @nestjs/throttler
```

Throttling by IP alone is too coarse for sign-in. It lets one client try passwords for many accounts, and customers behind the same network address share a limit. Track the email and the IP address together wherever the request body names an account:

src/auth/auth-throttler.guard.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { ThrottlerGuard } from '@nestjs/throttler';

/** Per IP everywhere; per (email, IP) where the request body names an account. */
@Injectable()
export class AuthThrottlerGuard extends ThrottlerGuard {
  protected async getTracker(req: Record<string, any>): Promise<string> {
    const ip = await super.getTracker(req);
    const email = typeof req.body?.email === 'string' ? req.body.email.trim().normalize('NFC').toLowerCase() : '';
    return email ? `${email}|${ip}` : ip;
  }
}
```

Register `ThrottlerModule` with a default limit of 100 requests a minute, and the guard as a global guard:

src/app.module.ts

JS TS

```typescript

import { APP_GUARD, APP_PIPE } from '@nestjs/core';
import { ThrottlerModule, minutes } from '@nestjs/throttler';
import { AuthThrottlerGuard } from './auth/auth-throttler.guard.js';
// ...

@Module({
  imports: [
    ThrottlerModule.forRoot([{ ttl: minutes(1), limit: 100 }]),
    // ...
  ],
  providers: [
    { provide: APP_PIPE, useValue: new ValidationPipe({ whitelist: true }) },
    { provide: APP_GUARD, useClass: AuthThrottlerGuard },
  ],
})
export class AppModule {}
```

The guard is registered in the root module, so it runs before the authentication guard. Global guards run in module order, and the root module comes first. That means guessed bearer tokens count against the limit too, rather than only being rejected with a 401.

Finally, tighten the limit on the routes that check a password or send an email. Each `@Throttle()` counts per route, and per email and IP:

src/auth/auth.controller.ts

JS TS

```typescript

@Throttle({ default: { limit: 5, ttl: minutes(15) } })
@Post('sign-in')
```

src/auth/tokens.controller.ts

JS TS

```typescript

@Throttle({ default: { limit: 5, ttl: minutes(15) } })
@Post()
```

src/auth/magic-link.controller.ts

JS TS

```typescript

@Throttle({ default: { limit: 3, ttl: minutes(15) } })
@Post()
```

src/auth/password-reset.controller.ts

JS TS

```typescript

@Throttle({ default: { limit: 3, ttl: minutes(15) } })
@Post('forgot')
```

`Throttle` and `minutes` are imported from `@nestjs/throttler`. The limits on the routes that send email also keep anyone from flooding a customer's inbox from one address. The two-factor codes don't need a throttle of their own: the package locks an account's codes after 5 failures, from any IP address, route or transport. Neither does `POST /auth/password/reset`: a guessed token costs one lookup, and there are 2^256 of them.

> **Hint** Behind a load balancer or reverse proxy, every request seems to come from the proxy. Enable `trust proxy`, as described in the throttler's [Proxies](/security/rate-limiting#proxies) section, so the tracker sees client addresses.

#### Keep sessions and tokens in your database[#](/security/authentication#keep-sessions-and-tokens-in-your-database)

Everything the package stores has lived in memory so far: sessions, refresh tokens, authenticators and recovery codes, and pending links and logins. It's lost on restart, and a second instance of the API wouldn't see it. The package doesn't talk to your database itself. It describes what it stores as six interfaces, `SessionStore`, `RefreshTokenStore`, `MfaStore`, `MagicLinkStore`, `OidcStateStore` and `EmailTokenStore`, and your application implements them with the database access it already has, then registers the implementation.

This step shows that implementation twice, for the two ORMs the family's tutorials use: first with Drizzle, which is the tutorial's path, and then, under "With TypeORM" at the end of the step, the same store for an application whose ORM is TypeORM. Take one of the two.

The store uses PostgreSQL with Drizzle, through [`@nestjs/drizzle`](/data/drizzle), which this step assumes your application already has. `DrizzleModule` opens a `pg` pool from the database's URL and provides the Drizzle database, and it closes the pool when the application shuts down, after the package has finished the work it still had in flight (a reset link on its way out, for instance). Add the URL to `.env`, and register the module in `AppModule`:

```bash

DATABASE_URL=postgres://localhost:5432/store
```

src/app.module.ts

JS TS

```typescript

import { DrizzleModule } from '@nestjs/drizzle';
import { drizzle } from 'drizzle-orm/node-postgres';
// ...
@Module({
  imports: [
    // The Drizzle database, on a pg pool the module closes when the application shuts down.
    DrizzleModule.forRootAsync({
      useFactory: () => ({ drizzle, connection: process.env.DATABASE_URL! }),
    }),
    // ...
  ],
})
export class AppModule {}
```

Start with the tables. They're ordinary Drizzle tables in the application's schema, next to your own:

src/database/schema.ts

JS TS

```typescript

// The store's Drizzle tables. drizzle-kit generates the migrations from this file.
import { boolean, index, integer, jsonb, pgTable, primaryKey, text, timestamp } from 'drizzle-orm/pg-core';

const at = (name: string) => timestamp(name, { withTimezone: true, mode: 'date' });

// Authentication state: what DrizzleAuthenticationStore (src/auth) keeps for @nestjs/authentication.
// Tokens, links and sessions are stored by their SHA-256; TOTP secrets arrive encrypted.

export const sessions = pgTable(
  'sessions',
  {
    id: text('id').primaryKey(),
    userId: text('user_id').notNull(),
    createdAt: at('created_at').notNull(),
    expiresAt: at('expires_at').notNull(),
    lastActiveAt: at('last_active_at').notNull(),
    mfa: text('mfa', { enum: ['pending', 'verified'] }),
    metadata: jsonb('metadata').$type<Record<string, unknown>>(),
  },
  (table) => [
    index('sessions_user_id_idx').on(table.userId),
    index('sessions_expires_at_idx').on(table.expiresAt),
  ],
);

export const refreshTokens = pgTable(
  'refresh_tokens',
  {
    id: text('id').primaryKey(),
    familyId: text('family_id').notNull(),
    userId: text('user_id').notNull(),
    createdAt: at('created_at').notNull(),
    expiresAt: at('expires_at').notNull(),
    familyExpiresAt: at('family_expires_at').notNull(),
    usedAt: at('used_at'),
    // A family is revoked when any of its tokens is: that covers a successor saved after the revocation.
    revoked: boolean('revoked').notNull().default(false),
    claims: jsonb('claims').$type<Record<string, unknown>>(),
  },
  (table) => [
    index('refresh_tokens_family_id_idx').on(table.familyId),
    index('refresh_tokens_user_id_idx').on(table.userId),
    index('refresh_tokens_family_expires_at_idx').on(table.familyExpiresAt),
  ],
);

export const mfaAuthenticators = pgTable('mfa_authenticators', {
  userId: text('user_id').primaryKey(),
  secret: text('secret').notNull(),
  confirmed: boolean('confirmed').notNull(),
  pendingSecret: text('pending_secret'),
  lastUsedStep: integer('last_used_step'),
});

export const mfaRecoveryCodes = pgTable(
  'mfa_recovery_codes',
  {
    userId: text('user_id').notNull(),
    codeHash: text('code_hash').notNull(),
  },
  (table) => [primaryKey({ columns: [table.userId, table.codeHash] })],
);

export const mfaFailures = pgTable(
  'mfa_failures',
  {
    id: integer('id').primaryKey().generatedAlwaysAsIdentity(),
    userId: text('user_id').notNull(),
    failedAt: at('failed_at').notNull(),
  },
  (table) => [
    index('mfa_failures_user_id_failed_at_idx').on(table.userId, table.failedAt),
    index('mfa_failures_failed_at_idx').on(table.failedAt),
  ],
);

export const magicLinks = pgTable(
  'magic_links',
  {
    id: text('id').primaryKey(),
    email: text('email').notNull(),
    createdAt: at('created_at').notNull(),
    expiresAt: at('expires_at').notNull(),
    redirectTo: text('redirect_to'),
  },
  (table) => [index('magic_links_expires_at_idx').on(table.expiresAt)],
);

export const oidcLogins = pgTable(
  'oidc_logins',
  {
    state: text('state').primaryKey(),
    provider: text('provider').notNull(),
    codeVerifier: text('code_verifier').notNull(),
    nonce: text('nonce'),
    redirectTo: text('redirect_to'),
    // Set for "connect your Google account" from a signed-in session.
    linkUserId: text('link_user_id'),
    linkSessionId: text('link_session_id'),
    createdAt: at('created_at').notNull(),
    expiresAt: at('expires_at').notNull(),
  },
  (table) => [index('oidc_logins_expires_at_idx').on(table.expiresAt)],
);

export const emailTokens = pgTable(
  'email_tokens',
  {
    id: text('id').primaryKey(),
    purpose: text('purpose', { enum: ['password-reset', 'email-verification'] }).notNull(),
    userId: text('user_id').notNull(),
    email: text('email').notNull(),
    fingerprint: text('fingerprint'),
    createdAt: at('created_at').notNull(),
    expiresAt: at('expires_at').notNull(),
  },
  (table) => [
    index('email_tokens_user_id_purpose_idx').on(table.userId, table.purpose),
    index('email_tokens_expires_at_idx').on(table.expiresAt),
  ],
);
```

* Sessions, tokens and links are stored as SHA-256 hashes of the values in the cookies and emails, TOTP secrets arrive encrypted with your key (see [two-factor authentication](/security/authentication#add-two-factor-authentication)), and recovery codes arrive hashed with scrypt. Nothing in these tables can be replayed.
* `revoked` is on each refresh token rather than in a table of families: a family counts as revoked when any of its tokens is. That covers a token saved after the revocation, by a refresh that lost a race.

Generate the migration from the schema, and apply it:

```bash

$ npx drizzle-kit generate --name=authentication
No config path provided, using default 'drizzle.config.ts'
Reading config file '/store/drizzle.config.ts'
8 tables
email_tokens 7 columns 2 indexes 0 fks
magic_links 5 columns 1 indexes 0 fks
mfa_authenticators 5 columns 0 indexes 0 fks
mfa_failures 3 columns 2 indexes 0 fks
mfa_recovery_codes 2 columns 0 indexes 0 fks
oidc_logins 9 columns 1 indexes 0 fks
refresh_tokens 9 columns 3 indexes 0 fks
sessions 7 columns 2 indexes 0 fks

[✓] Your SQL migration file ➜ drizzle/0000_authentication.sql 🚀
$ npx drizzle-kit migrate
No config path provided, using default 'drizzle.config.ts'
Reading config file '/store/drizzle.config.ts'
Using 'pg' driver for database querying
[✓] migrations applied successfully!
```

Now the store. It's a provider like any other: it injects the Drizzle database, implements the six interfaces with Drizzle's query builder, and registers itself with the package's `AuthenticationStorage` from its constructor:

src/auth/drizzle-authentication.store.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import {
  AuthenticationStorage,
  type EmailTokenPurpose,
  type EmailTokenRecord,
  type EmailTokenStore,
  type MagicLinkRecord,
  type MagicLinkStore,
  type MfaStore,
  type OidcStateStore,
  type OidcTransaction,
  type RefreshTokenRecord,
  type RefreshTokenStore,
  type SessionRecord,
  type SessionStore,
  type TotpRecord,
} from '@nestjs/authentication';
import { InjectDrizzle } from '@nestjs/drizzle';
import { and, desc, eq, gt, isNull, lt, lte, or, sql } from 'drizzle-orm';
import type { NodePgDatabase } from 'drizzle-orm/node-postgres';
import {
  emailTokens,
  magicLinks,
  mfaAuthenticators,
  mfaFailures,
  mfaRecoveryCodes,
  oidcLogins,
  refreshTokens,
  sessions,
} from '../database/schema.js';

/**
 * Keeps sessions, refresh tokens, authenticators and pending links in
 * PostgreSQL, through Drizzle. Every method that decides whether something
 * works once is a single conditional statement, so the guarantees hold with
 * any number of API instances.
 */
@Injectable()
export class DrizzleAuthenticationStore
  implements SessionStore, RefreshTokenStore, MfaStore, MagicLinkStore, OidcStateStore, EmailTokenStore
{
  /** Pending links and logins kept per table: anyone can create them. */
  protected readonly maxPending: number = 100_000;

  constructor(
    @InjectDrizzle() private readonly db: NodePgDatabase,
    storage: AuthenticationStorage,
  ) {
    storage.registerSource({
      sessions: this,
      refreshTokens: this,
      mfa: this,
      magicLinks: this,
      oidcStates: this,
      emailTokens: this,
    });
  }

  // Sessions

  async getSession(id: string): Promise<SessionRecord | undefined> {
    const [row] = await this.db.select().from(sessions).where(eq(sessions.id, id));
    return row && withoutNulls(row);
  }

  async createSession(record: SessionRecord): Promise<void> {
    await this.db.insert(sessions).values(record);
    await this.db.delete(sessions).where(lte(sessions.expiresAt, record.createdAt));
  }

  async touchSession(id: string, lastActiveAt: Date): Promise<void> {
    // Conditional: a session deleted by a sign-out stays deleted.
    await this.db
      .update(sessions)
      .set({ lastActiveAt })
      .where(and(eq(sessions.id, id), lt(sessions.lastActiveAt, lastActiveAt)));
  }

  // Whether this call deleted it: of two rotations of a session, or a rotation and a sign-out, one wins.
  async deleteSession(id: string): Promise<boolean> {
    const deleted = await this.db.delete(sessions).where(eq(sessions.id, id)).returning({ id: sessions.id });
    return deleted.length > 0;
  }

  async listUserSessions(userId: string): Promise<SessionRecord[]> {
    const rows = await this.db.select().from(sessions).where(eq(sessions.userId, userId));
    return rows.map(withoutNulls);
  }

  async deleteUserSessions(userId: string): Promise<void> {
    await this.db.delete(sessions).where(eq(sessions.userId, userId));
  }

  // Refresh tokens

  async getRefreshToken(id: string): Promise<RefreshTokenRecord | undefined> {
    const [row] = await this.db.select().from(refreshTokens).where(eq(refreshTokens.id, id));
    if (!row) {
      return undefined;
    }
    const { revoked: _, ...token } = row;
    return withoutNulls(token);
  }

  async saveRefreshToken(record: RefreshTokenRecord): Promise<void> {
    await this.db.insert(refreshTokens).values(record);
    await this.db.delete(refreshTokens).where(lte(refreshTokens.familyExpiresAt, record.createdAt));
  }

  async markRefreshTokenUsed(id: string, at: Date): Promise<boolean> {
    // Conditional: of two refreshes with the same token, one updates the row.
    const updated = await this.db
      .update(refreshTokens)
      .set({ usedAt: at })
      .where(and(eq(refreshTokens.id, id), isNull(refreshTokens.usedAt)))
      .returning({ id: refreshTokens.id });
    return updated.length === 1;
  }

  async revokeRefreshTokenFamily(familyId: string): Promise<void> {
    await this.db.update(refreshTokens).set({ revoked: true }).where(eq(refreshTokens.familyId, familyId));
  }

  async isRefreshTokenFamilyRevoked(familyId: string): Promise<boolean> {
    const revoked = await this.db
      .select({ id: refreshTokens.id })
      .from(refreshTokens)
      .where(and(eq(refreshTokens.familyId, familyId), eq(refreshTokens.revoked, true)))
      .limit(1);
    return revoked.length > 0;
  }

  async revokeUserRefreshTokens(userId: string): Promise<void> {
    await this.db.update(refreshTokens).set({ revoked: true }).where(eq(refreshTokens.userId, userId));
  }

  // Authenticators, recovery codes and failed attempts

  async getTotp(userId: string): Promise<TotpRecord | undefined> {
    const [row] = await this.db.select().from(mfaAuthenticators).where(eq(mfaAuthenticators.userId, userId));
    if (!row) {
      return undefined;
    }
    const { userId: _, ...totp } = row;
    return withoutNulls(totp);
  }

  async saveTotp(userId: string, record: TotpRecord | null): Promise<void> {
    if (!record) {
      await this.db.delete(mfaAuthenticators).where(eq(mfaAuthenticators.userId, userId));
      return;
    }
    const values = { secret: record.secret, confirmed: record.confirmed, pendingSecret: record.pendingSecret ?? null };
    await this.db
      .insert(mfaAuthenticators)
      .values({ userId, ...values, lastUsedStep: record.lastUsedStep })
      .onConflictDoUpdate({
        target: mfaAuthenticators.userId,
        // Never lower the claimed step: the record may have been read before a claim.
        set: { ...values, lastUsedStep: sql`greatest(${mfaAuthenticators.lastUsedStep}, excluded.last_used_step)` },
      });
  }

  async claimTotpStep(userId: string, step: number): Promise<boolean> {
    // Conditional: a code's time step is accepted once.
    const claimed = await this.db
      .update(mfaAuthenticators)
      .set({ lastUsedStep: step })
      .where(
        and(
          eq(mfaAuthenticators.userId, userId),
          or(isNull(mfaAuthenticators.lastUsedStep), lt(mfaAuthenticators.lastUsedStep, step)),
        ),
      )
      .returning({ userId: mfaAuthenticators.userId });
    return claimed.length === 1;
  }

  async saveRecoveryCodes(userId: string, hashes: string[]): Promise<void> {
    await this.db.transaction(async (tx) => {
      await tx.delete(mfaRecoveryCodes).where(eq(mfaRecoveryCodes.userId, userId));
      if (hashes.length > 0) {
        await tx.insert(mfaRecoveryCodes).values([...new Set(hashes)].map((codeHash) => ({ userId, codeHash })));
      }
    });
  }

  async consumeRecoveryCode(userId: string, hash: string): Promise<boolean> {
    // Conditional: of two requests with the same code, one deletes the row.
    const consumed = await this.db
      .delete(mfaRecoveryCodes)
      .where(and(eq(mfaRecoveryCodes.userId, userId), eq(mfaRecoveryCodes.codeHash, hash)))
      .returning({ userId: mfaRecoveryCodes.userId });
    return consumed.length === 1;
  }

  countRecoveryCodes(userId: string): Promise<number> {
    return this.db.$count(mfaRecoveryCodes, eq(mfaRecoveryCodes.userId, userId));
  }

  async recordMfaFailure(userId: string, windowMs: number, now: number): Promise<number> {
    // Insert, then count, each committed on its own (no transaction): every attempt
    // counts itself and all those recorded before it.
    await this.db.insert(mfaFailures).values({ userId, failedAt: new Date(now) });
    const failures = await this.countMfaFailures(userId, windowMs, now);
    await this.db.delete(mfaFailures).where(lte(mfaFailures.failedAt, new Date(now - windowMs)));
    return failures;
  }

  countMfaFailures(userId: string, windowMs: number, now: number): Promise<number> {
    return this.db.$count(
      mfaFailures,
      and(eq(mfaFailures.userId, userId), gt(mfaFailures.failedAt, new Date(now - windowMs))),
    );
  }

  async clearMfaFailures(userId: string): Promise<void> {
    await this.db.delete(mfaFailures).where(eq(mfaFailures.userId, userId));
  }

  // Magic links

  async saveMagicLink(record: MagicLinkRecord): Promise<void> {
    await this.db.insert(magicLinks).values(record);
    await this.trim(magicLinks, record.createdAt);
  }

  async consumeMagicLink(id: string): Promise<MagicLinkRecord | undefined> {
    // DELETE … RETURNING: of two requests with the same link, one gets the row.
    const [row] = await this.db.delete(magicLinks).where(eq(magicLinks.id, id)).returning();
    return row && withoutNulls(row);
  }

  // Sign-ins with Google in progress

  async saveOidcState({ link, ...login }: OidcTransaction): Promise<void> {
    await this.db.insert(oidcLogins).values({ ...login, linkUserId: link?.userId, linkSessionId: link?.sessionId });
    await this.trim(oidcLogins, login.createdAt);
  }

  async consumeOidcState(state: string): Promise<OidcTransaction | undefined> {
    const [row] = await this.db.delete(oidcLogins).where(eq(oidcLogins.state, state)).returning();
    if (!row) {
      return undefined;
    }
    const { linkUserId, linkSessionId, ...login } = withoutNulls(row);
    return linkUserId && linkSessionId ? { ...login, link: { userId: linkUserId, sessionId: linkSessionId } } : login;
  }

  // Password reset and email verification links

  async saveEmailToken(record: EmailTokenRecord): Promise<void> {
    await this.db.insert(emailTokens).values(record);
    await this.trim(emailTokens, record.createdAt);
  }

  async consumeEmailToken(id: string, purpose: EmailTokenPurpose): Promise<EmailTokenRecord | undefined> {
    const [row] = await this.db
      .delete(emailTokens)
      .where(and(eq(emailTokens.id, id), eq(emailTokens.purpose, purpose)))
      .returning();
    return row && withoutNulls(row);
  }

  async deleteUserEmailTokens(userId: string, purpose: EmailTokenPurpose): Promise<void> {
    await this.db.delete(emailTokens).where(and(eq(emailTokens.userId, userId), eq(emailTokens.purpose, purpose)));
  }

  /** Deletes what expired, and past `maxPending`, what expires first. */
  private async trim(table: typeof magicLinks | typeof oidcLogins | typeof emailTokens, now: Date) {
    await this.db.delete(table).where(lte(table.expiresAt, now));
    const [cutoff] = await this.db
      .select({ expiresAt: table.expiresAt })
      .from(table)
      .orderBy(desc(table.expiresAt))
      .limit(1)
      .offset(this.maxPending);
    if (cutoff) {
      await this.db.delete(table).where(lte(table.expiresAt, cutoff.expiresAt));
    }
  }
}

/** A row without its NULL columns: the package's records leave optional fields out. */
type WithoutNulls<T> = { [K in keyof T as null extends T[K] ? never : K]: T[K] } & {
  [K in keyof T as null extends T[K] ? K : never]?: Exclude<T[K], null>;
};

function withoutNulls<T extends object>(row: T): WithoutNulls<T> {
  return Object.fromEntries(Object.entries(row).filter(([, value]) => value !== null)) as WithoutNulls<T>;
}
```

Add it to the providers of `AuthModule`, like the credential providers and the handlers. Registering in the constructor is all it takes: Nest creates the provider at startup, before the first request.

src/auth/auth.module.ts

JS TS

```typescript

import { DrizzleAuthenticationStore } from './drizzle-authentication.store.js';
// ...
providers: [
  // ...
  MagicLinkMailer,
  DrizzleAuthenticationStore,
],
```

At startup, after the chain of providers and the handlers, the module logs where each kind of state lives:

```bash

LOG [AuthenticationModule] AuthenticationRegistry: providers SessionAuth, JwtAuth; handlers EmailVerificationMailer (emailVerification), PasswordResetMailer (passwordReset), MagicLinkMailer (magicLink), AccountLinker (oidc)
LOG [AuthenticationModule] AuthenticationStorage: DrizzleAuthenticationStore
```

* **One provider or several.**`registerSource()` takes the interfaces by name, so one class can implement all six, as here, or several classes can split them: a `RedisSessionStore` that registers `sessions`, and this class registering the other five. A second store for the same name fails at startup, naming both classes.
* **Some methods must be one statement.** Whatever decides that something works only once is a single conditional statement, never a read followed by a write. `touchSession()` updates only a session that still exists, so a request racing a sign-out can't bring the session back. `deleteSession()` resolves whether it deleted the row, so of two rotations of one session, or a rotation and a sign-out, exactly one wins. `markRefreshTokenUsed()`, `claimTotpStep()` and `consumeRecoveryCode()` count the rows they changed, and the three `consume` methods are a `DELETE … RETURNING`. `saveTotp()` keeps the larger time step with `greatest()`, the one place the store writes SQL by hand. `recordMfaFailure()` inserts first and counts second, outside a transaction, so a burst of parallel guesses can't all see a low count. Each method of the store interfaces gives its rule, and the race it prevents, in its doc comment.
* **Recording activity is best-effort.** If `touchSession()` fails (a lock timeout, a read-only replica), the request and sign-outs still succeed. The session is kept, `lastActiveAt` doesn't move, and the session goes idle at its previous deadline unless a later request records activity. Every failure emits a `session-touch-failed` event; the log gets one warning when failures start, nothing while they continue, and one line with their count on the next successful touch.
* **The tables stay bounded.** Anyone can ask for a magic link or a reset link, so each save deletes what has expired and, past 100,000 pending rows in a table, what expires first. Expired sessions and refresh-token families go as new ones are written.
* **Password reset and email verification keep working unchanged.** Their links are rows in `email_tokens` now, and their mailers still send them through `@nestjs/mail`.
* **Production refuses memory.** With `NODE_ENV` set to `production`, the module won't start while a store that a configured feature uses isn't registered, and names the interfaces to implement. Each feature needs only the stores it uses: `MfaStore` only with `mfa`, and `RefreshTokenStore` only with `accessToken` while refresh tokens are on. [The store contract](/security/authentication#the-store-contract) lists them. A store that none of your configured features uses fails at its first read instead. `allowInMemoryStorage: true` in the module options runs in memory anyway, but then every restart or deploy signs everyone out and forgets enrolled authenticators, and instances don't share any of it.

If your users live in the same database, `getSession()` can read each session's user in the same query and pass it on as `extra`, which `SessionAuth`'s `validate()` receives: one read per request instead of two. Type it with a `sessionExtra` key next to `user` (`users` and `toUser()` stand for your own table and the mapping that leaves out the password hash):

src/auth/auth-types.ts

JS TS

```typescript

import type { User } from '../users/user.js';

declare module '@nestjs/authentication' {
  interface AuthenticationTypes {
    user: User;
    sessionExtra: { user: User };
  }
}
```

src/auth/drizzle-authentication.store.ts

JS TS

```typescript

async getSession(id: string): Promise<SessionRecord | undefined> {
  // Joined fresh on every read. A session whose user is gone reads as unknown.
  const [row] = await this.db
    .select({ session: sessions, user: users })
    .from(sessions)
    .innerJoin(users, eq(users.id, sessions.userId))
    .where(eq(sessions.id, id));
  return row && { ...withoutNulls(row.session), extra: { user: toUser(row.user) } };
}
```

src/auth/session-auth.provider.ts

JS TS

```typescript

validate(session: SessionRecord) {
  return session.extra?.user ?? null;
}
```

`extra` is never stored: `createSession()` never receives it, a rotation leaves it out, and `listUserSessions()` shouldn't set it. Nor is it exposed: `@CurrentSession()`, `request.session` and `AuthenticationContext.session` carry the session without it, so whatever the handlers need goes in the user `validate()` returns. Don't copy the user onto the session row instead of joining it: the copy goes stale when the user changes.

The package ships its rules as tests. `authenticationStoreContract()` from `@nestjs/authentication/testing` returns test cases that work with any test runner, and `concurrent: true` adds the races: parallel refreshes of one token, parallel uses of one code or link, bursts of failed codes, a sign-out racing a request, parallel deletes of one session, and a rotation racing a sign-out or another rotation. Run them on PGlite and, where the calls really race, on PostgreSQL:

test/drizzle-authentication.store.e2e-spec.ts

JS TS

```typescript

import { fileURLToPath } from 'node:url';
import { PGlite } from '@electric-sql/pglite';
import { AuthenticationStorage } from '@nestjs/authentication';
import { authenticationStoreContract } from '@nestjs/authentication/testing';
import { sql } from 'drizzle-orm';
import { drizzle as nodePostgres, type NodePgDatabase } from 'drizzle-orm/node-postgres';
import { migrate as migrateNodePostgres } from 'drizzle-orm/node-postgres/migrator';
import { drizzle as pglite } from 'drizzle-orm/pglite';
import { migrate as migratePglite } from 'drizzle-orm/pglite/migrator';
import { Pool } from 'pg';
import { DrizzleAuthenticationStore } from '../src/auth/drizzle-authentication.store.js';
import { startPostgres } from './support/postgres.js';

type Database = NodePgDatabase;

const migrationsFolder = fileURLToPath(new URL('../drizzle', import.meta.url));

/** The store with a cap of 3 pending entries per table, so the suite can check it. */
class CappedStore extends DrizzleAuthenticationStore {
  protected override readonly maxPending = 3;
}

/** The store on empty tables, registered nowhere: the suite builds its own registry. */
async function emptyStore(db: Database) {
  await db.execute(
    sql`TRUNCATE sessions, refresh_tokens, mfa_authenticators, mfa_recovery_codes, mfa_failures, magic_links, oidc_logins, email_tokens`,
  );
  const store = new CappedStore(db, new AuthenticationStorage());
  return { sessions: store, refreshTokens: store, mfa: store, magicLinks: store, oidcStates: store, emailTokens: store };
}

describe('DrizzleAuthenticationStore on PGlite', () => {
  const client = new PGlite();
  const db = pglite(client) as unknown as Database;
  beforeAll(() => migratePglite(pglite(client), { migrationsFolder }));
  afterAll(() => client.close());

  for (const c of authenticationStoreContract(() => emptyStore(db), { concurrent: true, maxPending: 3 })) {
    it(c.name, c.run);
  }
});

// PostgreSQL on a pool of connections: the concurrency cases race for real.
const { postgres, reason } = await startPostgres();

describe.skipIf(!postgres)(`DrizzleAuthenticationStore on PostgreSQL${reason ? ` (skipped: ${reason})` : ''}`, () => {
  let pool: Pool;
  let db: Database;
  beforeAll(async () => {
    pool = new Pool({ connectionString: await postgres!.createDatabase('authentication_tutorial_store'), max: 10 });
    db = nodePostgres(pool);
    await migrateNodePostgres(db, { migrationsFolder });
  });
  afterAll(async () => {
    await pool?.end();
    postgres!.stop();
  });

  for (const c of authenticationStoreContract(() => emptyStore(db), { concurrent: true, maxPending: 3 })) {
    it(c.name, c.run);
  }
});
```

`CappedStore` lowers the cap on pending rows so that `maxPending: 3` can check it. `startPostgres()` is a test helper that creates a throwaway database on a PostgreSQL server, or skips the PostgreSQL cases without one. A store that reads a row and then writes it back passes the other tests and fails these.

**With TypeORM.** The same store for an application whose ORM is TypeORM, on the same eight tables. Drizzle stays the tutorial's path: take this store instead of the one above, not next to it. The tables are entities, and every column states its type, so that the TypeORM CLI, which loads them without decorator metadata, sees the same schema as the application:

src/typeorm/authentication.entities.ts

JS TS

```typescript

import type { EmailTokenPurpose, MfaState } from '@nestjs/authentication';
import { Column, Entity, Index, PrimaryColumn, PrimaryGeneratedColumn } from 'typeorm';

// The authentication tables, read and written by TypeOrmAuthenticationStore: the same
// tables as the Drizzle schema in src/database/schema.ts. Every column states its type, so
// the entities load the same with or without emitted decorator metadata (the TypeORM CLI
// runs them through tsx, which emits none). Tokens, links and sessions are stored by their
// SHA-256; TOTP secrets arrive encrypted.

/** What a `jsonb` column holds: a column typed `unknown` doesn't fit TypeORM's insert types. */
export type Json = object | string | number | boolean | null;

@Entity('sessions')
@Index('sessions_user_id_idx', ['userId'])
@Index('sessions_expires_at_idx', ['expiresAt'])
export class SessionEntity {
  @PrimaryColumn({ type: 'text' })
  id: string;

  @Column({ type: 'text', name: 'user_id' })
  userId: string;

  @Column({ type: 'timestamptz', name: 'created_at' })
  createdAt: Date;

  @Column({ type: 'timestamptz', name: 'expires_at' })
  expiresAt: Date;

  @Column({ type: 'timestamptz', name: 'last_active_at' })
  lastActiveAt: Date;

  @Column({ type: 'text', nullable: true })
  mfa: MfaState | null;

  @Column({ type: 'jsonb', nullable: true })
  metadata: Record<string, Json> | null;
}

@Entity('refresh_tokens')
@Index('refresh_tokens_family_id_idx', ['familyId'])
@Index('refresh_tokens_user_id_idx', ['userId'])
@Index('refresh_tokens_family_expires_at_idx', ['familyExpiresAt'])
export class RefreshTokenEntity {
  @PrimaryColumn({ type: 'text' })
  id: string;

  @Column({ type: 'text', name: 'family_id' })
  familyId: string;

  @Column({ type: 'text', name: 'user_id' })
  userId: string;

  @Column({ type: 'timestamptz', name: 'created_at' })
  createdAt: Date;

  @Column({ type: 'timestamptz', name: 'expires_at' })
  expiresAt: Date;

  @Column({ type: 'timestamptz', name: 'family_expires_at' })
  familyExpiresAt: Date;

  @Column({ type: 'timestamptz', name: 'used_at', nullable: true })
  usedAt: Date | null;

  // A family is revoked when any of its tokens is: that covers a successor saved after the revocation.
  @Column({ type: 'boolean', default: false })
  revoked: boolean;

  @Column({ type: 'jsonb', nullable: true })
  claims: Record<string, Json> | null;
}

@Entity('mfa_authenticators')
export class MfaAuthenticatorEntity {
  @PrimaryColumn({ type: 'text', name: 'user_id' })
  userId: string;

  @Column({ type: 'text' })
  secret: string;

  @Column({ type: 'boolean' })
  confirmed: boolean;

  @Column({ type: 'text', name: 'pending_secret', nullable: true })
  pendingSecret: string | null;

  @Column({ type: 'integer', name: 'last_used_step', nullable: true })
  lastUsedStep: number | null;
}

@Entity('mfa_recovery_codes')
export class MfaRecoveryCodeEntity {
  @PrimaryColumn({ type: 'text', name: 'user_id' })
  userId: string;

  @PrimaryColumn({ type: 'text', name: 'code_hash' })
  codeHash: string;
}

@Entity('mfa_failures')
@Index('mfa_failures_user_id_failed_at_idx', ['userId', 'failedAt'])
@Index('mfa_failures_failed_at_idx', ['failedAt'])
export class MfaFailureEntity {
  @PrimaryGeneratedColumn('identity', { type: 'integer', generatedIdentity: 'ALWAYS' })
  id: number;

  @Column({ type: 'text', name: 'user_id' })
  userId: string;

  @Column({ type: 'timestamptz', name: 'failed_at' })
  failedAt: Date;
}

@Entity('magic_links')
@Index('magic_links_expires_at_idx', ['expiresAt'])
export class MagicLinkEntity {
  @PrimaryColumn({ type: 'text' })
  id: string;

  @Column({ type: 'text' })
  email: string;

  @Column({ type: 'timestamptz', name: 'created_at' })
  createdAt: Date;

  @Column({ type: 'timestamptz', name: 'expires_at' })
  expiresAt: Date;

  @Column({ type: 'text', name: 'redirect_to', nullable: true })
  redirectTo: string | null;
}

@Entity('oidc_logins')
@Index('oidc_logins_expires_at_idx', ['expiresAt'])
export class OidcLoginEntity {
  @PrimaryColumn({ type: 'text' })
  state: string;

  @Column({ type: 'text' })
  provider: string;

  @Column({ type: 'text', name: 'code_verifier' })
  codeVerifier: string;

  @Column({ type: 'text', nullable: true })
  nonce: string | null;

  @Column({ type: 'text', name: 'redirect_to', nullable: true })
  redirectTo: string | null;

  // Set for "connect your Google account" from a signed-in session.
  @Column({ type: 'text', name: 'link_user_id', nullable: true })
  linkUserId: string | null;

  @Column({ type: 'text', name: 'link_session_id', nullable: true })
  linkSessionId: string | null;

  @Column({ type: 'timestamptz', name: 'created_at' })
  createdAt: Date;

  @Column({ type: 'timestamptz', name: 'expires_at' })
  expiresAt: Date;
}

@Entity('email_tokens')
@Index('email_tokens_user_id_purpose_idx', ['userId', 'purpose'])
@Index('email_tokens_expires_at_idx', ['expiresAt'])
export class EmailTokenEntity {
  @PrimaryColumn({ type: 'text' })
  id: string;

  @Column({ type: 'text' })
  purpose: EmailTokenPurpose;

  @Column({ type: 'text', name: 'user_id' })
  userId: string;

  @Column({ type: 'text' })
  email: string;

  @Column({ type: 'text', nullable: true })
  fingerprint: string | null;

  @Column({ type: 'timestamptz', name: 'created_at' })
  createdAt: Date;

  @Column({ type: 'timestamptz', name: 'expires_at' })
  expiresAt: Date;
}
```

The TypeORM CLI and `TypeOrmModule` share one set of options, in a data source file:

src/typeorm/data-source.ts

JS TS

```typescript

import { DataSource, type DataSourceOptions } from 'typeorm';
import {
  EmailTokenEntity,
  MagicLinkEntity,
  MfaAuthenticatorEntity,
  MfaFailureEntity,
  MfaRecoveryCodeEntity,
  OidcLoginEntity,
  RefreshTokenEntity,
  SessionEntity,
} from './authentication.entities.js';
import { Authentication1790235914534 } from './migrations/1790235914534-Authentication.js';

/** What the application's TypeOrmModule and the TypeORM CLI share. */
export const dataSourceOptions = {
  type: 'postgres',
  url: process.env.DATABASE_URL,
  entities: [
    SessionEntity,
    RefreshTokenEntity,
    MfaAuthenticatorEntity,
    MfaRecoveryCodeEntity,
    MfaFailureEntity,
    MagicLinkEntity,
    OidcLoginEntity,
    EmailTokenEntity,
  ],
  migrations: [Authentication1790235914534],
} satisfies DataSourceOptions;

// The TypeORM CLI's data source: `migration:generate` compares the entities with this database.
export default new DataSource(dataSourceOptions);
```

Generate the migration from the entities, against a database with your previous migrations applied, apply it, and check that the entities and the database agree. The CLI needs a TypeScript loader for the data source file; this uses `tsx`:

```bash

$ npx tsx ./node_modules/typeorm/cli.js migration:generate src/typeorm/migrations/Authentication -d src/typeorm/data-source.ts --pretty
Migration /store/src/typeorm/migrations/1790235914534-Authentication.ts has been generated successfully.
$ npx tsx ./node_modules/typeorm/cli.js migration:run -d src/typeorm/data-source.ts
$ npx tsx ./node_modules/typeorm/cli.js migration:generate src/typeorm/migrations/Check -d src/typeorm/data-source.ts --check
No changes in database schema were found
```

The migration it wrote, `1790235914534-Authentication.ts`, is the `CREATE TABLE` and `CREATE INDEX` statements of the eight tables above, and `migrations` in the data source lists it. Now the store, under the same rules as the Drizzle one:

src/typeorm/typeorm-authentication.store.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import {
  AuthenticationStorage,
  type EmailTokenPurpose,
  type EmailTokenRecord,
  type EmailTokenStore,
  type MagicLinkRecord,
  type MagicLinkStore,
  type MfaStore,
  type OidcStateStore,
  type OidcTransaction,
  type RefreshTokenRecord,
  type RefreshTokenStore,
  type SessionRecord,
  type SessionStore,
  type TotpRecord,
} from '@nestjs/authentication';
import {
  DataSource,
  IsNull,
  LessThan,
  LessThanOrEqual,
  MoreThan,
  Or,
  type EntityTarget,
  type FindOptionsWhere,
  type ObjectLiteral,
} from 'typeorm';
import {
  EmailTokenEntity,
  MagicLinkEntity,
  MfaAuthenticatorEntity,
  MfaFailureEntity,
  MfaRecoveryCodeEntity,
  OidcLoginEntity,
  RefreshTokenEntity,
  SessionEntity,
  type Json,
} from './authentication.entities.js';

/**
 * Keeps sessions, refresh tokens, authenticators and pending links in
 * PostgreSQL, through TypeORM: the Drizzle store above, on the same
 * tables. Every method that decides whether something works once is a
 * single conditional statement, so the guarantees hold with any number of
 * API instances.
 */
@Injectable()
export class TypeOrmAuthenticationStore
  implements SessionStore, RefreshTokenStore, MfaStore, MagicLinkStore, OidcStateStore, EmailTokenStore
{
  /** Pending links and logins kept per table: anyone can create them. */
  protected readonly maxPending: number = 100_000;

  constructor(
    private readonly dataSource: DataSource,
    storage: AuthenticationStorage,
  ) {
    storage.registerSource({
      sessions: this,
      refreshTokens: this,
      mfa: this,
      magicLinks: this,
      oidcStates: this,
      emailTokens: this,
    });
  }

  private get manager() {
    return this.dataSource.manager;
  }

  // Sessions

  async getSession(id: string): Promise<SessionRecord | undefined> {
    const row = await this.manager.findOneBy(SessionEntity, { id });
    return row ? withoutNulls(row) : undefined;
  }

  async createSession(record: SessionRecord): Promise<void> {
    // JSON-safe: the package stores what `session.metadata` returned, as JSON.
    const metadata = (record.metadata ?? null) as Record<string, Json> | null;
    await this.manager.insert(SessionEntity, { ...record, mfa: record.mfa ?? null, metadata });
    await this.manager.delete(SessionEntity, { expiresAt: LessThanOrEqual(record.createdAt) });
  }

  async touchSession(id: string, lastActiveAt: Date): Promise<void> {
    // Conditional: a session deleted by a sign-out stays deleted.
    await this.manager.update(SessionEntity, { id, lastActiveAt: LessThan(lastActiveAt) }, { lastActiveAt });
  }

  // Whether this call deleted it: of two rotations of a session, or a rotation and a sign-out, one wins.
  async deleteSession(id: string): Promise<boolean> {
    const { affected } = await this.manager.delete(SessionEntity, { id });
    return (affected ?? 0) > 0;
  }

  async listUserSessions(userId: string): Promise<SessionRecord[]> {
    const rows = await this.manager.findBy(SessionEntity, { userId });
    return rows.map(withoutNulls);
  }

  async deleteUserSessions(userId: string): Promise<void> {
    await this.manager.delete(SessionEntity, { userId });
  }

  // Refresh tokens

  async getRefreshToken(id: string): Promise<RefreshTokenRecord | undefined> {
    const row = await this.manager.findOneBy(RefreshTokenEntity, { id });
    if (!row) {
      return undefined;
    }
    const { revoked: _, ...token } = row;
    return withoutNulls(token);
  }

  async saveRefreshToken(record: RefreshTokenRecord): Promise<void> {
    const claims = (record.claims ?? null) as Record<string, Json> | null;
    await this.manager.insert(RefreshTokenEntity, { ...record, usedAt: record.usedAt ?? null, claims });
    await this.manager.delete(RefreshTokenEntity, { familyExpiresAt: LessThanOrEqual(record.createdAt) });
  }

  async markRefreshTokenUsed(id: string, at: Date): Promise<boolean> {
    // Conditional: of two refreshes with the same token, one updates the row.
    const { affected } = await this.manager.update(RefreshTokenEntity, { id, usedAt: IsNull() }, { usedAt: at });
    return affected === 1;
  }

  async revokeRefreshTokenFamily(familyId: string): Promise<void> {
    await this.manager.update(RefreshTokenEntity, { familyId }, { revoked: true });
  }

  isRefreshTokenFamilyRevoked(familyId: string): Promise<boolean> {
    return this.manager.existsBy(RefreshTokenEntity, { familyId, revoked: true });
  }

  async revokeUserRefreshTokens(userId: string): Promise<void> {
    await this.manager.update(RefreshTokenEntity, { userId }, { revoked: true });
  }

  // Authenticators, recovery codes and failed attempts

  async getTotp(userId: string): Promise<TotpRecord | undefined> {
    const row = await this.manager.findOneBy(MfaAuthenticatorEntity, { userId });
    if (!row) {
      return undefined;
    }
    const { userId: _, ...totp } = row;
    return withoutNulls(totp);
  }

  async saveTotp(userId: string, record: TotpRecord | null): Promise<void> {
    if (!record) {
      await this.manager.delete(MfaAuthenticatorEntity, { userId });
      return;
    }
    // An upsert that never lowers the claimed step: the record may have been read before a
    // claim. GREATEST() over the conflicting row is beyond the upsert API, so this one is SQL.
    await this.manager.query(
      `INSERT INTO mfa_authenticators (user_id, secret, confirmed, pending_secret, last_used_step)
       VALUES ($1, $2, $3, $4, $5)
       ON CONFLICT (user_id) DO UPDATE SET
         secret = EXCLUDED.secret,
         confirmed = EXCLUDED.confirmed,
         pending_secret = EXCLUDED.pending_secret,
         last_used_step = GREATEST(mfa_authenticators.last_used_step, EXCLUDED.last_used_step)`,
      [userId, record.secret, record.confirmed, record.pendingSecret ?? null, record.lastUsedStep ?? null],
    );
  }

  async claimTotpStep(userId: string, step: number): Promise<boolean> {
    // Conditional: a code's time step is accepted once.
    const { affected } = await this.manager.update(
      MfaAuthenticatorEntity,
      { userId, lastUsedStep: Or(IsNull(), LessThan(step)) },
      { lastUsedStep: step },
    );
    return affected === 1;
  }

  async saveRecoveryCodes(userId: string, hashes: string[]): Promise<void> {
    await this.dataSource.transaction(async (manager) => {
      await manager.delete(MfaRecoveryCodeEntity, { userId });
      if (hashes.length > 0) {
        await manager.insert(MfaRecoveryCodeEntity, [...new Set(hashes)].map((codeHash) => ({ userId, codeHash })));
      }
    });
  }

  async consumeRecoveryCode(userId: string, hash: string): Promise<boolean> {
    // Conditional: of two requests with the same code, one deletes the row.
    const { affected } = await this.manager.delete(MfaRecoveryCodeEntity, { userId, codeHash: hash });
    return affected === 1;
  }

  countRecoveryCodes(userId: string): Promise<number> {
    return this.manager.countBy(MfaRecoveryCodeEntity, { userId });
  }

  async recordMfaFailure(userId: string, windowMs: number, now: number): Promise<number> {
    // Insert, then count, each committed on its own (no transaction): every attempt
    // counts itself and all those recorded before it.
    await this.manager.insert(MfaFailureEntity, { userId, failedAt: new Date(now) });
    const failures = await this.countMfaFailures(userId, windowMs, now);
    await this.manager.delete(MfaFailureEntity, { failedAt: LessThanOrEqual(new Date(now - windowMs)) });
    return failures;
  }

  countMfaFailures(userId: string, windowMs: number, now: number): Promise<number> {
    return this.manager.countBy(MfaFailureEntity, { userId, failedAt: MoreThan(new Date(now - windowMs)) });
  }

  async clearMfaFailures(userId: string): Promise<void> {
    await this.manager.delete(MfaFailureEntity, { userId });
  }

  // Magic links

  async saveMagicLink(record: MagicLinkRecord): Promise<void> {
    await this.manager.insert(MagicLinkEntity, { ...record, redirectTo: record.redirectTo ?? null });
    await this.trim(MagicLinkEntity, record.createdAt);
  }

  async consumeMagicLink(id: string): Promise<MagicLinkRecord | undefined> {
    // DELETE … RETURNING: of two requests with the same link, one gets the row.
    const [row] = await this.deleteReturning(MagicLinkEntity, { id });
    return row && withoutNulls(row);
  }

  // Sign-ins with Google in progress

  async saveOidcState({ link, ...login }: OidcTransaction): Promise<void> {
    await this.manager.insert(OidcLoginEntity, {
      ...login,
      nonce: login.nonce ?? null,
      redirectTo: login.redirectTo ?? null,
      linkUserId: link?.userId ?? null,
      linkSessionId: link?.sessionId ?? null,
    });
    await this.trim(OidcLoginEntity, login.createdAt);
  }

  async consumeOidcState(state: string): Promise<OidcTransaction | undefined> {
    const [row] = await this.deleteReturning(OidcLoginEntity, { state });
    if (!row) {
      return undefined;
    }
    const { linkUserId, linkSessionId, ...login } = withoutNulls(row);
    return linkUserId && linkSessionId ? { ...login, link: { userId: linkUserId, sessionId: linkSessionId } } : login;
  }

  // Password reset and email verification links

  async saveEmailToken(record: EmailTokenRecord): Promise<void> {
    await this.manager.insert(EmailTokenEntity, { ...record, fingerprint: record.fingerprint ?? null });
    await this.trim(EmailTokenEntity, record.createdAt);
  }

  async consumeEmailToken(id: string, purpose: EmailTokenPurpose): Promise<EmailTokenRecord | undefined> {
    const [row] = await this.deleteReturning(EmailTokenEntity, { id, purpose });
    return row && withoutNulls(row);
  }

  async deleteUserEmailTokens(userId: string, purpose: EmailTokenPurpose): Promise<void> {
    await this.manager.delete(EmailTokenEntity, { userId, purpose });
  }

  /** `DELETE … RETURNING *`, as rows of the entity: the query builder returns raw column names. */
  private async deleteReturning<T extends ObjectLiteral>(entity: EntityTarget<T>, where: FindOptionsWhere<T>): Promise<T[]> {
    const { raw } = await this.manager.createQueryBuilder().delete().from(entity).where(where).returning('*').execute();
    const columns = this.dataSource.getMetadata(entity).columns;
    return (raw as Record<string, unknown>[]).map(
      (row) => Object.fromEntries(columns.map((column) => [column.propertyName, row[column.databaseName]])) as T,
    );
  }

  /** Deletes what expired, and past `maxPending`, what expires first. */
  private async trim<T extends { expiresAt: Date }>(entity: EntityTarget<T>, now: Date) {
    await this.manager.delete(entity, { expiresAt: LessThanOrEqual(now) } as FindOptionsWhere<T>);
    const [cutoff] = await this.manager.find(entity, {
      select: { expiresAt: true } as never,
      order: { expiresAt: 'DESC' } as never,
      skip: this.maxPending,
      take: 1,
    });
    if (cutoff) {
      await this.manager.delete(entity, { expiresAt: LessThanOrEqual(cutoff.expiresAt) } as FindOptionsWhere<T>);
    }
  }
}

/** A row without its NULL columns: the package's records leave optional fields out. */
type WithoutNulls<T> = { [K in keyof T as null extends T[K] ? never : K]: T[K] } & {
  [K in keyof T as null extends T[K] ? K : never]?: Exclude<T[K], null>;
};

function withoutNulls<T extends object>(row: T): WithoutNulls<T> {
  return Object.fromEntries(Object.entries(row).filter(([, value]) => value !== null)) as WithoutNulls<T>;
}
```

* **Conditional updates and deletes** put the condition in the criteria of `update()` and `delete()`, with `LessThan()`, `IsNull()` and `Or()`, and read `affected`. Never `save()`: it would write back a session that a sign-out just deleted.
* **`saveTotp()`** keeps the larger time step with `GREATEST()` over the conflicting row, which the upsert API can't express, so it is the one statement written as SQL, through `manager.query()`.
* **The `consume` methods** are the delete query builder with `returning('*')`. It returns raw rows under the database's column names, so `deleteReturning()` maps them back to entity properties through the entity metadata.
* **`recordMfaFailure()`** is two statements on `dataSource.manager`, each committed on its own, and `saveRecoveryCodes()` is the one method inside `dataSource.transaction()`.
* **Use it** in place of the Drizzle store: `TypeOrmModule.forRoot(dataSourceOptions)` in `AppModule` instead of `DrizzleModule`, and `TypeOrmAuthenticationStore` in the providers of `AuthModule` instead of `DrizzleAuthenticationStore`. It injects the `DataSource` that `TypeOrmModule` provides.

The contract suite runs on it unchanged. TypeORM connects through `pg`, so the suite needs a PostgreSQL server and is skipped without one. Two more cases check that the entities and the migration agree (what `migration:generate --check` checks), and that the store registers for all six contracts when provided in a module:

test/typeorm-authentication.store.e2e-spec.ts

JS TS

```typescript

/**
 * TypeOrmAuthenticationStore against the package's contract suite
 * (`@nestjs/authentication/testing`), on PostgreSQL (the server in
 * SQL_TEST_PG_URL, else a throwaway local cluster; see test/support/postgres.ts),
 * with the migration the TypeORM CLI generated. A pool, so the concurrency
 * cases race for real. Skipped, with the reason, without a server.
 */
import { Logger } from '@nestjs/common';
import { Test } from '@nestjs/testing';
import { AuthenticationModule, AuthenticationStorage } from '@nestjs/authentication';
import { authenticationStoreContract } from '@nestjs/authentication/testing';
import { TypeOrmModule } from '@nestjs/typeorm';
import { DataSource } from 'typeorm';
import { dataSourceOptions } from '../src/typeorm/data-source.js';
import { TypeOrmAuthenticationStore } from '../src/typeorm/typeorm-authentication.store.js';
import { startPostgres } from './support/postgres.js';

/** The store with a cap of 3 pending entries per table, so the suite can check it. */
class CappedStore extends TypeOrmAuthenticationStore {
  protected override readonly maxPending = 3;
}

const { postgres, reason } = await startPostgres();

describe.skipIf(!postgres)(`TypeOrmAuthenticationStore on PostgreSQL${reason ? ` (skipped: ${reason})` : ''}`, () => {
  let dataSource: DataSource;
  let url: string;

  beforeAll(async () => {
    url = await postgres!.createDatabase('authentication_tutorial_typeorm_store');
    dataSource = await new DataSource({ ...dataSourceOptions, url, poolSize: 10 }).initialize();
    await dataSource.runMigrations();
  });
  afterAll(async () => {
    await dataSource?.destroy();
    postgres!.stop();
  });

  /** The store on empty tables, registered nowhere: the suite builds its own registry. */
  async function emptyStore() {
    await dataSource.query(
      'TRUNCATE sessions, refresh_tokens, mfa_authenticators, mfa_recovery_codes, mfa_failures, magic_links, oidc_logins, email_tokens',
    );
    const store = new CappedStore(dataSource, new AuthenticationStorage());
    return { sessions: store, refreshTokens: store, mfa: store, magicLinks: store, oidcStates: store, emailTokens: store };
  }

  for (const c of authenticationStoreContract(emptyStore, { concurrent: true, maxPending: 3 })) {
    it(c.name, c.run);
  }

  it('has a migration that matches the entities (what `migration:generate --check` checks)', async () => {
    const { upQueries } = await dataSource.driver.createSchemaBuilder().log();
    expect(upQueries.map((query) => query.query)).toEqual([]);
  });

  it('registers itself for every contract when provided in a module', async () => {
    const log = vi.spyOn(Logger.prototype, 'log');
    const app = await Test.createTestingModule({
      imports: [TypeOrmModule.forRoot({ ...dataSourceOptions, url }), AuthenticationModule.forRoot()],
      providers: [TypeOrmAuthenticationStore],
    }).compile();
    await app.init();
    const storage = app.get(AuthenticationStorage);
    const store = app.get(TypeOrmAuthenticationStore);
    expect([storage.sessions, storage.refreshTokens, storage.mfa, storage.magicLinks, storage.oidcStates, storage.emailTokens]).toEqual(
      Array(6).fill(store),
    );
    expect(log).toHaveBeenCalledWith('AuthenticationStorage: TypeOrmAuthenticationStore');
    log.mockRestore();
    await app.close();
  });
});
```

> **Hint** Using Prisma? [The store contract](/security/authentication#the-store-contract), after the tutorial, lists what each contract must guarantee and how Prisma expresses the atomic methods. Test your store against the same cases.

#### Issue API keys to partners[#](/security/authentication#issue-api-keys-to-partners)

Cat shelters and pet shops restock in bulk from their own inventory systems, and some customers reorder with a script. A script can't fill in a sign-in form, and a refresh token that changes with every use is a poor fit for a nightly job. Give them API keys instead: long-lived secrets that a customer creates in the web app and revokes when they're no longer needed. The script sends its key as a bearer token, and acts as the customer who created it.

The package checks the keys, and your database keeps them. Add a table to the schema:

src/database/schema.ts

JS TS

```typescript

// API keys (src/auth/api-key-auth.provider.ts): the SHA-256 of each key, never the key.
export const apiKeys = pgTable(
  'api_keys',
  {
    id: text('id').primaryKey(),
    userId: text('user_id').notNull(),
    hash: text('hash').notNull(),
    createdAt: at('created_at').notNull(),
    expiresAt: at('expires_at').notNull(),
  },
  (table) => [index('api_keys_user_id_idx').on(table.userId)],
);
```

Generate its migration, and apply it (the output is trimmed):

```bash

$ npx drizzle-kit generate --name=api_keys
...
9 tables
api_keys 5 columns 1 indexes 0 fks
...
[✓] Your SQL migration file ➜ drizzle/0001_api_keys.sql 🚀
$ npx drizzle-kit migrate
...
[✓] migrations applied successfully!
```

The third credential provider extends `ApiKeyProvider`, and does one thing: it finds a key by its id.

src/auth/api-key-auth.provider.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { ApiKeyProvider, AuthenticationRegistry } from '@nestjs/authentication';
import { InjectDrizzle } from '@nestjs/drizzle';
import { eq } from 'drizzle-orm';
import type { NodePgDatabase } from 'drizzle-orm/node-postgres';
import { apiKeys } from '../database/schema.js';
import type { User } from '../users/user.js';
import { UsersRepository } from '../users/users.repository.js';

@Injectable()
export class ApiKeyAuth extends ApiKeyProvider<User> {
  constructor(
    @InjectDrizzle() private readonly db: NodePgDatabase,
    private readonly usersRepository: UsersRepository,
    registry: AuthenticationRegistry,
  ) {
    // Keys look like cat_<id>_<secret>. The prefix tells secret scanners what they found.
    super({ prefix: 'cat', realm: 'store' });
    // Third in the chain, after SessionAuth and JwtAuth.
    registry.registerProvider(this, { order: 2 });
  }

  // Called with the id part of a key; the provider then checks the hash and the expiry.
  // Returning null (no such key, or its owner was deleted) rejects the key.
  async findKey(id: string) {
    const [key] = await this.db.select().from(apiKeys).where(eq(apiKeys.id, id));
    const user = key && (await this.usersRepository.findById(key.userId));
    return user ? { hash: key.hash, user, expiresAt: key.expiresAt } : null;
  }
}
```

A key reads `cat_<id>_<secret>`: the prefix, a public id of 16 hex characters, and a secret of 256 random bits. `findKey()` looks up the id, and the provider does the rest. It compares the SHA-256 of the whole key with the stored `hash`, in constant time and with the same work for an id that doesn't exist, and refuses the key from `expiresAt` on. A slow hash such as the passwords' scrypt would add nothing here, since nobody guesses 256 random bits, and it would slow down every request. A wrong, expired or revoked key gets a 401 with `error="invalid_token"`, like a bad access token.

`JwtAuth` reads the same `Authorization` header. A JWT always contains two dots and a key contains none, so `JwtAuth` leaves keys to `ApiKeyAuth`, whichever of the two runs first. A request without credentials still gets a single challenge, `Bearer realm="store"`, since both providers use the same realm.

Now the endpoints that create, list and revoke keys:

src/auth/api-keys.controller.ts

JS TS

```typescript

import { Controller, Delete, Get, HttpCode, NotFoundException, Param, Post } from '@nestjs/common';
import { Authenticate, CurrentUser } from '@nestjs/authentication';
import { InjectDrizzle } from '@nestjs/drizzle';
import { and, eq } from 'drizzle-orm';
import type { NodePgDatabase } from 'drizzle-orm/node-postgres';
import { apiKeys } from '../database/schema.js';
import { ApiKeyAuth } from './api-key-auth.provider.js';
import { SessionAuth } from './session-auth.provider.js';

const ONE_YEAR = 365 * 24 * 60 * 60 * 1000;

// Managed from the web app, signed in with a session: a key can't create or revoke keys.
@Authenticate({ providers: [SessionAuth] })
@Controller('auth/api-keys')
export class ApiKeysController {
  constructor(
    @InjectDrizzle() private readonly db: NodePgDatabase,
    private readonly apiKeyAuth: ApiKeyAuth,
  ) {}

  // The only response that contains the key: the table keeps its hash.
  @Post()
  async create(@CurrentUser('id') userId: string) {
    const { key, id, hash } = this.apiKeyAuth.generate();
    const createdAt = new Date();
    const expiresAt = new Date(createdAt.getTime() + ONE_YEAR);
    await this.db.insert(apiKeys).values({ id, userId, hash, createdAt, expiresAt });
    return { id, key, createdAt, expiresAt };
  }

  @Get()
  list(@CurrentUser('id') userId: string) {
    return this.db
      .select({ id: apiKeys.id, createdAt: apiKeys.createdAt, expiresAt: apiKeys.expiresAt })
      .from(apiKeys)
      .where(eq(apiKeys.userId, userId));
  }

  // Revoked from the next request on. Another customer's key is a 404.
  @Delete(':id')
  @HttpCode(204)
  async revoke(@CurrentUser('id') userId: string, @Param('id') id: string) {
    const revoked = await this.db
      .delete(apiKeys)
      .where(and(eq(apiKeys.id, id), eq(apiKeys.userId, userId)))
      .returning();
    if (revoked.length === 0) {
      throw new NotFoundException();
    }
  }
}
```

* `generate()` returns the key, its id and its hash. The table stores the id and the hash, so `create` is the only time anyone sees the key. A customer who loses a key revokes it and creates another.
* The controller accepts `SessionAuth` alone, so keys are managed from the web app. Under `providers`, the credentials of any other provider count as none: a leaked key can't create more keys, or revoke its owner's.
* Keys expire after a year, so a forgotten key doesn't work forever. Deleting a key's row revokes it from the next request on.

Register both in `AuthModule`:

src/auth/auth.module.ts

JS TS

```typescript

import { ApiKeyAuth } from './api-key-auth.provider.js';
import { ApiKeysController } from './api-keys.controller.js';
// ...
controllers: [
  // ...
  SessionsController,
  ApiKeysController,
],
providers: [
  // ...
  DrizzleAuthenticationStore,
  ApiKeyAuth,
],
```

A key signs its owner in on every route that doesn't name its providers, `POST /orders` included. It never counts as a second factor: `PATCH /me/email` answers it with `mfa_required`, as it answers a session that hasn't passed the code. To keep a route to keys, or away from them, list the providers the route accepts in `@Authenticate()`. In a handler, `@CurrentSession()` holds the key's `keyId`, with `method` set to `api-key`, so an audit log can say which key placed an order. Keys that may only read, or only order, are a question of permissions, which is what [`@nestjs/authorization`](/security/authorization) is for.

**With TypeORM.** The table is an entity, next to the store's entities:

src/typeorm/api-key.entity.ts

JS TS

```typescript

import { Column, Entity, Index, PrimaryColumn } from 'typeorm';

// The api_keys table of src/database/schema.ts, for an application on TypeORM.
@Entity('api_keys')
@Index('api_keys_user_id_idx', ['userId'])
export class ApiKeyEntity {
  @PrimaryColumn({ type: 'text' })
  id: string;

  @Column({ type: 'text', name: 'user_id' })
  userId: string;

  @Column({ type: 'text' })
  hash: string;

  @Column({ type: 'timestamptz', name: 'created_at' })
  createdAt: Date;

  @Column({ type: 'timestamptz', name: 'expires_at' })
  expiresAt: Date;
}
```

List it in the data source's `entities`, and its migration, generated as for the store's tables, in `migrations`. `findKey()` reads the row through the entity's repository, with `findOneBy()`, and the controller writes it with `insert()` and `delete()`.

#### Try it[#](/security/authentication#try-it)

Apply the [migrations](/security/authentication#keep-sessions-and-tokens-in-your-database), and start the application with the `.env` file from the previous sections:

```bash

$ npm run start:dev -- --env-file .env
```

In another terminal, sign up. The `-c` flag saves the session cookie to a file, and `-b` sends it with later requests. `--json` (curl 7.82 or later) sends a `POST` with a JSON body. Response headers are trimmed here and below:

```bash

$ curl -i localhost:3000/auth/sign-up -c ada.txt --json '{"email":"ada@example.com","password":"correct horse battery"}'
HTTP/1.1 201 Created
Set-Cookie: __Host-sid=q0L7c...; Max-Age=1209600; Path=/; HttpOnly; Secure; SameSite=Lax
{"id":"7b5d3c2e-...","email":"ada@example.com","emailVerified":false,"roles":["customer"]}
```

The session and the pending verification link are rows in PostgreSQL now. The session's id is the SHA-256 hash of the cookie, and the link's token isn't stored at all:

```bash

$ psql "$DATABASE_URL" -c "SELECT user_id, mfa, metadata FROM sessions" -c "SELECT purpose, email FROM email_tokens"
               user_id                | mfa |          metadata
--------------------------------------+-----+-----------------------------
 7b5d3c2e-...                         |     | {"userAgent": "curl/8.7.1"}
(1 row)

      purpose       |      email
--------------------+-----------------
 email-verification | ada@example.com
(1 row)
```

The verification email appears in the application's log (`LogMailTransport` prints the text of each email):

```bash

LOG [LogMailTransport] "Confirm your email address" to ada@example.com
DEBUG [LogMailTransport] Confirm the email address of your store account:

Confirm my address (http://localhost:3000/verify-email?token=Vb3x...)

If you didn't create an account, ignore this email.
```

The cookie signs Ada in, but her address isn't verified, so she can't place an order yet. Send the token back as the verification page would, and the order goes through. Without the cookie, the API answers 401:

```bash

$ curl localhost:3000/me -b ada.txt
{"id":"7b5d3c2e-...","email":"ada@example.com","emailVerified":false,"roles":["customer"]}

$ curl localhost:3000/orders -b ada.txt --json '{"items":[{"productId":"salmon-kibble-2kg","quantity":1}]}'
{"message":"Email address not verified","error":"email_unverified","statusCode":403,"errorCode":"email_unverified"}

$ curl localhost:3000/auth/email/verify --json '{"token":"Vb3x..."}'
{"email":"ada@example.com","emailVerified":true}

$ curl localhost:3000/orders -b ada.txt --json '{"items":[{"productId":"salmon-kibble-2kg","quantity":1}]}'
{"id":"f3a1...","userId":"7b5d3c2e-...","items":[{"productId":"salmon-kibble-2kg","quantity":1}],"total":2499,"status":"pending"}

$ curl -i localhost:3000/orders
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer realm="store"
{"message":"Unauthorized","statusCode":401,"errorCode":"missing_credentials"}
```

Sign in as the mobile app, and use the access token. The commands below use [jq](https://jqlang.org/) to extract the tokens:

```bash

$ TOKENS=$(curl -s localhost:3000/auth/token --json '{"email":"ada@example.com","password":"correct horse battery"}')
$ echo $TOKENS
{"accessToken":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...","refreshToken":"Qm4x...","expiresIn":900}
$ ACCESS=$(echo $TOKENS | jq -r .accessToken) REFRESH=$(echo $TOKENS | jq -r .refreshToken)

$ curl localhost:3000/orders -H "Authorization: Bearer $ACCESS"
[{"id":"f3a1...","userId":"7b5d3c2e-...","items":[{"productId":"salmon-kibble-2kg","quantity":1}],"total":2499,"status":"pending"}]
```

A refresh token works once. The second attempt with the same token is treated as theft, and revokes the whole family:

```bash

$ curl localhost:3000/auth/token/refresh --json "{\"refreshToken\":\"$REFRESH\"}"
{"accessToken":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...","refreshToken":"n8Vb...","expiresIn":900}

$ curl localhost:3000/auth/token/refresh --json "{\"refreshToken\":\"$REFRESH\"}"
{"message":"Refresh token reused","error":"Unauthorized","statusCode":401}
```

Turn on two-factor authentication. Add the secret to an authenticator app, and confirm with the code it shows. The code proves this browser has the authenticator, so the session is verified from here on, under a new cookie (`-c` saves it):

```bash

$ curl -X POST localhost:3000/auth/mfa/enroll -b ada.txt
{"secret":"MZXW6YTBOI3DGNJS...","uri":"otpauth://totp/example.com:ada%40example.com?secret=MZXW6YTBOI3DGNJS...&issuer=example.com&algorithm=SHA1&digits=6&period=30"}

$ curl -i localhost:3000/auth/mfa/confirm -b ada.txt -c ada.txt --json '{"code":"492039"}'
HTTP/1.1 200 OK
Set-Cookie: __Host-sid=Kp4w...; Max-Age=1209571; Path=/; HttpOnly; Secure; SameSite=Lax
{"recoveryCodes":["7KQ2M-XR4PB","HT9WC-3MDNA","..."]}
```

> **Hint** With [oath-toolkit](https://www.nongnu.org/oath-toolkit/) installed, `oathtool --totp -b` followed by the secret prints the current code in the terminal.

Sign in again. The new session is pending until it passes the second factor, and verifying replaces the cookie:

```bash

$ curl localhost:3000/auth/sign-in -b ada.txt -c ada.txt --json '{"email":"ada@example.com","password":"correct horse battery"}'
{"mfaRequired":true}

$ curl localhost:3000/me -b ada.txt
{"message":"Second factor required","error":"mfa_required","statusCode":401,"errorCode":"mfa_required"}

$ curl localhost:3000/auth/mfa/verify -b ada.txt -c ada.txt --json '{"code":"815224"}'
{"mfa":"verified"}

$ curl -X PATCH localhost:3000/me/email -b ada.txt --json '{"email":"ada.lovelace@example.com"}'
{"id":"7b5d3c2e-...","email":"ada.lovelace@example.com","emailVerified":false,"roles":["customer"]}
```

The new address is unverified, and a verification email goes to it:

```bash

LOG [LogMailTransport] "Confirm your email address" to ada.lovelace@example.com
```

The mobile app is asked for a code too:

```bash

$ curl localhost:3000/auth/token --json '{"email":"ada.lovelace@example.com","password":"correct horse battery"}'
{"message":"Second factor required","error":"mfa_required","statusCode":401,"errorCode":"mfa_required"}
```

Start a Google sign-in. curl shows the redirect; open the same URL in a browser to complete it, and you land on `/orders`, signed in:

```bash

$ curl -i 'localhost:3000/auth/oidc/google/login?redirectTo=/orders'
HTTP/1.1 302 Found
Set-Cookie: __Host-oidc_tx=Zq8...; Max-Age=600; Path=/; HttpOnly; Secure; SameSite=Lax
Location: https://accounts.google.com/o/oauth2/v2/auth?response_type=code&client_id=...&redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fauth%2Foidc%2Fgoogle%2Fcallback&scope=openid+email+profile&state=pW4c...&code_challenge=...&code_challenge_method=S256&nonce=...
```

Ask for a magic link for a new customer, Grace. The link works only in the browser that asked for it, so keep the cookie the response sets. The email appears in the application's log:

```bash

$ curl -i localhost:3000/auth/magic-link -c grace.txt --json '{"email":"grace@example.com"}'
HTTP/1.1 202 Accepted
Set-Cookie: __Host-magic_link_tx=Vn3p...; Max-Age=900; Path=/; HttpOnly; Secure; SameSite=Lax
```

```bash

LOG [LogMailTransport] "Your sign-in link" to grace@example.com
DEBUG [LogMailTransport] Sign in to the store (http://localhost:3000/sign-in/magic?token=Hq2x...)

The link works once, for 15 minutes. If you didn't ask for it, ignore this email.
```

Send the token back as the page would, with that cookie. Grace gets an account, with a verified address, and a session:

```bash

$ curl localhost:3000/auth/magic-link/consume -b grace.txt -c grace.txt --json '{"token":"Hq2x..."}'
{"redirectTo":"/","mfaRequired":false}

$ curl localhost:3000/me -b grace.txt
{"id":"c41e9a07-...","email":"grace@example.com","emailVerified":true,"roles":["customer"]}
```

Grace runs a cat shelter, whose inventory system reorders litter. Create a key for it from her session, and place an order with the key. The key can't create keys, and once Grace revokes it, it stops working:

```bash

$ API_KEY=$(curl -s -X POST localhost:3000/auth/api-keys -b grace.txt)
$ echo $API_KEY
{"id":"d2cb7a64f3279c6b","key":"cat_d2cb7a64f3279c6b_QiBr...","createdAt":"2026-09-22T10:02:41.067Z","expiresAt":"2027-09-22T10:02:41.067Z"}
$ KEY=$(echo $API_KEY | jq -r .key) KEY_ID=$(echo $API_KEY | jq -r .id)

$ curl localhost:3000/orders -H "Authorization: Bearer $KEY" --json '{"items":[{"productId":"clumping-litter-10l","quantity":20}]}'
{"id":"db8a...","userId":"c41e9a07-...","items":[{"productId":"clumping-litter-10l","quantity":20}],"total":31980,"status":"pending"}

$ curl -X POST localhost:3000/auth/api-keys -H "Authorization: Bearer $KEY"
{"message":"Unauthorized","statusCode":401,"errorCode":"missing_credentials"}

$ curl -i -X DELETE localhost:3000/auth/api-keys/$KEY_ID -b grace.txt
HTTP/1.1 204 No Content

$ curl -i localhost:3000/orders -H "Authorization: Bearer $KEY"
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer realm="store", error="invalid_token", error_description="invalid api key"
{"message":"invalid api key","error":"Unauthorized","statusCode":401}
```

List Ada's sessions, then sign her out everywhere. Her old cookie stops working:

```bash

$ curl localhost:3000/auth/sessions -b ada.txt
[{"id":"eT0r...","createdAt":"2026-09-22T10:02:11.042Z","lastActiveAt":"2026-09-22T10:03:30.518Z","userAgent":"curl/8.7.1","current":true}]

$ curl -i -X POST localhost:3000/auth/sign-out-everywhere -b ada.txt
HTTP/1.1 204 No Content
Set-Cookie: __Host-sid=; Max-Age=0; Path=/; HttpOnly; Secure; SameSite=Lax

$ curl localhost:3000/me -b ada.txt
{"message":"Unauthorized","statusCode":401,"errorCode":"missing_credentials"}
```

Ada forgot her password. Ask for a reset link for her address, and for an address nobody registered: both get the same empty 202, and only Ada gets an email:

```bash

$ curl -i localhost:3000/auth/password/forgot --json '{"email":"ada.lovelace@example.com"}'
HTTP/1.1 202 Accepted

$ curl -i localhost:3000/auth/password/forgot --json '{"email":"nobody@example.com"}'
HTTP/1.1 202 Accepted
```

```bash

LOG [LogMailTransport] "Reset your password" to ada.lovelace@example.com
DEBUG [LogMailTransport] Someone asked to reset the password of your store account.

Choose a new password (http://localhost:3000/reset-password?token=Rt7k...)

The link works once, for an hour. If it wasn't you, ignore this email: your password stays as it is.
```

Choose a new password with the token, as the reset page would. Ada is signed in again, pending her second factor (a pending session lives ten minutes, `mfa.pendingTtl`, hence the `Max-Age`), and the old password no longer works:

```bash

$ curl -i localhost:3000/auth/password/reset -c ada.txt --json '{"token":"Rt7k...","password":"a brand new passphrase"}'
HTTP/1.1 200 OK
Set-Cookie: __Host-sid=Yb2d...; Max-Age=600; Path=/; HttpOnly; Secure; SameSite=Lax
{"mfaRequired":true}

$ curl localhost:3000/auth/sign-in --json '{"email":"ada.lovelace@example.com","password":"correct horse battery"}'
{"message":"Invalid email or password","error":"Unauthorized","statusCode":401}
```

Finally, guess Grace's password. The sixth attempt within 15 minutes is refused before the password is checked:

```bash

$ for i in 1 2 3 4 5 6; do curl -s -o /dev/null -w '%{http_code} ' localhost:3000/auth/sign-in --json '{"email":"grace@example.com","password":"password123"}'; done
401 401 401 401 401 429
```

#### GraphQL and WebSockets[#](/security/authentication#graphql-and-websockets)

The global guard, `@Public()`, `@CurrentUser()` and `AuthenticationContext` work in GraphQL resolvers and WebSocket gateways too. The guard reads the cookie and the headers from the request that carries them.

In GraphQL, that's the `req` on the GraphQL context, so the `context` option must be a function that builds a context for each request. A `context` given as an object would be one object for every request, and the app fails at startup. Nest runs global guards and interceptors on root resolvers only: to guard field resolvers too, and to give them `AuthenticationContext`, add `fieldResolverEnhancers: ['guards', 'interceptors']`.

src/app.module.ts

JS TS

```typescript

GraphQLModule.forRoot<ApolloDriverConfig>({
  driver: ApolloDriver,
  autoSchemaFile: true,
  subscriptions: { 'graphql-ws': true },
  // Over graphql-ws there is no request per operation: the upgrade request stands in for it.
  context: ({ req, res, extra }) => ({ req: req ?? extra?.request, res }),
  fieldResolverEnhancers: ['guards', 'interceptors'],
}),
```

Over `graphql-ws`, every operation on a socket shares that upgrade request, and each operation that needs a user authenticates again with its cookie, so a sign-out everywhere stops the next one. `@CurrentUser()` gives each operation its own user, and `null` to a `@Public()` one. `req.user`, which the module also sets for code that reads the request, holds whichever operation authenticated last: read `@CurrentUser()` instead.

Nest runs no guards on a gateway's `handleConnection()`, so authenticate the handshake with `WsAuthenticator`:

src/orders/orders.gateway.ts

JS TS

```typescript

import type { IncomingMessage } from 'node:http';
import { WebSocketGateway, type OnGatewayConnection } from '@nestjs/websockets';
import { WsAuthenticator } from '@nestjs/authentication';
import type { WebSocket } from 'ws';

@WebSocketGateway()
export class OrdersGateway implements OnGatewayConnection {
  constructor(private readonly wsAuthenticator: WsAuthenticator) {}

  async handleConnection(client: WebSocket, request: IncomingMessage) {
    await this.wsAuthenticator.authenticateConnection(client, request);
  }
}
```

It closes a connection that nobody signed in on, with code 1008, or socket.io's `disconnect()`; to keep guests, pass `authenticateConnection()` a third argument whose `required` option is `false`. With socket.io, it reads the handshake's headers, so the `request` argument can go. A handshake from another site's page is anonymous, as a [cross-origin write](/security/authentication#add-sign-up-and-sign-in) is. The guard then authenticates every message again, so a revoked session stops working mid-connection. `@CurrentUser()` is per message, `null` on a `@Public()` one. `client.user` holds the user of the last message that authenticated, and is cleared once a message is refused for its credentials.

[`@nestjs/authorization`](/security/authorization) checks `@Can()` against the user of each message and each operation, not the socket's.

#### Testing[#](/security/authentication#testing)

End-to-end tests boot the real `AppModule`, with three things changed. The database is [PGlite](https://pglite.dev), PostgreSQL compiled to WebAssembly, with your real migrations applied, so the tests need no server. Mail goes to an `InMemoryMailTransport`, which keeps each email for the test to read. And scrypt is slow on purpose, a few hundred milliseconds and 128 MiB of memory per hash at the default cost, so the test overrides `PasswordHasher` with a cheaper one. The application also reads its settings at bootstrap, so the tests need test values for them:

vitest.config.e2e.ts

JS TS

```typescript

export default defineConfig({
  // ...
  test: {
    // ...
    env: {
      APP_URL: 'http://localhost:3000',
      JWT_SECRET: 'test-only-jwt-secret-of-at-least-32-bytes',
      TOTP_ENCRYPTION_KEY: 'test-only-totp-key-of-at-least-32-chars',
      GOOGLE_CLIENT_ID: 'store.apps.googleusercontent.com',
      GOOGLE_CLIENT_SECRET: 'test-only-google-secret',
    },
  },
});
```

test/auth.e2e-spec.ts

JS TS

```typescript

import type { INestApplication } from '@nestjs/common';
import { Test } from '@nestjs/testing';
import { PGlite } from '@electric-sql/pglite';
import { PasswordHasher } from '@nestjs/authentication';
import { getDrizzleToken } from '@nestjs/drizzle';
import { InMemoryMailTransport, MailTransport } from '@nestjs/mail';
import { drizzle } from 'drizzle-orm/pglite';
import { migrate } from 'drizzle-orm/pglite/migrator';
import { fileURLToPath } from 'node:url';
import request from 'supertest';
import { AppModule } from '../src/app.module.js';
import { VerifyEmailMail } from '../src/auth/email-verification.mailer.js';
import { PasswordResetMail } from '../src/auth/password-reset.mailer.js';

describe('Authentication (e2e)', () => {
  const pglite = new PGlite(); // PostgreSQL in-process: no server to start
  const mailbox = new InMemoryMailTransport();
  let app: INestApplication;
  const ada = { email: 'ada@example.com', password: 'correct horse battery' };

  beforeAll(async () => {
    const db = drizzle(pglite);
    // The app's migrations, the authentication tables included.
    await migrate(db, { migrationsFolder: fileURLToPath(new URL('../drizzle', import.meta.url)) });
    const moduleRef = await Test.createTestingModule({ imports: [AppModule] })
      .overrideProvider(getDrizzleToken()) // the database DrizzleModule provides
      .useValue(db)
      .overrideProvider(MailTransport)
      .useValue(mailbox)
      .overrideProvider(PasswordHasher)
      .useValue(new PasswordHasher({ logN: 10 }))
      .compile();
    app = moduleRef.createNestApplication();
    await app.listen(0, '127.0.0.1');
  });

  afterAll(async () => {
    await app.close();
    await pglite.close();
  });

  it('signs up, verifies the address, then reads the profile with the session cookie', async () => {
    const res = await request(app.getHttpServer()).post('/auth/sign-up').send(ada).expect(201);
    const cookie = res.headers['set-cookie'][0].split(';')[0];

    const mail = mailbox.assertSent({ to: ada.email, mail: VerifyEmailMail });
    const token = mail.link('/verify-email').searchParams.get('token');
    await request(app.getHttpServer()).post('/auth/email/verify').send({ token }).expect(200);

    await request(app.getHttpServer())
      .get('/me')
      .set('Cookie', cookie)
      .expect(200, { id: res.body.id, email: ada.email, emailVerified: true, roles: ['customer'] });
  });

  it('issues bearer tokens to the mobile app', async () => {
    const res = await request(app.getHttpServer()).post('/auth/token').send(ada).expect(200);

    await request(app.getHttpServer())
      .get('/orders')
      .set('Authorization', `Bearer ${res.body.accessToken}`)
      .expect(200, []);
  });

  it('resets a forgotten password', async () => {
    await request(app.getHttpServer()).post('/auth/password/forgot').send({ email: ada.email }).expect(202);
    // The email goes out after the response, which doesn't wait for it.
    const mail = await vi.waitFor(() => mailbox.assertSent({ to: ada.email, mail: PasswordResetMail }));
    const token = mail.link('/reset-password').searchParams.get('token');

    await request(app.getHttpServer())
      .post('/auth/password/reset')
      .send({ token, password: 'a brand new passphrase' })
      .expect(200);
    await request(app.getHttpServer()).post('/auth/sign-in').send(ada).expect(401);
  });

  it('rejects anonymous requests and wrong passwords', async () => {
    await request(app.getHttpServer()).get('/orders').expect(401);
    await request(app.getHttpServer())
      .post('/auth/sign-in')
      .send({ ...ada, password: 'not the password' })
      .expect(401);
  });
});
```

* `mailbox.assertSent()` finds the latest email to an address, of a mail class, and `link()` returns its first link containing the path, as a `URL`. That's the whole flow for verification, reset and magic links: send, find the link, follow it.
* The reset email is sent after the response (see [Reset forgotten passwords](/security/authentication#reset-forgotten-passwords)), so the test waits for it with `vi.waitFor()`. The other emails are sent before the route answers.
* `DrizzleAuthenticationStore` runs on PGlite as it does on PostgreSQL. PGlite has a single connection, so two requests never truly race there; the store's [contract tests](/security/authentication#keep-sessions-and-tokens-in-your-database) run on PostgreSQL too, where they do.

To sign a test user in without going through a sign-in route, `SessionService.create()` returns a session cookie, and `TokenService.issue()` a bearer token (for a user without an authenticator). To test code that reads `AuthenticationContext` without HTTP, run it as a user: `run()` takes an authentication result (the user, and optionally the session) and a function to run.

#### Production checklist[#](/security/authentication#production-checklist)

* **Register a store for everything the module keeps**, as in [Keep sessions and tokens in your database](/security/authentication#keep-sessions-and-tokens-in-your-database), and apply its tables through your migrations. Every instance of the application uses them, so a restart signs nobody out. The module refuses to start while a store that a configured feature uses isn't registered, but only when `NODE_ENV` is `production`: set it, or a deployment that forgets it runs in memory with nothing but a startup log line to say so. Run the package's contract tests against your store with `concurrent: true` on PostgreSQL: they fail a store that reads and then writes where one conditional statement is needed.
* **Configure the same features in every application that shares the user database.** Each one decides from its own options whether a sign-in asks for a second factor and whether signing out everywhere ends refresh tokens. If any application that signs users in configures `mfa`, every one of them must, or a customer who enrolled through one signs in to another with a password alone. Likewise configure `accessToken`, with refresh tokens on, in each of them if a sign-out everywhere or a password reset in one should also sign out the token clients of the others.
* **Send email through a real provider.** Set `SMTP_URL`, or pass another transport. `LogMailTransport` writes every link to the log, where anyone who reads the logs could sign in as the customer.
* **Serve the application over HTTPS**, since the session cookie is `Secure`. If the web app runs on another origin than the API, list it in `session.trustedOrigins`, or its sign-ins and magic-link requests are refused, and its `POST` requests and WebSocket connections are anonymous. Behind a proxy that rewrites `Host`, list the public origin there too. Leave `cookie.secure` on: a `SameSite=None` cookie without it fails at startup, since browsers would drop it.
* **Call `app.enableCsrfProtection()` on Nest 12.1 or later**, with the same `trustedOrigins`. It refuses cross-origin writes to every route, not only those that use the session cookie.
* **Keep secrets in a secret manager**: the JWT secret, the TOTP encryption keys, the Google client secret and the SMTP credentials. Rotate the TOTP keys as described in [Add two-factor authentication](/security/authentication#add-two-factor-authentication).
* **Build the verification and reset pages to POST the token**, and serve them from `APP_URL`. Email scanners follow the links with GET requests; a page that used the token on load would let them spend it.
* **Keep `forgot` from revealing anything.** Answer it the same way whatever happens, as the [`forgot` route](/security/authentication#reset-forgotten-passwords) does, and don't `await``request()`. Sign-up still answers 409 for an address that has an account; if that matters to you, answer sign-up the same way too, and email the owner instead.
* **Register the production redirect URI** with Google, and set `APP_URL` to the public origin of the application.
* **Size the servers for scrypt.** Each hash at the default cost takes 128 MiB, on the libuv threadpool (four threads unless you set `UV_THREADPOOL_SIZE`). Sign-in bursts queue behind each other; the throttler bounds them.
* **Use shared storage for the throttler**, such as Redis. Its default storage counts in each process's memory, so every instance counts on its own and a restart or deploy resets the counts. Enable `trust proxy` behind a proxy. For guessing spread across many IP addresses, add a second throttler whose tracker is the email alone; it also keeps a customer's inbox from filling up with reset links.
* **Rotate sessions on privilege changes** with `SignInService.rotateSession()`. After a password change made while signed in, or when a customer turns two-factor authentication on or off, also end their other sessions and refresh tokens: `SessionService.revokeAll()` with the current session as `except`, and `TokenService.revokeAll()`. Whoever knew the old password may still be signed in. A [password reset](/security/authentication#reset-forgotten-passwords) does this for you.
* **Handle API keys as secrets.** The table keeps only their hashes, and a key is shown once, when it's created: a leaked database gives nobody a key, and a lost key is revoked and replaced, never shown again. Keys expire after a year, so remind their owners to create the next one while the old one still works. Add the `cat_` pattern to your secret scanner (GitHub secret scanning takes custom patterns) to find keys committed to repositories, and revoke them. Requests made with a key emit no events: log the `keyId` from `@CurrentSession()` where you need to know which key did what. A password reset or a sign-out everywhere leaves keys alone: revoke them on those events if they should cut keys off too.
* **Keep an audit trail.**`AuthenticationEvents` publishes every sign-in and sign-out, second-factor change, reused refresh token, password reset and email verification, on its `events$` stream and on `node:diagnostics_channel`. Store them where your security team can search them. Alert on repeated `mfa-failed` events with `locked: true` (someone who has the password is guessing codes), and on many `password-reset-requested` events without a `userId` from one source (someone is probing for accounts), and on `session-touch-failed` events, which mean the session store is refusing writes.
* **Import `AuthenticationModule` before `AuthorizationModule`** if you add `@nestjs/authorization`. Global guards run in import order, and authorization needs the user that authentication sets. The other order fails at startup. `@nestjs/authorization` denies a handler that declares no check, and counts `@Public()` as one: a public route needs no `@Can.Anyone()`.

#### The store contract[#](/security/authentication#the-store-contract)

The tutorial [wrote the authentication store with Drizzle](/security/authentication#keep-sessions-and-tokens-in-your-database). This section sums up what the six contracts ask of any store, for writing one with another ORM. Each method of the store interfaces gives its rule in its doc comment, with the race the rule prevents, and the package's contract tests check them.

**Registration.** A store is an ordinary singleton provider that registers itself in its constructor with `registerSource()` on the injectable `AuthenticationStorage`, by contract name: `sessions`, `refreshTokens`, `mfa`, `magicLinks`, `oidcStates` and `emailTokens`. Method names never repeat across the contracts, so one class can implement all six, or several classes can split them. The registry checks each store's shape at once, refuses a second store for a name unless it passes `replace: true`, and locks when `AuthenticationModule` initializes, logging where each kind of state lives. A contract with no store uses its in-memory default, which loses everything on restart and isn't shared between instances.

**Production guard.** With `NODE_ENV=production`, startup fails while a contract that a configured feature uses has no store, naming each missing interface:

| Configured                                        | Contracts                 |
| ------------------------------------------------- | ------------------------- |
| a `SessionCookieProvider`                         | `sessions`                |
| `accessToken`, with refresh tokens on             | `refreshTokens`           |
| `accessToken`, with `refreshToken` set to `false` | none                      |
| `mfa`                                             | `mfa`                     |
| `magicLink`                                       | `sessions`, `magicLinks`  |
| `oidc`                                            | `sessions`, `oidcStates`  |
| `passwordReset`                                   | `sessions`, `emailTokens` |
| `emailVerification`                               | `emailTokens`             |

Two-factor authentication is off without `mfa`: sign-ins don't read the `mfa` contract. Refresh tokens exist only with `accessToken`, so without it, or with `refreshToken` set to `false`, signing out everywhere and resetting a password end sessions alone. A contract that none of your configured features uses fails at its first read instead of running in memory. `allowInMemoryStorage: true` in the module options accepts the in-memory stores anyway, but then every restart or deploy signs everyone out and forgets enrolled authenticators, and instances don't share any of it.

**The methods that must be atomic.** Whatever decides that something works only once is one conditional statement, never a read followed by a write. The other methods are plain reads, inserts and deletes. None takes your transaction: authentication state is written on its own, never as part of a business transaction.

| Contract                                              | Method                                                            | Must be                                                                       | Why                                                                             |
| ----------------------------------------------------- | ----------------------------------------------------------------- | ----------------------------------------------------------------------------- | ------------------------------------------------------------------------------- |
| `SessionStore`                                        | `touchSession()`                                                  | a conditional `UPDATE` of an existing row, moving `lastActiveAt` forward only | a request writing the session back after a sign-out would bring it back         |
| `SessionStore`                                        | `deleteSession()`                                                 | a `DELETE` that resolves whether it deleted the row, from its row count       | of two rotations of one session, or a rotation and a sign-out, only one may win |
| `RefreshTokenStore`                                   | `markRefreshTokenUsed()`                                          | an `UPDATE ... WHERE used_at IS NULL`, counting rows                          | a thief and the owner refreshing at once must not both win                      |
| `MfaStore`                                            | `saveTotp()`                                                      | an upsert that keeps the larger `lastUsedStep`                                | saving the record must not reopen a step just claimed                           |
| `MfaStore`                                            | `claimTotpStep()`, `consumeRecoveryCode()`                        | a conditional `UPDATE`, a `DELETE`, counting rows                             | a replayed code must fail                                                       |
| `MfaStore`                                            | `recordMfaFailure()`                                              | an insert, then a count, each committed on its own                            | a burst of parallel guesses must not all see a low count                        |
| `MfaStore`                                            | `saveRecoveryCodes()`                                             | one transaction: delete, then insert                                          | a reader must never see half a batch                                            |
| `MagicLinkStore`, `OidcStateStore`, `EmailTokenStore` | `consumeMagicLink()`, `consumeOidcState()`, `consumeEmailToken()` | a `DELETE ... RETURNING`                                                      | one link must not sign in two browsers, or set two passwords                    |

A family of refresh tokens counts as revoked when any of its tokens is, so a successor saved after the revocation is revoked too. And the pending entries (magic links, OIDC logins, email tokens) stay bounded: each save deletes what has expired and, past a cap, what expires first.

`touchSession()` is best-effort: when it fails, the request goes on with the session as read, and a `session-touch-failed` event reports it. `getSession()` may set `extra` to what the same query read with the session, typically its user, for `SessionCookieProvider.validate()`. `createSession()` never receives it, and `listUserSessions()` doesn't set it.

**With Prisma.** The tutorial has the store with Drizzle and with TypeORM, on the same tables. A Prisma store follows the same rules:

* **Conditional updates and deletes** (`touchSession()`, `deleteSession()`, `markRefreshTokenUsed()`, `claimTotpStep()`, `consumeRecoveryCode()`) are `updateMany()` or `deleteMany()` with the condition in `where`, and their `count`: `deleteSession()` resolves `count > 0`. Never `upsert()` for `touchSession()`: it can write back a session that was just deleted.
* **`saveTotp()`** needs `GREATEST(..., excluded.last_used_step)` in its upsert. Prisma's upsert API doesn't take an expression from the conflicting row, so it is raw SQL, with `$executeRaw`.
* **The `consume` methods** are `delete()` with every condition in `where` (the id and, for `consumeEmailToken()`, the purpose), which throws `P2025` when nothing matched: turn that into `undefined`.
* **`recordMfaFailure()`** is two statements on their own: a `create()`, then a `count()`. Not `prisma.$transaction([create, count])`, which runs the two in one transaction that commits after the count.
* **`saveRecoveryCodes()`** is the one method that needs a transaction: `$transaction()`, whose array form fits here.

**Test it** with the suite from `@nestjs/authentication/testing`, as the tutorial does. `authenticationStoreContract()` returns cases for any test runner, for the contracts your factory returns. `concurrent: true` adds the races: parallel refreshes of one token, parallel uses of one code or link, bursts of failed codes, a sign-out racing a request, parallel deletes of one session, and a rotation racing a sign-out or another rotation. Run it against PostgreSQL with a connection pool, where a store that reads and then writes fails them. `maxPending` checks the cap on pending entries, with a small cap configured for the test. The suite ignores `extra` when it compares what `getSession()` returns, so a store that joins the user passes.

#### Reference[#](/security/authentication#reference)

##### Module options[#](/security/authentication#module-options)

`AuthenticationModule.forRoot()` takes these options, and the `forRootAsync()` factory returns them, except `isGlobal` and `globalGuard`, which stay at the top level. Lifetimes are milliseconds, or strings such as `'30s'`, `'15m'` and `'14d'`, up to 100 years; a longer one fails at startup. Every group that has a clock also takes `now`, a function returning epoch milliseconds, for tests.

| Option                                | Default                                        | Description                                                                                                                                                                                                                                                                                                                                      |
| ------------------------------------- | ---------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `isGlobal`                            | `true`                                         | Register the module globally.                                                                                                                                                                                                                                                                                                                    |
| `globalGuard`                         | `true`                                         | Register `AuthenticationGuard` as a global guard. With `false`, routes stay open until they use `@UseGuards(AuthenticationGuard)`.                                                                                                                                                                                                               |
| `allowInMemoryStorage`                | `false`                                        | Start with `NODE_ENV=production` while a contract a feature uses has no store. See [Keep sessions and tokens in your database](/security/authentication#keep-sessions-and-tokens-in-your-database).                                                                                                                                              |
| `session.cookieName`                  | `__Host-sid`                                   | The session cookie; `sid` when `cookie` rules out the `__Host-` prefix.                                                                                                                                                                                                                                                                          |
| `session.absoluteTtl`                 | `'7d'`                                         | A session's maximum lifetime, however active it is.                                                                                                                                                                                                                                                                                              |
| `session.idleTtl`                     | `'1d'`                                         | Idle timeout, extended by activity. `0` turns it off.                                                                                                                                                                                                                                                                                            |
| `session.touchInterval`               | `'1m'`                                         | How often activity is written to the store at most. Shorter than `idleTtl`, unless that is `0`: a longer one fails at startup, since active users would be signed out as idle.                                                                                                                                                                   |
| `session.cookie`                      | `secure: true`, `sameSite: 'lax'`, `path: '/'` | Cookie attributes: `secure`, `sameSite`, `path`, `domain`. `HttpOnly` is always set.                                                                                                                                                                                                                                                             |
| `session.trustedOrigins`              | none                                           | Other origins whose pages may use the session cookie for writes and sign in.                                                                                                                                                                                                                                                                     |
| `session.metadata`                    | none                                           | A function of the sign-in request whose result is stored with each new session. See [Let customers manage their sessions](/security/authentication#let-customers-manage-their-sessions).                                                                                                                                                         |
| `password.logN`                       | `17`                                           | Base-2 logarithm of the scrypt cost N, an integer from 10 to 22. `r` (default `8`, up to 32), `p` (`1`, up to 16), `keyLength` (`32`) and `saltLength` (`16`, both from 16 to 64) set the other parameters. A hash may take at most 1 GiB of memory (128·N·r bytes) and 16 times the default work (N·r·p), so with `r` at 8, `logN` stops at 20. |
| `accessToken.key`                     | required                                       | HS256 secret of at least 32 bytes, or a private key for RS256, ES256 or EdDSA, as PEM text or a `KeyObject`. A JWK or a DER key fails at startup: import it with `createPrivateKey()`. See [Issue tokens to the mobile app](/security/authentication#issue-tokens-to-the-mobile-app).                                                            |
| `accessToken.alg`                     | from the key                                   | Signing algorithm: HS256 for a secret, the key's own for a private key.                                                                                                                                                                                                                                                                          |
| `accessToken.issuer`, `audience`      | none                                           | The `iss` and `aud` claims, written into and checked on every token.                                                                                                                                                                                                                                                                             |
| `accessToken.ttl`                     | `'15m'`                                        | Access token lifetime.                                                                                                                                                                                                                                                                                                                           |
| `accessToken.kid`, `type`             | none, `JWT`                                    | The `kid` and `typ` headers.                                                                                                                                                                                                                                                                                                                     |
| `refreshToken`                        | on with `accessToken`                          | `false` issues access tokens alone, with no refresh tokens and no `RefreshTokenStore`. See [Issue tokens to the mobile app](/security/authentication#issue-tokens-to-the-mobile-app).                                                                                                                                                            |
| `refreshToken.ttl`                    | `'30d'`                                        | Lifetime of one refresh token.                                                                                                                                                                                                                                                                                                                   |
| `refreshToken.absoluteTtl`            | `'90d'`                                        | Maximum lifetime of a refresh-token family, however often it rotates.                                                                                                                                                                                                                                                                            |
| `mfa.encryption`                      | required                                       | `keys`, a list of AES-256-GCM keys, newest first, plus `migratePlaintext` (default `false`); or `false` to store secrets in plaintext. See [Add two-factor authentication](/security/authentication#add-two-factor-authentication).                                                                                                              |
| `mfa.issuer`                          | none                                           | The name authenticator apps show.                                                                                                                                                                                                                                                                                                                |
| `mfa.window`                          | `1`                                            | Accepted 30-second steps on either side of now, an integer from 0 to 10.                                                                                                                                                                                                                                                                         |
| `mfa.maxAttempts`                     | `5`                                            | Failed codes allowed per `lockoutWindow` before every code is refused, an integer of at least 1.                                                                                                                                                                                                                                                 |
| `mfa.lockoutWindow`                   | `'15m'`                                        | The window failed codes are counted in.                                                                                                                                                                                                                                                                                                          |
| `mfa.recoveryCodes`                   | `10`                                           | Recovery codes per batch, an integer of at least 1.                                                                                                                                                                                                                                                                                              |
| `mfa.pendingTtl`                      | `'10m'`                                        | How long a session may wait for its second factor.                                                                                                                                                                                                                                                                                               |
| `emailVerification.url`               | required                                       | The page verification links open. `ttl` defaults to `'24h'`. See [Verify email addresses](/security/authentication#verify-email-addresses).                                                                                                                                                                                                      |
| `passwordReset.url`                   | required                                       | The page reset links open. `ttl` defaults to `'1h'`. See [Reset forgotten passwords](/security/authentication#reset-forgotten-passwords).                                                                                                                                                                                                        |
| `magicLink.url`                       | required                                       | The page magic links open. `ttl` defaults to `'15m'`. See [Add magic-link sign-in](/security/authentication#add-magic-link-sign-in).                                                                                                                                                                                                             |
| `magicLink.bindToBrowser`             | `true`                                         | Accept a link only in the browser that requested it.                                                                                                                                                                                                                                                                                             |
| `magicLink.cookie`                    | `secure: true`                                 | Attributes of the `__Host-magic_link_tx` transaction cookie.                                                                                                                                                                                                                                                                                     |
| `oidc.callbackUrl`                    | required                                       | The public callback URL, with `:provider` in place of the provider's name, or a function of the request that returns it. See [Add "Sign in with Google"](/security/authentication#add-sign-in-with-google).                                                                                                                                      |
| `oidc.providers`                      | required                                       | Provider configurations by name, such as `google()`, `github()` and `microsoft()`, which also takes the directory's `tenant` id.                                                                                                                                                                                                                 |
| `oidc.redirectAfterLogin`             | `/`                                            | Where to land when the login had no `redirectTo`.                                                                                                                                                                                                                                                                                                |
| `oidc.transactionTtl`                 | `'10m'`                                        | How long a login may take between the redirect and the callback.                                                                                                                                                                                                                                                                                 |
| `oidc.cookie`                         | `secure: true`                                 | Attributes of the `__Host-oidc_tx` transaction cookie.                                                                                                                                                                                                                                                                                           |
| `oidc.discoveryTtl`, `clockTolerance` | `'1h'`, `'30s'`                                | How long a discovery document is trusted, and the leeway for ID token time claims.                                                                                                                                                                                                                                                               |

The `emailVerification`, `passwordReset`, `magicLink` and `oidc` features also need a registered handler of the same name; one without the other fails at startup. So does a value outside the ranges above, including the `NaN` that `Number()` makes of an environment variable that isn't set.

##### Route options[#](/security/authentication#route-options)

`@Authenticate()` takes these options, on a class or a method:

| Option          | Description                                                                                                                                                                                                                        |
| --------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `optional`      | Let anonymous callers through, with `null` as the user. Bad credentials still get a 401.                                                                                                                                           |
| `mfa`           | Require a verified second factor: a verified session, or a JWT whose `amr` contains `mfa`, `otp` or `hwk`. API keys never satisfy it. See [Add two-factor authentication](/security/authentication#add-two-factor-authentication). |
| `verifiedEmail` | Require a verified email address, or answer 403 with `email_unverified`. See [Read the current user](/security/authentication#read-the-current-user).                                                                              |
| `providers`     | Only these provider classes, or their subclasses, may authenticate the route.                                                                                                                                                      |

##### API keys[#](/security/authentication#api-keys)

`ApiKeyProvider` takes these options in `super()`. See [Issue API keys to partners](/security/authentication#issue-api-keys-to-partners).

| Option   | Default  | Description                                                                                                |
| -------- | -------- | ---------------------------------------------------------------------------------------------------------- |
| `prefix` | required | Starts every key, as in `cat_<id>_<secret>`: 1 to 16 lowercase letters and digits, starting with a letter. |
| `realm`  | `api`    | The realm in the `WWW-Authenticate` challenge.                                                             |

Your subclass implements `findKey(id)`, which returns the key's stored `hash`, its `user` and its `expiresAt`, or `null` for a key that doesn't exist, was revoked, or whose owner is gone. `generate()` returns a new key as `key`, shown once, with the `id` and `hash` to store. For a request made with a key, the session is the key's `keyId` and `expiresAt`, with `method` set to `api-key`.

##### Events[#](/security/authentication#events)

`AuthenticationEvents` publishes each event on its `events$` observable, and on the `nestjs:authentication:<type>` diagnostics channel, such as `nestjs:authentication:sign-in`.

| Type                       | Payload                                                                   | When                                                                                                   |
| -------------------------- | ------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------ |
| `sign-in`                  | `userId`, `sessionId` or `tokenFamilyId`, `method`, `mfa`, `metadata`     | `SignInService.signIn()` or `TokenService.issue()` signed a user in                                    |
| `sign-out`                 | `userId`, `sessionId`, `tokenFamilyId` or `everywhere`                    | A session, a refresh-token family, or all of them ended                                                |
| `mfa-verified`             | `userId`, `method` (`totp` or `recovery-code`)                            | A code was accepted                                                                                    |
| `mfa-failed`               | `userId`, `method`, `failures`, `locked`                                  | A code was refused, including during a lockout                                                         |
| `mfa-enabled`              | `userId`, `replaced`                                                      | An authenticator was confirmed                                                                         |
| `mfa-disabled`             | `userId`                                                                  | The authenticator and recovery codes were removed                                                      |
| `recovery-codes-generated` | `userId`, `count`                                                         | A new batch of recovery codes replaced the old one                                                     |
| `refresh-token-reused`     | `userId`, `tokenFamilyId`                                                 | A spent refresh token came back, and its family was revoked                                            |
| `password-reset-requested` | `email`, `userId` (absent for an unknown address)                         | Someone asked for a reset link                                                                         |
| `password-reset`           | `userId`                                                                  | A reset link set a new password                                                                        |
| `email-verified`           | `userId`, `email`                                                         | A verification link was used                                                                           |
| `magic-link-refused`       | `reason` (`not-this-browser`, `unknown`, `expired` or `refused`), `email` | A magic link signed nobody in                                                                          |
| `session-touch-failed`     | `userId`, `sessionId`, `error`                                            | `SessionStore.touchSession()` failed; the request went on, and the session's idle deadline didn't move |

##### Errors[#](/security/authentication#errors)

`AuthenticationError` is the base class of the package's errors. It carries `status`, and optionally `code`, `details` and `challenge` (the `WWW-Authenticate` header). Thrown from a handler or anything it calls, it becomes Nest's own HTTP exception, GraphQL `UNAUTHENTICATED`, a `WsException` or an `RpcException`. Its `code` is Nest's `errorCode`. Over HTTP and GraphQL it is set on the exception, so an exception filter reads `exception.errorCode`, and Nest puts it in the body, or in `extensions.originalError` for GraphQL. The ws and rpc payloads carry the same `errorCode` key. A refusal with a message also sends the code as `error`, as it always has. `details`, a plain object, is sent as `details`, as is; nothing else of the error (`cause`, the stack) reaches the client. For example, `new AuthenticationError('Too many attempts', options)` with `too_many_attempts` as the `code` and `retryAfter: 30` in `details` answers:

```json

{"message":"Too many attempts","error":"too_many_attempts","statusCode":401,"errorCode":"too_many_attempts","details":{"retryAfter":30}}
```

| Error                     | Status | `errorCode`        | `error`                                                      | When                                                                                                                       |
| ------------------------- | ------ | ------------------ | ------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------- |
| `AuthenticationError`     | 401    | its `code`, if any | its `code`; else `Unauthorized` with a message, none without | Bad credentials, or `requireUser()` without a user (no message, no code)                                                   |
| `JwtError`                | 401    | none               | `Unauthorized`                                               | A token is malformed, badly signed, expired, or for another issuer or audience                                             |
| `RefreshTokenError`       | 401    | none               | `Unauthorized`                                               | A refresh token is invalid, expired or reused; `reason` says which                                                         |
| `MagicLinkError`          | 401    | `not_this_browser` | `not_this_browser`                                           | A magic link was opened in another browser than the one that requested it, or after that browser requested five newer ones |
| `MfaAlreadyEnrolledError` | 409    | none               | `Conflict`                                                   | `enroll()` without `replace: true` for a user with a confirmed authenticator                                               |

When no provider recognises any credentials, the guard answers 401 with `missing_credentials`, and no `error`:

```json

{"message":"Unauthorized","statusCode":401,"errorCode":"missing_credentials"}
```

That covers a request without credentials, a stale or unknown session cookie (which counts as none, so optional routes keep working), and credentials that a route's `providers` doesn't accept. The guard and `TokenService.issue()` also answer 401 with `mfa_required` while a second factor is missing, and 403 with `email_unverified` on `verifiedEmail` routes, each as both `errorCode` and `error`. The OIDC routes answer 400 for a bad or forged callback, 401 when the provider's answer fails verification or a link flow has no signed-in session, 403 when the resolver refuses the account or a link flow is started from another site, 404 for a provider name that isn't configured, and 502 when the provider can't be reached or is misconfigured, such as an endpoint that isn't https or a key set that can't be loaded. `SignInService.signIn()` and `MagicLinkService.create()` answer 403 to a request posted from another origin.

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/security/authentication.md)

----
url: https://docs.nestjs.com/v9/openapi/security
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Security](https://docs.nestjs.com/v9/openapi/security#security)
* [Basic authentication](https://docs.nestjs.com/v9/openapi/security#basic-authentication)
* [Bearer authentication](https://docs.nestjs.com/v9/openapi/security#bearer-authentication)
* [OAuth2 authentication](https://docs.nestjs.com/v9/openapi/security#oauth2-authentication)
* [Cookie authentication](https://docs.nestjs.com/v9/openapi/security#cookie-authentication)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/openapi/security.md "Suggest Edits")

### Security

To define which security mechanisms should be used for a specific operation, use the `@ApiSecurity()` decorator.

```typescript

@ApiSecurity('basic')
@Controller('cats')
export class CatsController {}
```

Before you run your application, remember to add the security definition to your base document using `DocumentBuilder`:

```typescript

const options = new DocumentBuilder().addSecurity('basic', {
  type: 'http',
  scheme: 'basic',
});
```

Some of the most popular authentication techniques are built-in (e.g., `basic` and `bearer`) and therefore you don't have to define security mechanisms manually as shown above.

#### Basic authentication

To enable basic authentication, use `@ApiBasicAuth()`.

```typescript

@ApiBasicAuth()
@Controller('cats')
export class CatsController {}
```

Before you run your application, remember to add the security definition to your base document using `DocumentBuilder`:

```typescript

const options = new DocumentBuilder().addBasicAuth();
```

#### Bearer authentication

To enable bearer authentication, use `@ApiBearerAuth()`.

```typescript

@ApiBearerAuth()
@Controller('cats')
export class CatsController {}
```

Before you run your application, remember to add the security definition to your base document using `DocumentBuilder`:

```typescript

const options = new DocumentBuilder().addBearerAuth();
```

#### OAuth2 authentication

To enable OAuth2, use `@ApiOAuth2()`.

```typescript

@ApiOAuth2(['pets:write'])
@Controller('cats')
export class CatsController {}
```

Before you run your application, remember to add the security definition to your base document using `DocumentBuilder`:

```typescript

const options = new DocumentBuilder().addOAuth2();
```

#### Cookie authentication

To enable cookie authentication, use `@ApiCookieAuth()`.

```typescript

@ApiCookieAuth()
@Controller('cats')
export class CatsController {}
```

Before you run your application, remember to add the security definition to your base document using `DocumentBuilder`:

```typescript

const options = new DocumentBuilder().addCookieAuth('optional-session-id');
```

----
url: https://docs.nestjs.com/v8/openapi/types-and-parameters
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Types and parameters](https://docs.nestjs.com/v8/openapi/types-and-parameters#types-and-parameters)
* [Arrays](https://docs.nestjs.com/v8/openapi/types-and-parameters#arrays)
* [Circular dependencies](https://docs.nestjs.com/v8/openapi/types-and-parameters#circular-dependencies)
* [Generics and interfaces](https://docs.nestjs.com/v8/openapi/types-and-parameters#generics-and-interfaces)
* [Enums](https://docs.nestjs.com/v8/openapi/types-and-parameters#enums)
* [Enums schema](https://docs.nestjs.com/v8/openapi/types-and-parameters#enums-schema)
* [Raw definitions](https://docs.nestjs.com/v8/openapi/types-and-parameters#raw-definitions)
* [Extra models](https://docs.nestjs.com/v8/openapi/types-and-parameters#extra-models)
* [oneOf, anyOf, allOf](https://docs.nestjs.com/v8/openapi/types-and-parameters#oneof-anyof-allof)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/openapi/types-and-parameters.md "Suggest Edits")

### 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:

```typescript

@Post()
async create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

> **Hint** To explicitly set the body definition use the `@ApiBody()` decorator (imported from the `@nestjs/swagger` package).

Based on the `CreateCatDto`, the following model definition Swagger UI will be created:

As you can see, the definition is empty although the class has a few declared properties. In order to make the class properties visible to the `SwaggerModule`, we have to either annotate them with the `@ApiProperty()` decorator or use the CLI plugin (read more in the **Plugin** section) which will do it automatically:

```typescript

import { ApiProperty } from '@nestjs/swagger';

export class CreateCatDto {
  @ApiProperty()
  name: string;

  @ApiProperty()
  age: number;

  @ApiProperty()
  breed: string;
}
```

> **Hint** Instead of manually annotating each property, consider using the Swagger plugin (see [Plugin](/v8/openapi/cli-plugin) section) which will automatically provide this for you.

Let's open the browser and verify the generated `CreateCatDto` model:

In addition, the `@ApiProperty()` decorator allows setting various [Schema Object](https://swagger.io/specification/#schemaObject) properties:

```typescript

@ApiProperty({
  description: 'The age of a cat',
  minimum: 1,
  default: 1,
})
age: number;
```

> **Hint** Instead of explicitly typing the `@ApiProperty({ required: false })` you can use the `@ApiPropertyOptional()` short-hand decorator.

In order to explicitly set the type of the property, use the `type` key:

```typescript

@ApiProperty({
  type: Number,
})
age: number;
```

#### Arrays[#](/openapi/types-and-parameters#arrays)

When the property is an array, we must manually indicate the array type as shown below:

```typescript

@ApiProperty({ type: [String] })
names: string[];
```

> **Hint** Consider using the Swagger plugin (see [Plugin](/v8/openapi/cli-plugin) section) which will automatically detect arrays.

```typescript

@ApiProperty({ type: () => Node })
node: Node;
```

> **Hint** Consider using the Swagger plugin (see [Plugin](/v8/openapi/cli-plugin) section) which will automatically detect circular dependencies.

#### Generics and interfaces[#](/openapi/types-and-parameters#generics-and-interfaces)

Since TypeScript does not store metadata about generics or interfaces, when you use them in your DTOs, `SwaggerModule` may not be able to properly generate model definitions at runtime. For instance, the following code won't be correctly inspected by the Swagger module:

```typescript

createBulk(@Body() usersDto: CreateUserDto[])
```

In order to overcome this limitation, you can set the type explicitly:

```typescript

@ApiBody({ type: [CreateUserDto] })
createBulk(@Body() usersDto: CreateUserDto[])
```

#### Enums[#](/openapi/types-and-parameters#enums)

To identify an `enum`, we must manually set the `enum` property on the `@ApiProperty` with an array of values.

```typescript

@ApiProperty({ enum: ['Admin', 'Moderator', 'User']})
role: UserRole;
```

Alternatively, define an actual TypeScript enum as follows:

```typescript

export enum UserRole {
  Admin = 'Admin',
  Moderator = 'Moderator',
  User = 'User',
}
```

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

```typescript

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

With `isArray` set to **true**, the `enum` can be selected as a **multi-select**:

#### Enums schema[#](/openapi/types-and-parameters#enums-schema)

By default, the `enum` property will add a raw definition of [Enum](https://swagger.io/docs/specification/data-models/enums/) on the `parameter`.

```yaml

- breed:
    type: 'string'
    enum:
      - Persian
      - Tabby
      - Siamese
```

The above specification works fine for most cases. However, if you are utilizing a tool that takes the specification as **input** and generates **client-side** code, you might run into a problem with the generated code containing duplicated `enums`. Consider the following code snippet:

```typescript

// generated client-side code
export class CatDetail {
  breed: CatDetailEnum;
}

export class CatInformation {
  breed: CatInformationEnum;
}

export enum CatDetailEnum {
  Persian = 'Persian',
  Tabby = 'Tabby',
  Siamese = 'Siamese',
}

export enum CatInformationEnum {
  Persian = 'Persian',
  Tabby = 'Tabby',
  Siamese = 'Siamese',
}
```

> **Hint** The above snippet is generated using a tool called [NSwag](https://github.com/RicoSuter/NSwag).

You can see that now you have two `enums` that are exactly the same. To address this issue, you can pass an `enumName` along with the `enum` property in your decorator.

```typescript

export class CatDetail {
  @ApiProperty({ enum: CatBreed, enumName: 'CatBreed' })
  breed: CatBreed;
}
```

The `enumName` property enables `@nestjs/swagger` to turn `CatBreed` into its own `schema` which in turns makes `CatBreed` enum reusable. The specification will look like the following:

```yaml

CatDetail:
  type: 'object'
  properties:
    ...
    - breed:
        schema:
          $ref: '#/components/schemas/CatBreed'
CatBreed:
  type: string
  enum:
    - Persian
    - Tabby
    - Siamese
```

> **Hint** Any **decorator** that takes `enum` as a property will also take `enumName`.

#### Raw definitions[#](/openapi/types-and-parameters#raw-definitions)

In some specific scenarios (e.g., deeply nested arrays, matrices), you may want to describe your type by hand.

```typescript

@ApiProperty({
  type: 'array',
  items: {
    type: 'array',
    items: {
      type: 'number',
    },
  },
})
coords: number[][];
```

Likewise, in order to define your input/output content manually in controller classes, use the `schema` property:

```typescript

@ApiBody({
  schema: {
    type: 'array',
    items: {
      type: 'array',
      items: {
        type: 'number',
      },
    },
  },
})
async create(@Body() coords: number[][]) {}
```

#### Extra models[#](/openapi/types-and-parameters#extra-models)

To define additional models that are not directly referenced in your controllers but should be inspected by the Swagger module, use the `@ApiExtraModels()` decorator:

```typescript

@ApiExtraModels(ExtraModel)
export class CreateCatDto {}
```

> **Hint** You only need to use `@ApiExtraModels()` once for a specific model class.

Alternatively, you can pass an options object with the `extraModels` property specified to the `SwaggerModule#createDocument()` method, as follows:

```typescript

const document = SwaggerModule.createDocument(app, options, {
  extraModels: [ExtraModel],
});
```

To get a reference (`$ref`) to your model, use the `getSchemaPath(ExtraModel)` function:

```typescript

'application/vnd.api+json': {
   schema: { $ref: getSchemaPath(ExtraModel) },
},
```

#### oneOf, anyOf, allOf[#](/openapi/types-and-parameters#oneof-anyof-allof)

To combine schemas, you can use the `oneOf`, `anyOf` or `allOf` keywords ([read more](https://swagger.io/docs/specification/data-models/oneof-anyof-allof-not/)).

```typescript

@ApiProperty({
  oneOf: [
    { $ref: getSchemaPath(Cat) },
    { $ref: getSchemaPath(Dog) },
  ],
})
pet: Cat | Dog;
```

If you want to define a polymorphic array (i.e., an array whose members span multiple schemas), you should use a raw definition (see above) to define your type by hand.

```typescript

type Pet = Cat | Dog;

@ApiProperty({
  type: 'array',
  items: {
    oneOf: [
      { $ref: getSchemaPath(Cat) },
      { $ref: getSchemaPath(Dog) },
    ],
  },
})
pets: Pet[];
```

> **Hint** The `getSchemaPath()` function is imported from `@nestjs/swagger`.

Both `Cat` and `Dog` must be defined as extra models using the `@ApiExtraModels()` decorator (at the class-level).

----
url: https://docs.nestjs.com/v7/microservices/guards
----

* [Guards](https://docs.nestjs.com/v7/microservices/guards#guards)
* [Binding guards](https://docs.nestjs.com/v7/microservices/guards#binding-guards)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/microservices/guards.md "Suggest Edits")

### Guards

There is no fundamental difference between microservices guards and [regular HTTP application guards](/v7/guards). The only difference is that instead of throwing `HttpException`, you should use `RpcException`.

> **Hint** The `RpcException` class is exposed from `@nestjs/microservices` package.

#### Binding guards[#](/microservices/guards#binding-guards)

The following example uses a method-scoped guard. Just as with HTTP based applications, you can also use controller-scoped guards (i.e., prefix the controller class with a `@UseGuards()` decorator).

JS TS

```typescript

@UseGuards(AuthGuard)
@MessagePattern({ cmd: 'sum' })
accumulate(data: number[]): number {
  return (data || []).reduce((a, b) => a + b);
}
```

```typescript

@UseGuards(AuthGuard)
@MessagePattern({ cmd: 'sum' })
accumulate(data) {
  return (data || []).reduce((a, b) => a + b);
}
```

----
url: https://docs.nestjs.com/observability/distributed-tracing
----

[Skip to content](#content)

On this page

* [Distributed tracing](https://docs.nestjs.com/observability/distributed-tracing#distributed-tracing)
* [Reading the current trace id](https://docs.nestjs.com/observability/distributed-tracing#reading-the-current-trace-id)
* [HTTP to HTTP](https://docs.nestjs.com/observability/distributed-tracing#http-to-http)
* [gRPC](https://docs.nestjs.com/observability/distributed-tracing#grpc)
* [TCP, Redis, NATS, and other microservice transports](https://docs.nestjs.com/observability/distributed-tracing#tcp-redis-nats-and-other-microservice-transports)
* [GraphQL](https://docs.nestjs.com/observability/distributed-tracing#graphql)
* [Queue jobs (BullMQ and Bull)](https://docs.nestjs.com/observability/distributed-tracing#queue-jobs-bullmq-and-bull)
* [What a trace looks like in the dashboard](https://docs.nestjs.com/observability/distributed-tracing#what-a-trace-looks-like-in-the-dashboard)

### Distributed tracing

A **trace** is everything your applications recorded under a single trace id: the request or job that started it, and every span underneath. Within a single service this is automatic. The SDK generates a trace id when work starts, and every span underneath, including ones you add manually with [`TracerService`](/observability/manual-instrumentation), inherits it.

Across services, it depends on the channel. HTTP calls, queue jobs, and (on `@nestjs/microservices` 12.0.4 or later) the TCP and Redis transports carry the trace id on their own; gRPC and the other microservice transports need it forwarded. A single user action that touches more than one service (an API call that fans out to a gRPC service, or a message sent to another application over a microservice transport) shows up as **one trace** in your dashboard only if every service involved uses the same trace id. Otherwise, each service mints its own via `traceIdGenerator`, and the action shows up as several disconnected traces, one per service.

Where forwarding is needed, it is application code, not a dashboard setting, and the pattern is always the same: the caller puts its current trace id on whatever channel the protocol has, and the callee's `traceIdGenerator` reads it back out. This page shows how for each transport.

#### Reading the current trace id[#](/observability/distributed-tracing#reading-the-current-trace-id)

To forward a trace id downstream, a service first reads the one it's currently running under. `TracerService.currentTraceId()` returns it:

orders.service.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { TracerService } from '@nestjs/observe';

@Injectable()
export class OrdersService {
  constructor(private readonly tracerService: TracerService) {}

  async report(orderId: string) {
    const traceId = this.tracerService.currentTraceId();
    // ...forward traceId to the next service
  }
}
```

It reads from the same context store as `getAttribute()`/`setAttribute()`, but unlike those it doesn't throw outside a traced context. It returns `null` instead, so code that forwards a trace id from startup hooks or other untraced paths doesn't need a `try`/`catch`. If your code can run outside a trace, check for `null` before setting a header.

#### HTTP to HTTP[#](/observability/distributed-tracing#http-to-http)

HTTP propagation is automatic in both directions. On the way in, the default `traceIdGenerator` adopts a well-formed `x-request-id` header and otherwise mints a time-ordered UUID (v7). On the way out, the SDK adds the current trace id as `x-request-id` to outbound requests that don't already carry one, so a call from one instrumented service to another lands in the same trace with no application code.

Outbound propagation covers `fetch` and `undici`, including the [HTTP client](/application/http-client), on every supported Node version, and clients built on `node:http` (axios, got, `@nestjs/axios`) on Node 22.12 and later, the first release that lets a header be added after the request object is created. To limit which hosts receive the header, or switch it off, see [`outgoing.http.propagateTraceId`](/observability/sdk#database-queries-and-outbound-http).

On an older Node version with an axios-based client, register a request interceptor once to forward the id yourself:

orders.module.ts

JS TS

```typescript

@Module({
  imports: [HttpModule],
})
export class OrdersModule implements OnModuleInit {
  constructor(
    private readonly httpService: HttpService,
    private readonly tracerService: TracerService,
  ) {}

  onModuleInit() {
    this.httpService.axiosRef.interceptors.request.use((config) => {
      config.headers['x-request-id'] = this.tracerService.currentTraceId();
      return config;
    });
  }
}
```

> **Hint** Many reverse proxies and load balancers (nginx, Envoy, AWS ALB) can set `x-request-id` on every inbound request. When they do, the trace id in your dashboard matches the request id in your proxy's access logs.

#### gRPC[#](/observability/distributed-tracing#grpc)

gRPC has no headers, only metadata. The caller attaches the trace id as metadata, and the gRPC service overrides `traceIdGenerator` to read it back out, since the default generator doesn't read gRPC metadata:

caller.ts

JS TS

```typescript

import { Metadata } from '@grpc/grpc-js';

const metadata = new Metadata();
const traceId = this.tracerService.currentTraceId();
if (traceId) {
  metadata.set('x-request-id', traceId);
}
this.heroesService.findOne({ id: 1 }, metadata);
```

app.module.ts

JS TS

```typescript

import { randomUUID } from 'node:crypto';

// gRPC service - passed to createObserveModule(), not forRoot()
export const { ObserveModule, ObserveInstrument } = createObserveModule({
  traceIdGenerator: (call: any) => {
    const inbound = call.metadata?.get?.('x-request-id')?.[0];
    return typeof inbound === 'string' && inbound.length > 0
      ? inbound
      : randomUUID(); // no id was propagated - this call started its own trace
  },
});
```

See the [gRPC](/microservices/grpc) chapter for how metadata is read and written on both sides of a call.

#### TCP, Redis, NATS, and other microservice transports[#](/observability/distributed-tracing#tcp-redis-nats-and-other-microservice-transports)

On `@nestjs/microservices` 12.0.4 or later, the TCP and Redis transports carry packet metadata, and `@nestjs/observe` 0.3.0 or later uses it. The SDK attaches the current trace id to every packet sent through a `ClientProxy` registered as a provider (e.g., with `ClientsModule`), and the default `traceIdGenerator` on the receiving side adopts it, so no application code is needed.

The other transports, and TCP and Redis on earlier versions, have no metadata channel, only a message payload. There, the trace id has to travel as a field inside the payload itself:

caller.ts

JS TS

```typescript

this.client.send('orders.report', {
  ...payload,
  traceId: this.tracerService.currentTraceId(),
});
```

app.module.ts

JS TS

```typescript

import { randomUUID } from 'node:crypto';

// receiving service
export const { ObserveModule, ObserveInstrument } = createObserveModule({
  traceIdGenerator: (ctx: any) => ctx.getData()?.traceId ?? randomUUID(),
});
```

The generator receives the transport's context object, so the same code works for request-response (`send()`) and event-based (`emit()`) messages.

> **Warning** The same `traceIdGenerator` is called with HTTP requests and RPC contexts alike. In a [hybrid application](/faq/hybrid-application) that serves both HTTP and a microservice transport, write the generator defensively: check for `headers` first, then fall back to the payload.

#### GraphQL[#](/observability/distributed-tracing#graphql)

No extra configuration is needed when the GraphQL server sits behind the same service's HTTP layer. It joins whatever trace the HTTP agent already opened for that request, which may itself have been propagated via `x-request-id` as described above. Only operations with no enclosing HTTP trace, such as a subscription over a raw WebSocket, need separate handling, and there's currently no built-in propagation hook for that case.

#### Queue jobs (BullMQ and Bull)[#](/observability/distributed-tracing#queue-jobs-bullmq-and-bull)

Queue propagation is automatic. When a job is added from inside a traced operation (a request handler, an RPC handler, another job), the SDK stamps the current trace id onto the job's options, and the processor that picks the job up runs under that id instead of minting its own. The request and every job it enqueued render as one trace, with no application code involved:

orders.controller.ts

JS TS

```typescript

@Post()
async create(@Body() dto: CreateOrderDto) {
  const order = await this.ordersService.create(dto);
  // The job inherits this request's trace id
  await this.ordersQueue.add('send-confirmation', { orderId: order.id });
  return order;
}
```

This works the same way for `@nestjs/bullmq` and `@nestjs/bull`, for `add()` and `addBulk()`, and whether the worker runs in the same process as the producer or in a separate service: the id travels through Redis with the job. A retried job keeps the id it was enqueued with, so every attempt lands in the same trace.

Two cases deliberately start a trace of their own:

* **Repeatable jobs and `@nestjs/schedule` handlers.** A schedule outlives the operation that registered it, so each firing is its own trace rather than part of an ever-growing trace attached to whichever request set the schedule up.
* **Jobs added outside any traced operation**, e.g., from a bootstrap hook or a plain script. There is no trace to inherit.

> **Hint** The trace id is stored under the `observeTraceId` job option. To attach a job to a trace the SDK did not see (e.g., one enqueued by a non-Nest producer), set that option yourself when adding the job.

> **Warning** Trace inheritance for jobs requires `@nestjs/observe` 0.3.0 or later on **both** the service that adds the job and the service that processes it. With an older producer, jobs carry no id and each run opens its own trace, as before.

#### What a trace looks like in the dashboard[#](/observability/distributed-tracing#what-a-trace-looks-like-in-the-dashboard)

Once services agree on a trace id, the trace detail page renders every execution that ran under it, across services, requests, and jobs, as one waterfall: nesting depth as indentation, duration as bar length, and horizontal position as when the span ran. When reading it, keep the following in mind:

* **Self time** is the number that matters. A span's duration minus the time its children account for is the time the span spent in its own code. Ranking by total duration always puts the controller at the top (it contains everything); ranking by self time surfaces the repository call that actually burned the time. Every execution page carries a spans table sorted this way.
* **Overlapping children are flagged.** When a span's children sum to more than the span's own duration, they ran concurrently (`Promise.all`, a parallel fan-out) and the row says so.
* **Failing spans are marked**, and the execution page leads with an error card for the first span that threw - class, message, the trimmed stack trace with the throwing frame marked, and the source lines around it when [`sourceContext`](/observability/sdk#error-source-context) is on.
* **Logs sit on the trace's clock.** With `forwardLogs` enabled, each line is placed at its offset from the start of the trace and labeled with the span that was in flight when it was written; hovering a line marks that instant on the waterfall.

From any failed or unusually slow execution, the **Copy agent prompt** button packages the whole page (context, error, stack trace with source, top spans by self time, and logs) as a self-contained markdown prompt for a coding agent. See [Dashboard](/observability/dashboard#handing-a-failure-to-a-coding-agent).

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/observability/distributed-tracing.md)

----
url: https://docs.nestjs.com/recipes/crud-generator
----

[Skip to content](#content)

On this page

* [CRUD generator (TypeScript only)](https://docs.nestjs.com/recipes/crud-generator#crud-generator-typescript-only)
* [Introduction](https://docs.nestjs.com/recipes/crud-generator#introduction)
* [Generating a new resource](https://docs.nestjs.com/recipes/crud-generator#generating-a-new-resource)

[](https://srv.carbonads.net/ads/click/x/GTND4277CVSIC2JEFTBLYKQUF67D62JIF6YDTZ3JCAAI6KQJCABI4K3KC67DK5QLCEYDV53JFTSDK27IFTYDCKQYHEYI55QLCAYD653ECTNCYBZ52K)[Architectural guidance, code that runs. Free, for all levels. Start building ](https://srv.carbonads.net/ads/click/x/GTND4277CVSIC2JEFTBLYKQUF67D62JIF6YDTZ3JCAAI6KQJCABI4K3KC67DK5QLCEYDV53JFTSDK27IFTYDCKQYHEYI55QLCAYD653ECTNCYBZ52K)[ads via Carbon](http://carbonads.net/?utm_source=nestjscom\&utm_medium=ad_via_link\&utm_campaign=in_unit\&utm_term=carbon)

### CRUD generator (TypeScript only)

Over the lifespan of a project, building new features often means adding new resources to the application. Each new resource typically requires the same set of repetitive operations.

#### Introduction[#](/recipes/crud-generator#introduction)

Consider a real-world scenario in which you need to expose CRUD endpoints for two entities, **User** and **Product**. Following best practices, you would have to perform several operations for each entity:

* Generate a module (`nest g mo`) to keep code organized and establish clear boundaries (grouping related components)
* Generate a controller (`nest g co`) to define CRUD routes (or queries/mutations for GraphQL applications)
* Generate a service (`nest g s`) to implement and isolate business logic
* Generate an entity class/interface to represent the resource data shape
* Generate Data Transfer Objects (or inputs for GraphQL applications) to define how the data will be sent over the network

To speed up this repetitive process, the [Nest CLI](/cli/overview) provides a generator (schematic) that generates all of this boilerplate code automatically.

> **Note** The schematic supports generating **HTTP** controllers, **Microservice** controllers, **GraphQL** resolvers (both code first and schema first), and **WebSocket** Gateways.

#### Generating a new resource[#](/recipes/crud-generator#generating-a-new-resource)

To create a new resource, run the following command in the root directory of your project:

```shell

$ nest g resource
```

The `nest g resource` command generates not only the NestJS building blocks (module, service, and controller classes), but also an entity class, DTO classes, and the test (`.spec`) files.

Here's the generated controller file (for a REST API):

```typescript

@Controller('users')
export class UsersController {
  constructor(private readonly usersService: UsersService) {}

  @Post()
  create(@Body() createUserDto: CreateUserDto) {
    return this.usersService.create(createUserDto);
  }

  @Get()
  findAll() {
    return this.usersService.findAll();
  }

  @Get(':id')
  findOne(@Param('id') id: string) {
    return this.usersService.findOne(+id);
  }

  @Patch(':id')
  update(@Param('id') id: string, @Body() updateUserDto: UpdateUserDto) {
    return this.usersService.update(+id, updateUserDto);
  }

  @Delete(':id')
  remove(@Param('id') id: string) {
    return this.usersService.remove(+id);
  }
}
```

The command also creates placeholders for all the CRUD endpoints: routes for REST APIs, queries and mutations for GraphQL, and message handlers for both microservices and WebSocket gateways.

> **Note** Generated service classes are **not** tied to any specific **ORM (or data source)**, which makes the generator generic enough to meet the needs of any project. By default, all methods contain placeholders that you can populate with the data sources specific to your project.

Likewise, to generate resolvers for a GraphQL application, select `GraphQL (code first)` (or `GraphQL (schema first)`) as your transport layer.

In this case, Nest generates a resolver class instead of a REST API controller:

```shell

$ nest g resource users

> ? What transport layer do you use? GraphQL (code first)
> ? Would you like to generate CRUD entry points? Yes
> CREATE src/users/users.module.ts (224 bytes)
> CREATE src/users/users.resolver.spec.ts (525 bytes)
> CREATE src/users/users.resolver.ts (1109 bytes)
> CREATE src/users/users.service.spec.ts (453 bytes)
> CREATE src/users/users.service.ts (625 bytes)
> CREATE src/users/dto/create-user.input.ts (195 bytes)
> CREATE src/users/dto/update-user.input.ts (281 bytes)
> CREATE src/users/entities/user.entity.ts (187 bytes)
> UPDATE src/app.module.ts (312 bytes)
```

> **Hint** To skip generating test files, pass the `--no-spec` flag, as follows: `nest g resource users --no-spec`.

As shown below, the command not only creates all the boilerplate mutations and queries, but also wires everything together, using the `UsersService`, the `User` entity, and the DTOs.

```typescript

import { Resolver, Query, Mutation, Args, Int } from '@nestjs/graphql';
import { UsersService } from './users.service.js';
import { User } from './entities/user.entity.js';
import { CreateUserInput } from './dto/create-user.input.js';
import { UpdateUserInput } from './dto/update-user.input.js';

@Resolver(() => User)
export class UsersResolver {
  constructor(private readonly usersService: UsersService) {}

  @Mutation(() => User)
  createUser(@Args('createUserInput') createUserInput: CreateUserInput) {
    return this.usersService.create(createUserInput);
  }

  @Query(() => [User], { name: 'users' })
  findAll() {
    return this.usersService.findAll();
  }

  @Query(() => User, { name: 'user' })
  findOne(@Args('id', { type: () => Int }) id: number) {
    return this.usersService.findOne(id);
  }

  @Mutation(() => User)
  updateUser(@Args('updateUserInput') updateUserInput: UpdateUserInput) {
    return this.usersService.update(updateUserInput.id, updateUserInput);
  }

  @Mutation(() => User)
  removeUser(@Args('id', { type: () => Int }) id: number) {
    return this.usersService.remove(id);
  }
}
```

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/recipes/crud-generator.md)

----
url: https://docs.nestjs.com/v5/techniques/mongodb
----

### Mongo

There are two ways of dealing with the MongoDB database. You can either use an [ORM](https://github.com/typeorm/typeorm) that provides a MongoDB support or [Mongoose](http://mongoosejs.com) which is the most popular [MongoDB](https://www.mongodb.org/) object modeling tool. If you wanna stay with the **ORM** you can follow [these steps](/v5/techniques/sql). Otherwise, we'll use the dedicated `@nestjs/mongoose` package.

Firstly, we need to install all of the required dependencies:

```bash

$ npm install --save @nestjs/mongoose mongoose
```

Once the installation process is completed, we can import the `MongooseModule` into the root `ApplicationModule`.

app.module.ts

JS TS

TypeScript

```typescript

import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';

@Module({
  imports: [MongooseModule.forRoot('mongodb://localhost/nest')],
})
export class ApplicationModule {}
```

The `forRoot()` method accepts the same configuration object as `mongoose.connect()` from the [Mongoose](http://mongoosejs.com) package.

#### Model injection

With Mongoose, everything is derived from a [Schema](http://mongoosejs.com/docs/guide.html). Let's define the `CatSchema`:

cats/schemas/cat.schema.ts

JS TS

TypeScript

```typescript

import * as mongoose from 'mongoose';

export const CatSchema = new mongoose.Schema({
  name: String,
  age: Number,
  breed: String,
});
```

The `CatsSchema` belongs to the `cats` directory. This directory represents the `CatsModule`. It's your decision where you gonna keep your schema files. From our point of view, the best way's to hold them nearly their **domain**, in the appropriate module directory.

Let's have a look at the `CatsModule`:

cats/cats.module.ts

JS TS

TypeScript

```typescript

import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';
import { CatSchema } from './schemas/cat.schema';

@Module({
  imports: [MongooseModule.forFeature([{ name: 'Cat', schema: CatSchema }])],
  controllers: [CatsController],
  providers: [CatsService],
})
export class CatsModule {}
```

This module uses `forFeature()` method to define which models shall be registered in the current scope. Thanks to that, we can inject the `CatModel` to the `CatsService` using the `@InjectModel()` decorator:

cats/cats.service.ts

JS TS

TypeScript

```typescript

import { Model } from 'mongoose';
import { Injectable } from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import { Cat } from './interfaces/cat.interface';
import { CreateCatDto } from './dto/create-cat.dto';

@Injectable()
export class CatsService {
  constructor(@InjectModel('Cat') private readonly catModel: Model<Cat>) {}

  async create(createCatDto: CreateCatDto): Promise<Cat> {
    const createdCat = new this.catModel(createCatDto);
    return await createdCat.save();
  }

  async findAll(): Promise<Cat[]> {
    return await this.catModel.find().exec();
  }
}
```

TypeScript

```typescript

import { Model } from 'mongoose';
import { Injectable, Dependencies } from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import { CatSchema } from './schemas/cat.schema';

@Injectable()
@Dependencies(InjectModel(CatSchema))
export class CatsService {
  constructor(catModel) {
    this.catModel = catModel;
  }

  async create(createCatDto) {
    const createdCat = new this.catModel(createCatDto);
    return await createdCat.save();
  }

  async findAll() {
    return await this.catModel.find().exec();
  }
}
```

#### Testing

When it comes to unit test our application, we usually want to avoid any database connection, making our test suits independent and their execution process quick as possible. But our classes might depend on models that are pulled from the connection instance. What's then? The solution is to create fake models. In order to achieve that, we should set up [custom providers ](/v5/fundamentals/custom-providers). In fact, each registered model is represented by `NameModel` token, where `Name` is a model's name.

The `@nestjs/mongoose` package exposes `getModelToken()` function that returns prepared token based on a given model's name.

TypeScript

```typescript

@Module({
  providers: [
    CatsService,
    {
      provide: getModelToken('Cat'),
      useValue: catModel,
    },
  ],
})
export class CatsModule {}
```

Now a hardcoded `catModel` will be used as a `Model<Cat>`. Whenever any provider asks for `Model<Cat>` using an `@InjectModel()` decorator, Nest will use a registered `catModel` object.

#### Async configuration

Quite often you might want to asynchronously pass your module options instead of passing them beforehand. In such case, use `forRootAsync()` method, that provides a couple of various ways to deal with async data.

First possible approach is to use a factory function:

TypeScript

```typescript

MongooseModule.forRootAsync({
  useFactory: () => ({
    uri: 'mongodb://localhost/nest',
  }),
})
```

Obviously, our factory behaves like every other one (might be `async` and is able to inject dependencies through `inject`).

TypeScript

```typescript

MongooseModule.forRootAsync({
  imports: [ConfigModule],
  useFactory: async (configService: ConfigService) => ({
    uri: configService.getString('MONGODB_URI'),
  }),
  inject: [ConfigService],
})
```

Alternatively, you are able to use class instead of a factory.

TypeScript

```typescript

MongooseModule.forRootAsync({
  useClass: MongooseConfigService,
})
```

Above construction will instantiate `MongooseConfigService` inside `MongooseModule` and will leverage it to create options object. The `MongooseConfigService` has to implement `MongooseOptionsFactory` interface.

TypeScript

```typescript

@Injectable()
class MongooseConfigService implements MongooseOptionsFactory {
  createMongooseOptions(): MongooseModuleOptions {
    return {
      uri: 'mongodb://localhost/nest',
    };
  }
}
```

In order to prevent the creation of `MongooseConfigService` inside `MongooseModule` and use a provider imported from a different module, you can use the `useExisting` syntax.

TypeScript

```typescript

MongooseModule.forRootAsync({
  imports: [ConfigModule],
  useExisting: ConfigService,
})
```

It works the same as `useClass` with one critical difference - `MongooseModule` will lookup imported modules to reuse already created `ConfigService`, instead of instantiating it on its own.

#### Example

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/14-mongoose-base).

* Mongo
* Model injection
* Testing

----
url: https://docs.nestjs.com/recipes/passport
----

[Skip to content](#content)

On this page

* [Passport (authentication)](https://docs.nestjs.com/recipes/passport#passport-authentication)
* [Authentication requirements](https://docs.nestjs.com/recipes/passport#authentication-requirements)
* [Implementing Passport strategies](https://docs.nestjs.com/recipes/passport#implementing-passport-strategies)
* [Implementing Passport local](https://docs.nestjs.com/recipes/passport#implementing-passport-local)
* [Built-in Passport Guards](https://docs.nestjs.com/recipes/passport#built-in-passport-guards)
* [Login route](https://docs.nestjs.com/recipes/passport#login-route)
* [Logout route](https://docs.nestjs.com/recipes/passport#logout-route)
* [JWT functionality](https://docs.nestjs.com/recipes/passport#jwt-functionality)
* [Implementing Passport JWT](https://docs.nestjs.com/recipes/passport#implementing-passport-jwt)
* [Implement protected route and JWT strategy guards](https://docs.nestjs.com/recipes/passport#implement-protected-route-and-jwt-strategy-guards)
* [Extending guards](https://docs.nestjs.com/recipes/passport#extending-guards)
* [Enable authentication globally](https://docs.nestjs.com/recipes/passport#enable-authentication-globally)
* [Request-scoped strategies](https://docs.nestjs.com/recipes/passport#request-scoped-strategies)
* [Customize Passport](https://docs.nestjs.com/recipes/passport#customize-passport)
* [Named strategies](https://docs.nestjs.com/recipes/passport#named-strategies)
* [GraphQL](https://docs.nestjs.com/recipes/passport#graphql)

### Passport (authentication)

[Passport](https://github.com/jaredhanson/passport) is the most popular Node.js authentication library, well known in the community and used in many production applications. You can integrate it with a **Nest** application using the `@nestjs/passport` module. At a high level, Passport executes a series of steps to:

* Authenticate a user by verifying their "credentials" (such as username/password, JSON Web Token ([JWT](https://jwt.io/)), or identity token from an Identity Provider)
* Manage authenticated state (by issuing a portable token, such as a JWT, or creating an [Express session](https://github.com/expressjs/session))
* Attach information about the authenticated user to the `Request` object for further use in route handlers

Passport has a rich ecosystem of [strategies](http://www.passportjs.org/) that implement various authentication mechanisms. While simple in concept, the set of Passport strategies to choose from is large and varied. Passport abstracts these varied steps into a standard pattern, and the `@nestjs/passport` module wraps this pattern in familiar Nest constructs.

In this chapter, we'll implement a complete end-to-end authentication solution for a RESTful API server using these modules. You can follow the steps in this chapter to build the complete example, and apply the same concepts to implement any Passport strategy and customize your authentication scheme.

#### Authentication requirements[#](/recipes/passport#authentication-requirements)

For this use case, clients start by authenticating with a username and password. Once authenticated, the server issues a JWT that the client can send as a [bearer token in an authorization header](https://tools.ietf.org/html/rfc6750) on subsequent requests to prove authentication. We'll also create a protected route that is accessible only to requests that contain a valid JWT.

We'll start with the first requirement: authenticating a user. We'll then extend that by issuing a JWT. Finally, we'll create a protected route that checks for a valid JWT on the request.

First, install the required packages. Passport provides a strategy called [passport-local](https://github.com/jaredhanson/passport-local) that implements a username/password authentication mechanism, which suits this part of our use case.

```bash

$ npm install --save @nestjs/passport passport passport-local
$ npm install --save-dev @types/passport-local
```

> **Notice** For **any** Passport strategy you choose, you always need the `@nestjs/passport` and `passport` packages. You also need the strategy-specific package (e.g., `passport-jwt` or `passport-local`) that implements the authentication strategy you are building. You can also install the type definitions for the strategy, as shown above with `@types/passport-local`, to get type checking and editor assistance while writing TypeScript code.

#### Implementing Passport strategies[#](/recipes/passport#implementing-passport-strategies)

We're now ready to implement the authentication feature. We'll start with an overview of the process used for **any** Passport strategy. It's helpful to think of Passport as a mini framework in itself. It abstracts the authentication process into a few basic steps that you customize based on the strategy you're implementing. It's like a framework because you configure it by supplying customization parameters (as plain JSON objects) and custom code in the form of callback functions, which Passport calls at the appropriate time. The `@nestjs/passport` module wraps this framework in a Nest-style package, so that it integrates naturally into a Nest application. We'll use `@nestjs/passport` below, but first, let's consider how **vanilla Passport** works.

In vanilla Passport, you configure a strategy by providing two things:

1. A set of options that are specific to that strategy. For example, in a JWT strategy, you might provide a secret to sign tokens.
2. A "verify callback", which is where you tell Passport how to interact with your user store (where you manage user accounts). Here, you verify whether a user exists (and/or create a new user), and whether their credentials are valid. Passport expects this callback to return a full user if the validation succeeds, or `null` if it fails (failure means either that the user is not found or, in the case of passport-local, that the password does not match).

With `@nestjs/passport`, you configure a Passport strategy by extending the `PassportStrategy` class. You pass the strategy options (item 1 above) by calling `super()` in your subclass's constructor, optionally with an options object. You provide the verify callback (item 2 above) by implementing a `validate()` method in your subclass.

We'll start by generating an `AuthModule` and in it, an `AuthService`:

```bash

$ nest g module auth
$ nest g service auth
```

The `AuthService` will rely on a `UsersService` that encapsulates user operations, so generate that module and service now as well:

```bash

$ nest g module users
$ nest g service users
```

Replace the default contents of these generated files as shown below. In this sample app, `UsersService` keeps a hard-coded, in-memory list of users and exposes a `findOne()` method that looks up a user by username. In a real application, this is where you build your user model and persistence layer with your library of choice (e.g., TypeORM, Sequelize, Mongoose).

users/users.service.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';

// This should be a real class/interface representing a user entity
export type User = any;

@Injectable()
export class UsersService {
  private readonly users = [
    {
      userId: 1,
      username: 'john',
      password: 'changeme',
    },
    {
      userId: 2,
      username: 'maria',
      password: 'guess',
    },
  ];

  async findOne(username: string): Promise<User | undefined> {
    return this.users.find(user => user.username === username);
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';

@Injectable()
export class UsersService {
  constructor() {
    this.users = [
      {
        userId: 1,
        username: 'john',
        password: 'changeme',
      },
      {
        userId: 2,
        username: 'maria',
        password: 'guess',
      },
    ];
  }

  async findOne(username) {
    return this.users.find(user => user.username === username);
  }
}
```

In the `UsersModule`, the only change needed is to add the `UsersService` to the `exports` array of the `@Module()` decorator, so that it's visible outside this module (we'll use it in our `AuthService` shortly).

users/users.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { UsersService } from './users.service.js';

@Module({
  providers: [UsersService],
  exports: [UsersService],
})
export class UsersModule {}
```

```typescript

import { Module } from '@nestjs/common';
import { UsersService } from './users.service.js';

@Module({
  providers: [UsersService],
  exports: [UsersService],
})
export class UsersModule {}
```

Our `AuthService` retrieves a user and verifies the password. We create a `validateUser()` method for this purpose. In the code below, we use object rest syntax to strip the `password` property from the user object before returning it. Our Passport local strategy will call the `validateUser()` method in a moment.

auth/auth.service.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { UsersService } from '../users/users.service.js';

@Injectable()
export class AuthService {
  constructor(private usersService: UsersService) {}

  async validateUser(username: string, pass: string): Promise<any> {
    const user = await this.usersService.findOne(username);
    if (user && user.password === pass) {
      const { password, ...result } = user;
      return result;
    }
    return null;
  }
}
```

```typescript

import { Injectable, Dependencies } from '@nestjs/common';
import { UsersService } from '../users/users.service.js';

@Injectable()
@Dependencies(UsersService)
export class AuthService {
  constructor(usersService) {
    this.usersService = usersService;
  }

  async validateUser(username, pass) {
    const user = await this.usersService.findOne(username);
    if (user && user.password === pass) {
      const { password, ...result } = user;
      return result;
    }
    return null;
  }
}
```

> **Warning** In a real application, never store a password in plain text. Instead, use a library like [bcrypt](https://github.com/kelektiv/node.bcrypt.js#readme) with a salted one-way hash algorithm. With that approach, you store only hashed passwords and compare the stored hash to a hashed version of the **incoming** password, so user passwords are never stored or exposed in plain text. To keep our sample app simple, we violate that rule and use plain text. **Don't do this in your real app.**

Now, update the `AuthModule` to import the `UsersModule`.

auth/auth.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { AuthService } from './auth.service.js';
import { UsersModule } from '../users/users.module.js';

@Module({
  imports: [UsersModule],
  providers: [AuthService],
})
export class AuthModule {}
```

```typescript

import { Module } from '@nestjs/common';
import { AuthService } from './auth.service.js';
import { UsersModule } from '../users/users.module.js';

@Module({
  imports: [UsersModule],
  providers: [AuthService],
})
export class AuthModule {}
```

#### Implementing Passport local[#](/recipes/passport#implementing-passport-local)

Now we can implement our Passport **local authentication strategy**. Create a file called `local.strategy.ts` in the `auth` folder and add the following code:

auth/local.strategy.ts

JS TS

```typescript

import { Strategy } from 'passport-local';
import { PassportStrategy } from '@nestjs/passport';
import { Injectable, UnauthorizedException } from '@nestjs/common';
import { AuthService } from './auth.service.js';

@Injectable()
export class LocalStrategy extends PassportStrategy(Strategy) {
  constructor(private authService: AuthService) {
    super();
  }

  async validate(username: string, password: string): Promise<any> {
    const user = await this.authService.validateUser(username, password);
    if (!user) {
      throw new UnauthorizedException();
    }
    return user;
  }
}
```

```typescript

import { Strategy } from 'passport-local';
import { PassportStrategy } from '@nestjs/passport';
import { Injectable, UnauthorizedException, Dependencies } from '@nestjs/common';
import { AuthService } from './auth.service.js';

@Injectable()
@Dependencies(AuthService)
export class LocalStrategy extends PassportStrategy(Strategy) {
  constructor(authService) {
    super();
    this.authService = authService;
  }

  async validate(username, password) {
    const user = await this.authService.validateUser(username, password);
    if (!user) {
      throw new UnauthorizedException();
    }
    return user;
  }
}
```

We've followed the recipe described earlier for all Passport strategies. Our use of passport-local needs no configuration options, so the constructor calls `super()` without an options object.

> **Hint** You can pass an options object in the call to `super()` to customize the behavior of the Passport strategy. In this example, the passport-local strategy by default expects properties called `username` and `password` in the request body. Pass an options object to specify different property names, for example: `super({ usernameField: 'email' })`. See the [Passport documentation](http://www.passportjs.org/docs/configure/) for more information.

We've also implemented the `validate()` method. For each strategy, Passport calls the verify function (implemented with the `validate()` method in `@nestjs/passport`) with a strategy-specific set of parameters. For the local strategy, Passport expects a `validate()` method with the following signature: `validate(username: string, password: string): any`.

Most of the validation work is done in our `AuthService` (with the help of our `UsersService`), so this method is short. The `validate()` method for **any** Passport strategy follows a similar pattern, varying only in how credentials are represented. If a user is found and the credentials are valid, the method returns the user so that Passport can complete its tasks (e.g., creating the `user` property on the `Request` object), and the request handling pipeline can continue. If not, it throws an exception and lets our [exceptions layer](/exception-filters) handle it.

Typically, the only significant difference in the `validate()` method for each strategy is **how** you determine whether a user exists and is valid. For example, in a JWT strategy, depending on requirements, we may check whether the `userId` carried in the decoded token matches a record in our user database, or appears in a list of revoked tokens. This pattern of subclassing and implementing strategy-specific validation is consistent and extensible.

Next, configure the `AuthModule` to use the Passport features we just defined. Update `auth.module.ts` to look like this:

auth/auth.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { AuthService } from './auth.service.js';
import { UsersModule } from '../users/users.module.js';
import { PassportModule } from '@nestjs/passport';
import { LocalStrategy } from './local.strategy.js';

@Module({
  imports: [UsersModule, PassportModule],
  providers: [AuthService, LocalStrategy],
})
export class AuthModule {}
```

```typescript

import { Module } from '@nestjs/common';
import { AuthService } from './auth.service.js';
import { UsersModule } from '../users/users.module.js';
import { PassportModule } from '@nestjs/passport';
import { LocalStrategy } from './local.strategy.js';

@Module({
  imports: [UsersModule, PassportModule],
  providers: [AuthService, LocalStrategy],
})
export class AuthModule {}
```

#### Built-in Passport Guards[#](/recipes/passport#built-in-passport-guards)

The [Guards](/guards) chapter describes the primary function of guards: to determine whether a request will be handled by the route handler. That remains true, and we'll use that standard capability soon. However, the `@nestjs/passport` module also introduces a new wrinkle that may be confusing at first, so let's discuss it now. From an authentication perspective, your app can be in one of two states:

1. the user/client is **not** logged in (is not authenticated)
2. the user/client **is** logged in (is authenticated)

In the first case (user is not logged in), we need to perform two distinct functions:

* Restrict the routes an unauthenticated user can access (i.e., deny access to restricted routes). We'll use guards in their familiar capacity to handle this function, by placing a guard on the protected routes. This guard checks for the presence of a valid JWT, so we'll build it later, once we are issuing JWTs.

* Initiate the **authentication step** itself when a previously unauthenticated user attempts to log in. This is the step where we'll **issue** a JWT to a valid user. The client needs to `POST` username/password credentials to initiate authentication, so we'll set up a `POST /auth/login` route to handle that. The remaining question is how to invoke the passport-local strategy in that route.

The answer is another, slightly different type of guard. The `@nestjs/passport` module provides a built-in guard that invokes the Passport strategy and kicks off the steps described above (retrieving credentials, running the verify function, creating the `user` property, etc.).

The second case (a logged-in user) relies on the standard type of guard discussed above to allow access to protected routes.

## Learn the right way!

* 19 chapters
* Authn & Authz
* Official certificate
* Deep-dive sessions

[Purchase the Authentication course](https://courses.nestjs.com/#authentication "Courses | NestJS - A node.js framework built on top of TypeScript")

#### Login route[#](/recipes/passport#login-route)

With the strategy in place, we can now implement a bare-bones `/auth/login` route and apply the built-in guard to initiate the passport-local flow.

Open the `app.controller.ts` file and replace its contents with the following:

app.controller.ts

JS TS

```typescript

import { Controller, Request, Post, UseGuards } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';

@Controller()
export class AppController {
  @UseGuards(AuthGuard('local'))
  @Post('auth/login')
  async login(@Request() req: any) {
    return req.user;
  }
}
```

```typescript

import { Controller, Bind, Request, Post, UseGuards } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';

@Controller()
export class AppController {
  @UseGuards(AuthGuard('local'))
  @Post('auth/login')
  @Bind(Request())
  async login(req) {
    return req.user;
  }
}
```

`AuthGuard('local')` creates a guard that invokes the Passport strategy registered under the name `'local'`. When we extended the passport-local strategy, `@nestjs/passport` registered our `LocalStrategy` with Passport under that default name, which comes from the `passport-local` package. The name tells the guard which strategy to invoke when the app has multiple Passport strategies. We only have one strategy so far, but we'll add a second one shortly.

To test the route, we'll have `/auth/login` return the user for now. This also demonstrates another feature: the guard takes the value returned from the `validate()` method and assigns it to the `Request` object as `req.user`. Later, we'll replace this with code that creates and returns a JWT.

Since these are API routes, we'll test them using the widely available [cURL](https://curl.se/) command-line tool. You can test with any of the `user` objects hard-coded in the `UsersService`.

```bash

$ # POST to /auth/login
$ curl -X POST http://localhost:3000/auth/login -d '{"username": "john", "password": "changeme"}' -H "Content-Type: application/json"
$ # result -> {"userId":1,"username":"john"}
```

While this works, passing the strategy name directly to `AuthGuard()` introduces magic strings in the codebase. Instead, we recommend creating your own class, as shown below:

auth/local-auth.guard.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';

@Injectable()
export class LocalAuthGuard extends AuthGuard('local') {}
```

Now, update the `/auth/login` route handler to use the `LocalAuthGuard` instead:

```typescript

@UseGuards(LocalAuthGuard)
@Post('auth/login')
async login(@Request() req: any) {
  return req.user;
}
```

#### Logout route[#](/recipes/passport#logout-route)

To log out, you can create an additional route that invokes `req.logout()` to clear the user's session. This approach is typical for session-based authentication, but it does not apply to JWTs. It requires Passport's session support (`express-session` together with the `passport.initialize()` and `passport.session()` middleware), which this recipe doesn't set up. Since Passport 0.6, `req.logout()` is asynchronous and requires a callback, so wrap it in a promise:

```typescript

@UseGuards(LocalAuthGuard)
@Post('auth/logout')
async logout(@Request() req: any) {
  await new Promise<void>((resolve, reject) =>
    req.logout((err: any) => (err ? reject(err) : resolve())),
  );
}
```

#### JWT functionality[#](/recipes/passport#jwt-functionality)

We're ready to move on to the JWT portion of our auth system. Let's review and refine our requirements:

* Allow users to authenticate with username/password, returning a JWT for use in subsequent calls to protected API endpoints. We're well on our way to meeting this requirement. To complete it, we need to write the code that issues a JWT.
* Create API routes that are protected based on the presence of a valid JWT as a bearer token.

Install a couple more packages to support the JWT requirements:

```bash

$ npm install --save @nestjs/jwt passport-jwt
$ npm install --save-dev @types/passport-jwt
```

The [`@nestjs/jwt`](https://github.com/nestjs/jwt) package is a utility package that helps with JWT manipulation. The `passport-jwt` package is the Passport package that implements the JWT strategy, and `@types/passport-jwt` provides its TypeScript type definitions.

Let's take a closer look at how a `POST /auth/login` request is handled. We've decorated the route with the `LocalAuthGuard`, which invokes the passport-local strategy. This means that:

1. The route handler **will only be invoked if the user has been validated**
2. The `req` parameter will contain a `user` property (populated by Passport during the passport-local authentication flow)

With this in mind, we can now generate a real JWT and return it from this route. To keep our services cleanly modularized, we'll generate the JWT in the `AuthService`. Open the `auth.service.ts` file in the `auth` folder, inject the `JwtService`, and add the `login()` method, as shown:

auth/auth.service.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { UsersService } from '../users/users.service.js';
import { JwtService } from '@nestjs/jwt';

@Injectable()
export class AuthService {
  constructor(
    private usersService: UsersService,
    private jwtService: JwtService
  ) {}

  async validateUser(username: string, pass: string): Promise<any> {
    const user = await this.usersService.findOne(username);
    if (user && user.password === pass) {
      const { password, ...result } = user;
      return result;
    }
    return null;
  }

  async login(user: any) {
    const payload = { username: user.username, sub: user.userId };
    return {
      access_token: this.jwtService.sign(payload),
    };
  }
}
```

```typescript

import { Injectable, Dependencies } from '@nestjs/common';
import { UsersService } from '../users/users.service.js';
import { JwtService } from '@nestjs/jwt';

@Dependencies(UsersService, JwtService)
@Injectable()
export class AuthService {
  constructor(usersService, jwtService) {
    this.usersService = usersService;
    this.jwtService = jwtService;
  }

  async validateUser(username, pass) {
    const user = await this.usersService.findOne(username);
    if (user && user.password === pass) {
      const { password, ...result } = user;
      return result;
    }
    return null;
  }

  async login(user) {
    const payload = { username: user.username, sub: user.userId };
    return {
      access_token: this.jwtService.sign(payload),
    };
  }
}
```

The `JwtService` from `@nestjs/jwt` supplies a `sign()` method that generates our JWT from a subset of the `user` object properties. We return the token as a simple object with a single `access_token` property. We use the `sub` claim to hold our `userId` value, to be consistent with JWT standards.

Next, update the `AuthModule` to import the new dependencies and configure the `JwtModule`.

First, create `constants.ts` in the `auth` folder and add the following code:

auth/constants.ts

JS TS

```typescript

export const jwtConstants = {
  secret: 'DO NOT USE THIS VALUE. INSTEAD, CREATE A COMPLEX SECRET AND KEEP IT SAFE OUTSIDE OF THE SOURCE CODE.',
};
```

```typescript

export const jwtConstants = {
  secret: 'DO NOT USE THIS VALUE. INSTEAD, CREATE A COMPLEX SECRET AND KEEP IT SAFE OUTSIDE OF THE SOURCE CODE.',
};
```

We'll use this to share our key between the JWT signing and verifying steps.

> **Warning****Do not expose this key publicly**. We've done so here to make it clear what the code is doing, but in a production system **you must protect this key** using appropriate measures, such as a secrets vault, an environment variable, or a configuration service.

Now, open `auth.module.ts` in the `auth` folder and update it to look like this:

auth/auth.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { AuthService } from './auth.service.js';
import { LocalStrategy } from './local.strategy.js';
import { UsersModule } from '../users/users.module.js';
import { PassportModule } from '@nestjs/passport';
import { JwtModule } from '@nestjs/jwt';
import { jwtConstants } from './constants.js';

@Module({
  imports: [
    UsersModule,
    PassportModule,
    JwtModule.register({
      secret: jwtConstants.secret,
      signOptions: { expiresIn: '60s' },
    }),
  ],
  providers: [AuthService, LocalStrategy],
  exports: [AuthService],
})
export class AuthModule {}
```

```typescript

import { Module } from '@nestjs/common';
import { AuthService } from './auth.service.js';
import { LocalStrategy } from './local.strategy.js';
import { UsersModule } from '../users/users.module.js';
import { PassportModule } from '@nestjs/passport';
import { JwtModule } from '@nestjs/jwt';
import { jwtConstants } from './constants.js';

@Module({
  imports: [
    UsersModule,
    PassportModule,
    JwtModule.register({
      secret: jwtConstants.secret,
      signOptions: { expiresIn: '60s' },
    }),
  ],
  providers: [AuthService, LocalStrategy],
  exports: [AuthService],
})
export class AuthModule {}
```

We configure the `JwtModule` using `register()`, passing in a configuration object. See the [`@nestjs/jwt` README](https://github.com/nestjs/jwt/blob/master/README.md) for more on the Nest `JwtModule`, and the [`jsonwebtoken` usage documentation](https://github.com/auth0/node-jsonwebtoken#usage) for details on the available configuration options.

Now we can update the `/auth/login` route to return a JWT.

app.controller.ts

JS TS

```typescript

import { Controller, Request, Post, UseGuards } from '@nestjs/common';
import { LocalAuthGuard } from './auth/local-auth.guard.js';
import { AuthService } from './auth/auth.service.js';

@Controller()
export class AppController {
  constructor(private authService: AuthService) {}

  @UseGuards(LocalAuthGuard)
  @Post('auth/login')
  async login(@Request() req: any) {
    return this.authService.login(req.user);
  }
}
```

```typescript

import { Controller, Dependencies, Bind, Request, Post, UseGuards } from '@nestjs/common';
import { LocalAuthGuard } from './auth/local-auth.guard.js';
import { AuthService } from './auth/auth.service.js';

@Dependencies(AuthService)
@Controller()
export class AppController {
  constructor(authService) {
    this.authService = authService;
  }

  @UseGuards(LocalAuthGuard)
  @Post('auth/login')
  @Bind(Request())
  async login(req) {
    return this.authService.login(req.user);
  }
}
```

Test the routes using cURL again. You can use any of the `user` objects hard-coded in the `UsersService`.

```bash

$ # POST to /auth/login
$ curl -X POST http://localhost:3000/auth/login -d '{"username": "john", "password": "changeme"}' -H "Content-Type: application/json"
$ # result -> {"access_token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."}
$ # Note: above JWT truncated
```

#### Implementing Passport JWT[#](/recipes/passport#implementing-passport-jwt)

We can now address our final requirement: protecting endpoints by requiring a valid JWT on the request. Passport helps here too, with the [passport-jwt](https://github.com/mikenicholson/passport-jwt) strategy for securing RESTful endpoints with JSON Web Tokens. Start by creating a file called `jwt.strategy.ts` in the `auth` folder and add the following code:

auth/jwt.strategy.ts

JS TS

```typescript

import { ExtractJwt, Strategy } from 'passport-jwt';
import { PassportStrategy } from '@nestjs/passport';
import { Injectable } from '@nestjs/common';
import { jwtConstants } from './constants.js';

@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
  constructor() {
    super({
      jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
      ignoreExpiration: false,
      secretOrKey: jwtConstants.secret,
    });
  }

  async validate(payload: any) {
    return { userId: payload.sub, username: payload.username };
  }
}
```

```typescript

import { ExtractJwt, Strategy } from 'passport-jwt';
import { PassportStrategy } from '@nestjs/passport';
import { Injectable } from '@nestjs/common';
import { jwtConstants } from './constants.js';

@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
  constructor() {
    super({
      jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
      ignoreExpiration: false,
      secretOrKey: jwtConstants.secret,
    });
  }

  async validate(payload) {
    return { userId: payload.sub, username: payload.username };
  }
}
```

With our `JwtStrategy`, we've followed the same recipe described earlier for all Passport strategies. This strategy requires some initialization, so we pass an options object in the `super()` call. See the [passport-jwt strategy options](https://github.com/mikenicholson/passport-jwt#configure-strategy) for the full list. In our case, these options are:

* `jwtFromRequest`: supplies the method by which the JWT is extracted from the `Request`. We use the standard approach of supplying a bearer token in the `Authorization` header of our API requests. See [extracting the JWT from the request](https://github.com/mikenicholson/passport-jwt#extracting-the-jwt-from-the-request) for other options.
* `ignoreExpiration`: to be explicit, we set the default `false` value, which delegates the responsibility of ensuring that a JWT has not expired to the Passport module. If our route receives an expired JWT, the request is denied with a `401 Unauthorized` response.
* `secretOrKey`: we use the expedient option of supplying a symmetric secret for signing the token. Other options, such as a PEM-encoded public key, may be more appropriate for production apps (see the [passport-jwt strategy options](https://github.com/mikenicholson/passport-jwt#configure-strategy) for more information). In any case, as cautioned earlier, **do not expose this secret publicly**.

The `validate()` method deserves some discussion. For the JWT strategy, Passport first verifies the JWT's signature and decodes the JSON. It then invokes our `validate()` method, passing the decoded JSON as its single parameter. Based on the way JWT signing works, **we're guaranteed to receive a valid token** that we previously signed and issued to a valid user.

As a result, our `validate()` callback is trivial: it returns an object containing the `userId` and `username` properties. Recall that the value returned from `validate()` becomes the `user` property of the `Request` object.

You can also return an array, where the first value becomes the `user` object and the second value becomes the `authInfo` object (`req.authInfo`).

This approach also leaves room ('hooks', as it were) to inject other business logic into the process. For example, we could do a database lookup in our `validate()` method to extract more information about the user, resulting in a more enriched `user` object being available in our `Request`. This is also the place we may decide to do further token validation, such as looking up the `userId` in a list of revoked tokens, enabling us to perform token revocation. The model we've implemented here in our sample code is a fast, "stateless JWT" model, where each API call is immediately authorized based on the presence of a valid JWT, and a small bit of information about the requester (its `userId` and `username`) is available in our Request pipeline.

Add the new `JwtStrategy` as a provider in the `AuthModule`:

auth/auth.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { AuthService } from './auth.service.js';
import { LocalStrategy } from './local.strategy.js';
import { JwtStrategy } from './jwt.strategy.js';
import { UsersModule } from '../users/users.module.js';
import { PassportModule } from '@nestjs/passport';
import { JwtModule } from '@nestjs/jwt';
import { jwtConstants } from './constants.js';

@Module({
  imports: [
    UsersModule,
    PassportModule,
    JwtModule.register({
      secret: jwtConstants.secret,
      signOptions: { expiresIn: '60s' },
    }),
  ],
  providers: [AuthService, LocalStrategy, JwtStrategy],
  exports: [AuthService],
})
export class AuthModule {}
```

```typescript

import { Module } from '@nestjs/common';
import { AuthService } from './auth.service.js';
import { LocalStrategy } from './local.strategy.js';
import { JwtStrategy } from './jwt.strategy.js';
import { UsersModule } from '../users/users.module.js';
import { PassportModule } from '@nestjs/passport';
import { JwtModule } from '@nestjs/jwt';
import { jwtConstants } from './constants.js';

@Module({
  imports: [
    UsersModule,
    PassportModule,
    JwtModule.register({
      secret: jwtConstants.secret,
      signOptions: { expiresIn: '60s' },
    }),
  ],
  providers: [AuthService, LocalStrategy, JwtStrategy],
  exports: [AuthService],
})
export class AuthModule {}
```

By importing the same secret used when we signed the JWT, we ensure that the **verify** phase performed by Passport and the **sign** phase performed in our `AuthService` use a common secret.

Finally, we define the `JwtAuthGuard` class which extends the built-in `AuthGuard`:

auth/jwt-auth.guard.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';

@Injectable()
export class JwtAuthGuard extends AuthGuard('jwt') {}
```

#### Implement protected route and JWT strategy guards[#](/recipes/passport#implement-protected-route-and-jwt-strategy-guards)

We can now implement our protected route and its associated guard.

Open the `app.controller.ts` file and update it as shown below:

app.controller.ts

JS TS

```typescript

import { Controller, Get, Request, Post, UseGuards } from '@nestjs/common';
import { JwtAuthGuard } from './auth/jwt-auth.guard.js';
import { LocalAuthGuard } from './auth/local-auth.guard.js';
import { AuthService } from './auth/auth.service.js';

@Controller()
export class AppController {
  constructor(private authService: AuthService) {}

  @UseGuards(LocalAuthGuard)
  @Post('auth/login')
  async login(@Request() req: any) {
    return this.authService.login(req.user);
  }

  @UseGuards(JwtAuthGuard)
  @Get('profile')
  getProfile(@Request() req: any) {
    return req.user;
  }
}
```

```typescript

import { Controller, Dependencies, Bind, Get, Request, Post, UseGuards } from '@nestjs/common';
import { JwtAuthGuard } from './auth/jwt-auth.guard.js';
import { LocalAuthGuard } from './auth/local-auth.guard.js';
import { AuthService } from './auth/auth.service.js';

@Dependencies(AuthService)
@Controller()
export class AppController {
  constructor(authService) {
    this.authService = authService;
  }

  @UseGuards(LocalAuthGuard)
  @Post('auth/login')
  @Bind(Request())
  async login(req) {
    return this.authService.login(req.user);
  }

  @UseGuards(JwtAuthGuard)
  @Get('profile')
  @Bind(Request())
  getProfile(req) {
    return req.user;
  }
}
```

Once again, we're applying an `AuthGuard`, this time one that invokes the strategy registered under the passport-jwt default name, `jwt`. When our `GET /profile` route is hit, the guard invokes our custom-configured passport-jwt strategy, validates the JWT, and assigns the `user` property to the `Request` object.

Ensure the app is running, and test the routes using cURL.

```bash

$ # GET /profile
$ curl http://localhost:3000/profile
$ # result -> {"message":"Unauthorized","statusCode":401}

$ # POST /auth/login
$ curl -X POST http://localhost:3000/auth/login -d '{"username": "john", "password": "changeme"}' -H "Content-Type: application/json"
$ # result -> {"access_token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2Vybm... }

$ # GET /profile using access_token returned from previous step as bearer code
$ curl http://localhost:3000/profile -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2Vybm..."
$ # result -> {"userId":1,"username":"john"}
```

In the `AuthModule`, we configured the JWT to expire after 60 seconds. This is likely too short for a real application, and the details of token expiration and refresh are beyond the scope of this article. We chose it to demonstrate an important quality of JWTs and the passport-jwt strategy: if you wait 60 seconds after authenticating before sending a `GET /profile` request, you'll receive a `401 Unauthorized` response. Passport checks the JWT's expiration time automatically, so your application doesn't have to.

This completes our JWT authentication implementation. JavaScript clients (such as Angular, React, or Vue apps) and other clients can now authenticate and communicate securely with our API server.

#### Extending guards[#](/recipes/passport#extending-guards)

In most cases, using a provided `AuthGuard` class is sufficient. However, you may want to extend the default error handling or authentication logic. To do so, extend the built-in class and override its methods in a subclass.

```typescript

import {
  ExecutionContext,
  Injectable,
  UnauthorizedException,
} from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';

@Injectable()
export class JwtAuthGuard extends AuthGuard('jwt') {
  canActivate(context: ExecutionContext) {
    // Add your custom authentication logic here
    // for example, call super.logIn(request) to establish a session.
    return super.canActivate(context);
  }

  handleRequest(err: any, user: any, info: any) {
    // You can throw an exception based on either "info" or "err" arguments
    if (err || !user) {
      throw err || new UnauthorizedException();
    }
    return user;
  }
}
```

In addition to extending the default error handling and authentication logic, you can have authentication go through a chain of strategies. The first strategy to succeed, redirect, or error halts the chain. Authentication failures proceed through each strategy in series, and authentication fails only if all strategies fail.

```typescript

export class JwtAuthGuard extends AuthGuard(['strategy_jwt_1', 'strategy_jwt_2', '...']) { ... }
```

#### Enable authentication globally[#](/recipes/passport#enable-authentication-globally)

If most of your endpoints should be protected by default, you can register the authentication guard as a [global guard](/guards#binding-guards). Instead of using the `@UseGuards()` decorator on each controller, you then flag the routes that should be public.

First, register the `JwtAuthGuard` as a global guard using the following construction (in any module):

```typescript

providers: [
  {
    provide: APP_GUARD,
    useClass: JwtAuthGuard,
  },
],
```

With this in place, Nest will automatically bind `JwtAuthGuard` to all endpoints.

Next, provide a mechanism for declaring routes as public. For this, create a custom decorator using the `SetMetadata` decorator factory function.

```typescript

import { SetMetadata } from '@nestjs/common';

export const IS_PUBLIC_KEY = 'isPublic';
export const Public = () => SetMetadata(IS_PUBLIC_KEY, true);
```

The file above exports two constants: our metadata key, named `IS_PUBLIC_KEY`, and the new decorator itself, named `Public` (you can name it `SkipAuth`, `AllowAnon`, or whatever fits your project).

With the custom `@Public()` decorator in place, you can use it to decorate any method, as follows:

```typescript

@Public()
@Get()
findAll() {
  return [];
}
```

Lastly, the `JwtAuthGuard` needs to return `true` when the `"isPublic"` metadata is found. For this, use the `Reflector` class (see [putting it all together](/guards#putting-it-all-together) in the Guards chapter).

```typescript

@Injectable()
export class JwtAuthGuard extends AuthGuard('jwt') {
  constructor(private reflector: Reflector) {
    super();
  }

  canActivate(context: ExecutionContext) {
    const isPublic = this.reflector.getAllAndOverride<boolean>(IS_PUBLIC_KEY, [
      context.getHandler(),
      context.getClass(),
    ]);
    if (isPublic) {
      return true;
    }
    return super.canActivate(context);
  }
}
```

#### Request-scoped strategies[#](/recipes/passport#request-scoped-strategies)

The Passport API is based on registering strategies with the global instance of the library. Therefore, strategies are not designed to have request-dependent options or to be dynamically instantiated per request (see [injection scopes](/fundamentals/injection-scopes) to learn more about request-scoped providers). If you configure your strategy to be request-scoped, Nest never instantiates it, since it's not tied to any specific route, and there is no way to determine which "request-scoped" strategies should run for a given request.

However, you can dynamically resolve request-scoped providers within the strategy. For this, use the [module reference](/fundamentals/module-ref) feature.

First, open the `local.strategy.ts` file and inject the `ModuleRef` in the usual way:

```typescript

constructor(private moduleRef: ModuleRef) {
  super({
    passReqToCallback: true,
  });
}
```

> **Hint** The `ModuleRef` class is imported from the `@nestjs/core` package.

Be sure to set the `passReqToCallback` configuration property to `true`, as shown above.

In the next step, the request instance is used to obtain the current context identifier, instead of generating a new one (see [getting the current sub-tree](/fundamentals/module-ref#getting-current-sub-tree) to learn more about the request context).

Now, inside the `validate()` method of the `LocalStrategy` class, use the `getByRequest()` method of the `ContextIdFactory` class to create a context id based on the request object, and pass this to the `resolve()` call:

```typescript

async validate(
  request: Request,
  username: string,
  password: string,
) {
  const contextId = ContextIdFactory.getByRequest(request);
  // "AuthService" is a request-scoped provider
  const authService = await this.moduleRef.resolve(AuthService, contextId);
  ...
}
```

In the example above, the `resolve()` method asynchronously returns the request-scoped instance of the `AuthService` provider (assuming that `AuthService` is marked as a request-scoped provider).

#### Customize Passport[#](/recipes/passport#customize-passport)

To customize how the guards call Passport, pass options to the `PassportModule.register()` method. Apart from `defaultStrategy` and `property`, which `@nestjs/passport` uses itself, these options are passed to Passport's `authenticate()` call, so the available options depend on the strategy being implemented. For example:

```typescript

PassportModule.register({ session: true });
```

You can also configure a strategy by passing an options object to `super()` in its constructor. For example, for the local strategy:

```typescript

constructor(private authService: AuthService) {
  super({
    usernameField: 'email',
    passwordField: 'password',
  });
}
```

See the official [Passport website](http://www.passportjs.org/docs/oauth/) for the available property names.

#### Named strategies[#](/recipes/passport#named-strategies)

When implementing a strategy, you can name it by passing a second argument to the `PassportStrategy()` function. Otherwise, each strategy uses its default name (e.g., `'jwt'` for the JWT strategy):

```typescript

export class JwtStrategy extends PassportStrategy(Strategy, 'myjwt')
```

You then refer to it with a decorator like `@UseGuards(AuthGuard('myjwt'))`.

#### GraphQL[#](/recipes/passport#graphql)

To use an `AuthGuard` with [GraphQL](/graphql/quick-start), extend the built-in `AuthGuard` class and override the `getRequest()` method.

```typescript

@Injectable()
export class GqlAuthGuard extends AuthGuard('jwt') {
  getRequest(context: ExecutionContext) {
    const ctx = GqlExecutionContext.create(context);
    return ctx.getContext().req;
  }
}
```

To get the currently authenticated user in your GraphQL resolver, define a `@CurrentUser()` decorator:

```typescript

import { createParamDecorator, ExecutionContext } from '@nestjs/common';
import { GqlExecutionContext } from '@nestjs/graphql';

export const CurrentUser = createParamDecorator(
  (data: unknown, context: ExecutionContext) => {
    const ctx = GqlExecutionContext.create(context);
    return ctx.getContext().req.user;
  },
);
```

To use the decorator in your resolver, include it as a parameter of your query or mutation:

```typescript

@Query(() => User)
@UseGuards(GqlAuthGuard)
whoAmI(@CurrentUser() user: User) {
  return this.usersService.findById(user.id);
}
```

For the passport-local strategy, you also need to add the GraphQL context's arguments to the request body so that Passport can access them for validation. Otherwise, you'll get an `Unauthorized` error.

```typescript

@Injectable()
export class GqlLocalAuthGuard extends AuthGuard('local') {
  getRequest(context: ExecutionContext) {
    const gqlExecutionContext = GqlExecutionContext.create(context);
    const gqlContext = gqlExecutionContext.getContext();
    const gqlArgs = gqlExecutionContext.getArgs();

    gqlContext.req.body = { ...gqlContext.req.body, ...gqlArgs };
    return gqlContext.req;
  }
}
```

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/recipes/passport.md)

----
url: https://docs.nestjs.com/v10/openapi/mapped-types
----

* [Mapped types](https://docs.nestjs.com/v10/openapi/mapped-types#mapped-types)
* [Partial](https://docs.nestjs.com/v10/openapi/mapped-types#partial)
* [Pick](https://docs.nestjs.com/v10/openapi/mapped-types#pick)
* [Omit](https://docs.nestjs.com/v10/openapi/mapped-types#omit)
* [Intersection](https://docs.nestjs.com/v10/openapi/mapped-types#intersection)
* [Composition](https://docs.nestjs.com/v10/openapi/mapped-types#composition)

```typescript

import { ApiProperty } from '@nestjs/swagger';

export class CreateCatDto {
  @ApiProperty()
  name: string;

  @ApiProperty()
  age: number;

  @ApiProperty()
  breed: string;
}
```

By default, all of these fields are required. To create a type with the same fields, but with each one optional, use `PartialType()` passing the class reference (`CreateCatDto`) as an argument:

```typescript

export class UpdateCatDto extends PartialType(CreateCatDto) {}
```

> **Hint** The `PartialType()` function is imported from the `@nestjs/swagger` package.

#### Pick[#](/openapi/mapped-types#pick)

The `PickType()` function constructs a new type (class) by picking a set of properties from an input type. For example, suppose we start with a type like:

```typescript

import { ApiProperty } from '@nestjs/swagger';

export class CreateCatDto {
  @ApiProperty()
  name: string;

  @ApiProperty()
  age: number;

  @ApiProperty()
  breed: string;
}
```

We can pick a set of properties from this class using the `PickType()` utility function:

```typescript

export class UpdateCatAgeDto extends PickType(CreateCatDto, ['age'] as const) {}
```

> **Hint** The `PickType()` function is imported from the `@nestjs/swagger` package.

#### Omit[#](/openapi/mapped-types#omit)

The `OmitType()` function constructs a type by picking all properties from an input type and then removing a particular set of keys. For example, suppose we start with a type like:

```typescript

import { ApiProperty } from '@nestjs/swagger';

export class CreateCatDto {
  @ApiProperty()
  name: string;

  @ApiProperty()
  age: number;

  @ApiProperty()
  breed: string;
}
```

We can generate a derived type that has every property **except**`name` as shown below. In this construct, the second argument to `OmitType` is an array of property names.

```typescript

export class UpdateCatDto extends OmitType(CreateCatDto, ['name'] as const) {}
```

> **Hint** The `OmitType()` function is imported from the `@nestjs/swagger` package.

#### Intersection[#](/openapi/mapped-types#intersection)

The `IntersectionType()` function combines two types into one new type (class). For example, suppose we start with two types like:

```typescript

import { ApiProperty } from '@nestjs/swagger';

export class CreateCatDto {
  @ApiProperty()
  name: string;

  @ApiProperty()
  breed: string;
}

export class AdditionalCatInfo {
  @ApiProperty()
  color: string;
}
```

We can generate a new type that combines all properties in both types.

```typescript

export class UpdateCatDto extends IntersectionType(
  CreateCatDto,
  AdditionalCatInfo,
) {}
```

> **Hint** The `IntersectionType()` function is imported from the `@nestjs/swagger` package.

#### Composition[#](/openapi/mapped-types#composition)

The type mapping utility functions are composable. For example, the following will produce a type (class) that has all of the properties of the `CreateCatDto` type except for `name`, and those properties will be set to optional:

```typescript

export class UpdateCatDto extends PartialType(
  OmitType(CreateCatDto, ['name'] as const),
) {}
```

----
url: https://docs.nestjs.com/v11/techniques/mvc
----

* [Model-View-Controller](https://docs.nestjs.com/v11/techniques/mvc#model-view-controller)
* [Template rendering](https://docs.nestjs.com/v11/techniques/mvc#template-rendering)
* [Dynamic template rendering](https://docs.nestjs.com/v11/techniques/mvc#dynamic-template-rendering)
* [Example](https://docs.nestjs.com/v11/techniques/mvc#example)
* [Fastify](https://docs.nestjs.com/v11/techniques/mvc#fastify)
* [Example](https://docs.nestjs.com/v11/techniques/mvc#example-1)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/techniques/mvc.md "Suggest Edits")

### Model-View-Controller

Nest, by default, makes use of the [Express](https://github.com/expressjs/express) library under the hood. Hence, every technique for using the MVC (Model-View-Controller) pattern in Express applies to Nest as well.

First, let's scaffold a simple Nest application using the [CLI](https://github.com/nestjs/nest-cli) tool:

```bash

$ npm i -g @nestjs/cli
$ nest new project
```

In order to create an MVC app, we also need a [template engine](https://expressjs.com/en/guide/using-template-engines.html) to render our HTML views:

```bash

$ npm install --save hbs
```

We've used the `hbs` ([Handlebars](https://github.com/pillarjs/hbs#readme)) engine, though you can use whatever fits your requirements. Once the installation process is complete, we need to configure the express instance using the following code:

main.ts

JS TS

```typescript

import { NestFactory } from '@nestjs/core';
import { NestExpressApplication } from '@nestjs/platform-express';
import { join } from 'node:path';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create<NestExpressApplication>(
    AppModule,
  );

  app.useStaticAssets(join(__dirname, '..', 'public'));
  app.setBaseViewsDir(join(__dirname, '..', 'views'));
  app.setViewEngine('hbs');

  await app.listen(process.env.PORT ?? 3000);
}
bootstrap();
```

```typescript

import { NestFactory } from '@nestjs/core';
import { join } from 'node:path';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(
    AppModule,
  );

  app.useStaticAssets(join(__dirname, '..', 'public'));
  app.setBaseViewsDir(join(__dirname, '..', 'views'));
  app.setViewEngine('hbs');

  await app.listen(process.env.PORT ?? 3000);
}
bootstrap();
```

We told [Express](https://github.com/expressjs/express) that the `public` directory will be used for storing static assets, `views` will contain templates, and the `hbs` template engine should be used to render HTML output.

#### Template rendering[#](/techniques/mvc#template-rendering)

Now, let's create a `views` directory and `index.hbs` template inside it. In the template, we'll print a `message` passed from the controller:

```html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>App</title>
  </head>
  <body>
    {{ message }}
  </body>
</html>
```

Next, open the `app.controller` file and replace the `root()` method with the following code:

app.controller.ts

JS TS

```typescript

import { Get, Controller, Render } from '@nestjs/common';

@Controller()
export class AppController {
  @Get()
  @Render('index')
  root() {
    return { message: 'Hello world!' };
  }
}
```

In this code, we are specifying the template to use in the `@Render()` decorator, and the return value of the route handler method is passed to the template for rendering. Notice that the return value is an object with a property `message`, matching the `message` placeholder we created in the template.

While the application is running, open your browser and navigate to `http://localhost:3000`. You should see the `Hello world!` message.

#### Dynamic template rendering[#](/techniques/mvc#dynamic-template-rendering)

If the application logic must dynamically decide which template to render, then we should use the `@Res()` decorator, and supply the view name in our route handler, rather than in the `@Render()` decorator:

> **Hint** When Nest detects the `@Res()` decorator, it injects the library-specific `response` object. We can use this object to dynamically render the template. Learn more about the `response` object API [here](https://expressjs.com/en/api.html).

app.controller.ts

JS TS

```typescript

import { Get, Controller, Res, Render } from '@nestjs/common';
import { Response } from 'express';
import { AppService } from './app.service';

@Controller()
export class AppController {
  constructor(private appService: AppService) {}

  @Get()
  root(@Res() res: Response) {
    return res.render(
      this.appService.getViewName(),
      { message: 'Hello world!' },
    );
  }
}
```

#### Example[#](/techniques/mvc#example)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/15-mvc).

#### Fastify[#](/techniques/mvc#fastify)

As mentioned in this [chapter](/v11/techniques/performance), we are able to use any compatible HTTP provider together with Nest. One such library is [Fastify](https://github.com/fastify/fastify). In order to create an MVC application with Fastify, we have to install the following packages:

```bash

$ npm i --save @fastify/static @fastify/view handlebars
```

The next steps cover almost the same process used with Express, with minor differences specific to the platform. Once the installation process is complete, open the `main.ts` file and update its contents:

main.ts

JS TS

```typescript

import { NestFactory } from '@nestjs/core';
import { NestFastifyApplication, FastifyAdapter } from '@nestjs/platform-fastify';
import { AppModule } from './app.module';
import { join } from 'node:path';

async function bootstrap() {
  const app = await NestFactory.create<NestFastifyApplication>(
    AppModule,
    new FastifyAdapter(),
  );
  app.useStaticAssets({
    root: join(__dirname, '..', 'public'),
    prefix: '/public/',
  });
  app.setViewEngine({
    engine: {
      handlebars: require('handlebars'),
    },
    templates: join(__dirname, '..', 'views'),
  });
  await app.listen(process.env.PORT ?? 3000);
}
bootstrap();
```

```typescript

import { NestFactory } from '@nestjs/core';
import { FastifyAdapter } from '@nestjs/platform-fastify';
import { AppModule } from './app.module';
import { join } from 'node:path';

async function bootstrap() {
  const app = await NestFactory.create(AppModule, new FastifyAdapter());
  app.useStaticAssets({
    root: join(__dirname, '..', 'public'),
    prefix: '/public/',
  });
  app.setViewEngine({
    engine: {
      handlebars: require('handlebars'),
    },
    templates: join(__dirname, '..', 'views'),
  });
  await app.listen(process.env.PORT ?? 3000);
}
bootstrap();
```

The Fastify API has a few differences, but the end result of these method calls is the same. One notable difference is that when using Fastify, the template name you pass into the `@Render()` decorator must include the file extension.

Here’s how you can set it up:

app.controller.ts

JS TS

```typescript

import { Get, Controller, Render } from '@nestjs/common';

@Controller()
export class AppController {
  @Get()
  @Render('index.hbs')
  root() {
    return { message: 'Hello world!' };
  }
}
```

Alternatively, you can use the `@Res()` decorator to directly inject the response and specify the view you want to render, as shown below:

```typescript

import { Res } from '@nestjs/common';
import { FastifyReply } from 'fastify';

@Get()
root(@Res() res: FastifyReply) {
  return res.view('index.hbs', { title: 'Hello world!' });
}
```

While the application is running, open your browser and navigate to `http://localhost:3000`. You should see the `Hello world!` message.

#### Example[#](/techniques/mvc#example-1)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/17-mvc-fastify).

----
url: https://docs.nestjs.com/v11/fundamentals/lifecycle-events
----

* [Lifecycle Events](https://docs.nestjs.com/v11/fundamentals/lifecycle-events#lifecycle-events)
* [Lifecycle sequence](https://docs.nestjs.com/v11/fundamentals/lifecycle-events#lifecycle-sequence)
* [Lifecycle events](https://docs.nestjs.com/v11/fundamentals/lifecycle-events#lifecycle-events-1)
* [Usage](https://docs.nestjs.com/v11/fundamentals/lifecycle-events#usage)
* [Asynchronous initialization](https://docs.nestjs.com/v11/fundamentals/lifecycle-events#asynchronous-initialization)
* [Application shutdown](https://docs.nestjs.com/v11/fundamentals/lifecycle-events#application-shutdown)

| Lifecycle hook method           | Lifecycle event triggering the hook method call                                                                                                                                                              |
| ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `onModuleInit()`                | Called once the host module's dependencies have been resolved.                                                                                                                                               |
| `onApplicationBootstrap()`      | Called once all modules have been initialized, but before listening for connections.                                                                                                                         |
| `onModuleDestroy()`\*           | Called after a termination signal (e.g., `SIGTERM`) has been received.                                                                                                                                       |
| `beforeApplicationShutdown()`\* | Called after all `onModuleDestroy()` handlers have completed (Promises resolved or rejected); once complete (Promises resolved or rejected), all existing connections will be closed (`app.close()` called). |
| `onApplicationShutdown()`\*     | Called after connections close (`app.close()` resolves).                                                                                                                                                     |

\* For these events, if you're not calling `app.close()` explicitly, you must opt-in to make them work with system signals such as `SIGTERM`. See [Application shutdown](fundamentals/lifecycle-events#application-shutdown) below.

> **Warning** The lifecycle hooks listed above are not triggered for **request-scoped** classes. Request-scoped classes are not tied to the application lifecycle and their lifespan is unpredictable. They are exclusively created for each request and automatically garbage-collected after the response is sent.

> **Hint** Execution order of `onModuleInit()` and `onApplicationBootstrap()` directly depends on the order of module imports, awaiting the previous hook.

#### Usage[#](/fundamentals/lifecycle-events#usage)

Each lifecycle hook is represented by an interface. Interfaces are technically optional because they do not exist after TypeScript compilation. Nonetheless, it's good practice to use them in order to benefit from strong typing and editor tooling. To register a lifecycle hook, implement the appropriate interface. For example, to register a method to be called during module initialization on a particular class (e.g., Controller, Provider or Module), implement the `OnModuleInit` interface by supplying an `onModuleInit()` method, as shown below:

JS TS

```typescript

import { Injectable, OnModuleInit } from '@nestjs/common';

@Injectable()
export class UsersService implements OnModuleInit {
  onModuleInit() {
    console.log(`The module has been initialized.`);
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';

@Injectable()
export class UsersService {
  onModuleInit() {
    console.log(`The module has been initialized.`);
  }
}
```

#### Asynchronous initialization[#](/fundamentals/lifecycle-events#asynchronous-initialization)

Both the `OnModuleInit` and `OnApplicationBootstrap` hooks allow you to defer the application initialization process (return a `Promise` or mark the method as `async` and `await` an asynchronous method completion in the method body).

JS TS

```typescript

async onModuleInit(): Promise<void> {
  await this.fetch();
}
```

```typescript

async onModuleInit() {
  await this.fetch();
}
```

#### Application shutdown[#](/fundamentals/lifecycle-events#application-shutdown)

The `onModuleDestroy()`, `beforeApplicationShutdown()` and `onApplicationShutdown()` hooks are called in the terminating phase (in response to an explicit call to `app.close()` or upon receipt of system signals such as SIGTERM if opted-in). This feature is often used with [Kubernetes](https://kubernetes.io/) to manage containers' lifecycles, by [Heroku](https://www.heroku.com/) for dynos or similar services.

Shutdown hook listeners consume system resources, so they are disabled by default. To use shutdown hooks, you **must enable listeners** by calling `enableShutdownHooks()`:

```typescript

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);

  // Starts listening for shutdown hooks
  app.enableShutdownHooks();

  await app.listen(process.env.PORT ?? 3000);
}
bootstrap();
```

> **warning** Due to inherent platform limitations, NestJS has limited support for application shutdown hooks on Windows. You can expect `SIGINT` to work, as well as `SIGBREAK` and to some extent `SIGHUP` - [read more](https://nodejs.org/api/process.html#process_signal_events). However `SIGTERM` will never work on Windows because killing a process in the task manager is unconditional, "i.e., there's no way for an application to detect or prevent it". Here's some [relevant documentation](https://docs.libuv.org/en/v1.x/signal.html) from libuv to learn more about how `SIGINT`, `SIGBREAK` and others are handled on Windows. Also, see Node.js documentation of [Process Signal Events](https://nodejs.org/api/process.html#process_signal_events)

> **Info**`enableShutdownHooks` consumes memory by starting listeners. In cases where you are running multiple Nest apps in a single Node process (e.g., when running parallel tests with Jest), Node may complain about excessive listener processes. For this reason, `enableShutdownHooks` is not enabled by default. Be aware of this condition when you are running multiple instances in a single Node process.

When the application receives a termination signal it will call any registered `onModuleDestroy()`, `beforeApplicationShutdown()`, then `onApplicationShutdown()` methods (in the sequence described above) with the corresponding signal as the first parameter. If a registered function awaits an asynchronous call (returns a promise), Nest will not continue in the sequence until the promise is resolved or rejected.

JS TS

```typescript

@Injectable()
class UsersService implements OnApplicationShutdown {
  onApplicationShutdown(signal: string) {
    console.log(signal); // e.g. "SIGINT"
  }
}
```

```typescript

@Injectable()
class UsersService implements OnApplicationShutdown {
  onApplicationShutdown(signal) {
    console.log(signal); // e.g. "SIGINT"
  }
}
```

> **Info** Calling `app.close()` doesn't terminate the Node process but only triggers the `onModuleDestroy()` and `onApplicationShutdown()` hooks, so if there are some intervals, long-running background tasks, etc. the process won't be automatically terminated.

----
url: https://docs.nestjs.com/v9/websockets/pipes
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Pipes](https://docs.nestjs.com/v9/websockets/pipes#pipes)
* [Binding pipes](https://docs.nestjs.com/v9/websockets/pipes#binding-pipes)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/websockets/pipes.md "Suggest Edits")

### Pipes

There is no fundamental difference between [regular pipes](/v9/pipes) and web sockets pipes. The only difference is that instead of throwing `HttpException`, you should use `WsException`. In addition, all pipes will be only applied to the `data` parameter (because validating or transforming `client` instance is useless).

> **Hint** The `WsException` class is exposed from `@nestjs/websockets` package.

#### Binding pipes[#](/websockets/pipes#binding-pipes)

The following example uses a manually instantiated method-scoped pipe. Just as with HTTP based applications, you can also use gateway-scoped pipes (i.e., prefix the gateway class with a `@UsePipes()` decorator).

JS TS

```typescript

@UsePipes(new ValidationPipe())
@SubscribeMessage('events')
handleEvent(client: Client, data: unknown): WsResponse<unknown> {
  const event = 'events';
  return { event, data };
}
```

```typescript

@UsePipes(new ValidationPipe())
@SubscribeMessage('events')
handleEvent(client, data) {
  const event = 'events';
  return { event, data };
}
```

----
url: https://docs.nestjs.com/v8/exception-filters
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Exception filters](https://docs.nestjs.com/v8/exception-filters#exception-filters)
* [Throwing standard exceptions](https://docs.nestjs.com/v8/exception-filters#throwing-standard-exceptions)
* [Custom exceptions](https://docs.nestjs.com/v8/exception-filters#custom-exceptions)
* [Built-in HTTP exceptions](https://docs.nestjs.com/v8/exception-filters#built-in-http-exceptions)
* [Exception filters](https://docs.nestjs.com/v8/exception-filters#exception-filters-1)
* [Arguments host](https://docs.nestjs.com/v8/exception-filters#arguments-host)
* [Binding filters](https://docs.nestjs.com/v8/exception-filters#binding-filters)
* [Catch everything](https://docs.nestjs.com/v8/exception-filters#catch-everything)
* [Inheritance](https://docs.nestjs.com/v8/exception-filters#inheritance)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/exception-filters.md "Suggest Edits")

### Exception filters

Nest comes with a built-in **exceptions layer** which is responsible for processing all unhandled exceptions across an application. When an exception is not handled by your application code, it is caught by this layer, which then automatically sends an appropriate user-friendly response.

Out of the box, this action is performed by a built-in **global exception filter**, which handles exceptions of type `HttpException` (and subclasses of it). When an exception is **unrecognized** (is neither `HttpException` nor a class that inherits from `HttpException`), the built-in exception filter generates the following default JSON response:

```json

{
  "statusCode": 500,
  "message": "Internal server error"
}
```

> **Hint** The global exception filter partially supports the `http-errors` library. Basically, any thrown exception containing the `statusCode` and `message` property will be properly populated and send back as a response (instead of the default `InternalServerErrorException` for unrecognized exceptions).

#### Throwing standard exceptions[#](/exception-filters#throwing-standard-exceptions)

Nest provides a built-in `HttpException` class, exposed from the `@nestjs/common` package. For typical HTTP REST/GraphQL API based applications, it's best practice to send standard HTTP response objects when certain error conditions occur.

For example, in the `CatsController`, we have a `findAll()` method (a `GET` route handler). Let's assume that this route handler throws an exception for some reason. To demonstrate this, we'll hard-code it as follows:

cats.controller.ts

JS TS

```typescript

@Get()
async findAll() {
  throw new HttpException('Forbidden', HttpStatus.FORBIDDEN);
}
```

> **Hint** We used the `HttpStatus` here. This is a helper enum imported from the `@nestjs/common` package.

When the client calls this endpoint, the response looks like this:

```json

{
  "statusCode": 403,
  "message": "Forbidden"
}
```

```typescript

@Get()
async findAll() {
  throw new HttpException({
    status: HttpStatus.FORBIDDEN,
    error: 'This is a custom message',
  }, HttpStatus.FORBIDDEN);
}
```

Using the above, this is how the response would look:

```json

{
  "status": 403,
  "error": "This is a custom message"
}
```

#### Custom exceptions[#](/exception-filters#custom-exceptions)

In many cases, you will not need to write custom exceptions, and can use the built-in Nest HTTP exception, as described in the next section. If you do need to create customized exceptions, it's good practice to create your own **exceptions hierarchy**, where your custom exceptions inherit from the base `HttpException` class. With this approach, Nest will recognize your exceptions, and automatically take care of the error responses. Let's implement such a custom exception:

forbidden.exception.ts

JS TS

```typescript

export class ForbiddenException extends HttpException {
  constructor() {
    super('Forbidden', HttpStatus.FORBIDDEN);
  }
}
```

Since `ForbiddenException` extends the base `HttpException`, it will work seamlessly with the built-in exception handler, and therefore we can use it inside the `findAll()` method.

cats.controller.ts

JS TS

```typescript

@Get()
async findAll() {
  throw new ForbiddenException();
}
```

```typescript

import { ExceptionFilter, Catch, ArgumentsHost, HttpException } from '@nestjs/common';
import { Request, Response } from 'express';

@Catch(HttpException)
export class HttpExceptionFilter implements ExceptionFilter {
  catch(exception: HttpException, host: ArgumentsHost) {
    const ctx = host.switchToHttp();
    const response = ctx.getResponse<Response>();
    const request = ctx.getRequest<Request>();
    const status = exception.getStatus();

    response
      .status(status)
      .json({
        statusCode: status,
        timestamp: new Date().toISOString(),
        path: request.url,
      });
  }
}
```

```typescript

import { Catch, HttpException } from '@nestjs/common';

@Catch(HttpException)
export class HttpExceptionFilter {
  catch(exception, host) {
    const ctx = host.switchToHttp();
    const response = ctx.getResponse();
    const request = ctx.getRequest();
    const status = exception.getStatus();

    response
      .status(status)
      .json({
        statusCode: status,
        timestamp: new Date().toISOString(),
        path: request.url,
      });
  }
}
```

> **Hint** All exception filters should implement the generic `ExceptionFilter<T>` interface. This requires you to provide the `catch(exception: T, host: ArgumentsHost)` method with its indicated signature. `T` indicates the type of the exception.

The `@Catch(HttpException)` decorator binds the required metadata to the exception filter, telling Nest that this particular filter is looking for exceptions of type `HttpException` and nothing else. The `@Catch()` decorator may take a single parameter, or a comma-separated list. This lets you set up the filter for several types of exceptions at once.

#### Arguments host[#](/exception-filters#arguments-host)

Let's look at the parameters of the `catch()` method. The `exception` parameter is the exception object currently being processed. The `host` parameter is an `ArgumentsHost` object. `ArgumentsHost` is a powerful utility object that we'll examine further in the [execution context chapter](/v8/fundamentals/execution-context)\*. In this code sample, we use it to obtain a reference to the `Request` and `Response` objects that are being passed to the original request handler (in the controller where the exception originates). In this code sample, we've used some helper methods on `ArgumentsHost` to get the desired `Request` and `Response` objects. Learn more about `ArgumentsHost`[here](/v8/fundamentals/execution-context).

```typescript

@Post()
@UseFilters(new HttpExceptionFilter())
async create(@Body() createCatDto: CreateCatDto) {
  throw new ForbiddenException();
}
```

```typescript

@Post()
@UseFilters(new HttpExceptionFilter())
@Bind(Body())
async create(createCatDto) {
  throw new ForbiddenException();
}
```

> **Hint** The `@UseFilters()` decorator is imported from the `@nestjs/common` package.

We have used the `@UseFilters()` decorator here. Similar to the `@Catch()` decorator, it can take a single filter instance, or a comma-separated list of filter instances. Here, we created the instance of `HttpExceptionFilter` in place. Alternatively, you may pass the class (instead of an instance), leaving responsibility for instantiation to the framework, and enabling **dependency injection**.

cats.controller.ts

JS TS

```typescript

@Post()
@UseFilters(HttpExceptionFilter)
async create(@Body() createCatDto: CreateCatDto) {
  throw new ForbiddenException();
}
```

```typescript

@Post()
@UseFilters(HttpExceptionFilter)
@Bind(Body())
async create(createCatDto) {
  throw new ForbiddenException();
}
```

> **Hint** Prefer applying filters by using classes instead of instances when possible. It reduces **memory usage** since Nest can easily reuse instances of the same class across your entire module.

In the example above, the `HttpExceptionFilter` is applied only to the single `create()` route handler, making it method-scoped. Exception filters can be scoped at different levels: method-scoped, controller-scoped, or global-scoped. For example, to set up a filter as controller-scoped, you would do the following:

cats.controller.ts

JS TS

```typescript

@UseFilters(new HttpExceptionFilter())
export class CatsController {}
```

This construction sets up the `HttpExceptionFilter` for every route handler defined inside the `CatsController`.

To create a global-scoped filter, you would do the following:

main.ts

JS TS

```typescript

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.useGlobalFilters(new HttpExceptionFilter());
  await app.listen(3000);
}
bootstrap();
```

> **Warning** The `useGlobalFilters()` method does not set up filters for gateways or hybrid applications.

Global-scoped filters are used across the whole application, for every controller and every route handler. In terms of dependency injection, global filters registered from outside of any module (with `useGlobalFilters()` as in the example above) cannot inject dependencies since this is done outside the context of any module. In order to solve this issue, you can register a global-scoped filter **directly from any module** using the following construction:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { APP_FILTER } from '@nestjs/core';

@Module({
  providers: [
    {
      provide: APP_FILTER,
      useClass: HttpExceptionFilter,
    },
  ],
})
export class AppModule {}
```

> **Hint** When using this approach to perform dependency injection for the filter, note that regardless of the module where this construction is employed, the filter is, in fact, global. Where should this be done? Choose the module where the filter (`HttpExceptionFilter` in the example above) is defined. Also, `useClass` is not the only way of dealing with custom provider registration. Learn more [here](/v8/fundamentals/custom-providers).

You can add as many filters with this technique as needed; simply add each to the providers array.

#### Catch everything[#](/exception-filters#catch-everything)

In order to catch **every** unhandled exception (regardless of the exception type), leave the `@Catch()` decorator's parameter list empty, e.g., `@Catch()`.

In the example below we have a code that is platform-agnostic because it uses the [HTTP adapter](./faq/http-adapter) to deliver the response, and doesn't use any of the platform-specific objects (`Request` and `Response`) directly:

```typescript

import {
  ExceptionFilter,
  Catch,
  ArgumentsHost,
  HttpException,
  HttpStatus,
} from '@nestjs/common';
import { HttpAdapterHost } from '@nestjs/core';

@Catch()
export class AllExceptionsFilter implements ExceptionFilter {
  constructor(private readonly httpAdapterHost: HttpAdapterHost) {}

  catch(exception: unknown, host: ArgumentsHost): void {
    // In certain situations `httpAdapter` might not be available in the
    // constructor method, thus we should resolve it here.
    const { httpAdapter } = this.httpAdapterHost;

    const ctx = host.switchToHttp();

    const httpStatus =
      exception instanceof HttpException
        ? exception.getStatus()
        : HttpStatus.INTERNAL_SERVER_ERROR;

    const responseBody = {
      statusCode: httpStatus,
      timestamp: new Date().toISOString(),
      path: httpAdapter.getRequestUrl(ctx.getRequest()),
    };

    httpAdapter.reply(ctx.getResponse(), responseBody, httpStatus);
  }
}
```

#### Inheritance[#](/exception-filters#inheritance)

Typically, you'll create fully customized exception filters crafted to fulfill your application requirements. However, there might be use-cases when you would like to simply extend the built-in default **global exception filter**, and override the behavior based on certain factors.

In order to delegate exception processing to the base filter, you need to extend `BaseExceptionFilter` and call the inherited `catch()` method.

all-exceptions.filter.ts

JS TS

```typescript

import { Catch, ArgumentsHost } from '@nestjs/common';
import { BaseExceptionFilter } from '@nestjs/core';

@Catch()
export class AllExceptionsFilter extends BaseExceptionFilter {
  catch(exception: unknown, host: ArgumentsHost) {
    super.catch(exception, host);
  }
}
```

```typescript

import { Catch } from '@nestjs/common';
import { BaseExceptionFilter } from '@nestjs/core';

@Catch()
export class AllExceptionsFilter extends BaseExceptionFilter {
  catch(exception, host) {
    super.catch(exception, host);
  }
}
```

> **Warning** Method-scoped and Controller-scoped filters that extend the `BaseExceptionFilter` should not be instantiated with `new`. Instead, let the framework instantiate them automatically.

The above implementation is just a shell demonstrating the approach. Your implementation of the extended exception filter would include your tailored **business** logic (e.g., handling various conditions).

Global filters **can** extend the base filter. This can be done in either of two ways.

The first method is to inject the `HttpAdapter` reference when instantiating the custom global filter:

```typescript

async function bootstrap() {
  const app = await NestFactory.create(AppModule);

  const { httpAdapter } = app.get(HttpAdapterHost);
  app.useGlobalFilters(new AllExceptionsFilter(httpAdapter));

  await app.listen(3000);
}
bootstrap();
```

The second method is to use the `APP_FILTER` token [as shown here](exception-filters#binding-filters).

----
url: https://docs.nestjs.com/v7/custom-decorators
----

* [Custom route decorators](https://docs.nestjs.com/v7/custom-decorators#custom-route-decorators)
* [Param decorators](https://docs.nestjs.com/v7/custom-decorators#param-decorators)
* [Passing data](https://docs.nestjs.com/v7/custom-decorators#passing-data)
* [Working with pipes](https://docs.nestjs.com/v7/custom-decorators#working-with-pipes)
* [Decorator composition](https://docs.nestjs.com/v7/custom-decorators#decorator-composition)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/custom-decorators.md "Suggest Edits")

### Custom route decorators

Nest is built around a language feature called **decorators**. Decorators are a well-known concept in a lot of commonly used programming languages, but in the JavaScript world, they're still relatively new. In order to better understand how decorators work, we recommend reading [this article](https://medium.com/google-developers/exploring-es7-decorators-76ecb65fb841). Here's a simple definition:

> An ES2016 decorator is an expression which returns a function and can take a target, name and property descriptor as arguments. You apply it by prefixing the decorator with an `@` character and placing this at the very top of what you are trying to decorate. Decorators can be defined for either a class, a method or a property.

#### Param decorators[#](/custom-decorators#param-decorators)

Nest provides a set of useful **param decorators** that you can use together with the HTTP route handlers. Below is a list of the provided decorators and the plain Express (or Fastify) objects they represent

|                            |                                      |
| -------------------------- | ------------------------------------ |
| `@Request(), @Req()`       | `req`                                |
| `@Response(), @Res()`      | `res`                                |
| `@Next()`                  | `next`                               |
| `@Session()`               | `req.session`                        |
| `@Param(param?: string)`   | `req.params` / `req.params[param]`   |
| `@Body(param?: string)`    | `req.body` / `req.body[param]`       |
| `@Query(param?: string)`   | `req.query` / `req.query[param]`     |
| `@Headers(param?: string)` | `req.headers` / `req.headers[param]` |
| `@Ip()`                    | `req.ip`                             |
| `@HostParam()`             | `req.hosts`                          |

Additionally, you can create your own **custom decorators**. Why is this useful?

In the node.js world, it's common practice to attach properties to the **request** object. Then you manually extract them in each route handler, using code like the following:

```typescript

const user = req.user;
```

In order to make your code more readable and transparent, you can create a `@User()` decorator and reuse it across all of your controllers.

user.decorator.ts

JS TS

```typescript

import { createParamDecorator, ExecutionContext } from '@nestjs/common';

export const User = createParamDecorator(
  (data: unknown, ctx: ExecutionContext) => {
    const request = ctx.switchToHttp().getRequest();
    return request.user;
  },
);
```

Then, you can simply use it wherever it fits your requirements.

JS TS

```typescript

@Get()
async findOne(@User() user: UserEntity) {
  console.log(user);
}
```

```typescript

@Get()
@Bind(User())
async findOne(user) {
  console.log(user);
}
```

#### Passing data[#](/custom-decorators#passing-data)

When the behavior of your decorator depends on some conditions, you can use the `data` parameter to pass an argument to the decorator's factory function. One use case for this is a custom decorator that extracts properties from the request object by key. Let's assume, for example, that our [authentication layer](techniques/authentication#implementing-passport-strategies) validates requests and attaches a user entity to the request object. The user entity for an authenticated request might look like:

```json

{
  "id": 101,
  "firstName": "Alan",
  "lastName": "Turing",
  "email": "alan@email.com",
  "roles": ["admin"]
}
```

Let's define a decorator that takes a property name as key, and returns the associated value if it exists (or undefined if it doesn't exist, or if the `user` object has not been created).

user.decorator.ts

JS TS

```typescript

import { createParamDecorator, ExecutionContext } from '@nestjs/common';

export const User = createParamDecorator(
  (data: string, ctx: ExecutionContext) => {
    const request = ctx.switchToHttp().getRequest();
    const user = request.user;

    return data ? user?.[data] : user;
  },
);
```

```typescript

import { createParamDecorator } from '@nestjs/common';

export const User = createParamDecorator((data, ctx) => {
  const request = ctx.switchToHttp().getRequest();
  const user = request.user;

  return data ? user && user[data] : user;
});
```

Here's how you could then access a particular property via the `@User()` decorator in the controller:

JS TS

```typescript

@Get()
async findOne(@User('firstName') firstName: string) {
  console.log(`Hello ${firstName}`);
}
```

```typescript

@Get()
@Bind(User('firstName'))
async findOne(firstName) {
  console.log(`Hello ${firstName}`);
}
```

You can use this same decorator with different keys to access different properties. If the `user` object is deep or complex, this can make for easier and more readable request handler implementations.

> **Hint** For TypeScript users, note that `createParamDecorator<T>()` is a generic. This means you can explicitly enforce type safety, for example `createParamDecorator<string>((data, ctx) => ...)`. Alternatively, specify a parameter type in the factory function, for example `createParamDecorator((data: string, ctx) => ...)`. If you omit both, the type for `data` will be `any`.

#### Working with pipes[#](/custom-decorators#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:

JS TS

```typescript

@Get()
async findOne(
  @User(new ValidationPipe({ validateCustomDecorators: true }))
  user: UserEntity,
) {
  console.log(user);
}
```

```typescript

@Get()
@Bind(User(new ValidationPipe({ validateCustomDecorators: true })))
async findOne(user) {
  console.log(user);
}
```

> **Hint** Note that `validateCustomDecorators` option must be set to true. `ValidationPipe` does not validate arguments annotated with the custom decorators by default.

#### Decorator composition[#](/custom-decorators#decorator-composition)

Nest provides a helper method to compose multiple decorators. For example, suppose you want to combine all decorators related to authentication into a single decorator. This could be done with the following construction:

auth.decorator.ts

JS TS

```typescript

import { applyDecorators } from '@nestjs/common';

export function Auth(...roles: Role[]) {
  return applyDecorators(
    SetMetadata('roles', roles),
    UseGuards(AuthGuard, RolesGuard),
    ApiBearerAuth(),
    ApiUnauthorizedResponse({ description: 'Unauthorized' }),
  );
}
```

```typescript

import { applyDecorators } from '@nestjs/common';

export function Auth(...roles) {
  return applyDecorators(
    SetMetadata('roles', roles),
    UseGuards(AuthGuard, RolesGuard),
    ApiBearerAuth(),
    ApiUnauthorizedResponse({ description: 'Unauthorized' }),
  );
}
```

You can then use this custom `@Auth()` decorator as follows:

```typescript

@Get('users')
@Auth('admin')
findAllUsers() {}
```

This has the effect of applying all four decorators with a single declaration.

> **Warning** The `@ApiHideProperty()` decorator from the `@nestjs/swagger` package is not composable and won't work properly with the `applyDecorators` function.

----
url: https://docs.nestjs.com/v6/discover/companies
----

* [Who is using Nest?](https://docs.nestjs.com/v6/discover/companies#who-is-using-nest)
* [Companies](https://docs.nestjs.com/v6/discover/companies#companies)

### Who is using Nest?

We are proudly helping various companies building their products at scale. If you are using Nest and would you like to be listed here, see this [thread](https://github.com/nestjs/nest/issues/1006). We are willing to put your logo here!

#### Companies[#](/discover/companies#companies)

According to our knowledge, all the following companies have built awesome projects on top of our framework:

[](https://roche.com)[](https://adidas.com)[](https://capgemini.com)[](https://www.societegenerale.fr/)[](https://rewe-digital.com/)[](https://www.decathlon.com/)[](https://www.autodesk.com/)[](https://www.neo4j.com/)[](https://www.shipt.com/)[](https://www.sanofi.com/)[](https://valor-software.com/)[](https://sitepen.com)[](https://gojob.com/)[](https://neoteric.eu/)[](https://trellis.org/)[](https://scal.io)[](https://swingdev.io/)[](https://culturacolectiva.com)[](https://trilon.io)[](http://architectnow.net)[](https://www.iflix.com)[](https://genuinebee.com/)[](https://runplayersleague.com)[](http://www.yanrongyun.com)[](https://sclable.com)[](https://www.dozto.com)[](https://www.qingtui.cn/)[](https://crowdlinker.com/)[](https://nothing.ch/)[](https://swissdevjobs.ch/jobs/Dev-Ops/All)

|                                     |
| ----------------------------------- |
| <https://gorrion.io/>               |
| <http://balticdatascience.com/>     |
| <https://prohabits.com/>            |
| <https://komed-health.com/>         |
| <https://kerberus.com.co/>          |
| <http://xtremis.com/>               |
| <https://notadd.com/>               |
| <http://jsdaddy.io/>                |
| <https://yumpingo.com/>             |
| <https://analytics-importer.cz/>    |
| <https://dayzim.com/>               |
| <https://wizkids.co.uk/>            |
| <https://pilvia.com/>               |
| <https://wi-q.com/>                 |
| <http://agrofel.com.br>             |
| <https://societegenerale.com/>      |
| <https://trashpanda.hulan.nl/>      |
| <https://bytedance.com/>            |
| <https://votercircle.com>           |
| <https://erento.com>                |
| <https://ideas.manticore-labs.com/> |
| <https://smartexlab.com/>           |
| <https://automama.ru/>              |
| <https://iflix.com/>                |
| <https://frontendwatch.com/>        |
| <https://mobilejazz.com/>           |
| <https://cgiandi.com/>              |
| <https://www.titlex.com.au/>        |
| <https://codengage.com/>            |
| <https://budacode.com/>             |
| <https://blueanchor.io/>            |
| <https://www.easymetrics.com/>      |
| <https://getapollo.io/>             |
| <https://big-bench.com/>            |
| <https://www.qingtui.cn/>           |
| <https://www.rosebayconsult.com/>   |
| <https://www.patrocinium.com/>      |
| <https://creatorsdaily.com>         |
| <https://autoscar.com.br>           |
| <https://www.mediktiv.com>          |
| <https://harmonize.health>          |

and a lot more but we don't have enough time to update above list. Feel free to create a [pull request](https://github.com/nestjs/docs.nestjs.com/pulls) though!

----
url: https://docs.nestjs.com/v6/middleware
----

* [Middleware](https://docs.nestjs.com/v6/middleware#middleware)
* [Dependency injection](https://docs.nestjs.com/v6/middleware#dependency-injection)
* [Applying middleware](https://docs.nestjs.com/v6/middleware#applying-middleware)
* [Route wildcards](https://docs.nestjs.com/v6/middleware#route-wildcards)
* [Middleware consumer](https://docs.nestjs.com/v6/middleware#middleware-consumer)
* [Functional middleware](https://docs.nestjs.com/v6/middleware#functional-middleware)
* [Multiple middleware](https://docs.nestjs.com/v6/middleware#multiple-middleware)
* [Global middleware](https://docs.nestjs.com/v6/middleware#global-middleware)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/middlewares.md "Suggest Edits")

### Middleware

Middleware is a function which is called **before** the route handler. Middleware functions have access to the [request](http://expressjs.com/en/4x/api.html#req) and [response](http://expressjs.com/en/4x/api.html#res) objects, and the `next()` middleware function in the application’s request-response cycle. The **next** middleware function is commonly denoted by a variable named `next`.

Nest middleware are, by default, equivalent to [express](http://expressjs.com/en/guide/using-middleware.html) middleware. The following description from the official express documentation describes the capabilities of middleware:

> Middleware functions can perform the following tasks:
>
> * execute any code.
> * make changes to the request and the response objects.
> * end the request-response cycle.
> * call the next middleware function in the stack.
> * if the current middleware function does not end the request-response cycle, it must call `next()` to pass control to the next middleware function. Otherwise, the request will be left hanging.

You implement custom Nest middleware in either a function, or in a class with an `@Injectable()` decorator. The class should implement the `NestMiddleware` interface, while the function does not have any special requirements. Let's start by implementing a simple middleware feature using the class method.

logger.middleware.ts

JS TS

```typescript

import { Injectable, NestMiddleware } from '@nestjs/common';
import { Request, Response } from 'express';

@Injectable()
export class LoggerMiddleware implements NestMiddleware {
  use(req: Request, res: Response, next: Function) {
    console.log('Request...');
    next();
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';

@Injectable()
export class LoggerMiddleware {
  use(req, res, next) {
    console.log('Request...');
    next();
  }
}
```

#### Dependency injection[#](/middleware#dependency-injection)

Nest middleware fully supports Dependency Injection. Just as with providers and controllers, they are able to **inject dependencies** that are available within the same module. As usual, this is done through the `constructor`.

#### Applying middleware[#](/middleware#applying-middleware)

There is no place for middleware in the `@Module()` decorator. Instead, we set them up using the `configure()` method of the module class. Modules that include middleware have to implement the `NestModule` interface. Let's set up the `LoggerMiddleware` at the `AppModule` level.

app.module.ts

JS TS

```typescript

import { Module, NestModule, MiddlewareConsumer } from '@nestjs/common';
import { LoggerMiddleware } from './common/middleware/logger.middleware';
import { CatsModule } from './cats/cats.module';

@Module({
  imports: [CatsModule],
})
export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer
      .apply(LoggerMiddleware)
      .forRoutes('cats');
  }
}
```

```typescript

import { Module } from '@nestjs/common';
import { LoggerMiddleware } from './common/middleware/logger.middleware';
import { CatsModule } from './cats/cats.module';

@Module({
  imports: [CatsModule],
})
export class AppModule {
  configure(consumer) {
    consumer
      .apply(LoggerMiddleware)
      .forRoutes('cats');
  }
}
```

In the above example we have set up the `LoggerMiddleware` for the `/cats` route handlers that were previously defined inside the `CatsController`. We may also further restrict a middleware to a particular request method by passing an object containing the route `path` and request `method` to the `forRoutes()` method when configuring the middleware. In the example below, notice that we import the `RequestMethod` enum to reference the desired request method type.

app.module.ts

JS TS

```typescript

import { Module, NestModule, RequestMethod, MiddlewareConsumer } from '@nestjs/common';
import { LoggerMiddleware } from './common/middleware/logger.middleware';
import { CatsModule } from './cats/cats.module';

@Module({
  imports: [CatsModule],
})
export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer
      .apply(LoggerMiddleware)
      .forRoutes({ path: 'cats', method: RequestMethod.GET });
  }
}
```

```typescript

import { Module, RequestMethod } from '@nestjs/common';
import { LoggerMiddleware } from './common/middleware/logger.middleware';
import { CatsModule } from './cats/cats.module';

@Module({
  imports: [CatsModule],
})
export class AppModule {
  configure(consumer) {
    consumer
      .apply(LoggerMiddleware)
      .forRoutes({ path: 'cats', method: RequestMethod.GET });
  }
}
```

> **Hint** The `configure()` method can be made asynchronous using `async/await` (e.g., you can `await` completion of an asynchronous operation inside the `configure()` method body).

#### Route wildcards[#](/middleware#route-wildcards)

Pattern based routes are supported as well. For instance, the asterisk is used as a **wildcard**, and will match any combination of characters:

```typescript

forRoutes({ path: 'ab*cd', method: RequestMethod.ALL });
```

The `'ab*cd'` route path will match `abcd`, `ab_cd`, `abecd`, and so on. The characters `?`, `+`, `*`, and `()` may be used in a route path, and are subsets of their regular expression counterparts. The hyphen ( `-`) and the dot (`.`) are interpreted literally by string-based paths.

#### Middleware consumer[#](/middleware#middleware-consumer)

The `MiddlewareConsumer` is a helper class. It provides several built-in methods to manage middleware. All of them can be simply **chained** in the [fluent style](https://en.wikipedia.org/wiki/Fluent_interface). The `forRoutes()` method can take a single string, multiple strings, a `RouteInfo` object, a controller class and even multiple controller classes. In most cases you'll probably just pass a list of **controllers** separated by commas. Below is an example with a single controller:

app.module.ts

JS TS

```typescript

import { Module, NestModule, MiddlewareConsumer } from '@nestjs/common';
import { LoggerMiddleware } from './common/middleware/logger.middleware';
import { CatsModule } from './cats/cats.module';
import { CatsController } from './cats/cats.controller.ts';

@Module({
  imports: [CatsModule],
})
export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer
      .apply(LoggerMiddleware)
      .forRoutes(CatsController);
  }
}
```

```typescript

import { Module } from '@nestjs/common';
import { LoggerMiddleware } from './common/middleware/logger.middleware';
import { CatsModule } from './cats/cats.module';
import { CatsController } from './cats/cats.controller.ts';

@Module({
  imports: [CatsModule],
})
export class AppModule {
  configure(consumer) {
    consumer
      .apply(LoggerMiddleware)
      .forRoutes(CatsController);
  }
}
```

> **Hint** The `apply()` method may either take a single middleware, or multiple arguments to specify [multiple middlewares](/middleware#multiple-middleware).

Quite often we might want to **exclude** certain routes from having the middleware applied. When defining middleware with a class (as we have been doing so far, as opposed to using the alternative [functional middleware](/middleware#functional-middleware)), we can easily exclude certain routes with the `exclude()` method. This method takes one or more objects identifying the `path` and `method` to be excluded, as shown below:

```typescript

consumer
  .apply(LoggerMiddleware)
  .exclude(
    { path: 'cats', method: RequestMethod.GET },
    { path: 'cats', method: RequestMethod.POST },
  )
  .forRoutes(CatsController);
```

With the example above, `LoggerMiddleware` will be bound to all routes defined inside `CatsController`**except** the two passed to the `exclude()` method. Please note that the `exclude()` method **does not work** with functional middleware (middleware defined in a function rather than in a class; see below for more details). In addition, this method doesn't exclude paths from more generic routes (e.g., wildcards). If you need that level of control, you should put your paths-restriction logic directly into the middleware and, for example, access the request's URL to conditionally apply the middleware logic.

## Hoodies, T-shirts, and accessories!

Support our future development by shopping in the official store!

[See more](https://nestjs.threadless.com/ "Shop | NestJS - A node.js framework built on top of TypeScript")

#### Functional middleware[#](/middleware#functional-middleware)

The `LoggerMiddleware` class we've been using is quite simple. It has no members, no additional methods, and no dependencies. Why can't we just define it in a simple function instead of a class? In fact, we can. This type of middleware is called **functional middleware**. Let's transform the logger middleware from class-based into functional middleware to illustrate the difference:

logger.middleware.ts

JS TS

```typescript

export function logger(req, res, next) {
  console.log(`Request...`);
  next();
};
```

And use it within the `AppModule`:

app.module.ts

JS TS

```typescript

consumer
  .apply(logger)
  .forRoutes(CatsController);
```

> **Hint** Consider using the simpler **functional middleware** alternative any time your middleware doesn't need any dependencies.

#### Multiple middleware[#](/middleware#multiple-middleware)

As mentioned above, in order to bind multiple middleware that are executed sequentially, simply provide a comma separated list inside the `apply()` method:

```typescript

consumer.apply(cors(), helmet(), logger).forRoutes(CatsController);
```

#### Global middleware[#](/middleware#global-middleware)

If we want to bind middleware to every registered route at once, we can use the `use()` method that is supplied by the `INestApplication` instance:

```typescript

const app = await NestFactory.create(AppModule);
app.use(logger);
await app.listen(3000);
```

----
url: https://docs.nestjs.com/v5/fundamentals/platform-agnosticism
----

### Platform agnosticism

The whole point of Nest is staying as a platform-agnostic framework. A platform independence makes possible creating **reusable logical parts**, that people can take advantage of across several different types of applications. A framework's architecture is focused on being applicable to any kind of server-side solution.

#### Build once, use everywhere

An **overview** category is mostly referring to HTTP server (REST APIs). However, all those building blocks can be easily used in different transport layers (`microservices` or `websockets` packages). Furthermore, Nest comes with a dedicated [GraphQL](/v5/graphql/quick-start) module. Last but not least, an [execution context](/v5/execution-context) feature helps to create everything that runs on Node.js on top of Nest.

Nest inspires to be a fully-fledged platform, that brings a higher-level of reusability for your applications. Build once, use everywhere!

* Platform agnosticism
* Build once, use everywhere

----
url: https://docs.nestjs.com/v11/recipes/crud-generator
----

* [CRUD generator (TypeScript only)](https://docs.nestjs.com/v11/recipes/crud-generator#crud-generator-typescript-only)
* [Introduction](https://docs.nestjs.com/v11/recipes/crud-generator#introduction)
* [Generating a new resource](https://docs.nestjs.com/v11/recipes/crud-generator#generating-a-new-resource)

To help speed up this repetitive process, [Nest CLI](/v11/cli/overview) provides a generator (schematic) that automatically generates all the boilerplate code to help us avoid doing all of this, and make the developer experience much simpler.

> **Note** The schematic supports generating **HTTP** controllers, **Microservice** controllers, **GraphQL** resolvers (both code first and schema first), and **WebSocket** Gateways.

#### Generating a new resource[#](/recipes/crud-generator#generating-a-new-resource)

To create a new resource, simply run the following command in the root directory of your project:

```shell

$ nest g resource
```

`nest g resource` command not only generates all the NestJS building blocks (module, service, controller classes) but also an entity class, DTO classes as well as the testing (`.spec`) files.

Below you can see the generated controller file (for REST API):

```typescript

@Controller('users')
export class UsersController {
  constructor(private readonly usersService: UsersService) {}

  @Post()
  create(@Body() createUserDto: CreateUserDto) {
    return this.usersService.create(createUserDto);
  }

  @Get()
  findAll() {
    return this.usersService.findAll();
  }

  @Get(':id')
  findOne(@Param('id') id: string) {
    return this.usersService.findOne(+id);
  }

  @Patch(':id')
  update(@Param('id') id: string, @Body() updateUserDto: UpdateUserDto) {
    return this.usersService.update(+id, updateUserDto);
  }

  @Delete(':id')
  remove(@Param('id') id: string) {
    return this.usersService.remove(+id);
  }
}
```

Also, it automatically creates placeholders for all the CRUD endpoints (routes for REST APIs, queries and mutations for GraphQL, message subscribes for both Microservices and WebSocket Gateways) - all without having to lift a finger.

> **Note** Generated service classes are **not** tied to any specific **ORM (or data source)**. This makes the generator generic enough to meet the needs of any project. By default, all methods will contain placeholders, allowing you to populate it with the data sources specific to your project.

Likewise, if you want to generate resolvers for a GraphQL application, simply select the `GraphQL (code first)` (or `GraphQL (schema first)`) as your transport layer.

In this case, NestJS will generate a resolver class instead of a REST API controller:

```shell

$ nest g resource users

> ? What transport layer do you use? GraphQL (code first)
> ? Would you like to generate CRUD entry points? Yes
> CREATE src/users/users.module.ts (224 bytes)
> CREATE src/users/users.resolver.spec.ts (525 bytes)
> CREATE src/users/users.resolver.ts (1109 bytes)
> CREATE src/users/users.service.spec.ts (453 bytes)
> CREATE src/users/users.service.ts (625 bytes)
> CREATE src/users/dto/create-user.input.ts (195 bytes)
> CREATE src/users/dto/update-user.input.ts (281 bytes)
> CREATE src/users/entities/user.entity.ts (187 bytes)
> UPDATE src/app.module.ts (312 bytes)
```

> **Hint** To avoid generating test files, you can pass the `--no-spec` flag, as follows: `nest g resource users --no-spec`

We can see below, that not only were all boilerplate mutations and queries created, but everything is all tied together. We're utilizing the `UsersService`, `User` Entity, and our DTO's.

```typescript

import { Resolver, Query, Mutation, Args, Int } from '@nestjs/graphql';
import { UsersService } from './users.service';
import { User } from './entities/user.entity';
import { CreateUserInput } from './dto/create-user.input';
import { UpdateUserInput } from './dto/update-user.input';

@Resolver(() => User)
export class UsersResolver {
  constructor(private readonly usersService: UsersService) {}

  @Mutation(() => User)
  createUser(@Args('createUserInput') createUserInput: CreateUserInput) {
    return this.usersService.create(createUserInput);
  }

  @Query(() => [User], { name: 'users' })
  findAll() {
    return this.usersService.findAll();
  }

  @Query(() => User, { name: 'user' })
  findOne(@Args('id', { type: () => Int }) id: number) {
    return this.usersService.findOne(id);
  }

  @Mutation(() => User)
  updateUser(@Args('updateUserInput') updateUserInput: UpdateUserInput) {
    return this.usersService.update(updateUserInput.id, updateUserInput);
  }

  @Mutation(() => User)
  removeUser(@Args('id', { type: () => Int }) id: number) {
    return this.usersService.remove(id);
  }
}
```

----
url: https://docs.nestjs.com/v9/recipes/serve-static
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Serve Static](https://docs.nestjs.com/v9/recipes/serve-static#serve-static)
* [Installation](https://docs.nestjs.com/v9/recipes/serve-static#installation)
* [Bootstrap](https://docs.nestjs.com/v9/recipes/serve-static#bootstrap)
* [Configuration](https://docs.nestjs.com/v9/recipes/serve-static#configuration)
* [Example](https://docs.nestjs.com/v9/recipes/serve-static#example)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/recipes/serve-static.md "Suggest Edits")

### Serve Static

In order to serve static content like a Single Page Application (SPA) we can use the `ServeStaticModule` from the [`@nestjs/serve-static`](https://www.npmjs.com/package/@nestjs/serve-static) package.

#### Installation[#](/recipes/serve-static#installation)

First we need to install the required package:

```bash

$ npm install --save @nestjs/serve-static
```

#### Bootstrap[#](/recipes/serve-static#bootstrap)

Once the installation process is done, we can import the `ServeStaticModule` into the root `AppModule` and configure it by passing in a configuration object to the `forRoot()` method.

```typescript

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { ServeStaticModule } from '@nestjs/serve-static';
import { join } from 'path';

@Module({
  imports: [
    ServeStaticModule.forRoot({
      rootPath: join(__dirname, '..', 'client'),
    }),
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}
```

With this in place, build the static website and place its content in the location specified by the `rootPath` property.

#### Configuration[#](/recipes/serve-static#configuration)

[ServeStaticModule](https://github.com/nestjs/serve-static) can be configured with a variety of options to customize its behavior. You can set the path to render your static app, specify excluded paths, enable or disable setting Cache-Control response header, etc. See the full list of options [here](https://github.com/nestjs/serve-static/blob/master/lib/interfaces/serve-static-options.interface.ts).

> **Notice** The default `renderPath` of the Static App is `*` (all paths), and the module will send "index.html" files in response. It lets you create Client-Side routing for your SPA. Paths, specified in your controllers will fallback to the server. You can change this behavior setting `serveRoot`, `renderPath` combining them with other options.

#### Example[#](/recipes/serve-static#example)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/24-serve-static).

----
url: https://docs.nestjs.com/v10/custom-decorators
----

* [Custom route decorators](https://docs.nestjs.com/v10/custom-decorators#custom-route-decorators)
* [Param decorators](https://docs.nestjs.com/v10/custom-decorators#param-decorators)
* [Passing data](https://docs.nestjs.com/v10/custom-decorators#passing-data)
* [Working with pipes](https://docs.nestjs.com/v10/custom-decorators#working-with-pipes)
* [Decorator composition](https://docs.nestjs.com/v10/custom-decorators#decorator-composition)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/custom-decorators.md "Suggest Edits")

### Custom route decorators

Nest is built around a language feature called **decorators**. Decorators are a well-known concept in a lot of commonly used programming languages, but in the JavaScript world, they're still relatively new. In order to better understand how decorators work, we recommend reading [this article](https://medium.com/google-developers/exploring-es7-decorators-76ecb65fb841). Here's a simple definition:

> An ES2016 decorator is an expression which returns a function and can take a target, name and property descriptor as arguments. You apply it by prefixing the decorator with an `@` character and placing this at the very top of what you are trying to decorate. Decorators can be defined for either a class, a method or a property.

#### Param decorators[#](/custom-decorators#param-decorators)

Nest provides a set of useful **param decorators** that you can use together with the HTTP route handlers. Below is a list of the provided decorators and the plain Express (or Fastify) objects they represent

|                            |                                      |
| -------------------------- | ------------------------------------ |
| `@Request(), @Req()`       | `req`                                |
| `@Response(), @Res()`      | `res`                                |
| `@Next()`                  | `next`                               |
| `@Session()`               | `req.session`                        |
| `@Param(param?: string)`   | `req.params` / `req.params[param]`   |
| `@Body(param?: string)`    | `req.body` / `req.body[param]`       |
| `@Query(param?: string)`   | `req.query` / `req.query[param]`     |
| `@Headers(param?: string)` | `req.headers` / `req.headers[param]` |
| `@Ip()`                    | `req.ip`                             |
| `@HostParam()`             | `req.hosts`                          |

Additionally, you can create your own **custom decorators**. Why is this useful?

In the node.js world, it's common practice to attach properties to the **request** object. Then you manually extract them in each route handler, using code like the following:

```typescript

const user = req.user;
```

In order to make your code more readable and transparent, you can create a `@User()` decorator and reuse it across all of your controllers.

user.decorator.ts

JS TS

```typescript

import { createParamDecorator, ExecutionContext } from '@nestjs/common';

export const User = createParamDecorator(
  (data: unknown, ctx: ExecutionContext) => {
    const request = ctx.switchToHttp().getRequest();
    return request.user;
  },
);
```

Then, you can simply use it wherever it fits your requirements.

JS TS

```typescript

@Get()
async findOne(@User() user: UserEntity) {
  console.log(user);
}
```

```typescript

@Get()
@Bind(User())
async findOne(user) {
  console.log(user);
}
```

#### Passing data[#](/custom-decorators#passing-data)

When the behavior of your decorator depends on some conditions, you can use the `data` parameter to pass an argument to the decorator's factory function. One use case for this is a custom decorator that extracts properties from the request object by key. Let's assume, for example, that our [authentication layer](techniques/authentication#implementing-passport-strategies) validates requests and attaches a user entity to the request object. The user entity for an authenticated request might look like:

```json

{
  "id": 101,
  "firstName": "Alan",
  "lastName": "Turing",
  "email": "alan@email.com",
  "roles": ["admin"]
}
```

Let's define a decorator that takes a property name as key, and returns the associated value if it exists (or undefined if it doesn't exist, or if the `user` object has not been created).

user.decorator.ts

JS TS

```typescript

import { createParamDecorator, ExecutionContext } from '@nestjs/common';

export const User = createParamDecorator(
  (data: string, ctx: ExecutionContext) => {
    const request = ctx.switchToHttp().getRequest();
    const user = request.user;

    return data ? user?.[data] : user;
  },
);
```

```typescript

import { createParamDecorator } from '@nestjs/common';

export const User = createParamDecorator((data, ctx) => {
  const request = ctx.switchToHttp().getRequest();
  const user = request.user;

  return data ? user && user[data] : user;
});
```

Here's how you could then access a particular property via the `@User()` decorator in the controller:

JS TS

```typescript

@Get()
async findOne(@User('firstName') firstName: string) {
  console.log(`Hello ${firstName}`);
}
```

```typescript

@Get()
@Bind(User('firstName'))
async findOne(firstName) {
  console.log(`Hello ${firstName}`);
}
```

You can use this same decorator with different keys to access different properties. If the `user` object is deep or complex, this can make for easier and more readable request handler implementations.

> **Hint** For TypeScript users, note that `createParamDecorator<T>()` is a generic. This means you can explicitly enforce type safety, for example `createParamDecorator<string>((data, ctx) => ...)`. Alternatively, specify a parameter type in the factory function, for example `createParamDecorator((data: string, ctx) => ...)`. If you omit both, the type for `data` will be `any`.

#### Working with pipes[#](/custom-decorators#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:

JS TS

```typescript

@Get()
async findOne(
  @User(new ValidationPipe({ validateCustomDecorators: true }))
  user: UserEntity,
) {
  console.log(user);
}
```

```typescript

@Get()
@Bind(User(new ValidationPipe({ validateCustomDecorators: true })))
async findOne(user) {
  console.log(user);
}
```

> **Hint** Note that `validateCustomDecorators` option must be set to true. `ValidationPipe` does not validate arguments annotated with the custom decorators by default.

#### Decorator composition[#](/custom-decorators#decorator-composition)

Nest provides a helper method to compose multiple decorators. For example, suppose you want to combine all decorators related to authentication into a single decorator. This could be done with the following construction:

auth.decorator.ts

JS TS

```typescript

import { applyDecorators } from '@nestjs/common';

export function Auth(...roles: Role[]) {
  return applyDecorators(
    SetMetadata('roles', roles),
    UseGuards(AuthGuard, RolesGuard),
    ApiBearerAuth(),
    ApiUnauthorizedResponse({ description: 'Unauthorized' }),
  );
}
```

```typescript

import { applyDecorators } from '@nestjs/common';

export function Auth(...roles) {
  return applyDecorators(
    SetMetadata('roles', roles),
    UseGuards(AuthGuard, RolesGuard),
    ApiBearerAuth(),
    ApiUnauthorizedResponse({ description: 'Unauthorized' }),
  );
}
```

You can then use this custom `@Auth()` decorator as follows:

```typescript

@Get('users')
@Auth('admin')
findAllUsers() {}
```

This has the effect of applying all four decorators with a single declaration.

> **Warning** The `@ApiHideProperty()` decorator from the `@nestjs/swagger` package is not composable and won't work properly with the `applyDecorators` function.

----
url: https://docs.nestjs.com/v9/security/cors
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [CORS](https://docs.nestjs.com/v9/security/cors#cors)
* [Getting started](https://docs.nestjs.com/v9/security/cors#getting-started)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/security/cors.md "Suggest Edits")

### CORS

Cross-origin resource sharing (CORS) is a mechanism that allows resources to be requested from another domain. Under the hood, Nest makes use of the Express [cors](https://github.com/expressjs/cors) package. This package provides various options that you can customize based on your requirements.

#### Getting started[#](/security/cors#getting-started)

To enable CORS, call the `enableCors()` method on the Nest application object.

```typescript

const app = await NestFactory.create(AppModule);
app.enableCors();
await app.listen(3000);
```

The `enableCors()` method takes an optional configuration object argument. The available properties of this object are described in the official [CORS](https://github.com/expressjs/cors#configuration-options) documentation. Another way is to pass a [callback function](https://github.com/expressjs/cors#configuring-cors-asynchronously) that lets you define the configuration object asynchronously based on the request (on the fly).

Alternatively, enable CORS via the `create()` method's options object. Set the `cors` property to `true` to enable CORS with default settings. Or, pass a [CORS configuration object](https://github.com/expressjs/cors#configuration-options) or [callback function](https://github.com/expressjs/cors#configuring-cors-asynchronously) as the `cors` property value to customize its behavior.

```typescript

const app = await NestFactory.create(AppModule, { cors: true });
await app.listen(3000);
```

----
url: https://docs.nestjs.com/v11/recipes/sql-sequelize
----

* [SQL (Sequelize)](https://docs.nestjs.com/v11/recipes/sql-sequelize#sql-sequelize)
* [Getting started](https://docs.nestjs.com/v11/recipes/sql-sequelize#getting-started)
* [Model injection](https://docs.nestjs.com/v11/recipes/sql-sequelize#model-injection)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/recipes/sql-sequelize.md "Suggest Edits")

### SQL (Sequelize)

##### This chapter applies only to TypeScript

> **Warning** In this article, you'll learn how to create a `DatabaseModule` based on the **Sequelize** package from scratch using custom components. As a consequence, this technique contains a lot of overhead that you can avoid by using the dedicated, out-of-the-box `@nestjs/sequelize` package. To learn more, see [here](/techniques/database#sequelize-integration).

[Sequelize](https://github.com/sequelize/sequelize) is a popular Object Relational Mapper (ORM) written in a vanilla JavaScript, but there is a [sequelize-typescript](https://github.com/RobinBuschmann/sequelize-typescript) TypeScript wrapper which provides a set of decorators and other extras for the base sequelize.

#### Getting started[#](/recipes/sql-sequelize#getting-started)

To start the adventure with this library we have to install the following dependencies:

```bash

$ npm install --save sequelize sequelize-typescript mysql2
$ npm install --save-dev @types/sequelize
```

The first step we need to do is create a **Sequelize** instance with an options object passed into the constructor. Also, we need to add all models (the alternative is to use `modelPaths` property) and `sync()` our database tables.

database.providers.ts

JS TS

```typescript

import { Sequelize } from 'sequelize-typescript';
import { Cat } from '../cats/cat.entity';

export const databaseProviders = [
  {
    provide: 'SEQUELIZE',
    useFactory: async () => {
      const sequelize = new Sequelize({
        dialect: 'mysql',
        host: 'localhost',
        port: 3306,
        username: 'root',
        password: 'password',
        database: 'nest',
      });
      sequelize.addModels([Cat]);
      await sequelize.sync();
      return sequelize;
    },
  },
];
```

> **Hint** Following best practices, we declared the custom provider in the separated file which has a `*.providers.ts` suffix.

Then, we need to export these providers to make them **accessible** for the rest part of the application.

```typescript

import { Module } from '@nestjs/common';
import { databaseProviders } from './database.providers';

@Module({
  providers: [...databaseProviders],
  exports: [...databaseProviders],
})
export class DatabaseModule {}
```

Now we can inject the `Sequelize` object using `@Inject()` decorator. Each class that would depend on the `Sequelize` async provider will wait until a `Promise` is resolved.

#### Model injection[#](/recipes/sql-sequelize#model-injection)

In [Sequelize](https://github.com/sequelize/sequelize) the **Model** defines a table in the database. Instances of this class represent a database row. Firstly, we need at least one entity:

cat.entity.ts

JS TS

```typescript

import { Table, Column, Model } from 'sequelize-typescript';

@Table
export class Cat extends Model {
  @Column
  name: string;

  @Column
  age: number;

  @Column
  breed: string;
}
```

The `Cat` entity belongs to the `cats` directory. This directory represents the `CatsModule`. Now it's time to create a **Repository** provider:

cats.providers.ts

JS TS

```typescript

import { Cat } from './cat.entity';

export const catsProviders = [
  {
    provide: 'CATS_REPOSITORY',
    useValue: Cat,
  },
];
```

> **Warning** In the real-world applications you should avoid **magic strings**. Both `CATS_REPOSITORY` and `SEQUELIZE` should be kept in the separated `constants.ts` file.

In Sequelize, we use static methods to manipulate the data, and thus we created an **alias** here.

Now we can inject the `CATS_REPOSITORY` to the `CatsService` using the `@Inject()` decorator:

cats.service.ts

JS TS

```typescript

import { Injectable, Inject } from '@nestjs/common';
import { CreateCatDto } from './dto/create-cat.dto';
import { Cat } from './cat.entity';

@Injectable()
export class CatsService {
  constructor(
    @Inject('CATS_REPOSITORY')
    private catsRepository: typeof Cat
  ) {}

  async findAll(): Promise<Cat[]> {
    return this.catsRepository.findAll<Cat>();
  }
}
```

The database connection is **asynchronous**, but Nest makes this process completely invisible for the end-user. The `CATS_REPOSITORY` provider is waiting for the db connection, and the `CatsService` is delayed until repository is ready to use. The entire application can start when each class is instantiated.

Here is a final `CatsModule`:

cats.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';
import { catsProviders } from './cats.providers';
import { DatabaseModule } from '../database/database.module';

@Module({
  imports: [DatabaseModule],
  controllers: [CatsController],
  providers: [
    CatsService,
    ...catsProviders,
  ],
})
export class CatsModule {}
```

> **Hint** Do not forget to import the `CatsModule` into the root `AppModule`.

----
url: https://docs.nestjs.com/v7/fundamentals/injection-scopes
----

* [Injection scopes](https://docs.nestjs.com/v7/fundamentals/injection-scopes#injection-scopes)
* [Provider scope](https://docs.nestjs.com/v7/fundamentals/injection-scopes#provider-scope)
* [Usage](https://docs.nestjs.com/v7/fundamentals/injection-scopes#usage)
* [Controller scope](https://docs.nestjs.com/v7/fundamentals/injection-scopes#controller-scope)
* [Scope hierarchy](https://docs.nestjs.com/v7/fundamentals/injection-scopes#scope-hierarchy)
* [Request provider](https://docs.nestjs.com/v7/fundamentals/injection-scopes#request-provider)
* [Performance](https://docs.nestjs.com/v7/fundamentals/injection-scopes#performance)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/fundamentals/provider-scopes.md "Suggest Edits")

### Injection scopes

For people coming from different programming language backgrounds, it might be unexpected to learn that in Nest, almost everything is shared across incoming requests. We have a connection pool to the database, singleton services with global state, etc. Remember that Node.js doesn't follow the request/response Multi-Threaded Stateless Model in which every request is processed by a separate thread. Hence, using singleton instances is fully **safe** for our applications.

However, there are edge-cases when request-based lifetime may be the desired behavior, for instance per-request caching in GraphQL applications, request tracking, and multi-tenancy. Injection scopes provide a mechanism to obtain the desired provider lifetime behavior.

#### Provider scope[#](/fundamentals/injection-scopes#provider-scope)

A provider can have any of the following scopes:

|             |                                                                                                                                                                                                                                                                            |
| ----------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `DEFAULT`   | A single instance of the provider is shared across the entire application. The instance lifetime is tied directly to the application lifecycle. Once the application has bootstrapped, all singleton providers have been instantiated. Singleton scope is used by default. |
| `REQUEST`   | A new instance of the provider is created exclusively for each incoming **request**. The instance is garbage-collected after the request has completed processing.                                                                                                         |
| `TRANSIENT` | Transient providers are not shared across consumers. Each consumer that injects a transient provider will receive a new, dedicated instance.                                                                                                                               |

> **Hint** Using singleton scope is **recommended** for most use cases. Sharing providers across consumers and across requests means that an instance can be cached and its initialization occurs only once, during application startup.

#### Usage[#](/fundamentals/injection-scopes#usage)

Specify injection scope by passing the `scope` property to the `@Injectable()` decorator options object:

```typescript

import { Injectable, Scope } from '@nestjs/common';

@Injectable({ scope: Scope.REQUEST })
export class CatsService {}
```

Similarly, for [custom providers](/v7/fundamentals/custom-providers), set the `scope` property in the long-hand form for a provider registration:

```typescript

{
  provide: 'CACHE_MANAGER',
  useClass: CacheManager,
  scope: Scope.TRANSIENT,
}
```

> **Hint** Import the `Scope` enum from `@nestjs/common`

> **Notice** Gateways should not use request-scoped providers because they must act as singletons. Each gateway encapsulates a real socket and cannot be instantiated multiple times.

Singleton scope is used by default, and need not be declared. If you do want to declare a provider as singleton scoped, use the `Scope.DEFAULT` value for the `scope` property.

#### Controller scope[#](/fundamentals/injection-scopes#controller-scope)

Controllers can also have scope, which applies to all request method handlers declared in that controller. Like provider scope, the scope of a controller declares its lifetime. For a request-scoped controller, a new instance is created for each inbound request, and garbage-collected when the request has completed processing.

Declare controller scope with the `scope` property of the `ControllerOptions` object:

```typescript

@Controller({
  path: 'cats',
  scope: Scope.REQUEST,
})
export class CatsController {}
```

#### Scope hierarchy[#](/fundamentals/injection-scopes#scope-hierarchy)

Scope bubbles up the injection chain. A controller that depends on a request-scoped provider will, itself, be request-scoped.

Imagine the following dependency graph: `CatsController <- CatsService <- CatsRepository`. If `CatsService` is request-scoped (and the others are default singletons), the `CatsController` will become request-scoped as it is dependent on the injected service. The `CatsRepository`, which is not dependent, would remain singleton-scoped.

In an HTTP server-based application (e.g., using `@nestjs/platform-express` or `@nestjs/platform-fastify`), you may want to access a reference to the original request object when using request-scoped providers. You can do this by injecting the `REQUEST` object.

```typescript

import { Injectable, Scope, Inject } from '@nestjs/common';
import { REQUEST } from '@nestjs/core';
import { Request } from 'express';

@Injectable({ scope: Scope.REQUEST })
export class CatsService {
  constructor(@Inject(REQUEST) private request: Request) {}
}
```

Because of underlying platform/protocol differences, you access the inbound request slightly differently for Microservice or GraphQL applications. In [GraphQL](/v7/graphql/quick-start) applications, you inject `CONTEXT` instead of `REQUEST`:

```typescript

import { Injectable, Scope, Inject } from '@nestjs/common';
import { CONTEXT } from '@nestjs/graphql';

@Injectable({ scope: Scope.REQUEST })
export class CatsService {
  constructor(@Inject(CONTEXT) private context) {}
}
```

You then configure your `context` value (in the `GraphQLModule`) to contain `request` as its property.

#### Performance[#](/fundamentals/injection-scopes#performance)

Using request-scoped providers will have an impact on application performance. While Nest tries to cache as much metadata as possible, it will still have to create an instance of your class on each request. Hence, it will slow down your average response time and overall benchmarking result. Unless a provider must be request-scoped, it is strongly recommended that you use the default singleton scope.

----
url: https://docs.nestjs.com/data/prisma
----

[Skip to content](#content)

On this page

* [Prisma](https://docs.nestjs.com/data/prisma#prisma)
* [Installation](https://docs.nestjs.com/data/prisma#installation)
* [Set the generator output path](https://docs.nestjs.com/data/prisma#set-the-generator-output-path)
* [Configure the module format](https://docs.nestjs.com/data/prisma#configure-the-module-format)
* [Set the database connection](https://docs.nestjs.com/data/prisma#set-the-database-connection)
* [Models and migrations](https://docs.nestjs.com/data/prisma#models-and-migrations)
* [Generate Prisma Client](https://docs.nestjs.com/data/prisma#generate-prisma-client)
* [PrismaService](https://docs.nestjs.com/data/prisma#prismaservice)
* [Connection lifecycle](https://docs.nestjs.com/data/prisma#connection-lifecycle)
* [PrismaModule](https://docs.nestjs.com/data/prisma#prismamodule)
* [Querying from services](https://docs.nestjs.com/data/prisma#querying-from-services)
* [Transactions](https://docs.nestjs.com/data/prisma#transactions)
* [Testing](https://docs.nestjs.com/data/prisma#testing)
* [Example](https://docs.nestjs.com/data/prisma#example)

### Prisma

[Prisma](https://www.prisma.io) is an [open-source](https://github.com/prisma/prisma) ORM for Node.js and TypeScript. You can use it as an **alternative** to writing plain SQL or to other database access tools, such as SQL query builders (like [knex.js](https://knexjs.org/)) or other ORMs (like [TypeORM](https://typeorm.io/) and [Sequelize](https://sequelize.org/)). Prisma supports PostgreSQL, MySQL, SQL Server, SQLite, CockroachDB, and MongoDB (see [supported databases](https://www.prisma.io/docs/orm/reference/supported-databases)). This chapter uses Prisma ORM 7, which works with the SQL databases; MongoDB projects stay on Prisma ORM 6 for now.

While you can use Prisma with plain JavaScript, it embraces TypeScript and provides a level of type safety that goes beyond the guarantees of other ORMs in the TypeScript ecosystem. See the [comparison of the type safety guarantees of Prisma and TypeORM](https://www.prisma.io/docs/orm/more/comparisons/prisma-and-typeorm#type-safety) for details.

Prisma has no Nest-specific package. Instead, you generate a type-safe client (Prisma Client) from your Prisma schema, wrap it in a provider, and inject that provider wherever you need database access. This chapter sets up that integration with a [SQLite](https://sqlite.org/) database, which needs no database server, and notes the differences for PostgreSQL, MySQL, and SQL Server along the way.

> **Note** For an overview of how Prisma works, follow the [Quickstart](https://www.prisma.io/docs/getting-started/prisma-orm/quickstart/prisma-postgres) or read the [Introduction](https://www.prisma.io/docs/orm/overview/introduction/what-is-prisma) in the [Prisma documentation](https://www.prisma.io/docs). To add Prisma to a project that already has a database, follow the guide for [adding Prisma to an existing project](https://www.prisma.io/docs/getting-started/setup-prisma/add-to-existing-project-typescript-postgres). If you are migrating from TypeORM, read [Migrating from TypeORM to Prisma](https://www.prisma.io/docs/guides/migrate-from-typeorm).

#### Installation[#](/data/prisma#installation)

Install the [Prisma CLI](https://www.prisma.io/docs/orm/tools/prisma-cli) and `dotenv` as development dependencies, then install Prisma Client and the driver adapter for your database. For SQLite, the `@prisma/adapter-better-sqlite3` adapter also installs the `better-sqlite3` driver:

```bash

$ npm install prisma@7 dotenv --save-dev
$ npm install @prisma/client@7 @prisma/adapter-better-sqlite3
```

> **Warning** Install Prisma ORM 7 explicitly, as shown above. At the time of writing, the `latest` tag of the `prisma` package on npm points to a Prisma 8 pre-release, which is a different CLI that doesn't provide the `prisma migrate` and `prisma generate` commands used in this chapter. Keep `prisma` and `@prisma/client` on the same major version.

Expand if you're using PostgreSQL, MySQL, SQL Server, or Azure SQL

Install the adapter for your database instead of `@prisma/adapter-better-sqlite3`. Each adapter package includes its database driver.

* For PostgreSQL:

```bash

$ npm install @prisma/adapter-pg
```

* For MySQL (and MariaDB):

```bash

$ npm install @prisma/adapter-mariadb
```

* For SQL Server and Azure SQL:

```bash

$ npm install @prisma/adapter-mssql
```

Next, create the initial Prisma setup with the `init` command. Prefix Prisma CLI commands with `npx` so that they run the version installed in your project:

```bash

$ npx prisma init --datasource-provider sqlite --output ../src/generated/prisma
```

This command creates the following files:

* `prisma/schema.prisma`: Contains your database schema, including the data source provider and the Prisma Client generator
* `prisma7.config.ts`: The Prisma configuration file, created in the project root. It sets the location of the schema and migrations, and reads the database connection URL from the `DATABASE_URL` environment variable. Prisma ORM releases before 7.10 name this file `prisma.config.ts`, which Prisma still recognizes.
* `.env`: A [dotenv](https://github.com/motdotla/dotenv) file that stores the database connection URL in the `DATABASE_URL` environment variable

It also adds `.env` and the generated client directory to your `.gitignore` file.

#### Set the generator output path[#](/data/prisma#set-the-generator-output-path)

Prisma Client is generated into the directory set by the `output` field of the `generator` block, relative to the schema file. The `--output` option above places the client inside `src`, so that it's compiled along with the rest of your application. Without the option, `prisma init` sets the path to `../generated/prisma`, which is outside of `src`. You can also set the path directly in your Prisma schema:

```groovy

generator client {
  provider = "prisma-client"
  output   = "../src/generated/prisma"
}
```

Because the generated client is excluded from version control, run `npx prisma generate` before you build the application in a fresh checkout or in CI.

#### Configure the module format[#](/data/prisma#configure-the-module-format)

Prisma infers the module format of the generated client from your `tsconfig.json` file. A NestJS project that uses ES modules (the default for new projects) gets an ES module client, so it needs no extra configuration.

If your project uses CommonJS, set `moduleFormat` in the generator to `cjs`:

```groovy

generator client {
  provider     = "prisma-client"
  output       = "../src/generated/prisma"
  moduleFormat = "cjs"
}
```

> **Note** The generated ESM client relies on `import.meta`, which isn't available in CommonJS. Releases before Prisma ORM 7.10 generate an ES module whenever `tsconfig.json` sets `module` to `nodenext`, even in a CommonJS project, so set `moduleFormat` explicitly rather than relying on the inference.

#### Set the database connection[#](/data/prisma#set-the-database-connection)

The `datasource` block in your `schema.prisma` file defines which database you use. With the `--datasource-provider sqlite` option, `prisma init` sets its `provider` field to `sqlite` (the default is `postgresql`):

```groovy

datasource db {
  provider = "sqlite"
}
```

The connection URL itself isn't part of the schema: the Prisma configuration file reads it from the `DATABASE_URL` environment variable, which `prisma init` sets in `.env`:

```bash

DATABASE_URL="file:./dev.db"
```

A SQLite database is a plain file, so instead of a *host* and *port*, the connection URL points to a local file, in this case `dev.db` in the project root. Prisma creates the file when you run the first migration.

The Prisma CLI loads `.env` through the `dotenv/config` import at the top of the Prisma configuration file. Your NestJS application doesn't load `.env` automatically, though. Install the `@nestjs/config` package and register the [`ConfigModule`](/application/configuration) globally in your `AppModule`, so that `PrismaService` can read `DATABASE_URL` through `ConfigService`:

```bash

$ npm install @nestjs/config
```

```typescript

import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';

@Module({
  imports: [ConfigModule.forRoot({ isGlobal: true })],
})
export class AppModule {}
```

Expand if you're using PostgreSQL, MySQL, SQL Server, or Azure SQL

With PostgreSQL, MySQL, and SQL Server, the connection URL points to the *database server*. Pass the matching provider to `prisma init` (e.g., `--datasource-provider postgresql`), or change the `provider` field of the `datasource` block, and set `DATABASE_URL` in `.env`. See the [connection URL reference](https://www.prisma.io/docs/orm/reference/connection-urls) for the required format.

**PostgreSQL**

```groovy

datasource db {
  provider = "postgresql"
}
```

```bash

DATABASE_URL="postgresql://USER:PASSWORD@HOST:PORT/DATABASE?schema=SCHEMA"
```

Replace the uppercase placeholders with your database credentials. If you're unsure what to provide for the `SCHEMA` placeholder, it's most likely the default value `public`. If you don't have a PostgreSQL server yet, run `npx prisma dev` to start a local Prisma Postgres database in your terminal.

**MySQL**

```groovy

datasource db {
  provider = "mysql"
}
```

```bash

DATABASE_URL="mysql://USER:PASSWORD@HOST:PORT/DATABASE"
```

Replace the uppercase placeholders with your database credentials.

**Microsoft SQL Server / Azure SQL Server**

```groovy

datasource db {
  provider = "sqlserver"
}
```

```bash

DATABASE_URL="sqlserver://HOST:PORT;database=DATABASE;user=USER;password=PASSWORD;encrypt=true"
```

Replace the uppercase placeholders with your database credentials. If you're unsure what to provide for the `encrypt` option, it's most likely the default value `true`.

#### Models and migrations[#](/data/prisma#models-and-migrations)

[Prisma Migrate](https://www.prisma.io/docs/orm/prisma-migrate/getting-started) generates SQL migration files from the declarative data model in your Prisma schema. These migration files are fully customizable, so you can configure additional features of the underlying database or include additional commands (e.g., for seeding).

This chapter uses two models. Add them to your `schema.prisma` file:

```groovy

model User {
  id    Int     @default(autoincrement()) @id
  email String  @unique
  name  String?
  posts Post[]
}

model Post {
  id        Int      @default(autoincrement()) @id
  title     String
  content   String?
  published Boolean? @default(false)
  author    User?    @relation(fields: [authorId], references: [id])
  authorId  Int?
}
```

Then generate the first migration and run it against the database:

```bash

$ npx prisma migrate dev --name init
```

The `prisma migrate dev` command generates SQL files and runs them against the database directly. Because the database doesn't exist yet, it also creates the `dev.db` file. The migration files are created in the `prisma` directory:

```bash

$ tree prisma
prisma
├── migrations
│   ├── 20201207100915_init
│   │   └── migration.sql
│   └── migration_lock.toml
└── schema.prisma
```

Expand to view the generated SQL statements

The following tables were created in your SQLite database:

```sql

-- CreateTable
CREATE TABLE "User" (
    "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
    "email" TEXT NOT NULL,
    "name" TEXT
);

-- CreateTable
CREATE TABLE "Post" (
    "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
    "title" TEXT NOT NULL,
    "content" TEXT,
    "published" BOOLEAN DEFAULT false,
    "authorId" INTEGER,
    CONSTRAINT "Post_authorId_fkey" FOREIGN KEY ("authorId") REFERENCES "User" ("id") ON DELETE SET NULL ON UPDATE CASCADE
);

-- CreateIndex
CREATE UNIQUE INDEX "User_email_key" ON "User"("email");
```

#### Generate Prisma Client[#](/data/prisma#generate-prisma-client)

Prisma Client is a type-safe database client that's *generated* from your Prisma schema. This approach lets Prisma Client expose [CRUD](https://www.prisma.io/docs/orm/prisma-client/queries/crud) operations that are *tailored* specifically to your models. Generate the client and its types with the `generate` command:

```bash

$ npx prisma generate
```

`prisma migrate dev` doesn't run this command for you. Whenever you change your schema, rerun `prisma generate` to keep the client and its types in sync.

The generated `client.ts` file is the entry point of the client. It exports the `PrismaClient` class, a type for each model (e.g., `User` and `Post`), and the `Prisma` namespace, which contains the input types for queries (e.g., `Prisma.UserCreateInput`). Like any other relative import in an ESM project, import it with a `.js` extension (`./generated/prisma/client.js`).

#### PrismaService[#](/data/prisma#prismaservice)

In a NestJS application, you expose Prisma Client through a provider. Create a `PrismaService` class that extends `PrismaClient`, so that the service has the full Prisma Client API, and pass the driver adapter for your database to the `PrismaClient` constructor. Prisma ORM 7 requires a driver adapter (or a Prisma Accelerate URL) to create a client.

Create a `prisma.service.ts` file in the `src/prisma` directory:

```typescript

import { Injectable, OnModuleDestroy, OnModuleInit } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { PrismaBetterSqlite3 } from '@prisma/adapter-better-sqlite3';
import { PrismaClient } from '../generated/prisma/client.js';

@Injectable()
export class PrismaService
  extends PrismaClient
  implements OnModuleInit, OnModuleDestroy
{
  constructor(configService: ConfigService) {
    const adapter = new PrismaBetterSqlite3({
      url: configService.getOrThrow<string>('DATABASE_URL'),
    });
    super({ adapter });
  }

  async onModuleInit() {
    await this.$connect();
  }

  async onModuleDestroy() {
    await this.$disconnect();
  }
}
```

The constructor reads `DATABASE_URL` through `ConfigService` before it calls `super()`. The `getOrThrow()` method throws an error if the variable isn't set, so a missing connection URL stops the application at startup. The `onModuleInit()` and `onModuleDestroy()` hooks manage the connection, as described in [Connection lifecycle](/data/prisma#connection-lifecycle).

> **Hint** If you don't use `@nestjs/config`, start Node.js with the `--env-file=.env` flag and read `process.env.DATABASE_URL` in the constructor instead.

Expand if you're using PostgreSQL, MySQL, SQL Server, or Azure SQL

Replace `PrismaBetterSqlite3` with the adapter class for your database (`PrismaPg`, `PrismaMariaDb`, or `PrismaMssql`), and pass it the connection settings its driver expects. Each of these adapters also accepts a connection string. For example, with PostgreSQL:

```typescript

import { PrismaPg } from '@prisma/adapter-pg';

// inside the PrismaService constructor
const adapter = new PrismaPg({
  connectionString: configService.getOrThrow<string>('DATABASE_URL'),
});
super({ adapter });
```

#### Connection lifecycle[#](/data/prisma#connection-lifecycle)

Prisma Client connects lazily, when it sends the first query. Calling `$connect()` in the `onModuleInit()` hook connects during application bootstrap instead, so a misconfigured connection fails at startup rather than on the first request.

Calling `$disconnect()` in the `onModuleDestroy()` hook closes the connection when the application shuts down. It also disposes of the driver adapter, which closes the underlying driver connection (for example, it ends the connection pool that `PrismaPg` creates). Nest calls `onModuleDestroy()` when you call `app.close()`. To also call it when the process receives a termination signal, such as `SIGTERM`, enable shutdown hooks in your `main.ts` file:

```typescript

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module.js';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.enableShutdownHooks();
  await app.listen(process.env.PORT ?? 3000);
}
await bootstrap();
```

See [Application shutdown](/fundamentals/lifecycle-events#application-shutdown) to learn more about shutdown hooks.

> **Hint** Prisma ORM 7 doesn't support the `beforeExit` event (`$on('beforeExit', ...)`) that older Prisma integrations used to close the application. Use the Nest lifecycle hooks shown above instead.

#### PrismaModule[#](/data/prisma#prismamodule)

Register `PrismaService` in a dedicated module that exports it. Create a `prisma.module.ts` file next to the service:

```typescript

import { Module } from '@nestjs/common';
import { PrismaService } from './prisma.service.js';

@Module({
  providers: [PrismaService],
  exports: [PrismaService],
})
export class PrismaModule {}
```

Import `PrismaModule` into every module that needs database access. Providers are singletons by default, so all importing modules share the same `PrismaService` instance and its connection.

> **Hint** If most of your modules need database access, you can decorate `PrismaModule` with `@Global()` and import it only once, in your root module. See [Global modules](/modules#global-modules) for the trade-offs.

#### Querying from services[#](/data/prisma#querying-from-services)

With `PrismaModule` in place, inject `PrismaService` into your providers and query the database through its model properties, such as `this.prisma.user`. The following `UsersService` wraps the CRUD queries for the `User` model:

```typescript

import { Injectable } from '@nestjs/common';
import { PrismaService } from '../prisma/prisma.service.js';
import { Prisma, User } from '../generated/prisma/client.js';

@Injectable()
export class UsersService {
  constructor(private readonly prisma: PrismaService) {}

  async user(where: Prisma.UserWhereUniqueInput): Promise<User | null> {
    return this.prisma.user.findUnique({ where });
  }

  async users(params: {
    skip?: number;
    take?: number;
    cursor?: Prisma.UserWhereUniqueInput;
    where?: Prisma.UserWhereInput;
    orderBy?: Prisma.UserOrderByWithRelationInput;
  }): Promise<User[]> {
    const { skip, take, cursor, where, orderBy } = params;
    return this.prisma.user.findMany({ skip, take, cursor, where, orderBy });
  }

  async createUser(data: Prisma.UserCreateInput): Promise<User> {
    return this.prisma.user.create({ data });
  }

  async updateUser(params: {
    where: Prisma.UserWhereUniqueInput;
    data: Prisma.UserUpdateInput;
  }): Promise<User> {
    const { where, data } = params;
    return this.prisma.user.update({ data, where });
  }

  async deleteUser(where: Prisma.UserWhereUniqueInput): Promise<User> {
    return this.prisma.user.delete({ where });
  }
}
```

The service uses the generated types for its parameters and return values, so you don't need to write separate interfaces for your models. In a real-world application, the service is also the place for your business logic. For example, a `UsersService` could have an `updatePassword()` method responsible for updating a user's password.

A controller then exposes the service through route handlers:

```typescript

import {
  Body,
  Controller,
  Delete,
  Get,
  Param,
  ParseIntPipe,
  Post,
  Query,
} from '@nestjs/common';
import { UsersService } from './users.service.js';
import { User as UserModel } from '../generated/prisma/client.js';

@Controller('users')
export class UsersController {
  constructor(private readonly usersService: UsersService) {}

  @Get()
  async findAll(@Query('search') search?: string): Promise<UserModel[]> {
    return this.usersService.users({
      where: search
        ? {
            OR: [
              { name: { contains: search } },
              { email: { contains: search } },
            ],
          }
        : undefined,
      orderBy: { id: 'asc' },
    });
  }

  @Get(':id')
  async findOne(
    @Param('id', ParseIntPipe) id: number,
  ): Promise<UserModel | null> {
    return this.usersService.user({ id });
  }

  @Post()
  async create(
    @Body() userData: { name?: string; email: string },
  ): Promise<UserModel> {
    return this.usersService.createUser(userData);
  }

  @Delete(':id')
  async remove(@Param('id', ParseIntPipe) id: number): Promise<UserModel> {
    return this.usersService.deleteUser({ id });
  }
}
```

> **Hint** The generated types exist only at compile time, so the `ValidationPipe` can't use them to validate request payloads. To validate a request body, declare a DTO class, as described in [Validation](/application/validation).

Finally, register the controller and the service in a `UsersModule` that imports `PrismaModule`, and import `UsersModule` into your `AppModule`:

```typescript

import { Module } from '@nestjs/common';
import { PrismaModule } from '../prisma/prisma.module.js';
import { UsersController } from './users.controller.js';
import { UsersService } from './users.service.js';

@Module({
  imports: [PrismaModule],
  controllers: [UsersController],
  providers: [UsersService],
})
export class UsersModule {}
```

#### Transactions[#](/data/prisma#transactions)

Prisma Client offers several ways to run queries in a transaction (see [Transactions and batch queries](https://www.prisma.io/docs/orm/prisma-client/queries/transactions)):

* **Nested writes**, which create or update a record together with related records in a single query, run in a transaction automatically.
* **Sequential operations**: pass an array of queries to `$transaction()`. Prisma runs them in order, in a single transaction, and resolves to an array with their results.
* **Interactive transactions**: pass an async function to `$transaction()`. Prisma commits the transaction when the function resolves and rolls it back when it throws.

The following methods show the last two forms in the `UsersService`:

```typescript

async publishedPosts(skip: number, take: number) {
  const [posts, total] = await this.prisma.$transaction([
    this.prisma.post.findMany({ where: { published: true }, skip, take }),
    this.prisma.post.count({ where: { published: true } }),
  ]);
  return { posts, total };
}

async deleteUserWithPosts(id: number): Promise<User> {
  return this.prisma.$transaction(async (tx) => {
    await tx.post.deleteMany({ where: { authorId: id } });
    return tx.user.delete({ where: { id } });
  });
}
```

Inside an interactive transaction, send every query through the transaction client (`tx`) that Prisma passes to the function. Queries sent through `this.prisma` run outside the transaction. Both forms of `$transaction()` accept an options object as the second argument, with the `maxWait`, `timeout`, and `isolationLevel` properties.

Passing `tx` through every method that takes part in a transaction couples your services to one another. To declare transaction boundaries with a decorator instead, use the transactional plugin of the [`nestjs-cls`](/recipes/async-local-storage#nestjs-cls) package with its [Prisma adapter](https://papooch.github.io/nestjs-cls/plugins/available-plugins/transactional/prisma-adapter) (`@nestjs-cls/transactional-adapter-prisma`). It keeps the active transaction client in async local storage and provides a `@Transactional()` decorator and an injectable `TransactionHost`.

#### Testing[#](/data/prisma#testing)

When you unit test a provider that depends on `PrismaService`, you usually want to avoid a database connection. Because `PrismaService` is a regular class provider, you can replace it with a mock using the class itself as the injection token and any of the standard [custom provider](/fundamentals/custom-providers) techniques, such as `useValue`:

```typescript

import { Test } from '@nestjs/testing';
import { vi } from 'vitest';
import { PrismaService } from '../prisma/prisma.service.js';
import { UsersService } from './users.service.js';

describe('UsersService', () => {
  let usersService: UsersService;
  const prismaMock = {
    user: {
      findUnique: vi.fn(),
    },
  };

  beforeEach(async () => {
    const moduleRef = await Test.createTestingModule({
      providers: [
        UsersService,
        { provide: PrismaService, useValue: prismaMock },
      ],
    }).compile();

    usersService = moduleRef.get(UsersService);
  });

  it('returns a user by id', async () => {
    const user = { id: 1, email: 'alice@prisma.io', name: 'Alice' };
    prismaMock.user.findUnique.mockResolvedValue(user);

    expect(await usersService.user({ id: 1 })).toEqual(user);
    expect(prismaMock.user.findUnique).toHaveBeenCalledWith({
      where: { id: 1 },
    });
  });
});
```

The mock replaces `PrismaService` entirely, so its `onModuleInit()` hook doesn't run and the test never opens a database connection. When you test a module that imports `PrismaModule`, replace the provider with `overrideProvider(PrismaService)` instead. See [Testing](/fundamentals/testing) for more testing utilities.

#### Example[#](/data/prisma#example)

Ready-to-run example projects for [REST](https://github.com/prisma/prisma-examples/tree/b53fad046a6d55f0090ddce9fd17ec3f9b95cab3/orm/nest) and [GraphQL](https://github.com/prisma/prisma-examples/tree/b53fad046a6d55f0090ddce9fd17ec3f9b95cab3/orm/nest-graphql) are available in the [`prisma-examples`](https://github.com/prisma/prisma-examples/) repository. For more resources, see [NestJS & Prisma](https://www.prisma.io/nestjs) on the Prisma website.

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/data/prisma.md)

----
url: https://docs.nestjs.com/v9/openapi/other-features
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Other features](https://docs.nestjs.com/v9/openapi/other-features#other-features)
* [Global prefix](https://docs.nestjs.com/v9/openapi/other-features#global-prefix)
* [Multiple specifications](https://docs.nestjs.com/v9/openapi/other-features#multiple-specifications)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/openapi/other-features.md "Suggest Edits")

### Other features

This page lists all the other available features that you may find useful.

#### Global prefix[#](/openapi/other-features#global-prefix)

To ignore a global prefix for routes set through `setGlobalPrefix()`, use `ignoreGlobalPrefix`:

```typescript

const document = SwaggerModule.createDocument(app, options, {
  ignoreGlobalPrefix: true,
});
```

#### Multiple specifications[#](/openapi/other-features#multiple-specifications)

The `SwaggerModule` provides a way to support multiple specifications. In other words, you can serve different documentation, with different UIs, on different endpoints.

To support multiple specifications, your application must be written with a modular approach. The `createDocument()` method takes a 3rd argument, `extraOptions`, which is an object with a property named `include`. The `include` property takes a value which is an array of modules.

You can setup multiple specifications support as shown below:

```typescript

import { NestFactory } from '@nestjs/core';
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
import { AppModule } from './app.module';
import { CatsModule } from './cats/cats.module';
import { DogsModule } from './dogs/dogs.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);

  /**
   * createDocument(application, configurationOptions, extraOptions);
   *
   * createDocument method takes an optional 3rd argument "extraOptions"
   * which is an object with "include" property where you can pass an Array
   * of Modules that you want to include in that Swagger Specification
   * E.g: CatsModule and DogsModule will have two separate Swagger Specifications which
   * will be exposed on two different SwaggerUI with two different endpoints.
   */

  const options = new DocumentBuilder()
    .setTitle('Cats example')
    .setDescription('The cats API description')
    .setVersion('1.0')
    .addTag('cats')
    .build();

  const catDocument = SwaggerModule.createDocument(app, options, {
    include: [CatsModule],
  });
  SwaggerModule.setup('api/cats', app, catDocument);

  const secondOptions = new DocumentBuilder()
    .setTitle('Dogs example')
    .setDescription('The dogs API description')
    .setVersion('1.0')
    .addTag('dogs')
    .build();

  const dogDocument = SwaggerModule.createDocument(app, secondOptions, {
    include: [DogsModule],
  });
  SwaggerModule.setup('api/dogs', app, dogDocument);

  await app.listen(3000);
}
bootstrap();
```

Now you can start your server with the following command:

```bash

$ npm run start
```

Navigate to `http://localhost:3000/api/cats` to see the Swagger UI for cats:

In turn, `http://localhost:3000/api/dogs` will expose the Swagger UI for dogs:

----
url: https://docs.nestjs.com/v5/modules
----

### Modules

A module is a class annotated with a `@Module()` decorator. The `@Module()` decorator provides metadata that **Nest** makes use of to organize the application structure.

Each application has at least one module, a **root module**. The root module is the place where Nest is starting to arrange the application tree. In fact, the root module could be the only module in your application, especially when the app is small. For large applications however, it doesn't make sense. In most cases, you'll have several modules, each with a closely related set of **capabilities**.

The `@Module()` decorator takes a single object whose properties describe the module:

|               |                                                                                                             |
| ------------- | ----------------------------------------------------------------------------------------------------------- |
| `providers`   | the providers that will be instantiated by the Nest injector and may be shared at least across this module. |
| `controllers` | the set of controllers which have to be created                                                             |
| `imports`     | the list of imported modules that export the providers which are required in this module                    |
| `exports`     | the subset of `providers` that are provided by this module and should be available in the other modules     |

The module **encapsulates** providers by default. It means that it's impossible to inject providers that are neither directly part of the current module nor they're exported from the imported modules.

#### Feature modules

The `CatsController` and `CatsService` belong to the same application domain. We shall consider to move them to a feature module, being the `CatsModule`.

cats/cats.module.ts

JS TS

TypeScript

```typescript

import { Module } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

@Module({
  controllers: [CatsController],
  providers: [CatsService],
})
export class CatsModule {}
```

> **Hint** To create a module using CLI, simply execute `$ nest g module cats` command.

We defined the `cats.module.ts` file and after that moved everything related to this module into the `cats` directory. The last thing we need to do is import this module into the root module (`ApplicationModule`).

app.module.ts

JS TS

TypeScript

```typescript

import { Module } from '@nestjs/common';
import { CatsModule } from './cats/cats.module';

@Module({
  imports: [CatsModule],
})
export class ApplicationModule {}
```

Thanks to that Nest knows that besides `ApplicationModule`, it's essential to register the `CatsModule` as well. That's how our directory structure looks right now:

#### Shared module

In Nest, modules **are singletons** by default, and thus you can share the **same instance** of any provider between 2..\* modules effortlessly.

Every module is a **shared module** in fact. Once created it can be reused by any module. Let's imagine that we want to share the `CatsService` instance between few other modules. In order to do that, we need to put the `CatsService` into `exports` array as shown below:

cats.module.ts

JS TS

TypeScript

```typescript

import { Module } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

@Module({
  controllers: [CatsController],
  providers: [CatsService],
  exports: [CatsService]
})
export class CatsModule {}
```

Now each module which would import the `CatsModule` has an access to the `CatsService` and will share the same instance with all of the modules that import this module as well.

#### Modules re-exporting

The modules can export their internal providers. Moreover, they can re-export modules imported by themselves.

JS TS

TypeScript

```typescript

@Module({
  imports: [CommonModule],
  exports: [CommonModule],
})
export class CoreModule {}
```

#### Dependency injection

A module class can **inject** providers as well (e.g. for configuration purposes):

cats.module.ts

JS TS

TypeScript

```typescript

import { Module } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

@Module({
  controllers: [CatsController],
  providers: [CatsService],
})
export class CatsModule {
  constructor(private readonly catsService: CatsService) {}
}
```

TypeScript

```typescript

import { Module, Dependencies } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

@Module({
  controllers: [CatsController],
  providers: [CatsService],
})
@Dependencies(CatsService)
export class CatsModule {
  constructor(catsService) {
    this.catsService = catsService;
  }
}
```

However, module classes cannot be injected by the providers due to [circular dependency ](/fundamentals/circular-dependency).

#### Global modules

If you have to import the same set of modules everywhere, it might be annoying. In [Angular](https://angular.io), the `providers` are registered in the global scope. Once defined, they're available everywhere. On the other hand, Nest encapsulates providers inside the module scope. You aren't able to use the module providers elsewhere without importing them. But sometimes, you may just want to provide a set of things which should be available always - out-of-the-box, for example: helpers, database connection, whatever. That's why you're able to make the module a **global** one.

JS TS

TypeScript

```typescript

import { Module, Global } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

@Global()
@Module({
  controllers: [CatsController],
  providers: [CatsService],
  exports: [CatsService]
})
export class CatsModule {}
```

The `@Global()` decorator makes the module global-scoped. Global modules shall be registered **only once&#x20;**, in best case by the root or core module. Afterward, the `CatsService` provider will be ubiquitous, although `CatsModule` won't be imported.

> **Hint** Making everything global is not a good decision. The global modules are available to reduce the amount of necessary boilerplate. The `imports` array is still the best way to make the module API transparent.

#### Dynamic modules

The Nest module system comes with a feature called **dynamic modules**. It enables you to create customizable modules without any effort. Let's have a look at the `DatabaseModule`:

JS TS

TypeScript

```typescript

import { Module, DynamicModule } from '@nestjs/common';
import { createDatabaseProviders } from './database.providers';
import { Connection } from './connection.provider';

@Module({
  providers: [Connection],
})
export class DatabaseModule {
  static forRoot(entities = [], options?): DynamicModule {
    const providers = createDatabaseProviders(options, entities);
    return {
      module: DatabaseModule,
      providers: providers,
      exports: providers,
    };
  }
}
```

TypeScript

```typescript

import { Module } from '@nestjs/common';
import { createDatabaseProviders } from './database.providers';
import { Connection } from './connection.provider';

@Module({
  providers: [Connection],
})
export class DatabaseModule {
  static forRoot(entities = [], options?) {
    const providers = createDatabaseProviders(options, entities);
    return {
      module: DatabaseModule,
      providers: providers,
      exports: providers,
    };
  }
}
```

> **Hint** The `forRoot()` may return dynamic module either synchronously or asynchronously (`Promise`).

This module defines the `Connection` provider by default, but additionally - depending on the passed `options` and `entities` - it exposes a collection of the providers, for example, repositories. In fact, the dynamic module **extends** the base module metadata. This substantial feature is useful when you need to register providers dynamically. Then you could import the `DatabaseModule` in the following manner:

TypeScript

```typescript

import { Module } from '@nestjs/common';
import { DatabaseModule } from './database/database.module';
import { User } from './users/entities/user.entity';

@Module({
  imports: [
    DatabaseModule.forRoot([User]),
  ],
})
export class ApplicationModule {}
```

In order to export dynamic module, you can omit a function call part:

TypeScript

```typescript

import { Module } from '@nestjs/common';
import { DatabaseModule } from './database/database.module';
import { User } from './users/entities/user.entity';

@Module({
  imports: [
    DatabaseModule.forRoot([User]),
  ],
  exports: [DatabaseModule]
})
export class ApplicationModule {}
```

* Modules
* Feature modules
* Shared module
* Modules re-exporting
* Dependency injection
* Global modules
* Dynamic modules

----
url: https://docs.nestjs.com/v11/deployment
----

* [Deployment](https://docs.nestjs.com/v11/deployment#deployment)
* [Prerequisites](https://docs.nestjs.com/v11/deployment#prerequisites)
* [Building your application](https://docs.nestjs.com/v11/deployment#building-your-application)
* [Production environment](https://docs.nestjs.com/v11/deployment#production-environment)
* [NODE\_ENV=production](https://docs.nestjs.com/v11/deployment#node_envproduction)
* [Running your application](https://docs.nestjs.com/v11/deployment#running-your-application)
* [Health checks](https://docs.nestjs.com/v11/deployment#health-checks)
* [Logging](https://docs.nestjs.com/v11/deployment#logging)
* [Observability](https://docs.nestjs.com/v11/deployment#observability)
* [Scaling up or out](https://docs.nestjs.com/v11/deployment#scaling-up-or-out)
* [Some other tips](https://docs.nestjs.com/v11/deployment#some-other-tips)
* [Dockerizing your application](https://docs.nestjs.com/v11/deployment#dockerizing-your-application)
* [Easy deployment with Mau](https://docs.nestjs.com/v11/deployment#easy-deployment-with-mau)

> **Hint** If you are looking for a cloud-based platform to deploy your NestJS application, check out [Mau](https://mau.nestjs.com/ "Deploy Nest"), our official platform for deploying NestJS applications on AWS. With Mau, deploying your NestJS application is as simple as clicking a few buttons and running a single command:
>
> ```bash
>
> $ npm install -g @nestjs/mau
> $ mau deploy
> ```
>
> Once the deployment is complete, you'll have your NestJS application up and running on AWS in seconds!

#### Building your application[#](/deployment#building-your-application)

To build your NestJS application, you need to compile your TypeScript code into JavaScript. This process generates a `dist` directory containing the compiled files. You can build your application by running the following command:

```bash

$ npm run build
```

This command typically runs the `nest build` command under the hood, which is basically a wrapper around the TypeScript compiler with some additional features (assets copying, etc.). In case you have a custom build script, you can run it directly. Also, for NestJS CLI mono-repos, make sure to pass the name of the project to build as an argument (`npm run build my-app`).

Upon successful compilation, you should see a `dist` directory in your project root containing the compiled files, with the entry point being `main.js`. If you have any `.ts` files located in the root directory of your project (and your `tsconfig.json` configured to compile them), they will be copied to the `dist` directory as well, modifying the directory structure a bit (instead of `dist/main.js`, you will have `dist/src/main.js` so keep that in mind when configuring your server).

#### Production environment[#](/deployment#production-environment)

Your production environment is where your application will be accessible to external users. This could be a cloud-based platform like [AWS](https://aws.amazon.com/) (with EC2, ECS, etc.), [Azure](https://azure.microsoft.com/), or [Google Cloud](https://cloud.google.com/), or even a dedicated server you manage, such as [Hetzner](https://www.hetzner.com/).

To simplify the deployment process and avoid manual setup, you can use a service like [Mau](https://mau.nestjs.com/ "Deploy Nest"), our official platform for deploying NestJS applications on AWS. For more details, check out [this section](/v11/deployment/todo).

```bash

$ NODE_ENV=production node dist/main.js
```

Or just set it in your cloud provider's/Mau dashboard.

#### Running your application[#](/deployment#running-your-application)

To run your NestJS application in production, just use the following command:

```bash

$ node dist/main.js # Adjust this based on your entry point location
```

This command starts your application, which will listen on the specified port (usually `3000` by default). Ensure that this matches the port you’ve configured in your application.

Alternatively, you can use the `nest start` command. This command is a wrapper around `node dist/main.js`, but it has one key difference: it automatically runs `nest build` before starting the application, so you don’t need to manually execute `npm run build`.

#### Health checks[#](/deployment#health-checks)

Health checks are essential for monitoring the health and status of your NestJS application in production. By setting up a health check endpoint, you can regularly verify that your app is running as expected and respond to issues before they become critical.

In NestJS, you can easily implement health checks using the **@nestjs/terminus** package, which provides a powerful tool for adding health checks, including database connections, external services, and custom checks.

Check out [this guide](/v11/recipes/terminus) to learn how to implement health checks in your NestJS application, and ensure your app is always monitored and responsive.

> **Hint** If you're using [AWS](https://aws.amazon.com/) (with [Mau](https://mau.nestjs.com/ "Deploy Nest") or directly), consider JSON logging to make it easier to parse and analyze your logs.

For distributed applications, using a centralized logging service like ElasticSearch, Loggly, or Datadog can be incredibly useful. These tools offer powerful features like log aggregation, search, and visualization, making it easier to monitor and analyze your application's performance and behavior.

#### Observability[#](/deployment#observability)

Health checks and logs tell you whether the application is up; they don't tell you which route got slower after the last deploy, which class is burning the time, or which line threw. For that, instrument the application with [NestJS Observe](https://www.observe.nestjs.com/ "NestJS Observe"), our official observability platform: install the `@nestjs/observe` SDK, pass an API key, and requests, jobs, errors, logs, and traces start streaming to a dashboard with no manual span wiring or collector to run.

```typescript

const app = await NestFactory.create(AppModule, {
  instrument: ObserveInstrument,
});
```

See the [Observability](/v11/observability/overview) chapter for the full setup, including versioning deployments with `serviceVersion` so each release is compared against the one before it.

> **Hint**[Mau](https://mau.nestjs.com/ "Deploy Nest") offers built-in support for horizontal scaling on AWS, allowing you to easily deploy multiple instances of your NestJS application and manage them with just a few clicks.

* **Rate limiting**: Implement rate limiting to prevent abuse and protect your application from DDoS attacks. Check out [Rate limiting chapter](/v11/security/rate-limiting) for more details, or use a service like [AWS WAF](https://aws.amazon.com/waf/) for advanced protection.

```bash

# Use the official Node.js image as the base image
FROM node:20

# Set the working directory inside the container
WORKDIR /usr/src/app

# Copy package.json and package-lock.json to the working directory
COPY package*.json ./

# Install the application dependencies
RUN npm install

# Copy the rest of the application files
COPY . .

# Build the NestJS application
RUN npm run build

# Expose the application port
EXPOSE 3000

# Command to run the application
CMD ["node", "dist/main"]
```

> **Hint** Make sure to replace `node:20` with the appropriate Node.js version you're using in your project. You can find the available Node.js Docker images on the [official Docker Hub repository](https://hub.docker.com/_/node).

This is a basic Dockerfile that sets up a Node.js environment, installs the application dependencies, builds the NestJS application, and runs it. You can customize this file based on your project requirements (e.g., use different base images, optimize the build process, only install production dependencies, etc.).

Let's also create a `.dockerignore` file to specify which files and directories Docker should ignore when building the image. Create a `.dockerignore` file in your project root:

```bash

node_modules
dist
*.log
*.md
.git
```

This file ensures that unnecessary files are not included in the container image, keeping it lightweight. Now that you have your Dockerfile set up, you can build your Docker image. Open your terminal, navigate to your project directory, and run the following command:

```bash

docker build -t my-nestjs-app .
```

In this command:

* `-t my-nestjs-app`: Tags the image with the name `my-nestjs-app`.
* `.`: Indicates the current directory as the build context.

After building the image, you can run it as a container. Execute the following command:

```bash

docker run -p 3000:3000 my-nestjs-app
```

In this command:

* `-p 3000:3000`: Maps port 3000 on your host machine to port 3000 in the container.
* `my-nestjs-app`: Specifies the image to run.

Your NestJS application should now be running inside a Docker container.

If you want to deploy your Docker image to a cloud provider or share it with others, you'll need to push it to a Docker registry (like [Docker Hub](https://hub.docker.com/), [AWS ECR](https://aws.amazon.com/ecr/), or [Google Container Registry](https://cloud.google.com/container-registry)).

Once you decide on a registry, you can push your image by following these steps:

```bash

docker login # Log in to your Docker registry
docker tag my-nestjs-app your-dockerhub-username/my-nestjs-app # Tag your image
docker push your-dockerhub-username/my-nestjs-app # Push your image
```

```bash

$ npm install -g @nestjs/mau
$ mau deploy
```

Sign up today and [Deploy with Mau](https://mau.nestjs.com/ "Deploy Nest") to get your NestJS applications up and running on AWS in minutes!

----
url: https://docs.nestjs.com/v9/graphql/unions-and-enums
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Unions](https://docs.nestjs.com/v9/graphql/unions-and-enums#unions)
* [Code first](https://docs.nestjs.com/v9/graphql/unions-and-enums#code-first)
* [Schema first](https://docs.nestjs.com/v9/graphql/unions-and-enums#schema-first)
* [Enums](https://docs.nestjs.com/v9/graphql/unions-and-enums#enums)
* [Code first](https://docs.nestjs.com/v9/graphql/unions-and-enums#code-first-1)
* [Schema first](https://docs.nestjs.com/v9/graphql/unions-and-enums#schema-first-1)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/unions-and-enums.md "Suggest Edits")

### Unions

Union types are very similar to interfaces, but they don't get to specify any common fields between the types (read more [here](https://graphql.org/learn/schema/#union-types)). Unions are useful for returning disjoint data types from a single field.

#### Code first[#](/graphql/unions-and-enums#code-first)

To define a GraphQL union type, we must define classes that this union will be composed of. Following the [example](https://www.apollographql.com/docs/apollo-server/schema/unions-interfaces/#union-type) from the Apollo documentation, we'll create two classes. First, `Book`:

```typescript

import { Field, ObjectType } from '@nestjs/graphql';

@ObjectType()
export class Book {
  @Field()
  title: string;
}
```

And then `Author`:

```typescript

import { Field, ObjectType } from '@nestjs/graphql';

@ObjectType()
export class Author {
  @Field()
  name: string;
}
```

With this in place, register the `ResultUnion` union using the `createUnionType` function exported from the `@nestjs/graphql` package:

```typescript

export const ResultUnion = createUnionType({
  name: 'ResultUnion',
  types: () => [Author, Book] as const,
});
```

> **Warning** The array returned by the `types` property of the `createUnionType` function should be given a const assertion. If the const assertion is not given, a wrong declaration file will be generated at compile time, and an error will occur when using it from another project.

Now, we can reference the `ResultUnion` in our query:

```typescript

@Query(returns => [ResultUnion])
search(): Array<typeof ResultUnion> {
  return [new Author(), new Book()];
}
```

This will result in generating the following part of the GraphQL schema in SDL:

```graphql

type Author {
  name: String!
}

type Book {
  title: String!
}

union ResultUnion = Author | Book

type Query {
  search: [ResultUnion!]!
}
```

The default `resolveType()` function generated by the library will extract the type based on the value returned from the resolver method. That means returning class instances instead of literal JavaScript object is obligatory.

To provide a customized `resolveType()` function, pass the `resolveType` property to the options object passed into the `createUnionType()` function, as follows:

```typescript

export const ResultUnion = createUnionType({
  name: 'ResultUnion',
  types: () => [Author, Book] as const,
  resolveType(value) {
    if (value.name) {
      return Author;
    }
    if (value.title) {
      return Book;
    }
    return null;
  },
});
```

#### Schema first[#](/graphql/unions-and-enums#schema-first)

To define a union in the schema first approach, simply create a GraphQL union with SDL.

```graphql

type Author {
  name: String!
}

type Book {
  title: String!
}

union ResultUnion = Author | Book
```

Then, you can use the typings generation feature (as shown in the [quick start](/v9/graphql/quick-start) chapter) to generate corresponding TypeScript definitions:

```typescript

export class Author {
  name: string;
}

export class Book {
  title: string;
}

export type ResultUnion = Author | Book;
```

Unions require an extra `__resolveType` field in the resolver map to determine which type the union should resolve to. Also, note that the `ResultUnionResolver` class has to be registered as a provider in any module. Let's create a `ResultUnionResolver` class and define the `__resolveType` method.

```typescript

@Resolver('ResultUnion')
export class ResultUnionResolver {
  @ResolveField()
  __resolveType(value) {
    if (value.name) {
      return 'Author';
    }
    if (value.title) {
      return 'Book';
    }
    return null;
  }
}
```

> **Hint** All decorators are exported from the `@nestjs/graphql` package.

### Enums

Enumeration types are a special kind of scalar that is restricted to a particular set of allowed values (read more [here](https://graphql.org/learn/schema/#enumeration-types)). This allows you to:

* validate that any arguments of this type are one of the allowed values
* communicate through the type system that a field will always be one of a finite set of values

#### Code first[#](/graphql/unions-and-enums#code-first-1)

When using the code first approach, you define a GraphQL enum type by simply creating a TypeScript enum.

```typescript

export enum AllowedColor {
  RED,
  GREEN,
  BLUE,
}
```

With this in place, register the `AllowedColor` enum using the `registerEnumType` function exported from the `@nestjs/graphql` package:

```typescript

registerEnumType(AllowedColor, {
  name: 'AllowedColor',
});
```

Now you can reference the `AllowedColor` in our types:

```typescript

@Field(type => AllowedColor)
favoriteColor: AllowedColor;
```

This will result in generating the following part of the GraphQL schema in SDL:

```graphql

enum AllowedColor {
  RED
  GREEN
  BLUE
}
```

To provide a description for the enum, pass the `description` property into the `registerEnumType()` function.

```typescript

registerEnumType(AllowedColor, {
  name: 'AllowedColor',
  description: 'The supported colors.',
});
```

To provide a description for the enum values, or to mark a value as deprecated, pass the `valuesMap` property, as follows:

```typescript

registerEnumType(AllowedColor, {
  name: 'AllowedColor',
  description: 'The supported colors.',
  valuesMap: {
    RED: {
      description: 'The default color.',
    },
    BLUE: {
      deprecationReason: 'Too blue.',
    },
  },
});
```

This will generate the following GraphQL schema in SDL:

```graphql

"""
The supported colors.
"""
enum AllowedColor {
  """
  The default color.
  """
  RED
  GREEN
  BLUE @deprecated(reason: "Too blue.")
}
```

#### Schema first[#](/graphql/unions-and-enums#schema-first-1)

To define an enumerator in the schema first approach, simply create a GraphQL enum with SDL.

```graphql

enum AllowedColor {
  RED
  GREEN
  BLUE
}
```

Then you can use the typings generation feature (as shown in the [quick start](/v9/graphql/quick-start) chapter) to generate corresponding TypeScript definitions:

```typescript

export enum AllowedColor {
  RED
  GREEN
  BLUE
}
```

Sometimes a backend forces a different value for an enum internally than in the public API. In this example the API contains `RED`, however in resolvers we may use `#f00` instead (read more [here](https://www.apollographql.com/docs/apollo-server/schema/scalars-enums/#internal-values)). To accomplish this, declare a resolver object for the `AllowedColor` enum:

```typescript

export const allowedColorResolver: Record<keyof typeof AllowedColor, any> = {
  RED: '#f00',
};
```

> **Hint** All decorators are exported from the `@nestjs/graphql` package.

Then use this resolver object together with the `resolvers` property of the `GraphQLModule#forRoot()` method, as follows:

```typescript

GraphQLModule.forRoot({
  resolvers: {
    AllowedColor: allowedColorResolver,
  },
});
```

----
url: https://docs.nestjs.com/v6/graphql/quick-start
----

* [Installation](https://docs.nestjs.com/v6/graphql/quick-start#installation)
* [Overview](https://docs.nestjs.com/v6/graphql/quick-start#overview)
* [Getting started with GraphQL & TypeScript](https://docs.nestjs.com/v6/graphql/quick-start#getting-started-with-graphql--typescript)
* [Playground](https://docs.nestjs.com/v6/graphql/quick-start#playground)
* [Multiple endpoints](https://docs.nestjs.com/v6/graphql/quick-start#multiple-endpoints)
* [Schema first](https://docs.nestjs.com/v6/graphql/quick-start#schema-first)
* [Code first](https://docs.nestjs.com/v6/graphql/quick-start#code-first)
* [Async configuration](https://docs.nestjs.com/v6/graphql/quick-start#async-configuration)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/quick-start.md "Suggest Edits")

## Harnessing the power of TypeScript & GraphQL

[GraphQL](https://graphql.org/) is a powerful query language for APIs and a runtime for fulfilling those queries with your existing data. It's an elegant approach that solves many problems typically found with REST APIs. For background, we suggest reading this [comparison](https://dev-blog.apollodata.com/graphql-vs-rest-5d425123e34b) between GraphQL and REST.

GraphQL combined with [TypeScript](https://www.typescriptlang.org/) helps you develop better type safety with your GraphQL queries, giving you get end-to-end typing.

In this chapter, we assume a basic understanding of GraphQL, and focus on how to work with the built-in `@nestjs/graphql` module. The `GraphQLModule` is a wrapper around the [Apollo](https://www.apollographql.com/) server. We use this proven GraphQL package to provide a way to use GraphQL with Nest.

#### Installation[#](/graphql/quick-start#installation)

Start by installing the required packages:

```bash

$ npm i --save @nestjs/graphql graphql-tools graphql
```

And depending on what you use (Express or Fastify), you need to install `apollo-server-express` or `apollo-server-fastify`.

#### Overview[#](/graphql/quick-start#overview)

Nest offers two ways of building GraphQL applications, the **schema first** and the **code first** methods.

In the **schema first** approach, the source of truth is a GraphQL SDL (Schema Definition Language) SDL is a language-agnostic way to share schema files between different platforms. Nest automatically generates your TypeScript definitions based on the GraphQL schemas (using either classes or interfaces) to reduce redundancy.

In the **code first** approach, you use decorators and TypeScript classes to generate the corresponding GraphQL schema. This approach is useful if you prefer to work exclusively with TypeScript and avoid context switching between language syntaxes.

#### Getting started with GraphQL & TypeScript[#](/graphql/quick-start#getting-started-with-graphql--typescript)

Once the packages are installed, we can import the `GraphQLModule` and configure it with the `forRoot()` static method.

JS TS

```typescript

import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';

@Module({
  imports: [
    GraphQLModule.forRoot({}),
  ],
})
export class ApplicationModule {}
```

The `forRoot()` method takes an options object as an argument. These options are passed through to the underlying Apollo instance (read more about available settings [here](https://www.apollographql.com/docs/apollo-server/v2/api/apollo-server.html#constructor-options-lt-ApolloServer-gt)). For example, if you want to disable the `playground` and turn off `debug` mode, pass the following options:

JS TS

```typescript

import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';

@Module({
  imports: [
    GraphQLModule.forRoot({
      debug: false,
      playground: false,
    }),
  ],
})
export class ApplicationModule {}
```

#### Playground[#](/graphql/quick-start#playground)

The playground is a graphical, interactive, in-browser GraphQL IDE, available by default on the same URL as the GraphQL server itself. With your application running in the background, open your web browser and navigate to `http://localhost:3000/graphql` (host and port may vary depending on your configuration). You should see the GraphQL playground, as shown below.

#### Multiple endpoints[#](/graphql/quick-start#multiple-endpoints)

Another useful feature of the `@nestjs/graphql` module is the ability to serve multiple endpoints at once. This lets you decide which modules should be included in which endpoint. By default, `GraphQL` searches for resolvers throughout the whole app. To limit this scan to only a subset of modules, use the `include` property.

```typescript

GraphQLModule.forRoot({
  include: [CatsModule],
}),
```

#### Schema first[#](/graphql/quick-start#schema-first)

To use the schema first approach, start by adding a `typePaths` property to the options object.

```typescript

GraphQLModule.forRoot({
  typePaths: ['./**/*.graphql'],
}),
```

The `typePaths` property indicates where the `GraphQLModule` should look for GraphQL files. These files will be combined in memory; this allows you to split your schemas into several files and locate them near their resolvers.

Creating GraphQL types and corresponding TypeScript definitions is redundant and tedious. It leaves us without a single source of truth -- each change made within SDL forces us to adjust interfaces as well. To address this, the `@nestjs/graphql` package can automatically generate TS definitions from the abstract syntax tree (AST). To enable this feature, add the `definitions` options property when configuring the `GraphQLModule`.

```typescript

GraphQLModule.forRoot({
  typePaths: ['./**/*.graphql'],
  definitions: {
    path: join(process.cwd(), 'src/graphql.ts'),
  },
}),
```

The path property of the `definitions` object (e.g., `src/graphql.ts` above) indicates where to save TypeScript output. By default, all types are generated as interfaces. To generate classes instead, specify the `outputAs` property with a value of `'class'`.

```typescript

GraphQLModule.forRoot({
  typePaths: ['./**/*.graphql'],
  definitions: {
    path: join(process.cwd(), 'src/graphql.ts'),
    outputAs: 'class',
  },
}),
```

The above approach dynamically generates type definitions each time the application starts. Alternatively, it may be preferable to build a simple script to generate these on demand. For example, assume we create the following script as `generate-typings.ts`:

```typescript

import { GraphQLDefinitionsFactory } from '@nestjs/graphql';
import { join } from 'path';

const definitionsFactory = new GraphQLDefinitionsFactory();
definitionsFactory.generate({
  typePaths: ['./src/**/*.graphql'],
  path: join(process.cwd(), 'src/graphql.ts'),
  outputAs: 'class',
});
```

Now you can run this script only when needed:

```bash

$ ts-node generate-typings
```

> **Hint** You can compile the script beforehand (e.g., with `tsc`) and use `node` to execute it.

To enable watch mode for the script (to automatically generate typings whenever any `.graphql` file changes), pass the `watch` option to the `generate()` method.

```typescript

definitionsFactory.generate({
  typePaths: ['./src/**/*.graphql'],
  path: join(process.cwd(), 'src/graphql.ts'),
  outputAs: 'class',
  watch: true,
});
```

A fully working sample is available [here](https://github.com/nestjs/nest/tree/master/sample/12-graphql-apollo).

#### Code first[#](/graphql/quick-start#code-first)

In the **code first** approach, you use decorators and TypeScript classes to generate the corresponding GraphQL schema.

Nest uses the powerful [type-graphql](https://typegraphql.ml/) library under the hood to provide this functionality. To start using it, first install the package.

```bash

$ npm i type-graphql
```

Once installation is complete, we can add the `autoSchemaFile` property to the options object.

```typescript

GraphQLModule.forRoot({
  autoSchemaFile: 'schema.gql',
}),
```

The `autoSchemaFile` property value is the path where your automatically generated schema will be created. Additionally, you can pass the `buildSchemaOptions` property - an options object which will be passed in to the `buildSchema()` function (from the `type-graphql` package). Alternatively, the schema can be generated on-the-fly in memory. To enable this, set the `autoSchemaFile` property to `true`:

```typescript

GraphQLModule.forRoot({
  autoSchemaFile: true,
}),
```

A fully working sample is available [here](https://github.com/nestjs/nest/tree/master/sample/23-type-graphql).

#### Async configuration[#](/graphql/quick-start#async-configuration)

When you need to pass module options asynchronously instead of statically, use the `forRootAsync()` method. As with most dynamic modules, Nest provides several techniques to deal with async configuration.

One technique is to use a factory function:

```typescript

GraphQLModule.forRootAsync({
  useFactory: () => ({
    typePaths: ['./**/*.graphql'],
  }),
}),
```

Like other factory providers, our factory function can be [async](https://docs.nestjs.com/fundamentals/custom-providers#factory-providers-usefactory) and can inject dependencies through `inject`.

```typescript

GraphQLModule.forRootAsync({
  imports: [ConfigModule],
  useFactory: async (configService: ConfigService) => ({
    typePaths: configService.getString('GRAPHQL_TYPE_PATHS'),
  }),
  inject: [ConfigService],
}),
```

Alternatively, you can configure the `GraphQLModule` using a class instead of a factory, as shown below:

```typescript

GraphQLModule.forRootAsync({
  useClass: GqlConfigService,
}),
```

The construction above instantiates `GqlConfigService` inside `GraphQLModule`, using it to create options object. Note that in this example, the `GqlConfigService` has to implement the `GqlOptionsFactory` interface, as shown below. The `GraphQLModule` will call the `createGqlOptions()` method on the instantiated object of the supplied class.

```typescript

@Injectable()
class GqlConfigService implements GqlOptionsFactory {
  createGqlOptions(): GqlModuleOptions {
    return {
      typePaths: ['./**/*.graphql'],
    };
  }
}
```

If you want to reuse an existing options provider instead of creating a private copy inside the `GraphQLModule`, use the `useExisting` syntax.

```typescript

GraphQLModule.forRootAsync({
  imports: [ConfigModule],
  useExisting: ConfigService,
}),
```

----
url: https://docs.nestjs.com/v10/microservices/mqtt
----

* [MQTT](https://docs.nestjs.com/v10/microservices/mqtt#mqtt)
* [Installation](https://docs.nestjs.com/v10/microservices/mqtt#installation)
* [Overview](https://docs.nestjs.com/v10/microservices/mqtt#overview)
* [Options](https://docs.nestjs.com/v10/microservices/mqtt#options)
* [Client](https://docs.nestjs.com/v10/microservices/mqtt#client)
* [Context](https://docs.nestjs.com/v10/microservices/mqtt#context)
* [Wildcards](https://docs.nestjs.com/v10/microservices/mqtt#wildcards)
* [Quality of Service (QoS)](https://docs.nestjs.com/v10/microservices/mqtt#quality-of-service-qos)
* [Record builders](https://docs.nestjs.com/v10/microservices/mqtt#record-builders)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/microservices/mqtt.md "Suggest Edits")

### MQTT

[MQTT](https://mqtt.org/) (Message Queuing Telemetry Transport) is an open source, lightweight messaging protocol, optimized for low latency. This protocol provides a scalable and cost-efficient way to connect devices using a **publish/subscribe** model. A communication system built on MQTT consists of the publishing server, a broker and one or more clients. It is designed for constrained devices and low-bandwidth, high-latency or unreliable networks.

#### Installation[#](/microservices/mqtt#installation)

To start building MQTT-based microservices, first install the required package:

```bash

$ npm i --save mqtt
```

#### Overview[#](/microservices/mqtt#overview)

To use the MQTT transporter, pass the following options object to the `createMicroservice()` method:

main.ts

JS TS

```typescript

const app = await NestFactory.createMicroservice<MicroserviceOptions>(AppModule, {
  transport: Transport.MQTT,
  options: {
    url: 'mqtt://localhost:1883',
  },
});
```

```typescript

const app = await NestFactory.createMicroservice(AppModule, {
  transport: Transport.MQTT,
  options: {
    url: 'mqtt://localhost:1883',
  },
});
```

> **Hint** The `Transport` enum is imported from the `@nestjs/microservices` package.

#### Options[#](/microservices/mqtt#options)

The `options` object is specific to the chosen transporter. The **MQTT** transporter exposes the properties described [here](https://github.com/mqttjs/MQTT.js/#mqttclientstreambuilder-options).

#### Client[#](/microservices/mqtt#client)

Like other microservice transporters, you have [several options](https://docs.nestjs.com/microservices/basics#client) for creating a MQTT `ClientProxy` instance.

One method for creating an instance is to use use the `ClientsModule`. To create a client instance with the `ClientsModule`, import it and use the `register()` method to pass an options object with the same properties shown above in the `createMicroservice()` method, as well as a `name` property to be used as the injection token. Read more about `ClientsModule`[here](https://docs.nestjs.com/microservices/basics#client).

```typescript

@Module({
  imports: [
    ClientsModule.register([
      {
        name: 'MATH_SERVICE',
        transport: Transport.MQTT,
        options: {
          url: 'mqtt://localhost:1883',
        }
      },
    ]),
  ]
  ...
})
```

Other options to create a client (either `ClientProxyFactory` or `@Client()`) can be used as well. You can read about them [here](https://docs.nestjs.com/microservices/basics#client).

#### Context[#](/microservices/mqtt#context)

In more sophisticated scenarios, you may want to access more information about the incoming request. When using the MQTT transporter, you can access the `MqttContext` object.

JS TS

```typescript

@MessagePattern('notifications')
getNotifications(@Payload() data: number[], @Ctx() context: MqttContext) {
  console.log(`Topic: ${context.getTopic()}`);
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('notifications')
getNotifications(data, context) {
  console.log(`Topic: ${context.getTopic()}`);
}
```

> **Hint**`@Payload()`, `@Ctx()` and `MqttContext` are imported from the `@nestjs/microservices` package.

To access the original mqtt [packet](https://github.com/mqttjs/mqtt-packet), use the `getPacket()` method of the `MqttContext` object, as follows:

JS TS

```typescript

@MessagePattern('notifications')
getNotifications(@Payload() data: number[], @Ctx() context: MqttContext) {
  console.log(context.getPacket());
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('notifications')
getNotifications(data, context) {
  console.log(context.getPacket());
}
```

#### Wildcards[#](/microservices/mqtt#wildcards)

A subscription may be to an explicit topic, or it may include wildcards. Two wildcards are available, `+` and `#`. `+` is a single-level wildcard, while `#` is a multi-level wildcard which covers many topic levels.

JS TS

```typescript

@MessagePattern('sensors/+/temperature/+')
getTemperature(@Ctx() context: MqttContext) {
  console.log(`Topic: ${context.getTopic()}`);
}
```

```typescript

@Bind(Ctx())
@MessagePattern('sensors/+/temperature/+')
getTemperature(context) {
  console.log(`Topic: ${context.getTopic()}`);
}
```

#### Quality of Service (QoS)[#](/microservices/mqtt#quality-of-service-qos)

Any subscription created with `@MessagePattern` or `@EventPattern` decorators will subscribe with QoS 0. If a higher QoS is required, it can be set globally using the `subscribeOptions` block when establishing the connection as follows:

main.ts

JS TS

```typescript

const app = await NestFactory.createMicroservice<MicroserviceOptions>(AppModule, {
  transport: Transport.MQTT,
  options: {
    url: 'mqtt://localhost:1883',
    subscribeOptions: {
      qos: 2
    },
  },
});
```

```typescript

const app = await NestFactory.createMicroservice(AppModule, {
  transport: Transport.MQTT,
  options: {
    url: 'mqtt://localhost:1883',
    subscribeOptions: {
      qos: 2
    },
  },
});
```

If a topic specific QoS is required, consider creating a [Custom transporter](https://docs.nestjs.com/microservices/custom-transport).

#### Record builders[#](/microservices/mqtt#record-builders)

To configure message options (adjust the QoS level, set the Retain or DUP flags, or add additional properties to the payload), you can use the `MqttRecordBuilder` class. For example, to set `QoS` to `2` use the `setQoS` method, as follows:

```typescript

const userProperties = { 'x-version': '1.0.0' };
const record = new MqttRecordBuilder(':cat:')
  .setProperties({ userProperties })
  .setQoS(1)
  .build();
client.send('replace-emoji', record).subscribe(...);
```

> **Hint**`MqttRecordBuilder` class is exported from the `@nestjs/microservices` package.

And you can read these options on the server-side as well, by accessing the `MqttContext`.

JS TS

```typescript

@MessagePattern('replace-emoji')
replaceEmoji(@Payload() data: string, @Ctx() context: MqttContext): string {
  const { properties: { userProperties } } = context.getPacket();
  return userProperties['x-version'] === '1.0.0' ? '🐱' : '🐈';
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('replace-emoji')
replaceEmoji(data, context) {
  const { properties: { userProperties } } = context.getPacket();
  return userProperties['x-version'] === '1.0.0' ? '🐱' : '🐈';
}
```

In some cases you might want to configure user properties for multiple requests, you can pass these options to the `ClientProxyFactory`.

```typescript

import { Module } from '@nestjs/common';
import { ClientProxyFactory, Transport } from '@nestjs/microservices';

@Module({
  providers: [
    {
      provide: 'API_v1',
      useFactory: () =>
        ClientProxyFactory.create({
          transport: Transport.MQTT,
          options: {
            url: 'mqtt://localhost:1833',
            userProperties: { 'x-version': '1.0.0' },
          },
        }),
    },
  ],
})
export class ApiModule {}
```

----
url: https://docs.nestjs.com/v8/fundamentals/execution-context
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Execution context](https://docs.nestjs.com/v8/fundamentals/execution-context#execution-context)
* [ArgumentsHost class](https://docs.nestjs.com/v8/fundamentals/execution-context#argumentshost-class)
* [Current application context](https://docs.nestjs.com/v8/fundamentals/execution-context#current-application-context)
* [Host handler arguments](https://docs.nestjs.com/v8/fundamentals/execution-context#host-handler-arguments)
* [ExecutionContext class](https://docs.nestjs.com/v8/fundamentals/execution-context#executioncontext-class)
* [Reflection and metadata](https://docs.nestjs.com/v8/fundamentals/execution-context#reflection-and-metadata)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/fundamentals/execution-context.md "Suggest Edits")

### Execution context

Nest provides several utility classes that help make it easy to write applications that function across multiple application contexts (e.g., Nest HTTP server-based, microservices and WebSockets application contexts). These utilities provide information about the current execution context which can be used to build generic [guards](/v8/guards), [filters](/v8/exception-filters), and [interceptors](/v8/interceptors) that can work across a broad set of controllers, methods, and execution contexts.

We cover two such classes in this chapter: `ArgumentsHost` and `ExecutionContext`.

#### ArgumentsHost class[#](/fundamentals/execution-context#argumentshost-class)

The `ArgumentsHost` class provides methods for retrieving the arguments being passed to a handler. It allows choosing the appropriate context (e.g., HTTP, RPC (microservice), or WebSockets) to retrieve the arguments from. The framework provides an instance of `ArgumentsHost`, typically referenced as a `host` parameter, in places where you may want to access it. For example, the `catch()` method of an [exception filter](https://docs.nestjs.com/exception-filters#arguments-host) is called with an `ArgumentsHost`instance.

`ArgumentsHost` simply acts as an abstraction over a handler's arguments. For example, for HTTP server applications (when `@nestjs/platform-express` is being used), the `host` object encapsulates Express's `[request, response, next]` array, where `request` is the request object, `response` is the response object, and `next` is a function that controls the application's request-response cycle. On the other hand, for [GraphQL](/v8/graphql/quick-start) applications, the `host` object contains the `[root, args, context, info]` array.

#### Current application context[#](/fundamentals/execution-context#current-application-context)

When building generic [guards](/v8/guards), [filters](/v8/exception-filters), and [interceptors](/v8/interceptors) which are meant to run across multiple application contexts, we need a way to determine the type of application that our method is currently running in. Do this with the `getType()` method of `ArgumentsHost`:

```typescript

if (host.getType() === 'http') {
  // do something that is only important in the context of regular HTTP requests (REST)
} else if (host.getType() === 'rpc') {
  // do something that is only important in the context of Microservice requests
} else if (host.getType<GqlContextType>() === 'graphql') {
  // do something that is only important in the context of GraphQL requests
}
```

> **Hint** The `GqlContextType` is imported from the `@nestjs/graphql` package.

With the application type available, we can write more generic components, as shown below.

#### Host handler arguments[#](/fundamentals/execution-context#host-handler-arguments)

To retrieve the array of arguments being passed to the handler, one approach is to use the host object's `getArgs()` method.

```typescript

const [req, res, next] = host.getArgs();
```

You can pluck a particular argument by index using the `getArgByIndex()` method:

```typescript

const request = host.getArgByIndex(0);
const response = host.getArgByIndex(1);
```

In these examples we retrieved the request and response objects by index, which is not typically recommended as it couples the application to a particular execution context. Instead, you can make your code more robust and reusable by using one of the `host` object's utility methods to switch to the appropriate application context for your application. The context switch utility methods are shown below.

```typescript

/**
 * Switch context to RPC.
 */
switchToRpc(): RpcArgumentsHost;
/**
 * Switch context to HTTP.
 */
switchToHttp(): HttpArgumentsHost;
/**
 * Switch context to WebSockets.
 */
switchToWs(): WsArgumentsHost;
```

Let's rewrite the previous example using the `switchToHttp()` method. The `host.switchToHttp()` helper call returns an `HttpArgumentsHost` object that is appropriate for the HTTP application context. The `HttpArgumentsHost` object has two useful methods we can use to extract the desired objects. We also use the Express type assertions in this case to return native Express typed objects:

```typescript

const ctx = host.switchToHttp();
const request = ctx.getRequest<Request>();
const response = ctx.getResponse<Response>();
```

Similarly `WsArgumentsHost` and `RpcArgumentsHost` have methods to return appropriate objects in the microservices and WebSockets contexts. Here are the methods for `WsArgumentsHost`:

```typescript

export interface WsArgumentsHost {
  /**
   * Returns the data object.
   */
  getData<T>(): T;
  /**
   * Returns the client object.
   */
  getClient<T>(): T;
}
```

Following are the methods for `RpcArgumentsHost`:

```typescript

export interface RpcArgumentsHost {
  /**
   * Returns the data object.
   */
  getData<T>(): T;

  /**
   * Returns the context object.
   */
  getContext<T>(): T;
}
```

#### ExecutionContext class[#](/fundamentals/execution-context#executioncontext-class)

`ExecutionContext` extends `ArgumentsHost`, providing additional details about the current execution process. Like `ArgumentsHost`, Nest provides an instance of `ExecutionContext` in places you may need it, such as in the `canActivate()` method of a [guard](https://docs.nestjs.com/guards#execution-context) and the `intercept()` method of an [interceptor](https://docs.nestjs.com/interceptors#execution-context). It provides the following methods:

```typescript

export interface ExecutionContext extends ArgumentsHost {
  /**
   * Returns the type of the controller class which the current handler belongs to.
   */
  getClass<T>(): Type<T>;
  /**
   * Returns a reference to the handler (method) that will be invoked next in the
   * request pipeline.
   */
  getHandler(): Function;
}
```

The `getHandler()` method returns a reference to the handler about to be invoked. The `getClass()` method returns the type of the `Controller` class which this particular handler belongs to. For example, in an HTTP context, if the currently processed request is a `POST` request, bound to the `create()` method on the `CatsController`, `getHandler()` returns a reference to the `create()` method and `getClass()` returns the `CatsController`**type** (not instance).

```typescript

const methodKey = ctx.getHandler().name; // "create"
const className = ctx.getClass().name; // "CatsController"
```

```typescript

@Post()
@SetMetadata('roles', ['admin'])
async create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

```typescript

@Post()
@SetMetadata('roles', ['admin'])
@Bind(Body())
async create(createCatDto) {
  this.catsService.create(createCatDto);
}
```

> **Hint** The `@SetMetadata()` decorator is imported from the `@nestjs/common` package.

With the construction above, we attached the `roles` metadata (`roles` is a metadata key and `['admin']` is the associated value) to the `create()` method. While this works, it's not good practice to use `@SetMetadata()` directly in your routes. Instead, create your own decorators, as shown below:

roles.decorator.ts

JS TS

```typescript

import { SetMetadata } from '@nestjs/common';

export const Roles = (...roles: string[]) => SetMetadata('roles', roles);
```

```typescript

import { SetMetadata } from '@nestjs/common';

export const Roles = (...roles) => SetMetadata('roles', roles);
```

This approach is much cleaner and more readable, and is strongly typed. Now that we have a custom `@Roles()` decorator, we can use it to decorate the `create()` method.

cats.controller.ts

JS TS

```typescript

@Post()
@Roles('admin')
async create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

```typescript

@Post()
@Roles('admin')
@Bind(Body())
async create(createCatDto) {
  this.catsService.create(createCatDto);
}
```

To access the route's role(s) (custom metadata), we'll use the `Reflector` helper class, which is provided out of the box by the framework and exposed from the `@nestjs/core` package. `Reflector` can be injected into a class in the normal way:

roles.guard.ts

JS TS

```typescript

@Injectable()
export class RolesGuard {
  constructor(private reflector: Reflector) {}
}
```

```typescript

@Injectable()
@Dependencies(Reflector)
export class CatsService {
  constructor(reflector) {
    this.reflector = reflector;
  }
}
```

> **Hint** The `Reflector` class is imported from the `@nestjs/core` package.

Now, to read the handler metadata, use the `get()` method.

```typescript

const roles = this.reflector.get<string[]>('roles', context.getHandler());
```

The `Reflector#get` method allows us to easily access the metadata by passing in two arguments: a metadata **key** and a **context** (decorator target) to retrieve the metadata from. In this example, the specified **key** is `'roles'` (refer back to the `roles.decorator.ts` file above and the `SetMetadata()` call made there). The context is provided by the call to `context.getHandler()`, which results in extracting the metadata for the currently processed route handler. Remember, `getHandler()` gives us a **reference** to the route handler function.

Alternatively, we may organize our controller by applying metadata at the controller level, applying to all routes in the controller class.

cats.controller.ts

JS TS

```typescript

@Roles('admin')
@Controller('cats')
export class CatsController {}
```

```typescript

@Roles('admin')
@Controller('cats')
export class CatsController {}
```

In this case, to extract controller metadata, we pass `context.getClass()` as the second argument (to provide the controller class as the context for metadata extraction) instead of `context.getHandler()`:

roles.guard.ts

JS TS

```typescript

const roles = this.reflector.get<string[]>('roles', context.getClass());
```

```typescript

const roles = this.reflector.get('roles', context.getClass());
```

Given the ability to provide metadata at multiple levels, you may need to extract and merge metadata from several contexts. The `Reflector` class provides two utility methods used to help with this. These methods extract **both** controller and method metadata at once, and combine them in different ways.

Consider the following scenario, where you've supplied `'roles'` metadata at both levels.

cats.controller.ts

JS TS

```typescript

@Roles('user')
@Controller('cats')
export class CatsController {
  @Post()
  @Roles('admin')
  async create(@Body() createCatDto: CreateCatDto) {
    this.catsService.create(createCatDto);
  }
}
```

```typescript

@Roles('user')
@Controller('cats')
export class CatsController {}
  @Post()
  @Roles('admin')
  @Bind(Body())
  async create(createCatDto) {
    this.catsService.create(createCatDto);
  }
}
```

If your intent is to specify `'user'` as the default role, and override it selectively for certain methods, you would probably use the `getAllAndOverride()` method.

```typescript

const roles = this.reflector.getAllAndOverride<string[]>('roles', [
  context.getHandler(),
  context.getClass(),
]);
```

A guard with this code, running in the context of the `create()` method, with the above metadata, would result in `roles` containing `['admin']`.

To get metadata for both and merge it (this method merges both arrays and objects), use the `getAllAndMerge()` method:

```typescript

const roles = this.reflector.getAllAndMerge<string[]>('roles', [
  context.getHandler(),
  context.getClass(),
]);
```

This would result in `roles` containing `['user', 'admin']`.

For both of these merge methods, you pass the metadata key as the first argument, and an array of metadata target contexts (i.e., calls to the `getHandler()` and/or `getClass())` methods) as the second argument.

----
url: https://docs.nestjs.com/v7/providers
----

* [Providers](https://docs.nestjs.com/v7/providers#providers)
* [Services](https://docs.nestjs.com/v7/providers#services)
* [Dependency injection](https://docs.nestjs.com/v7/providers#dependency-injection)
* [Scopes](https://docs.nestjs.com/v7/providers#scopes)
* [Custom providers](https://docs.nestjs.com/v7/providers#custom-providers)
* [Optional providers](https://docs.nestjs.com/v7/providers#optional-providers)
* [Property-based injection](https://docs.nestjs.com/v7/providers#property-based-injection)
* [Provider registration](https://docs.nestjs.com/v7/providers#provider-registration)
* [Manual instantiation](https://docs.nestjs.com/v7/providers#manual-instantiation)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/components.md "Suggest Edits")

### Providers

Providers are a fundamental concept in Nest. Many of the basic Nest classes may be treated as a provider – services, repositories, factories, helpers, and so on. The main idea of a provider is that it can **inject** dependencies; this means objects can create various relationships with each other, and the function of "wiring up" instances of objects can largely be delegated to the Nest runtime system.

In the previous chapter, we built a simple `CatsController`. Controllers should handle HTTP requests and delegate more complex tasks to **providers**. Providers are plain JavaScript classes that are declared as `providers` in a [module](/v7/modules).

> **Hint** Since Nest enables the possibility to design and organize dependencies in a more OO-way, we strongly recommend following the [SOLID](https://en.wikipedia.org/wiki/SOLID) principles.

#### Services[#](/providers#services)

Let's start by creating a simple `CatsService`. This service will be responsible for data storage and retrieval, and is designed to be used by the `CatsController`, so it's a good candidate to be defined as a provider.

cats.service.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { Cat } from './interfaces/cat.interface';

@Injectable()
export class CatsService {
  private readonly cats: Cat[] = [];

  create(cat: Cat) {
    this.cats.push(cat);
  }

  findAll(): Cat[] {
    return this.cats;
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';

@Injectable()
export class CatsService {
  constructor() {
    this.cats = [];
  }

  create(cat) {
    this.cats.push(cat);
  }

  findAll() {
    return this.cats;
  }
}
```

> **Hint** To create a service using the CLI, simply execute the `$ nest g service cats` command.

Our `CatsService` is a basic class with one property and two methods. The only new feature is that it uses the `@Injectable()` decorator. The `@Injectable()` decorator attaches metadata, which declares that `CatsService` is a class that can be managed by the Nest IoC container. By the way, this example also uses a `Cat` interface, which probably looks something like this:

interfaces/cat.interface.ts

JS TS

```typescript

export interface Cat {
  name: string;
  age: number;
  breed: string;
}
```

Now that we have a service class to retrieve cats, let's use it inside the `CatsController`:

cats.controller.ts

JS TS

```typescript

import { Controller, Get, Post, Body } from '@nestjs/common';
import { CreateCatDto } from './dto/create-cat.dto';
import { CatsService } from './cats.service';
import { Cat } from './interfaces/cat.interface';

@Controller('cats')
export class CatsController {
  constructor(private catsService: CatsService) {}

  @Post()
  async create(@Body() createCatDto: CreateCatDto) {
    this.catsService.create(createCatDto);
  }

  @Get()
  async findAll(): Promise<Cat[]> {
    return this.catsService.findAll();
  }
}
```

```typescript

import { Controller, Get, Post, Body, Bind, Dependencies } from '@nestjs/common';
import { CatsService } from './cats.service';

@Controller('cats')
@Dependencies(CatsService)
export class CatsController {
  constructor(catsService) {
    this.catsService = catsService;
  }

  @Post()
  @Bind(Body())
  async create(createCatDto) {
    this.catsService.create(createCatDto);
  }

  @Get()
  async findAll() {
    return this.catsService.findAll();
  }
}
```

The `CatsService` is **injected** through the class constructor. Notice the use of the `private` syntax. This shorthand allows us to both declare and initialize the `catsService` member immediately in the same location.

#### Dependency injection[#](/providers#dependency-injection)

Nest is built around the strong design pattern commonly known as **Dependency injection**. We recommend reading a great article about this concept in the official [Angular](https://angular.io/guide/dependency-injection) documentation.

In Nest, thanks to TypeScript capabilities, it's extremely easy to manage dependencies because they are resolved just by type. In the example below, Nest will resolve the `catsService` by creating and returning an instance of `CatsService` (or, in the normal case of a singleton, returning the existing instance if it has already been requested elsewhere). This dependency is resolved and passed to your controller's constructor (or assigned to the indicated property):

```typescript

constructor(private catsService: CatsService) {}
```

#### Scopes[#](/providers#scopes)

Providers normally have a lifetime ("scope") synchronized with the application lifecycle. When the application is bootstrapped, every dependency must be resolved, and therefore every provider has to be instantiated. Similarly, when the application shuts down, each provider will be destroyed. However, there are ways to make your provider lifetime **request-scoped** as well. You can read more about these techniques [here](/v7/fundamentals/injection-scopes).

Nest has a built-in inversion of control ("IoC") container that resolves relationships between providers. This feature underlies the dependency injection feature described above, but is in fact far more powerful than what we've described so far. There are several ways to define a provider: you can use plain values, classes, and either asynchronous or synchronous factories. More examples are provided [here](/v7/fundamentals/dependency-injection).

#### Optional providers[#](/providers#optional-providers)

Occasionally, you might have dependencies which do not necessarily have to be resolved. For instance, your class may depend on a **configuration object**, but if none is passed, the default values should be used. In such a case, the dependency becomes optional, because lack of the configuration provider wouldn't lead to errors.

To indicate a provider is optional, use the `@Optional()` decorator in the constructor's signature.

```typescript

import { Injectable, Optional, Inject } from '@nestjs/common';

@Injectable()
export class HttpService<T> {
  constructor(@Optional() @Inject('HTTP_OPTIONS') private httpClient: T) {}
}
```

Note that in the example above we are using a custom provider, which is the reason we include the `HTTP_OPTIONS` custom **token**. Previous examples showed constructor-based injection indicating a dependency through a class in the constructor. Read more about custom providers and their associated tokens [here](/v7/fundamentals/custom-providers).

#### Property-based injection[#](/providers#property-based-injection)

The technique we've used so far is called constructor-based injection, as providers are injected via the constructor method. In some very specific cases, **property-based injection** might be useful. For instance, if your top-level class depends on either one or multiple providers, passing them all the way up by calling `super()` in sub-classes from the constructor can be very tedious. In order to avoid this, you can use the `@Inject()` decorator at the property level.

```typescript

import { Injectable, Inject } from '@nestjs/common';

@Injectable()
export class HttpService<T> {
  @Inject('HTTP_OPTIONS')
  private readonly httpClient: T;
}
```

> **Warning** If your class doesn't extend another provider, you should always prefer using **constructor-based** injection.

#### Provider registration[#](/providers#provider-registration)

Now that we have defined a provider (`CatsService`), and we have a consumer of that service (`CatsController`), we need to register the service with Nest so that it can perform the injection. We do this by editing our module file (`app.module.ts`) and adding the service to the `providers` array of the `@Module()` decorator.

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { CatsController } from './cats/cats.controller';
import { CatsService } from './cats/cats.service';

@Module({
  controllers: [CatsController],
  providers: [CatsService],
})
export class AppModule {}
```

#### Manual instantiation[#](/providers#manual-instantiation)

Thus far, we've discussed how Nest automatically handles most of the details of resolving dependencies. In certain circumstances, you may need to step outside of the built-in Dependency Injection system and manually retrieve or instantiate providers. We briefly discuss two such topics below.

To get existing instances, or instantiate providers dynamically, you can use [Module reference](https://docs.nestjs.com/fundamentals/module-ref).

To get providers within the `bootstrap()` function (for example for standalone applications without controllers, or to utilize a configuration service during bootstrapping) see [Standalone applications](https://docs.nestjs.com/standalone-applications).

----
url: https://docs.nestjs.com/reliability/resilience
----

[Skip to content](#content)

On this page

* [Resilience](https://docs.nestjs.com/reliability/resilience#resilience)
* [Prerequisites](https://docs.nestjs.com/reliability/resilience#prerequisites)
* [Register the module](https://docs.nestjs.com/reliability/resilience#register-the-module)
* [Put a time budget on the quotes route](https://docs.nestjs.com/reliability/resilience#put-a-time-budget-on-the-quotes-route)
* [Fail fast with a circuit breaker](https://docs.nestjs.com/reliability/resilience#fail-fast-with-a-circuit-breaker)
* [Cap concurrent CSV exports with a bulkhead](https://docs.nestjs.com/reliability/resilience#cap-concurrent-csv-exports-with-a-bulkhead)
* [Retry a POST safely](https://docs.nestjs.com/reliability/resilience#retry-a-post-safely)
* [Use the same policies inside services](https://docs.nestjs.com/reliability/resilience#use-the-same-policies-inside-services)
* [Other transports](https://docs.nestjs.com/reliability/resilience#other-transports)
* [Observe breaker transitions](https://docs.nestjs.com/reliability/resilience#observe-breaker-transitions)
* [Try it](https://docs.nestjs.com/reliability/resilience#try-it)
* [Testing](https://docs.nestjs.com/reliability/resilience#testing)
* [Production checklist](https://docs.nestjs.com/reliability/resilience#production-checklist)
* [Reference](https://docs.nestjs.com/reliability/resilience#reference)

### Resilience

Sooner or later, every application that calls another system meets one that is slow or down. Without a plan, a slow dependency ties up your request handlers, your clients wait until their own timeouts fire, and retries from every layer pile even more load onto the service that is already struggling.

`@nestjs/resilience` gives you the usual tools as decorators: **retry**, **timeout**, **circuit breaker**, **bulkhead** and **fallback**. They apply to your application's **entrypoints**, which are controllers, GraphQL resolvers, microservice message handlers and WebSocket gateways. For code inside services, the same settings are available as policy objects. A single global interceptor applies the decorators, so they behave the same on every transport, and each failure becomes that transport's native error. Over HTTP, for example, a timeout answers `504 Gateway Timeout` and an open breaker answers `503 Service Unavailable` with a `Retry-After` header.

In this tutorial you'll harden the order API of an online store for cat food and supplies. Checkout asks the shipping carrier for quotes, and the carrier's quotes API is slow at the best of times and occasionally down. By the end, a slow carrier costs checkout about three seconds at most. Once the carrier is known to be down, checkout stops waiting for it altogether: customers see flat-rate shipping instead of an error, and a background job stops calling the carrier until it recovers.

#### Prerequisites[#](/reliability/resilience#prerequisites)

This tutorial assumes an `OrdersModule` that exports an `OrdersService`. The service needs these methods: `findOne(id)` (which throws `NotFoundException` for an unknown id), `findAll()`, `update(id, changes)` and `exportCsv()`. Orders look like this:

orders/order.ts

JS TS

```typescript

export interface OrderItem {
  productId: string;
  quantity: number;
  price: number;
}

export interface Order {
  id: string;
  userId: string;
  items: OrderItem[];
  total: number;
  status: 'pending' | 'paid' | 'shipped';
}

export function subtotal(order: Order): number {
  return order.items.reduce((sum, item) => sum + item.price * item.quantity, 0);
}
```

Install the package:

```bash

$ npm i --save @nestjs/resilience
```

[Retry a POST safely](/reliability/resilience#retry-a-post-safely) also uses `@nestjs/idempotency` (see [Idempotency keys](/reliability/idempotency)).

#### Register the module[#](/reliability/resilience#register-the-module)

Import `ResilienceModule` into the root module. Configure field defaults and one named preset, `carrier`, that describes how the application should treat the carrier:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { ResilienceModule } from '@nestjs/resilience';
import { OrdersModule } from './orders/orders.module.js';
import { ShippingModule } from './shipping/shipping.module.js';

@Module({
  imports: [
    ResilienceModule.forRoot({
      defaults: {
        timeout: '5s',
        retry: { attempts: 3, backoff: { delay: '200ms', maxDelay: '2s' } },
      },
      presets: {
        carrier: {
          timeout: '2s',
          retry: { attempts: 2 },
          circuitBreaker: { failureRateThreshold: 50, minimumCalls: 10, openDuration: '30s' },
        },
      },
    }),
    OrdersModule,
    ShippingModule,
  ],
})
export class AppModule {}
```

The two options do different jobs:

* `defaults` fills in the fields of any stage that a decorator or preset turns on. Defaults never turn a stage on themselves. Here, a retry first waits a random time between 0 and 200 ms (the `delay`), then up to 400 ms, doubling each time up to 2 s (the `maxDelay`). A bare `@Timeout()` means 5 seconds.
* `presets` holds named sets of stages, usually one per dependency. The `carrier` preset gives each attempt 2 seconds, makes at most 2 attempts, and adds a circuit breaker. That breaker is **shared under the name `carrier`** by every route, handler and service that uses the preset. The carrier is one dependency, so it gets one breaker.

Every time-valued option takes milliseconds or a string such as `'200ms'`, `'2s'` or `'30s'`.

The module is global, so import it once, in the root module. It registers one app-wide interceptor, which does nothing for handlers without resilience decorators apart from error mapping. It checks its configuration at bootstrap: an unknown preset name, an invalid duration or number (such as the `NaN` of an unset environment variable), a missing fallback method or one breaker name configured in two different ways fails the boot instead of the first request. Use `ResilienceModule.forRootAsync()` to build the options from configuration.

#### Put a time budget on the quotes route[#](/reliability/resilience#put-a-time-budget-on-the-quotes-route)

Start with a client for the carrier. Every method takes an `AbortSignal` and hands it to `fetch()`:

shipping/carrier.client.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import type { Order } from '../orders/order.js';

export interface ShippingQuote {
  service: string;
  price: number;
  estimatedDays: number;
}

export interface Shipment {
  id: string;
  reference: string;
  trackingNumber: string;
}

export class CarrierError extends Error {
  constructor(readonly status: number) {
    super(`The carrier answered with status ${status}`);
  }
}

@Injectable()
export class CarrierClient {
  private readonly baseUrl = process.env.CARRIER_URL ?? 'https://api.carrier.example.com';

  getQuotes(order: Order, signal: AbortSignal): Promise<ShippingQuote[]> {
    return this.post('/v2/quotes', { reference: order.id, items: order.items }, signal);
  }

  /** The carrier returns the existing shipment when it has seen the reference before. */
  createShipment(order: Order, signal: AbortSignal): Promise<Shipment> {
    return this.post('/v2/shipments', { reference: order.id, items: order.items }, signal);
  }

  private async post<T>(path: string, body: unknown, signal: AbortSignal): Promise<T> {
    const response = await fetch(`${this.baseUrl}${path}`, {
      method: 'POST',
      headers: { 'content-type': 'application/json' },
      body: JSON.stringify(body),
      signal,
    });
    if (!response.ok) {
      throw new CarrierError(response.status);
    }
    return (await response.json()) as T;
  }
}
```

The service passes the signal through. It also has a flat-rate price list and a booking method, which the circuit breaker and the retried POST use below:

shipping/shipping.service.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { OrdersService } from '../orders/orders.service.js';
import { CarrierClient, type Shipment, type ShippingQuote } from './carrier.client.js';

@Injectable()
export class ShippingService {
  constructor(
    private readonly ordersService: OrdersService,
    private readonly carrierClient: CarrierClient,
  ) {}

  async getQuotes(orderId: string, signal: AbortSignal): Promise<ShippingQuote[]> {
    const order = await this.ordersService.findOne(orderId);
    return this.carrierClient.getQuotes(order, signal);
  }

  flatRateQuotes(): ShippingQuote[] {
    return [{ service: 'flat-rate', price: 4.99, estimatedDays: 5 }];
  }

  async createShipment(orderId: string, signal: AbortSignal): Promise<Shipment> {
    const order = await this.ordersService.findOne(orderId);
    return this.carrierClient.createShipment(order, signal);
  }
}
```

Now the route. `@Resilience('carrier')` applies the preset, and `@Signal()` injects the current attempt's `AbortSignal`:

shipping/shipping.controller.ts

JS TS

```typescript

import { Controller, Get, Query } from '@nestjs/common';
import { Resilience, Signal, Timeout } from '@nestjs/resilience';
import { ShippingService } from './shipping.service.js';

@Controller('shipping')
export class ShippingController {
  constructor(private readonly shippingService: ShippingService) {}

  @Get('quotes')
  @Resilience('carrier')
  @Timeout('1.5s')
  getQuotes(@Query('orderId') orderId: string, @Signal() signal: AbortSignal) {
    return this.shippingService.getQuotes(orderId, signal);
  }
}
```

Register `CarrierClient` and `ShippingService` as providers, and `ShippingController` as a controller, of a `ShippingModule` that imports `OrdersModule`.

Checkout can't wait long, so `@Timeout('1.5s')` gives this route a tighter budget than the preset's. Settings resolve **stage by stage**: a decorator on the handler wins over the preset for its own stage, and the preset still supplies the retry and the breaker. A bare `@Timeout()` would take the preset's 2 seconds, and fall back to `defaults.timeout` only where no preset or class-level `@Timeout()` sets a duration.

When an attempt runs out of time, three things happen:

1. The attempt is rejected with a `ResilienceTimeoutError`.
2. The signal is aborted with that same error. `fetch()` rejects and closes the connection, so nothing keeps waiting for an answer nobody will read. Cancellation is cooperative: code that ignores the signal keeps running in the background, and its result is dropped.
3. Because `GET` is a safe method, the preset's retry makes a second attempt. Only the pipes, inner interceptors and handler run again. Guards and middleware run once per request.

If the second attempt times out as well, the client gets a `504`:

```json

{
  "statusCode": 504,
  "error": "Gateway Timeout",
  "message": "The operation timed out",
  "code": "TIMEOUT"
}
```

The timeout applies **per attempt**, so a carrier that hangs costs this route about 3.2 seconds: two attempts of 1.5 s plus up to 200 ms of backoff. The status is 504 rather than 408 on purpose. A 408 claims that the *client* was too slow to send its request, and some clients and proxies repeat 408s automatically, even for `POST` requests.

Client errors are not failures. A request for an unknown order throws `NotFoundException` before the carrier is called. It answers 404, and it is neither retried nor counted by the breaker.

> **Hint** Code that can't take the signal as a parameter can inject `ResilienceContext` and read its `signal` and `attempt`. It reads the current attempt from `AsyncLocalStorage`, so it works in any service the handler calls, on every transport. A policy object used inside the attempt inherits its signal too, so the route's timeout also stops that policy's retries.

#### Fail fast with a circuit breaker[#](/reliability/resilience#fail-fast-with-a-circuit-breaker)

The preset's breaker records the outcome of every attempt. The `carrier` breaker opens once it has seen at least `minimumCalls` (10) calls, and at least `failureRateThreshold` (50%) of them failed. By default it looks at the last 20 calls. Every error counts as a failure, timeouts included, except client errors and rejections from other policies. A client error is a 4xx `HttpException`, or any other error with a 4xx `status` or `statusCode` property. That covers `CarrierError`: when the carrier answers `422` to a malformed request, it isn't down, so the breaker ignores the error and the retry doesn't repeat it. A `408` or `429` from the carrier is the exception, because it means the carrier is pushing back, so it counts like a `5xx`. An `HttpException` with one of those statuses is still a client error: the handler threw it to answer its own caller, and that says nothing about the carrier. To change what counts, pass a `recordIf` function in the breaker options.

While the breaker is **open**, calls fail immediately and the carrier is not called at all. The client gets a `503` with a `Retry-After` header: the number of seconds until the breaker lets a probe call through. The retry wraps the breaker, so a rejection is never retried.

After `openDuration` (30 s), the breaker is **half-open**. It lets one probe call through (see `halfOpenMaxCalls`). If the probe succeeds, the breaker closes and starts over with an empty window. If it fails, the breaker opens for another 30 seconds. The breaker doesn't use a timer for this. It checks the state on the next call.

A 503 is correct, but checkout can do better. Add a fallback that serves flat-rate quotes while the carrier is known to be down (import `Fallback` and `CircuitOpenError` from `@nestjs/resilience`):

shipping/shipping.controller.ts

JS TS

```typescript

@Get('quotes')
@Resilience('carrier')
@Timeout('1.5s')
@Fallback('flatRateQuotes', {
  handleIf: (error) => error instanceof CircuitOpenError,
})
getQuotes(@Query('orderId') orderId: string, @Signal() signal: AbortSignal) {
  return this.shippingService.getQuotes(orderId, signal);
}

flatRateQuotes() {
  return this.shippingService.flatRateQuotes();
}
```

`@Fallback()` takes the name of a method on the same class, or a function. TypeScript checks that the class has a method with that name. The fallback is called with the error and the `ExecutionContext`, and whatever it returns becomes the response. It can be a value, a `Promise` or an `Observable`. Fallback is the outermost stage, so it also sees the breaker's rejections.

By default, a fallback replaces every error except client errors. The `handleIf` option narrows that down. Flat rates cost the store money on heavy parcels, such as bags of litter, so here they're a last resort: they're served only when the breaker says the carrier is down, and a single slow answer still gets a 504.

> **Hint** To look at a breaker from your own code, inject `ResilienceService` and call `circuitBreaker('carrier')`. The breaker exposes `state` and `stats`, and you can force it open or closed with `trip()` and `reset()`.

#### Cap concurrent CSV exports with a bulkhead[#](/reliability/resilience#cap-concurrent-csv-exports-with-a-bulkhead)

The back office downloads all orders as a CSV file. Building the file reads every order and is heavy on both the database and the CPU. Two exports at a time are fine, but twenty would slow checkout down for everyone. A bulkhead caps how many run at the same time:

orders/orders.controller.ts

JS TS

```typescript

import { Controller, Get, Header } from '@nestjs/common';
import { Bulkhead } from '@nestjs/resilience';
import { OrdersService } from './orders.service.js';

@Controller('orders')
export class OrdersController {
  constructor(private readonly ordersService: OrdersService) {}

  @Get('export')
  @Header('Content-Type', 'text/csv')
  @Bulkhead({ maxConcurrent: 2, maxQueue: 3, queueTimeout: '10s' })
  export() {
    return this.ordersService.exportCsv();
  }
}
```

Two exports run at a time. Up to three more wait for a slot, for at most 10 seconds each. A sixth request gets a `503` right away, and so does a waiting request once its 10 seconds are up:

```json

{
  "statusCode": 503,
  "error": "Service Unavailable",
  "message": "Server is at capacity",
  "code": "BULKHEAD_FULL"
}
```

This 503 has no `Retry-After` header, because nobody knows when a slot will free up. The status is 503 rather than 429 because a 429 blames the client's request rate, while a full bulkhead means the server is at capacity for everyone.

A slot stays taken until the handler finishes, or until a timeout on the route gives up on the attempt. A handler that ignores its signal then keeps running in the background, outside the bulkhead's count, which is one more reason to pass the signal to every call that takes one. A bulkhead without a name belongs to its handler, and is registered under the handler's name. To read its load, inject `ResilienceService` and look at `bulkhead('OrdersController.export')`, which has `active` and `queued` counts. Give the bulkhead a `name` to share one pool of slots between several handlers.

#### Retry a POST safely[#](/reliability/resilience#retry-a-post-safely)

So far, retries have only happened on `GET`. That's deliberate. On HTTP, a retry applies only to the safe methods `GET`, `HEAD` and `OPTIONS`, and on GraphQL only to queries. Running a `POST` twice might create two shipments, and the package can't know whether that's harmless. So a preset's retry is simply skipped on a `POST`. A `@Retry()` decorator placed directly on a `POST` handler is skipped too, and bootstrap warns about it:

```bash

WARN [ResilienceModule] @Retry() on ShippingController.createShipment() is inactive: it only re-runs safe operations (GET, HEAD, OPTIONS, GraphQL queries). If the handler is safe to repeat, use @Retry({ idempotent: true }).
```

Booking a shipment *is* safe to repeat, because the carrier deduplicates shipments by `reference`, which is the order id. That matters for another reason too: a booking that timed out may still have gone through on the carrier's side, so the retry has to be safe anyway. Setting `idempotent: true` on `@Retry()` is how you state that running the handler twice within one request is fine:

shipping/shipping.controller.ts

JS TS

```typescript

import { Body, Controller, Get, Post, Query } from '@nestjs/common';
import { Idempotent } from '@nestjs/idempotency';
import { CircuitOpenError, Fallback, Resilience, Retry, Signal, Timeout } from '@nestjs/resilience';
import { ShippingService } from './shipping.service.js';

@Controller('shipping')
export class ShippingController {
  constructor(private readonly shippingService: ShippingService) {}

  @Get('quotes')
  @Resilience('carrier')
  @Timeout('1.5s')
  @Fallback('flatRateQuotes', {
    handleIf: (error) => error instanceof CircuitOpenError,
  })
  getQuotes(@Query('orderId') orderId: string, @Signal() signal: AbortSignal) {
    return this.shippingService.getQuotes(orderId, signal);
  }

  flatRateQuotes() {
    return this.shippingService.flatRateQuotes();
  }

  @Post('shipments')
  @Idempotent()
  @Resilience('carrier')
  @Retry({ idempotent: true })
  createShipment(@Body('orderId') orderId: string, @Signal() signal: AbortSignal) {
    return this.shippingService.createShipment(orderId, signal);
  }
}
```

A handler-level `@Retry()` merges into the preset's retry, field by field. The fields you set win, and the rest come from the preset, then from `defaults.retry`. So this route keeps the preset's 2 attempts and adds only `idempotent: true`. The preset's 2-second timeout and its breaker still apply. Only a decorator can say `idempotent: true`: a preset can't declare every handler that uses it safe to repeat.

`idempotent: true` and `@Idempotent()` solve two different problems:

* `idempotent: true` lets the **server** re-run the handler within one request.
* `@Idempotent()` deduplicates the **client's** retries of the whole request. When a client repeats a request with the same `Idempotency-Key` header, it gets the stored response back and the handler doesn't run again.

Register `IdempotencyModule`**before**`ResilienceModule`:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { IdempotencyModule } from '@nestjs/idempotency';
import { ResilienceModule } from '@nestjs/resilience';
import { OrdersModule } from './orders/orders.module.js';
import { ShippingModule } from './shipping/shipping.module.js';

@Module({
  imports: [
    // Import order matters: the first global interceptor runs outermost.
    IdempotencyModule.forRoot({}),
    ResilienceModule.forRoot({
      defaults: {
        timeout: '5s',
        retry: { attempts: 3, backoff: { delay: '200ms', maxDelay: '2s' } },
      },
      presets: {
        carrier: {
          timeout: '2s',
          retry: { attempts: 2 },
          circuitBreaker: { failureRateThreshold: 50, minimumCalls: 10, openDuration: '30s' },
        },
      },
    }),
    OrdersModule,
    ShippingModule,
  ],
})
export class AppModule {}
```

Both modules register a global interceptor, and the one imported first runs outermost. With this order:

* A replay, or a `409` for a key that is still in flight, is answered before any retry, breaker or timeout runs. A booking that already succeeded replays even while the breaker is open.
* All the retries of one request happen under a single claimed key.
* The stored response is the final outcome, after retries and any fallback.
* A `503` or `504` is a 5xx response, so the key is released and the client can try again later with the same key.

Releasing the key on a `504` has a catch. The key is released as soon as the timeout answers, but the timed-out run may still be in progress, or may already have reached the carrier, so a retry with the same key can overlap it. That's why the side effect has to be safe to repeat downstream, as the carrier makes it with `reference`. Passing the signal on, as `createShipment()` does, stops the local work sooner.

#### Use the same policies inside services[#](/reliability/resilience#use-the-same-policies-inside-services)

Pending orders include a shipping estimate in their `total`. Every 15 minutes, a background job re-quotes them. The job isn't an entrypoint, so it uses a **policy object**, which you get from `ResilienceService`:

shipping/repricing.service.ts

JS TS

```typescript

import { Injectable, Logger } from '@nestjs/common';
import { CircuitOpenError, ResilienceService, type ResiliencePolicy } from '@nestjs/resilience';
import { subtotal } from '../orders/order.js';
import { OrdersService } from '../orders/orders.service.js';
import { CarrierClient } from './carrier.client.js';

@Injectable()
export class RepricingService {
  private readonly logger = new Logger(RepricingService.name);
  private readonly resiliencePolicy: ResiliencePolicy;

  constructor(
    resilience: ResilienceService,
    private readonly ordersService: OrdersService,
    private readonly carrierClient: CarrierClient,
  ) {
    this.resiliencePolicy = resilience.preset('carrier');
  }

  /** Refreshes the shipping part of every pending order's total. */
  async repricePendingOrders(): Promise<number> {
    const pending = (await this.ordersService.findAll()).filter((order) => order.status === 'pending');
    let repriced = 0;
    for (const order of pending) {
      try {
        const quotes = await this.resiliencePolicy.execute(
          ({ signal }) => this.carrierClient.getQuotes(order, signal),
          { source: 'RepricingService.repricePendingOrders' },
        );
        const shipping = Math.min(...quotes.map((quote) => quote.price));
        await this.ordersService.update(order.id, { total: subtotal(order) + shipping });
        repriced++;
      } catch (error) {
        if (error instanceof CircuitOpenError) {
          this.logger.warn(`The carrier is unavailable, stopping after ${repriced} of ${pending.length} orders`);
          break;
        }
        this.logger.error(`Could not reprice order ${order.id}`, (error as Error).stack);
      }
    }
    return repriced;
  }
}
```

Add `RepricingService` to the providers of `ShippingModule`, and call `repricePendingOrders()` from a scheduled job (see [Task scheduling](/application/task-scheduling#declarative-cron-jobs)).

`resilience.preset('carrier')` returns the preset as one policy. Its breaker is the **same instance** that the routes use, so the job and checkout share what they learn about the carrier in both directions:

* While the breaker is open, the job gets a `CircuitOpenError` immediately and stops, instead of spending a timeout on every order.
* If the job is the first to find the carrier failing, its failures open the breaker, and checkout serves flat rates without waiting on timeouts first.

A few details differ from entrypoints:

* `execute()` passes your function the attempt's `signal` and `attempt` number. The `source` option labels the events this call emits.
* A policy object has no `GET` or `POST` to look at, so the preset's retry **always** applies. Only wrap calls that are safe to repeat (a quote is).
* The route's `@Timeout('1.5s')` belongs to the route. The job gets the preset's 2 seconds.
* Create the policy once, for example in the constructor, not on every call. For options that aren't a preset, use `resilience.create(options, name)`.

Why not put `@Retry()` on `repricePendingOrders()`? Resilience decorators are metadata that the global interceptor reads, and interceptors only run around entrypoints. On a provider method, a decorator would do nothing, so bootstrap warns instead:

```bash

WARN [ResilienceModule] Resilience decorators on RepricingService.repricePendingOrders() have no effect: RepricingService is not a controller, resolver or gateway. They apply to entrypoints only. Inside services, use a policy object (ResilienceService.preset() or create(), or new RetryPolicy() etc.).
```

This is a deliberate choice, for three reasons:

* Wrapping arbitrary provider methods would miss request-scoped and transient instances, which Nest creates after bootstrap.
* Retries hidden deep inside services multiply. A route that makes 3 attempts, calling a service that makes 3 attempts, calling an SDK that makes 3 attempts, sends up to 27 requests to a dependency that is already struggling.
* A policy object is visible at the call site, where you can see what it does.

> **Hint** An entrypoint without decorators still maps resilience errors. If a service throws a `CircuitOpenError` inside a plain route, the client gets a `503` with `Retry-After`. Set `mapErrors: false` in the module options to turn this off.

#### Other transports[#](/reliability/resilience#other-transports)

The same decorators work on microservice handlers. The warehouse service asks for quotes over TCP when it re-packs an order:

shipping/shipping.handlers.ts

JS TS

```typescript

import { Controller } from '@nestjs/common';
import { MessagePattern, Payload } from '@nestjs/microservices';
import { Resilience, Retry, Signal } from '@nestjs/resilience';
import { ShippingService } from './shipping.service.js';

@Controller()
export class ShippingHandlers {
  constructor(private readonly shippingService: ShippingService) {}

  @MessagePattern('shipping.quotes')
  @Resilience('carrier')
  @Retry({ attempts: 3 })
  getQuotes(@Payload() data: { orderId: string }, @Signal() signal: AbortSignal) {
    return this.shippingService.getQuotes(data.orderId, signal);
  }
}
```

Add `ShippingHandlers` to the `controllers` of `ShippingModule`.

A message has no `GET` or `POST` to tell whether it's safe to repeat, so on message, event and WebSocket handlers, only a `@Retry()` on the handler itself turns retries on. A preset's retry, or a class-level `@Retry()` without `idempotent: true`, doesn't apply there on its own, so reusing the `carrier` preset can't silently re-run a handler with side effects. Here the handler's `@Retry()` opts in, and its `attempts: 3` raises the preset's 2 attempts to 3. Only use it on handlers that are safe to run twice. Errors reach the caller as an `RpcException` with a structured payload:

```json

{ "status": "error", "code": "CIRCUIT_OPEN", "statusCode": 503, "message": "Service temporarily unavailable", "retryAfter": 30 }
```

A timeout has `"code": "TIMEOUT"` and `"statusCode": 504`, and no `retryAfter`. In a hybrid application, connect the microservice with `inheritAppConfig: true`, or the global interceptor won't reach its handlers (see [Hybrid application](/faq/hybrid-application#sharing-configuration)):

main.ts

JS TS

```typescript

import { NestFactory } from '@nestjs/core';
import { Transport, type MicroserviceOptions } from '@nestjs/microservices';
import { AppModule } from './app.module.js';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.connectMicroservice<MicroserviceOptions>(
    { transport: Transport.TCP, options: { port: 3001 } },
    { inheritAppConfig: true },
  );
  await app.startAllMicroservices();
  await app.listen(process.env.PORT ?? 3000);
}
await bootstrap();
```

GraphQL resolvers work the same way. If your application serves GraphQL, add a resolver to `ShippingModule`'s providers:

shipping/shipping.resolver.ts

JS TS

```typescript

import { Args, Field, Float, Int, ObjectType, Query, Resolver } from '@nestjs/graphql';
import { Resilience, Signal, Timeout } from '@nestjs/resilience';
import { ShippingService } from './shipping.service.js';

@ObjectType('ShippingQuote')
export class ShippingQuoteModel {
  @Field() service: string;
  @Field(() => Float) price: number;
  @Field(() => Int) estimatedDays: number;
}

@Resolver(() => ShippingQuoteModel)
export class ShippingResolver {
  constructor(private readonly shippingService: ShippingService) {}

  @Query(() => [ShippingQuoteModel], { nullable: true })
  @Resilience('carrier')
  @Timeout('1.5s')
  shippingQuotes(@Args('orderId') orderId: string, @Signal() signal: AbortSignal) {
    return this.shippingService.getQuotes(orderId, signal);
  }
}
```

Queries are retried, while mutations need `idempotent: true`, just like `POST` requests. A failure fails only its own field. The response still has status 200, and the error carries the code in `extensions`:

```graphql

{ shippingQuotes(orderId: "1001") { service price } }
```

```json

{
  "errors": [
    {
      "message": "The operation timed out",
      "locations": [{ "line": 1, "column": 3 }],
      "path": ["shippingQuotes"],
      "extensions": { "code": "TIMEOUT", "httpStatus": 504 }
    }
  ],
  "data": { "shippingQuotes": null }
}
```

An open breaker reports `"code": "CIRCUIT_OPEN"`, `"httpStatus": 503` and `"retryAfter"` in seconds. The package sets `httpStatus` rather than Apollo's `extensions.http`, because Apollo would apply `extensions.http` to the whole response, although only one field failed.

#### Observe breaker transitions[#](/reliability/resilience#observe-breaker-transitions)

Every policy emits typed events: `retry`, `timeout`, `circuit-open`, `circuit-half-open`, `circuit-closed`, `circuit-rejected`, `bulkhead-rejected`, `rate-limited` and `fallback`. Each event carries the `policy` name, and its `source` when there is one: the entrypoint (such as `ShippingController.getQuotes`) or the label passed to `execute()`. Inject `ResilienceEvents` to get them: its `events$` is an RxJS stream of every event from this application's policies. Log the ones someone should see:

resilience.logger.ts

JS TS

```typescript

import { Injectable, Logger, type OnModuleInit } from '@nestjs/common';
import { ResilienceEvents } from '@nestjs/resilience';

@Injectable()
export class ResilienceLogger implements OnModuleInit {
  private readonly logger = new Logger('Resilience');

  constructor(private readonly resilienceEvents: ResilienceEvents) {}

  onModuleInit() {
    this.resilienceEvents.events$.subscribe((event) => {
      switch (event.type) {
        case 'circuit-open':
        case 'circuit-half-open':
        case 'circuit-closed':
          this.logger.warn(`Circuit "${event.policy}" went from ${event.from} to ${event.to}`);
          break;
        case 'bulkhead-rejected':
          this.logger.warn(`${event.source} is at capacity (${event.active} running, ${event.queued} queued)`);
          break;
        case 'fallback':
          this.logger.log(`${event.source} answered with its fallback`);
          break;
      }
    });
  }
}
```

Add `ResilienceLogger` to the `providers` array of `AppModule`.

Every policy also publishes each event on a [diagnostics channel](https://nodejs.org/api/diagnostics_channel.html) of its own, such as `nestjs:resilience:timeout` or `nestjs:resilience:circuit-open`, including policies created without the module. Metrics and tracing tools can subscribe without any dependency on this package. `ResilienceTimeoutEvent` is the type of one channel's messages, and `ResilienceEvent` the union of them all:

```typescript

import { subscribe } from 'node:diagnostics_channel';
import type { ResilienceTimeoutEvent } from '@nestjs/resilience';

const timeouts = new Map<string, number>();

subscribe('nestjs:resilience:timeout', (message) => {
  const { policy } = message as ResilienceTimeoutEvent;
  timeouts.set(policy, (timeouts.get(policy) ?? 0) + 1);
});
```

[NestJS Observe](/observability/overview#what-it-offers) already reads outbound HTTP from Node's diagnostics channels (see [Database queries and outbound HTTP](/observability/sdk#database-queries-and-outbound-http)). It doesn't subscribe to the `nestjs:resilience` channels yet. Once it does, it can attach retries and timeouts to the request's span, chart breaker state per name, and alert on bulkhead rejections, with no code in either package that depends on the other.

#### Try it[#](/reliability/resilience#try-it)

Start the application with `CARRIER_URL` pointing at a carrier stub you control, such as a mock server or a few lines of `node:http`. While the carrier answers, checkout gets live quotes:

```bash

$ curl "localhost:3000/shipping/quotes?orderId=1001"
[{"service":"ground","price":6.9,"estimatedDays":4},{"service":"express","price":14.5,"estimatedDays":1}]
```

Now make the stub hang. The same request answers `504` after about 3 seconds, and the stub sees both of its requests cancelled:

```bash

$ curl "localhost:3000/shipping/quotes?orderId=1001"
{"statusCode":504,"error":"Gateway Timeout","message":"The operation timed out","code":"TIMEOUT"}
```

Keep sending it. Each request records two failed attempts. On the fifth slow request, the breaker has 10 calls in its window and 9 of them failed. The breaker opens, the request's second attempt is rejected, and the fallback answers. The application logs:

```bash

WARN [Resilience] Circuit "carrier" went from closed to open
LOG [Resilience] ShippingController.getQuotes answered with its fallback
```

From now on, booking a shipment fails fast without calling the carrier:

```bash

$ curl -i -X POST localhost:3000/shipping/shipments \
    -H "Content-Type: application/json" \
    -H "Idempotency-Key: 5f1c2a9e-shipment-1001" \
    -d '{"orderId":"1001"}'
HTTP/1.1 503 Service Unavailable
Retry-After: 30

{"statusCode":503,"error":"Service Unavailable","message":"Service temporarily unavailable","code":"CIRCUIT_OPEN"}
```

Quotes, meanwhile, answer immediately with the flat rate:

```bash

$ curl "localhost:3000/shipping/quotes?orderId=1002"
[{"service":"flat-rate","price":4.99,"estimatedDays":5}]
```

Let the stub answer again and wait 30 seconds. The next quote request is the probe. It succeeds, so the breaker closes and checkout shows live quotes again:

```bash

WARN [Resilience] Circuit "carrier" went from open to half-open
WARN [Resilience] Circuit "carrier" went from half-open to closed
```

Repeating the booking with the same `Idempotency-Key` now creates the shipment and returns `201`. The earlier 503 released the key.

#### Testing[#](/reliability/resilience#testing)

Resilience behavior is worth testing, but not by waiting 30 seconds for a breaker. Replace `CarrierClient` with a fake, and use Vitest's fake timers for the clock. Fake only `setTimeout`, `clearTimeout` and `Date`, so that the HTTP server and supertest keep working with real I/O:

test/shipping.e2e-spec.ts

JS TS

```typescript

import type { INestApplication } from '@nestjs/common';
import { ResilienceService } from '@nestjs/resilience';
import { Test } from '@nestjs/testing';
import request from 'supertest';
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
import { AppModule } from '../src/app.module.js';
import { CarrierClient } from '../src/shipping/carrier.client.js';

const liveQuotes = [{ service: 'ground', price: 6.9, estimatedDays: 4 }];

/** A carrier call that only ends when its signal aborts. */
const hang = (_order: unknown, signal: AbortSignal) =>
  new Promise((_, reject) => signal.addEventListener('abort', () => reject(signal.reason)));

describe('Shipping quotes', () => {
  let app: INestApplication;
  const carrier = { getQuotes: vi.fn(), createShipment: vi.fn() };

  beforeEach(async () => {
    const moduleRef = await Test.createTestingModule({ imports: [AppModule] })
      .overrideProvider(CarrierClient)
      .useValue(carrier)
      .compile();
    app = moduleRef.createNestApplication({ logger: false });
    await app.listen(0, '127.0.0.1');
    // Fake only timers and Date: the HTTP server and supertest keep real I/O.
    vi.useFakeTimers({ toFake: ['setTimeout', 'clearTimeout', 'Date'] });
  });

  afterEach(async () => {
    vi.useRealTimers();
    vi.resetAllMocks();
    await app.close();
  });

  it('answers 504 and cancels the carrier call when the carrier hangs', async () => {
    carrier.getQuotes.mockImplementation(hang);

    // .then() sends the request now; the clock only moves when we advance it.
    const response = request(app.getHttpServer())
      .get('/shipping/quotes?orderId=1001')
      .then((res) => res);
    await vi.waitFor(() => expect(carrier.getQuotes).toHaveBeenCalled());
    await vi.advanceTimersByTimeAsync(5_000); // two attempts of 1.5 s, plus backoff

    expect((await response).status).toBe(504);
    expect(carrier.getQuotes).toHaveBeenCalledTimes(2);
    const [, signal] = carrier.getQuotes.mock.calls[0];
    expect(signal.aborted).toBe(true);
  });

  it('serves flat rates while the breaker is open, then recovers', async () => {
    carrier.getQuotes.mockResolvedValue(liveQuotes);
    const breaker = app.get(ResilienceService).circuitBreaker('carrier');
    breaker.trip();

    const fallback = await request(app.getHttpServer()).get('/shipping/quotes?orderId=1001');
    expect(fallback.body).toEqual([
      { service: 'flat-rate', price: 4.99, estimatedDays: 5 },
    ]);
    expect(carrier.getQuotes).not.toHaveBeenCalled();

    vi.advanceTimersByTime(30_000); // openDuration: the next call is a probe
    const live = await request(app.getHttpServer()).get('/shipping/quotes?orderId=1001');
    expect(live.body).toEqual(liveQuotes);
    expect(breaker.state).toBe('closed');
  });
});
```

A few things make this work:

* `vi.waitFor()` waits until the request has actually reached the carrier. Only then are there timers to advance. With fake timers enabled, `vi.waitFor()` also moves the clock by its polling interval (50 ms), which stays well within the 1.5-second budget.
* `vi.advanceTimersByTimeAsync()` fires the timeouts and the backoff in order, and lets the promises in between settle.
* `trip()` opens the breaker directly, so you don't have to produce ten failures to test the open state. Because the breaker checks `openDuration` against `Date` on the next call, moving the fake clock forward is enough to make that call a probe.
* Breakers, bulkheads and outbound rate limits belong to the application that created them, so every test application starts with fresh state.
* To test with different settings, such as a shorter `openDuration`, override the module's options with `overrideProvider(RESILIENCE_MODULE_OPTIONS)`.

See [End-to-end testing](/fundamentals/testing#end-to-end-testing) for the testing basics.

#### Production checklist[#](/reliability/resilience#production-checklist)

* **Budget time end to end.** Time per attempt times the number of attempts, plus backoff, must fit inside your client's timeout and your load balancer's. For the quotes route, that's about 3.2 seconds.
* **Retry only what is safe.** Set `idempotent: true` only when a second run within the same request is harmless. Pair it with `@Idempotent()` to handle client retries.
* **Pass the signal to every I/O call.** Without it, timed-out work keeps running in the background, unseen by the bulkhead that admitted it.
* **Retry at one layer.** Retry at the entrypoint or in the service policy, not both, and turn off retries in SDKs and HTTP clients underneath.
* **Tune each breaker to its dependency.** Make `minimumCalls` high enough that two errors at night don't open it, set `openDuration` close to how long the dependency usually takes to recover, and use `recordIf` to leave out errors that aren't outages.
* **Give every breaker a timeout.** A breaker learns only from calls that finish. A call that hangs is never counted, and a hanging probe keeps a half-open breaker rejecting everything else.
* **Remember that state is per process.** With several instances, each one has its own breakers, bulkheads and outbound rate limits, and a restart starts them fresh. Each breaker opens on its own, bulkhead limits apply per instance, and an outbound rate limit allows `limit` calls per instance.
* **Keep fallbacks cheap and independent.** A fallback must never call the dependency it stands in for.
* **Alert on transitions.** A breaker opening and bulkheads rejecting requests are the signals to page on.
* **Register an idempotency store.** Without one, `@Idempotent()` keeps its records in each process's memory, lost on every restart or deploy, and production refuses to start. See [Store keys in PostgreSQL](/reliability/idempotency#store-keys-in-postgresql) in the idempotency tutorial.
* **Wire the modules correctly.** Import `ResilienceModule` once, in the root module, and `IdempotencyModule` before it. Use `inheritAppConfig: true` for hybrid applications.
* **Honor Retry-After in your clients.** It tells them when trying again can succeed.

#### Reference[#](/reliability/resilience#reference)

##### Module options[#](/reliability/resilience#module-options)

`ResilienceModule.forRoot()` takes these options. `forRootAsync()` builds the same object from a factory, a class implementing `ResilienceOptionsFactory`, or an existing provider.

| Option      | Type                               | Default | Description                                                                                                                                                                                                                         |
| ----------- | ---------------------------------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `defaults`  | `ResilienceDefaults`               | none    | Field defaults for `retry`, `timeout`, `circuitBreaker` and `bulkhead`. They fill in stages that a decorator or preset turns on, and never turn a stage on. See [Register the module](/reliability/resilience#register-the-module). |
| `presets`   | `Record<string, ResiliencePreset>` | none    | Named sets of stages: `retry`, `timeout`, `circuitBreaker`, `bulkhead`, `outboundRateLimit` and `fallback`. A preset's breaker, bulkhead and outbound rate limit are shared under the preset's name.                                |
| `mapErrors` | `boolean`                          | `true`  | Turns resilience errors thrown by any handler, with or without decorators, into the transport's error, as listed under Errors below.                                                                                                |
| `isGlobal`  | `boolean`                          | `true`  | Registers the module globally. Register it once, in the root module.                                                                                                                                                                |

Every time-valued option takes milliseconds or a string such as `'200ms'`, `'2s'` or `'15m'`. The options' injection token is `RESILIENCE_MODULE_OPTIONS`.

##### Decorators[#](/reliability/resilience#decorators)

Each decorator works on a handler or on a class, except `@Signal()`, which is a parameter decorator.

| Decorator                    | Options (default)                                                                                                                                                                                                                                                                                                                                                                                  |
| ---------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `@Retry(options)`            | `attempts` (3, including the first; `Infinity` retries until the signal aborts), `backoff`, `retryIf(error, attempt)` (every error except client errors), `idempotent` (see [Retry a POST safely](/reliability/resilience#retry-a-post-safely)). `@Retry(5)` sets `attempts`, and `@Retry(false)` turns off an inherited retry.                                                                    |
| `backoff` (of `@Retry()`)    | `delay` (`'200ms'`), `factor` (2), `maxDelay` (`'30s'`), `jitter`: `'full'`, `'equal'` or `'none'` (`'full'`, or `'none'` when `factor` is 1). Or a function of the failed attempt and its error that returns a duration.                                                                                                                                                                          |
| `@Timeout(duration)`         | Budget per attempt. Without an argument, the preset's or class's timeout, then `defaults.timeout`.                                                                                                                                                                                                                                                                                                 |
| `@CircuitBreaker(options)`   | `name`, `failureRateThreshold` (50, a percentage), `minimumCalls` (10), `slidingWindow` (the last 20 calls: `type` is `'count'` or `'time'`, with a `size`), `openDuration` (`'30s'`), `halfOpenMaxCalls` (1), `recordIf(error)` (every error except client errors). A string is a breaker name. See [Fail fast with a circuit breaker](/reliability/resilience#fail-fast-with-a-circuit-breaker). |
| `@Bulkhead(options)`         | `name`, `maxConcurrent` (10), `maxQueue` (0), `queueTimeout` (no limit). A string is a bulkhead name. See [Cap concurrent CSV exports with a bulkhead](/reliability/resilience#cap-concurrent-csv-exports-with-a-bulkhead).                                                                                                                                                                        |
| `@Fallback(method, options)` | A method name on the same class, or a function, called with the error and the `ExecutionContext`. `handleIf(error)` (every error except client errors).                                                                                                                                                                                                                                            |
| `@Resilience(preset)`        | Applies a preset from `presets`, stage by stage.                                                                                                                                                                                                                                                                                                                                                   |
| `@Signal()`                  | The current attempt's `AbortSignal`.                                                                                                                                                                                                                                                                                                                                                               |

A preset's `outboundRateLimit` takes `limit` (calls per `interval`), `interval` and `maxWait` (0: reject right away).

`ResilienceService` provides `preset(name)`, `create(options, name)`, `circuitBreaker(name)`, `bulkhead(name)`, `circuitBreakers()` and `bulkheads()`. See [Use the same policies inside services](/reliability/resilience#use-the-same-policies-inside-services).

##### Events[#](/reliability/resilience#events)

Every event is published on `ResilienceEvents.events$` and on the diagnostics channel `nestjs:resilience:<type>`. Each payload has `type`, `policy` and, when there is one, `source` (see [Observe breaker transitions](/reliability/resilience#observe-breaker-transitions)).

| Type                | Payload type                      | Other fields                                                                                |
| ------------------- | --------------------------------- | ------------------------------------------------------------------------------------------- |
| `retry`             | `ResilienceRetryEvent`            | `attempt` (the one that failed, 1-based), `delayMs` (the wait before the next one), `error` |
| `timeout`           | `ResilienceTimeoutEvent`          | `timeoutMs`                                                                                 |
| `circuit-open`      | `ResilienceCircuitOpenEvent`      | `from`, `to`                                                                                |
| `circuit-half-open` | `ResilienceCircuitHalfOpenEvent`  | `from`, `to`                                                                                |
| `circuit-closed`    | `ResilienceCircuitClosedEvent`    | `from`, `to`                                                                                |
| `circuit-rejected`  | `ResilienceCircuitRejectedEvent`  | `retryAfterMs`                                                                              |
| `bulkhead-rejected` | `ResilienceBulkheadRejectedEvent` | `reason` (`'full'` or `'queue-timeout'`), `active`, `queued`                                |
| `rate-limited`      | `ResilienceRateLimitedEvent`      | `retryAfterMs`                                                                              |
| `fallback`          | `ResilienceFallbackEvent`         | `error`                                                                                     |

A breaker's state (`from` and `to`) is `'closed'`, `'open'` or `'half-open'`. `ResilienceEvent` is the union of all payload types.

##### Errors[#](/reliability/resilience#errors)

All errors extend `ResilienceError`, which has a `code` and the `policy` name.

| Error                    | Code            | HTTP                    | Message sent to clients             | Fields         |
| ------------------------ | --------------- | ----------------------- | ----------------------------------- | -------------- |
| `ResilienceTimeoutError` | `TIMEOUT`       | 504                     | The operation timed out             | `timeoutMs`    |
| `CircuitOpenError`       | `CIRCUIT_OPEN`  | 503, with `Retry-After` | Service temporarily unavailable     | `retryAfterMs` |
| `BulkheadFullError`      | `BULKHEAD_FULL` | 503                     | Server is at capacity               | `reason`       |
| `OutboundRateLimitError` | `RATE_LIMITED`  | 503, with `Retry-After` | Rate limit of a dependency exceeded | `retryAfterMs` |

On microservice and WebSocket handlers, the error is an `RpcException` or `WsException` whose payload has `status`, `code`, `statusCode`, `message` and, for rejections that know it, `retryAfter` in seconds. On GraphQL, the field's error has `code`, `httpStatus` and `retryAfter` in `extensions` (see [Other transports](/reliability/resilience#other-transports)).

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/reliability/resilience.md)

----
url: https://docs.nestjs.com/v4/fundamentals/unit-testing
----

### Unit Testing

Unit tests are very important in the art of programming. There's a lot of great articles why and how we should write them, thus here I'm gonna show you only the Nest specific tools.

#### Isolated tests

Components, controllers, interceptors.. every Nest application building block is in fact just a simple class. Since each dependency is injected through the constructor, you can easily **mock** them using abilities of the popular libraries, for example [Jasmine](https://github.com/jasmine/jasmine) or [Jest](https://github.com/facebook/jest).

cats.controller.spec.ts

JavaScript TypeScript

TypeScript

```typescript

import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

describe('CatsController', () => {
  let catsController: CatsController;
  let catsService: CatsService;

  beforeEach(() => {
    catsService = new CatsService();
    catsController = new CatsController(catsService);
  });

  describe('findAll', () => {
    it('should return an array of cats', async () => {
      const result = ['test'];
      jest.spyOn(catsService, 'findAll').mockImplementation(() => result);

      expect(await catsController.findAll()).toBe(result);
    });
  });
});
```

TypeScript

```typescript

import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

describe('CatsController', () => {
  let catsController;
  let catsService;

  beforeEach(() => {
    catsService = new CatsService();
    catsController = new CatsController(catsService);
  });

  describe('findAll', () => {
    it('should return an array of cats', async () => {
      const result = ['test'];
      jest.spyOn(catsService, 'findAll').mockImplementation(() => result);

      expect(await catsController.findAll()).toBe(result);
    });
  });
});
```

> **Hint** Keep your test files nearby tested classes. The testing files should have a `.spec` or `.test` suffix.

Here's an example which is using [Jest](https://github.com/facebook/jest) library. We created the instances of the both `CatsController` and the `CatsService` manually, using the `new` keyword. We didn't use any Nest utility. This type of testing is called **isolated tests**.

#### Testing utilities

Nest has a special package `@nestjs/testing`, which gives a set of utilities to boost the testing process. Let's rewrite the example to make use of Nest `Test` static class.

cats.controller.spec.ts

JavaScript TypeScript

TypeScript

```typescript

import { Test } from '@nestjs/testing';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

describe('CatsController', () => {
  let catsController: CatsController;
  let catsService: CatsService;

  beforeEach(async () => {
    const module = await Test.createTestingModule({
        controllers: [CatsController],
        components: [CatsService],
      }).compile();

    catsService = module.get<CatsService>(CatsService);
    catsController = module.get<CatsController>(CatsController);
  });

  describe('findAll', () => {
    it('should return an array of cats', async () => {
      const result = ['test'];
      jest.spyOn(catsService, 'findAll').mockImplementation(() => result);

      expect(await catsController.findAll()).toBe(result);
    });
  });
});
```

TypeScript

```typescript

import { Test } from '@nestjs/testing';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

describe('CatsController', () => {
  let catsController;
  let catsService;

  beforeEach(async () => {
    const module = await Test.createTestingModule({
        controllers: [CatsController],
        components: [CatsService],
      }).compile();

    catsService = module.get(CatsService);
    catsController = module.get(CatsController);
  });

  describe('findAll', () => {
    it('should return an array of cats', async () => {
      const result = ['test'];
      jest.spyOn(catsService, 'findAll').mockImplementation(() => result);

      expect(await catsController.findAll()).toBe(result);
    });
  });
});
```

The `Test` class has a `createTestingModule()` method which takes as an argument the module metadata (same object as the `@Module()` decorator). This method creates a `TestingModule` instance, which in turn provides a few methods, but only one of them is useful within the unit testing - the `compile()`. This function is **asynchronous**, so it has to be awaited. When the module would be compiled and ready to use, you might retrieve any instance using `get()` method.

Sometimes you might want to use test doubles instead of real instances. It's easy because Nest permits to override the component using [custom components](/v4/fundamentals/dependency-injection).

> **Hint** Read more about the `TestingModule` class [here](/v4/fundamentals/e2e-testing).

#### Sponsors

[](https://valor-software.com/)

Nest is an MIT-licensed open source project. It can grow thanks to the support by these awesome people. If you'd like to join them, please read more [here](https://opencollective.com/nest). Thanks!

[](https://opencollective.com/nest/backer/0/website)[](https://opencollective.com/nest/backer/1/website)[](https://opencollective.com/nest/backer/2/website)[](https://opencollective.com/nest/backer/3/website)[](https://opencollective.com/nest/backer/4/website)[](https://opencollective.com/nest/backer/5/website)[](https://opencollective.com/nest/backer/6/website)[](https://opencollective.com/nest/backer/7/website)[](https://opencollective.com/nest/backer/8/website)[](https://opencollective.com/nest/backer/9/website)[](https://opencollective.com/nest/backer/10/website)[](https://opencollective.com/nest/backer/11/website)[](https://opencollective.com/nest/backer/12/website)[](https://opencollective.com/nest/backer/13/website)[](https://opencollective.com/nest/backer/14/website)[](https://opencollective.com/nest/backer/15/website)[](https://opencollective.com/nest/backer/16/website)[](https://opencollective.com/nest/backer/17/website)[](https://opencollective.com/nest/backer/18/website)[](https://opencollective.com/nest/backer/19/website)[](https://opencollective.com/nest/backer/20/website)[](https://opencollective.com/nest/backer/21/website)[](https://opencollective.com/nest/backer/22/website)[](https://opencollective.com/nest/backer/23/website)[](https://opencollective.com/nest/backer/24/website)[](https://opencollective.com/nest/backer/25/website)[](https://opencollective.com/nest/backer/26/website)[](https://opencollective.com/nest/backer/27/website)[](https://opencollective.com/nest/backer/28/website)[](https://opencollective.com/nest/backer/29/website)

[Become a sponsor](https://opencollective.com/nest)

----
url: https://docs.nestjs.com/microservices/kafka
----

[Skip to content](#content)

On this page

* [Kafka](https://docs.nestjs.com/microservices/kafka#kafka)
* [Installation](https://docs.nestjs.com/microservices/kafka#installation)
* [Overview](https://docs.nestjs.com/microservices/kafka#overview)
* [Options](https://docs.nestjs.com/microservices/kafka#options)
* [Client](https://docs.nestjs.com/microservices/kafka#client)
* [Message pattern](https://docs.nestjs.com/microservices/kafka#message-pattern)
* [Regular expression patterns](https://docs.nestjs.com/microservices/kafka#regular-expression-patterns)
* [Message response subscription](https://docs.nestjs.com/microservices/kafka#message-response-subscription)
* [Incoming](https://docs.nestjs.com/microservices/kafka#incoming)
* [Outgoing](https://docs.nestjs.com/microservices/kafka#outgoing)
* [Event-based](https://docs.nestjs.com/microservices/kafka#event-based)
* [Context](https://docs.nestjs.com/microservices/kafka#context)
* [Naming conventions](https://docs.nestjs.com/microservices/kafka#naming-conventions)
* [Retriable exceptions](https://docs.nestjs.com/microservices/kafka#retriable-exceptions)
* [Custom exception handling](https://docs.nestjs.com/microservices/kafka#custom-exception-handling)
* [Commit offsets](https://docs.nestjs.com/microservices/kafka#commit-offsets)
* [Instance status updates](https://docs.nestjs.com/microservices/kafka#instance-status-updates)
* [Underlying producer and consumer](https://docs.nestjs.com/microservices/kafka#underlying-producer-and-consumer)

### Kafka

[Kafka](https://kafka.apache.org/) is an open source, distributed streaming platform with three key capabilities:

* Publish and subscribe to streams of records, similar to a message queue or enterprise messaging system.
* Store streams of records in a fault-tolerant durable way.
* Process streams of records as they occur.

The Kafka project aims to provide a unified, high-throughput, low-latency platform for handling real-time data feeds. It integrates with Apache Storm and Spark for real-time streaming data analysis.

#### Installation[#](/microservices/kafka#installation)

To start building Kafka-based microservices, first install the required package:

```bash

$ npm i --save kafkajs
```

#### Overview[#](/microservices/kafka#overview)

As with other Nest microservice transport layer implementations, you select the Kafka transporter using the `transport` property of the options object passed to the `createMicroservice()` method, along with an optional `options` property, as shown below:

main.ts

JS TS

```typescript

const app = await NestFactory.createMicroservice<MicroserviceOptions>(AppModule, {
  transport: Transport.KAFKA,
  options: {
    client: {
      brokers: ['localhost:9092'],
    }
  }
});
```

```typescript

const app = await NestFactory.createMicroservice(AppModule, {
  transport: Transport.KAFKA,
  options: {
    client: {
      brokers: ['localhost:9092'],
    }
  }
});
```

> **Hint** The `Transport` enum is imported from the `@nestjs/microservices` package.

#### Options[#](/microservices/kafka#options)

The `options` property is specific to the chosen transporter. The **Kafka** transporter exposes the following properties.

|                    |                                                                                                                                                                                                                                                                                                                       |
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `client`           | Client configuration options (see the [KafkaJS client configuration](https://kafka.js.org/docs/configuration))                                                                                                                                                                                                        |
| `consumer`         | Consumer configuration options (see the [KafkaJS consumer options](https://kafka.js.org/docs/consuming#a-name-options-a-options))                                                                                                                                                                                     |
| `run`              | Options passed to the consumer's `run()` method (see [KafkaJS consuming messages](https://kafka.js.org/docs/consuming))                                                                                                                                                                                               |
| `subscribe`        | Options passed to the consumer's `subscribe()` method, except `topics`, which Nest derives from the registered patterns (see [KafkaJS fromBeginning](https://kafka.js.org/docs/consuming#frombeginning))                                                                                                              |
| `producer`         | Producer configuration options (see the [KafkaJS producer options](https://kafka.js.org/docs/producing#options))                                                                                                                                                                                                      |
| `send`             | Options passed to the producer's `send()` method, except `topic` and `messages` (see the [KafkaJS producing messages](https://kafka.js.org/docs/producing#options))                                                                                                                                                   |
| `parser`           | Options of the parser that decodes incoming messages: `keepBinary` passes message values to handlers as buffers instead of decoding them (`boolean`), and `maxMessageSize` is the size in bytes, after decompression, above which a message is skipped instead of decoded. Defaults to `16777216` (16 MiB) (`number`) |
| `producerOnlyMode` | Client only. Skips consumer group registration so the client acts only as a producer (`boolean`)                                                                                                                                                                                                                      |
| `postfixId`        | Suffix appended to the `clientId` and `groupId` values. Defaults to `'-server'` on the server and `'-client'` on the client (`string`)                                                                                                                                                                                |

#### Client[#](/microservices/kafka#client)

Kafka differs slightly from other microservice transporters: instead of the `ClientProxy` type, you use `ClientKafkaProxy`.

As with other microservice transporters, you have [several options](/microservices/basics#client-producer-class) for creating a `ClientKafkaProxy` instance.

One option is the `ClientsModule`. Import it and use its `register()` method to pass an options object with the same properties shown above for the `createMicroservice()` method, plus a `name` property used as the injection token. See the [client section of the microservices overview](/microservices/basics#client-producer-class) to learn more about `ClientsModule`.

```typescript

@Module({
  imports: [
    ClientsModule.register([
      {
        name: 'HERO_SERVICE',
        transport: Transport.KAFKA,
        options: {
          client: {
            clientId: 'hero',
            brokers: ['localhost:9092'],
          },
          consumer: {
            groupId: 'hero-consumer'
          }
        }
      },
    ]),
  ]
  ...
})
```

You can also create a client with `ClientProxyFactory` or the `@Client()` decorator, both described in the [microservices overview](/microservices/basics#client-producer-class).

Use the `@Client()` decorator as follows:

```typescript

@Client({
  transport: Transport.KAFKA,
  options: {
    client: {
      clientId: 'hero',
      brokers: ['localhost:9092'],
    },
    consumer: {
      groupId: 'hero-consumer'
    }
  }
})
client: ClientKafkaProxy;
```

#### Message pattern[#](/microservices/kafka#message-pattern)

The Kafka microservice message pattern uses two topics for the request and reply channels. The `ClientKafkaProxy.send()` method sends messages with a [return address](https://www.enterpriseintegrationpatterns.com/patterns/messaging/ReturnAddress.html) by associating a [correlation id](https://www.enterpriseintegrationpatterns.com/patterns/messaging/CorrelationIdentifier.html), reply topic, and reply partition with the request message. This requires the `ClientKafkaProxy` instance to be subscribed to the reply topic and assigned to at least one partition before sending a message.

As a result, you need at least one reply topic partition for every running Nest application. For example, if you run 4 Nest applications but the reply topic has only 3 partitions, 1 of the Nest applications will fail when it tries to send a message.

When new `ClientKafkaProxy` instances launch, they join the consumer group and subscribe to their respective topics. This triggers a rebalance of the topic partitions assigned to the consumers in the group.

Normally, topic partitions are assigned using the round-robin assigner, which assigns topic partitions to a collection of consumers sorted by consumer names that are randomly set on application launch. However, when a new consumer joins the consumer group, it can be positioned anywhere within that collection. Pre-existing consumers positioned after the new consumer can then be assigned different partitions, and those consumers lose the response messages of requests sent before the rebalance.

To prevent `ClientKafkaProxy` consumers from losing response messages, Nest uses a built-in custom partition assigner. During a rebalance, it lets each existing consumer keep the reply partition it was previously assigned, and distributes the remaining partitions among the other consumers.

#### Regular expression patterns[#](/microservices/kafka#regular-expression-patterns)

KafkaJS supports subscribing to topics by regular expression. Starting with NestJS v12, you can pass a `RegExp` directly to `@MessagePattern()` or `@EventPattern()`. Nest preserves the pattern, forwards it to the KafkaJS `subscribe()` call, and falls back to regular expression matching when resolving a handler for an incoming topic.

JS TS

```typescript

@EventPattern(/^hero\..+$/)
handleHeroEvents(@Payload() data: any, @Ctx() context: KafkaContext) {
  console.log(`Topic: ${context.getTopic()}`);
}
```

```typescript

@Bind(Payload(), Ctx())
@EventPattern(/^hero\..+$/)
handleHeroEvents(data, context) {
  console.log(`Topic: ${context.getTopic()}`);
}
```

This subscribes the handler to every topic matching the expression (`hero.kill.dragon`, `hero.rescue.villager`, and so on) without registering each one explicitly. Use `context.getTopic()` to find out which topic delivered the message.

> **Hint** Regular expression patterns are a Kafka-specific capability; other transporters continue to match patterns by exact value. Nest resets `lastIndex` before matching, so global (`/g`) and sticky (`/y`) expressions do not produce stateful misses.

#### Message response subscription[#](/microservices/kafka#message-response-subscription)

> **Note** This section is relevant only if you use the [request-response](/microservices/basics#request-response) message style (the `@MessagePattern()` decorator and the `ClientKafkaProxy.send()` method). Subscribing to the response topic is not necessary for [event-based](/microservices/basics#event-based) communication (the `@EventPattern()` decorator and the `ClientKafkaProxy.emit()` method).

`ClientKafkaProxy` provides the `subscribeToResponseOf()` method, which takes a request's topic name as an argument and adds the derived reply topic name to a collection of reply topics. This method is required when implementing the message pattern.

heroes.controller.ts

JS TS

```typescript

onModuleInit() {
  this.client.subscribeToResponseOf('hero.kill.dragon');
}
```

If the `ClientKafkaProxy` instance is created asynchronously, call the `subscribeToResponseOf()` method before calling the `connect()` method.

heroes.controller.ts

JS TS

```typescript

async onModuleInit() {
  this.client.subscribeToResponseOf('hero.kill.dragon');
  await this.client.connect();
}
```

#### Incoming[#](/microservices/kafka#incoming)

Nest receives incoming Kafka messages as objects with `key`, `value`, and `headers` properties whose values are of type `Buffer`. Nest parses these values by converting the buffers into strings. If a string is "object-like" (i.e., it starts with a curly brace or a square bracket), Nest attempts to parse it as JSON, except for the `kafka_correlationId`, `kafka_replyTopic` and `kafka_replyPartition` headers it routes replies with, which are always kept as strings. The `value` is then passed to the associated handler.

Nest does not decode a message larger than 16 MiB after decompression, counting its key, its headers and, unless `parser.keepBinary` is set, its value. It logs and skips the message, so that its offset is committed, and a `ClientKafkaProxy` fails the request that such a reply answers. To change the limit, set the `parser.maxMessageSize` option.

#### Outgoing[#](/microservices/kafka#outgoing)

Nest serializes outgoing Kafka messages before publishing events or sending messages. Serialization applies to the arguments passed to the `ClientKafkaProxy``emit()` and `send()` methods, and to the values returned from a `@MessagePattern()` method. It "stringifies" values that are not strings or buffers by using `JSON.stringify()` or the `toString()` prototype method.

heroes.controller.ts

JS TS

```typescript

@Controller()
export class HeroesController {
  @MessagePattern('hero.kill.dragon')
  killDragon(@Payload() message: KillDragonMessage): any {
    const dragonId = message.dragonId;
    const items = [
      { id: 1, name: 'Mythical Sword' },
      { id: 2, name: 'Key to Dungeon' },
    ];
    return items;
  }
}
```

> **Hint**`@Payload()` is imported from the `@nestjs/microservices` package.

You can also key outgoing messages by passing an object with the `key` and `value` properties. Keying messages is important for meeting the [co-partitioning requirement](https://docs.confluent.io/current/ksql/docs/developer-guide/partition-data.html#co-partitioning-requirements).

heroes.controller.ts

JS TS

```typescript

@Controller()
export class HeroesController {
  @MessagePattern('hero.kill.dragon')
  killDragon(@Payload() message: KillDragonMessage): any {
    const realm = 'Nest';
    const heroId = message.heroId;
    const dragonId = message.dragonId;

    const items = [
      { id: 1, name: 'Mythical Sword' },
      { id: 2, name: 'Key to Dungeon' },
    ];

    return {
      headers: {
        realm
      },
      key: heroId,
      value: items
    }
  }
}
```

Messages passed in this format can also contain custom headers set in the `headers` property. Header values must be of type `string` or `Buffer`, and a message can carry at most 10,000 of them, an array value counting once per item. Nest does not send a message with more: `emit()` and `send()` fail, and a `@MessagePattern()` reply is logged and dropped.

heroes.controller.ts

JS TS

```typescript

@Controller()
export class HeroesController {
  @MessagePattern('hero.kill.dragon')
  killDragon(@Payload() message: KillDragonMessage): any {
    const realm = 'Nest';
    const heroId = message.heroId;
    const dragonId = message.dragonId;

    const items = [
      { id: 1, name: 'Mythical Sword' },
      { id: 2, name: 'Key to Dungeon' },
    ];

    return {
      headers: {
        kafka_nestRealm: realm
      },
      key: heroId,
      value: items
    }
  }
}
```

#### Event-based[#](/microservices/kafka#event-based)

While the request-response method is ideal for exchanging messages between services, it is less suitable when your message style is event-based (which is ideal for Kafka), that is, when you want to publish events **without waiting for a response**. In that case, you don't want the overhead of maintaining two topics that request-response requires.

See [Overview: Event-based](/microservices/basics#event-based) and [Overview: Publishing events](/microservices/basics#publishing-events) to learn more.

#### Context[#](/microservices/kafka#context)

In more complex scenarios, you may need additional information about the incoming request. When using the Kafka transporter, you can access the `KafkaContext` object.

JS TS

```typescript

@MessagePattern('hero.kill.dragon')
killDragon(@Payload() message: KillDragonMessage, @Ctx() context: KafkaContext) {
  console.log(`Topic: ${context.getTopic()}`);
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('hero.kill.dragon')
killDragon(message, context) {
  console.log(`Topic: ${context.getTopic()}`);
}
```

> **Hint**`@Payload()`, `@Ctx()` and `KafkaContext` are imported from the `@nestjs/microservices` package.

To access the original Kafka `IncomingMessage` object, use the `getMessage()` method of the `KafkaContext` object, as follows:

JS TS

```typescript

@MessagePattern('hero.kill.dragon')
killDragon(@Payload() message: KillDragonMessage, @Ctx() context: KafkaContext) {
  const originalMessage = context.getMessage();
  const partition = context.getPartition();
  const { headers, timestamp } = originalMessage;
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('hero.kill.dragon')
killDragon(message, context) {
  const originalMessage = context.getMessage();
  const partition = context.getPartition();
  const { headers, timestamp } = originalMessage;
}
```

The `IncomingMessage` object fulfills the following interface:

```typescript

interface IncomingMessage {
  topic: string;
  partition: number;
  timestamp: string;
  size: number;
  attributes: number;
  offset: string;
  key: any;
  value: any;
  headers: Record<string, any>;
}
```

If your handler takes a long time to process each message, consider using the `heartbeat` callback. To retrieve the `heartbeat` function, use the `getHeartbeat()` method of the `KafkaContext`, as follows:

JS TS

```typescript

@MessagePattern('hero.kill.dragon')
async killDragon(@Payload() message: KillDragonMessage, @Ctx() context: KafkaContext) {
  const heartbeat = context.getHeartbeat();

  // Do some slow processing
  await doWorkPart1();

  // Send heartbeat to not exceed the sessionTimeout
  await heartbeat();

  // Do some slow processing again
  await doWorkPart2();
}
```

#### Naming conventions[#](/microservices/kafka#naming-conventions)

The Kafka microservice components append a description of their role to the `client.clientId` and `consumer.groupId` options to prevent collisions between Nest microservice client and server components. By default, the `ClientKafkaProxy` components append `-client` and the `ServerKafka` components append `-server` to both options. The comments below show how the provided values are transformed.

main.ts

JS TS

```typescript

const app = await NestFactory.createMicroservice<MicroserviceOptions>(AppModule, {
  transport: Transport.KAFKA,
  options: {
    client: {
      clientId: 'hero', // hero-server
      brokers: ['localhost:9092'],
    },
    consumer: {
      groupId: 'hero-consumer' // hero-consumer-server
    },
  }
});
```

And for the client:

heroes.controller.ts

JS TS

```typescript

@Client({
  transport: Transport.KAFKA,
  options: {
    client: {
      clientId: 'hero', // hero-client
      brokers: ['localhost:9092'],
    },
    consumer: {
      groupId: 'hero-consumer' // hero-consumer-client
    }
  }
})
client: ClientKafkaProxy;
```

> **Hint** To change the appended suffix, set the `postfixId` option. For further customization of the client and consumer naming conventions, extend the `ClientKafka` and `ServerKafka` classes in your own custom provider and override the constructor.

Because the Kafka microservice message pattern uses two topics for the request and reply channels, the reply pattern is derived from the request topic. By default, the name of the reply topic is the request topic name with `.reply` appended.

heroes.controller.ts

JS TS

```typescript

onModuleInit() {
  this.client.subscribeToResponseOf('hero.get'); // hero.get.reply
}
```

> **Hint** To customize the reply topic naming convention, extend the `ClientKafka` class in your own custom provider and override the `getResponsePatternName()` method.

#### Retriable exceptions[#](/microservices/kafka#retriable-exceptions)

As with other transporters, unhandled exceptions are automatically converted to a "user-friendly" format. However, in some edge cases you might want to bypass this mechanism and let the `kafkajs` driver consume exceptions instead. Throwing an exception while processing a message instructs `kafkajs` to **retry** it (redeliver it), which means that even though the message (or event) handler was triggered, the offset won't be committed to Kafka.

> **Warning** For event handlers (event-based communication), all unhandled exceptions are considered **retriable exceptions** by default.

For message handlers, use the dedicated `KafkaRetriableException` class, as follows:

```typescript

throw new KafkaRetriableException('...');
```

> **Hint** The `KafkaRetriableException` class is exported from the `@nestjs/microservices` package.

> **Warning** Nest handles a message as a request only when it carries the `kafka_correlationId` and `kafka_replyTopic` headers that `ClientKafkaProxy.send()` adds. Any other message, such as one written by a producer other than Nest, is handled as an event, even when it reaches a `@MessagePattern()` handler: its unhandled exceptions are retriable, and the next message of the partition is only processed once the stream the handler returns completes. For topics that other producers write to, make sure message handlers return streams that complete, and handle the messages they cannot process instead of throwing, unless these should be redelivered.

#### Custom exception handling[#](/microservices/kafka#custom-exception-handling)

Along with the default error handling mechanisms, you can create a custom exception filter for Kafka events to manage retry logic. For example, the filter below skips a problematic event after a configurable number of retries:

```typescript

import { Catch, ArgumentsHost, ExceptionFilter, Logger } from '@nestjs/common';
import { KafkaContext } from '@nestjs/microservices';
import { Producer } from 'kafkajs';

@Catch()
export class KafkaMaxRetryExceptionFilter implements ExceptionFilter {
  private readonly logger = new Logger(KafkaMaxRetryExceptionFilter.name);

  constructor(
    private readonly producer: Producer,
    private readonly maxRetries: number,
    // Optional custom function executed when max retries are exceeded
    private readonly skipHandler?: (message: any) => Promise<void>,
  ) {}

  async catch(exception: unknown, host: ArgumentsHost) {
    const kafkaContext = host.switchToRpc().getContext<KafkaContext>();
    const message = kafkaContext.getMessage();
    const currentRetryCount = this.getRetryCountFromContext(kafkaContext);

    if (currentRetryCount >= this.maxRetries) {
      this.logger.warn(
        `Max retries (${
          this.maxRetries
        }) exceeded for message: ${JSON.stringify(message)}`,
      );

      if (this.skipHandler) {
        try {
          await this.skipHandler(message);
        } catch (err) {
          this.logger.error('Error in skipHandler:', err);
        }
      }

      try {
        await this.commitOffset(kafkaContext);
      } catch (commitError) {
        this.logger.error('Failed to commit offset:', commitError);
      }
      return; // Stop propagating the exception
    }

    // Republish the message to the same topic with incremented retry count
    try {
      await this.republishWithRetry(kafkaContext, currentRetryCount + 1);
      await this.commitOffset(kafkaContext);
    } catch (republishError) {
      this.logger.error(
        'Failed to republish message for retry:',
        republishError,
      );
      // Rethrow so that KafkaJS retries the message
      throw exception;
    }
  }

  private getRetryCountFromContext(context: KafkaContext): number {
    const headers = context.getMessage().headers || {};
    const retryHeader = headers['retry-count'];
    if (!retryHeader) {
      return 0;
    }
    // Header values are Buffers, so convert to string first
    const value = Buffer.isBuffer(retryHeader)
      ? retryHeader.toString()
      : String(retryHeader);
    return parseInt(value, 10) || 0;
  }

  private async republishWithRetry(
    context: KafkaContext,
    retryCount: number,
  ): Promise<void> {
    const topic = context.getTopic();
    const message = context.getMessage();

    await this.producer.send({
      topic,
      messages: [
        {
          key: message.key,
          value: message.value,
          headers: {
            ...message.headers,
            'retry-count': retryCount.toString(),
          },
        },
      ],
    });
  }

  private async commitOffset(context: KafkaContext): Promise<void> {
    const consumer = context.getConsumer();
    if (!consumer) {
      throw new Error('Consumer instance is not available from KafkaContext.');
    }

    const topic = context.getTopic();
    const partition = context.getPartition();
    const message = context.getMessage();
    const offset = message.offset;

    if (!topic || partition === undefined || offset === undefined) {
      throw new Error(
        'Incomplete Kafka message context for committing offset.',
      );
    }

    await consumer.commitOffsets([
      {
        topic,
        partition,
        // When committing an offset, commit the next number (i.e., current offset + 1)
        offset: (Number(offset) + 1).toString(),
      },
    ]);
  }
}
```

This filter retries processing a Kafka event up to a configurable number of times. When an exception occurs, it republishes the message to the same topic with an incremented `retry-count` header, then commits the current offset. Once the maximum number of retries is reached, it calls the custom `skipHandler` (if provided) and commits the offset, skipping the problematic event. This allows subsequent events to be processed without interruption.

You can register this filter globally or at the controller level. It requires a Kafka producer instance:

kafka-retry.filter.ts

JS TS

```typescript

import { Inject, Injectable } from '@nestjs/common';
import { Producer } from 'kafkajs';

@Injectable()
export class AppKafkaRetryFilter extends KafkaMaxRetryExceptionFilter {
  constructor(@Inject('KAFKA_PRODUCER') producer: Producer) {
    super(producer, 5); // maxRetries = 5
  }
}
```

```typescript

import { Inject, Injectable } from '@nestjs/common';

@Injectable()
export class AppKafkaRetryFilter extends KafkaMaxRetryExceptionFilter {
  constructor(@Inject('KAFKA_PRODUCER') producer) {
    super(producer, 5); // maxRetries = 5
  }
}
```

my-event.handler.ts

JS TS

```typescript

@Controller()
@UseFilters(AppKafkaRetryFilter)
export class MyEventHandler {
  @EventPattern('your-topic')
  async handleEvent(@Payload() data: any, @Ctx() context: KafkaContext) {
    // Your event processing logic...
  }
}
```

```typescript

@Controller()
@UseFilters(AppKafkaRetryFilter)
export class MyEventHandler {
  @Bind(Payload(), Ctx())
  @EventPattern('your-topic')
  async handleEvent(data, context) {
    // Your event processing logic...
  }
}
```

Make sure to provide the Kafka producer in your module:

app.module.ts

JS TS

```typescript

import { Kafka } from 'kafkajs';

@Module({
  providers: [
    AppKafkaRetryFilter,
    {
      provide: 'KAFKA_PRODUCER',
      useFactory: async () => {
        const kafka = new Kafka({ brokers: ['localhost:9092'] });
        const producer = kafka.producer();
        await producer.connect();
        return producer;
      },
    },
  ],
})
export class AppModule {}
```

#### Commit offsets[#](/microservices/kafka#commit-offsets)

Committing offsets is essential when working with Kafka. By default, messages are committed automatically after a specific time (see the [KafkaJS autocommit documentation](https://kafka.js.org/docs/consuming#autocommit)). `KafkaContext` gives you access to the active consumer for committing offsets manually. The consumer is the KafkaJS consumer and works like the [native KafkaJS implementation](https://kafka.js.org/docs/consuming#manual-committing).

JS TS

```typescript

@EventPattern('user.created')
async handleUserCreated(@Payload() data: IncomingMessage, @Ctx() context: KafkaContext) {
  // business logic

  const { offset } = context.getMessage();
  const partition = context.getPartition();
  const topic = context.getTopic();
  const consumer = context.getConsumer();
  // Commit the next offset to consume (i.e., current offset + 1)
  await consumer.commitOffsets([
    { topic, partition, offset: (Number(offset) + 1).toString() },
  ]);
}
```

```typescript

@Bind(Payload(), Ctx())
@EventPattern('user.created')
async handleUserCreated(data, context) {
  // business logic

  const { offset } = context.getMessage();
  const partition = context.getPartition();
  const topic = context.getTopic();
  const consumer = context.getConsumer();
  // Commit the next offset to consume (i.e., current offset + 1)
  await consumer.commitOffsets([
    { topic, partition, offset: (Number(offset) + 1).toString() },
  ]);
}
```

To disable auto-committing, set `autoCommit: false` in the `run` configuration, as follows:

main.ts

JS TS

```typescript

const app = await NestFactory.createMicroservice<MicroserviceOptions>(AppModule, {
  transport: Transport.KAFKA,
  options: {
    client: {
      brokers: ['localhost:9092'],
    },
    run: {
      autoCommit: false
    }
  }
});
```

```typescript

const app = await NestFactory.createMicroservice(AppModule, {
  transport: Transport.KAFKA,
  options: {
    client: {
      brokers: ['localhost:9092'],
    },
    run: {
      autoCommit: false
    }
  }
});
```

#### Instance status updates[#](/microservices/kafka#instance-status-updates)

To get real-time updates on the connection and the state of the underlying driver instance, subscribe to the `status` stream. This stream provides status updates specific to the chosen driver. For the Kafka driver, the `status` stream emits `connected`, `disconnected`, `rebalancing`, `crashed`, and `stopped` events.

```typescript

this.client.status.subscribe((status: KafkaStatus) => {
  console.log(status);
});
```

> **Hint** The `KafkaStatus` type is imported from the `@nestjs/microservices` package.

Similarly, you can subscribe to the server's `status` stream to receive notifications about the server's status:

```typescript

const server = app.connectMicroservice<MicroserviceOptions>(...);
server.status.subscribe((status: KafkaStatus) => {
  console.log(status);
});
```

#### Underlying producer and consumer[#](/microservices/kafka#underlying-producer-and-consumer)

For more advanced use cases, you may need to access the underlying producer and consumer instances, for example, to close the connection manually or to use driver-specific methods. In most cases, however, you **shouldn't need** to access the driver directly.

To do so, use the `producer` and `consumer` properties exposed by the `ClientKafkaProxy` instance.

```typescript

const producer = this.client.producer;
const consumer = this.client.consumer;
```

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/microservices/kafka.md)

----
url: https://docs.nestjs.com/v8/cli/scripts
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Nest CLI and scripts](https://docs.nestjs.com/v8/cli/scripts#nest-cli-and-scripts)
* [The nest binary](https://docs.nestjs.com/v8/cli/scripts#the-nest-binary)
* [Build](https://docs.nestjs.com/v8/cli/scripts#build)
* [Execution](https://docs.nestjs.com/v8/cli/scripts#execution)
* [Generation](https://docs.nestjs.com/v8/cli/scripts#generation)
* [Package scripts](https://docs.nestjs.com/v8/cli/scripts#package-scripts)
* [Backward compatibility](https://docs.nestjs.com/v8/cli/scripts#backward-compatibility)
* [Migration](https://docs.nestjs.com/v8/cli/scripts#migration)

```bash

$ npm run build
```

and

```bash

$ npm run start
```

```bash

$ npm install -g @nestjs/cli
$ cd  /some/project/root/folder
$ npm install -D @nestjs/cli
```

You can then replace the `scripts` defined in `package.json` with the following ones:

```typescript

"build": "nest build",
"start": "nest start",
"start:dev": "nest start --watch",
"start:debug": "nest start --debug --watch",
```

----
url: https://docs.nestjs.com/v6/cli/monorepo
----

* [Workspaces](https://docs.nestjs.com/v6/cli/monorepo#workspaces)
* [Standard mode](https://docs.nestjs.com/v6/cli/monorepo#standard-mode)
* [Monorepo mode](https://docs.nestjs.com/v6/cli/monorepo#monorepo-mode)
* [Workspace projects](https://docs.nestjs.com/v6/cli/monorepo#workspace-projects)
* [Applications](https://docs.nestjs.com/v6/cli/monorepo#applications)
* [Libraries](https://docs.nestjs.com/v6/cli/monorepo#libraries)
* [CLI properties](https://docs.nestjs.com/v6/cli/monorepo#cli-properties)
* [Global compiler options](https://docs.nestjs.com/v6/cli/monorepo#global-compiler-options)
* [Global generate options](https://docs.nestjs.com/v6/cli/monorepo#global-generate-options)
* [Project-specific generate options](https://docs.nestjs.com/v6/cli/monorepo#project-specific-generate-options)
* [Specified compiler](https://docs.nestjs.com/v6/cli/monorepo#specified-compiler)
* [Webpack options](https://docs.nestjs.com/v6/cli/monorepo#webpack-options)
* [Assets](https://docs.nestjs.com/v6/cli/monorepo#assets)
* [Project properties](https://docs.nestjs.com/v6/cli/monorepo#project-properties)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/cli/workspaces.md "Suggest Edits")

```bash

nest new my-project
```

```bash

cd my-project
nest generate app my-app
```

> **Warning** The conversion of a standard mode structure to monorepo only works for projects that have followed the canonical Nest project structure. Specifically, during conversion, the schematic attempts to relocate the `src` and `test` folders in a project folder beneath the `apps` folder in the root. If a project does not use this structure, the conversion will fail or produce unreliable results.

#### Workspace projects[#](/cli/monorepo#workspace-projects)

A mono repo uses the concept of a workspace to manage its member entities. Workspaces are composed of **projects**. A project may be either:

* an **application**: a full Nest application including a `main.ts` file to bootstrap the application. Aside from compile and build considerations, an application-type project within a workspace is functionally identical to an application within a *standard mode* structure.
* a **library**: a library is a way of packaging a general purpose set of features (modules, providers, controllers, etc.) that can be used within other projects. A library cannot run on its own, and has no `main.ts` file. Read more about libraries [here](/v6/cli/libraries).

All workspaces have a **default project** (which should be an application-type project). This is defined by the top-level `"root"` property in the `nest-cli.json` file, which points at the root of the default project (see [CLI properties](/cli/monorepo#cli-properties) below for more details). Usually, this is the **standard mode** application you started with, and later converted to a monorepo using `nest generate app`. When you follow these steps, this property is populated automatically.

Default projects are used by `nest` commands like `nest build` and `nest start` when a project name is not supplied.

For example, in the above monorepo structure, running

```bash

$ nest start
```

will start up the `my-project` app. To start `my-app`, we'd use:

```bash

$ nest start my-app
```

#### Applications[#](/cli/monorepo#applications)

Application-type projects, or what we might informally refer to as just "applications", are complete Nest applications that you can run and deploy. You generate an application-type project with `nest generate app`.

This command automatically generates a project skeleton, including the standard `src` and `test` folders from the [typescript starter](https://github.com/nestjs/typescript-starter). Unlike standard mode, an application project in a monorepo does not have any of the package dependency (`package.json`) or other project configuration artifacts like `.prettierrc` and `tslint.json`. Instead, the monorepo-wide dependencies and config files are used.

However, the schematic does generate a project-specific `tsconfig.app.json` file in the root folder of the project. This config file automatically sets appropriate build options, including setting the compilation output folder properly. The file extends the top-level (monorepo) `tsconfig.json` file, so you can manage global settings monorepo-wide, but override them if needed at the project level.

#### Libraries[#](/cli/monorepo#libraries)

As mentioned, library-type projects, or simply "libraries", are packages of Nest components that need to be composed into applications in order to run. You generate a library-type project with `nest generate library`. Deciding what belongs in a library is an architectural design decision. We discuss libraries in depth in the [libraries](/v6/cli/libraries) chapter.

#### CLI properties[#](/cli/monorepo#cli-properties)

Nest keeps the metadata needed to organize, build and deploy both standard and monorepo structured projects in the `nest-cli.json` file. Nest automatically adds to and updates this file as you add projects, so you usually do not have to think about it or edit its contents. However, there are some settings you may want to change manually, so it's helpful to have an overview understanding of the file.

After running the steps above to create a monorepo, our `nest-cli.json` file looks like this:

```javascript

{
  "collection": "@nestjs/schematics",
  "sourceRoot": "apps/my-project/src",
  "monorepo": true,
  "root": "apps/my-project",
  "compilerOptions": {
    "webpack": true,
    "tsConfigPath": "apps/my-project/tsconfig.app.json"
  },
  "projects": {
    "my-project": {
      "type": "application",
      "root": "apps/my-project",
      "entryFile": "main",
      "sourceRoot": "apps/my-project/src",
      "compilerOptions": {
        "tsConfigPath": "apps/my-project/tsconfig.app.json"
      }
    },
    "my-app": {
      "type": "application",
      "root": "apps/my-app",
      "entryFile": "main",
      "sourceRoot": "apps/my-app/src",
      "compilerOptions": {
        "tsConfigPath": "apps/my-app/tsconfig.app.json"
      }
    }
  }
}
```

| Property Name       | Property Value Type | Description                                                                                                                                                                                                                           |
| ------------------- | ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `webpack`           | boolean             | If `true`, use [webpack compiler](https://webpack.js.org/). If `false` or not present, use `tsc`. In monorepo mode, the default is `true` (use webpack), in standard mode, the default is `false` (use `tsc`). See below for details. |
| `tsConfigPath`      | string              | (**monorepo only**) Points at the file containing the `tsconfig.json` settings that will be used when `nest build` or `nest start` is called without a `project` option (e.g., when the default project is built or started).         |
| `webpackConfigPath` | string              | Points at a webpack options file. If not specified, Nest looks for the file `webpack.config.js`. See below for more details.                                                                                                          |
| `deleteOutDir`      | boolean             | If `true`, whenever the compiler is invoked, it will first remove the compilation output directory (as configured in `tsconfig.json`, where the default is `./dist`).                                                                 |
| `assets`            | array               | Enables automatically distributing non-TypeScript assets whenever a compilation step begins (asset distribution does **not** happen on incremental compiles in `--watch` mode). See below for details.                                |

#### Global generate options[#](/cli/monorepo#global-generate-options)

These properties specify the default generate options to be used by the `nest generate` command.

| Property Name | Property Value Type | Description                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| ------------- | ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `spec`        | boolean *or* object | If the value is boolean, a value of `true` enables `spec` generation by default and a value of `false` disables it. A flag passed on the CLI command line overrides this setting, as does a project-specific `generateOptions` setting (more below). If the value is an object, each key represents a schematic name, and the boolean value determines whether the default spec generation is enabled / disabled for that specific schematic. |

The following example uses a boolean value to specify that spec file generation should be disabled by default for all projects:

```javascript

{
  "generateOptions": {
    "spec": false
  },
  ...
}
```

In the following example, `spec` file generation is disabled only for `service` schematics (e.g., `nest generate service...`):

```javascript

{
  "generateOptions": {
    "spec": {
      "service": false
    }
  },
  ...
}
```

> **Warning** When specifying the `spec` as an object, the key for the generation schematic does not currently support automatic alias handling. This means that specifying a key as for example `service: false` and trying to generate a service via the alias `s`, the spec would still be generated. To make sure both the normal schematic name and the alias work as intended, specify both the normal command name as well as the alias, as seen below.
>
> ```javascript
>
> {
>   "generateOptions": {
>     "spec": {
>       "service": false,
>       "s": false
>     }
>   },
>   ...
> }
> ```

#### Project-specific generate options[#](/cli/monorepo#project-specific-generate-options)

In addition to providing global generate options, you may also specify project-specific generate options. The project specific generate options follow the exact same format as the global generate options, but are specified directly on each project.

Project-specific generate options override global generate options.

```javascript

{
  "projects": {
    "cats-project": {
      "generateOptions": {
        "spec": {
          "service": false
        }
      },
      ...
    }
  },
  ...
}
```

> **Notice** The order of precedence for generate options is as follows. Options specified on the CLI command line take precedence over project-specific options. Project-specific options override global options.

#### Specified compiler[#](/cli/monorepo#specified-compiler)

The reason for the different default compilers is that for larger projects (e.g., more typical in a monorepo) webpack can have significant advantages in build times and in producing a single file bundling all project components together. If you wish to generate individual files, set `"webpack"` to `false`, which will cause the build process to use `tsc`.

#### Webpack options[#](/cli/monorepo#webpack-options)

The webpack options file can contain standard [webpack configuration options](https://webpack.js.org/configuration/). For example, to tell webpack to bundle `node_modules` (which are excluded by default), add the following to `webpack.config.js`:

```javascript

module.exports = {
  externals: [],
};
```

Since the webpack config file is a JavaScript file, you can even expose a function that takes default options and returns a modified object:

```javascript

module.exports = function(options) {
  return {
    ...options,
    externals: [],
  };
}
```

#### Assets[#](/cli/monorepo#assets)

TypeScript compilation automatically distributes compiler output (`.js` and `.d.ts` files) to the specified output directory. It can also be convenient to distribute non-TypeScript files, such as `.graphql` files, `images`, `.html` files and other assets. This allows you to treat `nest build` (and any initial compilation step) as a lightweight **development build** step, where you may be editing non-TypeScript files and iteratively compiling and testing.

The value of the `assets` key should be an array of elements specifying the files to be distributed. The elements can be simple strings with `glob`-like file specs, for example:

```typescript

"assets": ["**/*.graphql"]
```

For finer control, the elements can be objects with the following keys:

* `"include"`: `glob`-like file specifications for the assets to be distributed
* `"exclude"`: `glob`-like file specifications for assets to be **excluded** from the `include` list
* `"outDir"`: a string specifying the path (relative to the root folder) where the assets should be distributed. Defaults to the same output directory configured for compiler output.

For example:

```typescript

"assets": [
  { "include": "**/*.graphql", "exclude": "**/omitted.graphql" },
]
```

#### Project properties[#](/cli/monorepo#project-properties)

This element exists only for monorepo-mode structures. You generally should not edit these properties, as they are used by Nest to locate projects and their configuration options within the monorepo.

----
url: https://docs.nestjs.com/v6/recipes/sql-sequelize
----

* [SQL (Sequelize)](https://docs.nestjs.com/v6/recipes/sql-sequelize#sql-sequelize)
* [Getting started](https://docs.nestjs.com/v6/recipes/sql-sequelize#getting-started)
* [Model injection](https://docs.nestjs.com/v6/recipes/sql-sequelize#model-injection)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/recipes/sql-sequelize.md "Suggest Edits")

### SQL (Sequelize)

##### This chapter applies only to TypeScript

[Sequelize](https://github.com/sequelize/sequelize) is a popular Object Relational Mapper (ORM) written in a vanilla JavaScript, but there is a [sequelize-typescript](https://github.com/RobinBuschmann/sequelize-typescript) TypeScript wrapper which provides a set of decorators and other extras for the base sequelize.

#### Getting started[#](/recipes/sql-sequelize#getting-started)

To start the adventure with this library we have to install the following dependencies:

```bash

$ npm install --save sequelize sequelize-typescript mysql2
$ npm install --save-dev @types/sequelize
```

The first step we need to do is create a **Sequelize** instance with an options object passed into the constructor. Also, we need to add all models (the alternative is to use `modelPaths` property) and `sync()` our database tables.

database.providers.ts

JS TS

```typescript

import { Sequelize } from 'sequelize-typescript';
import { Cat } from '../cats/cat.entity';

export const databaseProviders = [
  {
    provide: 'SEQUELIZE',
    useFactory: async () => {
      const sequelize = new Sequelize({
        dialect: 'mysql',
        host: 'localhost',
        port: 3306,
        username: 'root',
        password: 'password',
        database: 'nest',
      });
      sequelize.addModels([Cat]);
      await sequelize.sync();
      return sequelize;
    },
  },
];
```

> **Hint** Following best practices, we declared the custom provider in the separated file which has a `*.providers.ts` suffix.

Then, we need to export these providers to make them **accessible** for the rest part of the application.

```typescript

import { Module } from '@nestjs/common';
import { databaseProviders } from './database.providers';

@Module({
  providers: [...databaseProviders],
  exports: [...databaseProviders],
})
export class DatabaseModule {}
```

Now we can inject the `Sequelize` object using `@Inject()` decorator. Each class that would depend on the `Sequelize` async provider will wait until a `Promise` is resolved.

#### Model injection[#](/recipes/sql-sequelize#model-injection)

In [Sequelize](https://github.com/sequelize/sequelize) the **Model** defines a table in the database. Instances of this class represent a database row. Firstly, we need at least one entity:

cat.entity.ts

JS TS

```typescript

import { Table, Column, Model } from 'sequelize-typescript';

@Table
export class Cat extends Model<Cat> {
  @Column
  name: string;

  @Column
  age: number;

  @Column
  breed: string;
}
```

The `Cat` entity belongs to the `cats` directory. This directory represents the `CatsModule`. Now it's time to create a **Repository** provider:

cats.providers.ts

JS TS

```typescript

import { Cat } from './cat.entity';

export const catsProviders = [
  {
    provide: 'CATS_REPOSITORY',
    useValue: Cat,
  },
];
```

> **Notice** In the real-world applications you should avoid **magic strings**. Both `CATS_REPOSITORY` and `SEQUELIZE` should be kept in the separated `constants.ts` file.

In Sequelize, we use static methods to manipulate the data, and thus we created an **alias** here.

Now we can inject the `CATS_REPOSITORY` to the `CatsService` using the `@Inject()` decorator:

cats.service.ts

JS TS

```typescript

import { Injectable, Inject } from '@nestjs/common';
import { CreateCatDto } from './dto/create-cat.dto';
import { Cat } from './cat.entity';

@Injectable()
export class CatsService {
  constructor(
    @Inject('CATS_REPOSITORY') private readonly catsRepository: typeof Cat) {}

  async findAll(): Promise<Cat[]> {
    return this.catsRepository.findAll<Cat>();
  }
}
```

The database connection is **asynchronous**, but Nest makes this process completely invisible for the end-user. The `CATS_REPOSITORY` provider is waiting for the db connection, and the `CatsService` is delayed until repository is ready to use. The entire application can start when each class is instantiated.

Here is a final `CatsModule`:

cats.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';
import { catsProviders } from './cats.providers';
import { DatabaseModule } from '../database/database.module';

@Module({
  imports: [DatabaseModule],
  controllers: [CatsController],
  providers: [
    CatsService,
    ...catsProviders,
  ],
})
export class CatsModule {}
```

> **Hint** Do not forget to import the `CatsModule` into the root `ApplicationModule`.

----
url: https://docs.nestjs.com/v9/graphql/complexity
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Complexity](https://docs.nestjs.com/v9/graphql/complexity#complexity)
* [Installation](https://docs.nestjs.com/v9/graphql/complexity#installation)
* [Getting started](https://docs.nestjs.com/v9/graphql/complexity#getting-started)
* [Field-level complexity](https://docs.nestjs.com/v9/graphql/complexity#field-level-complexity)
* [Query/Mutation-level complexity](https://docs.nestjs.com/v9/graphql/complexity#querymutation-level-complexity)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/complexity.md "Suggest Edits")

### Complexity

> **Warning** This chapter applies only to the code first approach.

Query complexity allows you to define how complex certain fields are, and to restrict queries with a **maximum complexity**. The idea is to define how complex each field is by using a simple number. A common default is to give each field a complexity of `1`. In addition, the complexity calculation of a GraphQL query can be customized with so-called complexity estimators. A complexity estimator is a simple function that calculates the complexity for a field. You can add any number of complexity estimators to the rule, which are then executed one after another. The first estimator that returns a numeric complexity value determines the complexity for that field.

The `@nestjs/graphql` package integrates very well with tools like [graphql-query-complexity](https://github.com/slicknode/graphql-query-complexity) that provides a cost analysis-based solution. With this library, you can reject queries to your GraphQL server that are deemed too costly to execute.

#### Installation[#](/graphql/complexity#installation)

To begin using it, we first install the required dependency.

```bash

$ npm install --save graphql-query-complexity
```

#### Getting started[#](/graphql/complexity#getting-started)

Once the installation process is complete, we can define the `ComplexityPlugin` class:

```typescript

import { GraphQLSchemaHost } from "@nestjs/graphql";
import { Plugin } from "@nestjs/apollo";
import {
  ApolloServerPlugin,
  GraphQLRequestListener,
} from 'apollo-server-plugin-base';
import { GraphQLError } from 'graphql';
import {
  fieldExtensionsEstimator,
  getComplexity,
  simpleEstimator,
} from 'graphql-query-complexity';

@Plugin()
export class ComplexityPlugin implements ApolloServerPlugin {
  constructor(private gqlSchemaHost: GraphQLSchemaHost) {}

  async requestDidStart(): Promise<GraphQLRequestListener> {
    const maxComplexity = 20;
    const { schema } = this.gqlSchemaHost;

    return {
      async didResolveOperation({ request, document }) {
        const complexity = getComplexity({
          schema,
          operationName: request.operationName,
          query: document,
          variables: request.variables,
          estimators: [
            fieldExtensionsEstimator(),
            simpleEstimator({ defaultComplexity: 1 }),
          ],
        });
        if (complexity > maxComplexity) {
          throw new GraphQLError(
            `Query is too complex: ${complexity}. Maximum allowed complexity: ${maxComplexity}`,
          );
        }
        console.log('Query Complexity:', complexity);
      },
    };
  }
}
```

For demonstration purposes, we specified the maximum allowed complexity as `20`. In the example above, we used 2 estimators, the `simpleEstimator` and the `fieldExtensionsEstimator`.

* `simpleEstimator`: the simple estimator returns a fixed complexity for each field
* `fieldExtensionsEstimator`: the field extensions estimator extracts the complexity value for each field of your schema

> **Hint** Remember to add this class to the providers array in any module.

#### Field-level complexity[#](/graphql/complexity#field-level-complexity)

With this plugin in place, we can now define the complexity for any field by specifying the `complexity` property in the options object passed into the `@Field()` decorator, as follows:

```typescript

@Field({ complexity: 3 })
title: string;
```

Alternatively, you can define the estimator function:

```typescript

@Field({ complexity: (options: ComplexityEstimatorArgs) => ... })
title: string;
```

#### Query/Mutation-level complexity[#](/graphql/complexity#querymutation-level-complexity)

In addition, `@Query()` and `@Mutation()` decorators may have a `complexity` property specified like so:

```typescript

@Query({ complexity: (options: ComplexityEstimatorArgs) => options.args.count * options.childComplexity })
items(@Args('count') count: number) {
  return this.itemsService.getItems({ count });
}
```

----
url: https://docs.nestjs.com/v10/openapi/types-and-parameters
----

* [Types and parameters](https://docs.nestjs.com/v10/openapi/types-and-parameters#types-and-parameters)
* [Arrays](https://docs.nestjs.com/v10/openapi/types-and-parameters#arrays)
* [Circular dependencies](https://docs.nestjs.com/v10/openapi/types-and-parameters#circular-dependencies)
* [Generics and interfaces](https://docs.nestjs.com/v10/openapi/types-and-parameters#generics-and-interfaces)
* [Enums](https://docs.nestjs.com/v10/openapi/types-and-parameters#enums)
* [Enums schema](https://docs.nestjs.com/v10/openapi/types-and-parameters#enums-schema)
* [Property value examples](https://docs.nestjs.com/v10/openapi/types-and-parameters#property-value-examples)
* [Raw definitions](https://docs.nestjs.com/v10/openapi/types-and-parameters#raw-definitions)
* [Extra models](https://docs.nestjs.com/v10/openapi/types-and-parameters#extra-models)
* [oneOf, anyOf, allOf](https://docs.nestjs.com/v10/openapi/types-and-parameters#oneof-anyof-allof)
* [Schema name and description](https://docs.nestjs.com/v10/openapi/types-and-parameters#schema-name-and-description)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/openapi/types-and-parameters.md "Suggest Edits")

### 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:

```typescript

@Post()
async create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

> **Hint** To explicitly set the body definition use the `@ApiBody()` decorator (imported from the `@nestjs/swagger` package).

Based on the `CreateCatDto`, the following model definition Swagger UI will be created:

As you can see, the definition is empty although the class has a few declared properties. In order to make the class properties visible to the `SwaggerModule`, we have to either annotate them with the `@ApiProperty()` decorator or use the CLI plugin (read more in the **Plugin** section) which will do it automatically:

```typescript

import { ApiProperty } from '@nestjs/swagger';

export class CreateCatDto {
  @ApiProperty()
  name: string;

  @ApiProperty()
  age: number;

  @ApiProperty()
  breed: string;
}
```

> **Hint** Instead of manually annotating each property, consider using the Swagger plugin (see [Plugin](/v10/openapi/cli-plugin) section) which will automatically provide this for you.

Let's open the browser and verify the generated `CreateCatDto` model:

In addition, the `@ApiProperty()` decorator allows setting various [Schema Object](https://swagger.io/specification/#schemaObject) properties:

```typescript

@ApiProperty({
  description: 'The age of a cat',
  minimum: 1,
  default: 1,
})
age: number;
```

> **Hint** Instead of explicitly typing the `@ApiProperty({ required: false })` you can use the `@ApiPropertyOptional()` short-hand decorator.

In order to explicitly set the type of the property, use the `type` key:

```typescript

@ApiProperty({
  type: Number,
})
age: number;
```

#### Arrays[#](/openapi/types-and-parameters#arrays)

When the property is an array, we must manually indicate the array type as shown below:

```typescript

@ApiProperty({ type: [String] })
names: string[];
```

> **Hint** Consider using the Swagger plugin (see [Plugin](/v10/openapi/cli-plugin) section) which will automatically detect arrays.

```typescript

@ApiProperty({ type: () => Node })
node: Node;
```

> **Hint** Consider using the Swagger plugin (see [Plugin](/v10/openapi/cli-plugin) section) which will automatically detect circular dependencies.

#### Generics and interfaces[#](/openapi/types-and-parameters#generics-and-interfaces)

Since TypeScript does not store metadata about generics or interfaces, when you use them in your DTOs, `SwaggerModule` may not be able to properly generate model definitions at runtime. For instance, the following code won't be correctly inspected by the Swagger module:

```typescript

createBulk(@Body() usersDto: CreateUserDto[])
```

In order to overcome this limitation, you can set the type explicitly:

```typescript

@ApiBody({ type: [CreateUserDto] })
createBulk(@Body() usersDto: CreateUserDto[])
```

#### Enums[#](/openapi/types-and-parameters#enums)

To identify an `enum`, we must manually set the `enum` property on the `@ApiProperty` with an array of values.

```typescript

@ApiProperty({ enum: ['Admin', 'Moderator', 'User']})
role: UserRole;
```

Alternatively, define an actual TypeScript enum as follows:

```typescript

export enum UserRole {
  Admin = 'Admin',
  Moderator = 'Moderator',
  User = 'User',
}
```

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

```typescript

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

With `isArray` set to **true**, the `enum` can be selected as a **multi-select**:

#### Enums schema[#](/openapi/types-and-parameters#enums-schema)

By default, the `enum` property will add a raw definition of [Enum](https://swagger.io/docs/specification/data-models/enums/) on the `parameter`.

```yaml

- breed:
    type: 'string'
    enum:
      - Persian
      - Tabby
      - Siamese
```

The above specification works fine for most cases. However, if you are utilizing a tool that takes the specification as **input** and generates **client-side** code, you might run into a problem with the generated code containing duplicated `enums`. Consider the following code snippet:

```typescript

// generated client-side code
export class CatDetail {
  breed: CatDetailEnum;
}

export class CatInformation {
  breed: CatInformationEnum;
}

export enum CatDetailEnum {
  Persian = 'Persian',
  Tabby = 'Tabby',
  Siamese = 'Siamese',
}

export enum CatInformationEnum {
  Persian = 'Persian',
  Tabby = 'Tabby',
  Siamese = 'Siamese',
}
```

> **Hint** The above snippet is generated using a tool called [NSwag](https://github.com/RicoSuter/NSwag).

You can see that now you have two `enums` that are exactly the same. To address this issue, you can pass an `enumName` along with the `enum` property in your decorator.

```typescript

export class CatDetail {
  @ApiProperty({ enum: CatBreed, enumName: 'CatBreed' })
  breed: CatBreed;
}
```

The `enumName` property enables `@nestjs/swagger` to turn `CatBreed` into its own `schema` which in turns makes `CatBreed` enum reusable. The specification will look like the following:

```yaml

CatDetail:
  type: 'object'
  properties:
    ...
    - breed:
        schema:
          $ref: '#/components/schemas/CatBreed'
CatBreed:
  type: string
  enum:
    - Persian
    - Tabby
    - Siamese
```

> **Hint** Any **decorator** that takes `enum` as a property will also take `enumName`.

#### Property value examples[#](/openapi/types-and-parameters#property-value-examples)

You can set a single example for a property by using the `example` key, like this:

```typescript

@ApiProperty({
  example: 'persian',
})
breed: string;
```

If you want to provide multiple examples, you can use the `examples` key by passing in an object structured like this:

```typescript

@ApiProperty({
  examples: {
    Persian: { value: 'persian' },
    Tabby: { value: 'tabby' },
    Siamese: { value: 'siamese' },
    'Scottish Fold': { value: 'scottish_fold' },
  },
})
breed: string;
```

#### Raw definitions[#](/openapi/types-and-parameters#raw-definitions)

In certain cases, such as deeply nested arrays or matrices, you may need to manually define your type:

```typescript

@ApiProperty({
  type: 'array',
  items: {
    type: 'array',
    items: {
      type: 'number',
    },
  },
})
coords: number[][];
```

You can also specify raw object schemas, like this:

```typescript

@ApiProperty({
  type: 'object',
  properties: {
    name: {
      type: 'string',
      example: 'Error'
    },
    status: {
      type: 'number',
      example: 400
    }
  },
  required: ['name', 'status']
})
rawDefinition: Record<string, any>;
```

To manually define input/output content in controller classes, use the `schema` property:

```typescript

@ApiBody({
  schema: {
    type: 'array',
    items: {
      type: 'array',
      items: {
        type: 'number',
      },
    },
  },
})
async create(@Body() coords: number[][]) {}
```

#### Extra models[#](/openapi/types-and-parameters#extra-models)

To define additional models that are not directly referenced in your controllers but should be inspected by the Swagger module, use the `@ApiExtraModels()` decorator:

```typescript

@ApiExtraModels(ExtraModel)
export class CreateCatDto {}
```

> **Hint** You only need to use `@ApiExtraModels()` once for a specific model class.

Alternatively, you can pass an options object with the `extraModels` property specified to the `SwaggerModule#createDocument()` method, as follows:

```typescript

const documentFactory = () =>
  SwaggerModule.createDocument(app, options, {
    extraModels: [ExtraModel],
  });
```

To get a reference (`$ref`) to your model, use the `getSchemaPath(ExtraModel)` function:

```typescript

'application/vnd.api+json': {
   schema: { $ref: getSchemaPath(ExtraModel) },
},
```

#### oneOf, anyOf, allOf[#](/openapi/types-and-parameters#oneof-anyof-allof)

To combine schemas, you can use the `oneOf`, `anyOf` or `allOf` keywords ([read more](https://swagger.io/docs/specification/data-models/oneof-anyof-allof-not/)).

```typescript

@ApiProperty({
  oneOf: [
    { $ref: getSchemaPath(Cat) },
    { $ref: getSchemaPath(Dog) },
  ],
})
pet: Cat | Dog;
```

If you want to define a polymorphic array (i.e., an array whose members span multiple schemas), you should use a raw definition (see above) to define your type by hand.

```typescript

type Pet = Cat | Dog;

@ApiProperty({
  type: 'array',
  items: {
    oneOf: [
      { $ref: getSchemaPath(Cat) },
      { $ref: getSchemaPath(Dog) },
    ],
  },
})
pets: Pet[];
```

> **Hint** The `getSchemaPath()` function is imported from `@nestjs/swagger`.

Both `Cat` and `Dog` must be defined as extra models using the `@ApiExtraModels()` decorator (at the class-level).

#### Schema name and description[#](/openapi/types-and-parameters#schema-name-and-description)

As you may have noticed, the name of the generated schema is based on the name of the original model class (for example, the `CreateCatDto` model generates a `CreateCatDto` schema). If you'd like to change the schema name, you can use the `@ApiSchema()` decorator.

Here’s an example:

```typescript

@ApiSchema({ name: 'CreateCatRequest' })
class CreateCatDto {}
```

The model above will be translated into the `CreateCatRequest` schema.

By default, no description is added to the generated schema. You can add one using the `description` attribute:

```typescript

@ApiSchema({ description: 'Description of the CreateCatDto schema' })
class CreateCatDto {}
```

That way, the description will be included in the schema, as follows:

```yaml

schemas:
  CreateCatDto:
    type: object
    description: Description of the CreateCatDto schema
```

----
url: https://docs.nestjs.com/v8/graphql/complexity
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Complexity](https://docs.nestjs.com/v8/graphql/complexity#complexity)
* [Installation](https://docs.nestjs.com/v8/graphql/complexity#installation)
* [Getting started](https://docs.nestjs.com/v8/graphql/complexity#getting-started)
* [Field-level complexity](https://docs.nestjs.com/v8/graphql/complexity#field-level-complexity)
* [Query/Mutation-level complexity](https://docs.nestjs.com/v8/graphql/complexity#querymutation-level-complexity)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/complexity.md "Suggest Edits")

### Complexity

> **Warning** This chapter applies only to the code first approach.

Query complexity allows you to define how complex certain fields are, and to restrict queries with a **maximum complexity**. The idea is to define how complex each field is by using a simple number. A common default is to give each field a complexity of `1`. In addition, the complexity calculation of a GraphQL query can be customized with so-called complexity estimators. A complexity estimator is a simple function that calculates the complexity for a field. You can add any number of complexity estimators to the rule, which are then executed one after another. The first estimator that returns a numeric complexity value determines the complexity for that field.

The `@nestjs/graphql` package integrates very well with tools like [graphql-query-complexity](https://github.com/slicknode/graphql-query-complexity) that provides a cost analysis-based solution. With this library, you can reject queries to your GraphQL server that are deemed too costly to execute.

#### Installation[#](/graphql/complexity#installation)

To begin using it, we first install the required dependency.

```bash

$ npm install --save graphql-query-complexity
```

#### Getting started[#](/graphql/complexity#getting-started)

Once the installation process is complete, we can define the `ComplexityPlugin` class:

```typescript

import { GraphQLSchemaHost } from "@nestjs/graphql";
import { Plugin } from "@nestjs/apollo";
import {
  ApolloServerPlugin,
  GraphQLRequestListener,
} from 'apollo-server-plugin-base';
import { GraphQLError } from 'graphql';
import {
  fieldExtensionsEstimator,
  getComplexity,
  simpleEstimator,
} from 'graphql-query-complexity';

@Plugin()
export class ComplexityPlugin implements ApolloServerPlugin {
  constructor(private gqlSchemaHost: GraphQLSchemaHost) {}

  async requestDidStart(): Promise<GraphQLRequestListener> {
    const maxComplexity = 20;
    const { schema } = this.gqlSchemaHost;

    return {
      async didResolveOperation({ request, document }) {
        const complexity = getComplexity({
          schema,
          operationName: request.operationName,
          query: document,
          variables: request.variables,
          estimators: [
            fieldExtensionsEstimator(),
            simpleEstimator({ defaultComplexity: 1 }),
          ],
        });
        if (complexity > maxComplexity) {
          throw new GraphQLError(
            `Query is too complex: ${complexity}. Maximum allowed complexity: ${maxComplexity}`,
          );
        }
        console.log('Query Complexity:', complexity);
      },
    };
  }
}
```

For demonstration purposes, we specified the maximum allowed complexity as `20`. In the example above, we used 2 estimators, the `simpleEstimator` and the `fieldExtensionsEstimator`.

* `simpleEstimator`: the simple estimator returns a fixed complexity for each field
* `fieldExtensionsEstimator`: the field extensions estimator extracts the complexity value for each field of your schema

> **Hint** Remember to add this class to the providers array in any module.

#### Field-level complexity[#](/graphql/complexity#field-level-complexity)

With this plugin in place, we can now define the complexity for any field by specifying the `complexity` property in the options object passed into the `@Field()` decorator, as follows:

```typescript

@Field({ complexity: 3 })
title: string;
```

Alternatively, you can define the estimator function:

```typescript

@Field({ complexity: (options: ComplexityEstimatorArgs) => ... })
title: string;
```

#### Query/Mutation-level complexity[#](/graphql/complexity#querymutation-level-complexity)

In addition, `@Query()` and `@Mutation()` decorators may have a `complexity` property specified like so:

```typescript

@Query({ complexity: (options: ComplexityEstimatorArgs) => options.args.count * options.childComplexity })
items(@Args('count') count: number) {
  return this.itemsService.getItems({ count });
}
```

----
url: https://docs.nestjs.com/v9/techniques/caching
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Caching](https://docs.nestjs.com/v9/techniques/caching#caching)
* [Installation](https://docs.nestjs.com/v9/techniques/caching#installation)
* [In-memory cache](https://docs.nestjs.com/v9/techniques/caching#in-memory-cache)
* [Interacting with the Cache store](https://docs.nestjs.com/v9/techniques/caching#interacting-with-the-cache-store)
* [Auto-caching responses](https://docs.nestjs.com/v9/techniques/caching#auto-caching-responses)
* [Customize caching](https://docs.nestjs.com/v9/techniques/caching#customize-caching)
* [Use module globally](https://docs.nestjs.com/v9/techniques/caching#use-module-globally)
* [Global cache overrides](https://docs.nestjs.com/v9/techniques/caching#global-cache-overrides)
* [WebSockets and Microservices](https://docs.nestjs.com/v9/techniques/caching#websockets-and-microservices)
* [Adjust tracking](https://docs.nestjs.com/v9/techniques/caching#adjust-tracking)
* [Different stores](https://docs.nestjs.com/v9/techniques/caching#different-stores)
* [Async configuration](https://docs.nestjs.com/v9/techniques/caching#async-configuration)
* [Example](https://docs.nestjs.com/v9/techniques/caching#example)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/techniques/caching.md "Suggest Edits")

### Caching

Caching is a great and simple **technique** that helps improve your app's performance. It acts as a temporary data store providing high performance data access.

#### Installation[#](/techniques/caching#installation)

First install required packages:

```bash

$ npm install @nestjs/cache-manager cache-manager
```

> **Warning**`cache-manager` version 4 uses seconds for `TTL (Time-To-Live)`. The current version of `cache-manager` (v5) has switched to using milliseconds instead. NestJS doesn't convert the value, and simply forwards the ttl you provide to the library. In other words:
>
> * If using `cache-manager` v4, provide ttl in seconds
> * If using `cache-manager` v5, provide ttl in milliseconds
> * Documentation is referring to seconds, since NestJS was released targeting version 4 of cache-manager.

#### In-memory cache[#](/techniques/caching#in-memory-cache)

Nest provides a unified API for various cache storage providers. The built-in one is an in-memory data store. However, you can easily switch to a more comprehensive solution, like Redis.

In order to enable caching, import the `CacheModule` and call its `register()` method.

```typescript

import { Module } from '@nestjs/common';
import { CacheModule } from '@nestjs/cache-manager';
import { AppController } from './app.controller';

@Module({
  imports: [CacheModule.register()],
  controllers: [AppController],
})
export class AppModule {}
```

#### Interacting with the Cache store[#](/techniques/caching#interacting-with-the-cache-store)

To interact with the cache manager instance, inject it to your class using the `CACHE_MANAGER` token, as follows:

```typescript

constructor(@Inject(CACHE_MANAGER) private cacheManager: Cache) {}
```

> **Hint** The `Cache` class is imported from the `cache-manager`, while `CACHE_MANAGER` token from the `@nestjs/cache-manager` package.

The `get` method on the `Cache` instance (from the `cache-manager` package) is used to retrieve items from the cache. If the item does not exist in the cache, `null` will be returned.

```typescript

const value = await this.cacheManager.get('key');
```

To add an item to the cache, use the `set` method:

```typescript

await this.cacheManager.set('key', 'value');
```

The default expiration time of the cache is 5 seconds.

You can manually specify a TTL (expiration time in seconds) for this specific key, as follows:

```typescript

await this.cacheManager.set('key', 'value', 1000);
```

To disable expiration of the cache, set the `ttl` configuration property to `0`:

```typescript

await this.cacheManager.set('key', 'value', 0);
```

To remove an item from the cache, use the `del` method:

```typescript

await this.cacheManager.del('key');
```

To clear the entire cache, use the `reset` method:

```typescript

await this.cacheManager.reset();
```

#### Auto-caching responses[#](/techniques/caching#auto-caching-responses)

> **Warning** In [GraphQL](/v9/graphql/quick-start) applications, interceptors are executed separately for each field resolver. Thus, `CacheModule` (which uses interceptors to cache responses) will not work properly.

To enable auto-caching responses, just tie the `CacheInterceptor` where you want to cache data.

```typescript

@Controller()
@UseInterceptors(CacheInterceptor)
export class AppController {
  @Get()
  findAll(): string[] {
    return [];
  }
}
```

> **Warning** Only `GET` endpoints are cached. Also, HTTP server routes that inject the native response object (`@Res()`) cannot use the Cache Interceptor. See [response mapping](https://docs.nestjs.com/interceptors#response-mapping) for more details.

To reduce the amount of required boilerplate, you can bind `CacheInterceptor` to all endpoints globally:

```typescript

import { Module } from '@nestjs/common';
import { CacheModule, CacheInterceptor } from '@nestjs/cache-manager';
import { AppController } from './app.controller';
import { APP_INTERCEPTOR } from '@nestjs/core';

@Module({
  imports: [CacheModule.register()],
  controllers: [AppController],
  providers: [
    {
      provide: APP_INTERCEPTOR,
      useClass: CacheInterceptor,
    },
  ],
})
export class AppModule {}
```

#### Customize caching[#](/techniques/caching#customize-caching)

All cached data has its own expiration time ([TTL](https://en.wikipedia.org/wiki/Time_to_live)). To customize default values, pass the options object to the `register()` method.

```typescript

CacheModule.register({
  ttl: 5, // seconds
  max: 10, // maximum number of items in cache
});
```

#### Use module globally[#](/techniques/caching#use-module-globally)

When you want to use `CacheModule` in other modules, you'll need to import it (as is standard with any Nest module). Alternatively, declare it as a [global module](https://docs.nestjs.com/modules#global-modules) by setting the options object's `isGlobal` property to `true`, as shown below. In that case, you will not need to import `CacheModule` in other modules once it's been loaded in the root module (e.g., `AppModule`).

```typescript

CacheModule.register({
  isGlobal: true,
});
```

#### Global cache overrides[#](/techniques/caching#global-cache-overrides)

While global cache is enabled, cache entries are stored under a `CacheKey` that is auto-generated based on the route path. You may override certain cache settings (`@CacheKey()` and `@CacheTTL()`) on a per-method basis, allowing customized caching strategies for individual controller methods. This may be most relevant while using [different cache stores.](https://docs.nestjs.com/techniques/caching#different-stores)

```typescript

@Controller()
export class AppController {
  @CacheKey('custom_key')
  @CacheTTL(20)
  findAll(): string[] {
    return [];
  }
}
```

> **Hint** The `@CacheKey()` and `@CacheTTL()` decorators are imported from the `@nestjs/cache-manager` package.

The `@CacheKey()` decorator may be used with or without a corresponding `@CacheTTL()` decorator and vice versa. One may choose to override only the `@CacheKey()` or only the `@CacheTTL()`. Settings that are not overridden with a decorator will use the default values as registered globally (see [Customize caching](https://docs.nestjs.com/techniques/caching#customize-caching)).

#### WebSockets and Microservices[#](/techniques/caching#websockets-and-microservices)

You can also apply the `CacheInterceptor` to WebSocket subscribers as well as Microservice's patterns (regardless of the transport method that is being used).

JS TS

```typescript

@CacheKey('events')
@UseInterceptors(CacheInterceptor)
@SubscribeMessage('events')
handleEvent(client: Client, data: string[]): Observable<string[]> {
  return [];
}
```

```typescript

@CacheKey('events')
@UseInterceptors(CacheInterceptor)
@SubscribeMessage('events')
handleEvent(client, data) {
  return [];
}
```

However, the additional `@CacheKey()` decorator is required in order to specify a key used to subsequently store and retrieve cached data. Also, please note that you **shouldn't cache everything**. Actions which perform some business operations rather than simply querying the data should never be cached.

Additionally, you may specify a cache expiration time (TTL) by using the `@CacheTTL()` decorator, which will override the global default TTL value.

JS TS

```typescript

@CacheTTL(10)
@UseInterceptors(CacheInterceptor)
@SubscribeMessage('events')
handleEvent(client: Client, data: string[]): Observable<string[]> {
  return [];
}
```

```typescript

@CacheTTL(10)
@UseInterceptors(CacheInterceptor)
@SubscribeMessage('events')
handleEvent(client, data) {
  return [];
}
```

> **Hint** The `@CacheTTL()` decorator may be used with or without a corresponding `@CacheKey()` decorator.

#### Adjust tracking[#](/techniques/caching#adjust-tracking)

By default, Nest uses the request URL (in an HTTP app) or cache key (in websockets and microservices apps, set through the `@CacheKey()` decorator) to associate cache records with your endpoints. Nevertheless, sometimes you might want to set up tracking based on different factors, for example, using HTTP headers (e.g. `Authorization` to properly identify `profile` endpoints).

In order to accomplish that, create a subclass of `CacheInterceptor` and override the `trackBy()` method.

```typescript

@Injectable()
class HttpCacheInterceptor extends CacheInterceptor {
  trackBy(context: ExecutionContext): string | undefined {
    return 'key';
  }
}
```

#### Different stores[#](/techniques/caching#different-stores)

This service takes advantage of [cache-manager](https://github.com/node-cache-manager/node-cache-manager) under the hood. The `cache-manager` package supports a wide-range of useful stores, for example, [Redis store](https://github.com/dabroek/node-cache-manager-redis-store). A full list of supported stores is available [here](https://github.com/node-cache-manager/node-cache-manager#store-engines). To set up the Redis store, simply pass the package together with corresponding options to the `register()` method.

```typescript

import type { RedisClientOptions } from 'redis';
import * as redisStore from 'cache-manager-redis-store';
import { Module } from '@nestjs/common';
import { CacheModule } from '@nestjs/cache-manager';
import { AppController } from './app.controller';

@Module({
  imports: [
    CacheModule.register<RedisClientOptions>({
      store: redisStore,

      // Store-specific configuration:
      host: 'localhost',
      port: 6379,
    }),
  ],
  controllers: [AppController],
})
export class AppModule {}
```

> **Warning**`cache-manager-redis-store` does not support redis v4. In order for the `ClientOpts` interface to exist and work correctly you need to install the latest `redis` 3.x.x major release. See this [issue](https://github.com/dabroek/node-cache-manager-redis-store/issues/40) to track the progress of this upgrade.

#### Async configuration[#](/techniques/caching#async-configuration)

You may want to asynchronously pass in module options instead of passing them statically at compile time. In this case, use the `registerAsync()` method, which provides several ways to deal with async configuration.

One approach is to use a factory function:

```typescript

CacheModule.registerAsync({
  useFactory: () => ({
    ttl: 5,
  }),
});
```

Our factory behaves like all other asynchronous module factories (it can be `async` and is able to inject dependencies through `inject`).

```typescript

CacheModule.registerAsync({
  imports: [ConfigModule],
  useFactory: async (configService: ConfigService) => ({
    ttl: configService.get('CACHE_TTL'),
  }),
  inject: [ConfigService],
});
```

Alternatively, you can use the `useClass` method:

```typescript

CacheModule.registerAsync({
  useClass: CacheConfigService,
});
```

The above construction will instantiate `CacheConfigService` inside `CacheModule` and will use it to get the options object. The `CacheConfigService` has to implement the `CacheOptionsFactory` interface in order to provide the configuration options:

```typescript

@Injectable()
class CacheConfigService implements CacheOptionsFactory {
  createCacheOptions(): CacheModuleOptions {
    return {
      ttl: 5,
    };
  }
}
```

If you wish to use an existing configuration provider imported from a different module, use the `useExisting` syntax:

```typescript

CacheModule.registerAsync({
  imports: [ConfigModule],
  useExisting: ConfigService,
});
```

This works the same as `useClass` with one critical difference - `CacheModule` will lookup imported modules to reuse any already-created `ConfigService`, instead of instantiating its own.

> **Hint**`CacheModule#register` and `CacheModule#registerAsync` and `CacheOptionsFactory` has an optional generic (type argument) to narrow down store-specific configuration options, making it type safe.

#### Example[#](/techniques/caching#example)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/20-cache).

----
url: https://docs.nestjs.com/v9/techniques/configuration
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Configuration](https://docs.nestjs.com/v9/techniques/configuration#configuration)
* [Installation](https://docs.nestjs.com/v9/techniques/configuration#installation)
* [Getting started](https://docs.nestjs.com/v9/techniques/configuration#getting-started)
* [Custom env file path](https://docs.nestjs.com/v9/techniques/configuration#custom-env-file-path)
* [Disable env variables loading](https://docs.nestjs.com/v9/techniques/configuration#disable-env-variables-loading)
* [Use module globally](https://docs.nestjs.com/v9/techniques/configuration#use-module-globally)
* [Custom configuration files](https://docs.nestjs.com/v9/techniques/configuration#custom-configuration-files)
* [Using the ConfigService](https://docs.nestjs.com/v9/techniques/configuration#using-the-configservice)
* [Configuration namespaces](https://docs.nestjs.com/v9/techniques/configuration#configuration-namespaces)
* [Cache environment variables](https://docs.nestjs.com/v9/techniques/configuration#cache-environment-variables)
* [Partial registration](https://docs.nestjs.com/v9/techniques/configuration#partial-registration)
* [Schema validation](https://docs.nestjs.com/v9/techniques/configuration#schema-validation)
* [Custom validate function](https://docs.nestjs.com/v9/techniques/configuration#custom-validate-function)
* [Custom getter functions](https://docs.nestjs.com/v9/techniques/configuration#custom-getter-functions)
* [Environment variables loaded hook](https://docs.nestjs.com/v9/techniques/configuration#environment-variables-loaded-hook)
* [Expandable variables](https://docs.nestjs.com/v9/techniques/configuration#expandable-variables)
* [Using in the main.ts](https://docs.nestjs.com/v9/techniques/configuration#using-in-the-maints)

```bash

$ npm i --save @nestjs/config
```

> **Hint** The `@nestjs/config` package internally uses [dotenv](https://github.com/motdotla/dotenv).

> **Note**`@nestjs/config` requires TypeScript 4.1 or later.

#### Getting started[#](/techniques/configuration#getting-started)

Once the installation process is complete, we can import the `ConfigModule`. Typically, we'll import it into the root `AppModule` and control its behavior using the `.forRoot()` static method. During this step, environment variable key/value pairs are parsed and resolved. Later, we'll see several options for accessing the `ConfigService` class of the `ConfigModule` in our other feature modules.

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';

@Module({
  imports: [ConfigModule.forRoot()],
})
export class AppModule {}
```

The above code will load and parse a `.env` file from the default location (the project root directory), merge key/value pairs from the `.env` file with environment variables assigned to `process.env`, and store the result in a private structure that you can access through the `ConfigService`. The `forRoot()` method registers the `ConfigService` provider, which provides a `get()` method for reading these parsed/merged configuration variables. Since `@nestjs/config` relies on [dotenv](https://github.com/motdotla/dotenv), it uses that package's rules for resolving conflicts in environment variable names. When a key exists both in the runtime environment as an environment variable (e.g., via OS shell exports like `export DATABASE_USER=test`) and in a `.env` file, the runtime environment variable takes precedence.

A sample `.env` file looks something like this:

```json

DATABASE_USER=test
DATABASE_PASSWORD=test
```

#### Custom env file path[#](/techniques/configuration#custom-env-file-path)

By default, the package looks for a `.env` file in the root directory of the application. To specify another path for the `.env` file, set the `envFilePath` property of an (optional) options object you pass to `forRoot()`, as follows:

```typescript

ConfigModule.forRoot({
  envFilePath: '.development.env',
});
```

You can also specify multiple paths for `.env` files like this:

```typescript

ConfigModule.forRoot({
  envFilePath: ['.env.development.local', '.env.development'],
});
```

If a variable is found in multiple files, the first one takes precedence.

#### Disable env variables loading[#](/techniques/configuration#disable-env-variables-loading)

If you don't want to load the `.env` file, but instead would like to simply access environment variables from the runtime environment (as with OS shell exports like `export DATABASE_USER=test`), set the options object's `ignoreEnvFile` property to `true`, as follows:

```typescript

ConfigModule.forRoot({
  ignoreEnvFile: true,
});
```

#### Use module globally[#](/techniques/configuration#use-module-globally)

When you want to use `ConfigModule` in other modules, you'll need to import it (as is standard with any Nest module). Alternatively, declare it as a [global module](https://docs.nestjs.com/modules#global-modules) by setting the options object's `isGlobal` property to `true`, as shown below. In that case, you will not need to import `ConfigModule` in other modules once it's been loaded in the root module (e.g., `AppModule`).

```typescript

ConfigModule.forRoot({
  isGlobal: true,
});
```

#### Custom configuration files[#](/techniques/configuration#custom-configuration-files)

For more complex projects, you may utilize custom configuration files to return nested configuration objects. This allows you to group related configuration settings by function (e.g., database-related settings), and to store related settings in individual files to help manage them independently.

A custom configuration file exports a factory function that returns a configuration object. The configuration object can be any arbitrarily nested plain JavaScript object. The `process.env` object will contain the fully resolved environment variable key/value pairs (with `.env` file and externally defined variables resolved and merged as described [above](techniques/configuration#getting-started)). Since you control the returned configuration object, you can add any required logic to cast values to an appropriate type, set default values, etc. For example:

config/configuration.ts

JS TS

```typescript

export default () => ({
  port: parseInt(process.env.PORT, 10) || 3000,
  database: {
    host: process.env.DATABASE_HOST,
    port: parseInt(process.env.DATABASE_PORT, 10) || 5432
  }
});
```

We load this file using the `load` property of the options object we pass to the `ConfigModule.forRoot()` method:

```typescript

import configuration from './config/configuration';

@Module({
  imports: [
    ConfigModule.forRoot({
      load: [configuration],
    }),
  ],
})
export class AppModule {}
```

> **Notice** The value assigned to the `load` property is an array, allowing you to load multiple configuration files (e.g. `load: [databaseConfig, authConfig]`)

With custom configuration files, we can also manage custom files such as YAML files. Here is an example of a configuration using YAML format:

```yaml

http:
  host: 'localhost'
  port: 8080

db:
  postgres:
    url: 'localhost'
    port: 5432
    database: 'yaml-db'

  sqlite:
    database: 'sqlite.db'
```

To read and parse YAML files, we can leverage the `js-yaml` package.

```bash

$ npm i js-yaml
$ npm i -D @types/js-yaml
```

Once the package is installed, we use `yaml#load` function to load YAML file we just created above.

config/configuration.ts

JS TS

```typescript

import { readFileSync } from 'fs';
import * as yaml from 'js-yaml';
import { join } from 'path';

const YAML_CONFIG_FILENAME = 'config.yaml';

export default () => {
  return yaml.load(
    readFileSync(join(__dirname, YAML_CONFIG_FILENAME), 'utf8'),
  ) as Record<string, any>;
};
```

> **Note** Nest CLI does not automatically move your "assets" (non-TS files) to the `dist` folder during the build process. To make sure that your YAML files are copied, you have to specify this in the `compilerOptions#assets` object in the `nest-cli.json` file. As an example, if the `config` folder is at the same level as the `src` folder, add `compilerOptions#assets` with the value `"assets": [{"include": "../config/*.yaml", "outDir": "./dist/config"}]`. Read more [here](/cli/monorepo#assets).

## Explore your graph with NestJS Devtools

* Graph visualizer
* Routes navigator
* Interactive playground
* CI/CD integration

[Sign up](https://devtools.nestjs.com "Devtools | NestJS - A node.js framework built on top of TypeScript")

#### Using the `ConfigService`[#](/techniques/configuration#using-the-configservice)

To access configuration values from our `ConfigService`, we first need to inject `ConfigService`. As with any provider, we need to import its containing module - the `ConfigModule` - into the module that will use it (unless you set the `isGlobal` property in the options object passed to the `ConfigModule.forRoot()` method to `true`). Import it into a feature module as shown below.

feature.module.ts

JS TS

```typescript

@Module({
  imports: [ConfigModule],
  // ...
})
```

Then we can inject it using standard constructor injection:

```typescript

constructor(private configService: ConfigService) {}
```

> **Hint** The `ConfigService` is imported from the `@nestjs/config` package.

And use it in our class:

```typescript

// get an environment variable
const dbUser = this.configService.get<string>('DATABASE_USER');

// get a custom configuration value
const dbHost = this.configService.get<string>('database.host');
```

As shown above, use the `configService.get()` method to get a simple environment variable by passing the variable name. You can do TypeScript type hinting by passing the type, as shown above (e.g., `get<string>(...)`). The `get()` method can also traverse a nested custom configuration object (created via a [Custom configuration file](techniques/configuration#custom-configuration-files)), as shown in the second example above.

You can also get the whole nested custom configuration object using an interface as the type hint:

```typescript

interface DatabaseConfig {
  host: string;
  port: number;
}

const dbConfig = this.configService.get<DatabaseConfig>('database');

// you can now use `dbConfig.port` and `dbConfig.host`
const port = dbConfig.port;
```

The `get()` method also takes an optional second argument defining a default value, which will be returned when the key doesn't exist, as shown below:

```typescript

// use "localhost" when "database.host" is not defined
const dbHost = this.configService.get<string>('database.host', 'localhost');
```

`ConfigService` has two optional generics (type arguments). The first one is to help prevent accessing a config property that does not exist. Use it as shown below:

```typescript

interface EnvironmentVariables {
  PORT: number;
  TIMEOUT: string;
}

// somewhere in the code
constructor(private configService: ConfigService<EnvironmentVariables>) {
  const port = this.configService.get('PORT', { infer: true });

  // TypeScript Error: this is invalid as the URL property is not defined in EnvironmentVariables
  const url = this.configService.get('URL', { infer: true });
}
```

With the `infer` property set to `true`, the `ConfigService#get` method will automatically infer the property type based on the interface, so for example, `typeof port === "number"` (if you're not using `strictNullChecks` flag from TypeScript) since `PORT` has a `number` type in the `EnvironmentVariables` interface.

Also, with the `infer` feature, you can infer the type of a nested custom configuration object's property, even when using dot notation, as follows:

```typescript

constructor(private configService: ConfigService<{ database: { host: string } }>) {
  const dbHost = this.configService.get('database.host', { infer: true })!;
  // typeof dbHost === "string"                                          |
  //                                                                     +--> non-null assertion operator
}
```

The second generic relies on the first one, acting as a type assertion to get rid of all `undefined` types that `ConfigService`'s methods can return when `strictNullChecks` is on. For instance:

```typescript

// ...
constructor(private configService: ConfigService<{ PORT: number }, true>) {
  //                                                               ^^^^
  const port = this.configService.get('PORT', { infer: true });
  //    ^^^ The type of port will be 'number' thus you don't need TS type assertions anymore
}
```

#### Configuration namespaces[#](/techniques/configuration#configuration-namespaces)

The `ConfigModule` allows you to define and load multiple custom configuration files, as shown in [Custom configuration files](techniques/configuration#custom-configuration-files) above. You can manage complex configuration object hierarchies with nested configuration objects as shown in that section. Alternatively, you can return a "namespaced" configuration object with the `registerAs()` function as follows:

config/database.config.ts

JS TS

```typescript

export default registerAs('database', () => ({
  host: process.env.DATABASE_HOST,
  port: process.env.DATABASE_PORT || 5432
}));
```

As with custom configuration files, inside your `registerAs()` factory function, the `process.env` object will contain the fully resolved environment variable key/value pairs (with `.env` file and externally defined variables resolved and merged as described [above](techniques/configuration#getting-started)).

> **Hint** The `registerAs` function is exported from the `@nestjs/config` package.

Load a namespaced configuration with the `load` property of the `forRoot()` method's options object, in the same way you load a custom configuration file:

```typescript

import databaseConfig from './config/database.config';

@Module({
  imports: [
    ConfigModule.forRoot({
      load: [databaseConfig],
    }),
  ],
})
export class AppModule {}
```

Now, to get the `host` value from the `database` namespace, use dot notation. Use `'database'` as the prefix to the property name, corresponding to the name of the namespace (passed as the first argument to the `registerAs()` function):

```typescript

const dbHost = this.configService.get<string>('database.host');
```

A reasonable alternative is to inject the `database` namespace directly. This allows us to benefit from strong typing:

```typescript

constructor(
  @Inject(databaseConfig.KEY)
  private dbConfig: ConfigType<typeof databaseConfig>,
) {}
```

> **Hint** The `ConfigType` is exported from the `@nestjs/config` package.

#### Cache environment variables[#](/techniques/configuration#cache-environment-variables)

As accessing `process.env` can be slow, you can set the `cache` property of the options object passed to `ConfigModule.forRoot()` to increase the performance of `ConfigService#get` method when it comes to variables stored in `process.env`.

```typescript

ConfigModule.forRoot({
  cache: true,
});
```

#### Partial registration[#](/techniques/configuration#partial-registration)

Thus far, we've processed configuration files in our root module (e.g., `AppModule`), with the `forRoot()` method. Perhaps you have a more complex project structure, with feature-specific configuration files located in multiple different directories. Rather than load all these files in the root module, the `@nestjs/config` package provides a feature called **partial registration**, which references only the configuration files associated with each feature module. Use the `forFeature()` static method within a feature module to perform this partial registration, as follows:

```typescript

import databaseConfig from './config/database.config';

@Module({
  imports: [ConfigModule.forFeature(databaseConfig)],
})
export class DatabaseModule {}
```

> **Warning** In some circumstances, you may need to access properties loaded via partial registration using the `onModuleInit()` hook, rather than in a constructor. This is because the `forFeature()` method is run during module initialization, and the order of module initialization is indeterminate. If you access values loaded this way by another module, in a constructor, the module that the configuration depends upon may not yet have initialized. The `onModuleInit()` method runs only after all modules it depends upon have been initialized, so this technique is safe.

#### Schema validation[#](/techniques/configuration#schema-validation)

It is standard practice to throw an exception during application startup if required environment variables haven't been provided or if they don't meet certain validation rules. The `@nestjs/config` package enables two different ways to do this:

* [Joi](https://github.com/sideway/joi) built-in validator. With Joi, you define an object schema and validate JavaScript objects against it.
* A custom `validate()` function which takes environment variables as an input.

To use Joi, we must install Joi package:

```bash

$ npm install --save joi
```

> **Notice** The latest version of `joi` requires you to be running Node v12 or later. For older versions of node, please install `v16.1.8`. This is mainly after the release of `v17.0.2` which causes errors during build time. For more information, please refer to [their 17.0.0 release notes](https://github.com/sideway/joi/issues/2262).

Now we can define a Joi validation schema and pass it via the `validationSchema` property of the `forRoot()` method's options object, as shown below:

app.module.ts

JS TS

```typescript

import * as Joi from 'joi';

@Module({
  imports: [
    ConfigModule.forRoot({
      validationSchema: Joi.object({
        NODE_ENV: Joi.string()
          .valid('development', 'production', 'test', 'provision')
          .default('development'),
        PORT: Joi.number().default(3000),
      }),
    }),
  ],
})
export class AppModule {}
```

By default, all schema keys are considered optional. Here, we set default values for `NODE_ENV` and `PORT` which will be used if we don't provide these variables in the environment (`.env` file or process environment). Alternatively, we can use the `required()` validation method to require that a value must be defined in the environment (`.env` file or process environment). In this case, the validation step will throw an exception if we don't provide the variable in the environment. See [Joi validation methods](https://joi.dev/api/?v=17.3.0#example) for more on how to construct validation schemas.

By default, unknown environment variables (environment variables whose keys are not present in the schema) are allowed and do not trigger a validation exception. By default, all validation errors are reported. You can alter these behaviors by passing an options object via the `validationOptions` key of the `forRoot()` options object. This options object can contain any of the standard validation options properties provided by [Joi validation options](https://joi.dev/api/?v=17.3.0#anyvalidatevalue-options). For example, to reverse the two settings above, pass options like this:

app.module.ts

JS TS

```typescript

import * as Joi from 'joi';

@Module({
  imports: [
    ConfigModule.forRoot({
      validationSchema: Joi.object({
        NODE_ENV: Joi.string()
          .valid('development', 'production', 'test', 'provision')
          .default('development'),
        PORT: Joi.number().default(3000),
      }),
      validationOptions: {
        allowUnknown: false,
        abortEarly: true,
      },
    }),
  ],
})
export class AppModule {}
```

```typescript

import { plainToInstance } from 'class-transformer';
import { IsEnum, IsNumber, validateSync } from 'class-validator';

enum Environment {
  Development = "development",
  Production = "production",
  Test = "test",
  Provision = "provision",
}

class EnvironmentVariables {
  @IsEnum(Environment)
  NODE_ENV: Environment;

  @IsNumber()
  PORT: number;
}

export function validate(config: Record<string, unknown>) {
  const validatedConfig = plainToInstance(
    EnvironmentVariables,
    config,
    { enableImplicitConversion: true },
  );
  const errors = validateSync(validatedConfig, { skipMissingProperties: false });

  if (errors.length > 0) {
    throw new Error(errors.toString());
  }
  return validatedConfig;
}
```

With this in place, use the `validate` function as a configuration option of the `ConfigModule`, as follows:

app.module.ts

JS TS

```typescript

import { validate } from './env.validation';

@Module({
  imports: [
    ConfigModule.forRoot({
      validate,
    }),
  ],
})
export class AppModule {}
```

## Hoodies, T-shirts, and accessories!

Support our future development by shopping in the official store!

[See more](https://nestjs.threadless.com/ "Shop | NestJS - A node.js framework built on top of TypeScript")

#### Custom getter functions[#](/techniques/configuration#custom-getter-functions)

`ConfigService` defines a generic `get()` method to retrieve a configuration value by key. We may also add `getter` functions to enable a little more natural coding style:

JS TS

```typescript

@Injectable()
export class ApiConfigService {
  constructor(private configService: ConfigService) {}

  get isAuthEnabled(): boolean {
    return this.configService.get('AUTH_ENABLED') === 'true';
  }
}
```

```typescript

@Dependencies(ConfigService)
@Injectable()
export class ApiConfigService {
  constructor(configService) {
    this.configService = configService;
  }

  get isAuthEnabled() {
    return this.configService.get('AUTH_ENABLED') === 'true';
  }
}
```

Now we can use the getter function as follows:

app.service.ts

JS TS

```typescript

@Injectable()
export class AppService {
  constructor(apiConfigService: ApiConfigService) {
    if (apiConfigService.isAuthEnabled) {
      // Authentication is enabled
    }
  }
}
```

```typescript

@Dependencies(ApiConfigService)
@Injectable()
export class AppService {
  constructor(apiConfigService) {
    if (apiConfigService.isAuthEnabled) {
      // Authentication is enabled
    }
  }
}
```

#### Environment variables loaded hook[#](/techniques/configuration#environment-variables-loaded-hook)

If a module configuration depends on the environment variables, and these variables are loaded from the `.env` file, you can use the `ConfigModule.envVariablesLoaded` hook to ensure that the file was loaded before interacting with the `process.env` object, see the following example:

```typescript

export async function getStorageModule() {
  await ConfigModule.envVariablesLoaded;
  return process.env.STORAGE === 'S3' ? S3StorageModule : DefaultStorageModule;
}
```

This construction guarantees that after the `ConfigModule.envVariablesLoaded` Promise resolves, all configuration variables are loaded up.

#### Expandable variables[#](/techniques/configuration#expandable-variables)

The `@nestjs/config` package supports environment variable expansion. With this technique, you can create nested environment variables, where one variable is referred to within the definition of another. For example:

```json

APP_URL=mywebsite.com
SUPPORT_EMAIL=support@${APP_URL}
```

With this construction, the variable `SUPPORT_EMAIL` resolves to `'support@mywebsite.com'`. Note the use of the `${...}` syntax to trigger resolving the value of the variable `APP_URL` inside the definition of `SUPPORT_EMAIL`.

> **Hint** For this feature, `@nestjs/config` package internally uses [dotenv-expand](https://github.com/motdotla/dotenv-expand).

Enable environment variable expansion using the `expandVariables` property in the options object passed to the `forRoot()` method of the `ConfigModule`, as shown below:

app.module.ts

JS TS

```typescript

@Module({
  imports: [
    ConfigModule.forRoot({
      // ...
      expandVariables: true,
    }),
  ],
})
export class AppModule {}
```

#### Using in the `main.ts`[#](/techniques/configuration#using-in-the-maints)

While our config is a stored in a service, it can still be used in the `main.ts` file. This way, you can use it to store variables such as the application port or the CORS host.

To access it, you must use the `app.get()` method, followed by the service reference:

```typescript

const configService = app.get(ConfigService);
```

You can then use it as usual, by calling the `get` method with the configuration key:

```typescript

const port = configService.get('PORT');
```

----
url: https://docs.nestjs.com/v7/fundamentals/async-providers
----

* [Asynchronous providers](https://docs.nestjs.com/v7/fundamentals/async-providers#asynchronous-providers)
* [Injection](https://docs.nestjs.com/v7/fundamentals/async-providers#injection)
* [Example](https://docs.nestjs.com/v7/fundamentals/async-providers#example)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/fundamentals/async-components.md "Suggest Edits")

### Asynchronous providers

At times, the application start should be delayed until one or more **asynchronous tasks** are completed. For example, you may not want to start accepting requests until the connection with the database has been established. You can achieve this using *asynchronous providers*.

The syntax for this is to use `async/await` with the `useFactory` syntax. The factory returns a `Promise`, and the factory function can `await` asynchronous tasks. Nest will await resolution of the promise before instantiating any class that depends on (injects) such a provider.

```typescript

{
  provide: 'ASYNC_CONNECTION',
  useFactory: async () => {
    const connection = await createConnection(options);
    return connection;
  },
}
```

> **Hint** Learn more about custom provider syntax [here](/v7/fundamentals/custom-providers).

#### Injection[#](/fundamentals/async-providers#injection)

Asynchronous providers are injected to other components by their tokens, like any other provider. In the example above, you would use the construct `@Inject('ASYNC_CONNECTION')`.

#### Example[#](/fundamentals/async-providers#example)

[The TypeORM recipe](/v7/recipes/sql-typeorm) has a more substantial example of an asynchronous provider.

----
url: https://docs.nestjs.com/v11/fundamentals/lazy-loading-modules
----

* [Lazy loading modules](https://docs.nestjs.com/v11/fundamentals/lazy-loading-modules#lazy-loading-modules)
* [Getting started](https://docs.nestjs.com/v11/fundamentals/lazy-loading-modules#getting-started)
* [Lazy loading controllers, gateways, and resolvers](https://docs.nestjs.com/v11/fundamentals/lazy-loading-modules#lazy-loading-controllers-gateways-and-resolvers)
* [Common use-cases](https://docs.nestjs.com/v11/fundamentals/lazy-loading-modules#common-use-cases)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/fundamentals/lazy-loading-modules.md "Suggest Edits")

### Lazy loading modules

By default, modules are eagerly loaded, which means that as soon as the application loads, so do all the modules, whether or not they are immediately necessary. While this is fine for most applications, it may become a bottleneck for apps/workers running in the **serverless environment**, where the startup latency ("cold start") is crucial.

Lazy loading can help decrease bootstrap time by loading only modules required by the specific serverless function invocation. In addition, you could also load other modules asynchronously once the serverless function is "warm" to speed-up the bootstrap time for subsequent calls even further (deferred modules registration).

> **Hint** If you're familiar with the **[Angular](https://angular.dev/)** framework, you might have seen the "[lazy-loading modules](https://angular.dev/guide/ngmodules/lazy-loading#lazy-loading-basics)" term before. Be aware that this technique is **functionally different** in Nest and so think about this as an entirely different feature that shares similar naming conventions.

> **Warning** Do note that [lifecycle hooks methods](https://docs.nestjs.com/fundamentals/lifecycle-events) are not invoked in lazy loaded modules and services.

#### Getting started[#](/fundamentals/lazy-loading-modules#getting-started)

To load modules on-demand, Nest provides the `LazyModuleLoader` class that can be injected into a class in the normal way:

cats.service.ts

JS TS

```typescript

@Injectable()
export class CatsService {
  constructor(private lazyModuleLoader: LazyModuleLoader) {}
}
```

```typescript

@Injectable()
@Dependencies(LazyModuleLoader)
export class CatsService {
  constructor(lazyModuleLoader) {
    this.lazyModuleLoader = lazyModuleLoader;
  }
}
```

> **Hint** The `LazyModuleLoader` class is imported from the `@nestjs/core` package.

Alternatively, you can obtain a reference to the `LazyModuleLoader` provider from within your application bootstrap file (`main.ts`), as follows:

```typescript

// "app" represents a Nest application instance
const lazyModuleLoader = app.get(LazyModuleLoader);
```

With this in place, you can now load any module using the following construction:

```typescript

const { LazyModule } = await import('./lazy.module');
const moduleRef = await this.lazyModuleLoader.load(() => LazyModule);
```

> **Hint** "Lazy loaded" modules are **cached** upon the first `LazyModuleLoader#load` method invocation. That means, each consecutive attempt to load `LazyModule` will be **very fast** and will return a cached instance, instead of loading the module again.
>
> ```bash
>
> Load "LazyModule" attempt: 1
> time: 2.379ms
> Load "LazyModule" attempt: 2
> time: 0.294ms
> Load "LazyModule" attempt: 3
> time: 0.303ms
> ```
>
> Also, "lazy loaded" modules share the same modules graph as those eagerly loaded on the application bootstrap as well as any other lazy modules registered later in your app.

Where `lazy.module.ts` is a TypeScript file that exports a **regular Nest module** (no extra changes are required).

The `LazyModuleLoader#load` method returns the [module reference](/v11/fundamentals/module-ref) (of `LazyModule`) that lets you navigate the internal list of providers and obtain a reference to any provider using its injection token as a lookup key.

For example, let's say we have a `LazyModule` with the following definition:

```typescript

@Module({
  providers: [LazyService],
  exports: [LazyService],
})
export class LazyModule {}
```

> **Hint** Lazy loaded modules cannot be registered as **global modules** as it simply makes no sense (since they are registered lazily, on-demand when all the statically registered modules have been already instantiated). Likewise, registered **global enhancers** (guards/interceptors/etc.) **will not work** properly either.

With this, we could obtain a reference to the `LazyService` provider, as follows:

```typescript

const { LazyModule } = await import('./lazy.module');
const moduleRef = await this.lazyModuleLoader.load(() => LazyModule);

const { LazyService } = await import('./lazy.service');
const lazyService = moduleRef.get(LazyService);
```

> **Warning** If you use **Webpack**, make sure to update your `tsconfig.json` file - setting `compilerOptions.module` to `"esnext"` and adding `compilerOptions.moduleResolution` property with `"node"` as a value:
>
> ```json
>
> {
>   "compilerOptions": {
>     "module": "esnext",
>     "moduleResolution": "node",
>     ...
>   }
> }
> ```
>
> With these options set up, you'll be able to leverage the [code splitting](https://webpack.js.org/guides/code-splitting/) feature.

#### Lazy loading controllers, gateways, and resolvers[#](/fundamentals/lazy-loading-modules#lazy-loading-controllers-gateways-and-resolvers)

Since controllers (or resolvers in GraphQL applications) in Nest represent sets of routes/paths/topics (or queries/mutations), you **cannot lazy load them** using the `LazyModuleLoader` class.

> **Warning** Controllers, [resolvers](/v11/graphql/resolvers), and [gateways](/v11/websockets/gateways) registered inside lazy loaded modules will not behave as expected. Similarly, you cannot register middleware functions (by implementing the `MiddlewareConsumer` interface) on-demand.

For example, let's say you're building a REST API (HTTP application) with a Fastify driver under the hood (using the `@nestjs/platform-fastify` package). Fastify does not let you register routes after the application is ready/successfully listening to messages. That means even if we analyzed route mappings registered in the module's controllers, all lazy loaded routes wouldn't be accessible since there is no way to register them at runtime.

Likewise, some transport strategies we provide as part of the `@nestjs/microservices` package (including Kafka, gRPC, or RabbitMQ) require to subscribe/listen to specific topics/channels before the connection is established. Once your application starts listening to messages, the framework would not be able to subscribe/listen to new topics.

Lastly, the `@nestjs/graphql` package with the code first approach enabled automatically generates the GraphQL schema on-the-fly based on the metadata. That means, it requires all classes to be loaded beforehand. Otherwise, it would not be doable to create the appropriate, valid schema.

#### Common use-cases[#](/fundamentals/lazy-loading-modules#common-use-cases)

Most commonly, you will see lazy loaded modules in situations when your worker/cron job/lambda & serverless function/webhook must trigger different services (different logic) based on the input arguments (route path/date/query parameters, etc.). On the other hand, lazy loading modules may not make too much sense for monolithic applications, where the startup time is rather irrelevant.

----
url: https://docs.nestjs.com/graphql/mapped-types
----

[Skip to content](#content)

On this page

* [Mapped types](https://docs.nestjs.com/graphql/mapped-types#mapped-types)
* [Partial](https://docs.nestjs.com/graphql/mapped-types#partial)
* [Pick](https://docs.nestjs.com/graphql/mapped-types#pick)
* [Omit](https://docs.nestjs.com/graphql/mapped-types#omit)
* [Intersection](https://docs.nestjs.com/graphql/mapped-types#intersection)
* [Composition](https://docs.nestjs.com/graphql/mapped-types#composition)

### Mapped types

> **Warning** This chapter applies only to the code first approach.

As you build out features like CRUD (Create/Read/Update/Delete), it's often useful to construct variants of a base entity type. Nest provides several utility functions that perform type transformations to make this task more convenient.

#### Partial[#](/graphql/mapped-types#partial)

When building input validation types (also called Data Transfer Objects or DTOs), it's often useful to build **create** and **update** variations on the same type. For example, the **create** variant may require all fields, while the **update** variant may make all fields optional.

Nest provides the `PartialType()` utility function to make this task easier and minimize boilerplate.

The `PartialType()` function returns a type (class) with all the properties of the input type set to optional. For example, suppose we have a **create** type as follows:

```typescript

@InputType()
class CreateUserInput {
  @Field()
  email: string;

  @Field()
  password: string;

  @Field()
  firstName: string;
}
```

By default, all of these fields are required. To create a type with the same fields, but with each one optional, use `PartialType()` passing the class reference (`CreateUserInput`) as an argument:

```typescript

@InputType()
export class UpdateUserInput extends PartialType(CreateUserInput) {}
```

> **Hint** The `PartialType()` function is imported from the `@nestjs/graphql` package.

The `PartialType()` function takes an optional second argument: a reference to a decorator factory. Use it to change the decorator applied to the resulting (child) class. If you don't specify it, the child class effectively uses the same decorator as the **parent** class (the class referenced in the first argument). In the example above, we extend `CreateUserInput`, which is annotated with the `@InputType()` decorator. Since we want `UpdateUserInput` to be treated as if it were also decorated with `@InputType()`, we didn't need to pass `InputType` as the second argument. If the parent and child types differ (e.g., the parent is decorated with `@ObjectType()`), pass `InputType` as the second argument:

```typescript

@InputType()
export class UpdateUserInput extends PartialType(User, InputType) {}
```

Instead of a decorator factory, you can pass an options object as the second argument. It accepts the `decorator` property, `omitDefaultValues` (set to `true` to drop the default values inherited from the parent fields), and `skipNullProperties` (defaults to `true`; set it to `false` to skip validation only for `undefined` values, and still validate `null`).

#### Pick[#](/graphql/mapped-types#pick)

The `PickType()` function constructs a new type (class) by picking a set of properties from an input type. For example, suppose we start with a type like:

```typescript

@InputType()
class CreateUserInput {
  @Field()
  email: string;

  @Field()
  password: string;

  @Field()
  firstName: string;
}
```

You can pick a set of properties from this class using the `PickType()` utility function:

```typescript

@InputType()
export class UpdateEmailInput extends PickType(CreateUserInput, [
  'email',
] as const) {}
```

> **Hint** The `PickType()` function is imported from the `@nestjs/graphql` package.

#### Omit[#](/graphql/mapped-types#omit)

The `OmitType()` function constructs a type by picking all properties from an input type and then removing a particular set of keys. For example, suppose we start with a type like:

```typescript

@InputType()
class CreateUserInput {
  @Field()
  email: string;

  @Field()
  password: string;

  @Field()
  firstName: string;
}
```

You can generate a derived type that has every property **except**`email`, as shown below. Here, the second argument to `OmitType()` is an array of property names.

```typescript

@InputType()
export class UpdateUserInput extends OmitType(CreateUserInput, [
  'email',
] as const) {}
```

> **Hint** The `OmitType()` function is imported from the `@nestjs/graphql` package.

#### Intersection[#](/graphql/mapped-types#intersection)

The `IntersectionType()` function combines two types into one new type (class). For example, suppose we start with two types like:

```typescript

@InputType()
class CreateUserInput {
  @Field()
  email: string;

  @Field()
  password: string;
}

@ObjectType()
export class AdditionalUserInfo {
  @Field()
  firstName: string;

  @Field()
  lastName: string;
}
```

You can generate a new type that combines all the properties of both types:

```typescript

@InputType()
export class UpdateUserInput extends IntersectionType(
  CreateUserInput,
  AdditionalUserInfo,
) {}
```

> **Hint** The `IntersectionType()` function is imported from the `@nestjs/graphql` package.

#### Composition[#](/graphql/mapped-types#composition)

The type mapping utility functions are composable. For example, the following produces a type (class) that has all the properties of the `CreateUserInput` type except `email`, with each of them set to optional:

```typescript

@InputType()
export class UpdateUserInput extends PartialType(
  OmitType(CreateUserInput, ['email'] as const),
) {}
```

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/mapped-types.md)

----
url: https://docs.nestjs.com/v9/techniques/compression
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Compression](https://docs.nestjs.com/v9/techniques/compression#compression)
* [Use with Express (default)](https://docs.nestjs.com/v9/techniques/compression#use-with-express-default)
* [Use with Fastify](https://docs.nestjs.com/v9/techniques/compression#use-with-fastify)

```bash

$ npm i --save compression
```

Once the installation is complete, apply the compression middleware as global middleware.

```typescript

import * as compression from 'compression';
// somewhere in your initialization file
app.use(compression());
```

#### Use with Fastify[#](/techniques/compression#use-with-fastify)

If using the `FastifyAdapter`, you'll want to use [fastify-compress](https://github.com/fastify/fastify-compress):

```bash

$ npm i --save @fastify/compress
```

Once the installation is complete, apply the `@fastify/compress` middleware as global middleware.

```typescript

import compression from '@fastify/compress';
// somewhere in your initialization file
await app.register(compression);
```

By default, `@fastify/compress` will use Brotli compression (on Node >= 11.7.0) when browsers indicate support for the encoding. While Brotli is quite efficient in terms of compression ratio, it's also quite slow. Due to this, you may want to tell fastify-compress to only use deflate and gzip to compress responses; you'll end up with larger responses but they'll be delivered much more quickly.

To specify encodings, provide a second argument to `app.register`:

```typescript

await app.register(compression, { encodings: ['gzip', 'deflate'] });
```

The above tells `fastify-compress` to only use gzip and deflate encodings, preferring gzip if the client supports both.

----
url: https://docs.nestjs.com/v9/techniques/mongodb
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Mongo](https://docs.nestjs.com/v9/techniques/mongodb#mongo)
* [Model injection](https://docs.nestjs.com/v9/techniques/mongodb#model-injection)
* [Connection](https://docs.nestjs.com/v9/techniques/mongodb#connection)
* [Multiple databases](https://docs.nestjs.com/v9/techniques/mongodb#multiple-databases)
* [Hooks (middleware)](https://docs.nestjs.com/v9/techniques/mongodb#hooks-middleware)
* [Plugins](https://docs.nestjs.com/v9/techniques/mongodb#plugins)
* [Discriminators](https://docs.nestjs.com/v9/techniques/mongodb#discriminators)
* [Testing](https://docs.nestjs.com/v9/techniques/mongodb#testing)
* [Async configuration](https://docs.nestjs.com/v9/techniques/mongodb#async-configuration)
* [Example](https://docs.nestjs.com/v9/techniques/mongodb#example)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/techniques/mongo.md "Suggest Edits")

### Mongo

Nest supports two methods for integrating with the [MongoDB](https://www.mongodb.com/) database. You can either use the built-in [TypeORM](https://github.com/typeorm/typeorm) module described [here](/v9/techniques/database), which has a connector for MongoDB, or use [Mongoose](https://mongoosejs.com), the most popular MongoDB object modeling tool. In this chapter we'll describe the latter, using the dedicated `@nestjs/mongoose` package.

Start by installing the [required dependencies](https://github.com/Automattic/mongoose):

```bash

$ npm i @nestjs/mongoose mongoose
```

Once the installation process is complete, we can import the `MongooseModule` into the root `AppModule`.

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';

@Module({
  imports: [MongooseModule.forRoot('mongodb://localhost/nest')],
})
export class AppModule {}
```

```typescript

import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
import { HydratedDocument } from 'mongoose';

export type CatDocument = HydratedDocument<Cat>;

@Schema()
export class Cat {
  @Prop()
  name: string;

  @Prop()
  age: number;

  @Prop()
  breed: string;
}

export const CatSchema = SchemaFactory.createForClass(Cat);
```

> **Hint** Note you can also generate a raw schema definition using the `DefinitionsFactory` class (from the `nestjs/mongoose`). This allows you to manually modify the schema definition generated based on the metadata you provided. This is useful for certain edge-cases where it may be hard to represent everything with decorators.

The `@Schema()` decorator marks a class as a schema definition. It maps our `Cat` class to a MongoDB collection of the same name, but with an additional “s” at the end - so the final mongo collection name will be `cats`. This decorator accepts a single optional argument which is a schema options object. Think of it as the object you would normally pass as a second argument of the `mongoose.Schema` class' constructor (e.g., `new mongoose.Schema(_, options)`)). To learn more about available schema options, see [this](https://mongoosejs.com/docs/guide.html#options) chapter.

The `@Prop()` decorator defines a property in the document. For example, in the schema definition above, we defined three properties: `name`, `age`, and `breed`. The [schema types](https://mongoosejs.com/docs/schematypes.html) for these properties are automatically inferred thanks to TypeScript metadata (and reflection) capabilities. However, in more complex scenarios in which types cannot be implicitly reflected (for example, arrays or nested object structures), types must be indicated explicitly, as follows:

```typescript

@Prop([String])
tags: string[];
```

Alternatively, the `@Prop()` decorator accepts an options object argument ([read more](https://mongoosejs.com/docs/schematypes.html#schematype-options) about the available options). With this, you can indicate whether a property is required or not, specify a default value, or mark it as immutable. For example:

```typescript

@Prop({ required: true })
name: string;
```

In case you want to specify relation to another model, later for populating, you can use `@Prop()` decorator as well. For example, if `Cat` has `Owner` which is stored in a different collection called `owners`, the property should have type and ref. For example:

```typescript

import * as mongoose from 'mongoose';
import { Owner } from '../owners/schemas/owner.schema';

// inside the class definition
@Prop({ type: mongoose.Schema.Types.ObjectId, ref: 'Owner' })
owner: Owner;
```

In case there are multiple owners, your property configuration should look as follows:

```typescript

@Prop({ type: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Owner' }] })
owner: Owner[];
```

Finally, the **raw** schema definition can also be passed to the decorator. This is useful when, for example, a property represents a nested object which is not defined as a class. For this, use the `raw()` function from the `@nestjs/mongoose` package, as follows:

```typescript

@Prop(raw({
  firstName: { type: String },
  lastName: { type: String }
}))
details: Record<string, any>;
```

Alternatively, if you prefer **not using decorators**, you can define a schema manually. For example:

```typescript

export const CatSchema = new mongoose.Schema({
  name: String,
  age: Number,
  breed: String,
});
```

The `cat.schema` file resides in a folder in the `cats` directory, where we also define the `CatsModule`. While you can store schema files wherever you prefer, we recommend storing them near their related **domain** objects, in the appropriate module directory.

Let's look at the `CatsModule`:

cats.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';
import { Cat, CatSchema } from './schemas/cat.schema';

@Module({
  imports: [MongooseModule.forFeature([{ name: Cat.name, schema: CatSchema }])],
  controllers: [CatsController],
  providers: [CatsService],
})
export class CatsModule {}
```

The `MongooseModule` provides the `forFeature()` method to configure the module, including defining which models should be registered in the current scope. If you also want to use the models in another module, add MongooseModule to the `exports` section of `CatsModule` and import `CatsModule` in the other module.

Once you've registered the schema, you can inject a `Cat` model into the `CatsService` using the `@InjectModel()` decorator:

cats.service.ts

JS TS

```typescript

import { Model } from 'mongoose';
import { Injectable } from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import { Cat } from './schemas/cat.schema';
import { CreateCatDto } from './dto/create-cat.dto';

@Injectable()
export class CatsService {
  constructor(@InjectModel(Cat.name) private catModel: Model<Cat>) {}

  async create(createCatDto: CreateCatDto): Promise<Cat> {
    const createdCat = new this.catModel(createCatDto);
    return createdCat.save();
  }

  async findAll(): Promise<Cat[]> {
    return this.catModel.find().exec();
  }
}
```

```typescript

import { Model } from 'mongoose';
import { Injectable, Dependencies } from '@nestjs/common';
import { getModelToken } from '@nestjs/mongoose';
import { Cat } from './schemas/cat.schema';

@Injectable()
@Dependencies(getModelToken(Cat.name))
export class CatsService {
  constructor(catModel) {
    this.catModel = catModel;
  }

  async create(createCatDto) {
    const createdCat = new this.catModel(createCatDto);
    return createdCat.save();
  }

  async findAll() {
    return this.catModel.find().exec();
  }
}
```

#### Connection[#](/techniques/mongodb#connection)

At times you may need to access the native [Mongoose Connection](https://mongoosejs.com/docs/api.html#Connection) object. For example, you may want to make native API calls on the connection object. You can inject the Mongoose Connection by using the `@InjectConnection()` decorator as follows:

```typescript

import { Injectable } from '@nestjs/common';
import { InjectConnection } from '@nestjs/mongoose';
import { Connection } from 'mongoose';

@Injectable()
export class CatsService {
  constructor(@InjectConnection() private connection: Connection) {}
}
```

#### Multiple databases[#](/techniques/mongodb#multiple-databases)

Some projects require multiple database connections. This can also be achieved with this module. To work with multiple connections, first create the connections. In this case, connection naming becomes **mandatory**.

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';

@Module({
  imports: [
    MongooseModule.forRoot('mongodb://localhost/test', {
      connectionName: 'cats',
    }),
    MongooseModule.forRoot('mongodb://localhost/users', {
      connectionName: 'users',
    }),
  ],
})
export class AppModule {}
```

> **Notice** Please note that you shouldn't have multiple connections without a name, or with the same name, otherwise they will get overridden.

With this setup, you have to tell the `MongooseModule.forFeature()` function which connection should be used.

```typescript

@Module({
  imports: [
    MongooseModule.forFeature([{ name: Cat.name, schema: CatSchema }], 'cats'),
  ],
})
export class CatsModule {}
```

You can also inject the `Connection` for a given connection:

```typescript

import { Injectable } from '@nestjs/common';
import { InjectConnection } from '@nestjs/mongoose';
import { Connection } from 'mongoose';

@Injectable()
export class CatsService {
  constructor(@InjectConnection('cats') private connection: Connection) {}
}
```

To inject a given `Connection` to a custom provider (for example, factory provider), use the `getConnectionToken()` function passing the name of the connection as an argument.

```typescript

{
  provide: CatsService,
  useFactory: (catsConnection: Connection) => {
    return new CatsService(catsConnection);
  },
  inject: [getConnectionToken('cats')],
}
```

If you are just looking to inject the model from a named database, you can use the connection name as a second parameter to the `@InjectModel()` decorator.

cats.service.ts

JS TS

```typescript

@Injectable()
export class CatsService {
  constructor(@InjectModel(Cat.name, 'cats') private catModel: Model<Cat>) {}
}
```

```typescript

@Injectable()
@Dependencies(getModelToken(Cat.name, 'cats'))
export class CatsService {
  constructor(catModel) {
    this.catModel = catModel;
  }
}
```

#### Hooks (middleware)[#](/techniques/mongodb#hooks-middleware)

Middleware (also called pre and post hooks) are functions which are passed control during execution of asynchronous functions. Middleware is specified on the schema level and is useful for writing plugins ([source](https://mongoosejs.com/docs/middleware.html)). Calling `pre()` or `post()` after compiling a model does not work in Mongoose. To register a hook **before** model registration, use the `forFeatureAsync()` method of the `MongooseModule` along with a factory provider (i.e., `useFactory`). With this technique, you can access a schema object, then use the `pre()` or `post()` method to register a hook on that schema. See example below:

```typescript

@Module({
  imports: [
    MongooseModule.forFeatureAsync([
      {
        name: Cat.name,
        useFactory: () => {
          const schema = CatsSchema;
          schema.pre('save', function () {
            console.log('Hello from pre save');
          });
          return schema;
        },
      },
    ]),
  ],
})
export class AppModule {}
```

Like other [factory providers](https://docs.nestjs.com/fundamentals/custom-providers#factory-providers-usefactory), our factory function can be `async` and can inject dependencies through `inject`.

```typescript

@Module({
  imports: [
    MongooseModule.forFeatureAsync([
      {
        name: Cat.name,
        imports: [ConfigModule],
        useFactory: (configService: ConfigService) => {
          const schema = CatsSchema;
          schema.pre('save', function() {
            console.log(
              `${configService.get('APP_NAME')}: Hello from pre save`,
            ),
          });
          return schema;
        },
        inject: [ConfigService],
      },
    ]),
  ],
})
export class AppModule {}
```

#### Plugins[#](/techniques/mongodb#plugins)

To register a [plugin](https://mongoosejs.com/docs/plugins.html) for a given schema, use the `forFeatureAsync()` method.

```typescript

@Module({
  imports: [
    MongooseModule.forFeatureAsync([
      {
        name: Cat.name,
        useFactory: () => {
          const schema = CatsSchema;
          schema.plugin(require('mongoose-autopopulate'));
          return schema;
        },
      },
    ]),
  ],
})
export class AppModule {}
```

To register a plugin for all schemas at once, call the `.plugin()` method of the `Connection` object. You should access the connection before models are created; to do this, use the `connectionFactory`:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';

@Module({
  imports: [
    MongooseModule.forRoot('mongodb://localhost/test', {
      connectionFactory: (connection) => {
        connection.plugin(require('mongoose-autopopulate'));
        return connection;
      }
    }),
  ],
})
export class AppModule {}
```

#### Discriminators[#](/techniques/mongodb#discriminators)

[Discriminators](https://mongoosejs.com/docs/discriminators.html) are a schema inheritance mechanism. They enable you to have multiple models with overlapping schemas on top of the same underlying MongoDB collection.

Suppose you wanted to track different types of events in a single collection. Every event will have a timestamp.

event.schema.ts

JS TS

```typescript

@Schema({ discriminatorKey: 'kind' })
export class Event {
  @Prop({
    type: String,
    required: true,
    enum: [ClickedLinkEvent.name, SignUpEvent.name],
  })
  kind: string;

  @Prop({ type: Date, required: true })
  time: Date;
}

export const EventSchema = SchemaFactory.createForClass(Event);
```

> **Hint** The way mongoose tells the difference between the different discriminator models is by the "discriminator key", which is `__t` by default. Mongoose adds a String path called `__t` to your schemas that it uses to track which discriminator this document is an instance of. You may also use the `discriminatorKey` option to define the path for discrimination.

`SignedUpEvent` and `ClickedLinkEvent` instances will be stored in the same collection as generic events.

Now, let's define the `ClickedLinkEvent` class, as follows:

click-link-event.schema.ts

JS TS

```typescript

@Schema()
export class ClickedLinkEvent {
  kind: string;
  time: Date;

  @Prop({ type: String, required: true })
  url: string;
}

export const ClickedLinkEventSchema = SchemaFactory.createForClass(ClickedLinkEvent);
```

And `SignUpEvent` class:

sign-up-event.schema.ts

JS TS

```typescript

@Schema()
export class SignUpEvent {
  kind: string;
  time: Date;

  @Prop({ type: String, required: true })
  user: string;
}

export const SignUpEventSchema = SchemaFactory.createForClass(SignUpEvent);
```

With this in place, use the `discriminators` option to register a discriminator for a given schema. It works on both `MongooseModule.forFeature` and `MongooseModule.forFeatureAsync`:

event.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';

@Module({
  imports: [
    MongooseModule.forFeature([
      {
        name: Event.name,
        schema: EventSchema,
        discriminators: [
          { name: ClickedLinkEvent.name, schema: ClickedLinkEventSchema },
          { name: SignUpEvent.name, schema: SignUpEventSchema },
        ],
      },
    ]),
  ]
})
export class EventsModule {}
```

#### Testing[#](/techniques/mongodb#testing)

When unit testing an application, we usually want to avoid any database connection, making our test suites simpler to set up and faster to execute. But our classes might depend on models that are pulled from the connection instance. How do we resolve these classes? The solution is to create mock models.

To make this easier, the `@nestjs/mongoose` package exposes a `getModelToken()` function that returns a prepared [injection token](https://docs.nestjs.com/fundamentals/custom-providers#di-fundamentals) based on a token name. Using this token, you can easily provide a mock implementation using any of the standard [custom provider](/v9/fundamentals/custom-providers) techniques, including `useClass`, `useValue`, and `useFactory`. For example:

```typescript

@Module({
  providers: [
    CatsService,
    {
      provide: getModelToken(Cat.name),
      useValue: catModel,
    },
  ],
})
export class CatsModule {}
```

```typescript

MongooseModule.forRootAsync({
  useFactory: () => ({
    uri: 'mongodb://localhost/nest',
  }),
});
```

Like other [factory providers](https://docs.nestjs.com/fundamentals/custom-providers#factory-providers-usefactory), our factory function can be `async` and can inject dependencies through `inject`.

```typescript

MongooseModule.forRootAsync({
  imports: [ConfigModule],
  useFactory: async (configService: ConfigService) => ({
    uri: configService.get<string>('MONGODB_URI'),
  }),
  inject: [ConfigService],
});
```

Alternatively, you can configure the `MongooseModule` using a class instead of a factory, as shown below:

```typescript

MongooseModule.forRootAsync({
  useClass: MongooseConfigService,
});
```

The construction above instantiates `MongooseConfigService` inside `MongooseModule`, using it to create the required options object. Note that in this example, the `MongooseConfigService` has to implement the `MongooseOptionsFactory` interface, as shown below. The `MongooseModule` will call the `createMongooseOptions()` method on the instantiated object of the supplied class.

```typescript

@Injectable()
export class MongooseConfigService implements MongooseOptionsFactory {
  createMongooseOptions(): MongooseModuleOptions {
    return {
      uri: 'mongodb://localhost/nest',
    };
  }
}
```

If you want to reuse an existing options provider instead of creating a private copy inside the `MongooseModule`, use the `useExisting` syntax.

```typescript

MongooseModule.forRootAsync({
  imports: [ConfigModule],
  useExisting: ConfigService,
});
```

#### Example[#](/techniques/mongodb#example)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/06-mongoose).

----
url: https://docs.nestjs.com/v10/openapi/cli-plugin
----

* [CLI Plugin](https://docs.nestjs.com/v10/openapi/cli-plugin#cli-plugin)
* [Overview](https://docs.nestjs.com/v10/openapi/cli-plugin#overview)
* [Comments introspection](https://docs.nestjs.com/v10/openapi/cli-plugin#comments-introspection)
* [Using the CLI plugin](https://docs.nestjs.com/v10/openapi/cli-plugin#using-the-cli-plugin)
* [SWC builder](https://docs.nestjs.com/v10/openapi/cli-plugin#swc-builder)
* [Integration with ts-jest (e2e tests)](https://docs.nestjs.com/v10/openapi/cli-plugin#integration-with-ts-jest-e2e-tests)
* [Troubleshooting jest (e2e tests)](https://docs.nestjs.com/v10/openapi/cli-plugin#troubleshooting-jest-e2e-tests)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/openapi/cli-plugin.md "Suggest Edits")

### CLI Plugin

[TypeScript](https://www.typescriptlang.org/docs/handbook/decorators.html)'s metadata reflection system has several limitations which make it impossible to, for instance, determine what properties a class consists of or recognize whether a given property is optional or required. However, some of these constraints can be addressed at compilation time. Nest provides a plugin that enhances the TypeScript compilation process to reduce the amount of boilerplate code required.

> **Hint** This plugin is **opt-in**. If you prefer, you can declare all decorators manually, or only specific decorators where you need them.

```typescript

export class CreateUserDto {
  @ApiProperty()
  email: string;

  @ApiProperty()
  password: string;

  @ApiProperty({ enum: RoleEnum, default: [], isArray: true })
  roles: RoleEnum[] = [];

  @ApiProperty({ required: false, default: true })
  isEnabled?: boolean = true;
}
```

While not a significant issue with medium-sized projects, it becomes verbose & hard to maintain once you have a large set of classes.

By [enabling the Swagger plugin](/openapi/cli-plugin#using-the-cli-plugin), the above class definition can be declared simply:

```typescript

export class CreateUserDto {
  email: string;
  password: string;
  roles: RoleEnum[] = [];
  isEnabled?: boolean = true;
}
```

> **Note** The Swagger plugin will derive the @ApiProperty() annotations from the TypeScript types and class-validator decorators. This helps in clearly describing your API for the generated Swagger UI documentation. However, the validation at runtime would still be handled by class-validator decorators. So, it is required to continue using validators like `IsEmail()`, `IsNumber()`, etc.

Hence, if you intend to rely on automatic annotations for generating documentations and still wish for runtime validations, then the class-validator decorators are still necessary.

> **Hint** When using [mapped types utilities](https://docs.nestjs.com/openapi/mapped-types) (like `PartialType`) in DTOs import them from `@nestjs/swagger` instead of `@nestjs/mapped-types` for the plugin to pick up the schema.

The plugin adds appropriate decorators on the fly based on the **Abstract Syntax Tree**. Thus you won't have to struggle with `@ApiProperty` decorators scattered throughout the code.

> **Hint** The plugin will automatically generate any missing swagger properties, but if you need to override them, you simply set them explicitly via `@ApiProperty()`.

#### Comments introspection[#](/openapi/cli-plugin#comments-introspection)

With the comments introspection feature enabled, CLI plugin will generate descriptions and example values for properties based on comments.

For example, given an example `roles` property:

```typescript

/**
 * A list of user's roles
 * @example ['admin']
 */
@ApiProperty({
  description: `A list of user's roles`,
  example: ['admin'],
})
roles: RoleEnum[] = [];
```

You must duplicate both description and example values. With `introspectComments` enabled, the CLI plugin can extract these comments and automatically provide descriptions (and examples, if defined) for properties. Now, the above property can be declared simply as follows:

```typescript

/**
 * A list of user's roles
 * @example ['admin']
 */
roles: RoleEnum[] = [];
```

There are `dtoKeyOfComment` and `controllerKeyOfComment` plugin options available for customizing how the plugin assigns values to the `ApiProperty` and `ApiOperation` decorators, respectively. See the example below:

```typescript

export class SomeController {
  /**
   * Create some resource
   */
  @Post()
  create() {}
}
```

This is equivalent to the following instruction:

```typescript

@ApiOperation({ summary: "Create some resource" })
```

> **Hint** For models, the same logic applies but is used with the `ApiProperty` decorator instead.

For controllers, you can provide not only a summary but also a description (remarks), tags (such as` @deprecated`), and response examples, like this:

```ts

/**
 * Create a new cat
 *
 * @remarks This operation allows you to create a new cat.
 *
 * @deprecated
 * @throws {500} Something went wrong.
 * @throws {400} Bad Request.
 */
@Post()
async create(): Promise<Cat> {}
```

#### Using the CLI plugin[#](/openapi/cli-plugin#using-the-cli-plugin)

To enable the plugin, open `nest-cli.json` (if you use [Nest CLI](/v10/cli/overview)) and add the following `plugins` configuration:

```javascript

{
  "collection": "@nestjs/schematics",
  "sourceRoot": "src",
  "compilerOptions": {
    "plugins": ["@nestjs/swagger"]
  }
}
```

You can use the `options` property to customize the behavior of the plugin.

```javascript

"plugins": [
  {
    "name": "@nestjs/swagger",
    "options": {
      "classValidatorShim": false,
      "introspectComments": true
    }
  }
]
```

The `options` property has to fulfill the following interface:

```typescript

export interface PluginOptions {
  dtoFileNameSuffix?: string[];
  controllerFileNameSuffix?: string[];
  classValidatorShim?: boolean;
  dtoKeyOfComment?: string;
  controllerKeyOfComment?: string;
  introspectComments?: boolean;
}
```

| Option                     | Default                     | Description                                                                                                                             |
| -------------------------- | --------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| `dtoFileNameSuffix`        | `['.dto.ts', '.entity.ts']` | DTO (Data Transfer Object) files suffix                                                                                                 |
| `controllerFileNameSuffix` | `.controller.ts`            | Controller files suffix                                                                                                                 |
| `classValidatorShim`       | `true`                      | If set to true, the module will reuse `class-validator` validation decorators (e.g. `@Max(10)` will add `max: 10` to schema definition) |
| `dtoKeyOfComment`          | `'description'`             | The property key to set the comment text to on `ApiProperty`.                                                                           |
| `controllerKeyOfComment`   | `'summary'`                 | The property key to set the comment text to on `ApiOperation`.                                                                          |
| `introspectComments`       | `false`                     | If set to true, plugin will generate descriptions and example values for properties based on comments                                   |

Make sure to delete the `/dist` folder and rebuild your application whenever plugin options are updated. If you don't use the CLI but instead have a custom `webpack` configuration, you can use this plugin in combination with `ts-loader`:

```javascript

getCustomTransformers: (program: any) => ({
  before: [require('@nestjs/swagger/plugin').before({}, program)]
}),
```

#### SWC builder[#](/openapi/cli-plugin#swc-builder)

For standard setups (non-monorepo), to use CLI Plugins with the SWC builder, you need to enable type checking, as described [here](/recipes/swc#type-checking).

```bash

$ nest start -b swc --type-check
```

For monorepo setups, follow the instructions [here](/recipes/swc#monorepo-and-cli-plugins).

```bash

$ npx ts-node src/generate-metadata.ts
# OR npx ts-node apps/{YOUR_APP}/src/generate-metadata.ts
```

Now, the serialized metadata file must be loaded by the `SwaggerModule#loadPluginMetadata` method, as shown below:

```typescript

import metadata from './metadata'; // <-- file auto-generated by the "PluginMetadataGenerator"

await SwaggerModule.loadPluginMetadata(metadata); // <-- here
const document = SwaggerModule.createDocument(app, config);
```

#### Integration with `ts-jest` (e2e tests)[#](/openapi/cli-plugin#integration-with-ts-jest-e2e-tests)

To run e2e tests, `ts-jest` compiles your source code files on the fly, in memory. This means, it doesn't use Nest CLI compiler and does not apply any plugins or perform AST transformations.

To enable the plugin, create the following file in your e2e tests directory:

```javascript

const transformer = require('@nestjs/swagger/plugin');

module.exports.name = 'nestjs-swagger-transformer';
// you should change the version number anytime you change the configuration below - otherwise, jest will not detect changes
module.exports.version = 1;

module.exports.factory = (cs) => {
  return transformer.before(
    {
      // @nestjs/swagger/plugin options (can be empty)
    },
    cs.program, // "cs.tsCompiler.program" for older versions of Jest (<= v27)
  );
};
```

With this in place, import AST transformer within your `jest` configuration file. By default (in the starter application), e2e tests configuration file is located under the `test` folder and is named `jest-e2e.json`.

If you use `jest@<29`, then use the snippet below.

```json

{
  ... // other configuration
  "globals": {
    "ts-jest": {
      "astTransformers": {
        "before": ["<path to the file created above>"]
      }
    }
  }
}
```

If you use `jest@^29`, then use the snippet below, as the previous approach got deprecated.

```json

{
  ... // other configuration
  "transform": {
    "^.+\\.(t|j)s$": [
      "ts-jest",
      {
        "astTransformers": {
          "before": ["<path to the file created above>"]
        }
      }
    ]
  }
}
```

#### Troubleshooting `jest` (e2e tests)[#](/openapi/cli-plugin#troubleshooting-jest-e2e-tests)

In case `jest` does not seem to pick up your configuration changes, it's possible that Jest has already **cached** the build result. To apply the new configuration, you need to clear Jest's cache directory.

To clear the cache directory, run the following command in your NestJS project folder:

```bash

$ npx jest --clearCache
```

In case the automatic cache clearance fails, you can still manually remove the cache folder with the following commands:

```bash

# Find jest cache directory (usually /tmp/jest_rs)
# by running the following command in your NestJS project root
$ npx jest --showConfig | grep cache
# ex result:
#   "cache": true,
#   "cacheDirectory": "/tmp/jest_rs"

# Remove or empty the Jest cache directory
$ rm -rf  <cacheDirectory value>
# ex:
# rm -rf /tmp/jest_rs
```

----
url: https://docs.nestjs.com/v6/graphql/subscriptions
----

* [Subscriptions](https://docs.nestjs.com/v6/graphql/subscriptions#subscriptions)
* [Schema first](https://docs.nestjs.com/v6/graphql/subscriptions#schema-first)
* [Type definitions](https://docs.nestjs.com/v6/graphql/subscriptions#type-definitions)
* [Code first](https://docs.nestjs.com/v6/graphql/subscriptions#code-first)
* [PubSub](https://docs.nestjs.com/v6/graphql/subscriptions#pubsub)
* [Module](https://docs.nestjs.com/v6/graphql/subscriptions#module)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/subscriptions.md "Suggest Edits")

### Subscriptions

Subscription is another GraphQL operation type, like Query and Mutation. It allows creating real-time subscriptions over a bi-directional transport layer, mainly over websockets. Read more about subscriptions [here](https://www.apollographql.com/docs/graphql-subscriptions). Below is a `commentAdded` subscription example, copied directly from the official [Apollo](https://www.apollographql.com/docs/graphql-subscriptions/subscriptions-to-schema.html) documentation.

```typescript

Subscription: {
  commentAdded: {
    subscribe: () => pubSub.asyncIterator('commentAdded');
  }
}
```

> **Notice** The `pubSub` object is an instance of the `PubSub` class. Read more about it [here](https://www.apollographql.com/docs/graphql-subscriptions/setup.html).

#### Schema first[#](/graphql/subscriptions#schema-first)

To create an equivalent subscription in Nest, we'll make use of the `@Subscription()` decorator.

```typescript

const pubSub = new PubSub();

@Resolver('Author')
export class AuthorResolver {
  constructor(
    private readonly authorsService: AuthorsService,
    private readonly postsService: PostsService,
  ) {}

  @Query('author')
  async getAuthor(@Args('id') id: number) {
    return this.authorsService.findOneById(id);
  }

  @ResolveProperty('posts')
  async getPosts(@Parent() author) {
    const { id } = author;
    return this.postsService.findAll({ authorId: id });
  }

  @Subscription()
  commentAdded() {
    return pubSub.asyncIterator('commentAdded');
  }
}
```

To filter out specific events based on context and arguments, set the `filter` property.

```typescript

@Subscription('commentAdded', {
  filter: (payload, variables) =>
    payload.commentAdded.repositoryName === variables.repoFullName,
})
commentAdded() {
  return pubSub.asyncIterator('commentAdded');
}
```

To mutate the published payload, we can use a `resolve` function.

```typescript

@Subscription('commentAdded', {
  resolve: value => value,
})
commentAdded() {
  return pubSub.asyncIterator('commentAdded');
}
```

If you need to access injected providers (e.g., use an external service to validate the data), use the following construction:

```typescript

@Subscription('commentAdded', {
  resolve(this: AuthorResolver, value) {
    // "this" refers to an instance of "AuthorResolver"
    return value;
  }
})
commentAdded() {
  return pubSub.asyncIterator('commentAdded');
}
```

The same construction works with filters:

```typescript

@Subscription('commentAdded', {
  filter(this: AuthorResolver, payload, variables) {
    // "this" refers to an instance of "AuthorResolver"
    return payload.commentAdded.repositoryName === variables.repoFullName;
  }
})
commentAdded() {
  return pubSub.asyncIterator('commentAdded');
}
```

#### Type definitions[#](/graphql/subscriptions#type-definitions)

The last step is to update the type definitions file.

```graphql

type Author {
  id: Int!
  firstName: String
  lastName: String
  posts: [Post]
}

type Post {
  id: Int!
  title: String
  votes: Int
}

type Query {
  author(id: Int!): Author
}

type Comment {
  id: String
  content: String
}

type Subscription {
  commentAdded(repoFullName: String!): Comment
}
```

With this, we've created a single `commentAdded(repoFullName: String!): Comment` subscription. You can find a full sample implementation [here](https://github.com/nestjs/nest/blob/master/sample/12-graphql-apollo).

#### Code first[#](/graphql/subscriptions#code-first)

To create a subscription using the code-first approach, we'll make use of the `@Subscription()` decorator.

```typescript

const pubSub = new PubSub();

@Resolver('Author')
export class AuthorResolver {
  constructor(
    private readonly authorsService: AuthorsService,
    private readonly postsService: PostsService,
  ) {}

  @Query(returns => Author, { name: 'author' })
  async getAuthor(@Args({ name: 'id', type: () => Int }) id: number) {
    return this.authorsService.findOneById(id);
  }

  @ResolveProperty('posts')
  async getPosts(@Parent() author) {
    const { id } = author;
    return this.postsService.findAll({ authorId: id });
  }

  @Subscription(returns => Comment)
  commentAdded() {
    return pubSub.asyncIterator('commentAdded');
  }
}
```

To filter out specific events based on context and arguments, set the `filter` property.

```typescript

@Subscription(returns => Comment, {
  filter: (payload, variables) =>
    payload.commentAdded.repositoryName === variables.repoFullName,
})
commentAdded(@Args({ name: 'repoFullName', type: () => String }) repoFullName: string ) {
  return pubSub.asyncIterator('commentAdded');
}
```

To mutate the published payload, we can use a `resolve` function.

```typescript

@Subscription(returns => Comment, {
  resolve: value => value,
})
commentAdded() {
  return pubSub.asyncIterator('commentAdded');
}
```

#### PubSub[#](/graphql/subscriptions#pubsub)

We used a local `PubSub` instance above. The preferred approach is to define `PubSub` as a [provider](/v6/fundamentals/custom-providers) and inject it through the constructor (using the `@Inject()` decorator). This allows us to re-use the instance across the whole application.

```typescript

{
  provide: 'PUB_SUB',
  useValue: new PubSub(),
}
```

#### Module[#](/graphql/subscriptions#module)

To enable subscriptions, set the `installSubscriptionHandlers` property to `true`.

```typescript

GraphQLModule.forRoot({
  typePaths: ['./**/*.graphql'],
  installSubscriptionHandlers: true,
}),
```

To customize the subscriptions server (e.g., change the listener port), use the `subscriptions` options property (read [more](https://www.apollographql.com/docs/apollo-server/v2/api/apollo-server.html#constructor-options-lt-ApolloServer-gt)).

----
url: https://docs.nestjs.com/v4/faq/hybrid-application
----

### Hybrid Application

The **hybrid application**'s an application with the connected microservice/s. It's possible to combine the `INestApplication` with the endless number of the `INestMicroservice` instances.

TypeScript

```typescript

const app = await NestFactory.create(ApplicationModule);
const microservice = app.connectMicroservice({
    transport: Transport.TCP,
});

await app.startAllMicroservicesAsync();
await app.listen(3001);
```

#### Sponsors

[](https://valor-software.com/)

Nest is an MIT-licensed open source project. It can grow thanks to the support by these awesome people. If you'd like to join them, please read more [here](https://opencollective.com/nest). Thanks!

[](https://opencollective.com/nest/backer/0/website)[](https://opencollective.com/nest/backer/1/website)[](https://opencollective.com/nest/backer/2/website)[](https://opencollective.com/nest/backer/3/website)[](https://opencollective.com/nest/backer/4/website)[](https://opencollective.com/nest/backer/5/website)[](https://opencollective.com/nest/backer/6/website)[](https://opencollective.com/nest/backer/7/website)[](https://opencollective.com/nest/backer/8/website)[](https://opencollective.com/nest/backer/9/website)[](https://opencollective.com/nest/backer/10/website)[](https://opencollective.com/nest/backer/11/website)[](https://opencollective.com/nest/backer/12/website)[](https://opencollective.com/nest/backer/13/website)[](https://opencollective.com/nest/backer/14/website)[](https://opencollective.com/nest/backer/15/website)[](https://opencollective.com/nest/backer/16/website)[](https://opencollective.com/nest/backer/17/website)[](https://opencollective.com/nest/backer/18/website)[](https://opencollective.com/nest/backer/19/website)[](https://opencollective.com/nest/backer/20/website)[](https://opencollective.com/nest/backer/21/website)[](https://opencollective.com/nest/backer/22/website)[](https://opencollective.com/nest/backer/23/website)[](https://opencollective.com/nest/backer/24/website)[](https://opencollective.com/nest/backer/25/website)[](https://opencollective.com/nest/backer/26/website)[](https://opencollective.com/nest/backer/27/website)[](https://opencollective.com/nest/backer/28/website)[](https://opencollective.com/nest/backer/29/website)

[Become a sponsor](https://opencollective.com/nest)

----
url: https://docs.nestjs.com/graphql/interfaces
----

[Skip to content](#content)

On this page

* [Interfaces](https://docs.nestjs.com/graphql/interfaces#interfaces)
* [Code first](https://docs.nestjs.com/graphql/interfaces#code-first)
* [Interface resolvers](https://docs.nestjs.com/graphql/interfaces#interface-resolvers)
* [Schema first](https://docs.nestjs.com/graphql/interfaces#schema-first)

### Interfaces

Like many type systems, GraphQL supports interfaces. An **interface** is an abstract type that defines a set of fields that a type must include to implement the interface (see [interfaces](https://graphql.org/learn/schema/#interfaces) in the GraphQL documentation).

#### Code first[#](/graphql/interfaces#code-first)

In the code first approach, you define a GraphQL interface by creating an abstract class annotated with the `@InterfaceType()` decorator, exported from the `@nestjs/graphql` package.

```typescript

import { Field, ID, InterfaceType } from '@nestjs/graphql';

@InterfaceType()
export abstract class Character {
  @Field(() => ID)
  id: string;

  @Field()
  name: string;
}
```

> **Warning** TypeScript interfaces cannot be used to define GraphQL interfaces.

This generates the following part of the GraphQL schema in SDL:

```graphql

interface Character {
  id: ID!
  name: String!
}
```

To implement the `Character` interface, use the `implements` key:

```typescript

@ObjectType({
  implements: () => [Character],
})
export class Human implements Character {
  id: string;
  name: string;
}
```

> **Hint** The `@ObjectType()` decorator is exported from the `@nestjs/graphql` package.

The default `resolveType()` function generated by the library determines the type based on the value returned from the resolver method. This means that you must return class instances, not plain JavaScript object literals.

To provide a custom `resolveType()` function, pass the `resolveType` property in the options object of the `@InterfaceType()` decorator:

```typescript

@InterfaceType({
  resolveType(book) {
    if (book.colors) {
      return ColoringBook;
    }
    return TextBook;
  },
})
export abstract class Book {
  @Field(() => ID)
  id: string;

  @Field()
  title: string;
}
```

#### Interface resolvers[#](/graphql/interfaces#interface-resolvers)

So far, interfaces have only let you share field definitions with your objects. To also share the field resolver implementations, create a dedicated interface resolver:

```typescript

import { Args, Info, Parent, ResolveField, Resolver } from '@nestjs/graphql';

@Resolver((type) => Character) // Reminder: Character is an interface
export class CharacterInterfaceResolver {
  @ResolveField(() => [Character])
  friends(
    @Parent() character, // Resolved object that implements Character
    @Info() { parentType }, // Type of the object that implements Character
    @Args('search', { type: () => String }) searchTerm: string,
  ) {
    // Get character's friends
    return [];
  }
}
```

The `friends` field resolver is now registered automatically for all object types that implement the `Character` interface.

> **Warning** This requires setting the `inheritResolversFromInterfaces` property to `true` in the `GraphQLModule` configuration.

#### Schema first[#](/graphql/interfaces#schema-first)

To define an interface in the schema first approach, create a GraphQL interface with SDL:

```graphql

interface Character {
  id: ID!
  name: String!
}
```

Then, you can use the typings generation feature (as shown in the [GraphQL quick start](/graphql/quick-start) chapter) to generate the corresponding TypeScript definitions:

```typescript

export interface Character {
  id: string;
  name: string;
}
```

Interfaces require an extra `__resolveType` field in the resolver map to determine which type the interface resolves to. Create a `CharactersResolver` class and define the `__resolveType` method, which returns the name of the concrete type:

```typescript

@Resolver('Character')
export class CharactersResolver {
  @ResolveField()
  __resolveType(value) {
    if ('age' in value) {
      return 'Person';
    }
    return null;
  }
}
```

> **Hint** All decorators are exported from the `@nestjs/graphql` package.

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/interfaces.md)

----
url: https://docs.nestjs.com/v11/fundamentals/circular-dependency
----

* [Circular dependency](https://docs.nestjs.com/v11/fundamentals/circular-dependency#circular-dependency)
* [Forward reference](https://docs.nestjs.com/v11/fundamentals/circular-dependency#forward-reference)
* [ModuleRef class alternative](https://docs.nestjs.com/v11/fundamentals/circular-dependency#moduleref-class-alternative)
* [Module forward reference](https://docs.nestjs.com/v11/fundamentals/circular-dependency#module-forward-reference)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/fundamentals/circular-dependency.md "Suggest Edits")

### Circular dependency

A circular dependency occurs when two classes depend on each other. For example, class A needs class B, and class B also needs class A. Circular dependencies can arise in Nest between modules and between providers.

While circular dependencies should be avoided where possible, you can't always do so. In such cases, Nest enables resolving circular dependencies between providers in two ways. In this chapter, we describe using **forward referencing** as one technique, and using the **ModuleRef** class to retrieve a provider instance from the DI container as another.

We also describe resolving circular dependencies between modules.

> **Warning** A circular dependency might also be caused when using "barrel files"/index.ts files to group imports. Barrel files should be omitted when it comes to module/provider classes. For example, barrel files should not be used when importing files within the same directory as the barrel file, i.e. `cats/cats.controller` should not import `cats` to import the `cats/cats.service` file. For more details please also see [this GitHub issue](https://github.com/nestjs/nest/issues/1181#issuecomment-430197191).

#### Forward reference[#](/fundamentals/circular-dependency#forward-reference)

A **forward reference** allows Nest to reference classes which aren't yet defined using the `forwardRef()` utility function. For example, if `CatsService` and `CommonService` depend on each other, both sides of the relationship can use `@Inject()` and the `forwardRef()` utility to resolve the circular dependency. Otherwise Nest won't instantiate them because all of the essential metadata won't be available. Here's an example:

cats.service.ts

JS TS

```typescript

@Injectable()
export class CatsService {
  constructor(
    @Inject(forwardRef(() => CommonService))
    private commonService: CommonService,
  ) {}
}
```

```typescript

@Injectable()
@Dependencies(forwardRef(() => CommonService))
export class CatsService {
  constructor(commonService) {
    this.commonService = commonService;
  }
}
```

> **Hint** The `forwardRef()` function is imported from the `@nestjs/common` package.

That covers one side of the relationship. Now let's do the same with `CommonService`:

common.service.ts

JS TS

```typescript

@Injectable()
export class CommonService {
  constructor(
    @Inject(forwardRef(() => CatsService))
    private catsService: CatsService,
  ) {}
}
```

```typescript

@Injectable()
@Dependencies(forwardRef(() => CatsService))
export class CommonService {
  constructor(catsService) {
    this.catsService = catsService;
  }
}
```

> **Warning** The order of instantiation is indeterminate. Make sure your code does not depend on which constructor is called first. Having circular dependencies depend on providers with `Scope.REQUEST` can lead to undefined dependencies. More information available [here](https://github.com/nestjs/nest/issues/5778)

#### ModuleRef class alternative[#](/fundamentals/circular-dependency#moduleref-class-alternative)

An alternative to using `forwardRef()` is to refactor your code and use the `ModuleRef` class to retrieve a provider on one side of the (otherwise) circular relationship. Learn more about the `ModuleRef` utility class [here](/v11/fundamentals/module-ref).

#### Module forward reference[#](/fundamentals/circular-dependency#module-forward-reference)

In order to resolve circular dependencies between modules, use the same `forwardRef()` utility function on both sides of the modules association. For example:

common.module.ts

JS TS

```typescript

@Module({
  imports: [forwardRef(() => CatsModule)],
})
export class CommonModule {}
```

That covers one side of the relationship. Now let's do the same with `CatsModule`:

cats.module.ts

JS TS

```typescript

@Module({
  imports: [forwardRef(() => CommonModule)],
})
export class CatsModule {}
```

----
url: https://docs.nestjs.com/v11/faq/request-lifecycle
----

* [Request lifecycle](https://docs.nestjs.com/v11/faq/request-lifecycle#request-lifecycle)
* [Middleware](https://docs.nestjs.com/v11/faq/request-lifecycle#middleware)
* [Guards](https://docs.nestjs.com/v11/faq/request-lifecycle#guards)
* [Interceptors](https://docs.nestjs.com/v11/faq/request-lifecycle#interceptors)
* [Pipes](https://docs.nestjs.com/v11/faq/request-lifecycle#pipes)
* [Filters](https://docs.nestjs.com/v11/faq/request-lifecycle#filters)
* [Summary](https://docs.nestjs.com/v11/faq/request-lifecycle#summary)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/faq/request-lifecycle.md "Suggest Edits")

### Request lifecycle

Nest applications handle requests and produce responses in a sequence we refer to as the **request lifecycle**. With the use of middleware, pipes, guards, and interceptors, it can be challenging to track down where a particular piece of code executes during the request lifecycle, especially as global, controller level, and route level components come into play. In general, a request flows through middleware to guards, then to interceptors, then to pipes and finally back to interceptors on the return path (as the response is generated).

#### Middleware[#](/faq/request-lifecycle#middleware)

Middleware is executed in a particular sequence. First, Nest runs globally bound middleware (such as middleware bound with `app.use`) and then it runs [module bound middleware](/v11/middleware), which are determined on paths. Middleware are run sequentially in the order they are bound, similar to the way middleware in Express works. In the case of middleware bound across different modules, the middleware bound to the root module will run first, and then middleware will run in the order that the modules are added to the imports array.

#### Guards[#](/faq/request-lifecycle#guards)

Guard execution starts with global guards, then proceeds to controller guards, and finally to route guards. As with middleware, guards run in the order in which they are bound. For example:

```typescript

@UseGuards(Guard1, Guard2)
@Controller('cats')
export class CatsController {
  constructor(private catsService: CatsService) {}

  @UseGuards(Guard3)
  @Get()
  getCats(): Cats[] {
    return this.catsService.getCats();
  }
}
```

`Guard1` will execute before `Guard2` and both will execute before `Guard3`.

> **Hint** When speaking about globally bound vs controller or locally bound, the difference is where the guard (or other component is bound). If you are using `app.useGlobalGuards()` or providing the component via a module, it is globally bound. Otherwise, it is bound to a controller if the decorator precedes a controller class, or to a route if the decorator precedes a route declaration.

#### Interceptors[#](/faq/request-lifecycle#interceptors)

Interceptors, for the most part, follow the same pattern as guards, with one catch: as interceptors return [RxJS Observables](https://github.com/ReactiveX/rxjs), the observables will be resolved in a first in last out manner. So inbound requests will go through the standard global, controller, route level resolution, but the response side of the request (i.e., after returning from the controller method handler) will be resolved from route to controller to global. Also, any errors thrown by pipes, controllers, or services can be read in the `catchError` operator of an interceptor.

#### Pipes[#](/faq/request-lifecycle#pipes)

Pipes follow the standard global to controller to route bound sequence, with the same first in first out in regards to the `@UsePipes()` parameters. However, at a route parameter level, if you have multiple pipes running, they will run in the order of the last parameter with a pipe to the first. This also applies to the route level and controller level pipes. For example, if we have the following controller:

```typescript

@UsePipes(GeneralValidationPipe)
@Controller('cats')
export class CatsController {
  constructor(private catsService: CatsService) {}

  @UsePipes(RouteSpecificPipe)
  @Patch(':id')
  updateCat(
    @Body() body: UpdateCatDTO,
    @Param() params: UpdateCatParams,
    @Query() query: UpdateCatQuery,
  ) {
    return this.catsService.updateCat(body, params, query);
  }
}
```

then the `GeneralValidationPipe` will run for the `query`, then the `params`, and then the `body` objects before moving on to the `RouteSpecificPipe`, which follows the same order. If any parameter-specific pipes were in place, they would run (again, from the last to first parameter) after the controller and route level pipes.

#### Filters[#](/faq/request-lifecycle#filters)

Filters are the only component that do not resolve global first. Instead, filters resolve from the lowest level possible, meaning execution starts with any route bound filters and proceeding next to controller level, and finally to global filters. Note that exceptions cannot be passed from filter to filter; if a route level filter catches the exception, a controller or global level filter cannot catch the same exception. The only way to achieve an effect like this is to use inheritance between the filters.

> **Hint** Filters are only executed if any uncaught exception occurs during the request process. Caught exceptions, such as those caught with a `try/catch` will not trigger Exception Filters to fire. As soon as an uncaught exception is encountered, the rest of the lifecycle is ignored and the request skips straight to the filter.

----
url: https://docs.nestjs.com/v11/faq/http-adapter
----

* [HTTP adapter](https://docs.nestjs.com/v11/faq/http-adapter#http-adapter)
* [Outside application context strategy](https://docs.nestjs.com/v11/faq/http-adapter#outside-application-context-strategy)
* [As injectable](https://docs.nestjs.com/v11/faq/http-adapter#as-injectable)
* [Listening event](https://docs.nestjs.com/v11/faq/http-adapter#listening-event)

```typescript

const app = await NestFactory.create(AppModule);
const httpAdapter = app.getHttpAdapter();
```

#### As injectable[#](/faq/http-adapter#as-injectable)

To get a reference to the `HttpAdapterHost` from within the application context, inject it using the same technique as any other existing provider (e.g., using constructor injection).

JS TS

```typescript

export class CatsService {
  constructor(private adapterHost: HttpAdapterHost) {}
}
```

```typescript

@Dependencies(HttpAdapterHost)
export class CatsService {
  constructor(adapterHost) {
    this.adapterHost = adapterHost;
  }
}
```

> **Hint** The `HttpAdapterHost` is imported from the `@nestjs/core` package.

The `HttpAdapterHost` is **not** an actual `HttpAdapter`. To get the actual `HttpAdapter` instance, simply access the `httpAdapter` property.

```typescript

const adapterHost = app.get(HttpAdapterHost);
const httpAdapter = adapterHost.httpAdapter;
```

The `httpAdapter` is the actual instance of the HTTP adapter used by the underlying framework. It is an instance of either `ExpressAdapter` or `FastifyAdapter` (both classes extend `AbstractHttpAdapter`).

The adapter object exposes several useful methods to interact with the HTTP server. However, if you want to access the library instance (e.g., the Express instance) directly, call the `getInstance()` method.

```typescript

const instance = httpAdapter.getInstance();
```

#### Listening event[#](/faq/http-adapter#listening-event)

To execute an action when the server begins listening for incoming requests, you can subscribe to the `listen$` stream, as demonstrated below:

```typescript

this.httpAdapterHost.listen$.subscribe(() =>
  console.log('HTTP server is listening'),
);
```

Additionally, the `HttpAdapterHost` provides a `listening` boolean property that indicates whether the server is currently active and listening:

```typescript

if (this.httpAdapterHost.listening) {
  console.log('HTTP server is listening');
}
```

----
url: https://docs.nestjs.com/v6/fundamentals/testing
----

* [Testing](https://docs.nestjs.com/v6/fundamentals/testing#testing)
* [Installation](https://docs.nestjs.com/v6/fundamentals/testing#installation)
* [Unit testing](https://docs.nestjs.com/v6/fundamentals/testing#unit-testing)
* [Testing utilities](https://docs.nestjs.com/v6/fundamentals/testing#testing-utilities)
* [End-to-end testing](https://docs.nestjs.com/v6/fundamentals/testing#end-to-end-testing)
* [Testing request-scoped instances](https://docs.nestjs.com/v6/fundamentals/testing#testing-request-scoped-instances)

```bash

$ npm i --save-dev @nestjs/testing
```

#### Unit testing[#](/fundamentals/testing#unit-testing)

In the following example, we test two classes: `CatsController` and `CatsService`. As mentioned, [Jest](https://github.com/facebook/jest) is provided as the default testing framework. It serves as a test-runner and also provides assert functions and test-double utilities that help with mocking, spying, etc. In the following basic test, we manually instantiate these classes, and ensure that the controller and service fulfill their API contract.

cats.controller.spec.ts

JS TS

```typescript

import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

describe('CatsController', () => {
  let catsController: CatsController;
  let catsService: CatsService;

  beforeEach(() => {
    catsService = new CatsService();
    catsController = new CatsController(catsService);
  });

  describe('findAll', () => {
    it('should return an array of cats', async () => {
      const result = ['test'];
      jest.spyOn(catsService, 'findAll').mockImplementation(() => result);

      expect(await catsController.findAll()).toBe(result);
    });
  });
});
```

```typescript

import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

describe('CatsController', () => {
  let catsController;
  let catsService;

  beforeEach(() => {
    catsService = new CatsService();
    catsController = new CatsController(catsService);
  });

  describe('findAll', () => {
    it('should return an array of cats', async () => {
      const result = ['test'];
      jest.spyOn(catsService, 'findAll').mockImplementation(() => result);

      expect(await catsController.findAll()).toBe(result);
    });
  });
});
```

> **Hint** Keep your test files located near the classes they test. Testing files should have a `.spec` or `.test` suffix.

Because the above sample is trivial, we aren't really testing anything Nest-specific. Indeed, we aren't even using dependency injection (notice that we pass an instance of `CatsService` to our `catsController`). This form of testing - where we manually instantiate the classes being tested - is often called **isolated testing** as it is independent from the framework. Let's introduce some more advanced capabilities that help you test applications that make more extensive use of Nest features.

#### Testing utilities[#](/fundamentals/testing#testing-utilities)

The `@nestjs/testing` package provides a set of utilities that enable a more robust testing process. Let's rewrite the previous example using the built-in `Test` class:

cats.controller.spec.ts

JS TS

```typescript

import { Test } from '@nestjs/testing';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

describe('CatsController', () => {
  let catsController: CatsController;
  let catsService: CatsService;

  beforeEach(async () => {
    const moduleRef = await Test.createTestingModule({
        controllers: [CatsController],
        providers: [CatsService],
      }).compile();

    catsService = moduleRef.get<CatsService>(CatsService);
    catsController = moduleRef.get<CatsController>(CatsController);
  });

  describe('findAll', () => {
    it('should return an array of cats', async () => {
      const result = ['test'];
      jest.spyOn(catsService, 'findAll').mockImplementation(() => result);

      expect(await catsController.findAll()).toBe(result);
    });
  });
});
```

```typescript

import { Test } from '@nestjs/testing';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

describe('CatsController', () => {
  let catsController;
  let catsService;

  beforeEach(async () => {
    const moduleRef = await Test.createTestingModule({
        controllers: [CatsController],
        providers: [CatsService],
      }).compile();

    catsService = moduleRef.get(CatsService);
    catsController = moduleRef.get(CatsController);
  });

  describe('findAll', () => {
    it('should return an array of cats', async () => {
      const result = ['test'];
      jest.spyOn(catsService, 'findAll').mockImplementation(() => result);

      expect(await catsController.findAll()).toBe(result);
    });
  });
});
```

The `Test` class is useful for providing an application execution context that essentially mocks the full Nest runtime, but gives you hooks that make it easy to manage class instances, including mocking and overriding. The `Test` class has a `createTestingModule()` method that takes a module metadata object as its argument (the same object you pass to the `@Module()` decorator). This method returns a `TestingModule` instance which in turn provides a few methods. For unit tests, the important one is the `compile()` method. This method bootstraps a module with its dependencies (similar to the way an application is bootstrapped in the conventional `main.ts` file using `NestFactory.create()`), and returns a module that is ready for testing.

> **Hint** The `compile()` method is **asynchronous** and therefore has to be awaited. Once the module is compiled you can retrieve any **static** instance it declares (controllers and providers) using the `get()` method.

`TestingModule` inherits from the [module reference](/v6/fundamentals/module-ref) class, and therefore its ability to dynamically resolve scoped providers (transient or request-scoped). Do this with the `resolve()` method (the `get()` method can only retrieve static instances).

```typescript

const moduleRef = await Test.createTestingModule({
  controllers: [CatsController],
  providers: [CatsService],
}).compile();

catsService = await moduleRef.resolve(CatsService);
```

> **Warning** The `resolve()` method returns a unique instance of the provider, from its own **DI container sub-tree**. Each sub-tree has a unique context identifier. Thus, if you call this method more than once and compare instance references, you will see that they are not equal.

> **Hint** Learn more about the module reference features [here](/v6/fundamentals/module-ref).

Instead of using the production version of any provider, you can override it with a [custom provider](/v6/fundamentals/custom-providers) for testing purposes. For example, you can mock a database service instead of connecting to a live database. We'll cover overrides in the next section, but they're available for unit tests as well.

## Learn the right way!

* 60+ chapters
* 4+ hours of videos

```typescript

import * as request from 'supertest';
import { Test } from '@nestjs/testing';
import { CatsModule } from '../../src/cats/cats.module';
import { CatsService } from '../../src/cats/cats.service';
import { INestApplication } from '@nestjs/common';

describe('Cats', () => {
  let app: INestApplication;
  let catsService = { findAll: () => ['test'] };

  beforeAll(async () => {
    const moduleRef = await Test.createTestingModule({
      imports: [CatsModule],
    })
      .overrideProvider(CatsService)
      .useValue(catsService)
      .compile();

    app = moduleRef.createNestApplication();
    await app.init();
  });

  it(`/GET cats`, () => {
    return request(app.getHttpServer())
      .get('/cats')
      .expect(200)
      .expect({
        data: catsService.findAll(),
      });
  });

  afterAll(async () => {
    await app.close();
  });
});
```

```typescript

import * as request from 'supertest';
import { Test } from '@nestjs/testing';
import { CatsModule } from '../../src/cats/cats.module';
import { CatsService } from '../../src/cats/cats.service';
import { INestApplication } from '@nestjs/common';

describe('Cats', () => {
  let app: INestApplication;
  let catsService = { findAll: () => ['test'] };

  beforeAll(async () => {
    const moduleRef = await Test.createTestingModule({
      imports: [CatsModule],
    })
      .overrideProvider(CatsService)
      .useValue(catsService)
      .compile();

    app = moduleRef.createNestApplication();
    await app.init();
  });

  it(`/GET cats`, () => {
    return request(app.getHttpServer())
      .get('/cats')
      .expect(200)
      .expect({
        data: catsService.findAll(),
      });
  });

  afterAll(async () => {
    await app.close();
  });
});
```

The compiled module has several useful methods, as described in the following table:

|                            |                                                                                                                                                                                                                                                   |
| -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `createNestApplication()`  | Creates and returns a Nest application (`INestApplication` instance) based on the given module. Note that you must manually initialize the application using the `init()` method.                                                                 |
| `createNestMicroservice()` | Creates and returns a Nest microservice (`INestMicroservice` instance) based on the given module.                                                                                                                                                 |
| `get()`                    | Retrieves a static instance of a controller or provider (including guards, filters, etc.) available in the application context. Inherited from the [module reference](/fundamentals/module-ref) class.                                            |
| `resolve()`                | Retrieves a dynamically created scoped instance (request or transient) of a controller or provider (including guards, filters, etc.) available in the application context. Inherited from the [module reference](/fundamentals/module-ref) class. |
| `select()`                 | Navigates through the module's dependency graph; can be used to retrieve a specific instance from the selected module (used along with strict mode (`strict: true`) in `get()` method).                                                           |

> **Hint** Keep your e2e test files inside the `e2e` directory. The testing files should have a `.e2e-spec` or `.e2e-test` suffix.

#### Testing request-scoped instances[#](/fundamentals/testing#testing-request-scoped-instances)

[Request-scoped](/v6/fundamentals/injection-scopes) providers are created uniquely for each incoming **request**. The instance is garbage-collected after the request has completed processing. This poses a problem, because we can't access a dependency injection sub-tree generated specifically for a tested request.

We know (based on the sections above) that the `resolve()` method can be used to retrieve a dynamically instantiated class. Also, as described [here](https://docs.nestjs/com/fundamentals/module-ref#resolving-scoped-providers), we know we can pass a unique context identifier to control the lifecycle of a DI container sub-tree. How do we leverage this in a testing context?

The strategy is to generate a context identifier beforehand and force Nest to use this particular ID to create a sub-tree for all incoming requests. In this way we'll be able to retrieve instances created for a tested request.

To accomplish this, use `jest.spyOn()` on the `ContextIdFactory`:

```typescript

const contextId = ContextIdFactory.create();
jest
  .spyOn(ContextIdFactory, 'getByRequest')
  .mockImplementation(() => contextId);
```

Now we can use the `contextId` to access a single generated DI container sub-tree for any subsequent request.

```typescript

catsService = await moduleRef.resolve(CatsService, contextId);
```

----
url: https://docs.nestjs.com/v9/recipes/cqrs
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [CQRS](https://docs.nestjs.com/v9/recipes/cqrs#cqrs)
* [Installation](https://docs.nestjs.com/v9/recipes/cqrs#installation)
* [Commands](https://docs.nestjs.com/v9/recipes/cqrs#commands)
* [Events](https://docs.nestjs.com/v9/recipes/cqrs#events)
* [Sagas](https://docs.nestjs.com/v9/recipes/cqrs#sagas)
* [Queries](https://docs.nestjs.com/v9/recipes/cqrs#queries)
* [Setup](https://docs.nestjs.com/v9/recipes/cqrs#setup)
* [Summary](https://docs.nestjs.com/v9/recipes/cqrs#summary)
* [Example](https://docs.nestjs.com/v9/recipes/cqrs#example)

```bash

$ npm install --save @nestjs/cqrs
```

#### Commands[#](/recipes/cqrs#commands)

In this model, each action is called a **Command**. When a command is dispatched, the application reacts to it. Commands can be dispatched from the services layer, or directly from controllers/gateways. Commands are consumed by **Command Handlers**.

heroes-game.service.ts

JS TS

```typescript

@Injectable()
export class HeroesGameService {
  constructor(private commandBus: CommandBus) {}

  async killDragon(heroId: string, killDragonDto: KillDragonDto) {
    return this.commandBus.execute(
      new KillDragonCommand(heroId, killDragonDto.dragonId)
    );
  }
}
```

```typescript

@Injectable()
@Dependencies(CommandBus)
export class HeroesGameService {
  constructor(commandBus) {
    this.commandBus = commandBus;
  }

  async killDragon(heroId, killDragonDto) {
    return this.commandBus.execute(
      new KillDragonCommand(heroId, killDragonDto.dragonId)
    );
  }
}
```

Here's a sample service that dispatches `KillDragonCommand`. Let's see how the command looks:

kill-dragon.command.ts

JS TS

```typescript

export class KillDragonCommand {
  constructor(
    public readonly heroId: string,
    public readonly dragonId: string,
  ) {}
}
```

```typescript

export class KillDragonCommand {
  constructor(heroId, dragonId) {
    this.heroId = heroId;
    this.dragonId = dragonId;
  }
}
```

The `CommandBus` is a **stream** of commands. It delegates commands to the equivalent handlers. Each command must have a corresponding **Command Handler**:

kill-dragon.handler.ts

JS TS

```typescript

@CommandHandler(KillDragonCommand)
export class KillDragonHandler implements ICommandHandler<KillDragonCommand> {
  constructor(private repository: HeroRepository) {}

  async execute(command: KillDragonCommand) {
    const { heroId, dragonId } = command;
    const hero = this.repository.findOneById(+heroId);

    hero.killEnemy(dragonId);
    await this.repository.persist(hero);
  }
}
```

```typescript

@CommandHandler(KillDragonCommand)
@Dependencies(HeroRepository)
export class KillDragonHandler {
  constructor(repository) {
    this.repository = repository;
  }

  async execute(command) {
    const { heroId, dragonId } = command;
    const hero = this.repository.findOneById(+heroId);

    hero.killEnemy(dragonId);
    await this.repository.persist(hero);
  }
}
```

With this approach, every application state change is driven by the occurrence of a **Command**. The logic is encapsulated in handlers. With this approach, we can simply add behavior like logging or persisting commands in the database (e.g., for diagnostics purposes).

#### Events[#](/recipes/cqrs#events)

Command handlers neatly encapsulate logic. While beneficial, the application structure is still not flexible enough, not **reactive**. To remedy this, we also introduce **events**.

hero-killed-dragon.event.ts

JS TS

```typescript

export class HeroKilledDragonEvent {
  constructor(
    public readonly heroId: string,
    public readonly dragonId: string,
  ) {}
}
```

```typescript

export class HeroKilledDragonEvent {
  constructor(heroId, dragonId) {
    this.heroId = heroId;
    this.dragonId = dragonId;
  }
}
```

Events are asynchronous. They are dispatched either by **models** or directly using `EventBus`. In order to dispatch events, models have to extend the `AggregateRoot` class.

hero.model.ts

JS TS

```typescript

export class Hero extends AggregateRoot {
  constructor(private id: string) {
    super();
  }

  killEnemy(enemyId: string) {
    // logic
    this.apply(new HeroKilledDragonEvent(this.id, enemyId));
  }
}
```

```typescript

export class Hero extends AggregateRoot {
  constructor(id) {
    super();
    this.id = id;
  }

  killEnemy(enemyId) {
    // logic
    this.apply(new HeroKilledDragonEvent(this.id, enemyId));
  }
}
```

The `apply()` method does not dispatch events yet because there's no relationship between the model and the `EventPublisher` class. How do we associate the model and the publisher? By using a publisher `mergeObjectContext()` method inside our command handler.

kill-dragon.handler.ts

JS TS

```typescript

@CommandHandler(KillDragonCommand)
export class KillDragonHandler implements ICommandHandler<KillDragonCommand> {
  constructor(
    private repository: HeroRepository,
    private publisher: EventPublisher,
  ) {}

  async execute(command: KillDragonCommand) {
    const { heroId, dragonId } = command;
    const hero = this.publisher.mergeObjectContext(
      await this.repository.findOneById(+heroId),
    );
    hero.killEnemy(dragonId);
    hero.commit();
  }
}
```

```typescript

@CommandHandler(KillDragonCommand)
@Dependencies(HeroRepository, EventPublisher)
export class KillDragonHandler {
  constructor(repository, publisher) {
    this.repository = repository;
    this.publisher = publisher;
  }

  async execute(command) {
    const { heroId, dragonId } = command;
    const hero = this.publisher.mergeObjectContext(
      await this.repository.findOneById(+heroId),
    );
    hero.killEnemy(dragonId);
    hero.commit();
  }
}
```

Now everything works as expected. Notice that we need to `commit()` events since they're not being dispatched immediately. Obviously, an object doesn't have to exist up front. We can easily merge type context as well:

```typescript

const HeroModel = this.publisher.mergeClassContext(Hero);
new HeroModel('id');
```

Now the model has the ability to publish events. Additionally, we can emit events manually using `EventBus`:

```typescript

this.eventBus.publish(new HeroKilledDragonEvent());
```

> **Hint** The `EventBus` is an injectable class.

Each event can have multiple **Event Handlers**.

hero-killed-dragon.handler.ts

JS TS

```typescript

@EventsHandler(HeroKilledDragonEvent)
export class HeroKilledDragonHandler implements IEventHandler<HeroKilledDragonEvent> {
  constructor(private repository: HeroRepository) {}

  handle(event: HeroKilledDragonEvent) {
    // logic
  }
}
```

Now we can move the **write logic** into the event handlers.

> **Hint** Be aware that when you start using event handlers you get out of the traditional HTTP web context.
>
> * Errors in `CommandHandlers` can still be caught by built-in [Exception filters](/v9/exception-filters).
> * Errors in `EventHandlers` can't be caught by Exception filters: you will have to handle them manually. Either by a simple `try/catch`, using [Sagas](/recipes/cqrs#sagas) by triggering a compensating event, or whatever other solution you choose.
> * HTTP Responses in `CommandHandlers` can still be sent back to the client.
> * HTTP Responses in `EventHandlers` cannot. If you want to send information to the client you could use [WebSocket](/v9/websockets/gateways), [SSE](/v9/techniques/server-sent-events), or whatever other solution you choose.

#### Sagas[#](/recipes/cqrs#sagas)

This type of **Event-Driven Architecture** improves application **reactiveness and scalability**. Now, when we have events, we can simply react to them in various ways. **Sagas** are the final building block from an architectural point of view.

Sagas are an extremely powerful feature. A single saga may listen for 1..\* events. Using the [RxJS](https://github.com/ReactiveX/rxjs) library, it can combine, merge, filter or apply other `RxJS` operators on the event stream. Each saga returns an Observable which contains a command. This command is dispatched **asynchronously**.

heroes-game.saga.ts

JS TS

```typescript

@Injectable()
export class HeroesGameSagas {
  @Saga()
  dragonKilled = (events$: Observable<any>): Observable<ICommand> => {
    return events$.pipe(
      ofType(HeroKilledDragonEvent),
      map((event) => new DropAncientItemCommand(event.heroId, fakeItemID)),
    );
  }
}
```

```typescript

@Injectable()
export class HeroesGameSagas {
  @Saga()
  dragonKilled = (events$) => {
    return events$.pipe(
      ofType(HeroKilledDragonEvent),
      map((event) => new DropAncientItemCommand(event.heroId, fakeItemID)),
    );
  }
}
```

> **Hint** The `ofType` operator and the `@Saga()` decorator are exported from the `@nestjs/cqrs` package.

```typescript

export const CommandHandlers = [KillDragonHandler, DropAncientItemHandler];
export const EventHandlers =  [HeroKilledDragonHandler, HeroFoundItemHandler];

@Module({
  imports: [CqrsModule],
  controllers: [HeroesGameController],
  providers: [
    HeroesGameService,
    HeroesGameSagas,
    ...CommandHandlers,
    ...EventHandlers,
    HeroRepository,
  ]
})
export class HeroesGameModule {}
```

#### Summary[#](/recipes/cqrs#summary)

`CommandBus`, `QueryBus` and `EventBus` are **Observables**. This means that you can easily subscribe to the whole stream and enrich your application with **Event Sourcing**.

#### Example[#](/recipes/cqrs#example)

A working example is available [here](https://github.com/kamilmysliwiec/nest-cqrs-example).

----
url: https://docs.nestjs.com/v7/security/csrf
----

* [CSRF Protection](https://docs.nestjs.com/v7/security/csrf#csrf-protection)
* [Use with Express (default)](https://docs.nestjs.com/v7/security/csrf#use-with-express-default)
* [Use with Fastify](https://docs.nestjs.com/v7/security/csrf#use-with-fastify)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/security/csrf.md "Suggest Edits")

### CSRF Protection

Cross-site request forgery (also known as CSRF or XSRF) is a type of malicious exploit of a website where **unauthorized** commands are transmitted from a user that the web application trusts. To mitigate this kind of attack you can use the [csurf](https://github.com/expressjs/csurf) package.

#### Use with Express (default)[#](/security/csrf#use-with-express-default)

Start by installing the required package:

```bash

$ npm i --save csurf
```

> **Warning** As explained on the [csurf middleware page](https://github.com/expressjs/csurf#csurf), the csurf module requires either session middleware or a cookie-parser to be initialized first. Please see that documentation for further instructions.

Once the installation is complete, apply the csurf middleware as global middleware.

```typescript

import * as csurf from 'csurf';
// somewhere in your initialization file
app.use(csurf());
```

#### Use with Fastify[#](/security/csrf#use-with-fastify)

Start by installing the required package:

```bash

$ npm i --save fastify-csrf
```

Once the installation is complete, register the `fastify-csrf` plugin, as follows:

```typescript

import fastifyCsrf from 'fastify-csrf';
// somewhere in your initialization file
app.register(fastifyCsrf);
```

----
url: https://docs.nestjs.com/v11/custom-decorators
----

* [Custom route decorators](https://docs.nestjs.com/v11/custom-decorators#custom-route-decorators)
* [Param decorators](https://docs.nestjs.com/v11/custom-decorators#param-decorators)
* [Passing data](https://docs.nestjs.com/v11/custom-decorators#passing-data)
* [Working with pipes](https://docs.nestjs.com/v11/custom-decorators#working-with-pipes)
* [Decorator composition](https://docs.nestjs.com/v11/custom-decorators#decorator-composition)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/custom-decorators.md "Suggest Edits")

### Custom route decorators

Nest is built around a language feature called **decorators**. Decorators are a well-known concept in a lot of commonly used programming languages, but in the JavaScript world, they're still relatively new. In order to better understand how decorators work, we recommend reading [this article](https://medium.com/google-developers/exploring-es7-decorators-76ecb65fb841). Here's a simple definition:

> An ES2016 decorator is an expression which returns a function and can take a target, name and property descriptor as arguments. You apply it by prefixing the decorator with an `@` character and placing this at the very top of what you are trying to decorate. Decorators can be defined for either a class, a method or a property.

#### Param decorators[#](/custom-decorators#param-decorators)

Nest provides a set of useful **param decorators** that you can use together with the HTTP route handlers. Below is a list of the provided decorators and the plain Express (or Fastify) objects they represent

|                            |                                      |
| -------------------------- | ------------------------------------ |
| `@Request(), @Req()`       | `req`                                |
| `@Response(), @Res()`      | `res`                                |
| `@Next()`                  | `next`                               |
| `@Session()`               | `req.session`                        |
| `@Param(param?: string)`   | `req.params` / `req.params[param]`   |
| `@Body(param?: string)`    | `req.body` / `req.body[param]`       |
| `@Query(param?: string)`   | `req.query` / `req.query[param]`     |
| `@Headers(param?: string)` | `req.headers` / `req.headers[param]` |
| `@Ip()`                    | `req.ip`                             |
| `@HostParam()`             | `req.hosts`                          |

Additionally, you can create your own **custom decorators**. Why is this useful?

In the node.js world, it's common practice to attach properties to the **request** object. Then you manually extract them in each route handler, using code like the following:

```typescript

const user = req.user;
```

In order to make your code more readable and transparent, you can create a `@User()` decorator and reuse it across all of your controllers.

user.decorator.ts

JS TS

```typescript

import { createParamDecorator, ExecutionContext } from '@nestjs/common';

export const User = createParamDecorator(
  (data: unknown, ctx: ExecutionContext) => {
    const request = ctx.switchToHttp().getRequest();
    return request.user;
  },
);
```

Then, you can simply use it wherever it fits your requirements.

JS TS

```typescript

@Get()
async findOne(@User() user: UserEntity) {
  console.log(user);
}
```

```typescript

@Get()
@Bind(User())
async findOne(user) {
  console.log(user);
}
```

#### Passing data[#](/custom-decorators#passing-data)

When the behavior of your decorator depends on some conditions, you can use the `data` parameter to pass an argument to the decorator's factory function. One use case for this is a custom decorator that extracts properties from the request object by key. Let's assume, for example, that our [authentication layer](techniques/authentication#implementing-passport-strategies) validates requests and attaches a user entity to the request object. The user entity for an authenticated request might look like:

```json

{
  "id": 101,
  "firstName": "Alan",
  "lastName": "Turing",
  "email": "alan@email.com",
  "roles": ["admin"]
}
```

Let's define a decorator that takes a property name as key, and returns the associated value if it exists (or undefined if it doesn't exist, or if the `user` object has not been created).

user.decorator.ts

JS TS

```typescript

import { createParamDecorator, ExecutionContext } from '@nestjs/common';

export const User = createParamDecorator(
  (data: string, ctx: ExecutionContext) => {
    const request = ctx.switchToHttp().getRequest();
    const user = request.user;

    return data ? user?.[data] : user;
  },
);
```

```typescript

import { createParamDecorator } from '@nestjs/common';

export const User = createParamDecorator((data, ctx) => {
  const request = ctx.switchToHttp().getRequest();
  const user = request.user;

  return data ? user && user[data] : user;
});
```

Here's how you could then access a particular property via the `@User()` decorator in the controller:

JS TS

```typescript

@Get()
async findOne(@User('firstName') firstName: string) {
  console.log(`Hello ${firstName}`);
}
```

```typescript

@Get()
@Bind(User('firstName'))
async findOne(firstName) {
  console.log(`Hello ${firstName}`);
}
```

You can use this same decorator with different keys to access different properties. If the `user` object is deep or complex, this can make for easier and more readable request handler implementations.

> **Hint** For TypeScript users, note that `createParamDecorator<T>()` is a generic. This means you can explicitly enforce type safety, for example `createParamDecorator<string>((data, ctx) => ...)`. Alternatively, specify a parameter type in the factory function, for example `createParamDecorator((data: string, ctx) => ...)`. If you omit both, the type for `data` will be `any`.

#### Working with pipes[#](/custom-decorators#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:

JS TS

```typescript

@Get()
async findOne(
  @User(new ValidationPipe({ validateCustomDecorators: true }))
  user: UserEntity,
) {
  console.log(user);
}
```

```typescript

@Get()
@Bind(User(new ValidationPipe({ validateCustomDecorators: true })))
async findOne(user) {
  console.log(user);
}
```

> **Hint** Note that `validateCustomDecorators` option must be set to true. `ValidationPipe` does not validate arguments annotated with the custom decorators by default.

#### Decorator composition[#](/custom-decorators#decorator-composition)

Nest provides a helper method to compose multiple decorators. For example, suppose you want to combine all decorators related to authentication into a single decorator. This could be done with the following construction:

auth.decorator.ts

JS TS

```typescript

import { applyDecorators } from '@nestjs/common';

export function Auth(...roles: Role[]) {
  return applyDecorators(
    SetMetadata('roles', roles),
    UseGuards(AuthGuard, RolesGuard),
    ApiBearerAuth(),
    ApiUnauthorizedResponse({ description: 'Unauthorized' }),
  );
}
```

```typescript

import { applyDecorators } from '@nestjs/common';

export function Auth(...roles) {
  return applyDecorators(
    SetMetadata('roles', roles),
    UseGuards(AuthGuard, RolesGuard),
    ApiBearerAuth(),
    ApiUnauthorizedResponse({ description: 'Unauthorized' }),
  );
}
```

You can then use this custom `@Auth()` decorator as follows:

```typescript

@Get('users')
@Auth('admin')
findAllUsers() {}
```

This has the effect of applying all four decorators with a single declaration.

> **Warning** The `@ApiHideProperty()` decorator from the `@nestjs/swagger` package is not composable and won't work properly with the `applyDecorators` function.

----
url: https://docs.nestjs.com/v10/fundamentals/platform-agnosticism
----

* [Platform agnosticism](https://docs.nestjs.com/v10/fundamentals/platform-agnosticism#platform-agnosticism)
* [Build once, use everywhere](https://docs.nestjs.com/v10/fundamentals/platform-agnosticism#build-once-use-everywhere)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/fundamentals/platform-agnosticism.md "Suggest Edits")

### Platform agnosticism

Nest is a platform-agnostic framework. This means you can develop **reusable logical parts** that can be used across different types of applications. For example, most components can be re-used without change across different underlying HTTP server frameworks (e.g., Express and Fastify), and even across different *types* of applications (e.g., HTTP server frameworks, Microservices with different transport layers, and Web Sockets).

#### Build once, use everywhere[#](/fundamentals/platform-agnosticism#build-once-use-everywhere)

The **Overview** section of the documentation primarily shows coding techniques using HTTP server frameworks (e.g., apps providing a REST API or providing an MVC-style server-side rendered app). However, all those building blocks can be used on top of different transport layers ([microservices](/v10/microservices/basics) or [websockets](/v10/websockets/gateways)).

Furthermore, Nest comes with a dedicated [GraphQL](/v10/graphql/quick-start) module. You can use GraphQL as your API layer interchangeably with providing a REST API.

In addition, the [application context](/v10/application-context) feature helps to create any kind of Node.js application - including things like CRON jobs and CLI apps - on top of Nest.

Nest aspires to be a full-fledged platform for Node.js apps that brings a higher-level of modularity and reusability to your applications. Build once, use everywhere!

----
url: https://docs.nestjs.com/v10/security/helmet
----

* [Helmet](https://docs.nestjs.com/v10/security/helmet#helmet)
* [Use with Express (default)](https://docs.nestjs.com/v10/security/helmet#use-with-express-default)
* [Use with Fastify](https://docs.nestjs.com/v10/security/helmet#use-with-fastify)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/security/helmet.md "Suggest Edits")

### Helmet

[Helmet](https://github.com/helmetjs/helmet) can help protect your app from some well-known web vulnerabilities by setting HTTP headers appropriately. Generally, Helmet is just a collection of smaller middleware functions that set security-related HTTP headers (read [more](https://github.com/helmetjs/helmet#how-it-works)).

> **Hint** Note that applying `helmet` as global or registering it must come before other calls to `app.use()` or setup functions that may call `app.use()`. This is due to the way the underlying platform (i.e., Express or Fastify) works, where the order that middleware/routes are defined matters. If you use middleware like `helmet` or `cors` after you define a route, then that middleware will not apply to that route, it will only apply to routes defined after the middleware.

#### Use with Express (default)[#](/security/helmet#use-with-express-default)

Start by installing the required package.

```bash

$ npm i --save helmet
```

Once the installation is complete, apply it as a global middleware.

```typescript

import helmet from 'helmet';
// somewhere in your initialization file
app.use(helmet());
```

> **Warning** When using `helmet`, `@apollo/server` (4.x), and the [Apollo Sandbox](https://docs.nestjs.com/graphql/quick-start#apollo-sandbox), there may be a problem with [CSP](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP) on the Apollo Sandbox. To solve this issue configure the CSP as shown below:
>
> ```typescript
>
> app.use(helmet({
>   crossOriginEmbedderPolicy: false,
>   contentSecurityPolicy: {
>     directives: {
>       imgSrc: [`'self'`, 'data:', 'apollo-server-landing-page.cdn.apollographql.com'],
>       scriptSrc: [`'self'`, `https: 'unsafe-inline'`],
>       manifestSrc: [`'self'`, 'apollo-server-landing-page.cdn.apollographql.com'],
>       frameSrc: [`'self'`, 'sandbox.embed.apollographql.com'],
>     },
>   },
> }));
> ```

#### Use with Fastify[#](/security/helmet#use-with-fastify)

If you are using the `FastifyAdapter`, install the [@fastify/helmet](https://github.com/fastify/fastify-helmet) package:

```bash

$ npm i --save @fastify/helmet
```

[fastify-helmet](https://github.com/fastify/fastify-helmet) should not be used as a middleware, but as a [Fastify plugin](https://www.fastify.io/docs/latest/Reference/Plugins/), i.e., by using `app.register()`:

```typescript

import helmet from '@fastify/helmet'
// somewhere in your initialization file
await app.register(helmet)
```

> **Warning** When using `apollo-server-fastify` and `@fastify/helmet`, there may be a problem with [CSP](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP) on the GraphQL playground, to solve this collision, configure the CSP as shown below:
>
> ```typescript
>
> await app.register(fastifyHelmet, {
>    contentSecurityPolicy: {
>      directives: {
>        defaultSrc: [`'self'`, 'unpkg.com'],
>        styleSrc: [
>          `'self'`,
>          `'unsafe-inline'`,
>          'cdn.jsdelivr.net',
>          'fonts.googleapis.com',
>          'unpkg.com',
>        ],
>        fontSrc: [`'self'`, 'fonts.gstatic.com', 'data:'],
>        imgSrc: [`'self'`, 'data:', 'cdn.jsdelivr.net'],
>        scriptSrc: [
>          `'self'`,
>          `https: 'unsafe-inline'`,
>          `cdn.jsdelivr.net`,
>          `'unsafe-eval'`,
>        ],
>      },
>    },
>  });
>
> // If you are not going to use CSP at all, you can use this:
> await app.register(fastifyHelmet, {
>   contentSecurityPolicy: false,
> });
> ```

----
url: https://docs.nestjs.com/v8/microservices/nats
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [NATS](https://docs.nestjs.com/v8/microservices/nats#nats)
* [Installation](https://docs.nestjs.com/v8/microservices/nats#installation)
* [Overview](https://docs.nestjs.com/v8/microservices/nats#overview)
* [Options](https://docs.nestjs.com/v8/microservices/nats#options)
* [Client](https://docs.nestjs.com/v8/microservices/nats#client)
* [Request-response](https://docs.nestjs.com/v8/microservices/nats#request-response)
* [Event-based](https://docs.nestjs.com/v8/microservices/nats#event-based)
* [Queue groups](https://docs.nestjs.com/v8/microservices/nats#queue-groups)
* [Context](https://docs.nestjs.com/v8/microservices/nats#context)
* [Wildcards](https://docs.nestjs.com/v8/microservices/nats#wildcards)
* [Record builders](https://docs.nestjs.com/v8/microservices/nats#record-builders)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/microservices/nats.md "Suggest Edits")

### NATS

[NATS](https://nats.io) is a simple, secure and high performance open source messaging system for cloud native applications, IoT messaging, and microservices architectures. The NATS server is written in the Go programming language, but client libraries to interact with the server are available for dozens of major programming languages. NATS supports both **At Most Once** and **At Least Once** delivery. It can run anywhere, from large servers and cloud instances, through edge gateways and even Internet of Things devices.

#### Installation[#](/microservices/nats#installation)

To start building NATS-based microservices, first install the required package:

```bash

$ npm i --save nats
```

#### Overview[#](/microservices/nats#overview)

To use the NATS transporter, pass the following options object to the `createMicroservice()` method:

main.ts

JS TS

```typescript

const app = await NestFactory.createMicroservice<MicroserviceOptions>(AppModule, {
  transport: Transport.NATS,
  options: {
    servers: ['nats://localhost:4222'],
  },
});
```

```typescript

const app = await NestFactory.createMicroservice(AppModule, {
  transport: Transport.NATS,
  options: {
    servers: ['nats://localhost:4222'],
  },
});
```

> **Hint** The `Transport` enum is imported from the `@nestjs/microservices` package.

#### Options[#](/microservices/nats#options)

The `options` object is specific to the chosen transporter. The **NATS** transporter exposes the properties described [here](https://github.com/nats-io/node-nats#connect-options). Additionally, there is a `queue` property which allows you to specify the name of the queue that your server should subscribe to (leave `undefined` to ignore this setting). Read more about NATS queue groups [below](https://docs.nestjs.com/microservices/nats#queue-groups).

#### Client[#](/microservices/nats#client)

Like other microservice transporters, you have [several options](https://docs.nestjs.com/microservices/basics#client) for creating a NATS `ClientProxy` instance.

One method for creating an instance is to use the `ClientsModule`. To create a client instance with the `ClientsModule`, import it and use the `register()` method to pass an options object with the same properties shown above in the `createMicroservice()` method, as well as a `name` property to be used as the injection token. Read more about `ClientsModule`[here](https://docs.nestjs.com/microservices/basics#client).

```typescript

@Module({
  imports: [
    ClientsModule.register([
      {
        name: 'MATH_SERVICE',
        transport: Transport.NATS,
        options: {
          servers: ['nats://localhost:4222'],
        }
      },
    ]),
  ]
  ...
})
```

```typescript

const app = await NestFactory.createMicroservice(AppModule, {
  transport: Transport.NATS,
  options: {
    servers: ['nats://localhost:4222'],
    queue: 'cats_queue',
  },
});
```

#### Context[#](/microservices/nats#context)

In more sophisticated scenarios, you may want to access more information about the incoming request. When using the NATS transporter, you can access the `NatsContext` object.

JS TS

```typescript

@MessagePattern('notifications')
getNotifications(@Payload() data: number[], @Ctx() context: NatsContext) {
  console.log(`Subject: ${context.getSubject()}`);
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('notifications')
getNotifications(data, context) {
  console.log(`Subject: ${context.getSubject()}`);
}
```

> **Hint**`@Payload()`, `@Ctx()` and `NatsContext` are imported from the `@nestjs/microservices` package.

#### Wildcards[#](/microservices/nats#wildcards)

A subscription may be to an explicit subject, or it may include wildcards.

JS TS

```typescript

@MessagePattern('time.us.*')
getDate(@Payload() data: number[], @Ctx() context: NatsContext) {
  console.log(`Subject: ${context.getSubject()}`); // e.g. "time.us.east"
  return new Date().toLocaleTimeString(...);
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('time.us.*')
getDate(data, context) {
  console.log(`Subject: ${context.getSubject()}`); // e.g. "time.us.east"
  return new Date().toLocaleTimeString(...);
}
```

#### Record builders[#](/microservices/nats#record-builders)

To configure message options, you can use the `NatsRecordBuilder` class (note: this is doable for event-based flows as well). For example, to add `x-version` header, use the `setHeaders` method, as follows:

```typescript

import * as nats from 'nats';

// somewhere in your code
const headers = nats.headers();
headers.set('x-version', '1.0.0');

const record = new NatsRecordBuilder(':cat:').setHeaders(headers).build();
this.client.send('replace-emoji', record).subscribe(...);
```

> **Hint**`NatsRecordBuilder` class is exported from the `@nestjs/microservices` package.

And you can read these headers on the server-side as well, by accessing the `NatsContext`, as follows:

JS TS

```typescript

@MessagePattern('replace-emoji')
replaceEmoji(@Payload() data: string, @Ctx() context: NatsContext): string {
  const headers = context.getHeaders();
  return headers['x-version'] === '1.0.0' ? '🐱' : '🐈';
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('replace-emoji')
replaceEmoji(data, context) {
  const headers = context.getHeaders();
  return headers['x-version'] === '1.0.0' ? '🐱' : '🐈';
}
```

In some cases you might want to configure headers for multiple requests, you can pass these as options to the `ClientProxyFactory`:

```typescript

import { Module } from '@nestjs/common';
import { ClientProxyFactory, Transport } from '@nestjs/microservices';

@Module({
  providers: [
    {
      provide: 'API_v1',
      useFactory: () =>
        ClientProxyFactory.create({
          transport: Transport.NATS,
          options: {
            servers: ['nats://localhost:4222'],
            headers: { 'x-version': '1.0.0' },
          },
        }),
    },
  ],
})
export class ApiModule {}
```

----
url: https://docs.nestjs.com/v8/security/csrf
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [CSRF Protection](https://docs.nestjs.com/v8/security/csrf#csrf-protection)
* [Use with Express (default)](https://docs.nestjs.com/v8/security/csrf#use-with-express-default)
* [Use with Fastify](https://docs.nestjs.com/v8/security/csrf#use-with-fastify)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/security/csrf.md "Suggest Edits")

### CSRF Protection

Cross-site request forgery (also known as CSRF or XSRF) is a type of malicious exploit of a website where **unauthorized** commands are transmitted from a user that the web application trusts. To mitigate this kind of attack you can use the [csurf](https://github.com/expressjs/csurf) package.

#### Use with Express (default)[#](/security/csrf#use-with-express-default)

Start by installing the required package:

```bash

$ npm i --save csurf
```

> **Warning** As explained in the [`csurf` docs](https://github.com/expressjs/csurf#csurf), this middleware requires either session middleware or `cookie-parser` to be initialized first. Please see that documentation for further instructions.

Once the installation is complete, apply the `csurf` middleware as global middleware.

```typescript

import * as csurf from 'csurf';
// ...
// somewhere in your initialization file
app.use(csurf());
```

#### Use with Fastify[#](/security/csrf#use-with-fastify)

Start by installing the required package:

```bash

$ npm i --save fastify-csrf
```

Once the installation is complete, register the `fastify-csrf` plugin, as follows:

```typescript

import fastifyCsrf from 'fastify-csrf';
// ...
// somewhere in your initialization file after registering some storage plugin
await app.register(fastifyCsrf);
```

> **Warning** As explained in the `fastify-csrf` docs [here](https://github.com/fastify/fastify-csrf#usage), this plugin requires a storage plugin to be initialized first. Please, see that documentation for further instructions.

----
url: https://docs.nestjs.com/microservices/redis
----

[Skip to content](#content)

On this page

* [Redis](https://docs.nestjs.com/microservices/redis#redis)
* [Installation](https://docs.nestjs.com/microservices/redis#installation)
* [Overview](https://docs.nestjs.com/microservices/redis#overview)
* [Options](https://docs.nestjs.com/microservices/redis#options)
* [Client](https://docs.nestjs.com/microservices/redis#client)
* [Context](https://docs.nestjs.com/microservices/redis#context)
* [Wildcards](https://docs.nestjs.com/microservices/redis#wildcards)
* [Instance status updates](https://docs.nestjs.com/microservices/redis#instance-status-updates)
* [Listening to Redis events](https://docs.nestjs.com/microservices/redis#listening-to-redis-events)
* [Underlying driver access](https://docs.nestjs.com/microservices/redis#underlying-driver-access)

### Redis

The [Redis](https://redis.io/) transporter implements the publish/subscribe messaging paradigm and uses the [Pub/Sub](https://redis.io/topics/pubsub) feature of Redis. Published messages are categorized in channels, without the publisher knowing which subscribers (if any) will receive them. Each microservice can subscribe to any number of channels, and a single message can be received by multiple subscribers. Messages exchanged through channels are **fire-and-forget**: if a message is published and no subscriber is interested in it, the message is removed and can't be recovered. As a result, there is no guarantee that a message or event is handled by at least one service.

#### Installation[#](/microservices/redis#installation)

To start building Redis-based microservices, first install the required package:

```bash

$ npm i --save ioredis
```

#### Overview[#](/microservices/redis#overview)

To use the Redis transporter, pass the following options object to the `createMicroservice()` method:

main.ts

JS TS

```typescript

const app = await NestFactory.createMicroservice<MicroserviceOptions>(AppModule, {
  transport: Transport.REDIS,
  options: {
    host: 'localhost',
    port: 6379,
  },
});
```

```typescript

const app = await NestFactory.createMicroservice(AppModule, {
  transport: Transport.REDIS,
  options: {
    host: 'localhost',
    port: 6379,
  },
});
```

> **Hint** The `Transport` enum is imported from the `@nestjs/microservices` package.

#### Options[#](/microservices/redis#options)

The `options` property is specific to the chosen transporter. The **Redis** transporter exposes the properties described below.

|                 |                                                                                                                                    |
| --------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| `host`          | Connection hostname                                                                                                                |
| `port`          | Connection port                                                                                                                    |
| `retryAttempts` | Number of times to retry the connection (default: `0`, i.e., no retries)                                                           |
| `retryDelay`    | Delay between connection retry attempts (ms) (default: `5000`)                                                                     |
| `wildcards`     | Enables Redis wildcard subscriptions, instructing the transporter to use `psubscribe`/`pmessage` under the hood (default: `false`) |

The transporter also supports all the properties of the official [ioredis](https://redis.github.io/ioredis/index.html#RedisOptions) client.

#### Client[#](/microservices/redis#client)

As with other microservice transporters, you have [several options](/microservices/basics#client-producer-class) for creating a Redis `ClientProxy` instance.

One way to create an instance is to use the `ClientsModule`. Import it and use its `register()` method to pass an options object with the same properties shown above for the `createMicroservice()` method, plus a `name` property to use as the injection token. Read more about the `ClientsModule` in the [client section of the overview](/microservices/basics#client-producer-class).

```typescript

@Module({
  imports: [
    ClientsModule.register([
      {
        name: 'MATH_SERVICE',
        transport: Transport.REDIS,
        options: {
          host: 'localhost',
          port: 6379,
        }
      },
    ]),
  ]
  ...
})
```

You can also create a client with `ClientProxyFactory` or the `@Client()` decorator. Both are described in the [client section of the overview](/microservices/basics#client-producer-class).

#### Context[#](/microservices/redis#context)

In more complex scenarios, you may need additional information about the incoming request. With the Redis transporter, you can access the `RedisContext` object.

JS TS

```typescript

@MessagePattern('notifications')
getNotifications(@Payload() data: number[], @Ctx() context: RedisContext) {
  console.log(`Channel: ${context.getChannel()}`);
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('notifications')
getNotifications(data, context) {
  console.log(`Channel: ${context.getChannel()}`);
}
```

> **Hint**`@Payload()`, `@Ctx()` and `RedisContext` are imported from the `@nestjs/microservices` package.

#### Wildcards[#](/microservices/redis#wildcards)

To enable wildcard support, set the `wildcards` option to `true`. This instructs the transporter to use `psubscribe` and `pmessage` under the hood.

```typescript

const app = await NestFactory.createMicroservice(AppModule, {
  transport: Transport.REDIS,
  options: {
    // Other options
    wildcards: true,
  },
});
```

Pass the `wildcards` option when creating a client instance as well.

With this option enabled, you can use wildcards in your message and event patterns. For example, to subscribe to all channels starting with `notifications.`, use the following pattern:

```typescript

@EventPattern('notifications.*')
```

#### Instance status updates[#](/microservices/redis#instance-status-updates)

To get real-time updates on the connection and the state of the underlying driver instance, subscribe to the `status` stream. This stream provides status updates specific to the chosen driver. For the Redis driver, the `status` stream emits `connected`, `disconnected`, and `reconnecting` events.

```typescript

this.client.status.subscribe((status: RedisStatus) => {
  console.log(status);
});
```

> **Hint** The `RedisStatus` type is imported from the `@nestjs/microservices` package.

Similarly, you can subscribe to the server's `status` stream to receive notifications about the server's status.

```typescript

const server = app.connectMicroservice<MicroserviceOptions>(...);
server.status.subscribe((status: RedisStatus) => {
  console.log(status);
});
```

#### Listening to Redis events[#](/microservices/redis#listening-to-redis-events)

In some cases, you might want to listen to internal events emitted by the microservice. For example, you could listen for the `error` event to trigger additional operations when an error occurs. To do this, use the `on()` method. Because the Redis transporter uses two connections (see [underlying driver access](/microservices/redis#underlying-driver-access)), the callback receives the connection that emitted the event (`'pub'` or `'sub'`) as its first argument:

```typescript

this.client.on('error', (client, err) => {
  console.error(client, err);
});
```

Similarly, you can listen to the server's internal events:

```typescript

server.on<RedisEvents>('error', (client, err) => {
  console.error(client, err);
});
```

> **Hint** The `RedisEvents` type is imported from the `@nestjs/microservices` package.

Starting with NestJS v12.1, listeners registered with the client's `on()` method stay registered until you call `close()`, so they are also attached to the new `pub` and `sub` connections the client creates on the next `send()` or `emit()` call after the connection ended (once any configured `retryAttempts` are exhausted). Registrations are not deduplicated, so register each listener once rather than again from its callback or after each reconnect.

#### Underlying driver access[#](/microservices/redis#underlying-driver-access)

For more advanced use cases, you may need to access the underlying driver instance, for example, to close the connection manually or to use driver-specific methods. In most cases, however, you **shouldn't need** to access the driver directly.

To do so, use the `unwrap()` method, which returns the underlying driver instance. The generic type parameter specifies the type of driver instance you expect.

```typescript

const [pub, sub] =
  this.client.unwrap<[import('ioredis').Redis, import('ioredis').Redis]>();
```

Similarly, you can access the server's underlying driver instance:

```typescript

const [pub, sub] =
  server.unwrap<[import('ioredis').Redis, import('ioredis').Redis]>();
```

Unlike other transporters, the Redis transporter returns a tuple of two `ioredis` instances: the first one publishes messages, and the second one subscribes to them.

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/microservices/redis.md)

----
url: https://docs.nestjs.com/v11/recipes/prisma
----

* [Prisma](https://docs.nestjs.com/v11/recipes/prisma#prisma)
* [Getting started](https://docs.nestjs.com/v11/recipes/prisma#getting-started)
* [Create your NestJS project](https://docs.nestjs.com/v11/recipes/prisma#create-your-nestjs-project)
* [Set up Prisma](https://docs.nestjs.com/v11/recipes/prisma#set-up-prisma)
* [Set the generator output path](https://docs.nestjs.com/v11/recipes/prisma#set-the-generator-output-path)
* [Configure the module format](https://docs.nestjs.com/v11/recipes/prisma#configure-the-module-format)
* [Set the database connection](https://docs.nestjs.com/v11/recipes/prisma#set-the-database-connection)
* [Create two database tables with Prisma Migrate](https://docs.nestjs.com/v11/recipes/prisma#create-two-database-tables-with-prisma-migrate)
* [Install and generate Prisma Client](https://docs.nestjs.com/v11/recipes/prisma#install-and-generate-prisma-client)
* [Use Prisma Client in your NestJS services](https://docs.nestjs.com/v11/recipes/prisma#use-prisma-client-in-your-nestjs-services)
* [Summary](https://docs.nestjs.com/v11/recipes/prisma#summary)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/recipes/prisma.md "Suggest Edits")

### Prisma

[Prisma](https://www.prisma.io) is an [open-source](https://github.com/prisma/prisma) ORM for Node.js and TypeScript. It is used as an **alternative** to writing plain SQL, or using another database access tool such as SQL query builders (like [knex.js](https://knexjs.org/)) or ORMs (like [TypeORM](https://typeorm.io/) and [Sequelize](https://sequelize.org/)). Prisma currently supports PostgreSQL, MySQL, SQL Server, SQLite, MongoDB and CockroachDB ([Preview](https://www.prisma.io/docs/orm/reference/supported-databases)).

While Prisma can be used with plain JavaScript, it embraces TypeScript and provides a level to type-safety that goes beyond the guarantees other ORMs in the TypeScript ecosystem. You can find an in-depth comparison of the type-safety guarantees of Prisma and TypeORM [here](https://www.prisma.io/docs/orm/more/comparisons/prisma-and-typeorm#type-safety).

> **Note** If you want to get a quick overview of how Prisma works, you can follow the [Quickstart](https://www.prisma.io/docs/getting-started/prisma-orm/quickstart/prisma-postgres) or read the [Introduction](https://www.prisma.io/docs/orm/overview/introduction/what-is-prisma) in the [documentation](https://www.prisma.io/docs). There also are ready-to-run examples for [REST](https://github.com/prisma/prisma-examples/tree/b53fad046a6d55f0090ddce9fd17ec3f9b95cab3/orm/nest) and [GraphQL](https://github.com/prisma/prisma-examples/tree/b53fad046a6d55f0090ddce9fd17ec3f9b95cab3/orm/nest-graphql) in the [`prisma-examples`](https://github.com/prisma/prisma-examples/) repo.

#### Getting started[#](/recipes/prisma#getting-started)

In this recipe, you'll learn how to get started with NestJS and Prisma from scratch. You are going to build a sample NestJS application with a REST API that can read and write data in a database.

For the purpose of this guide, you'll use a [SQLite](https://sqlite.org/) database to save the overhead of setting up a database server. Note that you can still follow this guide, even if you're using PostgreSQL or MySQL – you'll get extra instructions for using these databases at the right places.

> **Note** If you already have an existing project and consider migrating to Prisma, you can follow the guide for [adding Prisma to an existing project](https://www.prisma.io/docs/getting-started/setup-prisma/add-to-existing-project-typescript-postgres). If you are migrating from TypeORM, you can read the guide [Migrating from TypeORM to Prisma](https://www.prisma.io/docs/guides/migrate-from-typeorm).

#### Create your NestJS project[#](/recipes/prisma#create-your-nestjs-project)

To get started, install the NestJS CLI and create your app skeleton with the following commands:

```bash

$ npm install -g @nestjs/cli
$ nest new hello-prisma
```

See the [First steps](https://docs.nestjs.com/first-steps) page to learn more about the project files created by this command. Note also that you can now run `npm start` to start your application. The REST API running at `http://localhost:3000/` currently serves a single route that's implemented in `src/app.controller.ts`. Over the course of this guide, you'll implement additional routes to store and retrieve data about *users* and *posts*.

#### Set up Prisma[#](/recipes/prisma#set-up-prisma)

Start by installing the Prisma CLI as a development dependency in your project:

```bash

$ cd hello-prisma
$ npm install prisma --save-dev
```

In the following steps, we'll be utilizing the [Prisma CLI](https://www.prisma.io/docs/orm/tools/prisma-cli). As a best practice, it's recommended to invoke the CLI locally by prefixing it with `npx`:

```bash

$ npx prisma
```

Expand if you're using Yarn

If you're using Yarn, then you can install the Prisma CLI as follows:

```bash

$ yarn add prisma --dev
```

Once installed, you can invoke it by prefixing it with `yarn`:

```bash

$ yarn prisma
```

Now create your initial Prisma setup using the `init` command of the Prisma CLI:

```bash

$ npx prisma init
```

This command creates a new `prisma` directory with the following contents:

* `schema.prisma`: Specifies your database connection and contains the database schema
* `prisma.config.ts`: A configuration file for your projects
* `.env`: A [dotenv](https://github.com/motdotla/dotenv) file, typically used to store your database credentials in a group of environment variables

#### Set the generator output path[#](/recipes/prisma#set-the-generator-output-path)

Specify your output `path` for the generated Prisma client either by passing `--output ../src/generated/prisma` during prisma init, or directly in your Prisma schema:

```groovy

generator client {
  provider        = "prisma-client"
  output          = "../src/generated/prisma"
}
```

#### Configure the module format[#](/recipes/prisma#configure-the-module-format)

Set `moduleFormat` in the generator to `cjs`:

```groovy

generator client {
  provider        = "prisma-client"
  output          = "../src/generated/prisma"
  moduleFormat    = "cjs"
}
```

> **Note** The `moduleFormat` configuration is required because Prisma v7 ships as an ES module by default, which does not work with NestJS's CommonJS setup. Setting `moduleFormat` to `cjs` forces Prisma to generate a CommonJS module instead of ESM.

#### Set the database connection[#](/recipes/prisma#set-the-database-connection)

Your database connection is configured in the `datasource` block in your `schema.prisma` file. By default it's set to `postgresql`, but since you're using a SQLite database in this guide you need to adjust the `provider` field of the `datasource` block to `sqlite`:

```groovy

datasource db {
  provider = "sqlite"
}

generator client {
  provider      = "prisma-client"
  output        = "../src/generated/prisma"
  moduleFormat  = "cjs"
}
```

Now, open up `.env` and adjust the `DATABASE_URL` environment variable to look as follows:

```bash

DATABASE_URL="file:./dev.db"
```

Make sure you have a [ConfigModule](https://docs.nestjs.com/techniques/configuration) configured, otherwise the `DATABASE_URL` variable will not be picked up from `.env`.

SQLite databases are simple files; no server is required to use a SQLite database. So instead of configuring a connection URL with a *host* and *port*, you can just point it to a local file which in this case is called `dev.db`. This file will be created in the next step.

Expand if you're using PostgreSQL, MySQL, MsSQL or Azure SQL

With PostgreSQL and MySQL, you need to configure the connection URL to point to the *database server*. You can learn more about the required connection URL format [here](https://www.prisma.io/docs/orm/reference/connection-urls).

**PostgreSQL**

If you're using PostgreSQL, you have to adjust the `schema.prisma` and `.env` files as follows:

**`schema.prisma`**

```groovy

datasource db {
  provider = "postgresql"
}

generator client {
  provider = "prisma-client"
  output          = "../src/generated/prisma"
  moduleFormat  = "cjs"
}
```

**`.env`**

```bash

DATABASE_URL="postgresql://USER:PASSWORD@HOST:PORT/DATABASE?schema=SCHEMA"
```

Replace the placeholders spelled in all uppercase letters with your database credentials. Note that if you're unsure what to provide for the `SCHEMA` placeholder, it's most likely the default value `public`:

```bash

DATABASE_URL="postgresql://USER:PASSWORD@HOST:PORT/DATABASE?schema=public"
```

If you want to learn how to set up a PostgreSQL database, you can follow this guide on [setting up a free PostgreSQL database on Heroku](https://dev.to/prisma/how-to-setup-a-free-postgresql-database-on-heroku-1dc1).

**MySQL**

If you're using MySQL, you have to adjust the `schema.prisma` and `.env` files as follows:

**`schema.prisma`**

```groovy

datasource db {
  provider = "mysql"
}

generator client {
  provider = "prisma-client"
  output          = "../src/generated/prisma"
  moduleFormat  = "cjs"
}
```

**`.env`**

```bash

DATABASE_URL="mysql://USER:PASSWORD@HOST:PORT/DATABASE"
```

Replace the placeholders spelled in all uppercase letters with your database credentials.

**Microsoft SQL Server / Azure SQL Server**

If you're using Microsoft SQL Server or Azure SQL Server, you have to adjust the `schema.prisma` and `.env` files as follows:

**`schema.prisma`**

```groovy

datasource db {
  provider = "sqlserver"
}

generator client {
  provider = "prisma-client"
  output          = "../src/generated/prisma"
  moduleFormat  = "cjs"
}
```

**`.env`**

Replace the placeholders spelled in all uppercase letters with your database credentials. Note that if you're unsure what to provide for the `encrypt` placeholder, it's most likely the default value `true`:

```bash

DATABASE_URL="sqlserver://HOST:PORT;database=DATABASE;user=USER;password=PASSWORD;encrypt=true"
```

#### Create two database tables with Prisma Migrate[#](/recipes/prisma#create-two-database-tables-with-prisma-migrate)

In this section, you'll create two new tables in your database using [Prisma Migrate](https://www.prisma.io/docs/orm/prisma-migrate/getting-started). Prisma Migrate generates SQL migration files for your declarative data model definition in the Prisma schema. These migration files are fully customizable so that you can configure any additional features of the underlying database or include additional commands, e.g. for seeding.

Add the following two models to your `schema.prisma` file:

```groovy

model User {
  id    Int     @default(autoincrement()) @id
  email String  @unique
  name  String?
  posts Post[]
}

model Post {
  id        Int      @default(autoincrement()) @id
  title     String
  content   String?
  published Boolean? @default(false)
  author    User?    @relation(fields: [authorId], references: [id])
  authorId  Int?
}
```

With your Prisma models in place, you can generate your SQL migration files and run them against the database. Run the following commands in your terminal:

```bash

$ npx prisma migrate dev --name init
```

This `prisma migrate dev` command generates SQL files and directly runs them against the database. In this case, the following migration files was created in the existing `prisma` directory:

```bash

$ tree prisma
prisma
├── dev.db
├── migrations
│   └── 20201207100915_init
│       └── migration.sql
└── schema.prisma
```

Expand to view the generated SQL statements

The following tables were created in your SQLite database:

```sql

-- CreateTable
CREATE TABLE "User" (
    "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
    "email" TEXT NOT NULL,
    "name" TEXT
);

-- CreateTable
CREATE TABLE "Post" (
    "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
    "title" TEXT NOT NULL,
    "content" TEXT,
    "published" BOOLEAN DEFAULT false,
    "authorId" INTEGER,

    FOREIGN KEY ("authorId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE
);

-- CreateIndex
CREATE UNIQUE INDEX "User.email_unique" ON "User"("email");
```

#### Install and generate Prisma Client[#](/recipes/prisma#install-and-generate-prisma-client)

Prisma Client is a type-safe database client that's *generated* from your Prisma model definition. Because of this approach, Prisma Client can expose [CRUD](https://www.prisma.io/docs/orm/prisma-client/queries/crud) operations that are *tailored* specifically to your models.

To install Prisma Client in your project, run the following command in your terminal:

```bash

$ npm install @prisma/client
```

Once installed, you can run the generate command to generate the types and Client needed for your project. If any changes are made to your schema, you will need to rerun the `generate` command to keep those types in sync.

```bash

$ npx prisma generate
```

In addition to Prisma Client, you also need to a driver adapter for the type of database you are working with. For SQLite, you can install the `@prisma/adapter-better-sqlite3` driver.

```bash

npm install @prisma/adapter-better-sqlite3
```

Expand if you're using PostgreSQL, MySQL, MsSQL, or AzureSQL

* For PostgreSQL

```bash

npm install @prisma/adapter-pg
```

* For MySQL, MsSQL, AzureSQL:

```bash

npm install @prisma/adapter-mariadb
```

#### Use Prisma Client in your NestJS services[#](/recipes/prisma#use-prisma-client-in-your-nestjs-services)

You're now able to send database queries with Prisma Client. If you want to learn more about building queries with Prisma Client, check out the [API documentation](https://www.prisma.io/docs/orm/reference/prisma-client-reference).

When setting up your NestJS application, you'll want to abstract away the Prisma Client API for database queries within a service. To get started, you can create a new `PrismaService` that takes care of instantiating `PrismaClient` and connecting to your database.

Inside the `src` directory, create a new file called `prisma.service.ts` and add the following code to it:

```typescript

import { Injectable } from '@nestjs/common';
import { PrismaClient } from './generated/prisma/client';
import { PrismaBetterSqlite3 } from '@prisma/adapter-better-sqlite3';

@Injectable()
export class PrismaService extends PrismaClient {
  constructor() {
    const adapter = new PrismaBetterSqlite3({ url: process.env.DATABASE_URL });
    super({ adapter });
  }
}
```

Next, you can write services that you can use to make database calls for the `User` and `Post` models from your Prisma schema.

Still inside the `src` directory, create a new file called `user.service.ts` and add the following code to it:

```typescript

import { Injectable } from '@nestjs/common';
import { PrismaService } from './prisma.service';
import { User, Prisma } from 'generated/prisma';

@Injectable()
export class UsersService {
  constructor(private prisma: PrismaService) {}

  async user(
    userWhereUniqueInput: Prisma.UserWhereUniqueInput,
  ): Promise<User | null> {
    return this.prisma.user.findUnique({
      where: userWhereUniqueInput,
    });
  }

  async users(params: {
    skip?: number;
    take?: number;
    cursor?: Prisma.UserWhereUniqueInput;
    where?: Prisma.UserWhereInput;
    orderBy?: Prisma.UserOrderByWithRelationInput;
  }): Promise<User[]> {
    const { skip, take, cursor, where, orderBy } = params;
    return this.prisma.user.findMany({
      skip,
      take,
      cursor,
      where,
      orderBy,
    });
  }

  async createUser(data: Prisma.UserCreateInput): Promise<User> {
    return this.prisma.user.create({
      data,
    });
  }

  async updateUser(params: {
    where: Prisma.UserWhereUniqueInput;
    data: Prisma.UserUpdateInput;
  }): Promise<User> {
    const { where, data } = params;
    return this.prisma.user.update({
      data,
      where,
    });
  }

  async deleteUser(where: Prisma.UserWhereUniqueInput): Promise<User> {
    return this.prisma.user.delete({
      where,
    });
  }
}
```

Notice how you're using Prisma Client's generated types to ensure that the methods that are exposed by your service are properly typed. You therefore save the boilerplate of typing your models and creating additional interface or DTO files.

Now do the same for the `Post` model.

Still inside the `src` directory, create a new file called `post.service.ts` and add the following code to it:

```typescript

import { Injectable } from '@nestjs/common';
import { PrismaService } from './prisma.service';
import { Post, Prisma } from 'generated/prisma';

@Injectable()
export class PostsService {
  constructor(private prisma: PrismaService) {}

  async post(
    postWhereUniqueInput: Prisma.PostWhereUniqueInput,
  ): Promise<Post | null> {
    return this.prisma.post.findUnique({
      where: postWhereUniqueInput,
    });
  }

  async posts(params: {
    skip?: number;
    take?: number;
    cursor?: Prisma.PostWhereUniqueInput;
    where?: Prisma.PostWhereInput;
    orderBy?: Prisma.PostOrderByWithRelationInput;
  }): Promise<Post[]> {
    const { skip, take, cursor, where, orderBy } = params;
    return this.prisma.post.findMany({
      skip,
      take,
      cursor,
      where,
      orderBy,
    });
  }

  async createPost(data: Prisma.PostCreateInput): Promise<Post> {
    return this.prisma.post.create({
      data,
    });
  }

  async updatePost(params: {
    where: Prisma.PostWhereUniqueInput;
    data: Prisma.PostUpdateInput;
  }): Promise<Post> {
    const { data, where } = params;
    return this.prisma.post.update({
      data,
      where,
    });
  }

  async deletePost(where: Prisma.PostWhereUniqueInput): Promise<Post> {
    return this.prisma.post.delete({
      where,
    });
  }
}
```

Your `UsersService` and `PostsService` currently wrap the CRUD queries that are available in Prisma Client. In a real world application, the service would also be the place to add business logic to your application. For example, you could have a method called `updatePassword` inside the `UsersService` that would be responsible for updating the password of a user.

Remember to register the new services in the app module.

##### Implement your REST API routes in the main app controller

Finally, you'll use the services you created in the previous sections to implement the different routes of your app. For the purpose of this guide, you'll put all your routes into the already existing `AppController` class.

Replace the contents of the `app.controller.ts` file with the following code:

```typescript

import {
  Controller,
  Get,
  Param,
  Post,
  Body,
  Put,
  Delete,
} from '@nestjs/common';
import { UsersService } from './user.service';
import { PostsService } from './post.service';
import { User as UserModel, Post as PostModel } from 'generated/prisma';

@Controller()
export class AppController {
  constructor(
    private readonly userService: UsersService,
    private readonly postService: PostsService,
  ) {}

  @Get('post/:id')
  async getPostById(@Param('id') id: string): Promise<PostModel> {
    return this.postService.post({ id: Number(id) });
  }

  @Get('feed')
  async getPublishedPosts(): Promise<PostModel[]> {
    return this.postService.posts({
      where: { published: true },
    });
  }

  @Get('filtered-posts/:searchString')
  async getFilteredPosts(
    @Param('searchString') searchString: string,
  ): Promise<PostModel[]> {
    return this.postService.posts({
      where: {
        OR: [
          {
            title: { contains: searchString },
          },
          {
            content: { contains: searchString },
          },
        ],
      },
    });
  }

  @Post('post')
  async createDraft(
    @Body() postData: { title: string; content?: string; authorEmail: string },
  ): Promise<PostModel> {
    const { title, content, authorEmail } = postData;
    return this.postService.createPost({
      title,
      content,
      author: {
        connect: { email: authorEmail },
      },
    });
  }

  @Post('user')
  async signupUser(
    @Body() userData: { name?: string; email: string },
  ): Promise<UserModel> {
    return this.userService.createUser(userData);
  }

  @Put('publish/:id')
  async publishPost(@Param('id') id: string): Promise<PostModel> {
    return this.postService.updatePost({
      where: { id: Number(id) },
      data: { published: true },
    });
  }

  @Delete('post/:id')
  async deletePost(@Param('id') id: string): Promise<PostModel> {
    return this.postService.deletePost({ id: Number(id) });
  }
}
```

    * `title: String` (required): The title of the post
    * `content: String` (optional): The content of the post
    * `authorEmail: String` (required): The email of the user that creates the post

* `/user`: Create a new user

  * Body:

    * `email: String` (required): The email address of the user
    * `name: String` (optional): The name of the user

----
url: https://docs.nestjs.com/v9/graphql/mutations
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Mutations](https://docs.nestjs.com/v9/graphql/mutations#mutations)
* [Code first](https://docs.nestjs.com/v9/graphql/mutations#code-first)
* [Schema first](https://docs.nestjs.com/v9/graphql/mutations#schema-first)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/mutations.md "Suggest Edits")

### Mutations

Most discussions of GraphQL focus on data fetching, but any complete data platform needs a way to modify server-side data as well. In REST, any request could end up causing side-effects on the server, but best practice suggests we should not modify data in GET requests. GraphQL is similar - technically any query could be implemented to cause a data write. However, like REST, it's recommended to observe the convention that any operations that cause writes should be sent explicitly via a mutation (read more [here](https://graphql.org/learn/queries/#mutations)).

The official [Apollo](https://www.apollographql.com/docs/graphql-tools/generate-schema.html) documentation uses an `upvotePost()` mutation example. This mutation implements a method to increase a post's `votes` property value. To create an equivalent mutation in Nest, we'll make use of the `@Mutation()` decorator.

#### Code first[#](/graphql/mutations#code-first)

Let's add another method to the `AuthorResolver` used in the previous section (see [resolvers](/v9/graphql/resolvers)).

```typescript

@Mutation(returns => Post)
async upvotePost(@Args({ name: 'postId', type: () => Int }) postId: number) {
  return this.postsService.upvoteById({ id: postId });
}
```

> **Hint** All decorators (e.g., `@Resolver`, `@ResolveField`, `@Args`, etc.) are exported from the `@nestjs/graphql` package.

This will result in generating the following part of the GraphQL schema in SDL:

```graphql

type Mutation {
  upvotePost(postId: Int!): Post
}
```

The `upvotePost()` method takes `postId` (`Int`) as an argument and returns an updated `Post` entity. For the reasons explained in the [resolvers](/v9/graphql/resolvers) section, we have to explicitly set the expected type.

If the mutation needs to take an object as an argument, we can create an **input type**. The input type is a special kind of object type that can be passed in as an argument (read more [here](https://graphql.org/learn/schema/#input-types)). To declare an input type, use the `@InputType()` decorator.

```typescript

import { InputType, Field } from '@nestjs/graphql';

@InputType()
export class UpvotePostInput {
  @Field()
  postId: number;
}
```

> **Hint** The `@InputType()` decorator takes an options object as an argument, so you can, for example, specify the input type's description. Note that, due to TypeScript's metadata reflection system limitations, you must either use the `@Field` decorator to manually indicate a type, or use a [CLI plugin](/v9/graphql/cli-plugin).

We can then use this type in the resolver class:

```typescript

@Mutation(returns => Post)
async upvotePost(
  @Args('upvotePostData') upvotePostData: UpvotePostInput,
) {}
```

#### Schema first[#](/graphql/mutations#schema-first)

Let's extend our `AuthorResolver` used in the previous section (see [resolvers](/v9/graphql/resolvers)).

```typescript

@Mutation()
async upvotePost(@Args('postId') postId: number) {
  return this.postsService.upvoteById({ id: postId });
}
```

Note that we assumed above that the business logic has been moved to the `PostsService` (querying the post and incrementing its `votes` property). The logic inside the `PostsService` class can be as simple or sophisticated as needed. The main point of this example is to show how resolvers can interact with other providers.

The last step is to add our mutation to the existing types definition.

```graphql

type Author {
  id: Int!
  firstName: String
  lastName: String
  posts: [Post]
}

type Post {
  id: Int!
  title: String
  votes: Int
}

type Query {
  author(id: Int!): Author
}

type Mutation {
  upvotePost(postId: Int!): Post
}
```

The `upvotePost(postId: Int!): Post` mutation is now available to be called as part of our application's GraphQL API.

----
url: https://docs.nestjs.com/v10/faq/keep-alive-connections
----

* [Keep alive connections](https://docs.nestjs.com/v10/faq/keep-alive-connections#keep-alive-connections)
* [Usage](https://docs.nestjs.com/v10/faq/keep-alive-connections#usage)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/faq/keep-alive-connections.md "Suggest Edits")

### Keep alive connections

By default, the HTTP adapters of NestJS will wait until the response is finished before closing the application. But sometimes, this behavior is not desired, or unexpected. There might be some requests that use `Connection: Keep-Alive` headers that live for a long time.

For these scenarios where you always want your application to exit without waiting for requests to end, you can enable the `forceCloseConnections` option when creating your NestJS application.

> **Tip** Most users will not need to enable this option. But the symptom of needing this option is that your application will not exit when you expect it to. Usually when `app.enableShutdownHooks()` is enabled and you notice that the application is not restarting/exiting. Most likely while running the NestJS application during development with `--watch`.

#### Usage[#](/faq/keep-alive-connections#usage)

In your `main.ts` file, enable the option when creating your NestJS application:

```typescript

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule, {
    forceCloseConnections: true,
  });
  await app.listen(process.env.PORT ?? 3000);
}

bootstrap();
```

----
url: https://docs.nestjs.com/v6/websockets/guards
----

* [Guards](https://docs.nestjs.com/v6/websockets/guards#guards)
* [Binding guards](https://docs.nestjs.com/v6/websockets/guards#binding-guards)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/websockets/guards.md "Suggest Edits")

### Guards

There is no fundamental difference between web sockets guards and [regular HTTP application guards](/v6/guards). The only difference is that instead of throwing `HttpException`, you should use `WsException`.

> **Hint** The `WsException` class is exposed from `@nestjs/websockets` package.

#### Binding guards[#](/websockets/guards#binding-guards)

The following example uses a method-scoped guard. Just as with HTTP based applications, you can also use gateway-scoped guards (i.e., prefix the gateway class with a `@UseGuards()` decorator).

JS TS

```typescript

@UseGuards(AuthGuard)
@SubscribeMessage('events')
handleEvent(client: Client, data: unknown): WsResponse<unknown> {
  const event = 'events';
  return { event, data };
}
```

```typescript

@UseGuards(AuthGuard)
@SubscribeMessage('events')
handleEvent(client, data) {
  const event = 'events';
  return { event, data };
}
```

----
url: https://docs.nestjs.com/v6/microservices/mqtt
----

* [MQTT](https://docs.nestjs.com/v6/microservices/mqtt#mqtt)
* [Installation](https://docs.nestjs.com/v6/microservices/mqtt#installation)
* [Overview](https://docs.nestjs.com/v6/microservices/mqtt#overview)
* [Options](https://docs.nestjs.com/v6/microservices/mqtt#options)
* [Client](https://docs.nestjs.com/v6/microservices/mqtt#client)
* [Context](https://docs.nestjs.com/v6/microservices/mqtt#context)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/microservices/mqtt.md "Suggest Edits")

### MQTT

[MQTT](http://mqtt.org/) (Message Queuing Telemetry Transport) is an open source, lightweight messaging protocol, optimized for high-latency. This protocol provides a scalable and cost-efficient way to connect devices using a **publish/subscribe** model. A communication system built on MQTT consists of the publishing server, a broker and one or more clients. It is designed for constrained devices and low-bandwidth, high-latency or unreliable networks.

#### Installation[#](/microservices/mqtt#installation)

To start building MQTT-based microservices, first install the required package:

```bash

$ npm i --save mqtt
```

#### Overview[#](/microservices/mqtt#overview)

To use the MQTT transporter, pass the following options object to the `createMicroservice()` method:

main.ts

JS TS

```typescript

const app = await NestFactory.createMicroservice(ApplicationModule, {
  transport: Transport.MQTT,
  options: {
    host: 'localhost',
    port: 1883,
  },
});
```

> **Hint** The `Transport` enum is imported from the `@nestjs/microservices` package.

#### Options[#](/microservices/mqtt#options)

The `options` object is specific to the chosen transporter. The **MQTT** transporter exposes the properties described [here](https://github.com/mqttjs/MQTT.js/#mqttclientstreambuilder-options).

#### Client[#](/microservices/mqtt#client)

Like other microservice transporters, you have [several options](https://docs.nestjs.com/microservices/basics#client) for creating a MQTT `ClientProxy` instance.

One method for creating an instance is to use use the `ClientsModule`. To create a client instance with the `ClientsModule`, import it and use the `register()` method to pass an options object with the same properties shown above in the `createMicroservice()` method, as well as a `name` property to be used as the injection token. Read more about `ClientsModule`[here](https://docs.nestjs.com/microservices/basics#client).

```typescript

@Module({
  imports: [
    ClientsModule.register([
      {
        name: 'MATH_SERVICE',
        transport: Transport.MQTT,
        options: {
          host: 'localhost',
          port: 1883,
        }
      },
    ]),
  ]
  ...
})
```

Other options to create a client (either `ClientProxyFactory` or `@Client()`) can be used as well. You can read about them [here](https://docs.nestjs.com/microservices/basics#client).

#### Context[#](/microservices/mqtt#context)

In more sophisticated scenarios, you may want to access more information about the incoming request. When using the MQTT transporter, you can access the `MqttContext` object.

JS TS

```typescript

@MessagePattern('notifications')
getNotifications(@Payload() data: number[], @Ctx() context: MqttContext) {
  console.log(`Topic: ${context.getTopic()}`);
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('notifications')
getNotifications(data, context) {
  console.log(`Topic: ${context.getTopic()}`);
}
```

> **Hint**`@Payload()`, `@Ctx()` and `MqttContext` are imported from the `@nestjs/microservices` package.

To access the original mqtt [packet](https://github.com/mqttjs/mqtt-packet), use the `getPacket()` method of the `MqttContext` object, as follows:

JS TS

```typescript

@MessagePattern('notifications')
getNotifications(@Payload() data: number[], @Ctx() context: MqttContext) {
  console.log(context.getPacket());
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('notifications')
getNotifications(data, context) {
  console.log(context.getPacket());
}
```

----
url: https://docs.nestjs.com/graphql/quick-start
----

[Skip to content](#content)

On this page

* [Installation](https://docs.nestjs.com/graphql/quick-start#installation)
* [Overview](https://docs.nestjs.com/graphql/quick-start#overview)
* [Getting started with GraphQL & TypeScript](https://docs.nestjs.com/graphql/quick-start#getting-started-with-graphql--typescript)
* [Accessing the request and response objects](https://docs.nestjs.com/graphql/quick-start#accessing-the-request-and-response-objects)
* [GraphQL IDE](https://docs.nestjs.com/graphql/quick-start#graphql-ide)
* [Code first](https://docs.nestjs.com/graphql/quick-start#code-first)
* [Example](https://docs.nestjs.com/graphql/quick-start#example)
* [Schema first](https://docs.nestjs.com/graphql/quick-start#schema-first)
* [Apollo Sandbox](https://docs.nestjs.com/graphql/quick-start#apollo-sandbox)
* [Example](https://docs.nestjs.com/graphql/quick-start#example-1)
* [Accessing generated schema](https://docs.nestjs.com/graphql/quick-start#accessing-generated-schema)
* [Async configuration](https://docs.nestjs.com/graphql/quick-start#async-configuration)
* [Mercurius integration](https://docs.nestjs.com/graphql/quick-start#mercurius-integration)
* [Multiple endpoints](https://docs.nestjs.com/graphql/quick-start#multiple-endpoints)
* [Third-party integrations](https://docs.nestjs.com/graphql/quick-start#third-party-integrations)
* [Example](https://docs.nestjs.com/graphql/quick-start#example-2)

## Harnessing the power of TypeScript & GraphQL

[GraphQL](https://graphql.org/) is a query language for APIs and a runtime for fulfilling those queries with your existing data. It solves many problems typically found with REST APIs. For background, see this [comparison of GraphQL and REST](https://www.apollographql.com/blog/graphql-vs-rest). Combined with [TypeScript](https://www.typescriptlang.org/), GraphQL gives you better type safety for your queries and end-to-end typing.

This chapter assumes a basic understanding of GraphQL and focuses on working with the built-in `@nestjs/graphql` module. The `GraphQLModule` can be configured to use [Apollo](https://www.apollographql.com/) Server (with the `@nestjs/apollo` driver) or [Mercurius](https://github.com/mercurius-js/mercurius) (with the `@nestjs/mercurius` driver). Nest provides official integrations for both packages (see also the [third-party integrations](/graphql/quick-start#third-party-integrations) below).

You can also build your own driver (see [Creating a custom driver](/graphql/other-features#creating-a-custom-driver)).

#### Installation[#](/graphql/quick-start#installation)

Start by installing the required packages:

```bash

# For Express and Apollo (default)
$ npm i @nestjs/graphql @nestjs/apollo @apollo/server @as-integrations/express5 graphql

# For Fastify and Apollo
# npm i @nestjs/graphql @nestjs/apollo @apollo/server @as-integrations/fastify graphql

# For Fastify and Mercurius
# npm i @nestjs/graphql @nestjs/mercurius graphql mercurius
```

> **Warning**`@nestjs/apollo` v14 requires **Apollo Server v5** (the `@apollo/server` package). If you are upgrading from an older Apollo Server version, see the [Apollo Server migration guide](https://www.apollographql.com/docs/apollo-server/migration/).

#### Overview[#](/graphql/quick-start#overview)

Nest offers two ways of building GraphQL applications: **code first** and **schema first**. Choose the one that suits you best. Most chapters in this GraphQL section are divided into two parts: one for the **code first** approach and one for the **schema first** approach.

In the **code first** approach, you use decorators and TypeScript classes to generate the corresponding GraphQL schema. This approach suits you if you prefer to work exclusively in TypeScript and avoid switching between language syntaxes.

In the **schema first** approach, the source of truth is a set of GraphQL SDL (Schema Definition Language) files. SDL is a language-agnostic way to share schema files between platforms. Nest generates your TypeScript definitions (as classes or interfaces) from the GraphQL schemas, so you don't have to write redundant boilerplate code.

> **Hint** The following chapters use the `@nestjs/apollo` package. To use Mercurius instead, see [Mercurius integration](/graphql/quick-start#mercurius-integration).

Once the packages are installed, import the `GraphQLModule` and configure it with the `forRoot()` static method.

JS TS

```typescript

import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';
import { ApolloDriver, ApolloDriverConfig } from '@nestjs/apollo';

@Module({
  imports: [
    GraphQLModule.forRoot<ApolloDriverConfig>({
      driver: ApolloDriver,
    }),
  ],
})
export class AppModule {}
```

> **Hint** For the Mercurius integration, use `MercuriusDriver` and `MercuriusDriverConfig` instead. Both are exported from the `@nestjs/mercurius` package.

The `forRoot()` method takes an options object, which is passed through to the underlying driver instance (see the available settings for [Apollo](https://www.apollographql.com/docs/apollo-server/api/apollo-server) and [Mercurius](https://github.com/mercurius-js/mercurius/blob/master/docs/api/options.md#plugin-options)). For example, to disable the GraphQL IDE, pass the following options:

JS TS

```typescript

import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';
import { ApolloDriver, ApolloDriverConfig } from '@nestjs/apollo';

@Module({
  imports: [
    GraphQLModule.forRoot<ApolloDriverConfig>({
      driver: ApolloDriver,
      graphiql: false,
    }),
  ],
})
export class AppModule {}
```

> **Warning** The `graphql-playground` IDE was removed in `@nestjs/graphql` v14. The `playground` option remains only as a **deprecated boolean alias for GraphiQL**: `playground: false` disables the landing page and `playground: true` enables GraphiQL. Use `graphiql` in new code.

With the Apollo driver, these options are forwarded to the `ApolloServer` constructor.

#### Accessing the request and response objects[#](/graphql/quick-start#accessing-the-request-and-response-objects)

The `context` option is a factory that builds the GraphQL execution context for each request. Use it to expose the underlying request and response objects to your resolvers:

```typescript

GraphQLModule.forRoot<ApolloDriverConfig>({
  driver: ApolloDriver,
  context: ({ req, res }) => ({ req, res }),
}),
```

You can then read them in a resolver with the `@Context()` decorator:

```typescript

@Query(() => String)
userAgent(@Context('req') req: Request): string {
  return req.headers['user-agent'] ?? '';
}
```

> **Hint** Guards, interceptors, and other enhancers running in the GraphQL context can reach the same object via `GqlExecutionContext.create(context).getContext()` (see [Other features](/graphql/other-features)).

#### GraphQL IDE[#](/graphql/quick-start#graphql-ide)

[GraphiQL](https://github.com/graphql/graphiql) is the default graphical, interactive, in-browser GraphQL IDE. It is served on the same URL as the GraphQL server itself, so you need a basic GraphQL server configured and running to access it. To try it now, install and build the [code first sample application](https://github.com/nestjs/nest/tree/master/sample/23-graphql-code-first). If you're following along with these code samples, GraphiQL becomes available once you've completed the steps in the [Resolvers chapter](/graphql/resolvers).

With your application running, open your browser and navigate to `http://localhost:3000/graphql` (host and port may vary depending on your configuration). You will see GraphiQL, as shown below.

> **Note** The `@nestjs/mercurius` integration uses [GraphiQL](https://github.com/graphql/graphiql) as well.

##### Enabling and disabling GraphiQL[#](/graphql/quick-start#enabling-and-disabling-graphiql)

As of `@nestjs/graphql` v14, GraphiQL is the only built-in GraphQL IDE; the older `graphql-playground` has been removed. With the Apollo driver, GraphiQL is enabled automatically whenever `NODE_ENV` is not `production`. In development, it works without any configuration; in production, the landing page is disabled by default.

To control it explicitly, use the `graphiql` option:

```typescript

GraphQLModule.forRoot<ApolloDriverConfig>({
  driver: ApolloDriver,
  graphiql: true, // force it on, including in production
}),
```

```typescript

GraphQLModule.forRoot<ApolloDriverConfig>({
  driver: ApolloDriver,
  graphiql: false, // disable the landing page entirely
}),
```

> **Warning** The `playground` option still exists, but only as a **deprecated boolean alias** for `graphiql`. If both are set, `graphiql` takes precedence. Migrate `playground: false` to `graphiql: false` and `playground: true` to `graphiql: true`.

##### Configuring GraphiQL[#](/graphql/quick-start#configuring-graphiql)

To enable GraphiQL and configure it at the same time, pass an object instead of a boolean:

```typescript

GraphQLModule.forRoot<ApolloDriverConfig>({
  driver: ApolloDriver,
  graphiql: {
    url: '/graphql',
    headers: {
      authorization: 'Bearer <token>',
    },
    shouldPersistHeaders: true,
    isHeadersEditorEnabled: true,
    inputValueDeprecation: false,
  },
}),
```

The available options are:

|                          |                                                                                                                                                                                                           |
| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `url`                    | Endpoint the IDE sends operations to. Defaults to the driver's `path` option, so set it only when the IDE should target a different URL than the one it is served from.                                   |
| `headers`                | Headers applied to every request, e.g., a preconfigured `authorization` header during development. If the headers editor is enabled and the user sets the same header, the user's value takes precedence. |
| `shouldPersistHeaders`   | Whether the contents of the headers editor are persisted in browser storage. Default: `true`.                                                                                                             |
| `isHeadersEditorEnabled` | Whether the headers editor is shown inside the editor tools. Set to `false` to prevent users from editing headers. Default: `true`.                                                                       |
| `inputValueDeprecation`  | If `true`, schema documentation includes deprecated input fields and argument values, and introspection returns them. Default: `false`.                                                                   |

> **Hint** Because GraphiQL is enabled by default outside production, a common setup is to leave the default in place and set `graphiql: false` only for publicly reachable non-production environments where the IDE should not be exposed.

##### Subscriptions in the IDE[#](/graphql/quick-start#subscriptions-in-the-ide)

If your application uses [subscriptions](/graphql/subscriptions), use `graphql-ws`. Support for `subscriptions-transport-ws` has been **removed**: it is no longer accepted as a `subscriptions` key, and the package is no longer a dependency.

```typescript

GraphQLModule.forRoot<ApolloDriverConfig>({
  driver: ApolloDriver,
  subscriptions: {
    'graphql-ws': true,
  },
}),
```

GraphiQL can then execute subscription operations against your server directly.

#### Code first[#](/graphql/quick-start#code-first)

In the **code first** approach, you use decorators and TypeScript classes to generate the corresponding GraphQL schema.

To use the code first approach, start by adding the `autoSchemaFile` property to the options object:

```typescript

GraphQLModule.forRoot<ApolloDriverConfig>({
  driver: ApolloDriver,
  autoSchemaFile: join(process.cwd(), 'src/schema.gql'),
}),
```

The `autoSchemaFile` property value is the path where the automatically generated schema is written. Alternatively, the schema can be generated on the fly in memory. To do so, set the `autoSchemaFile` property to `true`:

```typescript

GraphQLModule.forRoot<ApolloDriverConfig>({
  driver: ApolloDriver,
  autoSchemaFile: true,
}),
```

By default, the types in the generated schema appear in the order they are defined in the included modules. To sort the schema lexicographically, set the `sortSchema` property to `true`:

```typescript

GraphQLModule.forRoot<ApolloDriverConfig>({
  driver: ApolloDriver,
  autoSchemaFile: join(process.cwd(), 'src/schema.gql'),
  sortSchema: true,
}),
```

#### Example[#](/graphql/quick-start#example)

A fully working [code first sample](https://github.com/nestjs/nest/tree/master/sample/23-graphql-code-first) is available in the NestJS repository.

#### Schema first[#](/graphql/quick-start#schema-first)

To use the schema first approach, start by adding a `typePaths` property to the options object. The `typePaths` property tells the `GraphQLModule` where to look for the GraphQL SDL schema definition files you'll write. These files are combined in memory, so you can split your schema into several files and keep them next to their resolvers.

```typescript

GraphQLModule.forRoot<ApolloDriverConfig>({
  driver: ApolloDriver,
  typePaths: ['./**/*.graphql'],
}),
```

You will typically also need TypeScript definitions (classes and interfaces) that correspond to the GraphQL SDL types. Writing them by hand is redundant and tedious, and it leaves you without a single source of truth: every change to the SDL forces you to update the TypeScript definitions as well. To address this, the `@nestjs/graphql` package can **automatically generate** TypeScript definitions from the abstract syntax tree ([AST](https://en.wikipedia.org/wiki/Abstract_syntax_tree)). To enable this feature, add the `definitions` property when configuring the `GraphQLModule`.

```typescript

GraphQLModule.forRoot<ApolloDriverConfig>({
  driver: ApolloDriver,
  typePaths: ['./**/*.graphql'],
  definitions: {
    path: join(process.cwd(), 'src/graphql.ts'),
  },
}),
```

The `path` property of the `definitions` object specifies where to save the generated TypeScript output. By default, all generated TypeScript types are interfaces. To generate classes instead, set the `outputAs` property to `'class'`.

```typescript

GraphQLModule.forRoot<ApolloDriverConfig>({
  driver: ApolloDriver,
  typePaths: ['./**/*.graphql'],
  definitions: {
    path: join(process.cwd(), 'src/graphql.ts'),
    outputAs: 'class',
  },
}),
```

This approach generates the TypeScript definitions each time the application starts. Alternatively, you can write a script that generates them on demand. For example, create the following `generate-typings.ts` script:

```typescript

import { GraphQLDefinitionsFactory } from '@nestjs/graphql';
import { join } from 'node:path';

const definitionsFactory = new GraphQLDefinitionsFactory();
definitionsFactory.generate({
  typePaths: ['./src/**/*.graphql'],
  path: join(process.cwd(), 'src/graphql.ts'),
  outputAs: 'class',
});
```

Now you can run this script on demand:

```bash

$ ts-node generate-typings
```

> **Hint** You can compile the script beforehand (e.g., with `tsc`) and use `node` to execute it.

To enable watch mode for the script (regenerating the typings whenever a `.graphql` file changes), pass the `watch` option to the `generate()` method.

```typescript

definitionsFactory.generate({
  typePaths: ['./src/**/*.graphql'],
  path: join(process.cwd(), 'src/graphql.ts'),
  outputAs: 'class',
  watch: true,
});
```

To generate an additional `__typename` field for every object type, enable the `emitTypenameField` option:

```typescript

definitionsFactory.generate({
  // ...
  emitTypenameField: true,
});
```

To generate resolvers (queries, mutations, subscriptions) as plain fields without arguments, enable the `skipResolverArgs` option:

```typescript

definitionsFactory.generate({
  // ...
  skipResolverArgs: true,
});
```

To generate enums as TypeScript union types instead of regular TypeScript enums, set the `enumsAsTypes` option to `true`:

```typescript

definitionsFactory.generate({
  // ...
  enumsAsTypes: true,
});
```

#### Apollo Sandbox[#](/graphql/quick-start#apollo-sandbox)

To use [Apollo Sandbox](https://www.apollographql.com/blog/announcement/platform/apollo-sandbox-an-open-graphql-ide-for-local-development/) instead of GraphiQL as a GraphQL IDE for local development, use the following configuration:

```typescript

import { ApolloDriver, ApolloDriverConfig } from '@nestjs/apollo';
import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';
import { ApolloServerPluginLandingPageLocalDefault } from '@apollo/server/plugin/landingPage/default';

@Module({
  imports: [
    GraphQLModule.forRoot<ApolloDriverConfig>({
      driver: ApolloDriver,
      graphiql: false,
      plugins: [ApolloServerPluginLandingPageLocalDefault()],
    }),
  ],
})
export class AppModule {}
```

#### Example[#](/graphql/quick-start#example-1)

A fully working [schema first sample](https://github.com/nestjs/nest/tree/master/sample/12-graphql-schema-first) is available in the NestJS repository.

#### Accessing generated schema[#](/graphql/quick-start#accessing-generated-schema)

In some circumstances, you may want a reference to the generated schema object. For example, in end-to-end tests you can then run queries with the `graphql` package directly, without any HTTP listeners.

You can access the generated schema (in either the code first or schema first approach) using the `GraphQLSchemaHost` class:

```typescript

const { schema } = app.get(GraphQLSchemaHost);
```

> **Hint** You must call the `GraphQLSchemaHost#schema` getter after the application has been initialized (after the `onModuleInit` hook has been triggered by either the `app.listen()` or `app.init()` method).

#### Async configuration[#](/graphql/quick-start#async-configuration)

When you need to pass module options asynchronously instead of statically, use the `forRootAsync()` method. As with most dynamic modules, Nest provides several techniques for async configuration.

One technique is to use a factory function:

```typescript

GraphQLModule.forRootAsync<ApolloDriverConfig>({
  driver: ApolloDriver,
  useFactory: () => ({
    typePaths: ['./**/*.graphql'],
  }),
}),
```

Like other [factory providers](/fundamentals/custom-providers#factory-providers-usefactory), the factory function can be async and can inject dependencies through `inject`.

```typescript

GraphQLModule.forRootAsync<ApolloDriverConfig>({
  driver: ApolloDriver,
  imports: [ConfigModule],
  useFactory: async (configService: ConfigService) => ({
    typePaths: configService.get<string[]>('GRAPHQL_TYPE_PATHS'),
  }),
  inject: [ConfigService],
}),
```

Alternatively, you can configure the `GraphQLModule` using a class instead of a factory, as shown below:

```typescript

GraphQLModule.forRootAsync<ApolloDriverConfig>({
  driver: ApolloDriver,
  useClass: GqlConfigService,
}),
```

The construction above instantiates `GqlConfigService` inside `GraphQLModule` and uses it to create the options object. `GqlConfigService` must implement the `GqlOptionsFactory` interface, as shown below. The `GraphQLModule` calls the `createGqlOptions()` method on the instantiated object of the supplied class.

```typescript

@Injectable()
class GqlConfigService implements GqlOptionsFactory {
  createGqlOptions(): ApolloDriverConfig {
    return {
      typePaths: ['./**/*.graphql'],
    };
  }
}
```

To reuse an existing options provider instead of creating a private copy inside the `GraphQLModule`, use the `useExisting` syntax.

```typescript

GraphQLModule.forRootAsync<ApolloDriverConfig>({
  driver: ApolloDriver,
  imports: [ConfigModule],
  useExisting: ConfigService,
}),
```

#### Mercurius integration[#](/graphql/quick-start#mercurius-integration)

Instead of Apollo, [Fastify](/http/performance) users can use the `@nestjs/mercurius` driver.

JS TS

```typescript

import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';
import { MercuriusDriver, MercuriusDriverConfig } from '@nestjs/mercurius';

@Module({
  imports: [
    GraphQLModule.forRoot<MercuriusDriverConfig>({
      driver: MercuriusDriver,
      graphiql: true,
    }),
  ],
})
export class AppModule {}
```

> **Hint** Once the application is running, open your browser and navigate to `http://localhost:3000/graphiql` to see the [GraphiQL IDE](https://github.com/graphql/graphiql).

The `forRoot()` method takes an options object, which is passed through to the underlying driver instance. See the [Mercurius plugin options](https://github.com/mercurius-js/mercurius/blob/master/docs/api/options.md#plugin-options) for the available settings.

#### Multiple endpoints[#](/graphql/quick-start#multiple-endpoints)

The `@nestjs/graphql` module can also serve multiple endpoints at once, and you decide which modules are included in which endpoint. By default, `GraphQLModule` searches for resolvers throughout the whole application. To limit this scan to a subset of modules, use the `include` property.

```typescript

GraphQLModule.forRoot<ApolloDriverConfig>({
  driver: ApolloDriver,
  include: [CatsModule],
}),
```

In the **code first** approach, the `include` option only determines which modules are scanned for resolvers. Types decorated with `@ObjectType()`, `@InputType()`, `@InterfaceType()`, `@ArgsType()`, or registered through `registerEnumType()` / `createUnionType()` still end up in every generated schema. To scope a type to a specific module, use the `registerIn` option:

```typescript

@ObjectType({ registerIn: () => CatsModule })
export class Cat {
  @Field()
  name: string;
}
```

When a schema is built with `include: [CatsModule]`, only types assigned to `CatsModule` become part of it, and types assigned to other modules are left out. Types without `registerIn` keep the default behavior and are available in every schema that references them.

The `registerIn` option is available on `@InputType()`, `@InterfaceType()`, and `@ArgsType()`, as well as `registerEnumType()` and `createUnionType()`:

```typescript

@InputType({ registerIn: () => CatsModule })
export class CreateCatInput {
  @Field()
  name: string;
}

registerEnumType(CatBreed, {
  name: 'CatBreed',
  registerIn: () => CatsModule,
});

export const CatsUnion = createUnionType({
  name: 'CatsUnion',
  types: () => [Lion, Tiger] as const,
  registerIn: () => CatsModule,
});
```

> **Hint** You can pass either the module class itself or a factory function returning it. Prefer the factory form (`() => CatsModule`) whenever the type and the module reference each other: it defers module resolution and avoids errors caused by circular imports.

> **Warning** If you use `@apollo/server` with the `@as-integrations/fastify` package and serve multiple GraphQL endpoints in a single application, enable the `disableHealthCheck` setting in the `GraphQLModule` configuration.

#### Third-party integrations[#](/graphql/quick-start#third-party-integrations)

* [GraphQL Yoga](https://github.com/dotansimha/graphql-yoga)

#### Example[#](/graphql/quick-start#example-2)

A working [Mercurius sample](https://github.com/nestjs/nest/tree/master/sample/33-graphql-mercurius) is available in the NestJS repository.

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/quick-start.md)

----
url: https://docs.nestjs.com/v8/microservices/kafka
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Kafka](https://docs.nestjs.com/v8/microservices/kafka#kafka)
* [Installation](https://docs.nestjs.com/v8/microservices/kafka#installation)
* [Overview](https://docs.nestjs.com/v8/microservices/kafka#overview)
* [Options](https://docs.nestjs.com/v8/microservices/kafka#options)
* [Client](https://docs.nestjs.com/v8/microservices/kafka#client)
* [Message pattern](https://docs.nestjs.com/v8/microservices/kafka#message-pattern)
* [Message response subscription](https://docs.nestjs.com/v8/microservices/kafka#message-response-subscription)
* [Incoming](https://docs.nestjs.com/v8/microservices/kafka#incoming)
* [Outgoing](https://docs.nestjs.com/v8/microservices/kafka#outgoing)
* [Event-based](https://docs.nestjs.com/v8/microservices/kafka#event-based)
* [Context](https://docs.nestjs.com/v8/microservices/kafka#context)
* [Naming conventions](https://docs.nestjs.com/v8/microservices/kafka#naming-conventions)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/microservices/kafka.md "Suggest Edits")

### Kafka

[Kafka](https://kafka.apache.org/) is an open source, distributed streaming platform which has three key capabilities:

* Publish and subscribe to streams of records, similar to a message queue or enterprise messaging system.
* Store streams of records in a fault-tolerant durable way.
* Process streams of records as they occur.

The Kafka project aims to provide a unified, high-throughput, low-latency platform for handling real-time data feeds. It integrates very well with Apache Storm and Spark for real-time streaming data analysis.

#### Installation[#](/microservices/kafka#installation)

To start building Kafka-based microservices, first install the required package:

```bash

$ npm i --save kafkajs
```

#### Overview[#](/microservices/kafka#overview)

Like other Nest microservice transport layer implementations, you select the Kafka transporter mechanism using the `transport` property of the options object passed to the `createMicroservice()` method, along with an optional `options` property, as shown below:

main.ts

JS TS

```typescript

const app = await NestFactory.createMicroservice<MicroserviceOptions>(AppModule, {
  transport: Transport.KAFKA,
  options: {
    client: {
      brokers: ['localhost:9092'],
    }
  }
});
```

```typescript

const app = await NestFactory.createMicroservice(AppModule, {
  transport: Transport.KAFKA,
  options: {
    client: {
      brokers: ['localhost:9092'],
    }
  }
});
```

> **Hint** The `Transport` enum is imported from the `@nestjs/microservices` package.

#### Options[#](/microservices/kafka#options)

The `options` property is specific to the chosen transporter. The **Kafka** transporter exposes the properties described below.

|                    |                                                                                                                 |
| ------------------ | --------------------------------------------------------------------------------------------------------------- |
| `client`           | Client configuration options (read more [here](https://kafka.js.org/docs/configuration))                        |
| `consumer`         | Consumer configuration options (read more [here](https://kafka.js.org/docs/consuming#a-name-options-a-options)) |
| `run`              | Run configuration options (read more [here](https://kafka.js.org/docs/consuming))                               |
| `subscribe`        | Subscribe configuration options (read more [here](https://kafka.js.org/docs/consuming#frombeginning))           |
| `producer`         | Producer configuration options (read more [here](https://kafka.js.org/docs/producing#options))                  |
| `send`             | Send configuration options (read more [here](https://kafka.js.org/docs/producing#options))                      |
| `producerOnlyMode` | **boolean** - Feature flag to skip consumer group registration and only act as a producer                       |

#### Client[#](/microservices/kafka#client)

There is a small difference in Kafka compared to other microservice transporters. Instead of the `ClientProxy` class, we use the `ClientKafka` class.

Like other microservice transporters, you have [several options](https://docs.nestjs.com/microservices/basics#client) for creating a `ClientKafka` instance.

One method for creating an instance is to use the `ClientsModule`. To create a client instance with the `ClientsModule`, import it and use the `register()` method to pass an options object with the same properties shown above in the `createMicroservice()` method, as well as a `name` property to be used as the injection token. Read more about `ClientsModule`[here](https://docs.nestjs.com/microservices/basics#client).

```typescript

@Module({
  imports: [
    ClientsModule.register([
      {
        name: 'HERO_SERVICE',
        transport: Transport.KAFKA,
        options: {
          client: {
            clientId: 'hero',
            brokers: ['localhost:9092'],
          },
          consumer: {
            groupId: 'hero-consumer'
          }
        }
      },
    ]),
  ]
  ...
})
```

Other options to create a client (either `ClientProxyFactory` or `@Client()`) can be used as well. You can read about them [here](https://docs.nestjs.com/microservices/basics#client).

Use the `@Client()` decorator as follows:

```typescript

@Client({
  transport: Transport.KAFKA,
  options: {
    client: {
      clientId: 'hero',
      brokers: ['localhost:9092'],
    },
    consumer: {
      groupId: 'hero-consumer'
    }
  }
})
client: ClientKafka;
```

> **Note** This section is only relevant if you use [request-response](/microservices/basics#request-response) message style (with the `@MessagePattern` decorator and the `ClientKafka#send` method). Subscribing to the response topic is not necessary for the [event-based](/microservices/basics#event-based) communication (`@EventPattern` decorator and `ClientKafka#emit` method).

The `ClientKafka` class provides the `subscribeToResponseOf()` method. The `subscribeToResponseOf()` method takes a request's topic name as an argument and adds the derived reply topic name to a collection of reply topics. This method is required when implementing the message pattern.

heroes.controller.ts

JS TS

```typescript

onModuleInit() {
  this.client.subscribeToResponseOf('hero.kill.dragon');
}
```

If the `ClientKafka` instance is created asynchronously, the `subscribeToResponseOf()` method must be called before calling the `connect()` method.

heroes.controller.ts

JS TS

```typescript

async onModuleInit() {
  this.client.subscribeToResponseOf('hero.kill.dragon');
  await this.client.connect();
}
```

#### Incoming[#](/microservices/kafka#incoming)

Nest receives incoming Kafka messages as an object with `key`, `value`, and `headers` properties that have values of type `Buffer`. Nest then parses these values by transforming the buffers into strings. If the string is "object like", Nest attempts to parse the string as `JSON`. The `value` is then passed to its associated handler.

#### Outgoing[#](/microservices/kafka#outgoing)

Nest sends outgoing Kafka messages after a serialization process when publishing events or sending messages. This occurs on arguments passed to the `ClientKafka``emit()` and `send()` methods or on values returned from a `@MessagePattern` method. This serialization "stringifies" objects that are not strings or buffers by using `JSON.stringify()` or the `toString()` prototype method.

heroes.controller.ts

JS TS

```typescript

@Controller()
export class HeroesController {
  @MessagePattern('hero.kill.dragon')
  killDragon(@Payload() message: KillDragonMessage): any {
    const dragonId = message.dragonId;
    const items = [
      { id: 1, name: 'Mythical Sword' },
      { id: 2, name: 'Key to Dungeon' },
    ];
    return items;
  }
}
```

> **Hint**`@Payload()` is imported from the `@nestjs/microservices`.

Outgoing messages can also be keyed by passing an object with the `key` and `value` properties. Keying messages is important for meeting the [co-partitioning requirement](https://docs.confluent.io/current/ksql/docs/developer-guide/partition-data.html#co-partitioning-requirements).

heroes.controller.ts

JS TS

```typescript

@Controller()
export class HeroesController {
  @MessagePattern('hero.kill.dragon')
  killDragon(@Payload() message: KillDragonMessage): any {
    const realm = 'Nest';
    const heroId = message.heroId;
    const dragonId = message.dragonId;

    const items = [
      { id: 1, name: 'Mythical Sword' },
      { id: 2, name: 'Key to Dungeon' },
    ];

    return {
      headers: {
        realm
      },
      key: heroId,
      value: items
    }
  }
}
```

Additionally, messages passed in this format can also contain custom headers set in the `headers` hash property. Header hash property values must be either of type `string` or type `Buffer`.

heroes.controller.ts

JS TS

```typescript

@Controller()
export class HeroesController {
  @MessagePattern('hero.kill.dragon')
  killDragon(@Payload() message: KillDragonMessage): any {
    const realm = 'Nest';
    const heroId = message.heroId;
    const dragonId = message.dragonId;

    const items = [
      { id: 1, name: 'Mythical Sword' },
      { id: 2, name: 'Key to Dungeon' },
    ];

    return {
      headers: {
        kafka_nestRealm: realm
      },
      key: heroId,
      value: items
    }
  }
}
```

#### Event-based[#](/microservices/kafka#event-based)

While the request-response method is ideal for exchanging messages between services, it is less suitable when your message style is event-based (which in turn is ideal for Kafka) - when you just want to publish events **without waiting for a response**. In that case, you do not want the overhead required by request-response for maintaining two topics.

Check out these two sections to learn more about this: [Overview: Event-based](/microservices/basics#event-based) and [Overview: Publishing events](/microservices/basics#publishing-events).

#### Context[#](/microservices/kafka#context)

In more sophisticated scenarios, you may want to access more information about the incoming request. When using the Kafka transporter, you can access the `KafkaContext` object.

JS TS

```typescript

@MessagePattern('hero.kill.dragon')
killDragon(@Payload() message: KillDragonMessage, @Ctx() context: KafkaContext) {
  console.log(`Topic: ${context.getTopic()}`);
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('hero.kill.dragon')
killDragon(message, context) {
  console.log(`Topic: ${context.getTopic()}`);
}
```

> **Hint**`@Payload()`, `@Ctx()` and `KafkaContext` are imported from the `@nestjs/microservices` package.

To access the original Kafka `IncomingMessage` object, use the `getMessage()` method of the `KafkaContext` object, as follows:

JS TS

```typescript

@MessagePattern('hero.kill.dragon')
killDragon(@Payload() message: KillDragonMessage, @Ctx() context: KafkaContext) {
  const originalMessage = context.getMessage();
  const { headers, partition, timestamp } = originalMessage;
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('hero.kill.dragon')
killDragon(message, context) {
  const originalMessage = context.getMessage();
  const { headers, partition, timestamp } = originalMessage;
}
```

Where the `IncomingMessage` fulfills the following interface:

```typescript

interface IncomingMessage {
  topic: string;
  partition: number;
  timestamp: string;
  size: number;
  attributes: number;
  offset: string;
  key: any;
  value: any;
  headers: Record<string, any>;
}
```

#### Naming conventions[#](/microservices/kafka#naming-conventions)

The Kafka microservice components append a description of their respective role onto the `client.clientId` and `consumer.groupId` options to prevent collisions between Nest microservice client and server components. By default the `ClientKafka` components append `-client` and the `ServerKafka` components append `-server` to both of these options. Note how the provided values below are transformed in that way (as shown in the comments).

main.ts

JS TS

```typescript

const app = await NestFactory.createMicroservice(AppModule, {
  transport: Transport.KAFKA,
  options: {
    client: {
      clientId: 'hero', // hero-server
      brokers: ['localhost:9092'],
    },
    consumer: {
      groupId: 'hero-consumer' // hero-consumer-server
    },
  }
});
```

And for the client:

heroes.controller.ts

JS TS

```typescript

@Client({
  transport: Transport.KAFKA,
  options: {
    client: {
      clientId: 'hero', // hero-client
      brokers: ['localhost:9092'],
    },
    consumer: {
      groupId: 'hero-consumer' // hero-consumer-client
    }
  }
})
client: ClientKafka;
```

> **Hint** Kafka client and consumer naming conventions can be customized by extending `ClientKafka` and `KafkaServer` in your own custom provider and overriding the constructor.

Since the Kafka microservice message pattern utilizes two topics for the request and reply channels, a reply pattern should be derived from the request topic. By default, the name of the reply topic is the composite of the request topic name with `.reply` appended.

heroes.controller.ts

JS TS

```typescript

onModuleInit() {
  this.client.subscribeToResponseOf('hero.get'); // hero.get.reply
}
```

> **Hint** Kafka reply topic naming conventions can be customized by extending `ClientKafka` in your own custom provider and overriding the `getResponsePatternName` method.

----
url: https://docs.nestjs.com/v9/graphql/subscriptions
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Subscriptions](https://docs.nestjs.com/v9/graphql/subscriptions#subscriptions)
* [Enable subscriptions with Apollo driver](https://docs.nestjs.com/v9/graphql/subscriptions#enable-subscriptions-with-apollo-driver)
* [Code first](https://docs.nestjs.com/v9/graphql/subscriptions#code-first)
* [Publishing](https://docs.nestjs.com/v9/graphql/subscriptions#publishing)
* [Filtering subscriptions](https://docs.nestjs.com/v9/graphql/subscriptions#filtering-subscriptions)
* [Mutating subscription payloads](https://docs.nestjs.com/v9/graphql/subscriptions#mutating-subscription-payloads)
* [Schema first](https://docs.nestjs.com/v9/graphql/subscriptions#schema-first)
* [PubSub](https://docs.nestjs.com/v9/graphql/subscriptions#pubsub)
* [Customize subscriptions server](https://docs.nestjs.com/v9/graphql/subscriptions#customize-subscriptions-server)
* [Authentication over WebSockets](https://docs.nestjs.com/v9/graphql/subscriptions#authentication-over-websockets)
* [Enable subscriptions with Mercurius driver](https://docs.nestjs.com/v9/graphql/subscriptions#enable-subscriptions-with-mercurius-driver)
* [Code first](https://docs.nestjs.com/v9/graphql/subscriptions#code-first-1)
* [Publishing](https://docs.nestjs.com/v9/graphql/subscriptions#publishing-1)
* [Filtering subscriptions](https://docs.nestjs.com/v9/graphql/subscriptions#filtering-subscriptions-1)
* [Schema first](https://docs.nestjs.com/v9/graphql/subscriptions#schema-first-1)
* [PubSub](https://docs.nestjs.com/v9/graphql/subscriptions#pubsub-1)
* [Authentication over WebSockets](https://docs.nestjs.com/v9/graphql/subscriptions#authentication-over-websockets-1)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/subscriptions.md "Suggest Edits")

### Subscriptions

In addition to fetching data using queries and modifying data using mutations, the GraphQL spec supports a third operation type, called `subscription`. GraphQL subscriptions are a way to push data from the server to the clients that choose to listen to real time messages from the server. Subscriptions are similar to queries in that they specify a set of fields to be delivered to the client, but instead of immediately returning a single answer, a channel is opened and a result is sent to the client every time a particular event happens on the server.

A common use case for subscriptions is notifying the client side about particular events, for example the creation of a new object, updated fields and so on (read more [here](https://www.apollographql.com/docs/react/data/subscriptions)).

#### Enable subscriptions with Apollo driver[#](/graphql/subscriptions#enable-subscriptions-with-apollo-driver)

To enable subscriptions, set the `installSubscriptionHandlers` property to `true`.

```typescript

GraphQLModule.forRoot<ApolloDriverConfig>({
  driver: ApolloDriver,
  installSubscriptionHandlers: true,
}),
```

> **Warning** The `installSubscriptionHandlers` configuration option has been removed from the latest version of Apollo server and will be soon deprecated in this package as well. By default, `installSubscriptionHandlers` will fallback to use the `subscriptions-transport-ws` ([read more](https://github.com/apollographql/subscriptions-transport-ws)) but we strongly recommend using the `graphql-ws`([read more](https://github.com/enisdenjo/graphql-ws)) library instead.

To switch to use the `graphql-ws` package instead, use the following configuration:

```typescript

GraphQLModule.forRoot<ApolloDriverConfig>({
  driver: ApolloDriver,
  subscriptions: {
    'graphql-ws': true
  },
}),
```

> **Hint** You can also use both packages (`subscriptions-transport-ws` and `graphql-ws`) at the same time, for example, for backward compatibility.

#### Code first[#](/graphql/subscriptions#code-first)

To create a subscription using the code first approach, we use the `@Subscription()` decorator (exported from the `@nestjs/graphql` package) and the `PubSub` class from the `graphql-subscriptions` package, which provides a simple **publish/subscribe API**.

The following subscription handler takes care of **subscribing** to an event by calling `PubSub#asyncIterator`. This method takes a single argument, the `triggerName`, which corresponds to an event topic name.

```typescript

const pubSub = new PubSub();

@Resolver((of) => Author)
export class AuthorResolver {
  // ...
  @Subscription((returns) => Comment)
  commentAdded() {
    return pubSub.asyncIterator('commentAdded');
  }
}
```

> **Hint** All decorators are exported from the `@nestjs/graphql` package, while the `PubSub` class is exported from the `graphql-subscriptions` package.

> **Note**`PubSub` is a class that exposes a simple `publish` and `subscribe API`. Read more about it [here](https://www.apollographql.com/docs/graphql-subscriptions/setup.html). Note that the Apollo docs warn that the default implementation is not suitable for production (read more [here](https://github.com/apollographql/graphql-subscriptions#getting-started-with-your-first-subscription)). Production apps should use a `PubSub` implementation backed by an external store (read more [here](https://github.com/apollographql/graphql-subscriptions#pubsub-implementations)).

This will result in generating the following part of the GraphQL schema in SDL:

```graphql

type Subscription {
  commentAdded(): Comment!
}
```

Note that subscriptions, by definition, return an object with a single top level property whose key is the name of the subscription. This name is either inherited from the name of the subscription handler method (i.e., `commentAdded` above), or is provided explicitly by passing an option with the key `name` as the second argument to the `@Subscription()` decorator, as shown below.

```typescript

@Subscription(returns => Comment, {
  name: 'commentAdded',
})
subscribeToCommentAdded() {
  return pubSub.asyncIterator('commentAdded');
}
```

This construct produces the same SDL as the previous code sample, but allows us to decouple the method name from the subscription.

#### Publishing[#](/graphql/subscriptions#publishing)

Now, to publish the event, we use the `PubSub#publish` method. This is often used within a mutation to trigger a client-side update when a part of the object graph has changed. For example:

posts/posts.resolver.ts

JS TS

```typescript

@Mutation(returns => Post)
async addComment(
  @Args('postId', { type: () => Int }) postId: number,
  @Args('comment', { type: () => Comment }) comment: CommentInput,
) {
  const newComment = this.commentsService.addComment({ id: postId, comment });
  pubSub.publish('commentAdded', { commentAdded: newComment });
  return newComment;
}
```

The `PubSub#publish` method takes a `triggerName` (again, think of this as an event topic name) as the first parameter, and an event payload as the second parameter. As mentioned, the subscription, by definition, returns a value and that value has a shape. Look again at the generated SDL for our `commentAdded` subscription:

```graphql

type Subscription {
  commentAdded(): Comment!
}
```

This tells us that the subscription must return an object with a top-level property name of `commentAdded` that has a value which is a `Comment` object. The important point to note is that the shape of the event payload emitted by the `PubSub#publish` method must correspond to the shape of the value expected to return from the subscription. So, in our example above, the `pubSub.publish('commentAdded', { commentAdded: newComment })` statement publishes a `commentAdded` event with the appropriately shaped payload. If these shapes don't match, your subscription will fail during the GraphQL validation phase.

#### Filtering subscriptions[#](/graphql/subscriptions#filtering-subscriptions)

To filter out specific events, set the `filter` property to a filter function. This function acts similar to the function passed to an array `filter`. It takes two arguments: `payload` containing the event payload (as sent by the event publisher), and `variables` taking any arguments passed in during the subscription request. It returns a boolean determining whether this event should be published to client listeners.

```typescript

@Subscription(returns => Comment, {
  filter: (payload, variables) =>
    payload.commentAdded.title === variables.title,
})
commentAdded(@Args('title') title: string) {
  return pubSub.asyncIterator('commentAdded');
}
```

#### Mutating subscription payloads[#](/graphql/subscriptions#mutating-subscription-payloads)

To mutate the published event payload, set the `resolve` property to a function. The function receives the event payload (as sent by the event publisher) and returns the appropriate value.

```typescript

@Subscription(returns => Comment, {
  resolve: value => value,
})
commentAdded() {
  return pubSub.asyncIterator('commentAdded');
}
```

> **Note** If you use the `resolve` option, you should return the unwrapped payload (e.g., with our example, return a `newComment` object directly, not a `{ commentAdded: newComment }` object).

If you need to access injected providers (e.g., use an external service to validate the data), use the following construction.

```typescript

@Subscription(returns => Comment, {
  resolve(this: AuthorResolver, value) {
    // "this" refers to an instance of "AuthorResolver"
    return value;
  }
})
commentAdded() {
  return pubSub.asyncIterator('commentAdded');
}
```

The same construction works with filters:

```typescript

@Subscription(returns => Comment, {
  filter(this: AuthorResolver, payload, variables) {
    // "this" refers to an instance of "AuthorResolver"
    return payload.commentAdded.title === variables.title;
  }
})
commentAdded() {
  return pubSub.asyncIterator('commentAdded');
}
```

#### Schema first[#](/graphql/subscriptions#schema-first)

To create an equivalent subscription in Nest, we'll make use of the `@Subscription()` decorator.

```typescript

const pubSub = new PubSub();

@Resolver('Author')
export class AuthorResolver {
  // ...
  @Subscription()
  commentAdded() {
    return pubSub.asyncIterator('commentAdded');
  }
}
```

To filter out specific events based on context and arguments, set the `filter` property.

```typescript

@Subscription('commentAdded', {
  filter: (payload, variables) =>
    payload.commentAdded.title === variables.title,
})
commentAdded() {
  return pubSub.asyncIterator('commentAdded');
}
```

To mutate the published payload, we can use a `resolve` function.

```typescript

@Subscription('commentAdded', {
  resolve: value => value,
})
commentAdded() {
  return pubSub.asyncIterator('commentAdded');
}
```

If you need to access injected providers (e.g., use an external service to validate the data), use the following construction:

```typescript

@Subscription('commentAdded', {
  resolve(this: AuthorResolver, value) {
    // "this" refers to an instance of "AuthorResolver"
    return value;
  }
})
commentAdded() {
  return pubSub.asyncIterator('commentAdded');
}
```

The same construction works with filters:

```typescript

@Subscription('commentAdded', {
  filter(this: AuthorResolver, payload, variables) {
    // "this" refers to an instance of "AuthorResolver"
    return payload.commentAdded.title === variables.title;
  }
})
commentAdded() {
  return pubSub.asyncIterator('commentAdded');
}
```

The last step is to update the type definitions file.

```graphql

type Author {
  id: Int!
  firstName: String
  lastName: String
  posts: [Post]
}

type Post {
  id: Int!
  title: String
  votes: Int
}

type Query {
  author(id: Int!): Author
}

type Comment {
  id: String
  content: String
}

type Subscription {
  commentAdded(title: String!): Comment
}
```

With this, we've created a single `commentAdded(title: String!): Comment` subscription. You can find a full sample implementation [here](https://github.com/nestjs/nest/blob/master/sample/12-graphql-schema-first).

#### PubSub[#](/graphql/subscriptions#pubsub)

We instantiated a local `PubSub` instance above. The preferred approach is to define `PubSub` as a [provider](/v9/fundamentals/custom-providers) and inject it through the constructor (using the `@Inject()` decorator). This allows us to re-use the instance across the whole application. For example, define a provider as follows, then inject `'PUB_SUB'` where needed.

```typescript

{
  provide: 'PUB_SUB',
  useValue: new PubSub(),
}
```

#### Customize subscriptions server[#](/graphql/subscriptions#customize-subscriptions-server)

To customize the subscriptions server (e.g., change the path), use the `subscriptions` options property.

```typescript

GraphQLModule.forRoot<ApolloDriverConfig>({
  driver: ApolloDriver,
  subscriptions: {
    'subscriptions-transport-ws': {
      path: '/graphql'
    },
  }
}),
```

If you're using the `graphql-ws` package for subscriptions, replace the `subscriptions-transport-ws` key with `graphql-ws`, as follows:

```typescript

GraphQLModule.forRoot<ApolloDriverConfig>({
  driver: ApolloDriver,
  subscriptions: {
    'graphql-ws': {
      path: '/graphql'
    },
  }
}),
```

#### Authentication over WebSockets[#](/graphql/subscriptions#authentication-over-websockets)

Checking whether the user is authenticated can be done inside the `onConnect` callback function that you can specify in the `subscriptions` options.

The `onConnect` will receive as a first argument the `connectionParams` passed to the `SubscriptionClient` (read [more](https://www.apollographql.com/docs/react/data/subscriptions/#5-authenticate-over-websocket-optional)).

```typescript

GraphQLModule.forRoot<ApolloDriverConfig>({
  driver: ApolloDriver,
  subscriptions: {
    'subscriptions-transport-ws': {
      onConnect: (connectionParams) => {
        const authToken = connectionParams.authToken;
        if (!isValid(authToken)) {
          throw new Error('Token is not valid');
        }
        // extract user information from token
        const user = parseToken(authToken);
        // return user info to add them to the context later
        return { user };
      },
    }
  },
  context: ({ connection }) => {
    // connection.context will be equal to what was returned by the "onConnect" callback
  },
}),
```

The `authToken` in this example is only sent once by the client, when the connection is first established. All subscriptions made with this connection will have the same `authToken`, and thus the same user info.

> **Note** There is a bug in `subscriptions-transport-ws` that allows connections to skip the `onConnect` phase (read [more](https://github.com/apollographql/subscriptions-transport-ws/issues/349)). You should not assume that `onConnect` was called when the user starts a subscription, and always check that the `context` is populated.

If you're using the `graphql-ws` package, the signature of the `onConnect` callback will be slightly different:

```typescript

GraphQLModule.forRoot<ApolloDriverConfig>({
  driver: ApolloDriver,
  subscriptions: {
    'graphql-ws': {
      onConnect: (context: Context<any>) => {
        const { connectionParams, extra } = context;
        // user validation will remain the same as in the example above
        // when using with graphql-ws, additional context value should be stored in the extra field
        extra.user = { user: {} };
      },
    },
  },
  context: ({ extra }) => {
    // you can now access your additional context value through the extra field
  },
});
```

#### Enable subscriptions with Mercurius driver[#](/graphql/subscriptions#enable-subscriptions-with-mercurius-driver)

To enable subscriptions, set the `subscription` property to `true`.

```typescript

GraphQLModule.forRoot<MercuriusDriverConfig>({
  driver: MercuriusDriver,
  subscription: true,
}),
```

> **Hint** You can also pass the options object to set up a custom emitter, validate incoming connections, etc. Read more [here](https://github.com/mercurius-js/mercurius/blob/master/docs/api/options.md#plugin-options) (see `subscription`).

#### Code first[#](/graphql/subscriptions#code-first-1)

To create a subscription using the code first approach, we use the `@Subscription()` decorator (exported from the `@nestjs/graphql` package) and the `PubSub` class from the `mercurius` package, which provides a simple **publish/subscribe API**.

The following subscription handler takes care of **subscribing** to an event by calling `PubSub#asyncIterator`. This method takes a single argument, the `triggerName`, which corresponds to an event topic name.

```typescript

@Resolver((of) => Author)
export class AuthorResolver {
  // ...
  @Subscription((returns) => Comment)
  commentAdded(@Context('pubsub') pubSub: PubSub) {
    return pubSub.subscribe('commentAdded');
  }
}
```

> **Hint** All decorators used in the example above are exported from the `@nestjs/graphql` package, while the `PubSub` class is exported from the `mercurius` package.

> **Note**`PubSub` is a class that exposes a simple `publish` and `subscribe` API. Check out [this section](https://github.com/mercurius-js/mercurius/blob/master/docs/subscriptions.md#subscriptions-with-custom-pubsub) on how to register a custom `PubSub` class.

This will result in generating the following part of the GraphQL schema in SDL:

```graphql

type Subscription {
  commentAdded(): Comment!
}
```

Note that subscriptions, by definition, return an object with a single top level property whose key is the name of the subscription. This name is either inherited from the name of the subscription handler method (i.e., `commentAdded` above), or is provided explicitly by passing an option with the key `name` as the second argument to the `@Subscription()` decorator, as shown below.

```typescript

@Subscription(returns => Comment, {
  name: 'commentAdded',
})
subscribeToCommentAdded(@Context('pubsub') pubSub: PubSub) {
  return pubSub.subscribe('commentAdded');
}
```

This construct produces the same SDL as the previous code sample, but allows us to decouple the method name from the subscription.

#### Publishing[#](/graphql/subscriptions#publishing-1)

Now, to publish the event, we use the `PubSub#publish` method. This is often used within a mutation to trigger a client-side update when a part of the object graph has changed. For example:

posts/posts.resolver.ts

JS TS

```typescript

@Mutation(returns => Post)
async addComment(
  @Args('postId', { type: () => Int }) postId: number,
  @Args('comment', { type: () => Comment }) comment: CommentInput,
  @Context('pubsub') pubSub: PubSub,
) {
  const newComment = this.commentsService.addComment({ id: postId, comment });
  await pubSub.publish({
    topic: 'commentAdded',
    payload: {
      commentAdded: newComment
    }
  });
  return newComment;
}
```

As mentioned, the subscription, by definition, returns a value and that value has a shape. Look again at the generated SDL for our `commentAdded` subscription:

```graphql

type Subscription {
  commentAdded(): Comment!
}
```

This tells us that the subscription must return an object with a top-level property name of `commentAdded` that has a value which is a `Comment` object. The important point to note is that the shape of the event payload emitted by the `PubSub#publish` method must correspond to the shape of the value expected to return from the subscription. So, in our example above, the `pubSub.publish({ topic: 'commentAdded', payload: { commentAdded: newComment } })` statement publishes a `commentAdded` event with the appropriately shaped payload. If these shapes don't match, your subscription will fail during the GraphQL validation phase.

#### Filtering subscriptions[#](/graphql/subscriptions#filtering-subscriptions-1)

To filter out specific events, set the `filter` property to a filter function. This function acts similar to the function passed to an array `filter`. It takes two arguments: `payload` containing the event payload (as sent by the event publisher), and `variables` taking any arguments passed in during the subscription request. It returns a boolean determining whether this event should be published to client listeners.

```typescript

@Subscription(returns => Comment, {
  filter: (payload, variables) =>
    payload.commentAdded.title === variables.title,
})
commentAdded(@Args('title') title: string, @Context('pubsub') pubSub: PubSub) {
  return pubSub.subscribe('commentAdded');
}
```

If you need to access injected providers (e.g., use an external service to validate the data), use the following construction.

```typescript

@Subscription(returns => Comment, {
  filter(this: AuthorResolver, payload, variables) {
    // "this" refers to an instance of "AuthorResolver"
    return payload.commentAdded.title === variables.title;
  }
})
commentAdded(@Args('title') title: string, @Context('pubsub') pubSub: PubSub) {
  return pubSub.subscribe('commentAdded');
}
```

#### Schema first[#](/graphql/subscriptions#schema-first-1)

To create an equivalent subscription in Nest, we'll make use of the `@Subscription()` decorator.

```typescript

const pubSub = new PubSub();

@Resolver('Author')
export class AuthorResolver {
  // ...
  @Subscription()
  commentAdded(@Context('pubsub') pubSub: PubSub) {
    return pubSub.subscribe('commentAdded');
  }
}
```

To filter out specific events based on context and arguments, set the `filter` property.

```typescript

@Subscription('commentAdded', {
  filter: (payload, variables) =>
    payload.commentAdded.title === variables.title,
})
commentAdded(@Context('pubsub') pubSub: PubSub) {
  return pubSub.subscribe('commentAdded');
}
```

If you need to access injected providers (e.g., use an external service to validate the data), use the following construction:

```typescript

@Subscription('commentAdded', {
  filter(this: AuthorResolver, payload, variables) {
    // "this" refers to an instance of "AuthorResolver"
    return payload.commentAdded.title === variables.title;
  }
})
commentAdded(@Context('pubsub') pubSub: PubSub) {
  return pubSub.subscribe('commentAdded');
}
```

The last step is to update the type definitions file.

```graphql

type Author {
  id: Int!
  firstName: String
  lastName: String
  posts: [Post]
}

type Post {
  id: Int!
  title: String
  votes: Int
}

type Query {
  author(id: Int!): Author
}

type Comment {
  id: String
  content: String
}

type Subscription {
  commentAdded(title: String!): Comment
}
```

With this, we've created a single `commentAdded(title: String!): Comment` subscription.

#### PubSub[#](/graphql/subscriptions#pubsub-1)

In the examples above, we used the default `PubSub` emitter ([mqemitter](https://github.com/mcollina/mqemitter)) The preferred approach (for production) is to use `mqemitter-redis`. Alternatively, a custom `PubSub` implementation can be provided (read more [here](https://github.com/mercurius-js/mercurius/blob/master/docs/subscriptions.md))

```typescript

GraphQLModule.forRoot<MercuriusDriverConfig>({
  driver: MercuriusDriver,
  subscription: {
    emitter: require('mqemitter-redis')({
      port: 6579,
      host: '127.0.0.1',
    }),
  },
});
```

#### Authentication over WebSockets[#](/graphql/subscriptions#authentication-over-websockets-1)

Checking whether the user is authenticated can be done inside the `verifyClient` callback function that you can specify in the `subscription` options.

The `verifyClient` will receive the `info` object as a first argument which you can use to retrieve the request's headers.

```typescript

GraphQLModule.forRoot<MercuriusDriverConfig>({
  driver: MercuriusDriver,
  subscription: {
    verifyClient: (info, next) => {
      const authorization = info.req.headers?.authorization as string;
      if (!authorization?.startsWith('Bearer ')) {
        return next(false);
      }
      next(true);
    },
  }
}),
```

----
url: https://docs.nestjs.com/v8/recipes/sql-typeorm
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [SQL (TypeORM)](https://docs.nestjs.com/v8/recipes/sql-typeorm#sql-typeorm)
* [Getting started](https://docs.nestjs.com/v8/recipes/sql-typeorm#getting-started)
* [Repository pattern](https://docs.nestjs.com/v8/recipes/sql-typeorm#repository-pattern)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/recipes/sql-typeorm.md "Suggest Edits")

### SQL (TypeORM)

##### This chapter applies only to TypeScript

> **Warning** In this article, you'll learn how to create a `DatabaseModule` based on the **TypeORM** package from scratch using custom providers mechanism. As a consequence, this solution contains a lot of overhead that you can omit using ready to use and available out-of-the-box dedicated `@nestjs/typeorm` package. To learn more, see [here](/v8/techniques/sql).

[TypeORM](https://github.com/typeorm/typeorm) is definitely the most mature Object Relational Mapper (ORM) available in the node.js world. Since it's written in TypeScript, it works pretty well with the Nest framework.

#### Getting started[#](/recipes/sql-typeorm#getting-started)

To start the adventure with this library we have to install all required dependencies:

```bash

$ npm install --save typeorm mysql2
```

The first step we need to do is to establish the connection with our database using `createConnection()` function imported from the `typeorm` package. The `createConnection()` function returns a `Promise`, and therefore we have to create an [async provider](/v8/fundamentals/async-components).

database.providers.ts

JS TS

```typescript

import { DataSource } from 'typeorm';

export const databaseProviders = [
  {
    provide: 'DATA_SOURCE',
    useFactory: async () => {
      const dataSource = new DataSource({
        type: 'mysql',
        host: 'localhost',
        port: 3306,
        username: 'root',
        password: 'root',
        database: 'test',
        entities: [
            __dirname + '/../**/*.entity{.ts,.js}',
        ],
        synchronize: true,
      });

      return dataSource.initialize();
    },
  },
];
```

> **Warning** Setting `synchronize: true` shouldn't be used in production - otherwise you can lose production data.

> **Hint** Following best practices, we declared the custom provider in the separated file which has a `*.providers.ts` suffix.

Then, we need to export these providers to make them **accessible** for the rest of the application.

database.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { databaseProviders } from './database.providers';

@Module({
  providers: [...databaseProviders],
  exports: [...databaseProviders],
})
export class DatabaseModule {}
```

Now we can inject the `Connection` object using `@Inject()` decorator. Each class that would depend on the `Connection` async provider will wait until a `Promise` is resolved.

#### Repository pattern[#](/recipes/sql-typeorm#repository-pattern)

The [TypeORM](https://github.com/typeorm/typeorm) supports the repository design pattern, thus each entity has its own Repository. These repositories can be obtained from the database connection.

But firstly, we need at least one entity. We are going to reuse the `Photo` entity from the official documentation.

photo.entity.ts

JS TS

```typescript

import { Entity, Column, PrimaryGeneratedColumn } from 'typeorm';

@Entity()
export class Photo {
  @PrimaryGeneratedColumn()
  id: number;

  @Column({ length: 500 })
  name: string;

  @Column('text')
  description: string;

  @Column()
  filename: string;

  @Column('int')
  views: number;

  @Column()
  isPublished: boolean;
}
```

The `Photo` entity belongs to the `photo` directory. This directory represents the `PhotoModule`. Now, let's create a **Repository** provider:

photo.providers.ts

JS TS

```typescript

import { DataSource } from 'typeorm';
import { Photo } from './photo.entity';

export const photoProviders = [
  {
    provide: 'PHOTO_REPOSITORY',
    useFactory: (dataSource: DataSource) => dataSource.getRepository(Photo),
    inject: ['DATA_SOURCE'],
  },
];
```

> **Warning** In the real-world applications you should avoid **magic strings**. Both `PHOTO_REPOSITORY` and `DATABASE_CONNECTION` should be kept in the separated `constants.ts` file.

Now we can inject the `Repository<Photo>` to the `PhotoService` using the `@Inject()` decorator:

photo.service.ts

JS TS

```typescript

import { Injectable, Inject } from '@nestjs/common';
import { Repository } from 'typeorm';
import { Photo } from './photo.entity';

@Injectable()
export class PhotoService {
  constructor(
    @Inject('PHOTO_REPOSITORY')
    private photoRepository: Repository<Photo>,
  ) {}

  async findAll(): Promise<Photo[]> {
    return this.photoRepository.find();
  }
}
```

The database connection is **asynchronous**, but Nest makes this process completely invisible for the end-user. The `PhotoRepository` is waiting for the db connection, and the `PhotoService` is delayed until repository is ready to use. The entire application can start when each class is instantiated.

Here is a final `PhotoModule`:

photo.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { DatabaseModule } from '../database/database.module';
import { photoProviders } from './photo.providers';
import { PhotoService } from './photo.service';

@Module({
  imports: [DatabaseModule],
  providers: [
    ...photoProviders,
    PhotoService,
  ],
})
export class PhotoModule {}
```

> **Hint** Do not forget to import the `PhotoModule` into the root `AppModule`.

----
url: https://docs.nestjs.com/v7/techniques/database
----

* [Database](https://docs.nestjs.com/v7/techniques/database#database)
* [TypeORM Integration](https://docs.nestjs.com/v7/techniques/database#typeorm-integration)
* [Repository pattern](https://docs.nestjs.com/v7/techniques/database#repository-pattern)
* [Relations](https://docs.nestjs.com/v7/techniques/database#relations)
* [Auto-load entities](https://docs.nestjs.com/v7/techniques/database#auto-load-entities)
* [Separating entity definition](https://docs.nestjs.com/v7/techniques/database#separating-entity-definition)
* [Transactions](https://docs.nestjs.com/v7/techniques/database#transactions)
* [Subscribers](https://docs.nestjs.com/v7/techniques/database#subscribers)
* [Migrations](https://docs.nestjs.com/v7/techniques/database#migrations)
* [Multiple databases](https://docs.nestjs.com/v7/techniques/database#multiple-databases)
* [Testing](https://docs.nestjs.com/v7/techniques/database#testing)
* [Custom repository](https://docs.nestjs.com/v7/techniques/database#custom-repository)
* [Async configuration](https://docs.nestjs.com/v7/techniques/database#async-configuration)
* [Example](https://docs.nestjs.com/v7/techniques/database#example)
* [Sequelize Integration](https://docs.nestjs.com/v7/techniques/database#sequelize-integration)
* [Models](https://docs.nestjs.com/v7/techniques/database#models)
* [Relations](https://docs.nestjs.com/v7/techniques/database#relations-1)
* [Auto-load models](https://docs.nestjs.com/v7/techniques/database#auto-load-models)
* [Transactions](https://docs.nestjs.com/v7/techniques/database#transactions-1)
* [Migrations](https://docs.nestjs.com/v7/techniques/database#migrations-1)
* [Multiple databases](https://docs.nestjs.com/v7/techniques/database#multiple-databases-1)
* [Testing](https://docs.nestjs.com/v7/techniques/database#testing-1)
* [Async configuration](https://docs.nestjs.com/v7/techniques/database#async-configuration-1)
* [Example](https://docs.nestjs.com/v7/techniques/database#example-1)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/techniques/sql.md "Suggest Edits")

### Database

Nest is database agnostic, allowing you to easily integrate with any SQL or NoSQL database. You have a number of options available to you, depending on your preferences. At the most general level, connecting Nest to a database is simply a matter of loading an appropriate Node.js driver for the database, just as you would with [Express](https://expressjs.com/en/guide/database-integration.html) or Fastify.

You can also directly use any general purpose Node.js database integration **library** or ORM, such as [Sequelize](https://sequelize.org/) (navigate to the [Sequelize integration](/techniques/database#sequelize-integration) section), [Knex.js](https://knexjs.org/) ([tutorial](https://dev.to/nestjs/build-a-nestjs-module-for-knex-js-or-other-resource-based-libraries-in-5-minutes-12an)), [TypeORM](https://github.com/typeorm/typeorm), and [Prisma](https://www.github.com/prisma/prisma) ([recipe](/v7/recipes/prisma)) , to operate at a higher level of abstraction.

For convenience, Nest provides tight integration with TypeORM and Sequelize out-of-the-box with the `@nestjs/typeorm` and `@nestjs/sequelize` packages respectively, which we'll cover in the current chapter, and Mongoose with `@nestjs/mongoose`, which is covered in [this chapter](/v7/techniques/mongodb). These integrations provide additional NestJS-specific features, such as model/repository injection, testability, and asynchronous configuration to make accessing your chosen database even easier.

### TypeORM Integration

For integrating with SQL and NoSQL databases, Nest provides the `@nestjs/typeorm` package. Nest uses [TypeORM](https://github.com/typeorm/typeorm) because it's the most mature Object Relational Mapper (ORM) available for TypeScript. Since it's written in TypeScript, it integrates well with the Nest framework.

To begin using it, we first install the required dependencies. In this chapter, we'll demonstrate using the popular [MySQL](https://www.mysql.com/) Relational DBMS, but TypeORM provides support for many relational databases, such as PostgreSQL, Oracle, Microsoft SQL Server, SQLite, and even NoSQL databases like MongoDB. The procedure we walk through in this chapter will be the same for any database supported by TypeORM. You'll simply need to install the associated client API libraries for your selected database.

```bash

$ npm install --save @nestjs/typeorm typeorm mysql2
```

Once the installation process is complete, we can import the `TypeOrmModule` into the root `AppModule`.

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';

@Module({
  imports: [
    TypeOrmModule.forRoot({
      type: 'mysql',
      host: 'localhost',
      port: 3306,
      username: 'root',
      password: 'root',
      database: 'test',
      entities: [],
      synchronize: true,
    }),
  ],
})
export class AppModule {}
```

> **Warning** Setting `synchronize: true` shouldn't be used in production - otherwise you can lose production data.

The `forRoot()` method supports all the configuration properties exposed by the `createConnection()` function from the [TypeORM](https://typeorm.io/#/connection-options) package. In addition, there are several extra configuration properties described below.

|                       |                                                                                     |
| --------------------- | ----------------------------------------------------------------------------------- |
| `retryAttempts`       | Number of attempts to connect to the database (default: `10`)                       |
| `retryDelay`          | Delay between connection retry attempts (ms) (default: `3000`)                      |
| `autoLoadEntities`    | If `true`, entities will be loaded automatically (default: `false`)                 |
| `keepConnectionAlive` | If `true`, connection will not be closed on application shutdown (default: `false`) |

> **Hint** Learn more about the connection options [here](https://typeorm.io/#/connection-options).

Alternatively, rather than passing a configuration object to `forRoot()`, we can create an `ormconfig.json` file in the project root directory.

```json

{
  "type": "mysql",
  "host": "localhost",
  "port": 3306,
  "username": "root",
  "password": "root",
  "database": "test",
  "entities": ["dist/**/*.entity{.ts,.js}"],
  "synchronize": true
}
```

Then, we can call `forRoot()` without any options:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';

@Module({
  imports: [TypeOrmModule.forRoot()],
})
export class AppModule {}
```

> **Warning** Static glob paths (e.g., `dist/**/*.entity{ .ts,.js}`) won't work properly with [webpack](https://webpack.js.org/).

> **Hint** Note that the `ormconfig.json` file is loaded by the `typeorm` library. Thus, any of the extra properties described above (which are supported internally by way of the `forRoot()` method - for example, `autoLoadEntities` and `retryDelay`) won't be applied. Luckily, TypeORM provides the [`getConnectionOptions`](https://typeorm.io/#/using-ormconfig/overriding-options-defined-in-ormconfig) function that reads connection options from the `ormconfig` file or environment variables. With this, you can still use the configuration file and set Nest-specific options, as follows:
>
> ```typescript
>
> TypeOrmModule.forRootAsync({
>   useFactory: async () =>
>     Object.assign(await getConnectionOptions(), {
>       autoLoadEntities: true,
>     }),
> })
> ```

Once this is done, the TypeORM `Connection` and `EntityManager` objects will be available to inject across the entire project (without needing to import any modules), for example:

app.module.ts

JS TS

```typescript

import { Connection } from 'typeorm';

@Module({
  imports: [TypeOrmModule.forRoot(), UsersModule],
})
export class AppModule {
  constructor(private connection: Connection) {}
}
```

```typescript

import { Connection } from 'typeorm';

@Dependencies(Connection)
@Module({
  imports: [TypeOrmModule.forRoot(), UsersModule],
})
export class AppModule {
  constructor(connection) {
    this.connection = connection;
  }
}
```

#### Repository pattern[#](/techniques/database#repository-pattern)

[TypeORM](https://github.com/typeorm/typeorm) supports the **repository design pattern**, so each entity has its own repository. These repositories can be obtained from the database connection.

To continue the example, we need at least one entity. Let's define the `User` entity.

user.entity.ts

JS TS

```typescript

import { Entity, Column, PrimaryGeneratedColumn } from 'typeorm';

@Entity()
export class User {
  @PrimaryGeneratedColumn()
  id: number;

  @Column()
  firstName: string;

  @Column()
  lastName: string;

  @Column({ default: true })
  isActive: boolean;
}
```

> **Hint** Learn more about entities in the [TypeORM documentation](https://typeorm.io/#/entities).

The `User` entity file sits in the `users` directory. This directory contains all files related to the `UsersModule`. You can decide where to keep your model files, however, we recommend creating them near their **domain**, in the corresponding module directory.

To begin using the `User` entity, we need to let TypeORM know about it by inserting it into the `entities` array in the module `forRoot()` method options (unless you use a static glob path):

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { User } from './users/user.entity';

@Module({
  imports: [
    TypeOrmModule.forRoot({
      type: 'mysql',
      host: 'localhost',
      port: 3306,
      username: 'root',
      password: 'root',
      database: 'test',
      entities: [User],
      synchronize: true,
    }),
  ],
})
export class AppModule {}
```

Next, let's look at the `UsersModule`:

users.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { UsersService } from './users.service';
import { UsersController } from './users.controller';
import { User } from './user.entity';

@Module({
  imports: [TypeOrmModule.forFeature([User])],
  providers: [UsersService],
  controllers: [UsersController],
})
export class UsersModule {}
```

This module uses the `forFeature()` method to define which repositories are registered in the current scope. With that in place, we can inject the `UsersRepository` into the `UsersService` using the `@InjectRepository()` decorator:

users.service.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { User } from './user.entity';

@Injectable()
export class UsersService {
  constructor(
    @InjectRepository(User)
    private usersRepository: Repository<User>,
  ) {}

  findAll(): Promise<User[]> {
    return this.usersRepository.find();
  }

  findOne(id: string): Promise<User> {
    return this.usersRepository.findOne(id);
  }

  async remove(id: string): Promise<void> {
    await this.usersRepository.delete(id);
  }
}
```

```typescript

import { Injectable, Dependencies } from '@nestjs/common';
import { getRepositoryToken } from '@nestjs/typeorm';
import { User } from './user.entity';

@Injectable()
@Dependencies(getRepositoryToken(User))
export class UsersService {
  constructor(usersRepository) {
    this.usersRepository = usersRepository;
  }

  findAll() {
    return this.usersRepository.find();
  }

  findOne(id) {
    return this.usersRepository.findOne(id);
  }

  async remove(id) {
    await this.usersRepository.delete(id);
  }
}
```

> **Notice** Don't forget to import the `UsersModule` into the root `AppModule`.

If you want to use the repository outside of the module which imports `TypeOrmModule.forFeature`, you'll need to re-export the providers generated by it. You can do this by exporting the whole module, like this:

users.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { User } from './user.entity';

@Module({
  imports: [TypeOrmModule.forFeature([User])],
  exports: [TypeOrmModule]
})
export class UsersModule {}
```

Now if we import `UsersModule` in `UserHttpModule`, we can use `@InjectRepository(User)` in the providers of the latter module.

users-http.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { UsersModule } from './users.module';
import { UsersService } from './users.service';
import { UsersController } from './users.controller';

@Module({
  imports: [UsersModule],
  providers: [UsersService],
  controllers: [UsersController]
})
export class UserHttpModule {}
```

### Relations

Relations are associations established between two or more tables. Relations are based on common fields from each table, often involving primary and foreign keys.

There are three types of relations:

|                             |                                                                                                                                                                                                                                 |
| --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `One-to-one`                | Every row in the primary table has one and only one associated row in the foreign table. Use the `@OneToOne()` decorator to define this type of relation.                                                                       |
| `One-to-many / Many-to-one` | Every row in the primary table has one or more related rows in the foreign table. Use the `@OneToMany()` and `@ManyToOne()` decorators to define this type of relation.                                                         |
| `Many-to-many`              | Every row in the primary table has many related rows in the foreign table, and every record in the foreign table has many related rows in the primary table. Use the `@ManyToMany()` decorator to define this type of relation. |

To define relations in entities, use the corresponding **decorators**. For example, to define that each `User` can have multiple photos, use the `@OneToMany()` decorator.

user.entity.ts

JS TS

```typescript

import { Entity, Column, PrimaryGeneratedColumn, OneToMany } from 'typeorm';
import { Photo } from '../photos/photo.entity';

@Entity()
export class User {
  @PrimaryGeneratedColumn()
  id: number;

  @Column()
  firstName: string;

  @Column()
  lastName: string;

  @Column({ default: true })
  isActive: boolean;

  @OneToMany(type => Photo, photo => photo.user)
  photos: Photo[];
}
```

> **Hint** To learn more about relations in TypeORM, visit the [TypeORM documentation](https://typeorm.io/#/relations).

#### Auto-load entities[#](/techniques/database#auto-load-entities)

Manually adding entities to the `entities` array of the connection options can be tedious. In addition, referencing entities from the root module breaks application domain boundaries and causes leaking implementation details to other parts of the application. To solve this issue, static glob paths can be used (e.g., `dist/**/*.entity{ .ts,.js}`).

Note, however, that glob paths are not supported by webpack, so if you are building your application within a monorepo, you won't be able to use them. To address this issue, an alternative solution is provided. To automatically load entities, set the `autoLoadEntities` property of the configuration object (passed into the `forRoot()` method) to `true`, as shown below:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';

@Module({
  imports: [
    TypeOrmModule.forRoot({
      ...
      autoLoadEntities: true,
    }),
  ],
})
export class AppModule {}
```

With that option specified, every entity registered through the `forFeature()` method will be automatically added to the `entities` array of the configuration object.

> **Warning** Note that entities that aren't registered through the `forFeature()` method, but are only referenced from the entity (via a relationship), won't be included by way of the `autoLoadEntities` setting.

#### Separating entity definition[#](/techniques/database#separating-entity-definition)

You can define an entity and its columns right in the model, using decorators. But some people prefer to define entities and their columns inside separate files using the ["entity schemas"](https://typeorm.io/#/separating-entity-definition).

```typescript

import { EntitySchema } from 'typeorm';
import { User } from './user.entity';

export const UserSchema = new EntitySchema<User>({
  name: 'User',
  target: User,
  columns: {
    id: {
      type: Number,
      primary: true,
      generated: true,
    },
    firstName: {
      type: String,
    },
    lastName: {
      type: String,
    },
    isActive: {
      type: Boolean,
      default: true,
    },
  },
  relations: {
    photos: {
      type: 'one-to-many',
      target: 'Photo', // the name of the PhotoSchema
    },
  },
});
```

> **Warning** If you provide the `target` option, the `name` option value has to be the same as the name of the target class. If you do not provide the `target` you can use any name.

Nest allows you to use an `EntitySchema` instance wherever an `Entity` is expected, for example:

```typescript

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { UserSchema } from './user.schema';
import { UsersController } from './users.controller';
import { UsersService } from './users.service';

@Module({
  imports: [TypeOrmModule.forFeature([UserSchema])],
  providers: [UsersService],
  controllers: [UsersController],
})
export class UsersModule {}
```

#### Transactions[#](/techniques/database#transactions)

A database transaction symbolizes a unit of work performed within a database management system against a database, and treated in a coherent and reliable way independent of other transactions. A transaction generally represents any change in a database ([learn more](https://en.wikipedia.org/wiki/Database_transaction)).

There are many different strategies to handle [TypeORM transactions](https://typeorm.io/#/transactions). We recommend using the `QueryRunner` class because it gives full control over the transaction.

First, we need to inject the `Connection` object into a class in the normal way:

```typescript

@Injectable()
export class UsersService {
  constructor(private connection: Connection) {}
}
```

> **Hint** The `Connection` class is imported from the `typeorm` package.

Now, we can use this object to create a transaction.

```typescript

async createMany(users: User[]) {
  const queryRunner = this.connection.createQueryRunner();

  await queryRunner.connect();
  await queryRunner.startTransaction();
  try {
    await queryRunner.manager.save(users[0]);
    await queryRunner.manager.save(users[1]);

    await queryRunner.commitTransaction();
  } catch (err) {
    // since we have errors lets rollback the changes we made
    await queryRunner.rollbackTransaction();
  } finally {
    // you need to release a queryRunner which was manually instantiated
    await queryRunner.release();
  }
}
```

> **Hint** Note that the `connection` is used only to create the `QueryRunner`. However, to test this class would require mocking the entire `Connection` object (which exposes several methods). Thus, we recommend using a helper factory class (e.g., `QueryRunnerFactory`) and defining an interface with a limited set of methods required to maintain transactions. This technique makes mocking these methods pretty straightforward.

Alternatively, you can use the callback-style approach with the `transaction` method of the `Connection` object ([read more](https://typeorm.io/#/transactions/creating-and-using-transactions)).

```typescript

async createMany(users: User[]) {
  await this.connection.transaction(async manager => {
    await manager.save(users[0]);
    await manager.save(users[1]);
  });
}
```

Using decorators to control the transaction (`@Transaction()` and `@TransactionManager()`) is not recommended.

## Hoodies, T-shirts, and accessories!

Support our future development by shopping in the official store!

[See more](https://nestjs.threadless.com/ "Shop | NestJS - A node.js framework built on top of TypeScript")

#### Subscribers[#](/techniques/database#subscribers)

With TypeORM [subscribers](https://typeorm.io/#/listeners-and-subscribers/what-is-a-subscriber), you can listen to specific entity events.

```typescript

import {
  Connection,
  EntitySubscriberInterface,
  EventSubscriber,
  InsertEvent,
} from 'typeorm';
import { User } from './user.entity';

@EventSubscriber()
export class UserSubscriber implements EntitySubscriberInterface<User> {
  constructor(connection: Connection) {
    connection.subscribers.push(this);
  }

  listenTo() {
    return User;
  }

  beforeInsert(event: InsertEvent<User>) {
    console.log(`BEFORE USER INSERTED: `, event.entity);
  }
}
```

> **Warning** Event subscribers can not be [request-scoped](/v7/fundamentals/injection-scopes).

Now, add the `UserSubscriber` class to the `providers` array:

```typescript

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { User } from './user.entity';
import { UsersController } from './users.controller';
import { UsersService } from './users.service';
import { UserSubscriber } from './user.subscriber';

@Module({
  imports: [TypeOrmModule.forFeature([User])],
  providers: [UsersService, UserSubscriber],
  controllers: [UsersController],
})
export class UsersModule {}
```

> **Hint** Learn more about entity subscribers [here](https://typeorm.io/#/listeners-and-subscribers/what-is-a-subscriber).

#### Migrations[#](/techniques/database#migrations)

[Migrations](https://typeorm.io/#/migrations) provide a way to incrementally update the database schema to keep it in sync with the application's data model while preserving existing data in the database. To generate, run, and revert migrations, TypeORM provides a dedicated [CLI](https://typeorm.io/#/migrations/creating-a-new-migration).

Migration classes are separate from the Nest application source code. Their lifecycle is maintained by the TypeORM CLI. Therefore, you are not able to leverage dependency injection and other Nest specific features with migrations. To learn more about migrations, follow the guide in the [TypeORM documentation](https://typeorm.io/#/migrations/creating-a-new-migration).

#### Multiple databases[#](/techniques/database#multiple-databases)

Some projects require multiple database connections. This can also be achieved with this module. To work with multiple connections, first create the connections. In this case, connection naming becomes **mandatory**.

Suppose you have an `Album` entity stored in its own database.

```typescript

const defaultOptions = {
  type: 'postgres',
  port: 5432,
  username: 'user',
  password: 'password',
  database: 'db',
  synchronize: true,
};

@Module({
  imports: [
    TypeOrmModule.forRoot({
      ...defaultOptions,
      host: 'user_db_host',
      entities: [User],
    }),
    TypeOrmModule.forRoot({
      ...defaultOptions,
      name: 'albumsConnection',
      host: 'album_db_host',
      entities: [Album],
    }),
  ],
})
export class AppModule {}
```

> **Notice** If you don't set the `name` for a connection, its name is set to `default`. Please note that you shouldn't have multiple connections without a name, or with the same name, otherwise they will get overridden.

At this point, you have `User` and `Album` entities registered with their own connection. With this setup, you have to tell the `TypeOrmModule.forFeature()` method and the `@InjectRepository()` decorator which connection should be used. If you do not pass any connection name, the `default` connection is used.

```typescript

@Module({
  imports: [
    TypeOrmModule.forFeature([User]),
    TypeOrmModule.forFeature([Album], 'albumsConnection'),
  ],
})
export class AppModule {}
```

You can also inject the `Connection` or `EntityManager` for a given connection:

```typescript

@Injectable()
export class AlbumsService {
  constructor(
    @InjectConnection('albumsConnection')
    private connection: Connection,
    @InjectEntityManager('albumsConnection')
    private entityManager: EntityManager,
  ) {}
}
```

It's also possible to inject any `Connection` to the providers:

```typescript

@Module({
  providers: [
    {
      provide: AlbumsService,
      useFactory: (albumsConnection: Connection) => {
        return new AlbumsService(albumsConnection);
      },
      inject: [getConnectionToken('albumsConnection')],
    },
  ],
})
export class AlbumsModule {}
```

#### Testing[#](/techniques/database#testing)

When it comes to unit testing an application, we usually want to avoid making a database connection, keeping our test suites independent and their execution process as fast as possible. But our classes might depend on repositories that are pulled from the connection instance. How do we handle that? The solution is to create mock repositories. In order to achieve that, we set up [custom providers](/v7/fundamentals/custom-providers). Each registered repository is automatically represented by an `<EntityName>Repository` token, where `EntityName` is the name of your entity class.

The `@nestjs/typeorm` package exposes the `getRepositoryToken()` function which returns a prepared token based on a given entity.

```typescript

@Module({
  providers: [
    UsersService,
    {
      provide: getRepositoryToken(User),
      useValue: mockRepository,
    },
  ],
})
export class UsersModule {}
```

Now a substitute `mockRepository` will be used as the `UsersRepository`. Whenever any class asks for `UsersRepository` using an `@InjectRepository()` decorator, Nest will use the registered `mockRepository` object.

#### Custom repository[#](/techniques/database#custom-repository)

TypeORM provides a feature called **custom repositories**. Custom repositories allow you to extend a base repository class, and enrich it with several special methods. To learn more about this feature, visit [this page](https://typeorm.io/#/custom-repository).

In order to create your custom repository, use the `@EntityRepository()` decorator and extend the `Repository` class.

```typescript

@EntityRepository(Author)
export class AuthorRepository extends Repository<Author> {}
```

> **Hint** Both `@EntityRepository()` and `Repository` are imported from the `typeorm` package.

Once the class is created, the next step is to delegate instantiation responsibility to Nest. For this, we have to pass the`AuthorRepository` class to the `TypeOrm.forFeature()` method.

```typescript

@Module({
  imports: [TypeOrmModule.forFeature([AuthorRepository])],
  controller: [AuthorController],
  providers: [AuthorService],
})
export class AuthorModule {}
```

Afterward, simply inject the repository using the following construction:

```typescript

@Injectable()
export class AuthorService {
  constructor(private authorRepository: AuthorRepository) {}
}
```

#### Async configuration[#](/techniques/database#async-configuration)

You may want to pass your repository module options asynchronously instead of statically. In this case, use the `forRootAsync()` method, which provides several ways to deal with async configuration.

One approach is to use a factory function:

```typescript

TypeOrmModule.forRootAsync({
  useFactory: () => ({
    type: 'mysql',
    host: 'localhost',
    port: 3306,
    username: 'root',
    password: 'root',
    database: 'test',
    entities: [__dirname + '/**/*.entity{.ts,.js}'],
    synchronize: true,
  }),
});
```

Our factory behaves like any other [asynchronous provider](https://docs.nestjs.com/fundamentals/async-providers) (e.g., it can be `async` and it's able to inject dependencies through `inject`).

```typescript

TypeOrmModule.forRootAsync({
  imports: [ConfigModule],
  useFactory: (configService: ConfigService) => ({
    type: 'mysql',
    host: configService.get('HOST'),
    port: +configService.get<number>('PORT'),
    username: configService.get('USERNAME'),
    password: configService.get('PASSWORD'),
    database: configService.get('DATABASE'),
    entities: [__dirname + '/**/*.entity{.ts,.js}'],
    synchronize: true,
  }),
  inject: [ConfigService],
});
```

Alternatively, you can use the `useClass` syntax:

```typescript

TypeOrmModule.forRootAsync({
  useClass: TypeOrmConfigService,
});
```

The construction above will instantiate `TypeOrmConfigService` inside `TypeOrmModule` and use it to provide an options object by calling `createTypeOrmOptions()`. Note that this means that the `TypeOrmConfigService` has to implement the `TypeOrmOptionsFactory` interface, as shown below:

```typescript

@Injectable()
class TypeOrmConfigService implements TypeOrmOptionsFactory {
  createTypeOrmOptions(): TypeOrmModuleOptions {
    return {
      type: 'mysql',
      host: 'localhost',
      port: 3306,
      username: 'root',
      password: 'root',
      database: 'test',
      entities: [__dirname + '/**/*.entity{.ts,.js}'],
      synchronize: true,
    };
  }
}
```

In order to prevent the creation of `TypeOrmConfigService` inside `TypeOrmModule` and use a provider imported from a different module, you can use the `useExisting` syntax.

```typescript

TypeOrmModule.forRootAsync({
  imports: [ConfigModule],
  useExisting: ConfigService,
});
```

This construction works the same as `useClass` with one critical difference - `TypeOrmModule` will lookup imported modules to reuse an existing `ConfigService` instead of instantiating a new one.

> **Hint** Make sure that the `name` property is defined at the same level as the `useFactory`, `useClass`, or `useValue` property. This will allow Nest to properly register the connection under the appropriate injection token.

```bash

$ npm install --save @nestjs/sequelize sequelize sequelize-typescript mysql2
$ npm install --save-dev @types/sequelize
```

Once the installation process is complete, we can import the `SequelizeModule` into the root `AppModule`.

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { SequelizeModule } from '@nestjs/sequelize';

@Module({
  imports: [
    SequelizeModule.forRoot({
      dialect: 'mysql',
      host: 'localhost',
      port: 3306,
      username: 'root',
      password: 'root',
      database: 'test',
      models: [],
    }),
  ],
})
export class AppModule {}
```

The `forRoot()` method supports all the configuration properties exposed by the Sequelize constructor ([read more](https://sequelize.org/v5/manual/getting-started.html#setting-up-a-connection)). In addition, there are several extra configuration properties described below.

|                       |                                                                                         |
| --------------------- | --------------------------------------------------------------------------------------- |
| `retryAttempts`       | Number of attempts to connect to the database (default: `10`)                           |
| `retryDelay`          | Delay between connection retry attempts (ms) (default: `3000`)                          |
| `autoLoadModels`      | If `true`, models will be loaded automatically (default: `false`)                       |
| `keepConnectionAlive` | If `true`, connection will not be closed on the application shutdown (default: `false`) |
| `synchronize`         | If `true`, automatically loaded models will be synchronized (default: `false`)          |

Once this is done, the `Sequelize` object will be available to inject across the entire project (without needing to import any modules), for example:

app.service.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { Sequelize } from 'sequelize-typescript';

@Injectable()
export class AppService {
  constructor(private sequelize: Sequelize) {}
}
```

```typescript

import { Injectable } from '@nestjs/common';
import { Sequelize } from 'sequelize-typescript';

@Dependencies(Sequelize)
@Injectable()
export class AppService {
  constructor(sequelize) {
    this.sequelize = sequelize;
  }
}
```

#### Models[#](/techniques/database#models)

Sequelize implements the Active Record pattern. With this pattern, you use model classes directly to interact with the database. To continue the example, we need at least one model. Let's define the `User` model.

user.model.ts

JS TS

```typescript

import { Column, Model, Table } from 'sequelize-typescript';

@Table
export class User extends Model<User> {
  @Column
  firstName: string;

  @Column
  lastName: string;

  @Column({ defaultValue: true })
  isActive: boolean;
}
```

> **Hint** Learn more about the available decorators [here](https://github.com/RobinBuschmann/sequelize-typescript#column).

The `User` model file sits in the `users` directory. This directory contains all files related to the `UsersModule`. You can decide where to keep your model files, however, we recommend creating them near their **domain**, in the corresponding module directory.

To begin using the `User` model, we need to let Sequelize know about it by inserting it into the `models` array in the module `forRoot()` method options:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { SequelizeModule } from '@nestjs/sequelize';
import { User } from './users/user.model';

@Module({
  imports: [
    SequelizeModule.forRoot({
      dialect: 'mysql',
      host: 'localhost',
      port: 3306,
      username: 'root',
      password: 'root',
      database: 'test',
      models: [User],
    }),
  ],
})
export class AppModule {}
```

Next, let's look at the `UsersModule`:

users.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { SequelizeModule } from '@nestjs/sequelize';
import { User } from './user.model';
import { UsersController } from './users.controller';
import { UsersService } from './users.service';

@Module({
  imports: [SequelizeModule.forFeature([User])],
  providers: [UsersService],
  controllers: [UsersController],
})
export class UsersModule {}
```

This module uses the `forFeature()` method to define which models are registered in the current scope. With that in place, we can inject the `UserModel` into the `UsersService` using the `@InjectModel()` decorator:

users.service.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { InjectModel } from '@nestjs/sequelize';
import { User } from './user.model';

@Injectable()
export class UsersService {
  constructor(
    @InjectModel(User)
    private userModel: typeof User,
  ) {}

  async findAll(): Promise<User[]> {
    return this.userModel.findAll();
  }

  findOne(id: string): Promise<User> {
    return this.userModel.findOne({
      where: {
        id,
      },
    });
  }

  async remove(id: string): Promise<void> {
    const user = await this.findOne(id);
    await user.destroy();
  }
}
```

```typescript

import { Injectable, Dependencies } from '@nestjs/common';
import { getModelToken } from '@nestjs/sequelize';
import { User } from './user.model';

@Injectable()
@Dependencies(getModelToken(User))
export class UsersService {
  constructor(usersRepository) {
    this.usersRepository = usersRepository;
  }

  async findAll() {
    return this.userModel.findAll();
  }

  findOne(id) {
    return this.userModel.findOne({
      where: {
        id,
      },
    });
  }

  async remove(id) {
    const user = await this.findOne(id);
    await user.destroy();
  }
}
```

> **Notice** Don't forget to import the `UsersModule` into the root `AppModule`.

If you want to use the repository outside of the module which imports `SequelizeModule.forFeature`, you'll need to re-export the providers generated by it. You can do this by exporting the whole module, like this:

users.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { SequelizeModule } from '@nestjs/sequelize';
import { User } from './user.entity';

@Module({
  imports: [SequelizeModule.forFeature([User])],
  exports: [SequelizeModule]
})
export class UsersModule {}
```

Now if we import `UsersModule` in `UserHttpModule`, we can use `@InjectModel(User)` in the providers of the latter module.

users-http.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { UsersModule } from './users.module';
import { UsersService } from './users.service';
import { UsersController } from './users.controller';

@Module({
  imports: [UsersModule],
  providers: [UsersService],
  controllers: [UsersController]
})
export class UserHttpModule {}
```

### Relations

Relations are associations established between two or more tables. Relations are based on common fields from each table, often involving primary and foreign keys.

There are three types of relations:

|                             |                                                                                                                                                             |
| --------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `One-to-one`                | Every row in the primary table has one and only one associated row in the foreign table                                                                     |
| `One-to-many / Many-to-one` | Every row in the primary table has one or more related rows in the foreign table                                                                            |
| `Many-to-many`              | Every row in the primary table has many related rows in the foreign table, and every record in the foreign table has many related rows in the primary table |

To define relations in entities, use the corresponding **decorators**. For example, to define that each `User` can have multiple photos, use the `@HasMany()` decorator.

user.entity.ts

JS TS

```typescript

import { Column, Model, Table, HasMany } from 'sequelize-typescript';
import { Photo } from '../photos/photo.model';

@Table
export class User extends Model<User> {
  @Column
  firstName: string;

  @Column
  lastName: string;

  @Column({ defaultValue: true })
  isActive: boolean;

  @HasMany(() => Photo)
  photos: Photo[];
}
```

> **Hint** To learn more about associations in Sequelize, read [this](https://github.com/RobinBuschmann/sequelize-typescript#model-association) chapter.

#### Auto-load models[#](/techniques/database#auto-load-models)

Manually adding models to the `models` array of the connection options can be tedious. In addition, referencing models from the root module breaks application domain boundaries and causes leaking implementation details to other parts of the application. To solve this issue, automatically load models by setting both `autoLoadModels` and `synchronize` properties of the configuration object (passed into the `forRoot()` method) to `true`, as shown below:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { SequelizeModule } from '@nestjs/sequelize';

@Module({
  imports: [
    SequelizeModule.forRoot({
      ...
      autoLoadModels: true,
      synchronize: true,
    }),
  ],
})
export class AppModule {}
```

With that option specified, every model registered through the `forFeature()` method will be automatically added to the `models` array of the configuration object.

> **Warning** Note that models that aren't registered through the `forFeature()` method, but are only referenced from the model (via an association), won't be included.

#### Transactions[#](/techniques/database#transactions-1)

A database transaction symbolizes a unit of work performed within a database management system against a database, and treated in a coherent and reliable way independent of other transactions. A transaction generally represents any change in a database ([learn more](https://en.wikipedia.org/wiki/Database_transaction)).

There are many different strategies to handle [Sequelize transactions](https://sequelize.org/v5/manual/transactions.html). Below is a sample implementation of a managed transaction (auto-callback).

First, we need to inject the `Sequelize` object into a class in the normal way:

```typescript

@Injectable()
export class UsersService {
  constructor(private sequelize: Sequelize) {}
}
```

> **Hint** The `Sequelize` class is imported from the `sequelize-typescript` package.

Now, we can use this object to create a transaction.

```typescript

async createMany() {
  try {
    await this.sequelize.transaction(async t => {
      const transactionHost = { transaction: t };

      await this.userModel.create(
          { firstName: 'Abraham', lastName: 'Lincoln' },
          transactionHost,
      );
      await this.userModel.create(
          { firstName: 'John', lastName: 'Boothe' },
          transactionHost,
      );
    });
  } catch (err) {
    // Transaction has been rolled back
    // err is whatever rejected the promise chain returned to the transaction callback
  }
}
```

> **Hint** Note that the `Sequelize` instance is used only to start the transaction. However, to test this class would require mocking the entire `Sequelize` object (which exposes several methods). Thus, we recommend using a helper factory class (e.g., `TransactionRunner`) and defining an interface with a limited set of methods required to maintain transactions. This technique makes mocking these methods pretty straightforward.

```typescript

const defaultOptions = {
  dialect: 'postgres',
  port: 5432,
  username: 'user',
  password: 'password',
  database: 'db',
  synchronize: true,
};

@Module({
  imports: [
    SequelizeModule.forRoot({
      ...defaultOptions,
      host: 'user_db_host',
      models: [User],
    }),
    SequelizeModule.forRoot({
      ...defaultOptions,
      name: 'albumsConnection',
      host: 'album_db_host',
      models: [Album],
    }),
  ],
})
export class AppModule {}
```

> **Notice** If you don't set the `name` for a connection, its name is set to `default`. Please note that you shouldn't have multiple connections without a name, or with the same name, otherwise they will get overridden.

At this point, you have `User` and `Album` models registered with their own connection. With this setup, you have to tell the `SequelizeModule.forFeature()` method and the `@InjectModel()` decorator which connection should be used. If you do not pass any connection name, the `default` connection is used.

```typescript

@Module({
  imports: [
    SequelizeModule.forFeature([User]),
    SequelizeModule.forFeature([Album], 'albumsConnection'),
  ],
})
export class AppModule {}
```

You can also inject the `Sequelize` instance for a given connection:

```typescript

@Injectable()
export class AlbumsService {
  constructor(
    @InjectConnection('albumsConnection')
    private sequelize: Sequelize,
  ) {}
}
```

It's also possible to inject any `Sequelize` instance to the providers:

```typescript

@Module({
  providers: [
    {
      provide: AlbumsService,
      useFactory: (albumsSequelize: Sequelize) => {
        return new AlbumsService(albumsSequelize);
      },
      inject: [getConnectionToken('albumsConnection')],
    },
  ],
})
export class AlbumsModule {}
```

#### Testing[#](/techniques/database#testing-1)

When it comes to unit testing an application, we usually want to avoid making a database connection, keeping our test suites independent and their execution process as fast as possible. But our classes might depend on models that are pulled from the connection instance. How do we handle that? The solution is to create mock models. In order to achieve that, we set up [custom providers](/v7/fundamentals/custom-providers). Each registered model is automatically represented by a `<ModelName>Model` token, where `ModelName` is the name of your model class.

The `@nestjs/sequelize` package exposes the `getModelToken()` function which returns a prepared token based on a given model.

```typescript

@Module({
  providers: [
    UsersService,
    {
      provide: getModelToken(User),
      useValue: mockModel,
    },
  ],
})
export class UsersModule {}
```

Now a substitute `mockModel` will be used as the `UserModel`. Whenever any class asks for `UserModel` using an `@InjectModel()` decorator, Nest will use the registered `mockModel` object.

#### Async configuration[#](/techniques/database#async-configuration-1)

You may want to pass your `SequelizeModule` options asynchronously instead of statically. In this case, use the `forRootAsync()` method, which provides several ways to deal with async configuration.

One approach is to use a factory function:

```typescript

SequelizeModule.forRootAsync({
  useFactory: () => ({
    dialect: 'mysql',
    host: 'localhost',
    port: 3306,
    username: 'root',
    password: 'root',
    database: 'test',
    models: [],
  }),
});
```

Our factory behaves like any other [asynchronous provider](https://docs.nestjs.com/fundamentals/async-providers) (e.g., it can be `async` and it's able to inject dependencies through `inject`).

```typescript

SequelizeModule.forRootAsync({
  imports: [ConfigModule],
  useFactory: (configService: ConfigService) => ({
    dialect: 'mysql',
    host: configService.get('HOST'),
    port: +configService.get('PORT'),
    username: configService.get('USERNAME'),
    password: configService.get('PASSWORD'),
    database: configService.get('DATABASE'),
    models: [],
  }),
  inject: [ConfigService],
});
```

Alternatively, you can use the `useClass` syntax:

```typescript

SequelizeModule.forRootAsync({
  useClass: SequelizeConfigService,
});
```

The construction above will instantiate `SequelizeConfigService` inside `SequelizeModule` and use it to provide an options object by calling `createSequelizeOptions()`. Note that this means that the `SequelizeConfigService` has to implement the `SequelizeOptionsFactory` interface, as shown below:

```typescript

@Injectable()
class SequelizeConfigService implements SequelizeOptionsFactory {
  createSequelizeOptions(): SequelizeModuleOptions {
    return {
      dialect: 'mysql',
      host: 'localhost',
      port: 3306,
      username: 'root',
      password: 'root',
      database: 'test',
      models: [],
    };
  }
}
```

In order to prevent the creation of `SequelizeConfigService` inside `SequelizeModule` and use a provider imported from a different module, you can use the `useExisting` syntax.

```typescript

SequelizeModule.forRootAsync({
  imports: [ConfigModule],
  useExisting: ConfigService,
});
```

This construction works the same as `useClass` with one critical difference - `SequelizeModule` will lookup imported modules to reuse an existing `ConfigService` instead of instantiating a new one.

#### Example[#](/techniques/database#example-1)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/07-sequelize).

----
url: https://docs.nestjs.com/v5/guards
----

### Guards

A guard is a class annotated with the `@Injectable()` decorator. The guard should implement the `CanActivate` interface.

The guards have a **single responsibility**. They determine whether a request shall be handled by the route handler or not. Until now, the access restriction logic was mostly inside the [middleware](/v5/middleware). It's still fine since things such as token validation or attaching properties to the `request` object are not strongly connected with a particular routes.

But middleware, by its nature, is dumb. It doesn't know which handler will be executed after calling the `next()` function. On the other hand, **Guards** have an access to the `ExecutionContext` instance, and thus we know exactly what's going to be evaluated.

> **Hint** Guards are executed **after** each middleware, but **before** any pipe.

#### Authorization guard

One of the best guards use-cases is the **authorization** logic because specific routes should be available only when the caller has sufficient permissions. The `AuthGuard` that we have a plan to create is going to sequentially extract and validate the token sent in request headers.

auth.guard.ts

JS TS

TypeScript

```typescript

import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
import { Observable } from 'rxjs';

@Injectable()
export class AuthGuard implements CanActivate {
  canActivate(
    context: ExecutionContext,
  ): boolean | Promise<boolean> | Observable<boolean> {
    const request = context.switchToHttp().getRequest();
    return validateRequest(request);
  }
}
```

TypeScript

```typescript

import { Injectable } from '@nestjs/common';

@Injectable()
export class AuthGuard {
  async canActivate(context) {
    const request = context.switchToHttp().getRequest();
    return await validateRequest(request);
  }
}
```

Regardless of the logic that sits behind `validateRequest()` function, the main point is to show how simple is to take advantage of guards. Every guard provides a `canActivate()` function. The guard might return its boolean answer either synchronously or asynchronously via a (`Promise` or `Observable`). The returned value controls the Nest behavior:

* if it returns `true`, the user call will be processed.
* if it returns `false`, Nest will ignore a currently processed request.

The `canActivate()` function takes single argument, the `ExecutionContext` instance. The `ExecutionContext` inherits from `ArgumentsHost` (first mention [here](/v5/exception-filters)). The `ArgumentsHost` is a wrapper around arguments that have been passed to the **original** handler, and it contains different arguments array under the hood based on the type of the application.

TypeScript

```typescript

export interface ArgumentsHost {
  getArgs<T extends Array<any> = any[]>(): T;
  getArgByIndex<T = any>(index: number): T;
  switchToRpc(): RpcArgumentsHost;
  switchToHttp(): HttpArgumentsHost;
  switchToWs(): WsArgumentsHost;
}
```

The `ArgumentsHost` supplies us with a set of useful methods that helps to pick correct arguments from the underlying array. In other words, `ArgumentsHost` is nothing else than just an **array of arguments**. For example, when the guard is used within HTTP application context, `ArgumentsHost` will contain `[request, response]` array inside. However, when current context is a web sockets application, this array will be equal to `[client, data]`. This design decision enables you to access any argument that would be eventually passed to the corresponding handler.

The `ExecutionContext` offers a little bit more. It extends `ArgumentsHost`, but also, provides more details about current execution process.

TypeScript

```typescript

export interface ExecutionContext extends ArgumentsHost {
  getClass<T = any>(): Type<T>;
  getHandler(): Function;
}
```

The `getHandler()` returns a reference to the currently processed handler, while `getClass()` returns a type of the `Controller` class which this particular handler belongs to. Using other words, if the user points to `create()` method that is defined and registered within `CatsController`, the `getHandler()` will return a reference to the `create()` method and `getClass()` in this case, will simply return a `CatsController`**type** (not instance).

#### Role-based authentication

A little bit more detailed example is a `RolesGuard`. This guard permits access only to users with a specific role. We are gonna start with a basic guard template:

roles.guard.ts

JS TS

TypeScript

```typescript

import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
import { Observable } from 'rxjs';

@Injectable()
export class RolesGuard implements CanActivate {
  canActivate(
    context: ExecutionContext,
  ): boolean | Promise<boolean> | Observable<boolean> {
    return true;
  }
}
```

TypeScript

```typescript

import { Injectable } from '@nestjs/common';

@Injectable()
export class RolesGuard {
  canActivate(context) {
    return true;
  }
}
```

#### Binding guards

The guards can be **controller-scoped**, method-scoped, and global-scoped as well. In order to set up the guard, we have to use a `@UseGuards()` decorator. This decorator may take an endless number of arguments, meaning, you can pass several guards and separate them by a comma.

cats.controller.ts

JS TS

TypeScript

```typescript

@Controller('cats')
@UseGuards(RolesGuard)
export class CatsController {}
```

> **Hint** The `@UseGuards()` decorator is imported from the `@nestjs/common` package.

We have passed the `RolesGuard` type instead of an instance, leaving framework the instantiation responsibility and enabling dependency injection. Another available way is to pass the immediately created instance:

cats.controller.ts

JS TS

TypeScript

```typescript

@Controller('cats')
@UseGuards(new RolesGuard())
export class CatsController {}
```

The construction above attaches the guard to every handler declared by this controller. If we decide to restrict only one of them, we just need to set up the guard at **method level**. In order to bind the global guard, we use the `useGlobalGuards()` method of the Nest application instance:

TypeScript

```typescript

const app = await NestFactory.create(ApplicationModule);
app.useGlobalGuards(new RolesGuard());
```

> **Notice** The `useGlobalGuards()` method doesn't set up guards for gateways and microservices.

The global guards are used across the whole application, for every controller and every route handler. In terms of dependency injection, global guards registered from the outside of any module (as in the previous example above) cannot inject dependencies since they don't belong to any module. In order to solve this issue, you can set up a guard **directly from any module** using following construction:

app.module.ts

JS TS

TypeScript

```typescript

import { Module } from '@nestjs/common';
import { APP_GUARD } from '@nestjs/core';

@Module({
  providers: [
    {
      provide: APP_GUARD,
      useClass: RolesGuard,
    },
  ],
})
export class ApplicationModule {}
```

> **Hint** The alternative option is to use an [execution context](/v5/execution-context) feature. Also, `useClass` is not the only way of dealing with custom providers registration. Learn more [here](/v5/fundamentals/dependency-injection).

#### Reflector

The guard is working now, but we're still not taking advantage of the most important guard features, being the **execution context&#x20;**.

The `RolesGuard` isn't reusable so far. How would we know which roles need to be processed by the handler? The `CatsController` could have a lot of them. Some might be available only for admin, some for everyone, although, they don't have any permissions.

That's why along with the guards, Nest provides the ability to attach **custom metadata** through `@ReflectMetadata()` decorator.

cats.controller.ts

JS TS

TypeScript

```typescript

@Post()
@ReflectMetadata('roles', ['admin'])
async create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

TypeScript

```typescript

@Post()
@ReflectMetadata('roles', ['admin'])
@Bind(Body())
async create(createCatDto) {
  this.catsService.create(createCatDto);
}
```

> **Hint** The `@ReflectMetadata()` decorator is imported from the `@nestjs/common` package.

With the construction above, we attached the `roles` metadata (`roles` is a key, while `['admin']` is a particular value) to the `create()` method. It's not a good practice to use `@ReflectMetadata()` directly. Instead, you should always create your own decorators:

roles.decorator.ts

JS TS

TypeScript

```typescript

import { ReflectMetadata } from '@nestjs/common';

export const Roles = (...roles: string[]) => ReflectMetadata('roles', roles);
```

TypeScript

```typescript

import { ReflectMetadata } from '@nestjs/common';

export const Roles = (...roles) => ReflectMetadata('roles', roles);
```

This approach is much cleaner and readable. Since we've got a `@Roles()` decorator now, we can use it with the `create()` method.

cats.controller.ts

JS TS

TypeScript

```typescript

@Post()
@Roles('admin')
async create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

TypeScript

```typescript

@Post()
@Roles('admin')
@Bind(Body())
async create(createCatDto) {
  this.catsService.create(createCatDto);
}
```

Alright. Let's take a step back to the `RolesGuard` again. It simply returns `true` immediately, allowing request to proceed so far. In order to reflect the metadata, we'll use the `Reflector` helper class which is provided out of the box by the framework and exposed from the `@nestjs/core` package.

roles.guard.ts

JS TS

TypeScript

```typescript

import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
import { Observable } from 'rxjs';
import { Reflector } from '@nestjs/core';

@Injectable()
export class RolesGuard implements CanActivate {
  constructor(private readonly reflector: Reflector) {}

  canActivate(context: ExecutionContext): boolean {
    const roles = this.reflector.get<string[]>('roles', context.getHandler());
    if (!roles) {
      return true;
    }
    const request = context.switchToHttp().getRequest();
    const user = request.user;
    const hasRole = () => user.roles.some((role) => roles.includes(role));
    return user && user.roles && hasRole();
  }
}
```

TypeScript

```typescript

import { Injectable, Dependencies } from '@nestjs/common';
import { Reflector } from '@nestjs/core';

@Injectable()
@Dependencies(Reflector)
export class RolesGuard {
  constructor(reflector) {
    this.reflector = reflector;
  }

  canActivate(context) {
    const roles = this.reflector.get('roles', context.getHandler());
    if (!roles) {
      return true;
    }
    const request = context.switchToHttp().getRequest();
    const user = request.user;
    const hasRole = () => user.roles.some((role) => roles.includes(role));
    return user && user.roles && hasRole();
  }
}
```

> **Hint** In the node.js world, it's a common practice to attach the authorized user to the `request` object. That's why we assumed that `request.user` contains the user instance.

The `Reflector` allows us to easily reflect the metadata by the specified **key**. In the example above, we used `getHandler()` in order to reflect the metadata because it's a **reference** to the route handler function. We could make this guard even **more generic** if we add the controller reflection part as well. To extract the **controller metadata**, we should use `context.getClass()` instead of `getHandler()` function:

JS TS

TypeScript

```typescript

const roles = this.reflector.get<string[]>('roles', context.getClass());
```

TypeScript

```typescript

const roles = this.reflector.get('roles', context.getClass());
```

When a user tries to call the `/cats` POST endpoint without enough privileges, Nest will automatically return response below:

TypeScript

```typescript

{
  "statusCode": 403,
  "message": "Forbidden resource"
}
```

In fact, the guard which returns `false` throws `HttpException`. If you want to return a different error response to the end-user, you should throw an exception. Afterward, this exception can be caught by the [exception filter ](/v5/exception-filters).

* Guards
* Authorization guard
* Role-based authentication
* Binding guards
* Reflector

----
url: https://docs.nestjs.com/v9/fundamentals/platform-agnosticism
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Platform agnosticism](https://docs.nestjs.com/v9/fundamentals/platform-agnosticism#platform-agnosticism)
* [Build once, use everywhere](https://docs.nestjs.com/v9/fundamentals/platform-agnosticism#build-once-use-everywhere)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/fundamentals/platform-agnosticism.md "Suggest Edits")

### Platform agnosticism

Nest is a platform-agnostic framework. This means you can develop **reusable logical parts** that can be used across different types of applications. For example, most components can be re-used without change across different underlying HTTP server frameworks (e.g., Express and Fastify), and even across different *types* of applications (e.g., HTTP server frameworks, Microservices with different transport layers, and Web Sockets).

#### Build once, use everywhere[#](/fundamentals/platform-agnosticism#build-once-use-everywhere)

The **Overview** section of the documentation primarily shows coding techniques using HTTP server frameworks (e.g., apps providing a REST API or providing an MVC-style server-side rendered app). However, all those building blocks can be used on top of different transport layers ([microservices](/v9/microservices/basics) or [websockets](/v9/websockets/gateways)).

Furthermore, Nest comes with a dedicated [GraphQL](/v9/graphql/quick-start) module. You can use GraphQL as your API layer interchangeably with providing a REST API.

In addition, the [application context](/v9/application-context) feature helps to create any kind of Node.js application - including things like CRON jobs and CLI apps - on top of Nest.

Nest aspires to be a full-fledged platform for Node.js apps that brings a higher-level of modularity and reusability to your applications. Build once, use everywhere!

----
url: https://docs.nestjs.com/v6/recipes/prisma
----

* [Prisma](https://docs.nestjs.com/v6/recipes/prisma#prisma)
* [Dependencies](https://docs.nestjs.com/v6/recipes/prisma#dependencies)
* [Setup Prisma](https://docs.nestjs.com/v6/recipes/prisma#setup-prisma)
* [Create the client](https://docs.nestjs.com/v6/recipes/prisma#create-the-client)
* [Integration](https://docs.nestjs.com/v6/recipes/prisma#integration)
* [Usage](https://docs.nestjs.com/v6/recipes/prisma#usage)
* [Example](https://docs.nestjs.com/v6/recipes/prisma#example)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/recipes/prisma.md "Suggest Edits")

### Prisma

[Prisma](https://www.prisma.io/) turns your database into a GraphQL API and enables the use of GraphQL as a universal query language for all databases. Instead of writing SQL or using a NoSQL API, you can query your database with GraphQL. In this chapter we won't go into details about Prisma, so head over to their website and have a look what [features](https://www.prisma.io/features/) are available.

> **Notice** In this article, you'll learn how to integrate `Prisma` into the Nest framework. We assume that you are already familiar with the GraphQL concepts and the `@nestjs/graphql` module.

#### Dependencies[#](/recipes/prisma#dependencies)

Firstly, we need to install the required packages:

```bash

$ npm install --save prisma-binding
```

#### Setup Prisma[#](/recipes/prisma#setup-prisma)

While working with Prisma you can either host your own instance or use the [Prisma Cloud](https://www.prisma.io/cloud/). In this introduction we are going to use the demo server provided by Prisma.

1. Install the Prisma CLI `npm install -g prisma`
2. Create a new service `prisma init`, choose the demo server and follow the instructions
3. Deploy your service `prisma deploy`

If you find yourself in trouble jump over to their [Quick Start](https://www.prisma.io/docs/quickstart/) section for further details. Eventually you should see two new files in your project directory, `prisma.yaml` configuration file:

```yaml

endpoint: https://us1.prisma.sh/nest-f6ec12/prisma/dev
datamodel: datamodel.graphql
```

and automatically created data model, `datamodel.graphql`.

```graphql

type User {
  id: ID! @unique
  name: String!
}
```

> **Notice** In the real-world applications you will create more complex data models. For more information about data modeling in Prisma click [here](https://www.prisma.io/features/data-modeling/).

By typing `prisma playground` you can open the Prisma GraphQL playground.

#### Create the client[#](/recipes/prisma#create-the-client)

There are a couple of ways to integrate a GraphQL API. We are going to use [GraphQL CLI](https://www.npmjs.com/package/graphql-cli), a command line tool for common GraphQL development workflows. To install the GraphQL CLI use the following command:

```bash

$ npm install -g graphql-cli
```

Next, create your `.graphqlconfig` in the root directory of the your Nest application:

```bash

$ touch .graphqlconfig.yml
```

Put the following content into it:

```yaml

projects:
  database:
    schemaPath: src/prisma/prisma-types.graphql
    extensions:
      endpoints:
        default: https://us1.prisma.sh/nest-f6ec12/prisma/dev
      codegen:
        - generator: prisma-binding
          language: typescript
          output:
            binding: src/prisma/prisma.binding.ts
```

To download your Prisma GraphQL schema to `prisma/prisma-types.graphql` and create your Prisma client under `prisma/prisma.binding.graphql`, run the following commands in your terminal:

```bash

$ graphql get-schema --project database
$ graphql codegen --project database
```

#### Integration[#](/recipes/prisma#integration)

Almost done. Now, let's create a module for our Prisma integration.

prisma.service.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { Prisma } from './prisma.binding';

@Injectable()
export class PrismaService extends Prisma {
  constructor() {
    super({
      endpoint: 'https://us1.prisma.sh/nest-f6ec12/prisma/dev',
      debug: false,
    });
  }
}
```

Once `PrismaService` is ready, we need to create a corresponding module.

prisma.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { PrismaService } from './prisma.service';

@Module({
  providers: [PrismaService],
  exports: [PrismaService],
})
export class PrismaModule {}
```

> **Hint** To create new modules and services in no time we can make use of the [Nest CLI](/v6/cli/overview). To create a `PrismaModule` type `nest g module prisma` and for the service `nest g service prisma`

#### Usage[#](/recipes/prisma#usage)

To use your new service we are going to import the `PrismaModule` and inject the `PrismaService` into `UsersResolver`.

users.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { UsersResolver } from './users.resolver';
import { PrismaModule } from '../prisma/prisma.module';

@Module({
  imports: [PrismaModule],
  providers: [UsersResolver],
})
export class UsersModule {}
```

Importing `PrismaModule` makes exported `PrismaService` available in the `UsersModule` context.

users.resolver.ts

JS TS

```typescript

import { Query, Resolver, Args, Info } from '@nestjs/graphql';
import { PrismaService } from '../prisma/prisma.service';
import { User } from '../graphql.schema';

@Resolver()
export class UsersResolver {
  constructor(private readonly prisma: PrismaService) {}

  @Query('users')
  async getUsers(@Args() args, @Info() info): Promise<User[]> {
    return this.prisma.query.users(args, info);
  }
}
```

#### Example[#](/recipes/prisma#example)

A slightly modified example is available [here](https://github.com/nestjs/nest/tree/master/sample/22-graphql-prisma).

----
url: https://docs.nestjs.com/v11/fundamentals/discovery-service
----

* [Discovery service](https://docs.nestjs.com/v11/fundamentals/discovery-service#discovery-service)
* [Getting started](https://docs.nestjs.com/v11/fundamentals/discovery-service#getting-started)
* [Discovering providers and controllers](https://docs.nestjs.com/v11/fundamentals/discovery-service#discovering-providers-and-controllers)
* [Extracting metadata](https://docs.nestjs.com/v11/fundamentals/discovery-service#extracting-metadata)
* [Conclusion](https://docs.nestjs.com/v11/fundamentals/discovery-service#conclusion)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/fundamentals/discovery-service.md "Suggest Edits")

### Discovery service

The `DiscoveryService` provided by the `@nestjs/core` package is a powerful utility that allows developers to dynamically inspect and retrieve providers, controllers, and other metadata within a NestJS application. This is particularly useful when building plugins, decorators, or advanced features that rely on runtime introspection. By leveraging `DiscoveryService`, developers can create more flexible and modular architectures, enabling automation and dynamic behavior in their applications.

#### Getting started[#](/fundamentals/discovery-service#getting-started)

Before using `DiscoveryService`, you need to import the `DiscoveryModule` in the module where you intend to use it. This ensures that the service is available for dependency injection. Below is an example of how to configure it within a NestJS module:

```typescript

import { Module } from '@nestjs/common';
import { DiscoveryModule } from '@nestjs/core';
import { ExampleService } from './example.service';

@Module({
  imports: [DiscoveryModule],
  providers: [ExampleService],
})
export class ExampleModule {}
```

Once the module is set up, `DiscoveryService` can be injected into any provider or service where dynamic discovery is required.

example.service.ts

JS TS

```typescript

@Injectable()
export class ExampleService {
  constructor(private readonly discoveryService: DiscoveryService) {}
}
```

```typescript

@Injectable()
@Dependencies(DiscoveryService)
export class ExampleService {
  constructor(discoveryService) {
    this.discoveryService = discoveryService;
  }
}
```

#### Discovering providers and controllers[#](/fundamentals/discovery-service#discovering-providers-and-controllers)

One of the key capabilities of `DiscoveryService` is retrieving all registered providers in the application. This is useful for dynamically processing providers based on specific conditions. The following snippet demonstrates how to access all providers:

```typescript

const providers = this.discoveryService.getProviders();
console.log(providers);
```

Each provider object contains information such as its instance, token, and metadata. Similarly, if you need to retrieve all registered controllers within the application, you can do so with:

```typescript

const controllers = this.discoveryService.getControllers();
console.log(controllers);
```

This feature is particularly beneficial for scenarios where controllers need to be processed dynamically, such as analytics tracking, or automatic registration mechanisms.

#### Extracting metadata[#](/fundamentals/discovery-service#extracting-metadata)

Beyond discovering providers and controllers, `DiscoveryService` also enables retrieval of metadata attached to these components. This is particularly valuable when working with custom decorators that store metadata at runtime.

For example, consider a case where a custom decorator is used to tag providers with specific metadata:

```typescript

import { DiscoveryService } from '@nestjs/core';

export const FeatureFlag = DiscoveryService.createDecorator();
```

Applying this decorator to a service allows it to store metadata that can later be queried:

```typescript

import { Injectable } from '@nestjs/common';
import { FeatureFlag } from './custom-metadata.decorator';

@Injectable()
@FeatureFlag('experimental')
export class CustomService {}
```

Once metadata is attached to providers in this way, `DiscoveryService` makes it easy to filter providers based on assigned metadata. The following code snippet demonstrates how to retrieve providers that have been tagged with a specific metadata value:

```typescript

const providers = this.discoveryService.getProviders();

const [provider] = providers.filter(
  (item) =>
    this.discoveryService.getMetadataByDecorator(FeatureFlag, item) ===
    'experimental',
);

console.log(
  'Providers with the "experimental" feature flag metadata:',
  provider,
);
```

#### Conclusion[#](/fundamentals/discovery-service#conclusion)

The `DiscoveryService` is a versatile and powerful tool that enables runtime introspection in NestJS applications. By allowing dynamic discovery of providers, controllers, and metadata, it plays a crucial role in building extensible frameworks, plugins, and automation-driven features. Whether you need to scan and process providers, extract metadata for advanced processing, or create modular and scalable architectures, `DiscoveryService` provides an efficient and structured approach to achieving these goals.

----
url: https://docs.nestjs.com/v10/graphql/subscriptions
----

* [Subscriptions](https://docs.nestjs.com/v10/graphql/subscriptions#subscriptions)
* [Enable subscriptions with Apollo driver](https://docs.nestjs.com/v10/graphql/subscriptions#enable-subscriptions-with-apollo-driver)
* [Code first](https://docs.nestjs.com/v10/graphql/subscriptions#code-first)
* [Publishing](https://docs.nestjs.com/v10/graphql/subscriptions#publishing)
* [Filtering subscriptions](https://docs.nestjs.com/v10/graphql/subscriptions#filtering-subscriptions)
* [Mutating subscription payloads](https://docs.nestjs.com/v10/graphql/subscriptions#mutating-subscription-payloads)
* [Schema first](https://docs.nestjs.com/v10/graphql/subscriptions#schema-first)
* [PubSub](https://docs.nestjs.com/v10/graphql/subscriptions#pubsub)
* [Customize subscriptions server](https://docs.nestjs.com/v10/graphql/subscriptions#customize-subscriptions-server)
* [Authentication over WebSockets](https://docs.nestjs.com/v10/graphql/subscriptions#authentication-over-websockets)
* [Enable subscriptions with Mercurius driver](https://docs.nestjs.com/v10/graphql/subscriptions#enable-subscriptions-with-mercurius-driver)
* [Code first](https://docs.nestjs.com/v10/graphql/subscriptions#code-first-1)
* [Publishing](https://docs.nestjs.com/v10/graphql/subscriptions#publishing-1)
* [Filtering subscriptions](https://docs.nestjs.com/v10/graphql/subscriptions#filtering-subscriptions-1)
* [Schema first](https://docs.nestjs.com/v10/graphql/subscriptions#schema-first-1)
* [PubSub](https://docs.nestjs.com/v10/graphql/subscriptions#pubsub-1)
* [Authentication over WebSockets](https://docs.nestjs.com/v10/graphql/subscriptions#authentication-over-websockets-1)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/subscriptions.md "Suggest Edits")

### Subscriptions

In addition to fetching data using queries and modifying data using mutations, the GraphQL spec supports a third operation type, called `subscription`. GraphQL subscriptions are a way to push data from the server to the clients that choose to listen to real time messages from the server. Subscriptions are similar to queries in that they specify a set of fields to be delivered to the client, but instead of immediately returning a single answer, a channel is opened and a result is sent to the client every time a particular event happens on the server.

A common use case for subscriptions is notifying the client side about particular events, for example the creation of a new object, updated fields and so on (read more [here](https://www.apollographql.com/docs/react/data/subscriptions)).

#### Enable subscriptions with Apollo driver[#](/graphql/subscriptions#enable-subscriptions-with-apollo-driver)

To enable subscriptions, set the `installSubscriptionHandlers` property to `true`.

```typescript

GraphQLModule.forRoot<ApolloDriverConfig>({
  driver: ApolloDriver,
  installSubscriptionHandlers: true,
}),
```

> **Warning** The `installSubscriptionHandlers` configuration option has been removed from the latest version of Apollo server and will be soon deprecated in this package as well. By default, `installSubscriptionHandlers` will fallback to use the `subscriptions-transport-ws` ([read more](https://github.com/apollographql/subscriptions-transport-ws)) but we strongly recommend using the `graphql-ws`([read more](https://github.com/enisdenjo/graphql-ws)) library instead.

To switch to use the `graphql-ws` package instead, use the following configuration:

```typescript

GraphQLModule.forRoot<ApolloDriverConfig>({
  driver: ApolloDriver,
  subscriptions: {
    'graphql-ws': true
  },
}),
```

> **Hint** You can also use both packages (`subscriptions-transport-ws` and `graphql-ws`) at the same time, for example, for backward compatibility.

#### Code first[#](/graphql/subscriptions#code-first)

To create a subscription using the code first approach, we use the `@Subscription()` decorator (exported from the `@nestjs/graphql` package) and the `PubSub` class from the `graphql-subscriptions` package, which provides a simple **publish/subscribe API**.

The following subscription handler takes care of **subscribing** to an event by calling `PubSub#asyncIterableIterator`. This method takes a single argument, the `triggerName`, which corresponds to an event topic name.

```typescript

const pubSub = new PubSub();

@Resolver(() => Author)
export class AuthorResolver {
  // ...
  @Subscription(() => Comment)
  commentAdded() {
    return pubSub.asyncIterableIterator('commentAdded');
  }
}
```

> **Hint** All decorators are exported from the `@nestjs/graphql` package, while the `PubSub` class is exported from the `graphql-subscriptions` package.

> **Note**`PubSub` is a class that exposes a simple `publish` and `subscribe API`. Read more about it [here](https://www.apollographql.com/docs/graphql-subscriptions/setup.html). Note that the Apollo docs warn that the default implementation is not suitable for production (read more [here](https://github.com/apollographql/graphql-subscriptions#getting-started-with-your-first-subscription)). Production apps should use a `PubSub` implementation backed by an external store (read more [here](https://github.com/apollographql/graphql-subscriptions#pubsub-implementations)).

This will result in generating the following part of the GraphQL schema in SDL:

```graphql

type Subscription {
  commentAdded(): Comment!
}
```

Note that subscriptions, by definition, return an object with a single top level property whose key is the name of the subscription. This name is either inherited from the name of the subscription handler method (i.e., `commentAdded` above), or is provided explicitly by passing an option with the key `name` as the second argument to the `@Subscription()` decorator, as shown below.

```typescript

@Subscription(() => Comment, {
  name: 'commentAdded',
})
subscribeToCommentAdded() {
  return pubSub.asyncIterableIterator('commentAdded');
}
```

This construct produces the same SDL as the previous code sample, but allows us to decouple the method name from the subscription.

#### Publishing[#](/graphql/subscriptions#publishing)

Now, to publish the event, we use the `PubSub#publish` method. This is often used within a mutation to trigger a client-side update when a part of the object graph has changed. For example:

posts/posts.resolver.ts

JS TS

```typescript

@Mutation(() => Comment)
async addComment(
  @Args('postId', { type: () => Int }) postId: number,
  @Args('comment', { type: () => Comment }) comment: CommentInput,
) {
  const newComment = this.commentsService.addComment({ id: postId, comment });
  pubSub.publish('commentAdded', { commentAdded: newComment });
  return newComment;
}
```

The `PubSub#publish` method takes a `triggerName` (again, think of this as an event topic name) as the first parameter, and an event payload as the second parameter. As mentioned, the subscription, by definition, returns a value and that value has a shape. Look again at the generated SDL for our `commentAdded` subscription:

```graphql

type Subscription {
  commentAdded(): Comment!
}
```

This tells us that the subscription must return an object with a top-level property name of `commentAdded` that has a value which is a `Comment` object. The important point to note is that the shape of the event payload emitted by the `PubSub#publish` method must correspond to the shape of the value expected to return from the subscription. So, in our example above, the `pubSub.publish('commentAdded', { commentAdded: newComment })` statement publishes a `commentAdded` event with the appropriately shaped payload. If these shapes don't match, your subscription will fail during the GraphQL validation phase.

#### Filtering subscriptions[#](/graphql/subscriptions#filtering-subscriptions)

To filter out specific events, set the `filter` property to a filter function. This function acts similar to the function passed to an array `filter`. It takes two arguments: `payload` containing the event payload (as sent by the event publisher), and `variables` taking any arguments passed in during the subscription request. It returns a boolean determining whether this event should be published to client listeners.

```typescript

@Subscription(() => Comment, {
  filter: (payload, variables) =>
    payload.commentAdded.title === variables.title,
})
commentAdded(@Args('title') title: string) {
  return pubSub.asyncIterableIterator('commentAdded');
}
```

#### Mutating subscription payloads[#](/graphql/subscriptions#mutating-subscription-payloads)

To mutate the published event payload, set the `resolve` property to a function. The function receives the event payload (as sent by the event publisher) and returns the appropriate value.

```typescript

@Subscription(() => Comment, {
  resolve: value => value,
})
commentAdded() {
  return pubSub.asyncIterableIterator('commentAdded');
}
```

> **Note** If you use the `resolve` option, you should return the unwrapped payload (e.g., with our example, return a `newComment` object directly, not a `{ commentAdded: newComment }` object).

If you need to access injected providers (e.g., use an external service to validate the data), use the following construction.

```typescript

@Subscription(() => Comment, {
  resolve(this: AuthorResolver, value) {
    // "this" refers to an instance of "AuthorResolver"
    return value;
  }
})
commentAdded() {
  return pubSub.asyncIterableIterator('commentAdded');
}
```

The same construction works with filters:

```typescript

@Subscription(() => Comment, {
  filter(this: AuthorResolver, payload, variables) {
    // "this" refers to an instance of "AuthorResolver"
    return payload.commentAdded.title === variables.title;
  }
})
commentAdded() {
  return pubSub.asyncIterableIterator('commentAdded');
}
```

#### Schema first[#](/graphql/subscriptions#schema-first)

To create an equivalent subscription in Nest, we'll make use of the `@Subscription()` decorator.

```typescript

const pubSub = new PubSub();

@Resolver('Author')
export class AuthorResolver {
  // ...
  @Subscription()
  commentAdded() {
    return pubSub.asyncIterableIterator('commentAdded');
  }
}
```

To filter out specific events based on context and arguments, set the `filter` property.

```typescript

@Subscription('commentAdded', {
  filter: (payload, variables) =>
    payload.commentAdded.title === variables.title,
})
commentAdded() {
  return pubSub.asyncIterableIterator('commentAdded');
}
```

To mutate the published payload, we can use a `resolve` function.

```typescript

@Subscription('commentAdded', {
  resolve: value => value,
})
commentAdded() {
  return pubSub.asyncIterableIterator('commentAdded');
}
```

If you need to access injected providers (e.g., use an external service to validate the data), use the following construction:

```typescript

@Subscription('commentAdded', {
  resolve(this: AuthorResolver, value) {
    // "this" refers to an instance of "AuthorResolver"
    return value;
  }
})
commentAdded() {
  return pubSub.asyncIterableIterator('commentAdded');
}
```

The same construction works with filters:

```typescript

@Subscription('commentAdded', {
  filter(this: AuthorResolver, payload, variables) {
    // "this" refers to an instance of "AuthorResolver"
    return payload.commentAdded.title === variables.title;
  }
})
commentAdded() {
  return pubSub.asyncIterableIterator('commentAdded');
}
```

The last step is to update the type definitions file.

```graphql

type Author {
  id: Int!
  firstName: String
  lastName: String
  posts: [Post]
}

type Post {
  id: Int!
  title: String
  votes: Int
}

type Query {
  author(id: Int!): Author
}

type Comment {
  id: String
  content: String
}

type Subscription {
  commentAdded(title: String!): Comment
}
```

With this, we've created a single `commentAdded(title: String!): Comment` subscription. You can find a full sample implementation [here](https://github.com/nestjs/nest/blob/master/sample/12-graphql-schema-first).

#### PubSub[#](/graphql/subscriptions#pubsub)

We instantiated a local `PubSub` instance above. The preferred approach is to define `PubSub` as a [provider](/v10/fundamentals/custom-providers) and inject it through the constructor (using the `@Inject()` decorator). This allows us to re-use the instance across the whole application. For example, define a provider as follows, then inject `'PUB_SUB'` where needed.

```typescript

{
  provide: 'PUB_SUB',
  useValue: new PubSub(),
}
```

#### Customize subscriptions server[#](/graphql/subscriptions#customize-subscriptions-server)

To customize the subscriptions server (e.g., change the path), use the `subscriptions` options property.

```typescript

GraphQLModule.forRoot<ApolloDriverConfig>({
  driver: ApolloDriver,
  subscriptions: {
    'subscriptions-transport-ws': {
      path: '/graphql'
    },
  }
}),
```

If you're using the `graphql-ws` package for subscriptions, replace the `subscriptions-transport-ws` key with `graphql-ws`, as follows:

```typescript

GraphQLModule.forRoot<ApolloDriverConfig>({
  driver: ApolloDriver,
  subscriptions: {
    'graphql-ws': {
      path: '/graphql'
    },
  }
}),
```

#### Authentication over WebSockets[#](/graphql/subscriptions#authentication-over-websockets)

Checking whether the user is authenticated can be done inside the `onConnect` callback function that you can specify in the `subscriptions` options.

The `onConnect` will receive as a first argument the `connectionParams` passed to the `SubscriptionClient` (read [more](https://www.apollographql.com/docs/react/data/subscriptions/#5-authenticate-over-websocket-optional)).

```typescript

GraphQLModule.forRoot<ApolloDriverConfig>({
  driver: ApolloDriver,
  subscriptions: {
    'subscriptions-transport-ws': {
      onConnect: (connectionParams) => {
        const authToken = connectionParams.authToken;
        if (!isValid(authToken)) {
          throw new Error('Token is not valid');
        }
        // extract user information from token
        const user = parseToken(authToken);
        // return user info to add them to the context later
        return { user };
      },
    }
  },
  context: ({ connection }) => {
    // connection.context will be equal to what was returned by the "onConnect" callback
  },
}),
```

The `authToken` in this example is only sent once by the client, when the connection is first established. All subscriptions made with this connection will have the same `authToken`, and thus the same user info.

> **Note** There is a bug in `subscriptions-transport-ws` that allows connections to skip the `onConnect` phase (read [more](https://github.com/apollographql/subscriptions-transport-ws/issues/349)). You should not assume that `onConnect` was called when the user starts a subscription, and always check that the `context` is populated.

If you're using the `graphql-ws` package, the signature of the `onConnect` callback will be slightly different:

```typescript

GraphQLModule.forRoot<ApolloDriverConfig>({
  driver: ApolloDriver,
  subscriptions: {
    'graphql-ws': {
      onConnect: (context: Context<any>) => {
        const { connectionParams, extra } = context;
        // user validation will remain the same as in the example above
        // when using with graphql-ws, additional context value should be stored in the extra field
        extra.user = { user: {} };
      },
    },
  },
  context: ({ extra }) => {
    // you can now access your additional context value through the extra field
  },
});
```

#### Enable subscriptions with Mercurius driver[#](/graphql/subscriptions#enable-subscriptions-with-mercurius-driver)

To enable subscriptions, set the `subscription` property to `true`.

```typescript

GraphQLModule.forRoot<MercuriusDriverConfig>({
  driver: MercuriusDriver,
  subscription: true,
}),
```

> **Hint** You can also pass the options object to set up a custom emitter, validate incoming connections, etc. Read more [here](https://github.com/mercurius-js/mercurius/blob/master/docs/api/options.md#plugin-options) (see `subscription`).

#### Code first[#](/graphql/subscriptions#code-first-1)

To create a subscription using the code first approach, we use the `@Subscription()` decorator (exported from the `@nestjs/graphql` package) and the `PubSub` class from the `mercurius` package, which provides a simple **publish/subscribe API**.

The following subscription handler takes care of **subscribing** to an event by calling `PubSub#asyncIterableIterator`. This method takes a single argument, the `triggerName`, which corresponds to an event topic name.

```typescript

@Resolver(() => Author)
export class AuthorResolver {
  // ...
  @Subscription(() => Comment)
  commentAdded(@Context('pubsub') pubSub: PubSub) {
    return pubSub.subscribe('commentAdded');
  }
}
```

> **Hint** All decorators used in the example above are exported from the `@nestjs/graphql` package, while the `PubSub` class is exported from the `mercurius` package.

> **Note**`PubSub` is a class that exposes a simple `publish` and `subscribe` API. Check out [this section](https://github.com/mercurius-js/mercurius/blob/master/docs/subscriptions.md#subscriptions-with-custom-pubsub) on how to register a custom `PubSub` class.

This will result in generating the following part of the GraphQL schema in SDL:

```graphql

type Subscription {
  commentAdded(): Comment!
}
```

Note that subscriptions, by definition, return an object with a single top level property whose key is the name of the subscription. This name is either inherited from the name of the subscription handler method (i.e., `commentAdded` above), or is provided explicitly by passing an option with the key `name` as the second argument to the `@Subscription()` decorator, as shown below.

```typescript

@Subscription(() => Comment, {
  name: 'commentAdded',
})
subscribeToCommentAdded(@Context('pubsub') pubSub: PubSub) {
  return pubSub.subscribe('commentAdded');
}
```

This construct produces the same SDL as the previous code sample, but allows us to decouple the method name from the subscription.

#### Publishing[#](/graphql/subscriptions#publishing-1)

Now, to publish the event, we use the `PubSub#publish` method. This is often used within a mutation to trigger a client-side update when a part of the object graph has changed. For example:

posts/posts.resolver.ts

JS TS

```typescript

@Mutation(() => Comment)
async addComment(
  @Args('postId', { type: () => Int }) postId: number,
  @Args('comment', { type: () => Comment }) comment: CommentInput,
  @Context('pubsub') pubSub: PubSub,
) {
  const newComment = this.commentsService.addComment({ id: postId, comment });
  await pubSub.publish({
    topic: 'commentAdded',
    payload: {
      commentAdded: newComment
    }
  });
  return newComment;
}
```

As mentioned, the subscription, by definition, returns a value and that value has a shape. Look again at the generated SDL for our `commentAdded` subscription:

```graphql

type Subscription {
  commentAdded(): Comment!
}
```

This tells us that the subscription must return an object with a top-level property name of `commentAdded` that has a value which is a `Comment` object. The important point to note is that the shape of the event payload emitted by the `PubSub#publish` method must correspond to the shape of the value expected to return from the subscription. So, in our example above, the `pubSub.publish({ topic: 'commentAdded', payload: { commentAdded: newComment } })` statement publishes a `commentAdded` event with the appropriately shaped payload. If these shapes don't match, your subscription will fail during the GraphQL validation phase.

#### Filtering subscriptions[#](/graphql/subscriptions#filtering-subscriptions-1)

To filter out specific events, set the `filter` property to a filter function. This function acts similar to the function passed to an array `filter`. It takes two arguments: `payload` containing the event payload (as sent by the event publisher), and `variables` taking any arguments passed in during the subscription request. It returns a boolean determining whether this event should be published to client listeners.

```typescript

@Subscription(() => Comment, {
  filter: (payload, variables) =>
    payload.commentAdded.title === variables.title,
})
commentAdded(@Args('title') title: string, @Context('pubsub') pubSub: PubSub) {
  return pubSub.subscribe('commentAdded');
}
```

If you need to access injected providers (e.g., use an external service to validate the data), use the following construction.

```typescript

@Subscription(() => Comment, {
  filter(this: AuthorResolver, payload, variables) {
    // "this" refers to an instance of "AuthorResolver"
    return payload.commentAdded.title === variables.title;
  }
})
commentAdded(@Args('title') title: string, @Context('pubsub') pubSub: PubSub) {
  return pubSub.subscribe('commentAdded');
}
```

#### Schema first[#](/graphql/subscriptions#schema-first-1)

To create an equivalent subscription in Nest, we'll make use of the `@Subscription()` decorator.

```typescript

const pubSub = new PubSub();

@Resolver('Author')
export class AuthorResolver {
  // ...
  @Subscription()
  commentAdded(@Context('pubsub') pubSub: PubSub) {
    return pubSub.subscribe('commentAdded');
  }
}
```

To filter out specific events based on context and arguments, set the `filter` property.

```typescript

@Subscription('commentAdded', {
  filter: (payload, variables) =>
    payload.commentAdded.title === variables.title,
})
commentAdded(@Context('pubsub') pubSub: PubSub) {
  return pubSub.subscribe('commentAdded');
}
```

If you need to access injected providers (e.g., use an external service to validate the data), use the following construction:

```typescript

@Subscription('commentAdded', {
  filter(this: AuthorResolver, payload, variables) {
    // "this" refers to an instance of "AuthorResolver"
    return payload.commentAdded.title === variables.title;
  }
})
commentAdded(@Context('pubsub') pubSub: PubSub) {
  return pubSub.subscribe('commentAdded');
}
```

The last step is to update the type definitions file.

```graphql

type Author {
  id: Int!
  firstName: String
  lastName: String
  posts: [Post]
}

type Post {
  id: Int!
  title: String
  votes: Int
}

type Query {
  author(id: Int!): Author
}

type Comment {
  id: String
  content: String
}

type Subscription {
  commentAdded(title: String!): Comment
}
```

With this, we've created a single `commentAdded(title: String!): Comment` subscription.

#### PubSub[#](/graphql/subscriptions#pubsub-1)

In the examples above, we used the default `PubSub` emitter ([mqemitter](https://github.com/mcollina/mqemitter)) The preferred approach (for production) is to use `mqemitter-redis`. Alternatively, a custom `PubSub` implementation can be provided (read more [here](https://github.com/mercurius-js/mercurius/blob/master/docs/subscriptions.md))

```typescript

GraphQLModule.forRoot<MercuriusDriverConfig>({
  driver: MercuriusDriver,
  subscription: {
    emitter: require('mqemitter-redis')({
      port: 6579,
      host: '127.0.0.1',
    }),
  },
});
```

#### Authentication over WebSockets[#](/graphql/subscriptions#authentication-over-websockets-1)

Checking whether the user is authenticated can be done inside the `verifyClient` callback function that you can specify in the `subscription` options.

The `verifyClient` will receive the `info` object as a first argument which you can use to retrieve the request's headers.

```typescript

GraphQLModule.forRoot<MercuriusDriverConfig>({
  driver: MercuriusDriver,
  subscription: {
    verifyClient: (info, next) => {
      const authorization = info.req.headers?.authorization as string;
      if (!authorization?.startsWith('Bearer ')) {
        return next(false);
      }
      next(true);
    },
  }
}),
```

----
url: https://docs.nestjs.com/v4/interceptors
----

### Interceptors

An interceptor is a class with the `@Interceptor()` decorator. The interceptor should implement the `NestInterceptor` interface.

Interceptors have a set of useful capabilities, which are inspired by the **Aspect-Oriented Programming** (AOP) technique. They make it possible to:

* bind **extra logic** before / after method execution
* **transform** the result returned from a function
* **transform** the exception thrown from a function
* completely **override** a function depending on the chosen conditions (e.g. caching purposes)

#### Basics

Each interceptor has the `intercept()` method. This function takes 3 arguments. First one is `dataOrRequest`. This value depends on where you actually have used the interceptor. When it's a HTTP request, this variable is a native expressjs [request](http://expressjs.com/en/api.html#req) object, otherwise, it's the data passed to the micro service / or web socket. The second argument is a `context`, which is exactly the same as in [Guards](/v4/guards). This object fulfils the `ExecutionContext` interface and contains 2 members - `parent` and `handler`. The `parent` holds the type of the `Controller` class, which the `handler` belongs to. The `handler` is a reference to the route handler function. The last one `stream$` is an `Observable`. If you'd not return this stream, the function won't be evaluated.

#### Before / After

The first use case is using the interceptor to provide extra logic before or after the function execution. It's useful when we're gonna **log interaction** with the application, e.g. storing user calls, or calculating the timestamp.

Let's create a simple `LoggingInterceptor`.

logging.interceptor.ts

JavaScript TypeScript

TypeScript

```typescript

import { Interceptor, NestInterceptor, ExecutionContext } from '@nestjs/common';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/do';

@Interceptor()
export class LoggingInterceptor implements NestInterceptor {
  intercept(dataOrRequest, context: ExecutionContext, stream$: Observable<any>): Observable<any> {
    console.log('Before...');
    const now = Date.now();

    return stream$.do(
      () => console.log(`After... ${Date.now() - now}ms`),
    );
  }
}
```

TypeScript

```typescript

import { Interceptor } from '@nestjs/common';
import 'rxjs/add/operator/do';

@Interceptor()
export class LoggingInterceptor {
  intercept(dataOrRequest, context, stream$) {
    console.log('Before...');
    const now = Date.now();

    return stream$.do(
      () => console.log(`After... ${Date.now() - now}ms`),
    );
  }
}
```

> **Notice** Interceptors act the same as controllers, components, guards and middleware they can **inject dependencies** through the constructor.

Since `stream$` is a [RxJS](https://github.com/reactivex/rxjs) `Observable`, we have a lot of various operators which we can use to manipulate the stream. In the example above, I've used the `do()` operator, which invokes the function upon graceful or exceptional termination of the observable sequence.

To set up the interceptor, we're using the `@UseInterceptors()` decorator imported from the `@nestjs/common` package. Same as [guards](/v4/guards), interceptors can be controller-scoped, method-scoped and global-scoped.

cats.controller.ts

JavaScript TypeScript

TypeScript

```typescript

@UseInterceptors(LoggingInterceptor)
export class CatsController {}
```

Now every route handler within `CatsController` is using `LoggingInterceptor`. When someone would call the GET `/cats` endpoint, you'll see similar output in your console window:

TypeScript

```typescript

Before...
After... 1ms
```

To bind the global interceptor, we're using the `useGlobalInterceptors()` method of the Nest application instance:

TypeScript

```typescript

const app = await NestFactory.create(ApplicationModule);
app.useGlobalInterceptors(new LoggingInterceptor());
```

#### Response mapping

The `stream$` is an `Observable`. This object contains the **returned** value of the route handler, so we can easily mutate it using the `map()` operator.

> **Notice** The response mapping doesn't work with the express response strategy (using the `@Res()` object directly is not possible).

Let's create the `TransformInterceptor` which will pack the response and assign it to the `data` property.

transform.interceptor.ts

JavaScript TypeScript

TypeScript

```typescript

import { Interceptor, NestInterceptor, ExecutionContext } from '@nestjs/common';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';

@Interceptor()
export class TransformInterceptor implements NestInterceptor {
  intercept(dataOrRequest, context: ExecutionContext, stream$: Observable<any>): Observable<any> {
    return stream$.map((data) => ({ data }));
  }
}
```

TypeScript

```typescript

import { Interceptor } from '@nestjs/common';
import 'rxjs/add/operator/map';

@Interceptor()
export class TransformInterceptor {
  intercept(dataOrRequest, context, stream$) {
    return stream$.map((data) => ({ data }));
  }
}
```

> **Hint** The `intercept()` method can be `async`.

Now, the response of the GET `/cats` request would look something like this:

TypeScript

```typescript

{
    "data": []
}
```

#### Exception mapping

Since `stream$` is an `Observable`, we can use the `catch()` operator to override the thrown exception with a new stream:

exception.interceptor.ts

JavaScript TypeScript

TypeScript

```typescript

import { Interceptor, NestInterceptor, ExecutionContext, HttpStatus } from '@nestjs/common';
import { HttpException } from '@nestjs/common';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/catch';
import 'rxjs/add/observable/throw';

@Interceptor()
export class ExceptionInterceptor implements NestInterceptor {
  intercept(dataOrRequest, context: ExecutionContext, stream$: Observable<any>): Observable<any> {
    return stream$.catch((err) => Observable.throw(
      new HttpException('Exception interceptor message', HttpStatus.BAD_GATEWAY),
    ));
  }
}
```

TypeScript

```typescript

import { Interceptor, HttpStatus } from '@nestjs/common';
import { HttpException } from '@nestjs/common';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/catch';
import 'rxjs/add/observable/throw';

@Interceptor()
export class ExceptionInterceptor {
  intercept(dataOrRequest, context, stream$) {
    return stream$.catch((err) => Observable.throw(
      new HttpException('Exception interceptor message', HttpStatus.BAD_GATEWAY),
    ));
  }
}
```

#### Stream overriding

Sometimes we might want to completely prevent calling the handler and return a different value instead. An excellent example of this is a **cache interceptor**, which would store the cached responses with some time.

cache.interceptor.ts

JavaScript TypeScript

TypeScript

```typescript

import { Interceptor, NestInterceptor, ExecutionContext } from '@nestjs/common';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/of';

@Interceptor()
export class CacheInterceptor implements NestInterceptor {
  intercept(dataOrRequest, context: ExecutionContext, stream$: Observable<any>): Observable<any> {
    const isCached = true;
    if (isCached) {
      return Observable.of([]);
    }
    return stream$;
  } 
}
```

TypeScript

```typescript

import { Interceptor } from '@nestjs/common';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/of';

@Interceptor()
export class CacheInterceptor {
  intercept(dataOrRequest, context, stream$) {
    const isCached = true;
    if (isCached) {
      return Observable.of([]);
    }
    return stream$;
  } 
}
```

Here's a `CacheInterceptor` with a hardcoded `isCached` variable and the cached response `[]`. Since we're returning a new stream created through the `of` operator, the route handler **won't be called**. To create a generic solution, you can use the `Reflector` and create a custom decorator. It's well described in the [guards](/v4/guards) article. That's everything.

> **Hint** Exceptions thrown within interceptors can be caught by [exception filters](/v4/exception-filters).

#### Global interceptors

Global interceptors don't belong to any scope. They live outside modules, thus as a result - they can't inject dependencies. We need to create an instance immediately. But quite often, global interceptors depend on other objects, for example, we'd love to dispatch an asynchronous event on each request using `EventsService`, but this service is a part of the `EventsModule`. How do we solve this?

The solution is pretty easy. Each Nest application instance is in fact, a created **Nest context**. The Nest context is a wrapper around the Nest container, which holds all instantiated classes. We can grab any existing instance from within any imported module directly using the application object.

Let's assume that we have a `EventsInterceptor` registered in the `EventsModule`. This `EventsModule` is imported into the **root module**. We can pick the `EventsInterceptor` instance using the following syntax:

TypeScript

```typescript

const app = await NestFactory.create(ApplicationModule);
const eventsInterceptor = app
  .select(EventsModule)
  .get(EventsInterceptor);

app.useGlobalInterceptors(eventsInterceptor);
```

To grab `EventsInterceptor` instance we have used 2 methods, well-described in the table below:

|            |                                                                                                                        |
| ---------- | ---------------------------------------------------------------------------------------------------------------------- |
| `get()`    | Makes it possible to retrieve the instance of the component or controller available inside the processed module.       |
| `select()` | Allows you to navigate through the module tree, for example, to pull out a specific instance from the selected module. |

> **Hint** The root module is selected by default. To select any other module, you need to go through the entire modules stack (step by step).

#### Sponsors

[](https://valor-software.com/)

Nest is an MIT-licensed open source project. It can grow thanks to the support by these awesome people. If you'd like to join them, please read more [here](https://opencollective.com/nest). Thanks!

[](https://opencollective.com/nest/backer/0/website)[](https://opencollective.com/nest/backer/1/website)[](https://opencollective.com/nest/backer/2/website)[](https://opencollective.com/nest/backer/3/website)[](https://opencollective.com/nest/backer/4/website)[](https://opencollective.com/nest/backer/5/website)[](https://opencollective.com/nest/backer/6/website)[](https://opencollective.com/nest/backer/7/website)[](https://opencollective.com/nest/backer/8/website)[](https://opencollective.com/nest/backer/9/website)[](https://opencollective.com/nest/backer/10/website)[](https://opencollective.com/nest/backer/11/website)[](https://opencollective.com/nest/backer/12/website)[](https://opencollective.com/nest/backer/13/website)[](https://opencollective.com/nest/backer/14/website)[](https://opencollective.com/nest/backer/15/website)[](https://opencollective.com/nest/backer/16/website)[](https://opencollective.com/nest/backer/17/website)[](https://opencollective.com/nest/backer/18/website)[](https://opencollective.com/nest/backer/19/website)[](https://opencollective.com/nest/backer/20/website)[](https://opencollective.com/nest/backer/21/website)[](https://opencollective.com/nest/backer/22/website)[](https://opencollective.com/nest/backer/23/website)[](https://opencollective.com/nest/backer/24/website)[](https://opencollective.com/nest/backer/25/website)[](https://opencollective.com/nest/backer/26/website)[](https://opencollective.com/nest/backer/27/website)[](https://opencollective.com/nest/backer/28/website)[](https://opencollective.com/nest/backer/29/website)

[Become a sponsor](https://opencollective.com/nest)

----
url: https://docs.nestjs.com/v10/graphql/extensions
----

* [Extensions](https://docs.nestjs.com/v10/graphql/extensions#extensions)
* [Adding custom metadata](https://docs.nestjs.com/v10/graphql/extensions#adding-custom-metadata)
* [Using custom metadata](https://docs.nestjs.com/v10/graphql/extensions#using-custom-metadata)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/extensions.md "Suggest Edits")

### Extensions

> **Warning** This chapter applies only to the code first approach.

Extensions is an **advanced, low-level feature** that lets you define arbitrary data in the types configuration. Attaching custom metadata to certain fields allows you to create more sophisticated, generic solutions. For example, with extensions, you can define field-level roles required to access particular fields. Such roles can be reflected at runtime to determine whether the caller has sufficient permissions to retrieve a specific field.

#### Adding custom metadata[#](/graphql/extensions#adding-custom-metadata)

To attach custom metadata for a field, use the `@Extensions()` decorator exported from the `@nestjs/graphql` package.

```typescript

@Field()
@Extensions({ role: Role.ADMIN })
password: string;
```

In the example above, we assigned the `role` metadata property the value of `Role.ADMIN`. `Role` is a simple TypeScript enum that groups all the user roles available in our system.

Note, in addition to setting metadata on fields, you can use the `@Extensions()` decorator at the class level and method level (e.g., on the query handler).

#### Using custom metadata[#](/graphql/extensions#using-custom-metadata)

Logic that leverages the custom metadata can be as complex as needed. For example, you can create a simple interceptor that stores/logs events per method invocation, or a [field middleware](/v10/graphql/field-middleware) that matches roles required to retrieve a field with the caller permissions (field-level permissions system).

For illustration purposes, let's define a `checkRoleMiddleware` that compares a user's role (hardcoded here) with a role required to access a target field:

```typescript

export const checkRoleMiddleware: FieldMiddleware = async (
  ctx: MiddlewareContext,
  next: NextFn,
) => {
  const { info } = ctx;
  const { extensions } = info.parentType.getFields()[info.fieldName];

  /**
   * In a real-world application, the "userRole" variable
   * should represent the caller's (user) role (for example, "ctx.user.role").
   */
  const userRole = Role.USER;
  if (userRole === extensions.role) {
    // or just "return null" to ignore
    throw new ForbiddenException(
      `User does not have sufficient permissions to access "${info.fieldName}" field.`,
    );
  }
  return next();
};
```

With this in place, we can register a middleware for the `password` field, as follows:

```typescript

@Field({ middleware: [checkRoleMiddleware] })
@Extensions({ role: Role.ADMIN })
password: string;
```

----
url: https://docs.nestjs.com/v8/openapi/introduction
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Introduction](https://docs.nestjs.com/v8/openapi/introduction#introduction)
* [Installation](https://docs.nestjs.com/v8/openapi/introduction#installation)
* [Bootstrap](https://docs.nestjs.com/v8/openapi/introduction#bootstrap)
* [Document options](https://docs.nestjs.com/v8/openapi/introduction#document-options)
* [Setup options](https://docs.nestjs.com/v8/openapi/introduction#setup-options)
* [Example](https://docs.nestjs.com/v8/openapi/introduction#example)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/openapi/introduction.md "Suggest Edits")

### Introduction

The [OpenAPI](https://swagger.io/specification/) specification is a language-agnostic definition format used to describe RESTful APIs. Nest provides a dedicated [module](https://github.com/nestjs/swagger) which allows generating such a specification by leveraging decorators.

#### Installation[#](/openapi/introduction#installation)

To begin using it, we first install the required dependencies.

```bash

$ npm install --save @nestjs/swagger swagger-ui-express
```

If you use fastify, install `fastify-swagger` instead of `swagger-ui-express`:

```bash

$ npm install --save @nestjs/swagger fastify-swagger
```

#### Bootstrap[#](/openapi/introduction#bootstrap)

Once the installation process is complete, open the `main.ts` file and initialize Swagger using the `SwaggerModule` class:

main.ts

JS TS

```typescript

import { NestFactory } from '@nestjs/core';
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);

  const config = new DocumentBuilder()
    .setTitle('Cats example')
    .setDescription('The cats API description')
    .setVersion('1.0')
    .addTag('cats')
    .build();
  const document = SwaggerModule.createDocument(app, config);
  SwaggerModule.setup('api', app, document);

  await app.listen(3000);
}
bootstrap();
```

> **Hint**`document` (returned by the `SwaggerModule#createDocument()` method) is a serializable object conforming to [OpenAPI Document](https://swagger.io/specification/#openapi-document). Instead of hosting it via HTTP, you could also save it as a JSON/YAML file, and consume it in different ways.

```bash

$ npm run start
```

While the application is running, open your browser and navigate to `http://localhost:3000/api`. You should see the Swagger UI.

The `SwaggerModule` automatically reflects all of your endpoints. Note that the Swagger UI is created using either `swagger-ui-express` or `fastify-swagger`, depending on the platform.

> **Hint** To generate and download a Swagger JSON file, navigate to `http://localhost:3000/api-json` (`swagger-ui-express`) or `http://localhost:3000/api/json` (`fastify-swagger`) in your browser (assuming that your Swagger documentation is available under `http://localhost:3000/api`).

> **Warning** When using `fastify-swagger` and `helmet`, there may be a problem with [CSP](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP), to solve this collision, configure the CSP as shown below:
>
> ```typescript
>
> app.register(helmet, {
>   contentSecurityPolicy: {
>     directives: {
>       defaultSrc: [`'self'`],
>       styleSrc: [`'self'`, `'unsafe-inline'`],
>       imgSrc: [`'self'`, 'data:', 'validator.swagger.io'],
>       scriptSrc: [`'self'`, `https: 'unsafe-inline'`],
>     },
>   },
> });
>
> // If you are not going to use CSP at all, you can use this:
> app.register(helmet, {
>   contentSecurityPolicy: false,
> });
> ```

#### Document options[#](/openapi/introduction#document-options)

When creating a document, it is possible to provide some extra options to fine tune the library's behavior. These options should be of type `SwaggerDocumentOptions`, which can be the following:

```typescript

export interface SwaggerDocumentOptions {
  /**
   * List of modules to include in the specification
   */
  include?: Function[];

  /**
   * Additional, extra models that should be inspected and included in the specification
   */
  extraModels?: Function[];

  /**
   * If `true`, swagger will ignore the global prefix set through `setGlobalPrefix()` method
   */
  ignoreGlobalPrefix?: boolean;

  /**
   * If `true`, swagger will also load routes from the modules imported by `include` modules
   */
  deepScanRoutes?: boolean;

  /**
   * Custom operationIdFactory that will be used to generate the `operationId`
   * based on the `controllerKey` and `methodKey`
   * @default () => controllerKey_methodKey
   */
  operationIdFactory?: (controllerKey: string, methodKey: string) => string;
}
```

For example, if you want to make sure that the library generates operation names like `createUser` instead of `UserController_createUser`, you can set the following:

```typescript

const options: SwaggerDocumentOptions =  {
  operationIdFactory: (
    controllerKey: string,
    methodKey: string
  ) => methodKey
};
const document = SwaggerModule.createDocument(app, config, options);
```

#### Setup options[#](/openapi/introduction#setup-options)

You can configure Swagger UI by passing the options object which fulfills the `ExpressSwaggerCustomOptions` (if you use express) interface as a fourth argument of the `SwaggerModule#setup` method.

```typescript

export interface ExpressSwaggerCustomOptions {
  explorer?: boolean;
  swaggerOptions?: Record<string, any>;
  customCss?: string;
  customCssUrl?: string;
  customJs?: string;
  customfavIcon?: string;
  swaggerUrl?: string;
  customSiteTitle?: string;
  validatorUrl?: string;
  url?: string;
  urls?: Record<'url' | 'name', string>[];
}
```

If you use fastify, you can configure the user interface by passing the `FastifySwaggerCustomOptions` object.

```typescript

export interface FastifySwaggerCustomOptions {
  uiConfig?: Record<string, any>;
}
```

For example, if you want to make sure that the authentication token persists after refreshing the page, or change the page title (that shows up in the browser), you can use the following settings:

```typescript

const customOptions: SwaggerCustomOptions = {
  swaggerOptions: {
    persistAuthorization: true,
  },
  customSiteTitle: 'My API Docs',
};
SwaggerModule.setup('docs', app, document, customOptions);
```

#### Example[#](/openapi/introduction#example)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/11-swagger).

----
url: https://docs.nestjs.com/v7/graphql/generating-sdl
----

* [Generating SDL](https://docs.nestjs.com/v7/graphql/generating-sdl#generating-sdl)
* [Usage](https://docs.nestjs.com/v7/graphql/generating-sdl#usage)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/schema-generator.md "Suggest Edits")

### Generating SDL

> **Warning** This chapter applies only to the code first approach.

To manually generate a GraphQL SDL schema (i.e., without running an application, connecting to the database, hooking up resolvers, etc.), use the `GraphQLSchemaBuilderModule`.

```typescript

async function generateSchema() {
  const app = await NestFactory.create(GraphQLSchemaBuilderModule);
  await app.init();

  const gqlSchemaFactory = app.get(GraphQLSchemaFactory);
  const schema = await gqlSchemaFactory.create([RecipesResolver]);
  console.log(printSchema(schema));
}
```

> **Hint** The `GraphQLSchemaBuilderModule` and `GraphQLSchemaFactory` are imported from the `@nestjs/graphql` package. The `printSchema` function is imported from the `graphql` package.

#### Usage[#](/graphql/generating-sdl#usage)

The `gqlSchemaFactory.create()` method takes an array of resolver class references. For example:

```typescript

const schema = await gqlSchemaFactory.create([
  RecipesResolver,
  AuthorsResolver,
  PostsResolvers,
]);
```

It also takes a second optional argument with an array of scalar classes:

```typescript

const schema = await gqlSchemaFactory.create(
  [RecipesResolver, AuthorsResolver, PostsResolvers],
  [DurationScalar, DateScalar],
);
```

Lastly, you can pass an options object:

```typescript

const schema = await gqlSchemaFactory.create([RecipesResolver], {
  skipCheck: true,
  orphanedTypes: [],
});
```

* `skipCheck`: ignore schema validation; boolean, defaults to `false`
* `orphanedTypes`: list of classes that are not explicitly referenced (not part of the object graph) to be generated. Normally, if a class is declared but isn't otherwise referenced in the graph, it's omitted. The property value is an array of class references.

----
url: https://docs.nestjs.com/v5/techniques/logger
----

### Logger

Nest comes with a default implementation of internal `Logger` that is used during the instantiation process and also, in several different situations, such as **occurred exception**, and so on. But sometimes, you might want to disable logging entirely, or provide a custom implementation and handle messages on your own. In order to turn off a logger, we use a Nest's options object.

TypeScript

```typescript

const app = await NestFactory.create(ApplicationModule, {
  logger: false,
});
await app.listen(3000);
```

Nevertheless, we could want to use a different logger under the hood, instead of disabling a whole logging mechanism. In order to do that, we have to pass an object that fulfills `LoggerService` interface. An example could be a built-in `console`.

TypeScript

```typescript

const app = await NestFactory.create(ApplicationModule, {
  logger: console,
});
await app.listen(3000);
```

But it's not an apt idea. However, we can create our own logger easily.

TypeScript

```typescript

import { LoggerService } from '@nestjs/common';

export class MyLogger implements LoggerService {
  log(message: string) {}
  error(message: string, trace: string) {}
  warn(message: string) {}
}
```

Then, we can apply `MyLogger` instance directly:

TypeScript

```typescript

const app = await NestFactory.create(ApplicationModule, {
  logger: new MyLogger(),
});
await app.listen(3000);
```

#### Extend built-in logger

Lot of use cases require creating your own logger. You don't have to entirely reinvent the wheel though. Simply extend built-in `Logger` class to partially override the default implementation, and use `super` to delegate the call to the parent class.

TypeScript

```typescript

import { Logger } from '@nestjs/common';

export class MyLogger extends Logger {
  error(message: string, trace: string) {
    // add your custom business logic
    super.error(message, trace);
  }
}
```

#### Dependency injection

If you want to enable dependency injection in your logger, you have to make the `MyLogger` class a part of the real application. For instance, you can create a `LoggerModule`.

TypeScript

```typescript

import { Module } from '@nestjs/common';
import { MyLogger } from './my-logger.service.ts';

@Module({
  providers: [MyLogger],
  exports: [MyLogger],
})
export class LoggerModule {};
```

Once `LoggerModule` is imported anywhere, the framework will take charge of creating an instance of your logger. Now, to use the same instance of a logger across the whole app, including bootstraping and error handling stuff, use following construction:

TypeScript

```typescript

const app = await NestFactory.create(ApplicationModule, {
  logger: false,
});
app.useLogger(app.get(MyLogger));
await app.listen(3000);
```

The only downside of this solution is that your first initialization messages won't be handled by your logger instance, though, it shouldn't really matter at this point.

* Logger
* Extend built-in logger
* Dependency injection

----
url: https://docs.nestjs.com/openapi/security
----

[Skip to content](#content)

On this page

* [Security](https://docs.nestjs.com/openapi/security#security)
* [Basic authentication](https://docs.nestjs.com/openapi/security#basic-authentication)
* [Bearer authentication](https://docs.nestjs.com/openapi/security#bearer-authentication)
* [OAuth2 authentication](https://docs.nestjs.com/openapi/security#oauth2-authentication)
* [Cookie authentication](https://docs.nestjs.com/openapi/security#cookie-authentication)

### Security

To define which security mechanisms a specific operation uses, apply the `@ApiSecurity()` decorator:

```typescript

@ApiSecurity('basic')
@Controller('cats')
export class CatsController {}
```

Before you run your application, add the security definition to your base document using `DocumentBuilder`:

```typescript

const options = new DocumentBuilder().addSecurity('basic', {
  type: 'http',
  scheme: 'basic',
});
```

The most popular authentication techniques (e.g., `basic` and `bearer`) are built in, so you don't have to define their security mechanisms manually as shown above.

#### Basic authentication[#](/openapi/security#basic-authentication)

To enable basic authentication, use `@ApiBasicAuth()`:

```typescript

@ApiBasicAuth()
@Controller('cats')
export class CatsController {}
```

Before you run your application, add the security definition to your base document using `DocumentBuilder`:

```typescript

const options = new DocumentBuilder().addBasicAuth();
```

#### Bearer authentication[#](/openapi/security#bearer-authentication)

To enable bearer authentication, use `@ApiBearerAuth()`:

```typescript

@ApiBearerAuth()
@Controller('cats')
export class CatsController {}
```

Before you run your application, add the security definition to your base document using `DocumentBuilder`:

```typescript

const options = new DocumentBuilder().addBearerAuth();
```

#### OAuth2 authentication[#](/openapi/security#oauth2-authentication)

To enable OAuth2, use `@ApiOAuth2()`:

```typescript

@ApiOAuth2(['pets:write'])
@Controller('cats')
export class CatsController {}
```

Before you run your application, add the security definition to your base document using `DocumentBuilder`:

```typescript

const options = new DocumentBuilder().addOAuth2();
```

#### Cookie authentication[#](/openapi/security#cookie-authentication)

To enable cookie authentication, use `@ApiCookieAuth()`:

```typescript

@ApiCookieAuth()
@Controller('cats')
export class CatsController {}
```

Before you run your application, add the security definition to your base document using `DocumentBuilder`:

```typescript

const options = new DocumentBuilder().addCookieAuth('optional-session-id');
```

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/openapi/security.md)

----
url: https://docs.nestjs.com/v6/techniques/performance
----

* [Performance (Fastify)](https://docs.nestjs.com/v6/techniques/performance#performance-fastify)
* [Installation](https://docs.nestjs.com/v6/techniques/performance#installation)
* [Adapter](https://docs.nestjs.com/v6/techniques/performance#adapter)
* [Platform specific packages](https://docs.nestjs.com/v6/techniques/performance#platform-specific-packages)
* [Redirect response](https://docs.nestjs.com/v6/techniques/performance#redirect-response)
* [Fastify options](https://docs.nestjs.com/v6/techniques/performance#fastify-options)
* [Example](https://docs.nestjs.com/v6/techniques/performance#example)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/techniques/performance.md "Suggest Edits")

### Performance (Fastify)

By default, Nest makes use of the [Express](https://expressjs.com/) framework. As mentioned earlier, Nest also provides compatibility with other libraries such as, for example, [Fastify](https://github.com/fastify/fastify). Nest achieves this framework independence by implementing a framework adapter whose primary function is to proxy middleware and handlers to appropriate library-specific implementations.

> **Hint** Note that in order for a framework adapter to be implemented, the target library has to provide similar request/response pipeline processing as found in Express.

[Fastify](https://github.com/fastify/fastify) provides a good alternative framework for Nest because it solves design issues in a similar manner to Express. However, fastify is much **faster** than Express, achieving almost two times better benchmarks results. A fair question is why does Nest use Express as the default HTTP provider? The reason is that Express is widely-used, well-known, and has an enormous set of compatible middleware, which is available to Nest users out-of-the-box.

But since Nest provides framework-independence, you can easily migrate between them. Fastify can be a better choice when you place high value on very fast performance. To utilize Fastify, simply choose the built-in `FastifyAdapter` as shown in this chapter.

#### Installation[#](/techniques/performance#installation)

First, we need to install the required package:

```bash

$ npm i --save @nestjs/platform-fastify
```

#### Adapter[#](/techniques/performance#adapter)

Once the Fastify platform is installed, we can use the `FastifyAdapter`.

```typescript

import { NestFactory } from '@nestjs/core';
import {
  FastifyAdapter,
  NestFastifyApplication,
} from '@nestjs/platform-fastify';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create<NestFastifyApplication>(
    AppModule,
    new FastifyAdapter()
  );
  await app.listen(3000);
}
bootstrap();
```

By default, Fastify listens only on the `localhost 127.0.0.1` interface ([read more](https://www.fastify.io/docs/latest/Getting-Started/#your-first-server)). If you want to accept connections on other hosts, you should specify `'0.0.0.0'` in the `listen()` call:

```typescript

async function bootstrap() {
  const app = await NestFactory.create<NestFastifyApplication>(
    AppModule,
    new FastifyAdapter()
  );
  await app.listen(3000, '0.0.0.0');
}
```

#### Platform specific packages[#](/techniques/performance#platform-specific-packages)

Keep in mind that when you use the `FastifyAdapter`, Nest uses Fastify as the **HTTP provider**. This means that each recipe that relies on Express may no longer work. You should, instead, use Fastify equivalent packages.

#### Redirect response[#](/techniques/performance#redirect-response)

Fastify handles redirect responses slightly differently than Express. To do a proper redirect with Fastify, return both the status code and the URL, as follows:

```typescript

@Get()
index(@Res() res) {
  res.status(302).redirect('/login');
}
```

#### Fastify options[#](/techniques/performance#fastify-options)

You can pass options into the Fastify constructor through the `FastifyAdapter` constructor. For example:

```typescript

new FastifyAdapter({ logger: true });
```

#### Example[#](/techniques/performance#example)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/10-fastify).

----
url: https://docs.nestjs.com/v6/recipes/sql-typeorm
----

* [SQL (TypeORM)](https://docs.nestjs.com/v6/recipes/sql-typeorm#sql-typeorm)
* [Getting started](https://docs.nestjs.com/v6/recipes/sql-typeorm#getting-started)
* [Repository pattern](https://docs.nestjs.com/v6/recipes/sql-typeorm#repository-pattern)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/recipes/sql-typeorm.md "Suggest Edits")

### SQL (TypeORM)

##### This chapter applies only to TypeScript

> **Warning** In this article, you'll learn how to create a `DatabaseModule` based on the **TypeORM** package from scratch using custom providers mechanism. As a consequence, this solution contains a lot of overhead that you can omit using ready to use and available out-of-the-box dedicated `@nestjs/typeorm` package. To learn more, see [here](/v6/techniques/sql).

[TypeORM](https://github.com/typeorm/typeorm) is definitely the most mature Object Relational Mapper (ORM) available in the node.js world. Since it's written in TypeScript, it works pretty well with the Nest framework.

#### Getting started[#](/recipes/sql-typeorm#getting-started)

To start the adventure with this library we have to install all required dependencies:

```bash

$ npm install --save typeorm mysql
```

The first step we need to do is to establish the connection with our database using `createConnection()` function imported from the `typeorm` package. The `createConnection()` function returns a `Promise`, and therefore we have to create an [async provider](/v6/fundamentals/async-components).

database.providers.ts

JS TS

```typescript

import { createConnection } from 'typeorm';

export const databaseProviders = [
  {
    provide: 'DATABASE_CONNECTION',
    useFactory: async () => await createConnection({
      type: 'mysql',
      host: 'localhost',
      port: 3306,
      username: 'root',
      password: 'root',
      database: 'test',
      entities: [
          __dirname + '/../**/*.entity{.ts,.js}',
      ],
      synchronize: true,
    }),
  },
];
```

> **Hint** Following best practices, we declared the custom provider in the separated file which has a `*.providers.ts` suffix.

Then, we need to export these providers to make them **accessible** for the rest of the application.

database.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { databaseProviders } from './database.providers';

@Module({
  providers: [...databaseProviders],
  exports: [...databaseProviders],
})
export class DatabaseModule {}
```

Now we can inject the `Connection` object using `@Inject()` decorator. Each class that would depend on the `Connection` async provider will wait until a `Promise` is resolved.

#### Repository pattern[#](/recipes/sql-typeorm#repository-pattern)

The [TypeORM](https://github.com/typeorm/typeorm) supports the repository design pattern, thus each entity has its own Repository. These repositories can be obtained from the database connection.

But firstly, we need at least one entity. We are going to reuse the `Photo` entity from the official documentation.

photo.entity.ts

JS TS

```typescript

import { Entity, Column, PrimaryGeneratedColumn } from 'typeorm';

@Entity()
export class Photo {
  @PrimaryGeneratedColumn()
  id: number;

  @Column({ length: 500 })
  name: string;

  @Column('text')
  description: string;

  @Column()
  filename: string;

  @Column('int')
  views: number;

  @Column()
  isPublished: boolean;
}
```

The `Photo` entity belongs to the `photo` directory. This directory represents the `PhotoModule`. Now, let's create a **Repository** provider:

photo.providers.ts

JS TS

```typescript

import { Connection, Repository } from 'typeorm';
import { Photo } from './photo.entity';

export const photoProviders = [
  {
    provide: 'PHOTO_REPOSITORY',
    useFactory: (connection: Connection) => connection.getRepository(Photo),
    inject: ['DATABASE_CONNECTION'],
  },
];
```

> **Notice** In the real-world applications you should avoid **magic strings**. Both `PHOTO_REPOSITORY` and `DATABASE_CONNECTION` should be kept in the separated `constants.ts` file.

Now we can inject the `Repository<Photo>` to the `PhotoService` using the `@Inject()` decorator:

photo.service.ts

JS TS

```typescript

import { Injectable, Inject } from '@nestjs/common';
import { Repository } from 'typeorm';
import { Photo } from './photo.entity';

@Injectable()
export class PhotoService {
  constructor(
    @Inject('PHOTO_REPOSITORY')
    private readonly photoRepository: Repository<Photo>,
  ) {}

  async findAll(): Promise<Photo[]> {
    return this.photoRepository.find();
  }
}
```

The database connection is **asynchronous**, but Nest makes this process completely invisible for the end-user. The `PhotoRepository` is waiting for the db connection, and the `PhotoService` is delayed until repository is ready to use. The entire application can start when each class is instantiated.

Here is a final `PhotoModule`:

photo.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { DatabaseModule } from '../database/database.module';
import { photoProviders } from './photo.providers';
import { PhotoService } from './photo.service';

@Module({
  imports: [DatabaseModule],
  providers: [
    ...photoProviders,
    PhotoService,
  ],
})
export class PhotoModule {}
```

> **Hint** Do not forget to import the `PhotoModule` into the root `ApplicationModule`.

----
url: https://docs.nestjs.com/v11/techniques/queues
----

* [Queues](https://docs.nestjs.com/v11/techniques/queues#queues)
* [BullMQ installation](https://docs.nestjs.com/v11/techniques/queues#bullmq-installation)
* [Named configurations](https://docs.nestjs.com/v11/techniques/queues#named-configurations)
* [Producers](https://docs.nestjs.com/v11/techniques/queues#producers)
* [Job options](https://docs.nestjs.com/v11/techniques/queues#job-options)
* [Consumers](https://docs.nestjs.com/v11/techniques/queues#consumers)
* [Request-scoped consumers](https://docs.nestjs.com/v11/techniques/queues#request-scoped-consumers)
* [Event listeners](https://docs.nestjs.com/v11/techniques/queues#event-listeners)
* [Queue management](https://docs.nestjs.com/v11/techniques/queues#queue-management)
* [Separate processes](https://docs.nestjs.com/v11/techniques/queues#separate-processes)
* [Async configuration](https://docs.nestjs.com/v11/techniques/queues#async-configuration)
* [Manual registration](https://docs.nestjs.com/v11/techniques/queues#manual-registration)
* [Bull installation](https://docs.nestjs.com/v11/techniques/queues#bull-installation)
* [Named configurations](https://docs.nestjs.com/v11/techniques/queues#named-configurations-1)
* [Producers](https://docs.nestjs.com/v11/techniques/queues#producers-1)
* [Named jobs](https://docs.nestjs.com/v11/techniques/queues#named-jobs)
* [Job options](https://docs.nestjs.com/v11/techniques/queues#job-options-1)
* [Consumers](https://docs.nestjs.com/v11/techniques/queues#consumers-1)
* [Request-scoped consumers](https://docs.nestjs.com/v11/techniques/queues#request-scoped-consumers-1)
* [Event listeners](https://docs.nestjs.com/v11/techniques/queues#event-listeners-1)
* [Queue management](https://docs.nestjs.com/v11/techniques/queues#queue-management-1)
* [Separate processes](https://docs.nestjs.com/v11/techniques/queues#separate-processes-1)
* [Async configuration](https://docs.nestjs.com/v11/techniques/queues#async-configuration-1)
* [Example](https://docs.nestjs.com/v11/techniques/queues#example)

```bash

$ npm install --save @nestjs/bullmq bullmq
```

Once the installation process is complete, we can import the `BullModule` into the root `AppModule`.

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { BullModule } from '@nestjs/bullmq';

@Module({
  imports: [
    BullModule.forRoot({
      connection: {
        host: 'localhost',
        port: 6379,
      },
    }),
  ],
})
export class AppModule {}
```

The `forRoot()` method is used to register a `bullmq` package configuration object that will be used by all queues registered in the application (unless specified otherwise). For your reference, the following are a few of the properties within a configuration object:

* `connection: ConnectionOptions` - Options to configure the Redis connection. See [Connections](https://docs.bullmq.io/guide/connections) for more information. Optional.
* `prefix: string` - Prefix for all queue keys. Optional.
* `defaultJobOptions: JobOpts` - Options to control the default settings for new jobs. See [JobOpts](https://github.com/OptimalBits/bull/blob/master/REFERENCE.md#queueadd) for more information. Optional.
* `settings: AdvancedSettings` - Advanced Queue configuration settings. These should usually not be changed. See [AdvancedSettings](https://github.com/OptimalBits/bull/blob/master/REFERENCE.md#queue) for more information. Optional.
* `extraOptions` - Extra options for module init. See [Manual Registration](https://docs.nestjs.com/techniques/queues#manual-registration)

All the options are optional, providing detailed control over queue behavior. These are passed directly to the BullMQ `Queue` constructor. Read more about these options and other options [here](https://api.docs.bullmq.io/interfaces/v4.QueueOptions.html).

To register a queue, import the `BullModule.registerQueue()` dynamic module, as follows:

```typescript

BullModule.registerQueue({
  name: 'audio',
});
```

> **Hint** Create multiple queues by passing multiple comma-separated configuration objects to the `registerQueue()` method.

The `registerQueue()` method is used to instantiate and/or register queues. Queues are shared across modules and processes that connect to the same underlying Redis database with the same credentials. Each queue is unique by its name property. A queue name is used as both an injection token (for injecting the queue into controllers/providers), and as an argument to decorators to associate consumer classes and listeners with queues.

You can also override some of the pre-configured options for a specific queue, as follows:

```typescript

BullModule.registerQueue({
  name: 'audio',
  connection: {
    port: 6380,
  },
});
```

BullMQ also supports parent - child relationships between jobs. This functionality enables the creation of flows where jobs are the node of trees of arbitrary depth. To read more about them check [here](https://docs.bullmq.io/guide/flows).

To add a flow, you can do the following:

```typescript

BullModule.registerFlowProducer({
  name: 'flowProducerName',
});
```

```typescript

BullModule.forRoot('alternative-config', {
  connection: {
    port: 6381,
  },
});
```

In the example above, `'alternative-config'` is just a configuration key (it can be any arbitrary string).

With this in place, you can now point to this configuration in the `registerQueue()` options object:

```typescript

BullModule.registerQueue({
  configKey: 'alternative-config',
  name: 'video',
});
```

#### Producers[#](/techniques/queues#producers)

Job producers add jobs to queues. Producers are typically application services (Nest [providers](/v11/providers)). To add jobs to a queue, first inject the queue into the service as follows:

```typescript

import { Injectable } from '@nestjs/common';
import { Queue } from 'bullmq';
import { InjectQueue } from '@nestjs/bullmq';

@Injectable()
export class AudioService {
  constructor(@InjectQueue('audio') private audioQueue: Queue) {}
}
```

> **Hint** The `@InjectQueue()` decorator identifies the queue by its name, as provided in the `registerQueue()` method call (e.g., `'audio'`).

Now, add a job by calling the queue's `add()` method, passing a user-defined job object. Jobs are represented as serializable JavaScript objects (since that is how they are stored in the Redis database). The shape of the job you pass is arbitrary; use it to represent the semantics of your job object. You also need to give it a name. This allows you to create specialized [consumers](techniques/queues#consumers) that will only process jobs with a given name.

```typescript

const job = await this.audioQueue.add('transcode', {
  foo: 'bar',
});
```

```typescript

const job = await this.audioQueue.add(
  'transcode',
  {
    foo: 'bar',
  },
  { delay: 3000 }, // 3 seconds delayed
);
```

To add a job to the right end of the queue (process the job as **LIFO** (Last In First Out)), set the `lifo` property of the configuration object to `true`.

```typescript

const job = await this.audioQueue.add(
  'transcode',
  {
    foo: 'bar',
  },
  { lifo: true },
);
```

To prioritize a job, use the `priority` property.

```typescript

const job = await this.audioQueue.add(
  'transcode',
  {
    foo: 'bar',
  },
  { priority: 2 },
);
```

For a full list of options, check the API documentation [here](https://api.docs.bullmq.io/types/v4.JobsOptions.html) and [here](https://api.docs.bullmq.io/interfaces/v4.BaseJobOptions.html).

#### Consumers[#](/techniques/queues#consumers)

A consumer is a **class** defining methods that either process jobs added into the queue, or listen for events on the queue, or both. Declare a consumer class using the `@Processor()` decorator as follows:

```typescript

import { Processor } from '@nestjs/bullmq';

@Processor('audio')
export class AudioConsumer {}
```

> **Hint** Consumers must be registered as `providers` so the `@nestjs/bullmq` package can pick them up.

Where the decorator's string argument (e.g., `'audio'`) is the name of the queue to be associated with the class methods.

```typescript

import { Processor, WorkerHost } from '@nestjs/bullmq';
import { Job } from 'bullmq';

@Processor('audio')
export class AudioConsumer extends WorkerHost {
  async process(job: Job<any, any, string>): Promise<any> {
    let progress = 0;
    for (let i = 0; i < 100; i++) {
      await doSomething(job.data);
      progress += 1;
      await job.updateProgress(progress);
    }
    return {};
  }
}
```

The process method is called whenever the worker is idle and there are jobs to process in the queue. This handler method receives the `job` object as its only argument. The value returned by the handler method is stored in the job object and can be accessed later on, for example in a listener for the completed event.

`Job` objects have multiple methods that allow you to interact with their state. For example, the above code uses the `updateProgress()` method to update the job's progress. See [here](https://api.docs.bullmq.io/classes/v4.Job.html) for the complete `Job` object API reference.

In the older version, Bull, you could designate that a job handler method will handle **only** jobs of a certain type (jobs with a specific `name`) by passing that `name` to the `@Process()` decorator as shown below.

> **Warning** This doesn't work with BullMQ, keep reading.

```typescript

@Process('transcode')
async transcode(job: Job<unknown>) { ... }
```

This behavior is not supported in BullMQ due to confusions it generated. Instead, you need switch cases to call different services or logic for each job name:

```typescript

import { Processor, WorkerHost } from '@nestjs/bullmq';
import { Job } from 'bullmq';

@Processor('audio')
export class AudioConsumer extends WorkerHost {
  async process(job: Job<any, any, string>): Promise<any> {
    switch (job.name) {
      case 'transcode': {
        let progress = 0;
        for (i = 0; i < 100; i++) {
          await doSomething(job.data);
          progress += 1;
          await job.progress(progress);
        }
        return {};
      }
      case 'concatenate': {
        await doSomeLogic2();
        break;
      }
    }
  }
}
```

This is covered in the [named processor](https://docs.bullmq.io/patterns/named-processor) section of the BullMQ documentation.

#### Request-scoped consumers[#](/techniques/queues#request-scoped-consumers)

When a consumer is flagged as request-scoped (learn more about the injection scopes [here](/fundamentals/injection-scopes#provider-scope)), a new instance of the class will be created exclusively for each job. The instance will be garbage-collected after the job has completed.

```typescript

@Processor({
  name: 'audio',
  scope: Scope.REQUEST,
})
```

Since request-scoped consumer classes are instantiated dynamically and scoped to a single job, you can inject a `JOB_REF` through the constructor using a standard approach.

```typescript

constructor(@Inject(JOB_REF) jobRef: Job) {
  console.log(jobRef);
}
```

> **Hint** The `JOB_REF` token is imported from the `@nestjs/bullmq` package.

#### Event listeners[#](/techniques/queues#event-listeners)

BullMQ generates a set of useful events when queue and/or job state changes occur. These events can be subscribed to at the Worker level using the `@OnWorkerEvent(event)` decorator, or at the Queue level with a dedicated listener class and the `@OnQueueEvent(event)` decorator.

Worker events must be declared within a [consumer](techniques/queues#consumers) class (i.e., within a class decorated with the `@Processor()` decorator). To listen for an event, use the `@OnWorkerEvent(event)` decorator with the event you want to be handled. For example, to listen to the event emitted when a job enters the active state in the `audio` queue, use the following construct:

```typescript

import { Processor, Process, OnWorkerEvent } from '@nestjs/bullmq';
import { Job } from 'bullmq';

@Processor('audio')
export class AudioConsumer {
  @OnWorkerEvent('active')
  onActive(job: Job) {
    console.log(
      `Processing job ${job.id} of type ${job.name} with data ${job.data}...`,
    );
  }

  // ...
}
```

You can see the complete list of events and their arguments as properties of WorkerListener [here](https://api.docs.bullmq.io/interfaces/v4.WorkerListener.html).

QueueEvent listeners must use the `@QueueEventsListener(queue)` decorator and extend the `QueueEventsHost` class provided by `@nestjs/bullmq`. To listen for an event, use the `@OnQueueEvent(event)` decorator with the event you want to be handled. For example, to listen to the event emitted when a job enters the active state in the `audio` queue, use the following construct:

```typescript

import {
  QueueEventsHost,
  QueueEventsListener,
  OnQueueEvent,
} from '@nestjs/bullmq';

@QueueEventsListener('audio')
export class AudioEventsListener extends QueueEventsHost {
  @OnQueueEvent('active')
  onActive(job: { jobId: string; prev?: string }) {
    console.log(`Processing job ${job.jobId}...`);
  }

  // ...
}
```

> **Hint** QueueEvent Listeners must be registered as `providers` so the `@nestjs/bullmq` package can pick them up.

You can see the complete list of events and their arguments as properties of QueueEventsListener [here](https://api.docs.bullmq.io/interfaces/v4.QueueEventsListener.html).

#### Queue management[#](/techniques/queues#queue-management)

Queues have an API that allows you to perform management functions like pausing and resuming, retrieving the count of jobs in various states, and several more. You can find the full queue API [here](https://api.docs.bullmq.io/classes/v4.Queue.html). Invoke any of these methods directly on the `Queue` object, as shown below with the pause/resume examples.

Pause a queue with the `pause()` method call. A paused queue will not process new jobs until resumed, but current jobs being processed will continue until they are finalized.

```typescript

await audioQueue.pause();
```

To resume a paused queue, use the `resume()` method, as follows:

```typescript

await audioQueue.resume();
```

```typescript

import { Module } from '@nestjs/common';
import { BullModule } from '@nestjs/bullmq';
import { join } from 'node:path';

@Module({
  imports: [
    BullModule.registerQueue({
      name: 'audio',
      processors: [join(__dirname, 'processor.js')],
    }),
  ],
})
export class AppModule {}
```

> **Warning** Please note that because your function is being executed in a forked process, Dependency Injection (and IoC container) won't be available. That means that your processor function will need to contain (or create) all instances of external dependencies it needs.

#### Async configuration[#](/techniques/queues#async-configuration)

You may want to pass `bullmq` options asynchronously instead of statically. In this case, use the `forRootAsync()` method which provides several ways to deal with async configuration. Likewise, if you want to pass queue options asynchronously, use the `registerQueueAsync()` method.

One approach is to use a factory function:

```typescript

BullModule.forRootAsync({
  useFactory: () => ({
    connection: {
      host: 'localhost',
      port: 6379,
    },
  }),
});
```

Our factory behaves like any other [asynchronous provider](https://docs.nestjs.com/fundamentals/async-providers) (e.g., it can be `async` and it's able to inject dependencies through `inject`).

```typescript

BullModule.forRootAsync({
  imports: [ConfigModule],
  useFactory: async (configService: ConfigService) => ({
    connection: {
      host: configService.get('QUEUE_HOST'),
      port: configService.get('QUEUE_PORT'),
    },
  }),
  inject: [ConfigService],
});
```

Alternatively, you can use the `useClass` syntax:

```typescript

BullModule.forRootAsync({
  useClass: BullConfigService,
});
```

The construction above will instantiate `BullConfigService` inside `BullModule` and use it to provide an options object by calling `createSharedConfiguration()`. Note that this means that the `BullConfigService` has to implement the `SharedBullConfigurationFactory` interface, as shown below:

```typescript

@Injectable()
class BullConfigService implements SharedBullConfigurationFactory {
  createSharedConfiguration(): BullModuleOptions {
    return {
      connection: {
        host: 'localhost',
        port: 6379,
      },
    };
  }
}
```

In order to prevent the creation of `BullConfigService` inside `BullModule` and use a provider imported from a different module, you can use the `useExisting` syntax.

```typescript

BullModule.forRootAsync({
  imports: [ConfigModule],
  useExisting: ConfigService,
});
```

This construction works the same as `useClass` with one critical difference - `BullModule` will lookup imported modules to reuse an existing `ConfigService` instead of instantiating a new one.

Likewise, if you want to pass queue options asynchronously, use the `registerQueueAsync()` method, just keep in mind to specify the `name` attribute outside the factory function.

```typescript

BullModule.registerQueueAsync({
  name: 'audio',
  useFactory: () => ({
    redis: {
      host: 'localhost',
      port: 6379,
    },
  }),
});
```

#### Manual registration[#](/techniques/queues#manual-registration)

By default, `BullModule` automatically registers BullMQ components (queues, processors, and event listener services) in the `onModuleInit` lifecycle function. However, in some cases, this behavior may not be ideal. To prevent automatic registration, enable `manualRegistration` in `BullModule` like this:

```typescript

BullModule.forRoot({
  extraOptions: {
    manualRegistration: true,
  },
});
```

To register these components manually, inject `BullRegistrar` and call the `register` function, ideally within `OnModuleInit` or `OnApplicationBootstrap`.

```typescript

import { Injectable, OnModuleInit } from '@nestjs/common';
import { BullRegistrar } from '@nestjs/bullmq';

@Injectable()
export class AudioService implements OnModuleInit {
  constructor(private bullRegistrar: BullRegistrar) {}

  onModuleInit() {
    if (yourConditionHere) {
      this.bullRegistrar.register();
    }
  }
}
```

Unless you call the `BullRegistrar#register` function, no BullMQ components will work—meaning no jobs will be processed.

#### Bull installation[#](/techniques/queues#bull-installation)

> **Note** If you decided to use BullMQ, skip this section and the following chapters.

To begin using Bull, we first install the required dependencies.

```bash

$ npm install --save @nestjs/bull bull
```

Once the installation process is complete, we can import the `BullModule` into the root `AppModule`.

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { BullModule } from '@nestjs/bull';

@Module({
  imports: [
    BullModule.forRoot({
      redis: {
        host: 'localhost',
        port: 6379,
      },
    }),
  ],
})
export class AppModule {}
```

```typescript

BullModule.registerQueue({
  name: 'audio',
});
```

> **Hint** Create multiple queues by passing multiple comma-separated configuration objects to the `registerQueue()` method.

The `registerQueue()` method is used to instantiate and/or register queues. Queues are shared across modules and processes that connect to the same underlying Redis database with the same credentials. Each queue is unique by its name property. A queue name is used as both an injection token (for injecting the queue into controllers/providers), and as an argument to decorators to associate consumer classes and listeners with queues.

You can also override some of the pre-configured options for a specific queue, as follows:

```typescript

BullModule.registerQueue({
  name: 'audio',
  redis: {
    port: 6380,
  },
});
```

```typescript

BullModule.forRoot('alternative-config', {
  redis: {
    port: 6381,
  },
});
```

In the example above, `'alternative-config'` is just a configuration key (it can be any arbitrary string).

With this in place, you can now point to this configuration in the `registerQueue()` options object:

```typescript

BullModule.registerQueue({
  configKey: 'alternative-config',
  name: 'video',
});
```

#### Producers[#](/techniques/queues#producers-1)

Job producers add jobs to queues. Producers are typically application services (Nest [providers](/v11/providers)). To add jobs to a queue, first inject the queue into the service as follows:

```typescript

import { Injectable } from '@nestjs/common';
import { Queue } from 'bull';
import { InjectQueue } from '@nestjs/bull';

@Injectable()
export class AudioService {
  constructor(@InjectQueue('audio') private audioQueue: Queue) {}
}
```

> **Hint** The `@InjectQueue()` decorator identifies the queue by its name, as provided in the `registerQueue()` method call (e.g., `'audio'`).

Now, add a job by calling the queue's `add()` method, passing a user-defined job object. Jobs are represented as serializable JavaScript objects (since that is how they are stored in the Redis database). The shape of the job you pass is arbitrary; use it to represent the semantics of your job object.

```typescript

const job = await this.audioQueue.add({
  foo: 'bar',
});
```

#### Named jobs[#](/techniques/queues#named-jobs)

Jobs may have unique names. This allows you to create specialized [consumers](techniques/queues#consumers) that will only process jobs with a given name.

```typescript

const job = await this.audioQueue.add('transcode', {
  foo: 'bar',
});
```

> **Warning** When using named jobs, you must create processors for each unique name added to a queue, or the queue will complain that you are missing a processor for the given job. See [here](techniques/queues#consumers) for more information on consuming named jobs.

```typescript

const job = await this.audioQueue.add(
  {
    foo: 'bar',
  },
  { delay: 3000 }, // 3 seconds delayed
);
```

To add a job to the right end of the queue (process the job as **LIFO** (Last In First Out)), set the `lifo` property of the configuration object to `true`.

```typescript

const job = await this.audioQueue.add(
  {
    foo: 'bar',
  },
  { lifo: true },
);
```

To prioritize a job, use the `priority` property.

```typescript

const job = await this.audioQueue.add(
  {
    foo: 'bar',
  },
  { priority: 2 },
);
```

#### Consumers[#](/techniques/queues#consumers-1)

A consumer is a **class** defining methods that either process jobs added into the queue, or listen for events on the queue, or both. Declare a consumer class using the `@Processor()` decorator as follows:

```typescript

import { Processor } from '@nestjs/bull';

@Processor('audio')
export class AudioConsumer {}
```

> **Hint** Consumers must be registered as `providers` so the `@nestjs/bull` package can pick them up.

Where the decorator's string argument (e.g., `'audio'`) is the name of the queue to be associated with the class methods.

Within a consumer class, declare job handlers by decorating handler methods with the `@Process()` decorator.

```typescript

import { Processor, Process } from '@nestjs/bull';
import { Job } from 'bull';

@Processor('audio')
export class AudioConsumer {
  @Process()
  async transcode(job: Job<unknown>) {
    let progress = 0;
    for (let i = 0; i < 100; i++) {
      await doSomething(job.data);
      progress += 1;
      await job.progress(progress);
    }
    return {};
  }
}
```

The decorated method (e.g., `transcode()`) is called whenever the worker is idle and there are jobs to process in the queue. This handler method receives the `job` object as its only argument. The value returned by the handler method is stored in the job object and can be accessed later on, for example in a listener for the completed event.

`Job` objects have multiple methods that allow you to interact with their state. For example, the above code uses the `progress()` method to update the job's progress. See [here](https://github.com/OptimalBits/bull/blob/master/REFERENCE.md#job) for the complete `Job` object API reference.

You can designate that a job handler method will handle **only** jobs of a certain type (jobs with a specific `name`) by passing that `name` to the `@Process()` decorator as shown below. You can have multiple `@Process()` handlers in a given consumer class, corresponding to each job type (`name`). When you use named jobs, be sure to have a handler corresponding to each name.

```typescript

@Process('transcode')
async transcode(job: Job<unknown>) { ... }
```

> **Warning** When defining multiple consumers for the same queue, the `concurrency` option in `@Process({ concurrency: 1 })` won't take effect. The minimum `concurrency` will match the number of consumers defined. This also applies even if `@Process()` handlers use a different `name` to handle named jobs.

#### Request-scoped consumers[#](/techniques/queues#request-scoped-consumers-1)

When a consumer is flagged as request-scoped (learn more about the injection scopes [here](/fundamentals/injection-scopes#provider-scope)), a new instance of the class will be created exclusively for each job. The instance will be garbage-collected after the job has completed.

```typescript

@Processor({
  name: 'audio',
  scope: Scope.REQUEST,
})
```

Since request-scoped consumer classes are instantiated dynamically and scoped to a single job, you can inject a `JOB_REF` through the constructor using a standard approach.

```typescript

constructor(@Inject(JOB_REF) jobRef: Job) {
  console.log(jobRef);
}
```

> **Hint** The `JOB_REF` token is imported from the `@nestjs/bull` package.

#### Event listeners[#](/techniques/queues#event-listeners-1)

Bull generates a set of useful events when queue and/or job state changes occur. Nest provides a set of decorators that allow subscribing to a core set of standard events. These are exported from the `@nestjs/bull` package.

Event listeners must be declared within a [consumer](techniques/queues#consumers) class (i.e., within a class decorated with the `@Processor()` decorator). To listen for an event, use one of the decorators in the table below to declare a handler for the event. For example, to listen to the event emitted when a job enters the active state in the `audio` queue, use the following construct:

```typescript

import { Processor, Process, OnQueueActive } from '@nestjs/bull';
import { Job } from 'bull';

@Processor('audio')
export class AudioConsumer {

  @OnQueueActive()
  onActive(job: Job) {
    console.log(
      `Processing job ${job.id} of type ${job.name} with data ${job.data}...`,
    );
  }
  ...
```

Since Bull operates in a distributed (multi-node) environment, it defines the concept of event locality. This concept recognizes that events may be triggered either entirely within a single process, or on shared queues from different processes. A **local** event is one that is produced when an action or state change is triggered on a queue in the local process. In other words, when your event producers and consumers are local to a single process, all events happening on queues are local.

When a queue is shared across multiple processes, we encounter the possibility of **global** events. For a listener in one process to receive an event notification triggered by another process, it must register for a global event.

Event handlers are invoked whenever their corresponding event is emitted. The handler is called with the signature shown in the table below, providing access to information relevant to the event. We discuss one key difference between local and global event handler signatures below.

| Local event listeners | Global event listeners      | Handler method signature / When fired                                                                                                                                 |
| --------------------- | --------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `@OnQueueError()`     | `@OnGlobalQueueError()`     | `handler(error: Error)` - An error occurred. `error` contains the triggering error.                                                                                   |
| `@OnQueueWaiting()`   | `@OnGlobalQueueWaiting()`   | `handler(jobId: number \| string)` - A Job is waiting to be processed as soon as a worker is idling. `jobId` contains the id for the job that has entered this state. |
| `@OnQueueActive()`    | `@OnGlobalQueueActive()`    | `handler(job: Job)` - Job `job`has started.                                                                                                                           |
| `@OnQueueStalled()`   | `@OnGlobalQueueStalled()`   | `handler(job: Job)` - Job `job` has been marked as stalled. This is useful for debugging job workers that crash or pause the event loop.                              |
| `@OnQueueProgress()`  | `@OnGlobalQueueProgress()`  | `handler(job: Job, progress: number)` - Job `job`'s progress was updated to value `progress`.                                                                         |
| `@OnQueueCompleted()` | `@OnGlobalQueueCompleted()` | `handler(job: Job, result: any)` Job `job` successfully completed with a result `result`.                                                                             |
| `@OnQueueFailed()`    | `@OnGlobalQueueFailed()`    | `handler(job: Job, err: Error)` Job `job` failed with reason `err`.                                                                                                   |
| `@OnQueuePaused()`    | `@OnGlobalQueuePaused()`    | `handler()` The queue has been paused.                                                                                                                                |
| `@OnQueueResumed()`   | `@OnGlobalQueueResumed()`   | `handler(job: Job)` The queue has been resumed.                                                                                                                       |
| `@OnQueueCleaned()`   | `@OnGlobalQueueCleaned()`   | `handler(jobs: Job[], type: string)` Old jobs have been cleaned from the queue. `jobs` is an array of cleaned jobs, and `type` is the type of jobs cleaned.           |
| `@OnQueueDrained()`   | `@OnGlobalQueueDrained()`   | `handler()` Emitted whenever the queue has processed all the waiting jobs (even if there can be some delayed jobs not yet processed).                                 |
| `@OnQueueRemoved()`   | `@OnGlobalQueueRemoved()`   | `handler(job: Job)` Job `job` was successfully removed.                                                                                                               |

When listening for global events, the method signatures can be slightly different from their local counterpart. Specifically, any method signature that receives `job` objects in the local version, instead receives a `jobId` (`number`) in the global version. To get a reference to the actual `job` object in such a case, use the `Queue#getJob` method. This call should be awaited, and therefore the handler should be declared `async`. For example:

```typescript

@OnGlobalQueueCompleted()
async onGlobalCompleted(jobId: number, result: any) {
  const job = await this.immediateQueue.getJob(jobId);
  console.log('(Global) on completed: job ', job.id, ' -> result: ', result);
}
```

> **Hint** To access the `Queue` object (to make a `getJob()` call), you must of course inject it. Also, the Queue must be registered in the module where you are injecting it.

In addition to the specific event listener decorators, you can also use the generic `@OnQueueEvent()` decorator in combination with either `BullQueueEvents` or `BullQueueGlobalEvents` enums. Read more about events [here](https://github.com/OptimalBits/bull/blob/master/REFERENCE.md#events).

#### Queue management[#](/techniques/queues#queue-management-1)

Queue's have an API that allows you to perform management functions like pausing and resuming, retrieving the count of jobs in various states, and several more. You can find the full queue API [here](https://github.com/OptimalBits/bull/blob/master/REFERENCE.md#queue). Invoke any of these methods directly on the `Queue` object, as shown below with the pause/resume examples.

Pause a queue with the `pause()` method call. A paused queue will not process new jobs until resumed, but current jobs being processed will continue until they are finalized.

```typescript

await audioQueue.pause();
```

To resume a paused queue, use the `resume()` method, as follows:

```typescript

await audioQueue.resume();
```

```ts

import { Module } from '@nestjs/common';
import { BullModule } from '@nestjs/bull';
import { join } from 'path';

@Module({
  imports: [
    BullModule.registerQueue({
      name: 'audio',
      processors: [join(__dirname, 'processor.js')],
    }),
  ],
})
export class AppModule {}
```

Please note that because your function is being executed in a forked process, Dependency Injection (and IoC container) won't be available. That means that your processor function will need to contain (or create) all instances of external dependencies it needs.

processor.ts

JS TS

```ts

import { Job, DoneCallback } from 'bull';

export default function (job: Job, cb: DoneCallback) {
  console.log(`[${process.pid}] ${JSON.stringify(job.data)}`);
  cb(null, 'It works');
}
```

#### Async configuration[#](/techniques/queues#async-configuration-1)

You may want to pass `bull` options asynchronously instead of statically. In this case, use the `forRootAsync()` method which provides several ways to deal with async configuration.

One approach is to use a factory function:

```typescript

BullModule.forRootAsync({
  useFactory: () => ({
    redis: {
      host: 'localhost',
      port: 6379,
    },
  }),
});
```

Our factory behaves like any other [asynchronous provider](https://docs.nestjs.com/fundamentals/async-providers) (e.g., it can be `async` and it's able to inject dependencies through `inject`).

```typescript

BullModule.forRootAsync({
  imports: [ConfigModule],
  useFactory: async (configService: ConfigService) => ({
    redis: {
      host: configService.get('QUEUE_HOST'),
      port: configService.get('QUEUE_PORT'),
    },
  }),
  inject: [ConfigService],
});
```

Alternatively, you can use the `useClass` syntax:

```typescript

BullModule.forRootAsync({
  useClass: BullConfigService,
});
```

The construction above will instantiate `BullConfigService` inside `BullModule` and use it to provide an options object by calling `createSharedConfiguration()`. Note that this means that the `BullConfigService` has to implement the `SharedBullConfigurationFactory` interface, as shown below:

```typescript

@Injectable()
class BullConfigService implements SharedBullConfigurationFactory {
  createSharedConfiguration(): BullModuleOptions {
    return {
      redis: {
        host: 'localhost',
        port: 6379,
      },
    };
  }
}
```

In order to prevent the creation of `BullConfigService` inside `BullModule` and use a provider imported from a different module, you can use the `useExisting` syntax.

```typescript

BullModule.forRootAsync({
  imports: [ConfigModule],
  useExisting: ConfigService,
});
```

This construction works the same as `useClass` with one critical difference - `BullModule` will lookup imported modules to reuse an existing `ConfigService` instead of instantiating a new one.

Likewise, if you want to pass queue options asynchronously, use the `registerQueueAsync()` method, just keep in mind to specify the `name` attribute outside the factory function.

```typescript

BullModule.registerQueueAsync({
  name: 'audio',
  useFactory: () => ({
    redis: {
      host: 'localhost',
      port: 6379,
    },
  }),
});
```

#### Example[#](/techniques/queues#example)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/26-queues).

----
url: https://docs.nestjs.com/graphql/field-middleware
----

[Skip to content](#content)

On this page

* [Field middleware](https://docs.nestjs.com/graphql/field-middleware#field-middleware)
* [Getting started](https://docs.nestjs.com/graphql/field-middleware#getting-started)
* [Global field middleware](https://docs.nestjs.com/graphql/field-middleware#global-field-middleware)

### Field middleware

> **Warning** This chapter applies only to the code first approach.

Field middleware lets you run arbitrary code **before or after** a field is resolved. You can use field middleware to convert the result of a field, validate the arguments of a field, or check field-level roles (for example, the roles required to access the field the middleware function runs for).

You can connect multiple middleware functions to a field. In this case, they are called sequentially along a chain, where each middleware decides whether to call the next one. The order of the functions in the `middleware` array matters. The first one is the outermost layer, so it runs first and finishes last (similar to the `graphql-middleware` package). The second one is the next layer in, so it runs second and finishes second to last.

#### Getting started[#](/graphql/field-middleware#getting-started)

Let's start by creating a simple middleware that logs a field value before it's sent back to the client:

```typescript

import { FieldMiddleware, MiddlewareContext, NextFn } from '@nestjs/graphql';

const loggerMiddleware: FieldMiddleware = async (
  ctx: MiddlewareContext,
  next: NextFn,
) => {
  const value = await next();
  console.log(value);
  return value;
};
```

> **Hint**`MiddlewareContext` is an object that consists of the same arguments that the GraphQL resolver function normally receives (`{ source, args, context, info }`), while `NextFn` is a function that executes the next middleware in the stack (bound to this field) or the actual field resolver.

> **Warning** Field middleware functions can't inject dependencies or access Nest's DI container. They are designed to be lightweight and shouldn't perform potentially time-consuming operations (like retrieving data from the database). If you need to call external services or query a data source, do it in a guard or interceptor bound to a root query or mutation handler, and assign the result to the `context` object. You can then access it from within the field middleware (through the `MiddlewareContext` object).

Field middleware must match the `FieldMiddleware` interface. In the example above, we first call the `next()` function (which executes the actual field resolver and returns the field value), and then log this value to the terminal. The value returned from the middleware function replaces the field value (if the middleware returns `undefined`, the value from `next()` is used). Since we don't want to change anything, we return the original value.

With this in place, register the middleware directly in the `@Field()` decorator:

```typescript

@ObjectType()
export class Recipe {
  @Field({ middleware: [loggerMiddleware] })
  title: string;
}
```

Now, whenever you request the `title` field of the `Recipe` object type, the field's original value is logged to the console.

> **Hint** To learn how to implement a field-level permissions system with the [extensions](/graphql/extensions) feature, see [using custom metadata](/graphql/extensions#using-custom-metadata).

> **Warning** Field middleware can be applied only to `ObjectType` classes. For more details, see [this GitHub issue](https://github.com/nestjs/graphql/issues/2446).

As mentioned above, you can control the field's value from within the middleware function. For demonstration purposes, let's uppercase a recipe's title (if present):

```typescript

const value = await next();
return value?.toUpperCase();
```

In this case, every title is automatically uppercased when requested.

Likewise, you can bind field middleware to a custom field resolver (a method annotated with the `@ResolveField()` decorator):

```typescript

@ResolveField(() => String, { middleware: [loggerMiddleware] })
title() {
  return 'Placeholder';
}
```

> **Warning** If enhancers are enabled at the field resolver level (see [executing enhancers at the field resolver level](/graphql/other-features#execute-enhancers-at-the-field-resolver-level)), field middleware functions run before any interceptors, guards, etc., **bound to the method** (but after the root-level enhancers registered for query or mutation handlers).

#### Global field middleware[#](/graphql/field-middleware#global-field-middleware)

In addition to binding middleware directly to a specific field, you can register one or more middleware functions globally. Global middleware is automatically connected to all fields of your object types.

```typescript

GraphQLModule.forRoot({
  autoSchemaFile: 'schema.gql',
  buildSchemaOptions: {
    fieldMiddleware: [loggerMiddleware],
  },
}),
```

> **Hint** Globally registered field middleware functions run **before** locally registered ones (those bound directly to specific fields).

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/field-middleware.md)

----
url: https://docs.nestjs.com/v10/recipes/prisma
----

* [Prisma](https://docs.nestjs.com/v10/recipes/prisma#prisma)
* [Getting started](https://docs.nestjs.com/v10/recipes/prisma#getting-started)
* [Create your NestJS project](https://docs.nestjs.com/v10/recipes/prisma#create-your-nestjs-project)
* [Set up Prisma](https://docs.nestjs.com/v10/recipes/prisma#set-up-prisma)
* [Set the database connection](https://docs.nestjs.com/v10/recipes/prisma#set-the-database-connection)
* [Create two database tables with Prisma Migrate](https://docs.nestjs.com/v10/recipes/prisma#create-two-database-tables-with-prisma-migrate)
* [Install and generate Prisma Client](https://docs.nestjs.com/v10/recipes/prisma#install-and-generate-prisma-client)
* [Use Prisma Client in your NestJS services](https://docs.nestjs.com/v10/recipes/prisma#use-prisma-client-in-your-nestjs-services)
* [Summary](https://docs.nestjs.com/v10/recipes/prisma#summary)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/recipes/prisma.md "Suggest Edits")

### Prisma

[Prisma](https://www.prisma.io) is an [open-source](https://github.com/prisma/prisma) ORM for Node.js and TypeScript. It is used as an **alternative** to writing plain SQL, or using another database access tool such as SQL query builders (like [knex.js](https://knexjs.org/)) or ORMs (like [TypeORM](https://typeorm.io/) and [Sequelize](https://sequelize.org/)). Prisma currently supports PostgreSQL, MySQL, SQL Server, SQLite, MongoDB and CockroachDB ([Preview](https://www.prisma.io/docs/reference/database-reference/supported-databases)).

While Prisma can be used with plain JavaScript, it embraces TypeScript and provides a level to type-safety that goes beyond the guarantees other ORMs in the TypeScript ecosystem. You can find an in-depth comparison of the type-safety guarantees of Prisma and TypeORM [here](https://www.prisma.io/docs/concepts/more/comparisons/prisma-and-typeorm#type-safety).

> **Note** If you want to get a quick overview of how Prisma works, you can follow the [Quickstart](https://www.prisma.io/docs/getting-started/quickstart) or read the [Introduction](https://www.prisma.io/docs/understand-prisma/introduction) in the [documentation](https://www.prisma.io/docs/). There also are ready-to-run examples for [REST](https://github.com/prisma/prisma-examples/tree/b53fad046a6d55f0090ddce9fd17ec3f9b95cab3/orm/nest) and [GraphQL](https://github.com/prisma/prisma-examples/tree/b53fad046a6d55f0090ddce9fd17ec3f9b95cab3/orm/nest-graphql) in the [`prisma-examples`](https://github.com/prisma/prisma-examples/) repo.

#### Getting started[#](/recipes/prisma#getting-started)

In this recipe, you'll learn how to get started with NestJS and Prisma from scratch. You are going to build a sample NestJS application with a REST API that can read and write data in a database.

For the purpose of this guide, you'll use a [SQLite](https://sqlite.org/) database to save the overhead of setting up a database server. Note that you can still follow this guide, even if you're using PostgreSQL or MySQL – you'll get extra instructions for using these databases at the right places.

> **Note** If you already have an existing project and consider migrating to Prisma, you can follow the guide for [adding Prisma to an existing project](https://www.prisma.io/docs/getting-started/setup-prisma/add-to-existing-project-typescript-postgres). If you are migrating from TypeORM, you can read the guide [Migrating from TypeORM to Prisma](https://www.prisma.io/docs/guides/migrate-to-prisma/migrate-from-typeorm).

#### Create your NestJS project[#](/recipes/prisma#create-your-nestjs-project)

To get started, install the NestJS CLI and create your app skeleton with the following commands:

```bash

$ npm install -g @nestjs/cli
$ nest new hello-prisma
```

See the [First steps](https://docs.nestjs.com/first-steps) page to learn more about the project files created by this command. Note also that you can now run `npm start` to start your application. The REST API running at `http://localhost:3000/` currently serves a single route that's implemented in `src/app.controller.ts`. Over the course of this guide, you'll implement additional routes to store and retrieve data about *users* and *posts*.

#### Set up Prisma[#](/recipes/prisma#set-up-prisma)

Start by installing the Prisma CLI as a development dependency in your project:

```bash

$ cd hello-prisma
$ npm install prisma --save-dev
```

In the following steps, we'll be utilizing the [Prisma CLI](https://www.prisma.io/docs/reference/tools-and-interfaces/prisma-cli). As a best practice, it's recommended to invoke the CLI locally by prefixing it with `npx`:

```bash

$ npx prisma
```

Expand if you're using Yarn

If you're using Yarn, then you can install the Prisma CLI as follows:

```bash

$ yarn add prisma --dev
```

Once installed, you can invoke it by prefixing it with `yarn`:

```bash

$ yarn prisma
```

Now create your initial Prisma setup using the `init` command of the Prisma CLI:

```bash

$ npx prisma init
```

This command creates a new `prisma` directory with the following contents:

* `schema.prisma`: Specifies your database connection and contains the database schema
* `.env`: A [dotenv](https://github.com/motdotla/dotenv) file, typically used to store your database credentials in a group of environment variables

#### Set the database connection[#](/recipes/prisma#set-the-database-connection)

Your database connection is configured in the `datasource` block in your `schema.prisma` file. By default it's set to `postgresql`, but since you're using a SQLite database in this guide you need to adjust the `provider` field of the `datasource` block to `sqlite`:

```groovy

datasource db {
  provider = "sqlite"
  url      = env("DATABASE_URL")
}

generator client {
  provider = "prisma-client-js"
}
```

Now, open up `.env` and adjust the `DATABASE_URL` environment variable to look as follows:

```bash

DATABASE_URL="file:./dev.db"
```

Make sure you have a [ConfigModule](https://docs.nestjs.com/techniques/configuration) configured, otherwise the `DATABASE_URL` variable will not be picked up from `.env`.

SQLite databases are simple files; no server is required to use a SQLite database. So instead of configuring a connection URL with a *host* and *port*, you can just point it to a local file which in this case is called `dev.db`. This file will be created in the next step.

Expand if you're using PostgreSQL, MySQL, MsSQL or Azure SQL

With PostgreSQL and MySQL, you need to configure the connection URL to point to the *database server*. You can learn more about the required connection URL format [here](https://www.prisma.io/docs/reference/database-reference/connection-urls).

**PostgreSQL**

If you're using PostgreSQL, you have to adjust the `schema.prisma` and `.env` files as follows:

**`schema.prisma`**

```groovy

datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}

generator client {
  provider = "prisma-client-js"
}
```

**`.env`**

```bash

DATABASE_URL="postgresql://USER:PASSWORD@HOST:PORT/DATABASE?schema=SCHEMA"
```

Replace the placeholders spelled in all uppercase letters with your database credentials. Note that if you're unsure what to provide for the `SCHEMA` placeholder, it's most likely the default value `public`:

```bash

DATABASE_URL="postgresql://USER:PASSWORD@HOST:PORT/DATABASE?schema=public"
```

If you want to learn how to set up a PostgreSQL database, you can follow this guide on [setting up a free PostgreSQL database on Heroku](https://dev.to/prisma/how-to-setup-a-free-postgresql-database-on-heroku-1dc1).

**MySQL**

If you're using MySQL, you have to adjust the `schema.prisma` and `.env` files as follows:

**`schema.prisma`**

```groovy

datasource db {
  provider = "mysql"
  url      = env("DATABASE_URL")
}

generator client {
  provider = "prisma-client-js"
}
```

**`.env`**

```bash

DATABASE_URL="mysql://USER:PASSWORD@HOST:PORT/DATABASE"
```

Replace the placeholders spelled in all uppercase letters with your database credentials.

**Microsoft SQL Server / Azure SQL Server**

If you're using Microsoft SQL Server or Azure SQL Server, you have to adjust the `schema.prisma` and `.env` files as follows:

**`schema.prisma`**

```groovy

datasource db {
  provider = "sqlserver"
  url      = env("DATABASE_URL")
}

generator client {
  provider = "prisma-client-js"
}
```

**`.env`**

Replace the placeholders spelled in all uppercase letters with your database credentials. Note that if you're unsure what to provide for the `encrypt` placeholder, it's most likely the default value `true`:

```bash

DATABASE_URL="sqlserver://HOST:PORT;database=DATABASE;user=USER;password=PASSWORD;encrypt=true"
```

#### Create two database tables with Prisma Migrate[#](/recipes/prisma#create-two-database-tables-with-prisma-migrate)

In this section, you'll create two new tables in your database using [Prisma Migrate](https://www.prisma.io/docs/concepts/components/prisma-migrate). Prisma Migrate generates SQL migration files for your declarative data model definition in the Prisma schema. These migration files are fully customizable so that you can configure any additional features of the underlying database or include additional commands, e.g. for seeding.

Add the following two models to your `schema.prisma` file:

```groovy

model User {
  id    Int     @default(autoincrement()) @id
  email String  @unique
  name  String?
  posts Post[]
}

model Post {
  id        Int      @default(autoincrement()) @id
  title     String
  content   String?
  published Boolean? @default(false)
  author    User?    @relation(fields: [authorId], references: [id])
  authorId  Int?
}
```

With your Prisma models in place, you can generate your SQL migration files and run them against the database. Run the following commands in your terminal:

```bash

$ npx prisma migrate dev --name init
```

This `prisma migrate dev` command generates SQL files and directly runs them against the database. In this case, the following migration files was created in the existing `prisma` directory:

```bash

$ tree prisma
prisma
├── dev.db
├── migrations
│   └── 20201207100915_init
│       └── migration.sql
└── schema.prisma
```

Expand to view the generated SQL statements

The following tables were created in your SQLite database:

```sql

-- CreateTable
CREATE TABLE "User" (
    "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
    "email" TEXT NOT NULL,
    "name" TEXT
);

-- CreateTable
CREATE TABLE "Post" (
    "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
    "title" TEXT NOT NULL,
    "content" TEXT,
    "published" BOOLEAN DEFAULT false,
    "authorId" INTEGER,

    FOREIGN KEY ("authorId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE
);

-- CreateIndex
CREATE UNIQUE INDEX "User.email_unique" ON "User"("email");
```

#### Install and generate Prisma Client[#](/recipes/prisma#install-and-generate-prisma-client)

Prisma Client is a type-safe database client that's *generated* from your Prisma model definition. Because of this approach, Prisma Client can expose [CRUD](https://www.prisma.io/docs/concepts/components/prisma-client/crud) operations that are *tailored* specifically to your models.

To install Prisma Client in your project, run the following command in your terminal:

```bash

$ npm install @prisma/client
```

Note that during installation, Prisma automatically invokes the `prisma generate` command for you. In the future, you need to run this command after *every* change to your Prisma models to update your generated Prisma Client.

> **Note** The `prisma generate` command reads your Prisma schema and updates the generated Prisma Client library inside `node_modules/@prisma/client`.

#### Use Prisma Client in your NestJS services[#](/recipes/prisma#use-prisma-client-in-your-nestjs-services)

You're now able to send database queries with Prisma Client. If you want to learn more about building queries with Prisma Client, check out the [API documentation](https://www.prisma.io/docs/reference/tools-and-interfaces/prisma-client/crud).

When setting up your NestJS application, you'll want to abstract away the Prisma Client API for database queries within a service. To get started, you can create a new `PrismaService` that takes care of instantiating `PrismaClient` and connecting to your database.

Inside the `src` directory, create a new file called `prisma.service.ts` and add the following code to it:

```typescript

import { Injectable, OnModuleInit } from '@nestjs/common';
import { PrismaClient } from '@prisma/client';

@Injectable()
export class PrismaService extends PrismaClient implements OnModuleInit {
  async onModuleInit() {
    await this.$connect();
  }
}
```

> **Note** The `onModuleInit` is optional — if you leave it out, Prisma will connect lazily on its first call to the database.

Next, you can write services that you can use to make database calls for the `User` and `Post` models from your Prisma schema.

Still inside the `src` directory, create a new file called `user.service.ts` and add the following code to it:

```typescript

import { Injectable } from '@nestjs/common';
import { PrismaService } from './prisma.service';
import { User, Prisma } from '@prisma/client';

@Injectable()
export class UserService {
  constructor(private prisma: PrismaService) {}

  async user(
    userWhereUniqueInput: Prisma.UserWhereUniqueInput,
  ): Promise<User | null> {
    return this.prisma.user.findUnique({
      where: userWhereUniqueInput,
    });
  }

  async users(params: {
    skip?: number;
    take?: number;
    cursor?: Prisma.UserWhereUniqueInput;
    where?: Prisma.UserWhereInput;
    orderBy?: Prisma.UserOrderByWithRelationInput;
  }): Promise<User[]> {
    const { skip, take, cursor, where, orderBy } = params;
    return this.prisma.user.findMany({
      skip,
      take,
      cursor,
      where,
      orderBy,
    });
  }

  async createUser(data: Prisma.UserCreateInput): Promise<User> {
    return this.prisma.user.create({
      data,
    });
  }

  async updateUser(params: {
    where: Prisma.UserWhereUniqueInput;
    data: Prisma.UserUpdateInput;
  }): Promise<User> {
    const { where, data } = params;
    return this.prisma.user.update({
      data,
      where,
    });
  }

  async deleteUser(where: Prisma.UserWhereUniqueInput): Promise<User> {
    return this.prisma.user.delete({
      where,
    });
  }
}
```

Notice how you're using Prisma Client's generated types to ensure that the methods that are exposed by your service are properly typed. You therefore save the boilerplate of typing your models and creating additional interface or DTO files.

Now do the same for the `Post` model.

Still inside the `src` directory, create a new file called `post.service.ts` and add the following code to it:

```typescript

import { Injectable } from '@nestjs/common';
import { PrismaService } from './prisma.service';
import { Post, Prisma } from '@prisma/client';

@Injectable()
export class PostService {
  constructor(private prisma: PrismaService) {}

  async post(
    postWhereUniqueInput: Prisma.PostWhereUniqueInput,
  ): Promise<Post | null> {
    return this.prisma.post.findUnique({
      where: postWhereUniqueInput,
    });
  }

  async posts(params: {
    skip?: number;
    take?: number;
    cursor?: Prisma.PostWhereUniqueInput;
    where?: Prisma.PostWhereInput;
    orderBy?: Prisma.PostOrderByWithRelationInput;
  }): Promise<Post[]> {
    const { skip, take, cursor, where, orderBy } = params;
    return this.prisma.post.findMany({
      skip,
      take,
      cursor,
      where,
      orderBy,
    });
  }

  async createPost(data: Prisma.PostCreateInput): Promise<Post> {
    return this.prisma.post.create({
      data,
    });
  }

  async updatePost(params: {
    where: Prisma.PostWhereUniqueInput;
    data: Prisma.PostUpdateInput;
  }): Promise<Post> {
    const { data, where } = params;
    return this.prisma.post.update({
      data,
      where,
    });
  }

  async deletePost(where: Prisma.PostWhereUniqueInput): Promise<Post> {
    return this.prisma.post.delete({
      where,
    });
  }
}
```

Your `UserService` and `PostService` currently wrap the CRUD queries that are available in Prisma Client. In a real world application, the service would also be the place to add business logic to your application. For example, you could have a method called `updatePassword` inside the `UserService` that would be responsible for updating the password of a user.

Remember to register the new services in the app module.

##### Implement your REST API routes in the main app controller

Finally, you'll use the services you created in the previous sections to implement the different routes of your app. For the purpose of this guide, you'll put all your routes into the already existing `AppController` class.

Replace the contents of the `app.controller.ts` file with the following code:

```typescript

import {
  Controller,
  Get,
  Param,
  Post,
  Body,
  Put,
  Delete,
} from '@nestjs/common';
import { UserService } from './user.service';
import { PostService } from './post.service';
import { User as UserModel, Post as PostModel } from '@prisma/client';

@Controller()
export class AppController {
  constructor(
    private readonly userService: UserService,
    private readonly postService: PostService,
  ) {}

  @Get('post/:id')
  async getPostById(@Param('id') id: string): Promise<PostModel> {
    return this.postService.post({ id: Number(id) });
  }

  @Get('feed')
  async getPublishedPosts(): Promise<PostModel[]> {
    return this.postService.posts({
      where: { published: true },
    });
  }

  @Get('filtered-posts/:searchString')
  async getFilteredPosts(
    @Param('searchString') searchString: string,
  ): Promise<PostModel[]> {
    return this.postService.posts({
      where: {
        OR: [
          {
            title: { contains: searchString },
          },
          {
            content: { contains: searchString },
          },
        ],
      },
    });
  }

  @Post('post')
  async createDraft(
    @Body() postData: { title: string; content?: string; authorEmail: string },
  ): Promise<PostModel> {
    const { title, content, authorEmail } = postData;
    return this.postService.createPost({
      title,
      content,
      author: {
        connect: { email: authorEmail },
      },
    });
  }

  @Post('user')
  async signupUser(
    @Body() userData: { name?: string; email: string },
  ): Promise<UserModel> {
    return this.userService.createUser(userData);
  }

  @Put('publish/:id')
  async publishPost(@Param('id') id: string): Promise<PostModel> {
    return this.postService.updatePost({
      where: { id: Number(id) },
      data: { published: true },
    });
  }

  @Delete('post/:id')
  async deletePost(@Param('id') id: string): Promise<PostModel> {
    return this.postService.deletePost({ id: Number(id) });
  }
}
```

    * `title: String` (required): The title of the post
    * `content: String` (optional): The content of the post
    * `authorEmail: String` (required): The email of the user that creates the post

* `/user`: Create a new user

  * Body:

    * `email: String` (required): The email address of the user
    * `name: String` (optional): The name of the user

----
url: https://docs.nestjs.com/v9/microservices/guards
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Guards](https://docs.nestjs.com/v9/microservices/guards#guards)
* [Binding guards](https://docs.nestjs.com/v9/microservices/guards#binding-guards)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/microservices/guards.md "Suggest Edits")

### Guards

There is no fundamental difference between microservices guards and [regular HTTP application guards](/v9/guards). The only difference is that instead of throwing `HttpException`, you should use `RpcException`.

> **Hint** The `RpcException` class is exposed from `@nestjs/microservices` package.

#### Binding guards[#](/microservices/guards#binding-guards)

The following example uses a method-scoped guard. Just as with HTTP based applications, you can also use controller-scoped guards (i.e., prefix the controller class with a `@UseGuards()` decorator).

JS TS

```typescript

@UseGuards(AuthGuard)
@MessagePattern({ cmd: 'sum' })
accumulate(data: number[]): number {
  return (data || []).reduce((a, b) => a + b);
}
```

```typescript

@UseGuards(AuthGuard)
@MessagePattern({ cmd: 'sum' })
accumulate(data) {
  return (data || []).reduce((a, b) => a + b);
}
```

----
url: https://docs.nestjs.com/v5/microservices/basics
----

### Basics

The Nest microservice is a type of application that uses a different **transport** layer than HTTP.

#### Installation

Firstly, we need to install the required package:

TypeScript

```typescript

$ npm i --save @nestjs/microservices
```

#### Overview

In general, Nest supports a bunch of built-in transporters. They are based on **request-response** paradigm and a whole communication logic is hidden behind an abstraction layer. Thanks to that you can easily switch between transporters without changing any line of your code. We don't support streaming platforms with log based persistance, such as [Kafka](https://docs.confluent.io/3.0.0/streams/) or [NATS streaming](https://github.com/nats-io/node-nats-streaming) because they have been created to solve a different range of issues. However, you can still use them with Nest by making use of [execution context](/v5/execution-context) feature.

In order to create a microservice, we use `createMicroservice()` method of the `NestFactory` class. By default, a microservice listens on messages via **TCP protocol**.

main.ts

JS TS

TypeScript

```typescript

import { NestFactory } from '@nestjs/core';
import { Transport } from '@nestjs/microservices';
import { ApplicationModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.createMicroservice(ApplicationModule, {
    transport: Transport.TCP,
  });
  app.listen(() => console.log('Microservice is listening'));
}
bootstrap();
```

The second argument of the `createMicroservice()` method is an options object. This object may have two members:

|             |                                                                             |
| ----------- | --------------------------------------------------------------------------- |
| `transport` | Specifies the transporter                                                   |
| `options`   | A transporter-specific options object that determines transporter behaviour |

The `options` object is different depending on chosen transporter. A **TCP** transporter exposes few properties described below.

|                 |                                       |
| --------------- | ------------------------------------- |
| `host`          | Connection hostname                   |
| `port`          | Connection port                       |
| `retryAttempts` | A total amount of connection attempts |
| `retryDelay`    | A connection retrying delay (ms)      |

#### Patterns

A microservice recognizes messages through **patterns**. The pattern is a plain value, for example, a literal object, string, or a symbol. In order to create a pattern handler, we use the `@MessagePattern()` decorator which is imported from the `@nestjs/microservices` package.

math.controller.ts

JS TS

TypeScript

```typescript

import { Controller } from '@nestjs/common';
import { MessagePattern } from '@nestjs/microservices';

@Controller()
export class MathController {
  @MessagePattern({ cmd: 'sum' })
  sum(data: number[]): number {
    return (data || []).reduce((a, b) => a + b);
  }
}
```

TypeScript

```typescript

import { Controller } from '@nestjs/common';
import { MessagePattern } from '@nestjs/microservices';

@Controller()
export class MathController {
  @MessagePattern({ cmd: 'sum' })
  sum(data) {
    return (data || []).reduce((a, b) => a + b);
  }
}
```

The `sum()` handler is listening to messages that fulfil the `cmd: 'sum'` pattern. The pattern handler takes a single argument, the `data` passed from the client. In this case, the data is an array of numbers which has to be accumulated.

#### Asynchronous responses

Each pattern handler is able to respond either synchronously or **asynchronously**. Hence, `async` methods are supported.

math.controller.ts

JS TS

TypeScript

```typescript

@MessagePattern({ cmd: 'sum' })
async sum(data: number[]): Promise<number> {
  return (data || []).reduce((a, b) => a + b);
}
```

TypeScript

```typescript

@MessagePattern({ cmd: 'sum' })
async sum(data) {
  return (data || []).reduce((a, b) => a + b);
}
```

Additionally, we are able to return the [Rx](https://github.com/reactivex/rxjs) `Observable`, and thus the values will be emitted until the stream is completed.

math.controller.ts

JS TS

TypeScript

```typescript

@MessagePattern({ cmd: 'sum' })
sum(data: number[]): Observable<number> {
  return from([1, 2, 3]);
}
```

TypeScript

```typescript

@MessagePattern({ cmd: 'sum' })
sum(data) {
  return from([1, 2, 3]);
}
```

Above message handler will respond **3 times** (with each item from the array).

#### Client

In order to connect with the Nest microservice, we are using the `ClientProxy` class which instance is assigned to a property through `@Client()` decorator. This decorator takes a single argument. It is the same object as a Nest microservice options object.

TypeScript

```typescript

@Client({ transport: Transport.TCP })
client: ClientProxy;
```

> **Hint** Both `@Client()` decorator and `ClientProxy` class are imported from the `@nestjs/microservices` package.

Another solution would be to manually create the `ClientProxy` instance using the `ClientProxyFactory` (exported from `@nestjs/microservices` package).

TypeScript

```typescript

constructor() {
  this.client = ClientProxyFactory.create({
    transport: Transport.TCP
  });
}
```

The `ClientProxy` is **lazy**. It doesn't initiate a connection immediately. Instead, it will be established before the first microservice's call, and then reused across each subsequent call. However, if you want to delay an application's bootstrapping process and manually initialize a connection, you can use a `connect()` method inside the `OnModuleInit` lifecycle hook.

TypeScript

```typescript

async onModuleInit() {
  await this.client.connect();
}
```

If the connection cannot be created, the `connect()` method will reject with the corresponding error object.

The `ClientProxy` exposes a `send()` method. This method is intended to call the microservice and returns the `Observable` with its response, meaning, we can subscribe to the emitted values easily.

JS TS

TypeScript

```typescript

@Get()
call(): Observable<number> {
  const pattern = { cmd: 'sum' };
  const payload = [1, 2, 3];
  return this.client.send<number>(pattern, payload);
}
```

TypeScript

```typescript

@Get()
call() {
  const pattern = { cmd: 'sum' };
  const payload = [1, 2, 3];
  return this.client.send(pattern, payload);
}
```

The `send()` method takes 2 arguments, `pattern` and `payload`. The `pattern` has to be equal to this one defined in the `@MessagePattern()` decorator, while `payload` is a message that we want to transmit to another microservice.

* Basics
* Installation
* Overview
* Patterns
* Asynchronous responses

----
url: https://docs.nestjs.com/v10/cli/scripts
----

* [Nest CLI and scripts](https://docs.nestjs.com/v10/cli/scripts#nest-cli-and-scripts)
* [The nest binary](https://docs.nestjs.com/v10/cli/scripts#the-nest-binary)
* [Build](https://docs.nestjs.com/v10/cli/scripts#build)
* [Execution](https://docs.nestjs.com/v10/cli/scripts#execution)
* [Generation](https://docs.nestjs.com/v10/cli/scripts#generation)
* [Package scripts](https://docs.nestjs.com/v10/cli/scripts#package-scripts)
* [Backward compatibility](https://docs.nestjs.com/v10/cli/scripts#backward-compatibility)
* [Migration](https://docs.nestjs.com/v10/cli/scripts#migration)

```bash

$ npm run build
```

and

```bash

$ npm run start
```

```bash

$ npm install -g @nestjs/cli
$ cd  /some/project/root/folder
$ npm install -D @nestjs/cli
```

You can then replace the `scripts` defined in `package.json` with the following ones:

```typescript

"build": "nest build",
"start": "nest start",
"start:dev": "nest start --watch",
"start:debug": "nest start --debug --watch",
```

----
url: https://docs.nestjs.com/v8/techniques/streaming-files
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Streaming files](https://docs.nestjs.com/v8/techniques/streaming-files#streaming-files)
* [Streamable File class](https://docs.nestjs.com/v8/techniques/streaming-files#streamable-file-class)
* [Cross-platform support](https://docs.nestjs.com/v8/techniques/streaming-files#cross-platform-support)
* [Example](https://docs.nestjs.com/v8/techniques/streaming-files#example)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/techniques/streaming-files.md "Suggest Edits")

### Streaming files

> **Note** This chapter shows how you can stream files from your **HTTP application**. The examples presented below do not apply to GraphQL or Microservice applications.

There may be times where you would like to send back a file from your REST API to the client. To do this with Nest, normally you'd do the following:

```ts

@Controller('file')
export class FileController {
  @Get()
  getFile(@Res() res: Response) {
    const file = createReadStream(join(process.cwd(), 'package.json'));
    file.pipe(res);
  }
}
```

But in doing so you end up losing access to your post-controller interceptor logic. To handle this, you can return a `StreamableFile` instance and under the hood, the framework will take care of piping the response.

#### Streamable File class[#](/techniques/streaming-files#streamable-file-class)

A `StreamableFile` is a class that holds onto the stream that is to be returned. To create a new `StreamableFile`, you can pass either a `Buffer` or a `Stream` to the `StreamableFile` constructor.

> **hint** The `StreamableFile` class can be imported from `@nestjs/common`.

#### Cross-platform support[#](/techniques/streaming-files#cross-platform-support)

Fastify, by default, can support sending files without needing to call `stream.pipe(res)`, so you don't need to use the `StreamableFile` class at all. However, Nest supports the use of `StreamableFile` in both platform types, so if you end up switching between Express and Fastify there's no need to worry about compatibility between the two engines.

#### Example[#](/techniques/streaming-files#example)

You can find a simple example of returning the `package.json` as a file instead of a JSON below, but the idea extends out naturally to images, documents, and any other file type.

```ts

import { Controller, Get, StreamableFile } from '@nestjs/common';
import { createReadStream } from 'fs';
import { join } from 'path';

@Controller('file')
export class FileController {
  @Get()
  getFile(): StreamableFile {
    const file = createReadStream(join(process.cwd(), 'package.json'));
    return new StreamableFile(file);
  }
}
```

The default content type is `application/octet-stream`, if you need to customize the response you can use the `res.set` method.

```ts

import { Controller, Get, StreamableFile, Response } from '@nestjs/common';
import { createReadStream } from 'fs';
import { join } from 'path';

@Controller('file')
export class FileController {
  @Get()
  getFile(@Response({ passthrough: true }) res): StreamableFile {
    const file = createReadStream(join(process.cwd(), 'package.json'));
    res.set({
      'Content-Type': 'application/json',
      'Content-Disposition': 'attachment; filename="package.json"',
    });
    return new StreamableFile(file);
  }
}
```

----
url: https://docs.nestjs.com/v8/techniques/mvc
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Model-View-Controller](https://docs.nestjs.com/v8/techniques/mvc#model-view-controller)
* [Template rendering](https://docs.nestjs.com/v8/techniques/mvc#template-rendering)
* [Dynamic template rendering](https://docs.nestjs.com/v8/techniques/mvc#dynamic-template-rendering)
* [Example](https://docs.nestjs.com/v8/techniques/mvc#example)
* [Fastify](https://docs.nestjs.com/v8/techniques/mvc#fastify)
* [Example](https://docs.nestjs.com/v8/techniques/mvc#example-1)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/techniques/mvc.md "Suggest Edits")

### Model-View-Controller

Nest, by default, makes use of the [Express](https://github.com/expressjs/express) library under the hood. Hence, every technique for using the MVC (Model-View-Controller) pattern in Express applies to Nest as well.

First, let's scaffold a simple Nest application using the [CLI](https://github.com/nestjs/nest-cli) tool:

```bash

$ npm i -g @nestjs/cli
$ nest new project
```

In order to create an MVC app, we also need a [template engine](https://expressjs.com/en/guide/using-template-engines.html) to render our HTML views:

```bash

$ npm install --save hbs
```

We've used the `hbs` ([Handlebars](https://github.com/pillarjs/hbs#readme)) engine, though you can use whatever fits your requirements. Once the installation process is complete, we need to configure the express instance using the following code:

main.ts

JS TS

```typescript

import { NestFactory } from '@nestjs/core';
import { NestExpressApplication } from '@nestjs/platform-express';
import { join } from 'path';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create<NestExpressApplication>(
    AppModule,
  );

  app.useStaticAssets(join(__dirname, '..', 'public'));
  app.setBaseViewsDir(join(__dirname, '..', 'views'));
  app.setViewEngine('hbs');

  await app.listen(3000);
}
bootstrap();
```

```typescript

import { NestFactory } from '@nestjs/core';
import { join } from 'path';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(
    AppModule,
  );

  app.useStaticAssets(join(__dirname, '..', 'public'));
  app.setBaseViewsDir(join(__dirname, '..', 'views'));
  app.setViewEngine('hbs');

  await app.listen(3000);
}
bootstrap();
```

We told [Express](https://github.com/expressjs/express) that the `public` directory will be used for storing static assets, `views` will contain templates, and the `hbs` template engine should be used to render HTML output.

#### Template rendering[#](/techniques/mvc#template-rendering)

Now, let's create a `views` directory and `index.hbs` template inside it. In the template, we'll print a `message` passed from the controller:

```html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>App</title>
  </head>
  <body>
    {{ message }}
  </body>
</html>
```

Next, open the `app.controller` file and replace the `root()` method with the following code:

app.controller.ts

JS TS

```typescript

import { Get, Controller, Render } from '@nestjs/common';

@Controller()
export class AppController {
  @Get()
  @Render('index')
  root() {
    return { message: 'Hello world!' };
  }
}
```

In this code, we are specifying the template to use in the `@Render()` decorator, and the return value of the route handler method is passed to the template for rendering. Notice that the return value is an object with a property `message`, matching the `message` placeholder we created in the template.

While the application is running, open your browser and navigate to `http://localhost:3000`. You should see the `Hello world!` message.

#### Dynamic template rendering[#](/techniques/mvc#dynamic-template-rendering)

If the application logic must dynamically decide which template to render, then we should use the `@Res()` decorator, and supply the view name in our route handler, rather than in the `@Render()` decorator:

> **Hint** When Nest detects the `@Res()` decorator, it injects the library-specific `response` object. We can use this object to dynamically render the template. Learn more about the `response` object API [here](https://expressjs.com/en/api.html).

app.controller.ts

JS TS

```typescript

import { Get, Controller, Res, Render } from '@nestjs/common';
import { Response } from 'express';
import { AppService } from './app.service';

@Controller()
export class AppController {
  constructor(private appService: AppService) {}

  @Get()
  root(@Res() res: Response) {
    return res.render(
      this.appService.getViewName(),
      { message: 'Hello world!' },
    );
  }
}
```

#### Example[#](/techniques/mvc#example)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/15-mvc).

#### Fastify[#](/techniques/mvc#fastify)

As mentioned in this [chapter](/v8/techniques/performance), we are able to use any compatible HTTP provider together with Nest. One such library is [Fastify](https://github.com/fastify/fastify). In order to create an MVC application with Fastify, we have to install the following packages:

```bash

$ npm i --save fastify-static point-of-view handlebars
```

The next steps cover almost the same process used with Express, with minor differences specific to the platform. Once the installation process is complete, open the `main.ts` file and update its contents:

main.ts

JS TS

```typescript

import { NestFactory } from '@nestjs/core';
import { NestFastifyApplication, FastifyAdapter } from '@nestjs/platform-fastify';
import { AppModule } from './app.module';
import { join } from 'path';

async function bootstrap() {
  const app = await NestFactory.create<NestFastifyApplication>(
    AppModule,
    new FastifyAdapter(),
  );
  app.useStaticAssets({
    root: join(__dirname, '..', 'public'),
    prefix: '/public/',
  });
  app.setViewEngine({
    engine: {
      handlebars: require('handlebars'),
    },
    templates: join(__dirname, '..', 'views'),
  });
  await app.listen(3000);
}
bootstrap();
```

```typescript

import { NestFactory } from '@nestjs/core';
import { FastifyAdapter } from '@nestjs/platform-fastify';
import { AppModule } from './app.module';
import { join } from 'path';

async function bootstrap() {
  const app = await NestFactory.create(AppModule, new FastifyAdapter());
  app.useStaticAssets({
    root: join(__dirname, '..', 'public'),
    prefix: '/public/',
  });
  app.setViewEngine({
    engine: {
      handlebars: require('handlebars'),
    },
    templates: join(__dirname, '..', 'views'),
  });
  await app.listen(3000);
}
bootstrap();
```

The Fastify API is slightly different but the end result of those methods calls remains the same. One difference to notice with Fastify is that the template name passed into the `@Render()` decorator must include a file extension.

app.controller.ts

JS TS

```typescript

import { Get, Controller, Render } from '@nestjs/common';

@Controller()
export class AppController {
  @Get()
  @Render('index.hbs')
  root() {
    return { message: 'Hello world!' };
  }
}
```

While the application is running, open your browser and navigate to `http://localhost:3000`. You should see the `Hello world!` message.

#### Example[#](/techniques/mvc#example-1)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/17-mvc-fastify).

----
url: https://docs.nestjs.com/v7/application-context
----

* [Standalone applications](https://docs.nestjs.com/v7/standalone-applications#standalone-applications)
* [Getting started](https://docs.nestjs.com/v7/standalone-applications#getting-started)
* [Example](https://docs.nestjs.com/v7/standalone-applications#example)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/application-context.md "Suggest Edits")

### Standalone applications

There are several ways of mounting a Nest application. You can create a web app, a microservice or just a bare Nest **standalone application** (without any network listeners). The Nest standalone application is a wrapper around the Nest **IoC container**, which holds all instantiated classes. We can obtain a reference to any existing instance from within any imported module directly using the standalone application object. Thus, you can take advantage of the Nest framework anywhere, including, for example, scripted **CRON** jobs. You can even build a **CLI** on top of it.

#### Getting started[#](/standalone-applications#getting-started)

To create a Nest standalone application, use the following construction:

JS TS

```typescript

async function bootstrap() {
  const app = await NestFactory.createApplicationContext(AppModule);
  // application logic...
}
bootstrap();
```

The standalone application object allows you to obtain a reference to any instance registered within the Nest application. Let's imagine that we have a `TasksService` in the `TasksModule`. This class provides a set of methods that we want to call from within a CRON job.

JS TS

```typescript

const app = await NestFactory.create(AppModule);
const tasksService = app.get(TasksService);
```

To access the `TasksService` instance we use the `get()` method. The `get()` method acts like a **query** that searches for an instance in each registered module. Alternatively, for strict context checking, pass an options object with the `strict: true` property. With this option in effect, you have to navigate through specific modules to obtain a particular instance from the selected context.

JS TS

```typescript

const app = await NestFactory.create(AppModule);
const tasksService = app.select(TasksModule).get(TasksService, { strict: true });
```

Following is a summary of the methods available for retrieving instance references from the standalone application object.

|            |                                                                                                                                                   |
| ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| `get()`    | Retrieves an instance of a controller or provider (including guards, filters, and so on) available in the application context.                    |
| `select()` | Navigates through the modules graph to pull out a specific instance from the selected module (used together with strict mode as described above). |

> **Hint** In non-strict mode, the root module is selected by default. To select any other module, you need to navigate the modules graph manually, step by step.

If you want the node application to close after the script finishes (e.g., for a script running CRON jobs), add `await app.close()` to the end of your `bootstrap` function:

JS TS

```typescript

async function bootstrap() {
  const app = await NestFactory.createApplicationContext(AppModule);
  // application logic...
  await app.close();
}
bootstrap();
```

#### Example[#](/standalone-applications#example)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/18-context).

----
url: https://docs.nestjs.com/v5/faq/express-instance
----

### Express instance

In order to have a full control of the `express` lifecycle, you can pass a self-created instance as a second argument of the `NestFactory.create()` method.

TypeScript

```typescript

const server = express();
const app = await NestFactory.create(ApplicationModule, server);
```

* Express instance

----
url: https://docs.nestjs.com/reliability/idempotency
----

[Skip to content](#content)

On this page

* [Idempotency keys](https://docs.nestjs.com/reliability/idempotency#idempotency-keys)
* [Prerequisites](https://docs.nestjs.com/reliability/idempotency#prerequisites)
* [Make the payment endpoint idempotent](https://docs.nestjs.com/reliability/idempotency#make-the-payment-endpoint-idempotent)
* [Send keys from the mobile app](https://docs.nestjs.com/reliability/idempotency#send-keys-from-the-mobile-app)
* [Store keys in PostgreSQL](https://docs.nestjs.com/reliability/idempotency#store-keys-in-postgresql)
* [Store keys in Redis instead](https://docs.nestjs.com/reliability/idempotency#store-keys-in-redis-instead)
* [Encrypt stored receipts](https://docs.nestjs.com/reliability/idempotency#encrypt-stored-receipts)
* [Pay through GraphQL](https://docs.nestjs.com/reliability/idempotency#pay-through-graphql)
* [Deduplicate order.paid events](https://docs.nestjs.com/reliability/idempotency#deduplicate-orderpaid-events)
* [Tune TTLs and failure handling](https://docs.nestjs.com/reliability/idempotency#tune-ttls-and-failure-handling)
* [Try it](https://docs.nestjs.com/reliability/idempotency#try-it)
* [Testing](https://docs.nestjs.com/reliability/idempotency#testing)
* [Production checklist](https://docs.nestjs.com/reliability/idempotency#production-checklist)
* [The store contract](https://docs.nestjs.com/reliability/idempotency#the-store-contract)
* [Reference](https://docs.nestjs.com/reliability/idempotency#reference)

### Idempotency keys

A customer of an online store for cat food and supplies pays for salmon kibble and cat litter in the store's mobile app, on a phone on a train. The app sends `POST /orders/ord_1001/pay`. The server charges the card through the payment provider, but the response never reaches the phone. The app can't tell a lost request from a lost response, so it retries. Without protection, the retry goes wrong in one of two ways:

* It arrives after the first request finished. The order is already `paid`, so the customer gets an error for a payment that went through.
* It arrives while the first request is still waiting for the payment provider. Both requests pass the "is the order still pending?" check, and the card is charged twice.

An **idempotency key** fixes both. The client generates a unique key for each payment attempt and sends it in the `Idempotency-Key` header with every retry. The server runs the handler once per key, stores the result, and answers every retry with that result. `@nestjs/idempotency` implements this for HTTP routes, GraphQL mutations and microservice handlers with one decorator, `@Idempotent()`. Its HTTP behavior follows the IETF [Idempotency-Key header draft](https://datatracker.ietf.org/doc/draft-ietf-httpapi-idempotency-key-header/).

In this tutorial, you'll make the payment endpoint idempotent, teach the mobile app to retry safely, move the keys to PostgreSQL (or to Redis), encrypt the stored receipts, protect the GraphQL mutation, and deduplicate the `order.paid` events that the shipping service consumes.

#### Prerequisites[#](/reliability/idempotency#prerequisites)

This tutorial starts from the store's order API, which already has:

* An `OrdersModule` with an `OrdersService` and an `OrdersController`. An `Order` has an `id`, a `userId`, `items`, a `total` in cents, and a `status` of `'pending'`, `'paid'`, `'shipped'` or `'refunded'`.
* A `PaymentProviderClient` that wraps the payment provider's SDK. It throws a 402 `HttpException` when a card is declined, and a `ServiceUnavailableException` (503) when the provider is down.
* An `AuthGuard` that validates the bearer token and sets `req.user` (see [Authentication](/security/authentication#issue-tokens-to-the-mobile-app)), plus a `@CurrentUser()` parameter decorator that reads it.
* A global `ValidationPipe`, and a TCP client for the shipping service, registered as `SHIPPING_SERVICE`.
* Its data in PostgreSQL, through Drizzle, with the database registered by `@nestjs/drizzle` (see [Drizzle](/data/drizzle)). Using TypeORM? [Store keys in PostgreSQL](/reliability/idempotency#store-keys-in-postgresql) ends with the store for TypeORM.

This is the method we need to protect:

orders/orders.service.ts

JS TS

```typescript

async pay(orderId: string, user: User, dto: PayOrderDto): Promise<PaymentReceipt> {
  const order = this.ordersRepository.findOwned(orderId, user.id);
  if (order.status !== 'pending') {
    throw new ConflictException(`Order ${order.id} is already ${order.status}`);
  }
  const charge = await this.paymentProviderClient.charge({
    amount: order.total,
    paymentMethod: dto.paymentMethod,
    reference: order.id,
  });
  this.ordersRepository.markPaid(order.id);
  this.shipping.emit('order.paid', {
    eventId: `order-paid:${order.id}`,
    orderId: order.id,
  });

  return {
    orderId: order.id,
    receiptId: charge.id,
    amount: charge.amount,
    cardLast4: charge.cardLast4,
    paidAt: charge.createdAt,
  };
}
```

The status check can't stop a double charge on its own: two requests that arrive together both see `pending` before either one reaches `markPaid()`.

Install the package:

```bash

$ npm i --save @nestjs/idempotency
```

#### Make the payment endpoint idempotent[#](/reliability/idempotency#make-the-payment-endpoint-idempotent)

Register `IdempotencyModule` once, in the root module:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { IdempotencyModule } from '@nestjs/idempotency';
import type { User } from './orders/order.js';
import { OrdersModule } from './orders/orders.module.js';

@Module({
  imports: [
    IdempotencyModule.forRoot({
      // Runs after guards, so req.user is set. Keys never collide across users.
      scope: (req: { user?: User }) => req.user?.id,
    }),
    OrdersModule,
  ],
})
export class AppModule {}
```

The module is global. It registers one app-wide interceptor, which does nothing for handlers that aren't marked with `@Idempotent()`, so no other route changes behavior.

`scope` gives every user's keys their own namespace. Without it, all clients share one namespace, and a key that one user picks could replay another user's receipt. With it, Alice and Bob can both send `Idempotency-Key: 1` without ever seeing each other's results. Because guards run before interceptors, `req.user` is already set when `scope` runs, and an unauthenticated request is rejected before it can use up a key. If a signed-in user calls an `@Idempotent()` handler that has no `scope`, the module logs a warning, once for each handler. Where one shared namespace is deliberate, such as a webhook keyed by the provider's event ids, set `scope: false`.

Now mark the handler:

orders/orders.controller.ts

JS TS

```typescript

import { Body, Controller, Param, Post, UseGuards } from '@nestjs/common';
import { Idempotent } from '@nestjs/idempotency';
import { AuthGuard } from '../auth/auth.guard.js';
import { CurrentUser } from '../auth/current-user.decorator.js';
import { PayOrderDto } from './dto/pay-order.dto.js';
import type { User } from './order.js';
import { OrdersService } from './orders.service.js';

@Controller('orders')
@UseGuards(AuthGuard)
export class OrdersController {
  constructor(private readonly ordersService: OrdersService) {}

  @Post(':id/pay')
  @Idempotent({ required: true })
  pay(
    @Param('id') id: string,
    @Body() dto: PayOrderDto,
    @CurrentUser() user: User,
  ) {
    return this.ordersService.pay(id, user, dto);
  }
}
```

`required: true` rejects a request without a key with a 400 `IDEMPOTENCY_KEY_REQUIRED` error, before the handler runs. A payment without a key can't be retried safely, so it's better to refuse it than to charge the card unprotected.

Here's what happens to a request that carries a key:

1. The interceptor computes a **fingerprint** of the request: a SHA-256 hash of the scope, the method, the URL (which includes the order id) and the body, with object keys sorted.
2. It atomically takes a lock on the **record key**`<scope>:<key>`, for example `usr_alice:5e0f6d0e-…`. If a record already exists, the handler doesn't run (see the table below). While the handler runs, the interceptor keeps renewing the lock, so a slow handler never loses it to a retry.
3. The handler runs. When it finishes, the lock becomes a completed record that holds the response: the status code, the body, and the headers from a short allowlist (`Location`, `Content-Type`, `Content-Language`, `Content-Location`, `ETag` and `Last-Modified`) if the handler or a middleware set them. They describe the stored body, so a retry sent with another `Accept-Language` still gets the stored body's `Content-Language`. Cookies, CORS and rate-limit headers belong to the original request and are never replayed.

Every later request with the same key gets one of these answers:

| Situation                             | Response                                                                               |
| ------------------------------------- | -------------------------------------------------------------------------------------- |
| The first request is still running    | 409 `IDEMPOTENCY_KEY_IN_USE`, with a `Retry-After` header                              |
| The first request completed           | The stored status and body, plus `Idempotent-Replayed: true`. The handler doesn't run. |
| Same key, but a different body or URL | 422 `IDEMPOTENCY_KEY_REUSED`                                                           |

Errors can be stored too. [Tune TTLs and failure handling](/reliability/idempotency#tune-ttls-and-failure-handling) covers which ones.

Because the interceptor is global, it runs outside the interceptors of your controllers and handlers. The stored body is exactly what the client received, after serializers and other interceptors ran, and a replay skips all of them. Pipes run inside it, so a `ValidationPipe` 400 is stored like any other client error. Other global interceptors are a different matter, as the production checklist explains.

Until you [store keys in PostgreSQL](/reliability/idempotency#store-keys-in-postgresql), records live in memory, in the default `InMemoryIdempotencyStore`. That's fine for a single instance in development, but every instance of the API has its own records, and they're lost on restart. When `NODE_ENV` is `production`, the app refuses to start this way, with an error that says how to register a store.

#### Send keys from the mobile app[#](/reliability/idempotency#send-keys-from-the-mobile-app)

The server can only deduplicate what the client sends consistently. The app follows two rules:

* It creates the key when the customer taps **Pay**, not once per request. Every retry of that payment sends the same key, even after the app is killed and restarted, so the key is saved with the pending payment.
* It creates a new key only for a new decision by the customer, such as choosing another card after a decline. Sending an old key with a different body is a 422.

mobile/pay-order.ts

JS TS

```typescript

export interface Receipt {
  orderId: string;
  receiptId: string;
  amount: number;
  cardLast4: string;
  paidAt: string;
}

export interface PendingPayment {
  orderId: string;
  paymentMethod: string;
  idempotencyKey: string;
}

export class PaymentError extends Error {
  constructor(
    readonly status: number,
    readonly body: { code?: string; message?: string },
  ) {
    super(body.message ?? `Payment failed with status ${status}`);
  }
}

// Call when the customer taps "Pay", and save the result with the order
// (for example in AsyncStorage). Retries, even after an app restart, reuse it.
export function startPayment(orderId: string, paymentMethod: string): PendingPayment {
  return { orderId, paymentMethod, idempotencyKey: crypto.randomUUID() };
}

export async function payOrder(
  apiUrl: string,
  token: string,
  payment: PendingPayment,
  maxAttempts = 5,
): Promise<Receipt> {
  for (let attempt = 1; ; attempt++) {
    const backoff = 250 * 2 ** (attempt - 1);
    let res: Response;
    try {
      res = await fetch(`${apiUrl}/orders/${payment.orderId}/pay`, {
        method: 'POST',
        headers: {
          Authorization: `Bearer ${token}`,
          'Content-Type': 'application/json',
          'Idempotency-Key': payment.idempotencyKey,
        },
        body: JSON.stringify({ paymentMethod: payment.paymentMethod }),
        signal: AbortSignal.timeout(15_000),
      });
    } catch (err) {
      // No response: the card may or may not have been charged. Same key, try again.
      if (attempt >= maxAttempts) {
        throw err;
      }
      await sleep(backoff);
      continue;
    }
    if (res.ok) {
      return res.json(); // the first result, even if Idempotent-Replayed: true
    }
    const body = await res.json().catch(() => ({})); // a proxy's 502 page isn't JSON
    const retryable =
      res.status >= 500 || // the server released the key
      res.status === 429 ||
      body.code === 'IDEMPOTENCY_KEY_IN_USE'; // the first attempt is still running
    if (!retryable || attempt >= maxAttempts) {
      throw new PaymentError(res.status, body);
    }
    const retryAfter = Number(res.headers.get('Retry-After'));
    await sleep(retryAfter > 0 ? retryAfter * 1000 : backoff);
  }
}

const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));
```

`crypto.randomUUID()` is available in browsers and Node.js. In React Native, use a UUID library, such as `randomUUID()` from `expo-crypto`.

These are the responses the app can get, and what they mean for a retry:

| Response                                                    | Meaning                                                                 | Retry with the same key?                         |
| ----------------------------------------------------------- | ----------------------------------------------------------------------- | ------------------------------------------------ |
| No response (network error, timeout)                        | The card may or may not have been charged                               | Yes                                              |
| 2xx                                                         | Done. With `Idempotent-Replayed: true`, it's the first attempt's result | No, show the receipt                             |
| 409 with the code `IDEMPOTENCY_KEY_IN_USE`                  | The first attempt is still running                                      | Yes, after `Retry-After` seconds                 |
| 5xx                                                         | The attempt failed, and the server released the key                     | Yes, with backoff                                |
| 429                                                         | Rate limited before the handler ran                                     | Yes, after `Retry-After` seconds                 |
| 422 `IDEMPOTENCY_KEY_REUSED`                                | A bug: the key was reused for a different request                       | No                                               |
| Any other 4xx: 400, 402 (declined), 404, 409 (already paid) | Final. Every retry with this key gets the same answer                   | No. Show the error; a new attempt gets a new key |

Check `code`, not just the status. A 409 can also mean that the order is already paid, and that one is final.

#### Store keys in PostgreSQL[#](/reliability/idempotency#store-keys-in-postgresql)

The in-memory store isn't enough in production. Its records vanish whenever the process stops, on every deploy or replaced container, so a retry that arrives afterwards runs the payment again. And once the API runs on more than one instance, a retry that lands on another instance wouldn't find the record, and two instances could both take the lock. The records need a shared store that can "create unless it exists" atomically.

`@nestjs/idempotency` doesn't ship one. It defines the contract, the `IdempotencyStore` interface, and you implement it in a provider of your app, with the database or the Redis client it already has. The interface has four methods. Each one takes the record key and an owner first, and durations arrive in whole milliseconds:

* `acquire(key, owner, fingerprint, lockTtl)` creates the lock, or returns the existing record: in flight, or completed with its response. It must be atomic: of any number of concurrent calls for a free key, exactly one may win.
* `complete(key, owner, response, ttl)` turns the lock into a completed record, if `owner` still holds it.
* `release(key, owner)` deletes the lock, if `owner` still holds it, so a retry can run the handler again.
* `extend(key, owner, lockTtl)` resets the lock's expiry to `lockTtl` from now, if `owner` still holds it. The interceptor calls it every `lockTtl / 3` while the handler runs and its result is being stored.

`owner` is a random id for each attempt, known as a fencing token. If an attempt stops renewing its lock (its instance crashed, say) and a retry takes over after `lockTtl`, the old attempt's `extend()`, `complete()` or `release()` does nothing, instead of overwriting the retry's record. So "if `owner` still holds it" has to be checked in the same atomic operation that writes: checked in a separate read first, a takeover could slip in between.

This section shows that store twice: first with Drizzle, which is the tutorial's path, and then, under "With TypeORM" at the end of the section, the same store for an application whose ORM is TypeORM. Take one of the two.

The store keeps its data in PostgreSQL, with Drizzle, so the records get a table in its Drizzle schema:

database/schema.ts

JS TS

```typescript

import type { IdempotencyStoredPayload } from '@nestjs/idempotency';
import { bigint, index, json, pgTable, text } from 'drizzle-orm/pg-core';

/** One row per idempotency record: an in-flight lock, or a completed response. */
export const idempotencyKeys = pgTable(
  'idempotency_keys',
  {
    // SHA-256 of the record key: keys can be longer than an index entry allows.
    keyHash: text('key_hash').primaryKey(),
    key: text('key').notNull(),
    fingerprint: text('fingerprint').notNull(),
    // The attempt holding the lock; null once the record is completed.
    owner: text('owner'),
    // null while in flight. json, not jsonb: jsonb rejects "\u0000" in strings.
    response: json('response').$type<IdempotencyStoredPayload>(),
    // Epoch milliseconds.
    expiresAt: bigint('expires_at', { mode: 'number' }).notNull(),
  },
  (table) => [index('idempotency_keys_expires_at_idx').on(table.expiresAt)],
);
```

The primary key is a SHA-256 hash of the record key, because record keys (a scope, the client's key and, for GraphQL, the field's path) can be longer than PostgreSQL allows in an index entry. The response is `json` rather than `jsonb`, because `jsonb` rejects a `\u0000` inside a string, and a response body can contain one. Generate the migration with drizzle-kit, and apply it with `npx drizzle-kit migrate` as usual:

```bash

$ npx drizzle-kit generate --name=idempotency
```

drizzle/0000\_idempotency.sql

JS TS

```sql

CREATE TABLE "idempotency_keys" (
	"key_hash" text PRIMARY KEY NOT NULL,
	"key" text NOT NULL,
	"fingerprint" text NOT NULL,
	"owner" text,
	"response" json,
	"expires_at" bigint NOT NULL
);
--> statement-breakpoint
CREATE INDEX "idempotency_keys_expires_at_idx" ON "idempotency_keys" USING btree ("expires_at");
```

The store implements each method with Drizzle's query builder. It injects the database with `@InjectDrizzle()` from `@nestjs/drizzle`, and the constructor registers the store with `IdempotencyStorage`, a registry that `IdempotencyModule` exports:

idempotency/drizzle-idempotency.store.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { InjectDrizzle } from '@nestjs/drizzle';
import {
  IdempotencyStorage,
  type IdempotencyAcquireResult,
  type IdempotencyStore,
  type IdempotencyStoredPayload,
} from '@nestjs/idempotency';
import { and, eq, gt, inArray, lte } from 'drizzle-orm';
import type { PgDatabase, PgQueryResultHKT } from 'drizzle-orm/pg-core';
import { createHash } from 'node:crypto';
import { idempotencyKeys } from '../database/schema.js';

/** A Drizzle database on PostgreSQL: node-postgres in the app, PGlite in its tests. */
export type Database = PgDatabase<PgQueryResultHKT>;

const { keyHash, owner: ownerColumn, expiresAt } = idempotencyKeys;

@Injectable()
export class DrizzleIdempotencyStore implements IdempotencyStore {
  constructor(
    @InjectDrizzle() private readonly db: Database,
    storage: IdempotencyStorage,
  ) {
    storage.registerSource(this);
  }

  async acquire(
    key: string,
    owner: string,
    fingerprint: string,
    lockTtl: number,
  ): Promise<IdempotencyAcquireResult> {
    const hash = hashOf(key);
    // A second round only happens when the row was released or expired
    // between the two statements below.
    for (let attempt = 0; attempt < 5; attempt++) {
      const now = Date.now();
      const lock = { fingerprint, owner, response: null, expiresAt: now + lockTtl };
      // Insert the lock, or take over an expired row. Of many concurrent
      // callers, PostgreSQL lets one write, and re-checks `setWhere` for the
      // others against the winner's row: they get no row back.
      const taken = await this.db
        .insert(idempotencyKeys)
        .values({ keyHash: hash, key, ...lock })
        .onConflictDoUpdate({
          target: keyHash,
          set: lock,
          setWhere: lte(expiresAt, now),
        })
        .returning({ keyHash });
      if (taken.length) {
        return { state: 'acquired' };
      }

      // Someone else holds the key: report their lock or record.
      const [row] = await this.db
        .select()
        .from(idempotencyKeys)
        .where(eq(keyHash, hash));
      if (row && row.expiresAt > now) {
        return row.response === null
          ? { state: 'in-flight', fingerprint: row.fingerprint }
          : { state: 'completed', fingerprint: row.fingerprint, response: row.response };
      }
    }
    throw new Error(`The idempotency record for "${key}" kept changing; try again`);
  }

  async complete(
    key: string,
    owner: string,
    response: IdempotencyStoredPayload,
    ttl: number,
  ): Promise<boolean> {
    const now = Date.now();
    const done = await this.db
      .update(idempotencyKeys)
      .set({ owner: null, response, expiresAt: now + ttl })
      .where(this.ownedBy(key, owner, now))
      .returning({ keyHash });
    return done.length === 1;
  }

  async release(key: string, owner: string): Promise<boolean> {
    const released = await this.db
      .delete(idempotencyKeys)
      .where(this.ownedBy(key, owner, Date.now()))
      .returning({ keyHash });
    return released.length === 1;
  }

  async extend(key: string, owner: string, lockTtl: number): Promise<boolean> {
    const now = Date.now();
    const extended = await this.db
      .update(idempotencyKeys)
      .set({ expiresAt: now + lockTtl })
      .where(this.ownedBy(key, owner, now))
      .returning({ keyHash });
    return extended.length === 1;
  }

  /**
   * Deletes up to `limit` expired rows, for a scheduled job. Expired rows are
   * already ignored, and reused by the next request with the same key.
   */
  async prune(limit = 1000): Promise<number> {
    const now = Date.now();
    const expired = this.db
      .select({ keyHash })
      .from(idempotencyKeys)
      .where(lte(expiresAt, now))
      .limit(limit);
    const deleted = await this.db
      .delete(idempotencyKeys)
      // Checks the expiry again: a row taken over since the subquery read it stays.
      .where(and(inArray(keyHash, expired), lte(expiresAt, now)))
      .returning({ keyHash });
    return deleted.length;
  }

  /** The caller's lock, if it still holds it and it hasn't expired. */
  private ownedBy(key: string, owner: string, now: number) {
    return and(eq(keyHash, hashOf(key)), eq(ownerColumn, owner), gt(expiresAt, now));
  }
}

function hashOf(key: string) {
  return createHash('sha256').update(key).digest('hex');
}
```

The database is typed as `PgDatabase`, what Drizzle's node-postgres and PGlite drivers have in common, so the tests below can run the store on PGlite. Each method is a single statement that PostgreSQL runs atomically, without a transaction:

* `acquire()` inserts the lock, or takes over an expired row, with one `INSERT ... ON CONFLICT DO UPDATE ... WHERE expires_at <= now`. When several callers race for a key, PostgreSQL lets one of them write and checks the `WHERE` again for the others against the winner's row, so they get no row back and read the winner's lock instead. If that row disappears in between (released, or expired), `acquire()` goes round again.
* `complete()`, `extend()` and `release()` check the owner, and that the lock hasn't expired, in the `WHERE` of the statement that writes. They count the rows that `returning()` gives back, which works the same on every Drizzle driver.
* Expired rows are ignored at once, and the next request with the same key reuses its row. To delete the rest, call `prune()` from a scheduled job, for example with `@Interval()` from `@nestjs/schedule`. It checks the expiry again in the `DELETE` itself, so a row that a retry took over in the meantime stays.

Expiry times come from each instance's clock (`Date.now()`), so keep the clocks in sync, as NTP does. Every idempotent request adds one or two statements to the connection pool, plus an `UPDATE` every `lockTtl / 3` while its handler runs.

The store is an ordinary provider. Register the database with `DrizzleModule` (see [Drizzle](/data/drizzle)), and add the store to the providers of `AppModule`:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { DrizzleModule } from '@nestjs/drizzle';
import { IdempotencyModule } from '@nestjs/idempotency';
import { drizzle } from 'drizzle-orm/node-postgres';
import { DrizzleIdempotencyStore } from './idempotency/drizzle-idempotency.store.js';
import type { User } from './orders/order.js';
import { OrdersModule } from './orders/orders.module.js';

@Module({
  imports: [
    DrizzleModule.forRootAsync({
      useFactory: () => ({ drizzle, connection: process.env.DATABASE_URL! }),
    }),
    IdempotencyModule.forRoot({
      scope: (req: { user?: User }) => req.user?.id,
    }),
    OrdersModule,
  ],
  // Registers itself with IdempotencyStorage when Nest creates it.
  providers: [DrizzleIdempotencyStore],
})
export class AppModule {}
```

> **Hint** The app reads `DATABASE_URL`, and, once receipts are encrypted, `IDEMPOTENCY_KEYS`, from `process.env`. An application loads its environment through `@nestjs/config`, with a validation schema that stops startup when a variable is missing, and injects `ConfigService` into these factories instead.

At startup, the module logs the store it uses, `IdempotencyStorage: DrizzleIdempotencyStore`, and then it stops taking registrations:

* An app has one store. A second `registerSource()` call throws, naming both classes.
* Register from the constructor of a singleton provider. The registry locks when `IdempotencyModule` initializes, so a store that registers later (from a lifecycle hook, per request, or in a lazy-loaded module) throws instead of being silently ignored.
* Without a registered store, the module keeps records in memory. In production (`NODE_ENV=production`), it refuses to start that way, unless you set `allowInMemoryStorage: true`, which accepts that every restart or deploy forgets the records.

Every store is tested with the same contract suite, which `@nestjs/idempotency/testing` exports as plain test cases for any test runner. It covers each method, the owner checks, expiry, and, with `concurrent`, the races that a store that reads and then writes gets wrong. The example project runs it against this store on PGlite, and on PostgreSQL through a `pg` pool, where 32 callers race for each key on up to 16 connections:

test/step-3.drizzle-store.spec.ts

JS TS

```typescript

import { PGlite } from '@electric-sql/pglite';
import { IdempotencyStorage } from '@nestjs/idempotency';
import { idempotencyStoreContract } from '@nestjs/idempotency/testing';
import { drizzle as drizzlePglite } from 'drizzle-orm/pglite';
import { migrate as migratePglite } from 'drizzle-orm/pglite/migrator';
import { DrizzleIdempotencyStore } from '../src/idempotency/drizzle-idempotency.store.js';

const migrationsFolder = new URL('../drizzle', import.meta.url).pathname;
// ...
describe('DrizzleIdempotencyStore on PGlite', () => {
  let pglite: PGlite;
  let store: DrizzleIdempotencyStore;

  beforeAll(async () => {
    pglite = new PGlite();
    const db = drizzlePglite(pglite);
    await migratePglite(db, { migrationsFolder }); // npx drizzle-kit migrate
    store = new DrizzleIdempotencyStore(db, new IdempotencyStorage());
  });
  afterAll(() => pglite.close());

  describe('the IdempotencyStore contract', () => {
    // The store reads Date.now(): fake Date alone, so the driver keeps its timers.
    beforeEach(() => vi.useFakeTimers({ toFake: ['Date'] }));
    afterEach(() => vi.useRealTimers());

    // One store and one table for every case: each case uses keys of its own.
    const cases = idempotencyStoreContract(() => store, {
      advanceTime: (ms) => vi.setSystemTime(Date.now() + ms),
      concurrent: true,
    });
    for (const c of cases) {
      it(c.name, c.run);
    }
  });
  // ...
});
```

**With TypeORM.** The same store for an application whose ORM is TypeORM, on the same table. Drizzle stays the tutorial's path: take this store instead of the one above, not next to it. The table is an entity, and every column states its type, so that the TypeORM CLI, which loads it without decorator metadata, sees the same schema as the application:

typeorm/idempotency-key.entity.ts

JS TS

```typescript

import { Column, Entity, Index, PrimaryColumn } from 'typeorm';

// The idempotency_keys table of the Drizzle schema in src/database/schema.ts, as an entity.
// Every column states its type, so the entity loads the same with or without emitted
// decorator metadata (the TypeORM CLI runs it through tsx, which emits none).

/** Reads a `bigint` column as a number: TypeORM returns it as a string. */
const epochMs = {
  to: (value: number) => value,
  from: (value: string) => Number(value),
};

/** One row per idempotency record: an in-flight lock, or a completed response. */
@Entity('idempotency_keys')
@Index('idempotency_keys_expires_at_idx', ['expiresAt'])
export class IdempotencyKeyEntity {
  // SHA-256 of the record key: keys can be longer than an index entry allows.
  @PrimaryColumn({ type: 'text', name: 'key_hash' })
  keyHash: string;

  @Column({ type: 'text' })
  key: string;

  @Column({ type: 'text' })
  fingerprint: string;

  // The attempt holding the lock; null once the record is completed.
  @Column({ type: 'text', nullable: true })
  owner: string | null;

  // null while in flight. json, not jsonb: jsonb rejects "\u0000" in strings. An
  // IdempotencyStoredPayload, typed `object`: its `unknown` body doesn't fit TypeORM's insert types.
  @Column({ type: 'json', nullable: true })
  response: object | null;

  // Epoch milliseconds.
  @Column({ type: 'bigint', name: 'expires_at', transformer: epochMs })
  expiresAt: number;
}
```

TypeORM returns a `bigint` column as a string, so a transformer reads `expiresAt` back as a number. The response column is typed `object` rather than `IdempotencyStoredPayload`, because the payload's `unknown` body doesn't fit TypeORM's insert types; the store casts it when it reads a record. The TypeORM CLI and `TypeOrmModule` share one set of options, in a data source file:

typeorm/data-source.ts

JS TS

```typescript

import { DataSource, type DataSourceOptions } from 'typeorm';
import { IdempotencyKeyEntity } from './idempotency-key.entity.js';
import { Idempotency1790321611502 } from './migrations/1790321611502-Idempotency.js';

/** What the application's TypeOrmModule and the TypeORM CLI share. */
export const dataSourceOptions = {
  type: 'postgres',
  url: process.env.DATABASE_URL,
  entities: [IdempotencyKeyEntity],
  migrations: [Idempotency1790321611502],
} satisfies DataSourceOptions;

// The TypeORM CLI's data source: `migration:generate` compares the entities with this database.
export default new DataSource(dataSourceOptions);
```

Generate the migration from the entity, apply it, and check that the entity and the database agree. The CLI needs a TypeScript loader for the data source file; this uses `tsx`:

```bash

$ npx tsx ./node_modules/typeorm/cli.js migration:generate src/typeorm/migrations/Idempotency -d src/typeorm/data-source.ts --pretty
Migration /store/src/typeorm/migrations/1790321611502-Idempotency.ts has been generated successfully.
$ npx tsx ./node_modules/typeorm/cli.js migration:run -d src/typeorm/data-source.ts
$ npx tsx ./node_modules/typeorm/cli.js migration:generate src/typeorm/migrations/Check -d src/typeorm/data-source.ts --check
No changes in database schema were found
```

The migration it wrote, `1790321611502-Idempotency.ts`, is the `CREATE TABLE` and `CREATE INDEX` statements of the Drizzle migration, and `migrations` in the data source lists it. Now the store, under the same rules as the Drizzle one:

typeorm/typeorm-idempotency.store.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import {
  IdempotencyStorage,
  type IdempotencyAcquireResult,
  type IdempotencyStore,
  type IdempotencyStoredPayload,
} from '@nestjs/idempotency';
import { createHash } from 'node:crypto';
import { DataSource, MoreThan } from 'typeorm';
import { IdempotencyKeyEntity } from './idempotency-key.entity.js';

/**
 * Keeps idempotency records in PostgreSQL, through TypeORM: the Drizzle
 * store, on the same table. Each method is a single statement, so the
 * guarantees hold with any number of API instances.
 */
@Injectable()
export class TypeOrmIdempotencyStore implements IdempotencyStore {
  constructor(
    private readonly dataSource: DataSource,
    storage: IdempotencyStorage,
  ) {
    storage.registerSource(this);
  }

  async acquire(
    key: string,
    owner: string,
    fingerprint: string,
    lockTtl: number,
  ): Promise<IdempotencyAcquireResult> {
    const hash = hashOf(key);
    // A second round only happens when the row was released or expired
    // between the two statements below.
    for (let attempt = 0; attempt < 5; attempt++) {
      const now = Date.now();
      // Insert the lock, or take over an expired row. Of many concurrent
      // callers, PostgreSQL lets one write, and re-checks the overwrite
      // condition for the others against the winner's row: they get no row back.
      const { raw } = await this.dataSource
        .createQueryBuilder()
        .insert()
        .into(IdempotencyKeyEntity)
        .values({ keyHash: hash, key, fingerprint, owner, response: null, expiresAt: now + lockTtl })
        .orUpdate(['fingerprint', 'owner', 'response', 'expires_at'], ['key_hash'], {
          overwriteCondition: { where: 'idempotency_keys.expires_at <= :now', parameters: { now } },
        })
        .returning(['keyHash'])
        .updateEntity(false)
        .execute();
      if ((raw as unknown[]).length === 1) {
        return { state: 'acquired' };
      }

      // Someone else holds the key: report their lock or record.
      const row = await this.dataSource.manager.findOneBy(IdempotencyKeyEntity, { keyHash: hash });
      if (row && row.expiresAt > now) {
        return row.response === null
          ? { state: 'in-flight', fingerprint: row.fingerprint }
          : { state: 'completed', fingerprint: row.fingerprint, response: row.response as IdempotencyStoredPayload };
      }
    }
    throw new Error(`The idempotency record for "${key}" kept changing; try again`);
  }

  async complete(
    key: string,
    owner: string,
    response: IdempotencyStoredPayload,
    ttl: number,
  ): Promise<boolean> {
    const now = Date.now();
    const { affected } = await this.dataSource.manager.update(IdempotencyKeyEntity, ownedBy(key, owner, now), {
      owner: null,
      response,
      expiresAt: now + ttl,
    });
    return affected === 1;
  }

  async release(key: string, owner: string): Promise<boolean> {
    const { affected } = await this.dataSource.manager.delete(IdempotencyKeyEntity, ownedBy(key, owner, Date.now()));
    return affected === 1;
  }

  async extend(key: string, owner: string, lockTtl: number): Promise<boolean> {
    const now = Date.now();
    const { affected } = await this.dataSource.manager.update(IdempotencyKeyEntity, ownedBy(key, owner, now), {
      expiresAt: now + lockTtl,
    });
    return affected === 1;
  }

  /**
   * Deletes up to `limit` expired rows, for a scheduled job. Expired rows are
   * already ignored, and reused by the next request with the same key.
   */
  async prune(limit = 1000): Promise<number> {
    const expired = this.dataSource.manager
      .createQueryBuilder(IdempotencyKeyEntity, 'expired')
      .select('expired.keyHash')
      .where('expired.expiresAt <= :now')
      .limit(limit);
    const { affected } = await this.dataSource
      .createQueryBuilder()
      .delete()
      .from(IdempotencyKeyEntity)
      .where(`key_hash IN (${expired.getQuery()})`)
      // Checks the expiry again: a row taken over since the subquery read it stays.
      .andWhere('expires_at <= :now', { now: Date.now() })
      .execute();
    return affected ?? 0;
  }
}

/** The caller's lock, if it still holds it and it hasn't expired. */
function ownedBy(key: string, owner: string, now: number) {
  return { keyHash: hashOf(key), owner, expiresAt: MoreThan(now) };
}

function hashOf(key: string) {
  return createHash('sha256').update(key).digest('hex');
}
```

* **`acquire()`** is the same `INSERT ... ON CONFLICT DO UPDATE ... WHERE expires_at <= now`, through the insert query builder: `orUpdate()` lists the columns a takeover overwrites, its `overwriteCondition` option is the `WHERE`, and `returning()` gives back a row only to the caller that wrote.
* **`complete()`, `extend()` and `release()`** are `update()` and `delete()` on the entity manager, with the owner and `MoreThan(now)` in their criteria, and they read `affected`. Never `save()`: it reads the row first, so a takeover could slip in between.
* **`prune()`** builds the subquery that picks the expired rows with a select query builder, and puts its SQL in the `WHERE` of the `DELETE`, next to the expiry check.

The store injects the `DataSource` that `TypeOrmModule` provides. Register the module with the data source's options in place of `DrizzleModule`, and the store in place of `DrizzleIdempotencyStore`:

typeorm/app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { IdempotencyModule } from '@nestjs/idempotency';
import { TypeOrmModule } from '@nestjs/typeorm';
import type { User } from '../orders/order.js';
import { OrdersModule } from '../orders/orders.module.js';
import { dataSourceOptions } from './data-source.js';
import { TypeOrmIdempotencyStore } from './typeorm-idempotency.store.js';

@Module({
  imports: [
    TypeOrmModule.forRootAsync({
      // The entity and migration the CLI uses; migrations run on deploy (`migration:run`).
      useFactory: () => ({ ...dataSourceOptions, url: process.env.DATABASE_URL }),
    }),
    IdempotencyModule.forRoot({
      scope: (req: { user?: User }) => req.user?.id,
    }),
    OrdersModule,
  ],
  // Registers itself with IdempotencyStorage when Nest creates it.
  providers: [TypeOrmIdempotencyStore],
})
export class AppModule {}
```

The contract suite runs on it unchanged. TypeORM connects through `pg`, so the suite needs a PostgreSQL server and is skipped without one. One more case checks that the entity and the migration agree, which is what `migration:generate --check` checks:

test/typeorm-idempotency.store.spec.ts

JS TS

```typescript

import { IdempotencyStorage } from '@nestjs/idempotency';
import { idempotencyStoreContract } from '@nestjs/idempotency/testing';
import { DataSource } from 'typeorm';
import { startPostgres } from '../../../test-support/postgres.js';
import { dataSourceOptions } from '../src/typeorm/data-source.js';
import { TypeOrmIdempotencyStore } from '../src/typeorm/typeorm-idempotency.store.js';
// ...
const { postgres, reason } = await startPostgres();
afterAll(() => postgres?.stop());

describe.skipIf(!postgres)(`TypeOrmIdempotencyStore on PostgreSQL${postgres ? '' : ` (skipped: ${reason})`}`, () => {
  let dataSource: DataSource;
  let url: string;
  let store: TypeOrmIdempotencyStore;

  beforeAll(async () => {
    url = await postgres!.createDatabase('idempotency_typeorm_store');
    dataSource = await new DataSource({ ...dataSourceOptions, url, poolSize: 16 }).initialize();
    await dataSource.runMigrations(); // npx typeorm migration:run
    store = new TypeOrmIdempotencyStore(dataSource, new IdempotencyStorage());
  });
  afterAll(() => dataSource?.destroy());

  describe('the IdempotencyStore contract', () => {
    // The store reads Date.now(): fake Date alone, so the driver keeps its timers.
    beforeEach(() => vi.useFakeTimers({ toFake: ['Date'] }));
    afterEach(() => vi.useRealTimers());

    // One store and one table for every case: each case uses keys of its own.
    // 32 callers per race, on up to 16 connections.
    const cases = idempotencyStoreContract(() => store, {
      advanceTime: (ms) => vi.setSystemTime(Date.now() + ms),
      concurrent: { callers: 32 },
    });
    for (const c of cases) {
      it(c.name, c.run);
    }
  });

  it('has a migration that matches the entity (what `migration:generate --check` checks)', async () => {
    const { upQueries } = await dataSource.driver.createSchemaBuilder().log();
    expect(upQueries.map((query) => query.query)).toEqual([]);
  });
  // ...
});
```

`startPostgres()` is a test helper that creates a throwaway database on a PostgreSQL server, or skips the suite without one. The example also runs two instances of the TypeORM `AppModule` on one database, one charging while the other answers 409.

> **Hint** Using Prisma? [The store contract](/reliability/idempotency#the-store-contract), after the tutorial, shows how Prisma expresses these statements. Check your store with the same suite.

#### Store keys in Redis instead[#](/reliability/idempotency#store-keys-in-redis-instead)

If your API already runs Redis, it can keep the records there instead of in PostgreSQL. Redis suits this store well: a record is a small hash that Redis expires on its own, so there's no pruning job, and a hot key, such as a client retrying one payment every second, costs a round trip to memory instead of a row lock in the primary database. The price is a second store to run, protect and back up, and Redis has to be configured never to evict the records (see the production checklist).

Each method is one Lua script, which Redis runs atomically:

idempotency/redis-idempotency.store.ts

JS TS

```typescript

import { Inject, Injectable } from '@nestjs/common';
import {
  IdempotencyStorage,
  type IdempotencyAcquireResult,
  type IdempotencyStore,
  type IdempotencyStoredPayload,
} from '@nestjs/idempotency';
import { REDIS } from '../redis/redis.module.js';

/** The one ioredis method this store needs. */
export interface RedisClient {
  eval(script: string, numKeys: number, ...args: (string | number)[]): Promise<unknown>;
}

// Creates the lock if no record exists. Otherwise returns the record, in the
// same round trip.
const ACQUIRE = `
if redis.call('EXISTS', KEYS[1]) == 0 then
  redis.call('HSET', KEYS[1], 'state', 'in-flight', 'fp', ARGV[1], 'owner', ARGV[2])
  redis.call('PEXPIRE', KEYS[1], ARGV[3])
  return {1}
end
local r = redis.call('HMGET', KEYS[1], 'state', 'fp', 'resp')
return {0, r[1], r[2], r[3]}
`;

// Turns our lock into a completed record, unless another attempt took it over.
const COMPLETE = `
if redis.call('HGET', KEYS[1], 'owner') ~= ARGV[1] then return 0 end
redis.call('HSET', KEYS[1], 'state', 'completed', 'resp', ARGV[2])
redis.call('HDEL', KEYS[1], 'owner')
redis.call('PEXPIRE', KEYS[1], ARGV[3])
return 1
`;

// Deletes the lock, but only if it is still ours.
const RELEASE = `
if redis.call('HGET', KEYS[1], 'owner') == ARGV[1] then
  return redis.call('DEL', KEYS[1])
end
return 0
`;

// Renews our lock while the handler runs, but only if it is still ours.
const EXTEND = `
if redis.call('HGET', KEYS[1], 'owner') ~= ARGV[1] then return 0 end
redis.call('PEXPIRE', KEYS[1], ARGV[2])
return 1
`;

type AcquireReply =
  | [1]
  | [0, 'in-flight' | 'completed', string, string | null];

@Injectable()
export class RedisIdempotencyStore implements IdempotencyStore {
  constructor(
    @Inject(REDIS) private readonly redis: RedisClient,
    storage: IdempotencyStorage,
  ) {
    storage.registerSource(this);
  }

  async acquire(
    key: string,
    owner: string,
    fingerprint: string,
    lockTtl: number,
  ): Promise<IdempotencyAcquireResult> {
    const reply = (await this.redis.eval(
      ACQUIRE, 1, this.key(key), fingerprint, owner, lockTtl,
    )) as AcquireReply;
    if (reply[0] === 1) {
      return { state: 'acquired' };
    }
    const [, state, storedFingerprint, response] = reply;
    return state === 'completed'
      ? { state, fingerprint: storedFingerprint, response: JSON.parse(response!) }
      : { state, fingerprint: storedFingerprint };
  }

  async complete(
    key: string,
    owner: string,
    response: IdempotencyStoredPayload,
    ttl: number,
  ): Promise<boolean> {
    const done = await this.redis.eval(
      COMPLETE, 1, this.key(key), owner, JSON.stringify(response), ttl,
    );
    return done === 1;
  }

  async release(key: string, owner: string): Promise<boolean> {
    const released = await this.redis.eval(RELEASE, 1, this.key(key), owner);
    return released === 1;
  }

  async extend(key: string, owner: string, lockTtl: number): Promise<boolean> {
    const extended = await this.redis.eval(EXTEND, 1, this.key(key), owner, lockTtl);
    return extended === 1;
  }

  private key(key: string) {
    return `idem:${key}`;
  }
}
```

Each record is a hash at `idem:<scope>:<key>`, with the fields `state`, `fp` (the fingerprint), `owner` and `resp` (the stored response as JSON). The hash expires on its own: `lockTtl` after the last renewal while it's in flight, and after `ttl` once it's completed, so no cleanup job is needed. Each script touches a single key, so the store also works with Redis Cluster. Redis runs a script atomically, but it doesn't undo the script's writes when a later command fails. `PEXPIRE`, for one, rejects a fraction of a millisecond, and failing after the `HSET`, it would leave a lock that never expires. That's why the interceptor hands the store whole milliseconds.

Nest injects the Redis client, and the constructor registers the store, as in the PostgreSQL store. An app has one store, so `RedisIdempotencyStore` takes the place of the other one in `AppModule`:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { IdempotencyModule } from '@nestjs/idempotency';
import { RedisIdempotencyStore } from './idempotency/redis-idempotency.store.js';
import type { User } from './orders/order.js';
import { OrdersModule } from './orders/orders.module.js';
import { RedisModule } from './redis/redis.module.js';

@Module({
  imports: [
    RedisModule,
    IdempotencyModule.forRoot({
      scope: (req: { user?: User }) => req.user?.id,
    }),
    OrdersModule,
  ],
  providers: [RedisIdempotencyStore],
})
export class AppModule {}
```

`RedisModule` stands for your app's Redis module: a global module that provides an ioredis client under the `REDIS` token, for example with `useFactory: () => new Redis(process.env.REDIS_URL!)`, and closes it with `quit()` in its `onApplicationShutdown()`, after the package has finished the requests in flight. `RedisClient` asks for nothing but `eval()`, which an ioredis `Redis` instance provides as is. At startup, the log line reads `IdempotencyStorage: RedisIdempotencyStore`, and the registry's rules from the PostgreSQL store apply: one store, registered from a constructor.

The example project runs the contract suite against this store too:

test/step-4.redis-store.spec.ts

JS TS

```typescript

import { idempotencyStoreContract } from '@nestjs/idempotency/testing';
// ...
describe('RedisIdempotencyStore, the IdempotencyStore contract (on FakeRedis)', () => {
  let redis: FakeRedis;
  const cases = idempotencyStoreContract(
    () => {
      redis = new FakeRedis();
      return new RedisIdempotencyStore(redis, new IdempotencyStorage());
    },
    // Redis expires keys on its own clock: the fake's.
    { advanceTime: (ms) => redis.advance(ms), concurrent: true },
  );
  for (const c of cases) {
    it(c.name, c.run);
  }
});
```

> **Hint** This tutorial's example project has no Redis server, so its tests run the store against an in-process fake that implements the same four scripts in JavaScript. That covers the store's logic and the way it reads replies, but not the Lua itself. Run the contract suite against a real Redis, for example in a container, before you rely on the store. Without `advanceTime`, the suite waits for real expiry, which takes about ten seconds.

The remaining steps show `DrizzleIdempotencyStore` in their module listings. With Redis, register `RedisIdempotencyStore` in its place: encryption, the shipping service and the tuning options work the same, and with encryption on, the `resp` field holds the sealed envelope instead of the `response` column.

#### Encrypt stored receipts[#](/reliability/idempotency#encrypt-stored-receipts)

The stored response is the whole receipt: the payment provider's receipt id, the amount, and the card's last four digits. They sit in `idempotency_keys` in plain text, in every backup and every dump of the database, so encrypt the records at rest.

The encryption keys are secrets that the app should read when it starts, not when `app.module.ts` is imported, so switch to `forRootAsync()`. The store stays as it is, a provider of `AppModule` that registers itself, and the factory returns the options:

app.module.ts

JS TS

```typescript

IdempotencyModule.forRootAsync({
  useFactory: () => ({
    scope: (req: { user?: User }) => req.user?.id,
    encryption: {
      // Newest first: seal with the first key, open with any of them.
      keys: process.env.IDEMPOTENCY_KEYS!.split(','),
    },
  }),
}),
```

Generate a key with `openssl rand -base64 32`, and store it in your secret manager as `IDEMPOTENCY_KEYS`. With encryption on, the `response` column holds a sealed envelope, `v1.<keyId>.<iv>.<ciphertext>.<tag>`, instead of the receipt:

* Records are encrypted with AES-256-GCM, with a random IV for each record.
* The fingerprint stays in plain text. The store has to compare it, and it's a hash anyway.
* The record key is authenticated along with the data, so a record copied under another user's key fails to open instead of replaying there.
* While encryption is on, plain-text records are rejected, so nobody with write access to the table can plant a response.
* A string key must be at least 32 characters, and it's expanded with HKDF-SHA256. That's fine for a random secret like the one above, but it isn't a password hash, so don't use a password that a person chose. A shorter key, or one with spaces around it (`IDEMPOTENCY_KEYS=new, old` splits into a second key that starts with a space), stops the app at startup, with an error that names it.

Turn encryption on before the endpoint stores its first record. It changes the record format both ways: a plain-text record stored before the switch, like a sealed record after encryption is turned off, fails to open until it expires, and its replays get the 500 described below.

To rotate the key without breaking replays:

1. Generate a new key and deploy `IDEMPOTENCY_KEYS=old-key,new-key`. Instances still seal records with the old key, but they can open records sealed with the new one.
2. Once every instance runs that configuration, deploy `IDEMPOTENCY_KEYS=new-key,old-key`. New records are sealed with the new key, and old records still open. During the rolling deploy, instances that haven't restarted yet can already open the new records, thanks to the first step.
3. When `ttl` has passed (48 hours, see [Tune TTLs and failure handling](/reliability/idempotency#tune-ttls-and-failure-handling)), every record sealed with the old key has expired. Deploy `IDEMPOTENCY_KEYS=new-key`.

If you remove a key too early, replays of records sealed with it **fail closed**. The client gets a 500 `IDEMPOTENCY_RECORD_UNREADABLE` error, the failure is logged, and the handler doesn't run again: the record proves that the card was already charged, so running the handler could charge it twice. The error stops when the record expires.

#### Pay through GraphQL[#](/reliability/idempotency#pay-through-graphql)

The store's website pays through a GraphQL mutation. Register `GraphQLModule` in `AppModule`:

app.module.ts

JS TS

```typescript

GraphQLModule.forRoot<ApolloDriverConfig>({
  driver: ApolloDriver,
  autoSchemaFile: true,
}),
```

Then add the mutation to the orders resolver, next to its queries. In GraphQL, the key can come from the `Idempotency-Key` header, as with REST, or from an argument. An argument puts the key in the schema, where code generators and reviewers can see it. It also suits GraphQL clients, which usually set headers once per connection rather than per operation. `@Idempotent()` reads a mutation's `idempotencyKey` argument when it has one, and the header otherwise, so the resolver only has to declare the argument:

orders/orders.resolver.ts

JS TS

```typescript

@Mutation(() => PaymentReceipt)
@Idempotent({ required: true })
payOrder(
  @Args('orderId', { type: () => ID }) orderId: string,
  @Args('input') input: PayOrderDto,
  @Args('idempotencyKey') _idempotencyKey: string,
  @CurrentUser() user: User,
) {
  return this.ordersService.pay(orderId, user, input);
}
```

`PayOrderDto` is the class the REST endpoint uses, with `@InputType()` and `@Field()` added, and `PaymentReceipt` is an `@ObjectType()` with the receipt's fields. The resolver uses the same `AuthGuard`, which reads the request from the GraphQL context. The module's `scope` receives that same request, so keys are per user here too. The argument is a non-null `String`, so GraphQL validation already rejects an operation without it:

```graphql

mutation PayOrder($orderId: ID!, $paymentMethod: String!, $key: String!) {
  payOrder(orderId: $orderId, input: { paymentMethod: $paymentMethod }, idempotencyKey: $key) {
    receiptId
    amount
    cardLast4
    paidAt
  }
}
```

A retry with the same variables returns the stored `payOrder` result, with the same types the resolver returned, so a `Date` field replays as a `Date`. The record key gets the field's path appended, as in `usr_alice:<key>:payOrder`, because one operation can contain several mutations. Each field is stored and replayed on its own, and aliases are part of the path, so a retry must send the same document.

A rejection is an error on that field, not an HTTP status. The response is still a 200, because other fields in the same operation may have succeeded, and the status and the retry delay are in `extensions` (`locations` omitted):

```json

{
  "errors": [
    {
      "message": "A request with this idempotency key is still being processed.",
      "path": ["payOrder"],
      "extensions": {
        "code": "IDEMPOTENCY_KEY_IN_USE",
        "httpStatus": 409,
        "retryAfter": 2
      }
    }
  ],
  "data": null
}
```

For the same reason, GraphQL replays don't set the `Idempotent-Replayed` header.

#### Deduplicate order.paid events[#](/reliability/idempotency#deduplicate-orderpaid-events)

After a payment, `OrdersService` emits an `order.paid` event, and the shipping service arranges a courier. In practice, events are delivered at least once. A publisher that retries after a timeout, or a broker (RabbitMQ, Kafka, NATS JetStream) that redelivers an unacknowledged message, can deliver the same event twice, and the customer gets two parcels.

Deduplicating events needs an id that's the same for every delivery of an event, so it's derived from the data rather than generated on each send. An order is paid once, so `OrdersService` uses `order-paid:` followed by the order id. Mark the [event handler](/microservices/basics#event-based) with `@Idempotent()`, and point `keyFrom` at that id:

shipping/shipping.controller.ts

JS TS

```typescript

import { Controller } from '@nestjs/common';
import { EventPattern, Payload } from '@nestjs/microservices';
import { Idempotent } from '@nestjs/idempotency';
import { ShipmentsService } from './shipments.service.js';

export interface OrderPaidEvent {
  eventId: string;
  orderId: string;
}

@Controller()
export class ShippingController {
  constructor(private readonly shipmentsService: ShipmentsService) {}

  @EventPattern('order.paid')
  @Idempotent({ required: true, keyFrom: { payload: 'eventId' } })
  async onOrderPaid(@Payload() event: OrderPaidEvent) {
    await this.shipmentsService.createFor(event.orderId);
  }
}
```

By default, microservice handlers read the key from the payload's `idempotencyKey` property, then from a transport header named by the `header` option. Here, `keyFrom` reads `eventId` instead, and `required: true` rejects events that don't have one.

The shipping service is a separate application, with its own database and its own `IdempotencyModule`, and it registers the same store class:

shipping/shipping.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { DrizzleModule } from '@nestjs/drizzle';
import { IdempotencyModule } from '@nestjs/idempotency';
import { drizzle } from 'drizzle-orm/node-postgres';
import { DrizzleIdempotencyStore } from '../idempotency/drizzle-idempotency.store.js';
import { ShipmentsService } from './shipments.service.js';
import { ShippingController } from './shipping.controller.js';

@Module({
  imports: [
    DrizzleModule.forRootAsync({
      useFactory: () => ({ drizzle, connection: process.env.DATABASE_URL! }),
    }),
    IdempotencyModule.forRoot({
      ttl: '7d', // brokers can redeliver long after the first delivery
    }),
  ],
  controllers: [ShippingController],
  providers: [ShipmentsService, DrizzleIdempotencyStore],
})
export class ShippingModule {}
```

shipping/main.ts

JS TS

```typescript

import { NestFactory } from '@nestjs/core';
import { Transport, type MicroserviceOptions } from '@nestjs/microservices';
import { ShippingModule } from './shipping.module.js';

async function bootstrap() {
  const app = await NestFactory.createMicroservice<MicroserviceOptions>(ShippingModule, {
    transport: Transport.TCP,
    options: { host: '0.0.0.0', port: 4001 },
  });
  await app.listen();
}
bootstrap();
```

A few details differ from the API:

* There's no `scope`, because event ids are unique across the whole system.
* `ttl` is 7 days, because a message can come back from a dead-letter queue long after it was first handled.
* Records belong to a handler: the record key ends with the handler's class and method, as in `order-paid%3Aord_1001:ShippingController.onOrderPaid`. Nest runs every handler registered for an event, so a second handler for `order.paid`, one that emails the tracking number, say, keeps its own records and still handles every event once.

A duplicate event is handled in one of two ways:

* If the first delivery has completed, the duplicate is skipped. The stored result is "replayed", and since events have no reply, nothing happens.
* If the first delivery is still running, the duplicate is rejected with `IDEMPOTENCY_KEY_IN_USE`, and Nest logs the error. With a transport that acknowledges messages, such as RabbitMQ or Kafka, don't acknowledge that delivery as processed. Let the transport redeliver it later, when it'll be skipped.

Either way, the courier is booked once. Retries of the HTTP payment don't produce duplicate events in the first place, because a replayed request never reaches `OrdersService`.

#### Tune TTLs and failure handling[#](/reliability/idempotency#tune-ttls-and-failure-handling)

The defaults are a starting point. This is the API's final configuration:

app.module.ts

JS TS

```typescript

IdempotencyModule.forRootAsync({
  useFactory: () => ({
    scope: (req: { user?: User }) => req.user?.id,
    encryption: {
      // Newest first: seal with the first key, open with any of them.
      keys: process.env.IDEMPOTENCY_KEYS!.split(','),
    },
    // Longer than the app keeps retrying a queued payment (24 hours).
    ttl: '48h',
    // A crashed instance blocks a key for at most 45 seconds. While a
    // charge runs, its lock is renewed every 15 seconds.
    lockTtl: '45s',
    // How long a client waits after a 409 before it asks again.
    retryAfter: '2s',
  }),
}),
```

Every duration takes milliseconds, or a string such as `'45s'`, `'48h'` or `'7d'`. A value that doesn't parse stops the app at startup, with an error that names the option.

* **`ttl`** (default: `'24h'`) is how long a completed result can be replayed. It must be longer than the longest time a client keeps retrying. The app queues payments made offline for up to a day, so it's 48 hours here. After `ttl`, the key is forgotten, and a retry runs the handler again. In this app, that ends in a 409 "already paid" error rather than a second charge, but the customer doesn't get the receipt.
* **`lockTtl`** (default: `'60s'`) is how long an in-flight lock survives after the instance running the handler crashes. While the handler runs, the interceptor renews the lock every `lockTtl / 3`, here every 15 seconds, so a charge that takes longer than 45 seconds still keeps it, and a retry gets a 409. Once renewals stop, the lock expires and a retry takes over the key. A shorter `lockTtl` frees keys sooner after a crash, but renews more often. If the store can't be reached to renew a lock, the interceptor logs a warning that the lock was lost.
* **`retryAfter`** (default: `'1s'`) is the value of the `Retry-After` header on a 409, in whole seconds. Card charges usually take a second or two, so the API asks clients to wait 2 seconds rather than check back after one.

`@Idempotent()` accepts `required`, `ttl`, `lockTtl`, `retryAfter`, `keyFrom`, `scope`, `fingerprint` and `storeIf`, which override the module's options for that handler. `fingerprint` selects what a retry must repeat, for example the body without a client timestamp; the method and the URL always count. The decorator also works on a controller or resolver class, where it covers the handlers that change state: GET routes and GraphQL queries are skipped unless they have their own `@Idempotent()`. A handler's own `@Idempotent()` is merged with the class's options, so a class-level `required: true` still applies to a handler that only sets `lockTtl`.

A `scope` function runs for every kind of handler, and what it receives depends on the handler: the request for HTTP and GraphQL, but the message payload for a microservice handler. In an app that serves both from one `IdempotencyModule`, pass `scope` an object instead, with one function per context under the `http`, `graphql` and `rpc` keys. Each function is typed for what its context passes in, and a context without one isn't scoped.

Not every outcome is stored. By default, anything below 500 is:

| Outcome                                                                   | Default                                                  | Why                                                       |
| ------------------------------------------------------------------------- | -------------------------------------------------------- | --------------------------------------------------------- |
| 2xx                                                                       | Stored and replayed                                      | The payment succeeded                                     |
| 4xx `HttpException` (validation 400, declined 402, 404, 409 already paid) | Stored, and thrown again on every replay                 | It's deterministic: the same request gets the same answer |
| Another error with a 4xx `status` (`AuthorizationError`, 403)             | Stored as Nest's exception for that status, and replayed | Its package turns it into that status                     |
| 5xx or an unknown error (payment provider 503, database down)             | Not stored. The key is released, so a retry runs again   | Most failures happen before the side effect               |
| `StreamableFile`, streams, `@Res()` without `passthrough`                 | Not stored. The key is released, and a warning is logged | They can't be replayed                                    |

A replayed error is rebuilt as a plain `HttpException` with the stored status and body, and it passes through your exception filters again. A filter that checks `instanceof` against a custom exception class sees the base class on a replay.

The `storeIf` option changes the rule. It receives the status and, when the handler threw, the error. For example, `storeIf: () => true` stores 5xx errors too, as Stripe does. That matters for the one gap the default leaves: a 5xx that happens **after** the side effect. If the payment provider charges the card and then `markPaid()` fails, the key is released, and the retry charges again. There are three ways to close the gap:

* Pass the payment provider a key derived from the user's id and the idempotency key. Most payment providers accept an idempotency key of their own, so the provider deduplicates the charge too. The idempotency key alone isn't enough, because two users can send the same one.
* Store 5xx errors for this handler with `storeIf`, and have the app start a new attempt after a 5xx. To store only the failure that follows a charge, throw a dedicated exception there and check for it: `storeIf: (status, error) => status < 500 || error instanceof ChargeCapturedError`.
* Write the payment and the event in one transaction, with a [transactional outbox](/reliability/outbox#prerequisites).

#### Try it[#](/reliability/idempotency#try-it)

Start the shipping service, and the API with `DATABASE_URL` (migrations applied), `IDEMPOTENCY_KEYS` and the payment provider's sandbox configured. The sandbox takes about half a second to answer. The outputs below are trimmed to the relevant headers.

A payment without a key is refused:

```bash

$ curl -i localhost:3000/orders/ord_1001/pay \
    -H 'Authorization: Bearer alice-token' \
    --json '{"paymentMethod":"pm_card_visa"}'
HTTP/1.1 400 Bad Request

{"statusCode":400,"error":"Bad Request","code":"IDEMPOTENCY_KEY_REQUIRED","message":"An idempotency key is required for this operation."}
```

The first call with a key charges the card:

```bash

$ KEY=$(uuidgen)
$ curl -i localhost:3000/orders/ord_1001/pay \
    -H 'Authorization: Bearer alice-token' \
    -H "Idempotency-Key: $KEY" \
    --json '{"paymentMethod":"pm_card_visa"}'
HTTP/1.1 201 Created
Content-Type: application/json; charset=utf-8

{"orderId":"ord_1001","receiptId":"ch_0001","amount":4098,"cardLast4":"4242","paidAt":"2026-09-22T11:09:25.813Z"}
```

A retry with the same key gets the same receipt, down to `paidAt`, and the payment provider isn't called:

```bash

$ curl -i localhost:3000/orders/ord_1001/pay \
    -H 'Authorization: Bearer alice-token' \
    -H "Idempotency-Key: $KEY" \
    --json '{"paymentMethod":"pm_card_visa"}'
HTTP/1.1 201 Created
Idempotent-Replayed: true
Content-Type: application/json; charset=utf-8

{"orderId":"ord_1001","receiptId":"ch_0001","amount":4098,"cardLast4":"4242","paidAt":"2026-09-22T11:09:25.813Z"}
```

The same key with a different card is a client bug:

```bash

$ curl -i localhost:3000/orders/ord_1001/pay \
    -H 'Authorization: Bearer alice-token' \
    -H "Idempotency-Key: $KEY" \
    --json '{"paymentMethod":"pm_card_mastercard"}'
HTTP/1.1 422 Unprocessable Entity

{"statusCode":422,"error":"Unprocessable Entity","code":"IDEMPOTENCY_KEY_REUSED","message":"This idempotency key was already used for a different request."}
```

Finally, send two requests with a new key at the same time, for the other order. One is charged, and the other gets a 409 with `Retry-After: 2` while the payment provider is still working:

```bash

$ KEY=$(uuidgen)
$ for i in 1 2; do
  curl -s -o /dev/null -w '%{http_code} %header{retry-after}\n' \
    localhost:3000/orders/ord_1002/pay \
    -H 'Authorization: Bearer alice-token' \
    -H "Idempotency-Key: $KEY" \
    --json '{"paymentMethod":"pm_card_visa"}' &
done; wait
409 2
201
```

> **Hint**`--json` needs curl 7.82 or later, and `%header` in `-w` needs curl 7.84 or later.

#### Testing[#](/reliability/idempotency#testing)

In end-to-end tests, keep the app's real configuration, but override the `DrizzleIdempotencyStore` provider with a plain `InMemoryIdempotencyStore`. A plain instance doesn't register itself, so the module falls back to its in-memory store, and since Nest never creates `DrizzleIdempotencyStore`, nothing queries the database (a node-postgres pool connects on the first query, so `DrizzleModule` opens no connection either). The encryption key still comes from `IDEMPOTENCY_KEYS`, so set it in the test environment, for example with `test.env` in `vitest.config.mts`.

Mock the payment provider with a small delay, so that two requests sent together overlap:

test/pay-order.e2e-spec.ts

JS TS

```typescript

import { ValidationPipe, type INestApplication } from '@nestjs/common';
import { InMemoryIdempotencyStore } from '@nestjs/idempotency';
import { Test } from '@nestjs/testing';
import { setTimeout } from 'node:timers/promises';
import { EMPTY } from 'rxjs';
import request from 'supertest';
import type { MockInstance } from 'vitest';
import { AppModule } from '../src/app.module.js';
import { DrizzleIdempotencyStore } from '../src/idempotency/drizzle-idempotency.store.js';
import { SHIPPING_SERVICE } from '../src/orders/orders.service.js';
import { PaymentProviderClient } from '../src/payments/payment-provider.client.js';

describe('POST /orders/:id/pay', () => {
  let app: INestApplication;
  let charge: MockInstance<PaymentProviderClient['charge']>;

  beforeEach(async () => {
    const moduleRef = await Test.createTestingModule({ imports: [AppModule] })
      .overrideProvider(DrizzleIdempotencyStore)
      .useValue(new InMemoryIdempotencyStore())
      .overrideProvider(SHIPPING_SERVICE)
      .useValue({ emit: () => EMPTY })
      .compile();

    app = moduleRef.createNestApplication();
    app.useGlobalPipes(new ValidationPipe({ whitelist: true }));
    await app.listen(0, '127.0.0.1');

    charge = vi.spyOn(app.get(PaymentProviderClient), 'charge').mockImplementation(async (input) => {
      await setTimeout(100); // slow enough for duplicates to overlap
      return {
        id: 'ch_test',
        amount: input.amount,
        cardLast4: '4242',
        reference: input.reference,
        createdAt: new Date().toISOString(),
      };
    });
  });

  afterEach(() => app.close());

  const pay = (key: string) =>
    request(app.getHttpServer())
      .post('/orders/ord_1001/pay')
      .set('Authorization', 'Bearer alice-token')
      .set('Idempotency-Key', key)
      .send({ paymentMethod: 'pm_card_visa' });

  it('charges once when the app retries', async () => {
    const first = await pay('key-1').expect(201);
    const retry = await pay('key-1').expect(201).expect('Idempotent-Replayed', 'true');

    expect(retry.body).toEqual(first.body);
    expect(charge).toHaveBeenCalledTimes(1);
  });

  it('rejects a duplicate that arrives while the first is in flight', async () => {
    const [a, b] = await Promise.all([pay('key-2'), pay('key-2')]);

    expect([a.status, b.status].sort()).toEqual([201, 409]);
    expect(charge).toHaveBeenCalledTimes(1);
  });
});
```

Once the app is initialized, `app.get(IdempotencyStorage).source` returns the store in use, here the in-memory one. Its `peek(key)` method returns the raw record under a record key such as `usr_alice:key-1` (`state`, `fingerprint` and `response`), for assertions such as "the declined payment was stored". Test your own store separately, with the contract suite from [Store keys in PostgreSQL](/reliability/idempotency#store-keys-in-postgresql), against a real server. To keep the Drizzle store in end-to-end tests instead, replace the database that `DrizzleModule` registered, with `overrideProvider(getDrizzleToken()).useValue(db)` (`getDrizzleToken` comes from `@nestjs/drizzle`), where `db` is a Drizzle database on PGlite migrated with your migrations. The example project tests encryption, GraphQL, events and tuning that way.

See [End-to-end testing](/fundamentals/testing#end-to-end-testing) for more about the testing setup.

#### Production checklist[#](/reliability/idempotency#production-checklist)

* Register a shared store (your database, or Redis), even for a single instance: in-memory records are lost on every restart or deploy, and a retry after one runs the handler again. Run the contract suite against it with `concurrent` on. In production, the app refuses to start without one, unless `allowInMemoryStorage` is set. With Redis, configure `maxmemory-policy noeviction`. A record evicted early is a double charge waiting to happen, and since every idempotency record has a TTL, the `volatile-*` policies would evict them too.
* Set `required: true` on every endpoint that moves money or creates something a customer would notice twice.
* Set `scope` for every client-facing endpoint. Without it, one user's key can replay another user's response. The module logs a warning when a signed-in user calls a handler that has none.
* Keep the idempotency interceptor outside your other global interceptors. Global interceptors run in the order they were registered, and the `APP_INTERCEPTOR` providers of `AppModule` register before those of the modules it imports, so they run outside it and see every replay. The module warns about them at startup. It refuses to start when one of them is `ClassSerializerInterceptor`, because a replay would hand it a plain object and send the fields that `@Exclude()` hides. Register such interceptors with `app.useGlobalInterceptors()` in `main.ts`, or in a module imported after `IdempotencyModule`.
* With a database store, create its table through your migrations, size the connection pool for its statements, keep the instances' clocks in sync, and call `prune()` on a schedule.
* Keep `ttl` above the client's retry window. `lockTtl` only needs to cover a crash, since the lock is renewed while the handler runs.
* Watch the events. `IdempotencyEvents` is injectable, and its `events$` stream reports every replay, every rejection with its `code`, and every lost lock. The same events are published on the `nestjs:idempotency:replayed`, `nestjs:idempotency:rejected` and `nestjs:idempotency:lock-lost` diagnostics channels for tracing tools. Alert on `lock-lost`: it means the attempt's outcome isn't in the store, because renewals failed (the store was unreachable, or the event loop was blocked for longer than `lockTtl`) or because the store failed when the result was written, and a retry may run the handler again.
* Turn on `encryption` when responses contain personal or payment data, before the endpoint stores its first record. Keep the keys in a secret manager, rotate them in the three steps above, and never remove a key before `ttl` has passed.
* Pass the payment provider a key derived from the user's id and the idempotency key, to cover a failure after the charge.
* When several services share one Redis, give each one its own key prefix (the `idem:` in the store) or its own database. Record keys are only unique within one service: two services can each have a handler class with the same name, and a client could send one key to both.
* Keep the state check in the service, ideally as a conditional database update. An idempotency key deduplicates retries of one attempt, but two taps that create two keys are two attempts.
* Let browsers send the header. For cross-origin clients, add `Idempotency-Key` to the CORS `allowedHeaders`, and `Idempotent-Replayed` and `Retry-After` to `exposedHeaders`.
* Keep idempotent responses small. The whole response body is stored, and the package has no size limit yet.

#### The store contract[#](/reliability/idempotency#the-store-contract)

The tutorial wrote the store with Drizzle, with TypeORM, and for Redis. This section sums up what any `IdempotencyStore` must do, for writing one with another ORM. The package README's "Implementing a store" has every method in detail.

**Registration.** The store is an ordinary singleton provider that calls `registerSource(this)` on the injectable `IdempotencyStorage` in its constructor. The registry checks the shape at once, refuses a second registration unless it passes `replace: true`, and locks when `IdempotencyModule` initializes, logging the store in use. With nothing registered, the module uses `InMemoryIdempotencyStore`, which one instance can't share with another, and which loses its records on restart. With `NODE_ENV=production`, startup fails instead, unless you set `allowInMemoryStorage: true`, which accepts losing the records on every restart or deploy.

**The methods.** All four are atomic: each one decides who holds a key, and a read followed by a separate write lets two requests both run the handler, which is the double charge the package exists to prevent. None takes your transaction: an idempotency record is written on its own, never as part of your business transaction.

| Method                                      | What it does                                                            | How it stays atomic                                                                                                                                  |
| ------------------------------------------- | ----------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| `acquire(key, owner, fingerprint, lockTtl)` | Takes the lock on a free or expired key, or returns the record it found | One insert that takes over an expired row in the same statement, so of many concurrent callers exactly one wins; the others read the winner's record |
| `complete(key, owner, response, ttl)`       | Turns the owner's live lock into a completed record                     | A compare-and-set: the owner and expiry checks are in the `WHERE` of the statement that writes                                                       |
| `release(key, owner)`                       | Deletes the owner's live lock, so a retry can run the handler           | A compare-and-set, as `complete()`                                                                                                                   |
| `extend(key, owner, lockTtl)`               | Renews the owner's live lock                                            | A compare-and-set, as `complete()`                                                                                                                   |

**With Prisma.** The Drizzle and TypeORM stores are the model, with the same table:

* **`acquire()`** is one `INSERT ... ON CONFLICT (key_hash) DO UPDATE ... WHERE expires_at <= now RETURNING`. Prisma's `upsert()` has no condition on the update, so use `$queryRaw`. When no row comes back, read the record, as the other stores do.
* **`complete()`, `release()` and `extend()`** put the owner and the expiry in the `WHERE` and count the rows: `updateMany()` or `deleteMany()` with `keyHash`, `owner` and a `gt: now` filter on `expiresAt` in `where`, and `count === 1`. Not `update()` after a `findUnique()`: it reads first.
* **The response column** is `json` rather than `jsonb`, in any ORM: `jsonb` rejects a `\u0000` inside a string, and a response body can contain one.

**Test it** with the suite from `@nestjs/idempotency/testing`, as the Drizzle, TypeORM and Redis stores do. `idempotencyStoreContract()` returns cases for any test runner. `concurrent: true` races 16 callers for each key; run it against PostgreSQL with a connection pool, where the calls really overlap. `advanceTime` moves the store's clock for the expiry cases, and without it they wait in real time.

#### Reference[#](/reliability/idempotency#reference)

##### Module options[#](/reliability/idempotency#module-options)

`IdempotencyModule.forRoot()` takes these options. `forRootAsync()` takes `isGlobal` and `imports` at the top level, next to `useFactory`, `useClass` or `useExisting`, and the factory returns the rest. Every option except `header`, `replayHeaders`, `encryption`, `allowInMemoryStorage` and `isGlobal` can also be set per class or handler in `@Idempotent()`, where it is merged field by field over the module's.

| Option                 | Type                              | Default             | Description                                                                                                                                                                                                                      |
| ---------------------- | --------------------------------- | ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `required`             | `boolean`                         | `false`             | Rejects calls without a key with `IDEMPOTENCY_KEY_REQUIRED`. See [Make the payment endpoint idempotent](/reliability/idempotency#make-the-payment-endpoint-idempotent).                                                          |
| `scope`                | function, object or `false`       | none                | The key namespace, such as the user id. An object has one function per context, under `http`, `graphql` and `rpc`. `false` shares one namespace on purpose.                                                                      |
| `ttl`                  | `Duration`                        | `'24h'`             | How long a completed result is replayed. See [Tune TTLs and failure handling](/reliability/idempotency#tune-ttls-and-failure-handling).                                                                                          |
| `lockTtl`              | `Duration`                        | `'60s'`             | How long an in-flight lock survives after renewals stop. The lock is renewed every `lockTtl / 3`.                                                                                                                                |
| `retryAfter`           | `Duration`                        | `'1s'`              | The wait sent with `IDEMPOTENCY_KEY_IN_USE`, in whole seconds, rounded up.                                                                                                                                                       |
| `keyFrom`              | source, or one source per context | see below           | Where the key comes from: `header`, `arg` (GraphQL), `payload` (microservices) or a function of the `ExecutionContext`.                                                                                                          |
| `fingerprint`          | `(payload, context) => unknown`   | the whole payload   | What a retry must repeat. The method and URL, GraphQL field or message pattern, and the scope always count.                                                                                                                      |
| `storeIf`              | `(status, error) => boolean`      | `status < 500`      | Which outcomes are stored and replayed. Others release the key.                                                                                                                                                                  |
| `header`               | `string`                          | `'Idempotency-Key'` | The HTTP header, also read by GraphQL, and the transport header name for microservices.                                                                                                                                          |
| `replayHeaders`        | `string[]`                        | none                | Response headers replayed in addition to `Location`, `Content-Type`, `Content-Language`, `Content-Location`, `ETag` and `Last-Modified`. `Set-Cookie` and headers the platform writes for every response are refused at startup. |
| `encryption`           | an object with `keys`             | off                 | AES-256-GCM encryption of stored records. `keys` lists 32-byte `Buffer`s or strings of at least 32 characters, newest first. See [Encrypt stored receipts](/reliability/idempotency#encrypt-stored-receipts).                    |
| `allowInMemoryStorage` | `boolean`                         | `false`             | Lets a production app start without a registered store.                                                                                                                                                                          |
| `isGlobal`             | `boolean`                         | `true`              | Registers the module globally.                                                                                                                                                                                                   |

Every duration takes milliseconds or a string such as `'45s'`, `'48h'` or `'7d'`.

The key comes from these sources by default:

| Context       | Default source                                                                       |
| ------------- | ------------------------------------------------------------------------------------ |
| HTTP          | The `Idempotency-Key` header (the `header` option)                                   |
| GraphQL       | The mutation's `idempotencyKey` argument, then the header                            |
| Microservices | The payload's `idempotencyKey` property, then the transport header named by `header` |

A key is 1 to 255 printable ASCII characters. A number in a payload counts as its digits.

##### Events[#](/reliability/idempotency#events)

`IdempotencyEvents.events$` emits every event, and each is also published on a diagnostics channel. Every payload has `type`, `context` (`'http'`, `'graphql'` or `'rpc'`), `handler` (such as `OrdersController.pay`), `key` and, when there is one, `scope`.

| Type        | Channel                        | Payload type               | Other fields                                      | When                                                                                                                       |
| ----------- | ------------------------------ | -------------------------- | ------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- |
| `replayed`  | `nestjs:idempotency:replayed`  | `IdempotencyReplayedEvent` | `status`                                          | A retry got the stored result, or a duplicate event was skipped                                                            |
| `rejected`  | `nestjs:idempotency:rejected`  | `IdempotencyRejectedEvent` | `code`, `status`                                  | A call was refused before its handler ran. There is no `key` for `IDEMPOTENCY_KEY_REQUIRED` and `IDEMPOTENCY_KEY_INVALID`. |
| `lock-lost` | `nestjs:idempotency:lock-lost` | `IdempotencyLockLostEvent` | `phase` (`'extend'`, `'complete'` or `'release'`) | The attempt's outcome isn't in the store, so a retry may run the handler again                                             |

`IdempotencyEvent` is the union of the three payload types.

##### Errors[#](/reliability/idempotency#errors)

Rejections carry one of these codes, typed as `IdempotencyErrorCode`. Over HTTP, the code is in the response body. In GraphQL, it's in the field error's `extensions`, with `httpStatus` and, for a 409, `retryAfter`. On microservices, the `RpcException` payload has `status`, `code`, `statusCode`, `message` and, for a 409, `retryAfter`.

| Code                            | Status                  | Message                                                          | Cause                                                                       |
| ------------------------------- | ----------------------- | ---------------------------------------------------------------- | --------------------------------------------------------------------------- |
| `IDEMPOTENCY_KEY_REQUIRED`      | 400                     | An idempotency key is required for this operation.               | No key, with `required: true`                                               |
| `IDEMPOTENCY_KEY_INVALID`       | 400                     | The idempotency key must be 1 to 255 printable ASCII characters. | A key that is too long, has other characters, or isn't a string or number   |
| `IDEMPOTENCY_KEY_IN_USE`        | 409, with `Retry-After` | A request with this idempotency key is still being processed.    | The first call with the key is still running                                |
| `IDEMPOTENCY_KEY_REUSED`        | 422                     | This idempotency key was already used for a different request.   | The same key with a different fingerprint                                   |
| `IDEMPOTENCY_RECORD_UNREADABLE` | 500                     | The stored result for this idempotency key could not be read.    | The stored record fails to decrypt, for example because its key was removed |

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/reliability/idempotency.md)

----
url: https://docs.nestjs.com/v11/recipes/passport
----

* [Passport (authentication)](https://docs.nestjs.com/v11/recipes/passport#passport-authentication)
* [Authentication requirements](https://docs.nestjs.com/v11/recipes/passport#authentication-requirements)
* [Implementing Passport strategies](https://docs.nestjs.com/v11/recipes/passport#implementing-passport-strategies)
* [Implementing Passport local](https://docs.nestjs.com/v11/recipes/passport#implementing-passport-local)
* [Built-in Passport Guards](https://docs.nestjs.com/v11/recipes/passport#built-in-passport-guards)
* [Login route](https://docs.nestjs.com/v11/recipes/passport#login-route)
* [Logout route](https://docs.nestjs.com/v11/recipes/passport#logout-route)
* [JWT functionality](https://docs.nestjs.com/v11/recipes/passport#jwt-functionality)
* [Implementing Passport JWT](https://docs.nestjs.com/v11/recipes/passport#implementing-passport-jwt)
* [Implement protected route and JWT strategy guards](https://docs.nestjs.com/v11/recipes/passport#implement-protected-route-and-jwt-strategy-guards)
* [Extending guards](https://docs.nestjs.com/v11/recipes/passport#extending-guards)
* [Enable authentication globally](https://docs.nestjs.com/v11/recipes/passport#enable-authentication-globally)
* [Request-scoped strategies](https://docs.nestjs.com/v11/recipes/passport#request-scoped-strategies)
* [Customize Passport](https://docs.nestjs.com/v11/recipes/passport#customize-passport)
* [Named strategies](https://docs.nestjs.com/v11/recipes/passport#named-strategies)
* [GraphQL](https://docs.nestjs.com/v11/recipes/passport#graphql)

```bash

$ npm install --save @nestjs/passport passport passport-local
$ npm install --save-dev @types/passport-local
```

> **Notice** For **any** Passport strategy you choose, you'll always need the `@nestjs/passport` and `passport` packages. Then, you'll need to install the strategy-specific package (e.g., `passport-jwt` or `passport-local`) that implements the particular authentication strategy you are building. In addition, you can also install the type definitions for any Passport strategy, as shown above with `@types/passport-local`, which provides assistance while writing TypeScript code.

```bash

$ nest g module auth
$ nest g service auth
```

As we implement the `AuthService`, we'll find it useful to encapsulate user operations in a `UsersService`, so let's generate that module and service now:

```bash

$ nest g module users
$ nest g service users
```

Replace the default contents of these generated files as shown below. For our sample app, the `UsersService` simply maintains a hard-coded in-memory list of users, and a find method to retrieve one by username. In a real app, this is where you'd build your user model and persistence layer, using your library of choice (e.g., TypeORM, Sequelize, Mongoose, etc.).

users/users.service.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';

// This should be a real class/interface representing a user entity
export type User = any;

@Injectable()
export class UsersService {
  private readonly users = [
    {
      userId: 1,
      username: 'john',
      password: 'changeme',
    },
    {
      userId: 2,
      username: 'maria',
      password: 'guess',
    },
  ];

  async findOne(username: string): Promise<User | undefined> {
    return this.users.find(user => user.username === username);
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';

@Injectable()
export class UsersService {
  constructor() {
    this.users = [
      {
        userId: 1,
        username: 'john',
        password: 'changeme',
      },
      {
        userId: 2,
        username: 'maria',
        password: 'guess',
      },
    ];
  }

  async findOne(username) {
    return this.users.find(user => user.username === username);
  }
}
```

In the `UsersModule`, the only change needed is to add the `UsersService` to the exports array of the `@Module` decorator so that it is visible outside this module (we'll soon use it in our `AuthService`).

users/users.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { UsersService } from './users.service';

@Module({
  providers: [UsersService],
  exports: [UsersService],
})
export class UsersModule {}
```

```typescript

import { Module } from '@nestjs/common';
import { UsersService } from './users.service';

@Module({
  providers: [UsersService],
  exports: [UsersService],
})
export class UsersModule {}
```

Our `AuthService` has the job of retrieving a user and verifying the password. We create a `validateUser()` method for this purpose. In the code below, we use a convenient ES6 spread operator to strip the password property from the user object before returning it. We'll be calling into the `validateUser()` method from our Passport local strategy in a moment.

auth/auth.service.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { UsersService } from '../users/users.service';

@Injectable()
export class AuthService {
  constructor(private usersService: UsersService) {}

  async validateUser(username: string, pass: string): Promise<any> {
    const user = await this.usersService.findOne(username);
    if (user && user.password === pass) {
      const { password, ...result } = user;
      return result;
    }
    return null;
  }
}
```

```typescript

import { Injectable, Dependencies } from '@nestjs/common';
import { UsersService } from '../users/users.service';

@Injectable()
@Dependencies(UsersService)
export class AuthService {
  constructor(usersService) {
    this.usersService = usersService;
  }

  async validateUser(username, pass) {
    const user = await this.usersService.findOne(username);
    if (user && user.password === pass) {
      const { password, ...result } = user;
      return result;
    }
    return null;
  }
}
```

> **Warning** Of course in a real application, you wouldn't store a password in plain text. You'd instead use a library like [bcrypt](https://github.com/kelektiv/node.bcrypt.js#readme), with a salted one-way hash algorithm. With that approach, you'd only store hashed passwords, and then compare the stored password to a hashed version of the **incoming** password, thus never storing or exposing user passwords in plain text. To keep our sample app simple, we violate that absolute mandate and use plain text. **Don't do this in your real app!**

Now, we update our `AuthModule` to import the `UsersModule`.

auth/auth.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { UsersModule } from '../users/users.module';

@Module({
  imports: [UsersModule],
  providers: [AuthService],
})
export class AuthModule {}
```

```typescript

import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { UsersModule } from '../users/users.module';

@Module({
  imports: [UsersModule],
  providers: [AuthService],
})
export class AuthModule {}
```

#### Implementing Passport local[#](/recipes/passport#implementing-passport-local)

Now we can implement our Passport **local authentication strategy**. Create a file called `local.strategy.ts` in the `auth` folder, and add the following code:

auth/local.strategy.ts

JS TS

```typescript

import { Strategy } from 'passport-local';
import { PassportStrategy } from '@nestjs/passport';
import { Injectable, UnauthorizedException } from '@nestjs/common';
import { AuthService } from './auth.service';

@Injectable()
export class LocalStrategy extends PassportStrategy(Strategy) {
  constructor(private authService: AuthService) {
    super();
  }

  async validate(username: string, password: string): Promise<any> {
    const user = await this.authService.validateUser(username, password);
    if (!user) {
      throw new UnauthorizedException();
    }
    return user;
  }
}
```

```typescript

import { Strategy } from 'passport-local';
import { PassportStrategy } from '@nestjs/passport';
import { Injectable, UnauthorizedException, Dependencies } from '@nestjs/common';
import { AuthService } from './auth.service';

@Injectable()
@Dependencies(AuthService)
export class LocalStrategy extends PassportStrategy(Strategy) {
  constructor(authService) {
    super();
    this.authService = authService;
  }

  async validate(username, password) {
    const user = await this.authService.validateUser(username, password);
    if (!user) {
      throw new UnauthorizedException();
    }
    return user;
  }
}
```

We've followed the recipe described earlier for all Passport strategies. In our use case with passport-local, there are no configuration options, so our constructor simply calls `super()`, without an options object.

> **Hint** We can pass an options object in the call to `super()` to customize the behavior of the passport strategy. In this example, the passport-local strategy by default expects properties called `username` and `password` in the request body. Pass an options object to specify different property names, for example: `super({ usernameField: 'email' })`. See the [Passport documentation](http://www.passportjs.org/docs/configure/) for more information.

We've also implemented the `validate()` method. For each strategy, Passport will call the verify function (implemented with the `validate()` method in `@nestjs/passport`) using an appropriate strategy-specific set of parameters. For the local-strategy, Passport expects a `validate()` method with the following signature: `validate(username: string, password:string): any`.

Most of the validation work is done in our `AuthService` (with the help of our `UsersService`), so this method is quite straightforward. The `validate()` method for **any** Passport strategy will follow a similar pattern, varying only in the details of how credentials are represented. If a user is found and the credentials are valid, the user is returned so Passport can complete its tasks (e.g., creating the `user` property on the `Request` object), and the request handling pipeline can continue. If it's not found, we throw an exception and let our [exceptions layer](exception-filters) handle it.

Typically, the only significant difference in the `validate()` method for each strategy is **how** you determine if a user exists and is valid. For example, in a JWT strategy, depending on requirements, we may evaluate whether the `userId` carried in the decoded token matches a record in our user database, or matches a list of revoked tokens. Hence, this pattern of sub-classing and implementing strategy-specific validation is consistent, elegant and extensible.

We need to configure our `AuthModule` to use the Passport features we just defined. Update `auth.module.ts` to look like this:

auth/auth.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { UsersModule } from '../users/users.module';
import { PassportModule } from '@nestjs/passport';
import { LocalStrategy } from './local.strategy';

@Module({
  imports: [UsersModule, PassportModule],
  providers: [AuthService, LocalStrategy],
})
export class AuthModule {}
```

```typescript

import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { UsersModule } from '../users/users.module';
import { PassportModule } from '@nestjs/passport';
import { LocalStrategy } from './local.strategy';

@Module({
  imports: [UsersModule, PassportModule],
  providers: [AuthService, LocalStrategy],
})
export class AuthModule {}
```

```typescript

import { Controller, Request, Post, UseGuards } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';

@Controller()
export class AppController {
  @UseGuards(AuthGuard('local'))
  @Post('auth/login')
  async login(@Request() req) {
    return req.user;
  }
}
```

```typescript

import { Controller, Bind, Request, Post, UseGuards } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';

@Controller()
export class AppController {
  @UseGuards(AuthGuard('local'))
  @Post('auth/login')
  @Bind(Request())
  async login(req) {
    return req.user;
  }
}
```

With `@UseGuards(AuthGuard('local'))` we are using an `AuthGuard` that `@nestjs/passport`**automatically provisioned** for us when we extended the passport-local strategy. Let's break that down. Our Passport local strategy has a default name of `'local'`. We reference that name in the `@UseGuards()` decorator to associate it with code supplied by the `passport-local` package. This is used to disambiguate which strategy to invoke in case we have multiple Passport strategies in our app (each of which may provision a strategy-specific `AuthGuard`). While we only have one such strategy so far, we'll shortly add a second, so this is needed for disambiguation.

In order to test our route we'll have our `/auth/login` route simply return the user for now. This also lets us demonstrate another Passport feature: Passport automatically creates a `user` object, based on the value we return from the `validate()` method, and assigns it to the `Request` object as `req.user`. Later, we'll replace this with code to create and return a JWT instead.

Since these are API routes, we'll test them using the commonly available [cURL](https://curl.haxx.se/) library. You can test with any of the `user` objects hard-coded in the `UsersService`.

```bash

$ # POST to /auth/login
$ curl -X POST http://localhost:3000/auth/login -d '{"username": "john", "password": "changeme"}' -H "Content-Type: application/json"
$ # result -> {"userId":1,"username":"john"}
```

While this works, passing the strategy name directly to the `AuthGuard()` introduces magic strings in the codebase. Instead, we recommend creating your own class, as shown below:

auth/local-auth.guard.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';

@Injectable()
export class LocalAuthGuard extends AuthGuard('local') {}
```

Now, we can update the `/auth/login` route handler and use the `LocalAuthGuard` instead:

```typescript

@UseGuards(LocalAuthGuard)
@Post('auth/login')
async login(@Request() req) {
  return req.user;
}
```

#### Logout route[#](/recipes/passport#logout-route)

To log out, we can create an additional route that invokes `req.logout()` to clear the user's session. This is a typical approach used in session-based authentication, but it does not apply to JWTs.

```typescript

@UseGuards(LocalAuthGuard)
@Post('auth/logout')
async logout(@Request() req) {
  return req.logout();
}
```

#### JWT functionality[#](/recipes/passport#jwt-functionality)

We're ready to move on to the JWT portion of our auth system. Let's review and refine our requirements:

* Allow users to authenticate with username/password, returning a JWT for use in subsequent calls to protected API endpoints. We're well on our way to meeting this requirement. To complete it, we'll need to write the code that issues a JWT.
* Create API routes which are protected based on the presence of a valid JWT as a bearer token

We'll need to install a couple more packages to support our JWT requirements:

```bash

$ npm install --save @nestjs/jwt passport-jwt
$ npm install --save-dev @types/passport-jwt
```

```typescript

import { Injectable } from '@nestjs/common';
import { UsersService } from '../users/users.service';
import { JwtService } from '@nestjs/jwt';

@Injectable()
export class AuthService {
  constructor(
    private usersService: UsersService,
    private jwtService: JwtService
  ) {}

  async validateUser(username: string, pass: string): Promise<any> {
    const user = await this.usersService.findOne(username);
    if (user && user.password === pass) {
      const { password, ...result } = user;
      return result;
    }
    return null;
  }

  async login(user: any) {
    const payload = { username: user.username, sub: user.userId };
    return {
      access_token: this.jwtService.sign(payload),
    };
  }
}
```

```typescript

import { Injectable, Dependencies } from '@nestjs/common';
import { UsersService } from '../users/users.service';
import { JwtService } from '@nestjs/jwt';

@Dependencies(UsersService, JwtService)
@Injectable()
export class AuthService {
  constructor(usersService, jwtService) {
    this.usersService = usersService;
    this.jwtService = jwtService;
  }

  async validateUser(username, pass) {
    const user = await this.usersService.findOne(username);
    if (user && user.password === pass) {
      const { password, ...result } = user;
      return result;
    }
    return null;
  }

  async login(user) {
    const payload = { username: user.username, sub: user.userId };
    return {
      access_token: this.jwtService.sign(payload),
    };
  }
}
```

We're using the `@nestjs/jwt` library, which supplies a `sign()` function to generate our JWT from a subset of the `user` object properties, which we then return as a simple object with a single `access_token` property. Note: we choose a property name of `sub` to hold our `userId` value to be consistent with JWT standards. Don't forget to inject the JwtService provider into the `AuthService`.

We now need to update the `AuthModule` to import the new dependencies and configure the `JwtModule`.

First, create `constants.ts` in the `auth` folder, and add the following code:

auth/constants.ts

JS TS

```typescript

export const jwtConstants = {
  secret: 'DO NOT USE THIS VALUE. INSTEAD, CREATE A COMPLEX SECRET AND KEEP IT SAFE OUTSIDE OF THE SOURCE CODE.',
};
```

```typescript

export const jwtConstants = {
  secret: 'DO NOT USE THIS VALUE. INSTEAD, CREATE A COMPLEX SECRET AND KEEP IT SAFE OUTSIDE OF THE SOURCE CODE.',
};
```

We'll use this to share our key between the JWT signing and verifying steps.

> **Warning****Do not expose this key publicly**. We have done so here to make it clear what the code is doing, but in a production system **you must protect this key** using appropriate measures such as a secrets vault, environment variable, or configuration service.

Now, open `auth.module.ts` in the `auth` folder and update it to look like this:

auth/auth.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { LocalStrategy } from './local.strategy';
import { UsersModule } from '../users/users.module';
import { PassportModule } from '@nestjs/passport';
import { JwtModule } from '@nestjs/jwt';
import { jwtConstants } from './constants';

@Module({
  imports: [
    UsersModule,
    PassportModule,
    JwtModule.register({
      secret: jwtConstants.secret,
      signOptions: { expiresIn: '60s' },
    }),
  ],
  providers: [AuthService, LocalStrategy],
  exports: [AuthService],
})
export class AuthModule {}
```

```typescript

import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { LocalStrategy } from './local.strategy';
import { UsersModule } from '../users/users.module';
import { PassportModule } from '@nestjs/passport';
import { JwtModule } from '@nestjs/jwt';
import { jwtConstants } from './constants';

@Module({
  imports: [
    UsersModule,
    PassportModule,
    JwtModule.register({
      secret: jwtConstants.secret,
      signOptions: { expiresIn: '60s' },
    }),
  ],
  providers: [AuthService, LocalStrategy],
  exports: [AuthService],
})
export class AuthModule {}
```

We configure the `JwtModule` using `register()`, passing in a configuration object. See [here](https://github.com/nestjs/jwt/blob/master/README.md) for more on the Nest `JwtModule` and [here](https://github.com/auth0/node-jsonwebtoken#usage) for more details on the available configuration options.

Now we can update the `/auth/login` route to return a JWT.

app.controller.ts

JS TS

```typescript

import { Controller, Request, Post, UseGuards } from '@nestjs/common';
import { LocalAuthGuard } from './auth/local-auth.guard';
import { AuthService } from './auth/auth.service';

@Controller()
export class AppController {
  constructor(private authService: AuthService) {}

  @UseGuards(LocalAuthGuard)
  @Post('auth/login')
  async login(@Request() req) {
    return this.authService.login(req.user);
  }
}
```

```typescript

import { Controller, Bind, Request, Post, UseGuards } from '@nestjs/common';
import { LocalAuthGuard } from './auth/local-auth.guard';
import { AuthService } from './auth/auth.service';

@Controller()
export class AppController {
  constructor(private authService: AuthService) {}

  @UseGuards(LocalAuthGuard)
  @Post('auth/login')
  @Bind(Request())
  async login(req) {
    return this.authService.login(req.user);
  }
}
```

Let's go ahead and test our routes using cURL again. You can test with any of the `user` objects hard-coded in the `UsersService`.

```bash

$ # POST to /auth/login
$ curl -X POST http://localhost:3000/auth/login -d '{"username": "john", "password": "changeme"}' -H "Content-Type: application/json"
$ # result -> {"access_token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."}
$ # Note: above JWT truncated
```

#### Implementing Passport JWT[#](/recipes/passport#implementing-passport-jwt)

We can now address our final requirement: protecting endpoints by requiring a valid JWT be present on the request. Passport can help us here too. It provides the [passport-jwt](https://github.com/mikenicholson/passport-jwt) strategy for securing RESTful endpoints with JSON Web Tokens. Start by creating a file called `jwt.strategy.ts` in the `auth` folder, and add the following code:

auth/jwt.strategy.ts

JS TS

```typescript

import { ExtractJwt, Strategy } from 'passport-jwt';
import { PassportStrategy } from '@nestjs/passport';
import { Injectable } from '@nestjs/common';
import { jwtConstants } from './constants';

@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
  constructor() {
    super({
      jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
      ignoreExpiration: false,
      secretOrKey: jwtConstants.secret,
    });
  }

  async validate(payload: any) {
    return { userId: payload.sub, username: payload.username };
  }
}
```

```typescript

import { ExtractJwt, Strategy } from 'passport-jwt';
import { PassportStrategy } from '@nestjs/passport';
import { Injectable } from '@nestjs/common';
import { jwtConstants } from './constants';

@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
  constructor() {
    super({
      jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
      ignoreExpiration: false,
      secretOrKey: jwtConstants.secret,
    });
  }

  async validate(payload) {
    return { userId: payload.sub, username: payload.username };
  }
}
```

```typescript

import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { LocalStrategy } from './local.strategy';
import { JwtStrategy } from './jwt.strategy';
import { UsersModule } from '../users/users.module';
import { PassportModule } from '@nestjs/passport';
import { JwtModule } from '@nestjs/jwt';
import { jwtConstants } from './constants';

@Module({
  imports: [
    UsersModule,
    PassportModule,
    JwtModule.register({
      secret: jwtConstants.secret,
      signOptions: { expiresIn: '60s' },
    }),
  ],
  providers: [AuthService, LocalStrategy, JwtStrategy],
  exports: [AuthService],
})
export class AuthModule {}
```

```typescript

import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { LocalStrategy } from './local.strategy';
import { JwtStrategy } from './jwt.strategy';
import { UsersModule } from '../users/users.module';
import { PassportModule } from '@nestjs/passport';
import { JwtModule } from '@nestjs/jwt';
import { jwtConstants } from './constants';

@Module({
  imports: [
    UsersModule,
    PassportModule,
    JwtModule.register({
      secret: jwtConstants.secret,
      signOptions: { expiresIn: '60s' },
    }),
  ],
  providers: [AuthService, LocalStrategy, JwtStrategy],
  exports: [AuthService],
})
export class AuthModule {}
```

By importing the same secret used when we signed the JWT, we ensure that the **verify** phase performed by Passport, and the **sign** phase performed in our AuthService, use a common secret.

Finally, we define the `JwtAuthGuard` class which extends the built-in `AuthGuard`:

auth/jwt-auth.guard.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';

@Injectable()
export class JwtAuthGuard extends AuthGuard('jwt') {}
```

#### Implement protected route and JWT strategy guards[#](/recipes/passport#implement-protected-route-and-jwt-strategy-guards)

We can now implement our protected route and its associated Guard.

Open the `app.controller.ts` file and update it as shown below:

app.controller.ts

JS TS

```typescript

import { Controller, Get, Request, Post, UseGuards } from '@nestjs/common';
import { JwtAuthGuard } from './auth/jwt-auth.guard';
import { LocalAuthGuard } from './auth/local-auth.guard';
import { AuthService } from './auth/auth.service';

@Controller()
export class AppController {
  constructor(private authService: AuthService) {}

  @UseGuards(LocalAuthGuard)
  @Post('auth/login')
  async login(@Request() req) {
    return this.authService.login(req.user);
  }

  @UseGuards(JwtAuthGuard)
  @Get('profile')
  getProfile(@Request() req) {
    return req.user;
  }
}
```

```typescript

import { Controller, Dependencies, Bind, Get, Request, Post, UseGuards } from '@nestjs/common';
import { JwtAuthGuard } from './auth/jwt-auth.guard';
import { LocalAuthGuard } from './auth/local-auth.guard';
import { AuthService } from './auth/auth.service';

@Dependencies(AuthService)
@Controller()
export class AppController {
  constructor(authService) {
    this.authService = authService;
  }

  @UseGuards(LocalAuthGuard)
  @Post('auth/login')
  @Bind(Request())
  async login(req) {
    return this.authService.login(req.user);
  }

  @UseGuards(JwtAuthGuard)
  @Get('profile')
  @Bind(Request())
  getProfile(req) {
    return req.user;
  }
}
```

Once again, we're applying the `AuthGuard` that the `@nestjs/passport` module has automatically provisioned for us when we configured the passport-jwt module. This Guard is referenced by its default name, `jwt`. When our `GET /profile` route is hit, the Guard will automatically invoke our passport-jwt custom configured strategy, validate the JWT, and assign the `user` property to the `Request` object.

Ensure the app is running, and test the routes using `cURL`.

```bash

$ # GET /profile
$ curl http://localhost:3000/profile
$ # result -> {"statusCode":401,"message":"Unauthorized"}

$ # POST /auth/login
$ curl -X POST http://localhost:3000/auth/login -d '{"username": "john", "password": "changeme"}' -H "Content-Type: application/json"
$ # result -> {"access_token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2Vybm... }

$ # GET /profile using access_token returned from previous step as bearer code
$ curl http://localhost:3000/profile -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2Vybm..."
$ # result -> {"userId":1,"username":"john"}
```

Note that in the `AuthModule`, we configured the JWT to have an expiration of `60 seconds`. This is probably too short an expiration, and dealing with the details of token expiration and refresh is beyond the scope of this article. However, we chose that to demonstrate an important quality of JWTs and the passport-jwt strategy. If you wait 60 seconds after authenticating before attempting a `GET /profile` request, you'll receive a `401 Unauthorized` response. This is because Passport automatically checks the JWT for its expiration time, saving you the trouble of doing so in your application.

We've now completed our JWT authentication implementation. JavaScript clients (such as Angular/React/Vue), and other JavaScript apps, can now authenticate and communicate securely with our API Server.

#### Extending guards[#](/recipes/passport#extending-guards)

In most cases, using a provided `AuthGuard` class is sufficient. However, there might be use-cases when you would like to simply extend the default error handling or authentication logic. For this, you can extend the built-in class and override methods within a sub-class.

```typescript

import {
  ExecutionContext,
  Injectable,
  UnauthorizedException,
} from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';

@Injectable()
export class JwtAuthGuard extends AuthGuard('jwt') {
  canActivate(context: ExecutionContext) {
    // Add your custom authentication logic here
    // for example, call super.logIn(request) to establish a session.
    return super.canActivate(context);
  }

  handleRequest(err, user, info) {
    // You can throw an exception based on either "info" or "err" arguments
    if (err || !user) {
      throw err || new UnauthorizedException();
    }
    return user;
  }
}
```

In addition to extending the default error handling and authentication logic, we can allow authentication to go through a chain of strategies. The first strategy to succeed, redirect, or error will halt the chain. Authentication failures will proceed through each strategy in series, ultimately failing if all strategies fail.

```typescript

export class JwtAuthGuard extends AuthGuard(['strategy_jwt_1', 'strategy_jwt_2', '...']) { ... }
```

#### Enable authentication globally[#](/recipes/passport#enable-authentication-globally)

If the vast majority of your endpoints should be protected by default, you can register the authentication guard as a [global guard](/guards#binding-guards) and instead of using `@UseGuards()` decorator on top of each controller, you could simply flag which routes should be public.

First, register the `JwtAuthGuard` as a global guard using the following construction (in any module):

```typescript

providers: [
  {
    provide: APP_GUARD,
    useClass: JwtAuthGuard,
  },
],
```

With this in place, Nest will automatically bind `JwtAuthGuard` to all endpoints.

Now we must provide a mechanism for declaring routes as public. For this, we can create a custom decorator using the `SetMetadata` decorator factory function.

```typescript

import { SetMetadata } from '@nestjs/common';

export const IS_PUBLIC_KEY = 'isPublic';
export const Public = () => SetMetadata(IS_PUBLIC_KEY, true);
```

In the file above, we exported two constants. One being our metadata key named `IS_PUBLIC_KEY`, and the other being our new decorator itself that we’re going to call `Public` (you can alternatively name it `SkipAuth` or `AllowAnon`, whatever fits your project).

Now that we have a custom `@Public()` decorator, we can use it to decorate any method, as follows:

```typescript

@Public()
@Get()
findAll() {
  return [];
}
```

Lastly, we need the `JwtAuthGuard` to return `true` when the `"isPublic"` metadata is found. For this, we'll use the `Reflector` class (read more [here](/guards#putting-it-all-together)).

```typescript

@Injectable()
export class JwtAuthGuard extends AuthGuard('jwt') {
  constructor(private reflector: Reflector) {
    super();
  }

  canActivate(context: ExecutionContext) {
    const isPublic = this.reflector.getAllAndOverride<boolean>(IS_PUBLIC_KEY, [
      context.getHandler(),
      context.getClass(),
    ]);
    if (isPublic) {
      return true;
    }
    return super.canActivate(context);
  }
}
```

#### Request-scoped strategies[#](/recipes/passport#request-scoped-strategies)

The passport API is based on registering strategies to the global instance of the library. Therefore strategies are not designed to have request-dependent options or to be dynamically instantiated per request (read more about the [request-scoped](/v11/fundamentals/injection-scopes) providers). When you configure your strategy to be request-scoped, Nest will never instantiate it since it's not tied to any specific route. There is no physical way to determine which "request-scoped" strategies should be executed per request.

However, there are ways to dynamically resolve request-scoped providers within the strategy. For this, we leverage the [module reference](/v11/fundamentals/module-ref) feature.

First, open the `local.strategy.ts` file and inject the `ModuleRef` in the normal way:

```typescript

constructor(private moduleRef: ModuleRef) {
  super({
    passReqToCallback: true,
  });
}
```

> **Hint** The `ModuleRef` class is imported from the `@nestjs/core` package.

Be sure to set the `passReqToCallback` configuration property to `true`, as shown above.

In the next step, the request instance will be used to obtain the current context identifier, instead of generating a new one (read more about request context [here](/fundamentals/module-ref#getting-current-sub-tree)).

Now, inside the `validate()` method of the `LocalStrategy` class, use the `getByRequest()` method of the `ContextIdFactory` class to create a context id based on the request object, and pass this to the `resolve()` call:

```typescript

async validate(
  request: Request,
  username: string,
  password: string,
) {
  const contextId = ContextIdFactory.getByRequest(request);
  // "AuthService" is a request-scoped provider
  const authService = await this.moduleRef.resolve(AuthService, contextId);
  ...
}
```

In the example above, the `resolve()` method will asynchronously return the request-scoped instance of the `AuthService` provider (we assumed that `AuthService` is marked as a request-scoped provider).

#### Customize Passport[#](/recipes/passport#customize-passport)

Any standard Passport customization options can be passed the same way, using the `register()` method. The available options depend on the strategy being implemented. For example:

```typescript

PassportModule.register({ session: true });
```

You can also pass strategies an options object in their constructors to configure them. For the local strategy you can pass e.g.:

```typescript

constructor(private authService: AuthService) {
  super({
    usernameField: 'email',
    passwordField: 'password',
  });
}
```

Take a look at the official [Passport Website](http://www.passportjs.org/docs/oauth/) for property names.

#### Named strategies[#](/recipes/passport#named-strategies)

When implementing a strategy, you can provide a name for it by passing a second argument to the `PassportStrategy` function. If you don't do this, each strategy will have a default name (e.g., 'jwt' for jwt-strategy):

```typescript

export class JwtStrategy extends PassportStrategy(Strategy, 'myjwt')
```

Then, you refer to this via a decorator like `@UseGuards(AuthGuard('myjwt'))`.

#### GraphQL[#](/recipes/passport#graphql)

In order to use an AuthGuard with [GraphQL](https://docs.nestjs.com/graphql/quick-start), extend the built-in `AuthGuard` class and override the `getRequest()` method.

```typescript

@Injectable()
export class GqlAuthGuard extends AuthGuard('jwt') {
  getRequest(context: ExecutionContext) {
    const ctx = GqlExecutionContext.create(context);
    return ctx.getContext().req;
  }
}
```

To get the current authenticated user in your graphql resolver, you can define a `@CurrentUser()` decorator:

```typescript

import { createParamDecorator, ExecutionContext } from '@nestjs/common';
import { GqlExecutionContext } from '@nestjs/graphql';

export const CurrentUser = createParamDecorator(
  (data: unknown, context: ExecutionContext) => {
    const ctx = GqlExecutionContext.create(context);
    return ctx.getContext().req.user;
  },
);
```

To use above decorator in your resolver, be sure to include it as a parameter of your query or mutation:

```typescript

@Query(() => User)
@UseGuards(GqlAuthGuard)
whoAmI(@CurrentUser() user: User) {
  return this.usersService.findById(user.id);
}
```

For the passport-local strategy, you'll also need to add the GraphQL context's arguments to the request body so Passport can access them for validation. Otherwise, you'll get an Unauthorized error.

```typescript

@Injectable()
export class GqlLocalAuthGuard extends AuthGuard('local') {
  getRequest(context: ExecutionContext) {
    const gqlExecutionContext = GqlExecutionContext.create(context);
    const gqlContext = gqlExecutionContext.getContext();
    const gqlArgs = gqlExecutionContext.getArgs();

    gqlContext.req.body = { ...gqlContext.req.body, ...gqlArgs };
    return gqlContext.req;
  }
}
```

----
url: https://docs.nestjs.com/v10/techniques/configuration
----

* [Configuration](https://docs.nestjs.com/v10/techniques/configuration#configuration)
* [Installation](https://docs.nestjs.com/v10/techniques/configuration#installation)
* [Getting started](https://docs.nestjs.com/v10/techniques/configuration#getting-started)
* [Custom env file path](https://docs.nestjs.com/v10/techniques/configuration#custom-env-file-path)
* [Disable env variables loading](https://docs.nestjs.com/v10/techniques/configuration#disable-env-variables-loading)
* [Use module globally](https://docs.nestjs.com/v10/techniques/configuration#use-module-globally)
* [Custom configuration files](https://docs.nestjs.com/v10/techniques/configuration#custom-configuration-files)
* [Using the ConfigService](https://docs.nestjs.com/v10/techniques/configuration#using-the-configservice)
* [Configuration namespaces](https://docs.nestjs.com/v10/techniques/configuration#configuration-namespaces)
* [Namespaced configurations in modules](https://docs.nestjs.com/v10/techniques/configuration#namespaced-configurations-in-modules)
* [Cache environment variables](https://docs.nestjs.com/v10/techniques/configuration#cache-environment-variables)
* [Partial registration](https://docs.nestjs.com/v10/techniques/configuration#partial-registration)
* [Schema validation](https://docs.nestjs.com/v10/techniques/configuration#schema-validation)
* [Custom validate function](https://docs.nestjs.com/v10/techniques/configuration#custom-validate-function)
* [Custom getter functions](https://docs.nestjs.com/v10/techniques/configuration#custom-getter-functions)
* [Environment variables loaded hook](https://docs.nestjs.com/v10/techniques/configuration#environment-variables-loaded-hook)
* [Conditional module configuration](https://docs.nestjs.com/v10/techniques/configuration#conditional-module-configuration)
* [Expandable variables](https://docs.nestjs.com/v10/techniques/configuration#expandable-variables)
* [Using in the main.ts](https://docs.nestjs.com/v10/techniques/configuration#using-in-the-maints)

```bash

$ npm i --save @nestjs/config
```

> **Hint** The `@nestjs/config` package internally uses [dotenv](https://github.com/motdotla/dotenv).

> **Note**`@nestjs/config` requires TypeScript 4.1 or later.

#### Getting started[#](/techniques/configuration#getting-started)

Once the installation process is complete, we can import the `ConfigModule`. Typically, we'll import it into the root `AppModule` and control its behavior using the `.forRoot()` static method. During this step, environment variable key/value pairs are parsed and resolved. Later, we'll see several options for accessing the `ConfigService` class of the `ConfigModule` in our other feature modules.

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';

@Module({
  imports: [ConfigModule.forRoot()],
})
export class AppModule {}
```

The above code will load and parse a `.env` file from the default location (the project root directory), merge key/value pairs from the `.env` file with environment variables assigned to `process.env`, and store the result in a private structure that you can access through the `ConfigService`. The `forRoot()` method registers the `ConfigService` provider, which provides a `get()` method for reading these parsed/merged configuration variables. Since `@nestjs/config` relies on [dotenv](https://github.com/motdotla/dotenv), it uses that package's rules for resolving conflicts in environment variable names. When a key exists both in the runtime environment as an environment variable (e.g., via OS shell exports like `export DATABASE_USER=test`) and in a `.env` file, the runtime environment variable takes precedence.

A sample `.env` file looks something like this:

```json

DATABASE_USER=test
DATABASE_PASSWORD=test
```

#### Custom env file path[#](/techniques/configuration#custom-env-file-path)

By default, the package looks for a `.env` file in the root directory of the application. To specify another path for the `.env` file, set the `envFilePath` property of an (optional) options object you pass to `forRoot()`, as follows:

```typescript

ConfigModule.forRoot({
  envFilePath: '.development.env',
});
```

You can also specify multiple paths for `.env` files like this:

```typescript

ConfigModule.forRoot({
  envFilePath: ['.env.development.local', '.env.development'],
});
```

If a variable is found in multiple files, the first one takes precedence.

#### Disable env variables loading[#](/techniques/configuration#disable-env-variables-loading)

If you don't want to load the `.env` file, but instead would like to simply access environment variables from the runtime environment (as with OS shell exports like `export DATABASE_USER=test`), set the options object's `ignoreEnvFile` property to `true`, as follows:

```typescript

ConfigModule.forRoot({
  ignoreEnvFile: true,
});
```

#### Use module globally[#](/techniques/configuration#use-module-globally)

When you want to use `ConfigModule` in other modules, you'll need to import it (as is standard with any Nest module). Alternatively, declare it as a [global module](https://docs.nestjs.com/modules#global-modules) by setting the options object's `isGlobal` property to `true`, as shown below. In that case, you will not need to import `ConfigModule` in other modules once it's been loaded in the root module (e.g., `AppModule`).

```typescript

ConfigModule.forRoot({
  isGlobal: true,
});
```

#### Custom configuration files[#](/techniques/configuration#custom-configuration-files)

For more complex projects, you may utilize custom configuration files to return nested configuration objects. This allows you to group related configuration settings by function (e.g., database-related settings), and to store related settings in individual files to help manage them independently.

A custom configuration file exports a factory function that returns a configuration object. The configuration object can be any arbitrarily nested plain JavaScript object. The `process.env` object will contain the fully resolved environment variable key/value pairs (with `.env` file and externally defined variables resolved and merged as described [above](techniques/configuration#getting-started)). Since you control the returned configuration object, you can add any required logic to cast values to an appropriate type, set default values, etc. For example:

config/configuration.ts

JS TS

```typescript

export default () => ({
  port: parseInt(process.env.PORT, 10) || 3000,
  database: {
    host: process.env.DATABASE_HOST,
    port: parseInt(process.env.DATABASE_PORT, 10) || 5432
  }
});
```

We load this file using the `load` property of the options object we pass to the `ConfigModule.forRoot()` method:

```typescript

import configuration from './config/configuration';

@Module({
  imports: [
    ConfigModule.forRoot({
      load: [configuration],
    }),
  ],
})
export class AppModule {}
```

> **Notice** The value assigned to the `load` property is an array, allowing you to load multiple configuration files (e.g. `load: [databaseConfig, authConfig]`)

With custom configuration files, we can also manage custom files such as YAML files. Here is an example of a configuration using YAML format:

```yaml

http:
  host: 'localhost'
  port: 8080

db:
  postgres:
    url: 'localhost'
    port: 5432
    database: 'yaml-db'

  sqlite:
    database: 'sqlite.db'
```

To read and parse YAML files, we can leverage the `js-yaml` package.

```bash

$ npm i js-yaml
$ npm i -D @types/js-yaml
```

Once the package is installed, we use `yaml#load` function to load YAML file we just created above.

config/configuration.ts

JS TS

```typescript

import { readFileSync } from 'fs';
import * as yaml from 'js-yaml';
import { join } from 'path';

const YAML_CONFIG_FILENAME = 'config.yaml';

export default () => {
  return yaml.load(
    readFileSync(join(__dirname, YAML_CONFIG_FILENAME), 'utf8'),
  ) as Record<string, any>;
};
```

> **Note** Nest CLI does not automatically move your "assets" (non-TS files) to the `dist` folder during the build process. To make sure that your YAML files are copied, you have to specify this in the `compilerOptions#assets` object in the `nest-cli.json` file. As an example, if the `config` folder is at the same level as the `src` folder, add `compilerOptions#assets` with the value `"assets": [{"include": "../config/*.yaml", "outDir": "./dist/config"}]`. Read more [here](/cli/monorepo#assets).

Just a quick note - configuration files aren't automatically validated, even if you're using the `validationSchema` option in NestJS's `ConfigModule`. If you need validation or want to apply any transformations, you'll have to handle that within the factory function where you have complete control over the configuration object. This allows you to implement any custom validation logic as needed.

For example, if you want to ensure that port is within a certain range, you can add a validation step to the factory function:

config/configuration.ts

JS TS

```typescript

export default () => {
  const config = yaml.load(
    readFileSync(join(__dirname, YAML_CONFIG_FILENAME), 'utf8'),
  ) as Record<string, any>;

  if (config.http.port < 1024 || config.http.port > 49151) {
    throw new Error('HTTP port must be between 1024 and 49151');
  }

  return config;
};
```

```typescript

@Module({
  imports: [ConfigModule],
  // ...
})
```

Then we can inject it using standard constructor injection:

```typescript

constructor(private configService: ConfigService) {}
```

> **Hint** The `ConfigService` is imported from the `@nestjs/config` package.

And use it in our class:

```typescript

// get an environment variable
const dbUser = this.configService.get<string>('DATABASE_USER');

// get a custom configuration value
const dbHost = this.configService.get<string>('database.host');
```

As shown above, use the `configService.get()` method to get a simple environment variable by passing the variable name. You can do TypeScript type hinting by passing the type, as shown above (e.g., `get<string>(...)`). The `get()` method can also traverse a nested custom configuration object (created via a [Custom configuration file](techniques/configuration#custom-configuration-files)), as shown in the second example above.

You can also get the whole nested custom configuration object using an interface as the type hint:

```typescript

interface DatabaseConfig {
  host: string;
  port: number;
}

const dbConfig = this.configService.get<DatabaseConfig>('database');

// you can now use `dbConfig.port` and `dbConfig.host`
const port = dbConfig.port;
```

The `get()` method also takes an optional second argument defining a default value, which will be returned when the key doesn't exist, as shown below:

```typescript

// use "localhost" when "database.host" is not defined
const dbHost = this.configService.get<string>('database.host', 'localhost');
```

`ConfigService` has two optional generics (type arguments). The first one is to help prevent accessing a config property that does not exist. Use it as shown below:

```typescript

interface EnvironmentVariables {
  PORT: number;
  TIMEOUT: string;
}

// somewhere in the code
constructor(private configService: ConfigService<EnvironmentVariables>) {
  const port = this.configService.get('PORT', { infer: true });

  // TypeScript Error: this is invalid as the URL property is not defined in EnvironmentVariables
  const url = this.configService.get('URL', { infer: true });
}
```

With the `infer` property set to `true`, the `ConfigService#get` method will automatically infer the property type based on the interface, so for example, `typeof port === "number"` (if you're not using `strictNullChecks` flag from TypeScript) since `PORT` has a `number` type in the `EnvironmentVariables` interface.

Also, with the `infer` feature, you can infer the type of a nested custom configuration object's property, even when using dot notation, as follows:

```typescript

constructor(private configService: ConfigService<{ database: { host: string } }>) {
  const dbHost = this.configService.get('database.host', { infer: true })!;
  // typeof dbHost === "string"                                          |
  //                                                                     +--> non-null assertion operator
}
```

The second generic relies on the first one, acting as a type assertion to get rid of all `undefined` types that `ConfigService`'s methods can return when `strictNullChecks` is on. For instance:

```typescript

// ...
constructor(private configService: ConfigService<{ PORT: number }, true>) {
  //                                                               ^^^^
  const port = this.configService.get('PORT', { infer: true });
  //    ^^^ The type of port will be 'number' thus you don't need TS type assertions anymore
}
```

#### Configuration namespaces[#](/techniques/configuration#configuration-namespaces)

The `ConfigModule` allows you to define and load multiple custom configuration files, as shown in [Custom configuration files](techniques/configuration#custom-configuration-files) above. You can manage complex configuration object hierarchies with nested configuration objects as shown in that section. Alternatively, you can return a "namespaced" configuration object with the `registerAs()` function as follows:

config/database.config.ts

JS TS

```typescript

export default registerAs('database', () => ({
  host: process.env.DATABASE_HOST,
  port: process.env.DATABASE_PORT || 5432
}));
```

As with custom configuration files, inside your `registerAs()` factory function, the `process.env` object will contain the fully resolved environment variable key/value pairs (with `.env` file and externally defined variables resolved and merged as described [above](techniques/configuration#getting-started)).

> **Hint** The `registerAs` function is exported from the `@nestjs/config` package.

Load a namespaced configuration with the `load` property of the `forRoot()` method's options object, in the same way you load a custom configuration file:

```typescript

import databaseConfig from './config/database.config';

@Module({
  imports: [
    ConfigModule.forRoot({
      load: [databaseConfig],
    }),
  ],
})
export class AppModule {}
```

Now, to get the `host` value from the `database` namespace, use dot notation. Use `'database'` as the prefix to the property name, corresponding to the name of the namespace (passed as the first argument to the `registerAs()` function):

```typescript

const dbHost = this.configService.get<string>('database.host');
```

A reasonable alternative is to inject the `database` namespace directly. This allows us to benefit from strong typing:

```typescript

constructor(
  @Inject(databaseConfig.KEY)
  private dbConfig: ConfigType<typeof databaseConfig>,
) {}
```

> **Hint** The `ConfigType` is exported from the `@nestjs/config` package.

#### Namespaced configurations in modules[#](/techniques/configuration#namespaced-configurations-in-modules)

To use a namespaced configuration as a configuration object for another module in your application, you can utilize the `.asProvider()` method of the configuration object. This method converts your namespaced configuration into a provider, which can then be passed to the `forRootAsync()` (or any equivalent method) of the module you want to use.

Here's an example:

```typescript

import databaseConfig from './config/database.config';

@Module({
  imports: [
    TypeOrmModule.forRootAsync(databaseConfig.asProvider()),
  ],
})
```

To understand how the `.asProvider()` method functions, let's examine the return value:

```typescript

// Return value of the .asProvider() method
{
  imports: [ConfigModule.forFeature(databaseConfig)],
  useFactory: (configuration: ConfigType<typeof databaseConfig>) => configuration,
  inject: [databaseConfig.KEY]
}
```

This structure allows you to seamlessly integrate namespaced configurations into your modules, ensuring that your application remains organized and modular, without writing boilerplate, repetitive code.

#### Cache environment variables[#](/techniques/configuration#cache-environment-variables)

As accessing `process.env` can be slow, you can set the `cache` property of the options object passed to `ConfigModule.forRoot()` to increase the performance of `ConfigService#get` method when it comes to variables stored in `process.env`.

```typescript

ConfigModule.forRoot({
  cache: true,
});
```

#### Partial registration[#](/techniques/configuration#partial-registration)

Thus far, we've processed configuration files in our root module (e.g., `AppModule`), with the `forRoot()` method. Perhaps you have a more complex project structure, with feature-specific configuration files located in multiple different directories. Rather than load all these files in the root module, the `@nestjs/config` package provides a feature called **partial registration**, which references only the configuration files associated with each feature module. Use the `forFeature()` static method within a feature module to perform this partial registration, as follows:

```typescript

import databaseConfig from './config/database.config';

@Module({
  imports: [ConfigModule.forFeature(databaseConfig)],
})
export class DatabaseModule {}
```

> **Warning** In some circumstances, you may need to access properties loaded via partial registration using the `onModuleInit()` hook, rather than in a constructor. This is because the `forFeature()` method is run during module initialization, and the order of module initialization is indeterminate. If you access values loaded this way by another module, in a constructor, the module that the configuration depends upon may not yet have initialized. The `onModuleInit()` method runs only after all modules it depends upon have been initialized, so this technique is safe.

#### Schema validation[#](/techniques/configuration#schema-validation)

It is standard practice to throw an exception during application startup if required environment variables haven't been provided or if they don't meet certain validation rules. The `@nestjs/config` package enables two different ways to do this:

* [Joi](https://github.com/sideway/joi) built-in validator. With Joi, you define an object schema and validate JavaScript objects against it.
* A custom `validate()` function which takes environment variables as an input.

To use Joi, we must install Joi package:

```bash

$ npm install --save joi
```

Now we can define a Joi validation schema and pass it via the `validationSchema` property of the `forRoot()` method's options object, as shown below:

app.module.ts

JS TS

```typescript

import * as Joi from 'joi';

@Module({
  imports: [
    ConfigModule.forRoot({
      validationSchema: Joi.object({
        NODE_ENV: Joi.string()
          .valid('development', 'production', 'test', 'provision')
          .default('development'),
        PORT: Joi.number().port().default(3000),
      }),
    }),
  ],
})
export class AppModule {}
```

By default, all schema keys are considered optional. Here, we set default values for `NODE_ENV` and `PORT` which will be used if we don't provide these variables in the environment (`.env` file or process environment). Alternatively, we can use the `required()` validation method to require that a value must be defined in the environment (`.env` file or process environment). In this case, the validation step will throw an exception if we don't provide the variable in the environment. See [Joi validation methods](https://joi.dev/api/?v=17.3.0#example) for more on how to construct validation schemas.

By default, unknown environment variables (environment variables whose keys are not present in the schema) are allowed and do not trigger a validation exception. By default, all validation errors are reported. You can alter these behaviors by passing an options object via the `validationOptions` key of the `forRoot()` options object. This options object can contain any of the standard validation options properties provided by [Joi validation options](https://joi.dev/api/?v=17.3.0#anyvalidatevalue-options). For example, to reverse the two settings above, pass options like this:

app.module.ts

JS TS

```typescript

import * as Joi from 'joi';

@Module({
  imports: [
    ConfigModule.forRoot({
      validationSchema: Joi.object({
        NODE_ENV: Joi.string()
          .valid('development', 'production', 'test', 'provision')
          .default('development'),
        PORT: Joi.number().port().default(3000),
      }),
      validationOptions: {
        allowUnknown: false,
        abortEarly: true,
      },
    }),
  ],
})
export class AppModule {}
```

```typescript

import { plainToInstance } from 'class-transformer';
import { IsEnum, IsNumber, Max, Min, validateSync } from 'class-validator';

enum Environment {
  Development = "development",
  Production = "production",
  Test = "test",
  Provision = "provision",
}

class EnvironmentVariables {
  @IsEnum(Environment)
  NODE_ENV: Environment;

  @IsNumber()
  @Min(0)
  @Max(65535)
  PORT: number;
}

export function validate(config: Record<string, unknown>) {
  const validatedConfig = plainToInstance(
    EnvironmentVariables,
    config,
    { enableImplicitConversion: true },
  );
  const errors = validateSync(validatedConfig, { skipMissingProperties: false });

  if (errors.length > 0) {
    throw new Error(errors.toString());
  }
  return validatedConfig;
}
```

With this in place, use the `validate` function as a configuration option of the `ConfigModule`, as follows:

app.module.ts

JS TS

```typescript

import { validate } from './env.validation';

@Module({
  imports: [
    ConfigModule.forRoot({
      validate,
    }),
  ],
})
export class AppModule {}
```

#### Custom getter functions[#](/techniques/configuration#custom-getter-functions)

`ConfigService` defines a generic `get()` method to retrieve a configuration value by key. We may also add `getter` functions to enable a little more natural coding style:

JS TS

```typescript

@Injectable()
export class ApiConfigService {
  constructor(private configService: ConfigService) {}

  get isAuthEnabled(): boolean {
    return this.configService.get('AUTH_ENABLED') === 'true';
  }
}
```

```typescript

@Dependencies(ConfigService)
@Injectable()
export class ApiConfigService {
  constructor(configService) {
    this.configService = configService;
  }

  get isAuthEnabled() {
    return this.configService.get('AUTH_ENABLED') === 'true';
  }
}
```

Now we can use the getter function as follows:

app.service.ts

JS TS

```typescript

@Injectable()
export class AppService {
  constructor(apiConfigService: ApiConfigService) {
    if (apiConfigService.isAuthEnabled) {
      // Authentication is enabled
    }
  }
}
```

```typescript

@Dependencies(ApiConfigService)
@Injectable()
export class AppService {
  constructor(apiConfigService) {
    if (apiConfigService.isAuthEnabled) {
      // Authentication is enabled
    }
  }
}
```

#### Environment variables loaded hook[#](/techniques/configuration#environment-variables-loaded-hook)

If a module configuration depends on the environment variables, and these variables are loaded from the `.env` file, you can use the `ConfigModule.envVariablesLoaded` hook to ensure that the file was loaded before interacting with the `process.env` object, see the following example:

```typescript

export async function getStorageModule() {
  await ConfigModule.envVariablesLoaded;
  return process.env.STORAGE === 'S3' ? S3StorageModule : DefaultStorageModule;
}
```

This construction guarantees that after the `ConfigModule.envVariablesLoaded` Promise resolves, all configuration variables are loaded up.

#### Conditional module configuration[#](/techniques/configuration#conditional-module-configuration)

There may be times where you want to conditionally load in a module and specify the condition in an env variable. Fortunately, `@nestjs/config` provides a `ConditionalModule` that allows you to do just that.

```typescript

@Module({
  imports: [
    ConfigModule.forRoot(),
    ConditionalModule.registerWhen(FooModule, 'USE_FOO'),
  ],
})
export class AppModule {}
```

The above module would only load in the `FooModule` if in the `.env` file there is not a `false` value for the env variable `USE_FOO`. You can also pass a custom condition yourself, a function receiving the `process.env` reference that should return a boolean for the `ConditionalModule` to handle:

```typescript

@Module({
  imports: [
    ConfigModule.forRoot(),
    ConditionalModule.registerWhen(
      FooBarModule,
      (env: NodeJS.ProcessEnv) => !!env['foo'] && !!env['bar'],
    ),
  ],
})
export class AppModule {}
```

It is important to be sure that when using the `ConditionalModule` you also have the `ConfigModule` loaded in the application, so that the `ConfigModule.envVariablesLoaded` hook can be properly referenced and utilized. If the hook is not flipped to true within 5 seconds, or a timeout in milliseconds, set by the user in the third options parameter of the `registerWhen` method, then the `ConditionalModule` will throw an error and Nest will abort starting the application.

#### Expandable variables[#](/techniques/configuration#expandable-variables)

The `@nestjs/config` package supports environment variable expansion. With this technique, you can create nested environment variables, where one variable is referred to within the definition of another. For example:

```json

APP_URL=mywebsite.com
SUPPORT_EMAIL=support@${APP_URL}
```

With this construction, the variable `SUPPORT_EMAIL` resolves to `'support@mywebsite.com'`. Note the use of the `${...}` syntax to trigger resolving the value of the variable `APP_URL` inside the definition of `SUPPORT_EMAIL`.

> **Hint** For this feature, `@nestjs/config` package internally uses [dotenv-expand](https://github.com/motdotla/dotenv-expand).

Enable environment variable expansion using the `expandVariables` property in the options object passed to the `forRoot()` method of the `ConfigModule`, as shown below:

app.module.ts

JS TS

```typescript

@Module({
  imports: [
    ConfigModule.forRoot({
      // ...
      expandVariables: true,
    }),
  ],
})
export class AppModule {}
```

#### Using in the `main.ts`[#](/techniques/configuration#using-in-the-maints)

While our config is stored in a service, it can still be used in the `main.ts` file. This way, you can use it to store variables such as the application port or the CORS host.

To access it, you must use the `app.get()` method, followed by the service reference:

```typescript

const configService = app.get(ConfigService);
```

You can then use it as usual, by calling the `get` method with the configuration key:

```typescript

const port = configService.get('PORT');
```

----
url: https://docs.nestjs.com/v10/techniques/database
----

* [Database](https://docs.nestjs.com/v10/techniques/database#database)
* [TypeORM Integration](https://docs.nestjs.com/v10/techniques/database#typeorm-integration)
* [Repository pattern](https://docs.nestjs.com/v10/techniques/database#repository-pattern)
* [Relations](https://docs.nestjs.com/v10/techniques/database#relations)
* [Auto-load entities](https://docs.nestjs.com/v10/techniques/database#auto-load-entities)
* [Separating entity definition](https://docs.nestjs.com/v10/techniques/database#separating-entity-definition)
* [TypeORM Transactions](https://docs.nestjs.com/v10/techniques/database#typeorm-transactions)
* [Subscribers](https://docs.nestjs.com/v10/techniques/database#subscribers)
* [Migrations](https://docs.nestjs.com/v10/techniques/database#migrations)
* [Multiple databases](https://docs.nestjs.com/v10/techniques/database#multiple-databases)
* [Testing](https://docs.nestjs.com/v10/techniques/database#testing)
* [Async configuration](https://docs.nestjs.com/v10/techniques/database#async-configuration)
* [Custom DataSource Factory](https://docs.nestjs.com/v10/techniques/database#custom-datasource-factory)
* [Example](https://docs.nestjs.com/v10/techniques/database#example)
* [Sequelize Integration](https://docs.nestjs.com/v10/techniques/database#sequelize-integration)
* [Models](https://docs.nestjs.com/v10/techniques/database#models)
* [Relations](https://docs.nestjs.com/v10/techniques/database#relations-1)
* [Auto-load models](https://docs.nestjs.com/v10/techniques/database#auto-load-models)
* [Sequelize Transactions](https://docs.nestjs.com/v10/techniques/database#sequelize-transactions)
* [Migrations](https://docs.nestjs.com/v10/techniques/database#migrations-1)
* [Multiple databases](https://docs.nestjs.com/v10/techniques/database#multiple-databases-1)
* [Testing](https://docs.nestjs.com/v10/techniques/database#testing-1)
* [Async configuration](https://docs.nestjs.com/v10/techniques/database#async-configuration-1)
* [Example](https://docs.nestjs.com/v10/techniques/database#example-1)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/techniques/sql.md "Suggest Edits")

### Database

Nest is database agnostic, allowing you to easily integrate with any SQL or NoSQL database. You have a number of options available to you, depending on your preferences. At the most general level, connecting Nest to a database is simply a matter of loading an appropriate Node.js driver for the database, just as you would with [Express](https://expressjs.com/en/guide/database-integration.html) or Fastify.

You can also directly use any general purpose Node.js database integration **library** or ORM, such as [MikroORM](https://mikro-orm.io/) (see [MikroORM recipe](/v10/recipes/mikroorm)), [Sequelize](https://sequelize.org/) (see [Sequelize integration](/techniques/database#sequelize-integration)), [Knex.js](https://knexjs.org/) (see [Knex.js tutorial](https://dev.to/nestjs/build-a-nestjs-module-for-knex-js-or-other-resource-based-libraries-in-5-minutes-12an)), [TypeORM](https://github.com/typeorm/typeorm), and [Prisma](https://www.github.com/prisma/prisma) (see [Prisma recipe](/v10/recipes/prisma)), to operate at a higher level of abstraction.

For convenience, Nest provides tight integration with TypeORM and Sequelize out-of-the-box with the `@nestjs/typeorm` and `@nestjs/sequelize` packages respectively, which we'll cover in the current chapter, and Mongoose with `@nestjs/mongoose`, which is covered in [this chapter](/v10/techniques/mongodb). These integrations provide additional NestJS-specific features, such as model/repository injection, testability, and asynchronous configuration to make accessing your chosen database even easier.

### TypeORM Integration

For integrating with SQL and NoSQL databases, Nest provides the `@nestjs/typeorm` package. [TypeORM](https://github.com/typeorm/typeorm) is the most mature Object Relational Mapper (ORM) available for TypeScript. Since it's written in TypeScript, it integrates well with the Nest framework.

To begin using it, we first install the required dependencies. In this chapter, we'll demonstrate using the popular [MySQL](https://www.mysql.com/) Relational DBMS, but TypeORM provides support for many relational databases, such as PostgreSQL, Oracle, Microsoft SQL Server, SQLite, and even NoSQL databases like MongoDB. The procedure we walk through in this chapter will be the same for any database supported by TypeORM. You'll simply need to install the associated client API libraries for your selected database.

```bash

$ npm install --save @nestjs/typeorm typeorm mysql2
```

Once the installation process is complete, we can import the `TypeOrmModule` into the root `AppModule`.

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';

@Module({
  imports: [
    TypeOrmModule.forRoot({
      type: 'mysql',
      host: 'localhost',
      port: 3306,
      username: 'root',
      password: 'root',
      database: 'test',
      entities: [],
      synchronize: true,
    }),
  ],
})
export class AppModule {}
```

> **Warning** Setting `synchronize: true` shouldn't be used in production - otherwise you can lose production data.

The `forRoot()` method supports all the configuration properties exposed by the `DataSource` constructor from the [TypeORM](https://typeorm.io/data-source-options#common-data-source-options) package. In addition, there are several extra configuration properties described below.

|                    |                                                                     |
| ------------------ | ------------------------------------------------------------------- |
| `retryAttempts`    | Number of attempts to connect to the database (default: `10`)       |
| `retryDelay`       | Delay between connection retry attempts (ms) (default: `3000`)      |
| `autoLoadEntities` | If `true`, entities will be loaded automatically (default: `false`) |

> **Hint** Learn more about the data source options [here](https://typeorm.io/data-source-options).

Once this is done, the TypeORM `DataSource` and `EntityManager` objects will be available to inject across the entire project (without needing to import any modules), for example:

app.module.ts

JS TS

```typescript

import { DataSource } from 'typeorm';

@Module({
  imports: [TypeOrmModule.forRoot(), UsersModule],
})
export class AppModule {
  constructor(private dataSource: DataSource) {}
}
```

```typescript

import { DataSource } from 'typeorm';

@Dependencies(DataSource)
@Module({
  imports: [TypeOrmModule.forRoot(), UsersModule],
})
export class AppModule {
  constructor(dataSource) {
    this.dataSource = dataSource;
  }
}
```

#### Repository pattern[#](/techniques/database#repository-pattern)

[TypeORM](https://github.com/typeorm/typeorm) supports the **repository design pattern**, so each entity has its own repository. These repositories can be obtained from the database data source.

To continue the example, we need at least one entity. Let's define the `User` entity.

user.entity.ts

JS TS

```typescript

import { Entity, Column, PrimaryGeneratedColumn } from 'typeorm';

@Entity()
export class User {
  @PrimaryGeneratedColumn()
  id: number;

  @Column()
  firstName: string;

  @Column()
  lastName: string;

  @Column({ default: true })
  isActive: boolean;
}
```

> **Hint** Learn more about entities in the [TypeORM documentation](https://typeorm.io/#/entities).

The `User` entity file sits in the `users` directory. This directory contains all files related to the `UsersModule`. You can decide where to keep your model files, however, we recommend creating them near their **domain**, in the corresponding module directory.

To begin using the `User` entity, we need to let TypeORM know about it by inserting it into the `entities` array in the module `forRoot()` method options (unless you use a static glob path):

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { User } from './users/user.entity';

@Module({
  imports: [
    TypeOrmModule.forRoot({
      type: 'mysql',
      host: 'localhost',
      port: 3306,
      username: 'root',
      password: 'root',
      database: 'test',
      entities: [User],
      synchronize: true,
    }),
  ],
})
export class AppModule {}
```

Next, let's look at the `UsersModule`:

users.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { UsersService } from './users.service';
import { UsersController } from './users.controller';
import { User } from './user.entity';

@Module({
  imports: [TypeOrmModule.forFeature([User])],
  providers: [UsersService],
  controllers: [UsersController],
})
export class UsersModule {}
```

This module uses the `forFeature()` method to define which repositories are registered in the current scope. With that in place, we can inject the `UsersRepository` into the `UsersService` using the `@InjectRepository()` decorator:

users.service.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { User } from './user.entity';

@Injectable()
export class UsersService {
  constructor(
    @InjectRepository(User)
    private usersRepository: Repository<User>,
  ) {}

  findAll(): Promise<User[]> {
    return this.usersRepository.find();
  }

  findOne(id: number): Promise<User | null> {
    return this.usersRepository.findOneBy({ id });
  }

  async remove(id: number): Promise<void> {
    await this.usersRepository.delete(id);
  }
}
```

```typescript

import { Injectable, Dependencies } from '@nestjs/common';
import { getRepositoryToken } from '@nestjs/typeorm';
import { User } from './user.entity';

@Injectable()
@Dependencies(getRepositoryToken(User))
export class UsersService {
  constructor(usersRepository) {
    this.usersRepository = usersRepository;
  }

  findAll() {
    return this.usersRepository.find();
  }

  findOne(id) {
    return this.usersRepository.findOneBy({ id });
  }

  async remove(id) {
    await this.usersRepository.delete(id);
  }
}
```

> **Notice** Don't forget to import the `UsersModule` into the root `AppModule`.

If you want to use the repository outside of the module which imports `TypeOrmModule.forFeature`, you'll need to re-export the providers generated by it. You can do this by exporting the whole module, like this:

users.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { User } from './user.entity';

@Module({
  imports: [TypeOrmModule.forFeature([User])],
  exports: [TypeOrmModule]
})
export class UsersModule {}
```

Now if we import `UsersModule` in `UserHttpModule`, we can use `@InjectRepository(User)` in the providers of the latter module.

users-http.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { UsersModule } from './users.module';
import { UsersService } from './users.service';
import { UsersController } from './users.controller';

@Module({
  imports: [UsersModule],
  providers: [UsersService],
  controllers: [UsersController]
})
export class UserHttpModule {}
```

#### Relations[#](/techniques/database#relations)

Relations are associations established between two or more tables. Relations are based on common fields from each table, often involving primary and foreign keys.

There are three types of relations:

|                             |                                                                                                                                                                                                                                 |
| --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `One-to-one`                | Every row in the primary table has one and only one associated row in the foreign table. Use the `@OneToOne()` decorator to define this type of relation.                                                                       |
| `One-to-many / Many-to-one` | Every row in the primary table has one or more related rows in the foreign table. Use the `@OneToMany()` and `@ManyToOne()` decorators to define this type of relation.                                                         |
| `Many-to-many`              | Every row in the primary table has many related rows in the foreign table, and every record in the foreign table has many related rows in the primary table. Use the `@ManyToMany()` decorator to define this type of relation. |

To define relations in entities, use the corresponding **decorators**. For example, to define that each `User` can have multiple photos, use the `@OneToMany()` decorator.

user.entity.ts

JS TS

```typescript

import { Entity, Column, PrimaryGeneratedColumn, OneToMany } from 'typeorm';
import { Photo } from '../photos/photo.entity';

@Entity()
export class User {
  @PrimaryGeneratedColumn()
  id: number;

  @Column()
  firstName: string;

  @Column()
  lastName: string;

  @Column({ default: true })
  isActive: boolean;

  @OneToMany(type => Photo, photo => photo.user)
  photos: Photo[];
}
```

> **Hint** To learn more about relations in TypeORM, visit the [TypeORM documentation](https://typeorm.io/#/relations).

#### Auto-load entities[#](/techniques/database#auto-load-entities)

Manually adding entities to the `entities` array of the data source options can be tedious. In addition, referencing entities from the root module breaks application domain boundaries and causes leaking implementation details to other parts of the application. To address this issue, an alternative solution is provided. To automatically load entities, set the `autoLoadEntities` property of the configuration object (passed into the `forRoot()` method) to `true`, as shown below:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';

@Module({
  imports: [
    TypeOrmModule.forRoot({
      ...
      autoLoadEntities: true,
    }),
  ],
})
export class AppModule {}
```

With that option specified, every entity registered through the `forFeature()` method will be automatically added to the `entities` array of the configuration object.

> **Warning** Note that entities that aren't registered through the `forFeature()` method, but are only referenced from the entity (via a relationship), won't be included by way of the `autoLoadEntities` setting.

#### Separating entity definition[#](/techniques/database#separating-entity-definition)

You can define an entity and its columns right in the model, using decorators. But some people prefer to define entities and their columns inside separate files using the ["entity schemas"](https://typeorm.io/#/separating-entity-definition).

```typescript

import { EntitySchema } from 'typeorm';
import { User } from './user.entity';

export const UserSchema = new EntitySchema<User>({
  name: 'User',
  target: User,
  columns: {
    id: {
      type: Number,
      primary: true,
      generated: true,
    },
    firstName: {
      type: String,
    },
    lastName: {
      type: String,
    },
    isActive: {
      type: Boolean,
      default: true,
    },
  },
  relations: {
    photos: {
      type: 'one-to-many',
      target: 'Photo', // the name of the PhotoSchema
    },
  },
});
```

> **Warning** If you provide the `target` option, the `name` option value has to be the same as the name of the target class. If you do not provide the `target` you can use any name.

Nest allows you to use an `EntitySchema` instance wherever an `Entity` is expected, for example:

```typescript

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { UserSchema } from './user.schema';
import { UsersController } from './users.controller';
import { UsersService } from './users.service';

@Module({
  imports: [TypeOrmModule.forFeature([UserSchema])],
  providers: [UsersService],
  controllers: [UsersController],
})
export class UsersModule {}
```

#### TypeORM Transactions[#](/techniques/database#typeorm-transactions)

A database transaction symbolizes a unit of work performed within a database management system against a database, and treated in a coherent and reliable way independent of other transactions. A transaction generally represents any change in a database ([learn more](https://en.wikipedia.org/wiki/Database_transaction)).

There are many different strategies to handle [TypeORM transactions](https://typeorm.io/#/transactions). We recommend using the `QueryRunner` class because it gives full control over the transaction.

First, we need to inject the `DataSource` object into a class in the normal way:

```typescript

@Injectable()
export class UsersService {
  constructor(private dataSource: DataSource) {}
}
```

> **Hint** The `DataSource` class is imported from the `typeorm` package.

Now, we can use this object to create a transaction.

```typescript

async createMany(users: User[]) {
  const queryRunner = this.dataSource.createQueryRunner();

  await queryRunner.connect();
  await queryRunner.startTransaction();
  try {
    await queryRunner.manager.save(users[0]);
    await queryRunner.manager.save(users[1]);

    await queryRunner.commitTransaction();
  } catch (err) {
    // since we have errors lets rollback the changes we made
    await queryRunner.rollbackTransaction();
  } finally {
    // you need to release a queryRunner which was manually instantiated
    await queryRunner.release();
  }
}
```

> **Hint** Note that the `dataSource` is used only to create the `QueryRunner`. However, to test this class would require mocking the entire `DataSource` object (which exposes several methods). Thus, we recommend using a helper factory class (e.g., `QueryRunnerFactory`) and defining an interface with a limited set of methods required to maintain transactions. This technique makes mocking these methods pretty straightforward.

```typescript

async createMany(users: User[]) {
  await this.dataSource.transaction(async manager => {
    await manager.save(users[0]);
    await manager.save(users[1]);
  });
}
```

#### Subscribers[#](/techniques/database#subscribers)

With TypeORM [subscribers](https://typeorm.io/#/listeners-and-subscribers/what-is-a-subscriber), you can listen to specific entity events.

```typescript

import {
  DataSource,
  EntitySubscriberInterface,
  EventSubscriber,
  InsertEvent,
} from 'typeorm';
import { User } from './user.entity';

@EventSubscriber()
export class UserSubscriber implements EntitySubscriberInterface<User> {
  constructor(dataSource: DataSource) {
    dataSource.subscribers.push(this);
  }

  listenTo() {
    return User;
  }

  beforeInsert(event: InsertEvent<User>) {
    console.log(`BEFORE USER INSERTED: `, event.entity);
  }
}
```

> **Warning** Event subscribers can not be [request-scoped](/v10/fundamentals/injection-scopes).

Now, add the `UserSubscriber` class to the `providers` array:

```typescript

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { User } from './user.entity';
import { UsersController } from './users.controller';
import { UsersService } from './users.service';
import { UserSubscriber } from './user.subscriber';

@Module({
  imports: [TypeOrmModule.forFeature([User])],
  providers: [UsersService, UserSubscriber],
  controllers: [UsersController],
})
export class UsersModule {}
```

> **Hint** Learn more about entity subscribers [here](https://typeorm.io/#/listeners-and-subscribers/what-is-a-subscriber).

#### Migrations[#](/techniques/database#migrations)

[Migrations](https://typeorm.io/#/migrations) provide a way to incrementally update the database schema to keep it in sync with the application's data model while preserving existing data in the database. To generate, run, and revert migrations, TypeORM provides a dedicated [CLI](https://typeorm.io/#/migrations/creating-a-new-migration).

Migration classes are separate from the Nest application source code. Their lifecycle is maintained by the TypeORM CLI. Therefore, you are not able to leverage dependency injection and other Nest specific features with migrations. To learn more about migrations, follow the guide in the [TypeORM documentation](https://typeorm.io/#/migrations/creating-a-new-migration).

#### Multiple databases[#](/techniques/database#multiple-databases)

Some projects require multiple database connections. This can also be achieved with this module. To work with multiple connections, first create the connections. In this case, data source naming becomes **mandatory**.

Suppose you have an `Album` entity stored in its own database.

```typescript

const defaultOptions = {
  type: 'postgres',
  port: 5432,
  username: 'user',
  password: 'password',
  database: 'db',
  synchronize: true,
};

@Module({
  imports: [
    TypeOrmModule.forRoot({
      ...defaultOptions,
      host: 'user_db_host',
      entities: [User],
    }),
    TypeOrmModule.forRoot({
      ...defaultOptions,
      name: 'albumsConnection',
      host: 'album_db_host',
      entities: [Album],
    }),
  ],
})
export class AppModule {}
```

> **Notice** If you don't set the `name` for a data source, its name is set to `default`. Please note that you shouldn't have multiple connections without a name, or with the same name, otherwise they will get overridden.

> **Notice** If you are using `TypeOrmModule.forRootAsync`, you have to **also** set the data source name outside `useFactory`. For example:
>
> ```typescript
>
> TypeOrmModule.forRootAsync({
>   name: 'albumsConnection',
>   useFactory: ...,
>   inject: ...,
> }),
> ```
>
> See [this issue](https://github.com/nestjs/typeorm/issues/86) for more details.

At this point, you have `User` and `Album` entities registered with their own data source. With this setup, you have to tell the `TypeOrmModule.forFeature()` method and the `@InjectRepository()` decorator which data source should be used. If you do not pass any data source name, the `default` data source is used.

```typescript

@Module({
  imports: [
    TypeOrmModule.forFeature([User]),
    TypeOrmModule.forFeature([Album], 'albumsConnection'),
  ],
})
export class AppModule {}
```

You can also inject the `DataSource` or `EntityManager` for a given data source:

```typescript

@Injectable()
export class AlbumsService {
  constructor(
    @InjectDataSource('albumsConnection')
    private dataSource: DataSource,
    @InjectEntityManager('albumsConnection')
    private entityManager: EntityManager,
  ) {}
}
```

It's also possible to inject any `DataSource` to the providers:

```typescript

@Module({
  providers: [
    {
      provide: AlbumsService,
      useFactory: (albumsConnection: DataSource) => {
        return new AlbumsService(albumsConnection);
      },
      inject: [getDataSourceToken('albumsConnection')],
    },
  ],
})
export class AlbumsModule {}
```

#### Testing[#](/techniques/database#testing)

When it comes to unit testing an application, we usually want to avoid making a database connection, keeping our test suites independent and their execution process as fast as possible. But our classes might depend on repositories that are pulled from the data source (connection) instance. How do we handle that? The solution is to create mock repositories. In order to achieve that, we set up [custom providers](/v10/fundamentals/custom-providers). Each registered repository is automatically represented by an `<EntityName>Repository` token, where `EntityName` is the name of your entity class.

The `@nestjs/typeorm` package exposes the `getRepositoryToken()` function which returns a prepared token based on a given entity.

```typescript

@Module({
  providers: [
    UsersService,
    {
      provide: getRepositoryToken(User),
      useValue: mockRepository,
    },
  ],
})
export class UsersModule {}
```

Now a substitute `mockRepository` will be used as the `UsersRepository`. Whenever any class asks for `UsersRepository` using an `@InjectRepository()` decorator, Nest will use the registered `mockRepository` object.

#### Async configuration[#](/techniques/database#async-configuration)

You may want to pass your repository module options asynchronously instead of statically. In this case, use the `forRootAsync()` method, which provides several ways to deal with async configuration.

One approach is to use a factory function:

```typescript

TypeOrmModule.forRootAsync({
  useFactory: () => ({
    type: 'mysql',
    host: 'localhost',
    port: 3306,
    username: 'root',
    password: 'root',
    database: 'test',
    entities: [],
    synchronize: true,
  }),
});
```

Our factory behaves like any other [asynchronous provider](https://docs.nestjs.com/fundamentals/async-providers) (e.g., it can be `async` and it's able to inject dependencies through `inject`).

```typescript

TypeOrmModule.forRootAsync({
  imports: [ConfigModule],
  useFactory: (configService: ConfigService) => ({
    type: 'mysql',
    host: configService.get('HOST'),
    port: +configService.get('PORT'),
    username: configService.get('USERNAME'),
    password: configService.get('PASSWORD'),
    database: configService.get('DATABASE'),
    entities: [],
    synchronize: true,
  }),
  inject: [ConfigService],
});
```

Alternatively, you can use the `useClass` syntax:

```typescript

TypeOrmModule.forRootAsync({
  useClass: TypeOrmConfigService,
});
```

The construction above will instantiate `TypeOrmConfigService` inside `TypeOrmModule` and use it to provide an options object by calling `createTypeOrmOptions()`. Note that this means that the `TypeOrmConfigService` has to implement the `TypeOrmOptionsFactory` interface, as shown below:

```typescript

@Injectable()
export class TypeOrmConfigService implements TypeOrmOptionsFactory {
  createTypeOrmOptions(): TypeOrmModuleOptions {
    return {
      type: 'mysql',
      host: 'localhost',
      port: 3306,
      username: 'root',
      password: 'root',
      database: 'test',
      entities: [],
      synchronize: true,
    };
  }
}
```

In order to prevent the creation of `TypeOrmConfigService` inside `TypeOrmModule` and use a provider imported from a different module, you can use the `useExisting` syntax.

```typescript

TypeOrmModule.forRootAsync({
  imports: [ConfigModule],
  useExisting: ConfigService,
});
```

This construction works the same as `useClass` with one critical difference - `TypeOrmModule` will lookup imported modules to reuse an existing `ConfigService` instead of instantiating a new one.

> **Hint** Make sure that the `name` property is defined at the same level as the `useFactory`, `useClass`, or `useValue` property. This will allow Nest to properly register the data source under the appropriate injection token.

#### Custom DataSource Factory[#](/techniques/database#custom-datasource-factory)

In conjunction with async configuration using `useFactory`, `useClass`, or `useExisting`, you can optionally specify a `dataSourceFactory` function which will allow you to provide your own TypeORM data source rather than allowing `TypeOrmModule` to create the data source.

`dataSourceFactory` receives the TypeORM `DataSourceOptions` configured during async configuration using `useFactory`, `useClass`, or `useExisting` and returns a `Promise` that resolves a TypeORM `DataSource`.

```typescript

TypeOrmModule.forRootAsync({
  imports: [ConfigModule],
  inject: [ConfigService],
  // Use useFactory, useClass, or useExisting
  // to configure the DataSourceOptions.
  useFactory: (configService: ConfigService) => ({
    type: 'mysql',
    host: configService.get('HOST'),
    port: +configService.get('PORT'),
    username: configService.get('USERNAME'),
    password: configService.get('PASSWORD'),
    database: configService.get('DATABASE'),
    entities: [],
    synchronize: true,
  }),
  // dataSource receives the configured DataSourceOptions
  // and returns a Promise<DataSource>.
  dataSourceFactory: async (options) => {
    const dataSource = await new DataSource(options).initialize();
    return dataSource;
  },
});
```

> **Hint** The `DataSource` class is imported from the `typeorm` package.

```bash

$ npm install --save @nestjs/sequelize sequelize sequelize-typescript mysql2
$ npm install --save-dev @types/sequelize
```

Once the installation process is complete, we can import the `SequelizeModule` into the root `AppModule`.

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { SequelizeModule } from '@nestjs/sequelize';

@Module({
  imports: [
    SequelizeModule.forRoot({
      dialect: 'mysql',
      host: 'localhost',
      port: 3306,
      username: 'root',
      password: 'root',
      database: 'test',
      models: [],
    }),
  ],
})
export class AppModule {}
```

The `forRoot()` method supports all the configuration properties exposed by the Sequelize constructor ([read more](https://sequelize.org/docs/v6/getting-started/#connecting-to-a-database)). In addition, there are several extra configuration properties described below.

|                       |                                                                                         |
| --------------------- | --------------------------------------------------------------------------------------- |
| `retryAttempts`       | Number of attempts to connect to the database (default: `10`)                           |
| `retryDelay`          | Delay between connection retry attempts (ms) (default: `3000`)                          |
| `autoLoadModels`      | If `true`, models will be loaded automatically (default: `false`)                       |
| `keepConnectionAlive` | If `true`, connection will not be closed on the application shutdown (default: `false`) |
| `synchronize`         | If `true`, automatically loaded models will be synchronized (default: `true`)           |

Once this is done, the `Sequelize` object will be available to inject across the entire project (without needing to import any modules), for example:

app.service.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { Sequelize } from 'sequelize-typescript';

@Injectable()
export class AppService {
  constructor(private sequelize: Sequelize) {}
}
```

```typescript

import { Injectable } from '@nestjs/common';
import { Sequelize } from 'sequelize-typescript';

@Dependencies(Sequelize)
@Injectable()
export class AppService {
  constructor(sequelize) {
    this.sequelize = sequelize;
  }
}
```

#### Models[#](/techniques/database#models)

Sequelize implements the Active Record pattern. With this pattern, you use model classes directly to interact with the database. To continue the example, we need at least one model. Let's define the `User` model.

user.model.ts

JS TS

```typescript

import { Column, Model, Table } from 'sequelize-typescript';

@Table
export class User extends Model {
  @Column
  firstName: string;

  @Column
  lastName: string;

  @Column({ defaultValue: true })
  isActive: boolean;
}
```

> **Hint** Learn more about the available decorators [here](https://github.com/RobinBuschmann/sequelize-typescript#column).

The `User` model file sits in the `users` directory. This directory contains all files related to the `UsersModule`. You can decide where to keep your model files, however, we recommend creating them near their **domain**, in the corresponding module directory.

To begin using the `User` model, we need to let Sequelize know about it by inserting it into the `models` array in the module `forRoot()` method options:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { SequelizeModule } from '@nestjs/sequelize';
import { User } from './users/user.model';

@Module({
  imports: [
    SequelizeModule.forRoot({
      dialect: 'mysql',
      host: 'localhost',
      port: 3306,
      username: 'root',
      password: 'root',
      database: 'test',
      models: [User],
    }),
  ],
})
export class AppModule {}
```

Next, let's look at the `UsersModule`:

users.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { SequelizeModule } from '@nestjs/sequelize';
import { User } from './user.model';
import { UsersController } from './users.controller';
import { UsersService } from './users.service';

@Module({
  imports: [SequelizeModule.forFeature([User])],
  providers: [UsersService],
  controllers: [UsersController],
})
export class UsersModule {}
```

This module uses the `forFeature()` method to define which models are registered in the current scope. With that in place, we can inject the `UserModel` into the `UsersService` using the `@InjectModel()` decorator:

users.service.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { InjectModel } from '@nestjs/sequelize';
import { User } from './user.model';

@Injectable()
export class UsersService {
  constructor(
    @InjectModel(User)
    private userModel: typeof User,
  ) {}

  async findAll(): Promise<User[]> {
    return this.userModel.findAll();
  }

  findOne(id: string): Promise<User> {
    return this.userModel.findOne({
      where: {
        id,
      },
    });
  }

  async remove(id: string): Promise<void> {
    const user = await this.findOne(id);
    await user.destroy();
  }
}
```

```typescript

import { Injectable, Dependencies } from '@nestjs/common';
import { getModelToken } from '@nestjs/sequelize';
import { User } from './user.model';

@Injectable()
@Dependencies(getModelToken(User))
export class UsersService {
  constructor(usersRepository) {
    this.usersRepository = usersRepository;
  }

  async findAll() {
    return this.userModel.findAll();
  }

  findOne(id) {
    return this.userModel.findOne({
      where: {
        id,
      },
    });
  }

  async remove(id) {
    const user = await this.findOne(id);
    await user.destroy();
  }
}
```

> **Notice** Don't forget to import the `UsersModule` into the root `AppModule`.

If you want to use the repository outside of the module which imports `SequelizeModule.forFeature`, you'll need to re-export the providers generated by it. You can do this by exporting the whole module, like this:

users.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { SequelizeModule } from '@nestjs/sequelize';
import { User } from './user.entity';

@Module({
  imports: [SequelizeModule.forFeature([User])],
  exports: [SequelizeModule]
})
export class UsersModule {}
```

Now if we import `UsersModule` in `UserHttpModule`, we can use `@InjectModel(User)` in the providers of the latter module.

users-http.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { UsersModule } from './users.module';
import { UsersService } from './users.service';
import { UsersController } from './users.controller';

@Module({
  imports: [UsersModule],
  providers: [UsersService],
  controllers: [UsersController]
})
export class UserHttpModule {}
```

#### Relations[#](/techniques/database#relations-1)

Relations are associations established between two or more tables. Relations are based on common fields from each table, often involving primary and foreign keys.

There are three types of relations:

|                             |                                                                                                                                                             |
| --------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `One-to-one`                | Every row in the primary table has one and only one associated row in the foreign table                                                                     |
| `One-to-many / Many-to-one` | Every row in the primary table has one or more related rows in the foreign table                                                                            |
| `Many-to-many`              | Every row in the primary table has many related rows in the foreign table, and every record in the foreign table has many related rows in the primary table |

To define relations in models, use the corresponding **decorators**. For example, to define that each `User` can have multiple photos, use the `@HasMany()` decorator.

user.model.ts

JS TS

```typescript

import { Column, Model, Table, HasMany } from 'sequelize-typescript';
import { Photo } from '../photos/photo.model';

@Table
export class User extends Model {
  @Column
  firstName: string;

  @Column
  lastName: string;

  @Column({ defaultValue: true })
  isActive: boolean;

  @HasMany(() => Photo)
  photos: Photo[];
}
```

> **Hint** To learn more about associations in Sequelize, read [this](https://github.com/RobinBuschmann/sequelize-typescript#model-association) chapter.

#### Auto-load models[#](/techniques/database#auto-load-models)

Manually adding models to the `models` array of the connection options can be tedious. In addition, referencing models from the root module breaks application domain boundaries and causes leaking implementation details to other parts of the application. To solve this issue, automatically load models by setting both `autoLoadModels` and `synchronize` properties of the configuration object (passed into the `forRoot()` method) to `true`, as shown below:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { SequelizeModule } from '@nestjs/sequelize';

@Module({
  imports: [
    SequelizeModule.forRoot({
      ...
      autoLoadModels: true,
      synchronize: true,
    }),
  ],
})
export class AppModule {}
```

With that option specified, every model registered through the `forFeature()` method will be automatically added to the `models` array of the configuration object.

> **Warning** Note that models that aren't registered through the `forFeature()` method, but are only referenced from the model (via an association), won't be included.

#### Sequelize Transactions[#](/techniques/database#sequelize-transactions)

A database transaction symbolizes a unit of work performed within a database management system against a database, and treated in a coherent and reliable way independent of other transactions. A transaction generally represents any change in a database ([learn more](https://en.wikipedia.org/wiki/Database_transaction)).

There are many different strategies to handle [Sequelize transactions](https://sequelize.org/docs/v6/other-topics/transactions/). Below is a sample implementation of a managed transaction (auto-callback).

First, we need to inject the `Sequelize` object into a class in the normal way:

```typescript

@Injectable()
export class UsersService {
  constructor(private sequelize: Sequelize) {}
}
```

> **Hint** The `Sequelize` class is imported from the `sequelize-typescript` package.

Now, we can use this object to create a transaction.

```typescript

async createMany() {
  try {
    await this.sequelize.transaction(async t => {
      const transactionHost = { transaction: t };

      await this.userModel.create(
          { firstName: 'Abraham', lastName: 'Lincoln' },
          transactionHost,
      );
      await this.userModel.create(
          { firstName: 'John', lastName: 'Boothe' },
          transactionHost,
      );
    });
  } catch (err) {
    // Transaction has been rolled back
    // err is whatever rejected the promise chain returned to the transaction callback
  }
}
```

> **Hint** Note that the `Sequelize` instance is used only to start the transaction. However, to test this class would require mocking the entire `Sequelize` object (which exposes several methods). Thus, we recommend using a helper factory class (e.g., `TransactionRunner`) and defining an interface with a limited set of methods required to maintain transactions. This technique makes mocking these methods pretty straightforward.

```typescript

const defaultOptions = {
  dialect: 'postgres',
  port: 5432,
  username: 'user',
  password: 'password',
  database: 'db',
  synchronize: true,
};

@Module({
  imports: [
    SequelizeModule.forRoot({
      ...defaultOptions,
      host: 'user_db_host',
      models: [User],
    }),
    SequelizeModule.forRoot({
      ...defaultOptions,
      name: 'albumsConnection',
      host: 'album_db_host',
      models: [Album],
    }),
  ],
})
export class AppModule {}
```

> **Notice** If you don't set the `name` for a connection, its name is set to `default`. Please note that you shouldn't have multiple connections without a name, or with the same name, otherwise they will get overridden.

At this point, you have `User` and `Album` models registered with their own connection. With this setup, you have to tell the `SequelizeModule.forFeature()` method and the `@InjectModel()` decorator which connection should be used. If you do not pass any connection name, the `default` connection is used.

```typescript

@Module({
  imports: [
    SequelizeModule.forFeature([User]),
    SequelizeModule.forFeature([Album], 'albumsConnection'),
  ],
})
export class AppModule {}
```

You can also inject the `Sequelize` instance for a given connection:

```typescript

@Injectable()
export class AlbumsService {
  constructor(
    @InjectConnection('albumsConnection')
    private sequelize: Sequelize,
  ) {}
}
```

It's also possible to inject any `Sequelize` instance to the providers:

```typescript

@Module({
  providers: [
    {
      provide: AlbumsService,
      useFactory: (albumsSequelize: Sequelize) => {
        return new AlbumsService(albumsSequelize);
      },
      inject: [getDataSourceToken('albumsConnection')],
    },
  ],
})
export class AlbumsModule {}
```

#### Testing[#](/techniques/database#testing-1)

When it comes to unit testing an application, we usually want to avoid making a database connection, keeping our test suites independent and their execution process as fast as possible. But our classes might depend on models that are pulled from the connection instance. How do we handle that? The solution is to create mock models. In order to achieve that, we set up [custom providers](/v10/fundamentals/custom-providers). Each registered model is automatically represented by a `<ModelName>Model` token, where `ModelName` is the name of your model class.

The `@nestjs/sequelize` package exposes the `getModelToken()` function which returns a prepared token based on a given model.

```typescript

@Module({
  providers: [
    UsersService,
    {
      provide: getModelToken(User),
      useValue: mockModel,
    },
  ],
})
export class UsersModule {}
```

Now a substitute `mockModel` will be used as the `UserModel`. Whenever any class asks for `UserModel` using an `@InjectModel()` decorator, Nest will use the registered `mockModel` object.

#### Async configuration[#](/techniques/database#async-configuration-1)

You may want to pass your `SequelizeModule` options asynchronously instead of statically. In this case, use the `forRootAsync()` method, which provides several ways to deal with async configuration.

One approach is to use a factory function:

```typescript

SequelizeModule.forRootAsync({
  useFactory: () => ({
    dialect: 'mysql',
    host: 'localhost',
    port: 3306,
    username: 'root',
    password: 'root',
    database: 'test',
    models: [],
  }),
});
```

Our factory behaves like any other [asynchronous provider](https://docs.nestjs.com/fundamentals/async-providers) (e.g., it can be `async` and it's able to inject dependencies through `inject`).

```typescript

SequelizeModule.forRootAsync({
  imports: [ConfigModule],
  useFactory: (configService: ConfigService) => ({
    dialect: 'mysql',
    host: configService.get('HOST'),
    port: +configService.get('PORT'),
    username: configService.get('USERNAME'),
    password: configService.get('PASSWORD'),
    database: configService.get('DATABASE'),
    models: [],
  }),
  inject: [ConfigService],
});
```

Alternatively, you can use the `useClass` syntax:

```typescript

SequelizeModule.forRootAsync({
  useClass: SequelizeConfigService,
});
```

The construction above will instantiate `SequelizeConfigService` inside `SequelizeModule` and use it to provide an options object by calling `createSequelizeOptions()`. Note that this means that the `SequelizeConfigService` has to implement the `SequelizeOptionsFactory` interface, as shown below:

```typescript

@Injectable()
class SequelizeConfigService implements SequelizeOptionsFactory {
  createSequelizeOptions(): SequelizeModuleOptions {
    return {
      dialect: 'mysql',
      host: 'localhost',
      port: 3306,
      username: 'root',
      password: 'root',
      database: 'test',
      models: [],
    };
  }
}
```

In order to prevent the creation of `SequelizeConfigService` inside `SequelizeModule` and use a provider imported from a different module, you can use the `useExisting` syntax.

```typescript

SequelizeModule.forRootAsync({
  imports: [ConfigModule],
  useExisting: ConfigService,
});
```

This construction works the same as `useClass` with one critical difference - `SequelizeModule` will lookup imported modules to reuse an existing `ConfigService` instead of instantiating a new one.

#### Example[#](/techniques/database#example-1)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/07-sequelize).

----
url: https://docs.nestjs.com/v10/recipes/repl
----

* [Read-Eval-Print-Loop (REPL)](https://docs.nestjs.com/v10/recipes/repl#read-eval-print-loop-repl)
* [Usage](https://docs.nestjs.com/v10/recipes/repl#usage)
* [Native functions](https://docs.nestjs.com/v10/recipes/repl#native-functions)
* [Watch mode](https://docs.nestjs.com/v10/recipes/repl#watch-mode)

```typescript

import { repl } from '@nestjs/core';
import { AppModule } from './src/app.module';

async function bootstrap() {
  await repl(AppModule);
}
bootstrap();
```

```typescript

import { repl } from '@nestjs/core';
import { AppModule } from './src/app.module';

async function bootstrap() {
  await repl(AppModule);
}
bootstrap();
```

Now in your terminal, start the REPL with the following command:

```bash

$ npm run start -- --entryFile repl
```

> **Hint**`repl` returns a [Node.js REPL server](https://nodejs.org/api/repl.html) object.

Once it's up and running, you should see the following message in your console:

```bash

LOG [NestFactory] Starting Nest application...
LOG [InstanceLoader] AppModule dependencies initialized
LOG REPL initialized
```

And now you can start interacting with your dependencies graph. For instance, you can retrieve an `AppService` (we are using the starter project as an example here) and call the `getHello()` method:

```typescript

> get(AppService).getHello()
'Hello World!'
```

You can execute any JavaScript code from within your terminal, for example, assign an instance of the `AppController` to a local variable, and use `await` to call an asynchronous method:

```typescript

> appController = get(AppController)
AppController { appService: AppService {} }
> await appController.getHello()
'Hello World!'
```

To display all public methods available on a given provider or controller, use the `methods()` function, as follows:

```typescript

> methods(AppController)

Methods:
 ◻ getHello
```

To print all registered modules as a list together with their controllers and providers, use `debug()`.

```typescript

> debug()

AppModule:
 - controllers:
  ◻ AppController
 - providers:
  ◻ AppService
```

Quick demo:

You can find more information about the existing, predefined native methods in the section below.

#### Native functions[#](/recipes/repl#native-functions)

The built-in NestJS REPL comes with a few native functions that are globally available when you start REPL. You can call `help()` to list them out.

If you don't recall what's the signature (ie: expected parameters and a return type) of a function, you can call `<function_name>.help`. For instance:

```text

> $.help
Retrieves an instance of either injectable or controller, otherwise, throws exception.
Interface: $(token: InjectionToken) => any
```

> **Hint** Those function interfaces are written in [TypeScript function type expression syntax](https://www.typescriptlang.org/docs/handbook/2/functions.html#function-type-expressions).

| Function     | Description                                                                                                        | Signature                                                             |
| ------------ | ------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------- |
| `debug`      | Print all registered modules as a list together with their controllers and providers.                              | `debug(moduleCls?: ClassRef \| string) => void`                       |
| `get` or `$` | Retrieves an instance of either injectable or controller, otherwise, throws exception.                             | `get(token: InjectionToken) => any`                                   |
| `methods`    | Display all public methods available on a given provider or controller.                                            | `methods(token: ClassRef \| string) => void`                          |
| `resolve`    | Resolves transient or request-scoped instance of either injectable or controller, otherwise, throws exception.     | `resolve(token: InjectionToken, contextId: any) => Promise<any>`      |
| `select`     | Allows navigating through the modules tree, for example, to pull out a specific instance from the selected module. | `select(token: DynamicModule \| ClassRef) => INestApplicationContext` |

#### Watch mode[#](/recipes/repl#watch-mode)

During development it is useful to run REPL in a watch mode to reflect all the code changes automatically:

```bash

$ npm run start -- --watch --entryFile repl
```

This has one flaw, the REPL's command history is discarded after each reload which might be cumbersome. Fortunately, there is a very simple solution. Modify your `bootstrap` function like this:

```typescript

async function bootstrap() {
  const replServer = await repl(AppModule);
  replServer.setupHistory(".nestjs_repl_history", (err) => {
    if (err) {
      console.error(err);
    }
  });
}
```

Now the history is preserved between the runs/reloads.

----
url: https://docs.nestjs.com/pipes
----

[Skip to content](#content)

On this page

* [Pipes](https://docs.nestjs.com/pipes#pipes)
* [Built-in pipes](https://docs.nestjs.com/pipes#built-in-pipes)
* [Binding pipes](https://docs.nestjs.com/pipes#binding-pipes)
* [Custom pipes](https://docs.nestjs.com/pipes#custom-pipes)
* [Schema based validation](https://docs.nestjs.com/pipes#schema-based-validation)
* [Object schema validation](https://docs.nestjs.com/pipes#object-schema-validation)
* [Binding validation pipes](https://docs.nestjs.com/pipes#binding-validation-pipes)
* [Class validator](https://docs.nestjs.com/pipes#class-validator)
* [Global scoped pipes](https://docs.nestjs.com/pipes#global-scoped-pipes)
* [The built-in ValidationPipe](https://docs.nestjs.com/pipes#the-built-in-validationpipe)
* [Transformation use case](https://docs.nestjs.com/pipes#transformation-use-case)
* [Providing defaults](https://docs.nestjs.com/pipes#providing-defaults)

[](https://srv.carbonads.net/ads/click/x/GTND4277CVSI623LCYYLYKQUF67D623NCASIPZ3JCAAI623LF67IK27KF67D553LCVADT5Q7F6AI52JECKYDE23KC6SILKJNF67DTK3EHJNCLSIZ)[Melia by Speechmatics: multilingual speech-to-text handling code-switching across 55+ languages. ](https://srv.carbonads.net/ads/click/x/GTND4277CVSI623LCYYLYKQUF67D623NCASIPZ3JCAAI623LF67IK27KF67D553LCVADT5Q7F6AI52JECKYDE23KC6SILKJNF67DTK3EHJNCLSIZ)[ads via Carbon](http://carbonads.net/?utm_source=nestjscom\&utm_medium=ad_via_link\&utm_campaign=in_unit\&utm_term=carbon)

### Pipes

A pipe is a class annotated with the `@Injectable()` decorator that implements the `PipeTransform` interface.

Pipes have two typical use cases:

* **transformation**: transform input data to the desired form (e.g., from string to integer)
* **validation**: evaluate input data and, if valid, pass it through unchanged; otherwise, throw an exception

In both cases, pipes operate on the arguments being processed by a [controller route handler](controllers#route-parameters). Nest interposes a pipe immediately before a method is invoked; the pipe receives the arguments destined for the method and operates on them. Any transformation or validation takes place at that point, after which the route handler is invoked with the (potentially) transformed arguments.

Nest comes with a number of built-in pipes that you can use out of the box, and you can also build your own. This chapter introduces the built-in pipes and shows how to bind them to route handlers. It then walks through several custom pipes to show how to build one from scratch.

> **Hint** Pipes run inside the exceptions zone. An exception thrown by a pipe is handled by the exceptions layer (the global exception filter and any [exception filters](/exception-filters) applied to the current context). When a pipe throws an exception, the route handler is not executed. This makes pipes the recommended place to validate data that enters the application from external sources, at the system boundary.

#### Built-in pipes[#](/pipes#built-in-pipes)

Nest provides the following pipes out of the box, all exported from the `@nestjs/common` package:

* `ValidationPipe`
* `StandardSchemaValidationPipe`

Let's start with `ParseIntPipe`. It is an example of the **transformation** use case: the pipe ensures that a route handler parameter is converted to a JavaScript integer, or throws an exception if the conversion fails. Later in this chapter, we'll build a simple custom implementation of `ParseIntPipe`. The techniques below also apply to the other built-in transformation pipes (`ParseBoolPipe`, `ParseFloatPipe`, `ParseEnumPipe`, `ParseArrayPipe`, `ParseDatePipe`, and `ParseUUIDPipe`), which this chapter refers to collectively as the `Parse*` pipes.

#### Binding pipes[#](/pipes#binding-pipes)

To use a pipe, bind an instance of the pipe class to the appropriate context. In the `ParseIntPipe` example, we want to associate the pipe with a particular route handler method and make sure it runs before the method is called. The following construct does this; we refer to it as binding the pipe at the method parameter level:

```typescript

@Get(':id')
async findOne(@Param('id', ParseIntPipe) id: number) {
  return this.catsService.findOne(id);
}
```

This guarantees one of two outcomes: either the parameter received by `findOne()` is a number (as `this.catsService.findOne()` expects), or an exception is thrown before the route handler is called.

For example, suppose the route is called as follows:

```bash

GET localhost:3000/abc
```

Nest throws an exception, which produces the following response:

```json

{
  "statusCode": 400,
  "message": "Validation failed (numeric string is expected)",
  "error": "Bad Request"
}
```

The exception prevents the body of the `findOne()` method from executing.

In the example above, we pass a class (`ParseIntPipe`), not an instance. This leaves instantiation to the framework and enables dependency injection. As with guards and exception filters, you can instead pass an in-place instance, which is useful when you want to customize the built-in pipe's behavior by passing options:

```typescript

@Get(':id')
async findOne(
  @Param('id', new ParseIntPipe({ errorHttpStatusCode: HttpStatus.NOT_ACCEPTABLE }))
  id: number,
) {
  return this.catsService.findOne(id);
}
```

The other transformation pipes (all of the **Parse\*** pipes) are bound the same way. They work with route parameters, query string parameters, and request body values.

For example, with a query string parameter:

```typescript

@Get()
async findOne(@Query('id', ParseIntPipe) id: number) {
  return this.catsService.findOne(id);
}
```

The following example uses `ParseUUIDPipe` to verify that a string parameter is a UUID:

JS TS

```typescript

@Get(':uuid')
async findOne(@Param('uuid', new ParseUUIDPipe()) uuid: string) {
  return this.catsService.findOne(uuid);
}
```

```typescript

@Get(':uuid')
@Bind(Param('uuid', new ParseUUIDPipe()))
async findOne(uuid) {
  return this.catsService.findOne(uuid);
}
```

> **Hint** By default, `ParseUUIDPipe` accepts a UUID of any version (versions 1 through 8, Nil, and Max UUIDs). To require a specific version, pass the `version` option (`'1'`, `'2'`, `'3'`, `'4'`, `'5'`, `'6'`, `'7'`, or `'8'`). Starting with NestJS v12.1.2, the `version` option also accepts these versions as numbers (for example, `7`), and `'all'` to accept any version, the same as leaving `version` out. The `UUIDVersion` type describes these values and is exported from `@nestjs/common`.

Binding validation pipes works slightly differently; we cover it later in this chapter.

> **Hint** See [Validation techniques](/application/validation) for extensive examples of validation pipes.

#### Custom pipes[#](/pipes#custom-pipes)

As mentioned, you can build your own pipes. Although Nest provides robust built-in `ParseIntPipe` and `ValidationPipe` implementations, let's build simple versions of each from scratch to see how custom pipes are constructed.

We start with a simple `ValidationPipe`. Initially, it takes an input value and returns it unchanged, behaving like an identity function.

validation.pipe.ts

JS TS

```typescript

import { PipeTransform, Injectable, ArgumentMetadata } from '@nestjs/common';

@Injectable()
export class ValidationPipe implements PipeTransform {
  transform(value: any, metadata: ArgumentMetadata) {
    return value;
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';

@Injectable()
export class ValidationPipe {
  transform(value, metadata) {
    return value;
  }
}
```

> **Hint**`PipeTransform<T, R>` is a generic interface that every pipe must implement. `T` indicates the type of the input `value`, and `R` indicates the return type of the `transform()` method.

Every pipe must implement the `transform()` method to fulfill the `PipeTransform` interface contract. This method has two parameters:

* `value`
* `metadata`

The `value` parameter is the method argument currently being processed (before the route handler receives it), and `metadata` is that argument's metadata. The metadata object has the following properties:

```typescript

export interface ArgumentMetadata {
  type: 'body' | 'query' | 'param' | 'custom';
  metatype?: Type<unknown>;
  data?: string;
  schema?: StandardSchemaV1;
}
```

These properties describe the argument being processed:

|            |                                                                                                                                                                                        |
| ---------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `type`     | Indicates whether the argument is a body (`@Body()`), query (`@Query()`), param (`@Param()`), or custom parameter (see [custom decorators](/custom-decorators)).                       |
| `metatype` | The metatype of the argument, for example, `String`. The value is `undefined` if you omit the type declaration in the route handler signature or use vanilla JavaScript.               |
| `data`     | The string passed to the decorator, for example, `@Body('string')`. It's `undefined` if you don't pass a string to the decorator, as in `@Body()`.                                     |
| `schema`   | A Standard Schema compatible schema attached through parameter decorator options such as `@Body({ schema })` or `@Param('id', { schema })`. It's `undefined` if no schema is attached. |

> **Warning** TypeScript interfaces disappear during transpilation. If a method parameter's type is declared as an interface instead of a class, the `metatype` value is `Object`.

> **Hint** The built-in `StandardSchemaValidationPipe` uses the `schema` field to validate arguments with any Standard Schema compatible library. Arguments without a schema pass through unchanged.

#### Schema based validation[#](/pipes#schema-based-validation)

> **Hint** The following sections build validation pipes from scratch to show how pipes work. For schema-based validation in production, use the built-in `StandardSchemaValidationPipe` instead. It works with Zod, Valibot, ArkType, and any other [Standard Schema](https://standardschema.dev/) compatible library, and reads the schema you attach through the `schema` option of parameter decorators such as `@Body()` and `@Param()`. See [Schema-based validation](/application/validation#schema-based-validation) for details.

Let's make our validation pipe more useful. Consider the `create()` method of the `CatsController`: we want to ensure that the POST body object is valid before running the service method.

JS TS

```typescript

@Post()
async create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

```typescript

@Post()
async create(@Body() createCatDto) {
  this.catsService.create(createCatDto);
}
```

The `createCatDto` body parameter is of type `CreateCatDto`:

create-cat.dto.ts

JS TS

```typescript

export class CreateCatDto {
  name: string;
  age: number;
  breed: string;
}
```

Every request to the `create()` method must contain a valid body, so we need to validate the three members of the `createCatDto` object. We could do this inside the route handler, but that would break the **single responsibility principle** (SRP).

Another approach is to create a **validator class** and delegate the task to it. The disadvantage is that we would have to remember to call the validator at the beginning of each method.

What about validation middleware? This could work, but it's not possible to create **generic middleware** that can be used in every context across the application. Middleware is unaware of the **execution context**, including the handler that will be called and its parameters.

Pipes are designed for exactly this use case, so we will refine our validation pipe.

## Learn the right way!

* 80+ chapters
* 5+ hours of videos
* Official certificate
* Deep-dive sessions

[Explore official courses](https://courses.nestjs.com "Courses | NestJS - A node.js framework built on top of TypeScript")

#### Object schema validation[#](/pipes#object-schema-validation)

There are several ways to validate objects in a clean, [DRY](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself) way. One common approach is **schema-based** validation, which we use here.

The [Zod](https://zod.dev/) library lets you define schemas with a readable API. Let's build a validation pipe that uses Zod schemas.

Start by installing the required package:

```bash

$ npm install --save zod
```

The class below takes a schema as a constructor argument and calls `schema.parse()`, which validates the incoming argument against that schema.

As noted earlier, a **validation pipe** either returns the value or throws an exception. This pipe returns the value parsed by the schema, or throws a `BadRequestException` if validation fails.

The next section shows how to supply the appropriate schema for a given route handler using the `@UsePipes()` decorator. This makes the validation pipe reusable across contexts, which is what we set out to do.

JS TS

```typescript

import { PipeTransform, ArgumentMetadata, BadRequestException } from '@nestjs/common';
import { ZodType } from 'zod';

export class ZodValidationPipe implements PipeTransform {
  constructor(private schema: ZodType) {}

  transform(value: unknown, metadata: ArgumentMetadata) {
    try {
      const parsedValue = this.schema.parse(value);
      return parsedValue;
    } catch (error) {
      throw new BadRequestException('Validation failed');
    }
  }
}
```

```typescript

import { BadRequestException } from '@nestjs/common';

export class ZodValidationPipe {
  constructor(schema) {
    this.schema = schema;
  }

  transform(value, metadata) {
    try {
      const parsedValue = this.schema.parse(value);
      return parsedValue;
    } catch (error) {
      throw new BadRequestException('Validation failed');
    }
  }
}
```

#### Binding validation pipes[#](/pipes#binding-validation-pipes)

Earlier, we saw how to bind transformation pipes (such as `ParseIntPipe` and the rest of the `Parse*` pipes). Binding validation pipes is equally straightforward.

In this case, we want to bind the pipe at the method level. To use the `ZodValidationPipe` in our example, we need to:

1. Create an instance of the `ZodValidationPipe`
2. Pass the context-specific Zod schema to the pipe's constructor
3. Bind the pipe to the method

Here's an example Zod schema:

```typescript

import { z } from 'zod';

export const createCatSchema = z.object({
  name: z.string(),
  age: z.number(),
  breed: z.string(),
});

export type CreateCatDto = z.infer<typeof createCatSchema>;
```

Bind the pipe with the `@UsePipes()` decorator:

cats.controller.ts

JS TS

```typescript

@Post()
@UsePipes(new ZodValidationPipe(createCatSchema))
async create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

```typescript

@Post()
@Bind(Body())
@UsePipes(new ZodValidationPipe(createCatSchema))
async create(createCatDto) {
  this.catsService.create(createCatDto);
}
```

> **Hint** The `@UsePipes()` decorator is imported from the `@nestjs/common` package.

You can also bind the `ZodValidationPipe` to a specific parameter, alongside built-in pipes. The following example validates the `id` route parameter with `ParseIntPipe` and the request body with `ZodValidationPipe`:

```typescript

@Put('/:id')
async update(
  @Param('id', ParseIntPipe) id: number,
  @Body(new ZodValidationPipe(createCatSchema)) body: CreateCatDto
): Promise<void> {
  this.catsService.update(id, body);
}
```

> **Warning** The `zod` library requires the `strictNullChecks` compiler option to be enabled in your `tsconfig.json` file.

#### Class validator[#](/pipes#class-validator)

> **Warning** The techniques in this section require TypeScript and are not available if your app is written in vanilla JavaScript.

This section presents an alternative implementation of our validation technique.

Nest works well with the [class-validator](https://github.com/typestack/class-validator) library, which provides decorator-based validation. Decorator-based validation pairs well with Nest's **pipe** capabilities, because a pipe has access to the `metatype` of the processed argument. Before we start, install the required packages:

```bash

$ npm i --save class-validator class-transformer
```

Once these are installed, add a few decorators to the `CreateCatDto` class. This shows a significant advantage of the technique: the `CreateCatDto` class remains the single source of truth for the POST body object, so you don't need a separate validation class.

create-cat.dto.ts

JS TS

```typescript

import { IsString, IsInt } from 'class-validator';

export class CreateCatDto {
  @IsString()
  name: string;

  @IsInt()
  age: number;

  @IsString()
  breed: string;
}
```

> **Hint** Read more about class-validator decorators in the [class-validator documentation](https://github.com/typestack/class-validator#usage).

We can now create a `ValidationPipe` class that uses these decorators.

validation.pipe.ts

JS TS

```typescript

import { PipeTransform, Injectable, ArgumentMetadata, BadRequestException } from '@nestjs/common';
import { validate } from 'class-validator';
import { plainToInstance } from 'class-transformer';

@Injectable()
export class ValidationPipe implements PipeTransform<any> {
  async transform(value: any, { metatype }: ArgumentMetadata) {
    if (!metatype || !this.toValidate(metatype)) {
      return value;
    }
    const object = plainToInstance(metatype, value);
    const errors = await validate(object);
    if (errors.length > 0) {
      throw new BadRequestException('Validation failed');
    }
    return value;
  }

  private toValidate(metatype: Function): boolean {
    const types: Function[] = [String, Boolean, Number, Array, Object];
    return !types.includes(metatype);
  }
}
```

> **Hint** This pipe is intentionally basic. You don't have to build a generic validation pipe yourself: Nest provides a more capable `ValidationPipe` out of the box, described at the end of this section.

> **Notice** The code above uses the [class-transformer](https://github.com/typestack/class-transformer) library, which is made by the same author as the **class-validator** library, so the two work well together.

Let's go through this code. First, the `transform()` method is marked as `async`. This is possible because Nest supports both synchronous and **asynchronous** pipes. We make this method `async` because some class-validator validations [can be async](https://github.com/typestack/class-validator#custom-validation-classes) (they return promises).

Next, we use destructuring to extract the `metatype` field from the `ArgumentMetadata` object. This is shorthand for receiving the full `ArgumentMetadata` and then assigning the `metatype` variable in a separate statement.

The helper method `toValidate()` skips validation when the argument being processed is a native JavaScript type. Native types can't have validation decorators attached, so there's no reason to validate them.

Next, we use the class-transformer function `plainToInstance()` to transform the plain JavaScript argument object into a typed object so that we can apply validation. This is necessary because the incoming POST body, when deserialized from the network request, does **not have any type information** (this is how the underlying platform, such as Express, works). Because class-validator relies on the validation decorators defined on the DTO earlier, we transform the incoming body into an instance of the decorated class rather than validating a plain object.

Finally, because this is a **validation pipe**, it either returns the value unchanged or throws an exception.

The last step is to bind the `ValidationPipe`. Pipes can be parameter-scoped, method-scoped, controller-scoped, or global-scoped. Earlier, we bound the Zod-based validation pipe at the method level with `@UsePipes()`. In the example below, we bind the pipe instance to the route handler's `@Body()` decorator so that the pipe validates the POST body.

cats.controller.ts

JS TS

```typescript

@Post()
async create(
  @Body(new ValidationPipe()) createCatDto: CreateCatDto,
) {
  this.catsService.create(createCatDto);
}
```

Parameter-scoped pipes are useful when the validation logic concerns only one parameter.

#### Global scoped pipes[#](/pipes#global-scoped-pipes)

Because the `ValidationPipe` is designed to be as generic as possible, it is most useful as a **global-scoped** pipe, applied to every route handler across the entire application.

main.ts

JS TS

```typescript

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.useGlobalPipes(new ValidationPipe());
  await app.listen(process.env.PORT ?? 3000);
}
await bootstrap();
```

> **Notice** In a hybrid application, `useGlobalPipes()` doesn't set up pipes for connected microservices by default (see [Hybrid application](/faq/hybrid-application) to change this behavior). In a standard (non-hybrid) microservice application, `useGlobalPipes()` does mount the pipes globally.

Global pipes registered outside of any module (with `useGlobalPipes()`, as in the example above) cannot inject dependencies, because the binding happens outside the context of any module. To solve this, you can register a global pipe **directly from any module** using the following construction:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { APP_PIPE } from '@nestjs/core';

@Module({
  providers: [
    {
      provide: APP_PIPE,
      useClass: ValidationPipe,
    },
  ],
})
export class AppModule {}
```

> **Hint** When you use this approach to perform dependency injection for the pipe, the pipe is global regardless of the module in which you register it. Register it in the module where the pipe (`ValidationPipe` in the example above) is defined. `useClass` is not the only way to register a custom provider; learn more in [Custom providers](/fundamentals/custom-providers).

#### The built-in ValidationPipe[#](/pipes#the-built-in-validationpipe)

You don't have to build a generic validation pipe yourself: Nest provides `ValidationPipe` out of the box. The built-in `ValidationPipe` offers more options than the sample built in this chapter, which is kept basic to illustrate the mechanics of a custom pipe. For schema-based validation, Nest also provides the built-in `StandardSchemaValidationPipe`. See [Validation techniques](/application/validation) for full details and many examples.

#### Transformation use case[#](/pipes#transformation-use-case)

Validation isn't the only use case for custom pipes. As mentioned at the beginning of this chapter, a pipe can also **transform** input data to the desired format. This is possible because the value returned from the `transform()` method replaces the previous value of the argument.

When is this useful? Sometimes the data passed from the client needs to be changed (for example, converted from a string to an integer) before the route handler can process it. Some required fields may also be missing, and you may want to apply default values. **Transformation pipes** perform these functions by interposing a processing function between the client request and the route handler.

Here's a simple `ParseIntPipe` that parses a string into an integer. (As noted above, Nest has a more sophisticated built-in `ParseIntPipe`; this is a simple example of a custom transformation pipe.)

parse-int.pipe.ts

JS TS

```typescript

import { PipeTransform, Injectable, ArgumentMetadata, BadRequestException } from '@nestjs/common';

@Injectable()
export class ParseIntPipe implements PipeTransform<string, number> {
  transform(value: string, metadata: ArgumentMetadata): number {
    const val = parseInt(value, 10);
    if (isNaN(val)) {
      throw new BadRequestException('Validation failed');
    }
    return val;
  }
}
```

```typescript

import { Injectable, BadRequestException } from '@nestjs/common';

@Injectable()
export class ParseIntPipe {
  transform(value, metadata) {
    const val = parseInt(value, 10);
    if (isNaN(val)) {
      throw new BadRequestException('Validation failed');
    }
    return val;
  }
}
```

We can then bind this pipe to the selected parameter:

JS TS

```typescript

@Get(':id')
async findOne(@Param('id', new ParseIntPipe()) id) {
  return this.catsService.findOne(id);
}
```

```typescript

@Get(':id')
@Bind(Param('id', new ParseIntPipe()))
async findOne(id) {
  return this.catsService.findOne(id);
}
```

Another useful transformation is to look up an **existing user** entity in the database using an ID supplied in the request:

JS TS

```typescript

@Get(':id')
findOne(@Param('id', UserByIdPipe) userEntity: UserEntity) {
  return userEntity;
}
```

```typescript

@Get(':id')
@Bind(Param('id', UserByIdPipe))
findOne(userEntity) {
  return userEntity;
}
```

We leave the implementation of this pipe to the reader. Like all other transformation pipes, it receives an input value (an `id`) and returns an output value (a `UserEntity` object). This makes your code more declarative and [DRY](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself) by moving boilerplate out of the route handler and into a reusable pipe.

#### Providing defaults[#](/pipes#providing-defaults)

By default, `Parse*` pipes expect a parameter's value to be defined and throw an exception when they receive `null` or `undefined` (unless you set their `optional` option to `true`). To let an endpoint handle missing query string parameters, provide a default value that is applied before the `Parse*` pipes operate on it. The `DefaultValuePipe` serves this purpose. Instantiate a `DefaultValuePipe` in the `@Query()` decorator before the relevant `Parse*` pipe, as shown below:

JS TS

```typescript

@Get()
async findAll(
  @Query('activeOnly', new DefaultValuePipe(false), ParseBoolPipe) activeOnly: boolean,
  @Query('page', new DefaultValuePipe(0), ParseIntPipe) page: number,
) {
  return this.catsService.findAll({ activeOnly, page });
}
```

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/pipes.md)

----
url: https://docs.nestjs.com/graphql/extensions
----

[Skip to content](#content)

On this page

* [Extensions](https://docs.nestjs.com/graphql/extensions#extensions)
* [Adding custom metadata](https://docs.nestjs.com/graphql/extensions#adding-custom-metadata)
* [Using custom metadata](https://docs.nestjs.com/graphql/extensions#using-custom-metadata)

### Extensions

> **Warning** This chapter applies only to the code first approach.

Extensions are an **advanced, low-level feature** that lets you define arbitrary data in the types configuration. Attaching custom metadata to certain fields allows you to build more sophisticated, generic solutions. For example, with extensions, you can define the roles required to access particular fields. Your code can read these roles at runtime to determine whether the caller has sufficient permissions to retrieve a specific field.

#### Adding custom metadata[#](/graphql/extensions#adding-custom-metadata)

To attach custom metadata to a field, use the `@Extensions()` decorator exported from the `@nestjs/graphql` package:

```typescript

@Field()
@Extensions({ role: Role.ADMIN })
password: string;
```

In the example above, we assigned the value `Role.ADMIN` to the `role` metadata property. `Role` is a TypeScript enum that groups all the user roles available in our system.

In addition to fields, you can use the `@Extensions()` decorator at the class level and at the method level (e.g., on a query handler).

#### Using custom metadata[#](/graphql/extensions#using-custom-metadata)

The logic that uses the custom metadata can be as complex as needed. For example, you can create an interceptor that stores or logs events per method invocation, or a [field middleware](/graphql/field-middleware) that matches the roles required to retrieve a field against the caller's permissions (a field-level permissions system).

For illustration purposes, let's define a `checkRoleMiddleware` that compares a user's role (hardcoded here) with the role required to access a target field:

```typescript

export const checkRoleMiddleware: FieldMiddleware = async (
  ctx: MiddlewareContext,
  next: NextFn,
) => {
  const info = ctx.info!;
  const { extensions } = info.parentType.getFields()[info.fieldName];

  /**
   * In a real-world application, the "userRole" variable
   * should represent the caller's (user) role (e.g., read from "ctx.context").
   */
  const userRole = Role.USER;
  if (userRole !== extensions.role) {
    // or "return null" to hide the value instead
    throw new ForbiddenException(
      `User does not have sufficient permissions to access "${info.fieldName}" field.`,
    );
  }
  return next();
};
```

With this in place, register the middleware for the `password` field:

```typescript

@Field({ middleware: [checkRoleMiddleware] })
@Extensions({ role: Role.ADMIN })
password: string;
```

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/extensions.md)

----
url: https://docs.nestjs.com/microservices/exception-filters
----

[Skip to content](#content)

On this page

* [Exception filters](https://docs.nestjs.com/microservices/exception-filters#exception-filters)
* [Filters](https://docs.nestjs.com/microservices/exception-filters#filters)
* [Inheritance](https://docs.nestjs.com/microservices/exception-filters#inheritance)

### Exception filters

The only difference between the HTTP [exception filter](/exception-filters) layer and the corresponding microservices layer is that microservices should throw `RpcException` instead of `HttpException`.

```typescript

throw new RpcException('Invalid credentials.');
```

> **Hint** The `RpcException` class is imported from the `@nestjs/microservices` package.

Nest handles the thrown exception and returns an `error` object with the following structure:

```json

{
  "status": "error",
  "message": "Invalid credentials."
}
```

If you pass an object to the `RpcException` constructor instead of a string, Nest returns that object as is.

> **Warning** An event handler has no response stream. An error that a filter rethrows for an `@EventPattern()` handler never reaches the producer, so handle the error inside the filter.

#### Filters[#](/microservices/exception-filters#filters)

Microservice exception filters behave like HTTP exception filters, with one difference: the `catch()` method must return an `Observable`.

rpc-exception.filter.ts

JS TS

```typescript

import { Catch, RpcExceptionFilter, ArgumentsHost } from '@nestjs/common';
import { Observable, throwError } from 'rxjs';
import { RpcException } from '@nestjs/microservices';

@Catch(RpcException)
export class ExceptionFilter implements RpcExceptionFilter<RpcException> {
  catch(exception: RpcException, host: ArgumentsHost): Observable<any> {
    return throwError(() => exception.getError());
  }
}
```

```typescript

import { Catch } from '@nestjs/common';
import { throwError } from 'rxjs';
import { RpcException } from '@nestjs/microservices';

@Catch(RpcException)
export class ExceptionFilter {
  catch(exception, host) {
    return throwError(() => exception.getError());
  }
}
```

> **Warning** Global exception filters registered on the main HTTP application don't apply to microservices connected to a [hybrid application](/faq/hybrid-application) unless you set the `inheritAppConfig` option. See [sharing configuration](/faq/hybrid-application#sharing-configuration).

The following example uses a manually instantiated method-scoped filter. As with HTTP-based applications, you can also use controller-scoped filters (i.e., prefix the controller class with a `@UseFilters()` decorator).

JS TS

```typescript

@UseFilters(new ExceptionFilter())
@MessagePattern({ cmd: 'sum' })
accumulate(data: number[]): number {
  return (data || []).reduce((a, b) => a + b);
}
```

```typescript

@UseFilters(new ExceptionFilter())
@MessagePattern({ cmd: 'sum' })
accumulate(data) {
  return (data || []).reduce((a, b) => a + b);
}
```

#### Inheritance[#](/microservices/exception-filters#inheritance)

Typically, you'll create fully customized exception filters tailored to your application's requirements. In some cases, however, you may want to extend the **core exception filter** and override its behavior based on certain factors.

To delegate exception processing to the base filter, extend `BaseRpcExceptionFilter` and call the inherited `catch()` method.

JS TS

```typescript

import { Catch, ArgumentsHost } from '@nestjs/common';
import { BaseRpcExceptionFilter } from '@nestjs/microservices';

@Catch()
export class AllExceptionsFilter extends BaseRpcExceptionFilter {
  catch(exception: any, host: ArgumentsHost) {
    return super.catch(exception, host);
  }
}
```

```typescript

import { Catch } from '@nestjs/common';
import { BaseRpcExceptionFilter } from '@nestjs/microservices';

@Catch()
export class AllExceptionsFilter extends BaseRpcExceptionFilter {
  catch(exception, host) {
    return super.catch(exception, host);
  }
}
```

The above implementation is only a shell that demonstrates the approach. Your implementation of the extended exception filter would include your own **business logic** (e.g., handling various conditions).

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/microservices/exception-filters.md)

----
url: https://docs.nestjs.com/v9/microservices/pipes
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Pipes](https://docs.nestjs.com/v9/microservices/pipes#pipes)
* [Binding pipes](https://docs.nestjs.com/v9/microservices/pipes#binding-pipes)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/microservices/pipes.md "Suggest Edits")

### Pipes

There is no fundamental difference between [regular pipes](/v9/pipes) and microservices pipes. The only difference is that instead of throwing `HttpException`, you should use `RpcException`.

> **Hint** The `RpcException` class is exposed from `@nestjs/microservices` package.

#### Binding pipes[#](/microservices/pipes#binding-pipes)

The following example uses a manually instantiated method-scoped pipe. Just as with HTTP based applications, you can also use controller-scoped pipes (i.e., prefix the controller class with a `@UsePipes()` decorator).

JS TS

```typescript

@UsePipes(new ValidationPipe())
@MessagePattern({ cmd: 'sum' })
accumulate(data: number[]): number {
  return (data || []).reduce((a, b) => a + b);
}
```

```typescript

@UsePipes(new ValidationPipe())
@MessagePattern({ cmd: 'sum' })
accumulate(data) {
  return (data || []).reduce((a, b) => a + b);
}
```

----
url: https://docs.nestjs.com/v9/recipes/terminus
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Healthchecks (Terminus)](https://docs.nestjs.com/v9/recipes/terminus#healthchecks-terminus)
* [Getting started](https://docs.nestjs.com/v9/recipes/terminus#getting-started)
* [Setting up a Healthcheck](https://docs.nestjs.com/v9/recipes/terminus#setting-up-a-healthcheck)
* [HTTP Healthcheck](https://docs.nestjs.com/v9/recipes/terminus#http-healthcheck)
* [TypeOrm health indicator](https://docs.nestjs.com/v9/recipes/terminus#typeorm-health-indicator)
* [Disk health indicator](https://docs.nestjs.com/v9/recipes/terminus#disk-health-indicator)
* [Memory health indicator](https://docs.nestjs.com/v9/recipes/terminus#memory-health-indicator)
* [Custom health indicator](https://docs.nestjs.com/v9/recipes/terminus#custom-health-indicator)
* [Logging](https://docs.nestjs.com/v9/recipes/terminus#logging)
* [More examples](https://docs.nestjs.com/v9/recipes/terminus#more-examples)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/recipes/terminus.md "Suggest Edits")

### Healthchecks (Terminus)

Terminus integration provides you with **readiness/liveness** health checks. Healthchecks are crucial when it comes to complex backend setups. In a nutshell, a health check in the realm of web development usually consists of a special address, for example, `https://my-website.com/health/readiness`. A service or a component of your infrastructure (e.g., Kubernetes) checks this address continuously. Depending on the HTTP status code returned from a `GET` request to this address the service will take action when it receives an "unhealthy" response. Since the definition of "healthy" or "unhealthy" varies with the type of service you provide, the **Terminus** integration supports you with a set of **health indicators**.

As an example, if your web server uses MongoDB to store its data, it would be vital information whether MongoDB is still up and running. In that case, you can make use of the `MongooseHealthIndicator`. If configured correctly - more on that later - your health check address will return a healthy or unhealthy HTTP status code, depending on whether MongoDB is running.

#### Getting started[#](/recipes/terminus#getting-started)

To get started with `@nestjs/terminus` we need to install the required dependency.

```bash

$ npm install --save @nestjs/terminus
```

#### Setting up a Healthcheck[#](/recipes/terminus#setting-up-a-healthcheck)

A health check represents a summary of **health indicators**. A health indicator executes a check of a service, whether it is in a healthy or unhealthy state. A health check is positive if all the assigned health indicators are up and running. Because a lot of applications will need similar health indicators, [`@nestjs/terminus`](https://github.com/nestjs/terminus) provides a set of predefined indicators, such as:

* `HttpHealthIndicator`
* `TypeOrmHealthIndicator`
* `MongooseHealthIndicator`
* `SequelizeHealthIndicator`
* `MikroOrmHealthIndicator`
* `MicroserviceHealthIndicator`
* `GRPCHealthIndicator`
* `MemoryHealthIndicator`
* `DiskHealthIndicator`

To get started with our first health check, let's create the `HealthModule` and import the `TerminusModule` into it in its imports array.

> **Hint** To create the module using the [Nest CLI](/v9/recipes/terminus/cli/overview), simply execute the `$ nest g module health` command.

health.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { TerminusModule } from '@nestjs/terminus';

@Module({
  imports: [TerminusModule]
})
export class HealthModule {}
```

Our healthcheck(s) can be executed using a [controller](/v9/controllers), which can be easily set up using the [Nest CLI](/v9/recipes/terminus/cli/overview).

```bash

$ nest g controller health
```

> **Info** It is highly recommended to enable shutdown hooks in your application. Terminus integration makes use of this lifecycle event if enabled. Read more about shutdown hooks [here](fundamentals/lifecycle-events#application-shutdown).

#### HTTP Healthcheck[#](/recipes/terminus#http-healthcheck)

Once we have installed `@nestjs/terminus`, imported our `TerminusModule` and created a new controller, we are ready to create a health check.

The `HTTPHealthIndicator` requires the `@nestjs/axios` package so make sure to have it installed:

```bash

$ npm i --save @nestjs/axios axios
```

Now we can setup our `HealthController`:

health.controller.ts

JS TS

```typescript

import { Controller, Get } from '@nestjs/common';
import { HealthCheckService, HttpHealthIndicator, HealthCheck } from '@nestjs/terminus';

@Controller('health')
export class HealthController {
  constructor(
    private health: HealthCheckService,
    private http: HttpHealthIndicator,
  ) {}

  @Get()
  @HealthCheck()
  check() {
    return this.health.check([
      () => this.http.pingCheck('nestjs-docs', 'https://docs.nestjs.com'),
    ]);
  }
}
```

```typescript

import { Controller, Get } from '@nestjs/common';
import { HealthCheckService, HttpHealthIndicator, HealthCheck } from '@nestjs/terminus';

@Controller('health')
@Dependencies(HealthCheckService, HttpHealthIndicator)
export class HealthController {
  constructor(
    private health,
    private http,
  ) { }

  @Get()
  @HealthCheck()
  healthCheck() {
    return this.health.check([
      () => this.http.pingCheck('nestjs-docs', 'https://docs.nestjs.com'),
    ])
  }
}
```

health.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { TerminusModule } from '@nestjs/terminus';
import { HttpModule } from '@nestjs/axios';
import { HealthController } from './health.controller';

@Module({
  imports: [TerminusModule, HttpModule],
  controllers: [HealthController],
})
export class HealthModule {}
```

```typescript

import { Module } from '@nestjs/common';
import { TerminusModule } from '@nestjs/terminus';
import { HttpModule } from '@nestjs/axios';
import { HealthController } from './health.controller';

@Module({
  imports: [TerminusModule, HttpModule],
  controllers: [HealthController],
})
export class HealthModule {}
```

Our health check will now send a *GET*-request to the `https://docs.nestjs.com` address. If we get a healthy response from that address, our route at `http://localhost:3000/health` will return the following object with a 200 status code.

```json

{
  "status": "ok",
  "info": {
    "nestjs-docs": {
      "status": "up"
    }
  },
  "error": {},
  "details": {
    "nestjs-docs": {
      "status": "up"
    }
  }
}
```

The interface of this response object can be accessed from the `@nestjs/terminus` package with the `HealthCheckResult` interface.

| `status`  | If any health indicator failed the status will be `'error'`. If the NestJS app is shutting down but still accepting HTTP requests, the health check will have the `'shutting_down'` status. | `'error' \| 'ok' \| 'shutting_down'` |
| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------ |
| `info`    | Object containing information of each health indicator which is of status `'up'`, or in other words "healthy".                                                                              | `object`                             |
| `error`   | Object containing information of each health indicator which is of status `'down'`, or in other words "unhealthy".                                                                          | `object`                             |
| `details` | Object containing all information of each health indicator                                                                                                                                  | `object`                             |

##### Check for specific HTTP response codes

In certain cases, you might want to check for specific criteria and validate the response. As an example, let's assume `https://my-external-service.com` returns a response code `204`. With `HttpHealthIndicator.responseCheck` you can check for that response code specifically and determine all other codes as unhealthy.

In case any other response code other than `204` gets returned, the following example would be unhealthy. The third parameter requires you to provide a function (sync or async) which returns a boolean whether the response is considered healthy (`true`) or unhealthy (`false`).

health.controller.ts

JS TS

```typescript

// Within the `HealthController`-class

@Get()
@HealthCheck()
check() {
  return this.health.check([
    () =>
      this.http.responseCheck(
        'my-external-service',
        'https://my-external-service.com',
        (res) => res.status === 204,
      ),
  ]);
}
```

#### TypeOrm health indicator[#](/recipes/terminus#typeorm-health-indicator)

Terminus offers the capability to add database checks to your health check. In order to get started with this health indicator, you should check out the [Database chapter](/v9/techniques/sql) and make sure your database connection within your application is established.

> **Hint** Behind the scenes the `TypeOrmHealthIndicator` simply executes a `SELECT 1`-SQL command which is often used to verify whether the database still alive. In case you are using an Oracle database it uses `SELECT 1 FROM DUAL`.

health.controller.ts

JS TS

```typescript

@Controller('health')
export class HealthController {
  constructor(
    private health: HealthCheckService,
    private db: TypeOrmHealthIndicator,
  ) {}

  @Get()
  @HealthCheck()
  check() {
    return this.health.check([
      () => this.db.pingCheck('database'),
    ]);
  }
}
```

```typescript

@Controller('health')
@Dependencies(HealthCheckService, TypeOrmHealthIndicator)
export class HealthController {
  constructor(
    private health,
    private db,
  ) { }

  @Get()
  @HealthCheck()
  healthCheck() {
    return this.health.check([
      () => this.db.pingCheck('database'),
    ])
  }
}
```

If your database is reachable, you should now see the following JSON-result when requesting `http://localhost:3000` with a `GET` request:

```json

{
  "status": "ok",
  "info": {
    "database": {
      "status": "up"
    }
  },
  "error": {},
  "details": {
    "database": {
      "status": "up"
    }
  }
}
```

In case your app uses [multiple databases](techniques/database#multiple-databases), you need to inject each connection into your `HealthController`. Then, you can simply pass the connection reference to the `TypeOrmHealthIndicator`.

health.controller.ts

JS TS

```typescript

@Controller('health')
export class HealthController {
  constructor(
    private health: HealthCheckService,
    private db: TypeOrmHealthIndicator,
    @InjectConnection('albumsConnection')
    private albumsConnection: Connection,
    @InjectConnection()
    private defaultConnection: Connection,
  ) {}

  @Get()
  @HealthCheck()
  check() {
    return this.health.check([
      () => this.db.pingCheck('albums-database', { connection: this.albumsConnection }),
      () => this.db.pingCheck('database', { connection: this.defaultConnection }),
    ]);
  }
}
```

#### Disk health indicator[#](/recipes/terminus#disk-health-indicator)

With the `DiskHealthIndicator` we can check how much storage is in use. To get started, make sure to inject the `DiskHealthIndicator` into your `HealthController`. The following example checks the storage used of the path `/` (or on Windows you can use `C:\\`). If that exceeds more than 50% of the total storage space it would response with an unhealthy Health Check.

health.controller.ts

JS TS

```typescript

@Controller('health')
export class HealthController {
  constructor(
    private readonly health: HealthCheckService,
    private readonly disk: DiskHealthIndicator,
  ) {}

  @Get()
  @HealthCheck()
  check() {
    return this.health.check([
      () => this.disk.checkStorage('storage', { path: '/', thresholdPercent: 0.5 }),
    ]);
  }
}
```

```typescript

@Controller('health')
@Dependencies(HealthCheckService, DiskHealthIndicator)
export class HealthController {
  constructor(health, disk) {}

  @Get()
  @HealthCheck()
  healthCheck() {
    return this.health.check([
      () => this.disk.checkStorage('storage', { path: '/', thresholdPercent: 0.5 }),
    ])
  }
}
```

With the `DiskHealthIndicator.checkStorage` function you also have the possibility to check for a fixed amount of space. The following example would be unhealthy in case the path `/my-app/` would exceed 250GB.

health.controller.ts

JS TS

```typescript

// Within the `HealthController`-class

@Get()
@HealthCheck()
check() {
  return this.health.check([
    () => this.disk.checkStorage('storage', {  path: '/', threshold: 250 * 1024 * 1024 * 1024, })
  ]);
}
```

#### Memory health indicator[#](/recipes/terminus#memory-health-indicator)

To make sure your process does not exceed a certain memory limit the `MemoryHealthIndicator` can be used. The following example can be used to check the heap of your process.

> **Hint** Heap is the portion of memory where dynamically allocated memory resides (i.e. memory allocated via malloc). Memory allocated from the heap will remain allocated until one of the following occurs:
>
> * The memory is *free*'d
> * The program terminates

health.controller.ts

JS TS

```typescript

@Controller('health')
export class HealthController {
  constructor(
    private health: HealthCheckService,
    private memory: MemoryHealthIndicator,
  ) {}

  @Get()
  @HealthCheck()
  check() {
    return this.health.check([
      () => this.memory.checkHeap('memory_heap', 150 * 1024 * 1024),
    ]);
  }
}
```

```typescript

@Controller('health')
@Dependencies(HealthCheckService, MemoryHealthIndicator)
export class HealthController {
  constructor(health, memory) {}

  @Get()
  @HealthCheck()
  healthCheck() {
    return this.health.check([
      () => this.memory.checkHeap('memory_heap', 150 * 1024 * 1024),
    ])
  }
}
```

It is also possible to verify the memory RSS of your process with `MemoryHealthIndicator.checkRSS`. This example would return an unhealthy response code in case your process does have more than 150MB allocated.

> **Hint** RSS is the Resident Set Size and is used to show how much memory is allocated to that process and is in RAM. It does not include memory that is swapped out. It does include memory from shared libraries as long as the pages from those libraries are actually in memory. It does include all stack and heap memory.

health.controller.ts

JS TS

```typescript

// Within the `HealthController`-class

@Get()
@HealthCheck()
check() {
  return this.health.check([
    () => this.memory.checkRSS('memory_rss', 150 * 1024 * 1024),
  ]);
}
```

#### Custom health indicator[#](/recipes/terminus#custom-health-indicator)

In some cases, the predefined health indicators provided by `@nestjs/terminus` do not cover all of your health check requirements. In that case, you can set up a custom health indicator according to your needs.

Let's get started by creating a service that will represent our custom indicator. To get a basic understanding of how an indicator is structured, we will create an example `DogHealthIndicator`. This service should have the state `'up'` if every `Dog` object has the type `'goodboy'`. If that condition is not satisfied then it should throw an error.

dog.health.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { HealthIndicator, HealthIndicatorResult, HealthCheckError } from '@nestjs/terminus';

export interface Dog {
  name: string;
  type: string;
}

@Injectable()
export class DogHealthIndicator extends HealthIndicator {
  private dogs: Dog[] = [
    { name: 'Fido', type: 'goodboy' },
    { name: 'Rex', type: 'badboy' },
  ];

  async isHealthy(key: string): Promise<HealthIndicatorResult> {
    const badboys = this.dogs.filter(dog => dog.type === 'badboy');
    const isHealthy = badboys.length === 0;
    const result = this.getStatus(key, isHealthy, { badboys: badboys.length });

    if (isHealthy) {
      return result;
    }
    throw new HealthCheckError('Dogcheck failed', result);
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';
import { HealthCheckError } from '@godaddy/terminus';

@Injectable()
export class DogHealthIndicator extends HealthIndicator {
  dogs = [
    { name: 'Fido', type: 'goodboy' },
    { name: 'Rex', type: 'badboy' },
  ];

  async isHealthy(key) {
    const badboys = this.dogs.filter(dog => dog.type === 'badboy');
    const isHealthy = badboys.length === 0;
    const result = this.getStatus(key, isHealthy, { badboys: badboys.length });

    if (isHealthy) {
      return result;
    }
    throw new HealthCheckError('Dogcheck failed', result);
  }
}
```

The next thing we need to do is register the health indicator as a provider.

health.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { TerminusModule } from '@nestjs/terminus';
import { DogHealthIndicator } from './dog.health';

@Module({
  controllers: [HealthController],
  imports: [TerminusModule],
  providers: [DogHealthIndicator]
})
export class HealthModule { }
```

> **Hint** In a real-world application the `DogHealthIndicator` should be provided in a separate module, for example, `DogModule`, which then will be imported by the `HealthModule`.

The last required step is to add the now available health indicator in the required health check endpoint. For that, we go back to our `HealthController` and add it to our `check` function.

health.controller.ts

JS TS

```typescript

import { HealthCheckService, HealthCheck } from '@nestjs/terminus';
import { Injectable, Get } from '@nestjs/common';
import { DogHealthIndicator } from './dog.health';

@Injectable()
export class HealthController {
  constructor(
    private health: HealthCheckService,
    private dogHealthIndicator: DogHealthIndicator
  ) {}

  @Get()
  @HealthCheck()
  healthCheck() {
    return this.health.check([
      () => this.dogHealthIndicator.isHealthy('dog'),
    ])
  }
}
```

```typescript

import { HealthCheckService, HealthCheck } from '@nestjs/terminus';
import { Injectable, Get } from '@nestjs/common';
import { DogHealthIndicator } from './dog.health';

@Injectable()
@Dependencies(HealthCheckService, DogHealthIndicator)
export class HealthController {
  constructor(
    private health,
    private dogHealthIndicator
  ) {}

  @Get()
  @HealthCheck()
  healthCheck() {
    return this.health.check([
      () => this.dogHealthIndicator.isHealthy('dog'),
    ])
  }
}
```

#### Logging[#](/recipes/terminus#logging)

Terminus only logs error messages, for instance when a Healthcheck has failed. With the `TerminusModule.forRoot()` method you have more control over how errors are being logged as well as completely take over the logging itself.

In this section, we are going to walk you through how you create a custom logger `TerminusLogger`. This logger extends the built-in logger. Therefore you can pick and choose which part of the logger you would like to overwrite

> **Info** If you want to learn more about custom loggers in NestJS, [read more here](/techniques/logger#injecting-a-custom-logger).

terminus-logger.service.ts

JS TS

```typescript

import { Injectable, Scope, ConsoleLogger } from '@nestjs/common';

@Injectable({ scope: Scope.TRANSIENT })
export class TerminusLogger extends ConsoleLogger {
  error(message: any, stack?: string, context?: string): void;
  error(message: any, ...optionalParams: any[]): void;
  error(
    message: unknown,
    stack?: unknown,
    context?: unknown,
    ...rest: unknown[]
  ): void {
    // Overwrite here how error messages should be logged
  }
}
```

Once you have created your custom logger, all you need to do is simply pass it into the `TerminusModule.forRoot()` as such.

health.module.ts

JS TS

```typescript

@Module({
imports: [
  TerminusModule.forRoot({
    logger: TerminusLogger,
  }),
],
})
export class HealthModule {}
```

To completely suppress any log messages coming from Terminus, including error messages, configure Terminus as such.

health.module.ts

JS TS

```typescript

@Module({
imports: [
  TerminusModule.forRoot({
    logger: false,
  }),
],
})
export class HealthModule {}
```

Terminus allows you to configure how Healthcheck errors should be displayed in your logs.

| Error Log Style  | Description                                                                                                                        | Example |
| :--------------- | :--------------------------------------------------------------------------------------------------------------------------------- | :------ |
| `json` (default) | Prints a summary of the health check result in case of an error as JSON object                                                     |         |
| `pretty`         | Prints a summary of the health check result in case of an error within formatted boxes and highlights successful/erroneous results |         |

You can change the log style using the `errorLogStyle` configuration option as in the following snippet.

health.module.ts

JS TS

```typescript

@Module({
  imports: [
    TerminusModule.forRoot({
      errorLogStyle: 'pretty',
    }),
  ]
})
export class HealthModule {}
```

#### More examples[#](/recipes/terminus#more-examples)

More working examples are available [here](https://github.com/nestjs/terminus/tree/master/sample).

----
url: https://docs.nestjs.com/faq/request-lifecycle
----

[Skip to content](#content)

On this page

* [Request lifecycle](https://docs.nestjs.com/faq/request-lifecycle#request-lifecycle)
* [Middleware](https://docs.nestjs.com/faq/request-lifecycle#middleware)
* [Guards](https://docs.nestjs.com/faq/request-lifecycle#guards)
* [Interceptors](https://docs.nestjs.com/faq/request-lifecycle#interceptors)
* [Pipes](https://docs.nestjs.com/faq/request-lifecycle#pipes)
* [Filters](https://docs.nestjs.com/faq/request-lifecycle#filters)
* [Summary](https://docs.nestjs.com/faq/request-lifecycle#summary)

### Request lifecycle

Nest applications handle requests and produce responses in a sequence called the **request lifecycle**. With middleware, pipes, guards, and interceptors in play, it can be challenging to track down where a particular piece of code runs during the request lifecycle, especially when global, controller-level, and route-level components are combined. In general, a request flows through middleware, then guards, then interceptors, then pipes, and finally back through interceptors on the return path (as the response is generated).

#### Middleware[#](/faq/request-lifecycle#middleware)

Middleware runs in a specific sequence. First, Nest runs globally bound middleware (such as middleware bound with `app.use()`), and then it runs [module-bound middleware](/middleware), which is matched by path. Middleware runs sequentially in the order it is bound, just like middleware in Express. For middleware bound in different modules, middleware from global modules (decorated with `@Global()`) runs first, then middleware bound in the root module, followed by middleware from the other modules, ordered by their distance from the root module in the import graph.

#### Guards[#](/faq/request-lifecycle#guards)

Guard execution starts with global guards, proceeds to controller guards, and ends with route guards. As with middleware, guards run in the order in which they are bound. For example:

```typescript

@UseGuards(Guard1, Guard2)
@Controller('cats')
export class CatsController {
  constructor(private catsService: CatsService) {}

  @UseGuards(Guard3)
  @Get()
  getCats(): Cats[] {
    return this.catsService.getCats();
  }
}
```

`Guard1` will execute before `Guard2` and both will execute before `Guard3`.

> **Hint** "Global", "controller", and "route" refer to where the guard (or other component) is bound. A component registered with `app.useGlobalGuards()` (or a similar method), or provided through a module with the `APP_GUARD` token (or a similar token), is globally bound. Otherwise, it is bound to a controller if the decorator precedes a controller class, or to a route if the decorator precedes a route handler.

#### Interceptors[#](/faq/request-lifecycle#interceptors)

Interceptors mostly follow the same pattern as guards, with one difference: because interceptors return [RxJS Observables](https://github.com/ReactiveX/rxjs), the observables are resolved in a first-in, last-out manner. Inbound requests go through the standard global, controller, route order, but the response side (i.e., after the route handler returns) is resolved from route to controller to global. Also, any errors thrown by pipes, controllers, or services can be read in an interceptor's `catchError` operator.

#### Pipes[#](/faq/request-lifecycle#pipes)

Pipes follow the standard global, controller, route sequence, and pipes passed to `@UsePipes()` run first in, first out. However, at the route parameter level, when several parameters have pipes, the pipes process the last parameter first and the first parameter last. This also applies to route-level and controller-level pipes. For example, consider the following controller:

```typescript

@UsePipes(GeneralValidationPipe)
@Controller('cats')
export class CatsController {
  constructor(private catsService: CatsService) {}

  @UsePipes(RouteSpecificPipe)
  @Patch(':id')
  updateCat(
    @Body() body: UpdateCatDTO,
    @Param() params: UpdateCatParams,
    @Query() query: UpdateCatQuery,
  ) {
    return this.catsService.updateCat(body, params, query);
  }
}
```

Here, the `GeneralValidationPipe` runs for the `query`, then the `params`, and then the `body` objects before moving on to the `RouteSpecificPipe`, which follows the same order. Any parameter-specific pipes would run (again, from the last parameter to the first) after the controller-level and route-level pipes.

#### Filters[#](/faq/request-lifecycle#filters)

Filters are the only component that don't resolve global first. Instead, filters resolve from the lowest level possible: Nest checks route-bound filters first, then controller-level filters, and finally global filters. Exceptions can't be passed from filter to filter; if a route-level filter catches the exception, a controller-level or global filter can't catch the same exception. To achieve a similar effect, use inheritance between the filters.

> **Hint** Filters run only when an uncaught exception occurs during request processing. Exceptions you catch yourself (e.g., with `try/catch`) don't trigger exception filters. As soon as an uncaught exception is encountered, the rest of the lifecycle is skipped and the request goes straight to the filter. Exceptions thrown from [middleware](/middleware#error-handling) are handled by the exceptions layer as well, but only **global** exception filters apply, because middleware runs before a route handler is selected.

#### Summary[#](/faq/request-lifecycle#summary)

In general, the request lifecycle looks like this:

1. Incoming request

2. Middleware

   * 2.1. Globally bound middleware
   * 2.2. Module bound middleware

3. Guards

   * 3.1 Global guards
   * 3.2 Controller guards
   * 3.3 Route guards

4. Interceptors (pre-controller)

   * 4.1 Global interceptors
   * 4.2 Controller interceptors
   * 4.3 Route interceptors

5. Pipes

   * 5.1 Global pipes
   * 5.2 Controller pipes
   * 5.3 Route pipes
   * 5.4 Route parameter pipes

6. Controller (method handler)

7. Service (if exists)

8. Interceptors (post-request)

   * 8.1 Route interceptors
   * 8.2 Controller interceptors
   * 8.3 Global interceptors

9. Exception filters

   * 9.1 Route filters
   * 9.2 Controller filters
   * 9.3 Global filters

10. Server response

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/faq/request-lifecycle.md)

----
url: https://docs.nestjs.com/v6/microservices/rabbitmq
----

* [RabbitMQ](https://docs.nestjs.com/v6/microservices/rabbitmq#rabbitmq)
* [Installation](https://docs.nestjs.com/v6/microservices/rabbitmq#installation)
* [Overview](https://docs.nestjs.com/v6/microservices/rabbitmq#overview)
* [Options](https://docs.nestjs.com/v6/microservices/rabbitmq#options)
* [Client](https://docs.nestjs.com/v6/microservices/rabbitmq#client)
* [Context](https://docs.nestjs.com/v6/microservices/rabbitmq#context)
* [Message acknowledgement](https://docs.nestjs.com/v6/microservices/rabbitmq#message-acknowledgement)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/microservices/rabbitmq.md "Suggest Edits")

### RabbitMQ

[RabbitMQ](https://www.rabbitmq.com/) is an open-source and lightweight message broker which supports multiple messaging protocols. It can be deployed in distributed and federated configurations to meet high-scale, high-availability requirements. In addition, it's the most widely deployed message broker, used worldwide at small startups and large enterprises.

#### Installation[#](/microservices/rabbitmq#installation)

To start building RabbitMQ-based microservices, first install the required packages:

```bash

$ npm i --save amqplib amqp-connection-manager
```

#### Overview[#](/microservices/rabbitmq#overview)

To use the RabbitMQ transporter, pass the following options object to the `createMicroservice()` method:

main.ts

JS TS

```typescript

const app = await NestFactory.createMicroservice(ApplicationModule, {
  transport: Transport.RMQ,
  options: {
    urls: ['amqp://localhost:5672'],
    queue: 'cats_queue',
    queueOptions: {
      durable: false
    },
  },
});
```

> **Hint** The `Transport` enum is imported from the `@nestjs/microservices` package.

#### Options[#](/microservices/rabbitmq#options)

The `options` property is specific to the chosen transporter. The **RabbitMQ** transporter exposes the properties described below.

|                         |                                                                                                                      |
| ----------------------- | -------------------------------------------------------------------------------------------------------------------- |
| `urls`                  | Connection urls                                                                                                      |
| `queue`                 | Queue name which your server will listen to                                                                          |
| `prefetchCount`         | Sets the prefetch count for the channel                                                                              |
| `isGlobalPrefetchCount` | Enables per channel prefetching                                                                                      |
| `noAck`                 | If `false`, manual acknowledgment mode enabled                                                                       |
| `queueOptions`          | Additional queue options (read more [here](https://www.squaremobius.net/amqp.node/channel_api.html#assertQueue))     |
| `socketOptions`         | Additional socket options (read more [here](https://www.squaremobius.net/amqp.node/channel_api.html#socket-options)) |

#### Client[#](/microservices/rabbitmq#client)

Like other microservice transporters, you have [several options](https://docs.nestjs.com/microservices/basics#client) for creating a RabbitMQ `ClientProxy` instance.

One method for creating an instance is to use use the `ClientsModule`. To create a client instance with the `ClientsModule`, import it and use the `register()` method to pass an options object with the same properties shown above in the `createMicroservice()` method, as well as a `name` property to be used as the injection token. Read more about `ClientsModule`[here](https://docs.nestjs.com/microservices/basics#client).

```typescript

@Module({
  imports: [
    ClientsModule.register([
      {
        name: 'MATH_SERVICE',
        transport: Transport.RMQ,
        options: {
          urls: ['amqp://localhost:5672'],
          queue: 'cats_queue',
          queueOptions: {
            durable: false
          },
        },
      },
    ]),
  ]
  ...
})
```

Other options to create a client (either `ClientProxyFactory` or `@Client()`) can be used as well. You can read about them [here](https://docs.nestjs.com/microservices/basics#client).

#### Context[#](/microservices/rabbitmq#context)

In more sophisticated scenarios, you may want to access more information about the incoming request. When using the RabbitMQ transporter, you can access the `RmqContext` object.

JS TS

```typescript

@MessagePattern('notifications')
getNotifications(@Payload() data: number[], @Ctx() context: RmqContext) {
  console.log(`Pattern: ${context.getPattern()}`);
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('notifications')
getNotifications(data, context) {
  console.log(`Pattern: ${context.getPattern()}`);
}
```

> **Hint**`@Payload()`, `@Ctx()` and `RmqContext` are imported from the `@nestjs/microservices` package.

To access the original RabbitMQ message (with the `properties`, `fields`, and `content`), use the `getMessage()` method of the `RmqContext` object, as follows:

JS TS

```typescript

@MessagePattern('notifications')
getNotifications(@Payload() data: number[], @Ctx() context: RmqContext) {
  console.log(context.getMessage());
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('notifications')
getNotifications(data, context) {
  console.log(context.getMessage());
}
```

To retrieve a reference to the RabbitMQ [channel](https://www.rabbitmq.com/channels.html), use the `getChannelRef` method of the `RmqContext` object, as follows:

JS TS

```typescript

@MessagePattern('notifications')
getNotifications(@Payload() data: number[], @Ctx() context: RmqContext) {
  console.log(context.getChannelRef());
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('notifications')
getNotifications(data, context) {
  console.log(context.getChannelRef());
}
```

#### Message acknowledgement[#](/microservices/rabbitmq#message-acknowledgement)

To make sure a message is never lost, RabbitMQ supports [message acknowledgements](https://www.rabbitmq.com/confirms.html). An acknowledgement is sent back by the consumer to tell RabbitMQ that a particular message has been received, processed and that RabbitMQ is free to delete it. If a consumer dies (its channel is closed, connection is closed, or TCP connection is lost) without sending an ack, RabbitMQ will understand that a message wasn't processed fully and will re-queue it.

To enable manual acknowledgment mode, set the `noAck` property to `false`:

```typescript

options: {
  urls: ['amqp://localhost:5672'],
  queue: 'cats_queue',
  noAck: false,
  queueOptions: {
    durable: false
  },
},
```

When manual consumer acknowledgements are turned on, we must send a proper acknowledgement from the worker to signal that we are done with a task.

JS TS

```typescript

@MessagePattern('notifications')
getNotifications(@Payload() data: number[], @Ctx() context: RmqContext) {
  const channel = context.getChannelRef();
  const originalMsg = context.getMessage();

  channel.ack(originalMsg);
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('notifications')
getNotifications(data, context) {
  const channel = context.getChannelRef();
  const originalMsg = context.getMessage();

  channel.ack(originalMsg);
}
```

----
url: https://docs.nestjs.com/microservices/nats
----

[Skip to content](#content)

On this page

* [NATS](https://docs.nestjs.com/microservices/nats#nats)
* [Installation](https://docs.nestjs.com/microservices/nats#installation)
* [Overview](https://docs.nestjs.com/microservices/nats#overview)
* [Options](https://docs.nestjs.com/microservices/nats#options)
* [Client](https://docs.nestjs.com/microservices/nats#client)
* [Request-response](https://docs.nestjs.com/microservices/nats#request-response)
* [Event-based](https://docs.nestjs.com/microservices/nats#event-based)
* [Queue groups](https://docs.nestjs.com/microservices/nats#queue-groups)
* [Context](https://docs.nestjs.com/microservices/nats#context)
* [Wildcards](https://docs.nestjs.com/microservices/nats#wildcards)
* [Record builders](https://docs.nestjs.com/microservices/nats#record-builders)
* [Custom serializers and deserializers](https://docs.nestjs.com/microservices/nats#custom-serializers-and-deserializers)
* [Instance status updates](https://docs.nestjs.com/microservices/nats#instance-status-updates)
* [Listening to NATS events](https://docs.nestjs.com/microservices/nats#listening-to-nats-events)
* [Underlying driver access](https://docs.nestjs.com/microservices/nats#underlying-driver-access)

### NATS

[NATS](https://nats.io) is a simple, secure, and high-performance open source messaging system for cloud native applications, IoT messaging, and microservices architectures. The NATS server is written in Go, and client libraries are available for dozens of major programming languages. NATS supports both **At Most Once** and **At Least Once** delivery. It runs anywhere, from large servers and cloud instances to edge gateways and Internet of Things devices.

#### Installation[#](/microservices/nats#installation)

To start building NATS-based microservices, first install the required package:

```bash

$ npm i --save @nats-io/transport-node
```

> **Warning** As of NestJS v12, the NATS transporter targets **NATS v3** and uses the `@nats-io/transport-node` driver. If you are upgrading from an earlier version, uninstall the legacy `nats` package (`npm uninstall nats`) and install `@nats-io/transport-node` instead. See the [migration guide](/migration-guide#nats-v3) for details.

#### Overview[#](/microservices/nats#overview)

To use the NATS transporter, pass the following options object to the `createMicroservice()` method:

main.ts

JS TS

```typescript

const app = await NestFactory.createMicroservice<MicroserviceOptions>(AppModule, {
  transport: Transport.NATS,
  options: {
    servers: ['nats://localhost:4222'],
  },
});
```

```typescript

const app = await NestFactory.createMicroservice(AppModule, {
  transport: Transport.NATS,
  options: {
    servers: ['nats://localhost:4222'],
  },
});
```

> **Hint** The `Transport` enum is imported from the `@nestjs/microservices` package.

#### Options[#](/microservices/nats#options)

The `options` object is specific to the chosen transporter. The **NATS** transporter exposes the [NATS connection options](https://github.com/nats-io/nats.js/blob/main/core/README.md#connecting-to-a-nats-server), as well as the following properties:

|                    |                                                                                                                                                                           |
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `queue`            | Queue group that your server subscribes with (leave `undefined` to ignore this setting). Read more about NATS queue groups [below](/microservices/nats#queue-groups).     |
| `gracefulShutdown` | Enables graceful shutdown. When enabled, the server first unsubscribes from all subjects, then waits for `gracePeriod` before closing the connection. Default is `false`. |
| `gracePeriod`      | Time in milliseconds to wait after unsubscribing from all subjects when `gracefulShutdown` is enabled. Default is `10000` ms.                                             |
| `headers`          | Headers added to every message a client sends (see [record builders](/microservices/nats#record-builders)).                                                               |

#### Client[#](/microservices/nats#client)

As with other microservice transporters, you have [several options](/microservices/basics#client-producer-class) for creating a NATS `ClientProxy` instance.

One way to create an instance is to use the `ClientsModule`. Import it and use its `register()` method to pass an options object with the same properties shown above for the `createMicroservice()` method, plus a `name` property to use as the injection token. Read more about the `ClientsModule` in the [client section of the overview](/microservices/basics#client-producer-class).

```typescript

@Module({
  imports: [
    ClientsModule.register([
      {
        name: 'MATH_SERVICE',
        transport: Transport.NATS,
        options: {
          servers: ['nats://localhost:4222'],
        }
      },
    ]),
  ]
  ...
})
```

You can also create a client with `ClientProxyFactory` or the `@Client()` decorator. Both are described in the [client section of the overview](/microservices/basics#client-producer-class).

#### Request-response[#](/microservices/nats#request-response)

For the [request-response](/microservices/basics#request-response) message style, the NATS transporter doesn't use the built-in NATS [Request-Reply](https://docs.nats.io/nats-concepts/reqreply) API. Instead, the client publishes a "request" on a given subject with the `publish()` method and a unique reply subject name. Responders listen on that subject and send responses to the reply subject. Reply subjects are routed back to the requester dynamically, regardless of the location of either party.

#### Event-based[#](/microservices/nats#event-based)

For the [event-based](/microservices/basics#event-based) message style, the NATS transporter uses the built-in NATS [Publish-Subscribe](https://docs.nats.io/nats-concepts/pubsub) mechanism. A publisher sends a message on a subject, and every active subscriber listening on that subject receives the message. Subscribers can also register interest in [wildcard](/microservices/nats#wildcards) subjects. This one-to-many pattern is sometimes called fan-out.

#### Queue groups[#](/microservices/nats#queue-groups)

NATS provides a built-in load balancing feature called [distributed queues](https://docs.nats.io/nats-concepts/queue). To create a queue subscription, use the `queue` property as follows:

main.ts

JS TS

```typescript

const app = await NestFactory.createMicroservice<MicroserviceOptions>(AppModule, {
  transport: Transport.NATS,
  options: {
    servers: ['nats://localhost:4222'],
    queue: 'cats_queue',
  },
});
```

#### Context[#](/microservices/nats#context)

In more complex scenarios, you may need additional information about the incoming request. With the NATS transporter, you can access the `NatsContext` object.

JS TS

```typescript

@MessagePattern('notifications')
getNotifications(@Payload() data: number[], @Ctx() context: NatsContext) {
  console.log(`Subject: ${context.getSubject()}`);
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('notifications')
getNotifications(data, context) {
  console.log(`Subject: ${context.getSubject()}`);
}
```

> **Hint**`@Payload()`, `@Ctx()` and `NatsContext` are imported from the `@nestjs/microservices` package.

#### Wildcards[#](/microservices/nats#wildcards)

A subscription can target an explicit subject, or it can include wildcards.

JS TS

```typescript

@MessagePattern('time.us.*')
getDate(@Payload() data: number[], @Ctx() context: NatsContext) {
  console.log(`Subject: ${context.getSubject()}`); // e.g. "time.us.east"
  return new Date().toLocaleTimeString(...);
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('time.us.*')
getDate(data, context) {
  console.log(`Subject: ${context.getSubject()}`); // e.g. "time.us.east"
  return new Date().toLocaleTimeString(...);
}
```

#### Record builders[#](/microservices/nats#record-builders)

To configure message options, use the `NatsRecordBuilder` class. It works for both request-response and event-based flows. For example, to add an `x-version` header, use the `setHeaders()` method:

```typescript

import * as nats from '@nats-io/nats-core';

// somewhere in your code
const headers = nats.headers();
headers.set('x-version', '1.0.0');

const record = new NatsRecordBuilder(':cat:').setHeaders(headers).build();
this.client.send('replace-emoji', record).subscribe(...);
```

> **Hint** The `NatsRecordBuilder` class is exported from the `@nestjs/microservices` package.

On the server side, you can read these headers through the `NatsContext`:

JS TS

```typescript

@MessagePattern('replace-emoji')
replaceEmoji(@Payload() data: string, @Ctx() context: NatsContext): string {
  const headers = context.getHeaders();
  return headers?.get('x-version') === '1.0.0' ? '🐱' : '🐈';
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('replace-emoji')
replaceEmoji(data, context) {
  const headers = context.getHeaders();
  return headers?.get('x-version') === '1.0.0' ? '🐱' : '🐈';
}
```

To configure headers for all requests sent by a client, pass them as options to the `ClientProxyFactory`:

```typescript

import { Module } from '@nestjs/common';
import { ClientProxyFactory, Transport } from '@nestjs/microservices';

@Module({
  providers: [
    {
      provide: 'API_v1',
      useFactory: () =>
        ClientProxyFactory.create({
          transport: Transport.NATS,
          options: {
            servers: ['nats://localhost:4222'],
            headers: { 'x-version': '1.0.0' },
          },
        }),
    },
  ],
})
export class ApiModule {}
```

Headers set on a record take precedence over the client-level `headers` option.

Starting with NestJS v12.1.3, a message handler can also return a record. Nest sends the record data as the reply and the record headers as the headers of the reply message:

```typescript

import * as nats from '@nats-io/nats-core';

@MessagePattern('replace-emoji')
replaceEmoji() {
  const headers = nats.headers();
  headers.set('x-version', '1.0.0');

  return new NatsRecordBuilder(':cat:').setHeaders(headers).build();
}
```

#### Custom serializers and deserializers[#](/microservices/nats#custom-serializers-and-deserializers)

Starting with NestJS v12, Nest serializes NATS packets as JSON strings, and custom NATS deserializers receive the full NATS message object instead of a raw `Uint8Array`. If you have written a custom deserializer, read the payload through `msg.json()` rather than decoding bytes manually:

```typescript

import { Deserializer, IncomingRequest } from '@nestjs/microservices';

export class CustomNatsDeserializer implements Deserializer {
  deserialize(msg: any): IncomingRequest {
    // Previously: JSON.parse(new TextDecoder().decode(msg));
    return msg.json();
  }
}
```

#### Instance status updates[#](/microservices/nats#instance-status-updates)

To get real-time updates on the connection and the state of the underlying driver instance, subscribe to the `status` stream. This stream provides status updates specific to the chosen driver. For the NATS driver, the `status` stream emits `connected`, `disconnected`, and `reconnecting` events.

```typescript

this.client.status.subscribe((status: NatsStatus) => {
  console.log(status);
});
```

> **Hint** The `NatsStatus` type is imported from the `@nestjs/microservices` package.

Similarly, you can subscribe to the server's `status` stream to receive notifications about the server's status.

```typescript

const server = app.connectMicroservice<MicroserviceOptions>(...);
server.status.subscribe((status: NatsStatus) => {
  console.log(status);
});
```

#### Listening to NATS events[#](/microservices/nats#listening-to-nats-events)

In some cases, you might want to listen to internal events emitted by the microservice. The NATS transporter emits the `disconnect`, `reconnect`, and `update` (cluster servers added or removed) events. For example, you could listen for the `disconnect` event to trigger additional operations when the connection is lost. To do this, use the `on()` method, as shown below:

```typescript

this.client.on('disconnect', (serverUrl) => {
  console.error(`Disconnected from ${serverUrl}`);
});
```

Similarly, you can listen to the server's internal events:

```typescript

server.on<NatsEvents>('disconnect', (serverUrl) => {
  console.error(`Disconnected from ${serverUrl}`);
});
```

> **Hint** The `NatsEvents` type is imported from the `@nestjs/microservices` package.

#### Underlying driver access[#](/microservices/nats#underlying-driver-access)

For more advanced use cases, you may need to access the underlying driver instance, for example, to close the connection manually or to use driver-specific methods. In most cases, however, you **shouldn't need** to access the driver directly.

To do so, use the `unwrap()` method, which returns the underlying driver instance. The generic type parameter specifies the type of driver instance you expect.

```typescript

const natsConnection =
  this.client.unwrap<import('@nats-io/transport-node').NatsConnection>();
```

Similarly, you can access the server's underlying driver instance:

```typescript

const natsConnection =
  server.unwrap<import('@nats-io/transport-node').NatsConnection>();
```

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/microservices/nats.md)

----
url: https://docs.nestjs.com/v10/techniques/queues
----

* [Queues](https://docs.nestjs.com/v10/techniques/queues#queues)
* [BullMQ installation](https://docs.nestjs.com/v10/techniques/queues#bullmq-installation)
* [Named configurations](https://docs.nestjs.com/v10/techniques/queues#named-configurations)
* [Producers](https://docs.nestjs.com/v10/techniques/queues#producers)
* [Job options](https://docs.nestjs.com/v10/techniques/queues#job-options)
* [Consumers](https://docs.nestjs.com/v10/techniques/queues#consumers)
* [Request-scoped consumers](https://docs.nestjs.com/v10/techniques/queues#request-scoped-consumers)
* [Event listeners](https://docs.nestjs.com/v10/techniques/queues#event-listeners)
* [Queue management](https://docs.nestjs.com/v10/techniques/queues#queue-management)
* [Separate processes](https://docs.nestjs.com/v10/techniques/queues#separate-processes)
* [Async configuration](https://docs.nestjs.com/v10/techniques/queues#async-configuration)
* [Bull installation](https://docs.nestjs.com/v10/techniques/queues#bull-installation)
* [Named configurations](https://docs.nestjs.com/v10/techniques/queues#named-configurations-1)
* [Producers](https://docs.nestjs.com/v10/techniques/queues#producers-1)
* [Named jobs](https://docs.nestjs.com/v10/techniques/queues#named-jobs)
* [Job options](https://docs.nestjs.com/v10/techniques/queues#job-options-1)
* [Consumers](https://docs.nestjs.com/v10/techniques/queues#consumers-1)
* [Request-scoped consumers](https://docs.nestjs.com/v10/techniques/queues#request-scoped-consumers-1)
* [Event listeners](https://docs.nestjs.com/v10/techniques/queues#event-listeners-1)
* [Queue management](https://docs.nestjs.com/v10/techniques/queues#queue-management-1)
* [Separate processes](https://docs.nestjs.com/v10/techniques/queues#separate-processes-1)
* [Async configuration](https://docs.nestjs.com/v10/techniques/queues#async-configuration-1)
* [Example](https://docs.nestjs.com/v10/techniques/queues#example)

```bash

$ npm install --save @nestjs/bullmq bullmq
```

Once the installation process is complete, we can import the `BullModule` into the root `AppModule`.

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { BullModule } from '@nestjs/bullmq';

@Module({
  imports: [
    BullModule.forRoot({
      connection: {
        host: 'localhost',
        port: 6379,
      },
    }),
  ],
})
export class AppModule {}
```

The `forRoot()` method is used to register a `bullmq` package configuration object that will be used by all queues registered in the application (unless specified otherwise). For your reference, the following are a few of the properties within a configuration object:

* `connection: ConnectionOptions` - Options to configure the Redis connection. See [Connections](https://docs.bullmq.io/guide/connections) for more information. Optional.
* `prefix: string` - Prefix for all queue keys. Optional.
* `defaultJobOptions: JobOpts` - Options to control the default settings for new jobs. See [JobOpts](https://github.com/OptimalBits/bull/blob/master/REFERENCE.md#queueadd) for more information. Optional.
* `settings: AdvancedSettings` - Advanced Queue configuration settings. These should usually not be changed. See [AdvancedSettings](https://github.com/OptimalBits/bull/blob/master/REFERENCE.md#queue) for more information. Optional.

All the options are optional, providing detailed control over queue behavior. These are passed directly to the BullMQ `Queue` constructor. Read more about these options and other options [here](https://api.docs.bullmq.io/interfaces/v4.QueueOptions.html).

To register a queue, import the `BullModule.registerQueue()` dynamic module, as follows:

```typescript

BullModule.registerQueue({
  name: 'audio',
});
```

> **Hint** Create multiple queues by passing multiple comma-separated configuration objects to the `registerQueue()` method.

The `registerQueue()` method is used to instantiate and/or register queues. Queues are shared across modules and processes that connect to the same underlying Redis database with the same credentials. Each queue is unique by its name property. A queue name is used as both an injection token (for injecting the queue into controllers/providers), and as an argument to decorators to associate consumer classes and listeners with queues.

You can also override some of the pre-configured options for a specific queue, as follows:

```typescript

BullModule.registerQueue({
  name: 'audio',
  connection: {
    port: 6380,
  },
});
```

BullMQ also supports parent - child relationships between jobs. This functionality enables the creation of flows where jobs are the node of trees of arbitrary depth. To read more about them check [here](https://docs.bullmq.io/guide/flows).

To add a flow, you can do the following:

```typescript

BullModule.registerFlowProducer({
  name: 'flowProducerName',
});
```

```typescript

BullModule.forRoot('alternative-config', {
  connection: {
    port: 6381,
  },
});
```

In the example above, `'alternative-config'` is just a configuration key (it can be any arbitrary string).

With this in place, you can now point to this configuration in the `registerQueue()` options object:

```typescript

BullModule.registerQueue({
  configKey: 'alternative-config',
  name: 'video',
});
```

#### Producers[#](/techniques/queues#producers)

Job producers add jobs to queues. Producers are typically application services (Nest [providers](/v10/providers)). To add jobs to a queue, first inject the queue into the service as follows:

```typescript

import { Injectable } from '@nestjs/common';
import { Queue } from 'bullmq';
import { InjectQueue } from '@nestjs/bullmq';

@Injectable()
export class AudioService {
  constructor(@InjectQueue('audio') private audioQueue: Queue) {}
}
```

> **Hint** The `@InjectQueue()` decorator identifies the queue by its name, as provided in the `registerQueue()` method call (e.g., `'audio'`).

Now, add a job by calling the queue's `add()` method, passing a user-defined job object. Jobs are represented as serializable JavaScript objects (since that is how they are stored in the Redis database). The shape of the job you pass is arbitrary; use it to represent the semantics of your job object. You also need to give it a name. This allows you to create specialized [consumers](techniques/queues#consumers) that will only process jobs with a given name.

```typescript

const job = await this.audioQueue.add('transcode', {
  foo: 'bar',
});
```

```typescript

const job = await this.audioQueue.add(
  'transcode',
  {
    foo: 'bar',
  },
  { delay: 3000 }, // 3 seconds delayed
);
```

To add a job to the right end of the queue (process the job as **LIFO** (Last In First Out)), set the `lifo` property of the configuration object to `true`.

```typescript

const job = await this.audioQueue.add(
  'transcode',
  {
    foo: 'bar',
  },
  { lifo: true },
);
```

To prioritize a job, use the `priority` property.

```typescript

const job = await this.audioQueue.add(
  'transcode',
  {
    foo: 'bar',
  },
  { priority: 2 },
);
```

For a full list of options, check the API documentation [here](https://api.docs.bullmq.io/types/v4.JobsOptions.html) and [here](https://api.docs.bullmq.io/interfaces/v4.BaseJobOptions.html).

#### Consumers[#](/techniques/queues#consumers)

A consumer is a **class** defining methods that either process jobs added into the queue, or listen for events on the queue, or both. Declare a consumer class using the `@Processor()` decorator as follows:

```typescript

import { Processor } from '@nestjs/bullmq';

@Processor('audio')
export class AudioConsumer {}
```

> **Hint** Consumers must be registered as `providers` so the `@nestjs/bullmq` package can pick them up.

Where the decorator's string argument (e.g., `'audio'`) is the name of the queue to be associated with the class methods.

```typescript

import { Processor, WorkerHost } from '@nestjs/bullmq';
import { Job } from 'bullmq';

@Processor('audio')
export class AudioConsumer extends WorkerHost {
  async process(job: Job<any, any, string>): Promise<any> {
    let progress = 0;
    for (i = 0; i < 100; i++) {
      await doSomething(job.data);
      progress += 1;
      await job.progress(progress);
    }
    return {};
  }
}
```

The process method is called whenever the worker is idle and there are jobs to process in the queue. This handler method receives the `job` object as its only argument. The value returned by the handler method is stored in the job object and can be accessed later on, for example in a listener for the completed event.

`Job` objects have multiple methods that allow you to interact with their state. For example, the above code uses the `progress()` method to update the job's progress. See [here](https://api.docs.bullmq.io/classes/v4.Job.html) for the complete `Job` object API reference.

In the older version, Bull, you could designate that a job handler method will handle **only** jobs of a certain type (jobs with a specific `name`) by passing that `name` to the `@Process()` decorator as shown below.

> **Warning** This doesn't work with BullMQ, keep reading.

```typescript

@Process('transcode')
async transcode(job: Job<unknown>) { ... }
```

This behavior is not supported in BullMQ due to confusions it generated. Instead, you need switch cases to call different services or logic for each job name:

```typescript

import { Processor, WorkerHost } from '@nestjs/bullmq';
import { Job } from 'bullmq';

@Processor('audio')
export class AudioConsumer extends WorkerHost {
  async process(job: Job<any, any, string>): Promise<any> {
    switch (job.name) {
      case 'transcode': {
        let progress = 0;
        for (i = 0; i < 100; i++) {
          await doSomething(job.data);
          progress += 1;
          await job.progress(progress);
        }
        return {};
      }
      case 'concatenate': {
        await doSomeLogic2();
        break;
      }
    }
  }
}
```

This is covered in the [named processor](https://docs.bullmq.io/patterns/named-processor) section of the BullMQ documentation.

#### Request-scoped consumers[#](/techniques/queues#request-scoped-consumers)

When a consumer is flagged as request-scoped (learn more about the injection scopes [here](/fundamentals/injection-scopes#provider-scope)), a new instance of the class will be created exclusively for each job. The instance will be garbage-collected after the job has completed.

```typescript

@Processor({
  name: 'audio',
  scope: Scope.REQUEST,
})
```

Since request-scoped consumer classes are instantiated dynamically and scoped to a single job, you can inject a `JOB_REF` through the constructor using a standard approach.

```typescript

constructor(@Inject(JOB_REF) jobRef: Job) {
  console.log(jobRef);
}
```

> **Hint** The `JOB_REF` token is imported from the `@nestjs/bullmq` package.

#### Event listeners[#](/techniques/queues#event-listeners)

BullMQ generates a set of useful events when queue and/or job state changes occur. These events can be subscribed to at the Worker level using the `@OnWorkerEvent(event)` decorator, or at the Queue level with a dedicated listener class and the `@OnQueueEvent(event)` decorator.

Worker events must be declared within a [consumer](techniques/queues#consumers) class (i.e., within a class decorated with the `@Processor()` decorator). To listen for an event, use the `@OnWorkerEvent(event)` decorator with the event you want to be handled. For example, to listen to the event emitted when a job enters the active state in the `audio` queue, use the following construct:

```typescript

import { Processor, Process, OnWorkerEvent } from '@nestjs/bullmq';
import { Job } from 'bullmq';

@Processor('audio')
export class AudioConsumer {
  @OnWorkerEvent('active')
  onActive(job: Job) {
    console.log(
      `Processing job ${job.id} of type ${job.name} with data ${job.data}...`,
    );
  }

  // ...
}
```

You can see the complete list of events and their arguments as properties of WorkerListener [here](https://api.docs.bullmq.io/interfaces/v4.WorkerListener.html).

QueueEvent listeners must use the `@QueueEventsListener(queue)` decorator and extend the `QueueEventsHost` class provided by `@nestjs/bullmq`. To listen for an event, use the `@OnQueueEvent(event)` decorator with the event you want to be handled. For example, to listen to the event emitted when a job enters the active state in the `audio` queue, use the following construct:

```typescript

import {
  QueueEventsHost,
  QueueEventsListener,
  OnQueueEvent,
} from '@nestjs/bullmq';

@QueueEventsListener('audio')
export class AudioEventsListener extends QueueEventsHost {
  @OnQueueEvent('active')
  onActive(job: { jobId: string; prev?: string }) {
    console.log(`Processing job ${job.jobId}...`);
  }

  // ...
}
```

> **Hint** QueueEvent Listeners must be registered as `providers` so the `@nestjs/bullmq` package can pick them up.

You can see the complete list of events and their arguments as properties of QueueEventsListener [here](https://api.docs.bullmq.io/interfaces/v4.QueueEventsListener.html).

#### Queue management[#](/techniques/queues#queue-management)

Queues have an API that allows you to perform management functions like pausing and resuming, retrieving the count of jobs in various states, and several more. You can find the full queue API [here](https://api.docs.bullmq.io/classes/v4.Queue.html). Invoke any of these methods directly on the `Queue` object, as shown below with the pause/resume examples.

Pause a queue with the `pause()` method call. A paused queue will not process new jobs until resumed, but current jobs being processed will continue until they are finalized.

```typescript

await audioQueue.pause();
```

To resume a paused queue, use the `resume()` method, as follows:

```typescript

await audioQueue.resume();
```

```typescript

import { Module } from '@nestjs/common';
import { BullModule } from '@nestjs/bullmq';
import { join } from 'path';

@Module({
  imports: [
    BullModule.registerQueue({
      name: 'audio',
      processors: [join(__dirname, 'processor.js')],
    }),
  ],
})
export class AppModule {}
```

> **Warning** Please note that because your function is being executed in a forked process, Dependency Injection (and IoC container) won't be available. That means that your processor function will need to contain (or create) all instances of external dependencies it needs.

#### Async configuration[#](/techniques/queues#async-configuration)

You may want to pass `bullmq` options asynchronously instead of statically. In this case, use the `forRootAsync()` method which provides several ways to deal with async configuration. Likewise, if you want to pass queue options asynchronously, use the `registerQueueAsync()` method.

One approach is to use a factory function:

```typescript

BullModule.forRootAsync({
  useFactory: () => ({
    connection: {
      host: 'localhost',
      port: 6379,
    },
  }),
});
```

Our factory behaves like any other [asynchronous provider](https://docs.nestjs.com/fundamentals/async-providers) (e.g., it can be `async` and it's able to inject dependencies through `inject`).

```typescript

BullModule.forRootAsync({
  imports: [ConfigModule],
  useFactory: async (configService: ConfigService) => ({
    connection: {
      host: configService.get('QUEUE_HOST'),
      port: configService.get('QUEUE_PORT'),
    },
  }),
  inject: [ConfigService],
});
```

Alternatively, you can use the `useClass` syntax:

```typescript

BullModule.forRootAsync({
  useClass: BullConfigService,
});
```

The construction above will instantiate `BullConfigService` inside `BullModule` and use it to provide an options object by calling `createSharedConfiguration()`. Note that this means that the `BullConfigService` has to implement the `SharedBullConfigurationFactory` interface, as shown below:

```typescript

@Injectable()
class BullConfigService implements SharedBullConfigurationFactory {
  createSharedConfiguration(): BullModuleOptions {
    return {
      connection: {
        host: 'localhost',
        port: 6379,
      },
    };
  }
}
```

In order to prevent the creation of `BullConfigService` inside `BullModule` and use a provider imported from a different module, you can use the `useExisting` syntax.

```typescript

BullModule.forRootAsync({
  imports: [ConfigModule],
  useExisting: ConfigService,
});
```

This construction works the same as `useClass` with one critical difference - `BullModule` will lookup imported modules to reuse an existing `ConfigService` instead of instantiating a new one.

Likewise, if you want to pass queue options asynchronously, use the `registerQueueAsync()` method, just keep in mind to specify the `name` attribute outside the factory function.

```typescript

BullModule.registerQueueAsync({
  name: 'audio',
  useFactory: () => ({
    redis: {
      host: 'localhost',
      port: 6379,
    },
  }),
});
```

#### Bull installation[#](/techniques/queues#bull-installation)

> **Note** If you decided to use BullMQ, skip this section and the following chapters.

To begin using Bull, we first install the required dependencies.

```bash

$ npm install --save @nestjs/bull bull
```

Once the installation process is complete, we can import the `BullModule` into the root `AppModule`.

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { BullModule } from '@nestjs/bull';

@Module({
  imports: [
    BullModule.forRoot({
      redis: {
        host: 'localhost',
        port: 6379,
      },
    }),
  ],
})
export class AppModule {}
```

```typescript

BullModule.registerQueue({
  name: 'audio',
});
```

> **Hint** Create multiple queues by passing multiple comma-separated configuration objects to the `registerQueue()` method.

The `registerQueue()` method is used to instantiate and/or register queues. Queues are shared across modules and processes that connect to the same underlying Redis database with the same credentials. Each queue is unique by its name property. A queue name is used as both an injection token (for injecting the queue into controllers/providers), and as an argument to decorators to associate consumer classes and listeners with queues.

You can also override some of the pre-configured options for a specific queue, as follows:

```typescript

BullModule.registerQueue({
  name: 'audio',
  redis: {
    port: 6380,
  },
});
```

```typescript

BullModule.forRoot('alternative-config', {
  redis: {
    port: 6381,
  },
});
```

In the example above, `'alternative-config'` is just a configuration key (it can be any arbitrary string).

With this in place, you can now point to this configuration in the `registerQueue()` options object:

```typescript

BullModule.registerQueue({
  configKey: 'alternative-config',
  name: 'video',
});
```

#### Producers[#](/techniques/queues#producers-1)

Job producers add jobs to queues. Producers are typically application services (Nest [providers](/v10/providers)). To add jobs to a queue, first inject the queue into the service as follows:

```typescript

import { Injectable } from '@nestjs/common';
import { Queue } from 'bull';
import { InjectQueue } from '@nestjs/bull';

@Injectable()
export class AudioService {
  constructor(@InjectQueue('audio') private audioQueue: Queue) {}
}
```

> **Hint** The `@InjectQueue()` decorator identifies the queue by its name, as provided in the `registerQueue()` method call (e.g., `'audio'`).

Now, add a job by calling the queue's `add()` method, passing a user-defined job object. Jobs are represented as serializable JavaScript objects (since that is how they are stored in the Redis database). The shape of the job you pass is arbitrary; use it to represent the semantics of your job object.

```typescript

const job = await this.audioQueue.add({
  foo: 'bar',
});
```

#### Named jobs[#](/techniques/queues#named-jobs)

Jobs may have unique names. This allows you to create specialized [consumers](techniques/queues#consumers) that will only process jobs with a given name.

```typescript

const job = await this.audioQueue.add('transcode', {
  foo: 'bar',
});
```

> **Warning** When using named jobs, you must create processors for each unique name added to a queue, or the queue will complain that you are missing a processor for the given job. See [here](techniques/queues#consumers) for more information on consuming named jobs.

```typescript

const job = await this.audioQueue.add(
  {
    foo: 'bar',
  },
  { delay: 3000 }, // 3 seconds delayed
);
```

To add a job to the right end of the queue (process the job as **LIFO** (Last In First Out)), set the `lifo` property of the configuration object to `true`.

```typescript

const job = await this.audioQueue.add(
  {
    foo: 'bar',
  },
  { lifo: true },
);
```

To prioritize a job, use the `priority` property.

```typescript

const job = await this.audioQueue.add(
  {
    foo: 'bar',
  },
  { priority: 2 },
);
```

#### Consumers[#](/techniques/queues#consumers-1)

A consumer is a **class** defining methods that either process jobs added into the queue, or listen for events on the queue, or both. Declare a consumer class using the `@Processor()` decorator as follows:

```typescript

import { Processor } from '@nestjs/bull';

@Processor('audio')
export class AudioConsumer {}
```

> **Hint** Consumers must be registered as `providers` so the `@nestjs/bull` package can pick them up.

Where the decorator's string argument (e.g., `'audio'`) is the name of the queue to be associated with the class methods.

Within a consumer class, declare job handlers by decorating handler methods with the `@Process()` decorator.

```typescript

import { Processor, Process } from '@nestjs/bull';
import { Job } from 'bull';

@Processor('audio')
export class AudioConsumer {
  @Process()
  async transcode(job: Job<unknown>) {
    let progress = 0;
    for (let i = 0; i < 100; i++) {
      await doSomething(job.data);
      progress += 1;
      await job.progress(progress);
    }
    return {};
  }
}
```

The decorated method (e.g., `transcode()`) is called whenever the worker is idle and there are jobs to process in the queue. This handler method receives the `job` object as its only argument. The value returned by the handler method is stored in the job object and can be accessed later on, for example in a listener for the completed event.

`Job` objects have multiple methods that allow you to interact with their state. For example, the above code uses the `progress()` method to update the job's progress. See [here](https://github.com/OptimalBits/bull/blob/master/REFERENCE.md#job) for the complete `Job` object API reference.

You can designate that a job handler method will handle **only** jobs of a certain type (jobs with a specific `name`) by passing that `name` to the `@Process()` decorator as shown below. You can have multiple `@Process()` handlers in a given consumer class, corresponding to each job type (`name`). When you use named jobs, be sure to have a handler corresponding to each name.

```typescript

@Process('transcode')
async transcode(job: Job<unknown>) { ... }
```

> **Warning** When defining multiple consumers for the same queue, the `concurrency` option in `@Process({ concurrency: 1 })` won't take effect. The minimum `concurrency` will match the number of consumers defined. This also applies even if `@Process()` handlers use a different `name` to handle named jobs.

#### Request-scoped consumers[#](/techniques/queues#request-scoped-consumers-1)

When a consumer is flagged as request-scoped (learn more about the injection scopes [here](/fundamentals/injection-scopes#provider-scope)), a new instance of the class will be created exclusively for each job. The instance will be garbage-collected after the job has completed.

```typescript

@Processor({
  name: 'audio',
  scope: Scope.REQUEST,
})
```

Since request-scoped consumer classes are instantiated dynamically and scoped to a single job, you can inject a `JOB_REF` through the constructor using a standard approach.

```typescript

constructor(@Inject(JOB_REF) jobRef: Job) {
  console.log(jobRef);
}
```

> **Hint** The `JOB_REF` token is imported from the `@nestjs/bull` package.

#### Event listeners[#](/techniques/queues#event-listeners-1)

Bull generates a set of useful events when queue and/or job state changes occur. Nest provides a set of decorators that allow subscribing to a core set of standard events. These are exported from the `@nestjs/bull` package.

Event listeners must be declared within a [consumer](techniques/queues#consumers) class (i.e., within a class decorated with the `@Processor()` decorator). To listen for an event, use one of the decorators in the table below to declare a handler for the event. For example, to listen to the event emitted when a job enters the active state in the `audio` queue, use the following construct:

```typescript

import { Processor, Process, OnQueueActive } from '@nestjs/bull';
import { Job } from 'bull';

@Processor('audio')
export class AudioConsumer {

  @OnQueueActive()
  onActive(job: Job) {
    console.log(
      `Processing job ${job.id} of type ${job.name} with data ${job.data}...`,
    );
  }
  ...
```

Since Bull operates in a distributed (multi-node) environment, it defines the concept of event locality. This concept recognizes that events may be triggered either entirely within a single process, or on shared queues from different processes. A **local** event is one that is produced when an action or state change is triggered on a queue in the local process. In other words, when your event producers and consumers are local to a single process, all events happening on queues are local.

When a queue is shared across multiple processes, we encounter the possibility of **global** events. For a listener in one process to receive an event notification triggered by another process, it must register for a global event.

Event handlers are invoked whenever their corresponding event is emitted. The handler is called with the signature shown in the table below, providing access to information relevant to the event. We discuss one key difference between local and global event handler signatures below.

| Local event listeners | Global event listeners      | Handler method signature / When fired                                                                                                                                 |
| --------------------- | --------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `@OnQueueError()`     | `@OnGlobalQueueError()`     | `handler(error: Error)` - An error occurred. `error` contains the triggering error.                                                                                   |
| `@OnQueueWaiting()`   | `@OnGlobalQueueWaiting()`   | `handler(jobId: number \| string)` - A Job is waiting to be processed as soon as a worker is idling. `jobId` contains the id for the job that has entered this state. |
| `@OnQueueActive()`    | `@OnGlobalQueueActive()`    | `handler(job: Job)` - Job `job`has started.                                                                                                                           |
| `@OnQueueStalled()`   | `@OnGlobalQueueStalled()`   | `handler(job: Job)` - Job `job` has been marked as stalled. This is useful for debugging job workers that crash or pause the event loop.                              |
| `@OnQueueProgress()`  | `@OnGlobalQueueProgress()`  | `handler(job: Job, progress: number)` - Job `job`'s progress was updated to value `progress`.                                                                         |
| `@OnQueueCompleted()` | `@OnGlobalQueueCompleted()` | `handler(job: Job, result: any)` Job `job` successfully completed with a result `result`.                                                                             |
| `@OnQueueFailed()`    | `@OnGlobalQueueFailed()`    | `handler(job: Job, err: Error)` Job `job` failed with reason `err`.                                                                                                   |
| `@OnQueuePaused()`    | `@OnGlobalQueuePaused()`    | `handler()` The queue has been paused.                                                                                                                                |
| `@OnQueueResumed()`   | `@OnGlobalQueueResumed()`   | `handler(job: Job)` The queue has been resumed.                                                                                                                       |
| `@OnQueueCleaned()`   | `@OnGlobalQueueCleaned()`   | `handler(jobs: Job[], type: string)` Old jobs have been cleaned from the queue. `jobs` is an array of cleaned jobs, and `type` is the type of jobs cleaned.           |
| `@OnQueueDrained()`   | `@OnGlobalQueueDrained()`   | `handler()` Emitted whenever the queue has processed all the waiting jobs (even if there can be some delayed jobs not yet processed).                                 |
| `@OnQueueRemoved()`   | `@OnGlobalQueueRemoved()`   | `handler(job: Job)` Job `job` was successfully removed.                                                                                                               |

When listening for global events, the method signatures can be slightly different from their local counterpart. Specifically, any method signature that receives `job` objects in the local version, instead receives a `jobId` (`number`) in the global version. To get a reference to the actual `job` object in such a case, use the `Queue#getJob` method. This call should be awaited, and therefore the handler should be declared `async`. For example:

```typescript

@OnGlobalQueueCompleted()
async onGlobalCompleted(jobId: number, result: any) {
  const job = await this.immediateQueue.getJob(jobId);
  console.log('(Global) on completed: job ', job.id, ' -> result: ', result);
}
```

> **Hint** To access the `Queue` object (to make a `getJob()` call), you must of course inject it. Also, the Queue must be registered in the module where you are injecting it.

In addition to the specific event listener decorators, you can also use the generic `@OnQueueEvent()` decorator in combination with either `BullQueueEvents` or `BullQueueGlobalEvents` enums. Read more about events [here](https://github.com/OptimalBits/bull/blob/master/REFERENCE.md#events).

#### Queue management[#](/techniques/queues#queue-management-1)

Queue's have an API that allows you to perform management functions like pausing and resuming, retrieving the count of jobs in various states, and several more. You can find the full queue API [here](https://github.com/OptimalBits/bull/blob/master/REFERENCE.md#queue). Invoke any of these methods directly on the `Queue` object, as shown below with the pause/resume examples.

Pause a queue with the `pause()` method call. A paused queue will not process new jobs until resumed, but current jobs being processed will continue until they are finalized.

```typescript

await audioQueue.pause();
```

To resume a paused queue, use the `resume()` method, as follows:

```typescript

await audioQueue.resume();
```

```ts

import { Module } from '@nestjs/common';
import { BullModule } from '@nestjs/bull';
import { join } from 'path';

@Module({
  imports: [
    BullModule.registerQueue({
      name: 'audio',
      processors: [join(__dirname, 'processor.js')],
    }),
  ],
})
export class AppModule {}
```

Please note that because your function is being executed in a forked process, Dependency Injection (and IoC container) won't be available. That means that your processor function will need to contain (or create) all instances of external dependencies it needs.

processor.ts

JS TS

```ts

import { Job, DoneCallback } from 'bull';

export default function (job: Job, cb: DoneCallback) {
  console.log(`[${process.pid}] ${JSON.stringify(job.data)}`);
  cb(null, 'It works');
}
```

#### Async configuration[#](/techniques/queues#async-configuration-1)

You may want to pass `bull` options asynchronously instead of statically. In this case, use the `forRootAsync()` method which provides several ways to deal with async configuration.

One approach is to use a factory function:

```typescript

BullModule.forRootAsync({
  useFactory: () => ({
    redis: {
      host: 'localhost',
      port: 6379,
    },
  }),
});
```

Our factory behaves like any other [asynchronous provider](https://docs.nestjs.com/fundamentals/async-providers) (e.g., it can be `async` and it's able to inject dependencies through `inject`).

```typescript

BullModule.forRootAsync({
  imports: [ConfigModule],
  useFactory: async (configService: ConfigService) => ({
    redis: {
      host: configService.get('QUEUE_HOST'),
      port: configService.get('QUEUE_PORT'),
    },
  }),
  inject: [ConfigService],
});
```

Alternatively, you can use the `useClass` syntax:

```typescript

BullModule.forRootAsync({
  useClass: BullConfigService,
});
```

The construction above will instantiate `BullConfigService` inside `BullModule` and use it to provide an options object by calling `createSharedConfiguration()`. Note that this means that the `BullConfigService` has to implement the `SharedBullConfigurationFactory` interface, as shown below:

```typescript

@Injectable()
class BullConfigService implements SharedBullConfigurationFactory {
  createSharedConfiguration(): BullModuleOptions {
    return {
      redis: {
        host: 'localhost',
        port: 6379,
      },
    };
  }
}
```

In order to prevent the creation of `BullConfigService` inside `BullModule` and use a provider imported from a different module, you can use the `useExisting` syntax.

```typescript

BullModule.forRootAsync({
  imports: [ConfigModule],
  useExisting: ConfigService,
});
```

This construction works the same as `useClass` with one critical difference - `BullModule` will lookup imported modules to reuse an existing `ConfigService` instead of instantiating a new one.

Likewise, if you want to pass queue options asynchronously, use the `registerQueueAsync()` method, just keep in mind to specify the `name` attribute outside the factory function.

```typescript

BullModule.registerQueueAsync({
  name: 'audio',
  useFactory: () => ({
    redis: {
      host: 'localhost',
      port: 6379,
    },
  }),
});
```

#### Example[#](/techniques/queues#example)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/26-queues).

----
url: https://docs.nestjs.com/v10/microservices/nats
----

* [NATS](https://docs.nestjs.com/v10/microservices/nats#nats)
* [Installation](https://docs.nestjs.com/v10/microservices/nats#installation)
* [Overview](https://docs.nestjs.com/v10/microservices/nats#overview)
* [Options](https://docs.nestjs.com/v10/microservices/nats#options)
* [Client](https://docs.nestjs.com/v10/microservices/nats#client)
* [Request-response](https://docs.nestjs.com/v10/microservices/nats#request-response)
* [Event-based](https://docs.nestjs.com/v10/microservices/nats#event-based)
* [Queue groups](https://docs.nestjs.com/v10/microservices/nats#queue-groups)
* [Context](https://docs.nestjs.com/v10/microservices/nats#context)
* [Wildcards](https://docs.nestjs.com/v10/microservices/nats#wildcards)
* [Record builders](https://docs.nestjs.com/v10/microservices/nats#record-builders)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/microservices/nats.md "Suggest Edits")

### NATS

[NATS](https://nats.io) is a simple, secure and high performance open source messaging system for cloud native applications, IoT messaging, and microservices architectures. The NATS server is written in the Go programming language, but client libraries to interact with the server are available for dozens of major programming languages. NATS supports both **At Most Once** and **At Least Once** delivery. It can run anywhere, from large servers and cloud instances, through edge gateways and even Internet of Things devices.

#### Installation[#](/microservices/nats#installation)

To start building NATS-based microservices, first install the required package:

```bash

$ npm i --save nats
```

#### Overview[#](/microservices/nats#overview)

To use the NATS transporter, pass the following options object to the `createMicroservice()` method:

main.ts

JS TS

```typescript

const app = await NestFactory.createMicroservice<MicroserviceOptions>(AppModule, {
  transport: Transport.NATS,
  options: {
    servers: ['nats://localhost:4222'],
  },
});
```

```typescript

const app = await NestFactory.createMicroservice(AppModule, {
  transport: Transport.NATS,
  options: {
    servers: ['nats://localhost:4222'],
  },
});
```

> **Hint** The `Transport` enum is imported from the `@nestjs/microservices` package.

#### Options[#](/microservices/nats#options)

The `options` object is specific to the chosen transporter. The **NATS** transporter exposes the properties described [here](https://github.com/nats-io/node-nats#connection-options). Additionally, there is a `queue` property which allows you to specify the name of the queue that your server should subscribe to (leave `undefined` to ignore this setting). Read more about NATS queue groups [below](https://docs.nestjs.com/microservices/nats#queue-groups).

#### Client[#](/microservices/nats#client)

Like other microservice transporters, you have [several options](https://docs.nestjs.com/microservices/basics#client) for creating a NATS `ClientProxy` instance.

One method for creating an instance is to use the `ClientsModule`. To create a client instance with the `ClientsModule`, import it and use the `register()` method to pass an options object with the same properties shown above in the `createMicroservice()` method, as well as a `name` property to be used as the injection token. Read more about `ClientsModule`[here](https://docs.nestjs.com/microservices/basics#client).

```typescript

@Module({
  imports: [
    ClientsModule.register([
      {
        name: 'MATH_SERVICE',
        transport: Transport.NATS,
        options: {
          servers: ['nats://localhost:4222'],
        }
      },
    ]),
  ]
  ...
})
```

```typescript

const app = await NestFactory.createMicroservice<MicroserviceOptions>(AppModule, {
  transport: Transport.NATS,
  options: {
    servers: ['nats://localhost:4222'],
    queue: 'cats_queue',
  },
});
```

#### Context[#](/microservices/nats#context)

In more sophisticated scenarios, you may want to access more information about the incoming request. When using the NATS transporter, you can access the `NatsContext` object.

JS TS

```typescript

@MessagePattern('notifications')
getNotifications(@Payload() data: number[], @Ctx() context: NatsContext) {
  console.log(`Subject: ${context.getSubject()}`);
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('notifications')
getNotifications(data, context) {
  console.log(`Subject: ${context.getSubject()}`);
}
```

> **Hint**`@Payload()`, `@Ctx()` and `NatsContext` are imported from the `@nestjs/microservices` package.

#### Wildcards[#](/microservices/nats#wildcards)

A subscription may be to an explicit subject, or it may include wildcards.

JS TS

```typescript

@MessagePattern('time.us.*')
getDate(@Payload() data: number[], @Ctx() context: NatsContext) {
  console.log(`Subject: ${context.getSubject()}`); // e.g. "time.us.east"
  return new Date().toLocaleTimeString(...);
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('time.us.*')
getDate(data, context) {
  console.log(`Subject: ${context.getSubject()}`); // e.g. "time.us.east"
  return new Date().toLocaleTimeString(...);
}
```

#### Record builders[#](/microservices/nats#record-builders)

To configure message options, you can use the `NatsRecordBuilder` class (note: this is doable for event-based flows as well). For example, to add `x-version` header, use the `setHeaders` method, as follows:

```typescript

import * as nats from 'nats';

// somewhere in your code
const headers = nats.headers();
headers.set('x-version', '1.0.0');

const record = new NatsRecordBuilder(':cat:').setHeaders(headers).build();
this.client.send('replace-emoji', record).subscribe(...);
```

> **Hint**`NatsRecordBuilder` class is exported from the `@nestjs/microservices` package.

And you can read these headers on the server-side as well, by accessing the `NatsContext`, as follows:

JS TS

```typescript

@MessagePattern('replace-emoji')
replaceEmoji(@Payload() data: string, @Ctx() context: NatsContext): string {
  const headers = context.getHeaders();
  return headers['x-version'] === '1.0.0' ? '🐱' : '🐈';
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('replace-emoji')
replaceEmoji(data, context) {
  const headers = context.getHeaders();
  return headers['x-version'] === '1.0.0' ? '🐱' : '🐈';
}
```

In some cases you might want to configure headers for multiple requests, you can pass these as options to the `ClientProxyFactory`:

```typescript

import { Module } from '@nestjs/common';
import { ClientProxyFactory, Transport } from '@nestjs/microservices';

@Module({
  providers: [
    {
      provide: 'API_v1',
      useFactory: () =>
        ClientProxyFactory.create({
          transport: Transport.NATS,
          options: {
            servers: ['nats://localhost:4222'],
            headers: { 'x-version': '1.0.0' },
          },
        }),
    },
  ],
})
export class ApiModule {}
```

----
url: https://docs.nestjs.com/v8/graphql/mutations
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Mutations](https://docs.nestjs.com/v8/graphql/mutations#mutations)
* [Code first](https://docs.nestjs.com/v8/graphql/mutations#code-first)
* [Schema first](https://docs.nestjs.com/v8/graphql/mutations#schema-first)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/mutations.md "Suggest Edits")

### Mutations

Most discussions of GraphQL focus on data fetching, but any complete data platform needs a way to modify server-side data as well. In REST, any request could end up causing side-effects on the server, but best practice suggests we should not modify data in GET requests. GraphQL is similar - technically any query could be implemented to cause a data write. However, like REST, it's recommended to observe the convention that any operations that cause writes should be sent explicitly via a mutation (read more [here](https://graphql.org/learn/queries/#mutations)).

The official [Apollo](https://www.apollographql.com/docs/graphql-tools/generate-schema.html) documentation uses an `upvotePost()` mutation example. This mutation implements a method to increase a post's `votes` property value. To create an equivalent mutation in Nest, we'll make use of the `@Mutation()` decorator.

#### Code first[#](/graphql/mutations#code-first)

Let's add another method to the `AuthorResolver` used in the previous section (see [resolvers](/v8/graphql/resolvers)).

```typescript

@Mutation(returns => Post)
async upvotePost(@Args({ name: 'postId', type: () => Int }) postId: number) {
  return this.postsService.upvoteById({ id: postId });
}
```

> **Hint** All decorators (e.g., `@Resolver`, `@ResolveField`, `@Args`, etc.) are exported from the `@nestjs/graphql` package.

This will result in generating the following part of the GraphQL schema in SDL:

```graphql

type Mutation {
  upvotePost(postId: Int!): Post
}
```

The `upvotePost()` method takes `postId` (`Int`) as an argument and returns an updated `Post` entity. For the reasons explained in the [resolvers](/v8/graphql/resolvers) section, we have to explicitly set the expected type.

If the mutation needs to take an object as an argument, we can create an **input type**. The input type is a special kind of object type that can be passed in as an argument (read more [here](https://graphql.org/learn/schema/#input-types)). To declare an input type, use the `@InputType()` decorator.

```typescript

import { InputType, Field } from '@nestjs/graphql';

@InputType()
export class UpvotePostInput {
  @Field()
  postId: number;
}
```

> **Hint** The `@InputType()` decorator takes an options object as an argument, so you can, for example, specify the input type's description. Note that, due to TypeScript's metadata reflection system limitations, you must either use the `@Field` decorator to manually indicate a type, or use a [CLI plugin](/v8/graphql/cli-plugin).

We can then use this type in the resolver class:

```typescript

@Mutation(returns => Post)
async upvotePost(
  @Args('upvotePostData') upvotePostData: UpvotePostInput,
) {}
```

#### Schema first[#](/graphql/mutations#schema-first)

Let's extend our `AuthorResolver` used in the previous section (see [resolvers](/v8/graphql/resolvers)).

```typescript

@Mutation()
async upvotePost(@Args('postId') postId: number) {
  return this.postsService.upvoteById({ id: postId });
}
```

Note that we assumed above that the business logic has been moved to the `PostsService` (querying the post and incrementing its `votes` property). The logic inside the `PostsService` class can be as simple or sophisticated as needed. The main point of this example is to show how resolvers can interact with other providers.

The last step is to add our mutation to the existing types definition.

```graphql

type Author {
  id: Int!
  firstName: String
  lastName: String
  posts: [Post]
}

type Post {
  id: Int!
  title: String
  votes: Int
}

type Query {
  author(id: Int!): Author
}

type Mutation {
  upvotePost(postId: Int!): Post
}
```

The `upvotePost(postId: Int!): Post` mutation is now available to be called as part of our application's GraphQL API.

----
url: https://docs.nestjs.com/v5/websockets/pipes
----

### Pipes

There is no difference between web sockets **pipes** and the [regular pipes](/v5/pipes). The only thing you should be aware of is that instead of throwing `HttpException`, you should use the `WsException`. Besides, all pipes will be applied only to the `data` parameter.

> **Hint** The `WsException` class is exposed from `@nestjs/websockets` package.

#### Binding pipes

Here is an example that makes use of a manually instantiated **method-scoped** pipe (class-scoped works either):

TypeScript

```typescript

@UsePipes(new ValidationPipe())
@SubscribeMessage('events')
onEvent(client, data: any): WsResponse<any> {
  const event = 'events';
  return { event, data };
}
```

----
url: https://docs.nestjs.com/cli/usages
----

[Skip to content](#content)

On this page

* [CLI command reference](https://docs.nestjs.com/cli/usages#cli-command-reference)
* [nest new](https://docs.nestjs.com/cli/usages#nest-new)
* [nest generate](https://docs.nestjs.com/cli/usages#nest-generate)
* [nest build](https://docs.nestjs.com/cli/usages#nest-build)
* [nest start](https://docs.nestjs.com/cli/usages#nest-start)
* [nest add](https://docs.nestjs.com/cli/usages#nest-add)
* [nest upgrade](https://docs.nestjs.com/cli/usages#nest-upgrade)
* [nest deploy](https://docs.nestjs.com/cli/usages#nest-deploy)
* [nest info](https://docs.nestjs.com/cli/usages#nest-info)

### CLI command reference

#### nest new[#](/cli/usages#nest-new)

Creates a new (standard mode) Nest project.

```bash

$ nest new <name> [options]
$ nest n <name> [options]
```

##### Description[#](/cli/usages#description)

Creates and initializes a new Nest project. The command prompts for any information you don't pass as an option: the project name, the package manager, the module system (ESM or CommonJS), and whether to set up [NestJS Observe](/observability/overview).

> **Hint** In non-interactive environments, such as CI, pass the project name and `--package-manager`. The module system then defaults to ESM, and Observe is set up only if you pass `--observe`.

> **Hint** Choosing **ESM** scaffolds an ESM-first project that uses Vitest for testing. Choosing **CommonJS** scaffolds the traditional layout, which uses Jest. Both variants use oxlint for linting.

The command:

* Creates a folder with the given `<name>`
* Populates the folder with configuration files
* Creates subfolders for source code (`/src`) and end-to-end tests (`/test`)
* Populates the subfolders with default files for application components and tests
* If Observe was set up, offers to link the project to it once the dependencies are installed (in an interactive terminal only). Accepting runs `npx @nestjs/observe link`, which writes the app key and secret into `.env` - see [Linking from the terminal](/observability/sdk#linking-from-the-terminal)

##### Arguments[#](/cli/usages#arguments)

| Argument | Description                 |
| -------- | --------------------------- |
| `<name>` | The name of the new project |

##### Options[#](/cli/usages#options)

| Option                                | Description                                                                                                                                                                                                                                                   |
| ------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--directory [directory]`             | Destination directory.                                                                                                                                                                                                                                        |
| `--dry-run`                           | Report the changes that would be made, without changing the filesystem. Alias: `-d`                                                                                                                                                                           |
| `--skip-git`                          | Skip git repository initialization. Alias: `-g`                                                                                                                                                                                                               |
| `--skip-install`                      | Skip package installation. Alias: `-s`                                                                                                                                                                                                                        |
| `--skip-tests`                        | Skip generating test files for the new project. Alias: `-t`                                                                                                                                                                                                   |
| `--package-manager [package-manager]` | Package manager to use: `npm`, `yarn`, `pnpm`, or `bun`. The package manager must be installed globally. Alias: `-p`                                                                                                                                          |
| `--language [language]`               | Programming language: `TS` (default) or `JS`. The value is case-insensitive, and `typescript` / `javascript` are also accepted. Alias: `-l`                                                                                                                   |
| `--collection [collectionName]`       | Schematics collection to use. Pass the package name of an installed npm package that contains the schematic. Alias: `-c`                                                                                                                                      |
| `--strict`                            | Enable TypeScript's `strict` mode (with `strictPropertyInitialization` disabled) in the generated `tsconfig.json`. Enabled by default, and there is no flag to disable it: to opt out, set `"strict": false` in `tsconfig.json` after generating the project. |
| `--format`                            | Format generated files using Prettier.                                                                                                                                                                                                                        |
| `--observe` / `--no-observe`          | Set up the `@nestjs/observe` SDK, or skip it, without being prompted. Omit both to be prompted in an interactive terminal (the prompt defaults to yes). Without a terminal, Observe is not set up.                                                            |

#### nest generate[#](/cli/usages#nest-generate)

Generates and/or modifies files based on a schematic.

```bash

$ nest generate <schematic> <name> [options]
$ nest g <schematic> <name> [options]
```

##### Arguments[#](/cli/usages#arguments-1)

| Argument      | Description                                                                                              |
| ------------- | -------------------------------------------------------------------------------------------------------- |
| `<schematic>` | The `schematic` or `collection:schematic` to generate. See the table below for the available schematics. |
| `<name>`      | The name of the generated component. If omitted, the schematic prompts for it.                           |

##### Schematics[#](/cli/usages#schematics)

| Name          | Alias | Description                                                                                                   |
| ------------- | ----- | ------------------------------------------------------------------------------------------------------------- |
| `app`         |       | Generate a new application within a monorepo (converting a standard mode structure to a monorepo).            |
| `library`     | `lib` | Generate a new library within a monorepo (converting a standard mode structure to a monorepo).                |
| `class`       | `cl`  | Generate a new class.                                                                                         |
| `controller`  | `co`  | Generate a controller declaration.                                                                            |
| `decorator`   | `d`   | Generate a custom decorator. As of v12, the generated decorator uses the `Reflector.createDecorator()` form.  |
| `filter`      | `f`   | Generate a filter declaration.                                                                                |
| `gateway`     | `ga`  | Generate a gateway declaration.                                                                               |
| `guard`       | `gu`  | Generate a guard declaration.                                                                                 |
| `interface`   | `itf` | Generate an interface.                                                                                        |
| `interceptor` | `itc` | Generate an interceptor declaration.                                                                          |
| `middleware`  | `mi`  | Generate a middleware declaration.                                                                            |
| `module`      | `mo`  | Generate a module declaration.                                                                                |
| `pipe`        | `pi`  | Generate a pipe declaration.                                                                                  |
| `provider`    | `pr`  | Generate a provider declaration.                                                                              |
| `resolver`    | `r`   | Generate a resolver declaration.                                                                              |
| `resource`    | `res` | Generate a new CRUD resource (TypeScript only). See the [CRUD (resource) generator](/recipes/crud-generator). |
| `service`     | `s`   | Generate a service declaration.                                                                               |

##### Options[#](/cli/usages#options-1)

| Option                          | Description                                                                                                              |
| ------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
| `--dry-run`                     | Report the changes that would be made, without changing the filesystem. Alias: `-d`                                      |
| `--project [project]`           | Project that the element should be added to. Alias: `-p`                                                                 |
| `--flat`                        | Do not generate a folder for the element.                                                                                |
| `--no-flat`                     | Generate a folder for the element.                                                                                       |
| `--collection [collectionName]` | Schematics collection to use. Pass the package name of an installed npm package that contains the schematic. Alias: `-c` |
| `--spec`                        | Generate spec files (default).                                                                                           |
| `--no-spec`                     | Skip generating spec files.                                                                                              |
| `--spec-file-suffix [suffix]`   | Use a custom suffix for spec files.                                                                                      |
| `--skip-import`                 | Skip importing the generated element into its closest module.                                                            |
| `--format`                      | Format generated files using Prettier.                                                                                   |
| `--type <type>`                 | (`resource` only) Transport layer: `rest`, `graphql-code-first`, `graphql-schema-first`, `microservice`, or `ws`.        |
| `--crud [value]`                | (`resource` only) Whether to generate CRUD entry points (`true` or `false`).                                             |

#### nest build[#](/cli/usages#nest-build)

Compiles an application or workspace into an output folder.

The `build` command is also responsible for:

* mapping paths (if you use path aliases) via `tsconfig-paths`
* annotating DTOs with OpenAPI decorators (if the `@nestjs/swagger` CLI plugin is enabled)
* annotating DTOs with GraphQL decorators (if the `@nestjs/graphql` CLI plugin is enabled)

```bash

$ nest build [name...] [options]
```

##### Arguments[#](/cli/usages#arguments-2)

| Argument    | Description                                                                                                               |
| ----------- | ------------------------------------------------------------------------------------------------------------------------- |
| `[name...]` | The name of the project to build. Pass several names to build several projects. If omitted, the default project is built. |

##### Options[#](/cli/usages#options-2)

| Option                     | Description                                                                                                                                                           |
| -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--path [path]`            | Path to `tsconfig` file. Alias `-p`                                                                                                                                   |
| `--config [path]`          | Path to `nest-cli` configuration file. Alias `-c`                                                                                                                     |
| `--watch`                  | Run in watch mode (live-reload). With the `tsc` compiler, you can type `rs` to restart the application (when the `manualRestart` option is set to `true`). Alias `-w` |
| `--builder [name]`         | Builder to use for compilation (`tsc`, `swc`, or `rspack`). Alias `-b`                                                                                                |
| `--webpack`                | Deprecated legacy flag for webpack-based compilation. Use `--builder rspack` or another explicit builder instead.                                                     |
| `--webpackPath [path]`     | Deprecated legacy path to a webpack configuration file. Use the configuration supported by your selected builder instead.                                             |
| `--rspackPath [path]`      | Path to a Rspack configuration file.                                                                                                                                  |
| `--tsc`                    | Force the use of `tsc` for compilation.                                                                                                                               |
| `--watchAssets`            | Watch non-TS files (assets such as `.graphql` files). See [Assets](/cli/monorepo#assets) for more details.                                                            |
| `--type-check`             | Enable type checking (when SWC is used).                                                                                                                              |
| `--no-type-check`          | Disable type checking (when SWC is used).                                                                                                                             |
| `--emit-declarations`      | Emit declaration files (`.d.ts`) when using the SWC builder.                                                                                                          |
| `--all`                    | Build all projects in a monorepo.                                                                                                                                     |
| `--parallel [concurrency]` | Build projects in parallel (use with `--all`). Pass a positive integer to limit concurrency, or omit the value for unlimited concurrency.                             |
| `--silent`                 | Suppress informational compiler logs.                                                                                                                                 |
| `--preserveWatchOutput`    | Keep outdated console output in watch mode instead of clearing the screen. (`tsc` watch mode only)                                                                    |

#### nest start[#](/cli/usages#nest-start)

Compiles and runs an application (or the default project in a workspace).

```bash

$ nest start [name] [options]
```

##### Arguments[#](/cli/usages#arguments-3)

| Argument | Description                                                           |
| -------- | --------------------------------------------------------------------- |
| `[name]` | The name of the project to run. If omitted, the default project runs. |

##### Options[#](/cli/usages#options-3)

| Option                      | Description                                                                                                                                                                                                                   |
| --------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--path [path]`             | Path to `tsconfig` file. Alias `-p`                                                                                                                                                                                           |
| `--config [path]`           | Path to `nest-cli` configuration file. Alias `-c`                                                                                                                                                                             |
| `--watch`                   | Run in watch mode (live-reload). Alias `-w`                                                                                                                                                                                   |
| `--builder [name]`          | Builder to use for compilation (`tsc`, `swc`, or `rspack`). Alias `-b`                                                                                                                                                        |
| `--preserveWatchOutput`     | Keep outdated console output in watch mode instead of clearing the screen. (`tsc` watch mode only)                                                                                                                            |
| `--watchAssets`             | Run in watch mode (live-reload), watching non-TS files (assets). See [Assets](/cli/monorepo#assets) for more details.                                                                                                         |
| `--debug [hostport]`        | Run in debug mode (with the `--inspect` flag). Alias `-d`                                                                                                                                                                     |
| `--webpack`                 | Deprecated legacy flag for webpack-based compilation. Use `--builder rspack` or another explicit builder instead.                                                                                                             |
| `--webpackPath [path]`      | Deprecated legacy path to a webpack configuration file. Use the configuration supported by your selected builder instead.                                                                                                     |
| `--rspackPath [path]`       | Path to a Rspack configuration file.                                                                                                                                                                                          |
| `--tsc`                     | Force the use of `tsc` for compilation.                                                                                                                                                                                       |
| `--type-check`              | Enable type checking (when SWC is used).                                                                                                                                                                                      |
| `--no-type-check`           | Disable type checking (when SWC is used).                                                                                                                                                                                     |
| `--emit-declarations`       | Emit declaration files (`.d.ts`) when using the SWC builder.                                                                                                                                                                  |
| `--silent`                  | Suppress informational compiler logs.                                                                                                                                                                                         |
| `--sourceRoot [sourceRoot]` | Root of the source code (overrides the `sourceRoot` setting in `nest-cli.json`).                                                                                                                                              |
| `--entryFile [entryFile]`   | Entry file to run (overrides the `entryFile` setting in `nest-cli.json`).                                                                                                                                                     |
| `--exec [binary]`           | Binary to run (default: `node`). Alias `-e`                                                                                                                                                                                   |
| `--no-shell`                | Do not spawn child processes within a shell (see the Node.js `child_process.spawn()` documentation).                                                                                                                          |
| `--env-file [path]`         | Load environment variables from a file, relative to the current directory, and expose them to the application on `process.env`. Repeat the option to load several files. A file that doesn't exist is skipped, with a notice. |
| `-- [key=value]`            | Command-line arguments that the application can read from `process.argv`.                                                                                                                                                     |

#### nest add[#](/cli/usages#nest-add)

Imports a library that has been packaged as a **nest library**, running its install schematic.

```bash

$ nest add <name> [options]
```

##### Arguments[#](/cli/usages#arguments-4)

| Argument | Description                        |
| -------- | ---------------------------------- |
| `<name>` | The name of the library to import. |

##### Options[#](/cli/usages#options-4)

| Option                | Description                                                                         |
| --------------------- | ----------------------------------------------------------------------------------- |
| `--dry-run`           | Report the changes that would be made, without changing the filesystem. Alias: `-d` |
| `--skip-install`      | Skip package installation. Alias: `-s`                                              |
| `--project [project]` | Project that the library should be added to. Alias: `-p`                            |

#### nest upgrade[#](/cli/usages#nest-upgrade)

Upgrades an existing project to the latest NestJS major version.

```bash

$ nest upgrade [options]
$ nest update [options]
```

##### Description[#](/cli/usages#description-1)

Run from the root of a NestJS v11 project, `nest upgrade` updates your dependencies to v12 and applies the mechanical parts of the migration:

* Refuses to run on Node.js releases that lack `require(esm)` (anything older than v20.19, or v22.x older than v22.12)
* Bumps every recognized `@nestjs/*` package to its v12-compatible major (`@nestjs/graphql`, `@nestjs/apollo`, and `@nestjs/mercurius` go to v14), and reports any other `@nestjs/*` package it doesn't recognize so you can review it yourself
* Bumps TypeScript to v6 (required by the v12 CLI and schematics), and raises `engines.node` in `package.json` to `>=20.19.0` if it declares a lower floor
* Migrates `nest-cli.json` off the deprecated `webpack` / `webpackConfigPath` options and onto `--builder rspack`, updating matching `package.json` scripts
* Renames the GraphQL `playground` option to `graphiql`, switches subscriptions from `subscriptions-transport-ws` to `graphql-ws`, and swaps the packages accordingly
* Replaces the legacy `nats` package with `@nats-io/transport-node` / `@nats-io/nats-core` and rewrites `nats` imports
* Moves library-specific `@nestjs/config` settings under `validationOptions.libraryOptions` and bumps Joi to v18 (the first release implementing Standard Schema)
* Bumps Jest to v30 (and `@types/jest` / `ts-jest` to matching releases) where present, and warns that Jest can `require()` the ESM-only v12 packages only on Node.js v24.9+
* Optionally installs and wires up [`@nestjs/observe`](/observability/overview). It prompts, unless you pass `--observe` or `--no-observe`
* Checks `tsconfig.json` and `tsconfig.build.json` for settings that TypeScript 6 or the ESM-only packages no longer support, such as a legacy `moduleResolution` or a missing `rootDir`
* Scans your sources and prints notes about behavior that changed but can't be migrated automatically, such as lifecycle hook ordering, refined pipe signatures, and structured logging params

The command finishes by installing the updated dependencies (unless `--skip-install` is passed) and printing a report of everything it changed, warned about, and left for you.

> **Warning**`nest upgrade` only bumps the **local**`@nestjs/cli` dependency. Update a globally installed CLI yourself with `npm i -g @nestjs/cli@latest`, and do it **before** running the upgrade, because the command itself ships with the CLI.

> **Hint** The command deliberately does not migrate your project to ESM, Vitest, or oxlint. Those are the defaults for newly generated v12 projects, but existing projects can adopt them on their own schedule. See the [migration guide](/migration-guide) for the full picture.

##### Options[#](/cli/usages#options-5)

| Option                          | Description                                                                                                                                                                                      |
| ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `--dry-run`                     | Report the changes that would be made, without changing the filesystem. Alias: `-d`                                                                                                              |
| `--skip-install`                | Skip package installation. Alias: `-s`                                                                                                                                                           |
| `--observe` / `--no-observe`    | Set up `@nestjs/observe`, or skip the setup, without being prompted. Omit both to be prompted in an interactive terminal (the prompt defaults to no). Without a terminal, Observe is not set up. |
| `--tag [tag]`                   | Use an npm dist-tag (e.g., `next`) instead of the default version ranges. Alias: `-t`                                                                                                            |
| `--collection [collectionName]` | Schematics collection to use. Pass the package name of an installed npm package that contains the schematic. Alias: `-c`                                                                         |

#### nest deploy[#](/cli/usages#nest-deploy)

Deploys your application to the cloud, powered by [Mau](https://mau.nestjs.com/).

```bash

$ nest deploy [mau-options]
```

##### Description[#](/cli/usages#description-2)

`nest deploy` is a thin wrapper around the Mau CLI. It locates the Mau binary and forwards every argument you pass to `mau deploy`, so any option Mau supports works here unchanged.

If Mau is not installed in your project, the command offers to add `@nestjs/mau` as a dev dependency and then continues. In a non-interactive environment (e.g., CI), the command fails instead of prompting, so install Mau explicitly first:

```bash

$ npm install --save-dev @nestjs/mau
```

Once Mau starts, it owns the terminal, so its output and prompts reach you directly. See the [Deployment chapter](/deployment#easy-deployment-with-mau) for what Mau does and how to configure it.

#### nest info[#](/cli/usages#nest-info)

Displays information about installed Nest packages and other useful system information. For example:

```bash

$ nest info
```

```bash

 _   _             _      ___  _____  _____  _     _____
| \ | |           | |    |_  |/  ___|/  __ \| |   |_   _|
|  \| |  ___  ___ | |_     | |\ `--. | /  \/| |     | |
| . ` | / _ \/ __|| __|    | | `--. \| |    | |     | |
| |\  ||  __/\__ \| |_ /\__/ //\__/ /| \__/\| |_____| |_
\_| \_/ \___||___/ \__|\____/ \____/  \____/\_____/\___/

[System Information]
OS Version     : macOS Sequoia 24.6.0
NodeJS Version : v22.12.0
NPM Version    : 10.9.0

[Nest CLI]
Nest CLI Version : 12.0.3

[Nest Platform Information]
platform-express version : 12.0.4
schematics version       : 12.0.4
testing version          : 12.0.4
common version           : 12.0.4
core version             : 12.0.4
cli version              : 12.0.3
```

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/cli/usages.md)

----
url: https://docs.nestjs.com/http/file-upload
----

### File upload and streaming

This chapter covers files in both directions: receiving files that clients upload, and [streaming files](/http/file-upload#streaming-files) back to clients.

To handle file uploads, Nest provides a built-in module based on the [multer](https://github.com/expressjs/multer) middleware package for Express. Multer handles data posted in the `multipart/form-data` format, which is primarily used to upload files with an HTTP `POST` request. The module is fully configurable, so you can adjust its behavior to your application's requirements.

> **Warning** Multer cannot process data that is not in the `multipart/form-data` format.

> **Hint** If your application runs on the `FastifyAdapter`, the same interceptors are available from the `@nestjs/platform-fastify` package, backed by [@fastify/multipart](https://github.com/fastify/fastify-multipart) instead of Multer, and the decorators and pipes described in this chapter work unchanged. Only the import path changes - see the [Fastify](/http/file-upload#fastify) section below.

For type safety, install the Multer type definitions:

```shell

$ npm i -D @types/multer
```

With this package installed, you can use the `Express.Multer.File` type (import the `Express` namespace with `import { Express } from 'express'`).

#### Basic example[#](/http/file-upload#basic-example)

To upload a single file, bind the `FileInterceptor()` interceptor to the route handler and extract the file from the request with the `@UploadedFile()` decorator.

JS TS

```typescript

@Post('upload')
@UseInterceptors(FileInterceptor('file'))
uploadFile(@UploadedFile() file: Express.Multer.File) {
  console.log(file);
}
```

```typescript

@Post('upload')
@UseInterceptors(FileInterceptor('file'))
@Bind(UploadedFile())
uploadFile(file) {
  console.log(file);
}
```

> **Hint** The `FileInterceptor()` decorator is exported from the `@nestjs/platform-express` package. The `@UploadedFile()` decorator is exported from `@nestjs/common`.

The `FileInterceptor()` decorator takes two arguments:

* `fieldName`: the name of the HTML form field that holds the file
* `options`: an optional object of type `MulterOptions`. This is the same object the Multer constructor accepts (see the [Multer options](https://github.com/expressjs/multer#multeropts)).

> **Warning**`FileInterceptor()` may not be compatible with third party cloud providers like Google Firebase or others.

#### File validation[#](/http/file-upload#file-validation)

You will often want to validate incoming file metadata, such as the file size or MIME type. To do so, create a [pipe](/pipes) and bind it to the parameter decorated with `@UploadedFile()`. The following example implements a basic file size validation pipe:

```typescript

import { PipeTransform, Injectable, ArgumentMetadata } from '@nestjs/common';

@Injectable()
export class FileSizeValidationPipe implements PipeTransform {
  transform(value: any, metadata: ArgumentMetadata) {
    // "value" is an object containing the file's attributes and metadata
    const oneKb = 1000;
    return value.size < oneKb;
  }
}
```

Use it together with the `FileInterceptor` as follows:

```typescript

@Post('file')
@UseInterceptors(FileInterceptor('file'))
uploadFileAndValidate(@UploadedFile(
  new FileSizeValidationPipe(),
  // other pipes can be added here
) file: Express.Multer.File, ) {
  return file;
}
```

For common cases, Nest provides a built-in pipe, `ParseFilePipe`, which also standardizes how new file validations are added:

```typescript

@Post('file')
uploadFileAndPassValidation(
  @Body() body: SampleDto,
  @UploadedFile(
    new ParseFilePipe({
      validators: [
        // ... Set of file validator instances here
      ]
    })
  )
  file: Express.Multer.File,
) {
  return {
    body,
    file: file.buffer.toString(),
  };
}
```

`ParseFilePipe` requires an array of file validators to execute. The validator interface is described below. The pipe also accepts two **optional** options:

|                       |                                                                                                   |
| --------------------- | ------------------------------------------------------------------------------------------------- |
| `errorHttpStatusCode` | The HTTP status code to be thrown in case **any** validator fails. Default is `400` (BAD REQUEST) |
| `exceptionFactory`    | A factory which receives the error message and returns an error.                                  |

Validators used by this pipe are either built-in implementations or your own subclasses of the abstract `FileValidator` class:

```typescript

export abstract class FileValidator<TValidationOptions = Record<string, any>> {
  constructor(protected readonly validationOptions: TValidationOptions) {}

  /**
   * Indicates if this file should be considered valid, according to the options passed in the constructor.
   * @param file the file from the request object
   */
  abstract isValid(file?: any): boolean | Promise<boolean>;

  /**
   * Builds an error message in case the validation fails.
   * @param file the file from the request object
   */
  abstract buildErrorMessage(file: any): string;
}
```

> **Hint** The `isValid()` method can be asynchronous. For type safety, type the `file` parameter as `Express.Multer.File` when you use Express (the default HTTP adapter).

A `FileValidator` receives the file object and validates it according to the options passed to its constructor. Nest provides two built-in implementations:

* `MaxFileSizeValidator` checks that the file's size is less than the provided value, in bytes.
* `FileTypeValidator` checks that the file's MIME type matches the given string or regular expression. By default, it determines the MIME type from the file content's [magic number](https://www.ibm.com/support/pages/what-magic-number).

The following snippet uses both validators with `ParseFilePipe`:

```typescript

@UploadedFile(
  new ParseFilePipe({
    validators: [
      new MaxFileSizeValidator({ maxSize: 1000 }),
      new FileTypeValidator({ fileType: 'image/jpeg' }),
    ],
  }),
)
file: Express.Multer.File,
```

> **Hint** If the list of validators grows long, define the array in a separate file and import it as a named constant, such as `fileValidators`.

Alternatively, compose the validators with the `ParseFilePipeBuilder` class. The builder instantiates each validator for you, so you pass only their options:

```typescript

@UploadedFile(
  new ParseFilePipeBuilder()
    .addFileTypeValidator({
      fileType: 'jpeg',
    })
    .addMaxSizeValidator({
      maxSize: 1000
    })
    .build({
      errorHttpStatusCode: HttpStatus.UNPROCESSABLE_ENTITY
    }),
)
file: Express.Multer.File,
```

> **Hint** A file is required by default. To make it optional, pass `fileIsRequired: false` in the options of the `build()` method (next to `errorHttpStatusCode`).

```typescript

@Post('upload')
@UseInterceptors(FilesInterceptor('files'))
uploadFile(@UploadedFiles() files: Array<Express.Multer.File>) {
  console.log(files);
}
```

```typescript

@Post('upload')
@UseInterceptors(FilesInterceptor('files'))
@Bind(UploadedFiles())
uploadFile(files) {
  console.log(files);
}
```

> **Hint** The `FilesInterceptor()` decorator is exported from the `@nestjs/platform-express` package. The `@UploadedFiles()` decorator is exported from `@nestjs/common`.

#### Validating an array of files[#](/http/file-upload#validating-an-array-of-files)

To validate an array of uploaded files, pass a pipe built with `ParseFilePipeBuilder` to the `@UploadedFiles()` decorator. The registered validators run against each file in the array.

JS TS

```typescript

@Post('upload')
@UseInterceptors(FilesInterceptor('files', 5))
uploadFiles(
  @UploadedFiles(
    new ParseFilePipeBuilder()
      .addFileTypeValidator({
        fileType: /^image\/(jpeg|png|gif)$/,
      })
      .addMaxSizeValidator({ maxSize: 5242880 })
      .build({
        errorHttpStatusCode: HttpStatus.UNPROCESSABLE_ENTITY,
      }),
  )
  files: Array<Express.Multer.File>,
) {
  console.log(files);
}
```

#### Multiple files[#](/http/file-upload#multiple-files)

To upload multiple files under different field names, use the `FileFieldsInterceptor()` decorator. It takes two arguments:

* `uploadedFields`: an array of objects, each with a required `name` property (the field name) and an optional `maxCount` property
* `options`: an optional `MulterOptions` object, as described above

When using `FileFieldsInterceptor()`, extract files from the `request` with the `@UploadedFiles()` decorator.

JS TS

```typescript

@Post('upload')
@UseInterceptors(FileFieldsInterceptor([
  { name: 'avatar', maxCount: 1 },
  { name: 'background', maxCount: 1 },
]))
uploadFile(@UploadedFiles() files: { avatar?: Express.Multer.File[], background?: Express.Multer.File[] }) {
  console.log(files);
}
```

```typescript

@Post('upload')
@Bind(UploadedFiles())
@UseInterceptors(FileFieldsInterceptor([
  { name: 'avatar', maxCount: 1 },
  { name: 'background', maxCount: 1 },
]))
uploadFile(files) {
  console.log(files);
}
```

#### Any files[#](/http/file-upload#any-files)

To accept files under any field names, use the `AnyFilesInterceptor()` decorator. It accepts an optional `options` object, as described above.

When using `AnyFilesInterceptor()`, extract files from the `request` with the `@UploadedFiles()` decorator.

JS TS

```typescript

@Post('upload')
@UseInterceptors(AnyFilesInterceptor())
uploadFile(@UploadedFiles() files: Array<Express.Multer.File>) {
  console.log(files);
}
```

```typescript

@Post('upload')
@Bind(UploadedFiles())
@UseInterceptors(AnyFilesInterceptor())
uploadFile(files) {
  console.log(files);
}
```

#### No files[#](/http/file-upload#no-files)

To accept `multipart/form-data` without allowing file uploads, use the `NoFilesInterceptor`. It sets the multipart fields as properties of the request body. A request that contains files is rejected with a `BadRequestException`.

```typescript

@Post('upload')
@UseInterceptors(NoFilesInterceptor())
handleMultiPartData(@Body() body) {
  console.log(body)
}
```

#### Default options[#](/http/file-upload#default-options)

You can pass Multer options to each file interceptor, as described above. To set default options instead, call the static `register()` method when you import the `MulterModule`. It accepts all [Multer options](https://github.com/expressjs/multer#multeropts).

```typescript

MulterModule.register({
  dest: './upload',
});
```

> **Hint** The `MulterModule` class is exported from the `@nestjs/platform-express` package.

Options passed to a file interceptor take precedence over these defaults. Starting with NestJS v12.0.4, the two `limits` objects are merged key by key, so a route that sets only `limits.fileSize` keeps a default such as `limits.files`. If one of them is a function, the interceptor's `limits` replaces the default one entirely.

#### Async configuration[#](/http/file-upload#async-configuration)

To set `MulterModule` options asynchronously instead of statically, use the `registerAsync()` method. As with most dynamic modules, it supports several techniques for async configuration.

One technique is to use a factory function:

```typescript

MulterModule.registerAsync({
  useFactory: () => ({
    dest: './upload',
  }),
});
```

Like other [factory providers](/fundamentals/custom-providers#factory-providers-usefactory), the factory function can be `async` and can inject dependencies through `inject`.

```typescript

MulterModule.registerAsync({
  imports: [ConfigModule],
  useFactory: async (configService: ConfigService) => ({
    dest: configService.get<string>('MULTER_DEST'),
  }),
  inject: [ConfigService],
});
```

Alternatively, you can configure the `MulterModule` using a class instead of a factory, as shown below:

```typescript

MulterModule.registerAsync({
  useClass: MulterConfigService,
});
```

The construction above instantiates `MulterConfigService` inside `MulterModule` and calls its `createMulterOptions()` method to obtain the options object. For this to work, `MulterConfigService` must implement the `MulterOptionsFactory` interface:

```typescript

@Injectable()
class MulterConfigService implements MulterOptionsFactory {
  createMulterOptions(): MulterModuleOptions {
    return {
      dest: './upload',
    };
  }
}
```

If you want to reuse an existing options provider instead of creating a private copy inside the `MulterModule`, use the `useExisting` syntax.

```typescript

MulterModule.registerAsync({
  imports: [ConfigModule],
  useExisting: ConfigService,
});
```

You can also pass `extraProviders` to the `registerAsync()` method. These providers are merged with the module's providers.

```typescript

MulterModule.registerAsync({
  imports: [ConfigModule],
  useClass: ConfigService,
  extraProviders: [MyAdditionalProvider],
});
```

This is useful when the factory function or the class constructor needs additional dependencies.

#### Memory usage and storage[#](/http/file-upload#memory-usage-and-storage)

By default, Multer uses its in-memory storage engine (`memoryStorage()`): every uploaded file is read completely into memory and exposed as a `Buffer` on `file.buffer` before your route handler runs. This is convenient for small files (avatars or CSV imports), but each in-flight upload occupies as much memory as its size, so large files or many concurrent uploads can quickly exhaust the memory of your process.

> **Warning** Multer does not limit the size of uploaded files by default. When you keep files in memory, always set `limits.fileSize`.

##### File size limit[#](/http/file-upload#file-size-limit)

Use the `limits` option to reject files that are too large. When a limit is exceeded, Nest responds with a `413 File too large` error (for `fileSize`) or `400 Bad Request` (for other limits, such as `files`) and the route handler is not called.

```typescript

@Post('upload')
@UseInterceptors(
  FileInterceptor('file', {
    limits: { fileSize: 5 * 1024 * 1024 }, // 5 MB
  }),
)
uploadFile(@UploadedFile() file: Express.Multer.File) {
  console.log(file.size);
}
```

> **Hint** Unlike `MaxFileSizeValidator`, which runs after the whole file has been received, `limits.fileSize` makes Multer stop storing the file and reject the request as soon as the limit is reached, so oversized files never fully reach memory or disk. See the [Multer limits](https://github.com/expressjs/multer#limits) for the full list of options.

##### Field name limits[#](/http/file-upload#field-name-limits)

Field names such as `user[address][city]` or `tags[2]` build nested objects and arrays in the request body. Two limits bound them: `fieldNestingDepth`, the number of nesting levels (`a[b][c]` has 2), and `fieldArrayIndexLimit`, the highest array index (`tags[2]` uses index 2). A request that exceeds either one is rejected with a `400 Bad Request` response. Starting with NestJS v12.1.4, they default to 32 and 1000 respectively (Multer leaves them unlimited), so that a single request cannot build an arbitrarily deep body or a huge array. Set a limit to `Infinity` to lift it.

##### Disk storage[#](/http/file-upload#disk-storage)

To keep memory usage constant regardless of file size, write uploads to disk with the `diskStorage()` engine. Multer then streams each file to disk as it arrives, and the file object exposes `destination`, `filename` and `path` instead of `buffer`.

```typescript

import { extname } from 'node:path';
import { randomUUID } from 'node:crypto';
import { diskStorage } from 'multer';

@Post('upload')
@UseInterceptors(
  FileInterceptor('file', {
    storage: diskStorage({
      destination: './uploads',
      filename: (req, file, cb) => {
        cb(null, `${randomUUID()}${extname(file.originalname)}`);
      },
    }),
    limits: { fileSize: 1024 * 1024 * 1024 }, // 1 GB
  }),
)
uploadFile(@UploadedFile() file: Express.Multer.File) {
  console.log(file.path);
}
```

> **Hint** The `diskStorage()` and `memoryStorage()` functions are exported from the `multer` package. As a shorthand, pass `dest: './uploads'` to store files on disk under random names. If you pass a `destination` function instead of a string, you are responsible for creating the directory.

To apply the same storage and limits to every file interceptor in a module, set them as [default options](/http/file-upload#default-options) or with [async configuration](/http/file-upload#async-configuration).

Files stored on disk are not removed automatically once your route handler has run. Delete them (for example with `unlink()` from `fs/promises`) once you have processed them, including when processing fails. Starting with NestJS v12.1.4, if a pipe rejects the request (for example, because `ParseFilePipe` validation fails), the route handler does not run, and the stored files are removed once the error response has been sent.

##### Sending files to external storage[#](/http/file-upload#sending-files-to-external-storage)

To store uploads in S3, Cloudflare R2 or another external store without buffering them in memory or writing a temporary file, use a storage engine that streams each file to its destination as it arrives. The [`@nestjs/storage`](/application/file-storage) package provides one, `uploadToDisk()`, which you pass as the `storage` option of `FileInterceptor()`. See [Upload product photos](/application/file-storage#upload-product-photos). Any other Multer [storage engine](https://github.com/expressjs/multer/blob/main/StorageEngine.md) works the same way.

> **Hint** On the `FastifyAdapter`, you can also receive the file as a stream inside the route handler with `FileStreamInterceptor()`. See [Streaming uploads](/http/file-upload#streaming-uploads).

#### Fastify[#](/http/file-upload#fastify)

Starting with NestJS v12.1, applications running on the `FastifyAdapter` (see [Performance (Fastify)](/http/performance)) can handle file uploads with the same API, backed by the [@fastify/multipart](https://github.com/fastify/fastify-multipart) plugin instead of Multer. The interceptors described in this chapter take the same arguments and options, populate the request in the same way, and fail with the same error responses, while `@UploadedFile()`, `@UploadedFiles()`, `ParseFilePipe`, `ParseFilePipeBuilder` and the built-in file validators work unchanged.

First, install the plugin:

```bash

$ npm i @fastify/multipart
```

There is no need to register it: the `FastifyAdapter` registers the plugin automatically as soon as your application uses one of the upload interceptors (in applications that don't, it is not registered at all). If the package is not installed, the application fails to start with an error naming it.

Next, import the interceptors from `@nestjs/platform-fastify/multipart` instead of `@nestjs/platform-express`. The rest of the controller stays the same, except that files are typed as `UploadedMultipartFile`:

```typescript

import {
  Controller,
  FileTypeValidator,
  MaxFileSizeValidator,
  ParseFilePipe,
  Post,
  UploadedFile,
  UseInterceptors,
} from '@nestjs/common';
import {
  FileInterceptor,
  UploadedMultipartFile,
} from '@nestjs/platform-fastify/multipart';

@Controller('files')
export class FilesController {
  @Post('upload')
  @UseInterceptors(FileInterceptor('file'))
  uploadFile(
    @UploadedFile(
      new ParseFilePipe({
        validators: [
          new MaxFileSizeValidator({ maxSize: 1000 }),
          new FileTypeValidator({ fileType: 'image/png' }),
        ],
      }),
    )
    file: UploadedMultipartFile,
  ) {
    console.log(file);
  }
}
```

> **Hint** Everything exported from `@nestjs/platform-fastify/multipart` is also re-exported from the `@nestjs/platform-fastify` package root. The interceptors only work with the `FastifyAdapter`: with the `ExpressAdapter`, the application fails to start, so keep importing them from `@nestjs/platform-express` there.

The table below maps the Express API to its Fastify counterpart:

| `@nestjs/platform-express`                                                                                            | `@nestjs/platform-fastify/multipart`                                                     |
| --------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- |
| `FileInterceptor()`, `FilesInterceptor()`, `FileFieldsInterceptor()`, `AnyFilesInterceptor()`, `NoFilesInterceptor()` | Same names, arguments and options                                                        |
| `MulterOptions`                                                                                                       | `MultipartOptions`                                                                       |
| `MulterModule`, `MulterOptionsFactory`, `createMulterOptions()`                                                       | `MultipartModule`, `MultipartOptionsFactory`, `createMultipartOptions()`                 |
| `Express.Multer.File`                                                                                                 | `UploadedMultipartFile`                                                                  |
| `memoryStorage()` and `diskStorage()` from the `multer` package                                                       | `memoryStorage()` and `diskStorage()`                                                    |
| -                                                                                                                     | `FileStreamInterceptor()` (see [Streaming uploads](/http/file-upload#streaming-uploads)) |

The interceptor options are the ones Multer accepts: `dest`, `storage`, `limits` (an object, or a function that receives the request and returns one), `fileFilter`, `preservePath` and `defParamCharset`. Uploaded files are exposed as `req.file` or `req.files` and text fields as `req.body`, exactly as with Multer. `UploadedMultipartFile` has the same shape as `Express.Multer.File`, so you don't need the `@types/multer` package.

`MultipartModule` sets default options for the upload interceptors of the module that imports it, just like `MulterModule`. Its `registerAsync()` method accepts `useFactory` (with `imports` and `inject`), `useClass` and `useExisting`.

```typescript

MultipartModule.register({
  dest: './upload',
});
```

##### Storage[#](/http/file-upload#storage)

As with Multer, files are kept in memory (in `file.buffer`) unless you set the `dest` or `storage` option. `dest` writes each file to the given folder under a random name, and the `diskStorage()` function lets you choose the folder and the file name. Disk storage sets `destination`, `filename` and `path` on the file instead of `buffer`.

```typescript

import {
  diskStorage,
  FileInterceptor,
  UploadedMultipartFile,
} from '@nestjs/platform-fastify/multipart';

@Post('upload')
@UseInterceptors(
  FileInterceptor('file', {
    storage: diskStorage({
      destination: './uploads',
      filename: (req, file, callback) =>
        callback(null, `${Date.now()}-${file.originalname}`),
    }),
  }),
)
uploadFile(@UploadedFile() file: UploadedMultipartFile) {
  console.log(file.path);
}
```

Storage engines follow Multer's storage engine contract (`_handleFile()` and `_removeFile()`), so Multer's own `multer.diskStorage()` and third-party Multer storage engines can be passed as `storage` unchanged.

##### Limits[#](/http/file-upload#limits)

`@fastify/multipart` applies stricter defaults than Multer. Unless configured otherwise, the maximum file size (`fileSize`) is the Fastify `bodyLimit` (1 MiB by default) and the maximum number of parts (`parts`) is 1000, whereas Multer limits neither. Larger files are rejected with a `413 File too large` response. You can raise these limits:

* for a single route, with the `limits` option of the interceptor
* for a module, with `MultipartModule.register()` or `registerAsync()`
* for the whole application, with the `multipart` option of the `FastifyAdapter`, which passes options to the plugin itself:

```typescript

const app = await NestFactory.create<NestFastifyApplication>(
  AppModule,
  new FastifyAdapter({
    multipart: { limits: { fileSize: 10 * 1024 * 1024 } },
  }),
);
```

```typescript

import multipart from '@fastify/multipart';

const app = await NestFactory.create<NestFastifyApplication>(
  AppModule,
  new FastifyAdapter(),
);
await app.register(multipart, { limits: { fileSize: 10 * 1024 * 1024 } });
```

> **Warning** Registering `@fastify/multipart` directly on the Fastify instance (`app.getHttpAdapter().getInstance().register(multipart)`), or passing a dynamic `import()` of it to `app.register()`, only works before `app.init()` (which `app.listen()` calls for you). After that, the adapter has already registered the plugin for your upload interceptors, and Fastify fails with an `FST_ERR_DEC_ALREADY_PRESENT` error. Use `app.register(multipart)` or the `multipart` option instead, or set the option to `false` to manage the plugin yourself.

##### Streaming uploads[#](/http/file-upload#streaming-uploads)

The interceptors described so far store every file (in memory or on disk) before the route handler runs. To process a file as it arrives instead, for example to pipe a large upload to its final destination, use `FileStreamInterceptor()`, which is available on Fastify only. It takes the name of the field that holds the file and an optional options object (the same as for the other interceptors, except `dest` and `storage`), and hands the route handler a file with a `stream` property in place of `buffer`:

```typescript

import { randomUUID } from 'node:crypto';
import { createWriteStream } from 'node:fs';
import { join } from 'node:path';
import { pipeline } from 'node:stream/promises';
import {
  FileStreamInterceptor,
  MultipartFileStream,
} from '@nestjs/platform-fastify/multipart';

@Post('upload')
@UseInterceptors(
  FileStreamInterceptor('file', { limits: { fileSize: 1024 * 1024 * 1024 } }),
)
async uploadFile(@UploadedFile() file: MultipartFileStream, @Body() body) {
  const path = join('uploads', randomUUID());
  await pipeline(file.stream, createWriteStream(path));
  return { originalname: file.originalname, path, body };
}
```

```typescript

@Controller('file')
export class FileController {
  @Get()
  getFile(@Res() res: Response) {
    const file = createReadStream(join(process.cwd(), 'package.json'));
    file.pipe(res);
  }
}
```

With this approach, the handler takes over the response, so post-controller [interceptor](/interceptors) logic no longer runs. Instead, return a `StreamableFile` instance, and Nest pipes it into the response for you.

> **Note** Streaming files applies to **HTTP applications**. The examples below do not apply to GraphQL or microservice applications.

##### Streamable file class[#](/http/file-upload#streamable-file-class)

A `StreamableFile` holds the content to be sent. Its constructor accepts either a `Readable` stream or a `Uint8Array` (including a `Buffer`). The following example returns the `package.json` file instead of a JSON response. The same approach works for images, documents, and any other file type:

```typescript

import { Controller, Get, StreamableFile } from '@nestjs/common';
import { createReadStream } from 'node:fs';
import { join } from 'node:path';

@Controller('file')
export class FileController {
  @Get()
  getFile(): StreamableFile {
    const file = createReadStream(join(process.cwd(), 'package.json'));
    return new StreamableFile(file);
  }
}
```

> **Hint** The `StreamableFile` class is exported from the `@nestjs/common` package.

Neither the `ClassSerializerInterceptor` nor the `StandardSchemaSerializerInterceptor`[serializes](/application/serialization)`StreamableFile` responses.

##### Response headers[#](/http/file-upload#response-headers)

By default, the `Content-Type` response header is `application/octet-stream`. To change it, and to set the `Content-Disposition` and `Content-Length` headers, pass the `type`, `disposition`, and `length` options to the `StreamableFile` constructor:

```typescript

@Get()
getFile(): StreamableFile {
  const file = createReadStream(join(process.cwd(), 'package.json'));
  return new StreamableFile(file, {
    type: 'application/json',
    disposition: 'attachment; filename="package.json"',
  });
}
```

When the content is a `Uint8Array`, `length` defaults to its size. For streams, set `length` yourself if you know the size in advance.

Headers with static values can also be set with the [`@Header()`](/controllers#response-headers) decorator:

```typescript

@Get()
@Header('Content-Type', 'application/json')
@Header('Content-Disposition', 'attachment; filename="package.json"')
getFile(): StreamableFile {
  const file = createReadStream(join(process.cwd(), 'package.json'));
  return new StreamableFile(file);
}
```

To compute headers at runtime, inject the response object with `passthrough` enabled, so that Nest still sends the returned `StreamableFile`:

```typescript

import type { Response } from 'express';

@Get()
getFile(@Res({ passthrough: true }) res: Response): StreamableFile {
  const file = createReadStream(join(process.cwd(), 'package.json'));
  res.set({
    'Content-Type': 'application/json',
    'Content-Disposition': 'attachment; filename="package.json"',
  });
  return new StreamableFile(file);
}
```

##### Stream errors[#](/http/file-upload#stream-errors)

With the Express adapter, if the stream emits an error before any data has been sent, the client receives a `400 Bad Request` response, and the error is logged. Starting with NestJS v12.1.4, the response body no longer contains the error message, which may include the path of the file. If data has already been sent, the response is ended. To customize this behavior, pass a handler to the `setErrorHandler()` method:

```typescript

@Get()
getReport(): StreamableFile {
  const file = createReadStream(join(process.cwd(), 'report.pdf'));
  return new StreamableFile(file).setErrorHandler((err, res) => {
    if (res.headersSent) {
      res.end();
      return;
    }
    res.statusCode = 404;
    res.send('Report not found');
  });
}
```

The `setErrorLogger()` method replaces the function that logs errors: those the default error handler answers, and those the response stream emits while the file is being written to it.

> **Note** The error handler and the error logger apply to the Express adapter. With the Fastify adapter, a stream error is handled by the [exceptions layer](/exception-filters), so by default the client receives a `500 Internal Server Error` response.

----
url: https://docs.nestjs.com/v10/security/encryption-and-hashing
----

* [Encryption and Hashing](https://docs.nestjs.com/v10/security/encryption-and-hashing#encryption-and-hashing)
* [Encryption](https://docs.nestjs.com/v10/security/encryption-and-hashing#encryption)
* [Hashing](https://docs.nestjs.com/v10/security/encryption-and-hashing#hashing)

```typescript

import { createCipheriv, randomBytes, scrypt } from 'crypto';
import { promisify } from 'util';

const iv = randomBytes(16);
const password = 'Password used to generate key';

// The key length is dependent on the algorithm.
// In this case for aes256, it is 32 bytes.
const key = (await promisify(scrypt)(password, 'salt', 32)) as Buffer;
const cipher = createCipheriv('aes-256-ctr', key, iv);

const textToEncrypt = 'Nest';
const encryptedText = Buffer.concat([
  cipher.update(textToEncrypt),
  cipher.final(),
]);
```

Now to decrypt `encryptedText` value:

```typescript

import { createDecipheriv } from 'crypto';

const decipher = createDecipheriv('aes-256-ctr', key, iv);
const decryptedText = Buffer.concat([
  decipher.update(encryptedText),
  decipher.final(),
]);
```

#### Hashing[#](/security/encryption-and-hashing#hashing)

For hashing, we recommend using either the [bcrypt](https://www.npmjs.com/package/bcrypt) or [argon2](https://www.npmjs.com/package/argon2) packages. Nest itself does not provide any additional wrappers on top of these modules to avoid introducing unnecessary abstractions (making the learning curve short).

As an example, let's use `bcrypt` to hash a random password.

First install required packages:

```shell

$ npm i bcrypt
$ npm i -D @types/bcrypt
```

Once the installation is complete, you can use the `hash` function, as follows:

```typescript

import * as bcrypt from 'bcrypt';

const saltOrRounds = 10;
const password = 'random_password';
const hash = await bcrypt.hash(password, saltOrRounds);
```

To generate a salt, use the `genSalt` function:

```typescript

const salt = await bcrypt.genSalt();
```

To compare/check a password, use the `compare` function:

```typescript

const isMatch = await bcrypt.compare(password, hash);
```

You can read more about available functions [here](https://www.npmjs.com/package/bcrypt).

----
url: https://docs.nestjs.com/v11/openapi/types-and-parameters
----

* [Types and parameters](https://docs.nestjs.com/v11/openapi/types-and-parameters#types-and-parameters)
* [Arrays](https://docs.nestjs.com/v11/openapi/types-and-parameters#arrays)
* [Circular dependencies](https://docs.nestjs.com/v11/openapi/types-and-parameters#circular-dependencies)
* [Generics and interfaces](https://docs.nestjs.com/v11/openapi/types-and-parameters#generics-and-interfaces)
* [Enums](https://docs.nestjs.com/v11/openapi/types-and-parameters#enums)
* [Enums schema](https://docs.nestjs.com/v11/openapi/types-and-parameters#enums-schema)
* [Property value examples](https://docs.nestjs.com/v11/openapi/types-and-parameters#property-value-examples)
* [Raw definitions](https://docs.nestjs.com/v11/openapi/types-and-parameters#raw-definitions)
* [Extra models](https://docs.nestjs.com/v11/openapi/types-and-parameters#extra-models)
* [oneOf, anyOf, allOf](https://docs.nestjs.com/v11/openapi/types-and-parameters#oneof-anyof-allof)
* [Schema name and description](https://docs.nestjs.com/v11/openapi/types-and-parameters#schema-name-and-description)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/openapi/types-and-parameters.md "Suggest Edits")

### 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:

```typescript

@Post()
async create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

> **Hint** To explicitly set the body definition use the `@ApiBody()` decorator (imported from the `@nestjs/swagger` package).

Based on the `CreateCatDto`, the following model definition Swagger UI will be created:

As you can see, the definition is empty although the class has a few declared properties. In order to make the class properties visible to the `SwaggerModule`, we have to either annotate them with the `@ApiProperty()` decorator or use the CLI plugin (read more in the **Plugin** section) which will do it automatically:

```typescript

import { ApiProperty } from '@nestjs/swagger';

export class CreateCatDto {
  @ApiProperty()
  name: string;

  @ApiProperty()
  age: number;

  @ApiProperty()
  breed: string;
}
```

> **Hint** Instead of manually annotating each property, consider using the Swagger plugin (see [Plugin](/v11/openapi/cli-plugin) section) which will automatically provide this for you.

Let's open the browser and verify the generated `CreateCatDto` model:

In addition, the `@ApiProperty()` decorator allows setting various [Schema Object](https://swagger.io/specification/#schemaObject) properties:

```typescript

@ApiProperty({
  description: 'The age of a cat',
  minimum: 1,
  default: 1,
})
age: number;
```

> **Hint** Instead of explicitly typing the `@ApiProperty({ required: false })` you can use the `@ApiPropertyOptional()` short-hand decorator.

In order to explicitly set the type of the property, use the `type` key:

```typescript

@ApiProperty({
  type: Number,
})
age: number;
```

#### Arrays[#](/openapi/types-and-parameters#arrays)

When the property is an array, we must manually indicate the array type as shown below:

```typescript

@ApiProperty({ type: [String] })
names: string[];
```

> **Hint** Consider using the Swagger plugin (see [Plugin](/v11/openapi/cli-plugin) section) which will automatically detect arrays.

```typescript

@ApiProperty({ type: () => Node })
node: Node;
```

> **Hint** Consider using the Swagger plugin (see [Plugin](/v11/openapi/cli-plugin) section) which will automatically detect circular dependencies.

#### Generics and interfaces[#](/openapi/types-and-parameters#generics-and-interfaces)

Since TypeScript does not store metadata about generics or interfaces, when you use them in your DTOs, `SwaggerModule` may not be able to properly generate model definitions at runtime. For instance, the following code won't be correctly inspected by the Swagger module:

```typescript

createBulk(@Body() usersDto: CreateUserDto[])
```

In order to overcome this limitation, you can set the type explicitly:

```typescript

@ApiBody({ type: [CreateUserDto] })
createBulk(@Body() usersDto: CreateUserDto[])
```

#### Enums[#](/openapi/types-and-parameters#enums)

To identify an `enum`, we must manually set the `enum` property on the `@ApiProperty` with an array of values.

```typescript

@ApiProperty({ enum: ['Admin', 'Moderator', 'User']})
role: UserRole;
```

Alternatively, define an actual TypeScript enum as follows:

```typescript

export enum UserRole {
  Admin = 'Admin',
  Moderator = 'Moderator',
  User = 'User',
}
```

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

```typescript

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

With `isArray` set to **true**, the `enum` can be selected as a **multi-select**:

#### Enums schema[#](/openapi/types-and-parameters#enums-schema)

By default, the `enum` property will add a raw definition of [Enum](https://swagger.io/docs/specification/data-models/enums/) on the `parameter`.

```yaml

- breed:
    type: 'string'
    enum:
      - Persian
      - Tabby
      - Siamese
```

The above specification works fine for most cases. However, if you are utilizing a tool that takes the specification as **input** and generates **client-side** code, you might run into a problem with the generated code containing duplicated `enums`. Consider the following code snippet:

```typescript

// generated client-side code
export class CatDetail {
  breed: CatDetailEnum;
}

export class CatInformation {
  breed: CatInformationEnum;
}

export enum CatDetailEnum {
  Persian = 'Persian',
  Tabby = 'Tabby',
  Siamese = 'Siamese',
}

export enum CatInformationEnum {
  Persian = 'Persian',
  Tabby = 'Tabby',
  Siamese = 'Siamese',
}
```

> **Hint** The above snippet is generated using a tool called [NSwag](https://github.com/RicoSuter/NSwag).

You can see that now you have two `enums` that are exactly the same. To address this issue, you can pass an `enumName` along with the `enum` property in your decorator.

```typescript

export class CatDetail {
  @ApiProperty({ enum: CatBreed, enumName: 'CatBreed' })
  breed: CatBreed;
}
```

The `enumName` property enables `@nestjs/swagger` to turn `CatBreed` into its own `schema` which in turns makes `CatBreed` enum reusable. The specification will look like the following:

```yaml

CatDetail:
  type: 'object'
  properties:
    ...
    - breed:
        schema:
          $ref: '#/components/schemas/CatBreed'
CatBreed:
  type: string
  enum:
    - Persian
    - Tabby
    - Siamese
```

> **Hint** Any **decorator** that takes `enum` as a property will also take `enumName`.

#### Property value examples[#](/openapi/types-and-parameters#property-value-examples)

You can set a single example for a property by using the `example` key, like this:

```typescript

@ApiProperty({
  example: 'persian',
})
breed: string;
```

If you want to provide multiple examples, you can use the `examples` key by passing in an object structured like this:

```typescript

@ApiProperty({
  examples: {
    Persian: { value: 'persian' },
    Tabby: { value: 'tabby' },
    Siamese: { value: 'siamese' },
    'Scottish Fold': { value: 'scottish_fold' },
  },
})
breed: string;
```

#### Raw definitions[#](/openapi/types-and-parameters#raw-definitions)

In certain cases, such as deeply nested arrays or matrices, you may need to manually define your type:

```typescript

@ApiProperty({
  type: 'array',
  items: {
    type: 'array',
    items: {
      type: 'number',
    },
  },
})
coords: number[][];
```

You can also specify raw object schemas, like this:

```typescript

@ApiProperty({
  type: 'object',
  properties: {
    name: {
      type: 'string',
      example: 'Error'
    },
    status: {
      type: 'number',
      example: 400
    }
  },
  required: ['name', 'status']
})
rawDefinition: Record<string, any>;
```

To manually define input/output content in controller classes, use the `schema` property:

```typescript

@ApiBody({
  schema: {
    type: 'array',
    items: {
      type: 'array',
      items: {
        type: 'number',
      },
    },
  },
})
async create(@Body() coords: number[][]) {}
```

#### Extra models[#](/openapi/types-and-parameters#extra-models)

To define additional models that are not directly referenced in your controllers but should be inspected by the Swagger module, use the `@ApiExtraModels()` decorator:

```typescript

@ApiExtraModels(ExtraModel)
export class CreateCatDto {}
```

> **Hint** You only need to use `@ApiExtraModels()` once for a specific model class.

Alternatively, you can pass an options object with the `extraModels` property specified to the `SwaggerModule.createDocument()` method, as follows:

```typescript

const documentFactory = () =>
  SwaggerModule.createDocument(app, options, {
    extraModels: [ExtraModel],
  });
```

To get a reference (`$ref`) to your model, use the `getSchemaPath(ExtraModel)` function:

```typescript

'application/vnd.api+json': {
   schema: { $ref: getSchemaPath(ExtraModel) },
},
```

#### oneOf, anyOf, allOf[#](/openapi/types-and-parameters#oneof-anyof-allof)

To combine schemas, you can use the `oneOf`, `anyOf` or `allOf` keywords ([read more](https://swagger.io/docs/specification/data-models/oneof-anyof-allof-not/)).

```typescript

@ApiProperty({
  oneOf: [
    { $ref: getSchemaPath(Cat) },
    { $ref: getSchemaPath(Dog) },
  ],
})
pet: Cat | Dog;
```

If you want to define a polymorphic array (i.e., an array whose members span multiple schemas), you should use a raw definition (see above) to define your type by hand.

```typescript

type Pet = Cat | Dog;

@ApiProperty({
  type: 'array',
  items: {
    oneOf: [
      { $ref: getSchemaPath(Cat) },
      { $ref: getSchemaPath(Dog) },
    ],
  },
})
pets: Pet[];
```

> **Hint** The `getSchemaPath()` function is imported from `@nestjs/swagger`.

Both `Cat` and `Dog` must be defined as extra models using the `@ApiExtraModels()` decorator (at the class-level).

#### Schema name and description[#](/openapi/types-and-parameters#schema-name-and-description)

As you may have noticed, the name of the generated schema is based on the name of the original model class (for example, the `CreateCatDto` model generates a `CreateCatDto` schema). If you'd like to change the schema name, you can use the `@ApiSchema()` decorator.

Here’s an example:

```typescript

@ApiSchema({ name: 'CreateCatRequest' })
class CreateCatDto {}
```

The model above will be translated into the `CreateCatRequest` schema.

By default, no description is added to the generated schema. You can add one using the `description` attribute:

```typescript

@ApiSchema({ description: 'Description of the CreateCatDto schema' })
class CreateCatDto {}
```

That way, the description will be included in the schema, as follows:

```yaml

schemas:
  CreateCatDto:
    type: object
    description: Description of the CreateCatDto schema
```

----
url: https://docs.nestjs.com/microservices/grpc
----

[Skip to content](#content)

On this page

* [gRPC](https://docs.nestjs.com/microservices/grpc#grpc)
* [Installation](https://docs.nestjs.com/microservices/grpc#installation)
* [Overview](https://docs.nestjs.com/microservices/grpc#overview)
* [Options](https://docs.nestjs.com/microservices/grpc#options)
* [Sample gRPC service](https://docs.nestjs.com/microservices/grpc#sample-grpc-service)
* [Client](https://docs.nestjs.com/microservices/grpc#client)
* [Exception handling](https://docs.nestjs.com/microservices/grpc#exception-handling)
* [Example](https://docs.nestjs.com/microservices/grpc#example)
* [gRPC Reflection](https://docs.nestjs.com/microservices/grpc#grpc-reflection)
* [gRPC Streaming](https://docs.nestjs.com/microservices/grpc#grpc-streaming)
* [Streaming sample](https://docs.nestjs.com/microservices/grpc#streaming-sample)
* [Subject strategy](https://docs.nestjs.com/microservices/grpc#subject-strategy)
* [Call stream handler](https://docs.nestjs.com/microservices/grpc#call-stream-handler)
* [Health checks](https://docs.nestjs.com/microservices/grpc#health-checks)
* [gRPC Metadata](https://docs.nestjs.com/microservices/grpc#grpc-metadata)

[](https://srv.carbonads.net/ads/click/x/GTND4277CVSD5KJUCAYLYKQUF67D62QUF6BIKZ3JCAAI623WC6YICK3KFTSI453WC6SIPK7ICVADE23MCESDE27KC6SILKJUCT7DEK3EHJNCLSIZ)[Use Agent Studio, Agent Builder, leading models in Gemini Enterprise Agent Platform. ](https://srv.carbonads.net/ads/click/x/GTND4277CVSD5KJUCAYLYKQUF67D62QUF6BIKZ3JCAAI623WC6YICK3KFTSI453WC6SIPK7ICVADE23MCESDE27KC6SILKJUCT7DEK3EHJNCLSIZ)[ads via Carbon](http://carbonads.net/?utm_source=nestjscom\&utm_medium=ad_via_link\&utm_campaign=in_unit\&utm_term=carbon)

### gRPC

[gRPC](https://github.com/grpc/grpc-node) is a modern, open source, high-performance RPC framework that can run in any environment. It connects services in and across data centers, with pluggable support for load balancing, tracing, health checking, and authentication.

Like many RPC systems, gRPC is based on defining a service in terms of functions (methods) that can be called remotely. For each method, you define the parameters and return types. Services, parameters, and return types are defined in `.proto` files using Google's open source, language-neutral [protocol buffers](https://protobuf.dev) mechanism.

With the gRPC transporter, Nest uses `.proto` files to dynamically bind clients and servers, which makes remote procedure calls straightforward to implement and serializes and deserializes structured data automatically.

#### Installation[#](/microservices/grpc#installation)

To start building gRPC-based microservices, first install the required packages:

```bash

$ npm i --save @grpc/grpc-js @grpc/proto-loader
```

#### Overview[#](/microservices/grpc#overview)

As with other Nest microservice transport layer implementations, you select the gRPC transporter using the `transport` property of the options object passed to the `createMicroservice()` method. In the following example, we'll set up a hero service. The `options` property provides metadata about that service; its properties are described in [Options](/microservices/grpc#options) below.

main.ts

JS TS

```typescript

const app = await NestFactory.createMicroservice<MicroserviceOptions>(AppModule, {
  transport: Transport.GRPC,
  options: {
    package: 'hero',
    protoPath: join(import.meta.dirname, 'hero/hero.proto'),
  },
});
```

```typescript

const app = await NestFactory.createMicroservice(AppModule, {
  transport: Transport.GRPC,
  options: {
    package: 'hero',
    protoPath: join(import.meta.dirname, 'hero/hero.proto'),
  },
});
```

> **Hint** The `join()` function is imported from the `path` package, and the `Transport` enum from the `@nestjs/microservices` package.

In the `nest-cli.json` file, add the `assets` property to distribute non-TypeScript files, and `watchAssets` to watch all non-TypeScript assets. In this case, we want `.proto` files to be copied to the `dist` folder automatically.

```json

{
  "compilerOptions": {
    "assets": ["**/*.proto"],
    "watchAssets": true
  }
}
```

#### Options[#](/microservices/grpc#options)

The **gRPC** transporter options object exposes the following properties.

|               |                                                                                                                                                                                                                                               |
| ------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `package`     | Protobuf package name (matches the `package` setting in the `.proto` file). Also accepts an array of package names. Required                                                                                                                  |
| `protoPath`   | Absolute (or relative to the current working directory) path to the `.proto` file, or an array of paths. Required unless you pass a preloaded `packageDefinition` instead                                                                     |
| `url`         | Connection URL. A string in the format `ip address/dns name:port` (e.g., `'0.0.0.0:50051'` for a Docker server) that defines the address and port on which the transporter establishes a connection. Optional. Defaults to `'localhost:5000'` |
| `protoLoader` | NPM package name for the utility to load `.proto` files. Optional. Defaults to `'@grpc/proto-loader'`                                                                                                                                         |
| `loader`      | `@grpc/proto-loader` options, which control how `.proto` files are loaded. Optional. See the [proto-loader README](https://github.com/grpc/grpc-node/blob/master/packages/proto-loader/README.md) for details                                 |
| `credentials` | Server credentials (channel credentials when used by a client). Optional. Defaults to insecure credentials. See the [`ServerCredentials` reference](https://grpc.io/grpc/node/grpc.ServerCredentials.html)                                    |

#### Sample gRPC service[#](/microservices/grpc#sample-grpc-service)

Let's define a sample gRPC service called `HeroesService`. In the `options` object above, the `protoPath` property sets the path to the `hero.proto` definitions file. The `hero.proto` file is structured using [protocol buffers](https://developers.google.com/protocol-buffers):

```typescript

// hero/hero.proto
syntax = "proto3";

package hero;

service HeroesService {
  rpc FindOne (HeroById) returns (Hero) {}
}

message HeroById {
  int32 id = 1;
}

message Hero {
  int32 id = 1;
  string name = 2;
}
```

`HeroesService` exposes a `FindOne()` method. This method expects an input argument of type `HeroById` and returns a `Hero` message (protocol buffers use `message` elements to define both parameter types and return types).

Next, implement the service. To define a handler that fulfills this definition, use the `@GrpcMethod()` decorator in a controller, as shown below. This decorator provides the metadata needed to declare a method as a gRPC service method.

> **Hint** The `@MessagePattern()` decorator (see [request-response](/microservices/basics#request-response)) introduced in previous microservices chapters is not used with gRPC-based microservices. The `@GrpcMethod()` decorator takes its place.

heroes.controller.ts

JS TS

```typescript

@Controller()
export class HeroesController {
  @GrpcMethod('HeroesService', 'FindOne')
  findOne(data: HeroById, metadata: Metadata, call: ServerUnaryCall<any, any>): Hero {
    const items = [
      { id: 1, name: 'John' },
      { id: 2, name: 'Doe' },
    ];
    return items.find(({ id }) => id === data.id);
  }
}
```

```typescript

@Controller()
export class HeroesController {
  @GrpcMethod('HeroesService', 'FindOne')
  findOne(data, metadata, call) {
    const items = [
      { id: 1, name: 'John' },
      { id: 2, name: 'Doe' },
    ];
    return items.find(({ id }) => id === data.id);
  }
}
```

> **Hint** The `@GrpcMethod()` decorator is imported from the `@nestjs/microservices` package, while `Metadata` and `ServerUnaryCall` are imported from the `@grpc/grpc-js` package.

The decorator takes two arguments. The first is the service name (e.g., `'HeroesService'`), corresponding to the `HeroesService` service definition in `hero.proto`. The second (the string `'FindOne'`) corresponds to the `FindOne()` rpc method defined within `HeroesService` in `hero.proto`.

The `findOne()` handler method takes three arguments: the `data` passed from the caller, the `metadata` that stores gRPC request metadata, and the `call` object, which exposes members such as `sendMetadata()` for sending metadata to the client.

Both `@GrpcMethod()` decorator arguments are optional. If you omit the second argument (e.g., `'FindOne'`), Nest associates the handler with the `.proto` rpc method whose name matches the handler name with its first letter capitalized (e.g., the `findOne` handler is associated with the `FindOne` rpc definition), as shown below.

heroes.controller.ts

JS TS

```typescript

@Controller()
export class HeroesController {
  @GrpcMethod('HeroesService')
  findOne(data: HeroById, metadata: Metadata, call: ServerUnaryCall<any, any>): Hero {
    const items = [
      { id: 1, name: 'John' },
      { id: 2, name: 'Doe' },
    ];
    return items.find(({ id }) => id === data.id);
  }
}
```

```typescript

@Controller()
export class HeroesController {
  @GrpcMethod('HeroesService')
  findOne(data, metadata, call) {
    const items = [
      { id: 1, name: 'John' },
      { id: 2, name: 'Doe' },
    ];
    return items.find(({ id }) => id === data.id);
  }
}
```

You can also omit the first `@GrpcMethod()` argument. In this case, Nest associates the handler with the service definition in the `.proto` file based on the name of the **class** where the handler is defined. For example, in the following code, the `HeroesService` class associates its handler methods with the `HeroesService` service definition in `hero.proto` because the names match.

heroes.controller.ts

JS TS

```typescript

@Controller()
export class HeroesService {
  @GrpcMethod()
  findOne(data: HeroById, metadata: Metadata, call: ServerUnaryCall<any, any>): Hero {
    const items = [
      { id: 1, name: 'John' },
      { id: 2, name: 'Doe' },
    ];
    return items.find(({ id }) => id === data.id);
  }
}
```

```typescript

@Controller()
export class HeroesService {
  @GrpcMethod()
  findOne(data, metadata, call) {
    const items = [
      { id: 1, name: 'John' },
      { id: 2, name: 'Doe' },
    ];
    return items.find(({ id }) => id === data.id);
  }
}
```

#### Client[#](/microservices/grpc#client)

Nest applications can act as gRPC clients, consuming services defined in `.proto` files. You access remote services through a `ClientGrpc` object, which you can obtain in several ways.

The preferred technique is to import the `ClientsModule`. Use its `register()` method to bind a package of services defined in a `.proto` file to an injection token, and to configure the service. The `name` property is the injection token. For gRPC services, use `transport: Transport.GRPC`. The `options` property is an object with the same properties described in [Options](/microservices/grpc#options) above.

```typescript

imports: [
  ClientsModule.register([
    {
      name: 'HERO_PACKAGE',
      transport: Transport.GRPC,
      options: {
        package: 'hero',
        protoPath: join(import.meta.dirname, 'hero/hero.proto'),
      },
    },
  ]),
];
```

> **Hint** The `register()` method takes an array of objects. To register multiple packages, provide a comma-separated list of registration objects.

Once registered, inject the configured `ClientGrpc` object with `@Inject()`. Then use the `ClientGrpc` object's `getService()` method to retrieve the service instance, as shown below.

```typescript

@Injectable()
export class AppService implements OnModuleInit {
  private heroesService: HeroesService;

  constructor(@Inject('HERO_PACKAGE') private client: ClientGrpc) {}

  onModuleInit() {
    this.heroesService = this.client.getService<HeroesService>('HeroesService');
  }

  getHero(): Observable<string> {
    return this.heroesService.findOne({ id: 1 });
  }
}
```

> **Warning** The gRPC client does not send fields that contain an underscore (`_`) in their names unless the `keepCase` option is set to `true` in the proto loader configuration (`options.loader.keepCase` in the microservice transporter configuration).

This differs slightly from the technique used with other microservice transporters. Instead of the `ClientProxy` class, you use the `ClientGrpc` class, which provides the `getService()` method. The generic `getService()` method takes a service name as an argument and returns its instance (if available).

Alternatively, you can use the `@Client()` decorator to instantiate a `ClientGrpc` object, as follows:

```typescript

@Injectable()
export class AppService implements OnModuleInit {
  @Client({
    transport: Transport.GRPC,
    options: {
      package: 'hero',
      protoPath: join(import.meta.dirname, 'hero/hero.proto'),
    },
  })
  client: ClientGrpc;

  private heroesService: HeroesService;

  onModuleInit() {
    this.heroesService = this.client.getService<HeroesService>('HeroesService');
  }

  getHero(): Observable<string> {
    return this.heroesService.findOne({ id: 1 });
  }
}
```

Finally, for more complex scenarios, you can inject a dynamically configured client using the `ClientProxyFactory` class, as described in the [client section of the microservices overview](/microservices/basics#client-producer-class).

In each case, you end up with a reference to the `HeroesService` proxy object, which exposes the same set of methods that are defined in the `.proto` file. When you call this proxy object (i.e., `heroesService`), gRPC serializes the request, forwards it to the remote system, returns a response, and deserializes the response. Because gRPC shields you from these network communication details, `heroesService` looks and acts like a local provider.

All service methods are **lower camel cased**, following the natural convention of the language. For example, while the `HeroesService` definition in the `.proto` file contains the `FindOne()` function, the `heroesService` instance provides the `findOne()` method.

```typescript

interface HeroesService {
  findOne(data: { id: number }): Observable<any>;
}
```

A handler can also return an `Observable`, in which case the result values are emitted until the stream completes.

heroes.controller.ts

JS TS

```typescript

@Get()
call(): Observable<any> {
  return this.heroesService.findOne({ id: 1 });
}
```

```typescript

@Get()
call() {
  return this.heroesService.findOne({ id: 1 });
}
```

To send gRPC metadata along with the request, pass a second argument, as follows:

```typescript

call(): Observable<any> {
  const metadata = new Metadata();
  metadata.add('Set-Cookie', 'yummy_cookie=choco');

  return this.heroesService.findOne({ id: 1 }, metadata);
}
```

> **Hint** The `Metadata` class is imported from the `@grpc/grpc-js` package.

This requires updating the `HeroesService` interface defined earlier to accept the second argument.

#### Exception handling[#](/microservices/grpc#exception-handling)

gRPC handlers can throw `RpcException`, but a plain `RpcException` does not carry a gRPC status code, so clients receive `UNKNOWN` for every failure. Starting with NestJS v12, the `@nestjs/microservices` package ships dedicated gRPC exceptions and a `GrpcExceptionFilter` that maps them to proper gRPC error objects.

Throw one of the status-specific exceptions from your handler:

heroes.controller.ts

JS TS

```typescript

import { GrpcAlreadyExistsException } from '@nestjs/microservices';

@GrpcMethod('HeroesService')
create(data: Hero): Hero {
  if (this.heroes.has(data.id)) {
    throw new GrpcAlreadyExistsException('Hero already exists');
  }
  return this.heroes.add(data);
}
```

Then register the filter so those exceptions are serialized into gRPC errors:

main.ts

JS TS

```typescript

import { GrpcExceptionFilter } from '@nestjs/microservices';

const app = await NestFactory.createMicroservice<MicroserviceOptions>(AppModule, {
  transport: Transport.GRPC,
  options: {
    package: 'hero',
    protoPath: join(import.meta.dirname, 'hero/hero.proto'),
  },
});
app.useGlobalFilters(new GrpcExceptionFilter());
```

With the filter in place, the client receives `ALREADY_EXISTS` instead of `UNKNOWN`.

You can also use the generic `GrpcException` and pass a status explicitly:

```typescript

import { GrpcException, GrpcStatus } from '@nestjs/microservices';

throw new GrpcException('Rate limit exceeded', GrpcStatus.RESOURCE_EXHAUSTED);
```

The following status-specific exception classes are available. Each corresponds to a member of the `GrpcStatus` enum:

|                                   |                              |                                 |                                  |
| --------------------------------- | ---------------------------- | ------------------------------- | -------------------------------- |
| `GrpcCancelledException`          | `GrpcUnknownException`       | `GrpcInvalidArgumentException`  | `GrpcDeadlineExceededException`  |
| `GrpcNotFoundException`           | `GrpcAlreadyExistsException` | `GrpcPermissionDeniedException` | `GrpcResourceExhaustedException` |
| `GrpcFailedPreconditionException` | `GrpcAbortedException`       | `GrpcOutOfRangeException`       | `GrpcUnimplementedException`     |
| `GrpcInternalException`           | `GrpcUnavailableException`   | `GrpcDataLossException`         | `GrpcUnauthenticatedException`   |

> **Hint**`GrpcExceptionFilter` also handles `RpcException`. If the error object passed to the `RpcException` constructor carries a numeric `code` or `status` property, that value is used as the gRPC status; otherwise, the error is reported as `UNKNOWN`. Any other exception is reported as `UNKNOWN` with a generic message.

#### Example[#](/microservices/grpc#example)

A working example is available in the [gRPC sample](https://github.com/nestjs/nest/tree/master/sample/04-grpc) of the NestJS repository.

#### gRPC Reflection[#](/microservices/grpc#grpc-reflection)

The [gRPC Server Reflection Specification](https://grpc.io/docs/guides/reflection/#overview) is a standard that allows gRPC clients to request details about the API the server exposes, similar to exposing an OpenAPI document for a REST API. This makes it easier to work with debugging tools such as grpc-ui or Postman.

To add gRPC reflection support to your server, first install the implementation package:

```bash

$ npm i --save @grpc/reflection
```

Then hook it into the gRPC server using the `onLoadPackageDefinition` hook in your gRPC server options, as follows:

main.ts

JS TS

```typescript

import { ReflectionService } from '@grpc/reflection';

const app = await NestFactory.createMicroservice<MicroserviceOptions>(AppModule, {
  transport: Transport.GRPC,
  options: {
    package: 'hero',
    protoPath: join(import.meta.dirname, 'hero/hero.proto'),
    onLoadPackageDefinition: (pkg, server) => {
      new ReflectionService(pkg).addToServer(server);
    },
  },
});
```

Your server now responds to reflection requests for API details.

#### gRPC Streaming[#](/microservices/grpc#grpc-streaming)

gRPC supports long-lived connections, conventionally known as `streams`. Streams are useful for cases such as chat, observation, or chunked data transfers. See the [gRPC core concepts guide](https://grpc.io/docs/guides/concepts/) for details.

Nest supports gRPC stream handlers in two ways:

* RxJS `Subject` + `Observable` handler: useful for writing responses directly inside a controller method, or for passing them to a `Subject`/`Observable` consumer
* Pure gRPC call stream handler: useful for passing the call to an executor that handles the rest of the dispatch for the standard Node.js `Duplex` stream

Let's define a new sample gRPC service called `HelloService`. The `hello.proto` file is structured using [protocol buffers](https://developers.google.com/protocol-buffers):

```typescript

// hello/hello.proto
syntax = "proto3";

package hello;

service HelloService {
  rpc BidiHello(stream HelloRequest) returns (stream HelloResponse);
  rpc LotsOfGreetings(stream HelloRequest) returns (HelloResponse);
}

message HelloRequest {
  string greeting = 1;
}

message HelloResponse {
  string reply = 1;
}
```

> **Hint**`LotsOfGreetings` streams requests but returns a single response. Because its requests are streamed, it can't be implemented with `@GrpcMethod()`; use `@GrpcStreamMethod()` (the last value the returned `Observable` emits is sent as the response) or `@GrpcStreamCall()` (respond through the callback), both shown below.

Based on this `.proto` file, define the `HelloService` interface:

```typescript

interface HelloService {
  bidiHello(upstream: Observable<HelloRequest>): Observable<HelloResponse>;
  lotsOfGreetings(
    upstream: Observable<HelloRequest>,
  ): Observable<HelloResponse>;
}

interface HelloRequest {
  greeting: string;
}

interface HelloResponse {
  reply: string;
}
```

> **Hint** The proto interface can be generated automatically by the [ts-proto](https://github.com/stephenh/ts-proto) package. See the [ts-proto NestJS guide](https://github.com/stephenh/ts-proto/blob/main/NESTJS.markdown) to learn more.

#### Subject strategy[#](/microservices/grpc#subject-strategy)

The `@GrpcStreamMethod()` decorator provides the function parameter as an RxJS `Observable`, so the handler can receive and process multiple messages.

```typescript

@GrpcStreamMethod()
bidiHello(messages: Observable<any>, metadata: Metadata, call: ServerDuplexStream<any, any>): Observable<any> {
  const subject = new Subject();

  const onNext = message => {
    console.log(message);
    subject.next({
      reply: 'Hello, world!'
    });
  };
  const onComplete = () => subject.complete();
  messages.subscribe({
    next: onNext,
    complete: onComplete,
  });


  return subject.asObservable();
}
```

> **Warning** To support full-duplex interaction with the `@GrpcStreamMethod()` decorator, the controller method must return an RxJS `Observable`.

> **Hint** The `Metadata` class and the `ServerDuplexStream` interface are imported from the `@grpc/grpc-js` package.

According to the service definition in the `.proto` file, the `BidiHello` method streams requests to the service. To send multiple asynchronous messages to the stream from a client, use an RxJS `ReplaySubject`.

```typescript

const helloService = this.client.getService<HelloService>('HelloService');
const helloRequest$ = new ReplaySubject<HelloRequest>();

helloRequest$.next({ greeting: 'Hello (1)!' });
helloRequest$.next({ greeting: 'Hello (2)!' });
helloRequest$.complete();

return helloService.bidiHello(helloRequest$);
```

In the example above, we wrote two messages to the stream (the `next()` calls) and notified the service that we finished sending data (the `complete()` call).

#### Call stream handler[#](/microservices/grpc#call-stream-handler)

When the method's response is defined as a `stream`, the `@GrpcStreamCall()` decorator provides the function parameter as a `grpc.ServerDuplexStream`, which supports standard methods such as `.on('data', callback)`, `.write(message)`, and `.end()`. See the [gRPC Node.js API reference](https://grpc.github.io/grpc/node/grpc-ClientDuplexStream.html) for the full list of methods.

When the method's response is not a `stream`, the `@GrpcStreamCall()` decorator provides two function parameters: a `grpc.ServerReadableStream` (see the [`ServerReadableStream` reference](https://grpc.github.io/grpc/node/grpc-ServerReadableStream.html)) and a `callback`.

Let's start by implementing `BidiHello`, which supports full-duplex interaction.

```typescript

@GrpcStreamCall()
bidiHello(requestStream: any) {
  requestStream.on('data', message => {
    console.log(message);
    requestStream.write({
      reply: 'Hello, world!'
    });
  });
}
```

> **Hint** This decorator doesn't require the handler to return anything. You handle the stream as you would any other standard stream.

In the example above, we used the `write()` method to write objects to the response stream. The callback passed to the `.on()` method as the second parameter is called every time the service receives a new chunk of data.

Next, implement the `LotsOfGreetings` method.

```typescript

@GrpcStreamCall()
lotsOfGreetings(requestStream: any, callback: (err: unknown, value: HelloResponse) => void) {
  requestStream.on('data', message => {
    console.log(message);
  });
  requestStream.on('end', () => callback(null, { reply: 'Hello, world!' }));
}
```

Here, the `callback` function sends the response once the `requestStream` has been fully processed.

#### Health checks[#](/microservices/grpc#health-checks)

When you run a gRPC application in an orchestrator such as Kubernetes, the orchestrator needs to know whether the application is running and healthy. The [gRPC Health Check specification](https://grpc.io/docs/guides/health-checking/) is a standard that lets gRPC servers expose their health status so that the orchestrator can act accordingly.

To add gRPC health check support, first install the [grpc-health-check](https://github.com/grpc/grpc-node/tree/master/packages/grpc-health-check) package:

```bash

$ npm i --save grpc-health-check
```

Then hook it into the gRPC service using the `onLoadPackageDefinition` hook in your gRPC server options, as follows. The `protoPath` must include both the health check and the hero `.proto` files.

main.ts

JS TS

```typescript

import { HealthImplementation, protoPath as healthCheckProtoPath } from 'grpc-health-check';

const app = await NestFactory.createMicroservice<MicroserviceOptions>(AppModule, {
  transport: Transport.GRPC,
  options: {
    package: 'hero',
    protoPath: [
      healthCheckProtoPath,
      join(import.meta.dirname, 'hero/hero.proto'),
    ],
    onLoadPackageDefinition: (pkg, server) => {
      const healthImpl = new HealthImplementation({
        '': 'UNKNOWN',
      });

      healthImpl.addToServer(server);
      healthImpl.setStatus('', 'SERVING');
    },
  },
});
```

> **Hint** The [gRPC health probe](https://github.com/grpc-ecosystem/grpc-health-probe) is a CLI for testing gRPC health checks in a containerized environment.

#### gRPC Metadata[#](/microservices/grpc#grpc-metadata)

Metadata is information about a particular RPC call in the form of a list of key-value pairs, where the keys are strings and the values are typically strings but can be binary data. Metadata is opaque to gRPC itself: it lets the client provide information associated with the call to the server, and vice versa. Metadata may include authentication tokens, request identifiers and tags for monitoring purposes, and data information such as the number of records in a data set.

To read the metadata in a `@GrpcMethod()` handler, use the second argument (`metadata`), which is of type `Metadata` (imported from the `@grpc/grpc-js` package).

To send metadata back from the handler, use the `ServerUnaryCall#sendMetadata()` method (on the third handler argument).

heroes.controller.ts

JS TS

```typescript

@Controller()
export class HeroesService {
  @GrpcMethod()
  findOne(data: HeroById, metadata: Metadata, call: ServerUnaryCall<any, any>): Hero {
    const serverMetadata = new Metadata();
    const items = [
      { id: 1, name: 'John' },
      { id: 2, name: 'Doe' },
    ];

    serverMetadata.add('Set-Cookie', 'yummy_cookie=choco');
    call.sendMetadata(serverMetadata);

    return items.find(({ id }) => id === data.id);
  }
}
```

```typescript

@Controller()
export class HeroesService {
  @GrpcMethod()
  findOne(data, metadata, call) {
    const serverMetadata = new Metadata();
    const items = [
      { id: 1, name: 'John' },
      { id: 2, name: 'Doe' },
    ];

    serverMetadata.add('Set-Cookie', 'yummy_cookie=choco');
    call.sendMetadata(serverMetadata);

    return items.find(({ id }) => id === data.id);
  }
}
```

Likewise, to read the metadata in handlers annotated with the `@GrpcStreamMethod()` decorator (see [Subject strategy](/microservices/grpc#subject-strategy)), use the second argument (`metadata`), which is of type `Metadata` (imported from the `@grpc/grpc-js` package).

To send metadata back from the handler, use the `ServerDuplexStream#sendMetadata()` method (on the third handler argument).

To read metadata from within [call stream handlers](/microservices/grpc#call-stream-handler) (handlers annotated with the `@GrpcStreamCall()` decorator), listen to the `metadata` event on the `requestStream` reference, as follows:

```typescript

requestStream.on('metadata', (metadata: Metadata) => {
  const meta = metadata.get('X-Meta');
});
```

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/microservices/grpc.md)

----
url: https://docs.nestjs.com/v11/graphql/federation
----

* [Federation](https://docs.nestjs.com/v11/graphql/federation#federation)
* [Federation with Apollo](https://docs.nestjs.com/v11/graphql/federation#federation-with-apollo)
* [Schema first](https://docs.nestjs.com/v11/graphql/federation#schema-first)
* [Code first](https://docs.nestjs.com/v11/graphql/federation#code-first)
* [Federated example: Posts](https://docs.nestjs.com/v11/graphql/federation#federated-example-posts)
* [Schema first](https://docs.nestjs.com/v11/graphql/federation#schema-first-1)
* [Code first](https://docs.nestjs.com/v11/graphql/federation#code-first-1)
* [Federated example: Gateway](https://docs.nestjs.com/v11/graphql/federation#federated-example-gateway)
* [Federation with Mercurius](https://docs.nestjs.com/v11/graphql/federation#federation-with-mercurius)
* [Schema first](https://docs.nestjs.com/v11/graphql/federation#schema-first-2)
* [Code first](https://docs.nestjs.com/v11/graphql/federation#code-first-2)
* [Federated example: Posts](https://docs.nestjs.com/v11/graphql/federation#federated-example-posts-1)
* [Schema first](https://docs.nestjs.com/v11/graphql/federation#schema-first-3)
* [Code first](https://docs.nestjs.com/v11/graphql/federation#code-first-3)
* [Federated example: Gateway](https://docs.nestjs.com/v11/graphql/federation#federated-example-gateway-1)
* [Federation 2](https://docs.nestjs.com/v11/graphql/federation#federation-2)
* [Federated example: Users](https://docs.nestjs.com/v11/graphql/federation#federated-example-users)
* [Schema first](https://docs.nestjs.com/v11/graphql/federation#schema-first-4)
* [Code first](https://docs.nestjs.com/v11/graphql/federation#code-first-4)
* [Federated example: Posts](https://docs.nestjs.com/v11/graphql/federation#federated-example-posts-2)
* [Schema first](https://docs.nestjs.com/v11/graphql/federation#schema-first-5)
* [Code first](https://docs.nestjs.com/v11/graphql/federation#code-first-5)

> **Warning** Federation currently does not support subscriptions.

In the following sections, we'll set up a demo application that consists of a gateway and two federated endpoints: Users service and Posts service.

#### Federation with Apollo[#](/graphql/federation#federation-with-apollo)

Start by installing the required dependencies:

```bash

$ npm install --save @apollo/subgraph
```

#### Schema first[#](/graphql/federation#schema-first)

The "User service" provides a simple schema. Note the `@key` directive: it instructs the Apollo query planner that a particular instance of `User` can be fetched if you specify its `id`. Also, note that we `extend` the `Query` type.

```graphql

type User @key(fields: "id") {
  id: ID!
  name: String!
}

extend type Query {
  getUser(id: ID!): User
}
```

Resolver provides one additional method named `resolveReference()`. This method is triggered by the Apollo Gateway whenever a related resource requires a User instance. We'll see an example of this in the Posts service later. Please note that the method must be annotated with the `@ResolveReference()` decorator.

```typescript

import { Args, Query, Resolver, ResolveReference } from '@nestjs/graphql';
import { UsersService } from './users.service';

@Resolver('User')
export class UsersResolver {
  constructor(private usersService: UsersService) {}

  @Query()
  getUser(@Args('id') id: string) {
    return this.usersService.findById(id);
  }

  @ResolveReference()
  resolveReference(reference: { __typename: string; id: string }) {
    return this.usersService.findById(reference.id);
  }
}
```

Finally, we hook everything up by registering the `GraphQLModule` passing the `ApolloFederationDriver` driver in the configuration object:

```typescript

import {
  ApolloFederationDriver,
  ApolloFederationDriverConfig,
} from '@nestjs/apollo';
import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';
import { UsersResolver } from './users.resolver';

@Module({
  imports: [
    GraphQLModule.forRoot<ApolloFederationDriverConfig>({
      driver: ApolloFederationDriver,
      typePaths: ['**/*.graphql'],
    }),
  ],
  providers: [UsersResolver],
})
export class AppModule {}
```

#### Code first[#](/graphql/federation#code-first)

Start by adding some extra decorators to the `User` entity.

```ts

import { Directive, Field, ID, ObjectType } from '@nestjs/graphql';

@ObjectType()
@Directive('@key(fields: "id")')
export class User {
  @Field(() => ID)
  id: number;

  @Field()
  name: string;
}
```

Resolver provides one additional method named `resolveReference()`. This method is triggered by the Apollo Gateway whenever a related resource requires a User instance. We'll see an example of this in the Posts service later. Please note that the method must be annotated with the `@ResolveReference()` decorator.

```ts

import { Args, Query, Resolver, ResolveReference } from '@nestjs/graphql';
import { User } from './user.entity';
import { UsersService } from './users.service';

@Resolver(() => User)
export class UsersResolver {
  constructor(private usersService: UsersService) {}

  @Query(() => User)
  getUser(@Args('id') id: number): User {
    return this.usersService.findById(id);
  }

  @ResolveReference()
  resolveReference(reference: { __typename: string; id: number }): User {
    return this.usersService.findById(reference.id);
  }
}
```

Finally, we hook everything up by registering the `GraphQLModule` passing the `ApolloFederationDriver` driver in the configuration object:

```typescript

import {
  ApolloFederationDriver,
  ApolloFederationDriverConfig,
} from '@nestjs/apollo';
import { Module } from '@nestjs/common';
import { UsersResolver } from './users.resolver';
import { UsersService } from './users.service'; // Not included in this example

@Module({
  imports: [
    GraphQLModule.forRoot<ApolloFederationDriverConfig>({
      driver: ApolloFederationDriver,
      autoSchemaFile: true,
    }),
  ],
  providers: [UsersResolver, UsersService],
})
export class AppModule {}
```

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/31-graphql-federation-code-first/users-application) in code first mode and [here](https://github.com/nestjs/nest/tree/master/sample/32-graphql-federation-schema-first/users-application) in schema first mode.

#### Federated example: Posts[#](/graphql/federation#federated-example-posts)

Post service is supposed to serve aggregated posts through the `getPosts` query, but also extend our `User` type with the `user.posts` field.

#### Schema first[#](/graphql/federation#schema-first-1)

"Posts service" references the `User` type in its schema by marking it with the `extend` keyword. It also declares one additional property on the `User` type (`posts`). Note the `@key` directive used for matching instances of User, and the `@external` directive indicating that the `id` field is managed elsewhere.

```graphql

type Post @key(fields: "id") {
  id: ID!
  title: String!
  body: String!
  user: User
}

extend type User @key(fields: "id") {
  id: ID! @external
  posts: [Post]
}

extend type Query {
  getPosts: [Post]
}
```

In the following example, the `PostsResolver` provides the `getUser()` method that returns a reference containing `__typename` and some additional properties your application may need to resolve the reference, in this case `id`. `__typename` is used by the GraphQL Gateway to pinpoint the microservice responsible for the User type and retrieve the corresponding instance. The "Users service" described above will be requested upon execution of the `resolveReference()` method.

```typescript

import { Query, Resolver, Parent, ResolveField } from '@nestjs/graphql';
import { PostsService } from './posts.service';
import { Post } from './posts.interfaces';

@Resolver('Post')
export class PostsResolver {
  constructor(private postsService: PostsService) {}

  @Query('getPosts')
  getPosts() {
    return this.postsService.findAll();
  }

  @ResolveField('user')
  getUser(@Parent() post: Post) {
    return { __typename: 'User', id: post.userId };
  }
}
```

Lastly, we must register the `GraphQLModule`, similarly to what we did in the "Users service" section.

```typescript

import {
  ApolloFederationDriver,
  ApolloFederationDriverConfig,
} from '@nestjs/apollo';
import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';
import { PostsResolver } from './posts.resolver';

@Module({
  imports: [
    GraphQLModule.forRoot<ApolloFederationDriverConfig>({
      driver: ApolloFederationDriver,
      typePaths: ['**/*.graphql'],
    }),
  ],
  providers: [PostsResolver],
})
export class AppModule {}
```

#### Code first[#](/graphql/federation#code-first-1)

First, we will have to declare a class representing the `User` entity. Although the entity itself lives in another service, we will be using it (extending its definition) here. Note the `@extends` and `@external` directives.

```ts

import { Directive, ObjectType, Field, ID } from '@nestjs/graphql';
import { Post } from './post.entity';

@ObjectType()
@Directive('@extends')
@Directive('@key(fields: "id")')
export class User {
  @Field(() => ID)
  @Directive('@external')
  id: number;

  @Field(() => [Post])
  posts?: Post[];
}
```

Now let's create the corresponding resolver for our extension on the `User` entity, as follows:

```ts

import { Parent, ResolveField, Resolver } from '@nestjs/graphql';
import { PostsService } from './posts.service';
import { Post } from './post.entity';
import { User } from './user.entity';

@Resolver(() => User)
export class UsersResolver {
  constructor(private readonly postsService: PostsService) {}

  @ResolveField(() => [Post])
  public posts(@Parent() user: User): Post[] {
    return this.postsService.forAuthor(user.id);
  }
}
```

We also have to define the `Post` entity class:

```ts

import { Directive, Field, ID, Int, ObjectType } from '@nestjs/graphql';
import { User } from './user.entity';

@ObjectType()
@Directive('@key(fields: "id")')
export class Post {
  @Field(() => ID)
  id: number;

  @Field()
  title: string;

  @Field(() => Int)
  authorId: number;

  @Field(() => User)
  user?: User;
}
```

And its resolver:

```ts

import { Query, Args, ResolveField, Resolver, Parent } from '@nestjs/graphql';
import { PostsService } from './posts.service';
import { Post } from './post.entity';
import { User } from './user.entity';

@Resolver(() => Post)
export class PostsResolver {
  constructor(private readonly postsService: PostsService) {}

  @Query(() => Post)
  findPost(@Args('id') id: number): Post {
    return this.postsService.findOne(id);
  }

  @Query(() => [Post])
  getPosts(): Post[] {
    return this.postsService.all();
  }

  @ResolveField(() => User)
  user(@Parent() post: Post): any {
    return { __typename: 'User', id: post.authorId };
  }
}
```

And finally, tie it together in a module. Note the schema build options, where we specify that `User` is an orphaned (external) type.

```ts

import {
  ApolloFederationDriver,
  ApolloFederationDriverConfig,
} from '@nestjs/apollo';
import { Module } from '@nestjs/common';
import { User } from './user.entity';
import { PostsResolver } from './posts.resolvers';
import { UsersResolver } from './users.resolvers';
import { PostsService } from './posts.service'; // Not included in example

@Module({
  imports: [
    GraphQLModule.forRoot<ApolloFederationDriverConfig>({
      driver: ApolloFederationDriver,
      autoSchemaFile: true,
      buildSchemaOptions: {
        orphanedTypes: [User],
      },
    }),
  ],
  providers: [PostsResolver, UsersResolver, PostsService],
})
export class AppModule {}
```

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/31-graphql-federation-code-first/posts-application) for the code first mode and [here](https://github.com/nestjs/nest/tree/master/sample/32-graphql-federation-schema-first/posts-application) for the schema first mode.

#### Federated example: Gateway[#](/graphql/federation#federated-example-gateway)

Start by installing the required dependency:

```bash

$ npm install --save @apollo/gateway
```

The gateway requires a list of endpoints to be specified and it will auto-discover the corresponding schemas. Therefore the implementation of the gateway service will remain the same for both code and schema first approaches.

```typescript

import { IntrospectAndCompose } from '@apollo/gateway';
import { ApolloGatewayDriver, ApolloGatewayDriverConfig } from '@nestjs/apollo';
import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';

@Module({
  imports: [
    GraphQLModule.forRoot<ApolloGatewayDriverConfig>({
      driver: ApolloGatewayDriver,
      server: {
        // ... Apollo server options
        cors: true,
      },
      gateway: {
        supergraphSdl: new IntrospectAndCompose({
          subgraphs: [
            { name: 'users', url: 'http://user-service/graphql' },
            { name: 'posts', url: 'http://post-service/graphql' },
          ],
        }),
      },
    }),
  ],
})
export class AppModule {}
```

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/31-graphql-federation-code-first/gateway) for the code first mode and [here](https://github.com/nestjs/nest/tree/master/sample/32-graphql-federation-schema-first/gateway) for the schema first mode.

#### Federation with Mercurius[#](/graphql/federation#federation-with-mercurius)

Start by installing the required dependencies:

```bash

$ npm install --save @apollo/subgraph @nestjs/mercurius
```

> **Note** The `@apollo/subgraph` package is required to build a subgraph schema (`buildSubgraphSchema`, `printSubgraphSchema` functions).

#### Schema first[#](/graphql/federation#schema-first-2)

The "User service" provides a simple schema. Note the `@key` directive: it instructs the Mercurius query planner that a particular instance of `User` can be fetched if you specify its `id`. Also, note that we `extend` the `Query` type.

```graphql

type User @key(fields: "id") {
  id: ID!
  name: String!
}

extend type Query {
  getUser(id: ID!): User
}
```

Resolver provides one additional method named `resolveReference()`. This method is triggered by the Mercurius Gateway whenever a related resource requires a User instance. We'll see an example of this in the Posts service later. Please note that the method must be annotated with the `@ResolveReference()` decorator.

```typescript

import { Args, Query, Resolver, ResolveReference } from '@nestjs/graphql';
import { UsersService } from './users.service';

@Resolver('User')
export class UsersResolver {
  constructor(private usersService: UsersService) {}

  @Query()
  getUser(@Args('id') id: string) {
    return this.usersService.findById(id);
  }

  @ResolveReference()
  resolveReference(reference: { __typename: string; id: string }) {
    return this.usersService.findById(reference.id);
  }
}
```

Finally, we hook everything up by registering the `GraphQLModule` passing the `MercuriusFederationDriver` driver in the configuration object:

```typescript

import {
  MercuriusFederationDriver,
  MercuriusFederationDriverConfig,
} from '@nestjs/mercurius';
import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';
import { UsersResolver } from './users.resolver';

@Module({
  imports: [
    GraphQLModule.forRoot<MercuriusFederationDriverConfig>({
      driver: MercuriusFederationDriver,
      typePaths: ['**/*.graphql'],
      federationMetadata: true,
    }),
  ],
  providers: [UsersResolver],
})
export class AppModule {}
```

#### Code first[#](/graphql/federation#code-first-2)

Start by adding some extra decorators to the `User` entity.

```ts

import { Directive, Field, ID, ObjectType } from '@nestjs/graphql';

@ObjectType()
@Directive('@key(fields: "id")')
export class User {
  @Field(() => ID)
  id: number;

  @Field()
  name: string;
}
```

Resolver provides one additional method named `resolveReference()`. This method is triggered by the Mercurius Gateway whenever a related resource requires a User instance. We'll see an example of this in the Posts service later. Please note that the method must be annotated with the `@ResolveReference()` decorator.

```ts

import { Args, Query, Resolver, ResolveReference } from '@nestjs/graphql';
import { User } from './user.entity';
import { UsersService } from './users.service';

@Resolver(() => User)
export class UsersResolver {
  constructor(private usersService: UsersService) {}

  @Query(() => User)
  getUser(@Args('id') id: number): User {
    return this.usersService.findById(id);
  }

  @ResolveReference()
  resolveReference(reference: { __typename: string; id: number }): User {
    return this.usersService.findById(reference.id);
  }
}
```

Finally, we hook everything up by registering the `GraphQLModule` passing the `MercuriusFederationDriver` driver in the configuration object:

```typescript

import {
  MercuriusFederationDriver,
  MercuriusFederationDriverConfig,
} from '@nestjs/mercurius';
import { Module } from '@nestjs/common';
import { UsersResolver } from './users.resolver';
import { UsersService } from './users.service'; // Not included in this example

@Module({
  imports: [
    GraphQLModule.forRoot<MercuriusFederationDriverConfig>({
      driver: MercuriusFederationDriver,
      autoSchemaFile: true,
      federationMetadata: true,
    }),
  ],
  providers: [UsersResolver, UsersService],
})
export class AppModule {}
```

#### Federated example: Posts[#](/graphql/federation#federated-example-posts-1)

Post service is supposed to serve aggregated posts through the `getPosts` query, but also extend our `User` type with the `user.posts` field.

#### Schema first[#](/graphql/federation#schema-first-3)

"Posts service" references the `User` type in its schema by marking it with the `extend` keyword. It also declares one additional property on the `User` type (`posts`). Note the `@key` directive used for matching instances of User, and the `@external` directive indicating that the `id` field is managed elsewhere.

```graphql

type Post @key(fields: "id") {
  id: ID!
  title: String!
  body: String!
  user: User
}

extend type User @key(fields: "id") {
  id: ID! @external
  posts: [Post]
}

extend type Query {
  getPosts: [Post]
}
```

In the following example, the `PostsResolver` provides the `getUser()` method that returns a reference containing `__typename` and some additional properties your application may need to resolve the reference, in this case `id`. `__typename` is used by the GraphQL Gateway to pinpoint the microservice responsible for the User type and retrieve the corresponding instance. The "Users service" described above will be requested upon execution of the `resolveReference()` method.

```typescript

import { Query, Resolver, Parent, ResolveField } from '@nestjs/graphql';
import { PostsService } from './posts.service';
import { Post } from './posts.interfaces';

@Resolver('Post')
export class PostsResolver {
  constructor(private postsService: PostsService) {}

  @Query('getPosts')
  getPosts() {
    return this.postsService.findAll();
  }

  @ResolveField('user')
  getUser(@Parent() post: Post) {
    return { __typename: 'User', id: post.userId };
  }
}
```

Lastly, we must register the `GraphQLModule`, similarly to what we did in the "Users service" section.

```typescript

import {
  MercuriusFederationDriver,
  MercuriusFederationDriverConfig,
} from '@nestjs/mercurius';
import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';
import { PostsResolver } from './posts.resolver';

@Module({
  imports: [
    GraphQLModule.forRoot<MercuriusFederationDriverConfig>({
      driver: MercuriusFederationDriver,
      federationMetadata: true,
      typePaths: ['**/*.graphql'],
    }),
  ],
  providers: [PostsResolver],
})
export class AppModule {}
```

#### Code first[#](/graphql/federation#code-first-3)

First, we will have to declare a class representing the `User` entity. Although the entity itself lives in another service, we will be using it (extending its definition) here. Note the `@extends` and `@external` directives.

```ts

import { Directive, ObjectType, Field, ID } from '@nestjs/graphql';
import { Post } from './post.entity';

@ObjectType()
@Directive('@extends')
@Directive('@key(fields: "id")')
export class User {
  @Field(() => ID)
  @Directive('@external')
  id: number;

  @Field(() => [Post])
  posts?: Post[];
}
```

Now let's create the corresponding resolver for our extension on the `User` entity, as follows:

```ts

import { Parent, ResolveField, Resolver } from '@nestjs/graphql';
import { PostsService } from './posts.service';
import { Post } from './post.entity';
import { User } from './user.entity';

@Resolver(() => User)
export class UsersResolver {
  constructor(private readonly postsService: PostsService) {}

  @ResolveField(() => [Post])
  public posts(@Parent() user: User): Post[] {
    return this.postsService.forAuthor(user.id);
  }
}
```

We also have to define the `Post` entity class:

```ts

import { Directive, Field, ID, Int, ObjectType } from '@nestjs/graphql';
import { User } from './user.entity';

@ObjectType()
@Directive('@key(fields: "id")')
export class Post {
  @Field(() => ID)
  id: number;

  @Field()
  title: string;

  @Field(() => Int)
  authorId: number;

  @Field(() => User)
  user?: User;
}
```

And its resolver:

```ts

import { Query, Args, ResolveField, Resolver, Parent } from '@nestjs/graphql';
import { PostsService } from './posts.service';
import { Post } from './post.entity';
import { User } from './user.entity';

@Resolver(() => Post)
export class PostsResolver {
  constructor(private readonly postsService: PostsService) {}

  @Query(() => Post)
  findPost(@Args('id') id: number): Post {
    return this.postsService.findOne(id);
  }

  @Query(() => [Post])
  getPosts(): Post[] {
    return this.postsService.all();
  }

  @ResolveField(() => User)
  user(@Parent() post: Post): any {
    return { __typename: 'User', id: post.authorId };
  }
}
```

And finally, tie it together in a module. Note the schema build options, where we specify that `User` is an orphaned (external) type.

```ts

import {
  MercuriusFederationDriver,
  MercuriusFederationDriverConfig,
} from '@nestjs/mercurius';
import { Module } from '@nestjs/common';
import { User } from './user.entity';
import { PostsResolver } from './posts.resolvers';
import { UsersResolver } from './users.resolvers';
import { PostsService } from './posts.service'; // Not included in example

@Module({
  imports: [
    GraphQLModule.forRoot<MercuriusFederationDriverConfig>({
      driver: MercuriusFederationDriver,
      autoSchemaFile: true,
      federationMetadata: true,
      buildSchemaOptions: {
        orphanedTypes: [User],
      },
    }),
  ],
  providers: [PostsResolver, UsersResolver, PostsService],
})
export class AppModule {}
```

#### Federated example: Gateway[#](/graphql/federation#federated-example-gateway-1)

The gateway requires a list of endpoints to be specified and it will auto-discover the corresponding schemas. Therefore the implementation of the gateway service will remain the same for both code and schema first approaches.

```typescript

import {
  MercuriusGatewayDriver,
  MercuriusGatewayDriverConfig,
} from '@nestjs/mercurius';
import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';

@Module({
  imports: [
    GraphQLModule.forRoot<MercuriusGatewayDriverConfig>({
      driver: MercuriusGatewayDriver,
      gateway: {
        services: [
          { name: 'users', url: 'http://user-service/graphql' },
          { name: 'posts', url: 'http://post-service/graphql' },
        ],
      },
    }),
  ],
})
export class AppModule {}
```

### Federation 2

To quote the [Apollo docs](https://www.apollographql.com/docs/federation/federation-2/new-in-federation-2), Federation 2 improves developer experience from the original Apollo Federation (called Federation 1 in this doc), which is backward compatible with most original supergraphs.

> **Warning** Mercurius doesn't fully support Federation 2. You can see the list of libraries that support Federation 2 [here](https://www.apollographql.com/docs/federation/supported-subgraphs#javascript--typescript).

In the following sections, we'll upgrade the previous example to Federation 2.

#### Federated example: Users[#](/graphql/federation#federated-example-users)

One change in Federation 2 is that entities have no originating subgraph, so we don't need to extend `Query` anymore. For more detail please refer to [the entities topic](https://www.apollographql.com/docs/federation/federation-2/new-in-federation-2#entities) in Apollo Federation 2 docs.

#### Schema first[#](/graphql/federation#schema-first-4)

We can simply remove `extend` keyword from the schema.

```graphql

type User @key(fields: "id") {
  id: ID!
  name: String!
}

type Query {
  getUser(id: ID!): User
}
```

#### Code first[#](/graphql/federation#code-first-4)

To use Federation 2, we need to specify the federation version in `autoSchemaFile` option.

```ts

import {
  ApolloFederationDriver,
  ApolloFederationDriverConfig,
} from '@nestjs/apollo';
import { Module } from '@nestjs/common';
import { UsersResolver } from './users.resolver';
import { UsersService } from './users.service'; // Not included in this example

@Module({
  imports: [
    GraphQLModule.forRoot<ApolloFederationDriverConfig>({
      driver: ApolloFederationDriver,
      autoSchemaFile: {
        federation: 2,
      },
    }),
  ],
  providers: [UsersResolver, UsersService],
})
export class AppModule {}
```

#### Federated example: Posts[#](/graphql/federation#federated-example-posts-2)

With the same reason as above, we don't need to extend `User` and `Query` anymore.

#### Schema first[#](/graphql/federation#schema-first-5)

We can simply remove `extend` and `external` directives from the schema

```graphql

type Post @key(fields: "id") {
  id: ID!
  title: String!
  body: String!
  user: User
}

type User @key(fields: "id") {
  id: ID!
  posts: [Post]
}

type Query {
  getPosts: [Post]
}
```

#### Code first[#](/graphql/federation#code-first-5)

Since we don't extend `User` entity anymore, we can simply remove `extends` and `external` directives from `User`.

```ts

import { Directive, ObjectType, Field, ID } from '@nestjs/graphql';
import { Post } from './post.entity';

@ObjectType()
@Directive('@key(fields: "id")')
export class User {
  @Field(() => ID)
  id: number;

  @Field(() => [Post])
  posts?: Post[];
}
```

Also, similarly to the User service, we need to specify in the `GraphQLModule` to use Federation 2.

```ts

import {
  ApolloFederationDriver,
  ApolloFederationDriverConfig,
} from '@nestjs/apollo';
import { Module } from '@nestjs/common';
import { User } from './user.entity';
import { PostsResolver } from './posts.resolvers';
import { UsersResolver } from './users.resolvers';
import { PostsService } from './posts.service'; // Not included in example

@Module({
  imports: [
    GraphQLModule.forRoot<ApolloFederationDriverConfig>({
      driver: ApolloFederationDriver,
      autoSchemaFile: {
        federation: 2,
      },
      buildSchemaOptions: {
        orphanedTypes: [User],
      },
    }),
  ],
  providers: [PostsResolver, UsersResolver, PostsService],
})
export class AppModule {}
```

----
url: https://docs.nestjs.com/v11/cli/monorepo
----

* [Workspaces](https://docs.nestjs.com/v11/cli/monorepo#workspaces)
* [Standard mode](https://docs.nestjs.com/v11/cli/monorepo#standard-mode)
* [Monorepo mode](https://docs.nestjs.com/v11/cli/monorepo#monorepo-mode)
* [Workspace projects](https://docs.nestjs.com/v11/cli/monorepo#workspace-projects)
* [Applications](https://docs.nestjs.com/v11/cli/monorepo#applications)
* [Libraries](https://docs.nestjs.com/v11/cli/monorepo#libraries)
* [CLI properties](https://docs.nestjs.com/v11/cli/monorepo#cli-properties)
* [Global compiler options](https://docs.nestjs.com/v11/cli/monorepo#global-compiler-options)
* [Global generate options](https://docs.nestjs.com/v11/cli/monorepo#global-generate-options)
* [Project-specific generate options](https://docs.nestjs.com/v11/cli/monorepo#project-specific-generate-options)
* [Specified compiler](https://docs.nestjs.com/v11/cli/monorepo#specified-compiler)
* [Webpack options](https://docs.nestjs.com/v11/cli/monorepo#webpack-options)
* [Assets](https://docs.nestjs.com/v11/cli/monorepo#assets)
* [Project properties](https://docs.nestjs.com/v11/cli/monorepo#project-properties)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/cli/workspaces.md "Suggest Edits")

### Workspaces

Nest has two modes for organizing code:

* **standard mode**: useful for building individual project-focused applications that have their own dependencies and settings, and don't need to optimize for sharing modules, or optimizing complex builds. This is the default mode.
* **monorepo mode**: this mode treats code artifacts as part of a lightweight **monorepo**, and may be more appropriate for teams of developers and/or multi-project environments. It automates parts of the build process to make it easy to create and compose modular components, promotes code re-use, makes integration testing easier, makes it easy to share project-wide artifacts like `eslint` rules and other configuration policies, and is easier to use than alternatives like Git submodules. Monorepo mode employs the concept of a **workspace**, represented in the `nest-cli.json` file, to coordinate the relationship between the components of the monorepo.

It's important to note that virtually all of Nest's features are independent of your code organization mode. The **only** effect of this choice is how your projects are composed and how build artifacts are generated. All other functionality, from the CLI to core modules to add-on modules work the same in either mode.

```bash

$ nest new my-project
```

We've constructed a *standard mode* structure, with a folder structure that looks like this:

eslint.config.mjs

We can convert this to a monorepo mode structure as follows:

```bash

$ cd my-project
$ nest generate app my-app
```

At this point, `nest` converts the existing structure to a **monorepo mode** structure. This results in a few important changes. The folder structure now looks like this:

apps

my-app

src

app.controller.ts

app.module.ts

app.service.ts

eslint.config.mjs

The `generate app` schematic has reorganized the code - moving each **application** project under the `apps` folder, and adding a project-specific `tsconfig.app.json` file in each project's root folder. Our original `my-project` app has become the **default project** for the monorepo, and is now a peer with the just-added `my-app`, located under the `apps` folder. We'll cover default projects below.

> **Warning** The conversion of a standard mode structure to monorepo only works for projects that have followed the canonical Nest project structure. Specifically, during conversion, the schematic attempts to relocate the `src` and `test` folders in a project folder beneath the `apps` folder in the root. If a project does not use this structure, the conversion will fail or produce unreliable results.

#### Workspace projects[#](/cli/monorepo#workspace-projects)

A monorepo uses the concept of a workspace to manage its member entities. Workspaces are composed of **projects**. A project may be either:

* an **application**: a full Nest application including a `main.ts` file to bootstrap the application. Aside from compile and build considerations, an application-type project within a workspace is functionally identical to an application within a *standard mode* structure.
* a **library**: a library is a way of packaging a general purpose set of features (modules, providers, controllers, etc.) that can be used within other projects. A library cannot run on its own, and has no `main.ts` file. Read more about libraries [here](/v11/cli/libraries).

All workspaces have a **default project** (which should be an application-type project). This is defined by the top-level `"root"` property in the `nest-cli.json` file, which points at the root of the default project (see [CLI properties](/cli/monorepo#cli-properties) below for more details). Usually, this is the **standard mode** application you started with, and later converted to a monorepo using `nest generate app`. When you follow these steps, this property is populated automatically.

Default projects are used by `nest` commands like `nest build` and `nest start` when a project name is not supplied.

For example, in the above monorepo structure, running

```bash

$ nest start
```

will start up the `my-project` app. To start `my-app`, we'd use:

```bash

$ nest start my-app
```

#### Applications[#](/cli/monorepo#applications)

Application-type projects, or what we might informally refer to as just "applications", are complete Nest applications that you can run and deploy. You generate an application-type project with `nest generate app`.

This command automatically generates a project skeleton, including the standard `src` and `test` folders from the [typescript starter](https://github.com/nestjs/typescript-starter). Unlike standard mode, an application project in a monorepo does not have any of the package dependency (`package.json`) or other project configuration artifacts like `.prettierrc` and `eslint.config.mjs`. Instead, the monorepo-wide dependencies and config files are used.

However, the schematic does generate a project-specific `tsconfig.app.json` file in the root folder of the project. This config file automatically sets appropriate build options, including setting the compilation output folder properly. The file extends the top-level (monorepo) `tsconfig.json` file, so you can manage global settings monorepo-wide, but override them if needed at the project level.

#### Libraries[#](/cli/monorepo#libraries)

As mentioned, library-type projects, or simply "libraries", are packages of Nest components that need to be composed into applications in order to run. You generate a library-type project with `nest generate library`. Deciding what belongs in a library is an architectural design decision. We discuss libraries in depth in the [libraries](/v11/cli/libraries) chapter.

#### CLI properties[#](/cli/monorepo#cli-properties)

Nest keeps the metadata needed to organize, build and deploy both standard and monorepo structured projects in the `nest-cli.json` file. Nest automatically adds to and updates this file as you add projects, so you usually do not have to think about it or edit its contents. However, there are some settings you may want to change manually, so it's helpful to have an overview understanding of the file.

After running the steps above to create a monorepo, our `nest-cli.json` file looks like this:

```javascript

{
  "collection": "@nestjs/schematics",
  "sourceRoot": "apps/my-project/src",
  "monorepo": true,
  "root": "apps/my-project",
  "compilerOptions": {
    "webpack": true,
    "tsConfigPath": "apps/my-project/tsconfig.app.json"
  },
  "projects": {
    "my-project": {
      "type": "application",
      "root": "apps/my-project",
      "entryFile": "main",
      "sourceRoot": "apps/my-project/src",
      "compilerOptions": {
        "tsConfigPath": "apps/my-project/tsconfig.app.json"
      }
    },
    "my-app": {
      "type": "application",
      "root": "apps/my-app",
      "entryFile": "main",
      "sourceRoot": "apps/my-app/src",
      "compilerOptions": {
        "tsConfigPath": "apps/my-app/tsconfig.app.json"
      }
    }
  }
}
```

| Property Name       | Property Value Type | Description                                                                                                                                                                                                                                                               |
| ------------------- | ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `webpack`           | boolean             | If `true`, use [webpack compiler](https://webpack.js.org/). If `false` or not present, use `tsc`. In monorepo mode, the default is `true` (use webpack), in standard mode, the default is `false` (use `tsc`). See below for details. (deprecated: use `builder` instead) |
| `tsConfigPath`      | string              | (**monorepo only**) Points at the file containing the `tsconfig.json` settings that will be used when `nest build` or `nest start` is called without a `project` option (e.g., when the default project is built or started).                                             |
| `webpackConfigPath` | string              | Points at a webpack options file. If not specified, Nest looks for the file `webpack.config.js`. See below for more details.                                                                                                                                              |
| `deleteOutDir`      | boolean             | If `true`, whenever the compiler is invoked, it will first remove the compilation output directory (as configured in `tsconfig.json`, where the default is `./dist`).                                                                                                     |
| `assets`            | array               | Enables automatically distributing non-TypeScript assets whenever a compilation step begins (asset distribution does **not** happen on incremental compiles in `--watch` mode). See below for details.                                                                    |
| `watchAssets`       | boolean             | If `true`, run in watch-mode, watching **all** non-TypeScript assets. (For more fine-grained control of the assets to watch, see [Assets](cli/monorepo#assets) section below).                                                                                            |
| `manualRestart`     | boolean             | If `true`, enables the shortcut `rs` to manually restart the server. Default value is `false`.                                                                                                                                                                            |
| `builder`           | string/object       | Instructs CLI on what `builder` to use to compile the project (`tsc`, `swc`, or `webpack`). To customize builder's behavior, you can pass an object containing two attributes: `type` (`tsc`, `swc`, or `webpack`) and `options`.                                         |
| `typeCheck`         | boolean             | If `true`, enables type checking for SWC-driven projects (when `builder` is `swc`). Default value is `false`.                                                                                                                                                             |

#### Global generate options[#](/cli/monorepo#global-generate-options)

These properties specify the default generate options to be used by the `nest generate` command.

| Property Name | Property Value Type | Description                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| ------------- | ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `spec`        | boolean *or* object | If the value is boolean, a value of `true` enables `spec` generation by default and a value of `false` disables it. A flag passed on the CLI command line overrides this setting, as does a project-specific `generateOptions` setting (more below). If the value is an object, each key represents a schematic name, and the boolean value determines whether the default spec generation is enabled / disabled for that specific schematic. |
| `flat`        | boolean             | If true, all generate commands will generate a flat structure                                                                                                                                                                                                                                                                                                                                                                                 |

The following example uses a boolean value to specify that spec file generation should be disabled by default for all projects:

```javascript

{
  "generateOptions": {
    "spec": false
  },
  ...
}
```

The following example uses a boolean value to specify flat file generation should be the default for all projects:

```javascript

{
  "generateOptions": {
    "flat": true
  },
  ...
}
```

In the following example, `spec` file generation is disabled only for `service` schematics (e.g., `nest generate service...`):

```javascript

{
  "generateOptions": {
    "spec": {
      "service": false
    }
  },
  ...
}
```

> **Warning** When specifying the `spec` as an object, the key for the generation schematic does not currently support automatic alias handling. This means that specifying a key as for example `service: false` and trying to generate a service via the alias `s`, the spec would still be generated. To make sure both the normal schematic name and the alias work as intended, specify both the normal command name as well as the alias, as seen below.
>
> ```javascript
>
> {
>   "generateOptions": {
>     "spec": {
>       "service": false,
>       "s": false
>     }
>   },
>   ...
> }
> ```

#### Project-specific generate options[#](/cli/monorepo#project-specific-generate-options)

In addition to providing global generate options, you may also specify project-specific generate options. The project specific generate options follow the exact same format as the global generate options, but are specified directly on each project.

Project-specific generate options override global generate options.

```javascript

{
  "projects": {
    "cats-project": {
      "generateOptions": {
        "spec": {
          "service": false
        }
      },
      ...
    }
  },
  ...
}
```

> **Warning** The order of precedence for generate options is as follows. Options specified on the CLI command line take precedence over project-specific options. Project-specific options override global options.

#### Specified compiler[#](/cli/monorepo#specified-compiler)

The reason for the different default compilers is that for larger projects (e.g., more typical in a monorepo) webpack can have significant advantages in build times and in producing a single file bundling all project components together. If you wish to generate individual files, set `"webpack"` to `false`, which will cause the build process to use `tsc` (or `swc`).

#### Webpack options[#](/cli/monorepo#webpack-options)

The webpack options file can contain standard [webpack configuration options](https://webpack.js.org/configuration/). For example, to tell webpack to bundle `node_modules` (which are excluded by default), add the following to `webpack.config.js`:

```javascript

module.exports = {
  externals: [],
};
```

Since the webpack config file is a JavaScript file, you can even expose a function that takes default options and returns a modified object:

```javascript

module.exports = function (options) {
  return {
    ...options,
    externals: [],
  };
};
```

#### Assets[#](/cli/monorepo#assets)

TypeScript compilation automatically distributes compiler output (`.js` and `.d.ts` files) to the specified output directory. It can also be convenient to distribute non-TypeScript files, such as `.graphql` files, `images`, `.html` files and other assets. This allows you to treat `nest build` (and any initial compilation step) as a lightweight **development build** step, where you may be editing non-TypeScript files and iteratively compiling and testing. The assets should be located in the `src` folder otherwise they will not be copied.

The value of the `assets` key should be an array of elements specifying the files to be distributed. The elements can be simple strings with `glob`-like file specs, for example:

```typescript

"assets": ["**/*.graphql"],
"watchAssets": true,
```

For finer control, the elements can be objects with the following keys:

* `"include"`: `glob`-like file specifications for the assets to be distributed
* `"exclude"`: `glob`-like file specifications for assets to be **excluded** from the `include` list
* `"outDir"`: a string specifying the path (relative to the root folder) where the assets should be distributed. Defaults to the same output directory configured for compiler output.
* `"watchAssets"`: boolean; if `true`, run in watch mode watching specified assets

For example:

```typescript

"assets": [
  { "include": "**/*.graphql", "exclude": "**/omitted.graphql", "watchAssets": true },
]
```

> **Warning** Setting `watchAssets` in a top-level `compilerOptions` property overrides any `watchAssets` settings within the `assets` property.

#### Project properties[#](/cli/monorepo#project-properties)

This element exists only for monorepo-mode structures. You generally should not edit these properties, as they are used by Nest to locate projects and their configuration options within the monorepo.

----
url: https://docs.nestjs.com/v4/first-steps
----

### First Steps

In this set of articles, you'll learn the **core fundamentals** of Nest. The main idea is to get familiar with essential Nest application building blocks. You'll build a basic CRUD application which features covers a lot of ground at an introductory level.

### Language

We're in love with [TypeScript](http://www.typescriptlang.org/), but above all - we love [Node.js](https://nodejs.org/en/). That's why Nest is compatible with both TypeScript and **pure JavaScript**. Nest is taking advantage of latest language features, so to use a framework with simple JavaScript we need a [Babel](http://babeljs.io/) compiler.

In the articles, we're mostly using TypeScript, but you can always **switch the code snippets** to the JavaScript version when it contains some TypeScript-specific expressions.

### Prerequisites

Please make sure that [Node.js](https://nodejs.org/) (>= 6.11.0) is installed on your operating system.

### Setup

Setting up a new project is quite simple with [Starter repository](https://github.com/kamilmysliwiec/nest-typescript-starter). Just make sure that you have [npm](https://www.npmjs.com/) installed then use following commands in your OS terminal:

JavaScript TypeScript

```bash

$ git clone https://github.com/nestjs/typescript-starter.git project
$ cd project
$ npm install
```

```bash

$ git clone https://github.com/nestjs/javascript-starter.git project
$ cd project
$ npm install
```

The `project` directory will contain several core files inside `src` directory.

src

app.controller.ts

app.module.ts

main.ts

Following the convention, newly created modules should have a dedicated directory.

|                     |                                                                                                   |
| ------------------- | ------------------------------------------------------------------------------------------------- |
| `main.ts`           | The entry file of the application. It uses `NestFactory` to create the Nest application instance. |
| `app.module.ts`     | Defines `AppModule`, the root module of the application.                                          |
| `app.controller.ts` | Basic controller sample with a single route.                                                      |

The `main.ts` includes an async function, which responsibility is to **bootstrap** our application:

main.ts

JavaScript TypeScript

TypeScript

```typescript

import { NestFactory } from '@nestjs/core';
import { ApplicationModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(ApplicationModule);
  await app.listen(3000);
}
bootstrap();
```

To create a Nest application instance, we are using the `NestFactory`. The `create()` method returns an object, which fulfills `INestApplication` interface, and provides a set of usable methods, which are well described in the next chapters.

### Running application

Once the installation process is completed, you can run the following command to start the HTTP server:

```bash

$ npm run start
```

This command starts the HTTP server on the port defined inside the `main.ts` file in the `src` directory. While the application is running, open your browser and navigate to `http://localhost:3000/`. You should see the `Hello world!` message.

#### Sponsors

[](https://valor-software.com/)

Nest is an MIT-licensed open source project. It can grow thanks to the support by these awesome people. If you'd like to join them, please read more [here](https://opencollective.com/nest). Thanks!

[](https://opencollective.com/nest/backer/0/website)[](https://opencollective.com/nest/backer/1/website)[](https://opencollective.com/nest/backer/2/website)[](https://opencollective.com/nest/backer/3/website)[](https://opencollective.com/nest/backer/4/website)[](https://opencollective.com/nest/backer/5/website)[](https://opencollective.com/nest/backer/6/website)[](https://opencollective.com/nest/backer/7/website)[](https://opencollective.com/nest/backer/8/website)[](https://opencollective.com/nest/backer/9/website)[](https://opencollective.com/nest/backer/10/website)[](https://opencollective.com/nest/backer/11/website)[](https://opencollective.com/nest/backer/12/website)[](https://opencollective.com/nest/backer/13/website)[](https://opencollective.com/nest/backer/14/website)[](https://opencollective.com/nest/backer/15/website)[](https://opencollective.com/nest/backer/16/website)[](https://opencollective.com/nest/backer/17/website)[](https://opencollective.com/nest/backer/18/website)[](https://opencollective.com/nest/backer/19/website)[](https://opencollective.com/nest/backer/20/website)[](https://opencollective.com/nest/backer/21/website)[](https://opencollective.com/nest/backer/22/website)[](https://opencollective.com/nest/backer/23/website)[](https://opencollective.com/nest/backer/24/website)[](https://opencollective.com/nest/backer/25/website)[](https://opencollective.com/nest/backer/26/website)[](https://opencollective.com/nest/backer/27/website)[](https://opencollective.com/nest/backer/28/website)[](https://opencollective.com/nest/backer/29/website)

[Become a sponsor](https://opencollective.com/nest)

----
url: https://docs.nestjs.com/fundamentals/dynamic-modules
----

[Skip to content](#content)

On this page

* [Dynamic modules](https://docs.nestjs.com/fundamentals/dynamic-modules#dynamic-modules)
* [Introduction](https://docs.nestjs.com/fundamentals/dynamic-modules#introduction)
* [Dynamic module use case](https://docs.nestjs.com/fundamentals/dynamic-modules#dynamic-module-use-case)
* [Dynamic module example](https://docs.nestjs.com/fundamentals/dynamic-modules#dynamic-module-example)
* [Module configuration](https://docs.nestjs.com/fundamentals/dynamic-modules#module-configuration)
* [Community guidelines](https://docs.nestjs.com/fundamentals/dynamic-modules#community-guidelines)
* [Configurable module builder](https://docs.nestjs.com/fundamentals/dynamic-modules#configurable-module-builder)
* [Custom method key](https://docs.nestjs.com/fundamentals/dynamic-modules#custom-method-key)
* [Custom options factory class](https://docs.nestjs.com/fundamentals/dynamic-modules#custom-options-factory-class)
* [Extra options](https://docs.nestjs.com/fundamentals/dynamic-modules#extra-options)
* [Extending auto-generated methods](https://docs.nestjs.com/fundamentals/dynamic-modules#extending-auto-generated-methods)

[](https://srv.carbonads.net/ads/click/x/GTND4277CVSD5KJUCAYLYKQUF67D62Q7CW7DTZ3JCAAI6KQJCASIV2QKCKYIVK3UCYAIP2JECA7DTKQUCESDC53KC6SILKJUCT7DEK3EHJNCLSIZ)[Your side project deserves Lambda, not localhost. Start building ](https://srv.carbonads.net/ads/click/x/GTND4277CVSD5KJUCAYLYKQUF67D62Q7CW7DTZ3JCAAI6KQJCASIV2QKCKYIVK3UCYAIP2JECA7DTKQUCESDC53KC6SILKJUCT7DEK3EHJNCLSIZ)[ads via Carbon](http://carbonads.net/?utm_source=nestjscom\&utm_medium=ad_via_link\&utm_campaign=in_unit\&utm_term=carbon)

### Dynamic modules

The [Modules chapter](/modules) covers the basics of Nest modules and includes a brief introduction to [dynamic modules](/modules#dynamic-modules). This chapter expands on the subject: what dynamic modules are, how to build them, and when to use them.

#### Introduction[#](/fundamentals/dynamic-modules#introduction)

Most code examples in the **Overview** section of the documentation use regular, or static, modules. Modules define groups of components, such as [providers](/providers) and [controllers](/controllers), that fit together as a modular part of an application. They provide an execution context, or scope, for these components. For example, providers defined in a module are visible to other members of the module without being exported. When a provider needs to be visible outside of a module, it is first exported from its host module, and then imported into its consuming module.

Consider a familiar example. First, a `UsersModule` provides and exports a `UsersService`. `UsersModule` is the **host** module for `UsersService`.

```typescript

import { Module } from '@nestjs/common';
import { UsersService } from './users.service.js';

@Module({
  providers: [UsersService],
  exports: [UsersService],
})
export class UsersModule {}
```

Next, an `AuthModule` imports `UsersModule`, which makes `UsersModule`'s exported providers available inside `AuthModule`:

```typescript

import { Module } from '@nestjs/common';
import { AuthService } from './auth.service.js';
import { UsersModule } from '../users/users.module.js';

@Module({
  imports: [UsersModule],
  providers: [AuthService],
  exports: [AuthService],
})
export class AuthModule {}
```

These constructs allow us to inject `UsersService` into, for example, the `AuthService` hosted in `AuthModule`:

```typescript

import { Injectable } from '@nestjs/common';
import { UsersService } from '../users/users.service.js';

@Injectable()
export class AuthService {
  constructor(private readonly usersService: UsersService) {}
  /*
    Implementation that makes use of this.usersService
  */
}
```

We'll refer to this as **static** module binding. All the information Nest needs to wire the modules together is declared in the host and consuming modules. Nest makes `UsersService` available inside `AuthModule` by:

1. Instantiating `UsersModule`, including transitively importing the modules that `UsersModule` itself consumes, and transitively resolving any dependencies (see [Custom providers](/fundamentals/custom-providers)).
2. Instantiating `AuthModule`, and making `UsersModule`'s exported providers available to components in `AuthModule` (as if they had been declared in `AuthModule`).
3. Injecting an instance of `UsersService` into `AuthService`.

#### Dynamic module use case[#](/fundamentals/dynamic-modules#dynamic-module-use-case)

With static module binding, the consuming module has no way to **influence** how the providers of the host module are configured. This matters for general-purpose modules that need to behave differently for each consumer, much like a "plugin" that requires some configuration before it can be used.

As an example, consider a module that generates the public identifiers of your entities. Identifiers that start with a type prefix, such as `usr_` for users and `ord_` for orders, tell you at a glance what kind of entity they refer to. The generation logic is the same for every entity, and only the prefix differs. With static binding, an `IdGeneratorModule` could provide only one generator, configured one way for every module that imports it. What we need instead is for `UsersModule` and `OrdersModule` to each import the module with their own prefix.

This is where **dynamic modules** come into play. A dynamic module provides an API for importing one module into another and customizing the properties and behavior of that module at the time it is imported.

## Debug production with NestJS Observe

* Every request traced
* Errors with source code
* Logs in context
* Zero config, free plan

[Start for free](https://observe.nestjs.com "Observe | NestJS - A progressive Node.js framework")

#### Dynamic module example[#](/fundamentals/dynamic-modules#dynamic-module-example)

It's helpful to start from how the module looks from the consuming module's perspective, and then work backwards. A static import leaves no room to pass a prefix:

```typescript

import { Module } from '@nestjs/common';
import { IdGeneratorModule } from '../id-generator/id-generator.module.js';
import { UsersService } from './users.service.js';

@Module({
  imports: [IdGeneratorModule],
  providers: [UsersService],
})
export class UsersModule {}
```

A dynamic import, on the other hand, passes an options object. Compare the `imports` arrays of the two examples:

```typescript

import { Module } from '@nestjs/common';
import { IdGeneratorModule } from '../id-generator/id-generator.module.js';
import { UsersService } from './users.service.js';

@Module({
  imports: [IdGeneratorModule.register({ prefix: 'usr' })],
  providers: [UsersService],
})
export class UsersModule {}
```

Let's look at the moving parts of the dynamic example:

1. `IdGeneratorModule` is a normal class, so it must have a **static method** called `register()`. The method is static because it's called on the class, not on an **instance** of the class. The method can have any name, but by convention it's called `register()`, `forRoot()`, or `forFeature()` (see [Community guidelines](/fundamentals/dynamic-modules#community-guidelines)).
2. We define the `register()` method ourselves, so it can accept any arguments we like. Typically, as here, it accepts an options object.
3. The value returned by `register()` appears in the `imports` array, alongside module classes, so it must be something Nest can treat as a module.

In fact, `register()` returns a `DynamicModule`. A dynamic module is a module created at runtime. It has exactly the same properties as the metadata of a static module, plus one additional property called `module`. Here's a sample static module declaration, for comparison:

```typescript

@Module({
  imports: [DogsModule],
  controllers: [CatsController],
  providers: [CatsService],
  exports: [CatsService],
})
```

A dynamic module is an object with the same properties, plus the `module` property, which references the module class itself.

> **Hint** For a dynamic module, all properties of the module options object are optional **except**`module`.

The job of the static `register()` method is therefore to return an object that implements the `DynamicModule` interface. Calling it provides a module to the `imports` array, much like listing a module class does in the static case. The difference is that the module's properties are specified programmatically instead of being fixed in the `@Module()` decorator.

Two more details complete the picture:

1. The `imports` array of the `@Module()` decorator accepts not only module classes (e.g., `imports: [UsersModule]`), but also the dynamic modules returned by static methods (e.g., `imports: [IdGeneratorModule.register(...)]`).
2. A dynamic module can itself import other modules. If it depends on providers from other modules, list them in its optional `imports` property, exactly as you would in the `@Module()` decorator of a static module.

With this in mind, here's a first version of the dynamic `IdGeneratorModule`:

```typescript

import { DynamicModule, Module } from '@nestjs/common';
import { IdGenerator } from './id-generator.js';

@Module({})
export class IdGeneratorModule {
  static register(): DynamicModule {
    return {
      module: IdGeneratorModule,
      providers: [IdGenerator],
      exports: [IdGenerator],
    };
  }
}
```

Calling `IdGeneratorModule.register()` returns a `DynamicModule` object whose properties are essentially the same as those that, until now, we've provided as metadata through the `@Module()` decorator.

> **Hint** Import `DynamicModule` from `@nestjs/common`.

This module isn't configurable yet, though. Let's address that next.

#### Module configuration[#](/fundamentals/dynamic-modules#module-configuration)

The consuming module passes the options to `register()`, as shown above. The question is how to get them to the component that needs them. `IdGeneratorModule` hosts and exports an injectable service, `IdGenerator`, and it's `IdGenerator` that needs the prefix. For now, the service hard-codes it:

```typescript

import { Injectable } from '@nestjs/common';
import { randomUUID } from 'node:crypto';

@Injectable()
export class IdGenerator {
  generate(): string {
    const options = { prefix: 'usr' };
    return `${options.prefix}_${randomUUID()}`;
  }
}
```

Our remaining task is to pass the `options` object from the `register()` method to `IdGenerator`, and we'll use *dependency injection* to do it. This is the key point: `IdGeneratorModule` provides `IdGenerator`, and `IdGenerator` depends on an `options` object that is supplied only at runtime. So, at runtime, we first bind the `options` object to the Nest IoC container, and then let Nest inject it into `IdGenerator`. As the **Custom providers** chapter explains, providers can [be any value](/fundamentals/custom-providers#non-service-based-providers), not only services, so a plain `options` object works too.

First, describe the options with an interface, and define an injection token for them. A token defined as a constant (or a `Symbol`) in a separate file can be imported wherever it's needed:

id-generator.interfaces.ts

JS TS

```typescript

export interface IdGeneratorModuleOptions {
  prefix: string;
}

export const ID_GENERATOR_OPTIONS = 'ID_GENERATOR_OPTIONS';
```

Next, bind the options object to the IoC container in the static `register()` method. We are constructing a module dynamically, and one of the properties of a module is its list of providers, so we define the options object as a provider. Pay attention to the `providers` array:

```typescript

import { DynamicModule, Module } from '@nestjs/common';
import { IdGenerator } from './id-generator.js';
import {
  ID_GENERATOR_OPTIONS,
  IdGeneratorModuleOptions,
} from './id-generator.interfaces.js';

@Module({})
export class IdGeneratorModule {
  static register(options: IdGeneratorModuleOptions): DynamicModule {
    return {
      module: IdGeneratorModule,
      providers: [
        {
          provide: ID_GENERATOR_OPTIONS,
          useValue: options,
        },
        IdGenerator,
      ],
      exports: [IdGenerator],
    };
  }
}
```

Now inject the options into `IdGenerator`. A provider registered with a non-class token is injected with the `@Inject()` decorator, as described in [Non-class-based provider tokens](/fundamentals/custom-providers#non-class-based-provider-tokens):

```typescript

import { Inject, Injectable } from '@nestjs/common';
import { randomUUID } from 'node:crypto';
import {
  ID_GENERATOR_OPTIONS,
  type IdGeneratorModuleOptions,
} from './id-generator.interfaces.js';

@Injectable()
export class IdGenerator {
  constructor(
    @Inject(ID_GENERATOR_OPTIONS)
    private readonly options: IdGeneratorModuleOptions,
  ) {}

  generate(): string {
    return `${this.options.prefix}_${randomUUID()}`;
  }
}
```

With that in place, each consuming module configures its own generator:

```typescript

@Module({
  imports: [IdGeneratorModule.register({ prefix: 'usr' })],
  providers: [UsersService],
})
export class UsersModule {}

@Module({
  imports: [IdGeneratorModule.register({ prefix: 'ord' })],
  providers: [OrdersService],
})
export class OrdersModule {}
```

`UsersService` and `OrdersService` both inject `IdGenerator`, but each receives its own instance, configured by the module that imported it: user identifiers start with `usr_`, and order identifiers with `ord_`.

A working example is available in the [dynamic modules sample](https://github.com/nestjs/nest/tree/master/sample/25-dynamic-modules) on GitHub.

#### Community guidelines[#](/fundamentals/dynamic-modules#community-guidelines)

You may have seen methods like `forRoot()`, `register()`, and `forFeature()` in some of the `@nestjs/` packages, and wondered how they differ. There is no hard rule, but the `@nestjs/` packages follow these guidelines:

* `register()` configures a dynamic module for use only by the calling module, as our `IdGeneratorModule` does. For example, with `@nestjs/http-client`, `HttpClientModule.register({ baseUrl: 'someUrl' })` configures an HTTP client for the calling module. Another module can call `HttpClientModule.register({ baseUrl: 'somewhere else' })` to get a differently configured client. You can do this in as many modules as you want.
* `forRoot()` configures a dynamic module once and reuses that configuration in multiple places (possibly without the consumers being aware of it). This is why an application has one `GraphQLModule.forRoot()`, one `TypeOrmModule.forRoot()`, and so on.
* `forFeature()` uses the configuration set up by `forRoot()`, but modifies some of it for the needs of the calling module (e.g., which repositories the module has access to, or the context a logger should use).

Each of these usually has an asynchronous counterpart, `registerAsync()`, `forRootAsync()`, and `forFeatureAsync()`, which means the same thing, but resolves the configuration through Nest's dependency injection.

#### Configurable module builder[#](/fundamentals/dynamic-modules#configurable-module-builder)

Manually creating highly configurable dynamic modules that also expose asynchronous methods (`registerAsync()`, `forRootAsync()`, etc.) is complicated, especially for newcomers. To simplify this, Nest provides the `ConfigurableModuleBuilder` class, which constructs a module "blueprint" in a few lines of code.

As an example, let's convert the `IdGeneratorModule` above to use the `ConfigurableModuleBuilder`. It keeps the `IdGeneratorModuleOptions` interface, but the builder generates the injection token, so the `ID_GENERATOR_OPTIONS` constant is no longer needed.

Create a new file alongside `id-generator.module.ts`, named `id-generator.module-definition.ts`, and use the `ConfigurableModuleBuilder` to construct the `IdGeneratorModule` definition:

id-generator.module-definition.ts

JS TS

```typescript

import { ConfigurableModuleBuilder } from '@nestjs/common';
import type { IdGeneratorModuleOptions } from './id-generator.interfaces.js';

export const { ConfigurableModuleClass, MODULE_OPTIONS_TOKEN } =
  new ConfigurableModuleBuilder<IdGeneratorModuleOptions>().build();
```

```typescript

import { ConfigurableModuleBuilder } from '@nestjs/common';

export const { ConfigurableModuleClass, MODULE_OPTIONS_TOKEN } =
  new ConfigurableModuleBuilder().build();
```

Next, change `id-generator.module.ts` to extend the generated `ConfigurableModuleClass`:

```typescript

import { Module } from '@nestjs/common';
import { IdGenerator } from './id-generator.js';
import { ConfigurableModuleClass } from './id-generator.module-definition.js';

@Module({
  providers: [IdGenerator],
  exports: [IdGenerator],
})
export class IdGeneratorModule extends ConfigurableModuleClass {}
```

As with any dynamic module, the metadata returned by the generated methods extends the metadata in the `@Module()` decorator, so `IdGenerator` is provided and exported alongside the generated options provider.

Finally, update `IdGenerator` to inject the generated options provider instead of the `ID_GENERATOR_OPTIONS` token:

```typescript

import { Inject, Injectable } from '@nestjs/common';
import { randomUUID } from 'node:crypto';
import type { IdGeneratorModuleOptions } from './id-generator.interfaces.js';
import { MODULE_OPTIONS_TOKEN } from './id-generator.module-definition.js';

@Injectable()
export class IdGenerator {
  constructor(
    @Inject(MODULE_OPTIONS_TOKEN)
    private readonly options: IdGeneratorModuleOptions,
  ) {}

  generate(): string {
    return `${this.options.prefix}_${randomUUID()}`;
  }
}
```

Extending `ConfigurableModuleClass` gives `IdGeneratorModule` not only the `register()` method (as the manual implementation did), but also `registerAsync()`, which lets consumers configure the module asynchronously. For example, the following factory reads the prefix with the `ConfigService` from [`@nestjs/config`](/application/configuration):

```typescript

import { Module } from '@nestjs/common';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { IdGeneratorModule } from '../id-generator/id-generator.module.js';
import { UsersService } from './users.service.js';

@Module({
  imports: [
    IdGeneratorModule.registerAsync({
      imports: [ConfigModule],
      useFactory: (configService: ConfigService) => ({
        prefix: configService.getOrThrow<string>('USER_ID_PREFIX'),
      }),
      inject: [ConfigService],
    }),
  ],
  providers: [UsersService],
})
export class UsersModule {}
```

The `registerAsync()` method takes an object with the following properties:

```typescript

{
  /**
   * Modules whose exported providers the factory, class, or existing
   * provider depends on.
   */
  imports?: ModuleMetadata['imports'];
  /**
   * Function returning options (or a Promise resolving to options) to configure the
   * module.
   */
  useFactory?: (...args: any[]) => Promise<ModuleOptions> | ModuleOptions;
  /**
   * Dependencies that a Factory may inject.
   */
  inject?: FactoryProvider['inject'];
  /**
   * Injection token resolving to a class that will be instantiated as a provider.
   * The class must implement the corresponding interface.
   */
  useClass?: Type<
    ConfigurableModuleOptionsFactory<ModuleOptions, FactoryClassMethodKey>
  >;
  /**
   * Injection token resolving to an existing provider. The provider must implement
   * the corresponding interface.
   */
  useExisting?: Type<
    ConfigurableModuleOptionsFactory<ModuleOptions, FactoryClassMethodKey>
  >;
  /**
   * List of parent module's providers that will be filtered to only provide necessary
   * providers for the 'inject' array.
   */
  provideInjectionTokensFrom?: Provider[];
}
```

Let's go through these properties one by one:

* `imports` - modules to import into the dynamic module, so that the factory, class, or existing provider can inject their exported providers. The example above imports `ConfigModule` to inject `ConfigService`.
* `useFactory` - a function that returns the options object. It can be either synchronous or asynchronous. To inject dependencies into the factory function, use the `inject` property. The example above uses this variant.
* `inject` - an array of dependencies to inject into the factory function. The order of the dependencies must match the order of the factory function's parameters.
* `useClass` - a class to instantiate as a provider. The class must implement the corresponding interface, which by default means providing a `create()` method that returns the options object. See [Custom options factory class](/fundamentals/dynamic-modules#custom-options-factory-class) below.
* `useExisting` - a variant of `useClass` that reuses an existing provider instead of instructing Nest to create a new instance of the class. The provider must implement the same interface as a `useClass` class (and so must provide the `create()` method, unless you change the method name, as described in [Custom options factory class](/fundamentals/dynamic-modules#custom-options-factory-class) below).
* `provideInjectionTokensFrom` - used together with `useFactory` (or `useExisting`) and `inject`: a list of providers from which Nest picks the ones listed in `inject` and registers them in the dynamic module. This is useful when a module passes its own options on to a nested module that it configures asynchronously.

Always choose exactly one of `useFactory`, `useClass`, and `useExisting`, as they are mutually exclusive.

#### Custom method key[#](/fundamentals/dynamic-modules#custom-method-key)

By default, `ConfigurableModuleClass` provides the `register()` method and its `registerAsync()` counterpart. To use a different method name, use the `ConfigurableModuleBuilder#setClassMethodName` method. For example, if your module is meant to be configured once for the entire application, the [community guidelines](/fundamentals/dynamic-modules#community-guidelines) suggest `forRoot()`:

id-generator.module-definition.ts

JS TS

```typescript

export const { ConfigurableModuleClass, MODULE_OPTIONS_TOKEN } =
  new ConfigurableModuleBuilder<IdGeneratorModuleOptions>()
    .setClassMethodName('forRoot')
    .build();
```

```typescript

export const { ConfigurableModuleClass, MODULE_OPTIONS_TOKEN } =
  new ConfigurableModuleBuilder().setClassMethodName('forRoot').build();
```

This instructs `ConfigurableModuleBuilder` to generate a class that exposes `forRoot()` and `forRootAsync()` instead:

```typescript

@Module({
  imports: [
    IdGeneratorModule.forRoot({ prefix: 'id' }), // <-- note "forRoot" instead of "register"
    // or alternatively:
    // IdGeneratorModule.forRootAsync({
    //   useFactory: () => ({ prefix: 'id' }),
    //   inject: [...any extra dependencies...],
    // }),
  ],
})
export class AppModule {}
```

#### Custom options factory class[#](/fundamentals/dynamic-modules#custom-options-factory-class)

Because the `registerAsync()` method (or `forRootAsync()`, or any other name, depending on the configuration) lets consumers pass a provider definition that resolves to the module options, a consumer can also supply a class that constructs the options object:

```typescript

@Module({
  imports: [
    IdGeneratorModule.registerAsync({
      useClass: IdGeneratorConfigService,
    }),
  ],
})
export class UsersModule {}
```

By default, this class must provide a `create()` method that returns the module options. The `ConfigurableModuleOptionsFactory` interface, exported from `@nestjs/common`, describes this contract:

```typescript

import { ConfigurableModuleOptionsFactory, Injectable } from '@nestjs/common';
import type { IdGeneratorModuleOptions } from '../id-generator/id-generator.interfaces.js';

@Injectable()
export class IdGeneratorConfigService
  implements ConfigurableModuleOptionsFactory<IdGeneratorModuleOptions, 'create'>
{
  create(): IdGeneratorModuleOptions {
    return { prefix: 'usr' };
  }
}
```

If your library follows a different naming convention, instruct `ConfigurableModuleBuilder` to expect a different method, for example, `createIdGeneratorOptions`, with the `ConfigurableModuleBuilder#setFactoryMethodName` method:

id-generator.module-definition.ts

JS TS

```typescript

export const { ConfigurableModuleClass, MODULE_OPTIONS_TOKEN } =
  new ConfigurableModuleBuilder<IdGeneratorModuleOptions>()
    .setFactoryMethodName('createIdGeneratorOptions')
    .build();
```

```typescript

export const { ConfigurableModuleClass, MODULE_OPTIONS_TOKEN } =
  new ConfigurableModuleBuilder()
    .setFactoryMethodName('createIdGeneratorOptions')
    .build();
```

Now the `IdGeneratorConfigService` class must expose the `createIdGeneratorOptions()` method instead of `create()`:

```typescript

@Module({
  imports: [
    IdGeneratorModule.registerAsync({
      useClass: IdGeneratorConfigService, // <-- this class must provide the "createIdGeneratorOptions" method
    }),
  ],
})
export class UsersModule {}
```

#### Extra options[#](/fundamentals/dynamic-modules#extra-options)

In some cases, a module needs extra options that determine how it behaves, but that shouldn't be included in the `MODULE_OPTIONS_TOKEN` provider, because they are irrelevant to the providers registered within the module. A good example is an `isGlobal` flag: `IdGenerator` doesn't need to know whether its host module is registered as a global module.

For such options, use the `ConfigurableModuleBuilder#setExtras` method:

```typescript

export const { ConfigurableModuleClass, MODULE_OPTIONS_TOKEN } =
  new ConfigurableModuleBuilder<IdGeneratorModuleOptions>()
    .setExtras(
      {
        isGlobal: false,
      },
      (definition, extras) => ({
        ...definition,
        global: extras.isGlobal,
      }),
    )
    .build();
```

The first argument passed to the `setExtras` method is an object with the default values of the extra properties. The second argument is a function that receives the auto-generated module definition (with `providers`, `exports`, etc.) and the `extras` object, which holds the extra properties (either specified by the consumer or the defaults). The function returns the modified module definition. In this example, the `extras.isGlobal` property is assigned to the `global` property of the module definition, which determines whether the module is global (see [Dynamic modules](/modules#dynamic-modules) in the Modules chapter).

Now, when importing this module, consumers can pass the additional `isGlobal` flag. For example, an application that uses one prefix for all of its identifiers can register the module once, globally:

```typescript

@Module({
  imports: [
    IdGeneratorModule.register({
      isGlobal: true,
      prefix: 'id',
    }),
  ],
})
export class AppModule {}
```

However, since `isGlobal` is declared as an extra property, it isn't part of the options object provided by `MODULE_OPTIONS_TOKEN`:

```typescript

@Injectable()
export class IdGenerator {
  constructor(
    @Inject(MODULE_OPTIONS_TOKEN)
    private readonly options: IdGeneratorModuleOptions,
  ) {
    // "options" object will not have the "isGlobal" property
    // ...
  }
}
```

#### Extending auto-generated methods[#](/fundamentals/dynamic-modules#extending-auto-generated-methods)

The auto-generated static methods (`register()`, `registerAsync()`, etc.) can be extended if needed, as follows:

```typescript

import { DynamicModule, Module } from '@nestjs/common';
import { IdGenerator } from './id-generator.js';
import {
  ASYNC_OPTIONS_TYPE,
  ConfigurableModuleClass,
  OPTIONS_TYPE,
} from './id-generator.module-definition.js';

@Module({
  providers: [IdGenerator],
  exports: [IdGenerator],
})
export class IdGeneratorModule extends ConfigurableModuleClass {
  static register(options: typeof OPTIONS_TYPE): DynamicModule {
    return {
      // your custom logic here
      ...super.register(options),
    };
  }

  static registerAsync(options: typeof ASYNC_OPTIONS_TYPE): DynamicModule {
    return {
      // your custom logic here
      ...super.registerAsync(options),
    };
  }
}
```

Note the `OPTIONS_TYPE` and `ASYNC_OPTIONS_TYPE` types, which must be exported from the module definition file:

```typescript

export const {
  ConfigurableModuleClass,
  MODULE_OPTIONS_TOKEN,
  OPTIONS_TYPE,
  ASYNC_OPTIONS_TYPE,
} = new ConfigurableModuleBuilder<IdGeneratorModuleOptions>().build();
```

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/fundamentals/dynamic-modules.md)

----
url: https://docs.nestjs.com/microservices/rabbitmq
----

[Skip to content](#content)

On this page

* [RabbitMQ](https://docs.nestjs.com/microservices/rabbitmq#rabbitmq)
* [Installation](https://docs.nestjs.com/microservices/rabbitmq#installation)
* [Overview](https://docs.nestjs.com/microservices/rabbitmq#overview)
* [Options](https://docs.nestjs.com/microservices/rabbitmq#options)
* [Client](https://docs.nestjs.com/microservices/rabbitmq#client)
* [Context](https://docs.nestjs.com/microservices/rabbitmq#context)
* [Message acknowledgement](https://docs.nestjs.com/microservices/rabbitmq#message-acknowledgement)
* [Record builders](https://docs.nestjs.com/microservices/rabbitmq#record-builders)
* [Instance status updates](https://docs.nestjs.com/microservices/rabbitmq#instance-status-updates)
* [Listening to RabbitMQ events](https://docs.nestjs.com/microservices/rabbitmq#listening-to-rabbitmq-events)
* [Underlying driver access](https://docs.nestjs.com/microservices/rabbitmq#underlying-driver-access)
* [Wildcards](https://docs.nestjs.com/microservices/rabbitmq#wildcards)

[](https://srv.carbonads.net/ads/click/x/GTND4277CVSD5KJUCAYLYKQUF67D62QUF6BIKZ3JCAAI623WC67ITKJKCVBDL23MC6YIP2QICYSI6KJWCT7I6K7KC6SILKJUCT7DEK3EHJNCLSIZ)[Take a tutorial on how to deploy VMs, load balancers, Java apps, websites or LAMP stacks. ](https://srv.carbonads.net/ads/click/x/GTND4277CVSD5KJUCAYLYKQUF67D62QUF6BIKZ3JCAAI623WC67ITKJKCVBDL23MC6YIP2QICYSI6KJWCT7I6K7KC6SILKJUCT7DEK3EHJNCLSIZ)[ads via Carbon](http://carbonads.net/?utm_source=nestjscom\&utm_medium=ad_via_link\&utm_campaign=in_unit\&utm_term=carbon)

### RabbitMQ

[RabbitMQ](https://www.rabbitmq.com/) is an open-source, lightweight message broker that supports multiple messaging protocols. It can be deployed in distributed and federated configurations to meet high-scale, high-availability requirements, and it is one of the most widely deployed message brokers, used by small startups and large enterprises alike.

#### Installation[#](/microservices/rabbitmq#installation)

To start building RabbitMQ-based microservices, first install the required packages:

```bash

$ npm i --save amqplib amqp-connection-manager
```

#### Overview[#](/microservices/rabbitmq#overview)

To use the RabbitMQ transporter, pass the following options object to the `createMicroservice()` method:

main.ts

JS TS

```typescript

const app = await NestFactory.createMicroservice<MicroserviceOptions>(AppModule, {
  transport: Transport.RMQ,
  options: {
    urls: ['amqp://localhost:5672'],
    queue: 'cats_queue',
    queueOptions: {
      durable: false
    },
  },
});
```

```typescript

const app = await NestFactory.createMicroservice(AppModule, {
  transport: Transport.RMQ,
  options: {
    urls: ['amqp://localhost:5672'],
    queue: 'cats_queue',
    queueOptions: {
      durable: false
    },
  },
});
```

> **Hint** The `Transport` enum is imported from the `@nestjs/microservices` package.

#### Options[#](/microservices/rabbitmq#options)

The `options` property is specific to the chosen transporter. The **RabbitMQ** transporter exposes the following properties.

|                         |                                                                                                                                                                                                                                                                                                                                                                     |
| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `urls`                  | An array of connection URLs to try in order                                                                                                                                                                                                                                                                                                                         |
| `queue`                 | Name of the queue your server listens to                                                                                                                                                                                                                                                                                                                            |
| `prefetchCount`         | Sets the prefetch count for the channel                                                                                                                                                                                                                                                                                                                             |
| `isGlobalPrefetchCount` | If `true`, applies the prefetch count per channel instead of per consumer                                                                                                                                                                                                                                                                                           |
| `noAck`                 | If `false`, enables manual acknowledgment mode. Defaults to `true`                                                                                                                                                                                                                                                                                                  |
| `consumerTag`           | A name the server uses to distinguish message deliveries for the consumer; it must not already be in use on the channel. It's usually easier to omit it, in which case the server creates a random name and supplies it in the reply (see [`channel.consume()` in the amqplib documentation](https://amqp-node.github.io/amqplib/channel_api.html#channel_consume)) |
| `queueOptions`          | Additional queue options (see [`channel.assertQueue()` in the amqplib documentation](https://amqp-node.github.io/amqplib/channel_api.html#channel_assertQueue))                                                                                                                                                                                                     |
| `socketOptions`         | Additional socket options (see [`connect()` in the amqplib documentation](https://amqp-node.github.io/amqplib/channel_api.html#connect))                                                                                                                                                                                                                            |
| `headers`               | Headers to send with every message. Applies only to the producer (client) configuration                                                                                                                                                                                                                                                                             |
| `replyQueue`            | Reply queue for the producer. Defaults to `amq.rabbitmq.reply-to`                                                                                                                                                                                                                                                                                                   |
| `persistent`            | If truthy, messages survive broker restarts, provided they are in a queue that also survives restarts                                                                                                                                                                                                                                                               |
| `noAssert`              | If `true`, the queue is not asserted before consuming. Defaults to `false`                                                                                                                                                                                                                                                                                          |
| `wildcards`             | Set to `true` only if you want to use a topic exchange to route messages to queues. Enabling it lets you use wildcards (`*`, `#`) in message and event patterns                                                                                                                                                                                                     |
| `exchange`              | Name of the exchange. Defaults to the queue name when `wildcards` is set to `true`                                                                                                                                                                                                                                                                                  |
| `exchangeType`          | Type of the exchange. Defaults to `topic`. Accepts the standard AMQP types `direct`, `fanout`, `topic`, and `headers`, or the name of a custom exchange type                                                                                                                                                                                                        |
| `exchangeArguments`     | Additional arguments passed when asserting the exchange                                                                                                                                                                                                                                                                                                             |
| `routingKey`            | Additional routing key for the topic exchange                                                                                                                                                                                                                                                                                                                       |
| `maxConnectionAttempts` | Maximum number of connection attempts. Applies only to the consumer configuration. Defaults to `-1` (infinite)                                                                                                                                                                                                                                                      |

#### Client[#](/microservices/rabbitmq#client)

As with other microservice transporters, you have [several options](/microservices/basics#client-producer-class) for creating a RabbitMQ `ClientProxy` instance.

One way to create an instance is to use the `ClientsModule`. Import it and call its `register()` method, passing an options object with the same properties shown above for the `createMicroservice()` method, plus a `name` property to use as the injection token. Read more about `ClientsModule` in the [microservices overview](/microservices/basics#client-producer-class).

```typescript

@Module({
  imports: [
    ClientsModule.register([
      {
        name: 'MATH_SERVICE',
        transport: Transport.RMQ,
        options: {
          urls: ['amqp://localhost:5672'],
          queue: 'cats_queue',
          queueOptions: {
            durable: false
          },
        },
      },
    ]),
  ]
  ...
})
```

You can also create a client with `ClientProxyFactory` or `@Client()`, as described in the [microservices overview](/microservices/basics#client-producer-class).

#### Context[#](/microservices/rabbitmq#context)

In more complex scenarios, you may need additional information about the incoming request. When using the RabbitMQ transporter, you can access the `RmqContext` object.

JS TS

```typescript

@MessagePattern('notifications')
getNotifications(@Payload() data: number[], @Ctx() context: RmqContext) {
  console.log(`Pattern: ${context.getPattern()}`);
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('notifications')
getNotifications(data, context) {
  console.log(`Pattern: ${context.getPattern()}`);
}
```

> **Hint**`@Payload()`, `@Ctx()` and `RmqContext` are imported from the `@nestjs/microservices` package.

To access the original RabbitMQ message (with its `properties`, `fields`, and `content`), use the `getMessage()` method of the `RmqContext` object:

JS TS

```typescript

@MessagePattern('notifications')
getNotifications(@Payload() data: number[], @Ctx() context: RmqContext) {
  console.log(context.getMessage());
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('notifications')
getNotifications(data, context) {
  console.log(context.getMessage());
}
```

To retrieve a reference to the RabbitMQ [channel](https://www.rabbitmq.com/channels.html), use the `getChannelRef()` method of the `RmqContext` object:

JS TS

```typescript

@MessagePattern('notifications')
getNotifications(@Payload() data: number[], @Ctx() context: RmqContext) {
  console.log(context.getChannelRef());
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('notifications')
getNotifications(data, context) {
  console.log(context.getChannelRef());
}
```

#### Message acknowledgement[#](/microservices/rabbitmq#message-acknowledgement)

To make sure a message is never lost, RabbitMQ supports [message acknowledgements](https://www.rabbitmq.com/confirms.html). The consumer sends an acknowledgement back to tell RabbitMQ that a particular message has been received and processed, and that RabbitMQ is free to delete it. If a consumer dies (its channel is closed, its connection is closed, or the TCP connection is lost) without sending an ack, RabbitMQ assumes the message wasn't fully processed and re-queues it.

By default, the RabbitMQ transporter doesn't expect acknowledgements (`noAck` is `true`). To enable manual acknowledgment mode, set the `noAck` property to `false`:

```typescript

options: {
  urls: ['amqp://localhost:5672'],
  queue: 'cats_queue',
  noAck: false,
  queueOptions: {
    durable: false
  },
},
```

When manual consumer acknowledgements are turned on, you must send an acknowledgement from the worker to signal that it has finished the task:

JS TS

```typescript

@MessagePattern('notifications')
getNotifications(@Payload() data: number[], @Ctx() context: RmqContext) {
  const channel = context.getChannelRef();
  const originalMsg = context.getMessage();

  channel.ack(originalMsg);
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('notifications')
getNotifications(data, context) {
  const channel = context.getChannelRef();
  const originalMsg = context.getMessage();

  channel.ack(originalMsg);
}
```

#### Record builders[#](/microservices/rabbitmq#record-builders)

To configure message options, use the `RmqRecordBuilder` class (this works for event-based flows as well). For example, to set the `headers` and `priority` properties, use the `setOptions()` method:

```typescript

const message = ':cat:';
const record = new RmqRecordBuilder(message)
  .setOptions({
    headers: {
      ['x-version']: '1.0.0',
    },
    priority: 3,
  })
  .build();

this.client.send('replace-emoji', record).subscribe(...);
```

> **Hint** The `RmqRecordBuilder` class is exported from the `@nestjs/microservices` package.

You can read these values on the server side as well, by accessing the `RmqContext`:

JS TS

```typescript

@MessagePattern('replace-emoji')
replaceEmoji(@Payload() data: string, @Ctx() context: RmqContext): string {
  const { properties: { headers } } = context.getMessage();
  return headers['x-version'] === '1.0.0' ? '🐱' : '🐈';
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('replace-emoji')
replaceEmoji(data, context) {
  const { properties: { headers } } = context.getMessage();
  return headers['x-version'] === '1.0.0' ? '🐱' : '🐈';
}
```

Starting with NestJS v12.1.3, a message handler can also return a record. Nest sends the record data as the reply and applies the record options (for example, the `headers` and `priority` properties) to the reply message:

```typescript

@MessagePattern('replace-emoji')
replaceEmoji() {
  return new RmqRecordBuilder(':cat:')
    .setOptions({
      headers: {
        ['x-version']: '1.0.0',
      },
      priority: 3,
    })
    .build();
}
```

The reply always carries the correlation id of the request, so the client can match it to the request.

#### Instance status updates[#](/microservices/rabbitmq#instance-status-updates)

To get real-time updates on the connection and the state of the underlying driver instance, subscribe to the `status` stream. This stream provides status updates specific to the chosen driver. For the RMQ driver, the `status` stream emits `connected`, `disconnected`, `blocked`, and `unblocked` events.

```typescript

this.client.status.subscribe((status: RmqStatus) => {
  console.log(status);
});
```

> **Hint** The `RmqStatus` type is imported from the `@nestjs/microservices` package.

Similarly, you can subscribe to the server's `status` stream to receive notifications about the server's status:

```typescript

const server = app.connectMicroservice<MicroserviceOptions>(...);
server.status.subscribe((status: RmqStatus) => {
  console.log(status);
});
```

#### Listening to RabbitMQ events[#](/microservices/rabbitmq#listening-to-rabbitmq-events)

In some cases, you might want to listen to internal events emitted by the microservice. For example, you could listen for the `error` event to trigger additional operations when an error occurs. To do this, use the `on()` method:

```typescript

this.client.on('error', (err) => {
  console.error(err);
});
```

Similarly, you can listen to the server's internal events:

```typescript

server.on<RmqEvents>('error', (err) => {
  console.error(err);
});
```

> **Hint** The `RmqEvents` type is imported from the `@nestjs/microservices` package.

Starting with NestJS v12.1.2, listeners registered with the client's `on()` method stay registered until you call `close()`, so they are also attached to the new connection the client creates on the next `send()` or `emit()` call after a connection attempt failed. Registrations are not deduplicated, so register each listener once rather than again after a failed attempt.

#### Underlying driver access[#](/microservices/rabbitmq#underlying-driver-access)

For more advanced use cases, you may need to access the underlying driver instance, for example, to close the connection manually or to use driver-specific methods. However, in most cases you **shouldn't need** to access the driver directly.

To do so, use the `unwrap()` method, which returns the underlying driver instance. Use the generic type parameter to specify the type of driver instance you expect.

```typescript

const managerRef =
  this.client.unwrap<import('amqp-connection-manager').AmqpConnectionManager>();
```

Similarly, you can access the server's underlying driver instance:

```typescript

const managerRef =
  server.unwrap<import('amqp-connection-manager').AmqpConnectionManager>();
```

#### Wildcards[#](/microservices/rabbitmq#wildcards)

RabbitMQ supports the use of wildcards in routing keys to allow for flexible message routing. The `#` wildcard matches zero or more words, while the `*` wildcard matches exactly one word.

For example, the routing key `cats.#` matches `cats`, `cats.meow`, and `cats.meow.purr`. The routing key `cats.*` matches `cats.meow` but not `cats.meow.purr`.

To enable wildcard support in your RabbitMQ microservice, set the `wildcards` configuration option to `true` in the options object:

```typescript

const app = await NestFactory.createMicroservice<MicroserviceOptions>(
  AppModule,
  {
    transport: Transport.RMQ,
    options: {
      urls: ['amqp://localhost:5672'],
      queue: 'cats_queue',
      wildcards: true,
    },
  },
);
```

With this configuration, you can use wildcards in your routing keys when subscribing to events and messages. For example, to listen for messages with the routing key `cats.#`:

```typescript

@MessagePattern('cats.#')
getCats(@Payload() data: { message: string }, @Ctx() context: RmqContext) {
  console.log(`Received message with routing key: ${context.getPattern()}`);

  return {
    message: 'Hello from the cats service!',
  }
}
```

To send a message with a specific routing key, use the `send()` method of the `ClientProxy` instance:

```typescript

this.client.send('cats.meow', { message: 'Meow!' }).subscribe((response) => {
  console.log(response);
});
```

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/microservices/rabbitmq.md)

----
url: https://docs.nestjs.com/application/validation
----

[Skip to content](#content)

On this page

* [Validation](https://docs.nestjs.com/application/validation#validation)
* [Overview](https://docs.nestjs.com/application/validation#overview)
* [Using the built-in ValidationPipe](https://docs.nestjs.com/application/validation#using-the-built-in-validationpipe)
* [Auto-validation](https://docs.nestjs.com/application/validation#auto-validation)
* [Disable detailed errors](https://docs.nestjs.com/application/validation#disable-detailed-errors)
* [Stripping properties](https://docs.nestjs.com/application/validation#stripping-properties)
* [Transform payload objects](https://docs.nestjs.com/application/validation#transform-payload-objects)
* [Explicit conversion](https://docs.nestjs.com/application/validation#explicit-conversion)
* [Mapped types](https://docs.nestjs.com/application/validation#mapped-types)
* [Parsing and validating arrays](https://docs.nestjs.com/application/validation#parsing-and-validating-arrays)
* [Schema-based validation](https://docs.nestjs.com/application/validation#schema-based-validation)
* [Coercion and transformation](https://docs.nestjs.com/application/validation#coercion-and-transformation)
* [Unknown properties](https://docs.nestjs.com/application/validation#unknown-properties)
* [Deriving schemas](https://docs.nestjs.com/application/validation#deriving-schemas)
* [Validating custom decorators](https://docs.nestjs.com/application/validation#validating-custom-decorators)
* [Schema validation options](https://docs.nestjs.com/application/validation#schema-validation-options)
* [Other schema libraries](https://docs.nestjs.com/application/validation#other-schema-libraries)
* [WebSockets and Microservices](https://docs.nestjs.com/application/validation#websockets-and-microservices)
* [Learn more](https://docs.nestjs.com/application/validation#learn-more)

[](https://srv.carbonads.net/ads/click/x/GTND4277CVSDE23NCWALYKQUF67D623NCAYDVZ3JCAAI6KQICTBDL2QKC6BI6KQECWBD5KQLF6YDEKJUCVSDP5Q7HEYI55QLCYAI6K3ECTNCYBZ52K)[Architectural guidance, code that runs. Free, for all levels. Start building ](https://srv.carbonads.net/ads/click/x/GTND4277CVSDE23NCWALYKQUF67D623NCAYDVZ3JCAAI6KQICTBDL2QKC6BI6KQECWBD5KQLF6YDEKJUCVSDP5Q7HEYI55QLCYAI6K3ECTNCYBZ52K)[ads via Carbon](http://carbonads.net/?utm_source=nestjscom\&utm_medium=ad_via_link\&utm_campaign=in_unit\&utm_term=carbon)

### Validation

Validate every piece of data a web application receives before acting on it. Nest provides several pipes that validate incoming requests automatically:

* `ValidationPipe` validates classes decorated with [class-validator](https://github.com/typestack/class-validator) rules.
* `StandardSchemaValidationPipe` validates schemas written with [Zod](https://zod.dev/), [Valibot](https://valibot.dev/), [ArkType](https://arktype.io/), or any other [Standard Schema](https://standardschema.dev/) compatible library.
* `ParseIntPipe`, `ParseBoolPipe`, `ParseArrayPipe`, and `ParseUUIDPipe` validate and convert individual values.

#### Overview[#](/application/validation#overview)

The [Pipes](/pipes) chapter explains how pipes work and how to bind them to parameters, route handlers, controllers, or the whole application. This chapter builds on it and covers real-world use of the two validation pipes.

The pipes differ in where the validation rules live:

* With `ValidationPipe`, rules are decorators on a **DTO class**, and the class is also the parameter's TypeScript type. This approach integrates with the [mapped types](/application/validation#mapped-types) utilities and with the Swagger CLI plugin.
* With `StandardSchemaValidationPipe`, rules are a **schema object**, and the parameter's TypeScript type is inferred from the schema. Schemas compose with the methods of their library, and no class or reflection metadata is involved.

Both pipes can be registered at the same time. `ValidationPipe` only validates parameters typed with a class, and `StandardSchemaValidationPipe` only validates parameters that declare a schema, so you can adopt schemas incrementally in an existing application.

#### Using the built-in ValidationPipe[#](/application/validation#using-the-built-in-validationpipe)

To begin using it, first install the required dependencies.

```bash

$ npm i --save class-validator class-transformer
```

> **Hint** The `ValidationPipe` is exported from the `@nestjs/common` package.

Because this pipe uses the [`class-validator`](https://github.com/typestack/class-validator) and [`class-transformer`](https://github.com/typestack/class-transformer) libraries, it supports many options. Pass them in a configuration object to the pipe's constructor. The pipe's own options are:

```typescript

export interface ValidationPipeOptions extends ValidatorOptions {
  transform?: boolean;
  disableErrorMessages?: boolean;
  exceptionFactory?: (errors: ValidationError[]) => any;
  errorFormat?: 'list' | 'grouped';
}
```

In addition to these, all `class-validator` options (inherited from the `ValidatorOptions` interface) are available:

| Option                    | Type                  | Description                                                                                                                                                                                                                                                                                                  |
| ------------------------- | --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `enableDebugMessages`     | `boolean`             | If set to true, validator will print extra warning messages to the console when something is not right.                                                                                                                                                                                                      |
| `skipUndefinedProperties` | `boolean`             | If set to true then validator will skip validation of all properties that are undefined in the validating object.                                                                                                                                                                                            |
| `skipNullProperties`      | `boolean`             | If set to true then validator will skip validation of all properties that are null in the validating object.                                                                                                                                                                                                 |
| `skipMissingProperties`   | `boolean`             | If set to true then validator will skip validation of all properties that are null or undefined in the validating object.                                                                                                                                                                                    |
| `whitelist`               | `boolean`             | If set to true, validator will strip validated (returned) object of any properties that do not use any validation decorators.                                                                                                                                                                                |
| `forbidNonWhitelisted`    | `boolean`             | If set to true, instead of stripping non-whitelisted properties validator will throw an exception.                                                                                                                                                                                                           |
| `forbidUnknownValues`     | `boolean`             | If set to true, attempts to validate unknown objects fail immediately.                                                                                                                                                                                                                                       |
| `disableErrorMessages`    | `boolean`             | If set to true, validation errors will not be returned to the client.                                                                                                                                                                                                                                        |
| `errorHttpStatusCode`     | `number`              | This setting allows you to specify which exception type will be used in case of an error. By default it throws `BadRequestException`.                                                                                                                                                                        |
| `exceptionFactory`        | `Function`            | Takes an array of the validation errors and returns an exception object to be thrown.                                                                                                                                                                                                                        |
| `groups`                  | `string[]`            | Groups to be used during validation of the object.                                                                                                                                                                                                                                                           |
| `always`                  | `boolean`             | Set default for `always` option of decorators. Default can be overridden in decorator options.                                                                                                                                                                                                               |
| `strictGroups`            | `boolean`             | If `groups` is not given or is empty, ignore decorators with at least one group.                                                                                                                                                                                                                             |
| `dismissDefaultMessages`  | `boolean`             | If set to true, the validation will not use default messages. Error message always will be `undefined` if its not explicitly set.                                                                                                                                                                            |
| `validationError.target`  | `boolean`             | Indicates if target should be exposed in `ValidationError`.                                                                                                                                                                                                                                                  |
| `validationError.value`   | `boolean`             | Indicates if validated value should be exposed in `ValidationError`.                                                                                                                                                                                                                                         |
| `stopAtFirstError`        | `boolean`             | When set to true, validation of the given property will stop after encountering the first error. Defaults to false.                                                                                                                                                                                          |
| `errorFormat`             | `'list' \| 'grouped'` | Specifies the format of validation error messages. `'list'` (default) returns an array of error message strings. `'grouped'` returns an object with property paths as keys and arrays of unmodified error messages as values, preserving custom validation messages without prepending parent path prefixes. |

> **Notice** Find more information about the `class-validator` package in its [repository](https://github.com/typestack/class-validator).

#### Auto-validation[#](/application/validation#auto-validation)

Start by binding `ValidationPipe` at the application level, so that every endpoint is protected from receiving invalid data.

```typescript

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.useGlobalPipes(new ValidationPipe());
  await app.listen(process.env.PORT ?? 3000);
}
await bootstrap();
```

To test the pipe, create a basic endpoint:

```typescript

@Post()
create(@Body() createUserDto: CreateUserDto) {
  return 'This action adds a new user';
}
```

> **Hint** TypeScript does not emit metadata for **generics or interfaces**, so `ValidationPipe` cannot validate DTOs declared with them. Use concrete classes for your DTOs.

> **Hint** Don't import DTOs with a type-only import, because type-only imports are erased at runtime. Write `import { CreateUserDto }` instead of `import type { CreateUserDto }`.

Next, add validation rules to the `CreateUserDto` with the decorators provided by the `class-validator` package (see the [full list](https://github.com/typestack/class-validator#validation-decorators)). Every route that uses `CreateUserDto` then enforces these rules.

```typescript

import { IsEmail, IsNotEmpty } from 'class-validator';

export class CreateUserDto {
  @IsEmail()
  email: string;

  @IsNotEmpty()
  password: string;
}
```

With these rules in place, a request whose body contains an invalid `email` property receives a `400 Bad Request` response with the following body:

```json

{
  "statusCode": 400,
  "error": "Bad Request",
  "message": ["email must be an email"]
}
```

`ValidationPipe` validates other parts of the request as well. For example, to accept only numeric values for the `:id` path parameter, use the following construct:

```typescript

@Get(':id')
findOne(@Param() params: FindOneParams) {
  return 'This action returns a user';
}
```

Like a DTO, `FindOneParams` is a class that defines validation rules with `class-validator`:

```typescript

import { IsNumberString } from 'class-validator';

export class FindOneParams {
  @IsNumberString()
  id: string;
}
```

#### Disable detailed errors[#](/application/validation#disable-detailed-errors)

Error messages explain what was wrong with a request, but some production environments prefer not to expose them. To disable detailed errors, pass an options object to the `ValidationPipe`:

```typescript

app.useGlobalPipes(
  new ValidationPipe({
    disableErrorMessages: true,
  }),
);
```

As a result, the response body no longer contains detailed error messages.

#### Stripping properties[#](/application/validation#stripping-properties)

`ValidationPipe` can also filter out properties that the route handler should not receive. When you **whitelist** the acceptable properties, any property not included in the whitelist is stripped from the resulting object. For example, if the handler expects `email` and `password`, but a request also includes an `age` property, `age` is removed from the resulting DTO. To enable this behavior, set `whitelist` to `true`.

```typescript

app.useGlobalPipes(
  new ValidationPipe({
    whitelist: true,
  }),
);
```

With this option enabled, properties without any decorator in the validation class are removed.

Alternatively, you can reject requests that contain non-whitelisted properties with an error response. To do so, set `forbidNonWhitelisted` to `true` in addition to `whitelist`.

## Learn the right way!

* 80+ chapters
* 5+ hours of videos
* Official certificate
* Deep-dive sessions

[Explore official courses](https://courses.nestjs.com "Courses | NestJS - A node.js framework built on top of TypeScript")

#### Transform payload objects[#](/application/validation#transform-payload-objects)

Payloads arrive over the network as plain JavaScript objects. `ValidationPipe` can transform them into instances of their DTO classes. To enable auto-transformation, set `transform` to `true`. You can do this at the method level:

cats.controller.ts

JS TS

```typescript

@Post()
@UsePipes(new ValidationPipe({ transform: true }))
async create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

To enable this behavior globally, set the option on a global pipe:

```typescript

app.useGlobalPipes(
  new ValidationPipe({
    transform: true,
  }),
);
```

With auto-transformation enabled, `ValidationPipe` also converts primitive types. In the following example, the `findOne()` method takes the `id` path parameter as an argument:

```typescript

@Get(':id')
findOne(@Param('id') id: number) {
  console.log(typeof id === 'number'); // true
  return 'This action returns a user';
}
```

Path parameters and query parameters always arrive as strings. Because the method signature declares `id` as a `number`, `ValidationPipe` converts the string identifier to a number.

#### Explicit conversion[#](/application/validation#explicit-conversion)

The previous section showed how `ValidationPipe` implicitly converts query and path parameters based on their declared types. That conversion requires auto-transformation to be enabled.

With auto-transformation disabled, you can convert values explicitly with `ParseIntPipe` or `ParseBoolPipe`. There is no `ParseStringPipe`, because path and query parameters are already strings.

```typescript

@Get(':id')
findOne(
  @Param('id', ParseIntPipe) id: number,
  @Query('sort', ParseBoolPipe) sort: boolean,
) {
  console.log(typeof id === 'number'); // true
  console.log(typeof sort === 'boolean'); // true
  return 'This action returns a user';
}
```

> **Hint** The `ParseIntPipe` and `ParseBoolPipe` are exported from the `@nestjs/common` package.

#### Mapped types[#](/application/validation#mapped-types)

Features such as **CRUD** (Create/Read/Update/Delete) often need several variants of a base type. Nest provides utility functions that perform these type transformations.

> **Warning** If your application uses the `@nestjs/swagger` package, see [this chapter](/openapi/mapped-types) for more information about mapped types. Likewise, if you use the `@nestjs/graphql` package, see [this chapter](/graphql/mapped-types). Both packages rely heavily on type metadata, so they export their own versions of these utilities. Importing them from `@nestjs/mapped-types` instead of `@nestjs/swagger` or `@nestjs/graphql` can cause undocumented side effects.

Input validation types (DTOs) often come in **create** and **update** variants of the same type: the **create** variant requires all fields, while the **update** variant makes them optional. The mapped types utilities derive such variants without repeating the property declarations or their validation decorators. Consider the following **create** type:

```typescript

export class CreateCatDto {
  name: string;
  age: number;
  breed: string;
}
```

> **Hint**`PartialType()`, `PickType()`, `OmitType()`, and `IntersectionType()` are imported from the `@nestjs/mapped-types` package.

The `PartialType()` function returns a type (class) with all the properties of the input type set to optional:

```typescript

export class UpdateCatDto extends PartialType(CreateCatDto) {}
```

The `PickType()` function constructs a type from a subset of the input type's properties:

```typescript

export class UpdateCatAgeDto extends PickType(CreateCatDto, ['age'] as const) {}
```

The `OmitType()` function constructs a type with every property of the input type **except** the listed ones. The second argument is an array of property names:

```typescript

export class UpdateCatDto extends OmitType(CreateCatDto, ['name'] as const) {}
```

The `IntersectionType()` function combines the properties of two types into one new type (class). For example, given an additional type:

```typescript

export class AdditionalCatInfo {
  color: string;
}
```

The following type contains the properties of both:

```typescript

export class UpdateCatDto extends IntersectionType(
  CreateCatDto,
  AdditionalCatInfo,
) {}
```

The type mapping utility functions are composable. For example, the following type has all of the properties of `CreateCatDto` except `name`, all set to optional:

```typescript

export class UpdateCatDto extends PartialType(
  OmitType(CreateCatDto, ['name'] as const),
) {}
```

#### Parsing and validating arrays[#](/application/validation#parsing-and-validating-arrays)

TypeScript does not emit metadata for generic types such as arrays, so `ValidationPipe` cannot validate the elements of an array parameter. In the following code, the elements of `createUserDtos` are not validated:

```typescript

@Post()
createBulk(@Body() createUserDtos: CreateUserDto[]) {
  return 'This action adds new users';
}
```

To validate the array, create a dedicated class with a property that wraps the array, or use the `ParseArrayPipe`:

```typescript

@Post()
createBulk(
  @Body(new ParseArrayPipe({ items: CreateUserDto }))
  createUserDtos: CreateUserDto[],
) {
  return 'This action adds new users';
}
```

`ParseArrayPipe` is also useful for parsing query parameters. Consider a `findByIds()` method that returns users based on identifiers passed in the query string:

```typescript

@Get()
findByIds(
  @Query('ids', new ParseArrayPipe({ items: Number, separator: ',' }))
  ids: number[],
) {
  return 'This action returns users by ids';
}
```

This construction parses and validates the query parameters of a request such as the following:

```bash

GET /?ids=1,2,3
```

#### Schema-based validation[#](/application/validation#schema-based-validation)

The `StandardSchemaValidationPipe` validates values against schemas instead of decorated classes. It accepts any schema that implements the [Standard Schema](https://standardschema.dev/) specification, which includes [Zod](https://zod.dev/), [Valibot](https://valibot.dev/), and [ArkType](https://arktype.io/). The schema is the single source of truth for a payload: it validates the value at runtime, and its inferred type is the handler parameter's TypeScript type. The examples in this section use Zod.

```bash

$ npm i --save zod
```

Define a schema and infer the DTO type from it:

create-user.dto.ts

JS TS

```typescript

import { z } from 'zod';

export const createUserSchema = z.object({
  email: z.email(),
  password: z.string().min(8),
  displayName: z.string().max(50).optional(),
});

export type CreateUserDto = z.infer<typeof createUserSchema>;
```

Next, bind the pipe at the application level:

main.ts

JS TS

```typescript

import { StandardSchemaValidationPipe } from '@nestjs/common';
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module.js';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.useGlobalPipes(new StandardSchemaValidationPipe());
  await app.listen(process.env.PORT ?? 3000);
}
await bootstrap();
```

Then attach the schema to a parameter with the `schema` option of the parameter decorator:

users.controller.ts

JS TS

```typescript

@Post()
create(@Body({ schema: createUserSchema }) createUserDto: CreateUserDto) {
  return this.usersService.create(createUserDto);
}
```

The pipe validates only the parameters that declare a schema and passes every other value through unchanged, so binding it globally is safe. If the request body doesn't match the schema, the application responds with `400 Bad Request`. Each message is prefixed with the path of the invalid property:

```json

{
  "statusCode": 400,
  "error": "Bad Request",
  "message": [
    "email: Invalid email address",
    "password: Too small: expected string to have >=8 characters"
  ]
}
```

The `schema` option is supported by `@Body()`, `@Query()`, and `@Param()`, as well as by `@MessageBody()` in [gateways](/websockets/gateways) and `@Payload()` in [microservices](/microservices/basics). Pass it as the only argument to validate the whole object, or after a property name to validate a single value:

```typescript

@Post('invitations')
invite(@Body('email', { schema: z.email() }) email: string) {
  return this.usersService.invite(email);
}
```

#### Coercion and transformation[#](/application/validation#coercion-and-transformation)

Path parameters and query parameters always arrive as strings. Coercing schemas, such as `z.coerce.number()`, convert them before validating:

```typescript

@Get(':id')
findOne(@Param('id', { schema: z.coerce.number().int().positive() }) id: number) {
  return this.usersService.findOne(id);
}
```

Schemas can also apply defaults and transformations. The following schema describes the query string of a paginated list:

list-users-query.dto.ts

JS TS

```typescript

import { z } from 'zod';

export const listUsersQuerySchema = z.object({
  page: z.coerce.number().int().min(1).default(1),
  limit: z.coerce.number().int().min(1).max(100).default(20),
  search: z.string().trim().optional(),
});

export type ListUsersQuery = z.infer<typeof listUsersQuerySchema>;
```

```typescript

@Get()
findAll(@Query({ schema: listUsersQuerySchema }) query: ListUsersQuery) {
  return this.usersService.findAll(query);
}
```

For the request `GET /users?page=2&search=%20kamil%20`, the handler receives `page` as the number `2`, `limit` as the default `20`, and `search` as the trimmed string `'kamil'`.

By default, the pipe passes the schema's **output** to the handler, so coercion, defaults, and transformations take effect. To validate the value but pass the original input through unchanged, set `transform` to `false`. In that case, type the parameter with the schema's input type (`z.input<typeof schema>` in Zod).

#### Unknown properties[#](/application/validation#unknown-properties)

How a schema treats properties it doesn't declare is decided by the schema itself, not by the pipe. In Zod:

* `z.object()` strips unknown properties, like the `whitelist` option of `ValidationPipe`.
* `z.strictObject()` rejects them, like the `forbidNonWhitelisted` option. The error message is `Unrecognized key: "age"`.
* `z.looseObject()` keeps them.

#### Deriving schemas[#](/application/validation#deriving-schemas)

The [mapped types](/application/validation#mapped-types) utilities derive new DTO classes from existing ones. With schemas, the library's own methods serve the same purpose:

update-user.dto.ts

JS TS

```typescript

import { z } from 'zod';
import { createUserSchema } from './create-user.dto.js';

// All properties optional, like PartialType()
export const updateUserSchema = createUserSchema.partial();

// Only the listed properties, like PickType()
export const changeEmailSchema = createUserSchema.pick({ email: true });

// Every property except the listed ones, like OmitType()
export const publicProfileSchema = createUserSchema.omit({ password: true });

// Additional properties, like IntersectionType()
export const createAdminSchema = createUserSchema.extend({
  role: z.enum(['admin', 'editor']),
});

export type UpdateUserDto = z.infer<typeof updateUserSchema>;
```

Arrays need no special handling either. Wrap the item schema in `z.array()`, and every element is validated:

```typescript

@Post('bulk')
createBulk(
  @Body({ schema: z.array(createUserSchema) }) createUserDtos: CreateUserDto[],
) {
  return this.usersService.createMany(createUserDtos);
}
```

A message for an invalid element is prefixed with its index, e.g., `1.email: Invalid email address`.

#### Validating custom decorators[#](/application/validation#validating-custom-decorators)

Parameter decorators created with [`createParamDecorator()`](/custom-decorators) accept the `schema` option too. For example, the following decorator extracts a tenant identifier from a request header:

tenant-id.decorator.ts

JS TS

```typescript

import { createParamDecorator, ExecutionContext } from '@nestjs/common';

export const TenantId = createParamDecorator(
  (data: unknown, ctx: ExecutionContext) =>
    ctx.switchToHttp().getRequest().headers['x-tenant-id'],
);
```

```typescript

@Get()
findAll(@TenantId({ schema: z.uuid() }) tenantId: string) {
  return this.projectsService.findAll(tenantId);
}
```

The pipe skips custom decorators unless you enable the `validateCustomDecorators` option:

```typescript

app.useGlobalPipes(
  new StandardSchemaValidationPipe({
    validateCustomDecorators: true,
  }),
);
```

#### Schema validation options[#](/application/validation#schema-validation-options)

The `StandardSchemaValidationPipe` constructor accepts the following options:

| Option                     | Type                      | Description                                                                                                                                                |
| -------------------------- | ------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `transform`                | `boolean`                 | If `true`, the handler receives the value produced by the schema. If `false`, it receives the original input after successful validation. Default: `true`. |
| `validateCustomDecorators` | `boolean`                 | If `true`, parameters of custom decorators created with `createParamDecorator()` are validated as well. Default: `false`.                                  |
| `validateOptions`          | `Record<string, unknown>` | Options forwarded to the schema's `~standard.validate()` method, for libraries that support them.                                                          |
| `errorHttpStatusCode`      | `number`                  | The HTTP status code of the exception thrown when validation fails. Default: `400`.                                                                        |
| `exceptionFactory`         | `Function`                | Receives the array of validation issues and returns the exception to throw.                                                                                |

Use `exceptionFactory` to change the shape of the error response. Each issue has a `message` and, for nested values, a `path` whose segments are either property keys or objects with a `key` property:

```typescript

app.useGlobalPipes(
  new StandardSchemaValidationPipe({
    exceptionFactory: (issues) =>
      new UnprocessableEntityException({
        message: 'Validation failed',
        errors: issues.map((issue) => ({
          path: issue.path
            ?.map((segment) => (typeof segment === 'object' ? segment.key : segment))
            .join('.'),
          message: issue.message,
        })),
      }),
  }),
);
```

With this factory, an invalid request produces a `422 Unprocessable Entity` response:

```json

{
  "message": "Validation failed",
  "errors": [
    { "path": "email", "message": "Invalid email address" },
    { "path": "password", "message": "Too small: expected string to have >=8 characters" }
  ]
}
```

#### Other schema libraries[#](/application/validation#other-schema-libraries)

Nothing in the pipe is specific to Zod. The same `schema` option accepts a Valibot schema:

```typescript

import * as v from 'valibot';

export const createUserSchema = v.object({
  email: v.pipe(v.string(), v.email()),
  password: v.pipe(v.string(), v.minLength(8)),
});

export type CreateUserDto = v.InferOutput<typeof createUserSchema>;
```

Or an ArkType schema:

```typescript

import { type } from 'arktype';

export const createUserSchema = type({
  email: 'string.email',
  password: 'string >= 8',
});

export type CreateUserDto = typeof createUserSchema.infer;
```

Error messages come from the library, so their wording differs between libraries.

> **Hint** The same schemas can describe your API in the OpenAPI document. See [Standard Schema (Zod, Valibot)](/openapi/introduction#standard-schema-zod-valibot) in the OpenAPI chapter.

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/35-zod-validation).

#### WebSockets and Microservices[#](/application/validation#websockets-and-microservices)

While this chapter shows examples using HTTP applications (e.g., Express or Fastify), both `ValidationPipe` and `StandardSchemaValidationPipe` work the same for WebSockets and microservices, regardless of the transport. By default, both throw an HTTP exception when validation fails. To report errors in a way the transport understands, return a `WsException` or an `RpcException` from the `exceptionFactory` option:

```typescript

new StandardSchemaValidationPipe({
  exceptionFactory: (issues) =>
    new WsException(issues.map((issue) => issue.message)),
});
```

#### Learn more[#](/application/validation#learn-more)

Read more about custom validators, error messages, and available decorators in the [class-validator](https://github.com/typestack/class-validator) repository. For schema libraries, see the [Zod](https://zod.dev/), [Valibot](https://valibot.dev/), and [ArkType](https://arktype.io/) documentation, and the list of [Standard Schema compatible libraries](https://standardschema.dev/schema#what-schema-libraries-implement-the-spec).

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/application/validation.md)

----
url: https://docs.nestjs.com/v6/faq/http-adapter
----

* [HTTP adapter](https://docs.nestjs.com/v6/faq/http-adapter#http-adapter)
* [Outside application context strategy](https://docs.nestjs.com/v6/faq/http-adapter#outside-application-context-strategy)
* [In-context strategy](https://docs.nestjs.com/v6/faq/http-adapter#in-context-strategy)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/faq/http-adapter.md "Suggest Edits")

### HTTP adapter

Occasionally, you may want to access the underlying HTTP server, either within the Nest application context or from the outside.

Every native (platform-specific) HTTP server/library (e.g., Express and Fastify) instance is wrapped in an **adapter**. The adapter is registered as a globally available provider that can be retrieved from the application context, as well as injected into other providers.

#### Outside application context strategy[#](/faq/http-adapter#outside-application-context-strategy)

To get a reference to the `HttpAdapter` from outside of the application context, call the `getHttpAdapter()` method.

JS TS

```typescript

const app = await NestFactory.create(ApplicationModule);
const httpAdapter = app.getHttpAdapter();
```

#### In-context strategy[#](/faq/http-adapter#in-context-strategy)

To get a reference to the `HttpAdapterHost` from within the application context, inject it using the same technique as any other existing provider (e.g., using constructor injection).

JS TS

```typescript

export class CatsService {
  constructor(private readonly adapterHost: HttpAdapterHost) {}
}
```

```typescript

@Dependencies(HttpAdapterHost)
export class CatsService {
  constructor(adapterHost) {
    this.adapterHost = adapterHost;
  }
}
```

> **Hint** The `HttpAdapterHost` is imported from the `@nestjs/core` package.

The `HttpAdapterHost` is **not** an actual `HttpAdapter`. To get the actual `HttpAdapter` instance, simply access the `httpAdapter` property.

```typescript

const adapterHost = app.get(HttpAdapterHost);
const httpAdapter = adapterHost.httpAdapter;
```

The `httpAdapter` is the actual instance of the HTTP adapter used by the underlying framework. It is an instance of either `ExpressAdapter` or `FastifyAdapter` (both classes extend `AbstractHttpAdapter`).

The adapter object exposes several useful methods to interact with the HTTP server. However, if you want to access the library instance (e.g., the Express instance) directly, call the `getInstance()` method.

```typescript

const instance = httpAdapter.getInstance();
```

----
url: https://docs.nestjs.com/v7/graphql/resolvers
----

* [Resolvers](https://docs.nestjs.com/v7/graphql/resolvers#resolvers)
* [Code first](https://docs.nestjs.com/v7/graphql/resolvers#code-first)
* [Object types](https://docs.nestjs.com/v7/graphql/resolvers#object-types)
* [Code first resolver](https://docs.nestjs.com/v7/graphql/resolvers#code-first-resolver)
* [Query type names](https://docs.nestjs.com/v7/graphql/resolvers#query-type-names)
* [Query decorator options](https://docs.nestjs.com/v7/graphql/resolvers#query-decorator-options)
* [Args decorator options](https://docs.nestjs.com/v7/graphql/resolvers#args-decorator-options)
* [Dedicated arguments class](https://docs.nestjs.com/v7/graphql/resolvers#dedicated-arguments-class)
* [Class inheritance](https://docs.nestjs.com/v7/graphql/resolvers#class-inheritance)
* [Generics](https://docs.nestjs.com/v7/graphql/resolvers#generics)
* [Schema first](https://docs.nestjs.com/v7/graphql/resolvers#schema-first)
* [Schema first resolver](https://docs.nestjs.com/v7/graphql/resolvers#schema-first-resolver)
* [Generating types](https://docs.nestjs.com/v7/graphql/resolvers#generating-types)
* [GraphQL argument decorators](https://docs.nestjs.com/v7/graphql/resolvers#graphql-argument-decorators)
* [Module](https://docs.nestjs.com/v7/graphql/resolvers#module)

```graphql

type Author {
  id: Int!
  firstName: String
  lastName: String
  posts: [Post]
}
```

In this case, using the code first approach, we define schemas using TypeScript classes and using TypeScript decorators to annotate the fields of those classes. The equivalent of the above SDL in the code first approach is:

authors/models/author.model.ts

JS TS

```typescript

import { Field, Int, ObjectType } from '@nestjs/graphql';
import { Post } from './post';

@ObjectType()
export class Author {
  @Field(type => Int)
  id: number;

  @Field({ nullable: true })
  firstName?: string;

  @Field({ nullable: true })
  lastName?: string;

  @Field(type => [Post])
  posts: Post[];
}
```

> **Hint** TypeScript's metadata reflection system has several limitations which make it impossible, for instance, to determine what properties a class consists of or recognize whether a given property is optional or required. Because of these limitations, we must either explicitly use the `@Field()` decorator in our schema definition classes to provide metadata about each field's GraphQL type and optionality, or use a [CLI plugin](/v7/graphql/cli-plugin) to generate these for us.

The `Author` object type, like any class, is made of a collection of fields, with each field declaring a type. A field's type corresponds to a [GraphQL type](https://graphql.org/learn/schema/). A field's GraphQL type can be either another object type or a scalar type. A GraphQL scalar type is a primitive (like `ID`, `String`, `Boolean`, or `Int`) that resolves to a single value.

> **Hint** In addition to GraphQL's built-in scalar types, you can define custom scalar types (read [more](/v7/graphql/scalars)).

The above `Author` object type definition will cause Nest to **generate** the SDL we showed above:

```graphql

type Author {
  id: Int!
  firstName: String
  lastName: String
  posts: [Post]
}
```

```typescript

@Field({ description: `Book title`, deprecationReason: 'Not useful in v2 schema' })
title: string;
```

> **Hint** You can also add a description to, or deprecate, the whole object type: `@ObjectType({ description: 'Author model' })`.

When the field is an array, we must manually indicate the array type in the `Field()` decorator's type function, as shown below:

```typescript

@Field(type => [Post])
posts: Post[];
```

> **Hint** Using array bracket notation (`[ ]`), we can indicate the depth of the array. For example, using `[[Int]]` would represent an integer matrix.

To declare that an array's items (not the array itself) are nullable, set the `nullable` property to `'items'` as shown below:

```typescript

@Field(type => [Post], { nullable: 'items' })
posts: Post[];
```

> **Hint** If both the array and its items are nullable, set `nullable` to `'itemsAndList'` instead.

Now that the `Author` object type is created, let's define the `Post` object type.

posts/models/post.model.ts

JS TS

```typescript

import { Field, Int, ObjectType } from '@nestjs/graphql';

@ObjectType()
export class Post {
  @Field(type => Int)
  id: number;

  @Field()
  title: string;

  @Field(type => Int, { nullable: true })
  votes?: number;
}
```

The `Post` object type will result in generating the following part of the GraphQL schema in SDL:

```graphql

type Post {
  id: Int!
  title: String!
  votes: Int
}
```

#### Code first resolver[#](/graphql/resolvers#code-first-resolver)

At this point, we've defined the objects (type definitions) that can exist in our data graph, but clients don't yet have a way to interact with those objects. To address that, we need to create a resolver class. In the code first method, a resolver class both defines resolver functions **and** generates the **Query type**. This will be clear as we work through the example below:

authors/authors.resolver.ts

JS TS

```typescript

@Resolver(of => Author)
export class AuthorsResolver {
  constructor(
    private authorsService: AuthorsService,
    private postsService: PostsService,
  ) {}

  @Query(returns => Author)
  async author(@Args('id', { type: () => Int }) id: number) {
    return this.authorsService.findOneById(id);
  }

  @ResolveField()
  async posts(@Parent() author: Author) {
    const { id } = author;
    return this.postsService.findAll({ authorId: id });
  }
}
```

> **Hint** All decorators (e.g., `@Resolver`, `@ResolveField`, `@Args`, etc.) are exported from the `@nestjs/graphql` package.

You can define multiple resolver classes. Nest will combine these at run time. See the [module](/graphql/resolvers#module) section below for more on code organization.

> **Note** The logic inside the `AuthorsService` and `PostsService` classes can be as simple or sophisticated as needed. The main point of this example is to show how to construct resolvers and how they can interact with other providers.

In the example above, we created the `AuthorsResolver` which defines one query resolver function and one field resolver function. To create a resolver, we create a class with resolver functions as methods, and annotate the class with the `@Resolver()` decorator.

In this example, we defined a query handler to get the author object based on the `id` sent in the request. To specify that the method is a query handler, use the `@Query()` decorator.

The argument passed to the `@Resolver()` decorator is optional, but comes into play when our graph becomes non-trivial. It's used to supply a parent object used by field resolver functions as they traverse down through an object graph.

In our example, since the class includes a **field resolver** function (for the `posts` property of the `Author` object type), we **must** supply the `@Resolver()` decorator with a value to indicate which class is the parent type (i.e., the corresponding `ObjectType` class name) for all field resolvers defined within this class. As should be clear from the example, when writing a field resolver function, it's necessary to access the parent object (the object the field being resolved is a member of). In this example, we populate an author's posts array with a field resolver that calls a service which takes the author's `id` as an argument. Hence the need to identify the parent object in the `@Resolver()` decorator. Note the corresponding use of the `@Parent()` method parameter decorator to then extract a reference to that parent object in the field resolver.

We can define multiple `@Query()` resolver functions (both within this class, and in any other resolver class), and they will be aggregated into a single **Query type** definition in the generated SDL along with the appropriate entries in the resolver map. This allows you to define queries close to the models and services that they use, and to keep them well organized in modules.

> **Hint** Nest CLI provides a generator (schematic) that automatically generates **all the boilerplate code** to help us avoid doing all of this, and make the developer experience much simpler. Read more about this feature [here](/v7/recipes/crud-generator).

#### Query type names[#](/graphql/resolvers#query-type-names)

In the above examples, the `@Query()` decorator generates a GraphQL schema query type name based on the method name. For example, consider the following construction from the example above:

```typescript

@Query(returns => Author)
async author(@Args('id', { type: () => Int }) id: number) {
  return this.authorsService.findOneById(id);
}
```

This generates the following entry for the author query in our schema (the query type uses the same name as the method name):

```graphql

type Query {
  author(id: Int!): Author
}
```

> **Hint** Learn more about GraphQL queries [here](https://graphql.org/learn/queries/).

Conventionally, we prefer to decouple these names; for example, we prefer to use a name like `getAuthor()` for our query handler method, but still use `author` for our query type name. The same applies to our field resolvers. We can easily do this by passing the mapping names as arguments of the `@Query()` and `@ResolveField()` decorators, as shown below:

authors/authors.resolver.ts

JS TS

```typescript

@Resolver(of => Author)
export class AuthorsResolver {
  constructor(
    private authorsService: AuthorsService,
    private postsService: PostsService,
  ) {}

  @Query(returns => Author, { name: 'author' })
  async getAuthor(@Args('id', { type: () => Int }) id: number) {
    return this.authorsService.findOneById(id);
  }

  @ResolveField('posts', returns => [Post])
  async getPosts(@Parent() author: Author) {
    const { id } = author;
    return this.postsService.findAll({ authorId: id });
  }
}
```

The `getAuthor` handler method above will result in generating the following part of the GraphQL schema in SDL:

```graphql

type Query {
  author(id: Int!): Author
}
```

```typescript

@Args('id') id: string
```

In the `getAuthor()` case, the `number` type is used, which presents a challenge. The `number` TypeScript type doesn't give us enough information about the expected GraphQL representation (e.g., `Int` vs. `Float`). Thus we have to **explicitly** pass the type reference. We do that by passing a second argument to the `Args()` decorator, containing argument options, as shown below:

```typescript

@Query(returns => Author, { name: 'author' })
async getAuthor(@Args('id', { type: () => Int }) id: number) {
  return this.authorsService.findOneById(id);
}
```

```typescript

getAuthor(
  @Args('firstName', { nullable: true }) firstName?: string,
  @Args('lastName', { defaultValue: '' }) lastName?: string,
) {}
```

#### Dedicated arguments class[#](/graphql/resolvers#dedicated-arguments-class)

With inline `@Args()` calls, code like the example above becomes bloated. Instead, you can create a dedicated `GetAuthorArgs` arguments class and access it in the handler method as follows:

```typescript

@Args() args: GetAuthorArgs
```

Create the `GetAuthorArgs` class using `@ArgsType()` as shown below:

authors/dto/get-author.args.ts

JS TS

```typescript

import { MinLength } from 'class-validator';
import { Field, ArgsType } from '@nestjs/graphql';

@ArgsType()
class GetAuthorArgs {
  @Field({ nullable: true })
  firstName?: string;

  @Field({ defaultValue: '' })
  @MinLength(3)
  lastName: string;
}
```

> **Hint** Again, due to TypeScript's metadata reflection system limitations, it's required to either use the `@Field` decorator to manually indicate type and optionality, or use a [CLI plugin](/v7/graphql/cli-plugin).

This will result in generating the following part of the GraphQL schema in SDL:

```graphql

type Query {
  author(firstName: String, lastName: String = ''): Author
}
```

> **Hint** Note that arguments classes like `GetAuthorArgs` play very well with the `ValidationPipe` (read [more](/v7/techniques/validation)).

#### Class inheritance[#](/graphql/resolvers#class-inheritance)

You can use standard TypeScript class inheritance to create base classes with generic utility type features (fields and field properties, validations, etc.) that can be extended. For example, you may have a set of pagination related arguments that always include the standard `offset` and `limit` fields, but also other index fields that are type-specific. You can set up a class hierarchy as shown below.

Base `@ArgsType()` class:

```typescript

@ArgsType()
class PaginationArgs {
  @Field((type) => Int)
  offset: number = 0;

  @Field((type) => Int)
  limit: number = 10;
}
```

Type specific sub-class of the base `@ArgsType()` class:

```typescript

@ArgsType()
class GetAuthorArgs extends PaginationArgs {
  @Field({ nullable: true })
  firstName?: string;

  @Field({ defaultValue: '' })
  @MinLength(3)
  lastName: string;
}
```

The same approach can be taken with `@ObjectType()` objects. Define generic properties on the base class:

```typescript

@ObjectType()
class Character {
  @Field((type) => Int)
  id: number;

  @Field()
  name: string;
}
```

Add type-specific properties on sub-classes:

```typescript

@ObjectType()
class Warrior extends Character {
  @Field()
  level: number;
}
```

You can use inheritance with a resolver as well. You can ensure type safety by combining inheritance and TypeScript generics. For example, to create a base class with a generic `findAll` query, use a construction like this:

```typescript

function BaseResolver<T extends Type<unknown>>(classRef: T): any {
  @Resolver({ isAbstract: true })
  abstract class BaseResolverHost {
    @Query((type) => [classRef], { name: `findAll${classRef.name}` })
    async findAll(): Promise<T[]> {
      return [];
    }
  }
  return BaseResolverHost;
}
```

Note the following:

* an explicit return type (`any` above) is required: otherwise TypeScript complains about the usage of a private class definition. Recommended: define an interface instead of using `any`.
* `Type` is imported from the `@nestjs/common` package
* The `isAbstract: true` property indicates that SDL (Schema Definition Language statements) shouldn't be generated for this class. Note, you can set this property for other types as well to suppress SDL generation.

Here's how you could generate a concrete sub-class of the `BaseResolver`:

```typescript

@Resolver((of) => Recipe)
export class RecipesResolver extends BaseResolver(Recipe) {
  constructor(private recipesService: RecipesService) {
    super();
  }
}
```

This construct would generated the following SDL:

```graphql

type Query {
  findAllRecipe: [Recipe!]!
}
```

#### Generics[#](/graphql/resolvers#generics)

We saw one use of generics above. This powerful TypeScript feature can be used to create useful abstractions. For example, here's a sample cursor-based pagination implementation based on [this documentation](https://graphql.org/learn/pagination/#pagination-and-edges):

```typescript

import { Field, ObjectType, Int } from '@nestjs/graphql';
import { Type } from '@nestjs/common';

export function Paginated<T>(classRef: Type<T>): any {
  @ObjectType(`${classRef.name}Edge`)
  abstract class EdgeType {
    @Field((type) => String)
    cursor: string;

    @Field((type) => classRef)
    node: T;
  }

  @ObjectType({ isAbstract: true })
  abstract class PaginatedType {
    @Field((type) => [EdgeType], { nullable: true })
    edges: EdgeType[];

    @Field((type) => [classRef], { nullable: true })
    nodes: T[];

    @Field((type) => Int)
    totalCount: number;

    @Field()
    hasNextPage: boolean;
  }
  return PaginatedType;
}
```

With the above base class defined, we can now easily create specialized types that inherit this behavior. For example:

```typescript

@ObjectType()
class PaginatedAuthor extends Paginated(Author) {}
```

#### Schema first[#](/graphql/resolvers#schema-first)

As mentioned in the [previous](/v7/graphql/quick-start) chapter, in the schema first approach we start by manually defining schema types in SDL (read [more](https://graphql.org/learn/schema/#type-language)). Consider the following SDL type definitions.

> **Hint** For convenience in this chapter, we've aggregated all of the SDL in one location (e.g., one `.graphql` file, as shown below). In practice, you may find it appropriate to organize your code in a modular fashion. For example, it can be helpful to create individual SDL files with type definitions representing each domain entity, along with related services, resolver code, and the Nest module definition class, in a dedicated directory for that entity. Nest will aggregate all the individual schema type definitions at run time.

```graphql

type Author {
  id: Int!
  firstName: String
  lastName: String
  posts: [Post]
}

type Post {
  id: Int!
  title: String!
  votes: Int
}

type Query {
  author(id: Int!): Author
}
```

#### Schema first resolver[#](/graphql/resolvers#schema-first-resolver)

The schema above exposes a single query - `author(id: Int!): Author`.

> **Hint** Learn more about GraphQL queries [here](https://graphql.org/learn/queries/).

Let's now create an `AuthorsResolver` class that resolves author queries:

authors/authors.resolver.ts

JS TS

```typescript

@Resolver('Author')
export class AuthorsResolver {
  constructor(
    private authorsService: AuthorsService,
    private postsService: PostsService,
  ) {}

  @Query()
  async author(@Args('id') id: number) {
    return this.authorsService.findOneById(id);
  }

  @ResolveField()
  async posts(@Parent() author) {
    const { id } = author;
    return this.postsService.findAll({ authorId: id });
  }
}
```

> **Hint** All decorators (e.g., `@Resolver`, `@ResolveField`, `@Args`, etc.) are exported from the `@nestjs/graphql` package.

> **Note** The logic inside the `AuthorsService` and `PostsService` classes can be as simple or sophisticated as needed. The main point of this example is to show how to construct resolvers and how they can interact with other providers.

The `@Resolver()` decorator is required. It takes an optional string argument with the name of a class. This class name is required whenever the class includes `@ResolveField()` decorators to inform Nest that the decorated method is associated with a parent type (the `Author` type in our current example). Alternatively, instead of setting `@Resolver()` at the top of the class, this can be done for each method:

```typescript

@Resolver('Author')
@ResolveField()
async posts(@Parent() author) {
  const { id } = author;
  return this.postsService.findAll({ authorId: id });
}
```

In this case (`@Resolver()` decorator at the method level), if you have multiple `@ResolveField()` decorators inside a class, you must add `@Resolver()` to all of them. This is not considered the best practice (as it creates extra overhead).

> **Hint** Any class name argument passed to `@Resolver()`**does not** affect queries (`@Query()` decorator) or mutations (`@Mutation()` decorator).

> **Warning** Using the `@Resolver` decorator at the method level is not supported with the **code first** approach.

In the above examples, the `@Query()` and `@ResolveField()` decorators are associated with GraphQL schema types based on the method name. For example, consider the following construction from the example above:

```typescript

@Query()
async author(@Args('id') id: number) {
  return this.authorsService.findOneById(id);
}
```

This generates the following entry for the author query in our schema (the query type uses the same name as the method name):

```graphql

type Query {
  author(id: Int!): Author
}
```

Conventionally, we would prefer to decouple these, using names like `getAuthor()` or `getPosts()` for our resolver methods. We can easily do this by passing the mapping name as an argument to the decorator, as shown below:

authors/authors.resolver.ts

JS TS

```typescript

@Resolver('Author')
export class AuthorsResolver {
  constructor(
    private authorsService: AuthorsService,
    private postsService: PostsService,
  ) {}

  @Query('author')
  async getAuthor(@Args('id') id: number) {
    return this.authorsService.findOneById(id);
  }

  @ResolveField('posts')
  async getPosts(@Parent() author) {
    const { id } = author;
    return this.postsService.findAll({ authorId: id });
  }
}
```

> **Hint** Nest CLI provides a generator (schematic) that automatically generates **all the boilerplate code** to help us avoid doing all of this, and make the developer experience much simpler. Read more about this feature [here](/v7/recipes/crud-generator).

#### Generating types[#](/graphql/resolvers#generating-types)

Assuming that we use the schema first approach and have enabled the typings generation feature (with `outputAs: 'class'` as shown in the [previous](/v7/graphql/quick-start) chapter), once you run the application it will generate the following file (in the location you specified in the `GraphQLModule.forRoot()` method). For example, in `src/graphql.ts`:

graphql.ts

JS TS

```typescript

export class Author {
  id: number;
  firstName?: string;
  lastName?: string;
  posts?: Post[];
}

export class Post {
  id: number;
  title: string;
  votes?: number;
}

export abstract class IQuery {
  abstract author(id: number): Author | Promise<Author>;
}
```

By generating classes (instead of the default technique of generating interfaces), you can use declarative validation **decorators** in combination with the schema first approach, which is an extremely useful technique (read [more](/v7/techniques/validation)). For example, you could add `class-validator` decorators to the generated `CreatePostInput` class as shown below to enforce minimum and maximum string lengths on the `title` field:

```typescript

import { MinLength, MaxLength } from 'class-validator';

export class CreatePostInput {
  @MinLength(3)
  @MaxLength(50)
  title: string;
}
```

> **Notice** To enable auto-validation of your inputs (and parameters), use `ValidationPipe`. Read more about validation [here](/v7/techniques/validation) and more specifically about pipes [here](/v7/pipes).

However, if you add decorators directly to the automatically generated file, they will be **overwritten** each time the file is generated. Instead, create a separate file and simply extend the generated class.

```typescript

import { MinLength, MaxLength } from 'class-validator';
import { Post } from '../../graphql.ts';

export class CreatePostInput extends Post {
  @MinLength(3)
  @MaxLength(50)
  title: string;
}
```

#### GraphQL argument decorators[#](/graphql/resolvers#graphql-argument-decorators)

We can access the standard GraphQL resolver arguments using dedicated decorators. Below is a comparison of the Nest decorators and the plain Apollo parameters they represent.

|                            |                              |
| -------------------------- | ---------------------------- |
| `@Root()` and `@Parent()`  | `root`/`parent`              |
| `@Context(param?: string)` | `context` / `context[param]` |
| `@Info(param?: string)`    | `info` / `info[param]`       |
| `@Args(param?: string)`    | `args` / `args[param]`       |

```typescript

@Module({
  imports: [PostsModule],
  providers: [AuthorsService, AuthorsResolver],
})
export class AuthorsModule {}
```

> **Hint** It is helpful to organize your code by your so-called **domain model** (similar to the way you would organize entry points in a REST API). In this approach, keep your models (`ObjectType` classes), resolvers and services together within a Nest module representing the domain model. Keep all of these components in a single folder per module. When you do this, and use the [Nest CLI](/v7/cli/overview) to generate each element, Nest will wire all of these parts together (locating files in appropriate folders, generating entries in `provider` and `imports` arrays, etc.) automatically for you.

----
url: https://docs.nestjs.com/v11/techniques/logger
----

* [Logger](https://docs.nestjs.com/v11/techniques/logger#logger)
* [Basic customization](https://docs.nestjs.com/v11/techniques/logger#basic-customization)
* [JSON logging](https://docs.nestjs.com/v11/techniques/logger#json-logging)
* [Using the logger for application logging](https://docs.nestjs.com/v11/techniques/logger#using-the-logger-for-application-logging)
* [Logs with timestamps](https://docs.nestjs.com/v11/techniques/logger#logs-with-timestamps)
* [Custom implementation](https://docs.nestjs.com/v11/techniques/logger#custom-implementation)
* [Extend built-in logger](https://docs.nestjs.com/v11/techniques/logger#extend-built-in-logger)
* [Dependency injection](https://docs.nestjs.com/v11/techniques/logger#dependency-injection)
* [Injecting a custom logger](https://docs.nestjs.com/v11/techniques/logger#injecting-a-custom-logger)
* [Use external logger](https://docs.nestjs.com/v11/techniques/logger#use-external-logger)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/techniques/logger.md "Suggest Edits")

### Logger

Nest comes with a built-in text-based logger which is used during application bootstrapping and several other circumstances such as displaying caught exceptions (i.e., system logging). This functionality is provided via the `Logger` class in the `@nestjs/common` package. You can fully control the behavior of the logging system, including any of the following:

* disable logging entirely
* specify the log level of detail (e.g., display errors, warnings, debug information, etc.)
* configure formatting of log messages (raw, json, colorized, etc.)
* override timestamp in the default logger (e.g., use ISO8601 standard as date format)
* completely override the default logger
* customize the default logger by extending it
* make use of dependency injection to simplify composing and testing your application

You can also make use of the built-in logger, or create your own custom implementation, to log your own application-level events and messages.

If your application requires integration with external logging systems, automatic file-based logging, or forwarding logs to a centralized logging service, you can implement a fully custom logging solution using a Node.js logging library. One popular choice is [Pino](https://github.com/pinojs/pino), known for its high performance and flexibility.

#### Basic customization[#](/techniques/logger#basic-customization)

To disable logging, set the `logger` property to `false` in the (optional) Nest application options object passed as the second argument to the `NestFactory.create()` method.

```typescript

const app = await NestFactory.create(AppModule, {
  logger: false,
});
await app.listen(process.env.PORT ?? 3000);
```

To enable specific logging levels, set the `logger` property to an array of strings specifying the log levels to display, as follows:

```typescript

const app = await NestFactory.create(AppModule, {
  logger: ['error', 'warn'],
});
await app.listen(process.env.PORT ?? 3000);
```

Values in the array can be any combination of `'log'`, `'fatal'`, `'error'`, `'warn'`, `'debug'`, and `'verbose'`.

> **Hint** Log levels in Nest are cascading (inherited). This means that providing a specific log level (like `'log'`) will automatically include all higher-severity levels (e.g., `'warn'`, `'error'`, and `'fatal'`).

To disable colorized output, pass the `ConsoleLogger` object with the `colors` property set to `false` as the value of the `logger` property.

```typescript

const app = await NestFactory.create(AppModule, {
  logger: new ConsoleLogger({
    colors: false,
  }),
});
```

To configure a prefix for each log message, pass the `ConsoleLogger` object with the `prefix` attribute set:

```typescript

const app = await NestFactory.create(AppModule, {
  logger: new ConsoleLogger({
    prefix: 'MyApp', // Default is "Nest"
  }),
});
```

Here are all the available options listed in the table below:

| Option            | Description                                                                                                                                                                                                                                                                                                                                          | Default                                                 |
| ----------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------- |
| `logLevels`       | Enabled log levels.                                                                                                                                                                                                                                                                                                                                  | `['log', 'fatal', 'error', 'warn', 'debug', 'verbose']` |
| `timestamp`       | If enabled, will print timestamp (time difference) between current and previous log message. Note: This option is not used when `json` is enabled.                                                                                                                                                                                                   | `false`                                                 |
| `prefix`          | A prefix to be used for each log message. Note: This option is not used when `json` is enabled.                                                                                                                                                                                                                                                      | `Nest`                                                  |
| `json`            | If enabled, will print the log message in JSON format.                                                                                                                                                                                                                                                                                               | `false`                                                 |
| `colors`          | If enabled, will print the log message in color. Default true if json is disabled, false otherwise.                                                                                                                                                                                                                                                  | `true`                                                  |
| `context`         | The context of the logger.                                                                                                                                                                                                                                                                                                                           | `undefined`                                             |
| `compact`         | If enabled, will print the log message in a single line, even if it is an object with multiple properties. If set to a number, the most n inner elements are united on a single line as long as all properties fit into breakLength. Short array elements are also grouped together.                                                                 | `true`                                                  |
| `maxArrayLength`  | Specifies the maximum number of Array, TypedArray, Map, Set, WeakMap, and WeakSet elements to include when formatting. Set to null or Infinity to show all elements. Set to 0 or negative to show no elements. Ignored when `json` is enabled, colors are disabled, and `compact` is set to true as it produces a parseable JSON output.             | `100`                                                   |
| `maxStringLength` | Specifies the maximum number of characters to include when formatting. Set to null or Infinity to show all elements. Set to 0 or negative to show no characters. Ignored when `json` is enabled, colors are disabled, and `compact` is set to true as it produces a parseable JSON output.                                                           | `10000`                                                 |
| `sorted`          | If enabled, will sort keys while formatting objects. Can also be a custom sorting function. Ignored when `json` is enabled, colors are disabled, and `compact` is set to true as it produces a parseable JSON output.                                                                                                                                | `false`                                                 |
| `depth`           | Specifies the number of times to recurse while formatting object. This is useful for inspecting large objects. To recurse up to the maximum call stack size pass Infinity or null. Ignored when `json` is enabled, colors are disabled, and `compact` is set to true as it produces a parseable JSON output.                                         | `5`                                                     |
| `showHidden`      | If true, object's non-enumerable symbols and properties are included in the formatted result. WeakMap and WeakSet entries are also included as well as user defined prototype properties                                                                                                                                                             | `false`                                                 |
| `breakLength`     | The length at which input values are split across multiple lines. Set to Infinity to format the input as a single line (in combination with "compact" set to true). Default Infinity when "compact" is true, 80 otherwise. Ignored when `json` is enabled, colors are disabled, and `compact` is set to true as it produces a parseable JSON output. | `Infinity`                                              |

#### JSON logging[#](/techniques/logger#json-logging)

JSON logging is essential for modern application observability and integration with log management systems. To enable JSON logging in your NestJS application, configure the `ConsoleLogger` object with its `json` property set to `true`. Then, provide this logger configuration as the value for the `logger` property when creating the application instance.

```typescript

const app = await NestFactory.create(AppModule, {
  logger: new ConsoleLogger({
    json: true,
  }),
});
```

This configuration outputs logs in a structured JSON format, making it easier to integrate with external systems such as log aggregators and cloud platforms. For example, platforms like **AWS ECS** (Elastic Container Service) natively support JSON logs, enabling advanced features like:

* **Log Filtering**: Easily narrow down logs based on fields like log level, timestamp, or custom metadata.
* **Search and Analysis**: Use query tools to analyze and track trends in your application's behavior.

Additionally, if you're using [NestJS Mau](https://mau.nestjs.com), JSON logging simplifies the process of viewing logs in a well-organized, structured format, which is especially useful for debugging and performance monitoring.

> **Note** When `json` is set to `true`, the `ConsoleLogger` automatically disables text colorization by setting the `colors` property to `false`. This ensures that the output remains valid JSON, free of formatting artifacts. However, for development purposes, you can override this behavior by explicitly setting `colors` to `true`. This adds colorized JSON logs, which can make log entries more readable during local debugging.

When JSON logging is enabled, the log output will look like this (in a single line):

```json

{
  "level": "log",
  "pid": 19096,
  "timestamp": 1607370779834,
  "message": "Starting Nest application...",
  "context": "NestFactory"
}
```

You can see different variants in this [Pull Request](https://github.com/nestjs/nest/pull/14121).

#### Using the logger for application logging[#](/techniques/logger#using-the-logger-for-application-logging)

We can combine several of the techniques above to provide consistent behavior and formatting across both Nest system logging and our own application event/message logging.

A good practice is to instantiate `Logger` class from `@nestjs/common` in each of our services. We can supply our service name as the `context` argument in the `Logger` constructor, like so:

```typescript

import { Logger, Injectable } from '@nestjs/common';

@Injectable()
class MyService {
  private readonly logger = new Logger(MyService.name);

  doSomething() {
    this.logger.log('Doing something...');
  }
}
```

In the default logger implementation, `context` is printed in the square brackets, like `NestFactory` in the example below:

```bash

[Nest] 19096   - 12/08/2019, 7:12:59 AM   [NestFactory] Starting Nest application...
```

If we supply a custom logger via `app.useLogger()`, it will actually be used by Nest internally. That means that our code remains implementation agnostic, while we can easily substitute the default logger for our custom one by calling `app.useLogger()`.

That way if we follow the steps from the previous section and call `app.useLogger(app.get(MyLogger))`, the following calls to `this.logger.log()` from `MyService` would result in calls to method `log` from `MyLogger` instance.

This should be suitable for most cases. But if you need more customization (like adding and calling custom methods), move to the next section.

#### Logs with timestamps[#](/techniques/logger#logs-with-timestamps)

To enable timestamp logging for every logged message, you can use the optional `timestamp: true` setting when creating the logger instance.

```typescript

import { Logger, Injectable } from '@nestjs/common';

@Injectable()
class MyService {
  private readonly logger = new Logger(MyService.name, { timestamp: true });

  doSomething() {
    this.logger.log('Doing something with timestamp here ->');
  }
}
```

This will produce output in the following format:

```bash

[Nest] 19096   - 04/19/2024, 7:12:59 AM   [MyService] Doing something with timestamp here +5ms
```

Note the `+5ms` at the end of the line. For each log statement, the time difference from the previous message is calculated and displayed at the end of the line.

#### Custom implementation[#](/techniques/logger#custom-implementation)

You can provide a custom logger implementation to be used by Nest for system logging by setting the value of the `logger` property to an object that fulfills the `LoggerService` interface. For example, you can tell Nest to use the built-in global JavaScript `console` object (which implements the `LoggerService` interface), as follows:

```typescript

const app = await NestFactory.create(AppModule, {
  logger: console,
});
await app.listen(process.env.PORT ?? 3000);
```

Implementing your own custom logger is straightforward. Simply implement each of the methods of the `LoggerService` interface as shown below.

```typescript

import { LoggerService, Injectable } from '@nestjs/common';

@Injectable()
export class MyLogger implements LoggerService {
  /**
   * Write a 'log' level log.
   */
  log(message: any, ...optionalParams: any[]) {}

  /**
   * Write a 'fatal' level log.
   */
  fatal(message: any, ...optionalParams: any[]) {}

  /**
   * Write an 'error' level log.
   */
  error(message: any, ...optionalParams: any[]) {}

  /**
   * Write a 'warn' level log.
   */
  warn(message: any, ...optionalParams: any[]) {}

  /**
   * Write a 'debug' level log.
   */
  debug?(message: any, ...optionalParams: any[]) {}

  /**
   * Write a 'verbose' level log.
   */
  verbose?(message: any, ...optionalParams: any[]) {}
}
```

You can then supply an instance of `MyLogger` via the `logger` property of the Nest application options object.

```typescript

const app = await NestFactory.create(AppModule, {
  logger: new MyLogger(),
});
await app.listen(process.env.PORT ?? 3000);
```

This technique, while simple, doesn't utilize dependency injection for the `MyLogger` class. This can pose some challenges, particularly for testing, and limit the reusability of `MyLogger`. For a better solution, see the [Dependency Injection](techniques/logger#dependency-injection) section below.

#### Extend built-in logger[#](/techniques/logger#extend-built-in-logger)

Rather than writing a logger from scratch, you may be able to meet your needs by extending the built-in `ConsoleLogger` class and overriding selected behavior of the default implementation.

```typescript

import { ConsoleLogger } from '@nestjs/common';

export class MyLogger extends ConsoleLogger {
  error(message: any, stack?: string, context?: string) {
    // add your tailored logic here
    super.error(...arguments);
  }
}
```

```typescript

import { Module } from '@nestjs/common';
import { MyLogger } from './my-logger.service';

@Module({
  providers: [MyLogger],
  exports: [MyLogger],
})
export class LoggerModule {}
```

With this construct, you are now providing your custom logger for use by any other module. Because your `MyLogger` class is part of a module, it can use dependency injection (for example, to inject a `ConfigService`). There's one more technique needed to provide this custom logger for use by Nest for system logging (e.g., for bootstrapping and error handling).

Because application instantiation (`NestFactory.create()`) happens outside the context of any module, it doesn't participate in the normal Dependency Injection phase of initialization. So we must ensure that at least one application module imports the `LoggerModule` to trigger Nest to instantiate a singleton instance of our `MyLogger` class.

We can then instruct Nest to use the same singleton instance of `MyLogger` with the following construction:

```typescript

const app = await NestFactory.create(AppModule, {
  bufferLogs: true,
});
app.useLogger(app.get(MyLogger));
await app.listen(process.env.PORT ?? 3000);
```

> **Note** In the example above, we set the `bufferLogs` to `true` to make sure all logs will be buffered until a custom logger is attached (`MyLogger` in this case) and the application initialisation process either completes or fails. If the initialisation process fails, Nest will fallback to the original `ConsoleLogger` to print out any reported error messages. Also, you can set the `autoFlushLogs` to `false` (default `true`) to manually flush logs (using the `Logger.flush()` method).

Here we use the `get()` method on the `NestApplication` instance to retrieve the singleton instance of the `MyLogger` object. This technique is essentially a way to "inject" an instance of a logger for use by Nest. The `app.get()` call retrieves the singleton instance of `MyLogger`, and depends on that instance being first injected in another module, as described above.

You can also inject this `MyLogger` provider in your feature classes, thus ensuring consistent logging behavior across both Nest system logging and application logging. See [Using the logger for application logging](techniques/logger#using-the-logger-for-application-logging) and [Injecting a custom logger](techniques/logger#injecting-a-custom-logger) below for more information.

#### Injecting a custom logger[#](/techniques/logger#injecting-a-custom-logger)

To start, extend the built-in logger with code like the following. We supply the `scope` option as configuration metadata for the `ConsoleLogger` class, specifying a [transient](/v11/fundamentals/injection-scopes) scope so that each feature module gets its own logger instance. This is important because each module sets a unique context on its logger via `setContext()` — with a singleton, that call would overwrite the context across the entire app. In this example, we do not extend the individual `ConsoleLogger` methods (like `log()`, `warn()`, etc.), though you may choose to do so.

```typescript

import { Injectable, Scope, ConsoleLogger } from '@nestjs/common';

@Injectable({ scope: Scope.TRANSIENT })
export class MyLogger extends ConsoleLogger {
  customLog() {
    this.log('Please feed the cat!');
  }
}
```

Next, create a `LoggerModule` with a construction like this:

```typescript

import { Module } from '@nestjs/common';
import { MyLogger } from './my-logger.service';

@Module({
  providers: [MyLogger],
  exports: [MyLogger],
})
export class LoggerModule {}
```

Next, import the `LoggerModule` into your feature module. Since we extended default `Logger` we have the convenience of using `setContext` method. So we can start using the context-aware custom logger, like this:

```typescript

import { Injectable } from '@nestjs/common';
import { MyLogger } from './my-logger.service';

@Injectable()
export class CatsService {
  private readonly cats: Cat[] = [];

  constructor(private myLogger: MyLogger) {
    // Due to transient scope, CatsService has its own unique instance of MyLogger,
    // so setting context here will not affect other instances in other services
    this.myLogger.setContext('CatsService');
  }

  findAll(): Cat[] {
    // You can call all the default methods
    this.myLogger.warn('About to return cats!');
    // And your custom methods
    this.myLogger.customLog();
    return this.cats;
  }
}
```

Finally, instruct Nest to use an instance of the custom logger in your `main.ts` file as shown below. Of course in this example, we haven't actually customized the logger behavior (by extending the `Logger` methods like `log()`, `warn()`, etc.), so this step isn't actually needed. But it **would** be needed if you added custom logic to those methods and wanted Nest to use the same implementation.

```typescript

const app = await NestFactory.create(AppModule, {
  bufferLogs: true,
});
app.useLogger(new MyLogger());
await app.listen(process.env.PORT ?? 3000);
```

> **Hint** Alternatively, instead of setting `bufferLogs` to `true`, you could temporarily disable the logger with `logger: false` instruction. Be mindful that if you supply `logger: false` to `NestFactory.create`, nothing will be logged until you call `useLogger`, so you may miss some important initialization errors. If you don't mind that some of your initial messages will be logged with the default logger, you can just omit the `logger: false` option.

#### Use external logger[#](/techniques/logger#use-external-logger)

Production applications often have specific logging requirements, including advanced filtering, formatting and centralized logging. Nest's built-in logger is used for monitoring Nest system behavior, and can also be useful for basic formatted text logging in your feature modules while in development, but production applications often take advantage of dedicated logging modules like [Winston](https://github.com/winstonjs/winston). As with any standard Node.js application, you can take full advantage of such modules in Nest.

----
url: https://docs.nestjs.com/v11/recipes/sentry
----

* [Sentry](https://docs.nestjs.com/v11/recipes/sentry#sentry)
* [Installation](https://docs.nestjs.com/v11/recipes/sentry#installation)
* [Basic setup](https://docs.nestjs.com/v11/recipes/sentry#basic-setup)
* [Exception handling](https://docs.nestjs.com/v11/recipes/sentry#exception-handling)
* [Readable stack traces](https://docs.nestjs.com/v11/recipes/sentry#readable-stack-traces)
* [Testing the integration](https://docs.nestjs.com/v11/recipes/sentry#testing-the-integration)
* [Summary](https://docs.nestjs.com/v11/recipes/sentry#summary)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/recipes/sentry.md "Suggest Edits")

### Sentry

[Sentry](https://sentry.io) is an error tracking and performance monitoring platform that helps developers identify and fix issues in real-time. This recipe shows how to integrate Sentry's [NestJS SDK](https://docs.sentry.io/platforms/javascript/guides/nestjs/) with your NestJS application.

#### Installation[#](/recipes/sentry#installation)

First, install the required dependencies:

```bash

$ npm install --save @sentry/nestjs @sentry/profiling-node
```

> **Hint**`@sentry/profiling-node` is optional, but recommended for performance profiling.

#### Basic setup[#](/recipes/sentry#basic-setup)

To get started with Sentry, you'll need to create a file named `instrument.ts` that should be imported before any other modules in your application:

instrument.ts

JS TS

```typescript

const Sentry = require("@sentry/nestjs");
const { nodeProfilingIntegration } = require("@sentry/profiling-node");

// Ensure to call this before requiring any other modules!
Sentry.init({
  dsn: SENTRY_DSN,
  integrations: [
    // Add our Profiling integration
    nodeProfilingIntegration(),
  ],

  // Add Tracing by setting tracesSampleRate
  // We recommend adjusting this value in production
  tracesSampleRate: 1.0,

  // Set sampling rate for profiling
  // This is relative to tracesSampleRate
  profilesSampleRate: 1.0,
});
```

Update your `main.ts` file to import `instrument.ts` before other imports:

main.ts

JS TS

```typescript

// Import this first!
import "./instrument";

// Now import other modules
import { NestFactory } from "@nestjs/core";
import { AppModule } from "./app.module";

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  await app.listen(3000);
}

bootstrap();
```

Afterwards, add the `SentryModule` as a root module to your main module:

app.module.ts

JS TS

```typescript

import { Module } from "@nestjs/common";
import { SentryModule } from "@sentry/nestjs/setup";
import { AppController } from "./app.controller";
import { AppService } from "./app.service";

@Module({
  imports: [
    SentryModule.forRoot(),
    // ...other modules
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}
```

#### Exception handling[#](/recipes/sentry#exception-handling)

If you're using a global catch-all exception filter (which is either a filter registered with `app.useGlobalFilters()` or a filter registered in your app module providers annotated with a `@Catch()` decorator without arguments), add a `@SentryExceptionCaptured()` decorator to the filter's `catch()` method. This decorator will report all unexpected errors that are received by your global error filter to Sentry:

```typescript

import { Catch, ExceptionFilter } from '@nestjs/common';
import { SentryExceptionCaptured } from '@sentry/nestjs';

@Catch()
export class YourCatchAllExceptionFilter implements ExceptionFilter {
  @SentryExceptionCaptured()
  catch(exception, host): void {
    // your implementation here
  }
}
```

By default, only unhandled exceptions that are not caught by an error filter are reported to Sentry. `HttpExceptions` (including [derivatives](https://docs.nestjs.com/exception-filters#built-in-http-exceptions)) are also not captured by default because they mostly act as control flow vehicles.

If you don't have a global catch-all exception filter, add the `SentryGlobalFilter` to the providers of your main module. This filter will report any unhandled errors that aren't caught by other error filters to Sentry.

> **Warning** The `SentryGlobalFilter` needs to be registered before any other exception filters.

app.module.ts

JS TS

```typescript

import { Module } from "@nestjs/common";
import { APP_FILTER } from "@nestjs/core";
import { SentryGlobalFilter } from "@sentry/nestjs/setup";

@Module({
  providers: [
    {
      provide: APP_FILTER,
      useClass: SentryGlobalFilter,
    },
    // ..other providers
  ],
})
export class AppModule {}
```

#### Readable stack traces[#](/recipes/sentry#readable-stack-traces)

Depending on how you've set up your project, the stack traces in your Sentry errors probably won't look like your actual code.

To fix this, upload your source maps to Sentry. The easiest way to do this is by using the Sentry Wizard:

```bash

npx @sentry/wizard@latest -i sourcemaps
```

#### Testing the integration[#](/recipes/sentry#testing-the-integration)

To verify your Sentry integration is working, you can add a test endpoint that throws an error:

```typescript

@Get("debug-sentry")
getError() {
  throw new Error("My first Sentry error!");
}
```

Visit `/debug-sentry` in your application, and you should see the error appear in your Sentry dashboard.

### Summary

For complete documentation about Sentry's NestJS SDK, including advanced configuration options and features, visit the [official Sentry documentation](https://docs.sentry.io/platforms/javascript/guides/nestjs/).

While software bugs are Sentry's thing, we still write them. If you come across any problems while installing our SDK, please open a [GitHub Issue](https://github.com/getsentry/sentry-javascript/issues) or reach out on [Discord](https://discord.com/invite/sentry).

----
url: https://docs.nestjs.com/v10/graphql/migration-guide
----

* [Migrating to v11 from v10](https://docs.nestjs.com/v10/graphql/migration-guide#migrating-to-v11-from-v10)
* [Apollo packages](https://docs.nestjs.com/v10/graphql/migration-guide#apollo-packages)
* [Mercurius packages](https://docs.nestjs.com/v10/graphql/migration-guide#mercurius-packages)
* [Migrating to v10 from v9](https://docs.nestjs.com/v10/graphql/migration-guide#migrating-to-v10-from-v9)
* [Introducing "driver" packages](https://docs.nestjs.com/v10/graphql/migration-guide#introducing-driver-packages)
* [Plugins](https://docs.nestjs.com/v10/graphql/migration-guide#plugins)
* [Directives](https://docs.nestjs.com/v10/graphql/migration-guide#directives)
* [Federation](https://docs.nestjs.com/v10/graphql/migration-guide#federation)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/migration.md "Suggest Edits")

### Migrating to v11 from v10

This chapter provides a set of guidelines for migrating from `@nestjs/graphql` version 10 to version 11. As part of this major release, we updated the Apollo driver to be compatible with Apollo Server v4 (instead of v3). Note: there are several breaking changes in Apollo Server v4 (especially around plugins and ecosystem packages), so you'll have to update your codebase accordingly. For more information, see the [Apollo Server v4 migration guide](https://www.apollographql.com/docs/apollo-server/migration/).

#### Apollo packages[#](/graphql/migration-guide#apollo-packages)

Instead of installing the `apollo-server-express` package, you'll have to install `@apollo/server`:

```bash

$ npm uninstall apollo-server-express
$ npm install @apollo/server
```

If you use the Fastify adapter, you'll have to install the `@as-integrations/fastify` package instead:

```bash

$ npm uninstall apollo-server-fastify
$ npm install @apollo/server @as-integrations/fastify
```

#### Mercurius packages[#](/graphql/migration-guide#mercurius-packages)

Mercurius gateway is no longer a part of the `mercurius` package. Instead, you'll have to install the `@mercuriusjs/gateway` package separately:

```bash

$ npm install @mercuriusjs/gateway
```

Similarly, for creating federated schemas, you'll have to install the `@mercuriusjs/federation` package:

```bash

$ npm install @mercuriusjs/federation
```

### Migrating to v10 from v9

This chapter provides a set of guidelines for migrating from `@nestjs/graphql` version 9 to version 10. The focus of this major-version release is to provide a lighter, platform-agnostic core library.

#### Introducing "driver" packages[#](/graphql/migration-guide#introducing-driver-packages)

In the latest version, we made a decision to break the `@nestjs/graphql` package up into a few separate libraries, letting you choose whether to use Apollo (`@nestjs/apollo`), Mercurius (`@nestjs/mercurius`), or another GraphQL library in your project.

This implies that now you have to explicitly specify what driver your application will use.

```typescript

// Before
import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';

@Module({
  imports: [
    GraphQLModule.forRoot({
      autoSchemaFile: 'schema.gql',
    }),
  ],
})
export class AppModule {}

// After
import { ApolloDriver, ApolloDriverConfig } from '@nestjs/apollo';
import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';

@Module({
  imports: [
    GraphQLModule.forRoot<ApolloDriverConfig>({
      driver: ApolloDriver,
      autoSchemaFile: 'schema.gql',
    }),
  ],
})
export class AppModule {}
```

#### Plugins[#](/graphql/migration-guide#plugins)

Apollo Server plugins let you perform custom operations in response to certain events. Since this is an exclusive Apollo feature, we moved it from the `@nestjs/graphql` to the newly created `@nestjs/apollo` package so you'll have to update imports in your application.

```typescript

// Before
import { Plugin } from '@nestjs/graphql';

// After
import { Plugin } from '@nestjs/apollo';
```

#### Directives[#](/graphql/migration-guide#directives)

`schemaDirectives` feature has been replaced with the new [Schema directives API](https://www.graphql-tools.com/docs/schema-directives) in v8 of `@graphql-tools/schema` package.

```typescript

// Before
import { SchemaDirectiveVisitor } from '@graphql-tools/utils';
import { defaultFieldResolver, GraphQLField } from 'graphql';

export class UpperCaseDirective extends SchemaDirectiveVisitor {
  visitFieldDefinition(field: GraphQLField<any, any>) {
    const { resolve = defaultFieldResolver } = field;
    field.resolve = async function (...args) {
      const result = await resolve.apply(this, args);
      if (typeof result === 'string') {
        return result.toUpperCase();
      }
      return result;
    };
  }
}

// After
import { getDirective, MapperKind, mapSchema } from '@graphql-tools/utils';
import { defaultFieldResolver, GraphQLSchema } from 'graphql';

export function upperDirectiveTransformer(
  schema: GraphQLSchema,
  directiveName: string,
) {
  return mapSchema(schema, {
    [MapperKind.OBJECT_FIELD]: (fieldConfig) => {
      const upperDirective = getDirective(
        schema,
        fieldConfig,
        directiveName,
      )?.[0];

      if (upperDirective) {
        const { resolve = defaultFieldResolver } = fieldConfig;

        // Replace the original resolver with a function that *first* calls
        // the original resolver, then converts its result to upper case
        fieldConfig.resolve = async function (source, args, context, info) {
          const result = await resolve(source, args, context, info);
          if (typeof result === 'string') {
            return result.toUpperCase();
          }
          return result;
        };
        return fieldConfig;
      }
    },
  });
}
```

To apply this directive implementation to a schema that contains `@upper` directives, use the `transformSchema` function:

```typescript

GraphQLModule.forRoot<ApolloDriverConfig>({
  ...
  transformSchema: schema => upperDirectiveTransformer(schema, 'upper'),
})
```

#### Federation[#](/graphql/migration-guide#federation)

`GraphQLFederationModule` has been removed and replaced with the corresponding driver class:

```typescript

// Before
GraphQLFederationModule.forRoot({
  autoSchemaFile: true,
});

// After
GraphQLModule.forRoot<ApolloFederationDriverConfig>({
  driver: ApolloFederationDriver,
  autoSchemaFile: true,
});
```

> **Hint** Both `ApolloFederationDriver` class and `ApolloFederationDriverConfig` are exported from the `@nestjs/apollo` package.

Likewise, instead of using a dedicated `GraphQLGatewayModule`, simply pass the appropriate `driver` class to your `GraphQLModule` settings:

```typescript

// Before
GraphQLGatewayModule.forRoot({
  gateway: {
    supergraphSdl: new IntrospectAndCompose({
      subgraphs: [
        { name: 'users', url: 'http://localhost:3000/graphql' },
        { name: 'posts', url: 'http://localhost:3001/graphql' },
      ],
    }),
  },
});

// After
GraphQLModule.forRoot<ApolloGatewayDriverConfig>({
  driver: ApolloGatewayDriver,
  gateway: {
    supergraphSdl: new IntrospectAndCompose({
      subgraphs: [
        { name: 'users', url: 'http://localhost:3000/graphql' },
        { name: 'posts', url: 'http://localhost:3001/graphql' },
      ],
    }),
  },
});
```

> **Hint** Both `ApolloGatewayDriver` class and `ApolloGatewayDriverConfig` are exported from the `@nestjs/apollo` package.

----
url: https://docs.nestjs.com/v7/fundamentals/custom-providers
----

* [Custom providers](https://docs.nestjs.com/v7/fundamentals/custom-providers#custom-providers)
* [DI fundamentals](https://docs.nestjs.com/v7/fundamentals/custom-providers#di-fundamentals)
* [Standard providers](https://docs.nestjs.com/v7/fundamentals/custom-providers#standard-providers)
* [Custom providers](https://docs.nestjs.com/v7/fundamentals/custom-providers#custom-providers-1)
* [Value providers: useValue](https://docs.nestjs.com/v7/fundamentals/custom-providers#value-providers-usevalue)
* [Non-class-based provider tokens](https://docs.nestjs.com/v7/fundamentals/custom-providers#non-class-based-provider-tokens)
* [Class providers: useClass](https://docs.nestjs.com/v7/fundamentals/custom-providers#class-providers-useclass)
* [Factory providers: useFactory](https://docs.nestjs.com/v7/fundamentals/custom-providers#factory-providers-usefactory)
* [Alias providers: useExisting](https://docs.nestjs.com/v7/fundamentals/custom-providers#alias-providers-useexisting)
* [Non-service based providers](https://docs.nestjs.com/v7/fundamentals/custom-providers#non-service-based-providers)
* [Export custom provider](https://docs.nestjs.com/v7/fundamentals/custom-providers#export-custom-provider)

```typescript

import { Injectable } from '@nestjs/common';
import { Cat } from './interfaces/cat.interface';

@Injectable()
export class CatsService {
  private readonly cats: Cat[] = [];

  findAll(): Cat[] {
    return this.cats;
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';

@Injectable()
export class CatsService {
  constructor() {
    this.cats = [];
  }

  findAll() {
    return this.cats;
  }
}
```

Then we request that Nest inject the provider into our controller class:

cats.controller.ts

JS TS

```typescript

import { Controller, Get } from '@nestjs/common';
import { CatsService } from './cats.service';
import { Cat } from './interfaces/cat.interface';

@Controller('cats')
export class CatsController {
  constructor(private catsService: CatsService) {}

  @Get()
  async findAll(): Promise<Cat[]> {
    return this.catsService.findAll();
  }
}
```

```typescript

import { Controller, Get, Bind, Dependencies } from '@nestjs/common';
import { CatsService } from './cats.service';

@Controller('cats')
@Dependencies(CatsService)
export class CatsController {
  constructor(catsService) {
    this.catsService = catsService;
  }

  @Get()
  async findAll() {
    return this.catsService.findAll();
  }
}
```

Finally, we register the provider with the Nest IoC container:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { CatsController } from './cats/cats.controller';
import { CatsService } from './cats/cats.service';

@Module({
  controllers: [CatsController],
  providers: [CatsService],
})
export class AppModule {}
```

What exactly is happening under the covers to make this work? There are three key steps in the process:

1. In `cats.service.ts`, the `@Injectable()` decorator declares the `CatsService` class as a class that can be managed by the Nest IoC container.
2. In `cats.controller.ts`, `CatsController` declares a dependency on the `CatsService` token with constructor injection:

```typescript

  constructor(private catsService: CatsService)
```

3. In `app.module.ts`, we associate the token `CatsService` with the class `CatsService` from the `cats.service.ts` file. We'll [see below](/fundamentals/custom-providers#standard-providers) exactly how this association (also called *registration*) occurs.

When the Nest IoC container instantiates a `CatsController`, it first looks for any dependencies\*. When it finds the `CatsService` dependency, it performs a lookup on the `CatsService` token, which returns the `CatsService` class, per the registration step (#3 above). Assuming `SINGLETON` scope (the default behavior), Nest will then either create an instance of `CatsService`, cache it, and return it, or if one is already cached, return the existing instance.

\*This explanation is a bit simplified to illustrate the point. One important area we glossed over is that the process of analyzing the code for dependencies is very sophisticated, and happens during application bootstrapping. One key feature is that dependency analysis (or "creating the dependency graph"), is **transitive**. In the above example, if the `CatsService` itself had dependencies, those too would be resolved. The dependency graph ensures that dependencies are resolved in the correct order - essentially "bottom up". This mechanism relieves the developer from having to manage such complex dependency graphs.

## Learn the right way!

* **80+ chapters
* **5+ hours of videos
* **Official certificate
* **Deep-dive sessions

[Explore official courses](https://courses.nestjs.com "Courses | NestJS - A node.js framework built on top of TypeScript")

#### Standard providers[#](/fundamentals/custom-providers#standard-providers)

Let's take a closer look at the `@Module()` decorator. In `app.module`, we declare:

```typescript

@Module({
  controllers: [CatsController],
  providers: [CatsService],
})
```

The `providers` property takes an array of `providers`. So far, we've supplied those providers via a list of class names. In fact, the syntax `providers: [CatsService]` is short-hand for the more complete syntax:

```typescript

providers: [
  {
    provide: CatsService,
    useClass: CatsService,
  },
];
```

```typescript

import { CatsService } from './cats.service';

const mockCatsService = {
  /* mock implementation
  ...
  */
};

@Module({
  imports: [CatsModule],
  providers: [
    {
      provide: CatsService,
      useValue: mockCatsService,
    },
  ],
})
export class AppModule {}
```

In this example, the `CatsService` token will resolve to the `mockCatsService` mock object. `useValue` requires a value - in this case a literal object that has the same interface as the `CatsService` class it is replacing. Because of TypeScript's [structural typing](https://www.typescriptlang.org/docs/handbook/type-compatibility.html), you can use any object that has a compatible interface, including a literal object or a class instance instantiated with `new`.

#### Non-class-based provider tokens[#](/fundamentals/custom-providers#non-class-based-provider-tokens)

So far, we've used class names as our provider tokens (the value of the `provide` property in a provider listed in the `providers` array). This is matched by the standard pattern used with [constructor based injection](https://docs.nestjs.com/providers#dependency-injection), where the token is also a class name. (Refer back to [DI Fundamentals](/fundamentals/custom-providers#di-fundamentals) for a refresher on tokens if this concept isn't entirely clear). Sometimes, we may want the flexibility to use strings or symbols as the DI token. For example:

```typescript

import { connection } from './connection';

@Module({
  providers: [
    {
      provide: 'CONNECTION',
      useValue: connection,
    },
  ],
})
export class AppModule {}
```

In this example, we are associating a string-valued token (`'CONNECTION'`) with a pre-existing `connection` object we've imported from an external file.

> **Notice** In addition to using strings as token values, you can also use JavaScript [symbols](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol) or TypeScript [enums](https://www.typescriptlang.org/docs/handbook/enums.html).

We've previously seen how to inject a provider using the standard [constructor based injection](https://docs.nestjs.com/providers#dependency-injection) pattern. This pattern **requires** that the dependency be declared with a class name. The `'CONNECTION'` custom provider uses a string-valued token. Let's see how to inject such a provider. To do so, we use the `@Inject()` decorator. This decorator takes a single argument - the token.

JS TS

```typescript

@Injectable()
export class CatsRepository {
  constructor(@Inject('CONNECTION') connection: Connection) {}
}
```

```typescript

@Injectable()
@Dependencies('CONNECTION')
export class CatsRepository {
  constructor(connection) {}
}
```

> **Hint** The `@Inject()` decorator is imported from `@nestjs/common` package.

While we directly use the string `'CONNECTION'` in the above examples for illustration purposes, for clean code organization, it's best practice to define tokens in a separate file, such as `constants.ts`. Treat them much as you would symbols or enums that are defined in their own file and imported where needed.

#### Class providers: `useClass`[#](/fundamentals/custom-providers#class-providers-useclass)

The `useClass` syntax allows you to dynamically determine a class that a token should resolve to. For example, suppose we have an abstract (or default) `ConfigService` class. Depending on the current environment, we want Nest to provide a different implementation of the configuration service. The following code implements such a strategy.

```typescript

const configServiceProvider = {
  provide: ConfigService,
  useClass:
    process.env.NODE_ENV === 'development'
      ? DevelopmentConfigService
      : ProductionConfigService,
};

@Module({
  providers: [configServiceProvider],
})
export class AppModule {}
```

```typescript

const connectionFactory = {
  provide: 'CONNECTION',
  useFactory: (optionsProvider: OptionsProvider) => {
    const options = optionsProvider.get();
    return new DatabaseConnection(options);
  },
  inject: [OptionsProvider],
};

@Module({
  providers: [connectionFactory],
})
export class AppModule {}
```

```typescript

const connectionFactory = {
  provide: 'CONNECTION',
  useFactory: (optionsProvider) => {
    const options = optionsProvider.get();
    return new DatabaseConnection(options);
  },
  inject: [OptionsProvider],
};

@Module({
  providers: [connectionFactory],
})
export class AppModule {}
```

#### Alias providers: `useExisting`[#](/fundamentals/custom-providers#alias-providers-useexisting)

The `useExisting` syntax allows you to create aliases for existing providers. This creates two ways to access the same provider. In the example below, the (string-based) token `'AliasedLoggerService'` is an alias for the (class-based) token `LoggerService`. Assume we have two different dependencies, one for `'AliasedLoggerService'` and one for `LoggerService`. If both dependencies are specified with `SINGLETON` scope, they'll both resolve to the same instance.

```typescript

@Injectable()
class LoggerService {
  /* implementation details */
}

const loggerAliasProvider = {
  provide: 'AliasedLoggerService',
  useExisting: LoggerService,
};

@Module({
  providers: [LoggerService, loggerAliasProvider],
})
export class AppModule {}
```

#### Non-service based providers[#](/fundamentals/custom-providers#non-service-based-providers)

While providers often supply services, they are not limited to that usage. A provider can supply **any** value. For example, a provider may supply an array of configuration objects based on the current environment, as shown below:

```typescript

const configFactory = {
  provide: 'CONFIG',
  useFactory: () => {
    return process.env.NODE_ENV === 'development' ? devConfig : prodConfig;
  },
};

@Module({
  providers: [configFactory],
})
export class AppModule {}
```

#### Export custom provider[#](/fundamentals/custom-providers#export-custom-provider)

Like any provider, a custom provider is scoped to its declaring module. To make it visible to other modules, it must be exported. To export a custom provider, we can either use its token or the full provider object.

The following example shows exporting using the token:

JS TS

```typescript

const connectionFactory = {
  provide: 'CONNECTION',
  useFactory: (optionsProvider: OptionsProvider) => {
    const options = optionsProvider.get();
    return new DatabaseConnection(options);
  },
  inject: [OptionsProvider],
};

@Module({
  providers: [connectionFactory],
  exports: ['CONNECTION'],
})
export class AppModule {}
```

```typescript

const connectionFactory = {
  provide: 'CONNECTION',
  useFactory: (optionsProvider) => {
    const options = optionsProvider.get();
    return new DatabaseConnection(options);
  },
  inject: [OptionsProvider],
};

@Module({
  providers: [connectionFactory],
  exports: ['CONNECTION'],
})
export class AppModule {}
```

Alternatively, export with the full provider object:

JS TS

```typescript

const connectionFactory = {
  provide: 'CONNECTION',
  useFactory: (optionsProvider: OptionsProvider) => {
    const options = optionsProvider.get();
    return new DatabaseConnection(options);
  },
  inject: [OptionsProvider],
};

@Module({
  providers: [connectionFactory],
  exports: [connectionFactory],
})
export class AppModule {}
```

```typescript

const connectionFactory = {
  provide: 'CONNECTION',
  useFactory: (optionsProvider) => {
    const options = optionsProvider.get();
    return new DatabaseConnection(options);
  },
  inject: [OptionsProvider],
};

@Module({
  providers: [connectionFactory],
  exports: [connectionFactory],
})
export class AppModule {}
```

----
url: https://docs.nestjs.com/v7/graphql/scalars
----

* [Scalars](https://docs.nestjs.com/v7/graphql/scalars#scalars)
* [Code first](https://docs.nestjs.com/v7/graphql/scalars#code-first)
* [Schema first](https://docs.nestjs.com/v7/graphql/scalars#schema-first)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/scalars.md "Suggest Edits")

### Scalars

A GraphQL object type has a name and fields, but at some point those fields have to resolve to some concrete data. That's where the scalar types come in: they represent the leaves of the query (read more [here](https://graphql.org/learn/schema/#scalar-types)). GraphQL includes the following default types: `Int`, `Float`, `String`, `Boolean` and `ID`. In addition to these built-in types, you may need to support custom atomic data types (e.g., `Date`).

#### Code first[#](/graphql/scalars#code-first)

The code-first approach ships with five scalars in which three of them are simple aliases for the existing GraphQL types.

* `ID` (alias for `GraphQLID`) - represents a unique identifier, often used to refetch an object or as the key for a cache
* `Int` (alias for `GraphQLInt`) - a signed 32‐bit integer
* `Float` (alias for `GraphQLFloat`) - a signed double-precision floating-point value
* `GraphQLISODateTime` - a date-time string at UTC (used by default to represent `Date` type)
* `GraphQLTimestamp` - a numeric string which represents time and date as number of milliseconds from start of UNIX epoch

The `GraphQLISODateTime` (e.g. `2019-12-03T09:54:33Z`) is used by default to represent the `Date` type. To use the `GraphQLTimestamp` instead, set the `dateScalarMode` of the `buildSchemaOptions` object to `'timestamp'` as follows:

```typescript

GraphQLModule.forRoot({
  buildSchemaOptions: {
    dateScalarMode: 'timestamp',
  }
}),
```

Likewise, the `GraphQLFloat` is used by default to represent the `number` type. To use the `GraphQLInt` instead, set the `numberScalarMode` of the `buildSchemaOptions` object to `'integer'` as follows:

```typescript

GraphQLModule.forRoot({
  buildSchemaOptions: {
    numberScalarMode: 'integer',
  }
}),
```

In addition, you can create custom scalars. For example, to create a `Date` scalar, simply create a new class.

```typescript

import { Scalar, CustomScalar } from '@nestjs/graphql';
import { Kind, ValueNode } from 'graphql';

@Scalar('Date', (type) => Date)
export class DateScalar implements CustomScalar<number, Date> {
  description = 'Date custom scalar type';

  parseValue(value: number): Date {
    return new Date(value); // value from the client
  }

  serialize(value: Date): number {
    return value.getTime(); // value sent to the client
  }

  parseLiteral(ast: ValueNode): Date {
    if (ast.kind === Kind.INT) {
      return new Date(ast.value);
    }
    return null;
  }
}
```

With this in place, register `DateScalar` as a provider.

```typescript

@Module({
  providers: [DateScalar],
})
export class CommonModule {}
```

Now we can use the `Date` type in our classes.

```typescript

@Field()
creationDate: Date;
```

#### Schema first[#](/graphql/scalars#schema-first)

To define a custom scalar (read more about scalars [here](https://www.apollographql.com/docs/graphql-tools/scalars.html)), create a type definition and a dedicated resolver. Here (as in the official documentation), we’ll use the `graphql-type-json` package for demonstration purposes. This npm package defines a `JSON` GraphQL scalar type.

Start by installing the package:

```bash

$ npm i --save graphql-type-json
```

Once the package is installed, we pass a custom resolver to the `forRoot()` method:

```typescript

import GraphQLJSON from 'graphql-type-json';

@Module({
  imports: [
    GraphQLModule.forRoot({
      typePaths: ['./**/*.graphql'],
      resolvers: { JSON: GraphQLJSON },
    }),
  ],
})
export class ApplicationModule {}
```

Now we can use the `JSON` scalar in our type definitions:

```graphql

scalar JSON

type Foo {
  field: JSON
}
```

Another method to define a scalar type is to create a simple class. Assume we want to enhance our schema with the `Date` type.

```typescript

import { Scalar, CustomScalar } from '@nestjs/graphql';
import { Kind, ValueNode } from 'graphql';

@Scalar('Date')
export class DateScalar implements CustomScalar<number, Date> {
  description = 'Date custom scalar type';

  parseValue(value: number): Date {
    return new Date(value); // value from the client
  }

  serialize(value: Date): number {
    return value.getTime(); // value sent to the client
  }

  parseLiteral(ast: ValueNode): Date {
    if (ast.kind === Kind.INT) {
      return new Date(ast.value);
    }
    return null;
  }
}
```

With this in place, register `DateScalar` as a provider.

```typescript

@Module({
  providers: [DateScalar],
})
export class CommonModule {}
```

Now we can use the `Date` scalar in type definitions.

```graphql

scalar Date
```

By default, the generated TypeScript definition for all scalars is `any` - which isn't particularly typesafe. But, you can configure how Nest generates typings for your custom scalars when you specify how to generate types:

```typescript

import { GraphQLDefinitionsFactory } from '@nestjs/graphql';
import { join } from 'path';

const definitionsFactory = new GraphQLDefinitionsFactory()

definitionsFactory.generate({
  typePaths: ['./src/**/*.graphql'],
  path: join(process.cwd(), 'src/graphql.ts'),
  outputAs: 'class',
  defaultScalarType: 'unknown',
  customScalarTypeMapping: {
    DateTime: 'Date',
    BigNumber: '_BigNumber',
  },
  additionalHeader: "import _BigNumber from 'bignumber.js'",
})
```

> **Hint** Alternatively, you can use a type reference instead, for example: `DateTime: Date`. In this case, `GraphQLDefinitionsFactory` will extract the name property of the specified type (`Date.name`) to generate TS definitions. Note: adding an import statement for non-built-in types (custom types) is required.

Now, given the following GraphQL custom scalar types:

```graphql

scalar DateTime
scalar BigNumber
scalar Payload
```

We will now see the following generated TypeScript definitions in `src/graphql.ts`:

```typescript

import _BigNumber from 'bignumber.js'

export type DateTime = Date
export type BigNumber = _BigNumber
export type Payload = unknown
```

Here, we've used the `customScalarTypeMapping` property to supply a map of the types we wish to declare for our custom scalars. We've also provided an `additionalHeader` property so that we can add any imports required for these type definitions. Lastly, we've added a `defaultScalarType` of `'unknown'`, so that any custom scalars not specified in `customScalarTypeMapping` will be aliased to `unknown` instead of `any` (which [TypeScript recommends](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-0.html#new-unknown-top-type) using since 3.0 for added type safety).

> **Hint** Note that we've imported `_BigNumber` from `bignumber.js`; this is to avoid [circular type references](https://github.com/Microsoft/TypeScript/issues/12525#issuecomment-263166239).

----
url: https://docs.nestjs.com/v4/websockets/interceptors
----

### Interceptors

There's one difference between [regular interceptors](/v4/interceptors) and the websockets **interceptors**. The websockets interceptors takes the `data` passed from the client instead of expressjs request object as an argument of the `intercept()` function.

#### Sponsors

[](https://valor-software.com/)

Nest is an MIT-licensed open source project. It can grow thanks to the support by these awesome people. If you'd like to join them, please read more [here](https://opencollective.com/nest). Thanks!

[](https://opencollective.com/nest/backer/0/website)[](https://opencollective.com/nest/backer/1/website)[](https://opencollective.com/nest/backer/2/website)[](https://opencollective.com/nest/backer/3/website)[](https://opencollective.com/nest/backer/4/website)[](https://opencollective.com/nest/backer/5/website)[](https://opencollective.com/nest/backer/6/website)[](https://opencollective.com/nest/backer/7/website)[](https://opencollective.com/nest/backer/8/website)[](https://opencollective.com/nest/backer/9/website)[](https://opencollective.com/nest/backer/10/website)[](https://opencollective.com/nest/backer/11/website)[](https://opencollective.com/nest/backer/12/website)[](https://opencollective.com/nest/backer/13/website)[](https://opencollective.com/nest/backer/14/website)[](https://opencollective.com/nest/backer/15/website)[](https://opencollective.com/nest/backer/16/website)[](https://opencollective.com/nest/backer/17/website)[](https://opencollective.com/nest/backer/18/website)[](https://opencollective.com/nest/backer/19/website)[](https://opencollective.com/nest/backer/20/website)[](https://opencollective.com/nest/backer/21/website)[](https://opencollective.com/nest/backer/22/website)[](https://opencollective.com/nest/backer/23/website)[](https://opencollective.com/nest/backer/24/website)[](https://opencollective.com/nest/backer/25/website)[](https://opencollective.com/nest/backer/26/website)[](https://opencollective.com/nest/backer/27/website)[](https://opencollective.com/nest/backer/28/website)[](https://opencollective.com/nest/backer/29/website)

[Become a sponsor](https://opencollective.com/nest)

----
url: https://docs.nestjs.com/v4/recipes/sql-typeorm
----

### SQL (TypeORM)

##### This chapter applies only to TypeScript

> **Warning** In this article, you'll learn how to create a `DatabaseModule` based on the **TypeORM** package from scratch using custom components. As a consequence, this solution contains a lot of overhead that you can omit using ready to use and available out-of-the-box dedicated `@nestjs/typeorm` package. To learn more, see [here](/v4/techniques/sql).

[TypeORM](https://github.com/typeorm/typeorm) is definitely the most mature Object Relational Mapper (ORM) available in the node.js world. Since it's written in TypeScript, it works pretty well with the Nest framework. To start the adventure with this library we have to install all of the required dependencies:

TypeScript

```typescript

$ npm install --save typeorm mysql
```

The first step we need to do is to establish the connection with our database using `createConnection()` function imported from the `typeorm` package. The `createConnection()` function returns the `Promise`, so it's necessary to create an [async component](/v4/fundamentals/async-components).

database.providers.ts

TypeScript

```typescript

import { createConnection } from 'typeorm';

export const databaseProviders = [
  {
    provide: 'DbConnectionToken',
    useFactory: async () => await createConnection({
      type: 'mysql',
      host: 'localhost',
      port: 3306,
      username: 'root',
      password: 'root',
      database: 'test',
      entities: [
          __dirname + '/../**/*.entity{.ts,.js}',
      ],
      autoSchemaSync: true,
    }),
  },
];
```

> **Hint** Following best practices, we've declared the custom component in the separated file which has a `*.providers.ts` suffix.

Then we need to export these providers to make them **accessible** for the rest part of the application.

database.module.ts

TypeScript

```typescript

import { Module } from '@nestjs/common';
import { databaseProviders } from './database.providers';

@Module({
  components: [...databaseProviders],
  exports: [...databaseProviders],
})
export class DatabaseModule {}
```

It's everything. Now we can inject the `Connection` object using `@Inject()` decorator. Each component which would depend on the `Connection` async component will wait until the `Promise` would be resolved.

#### Repository pattern

The [TypeORM](https://github.com/typeorm/typeorm) supports the repository design pattern, so each entity has its own Repository. These repositories can be obtained from the database connection.

Firstly, we need at least one entity. We're gonna reuse the `Photo` entity from the offical documentation.

photo/photo.entity.ts

TypeScript

```typescript

import { Entity, Column, PrimaryGeneratedColumn } from 'typeorm';

@Entity()
export class Photo {
  @PrimaryGeneratedColumn()
  id: number;

  @Column({ length: 500 })
  name: string;

  @Column('text')
  description: string;

  @Column()
  filename: string;

  @Column('int')
  views: number;

  @Column()
  isPublished: boolean;
}
```

The `Photo` entity belongs to the `photo` directory. This directory represents the `PhotoModule`. It's your decision where you gonna keep your model files. From my point of view, the best way's to hold them nearly their **domain**, in the appropriate module directory.

Let's create a **Repository** component:

photo.providers.ts

TypeScript

```typescript

import { Connection, Repository } from 'typeorm';
import { Photo } from './photo.entity';

export const photoProviders = [
  {
    provide: 'PhotoRepositoryToken',
    useFactory: (connection: Connection) => connection.getRepository(Photo),
    inject: ['DbConnectionToken'],
  },
];
```

> **Notice** In the real-world applications you should avoid **magic strings** at all. Both `PhotoRepositoryToken` and `DbConnectionToken` should be kept in the separated `constants.ts` file.

Now we can inject the `PhotoRepository` to the `PhotoService` using the `@Inject()` decorator:

photo.service.ts

TypeScript

```typescript

import { Component, Inject } from '@nestjs/common';
import { Repository } from 'typeorm';
import { Photo } from './photo.entity';

@Component()
export class PhotoService {
  constructor(
    @Inject('PhotoRepositoryToken') private readonly photoRepository: Repository<Photo>) {}

  async findAll(): Promise<Photo[]> {
    return await this.photoRepository.find();
  }
}
```

The database connection's **asynchronous**, but Nest makes this process's completely invisible for the end-user. The `PhotoRepository` component's waiting for the db connection, and the `PhotoService` is delayed until repository would be ready to use. The entire application can start when each component is instantiated.

Here's a final `PhotoModule`:

photo.module.ts

TypeScript

```typescript

import { Module } from '@nestjs/common';
import { DatabaseModule } from '../database/database.module';
import { photoProviders } from './photo.providers';
import { PhotoService } from './photo.service';

@Module({
  imports: [DatabaseModule],
  components: [
    ...photoProviders,
    PhotoService,
  ],
})
export class PhotoModule {}
```

> **Hint** Don't forget to import the `PhotoModule` into the root `ApplicationModule`.

#### Sponsors

[](https://valor-software.com/)

Nest is an MIT-licensed open source project. It can grow thanks to the support by these awesome people. If you'd like to join them, please read more [here](https://opencollective.com/nest). Thanks!

[](https://opencollective.com/nest/backer/0/website)[](https://opencollective.com/nest/backer/1/website)[](https://opencollective.com/nest/backer/2/website)[](https://opencollective.com/nest/backer/3/website)[](https://opencollective.com/nest/backer/4/website)[](https://opencollective.com/nest/backer/5/website)[](https://opencollective.com/nest/backer/6/website)[](https://opencollective.com/nest/backer/7/website)[](https://opencollective.com/nest/backer/8/website)[](https://opencollective.com/nest/backer/9/website)[](https://opencollective.com/nest/backer/10/website)[](https://opencollective.com/nest/backer/11/website)[](https://opencollective.com/nest/backer/12/website)[](https://opencollective.com/nest/backer/13/website)[](https://opencollective.com/nest/backer/14/website)[](https://opencollective.com/nest/backer/15/website)[](https://opencollective.com/nest/backer/16/website)[](https://opencollective.com/nest/backer/17/website)[](https://opencollective.com/nest/backer/18/website)[](https://opencollective.com/nest/backer/19/website)[](https://opencollective.com/nest/backer/20/website)[](https://opencollective.com/nest/backer/21/website)[](https://opencollective.com/nest/backer/22/website)[](https://opencollective.com/nest/backer/23/website)[](https://opencollective.com/nest/backer/24/website)[](https://opencollective.com/nest/backer/25/website)[](https://opencollective.com/nest/backer/26/website)[](https://opencollective.com/nest/backer/27/website)[](https://opencollective.com/nest/backer/28/website)[](https://opencollective.com/nest/backer/29/website)

[Become a sponsor](https://opencollective.com/nest)

----
url: https://docs.nestjs.com/v6/techniques/task-scheduling
----

* [Task Scheduling](https://docs.nestjs.com/v6/techniques/task-scheduling#task-scheduling)
* [Installation](https://docs.nestjs.com/v6/techniques/task-scheduling#installation)
* [Declarative cron jobs](https://docs.nestjs.com/v6/techniques/task-scheduling#declarative-cron-jobs)
* [Declarative intervals](https://docs.nestjs.com/v6/techniques/task-scheduling#declarative-intervals)
* [Declarative timeouts](https://docs.nestjs.com/v6/techniques/task-scheduling#declarative-timeouts)
* [Dynamic schedule module API](https://docs.nestjs.com/v6/techniques/task-scheduling#dynamic-schedule-module-api)
* [Dynamic cron jobs](https://docs.nestjs.com/v6/techniques/task-scheduling#dynamic-cron-jobs)
* [Dynamic intervals](https://docs.nestjs.com/v6/techniques/task-scheduling#dynamic-intervals)
* [Dynamic timeouts](https://docs.nestjs.com/v6/techniques/task-scheduling#dynamic-timeouts)
* [Example](https://docs.nestjs.com/v6/techniques/task-scheduling#example)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/techniques/task-scheduling.md "Suggest Edits")

### Task Scheduling

Task scheduling allows you to schedule arbitrary code (methods/functions) to execute at a fixed date/time, at recurring intervals, or once after a specified interval. In the Linux world, this is often handled by packages like [cron](https://en.wikipedia.org/wiki/Cron) at the OS level. For Node.js apps, there are several packages that emulate cron-like functionality. Nest provides the `@nestjs/schedule` package, which integrates with the popular Node.js [node-cron](https://github.com/kelektiv/node-cron) package. We'll cover this package in the current chapter.

#### Installation[#](/techniques/task-scheduling#installation)

To begin using it, we first install the required dependencies.

```bash

$ npm install --save @nestjs/schedule
```

To activate job scheduling, import the `ScheduleModule` into the root `AppModule` and run the `forRoot()` static method as shown below:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { ScheduleModule } from '@nestjs/schedule';

@Module({
  imports: [
    ScheduleModule.forRoot()
  ],
})
export class AppModule {}
```

The `.forRoot()` call initializes the scheduler and registers any declarative [cron jobs](techniques/task-scheduling#declarative-cron-jobs), [timeouts](techniques/task-scheduling#declarative-timeouts) and [intervals](techniques/task-scheduling#declarative-intervals) that exist within your app. Registration occurs when the `onApplicationBootstrap` lifecycle hook occurs, ensuring that all modules have loaded and declared any scheduled jobs.

#### Declarative cron jobs[#](/techniques/task-scheduling#declarative-cron-jobs)

A cron job schedules an arbitrary function (method call) to run automatically. Cron jobs can run:

* Once, at a specified date/time.
* On a recurring basis; recurring jobs can run at a specified instant within a specified interval (for example, once per hour, once per week, once every 5 minutes)

Declare a cron job with the `@Cron()` decorator preceding the method definition containing the code to be executed, as follows:

```typescript

import { Injectable, Logger } from '@nestjs/common';
import { Cron } from '@nestjs/schedule';

@Injectable()
export class TasksService {
  private readonly logger = new Logger(TasksService.name);

  @Cron('45 * * * * *')
  handleCron() {
    this.logger.debug('Called when the current second is 45');
  }
}
```

In this example, the `handleCron()` method will be called each time the current second is `45`. In other words, the method will be run once per minute, at the 45 second mark.

The `@Cron()` decorator supports all standard [cron patterns](http://crontab.org/):

* Asterisk (e.g. `*`)
* Ranges (e.g. `1-3,5`)
* Steps (e.g. `*/2`)

In the example above, we passed `45 * * * * *` to the decorator. The following key shows how each position in the cron pattern string is interpreted:

```javascript

* * * * * *
| | | | | |
| | | | | day of week
| | | | month
| | | day of month
| | hour
| minute
second (optional)
```

Some sample cron patterns are:

|                     |                                             |
| ------------------- | ------------------------------------------- |
| `* * * * * *`       | every second                                |
| `45 * * * * *`      | every minute, on the 45th second            |
| `* 10 * * * *`      | every hour, at the start of the 10th minute |
| `0 */30 9-17 * * *` | every 30 minutes between 9am and 5pm        |
| `0 30 11 * * 1-5`   | Monday to Friday at 11:30am                 |

The `@nestjs/schedule` package provides a convenience enum with commonly used cron patterns. You can use this enum as follows:

```typescript

import { Injectable, Logger } from '@nestjs/common';
import { Cron, CronExpression } from '@nestjs/schedule';

@Injectable()
export class TasksService {
  private readonly logger = new Logger(TasksService.name);

  @Cron(CronExpression.EVERY_45_SECONDS)
  handleCron() {
    this.logger.debug('Called every 45 seconds');
  }
}
```

In this example, the `handleCron()` method will be called every `45` seconds.

Alternatively, you can supply a JavaScript `Date` object to the `@Cron()` decorator. Doing so causes the job to execute exactly once, at the specified date.

> **Hint** Use JavaScript date arithmetic to schedule jobs relative to the current date. For example, `@Cron(new Date(Date.now() + 10 * 1000))` to schedule a job to run 10 seconds after the app starts.

You can access and control a cron job after it's been declared, or dynamically create a cron job (where its cron pattern is defined at runtime) with the [Dynamic API](/techniques/task-scheduling#dynamic-schedule-module-api). To access a declarative cron job via the API, you must associate the job with a name by passing the `name` property in an optional options object as the second argument of the decorator, as shown below:

```typescript

@Cron('* * 8 * * *', {
  name: 'notifications',
})
triggerNotifications() {}
```

#### Declarative intervals[#](/techniques/task-scheduling#declarative-intervals)

To declare that a method should run at a (recurring) specified interval, prefix the method definition with the `@Interval()` decorator. Pass the interval value, as a number in milliseconds, to the decorator as shown below:

```typescript

@Interval(10000)
handleInterval() {
  this.logger.debug('Called every 10 seconds');
}
```

> **Hint** This mechanism uses the JavaScript `setInterval()` function under the hood. You can also utilize a cron job to schedule recurring jobs.

If you want to control your declarative interval from outside the declaring class via the [Dynamic API](/techniques/task-scheduling#dynamic-schedule-module-api), associate the interval with a name using the following construction:

```typescript

@Interval('notifications', 2500)
handleInterval() {}
```

The [Dynamic API](techniques/task-scheduling#dynamic-intervals) also enables **creating** dynamic intervals, where the interval's properties are defined at runtime, and **listing and deleting** them.

## Official enterprise support

* **Providing technical guidance
* **Performing in-depth code reviews
* **Mentoring team members
* **Advising best practices

[Explore more](https://enterprise.nestjs.com "Enterprise | NestJS - A progressive Node.js framework")

#### Declarative timeouts[#](/techniques/task-scheduling#declarative-timeouts)

To declare that a method should run (once) at a specified timeout, prefix the method definition with the `@Timeout()` decorator. Pass the relative time offset (in milliseconds), from application startup, to the decorator as shown below:

```typescript

@Timeout(5000)
handleTimeout() {
  this.logger.debug('Called once after 5 seconds');
}
```

> **Hint** This mechanism uses the JavaScript `setTimeout()` function under the hood.

If you want to control your declarative timeout from outside the declaring class via the [Dynamic API](/techniques/task-scheduling#dynamic-schedule-module-api), associate the timeout with a name using the following construction:

```typescript

@Timeout('notifications', 2500)
handleTimeout() {}
```

The [Dynamic API](techniques/task-scheduling#dynamic-timeouts) also enables **creating** dynamic timeouts, where the timeout's properties are defined at runtime, and **listing and deleting** them.

#### Dynamic schedule module API[#](/techniques/task-scheduling#dynamic-schedule-module-api)

The `@nestjs/schedule` module provides a dynamic API that enables managing declarative [cron jobs](techniques/task-scheduling#declarative-cron-jobs), [timeouts](techniques/task-scheduling#declarative-timeouts) and [intervals](techniques/task-scheduling#declarative-intervals). The API also enables creating and managing **dynamic** cron jobs, timeouts and intervals, where the properties are defined at runtime.

#### Dynamic cron jobs[#](/techniques/task-scheduling#dynamic-cron-jobs)

Obtain a reference to a `CronJob` instance by name from anywhere in your code using the `SchedulerRegistry` API. First, inject `SchedulerRegistry` using standard constructor injection:

```typescript

constructor(private readonly schedulerRegistry: SchedulerRegistry) {}
```

> **Hint** Import the `SchedulerRegistry` from the `@nestjs/schedule` package.

Then use it in a class as follows. Assume a cron job was created with the following declaration:

```typescript

@Cron('* * 8 * * *', {
  name: 'notifications',
})
triggerNotifications() {}
```

Access this job using the following:

```typescript

const job = this.schedulerRegistry.getCronJob('notifications');

job.stop();
console.log(job.lastDate());
```

The `getCronJob()` method returns the named cron job. The returned `CronJob` object has the following methods:

* `stop()` - stops a job that is scheduled to run.
* `start()` - restarts a job that has been stopped.
* `setTime(time: CronTime)` - stops a job, sets a new time for it, and then starts it
* `lastDate()` - returns a string representation of the last date a job executed
* `nextDates(count: number)` - returns an array (size `count`) of `moment` objects representing upcoming job execution dates.

> **Hint** Use `toDate()` on `moment` objects to render them in human readable form.

**Create** a new cron job dynamically using the `SchedulerRegistry.addCronJob()` method, as follows:

```typescript

addCronJob(name: string, seconds: string) {
  const job = new CronJob(`${seconds} * * * * *`, () => {
    this.logger.warn(`time (${seconds}) for job ${name} to run!`);
  });

  this.scheduler.addCronJob(name, job);
  job.start();

  this.logger.warn(
    `job ${name} added for each minute at ${seconds} seconds!`,
  );
}
```

In this code, we use the `CronJob` object from the `cron` package to create the cron job. The `CronJob` constructor takes a cron pattern (just like the `@Cron()`[decorator](techniques/task-scheduling#declarative-cron-jobs)) as its first argument, and a callback to be executed when the cron timer fires as its second argument. The `SchedulerRegistry.addCronJob()` method takes two arguments: a name for the `CronJob`, and the `CronJob` object itself.

> **Warning** Remember to inject the `SchedulerRegistry` before accessing it. Import `CronJob` from the `cron` package.

**Delete** a named cron job using the `SchedulerRegistry.deleteCronJob()` method, as follows:

```typescript

deleteCron(name: string) {
  this.scheduler.deleteCronJob(name);
  this.logger.warn(`job ${name} deleted!`);
}
```

**List** all cron jobs using the `SchedulerRegistry.getCronJobs()` method as follows:

```typescript

getCrons() {
  const jobs = this.scheduler.getCronJobs();
  jobs.forEach((value, key, map) => {
    let next;
    try {
      next = value.nextDates().toDate();
    } catch (e) {
      next = 'error: next fire date is in the past!';
    }
    this.logger.log(`job: ${key} -> next: ${next}`);
  });
}
```

The `getCronJobs()` method returns a `map`. In this code, we iterate over the map and attempt to access the `nextDates()` method of each `CronJob`. In the `CronJob` API, if a job has already fired and has no future firing dates, it throws an exception.

#### Dynamic intervals[#](/techniques/task-scheduling#dynamic-intervals)

Obtain a reference to an interval with the `SchedulerRegistry.getInterval()` method. As above, inject `SchedulerRegistry` using standard constructor injection:

```typescript

constructor(private readonly schedulerRegistry: SchedulerRegistry) {}
```

And use it as follows:

```typescript

const interval = this.schedulerRegistry.getInterval('notifications');
clearInterval(interval);
```

**Create** a new interval dynamically using the `SchedulerRegistry.addInterval()` method, as follows:

```typescript

addInterval(name: string, seconds: string) {
  const callback = () => {
    this.logger.warn(`Interval ${name} executing at time (${seconds})!`);
  };

  const interval = setInterval(callback, seconds);
  this.scheduler.addInterval(name, interval);
}
```

In this code, we create a standard JavaScript interval, then pass it to the `ScheduleRegistry.addInterval()` method. That method takes two arguments: a name for the interval, and the interval itself.

**Delete** a named interval using the `SchedulerRegistry.deleteInterval()` method, as follows:

```typescript

deleteInterval(name: string) {
  this.scheduler.deleteInterval(name);
  this.logger.warn(`Interval ${name} deleted!`);
}
```

**List** all intervals using the `SchedulerRegistry.getIntervals()` method as follows:

```typescript

getIntervals() {
  const intervals = this.scheduler.getIntervals();
  intervals.forEach(key => this.logger.log(`Interval: ${key}`));
}
```

#### Dynamic timeouts[#](/techniques/task-scheduling#dynamic-timeouts)

Obtain a reference to a timeout with the `SchedulerRegistry.getTimeout()` method. As above, inject `SchedulerRegistry` using standard constructor injection:

```typescript

constructor(private readonly schedulerRegistry: SchedulerRegistry) {}
```

And use it as follows:

```typescript

const timeout = this.schedulerRegistry.getTimeout('notifications');
clearTimeout(timeout);
```

**Create** a new timeout dynamically using the `SchedulerRegistry.addTimeout()` method, as follows:

```typescript

addTimeout(name: string, seconds: string) {
  const callback = () => {
    this.logger.warn(`Timeout ${name} executing after (${seconds})!`);
  });

  const timeout = setTimeout(callback, seconds);
  this.scheduler.addTimeout(name, timeout);
}
```

In this code, we create a standard JavaScript timeout, then pass it to the `ScheduleRegistry.addTimeout()` method. That method takes two arguments: a name for the timeout, and the timeout itself.

**Delete** a named timeout using the `SchedulerRegistry.deleteTimeout()` method, as follows:

```typescript

deleteTimeout(name: string) {
  this.scheduler.deleteTimeout(name);
  this.logger.warn(`Timeout ${name} deleted!`);
}
```

**List** all timeouts using the `SchedulerRegistry.getTimeouts()` method as follows:

```typescript

getTimeouts() {
  const timeouts = this.scheduler.getTimeouts();
  timeouts.forEach(key => this.logger.log(`Timeout: ${key}`));
}
```

#### Example[#](/techniques/task-scheduling#example)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/27-scheduling).

----
url: https://docs.nestjs.com/fundamentals/testing
----

[Skip to content](#content)

On this page

* [Testing](https://docs.nestjs.com/fundamentals/testing#testing)
* [Installation](https://docs.nestjs.com/fundamentals/testing#installation)
* [Unit testing](https://docs.nestjs.com/fundamentals/testing#unit-testing)
* [Testing utilities](https://docs.nestjs.com/fundamentals/testing#testing-utilities)
* [Auto mocking](https://docs.nestjs.com/fundamentals/testing#auto-mocking)
* [End-to-end testing](https://docs.nestjs.com/fundamentals/testing#end-to-end-testing)
* [Overriding globally registered enhancers](https://docs.nestjs.com/fundamentals/testing#overriding-globally-registered-enhancers)
* [Testing request-scoped instances](https://docs.nestjs.com/fundamentals/testing#testing-request-scoped-instances)

### Testing

Automated testing is an essential part of any serious software development effort. Automation makes it easy to repeat individual tests or test suites quickly during development, which helps ensure that releases meet quality and performance goals. It increases coverage, gives developers a faster feedback loop, and ensures that tests run at critical points in the development lifecycle, such as source control check-in, feature integration, and version release.

These tests span a variety of types, including unit tests, end-to-end (e2e) tests, and integration tests. While the benefits are clear, setting them up can be tedious. Nest promotes development best practices, including effective testing, and includes the following features to help developers and teams build and automate tests. Nest:

* automatically scaffolds default unit tests for components and e2e tests for applications
* provides default tooling (such as a test runner that builds an isolated module/application loader)
* provides integration with [Vitest](https://vitest.dev/) and [Supertest](https://github.com/visionmedia/supertest) while remaining agnostic to testing tools
* makes the Nest dependency injection system available in the testing environment, so you can mock components without extra setup

You can use any **testing framework** you like, because Nest doesn't force any specific tooling. Replace the elements you need (such as the test runner), and you still benefit from Nest's ready-made testing facilities.

> **Hint** Newly generated projects use Vitest by default. The testing APIs exposed by Nest don't depend on a specific runner, so the same patterns work with other tools as well.

#### Installation[#](/fundamentals/testing#installation)

To get started, install the required package:

```bash

$ npm i --save-dev @nestjs/testing
```

#### Unit testing[#](/fundamentals/testing#unit-testing)

The following example tests two classes, `CatsController` and `CatsService`, with [Vitest](https://vitest.dev/). Vitest serves as the test runner and also provides assertion functions and test-double utilities for mocking, spying, and stubbing. This basic test instantiates the classes manually and checks that the controller and service fulfill their API contract.

cats.controller.spec.ts

JS TS

```typescript

import { vi } from 'vitest';
import { CatsController } from './cats.controller.js';
import { CatsService } from './cats.service.js';

describe('CatsController', () => {
  let catsController: CatsController;
  let catsService: CatsService;

  beforeEach(() => {
    catsService = new CatsService();
    catsController = new CatsController(catsService);
  });

  describe('findAll', () => {
    it('should return an array of cats', async () => {
      const result = ['test'];
      vi.spyOn(catsService, 'findAll').mockImplementation(() => result);

      expect(await catsController.findAll()).toBe(result);
    });
  });
});
```

```typescript

import { vi } from 'vitest';
import { CatsController } from './cats.controller.js';
import { CatsService } from './cats.service.js';

describe('CatsController', () => {
  let catsController;
  let catsService;

  beforeEach(() => {
    catsService = new CatsService();
    catsController = new CatsController(catsService);
  });

  describe('findAll', () => {
    it('should return an array of cats', async () => {
      const result = ['test'];
      vi.spyOn(catsService, 'findAll').mockImplementation(() => result);

      expect(await catsController.findAll()).toBe(result);
    });
  });
});
```

> **Hint** Keep your test files near the classes they test. Test files should have a `.spec` or `.test` suffix.

Because the sample above is trivial, it doesn't test anything Nest-specific. It doesn't even use dependency injection (it passes an instance of `CatsService` to `catsController` directly). This form of testing, where you manually instantiate the classes being tested, is often called **isolated testing**, because it is independent of the framework. The following sections introduce more advanced capabilities that help you test applications that make more extensive use of Nest features.

#### Testing utilities[#](/fundamentals/testing#testing-utilities)

The `@nestjs/testing` package provides a set of utilities for a more robust testing process. Let's rewrite the previous example using the built-in `Test` class:

cats.controller.spec.ts

JS TS

```typescript

import { vi } from 'vitest';
import { Test } from '@nestjs/testing';
import { CatsController } from './cats.controller.js';
import { CatsService } from './cats.service.js';

describe('CatsController', () => {
  let catsController: CatsController;
  let catsService: CatsService;

  beforeEach(async () => {
    const moduleRef = await Test.createTestingModule({
        controllers: [CatsController],
        providers: [CatsService],
      }).compile();

    catsService = moduleRef.get(CatsService);
    catsController = moduleRef.get(CatsController);
  });

  describe('findAll', () => {
    it('should return an array of cats', async () => {
      const result = ['test'];
      vi.spyOn(catsService, 'findAll').mockImplementation(() => result);

      expect(await catsController.findAll()).toBe(result);
    });
  });
});
```

```typescript

import { vi } from 'vitest';
import { Test } from '@nestjs/testing';
import { CatsController } from './cats.controller.js';
import { CatsService } from './cats.service.js';

describe('CatsController', () => {
  let catsController;
  let catsService;

  beforeEach(async () => {
    const moduleRef = await Test.createTestingModule({
        controllers: [CatsController],
        providers: [CatsService],
      }).compile();

    catsService = moduleRef.get(CatsService);
    catsController = moduleRef.get(CatsController);
  });

  describe('findAll', () => {
    it('should return an array of cats', async () => {
      const result = ['test'];
      vi.spyOn(catsService, 'findAll').mockImplementation(() => result);

      expect(await catsController.findAll()).toBe(result);
    });
  });
});
```

The `Test` class provides an application execution context that essentially mocks the full Nest runtime, but gives you hooks for managing class instances, including mocking and overriding. Its `createTestingModule()` method takes a module metadata object as its argument (the same object you pass to the `@Module()` decorator) and returns a `TestingModuleBuilder` instance, which in turn provides a few methods. For unit tests, the important one is `compile()`. It bootstraps a module with its dependencies (similar to the way an application is bootstrapped in the conventional `main.ts` file using `NestFactory.create()`), and returns a `TestingModule` that is ready for testing.

> **Hint** The `compile()` method is **asynchronous**, so you have to await it. Once the module is compiled, you can retrieve any **static** instance it declares (controllers and providers) using the `get()` method.

`TestingModule` exposes the same instance-resolution API as the [module reference](/fundamentals/module-ref) class, including the ability to dynamically resolve scoped providers (transient or request-scoped). Use the `resolve()` method for this (the `get()` method can only retrieve static instances).

```typescript

const moduleRef = await Test.createTestingModule({
  controllers: [CatsController],
  providers: [CatsService],
}).compile();

catsService = await moduleRef.resolve(CatsService);
```

> **Warning** The `resolve()` method returns a unique instance of the provider from its own **DI container sub-tree**. Each sub-tree has a unique context identifier. If you call this method more than once and compare the instance references, you'll see that they are not equal.

> **Hint** Learn more about its features in the [module reference](/fundamentals/module-ref) chapter.

Instead of using the production version of a provider, you can override it with a [custom provider](/fundamentals/custom-providers) for testing purposes. For example, you can mock a database service instead of connecting to a live database. Overrides are covered in the [end-to-end testing](/fundamentals/testing#end-to-end-testing) section, but they're available for unit tests as well.

## Learn the right way!

* 80+ chapters
* 5+ hours of videos
* Official certificate
* Deep-dive sessions

[Explore official courses](https://courses.nestjs.com "Courses | NestJS - A node.js framework built on top of TypeScript")

#### Auto mocking[#](/fundamentals/testing#auto-mocking)

Nest also lets you define a mock factory to apply to all of your missing dependencies. This is useful when a class has a large number of dependencies and mocking all of them would take a lot of time and setup. To use this feature, chain the `useMocker()` method onto `createTestingModule()`, passing a factory for your dependency mocks. The factory receives an optional token (any token that is valid for a Nest provider) and returns a mock implementation. The example below creates a specific mock for `CatsService` using `vi.fn()`.

```typescript

import { vi } from 'vitest';

describe('CatsController', () => {
  let controller: CatsController;

  beforeEach(async () => {
    const moduleRef = await Test.createTestingModule({
      controllers: [CatsController],
    })
      .useMocker((token) => {
        const results = ['test1', 'test2'];
        if (token === CatsService) {
          return { findAll: vi.fn().mockResolvedValue(results) };
        }
      })
      .compile();

    controller = moduleRef.get(CatsController);
  });
});
```

You can retrieve these mocks from the testing container as you would custom providers, e.g., `moduleRef.get(CatsService)`.

> **Hint** You can also pass a reusable mock factory helper directly to `useMocker()` when you want to share test doubles across suites.

> **Hint**`REQUEST` and `INQUIRER` providers cannot be auto-mocked, because they're already predefined in the context. However, you can *overwrite* them using the custom provider syntax or the `overrideProvider()` method.

#### End-to-end testing[#](/fundamentals/testing#end-to-end-testing)

Unlike unit testing, which focuses on individual modules and classes, end-to-end (e2e) testing covers the interaction of classes and modules at a more aggregate level, closer to the kind of interaction that end users have with the production system. As an application grows, it becomes hard to manually test the end-to-end behavior of each API endpoint. Automated end-to-end tests help ensure that the overall behavior of the system is correct and meets project requirements. E2e tests use a configuration similar to the one covered in **unit testing**. In addition, Nest makes it easy to use the [Supertest](https://github.com/visionmedia/supertest) library to simulate HTTP requests.

cats.e2e-spec.ts

JS TS

```typescript

import request from 'supertest';
import { Test } from '@nestjs/testing';
import { CatsModule } from '../../src/cats/cats.module.js';
import { CatsService } from '../../src/cats/cats.service.js';
import { INestApplication } from '@nestjs/common';

describe('Cats', () => {
  let app: INestApplication;
  let catsService = { findAll: () => ['test'] };

  beforeAll(async () => {
    const moduleRef = await Test.createTestingModule({
      imports: [CatsModule],
    })
      .overrideProvider(CatsService)
      .useValue(catsService)
      .compile();

    app = moduleRef.createNestApplication();
    await app.init();
  });

  it(`/GET cats`, () => {
    return request(app.getHttpServer())
      .get('/cats')
      .expect(200)
      .expect({
        data: catsService.findAll(),
      });
  });

  afterAll(async () => {
    await app.close();
  });
});
```

```typescript

import request from 'supertest';
import { Test } from '@nestjs/testing';
import { CatsModule } from '../../src/cats/cats.module.js';
import { CatsService } from '../../src/cats/cats.service.js';

describe('Cats', () => {
  let app;
  let catsService = { findAll: () => ['test'] };

  beforeAll(async () => {
    const moduleRef = await Test.createTestingModule({
      imports: [CatsModule],
    })
      .overrideProvider(CatsService)
      .useValue(catsService)
      .compile();

    app = moduleRef.createNestApplication();
    await app.init();
  });

  it(`/GET cats`, () => {
    return request(app.getHttpServer())
      .get('/cats')
      .expect(200)
      .expect({
        data: catsService.findAll(),
      });
  });

  afterAll(async () => {
    await app.close();
  });
});
```

> **Hint** If you use [Fastify](/http/performance) as your HTTP adapter, it requires a slightly different configuration and has built-in testing capabilities:
>
> ```ts
>
> let app: NestFastifyApplication;
>
> beforeAll(async () => {
>   app = moduleRef.createNestApplication<NestFastifyApplication>(
>     new FastifyAdapter(),
>   );
>
>   await app.init();
>   await app.getHttpAdapter().getInstance().ready();
> });
>
> it(`/GET cats`, () => {
>   return app
>     .inject({
>       method: 'GET',
>       url: '/cats',
>     })
>     .then((result) => {
>       expect(result.statusCode).toEqual(200);
>       expect(result.payload).toEqual(/* expectedPayload */);
>     });
> });
>
> afterAll(async () => {
>   await app.close();
> });
> ```

This example builds on the concepts described earlier. In addition to the `compile()` method, it uses the `createNestApplication()` method to instantiate a full Nest runtime environment.

One caveat: when your application is compiled with the `compile()` method, `HttpAdapterHost#httpAdapter` is still undefined, because no HTTP adapter or server has been created during the compilation phase. If your test requires the `httpAdapter`, use the `createNestApplication()` method to create the application instance, or refactor your project to avoid this dependency while the dependency graph is initialized.

Let's break down the example.

The test saves a reference to the running app in the `app` variable, so it can use it to simulate HTTP requests.

HTTP requests are simulated with the `request()` function from Supertest. To route these requests to the running Nest app, the test passes `request()` a reference to the HTTP listener that underlies Nest (which, in turn, may be provided by the Express platform). Hence the construction `request(app.getHttpServer())`. The call to `request()` returns a wrapped HTTP server, connected to the Nest app, which exposes methods to simulate an actual HTTP request. For example, `request(...).get('/cats')` initiates a request to the Nest app that is identical to an **actual**`GET /cats` HTTP request coming in over the network.

The example also provides an alternate (test-double) implementation of `CatsService` that returns a hard-coded value the test can check for. Use `overrideProvider()` to provide such an alternate implementation. Similarly, Nest provides the `overrideModule()`, `overrideGuard()`, `overrideInterceptor()`, `overrideFilter()`, and `overridePipe()` methods to override modules, guards, interceptors, filters, and pipes, respectively.

Each of the override methods (except `overrideModule()`) returns an object with three methods that mirror those described for [custom providers](/fundamentals/custom-providers):

* `useClass`: you supply a class that is instantiated to provide the instance that overrides the object (provider, guard, etc.).
* `useValue`: you supply an instance that overrides the object.
* `useFactory`: you supply a function that returns an instance that overrides the object.

`overrideModule()`, on the other hand, returns an object with the `useModule()` method, which you use to supply a module that overrides the original module:

```typescript

const moduleRef = await Test.createTestingModule({
  imports: [AppModule],
})
  .overrideModule(CatsModule)
  .useModule(AlternateCatsModule)
  .compile();
```

Each of these methods, in turn, returns the `TestingModuleBuilder` instance, so you can chain them with other methods in the [fluent style](https://en.wikipedia.org/wiki/Fluent_interface). Call `compile()` at the end of the chain to make Nest instantiate and initialize the module.

You may also want to provide a custom logger when the tests run (for example, on a CI server). Use the `setLogger()` method and pass an object that fulfills the `LoggerService` interface to tell the `TestingModuleBuilder` how to log during tests (by default, only "error" logs are written to the console).

The compiled module has several useful methods, as described in the following table:

|                            |                                                                                                                                                                                                                                                                  |
| -------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `createNestApplication()`  | Creates and returns a Nest application (`INestApplication` instance) based on the given module. Note that you must manually initialize the application using the `init()` method.                                                                                |
| `createNestMicroservice()` | Creates and returns a Nest microservice (`INestMicroservice` instance) based on the given module.                                                                                                                                                                |
| `get()`                    | Retrieves a static instance of a controller or provider (including guards, filters, etc.) available in the application context. Works like the same method of the [module reference](/fundamentals/module-ref) class.                                            |
| `resolve()`                | Retrieves a dynamically created scoped instance (request or transient) of a controller or provider (including guards, filters, etc.) available in the application context. Works like the same method of the [module reference](/fundamentals/module-ref) class. |
| `select()`                 | Navigates through the module's dependency graph; can be used to retrieve a specific instance from the selected module (used along with strict mode (`strict: true`) in the `get()` method).                                                                      |

> **Hint** Keep your e2e test files inside the `test` directory. Test files should have an `.e2e-spec` suffix.

#### Overriding globally registered enhancers[#](/fundamentals/testing#overriding-globally-registered-enhancers)

If you have a globally registered guard (or pipe, interceptor, or filter), you need to take a few more steps to override that enhancer. To recap, the original registration looks like this:

```typescript

providers: [
  {
    provide: APP_GUARD,
    useClass: JwtAuthGuard,
  },
],
```

This registers the guard as a "multi" provider through the `APP_*` token. To be able to replace `JwtAuthGuard` here, the registration needs to use an existing provider in this slot:

```typescript

providers: [
  {
    provide: APP_GUARD,
    useExisting: JwtAuthGuard,
    // ^^^^^^^^ notice the use of 'useExisting' instead of 'useClass'
  },
  JwtAuthGuard,
],
```

> **Hint** Change `useClass` to `useExisting` to reference a registered provider instead of having Nest instantiate it behind the token.

`JwtAuthGuard` is now visible to Nest as a regular provider that can be overridden when creating the `TestingModule`:

```typescript

const moduleRef = await Test.createTestingModule({
  imports: [AppModule],
})
  .overrideProvider(JwtAuthGuard)
  .useClass(MockAuthGuard)
  .compile();
```

All your tests now use `MockAuthGuard` on every request.

#### Testing request-scoped instances[#](/fundamentals/testing#testing-request-scoped-instances)

[Request-scoped](/fundamentals/injection-scopes) providers are created uniquely for each incoming **request**, and the instance is garbage-collected after the request has been processed. This poses a problem, because you can't access a dependency injection sub-tree generated specifically for a tested request.

As shown in the sections above, the `resolve()` method retrieves a dynamically instantiated class. Also, as described in [resolving scoped providers](/fundamentals/module-ref#resolving-scoped-providers), you can pass a unique context identifier to control the lifecycle of a DI container sub-tree. You can combine the two in a testing context.

The strategy is to generate a context identifier beforehand and force Nest to use this particular ID to create a sub-tree for all incoming requests. This way, you can retrieve the instances created for a tested request.

To accomplish this, use `vi.spyOn()` on the `ContextIdFactory`:

```typescript

const contextId = ContextIdFactory.create();
vi
  .spyOn(ContextIdFactory, 'getByRequest')
  .mockImplementation(() => contextId);
```

You can now use the `contextId` to access a single generated DI container sub-tree for any subsequent request.

```typescript

catsService = await moduleRef.resolve(CatsService, contextId);
```

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/fundamentals/unit-testing.md)

----
url: https://docs.nestjs.com/v9/websockets/adapter
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Adapters](https://docs.nestjs.com/v9/websockets/adapter#adapters)
* [Extend socket.io](https://docs.nestjs.com/v9/websockets/adapter#extend-socketio)
* [Ws library](https://docs.nestjs.com/v9/websockets/adapter#ws-library)
* [Advanced (custom adapter)](https://docs.nestjs.com/v9/websockets/adapter#advanced-custom-adapter)
* [Example](https://docs.nestjs.com/v9/websockets/adapter#example)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/websockets/adapter.md "Suggest Edits")

### Adapters

The WebSockets module is platform-agnostic, hence, you can bring your own library (or even a native implementation) by making use of `WebSocketAdapter` interface. This interface forces to implement few methods described in the following table:

|                        |                                                                 |
| ---------------------- | --------------------------------------------------------------- |
| `create`               | Creates a socket instance based on passed arguments             |
| `bindClientConnect`    | Binds the client connection event                               |
| `bindClientDisconnect` | Binds the client disconnection event (optional\*)               |
| `bindMessageHandlers`  | Binds the incoming message to the corresponding message handler |
| `close`                | Terminates a server instance                                    |

#### Extend socket.io[#](/websockets/adapter#extend-socketio)

The [socket.io](https://github.com/socketio/socket.io) package is wrapped in an `IoAdapter` class. What if you would like to enhance the basic functionality of the adapter? For instance, your technical requirements require a capability to broadcast events across multiple load-balanced instances of your web service. For this, you can extend `IoAdapter` and override a single method which responsibility is to instantiate new socket.io servers. But first of all, let's install the required package.

> **Warning** To use socket.io with multiple load-balanced instances you either have to disable polling by setting `transports: ['websocket']` in your clients socket.io configuration or you have to enable cookie based routing in your load balancer. Redis alone is not enough. See [here](https://socket.io/docs/v4/using-multiple-nodes/#enabling-sticky-session) for more information.

```bash

$ npm i --save redis socket.io @socket.io/redis-adapter
```

Once the package is installed, we can create a `RedisIoAdapter` class.

```typescript

import { IoAdapter } from '@nestjs/platform-socket.io';
import { ServerOptions } from 'socket.io';
import { createAdapter } from '@socket.io/redis-adapter';
import { createClient } from 'redis';

export class RedisIoAdapter extends IoAdapter {
  private adapterConstructor: ReturnType<typeof createAdapter>;

  async connectToRedis(): Promise<void> {
    const pubClient = createClient({ url: `redis://localhost:6379` });
    const subClient = pubClient.duplicate();

    await Promise.all([pubClient.connect(), subClient.connect()]);

    this.adapterConstructor = createAdapter(pubClient, subClient);
  }

  createIOServer(port: number, options?: ServerOptions): any {
    const server = super.createIOServer(port, options);
    server.adapter(this.adapterConstructor);
    return server;
  }
}
```

Afterward, simply switch to your newly created Redis adapter.

```typescript

const app = await NestFactory.create(AppModule);
const redisIoAdapter = new RedisIoAdapter(app);
await redisIoAdapter.connectToRedis();

app.useWebSocketAdapter(redisIoAdapter);
```

#### Ws library[#](/websockets/adapter#ws-library)

Another available adapter is a `WsAdapter` which in turn acts like a proxy between the framework and integrate blazing fast and thoroughly tested [ws](https://github.com/websockets/ws) library. This adapter is fully compatible with native browser WebSockets and is far faster than socket.io package. Unluckily, it has significantly fewer functionalities available out-of-the-box. In some cases, you may just don't necessarily need them though.

> **Hint**`ws` library does not support namespaces (communication channels popularised by `socket.io`). However, to somehow mimic this feature, you can mount multiple `ws` servers on different paths (example: `@WebSocketGateway({ path: '/users' })`).

In order to use `ws`, we firstly have to install the required package:

```bash

$ npm i --save @nestjs/platform-ws
```

Once the package is installed, we can switch an adapter:

```typescript

const app = await NestFactory.create(AppModule);
app.useWebSocketAdapter(new WsAdapter(app));
```

> **Hint** The `WsAdapter` is imported from `@nestjs/platform-ws`.

#### Advanced (custom adapter)[#](/websockets/adapter#advanced-custom-adapter)

For demonstration purposes, we are going to integrate the [ws](https://github.com/websockets/ws) library manually. As mentioned, the adapter for this library is already created and is exposed from the `@nestjs/platform-ws` package as a `WsAdapter` class. Here is how the simplified implementation could potentially look like:

ws-adapter.ts

JS TS

```typescript

import * as WebSocket from 'ws';
import { WebSocketAdapter, INestApplicationContext } from '@nestjs/common';
import { MessageMappingProperties } from '@nestjs/websockets';
import { Observable, fromEvent, EMPTY } from 'rxjs';
import { mergeMap, filter } from 'rxjs/operators';

export class WsAdapter implements WebSocketAdapter {
  constructor(private app: INestApplicationContext) {}

  create(port: number, options: any = {}): any {
    return new WebSocket.Server({ port, ...options });
  }

  bindClientConnect(server, callback: Function) {
    server.on('connection', callback);
  }

  bindMessageHandlers(
    client: WebSocket,
    handlers: MessageMappingProperties[],
    process: (data: any) => Observable<any>,
  ) {
    fromEvent(client, 'message')
      .pipe(
        mergeMap(data => this.bindMessageHandler(data, handlers, process)),
        filter(result => result),
      )
      .subscribe(response => client.send(JSON.stringify(response)));
  }

  bindMessageHandler(
    buffer,
    handlers: MessageMappingProperties[],
    process: (data: any) => Observable<any>,
  ): Observable<any> {
    const message = JSON.parse(buffer.data);
    const messageHandler = handlers.find(
      handler => handler.message === message.event,
    );
    if (!messageHandler) {
      return EMPTY;
    }
    return process(messageHandler.callback(message.data));
  }

  close(server) {
    server.close();
  }
}
```

> **Hint** When you want to take advantage of [ws](https://github.com/websockets/ws) library, use built-in `WsAdapter` instead of creating your own one.

Then, we can set up a custom adapter using `useWebSocketAdapter()` method:

main.ts

JS TS

```typescript

const app = await NestFactory.create(AppModule);
app.useWebSocketAdapter(new WsAdapter(app));
```

#### Example[#](/websockets/adapter#example)

A working example that uses `WsAdapter` is available [here](https://github.com/nestjs/nest/tree/master/sample/16-gateways-ws).

----
url: https://docs.nestjs.com/v4/techniques/mongodb
----

### MongoDB

There are 2 ways of dealing with the MongoDB. You can use a [TypeORM](https://github.com/typeorm/typeorm) that provides a MongoDB support or [Mongoose](http://mongoosejs.com) which is the most popular [MongoDB](https://www.mongodb.org/) object modelling tool. If you wanna stay with the **TypeORM** you can follow [these steps](/v4/techniques/sql). Otherwise, we'll use a dedicated `@nestjs/mongoose` package.

Firstly, we need to install all of the required dependencies:

```bash

$ npm install --save @nestjs/mongoose mongoose
```

Once the installation process is completed, we can import the `MongooseModule` into the root `ApplicationModule`.

app.module.ts

JavaScript TypeScript

TypeScript

```typescript

import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';

@Module({
  imports: [MongooseModule.forRoot('mongodb://localhost/nest')],
})
export class ApplicationModule {}
```

The `forRoot()` method accepts the same configuration object as `mongoose.connect()` from the [Mongoose](http://mongoosejs.com) package.

#### Model injection

With Mongoose, everything is derived from a [Schema](http://mongoosejs.com/docs/guide.html). Let's define the `CatSchema`:

cats/schemas/cat.schema.ts

JavaScript TypeScript

TypeScript

```typescript

import * as mongoose from 'mongoose';

export const CatSchema = new mongoose.Schema({
  name: String,
  age: Number,
  breed: String,
});
```

The `CatsSchema` belongs to the `cats` directory. This directory represents the `CatsModule`. It's your decision where you gonna keep your schema files. From my point of view, the best way's to hold them nearly their **domain**, in the appropriate module directory.

Let's have a look at the `CatsModule`:

cats/cats.module.ts

JavaScript TypeScript

TypeScript

```typescript

import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';
import { CatSchema } from './schemas/cat.schema';

@Module({
  imports: [MongooseModule.forFeature([{ name: 'Cat', schema: CatSchema }])],
  controllers: [CatsController],
  components: [CatsService],
})
export class CatsModule {}
```

This module uses `forFeature()` method to define which models shall be registered in the current scope.

Now we can inject the `CatModel` to the `CatsService` using the `@InjectModel()` decorator:

cats/cats.service.ts

JavaScript TypeScript

TypeScript

```typescript

import { Model } from 'mongoose';
import { Component } from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import { Cat } from './interfaces/cat.interface';
import { CreateCatDto } from './dto/create-cat.dto';
import { CatSchema } from './schemas/cat.schema';

@Component()
export class CatsService {
  constructor(@InjectModel(CatSchema) private readonly catModel: Model<Cat>) {}

  async create(createCatDto: CreateCatDto): Promise<Cat> {
    const createdCat = new this.catModel(createCatDto);
    return await createdCat.save();
  }

  async findAll(): Promise<Cat[]> {
    return await this.catModel.find().exec();
  }
}
```

TypeScript

```typescript

import { Model } from 'mongoose';
import { Component, Dependencies } from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import { CatSchema } from './schemas/cat.schema';

@Component()
@Dependencies(InjectModel(CatSchema))
export class CatsService {
  constructor(catModel) {
    this.catModel = catModel;
  }

  async create(createCatDto) {
    const createdCat = new this.catModel(createCatDto);
    return await createdCat.save();
  }

  async findAll() {
    return await this.catModel.find().exec();
  }
}
```

That's all. The full source code's available [here](https://github.com/nestjs/nest/tree/master/examples/14-mongoose-module).

> **Hint** Don't forget to import the `CatsModule` into the root `ApplicationModule`.

#### Sponsors

[](https://valor-software.com/)

Nest is an MIT-licensed open source project. It can grow thanks to the support by these awesome people. If you'd like to join them, please read more [here](https://opencollective.com/nest). Thanks!

[](https://opencollective.com/nest/backer/0/website)[](https://opencollective.com/nest/backer/1/website)[](https://opencollective.com/nest/backer/2/website)[](https://opencollective.com/nest/backer/3/website)[](https://opencollective.com/nest/backer/4/website)[](https://opencollective.com/nest/backer/5/website)[](https://opencollective.com/nest/backer/6/website)[](https://opencollective.com/nest/backer/7/website)[](https://opencollective.com/nest/backer/8/website)[](https://opencollective.com/nest/backer/9/website)[](https://opencollective.com/nest/backer/10/website)[](https://opencollective.com/nest/backer/11/website)[](https://opencollective.com/nest/backer/12/website)[](https://opencollective.com/nest/backer/13/website)[](https://opencollective.com/nest/backer/14/website)[](https://opencollective.com/nest/backer/15/website)[](https://opencollective.com/nest/backer/16/website)[](https://opencollective.com/nest/backer/17/website)[](https://opencollective.com/nest/backer/18/website)[](https://opencollective.com/nest/backer/19/website)[](https://opencollective.com/nest/backer/20/website)[](https://opencollective.com/nest/backer/21/website)[](https://opencollective.com/nest/backer/22/website)[](https://opencollective.com/nest/backer/23/website)[](https://opencollective.com/nest/backer/24/website)[](https://opencollective.com/nest/backer/25/website)[](https://opencollective.com/nest/backer/26/website)[](https://opencollective.com/nest/backer/27/website)[](https://opencollective.com/nest/backer/28/website)[](https://opencollective.com/nest/backer/29/website)

[Become a sponsor](https://opencollective.com/nest)

----
url: https://docs.nestjs.com/v4/advanced/mixins
----

### Mixin Class

##### This chapter applies only to TypeScript

TypeScript 2.2 adds support for the ECMAScript 2015 [mixin class pattern](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-2.html). This pattern's quite useful since it's not easy to pass custom arguments to some Nest application building blocks, such as [interceptors](/v4/interceptors) or [guards](/v4/guards). The **mixin classes** have much more applications, but here we're gonna focus on this single use-case.

For demonstration purposes, let's rewrite the `CacheInterceptor` which we've built in the [interceptors](/v4/interceptors) section and extract the `isCached` condition.

cache.interceptor.ts

TypeScript

```typescript

import { Interceptor, NestInterceptor, ExecutionContext } from '@nestjs/common';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/of';

@Interceptor()
export abstract class CacheInterceptor implements NestInterceptor {
  protected abstract readonly isCached: () => boolean;

  intercept(dataOrRequest, context: ExecutionContext, stream$: Observable<any>): Observable<any> {
    if (this.isCached()) {
      return Observable.of([]);
    }
    return stream$;
  }
}
```

Now the `CacheInterceptor` is abstract and contains the single abstract member - the `isCached` function. Based on this class, we're gonna create the `mixinCacheInterceptor` function.

mixin-cache.interceptor.ts

TypeScript

```typescript

import { mixin } from '@nestjs/common';
import { CacheInterceptor } from './cache.interceptor';

export function mixinCacheInterceptor(isCached: () => boolean) {
  return mixin(class extends CacheInterceptor {
    protected readonly isCached = isCached;
  });
}
```

> **Notice** The `mixin()` is a helper function. Use it whenever you wanna create a mixin class.

This function takes the `isCached()` predicate as an argument and assigns it to the mixin class. The last step is to set up the interceptor:

TypeScript

```typescript

@UseInterceptors(mixinCacheInterceptor(() => true))
async findAll(): Promise<Cat[]> {
  return this.catsService.findAll();
}
```

The `mixin()` function returns the class, so you can use it in the same manner as a plain, self-created classes.

#### Sponsors

[](https://valor-software.com/)

Nest is an MIT-licensed open source project. It can grow thanks to the support by these awesome people. If you'd like to join them, please read more [here](https://opencollective.com/nest). Thanks!

[](https://opencollective.com/nest/backer/0/website)[](https://opencollective.com/nest/backer/1/website)[](https://opencollective.com/nest/backer/2/website)[](https://opencollective.com/nest/backer/3/website)[](https://opencollective.com/nest/backer/4/website)[](https://opencollective.com/nest/backer/5/website)[](https://opencollective.com/nest/backer/6/website)[](https://opencollective.com/nest/backer/7/website)[](https://opencollective.com/nest/backer/8/website)[](https://opencollective.com/nest/backer/9/website)[](https://opencollective.com/nest/backer/10/website)[](https://opencollective.com/nest/backer/11/website)[](https://opencollective.com/nest/backer/12/website)[](https://opencollective.com/nest/backer/13/website)[](https://opencollective.com/nest/backer/14/website)[](https://opencollective.com/nest/backer/15/website)[](https://opencollective.com/nest/backer/16/website)[](https://opencollective.com/nest/backer/17/website)[](https://opencollective.com/nest/backer/18/website)[](https://opencollective.com/nest/backer/19/website)[](https://opencollective.com/nest/backer/20/website)[](https://opencollective.com/nest/backer/21/website)[](https://opencollective.com/nest/backer/22/website)[](https://opencollective.com/nest/backer/23/website)[](https://opencollective.com/nest/backer/24/website)[](https://opencollective.com/nest/backer/25/website)[](https://opencollective.com/nest/backer/26/website)[](https://opencollective.com/nest/backer/27/website)[](https://opencollective.com/nest/backer/28/website)[](https://opencollective.com/nest/backer/29/website)

[Become a sponsor](https://opencollective.com/nest)

----
url: https://docs.nestjs.com/v11/fundamentals/injection-scopes
----

* [Injection scopes](https://docs.nestjs.com/v11/fundamentals/injection-scopes#injection-scopes)
* [Provider scope](https://docs.nestjs.com/v11/fundamentals/injection-scopes#provider-scope)
* [Usage](https://docs.nestjs.com/v11/fundamentals/injection-scopes#usage)
* [Controller scope](https://docs.nestjs.com/v11/fundamentals/injection-scopes#controller-scope)
* [Scope hierarchy](https://docs.nestjs.com/v11/fundamentals/injection-scopes#scope-hierarchy)
* [Request provider](https://docs.nestjs.com/v11/fundamentals/injection-scopes#request-provider)
* [Inquirer provider](https://docs.nestjs.com/v11/fundamentals/injection-scopes#inquirer-provider)
* [Performance](https://docs.nestjs.com/v11/fundamentals/injection-scopes#performance)
* [Durable providers](https://docs.nestjs.com/v11/fundamentals/injection-scopes#durable-providers)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/fundamentals/provider-scopes.md "Suggest Edits")

### Injection scopes

For people coming from different programming language backgrounds, it might be unexpected to learn that in Nest, almost everything is shared across incoming requests. We have a connection pool to the database, singleton services with global state, etc. Remember that Node.js doesn't follow the request/response Multi-Threaded Stateless Model in which every request is processed by a separate thread. Hence, using singleton instances is fully **safe** for our applications.

However, there are edge cases when request-based lifetime may be the desired behavior, for instance, per-request caching in GraphQL applications, request tracking, and multi-tenancy. Injection scopes provide a mechanism to obtain the desired provider lifetime behavior.

#### Provider scope[#](/fundamentals/injection-scopes#provider-scope)

A provider can have any of the following scopes:

|             |                                                                                                                                                                                                                                                                            |
| ----------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `DEFAULT`   | A single instance of the provider is shared across the entire application. The instance lifetime is tied directly to the application lifecycle. Once the application has bootstrapped, all singleton providers have been instantiated. Singleton scope is used by default. |
| `REQUEST`   | A new instance of the provider is created exclusively for each incoming **request**. The instance is garbage-collected after the request has completed processing.                                                                                                         |
| `TRANSIENT` | Transient providers are not shared across consumers. Each consumer that injects a transient provider will receive a new, dedicated instance.                                                                                                                               |

> **Hint** Using singleton scope is **recommended** for most use cases. Sharing providers across consumers and across requests means that an instance can be cached and its initialization occurs only once, during application startup.

#### Usage[#](/fundamentals/injection-scopes#usage)

Specify injection scope by passing the `scope` property to the `@Injectable()` decorator options object:

```typescript

import { Injectable, Scope } from '@nestjs/common';

@Injectable({ scope: Scope.REQUEST })
export class CatsService {}
```

Similarly, for [custom providers](/v11/fundamentals/custom-providers), set the `scope` property in the long-hand form for a provider registration:

```typescript

{
  provide: 'CACHE_MANAGER',
  useClass: CacheManager,
  scope: Scope.TRANSIENT,
}
```

> **Hint** Import the `Scope` enum from `@nestjs/common`

Singleton scope is used by default and does not need be declared. If you do want to declare a provider as singleton scoped, use the `Scope.DEFAULT` value for the `scope` property.

> **Notice** Websocket Gateways should not use request-scoped providers because they must act as singletons. Each gateway encapsulates a real socket and cannot be instantiated multiple times. The limitation also applies to some other providers, like [*Passport strategies*](../security/authentication#request-scoped-strategies) or *Cron controllers*.

#### Controller scope[#](/fundamentals/injection-scopes#controller-scope)

Controllers can also have scope, which applies to all request method handlers declared in that controller. Like provider scope, the scope of a controller declares its lifetime. For a request-scoped controller, a new instance is created for each inbound request, and garbage-collected when the request has completed processing.

Declare controller scope with the `scope` property of the `ControllerOptions` object:

```typescript

@Controller({
  path: 'cats',
  scope: Scope.REQUEST,
})
export class CatsController {}
```

```typescript

import { Injectable, Scope, Inject } from '@nestjs/common';
import { REQUEST } from '@nestjs/core';
import { Request } from 'express';

@Injectable({ scope: Scope.REQUEST })
export class CatsService {
  constructor(@Inject(REQUEST) private request: Request) {}
}
```

Because of underlying platform/protocol differences, you access the inbound request slightly differently for Microservice or GraphQL applications. In [GraphQL](/v11/graphql/quick-start) applications, you inject `CONTEXT` instead of `REQUEST`:

```typescript

import { Injectable, Scope, Inject } from '@nestjs/common';
import { CONTEXT } from '@nestjs/graphql';

@Injectable({ scope: Scope.REQUEST })
export class CatsService {
  constructor(@Inject(CONTEXT) private context) {}
}
```

You then configure your `context` value (in the `GraphQLModule`) to contain `request` as its property.

#### Inquirer provider[#](/fundamentals/injection-scopes#inquirer-provider)

If you want to get the class where a provider was constructed, for instance in logging or metrics providers, you can inject the `INQUIRER` token.

```typescript

import { Inject, Injectable, Scope } from '@nestjs/common';
import { INQUIRER } from '@nestjs/core';

@Injectable({ scope: Scope.TRANSIENT })
export class HelloService {
  constructor(@Inject(INQUIRER) private parentClass: object) {}

  sayHello(message: string) {
    console.log(`${this.parentClass?.constructor?.name}: ${message}`);
  }
}
```

And then use it as follows:

```typescript

import { Injectable } from '@nestjs/common';
import { HelloService } from './hello.service';

@Injectable()
export class AppService {
  constructor(private helloService: HelloService) {}

  getRoot(): string {
    this.helloService.sayHello('My name is getRoot');

    return 'Hello world!';
  }
}
```

In the example above when `AppService#getRoot` is called, `"AppService: My name is getRoot"` will be logged to the console.

#### Performance[#](/fundamentals/injection-scopes#performance)

Using request-scoped providers will have an impact on application performance. While Nest tries to cache as much metadata as possible, it will still have to create an instance of your class on each request. Hence, it will slow down your average response time and overall benchmarking result. Unless a provider must be request-scoped, it is strongly recommended that you use the default singleton scope.

> **Hint** Although it all sounds quite intimidating, a properly designed application that leverages request-scoped providers should not slow down by more than \~5% latency-wise.

```typescript

import {
  HostComponentInfo,
  ContextId,
  ContextIdFactory,
  ContextIdStrategy,
} from '@nestjs/core';
import { Request } from 'express';

const tenants = new Map<string, ContextId>();

export class AggregateByTenantContextIdStrategy implements ContextIdStrategy {
  attach(contextId: ContextId, request: Request) {
    const tenantId = request.headers['x-tenant-id'] as string;
    let tenantSubTreeId: ContextId;

    if (tenants.has(tenantId)) {
      tenantSubTreeId = tenants.get(tenantId);
    } else {
      tenantSubTreeId = ContextIdFactory.create();
      tenants.set(tenantId, tenantSubTreeId);
    }

    // If tree is not durable, return the original "contextId" object
    return (info: HostComponentInfo) =>
      info.isTreeDurable ? tenantSubTreeId : contextId;
  }
}
```

> **Hint** Similar to the request scope, durability bubbles up the injection chain. That means if A depends on B which is flagged as `durable`, A implicitly becomes durable too (unless `durable` is explicitly set to `false` for A provider).

> **Warning** Note this strategy is not ideal for applications operating with a large number of tenants.

The value returned from the `attach` method instructs Nest what context identifier should be used for a given host. In this case, we specified that the `tenantSubTreeId` should be used instead of the original, auto-generated `contextId` object, when the host component (e.g., request-scoped controller) is flagged as durable (you can learn how to mark providers as durable below). Also, in the above example, **no payload** would be registered (where payload = `REQUEST`/`CONTEXT` provider that represents the "root" - parent of the sub-tree).

If you want to register the payload for a durable tree, use the following construction instead:

```typescript

// The return of `AggregateByTenantContextIdStrategy#attach` method:
return {
  resolve: (info: HostComponentInfo) =>
    info.isTreeDurable ? tenantSubTreeId : contextId,
  payload: { tenantId },
};
```

Now whenever you inject the `REQUEST` provider (or `CONTEXT` for GraphQL applications) using the `@Inject(REQUEST)`/`@Inject(CONTEXT)`, the `payload` object would be injected (consisting of a single property - `tenantId` in this case).

Alright so with this strategy in place, you can register it somewhere in your code (as it applies globally anyway), so for example, you could place it in the `main.ts` file:

```typescript

ContextIdFactory.apply(new AggregateByTenantContextIdStrategy());
```

> **Hint** The `ContextIdFactory` class is imported from the `@nestjs/core` package.

As long as the registration occurs before any request hits your application, everything will work as intended.

Lastly, to turn a regular provider into a durable provider, simply set the `durable` flag to `true` and change its scope to `Scope.REQUEST` (not needed if the REQUEST scope is in the injection chain already):

```typescript

import { Injectable, Scope } from '@nestjs/common';

@Injectable({ scope: Scope.REQUEST, durable: true })
export class CatsService {}
```

Similarly, for [custom providers](/v11/fundamentals/custom-providers), set the `durable` property in the long-hand form for a provider registration:

```typescript

{
  provide: 'foobar',
  useFactory: () => { ... },
  scope: Scope.REQUEST,
  durable: true,
}
```

----
url: https://docs.nestjs.com/v10/techniques/caching
----

* [Caching](https://docs.nestjs.com/v10/techniques/caching#caching)
* [Installation](https://docs.nestjs.com/v10/techniques/caching#installation)
* [In-memory cache](https://docs.nestjs.com/v10/techniques/caching#in-memory-cache)
* [Interacting with the Cache store](https://docs.nestjs.com/v10/techniques/caching#interacting-with-the-cache-store)
* [Auto-caching responses](https://docs.nestjs.com/v10/techniques/caching#auto-caching-responses)
* [Customize caching](https://docs.nestjs.com/v10/techniques/caching#customize-caching)
* [Use module globally](https://docs.nestjs.com/v10/techniques/caching#use-module-globally)
* [Global cache overrides](https://docs.nestjs.com/v10/techniques/caching#global-cache-overrides)
* [WebSockets and Microservices](https://docs.nestjs.com/v10/techniques/caching#websockets-and-microservices)
* [Adjust tracking](https://docs.nestjs.com/v10/techniques/caching#adjust-tracking)
* [Different stores](https://docs.nestjs.com/v10/techniques/caching#different-stores)
* [Async configuration](https://docs.nestjs.com/v10/techniques/caching#async-configuration)
* [Example](https://docs.nestjs.com/v10/techniques/caching#example)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/techniques/caching.md "Suggest Edits")

### Caching

Caching is a great and simple **technique** that helps improve your app's performance. It acts as a temporary data store providing high performance data access.

#### Installation[#](/techniques/caching#installation)

First install required packages:

```bash

$ npm install @nestjs/cache-manager cache-manager
```

> **Warning**`cache-manager` version 4 uses seconds for `TTL (Time-To-Live)`. The current version of `cache-manager` (v5) has switched to using milliseconds instead. NestJS doesn't convert the value, and simply forwards the ttl you provide to the library. In other words:
>
> * If using `cache-manager` v4, provide ttl in seconds
> * If using `cache-manager` v5, provide ttl in milliseconds
> * Documentation is referring to seconds, since NestJS was released targeting version 4 of cache-manager.

#### In-memory cache[#](/techniques/caching#in-memory-cache)

Nest provides a unified API for various cache storage providers. The built-in one is an in-memory data store. However, you can easily switch to a more comprehensive solution, like Redis.

In order to enable caching, import the `CacheModule` and call its `register()` method.

```typescript

import { Module } from '@nestjs/common';
import { CacheModule } from '@nestjs/cache-manager';
import { AppController } from './app.controller';

@Module({
  imports: [CacheModule.register()],
  controllers: [AppController],
})
export class AppModule {}
```

#### Interacting with the Cache store[#](/techniques/caching#interacting-with-the-cache-store)

To interact with the cache manager instance, inject it to your class using the `CACHE_MANAGER` token, as follows:

```typescript

constructor(@Inject(CACHE_MANAGER) private cacheManager: Cache) {}
```

> **Hint** The `Cache` class is imported from the `cache-manager`, while `CACHE_MANAGER` token from the `@nestjs/cache-manager` package.

The `get` method on the `Cache` instance (from the `cache-manager` package) is used to retrieve items from the cache. If the item does not exist in the cache, `null` will be returned.

```typescript

const value = await this.cacheManager.get('key');
```

To add an item to the cache, use the `set` method:

```typescript

await this.cacheManager.set('key', 'value');
```

> **Note** The in-memory cache storage can only store values of types that are supported by [the structured clone algorithm](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm#javascript_types).

The default expiration time of the cache is 5 seconds.

You can manually specify a TTL (expiration time in seconds) for this specific key, as follows:

```typescript

await this.cacheManager.set('key', 'value', 1000);
```

To disable expiration of the cache, set the `ttl` configuration property to `0`:

```typescript

await this.cacheManager.set('key', 'value', 0);
```

To remove an item from the cache, use the `del` method:

```typescript

await this.cacheManager.del('key');
```

To clear the entire cache, use the `reset` method:

```typescript

await this.cacheManager.reset();
```

#### Auto-caching responses[#](/techniques/caching#auto-caching-responses)

> **Warning** In [GraphQL](/v10/graphql/quick-start) applications, interceptors are executed separately for each field resolver. Thus, `CacheModule` (which uses interceptors to cache responses) will not work properly.

To enable auto-caching responses, just tie the `CacheInterceptor` where you want to cache data.

```typescript

@Controller()
@UseInterceptors(CacheInterceptor)
export class AppController {
  @Get()
  findAll(): string[] {
    return [];
  }
}
```

> **Warning** Only `GET` endpoints are cached. Also, HTTP server routes that inject the native response object (`@Res()`) cannot use the Cache Interceptor. See [response mapping](https://docs.nestjs.com/interceptors#response-mapping) for more details.

To reduce the amount of required boilerplate, you can bind `CacheInterceptor` to all endpoints globally:

```typescript

import { Module } from '@nestjs/common';
import { CacheModule, CacheInterceptor } from '@nestjs/cache-manager';
import { AppController } from './app.controller';
import { APP_INTERCEPTOR } from '@nestjs/core';

@Module({
  imports: [CacheModule.register()],
  controllers: [AppController],
  providers: [
    {
      provide: APP_INTERCEPTOR,
      useClass: CacheInterceptor,
    },
  ],
})
export class AppModule {}
```

#### Customize caching[#](/techniques/caching#customize-caching)

All cached data has its own expiration time ([TTL](https://en.wikipedia.org/wiki/Time_to_live)). To customize default values, pass the options object to the `register()` method.

```typescript

CacheModule.register({
  ttl: 5, // seconds
  max: 10, // maximum number of items in cache
});
```

#### Use module globally[#](/techniques/caching#use-module-globally)

When you want to use `CacheModule` in other modules, you'll need to import it (as is standard with any Nest module). Alternatively, declare it as a [global module](https://docs.nestjs.com/modules#global-modules) by setting the options object's `isGlobal` property to `true`, as shown below. In that case, you will not need to import `CacheModule` in other modules once it's been loaded in the root module (e.g., `AppModule`).

```typescript

CacheModule.register({
  isGlobal: true,
});
```

#### Global cache overrides[#](/techniques/caching#global-cache-overrides)

While global cache is enabled, cache entries are stored under a `CacheKey` that is auto-generated based on the route path. You may override certain cache settings (`@CacheKey()` and `@CacheTTL()`) on a per-method basis, allowing customized caching strategies for individual controller methods. This may be most relevant while using [different cache stores.](https://docs.nestjs.com/techniques/caching#different-stores)

You can apply the `@CacheTTL()` decorator on a per-controller basis to set a caching TTL for the entire controller. In situations where both controller-level and method-level cache TTL settings are defined, the cache TTL settings specified at the method level will take priority over the ones set at the controller level.

```typescript

@Controller()
@CacheTTL(50)
export class AppController {
  @CacheKey('custom_key')
  @CacheTTL(20)
  findAll(): string[] {
    return [];
  }
}
```

> **Hint** The `@CacheKey()` and `@CacheTTL()` decorators are imported from the `@nestjs/cache-manager` package.

The `@CacheKey()` decorator may be used with or without a corresponding `@CacheTTL()` decorator and vice versa. One may choose to override only the `@CacheKey()` or only the `@CacheTTL()`. Settings that are not overridden with a decorator will use the default values as registered globally (see [Customize caching](https://docs.nestjs.com/techniques/caching#customize-caching)).

#### WebSockets and Microservices[#](/techniques/caching#websockets-and-microservices)

You can also apply the `CacheInterceptor` to WebSocket subscribers as well as Microservice's patterns (regardless of the transport method that is being used).

JS TS

```typescript

@CacheKey('events')
@UseInterceptors(CacheInterceptor)
@SubscribeMessage('events')
handleEvent(client: Client, data: string[]): Observable<string[]> {
  return [];
}
```

```typescript

@CacheKey('events')
@UseInterceptors(CacheInterceptor)
@SubscribeMessage('events')
handleEvent(client, data) {
  return [];
}
```

However, the additional `@CacheKey()` decorator is required in order to specify a key used to subsequently store and retrieve cached data. Also, please note that you **shouldn't cache everything**. Actions which perform some business operations rather than simply querying the data should never be cached.

Additionally, you may specify a cache expiration time (TTL) by using the `@CacheTTL()` decorator, which will override the global default TTL value.

JS TS

```typescript

@CacheTTL(10)
@UseInterceptors(CacheInterceptor)
@SubscribeMessage('events')
handleEvent(client: Client, data: string[]): Observable<string[]> {
  return [];
}
```

```typescript

@CacheTTL(10)
@UseInterceptors(CacheInterceptor)
@SubscribeMessage('events')
handleEvent(client, data) {
  return [];
}
```

> **Hint** The `@CacheTTL()` decorator may be used with or without a corresponding `@CacheKey()` decorator.

#### Adjust tracking[#](/techniques/caching#adjust-tracking)

By default, Nest uses the request URL (in an HTTP app) or cache key (in websockets and microservices apps, set through the `@CacheKey()` decorator) to associate cache records with your endpoints. Nevertheless, sometimes you might want to set up tracking based on different factors, for example, using HTTP headers (e.g. `Authorization` to properly identify `profile` endpoints).

In order to accomplish that, create a subclass of `CacheInterceptor` and override the `trackBy()` method.

```typescript

@Injectable()
class HttpCacheInterceptor extends CacheInterceptor {
  trackBy(context: ExecutionContext): string | undefined {
    return 'key';
  }
}
```

#### Different stores[#](/techniques/caching#different-stores)

The `cache-manager` package offers a variety of useful storage options, including the [Redis store](https://www.npmjs.com/package/cache-manager-redis-yet), which is the official package for integrating Redis with cache-manager. You can find a comprehensive list of supported stores [here](https://github.com/jaredwray/cacheable/blob/main/packages/cache-manager/READMEv5.md#store-engines). To configure the Redis store, use the `registerAsync()` method to initialize it, as shown below:

```typescript

import { redisStore } from 'cache-manager-redis-yet';
import { Module } from '@nestjs/common';
import { CacheModule, CacheStore } from '@nestjs/cache-manager';
import { AppController } from './app.controller';

@Module({
  imports: [
    CacheModule.registerAsync({
      useFactory: async () => {
        const store = await redisStore({
          socket: {
            host: 'localhost',
            port: 6379,
          },
        });

        return {
          store: store as unknown as CacheStore,
          ttl: 3 * 60000, // 3 minutes (milliseconds)
        };
      },
    }),
  ],
  controllers: [AppController],
})
export class AppModule {}
```

> **Warning** The `cache-manager-redis-yet` package requires the `ttl` (time-to-live) setting to be specified directly rather than as part of the module options.

#### Async configuration[#](/techniques/caching#async-configuration)

You may want to asynchronously pass in module options instead of passing them statically at compile time. In this case, use the `registerAsync()` method, which provides several ways to deal with async configuration.

One approach is to use a factory function:

```typescript

CacheModule.registerAsync({
  useFactory: () => ({
    ttl: 5,
  }),
});
```

Our factory behaves like all other asynchronous module factories (it can be `async` and is able to inject dependencies through `inject`).

```typescript

CacheModule.registerAsync({
  imports: [ConfigModule],
  useFactory: async (configService: ConfigService) => ({
    ttl: configService.get('CACHE_TTL'),
  }),
  inject: [ConfigService],
});
```

Alternatively, you can use the `useClass` method:

```typescript

CacheModule.registerAsync({
  useClass: CacheConfigService,
});
```

The above construction will instantiate `CacheConfigService` inside `CacheModule` and will use it to get the options object. The `CacheConfigService` has to implement the `CacheOptionsFactory` interface in order to provide the configuration options:

```typescript

@Injectable()
class CacheConfigService implements CacheOptionsFactory {
  createCacheOptions(): CacheModuleOptions {
    return {
      ttl: 5,
    };
  }
}
```

If you wish to use an existing configuration provider imported from a different module, use the `useExisting` syntax:

```typescript

CacheModule.registerAsync({
  imports: [ConfigModule],
  useExisting: ConfigService,
});
```

This works the same as `useClass` with one critical difference - `CacheModule` will lookup imported modules to reuse any already-created `ConfigService`, instead of instantiating its own.

> **Hint**`CacheModule#register` and `CacheModule#registerAsync` and `CacheOptionsFactory` has an optional generic (type argument) to narrow down store-specific configuration options, making it type safe.

You can also pass so-called `extraProviders` to the `registerAsync()` method. These providers will be merged with the module providers.

```typescript

CacheModule.registerAsync({
  imports: [ConfigModule],
  useClass: ConfigService,
  extraProviders: [MyAdditionalProvider],
});
```

This is useful when you want to provide additional dependencies to the factory function or the class constructor.

#### Example[#](/techniques/caching#example)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/20-cache).

----
url: https://docs.nestjs.com/v10/recipes/crud-generator
----

* [CRUD generator (TypeScript only)](https://docs.nestjs.com/v10/recipes/crud-generator#crud-generator-typescript-only)
* [Introduction](https://docs.nestjs.com/v10/recipes/crud-generator#introduction)
* [Generating a new resource](https://docs.nestjs.com/v10/recipes/crud-generator#generating-a-new-resource)

To help speed up this repetitive process, [Nest CLI](/v10/cli/overview) provides a generator (schematic) that automatically generates all the boilerplate code to help us avoid doing all of this, and make the developer experience much simpler.

> **Note** The schematic supports generating **HTTP** controllers, **Microservice** controllers, **GraphQL** resolvers (both code first and schema first), and **WebSocket** Gateways.

#### Generating a new resource[#](/recipes/crud-generator#generating-a-new-resource)

To create a new resource, simply run the following command in the root directory of your project:

```shell

$ nest g resource
```

`nest g resource` command not only generates all the NestJS building blocks (module, service, controller classes) but also an entity class, DTO classes as well as the testing (`.spec`) files.

Below you can see the generated controller file (for REST API):

```typescript

@Controller('users')
export class UsersController {
  constructor(private readonly usersService: UsersService) {}

  @Post()
  create(@Body() createUserDto: CreateUserDto) {
    return this.usersService.create(createUserDto);
  }

  @Get()
  findAll() {
    return this.usersService.findAll();
  }

  @Get(':id')
  findOne(@Param('id') id: string) {
    return this.usersService.findOne(+id);
  }

  @Patch(':id')
  update(@Param('id') id: string, @Body() updateUserDto: UpdateUserDto) {
    return this.usersService.update(+id, updateUserDto);
  }

  @Delete(':id')
  remove(@Param('id') id: string) {
    return this.usersService.remove(+id);
  }
}
```

Also, it automatically creates placeholders for all the CRUD endpoints (routes for REST APIs, queries and mutations for GraphQL, message subscribes for both Microservices and WebSocket Gateways) - all without having to lift a finger.

> **Note** Generated service classes are **not** tied to any specific **ORM (or data source)**. This makes the generator generic enough to meet the needs of any project. By default, all methods will contain placeholders, allowing you to populate it with the data sources specific to your project.

Likewise, if you want to generate resolvers for a GraphQL application, simply select the `GraphQL (code first)` (or `GraphQL (schema first)`) as your transport layer.

In this case, NestJS will generate a resolver class instead of a REST API controller:

```shell

$ nest g resource users

> ? What transport layer do you use? GraphQL (code first)
> ? Would you like to generate CRUD entry points? Yes
> CREATE src/users/users.module.ts (224 bytes)
> CREATE src/users/users.resolver.spec.ts (525 bytes)
> CREATE src/users/users.resolver.ts (1109 bytes)
> CREATE src/users/users.service.spec.ts (453 bytes)
> CREATE src/users/users.service.ts (625 bytes)
> CREATE src/users/dto/create-user.input.ts (195 bytes)
> CREATE src/users/dto/update-user.input.ts (281 bytes)
> CREATE src/users/entities/user.entity.ts (187 bytes)
> UPDATE src/app.module.ts (312 bytes)
```

> **Hint** To avoid generating test files, you can pass the `--no-spec` flag, as follows: `nest g resource users --no-spec`

We can see below, that not only were all boilerplate mutations and queries created, but everything is all tied together. We're utilizing the `UsersService`, `User` Entity, and our DTO's.

```typescript

import { Resolver, Query, Mutation, Args, Int } from '@nestjs/graphql';
import { UsersService } from './users.service';
import { User } from './entities/user.entity';
import { CreateUserInput } from './dto/create-user.input';
import { UpdateUserInput } from './dto/update-user.input';

@Resolver(() => User)
export class UsersResolver {
  constructor(private readonly usersService: UsersService) {}

  @Mutation(() => User)
  createUser(@Args('createUserInput') createUserInput: CreateUserInput) {
    return this.usersService.create(createUserInput);
  }

  @Query(() => [User], { name: 'users' })
  findAll() {
    return this.usersService.findAll();
  }

  @Query(() => User, { name: 'user' })
  findOne(@Args('id', { type: () => Int }) id: number) {
    return this.usersService.findOne(id);
  }

  @Mutation(() => User)
  updateUser(@Args('updateUserInput') updateUserInput: UpdateUserInput) {
    return this.usersService.update(updateUserInput.id, updateUserInput);
  }

  @Mutation(() => User)
  removeUser(@Args('id', { type: () => Int }) id: number) {
    return this.usersService.remove(id);
  }
}
```

----
url: https://docs.nestjs.com/v7/techniques/events
----

* [Events](https://docs.nestjs.com/v7/techniques/events#events)
* [Getting started](https://docs.nestjs.com/v7/techniques/events#getting-started)
* [Dispatching Events](https://docs.nestjs.com/v7/techniques/events#dispatching-events)
* [Listening to Events](https://docs.nestjs.com/v7/techniques/events#listening-to-events)
* [Example](https://docs.nestjs.com/v7/techniques/events#example)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/techniques/events.md "Suggest Edits")

### Events

[Event Emitter](https://www.npmjs.com/package/@nestjs/event-emitter) package (`@nestjs/event-emitter`) provides a simple observer implementation, allowing you to subscribe and listen for various events that occur in your application. Events serve as a great way to decouple various aspects of your application, since a single event can have multiple listeners that do not depend on each other.

`EventEmitterModule` internally uses the [eventemitter2](https://github.com/EventEmitter2/EventEmitter2) package.

#### Getting started[#](/techniques/events#getting-started)

First install the required package:

```shell

$ npm i --save @nestjs/event-emitter
```

Once the installation is complete, import the `EventEmitterModule` into the root `AppModule` and run the `forRoot()` static method as shown below:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { EventEmitterModule } from '@nestjs/event-emitter';

@Module({
  imports: [
    EventEmitterModule.forRoot()
  ],
})
export class AppModule {}
```

The `.forRoot()` call initializes the event emitter and registers any declarative event listeners that exist within your app. Registration occurs when the `onApplicationBootstrap` lifecycle hook occurs, ensuring that all modules have loaded and declared any scheduled jobs.

To configure the underlying `EventEmitter` instance, pass the configuration object to the `.forRoot()` method, as follows:

```typescript

EventEmitterModule.forRoot({
  // set this to `true` to use wildcards
  wildcard: false,
  // the delimiter used to segment namespaces
  delimiter: '.',
  // set this to `true` if you want to emit the newListener event
  newListener: false,
  // set this to `true` if you want to emit the removeListener event
  removeListener: false,
  // the maximum amount of listeners that can be assigned to an event
  maxListeners: 10,
  // show event name in memory leak message when more than maximum amount of listeners is assigned
  verboseMemoryLeak: false,
  // disable throwing uncaughtException if an error event is emitted and it has no listeners
  ignoreErrors: false,
});
```

#### Dispatching Events[#](/techniques/events#dispatching-events)

To dispatch (i.e., fire) an event, first inject `EventEmitter2` using standard constructor injection:

```typescript

constructor(private eventEmitter: EventEmitter2) {}
```

> **Hint** Import the `EventEmitter2` from the `@nestjs/event-emitter` package.

Then use it in a class as follows:

```typescript

this.eventEmitter.emit(
  'order.created',
  new OrderCreatedEvent({
    orderId: 1,
    payload: {},
  }),
);
```

#### Listening to Events[#](/techniques/events#listening-to-events)

To declare an event listener, decorate a method with the `@OnEvent()` decorator preceding the method definition containing the code to be executed, as follows:

```typescript

@OnEvent('order.created')
handleOrderCreatedEvent(payload: OrderCreatedEvent) {
  // handle and process "OrderCreatedEvent" event
}
```

> **Warning** Event subscribers cannot be request-scoped.

The first argument can be a `string` or `symbol` for a simple event emitter and a `string | symbol | Array<string | symbol>` in a case of a wildcard emitter. The second argument (optional) is a listener options object ([read more](https://github.com/EventEmitter2/EventEmitter2#emitteronevent-listener-options-objectboolean)).

```typescript

@OnEvent('order.created', { async: true })
handleOrderCreatedEvent(payload: OrderCreatedEvent) {
  // handle and process "OrderCreatedEvent" event
}
```

To use namespaces/wildcards, pass the `wildcard` option into the `EventEmitterModule#forRoot()` method. When namespaces/wildcards are enabled, events can either be strings (`foo.bar`) separated by a delimiter or arrays (`['foo', 'bar']`). The delimiter is also configurable as a configuration property (`delimiter`). With namespaces feature enabled, you can subscribe to events using a wildcard:

```typescript

@OnEvent('order.*')
handleOrderEvents(payload: OrderCreatedEvent | OrderRemovedEvent | OrderUpdatedEvent) {
  // handle and process an event
}
```

Note that such a wildcard only applies to one block. The argument `order.*` will match, for example, the events `order.created` and `order.shipped` but not `order.delayed.out_of_stock`. In order to listen to such events, use the `multilevel wildcard` pattern (i.e, `**`), described in the `EventEmitter2`[documentation](https://github.com/EventEmitter2/EventEmitter2#multi-level-wildcards).

With this pattern, you can, for example, create an event listener that catches all events.

```typescript

@OnEvent('**')
handleEverything(payload: any) {
  // handle and process an event
}
```

> **Hint**`EventEmitter2` class provides several useful methods for interacting with events, like `waitFor` and `onAny`. You can read more about them [here](https://github.com/EventEmitter2/EventEmitter2).

#### Example[#](/techniques/events#example)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/30-event-emitter).

----
url: https://docs.nestjs.com/fundamentals/lazy-loading-modules
----

[Skip to content](#content)

On this page

* [Lazy loading modules](https://docs.nestjs.com/fundamentals/lazy-loading-modules#lazy-loading-modules)
* [Getting started](https://docs.nestjs.com/fundamentals/lazy-loading-modules#getting-started)
* [Lazy loading controllers, gateways, and resolvers](https://docs.nestjs.com/fundamentals/lazy-loading-modules#lazy-loading-controllers-gateways-and-resolvers)
* [Common use-cases](https://docs.nestjs.com/fundamentals/lazy-loading-modules#common-use-cases)

### Lazy loading modules

By default, modules are eagerly loaded: as soon as the application loads, so do all the modules, whether or not they are immediately needed. This is fine for most applications, but it can become a bottleneck for apps and workers running in a **serverless environment**, where startup latency ("cold start") is crucial.

Lazy loading can decrease bootstrap time by loading only the modules required by a specific serverless function invocation. You can also load other modules asynchronously once the serverless function is "warm", to further speed up bootstrap time for subsequent calls (deferred module registration).

> **Hint** If you're familiar with the **[Angular](https://angular.dev/)** framework, you might have seen the term "[lazy-loading modules](https://angular.dev/guide/ngmodules/lazy-loading#lazy-loading-basics)" before. This technique is **functionally different** in Nest, so think of it as an entirely different feature that happens to share a similar name.

> **Warning**[Lifecycle hook methods](/fundamentals/lifecycle-events) are not invoked in lazy loaded modules and services.

#### Getting started[#](/fundamentals/lazy-loading-modules#getting-started)

To load modules on demand, Nest provides the `LazyModuleLoader` class, which you inject into a class like any other dependency:

cats.service.ts

JS TS

```typescript

@Injectable()
export class CatsService {
  constructor(private lazyModuleLoader: LazyModuleLoader) {}
}
```

```typescript

@Injectable()
@Dependencies(LazyModuleLoader)
export class CatsService {
  constructor(lazyModuleLoader) {
    this.lazyModuleLoader = lazyModuleLoader;
  }
}
```

> **Hint** The `LazyModuleLoader` class is imported from the `@nestjs/core` package.

Alternatively, you can obtain a reference to the `LazyModuleLoader` provider from within your application bootstrap file (`main.ts`):

```typescript

// "app" represents a Nest application instance
const lazyModuleLoader = app.get(LazyModuleLoader);
```

With this in place, you can load any module using the following construction:

```typescript

const { LazyModule } = await import('./lazy.module.js');
const moduleRef = await this.lazyModuleLoader.load(() => LazyModule);
```

> **Hint** Lazy loaded modules are **cached** on the first `LazyModuleLoader#load` method invocation. Each subsequent attempt to load `LazyModule` is therefore **very fast** and returns a cached instance instead of loading the module again.
>
> ```bash
>
> Load "LazyModule" attempt: 1
> time: 2.379ms
> Load "LazyModule" attempt: 2
> time: 0.294ms
> Load "LazyModule" attempt: 3
> time: 0.303ms
> ```
>
> Also, lazy loaded modules share the same module graph as the modules eagerly loaded on application bootstrap, as well as any other lazy modules registered later in your app.

Here, `lazy.module.ts` is a TypeScript file that exports a **regular Nest module** (no extra changes are required).

The `LazyModuleLoader#load` method returns the [module reference](/fundamentals/module-ref) (of `LazyModule`), which lets you navigate the internal list of providers and obtain a reference to any provider, using its injection token as a lookup key.

> **Hint** The `load()` method accepts an optional second argument, an options object. Set its `logger` property to `false` to suppress the logs Nest generates while loading the module.

For example, suppose we have a `LazyModule` with the following definition:

```typescript

@Module({
  providers: [LazyService],
  exports: [LazyService],
})
export class LazyModule {}
```

> **Hint** Lazy loaded modules cannot be registered as **global modules**, because they are registered lazily, on demand, after all the statically registered modules have been instantiated. Likewise, registered **global enhancers** (guards, interceptors, etc.) **will not work** properly either.

With this, we can obtain a reference to the `LazyService` provider:

```typescript

const { LazyModule } = await import('./lazy.module.js');
const moduleRef = await this.lazyModuleLoader.load(() => LazyModule);

const { LazyService } = await import('./lazy.service.js');
const lazyService = moduleRef.get(LazyService);
```

> **Warning** If you use **webpack**, update your `tsconfig.json` file: set `compilerOptions.module` to `"esnext"` and add the `compilerOptions.moduleResolution` property with `"node"` as its value:
>
> ```json
>
> {
>   "compilerOptions": {
>     "module": "esnext",
>     "moduleResolution": "node",
>     ...
>   }
> }
> ```
>
> With these options set, you can use webpack's [code splitting](https://webpack.js.org/guides/code-splitting/) feature.

#### Lazy loading controllers, gateways, and resolvers[#](/fundamentals/lazy-loading-modules#lazy-loading-controllers-gateways-and-resolvers)

Because controllers (or resolvers, in GraphQL applications) in Nest represent sets of routes, paths, or topics (or queries and mutations), you **cannot lazy load them** using the `LazyModuleLoader` class.

> **Warning** Controllers, [resolvers](/graphql/resolvers), and [gateways](/websockets/gateways) registered inside lazy loaded modules will not behave as expected. Similarly, you cannot register middleware (by implementing the `NestModule` interface's `configure()` method with the `MiddlewareConsumer`) on demand.

For example, suppose you're building a REST API (HTTP application) with Fastify under the hood (using the `@nestjs/platform-fastify` package). Fastify doesn't let you register routes after the application is ready and listening. So even if Nest analyzed the route mappings registered in the module's controllers, the lazy loaded routes would not be accessible, because there is no way to register them at runtime.

Likewise, some transport strategies provided by the `@nestjs/microservices` package (including Kafka, gRPC, and RabbitMQ) must subscribe to specific topics or channels before the connection is established. Once your application starts listening to messages, the framework can't subscribe to new topics.

Finally, the `@nestjs/graphql` package, with the code first approach enabled, generates the GraphQL schema on the fly based on metadata. This requires all classes to be loaded beforehand; otherwise, it can't create a valid schema.

#### Common use-cases[#](/fundamentals/lazy-loading-modules#common-use-cases)

Lazy loaded modules are most common when a worker, cron job, lambda or other serverless function, or webhook must trigger different services (different logic) based on its input arguments (route path, date, query parameters, etc.). Lazy loading modules makes less sense for monolithic applications, where startup time is largely irrelevant.

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/fundamentals/lazy-loading-modules.md)

----
url: https://docs.nestjs.com/deployment
----

[Skip to content](#content)

On this page

* [Deployment](https://docs.nestjs.com/deployment#deployment)
* [Prerequisites](https://docs.nestjs.com/deployment#prerequisites)
* [Building your application](https://docs.nestjs.com/deployment#building-your-application)
* [Production environment](https://docs.nestjs.com/deployment#production-environment)
* [NODE\_ENV=production](https://docs.nestjs.com/deployment#node_envproduction)
* [Running your application](https://docs.nestjs.com/deployment#running-your-application)
* [Health checks](https://docs.nestjs.com/deployment#health-checks)
* [Logging](https://docs.nestjs.com/deployment#logging)
* [Observability](https://docs.nestjs.com/deployment#observability)
* [Scaling up or out](https://docs.nestjs.com/deployment#scaling-up-or-out)
* [Some other tips](https://docs.nestjs.com/deployment#some-other-tips)
* [Dockerizing your application](https://docs.nestjs.com/deployment#dockerizing-your-application)
* [Easy deployment with Mau](https://docs.nestjs.com/deployment#easy-deployment-with-mau)

### Deployment

When you're ready to deploy your NestJS application to production, there are key steps you can take to ensure it runs as efficiently as possible. This guide covers essential tips and best practices for deploying your NestJS application successfully.

If you'd rather not manage infrastructure yourself, [Mau](https://mau.nestjs.com/ "Deploy Nest"), our official deployment platform, gets you to production on AWS with a single command. Jump straight to [Easy deployment with Mau](/deployment#easy-deployment-with-mau), or read on for the underlying concepts that apply to any hosting choice.

#### Prerequisites[#](/deployment#prerequisites)

Before deploying your NestJS application, ensure you have:

* A working NestJS application that is ready for deployment.
* Access to a deployment platform or server where you can host your application.
* All necessary environment variables set up for your application.
* Any required services, like a database, set up and ready to go.
* Node.js 20.19 or later (22.12 or later on the 22.x line) installed on your deployment platform, as described in [Prerequisites](/first-steps#prerequisites). Prefer a Node.js version that is still in active LTS.

> **Hint** With [Mau](https://mau.nestjs.com/ "Deploy Nest"), most of the list above is handled for you: it provisions the server, the databases and brokers your app needs, and the environment variables, so the only prerequisite left is the application itself.

#### Building your application[#](/deployment#building-your-application)

To build your NestJS application, compile your TypeScript code into JavaScript. This process generates a `dist` directory containing the compiled files. Build your application by running the following command:

```bash

$ npm run build
```

This command typically runs `nest build` under the hood, which is a wrapper around the TypeScript compiler with some additional features (such as copying assets). If you have a custom build script, you can run it directly. For Nest CLI monorepos, pass the name of the project to build as an argument (`npm run build my-app`).

After a successful compilation, you should see a `dist` directory in your project root containing the compiled files, with `main.js` as the entry point. If you have any `.ts` files in the root directory of your project (and your `tsconfig.json` is configured to compile them), they are compiled into the `dist` directory as well, which changes the directory structure: instead of `dist/main.js`, you get `dist/src/main.js`. Keep that in mind when configuring your server.

#### Production environment[#](/deployment#production-environment)

Your production environment is where your application is accessible to external users. This could be a cloud-based platform like [AWS](https://aws.amazon.com/) (with EC2, ECS, etc.), [Azure](https://azure.microsoft.com/), or [Google Cloud](https://cloud.google.com/), or a dedicated server you manage, such as [Hetzner](https://www.hetzner.com/).

To simplify the deployment process and avoid manual setup, you can use [Mau](https://mau.nestjs.com/ "Deploy Nest"), our official platform for deploying NestJS applications on AWS. It gives you the benefits of AWS listed below without requiring you to configure any of it yourself. See [Easy deployment with Mau](/deployment#easy-deployment-with-mau) for details.

Some of the pros of using a **cloud-based platform** or service like [Mau](https://mau.nestjs.com/ "Deploy Nest") include:

* Scalability: Scale your application as your user base grows.
* Security: Benefit from built-in security features and compliance certifications.
* Monitoring: Monitor your application's performance and health in real time.
* Reliability: Ensure your application is always available with high uptime guarantees.

On the other hand, cloud-based platforms are typically more expensive than self-hosting, and you may have less control over the underlying infrastructure. A simple VPS can be a good choice if you're looking for a more cost-effective solution and have the technical expertise to manage the server yourself. Keep in mind that you'll need to handle tasks like server maintenance, security, and backups manually.

#### NODE\_ENV=production[#](/deployment#node_envproduction)

While there's technically no difference between development and production in Node.js and NestJS, it's good practice to set the `NODE_ENV` environment variable to `production` when running your application in a production environment, because some libraries in the ecosystem behave differently based on this variable (e.g., enabling or disabling debugging output).

You can set the `NODE_ENV` environment variable when starting your application:

```bash

$ NODE_ENV=production node dist/main.js
```

Alternatively, set it in your cloud provider's or Mau's dashboard.

#### Running your application[#](/deployment#running-your-application)

To run your NestJS application in production, use the following command:

```bash

$ node dist/main.js # Adjust this based on your entry point location
```

This command starts your application, which listens on the port passed to `app.listen()` (`3000` in newly generated projects, unless the `PORT` environment variable is set). Make sure your deployment platform routes traffic to that port.

Alternatively, you can use the `nest start` command. It is a wrapper around `node dist/main.js`, with one key difference: it runs `nest build` before starting the application, so you don't need to run `npm run build` manually.

#### Health checks[#](/deployment#health-checks)

Health checks are essential for monitoring the health and status of your NestJS application in production. With a health check endpoint, you can regularly verify that your app is running as expected and respond to issues before they become critical.

In NestJS, you can implement health checks with the **@nestjs/terminus** package, which supports checks for database connections, external services, and custom indicators.

See the [health checks (Terminus)](/reliability/terminus) chapter to learn how to implement health checks in your NestJS application.

#### Logging[#](/deployment#logging)

Logging is essential for any production-ready application. It helps you track errors, monitor behavior, and troubleshoot issues. In NestJS, you can manage logging with the [built-in logger](/application/logger), or opt for external libraries if you need more advanced features.

Best practices for logging:

* Log errors, not exceptions: Focus on logging detailed error messages to speed up debugging and issue resolution.
* Avoid sensitive data: Never log sensitive information such as passwords or tokens.
* Use correlation IDs: In distributed systems, include unique identifiers (like correlation IDs) in your logs to trace requests across services.
* Use log levels: Categorize logs by severity (e.g., `info`, `warn`, `error`), and disable debug or verbose logs in production to reduce noise.

> **Hint** If you're using [AWS](https://aws.amazon.com/) (with [Mau](https://mau.nestjs.com/ "Deploy Nest") or directly), consider JSON logging to make it easier to parse and analyze your logs.

For distributed applications, a centralized logging service such as Elasticsearch, Loggly, or Datadog is very useful. These tools offer log aggregation, search, and visualization, making it easier to monitor and analyze your application's performance and behavior.

#### Observability[#](/deployment#observability)

Health checks and logs tell you whether the application is up; they don't tell you which route got slower after the last deploy, which class is burning the time, or which line threw. For that, instrument the application with [NestJS Observe](https://www.observe.nestjs.com/ "NestJS Observe"), our official observability platform: install the `@nestjs/observe` SDK, pass an API key, and requests, jobs, errors, logs, and traces start streaming to a dashboard with no manual span wiring or collector to run.

```typescript

const app = await NestFactory.create(AppModule, {
  instrument: ObserveInstrument,
});
```

See the [Observability](/observability/overview) chapter for the full setup, including versioning deployments with `serviceVersion` so each release is compared against the one before it.

#### Scaling up or out[#](/deployment#scaling-up-or-out)

Scaling your NestJS application effectively is crucial for handling increased traffic and ensuring optimal performance. There are two primary strategies for scaling: **vertical scaling** and **horizontal scaling**. Understanding both helps you design your application to manage load efficiently.

**Vertical scaling**, often referred to as "scaling up", involves increasing the resources of a single server to improve its performance. This could mean adding more CPU, RAM, or storage to your existing machine. Key points to consider:

* Simplicity: Vertical scaling is generally simpler to implement since you only need to upgrade your existing server rather than manage multiple instances.
* Limitations: There are physical limits to how much you can scale a single machine. Once you reach the maximum capacity, you may need to consider other options.
* Cost-effectiveness: For applications with moderate traffic, vertical scaling can be cost-effective, as it reduces the need for additional infrastructure.

Example: If your NestJS app is hosted on a virtual machine and you notice that it's running slowly during peak hours, you can upgrade the VM to a larger instance with more resources, typically by selecting a larger instance type in your provider's dashboard.

**Horizontal scaling**, or "scaling out", involves adding more servers or instances to distribute the load. This strategy is widely used in cloud environments and is essential for applications expecting high traffic. Benefits and considerations:

* Increased capacity: By adding more instances of your application, you can handle a larger number of concurrent users without degrading performance.
* Redundancy: The failure of one server doesn't bring down your entire application, because traffic can be redistributed among the remaining servers.
* Load balancing: To manage multiple instances effectively, use load balancers (like Nginx or AWS Elastic Load Balancing) to distribute incoming traffic evenly across your servers.

Example: For a NestJS application experiencing high traffic, you can deploy multiple instances of your app in a cloud environment and use a load balancer to route requests, ensuring that no single instance becomes a bottleneck.

Containerization technologies like [Docker](https://www.docker.com/) and container orchestration platforms such as [Kubernetes](https://kubernetes.io/) make this process straightforward. You can also use cloud-specific load balancers like [AWS Elastic Load Balancing](https://aws.amazon.com/elasticloadbalancing/) or [Azure Load Balancer](https://azure.microsoft.com/en-us/services/load-balancer/) to distribute traffic across your application instances.

> **Hint**[Mau](https://mau.nestjs.com/ "Deploy Nest") offers built-in support for horizontal scaling on AWS, so you can deploy multiple instances of your NestJS application and manage them with just a few clicks.

#### Some other tips[#](/deployment#some-other-tips)

Keep these additional tips in mind when deploying your NestJS application:

* **Security**: Protect your application from common threats such as SQL injection and XSS. See the chapters in the "Security" category, such as [Helmet](/security/helmet) and [CORS](/security/cors), for details.
* **Monitoring**: Use monitoring tools like [Prometheus](https://prometheus.io/) or [New Relic](https://newrelic.com/) to track your application's performance and health. Cloud providers and Mau may offer built-in monitoring services (such as [AWS CloudWatch](https://aws.amazon.com/cloudwatch/)).
* **Do not hardcode environment variables**: Avoid hardcoding sensitive information like API keys, passwords, or tokens in your code. Use environment variables or a secrets manager to store and access these values securely.
* **Backups**: Regularly back up your data to prevent data loss in case of an incident.
* **Automate deployments**: Use CI/CD pipelines to automate your deployment process and ensure consistency across environments.
* **Rate limiting**: Implement rate limiting to prevent abuse and protect your application from DDoS attacks. See the [rate limiting](/security/rate-limiting) chapter for details, or use a service like [AWS WAF](https://aws.amazon.com/waf/) for advanced protection.

#### Dockerizing your application[#](/deployment#dockerizing-your-application)

[Docker](https://www.docker.com/) is a platform that uses containerization to let developers package applications along with their dependencies into a standardized unit called a container. Containers are lightweight, portable, and isolated, which makes them ideal for deploying applications in various environments, from local development to production.

Benefits of Dockerizing your NestJS application:

* Consistency: Docker ensures that your application runs the same way on any machine, eliminating the "it works on my machine" problem.
* Isolation: Each container runs in its own isolated environment, preventing conflicts between dependencies.
* Scalability: You can scale your application by running multiple containers across different machines or cloud instances.
* Portability: Containers move between environments without changes, so you can deploy your application on different platforms.

To install Docker, follow the instructions on the [Docker website](https://www.docker.com/get-started). Once Docker is installed, create a `Dockerfile` in your NestJS project. It is a text file that contains the instructions Docker uses to build your container image.

Here's a sample `Dockerfile` for a NestJS application:

```bash

# Use the official Node.js image as the base image
FROM node:24

# Set the working directory inside the container
WORKDIR /usr/src/app

# Copy package.json and package-lock.json to the working directory
COPY package*.json ./

# Install the application dependencies
RUN npm install

# Copy the rest of the application files
COPY . .

# Build the NestJS application
RUN npm run build

# Expose the application port
EXPOSE 3000

# Command to run the application
CMD ["node", "dist/main"]
```

> **Hint** Replace `node:24` with the Node.js version your project uses (NestJS v12 requires Node.js 20.19 or later, or 22.12 or later on the 22.x line). You can find the available Node.js Docker images in the [official Docker Hub repository](https://hub.docker.com/_/node).

This basic `Dockerfile` sets up a Node.js environment, installs the application dependencies, builds the NestJS application, and runs it. You can customize it based on your project requirements (e.g., use a different base image, optimize the build process, or install only production dependencies).

Next, create a `.dockerignore` file in your project root to specify which files and directories Docker should ignore when building the image:

```bash

node_modules
dist
*.log
*.md
.git
```

This file keeps unnecessary files out of the container image, keeping it lightweight. With the `Dockerfile` in place, you can build your Docker image. Open your terminal, navigate to your project directory, and run the following command:

```bash

docker build -t my-nestjs-app .
```

In this command:

* `-t my-nestjs-app`: Tags the image with the name `my-nestjs-app`.
* `.`: Indicates the current directory as the build context.

After building the image, run it as a container:

```bash

docker run -p 3000:3000 my-nestjs-app
```

In this command:

* `-p 3000:3000`: Maps port 3000 on your host machine to port 3000 in the container.
* `my-nestjs-app`: Specifies the image to run.

Your NestJS application should now be running inside a Docker container.

To deploy your Docker image to a cloud provider or share it with others, push it to a container registry (such as [Docker Hub](https://hub.docker.com/), [Amazon ECR](https://aws.amazon.com/ecr/), or [Google Artifact Registry](https://cloud.google.com/artifact-registry)).

Once you've chosen a registry, push your image:

```bash

docker login # Log in to your Docker registry
docker tag my-nestjs-app your-dockerhub-username/my-nestjs-app # Tag your image
docker push your-dockerhub-username/my-nestjs-app # Push your image
```

Replace `your-dockerhub-username` with your Docker Hub username or the appropriate registry URL. After pushing your image, you can pull it on any machine and run it as a container.

Cloud providers like AWS, Azure, and Google Cloud offer managed container services that simplify deploying and managing containers at scale. These services provide features like auto-scaling, load balancing, and monitoring for your NestJS application in production.

#### Easy deployment with Mau[#](/deployment#easy-deployment-with-mau)

[Mau](https://mau.nestjs.com/ "Deploy Nest") is our official platform for deploying NestJS applications on [AWS](https://aws.amazon.com/). It handles everything the previous sections described (provisioning the server, wiring up databases and brokers, managing environment variables, scaling, monitoring, and CI/CD), so you don't have to assemble it yourself.

##### Deploying[#](/deployment#deploying)

As of NestJS v12, the Nest CLI ships a `deploy` command. Run it from your project root:

```bash

$ nest deploy
```

If Mau isn't installed yet, the command offers to add `@nestjs/mau` as a dev dependency and then continues. Any options you pass are forwarded to `mau deploy`. See [nest deploy](/cli/usages#nest-deploy) for details.

You can also install the Mau CLI globally and invoke it directly. This is the right choice for CI environments, where interactive prompts aren't available:

```bash

$ npm install -g @nestjs/mau
$ mau deploy
```

Once the deployment completes, your application is live on AWS, typically within minutes of your first run.

##### Why Mau[#](/deployment#why-mau)

With Mau, provisioning and maintaining your infrastructure takes just a few clicks. Under the hood, Mau uses **Amazon Web Services** to give you a powerful and reliable platform, while abstracting away the complexity of AWS. You get the advantages of AWS without having to learn and manage its details, which makes Mau a good fit for startups, small-to-medium businesses, large enterprises, and any developer who would rather ship than configure infrastructure.

With [Mau](https://mau.nestjs.com/ "Deploy Nest"), you can:

* Deploy your NestJS applications with just a few clicks (APIs, microservices, etc.).

* Provision **databases** such as:

  * PostgreSQL
  * MySQL
  * MongoDB (DocumentDB)
  * Redis
  * more

* Set up broker services like:

  * RabbitMQ
  * Kafka
  * NATS

* Deploy scheduled tasks (**CRON jobs**) and background workers.

* Deploy lambda functions and serverless applications.

* Set up **CI/CD pipelines** for automated deployments.

* And much more.

##### How Mau maps to this guide[#](/deployment#how-mau-maps-to-this-guide)

Each topic covered earlier in this chapter has a managed equivalent in Mau:

|                                                         |                                                                                                                                          |
| ------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| [Environment variables](/deployment#node_envproduction) | Set `NODE_ENV` and your secrets in the Mau dashboard instead of managing them on the server.                                             |
| [Logging](/deployment#logging)                          | Logs are collected and viewable in the dashboard. JSON logging is especially useful here; see the [Logger chapter](/application/logger). |
| [Scaling](/deployment#scaling-up-or-out)                | Built-in support for horizontal scaling: run multiple instances of your application and manage them from the dashboard.                  |
| [Health checks](/deployment#health-checks)              | Point Mau at the endpoint you expose with [Terminus](/reliability/terminus) and unhealthy instances are handled for you.                 |
| [Monitoring and backups](/deployment#some-other-tips)   | Metrics come from AWS CloudWatch, and managed databases are backed up automatically.                                                     |

Sign up today and [deploy with Mau](https://mau.nestjs.com/ "Deploy Nest") to get your NestJS applications up and running on AWS in minutes.

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/deployment.md)

----
url: https://docs.nestjs.com/v8/graphql/interfaces
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Interfaces](https://docs.nestjs.com/v8/graphql/interfaces#interfaces)
* [Code first](https://docs.nestjs.com/v8/graphql/interfaces#code-first)
* [Interface resolvers](https://docs.nestjs.com/v8/graphql/interfaces#interface-resolvers)
* [Schema first](https://docs.nestjs.com/v8/graphql/interfaces#schema-first)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/interfaces.md "Suggest Edits")

### Interfaces

Like many type systems, GraphQL supports interfaces. An **Interface** is an abstract type that includes a certain set of fields that a type must include to implement the interface (read more [here](https://graphql.org/learn/schema/#interfaces)).

#### Code first

When using the code first approach, you define a GraphQL interface by creating an abstract class annotated with the `@InterfaceType()` decorator exported from the `@nestjs/graphql`.

```typescript

import { Field, ID, InterfaceType } from '@nestjs/graphql';

@InterfaceType()
export abstract class Character {
  @Field((type) => ID)
  id: string;

  @Field()
  name: string;
}
```

> **Warning** TypeScript interfaces cannot be used to define GraphQL interfaces.

This will result in generating the following part of the GraphQL schema in SDL:

```graphql

interface Character {
  id: ID!
  name: String!
}
```

Now, to implement the `Character` interface, use the `implements` key:

```typescript

@ObjectType({
  implements: () => [Character],
})
export class Human implements Character {
  id: string;
  name: string;
}
```

> **Hint** The `@ObjectType()` decorator is exported from the `@nestjs/graphql` package.

The default `resolveType()` function generated by the library extracts the type based on the value returned from the resolver method. This means that you must return class instances (you cannot return literal JavaScript objects).

To provide a customized `resolveType()` function, pass the `resolveType` property to the options object passed into the `@InterfaceType()` decorator, as follows:

```typescript

@InterfaceType({
  resolveType(book) {
    if (book.colors) {
      return ColoringBook;
    }
    return TextBook;
  },
})
export abstract class Book {
  @Field((type) => ID)
  id: string;

  @Field()
  title: string;
}
```

#### Interface resolvers

So far, using interfaces, you could only share field definitions with your objects. If you also want to share the actual field resolvers implementation, you can create a dedicated interface resolver, as follows:

```typescript

import { Resolver, ResolveField, Parent, Info } from '@nestjs/graphql';

@Resolver(type => Character) // Reminder: Character is an interface
export class CharacterInterfaceResolver {
  @ResolveField(() => [Character])
  friends(
    @Parent() character, // Resolved object that implements Character
    @Info() { parentType }, // Type of the object that implements Character
    @Args('search', { type: () => String }) searchTerm: string,
  ) {
    // Get character's friends
    return [];
  }
}
```

Now the `friends` field resolver is auto-registered for all object types that implement the `Character` interface.

#### Schema first

To define an interface in the schema first approach, simply create a GraphQL interface with SDL.

```graphql

interface Character {
  id: ID!
  name: String!
}
```

Then, you can use the typings generation feature (as shown in the [quick start]() chapter) to generate corresponding TypeScript definitions:

```typescript

export interface Character {
  id: string;
  name: string;
}
```

Interfaces require an extra `__resolveType` field in the resolver map to determine which type the interface should resolve to. Let's create a `CharactersResolver` class and define the `__resolveType` method:

```typescript

@Resolver('Character')
export class CharactersResolver {
  @ResolveField()
  __resolveType(value) {
    if ('age' in value) {
      return Person;
    }
    return null;
  }
}
```

> **Hint** All decorators are exported from the `@nestjs/graphql` package.

----
url: https://docs.nestjs.com/v5/faq/multiple-servers
----

### HTTPS

In order to create application that uses HTTPS protocol, we have to pass an options object:

TypeScript

```typescript

const httpsOptions = {
  key: fs.readFileSync('./secrets/private-key.pem'),
  cert: fs.readFileSync('./secrets/public-certificate.pem')
};
const app = await NestFactory.create(ApplicationModule, {
  httpsOptions,
});
await app.listen(3000);
```

#### Multiple simultaneous servers

A full control over the `express` instance gives a simple way to create a several multiple simultaneous servers that are listening on different ports.

TypeScript

```typescript

const httpsOptions = {
  key: fs.readFileSync('./secrets/private-key.pem'),
  cert: fs.readFileSync('./secrets/public-certificate.pem')
};

const server = express();
const app = await NestFactory.create(ApplicationModule, server);
await app.init();

http.createServer(server).listen(3000);
https.createServer(httpsOptions, server).listen(443);
```

* HTTPS
* Multiple simultaneous servers

----
url: https://docs.nestjs.com/v5/fundamentals/unit-testing
----

### Testing

Automatic tests are an essential part of the fully functional **software product**. That is very critical to cover at least the most sensitive parts of your system. In order to achieve that goal, we produce a set of different tests like integration tests, unit tests, e2e tests, and so on. And Nest provides a bunch of test utilities that improves testing experience.

In general, you can use any **testing framework** that you enjoy working with. We don't enforce tooling, choose whatever fits your requirements. The main Nest application starter is integrated with [Jest](https://github.com/facebook/jest) framework to reduce an amount of overhead when it comes to start writing your tests, but still, you can get rid of it and use any other tool easily.

#### Installation

Firstly, we need to install the required package:

TypeScript

```typescript

$ npm i --save-dev @nestjs/testing
```

#### Unit testing

In the following example, we have two different classes, `CatsController` and `CatsService` respectively. As mentioned before, [Jest](https://github.com/facebook/jest) is used as a fully-fledged testing framework. That framework behaves like a test-runner and also, provides assert functions and test-doubles utilities that helps with mocking, spying, etc. We have manually enforced `catsService.findAll()` method to return `result` variable, once it's called. Thanks to that, we can test whether `catsController.findAll()` returns expected result, or not.

cats.controller.spec.ts

JS TS

TypeScript

```typescript

import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

describe('CatsController', () => {
  let catsController: CatsController;
  let catsService: CatsService;

  beforeEach(() => {
    catsService = new CatsService();
    catsController = new CatsController(catsService);
  });

  describe('findAll', () => {
    it('should return an array of cats', async () => {
      const result = ['test'];
      jest.spyOn(catsService, 'findAll').mockImplementation(() => result);

      expect(await catsController.findAll()).toBe(result);
    });
  });
});
```

TypeScript

```typescript

import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

describe('CatsController', () => {
  let catsController;
  let catsService;

  beforeEach(() => {
    catsService = new CatsService();
    catsController = new CatsController(catsService);
  });

  describe('findAll', () => {
    it('should return an array of cats', async () => {
      const result = ['test'];
      jest.spyOn(catsService, 'findAll').mockImplementation(() => result);

      expect(await catsController.findAll()).toBe(result);
    });
  });
});
```

> **Hint** Keep your test files nearby tested classes. The testing files should have a `.spec` or `.test` suffix.

We didn't make use of any existing Nest testing utility so far. Since we have manually taken care of instantiating tested classes, above test suite has nothing to do with Nest. This type of testing is called **isolated tests**.

#### Testing utilities

The `@nestjs/testing` package gives us a set of utilities that boost the testing process. Let's rewrite the previous example, but now, using exposed `Test` class.

cats.controller.spec.ts

JS TS

TypeScript

```typescript

import { Test } from '@nestjs/testing';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

describe('CatsController', () => {
  let catsController: CatsController;
  let catsService: CatsService;

  beforeEach(async () => {
    const module = await Test.createTestingModule({
        controllers: [CatsController],
        providers: [CatsService],
      }).compile();

    catsService = module.get<CatsService>(CatsService);
    catsController = module.get<CatsController>(CatsController);
  });

  describe('findAll', () => {
    it('should return an array of cats', async () => {
      const result = ['test'];
      jest.spyOn(catsService, 'findAll').mockImplementation(() => result);

      expect(await catsController.findAll()).toBe(result);
    });
  });
});
```

TypeScript

```typescript

import { Test } from '@nestjs/testing';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

describe('CatsController', () => {
  let catsController;
  let catsService;

  beforeEach(async () => {
    const module = await Test.createTestingModule({
        controllers: [CatsController],
        providers: [CatsService],
      }).compile();

    catsService = module.get(CatsService);
    catsController = module.get(CatsController);
  });

  describe('findAll', () => {
    it('should return an array of cats', async () => {
      const result = ['test'];
      jest.spyOn(catsService, 'findAll').mockImplementation(() => result);

      expect(await catsController.findAll()).toBe(result);
    });
  });
});
```

`Test` class has a `createTestingModule()` method that takes a module metadata (the same object as this one passed in `@Module()` decorator) as an argument. This method creates a `TestingModule` instance which in turn provides a few methods, but only one of them is useful when it comes to unit tests - the `compile()`. This function is **asynchronous**, therefore it has to be awaited. Once module is compiled, you can retrieve any instance using `get()` method.

In order to mock a real instance, you can override existing provider with a [custom provider](/v5/fundamentals/dependency-injection).

#### End-to-end testing

When the application grows, it is difficult to manually test a behavior of each API endpoint. The end-to-end tests help us to make sure that everything is working correctly and fits project requirements. To perform e2e tests we use the same configuration as in the case of **unit testing**, but additionally, we take advantage of [supertest](https://github.com/visionmedia/supertest) library that allows simulating HTTP requests.

cats.e2e-spec.ts

JS TS

TypeScript

```typescript

import * as request from 'supertest';
import { Test } from '@nestjs/testing';
import { CatsModule } from '../../src/cats/cats.module';
import { CatsService } from '../../src/cats/cats.service';
import { INestApplication } from '@nestjs/common';

describe('Cats', () => {
  let app: INestApplication;
  let catsService = { findAll: () => ['test'] };

  beforeAll(async () => {
    const module = await Test.createTestingModule({
      imports: [CatsModule],
    })
      .overrideProvider(CatsService)
      .useValue(catsService)
      .compile();

    app = module.createNestApplication();
    await app.init();
  });

  it(`/GET cats`, () => {
    return request(app.getHttpServer())
      .get('/cats')
      .expect(200)
      .expect({
        data: catsService.findAll(),
      });
  });

  afterAll(async () => {
    await app.close();
  });
});
```

> **Hint** Keep your e2e test files inside the `e2e` directory. The testing files should have a `.e2e-spec` or `.e2e-test` suffix.

The `cats.e2e-spec.ts` test file contains a single HTTP endpoint test (`/cats`). We have used `app.getHttpServer()` method to pick up an underlying HTTP server that runs in the background of Nest application. Notice that `TestingModule` instance provides a `overrideProvider()` method, and thus we can **override** the existing provider which is declared by the imported module. Also, we can successively override the guards, interceptors, filters, and pipes using corresponding methods, `overrideGuard()`, `overrideInterceptor()`, `overrideFilter()`, and `overridePipe()` respectively.

The compiled module has several methods well described in the following table:

|                            |                                                                                                                                                                        |
| -------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `createNestInstance()`     | Creates a Nest instance based on a given module (returns `INestApplication`). Notice that it's necessary to manually initialize the application using `init()` method. |
| `createNestMicroservice()` | Creates a Nest microservice instance based on a given module (returns `INestMicroservice`).                                                                            |
| `get()`                    | Retrieves an instance of either controller or provider (including guards, filters, and so on) available in the application context.                                    |
| `select()`                 | Navigates through the module tree, for example, to pull out a specific instance from the selected module (used together with enabled strict mode).                     |

* Testing
* Installation
* Unit testing
* Testing utilities
* End-to-end testing

----
url: https://docs.nestjs.com/data/caching
----

[Skip to content](#content)

On this page

* [Caching](https://docs.nestjs.com/data/caching#caching)
* [Installation](https://docs.nestjs.com/data/caching#installation)
* [In-memory cache](https://docs.nestjs.com/data/caching#in-memory-cache)
* [Interacting with the Cache store](https://docs.nestjs.com/data/caching#interacting-with-the-cache-store)
* [Auto-caching responses](https://docs.nestjs.com/data/caching#auto-caching-responses)
* [Time-to-live (TTL)](https://docs.nestjs.com/data/caching#time-to-live-ttl)
* [Use module globally](https://docs.nestjs.com/data/caching#use-module-globally)
* [Global cache overrides](https://docs.nestjs.com/data/caching#global-cache-overrides)
* [WebSockets and Microservices](https://docs.nestjs.com/data/caching#websockets-and-microservices)
* [Adjust tracking](https://docs.nestjs.com/data/caching#adjust-tracking)
* [Using alternative Cache stores](https://docs.nestjs.com/data/caching#using-alternative-cache-stores)
* [Async configuration](https://docs.nestjs.com/data/caching#async-configuration)
* [Example](https://docs.nestjs.com/data/caching#example)

### Caching

Caching is a straightforward and effective **technique** for improving your application's performance. A cache acts as a temporary storage layer that provides quick access to frequently used data, so you don't have to fetch or compute the same information repeatedly. The result is faster response times and better overall efficiency.

#### Installation[#](/data/caching#installation)

To get started with caching in Nest, install the `@nestjs/cache-manager` package along with the `cache-manager` package:

```bash

$ npm install @nestjs/cache-manager cache-manager
```

By default, everything is stored in memory. Because `cache-manager` uses [Keyv](https://keyv.org/docs/) under the hood, you can switch to a different storage solution, such as Redis, by installing the appropriate package. See [Using alternative Cache stores](/data/caching#using-alternative-cache-stores) below.

#### In-memory cache[#](/data/caching#in-memory-cache)

To enable caching in your application, import the `CacheModule` and configure it using the `register()` method:

```typescript

import { Module } from '@nestjs/common';
import { CacheModule } from '@nestjs/cache-manager';
import { AppController } from './app.controller.js';

@Module({
  imports: [CacheModule.register()],
  controllers: [AppController],
})
export class AppModule {}
```

This setup initializes in-memory caching with the default settings, so you can start caching data immediately.

#### Interacting with the Cache store[#](/data/caching#interacting-with-the-cache-store)

To interact with the cache manager instance, inject it into your class using the `CACHE_MANAGER` token, as follows:

```typescript

constructor(@Inject(CACHE_MANAGER) private cacheManager: Cache) {}
```

> **Hint** The `Cache` class and the `CACHE_MANAGER` token are both imported from the `@nestjs/cache-manager` package.

Use the `get()` method of the `Cache` instance (from the `cache-manager` package) to retrieve items from the cache. If the item doesn't exist in the cache, `get()` returns `undefined` (`cache-manager` v6 returned `null` instead). Treat both as a cache miss when migrating.

```typescript

const value = await this.cacheManager.get('key');
```

To add an item to the cache, use the `set()` method:

```typescript

await this.cacheManager.set('key', 'value');
```

> **Note** The default in-memory store is a Keyv instance, which serializes values to JSON before storing them (Buffers are also supported). Store only JSON-serializable values: class instances come back as plain objects, `Date` objects come back as strings, and symbols can't be stored.

You can specify a TTL (expiration time in milliseconds) for a specific key, as follows:

```typescript

await this.cacheManager.set('key', 'value', 1000);
```

Here, the cache item expires after one second.

To store an item that never expires, pass a TTL of `0`:

```typescript

await this.cacheManager.set('key', 'value', 0);
```

To remove an item from the cache, use the `del()` method:

```typescript

await this.cacheManager.del('key');
```

To clear the entire cache, use the `clear()` method:

```typescript

await this.cacheManager.clear();
```

#### Auto-caching responses[#](/data/caching#auto-caching-responses)

> **Warning** In [GraphQL](/graphql/quick-start) applications, interceptors are executed separately for each field resolver. As a result, `CacheModule` (which uses interceptors to cache responses) doesn't work properly there.

To cache responses automatically, bind the `CacheInterceptor` where you want to cache data:

```typescript

@Controller()
@UseInterceptors(CacheInterceptor)
export class AppController {
  @Get()
  findAll(): string[] {
    return [];
  }
}
```

> **Warning** By default, only `GET` endpoints are cached (an explicit `@CacheKey()` on a route handler bypasses this check). Also, HTTP routes that inject the native response object (`@Res()`) can't use the `CacheInterceptor`. See [response mapping](/interceptors#response-mapping) for more details.

To reduce boilerplate, you can bind `CacheInterceptor` to all endpoints globally:

```typescript

import { Module } from '@nestjs/common';
import { CacheModule, CacheInterceptor } from '@nestjs/cache-manager';
import { AppController } from './app.controller.js';
import { APP_INTERCEPTOR } from '@nestjs/core';

@Module({
  imports: [CacheModule.register()],
  controllers: [AppController],
  providers: [
    {
      provide: APP_INTERCEPTOR,
      useClass: CacheInterceptor,
    },
  ],
})
export class AppModule {}
```

#### Time-to-live (TTL)[#](/data/caching#time-to-live-ttl)

By default, `ttl` isn't set, so cache entries never expire (the same as setting it to `0`). To specify a custom [TTL](https://en.wikipedia.org/wiki/Time_to_live), pass the `ttl` option to the `register()` method:

```typescript

CacheModule.register({
  ttl: 5000, // milliseconds
});
```

#### Use module globally[#](/data/caching#use-module-globally)

To use `CacheModule` in other modules, you need to import it (as with any Nest module). Alternatively, declare it as a [global module](/modules#global-modules) by setting the `isGlobal` property of the options object to `true`, as shown below. In that case, once `CacheModule` is loaded in the root module (e.g., `AppModule`), you don't need to import it in other modules.

```typescript

CacheModule.register({
  isGlobal: true,
});
```

#### Global cache overrides[#](/data/caching#global-cache-overrides)

When the `CacheInterceptor` is bound globally, cache entries are stored under a key that is generated automatically from the request URL. You can override certain cache settings (`@CacheKey()` and `@CacheTTL()`) on a per-method basis to customize the caching strategy for individual controller methods. This is most relevant when using [different cache stores](/data/caching#using-alternative-cache-stores).

You can also apply the `@CacheTTL()` decorator to a controller to set the TTL for all of its routes. When both controller-level and method-level TTL settings are defined, the method-level setting takes priority.

```typescript

@Controller()
@CacheTTL(5000)
export class AppController {
  @CacheKey('custom_key')
  @CacheTTL(2000)
  findAll(): string[] {
    return [];
  }
}
```

> **Hint** The `@CacheKey()` and `@CacheTTL()` decorators are imported from the `@nestjs/cache-manager` package.

You can use the `@CacheKey()` decorator with or without a corresponding `@CacheTTL()` decorator, and vice versa, to override only the key or only the TTL. Settings that aren't overridden with a decorator use the defaults registered with the module (see [Time-to-live (TTL)](/data/caching#time-to-live-ttl)).

#### WebSockets and Microservices[#](/data/caching#websockets-and-microservices)

You can also apply the `CacheInterceptor` to WebSocket subscribers and microservice patterns (regardless of the transport used).

JS TS

```typescript

@CacheKey('events')
@UseInterceptors(CacheInterceptor)
@SubscribeMessage('events')
handleEvent(client: Client, data: string[]): string[] {
  return [];
}
```

```typescript

@CacheKey('events')
@UseInterceptors(CacheInterceptor)
@SubscribeMessage('events')
handleEvent(client, data) {
  return [];
}
```

In these contexts, the `@CacheKey()` decorator is required: it specifies the key used to store and retrieve the cached data. Without it, responses aren't cached. Also, keep in mind that you **shouldn't cache everything**. Never cache actions that perform business operations rather than only querying data.

You can also specify a cache expiration time (TTL) with the `@CacheTTL()` decorator, which overrides the default TTL:

JS TS

```typescript

@CacheKey('events')
@CacheTTL(1000)
@UseInterceptors(CacheInterceptor)
@SubscribeMessage('events')
handleEvent(client: Client, data: string[]): string[] {
  return [];
}
```

```typescript

@CacheKey('events')
@CacheTTL(1000)
@UseInterceptors(CacheInterceptor)
@SubscribeMessage('events')
handleEvent(client, data) {
  return [];
}
```

> **Hint** In HTTP applications, the `@CacheTTL()` decorator works with or without a corresponding `@CacheKey()` decorator. In WebSocket and microservice contexts, it has no effect without `@CacheKey()`, because nothing is cached without a key.

#### Adjust tracking[#](/data/caching#adjust-tracking)

By default, Nest uses the request URL (in HTTP apps) or the cache key set through the `@CacheKey()` decorator (in WebSocket and microservice apps) to associate cache records with your endpoints. Sometimes you might want to track records based on other factors, for example, HTTP headers (e.g., `Authorization` to correctly identify `profile` endpoints).

To do that, create a subclass of `CacheInterceptor` and override the `trackBy()` method:

```typescript

@Injectable()
class HttpCacheInterceptor extends CacheInterceptor {
  trackBy(context: ExecutionContext): string | undefined {
    return 'key';
  }
}
```

#### Using alternative Cache stores[#](/data/caching#using-alternative-cache-stores)

To switch to a different cache store, first install the appropriate package. For example, to use Redis, install the `@keyv/redis` package. The example below also uses the in-memory store from the `cacheable` package:

```bash

$ npm install @keyv/redis cacheable
```

With this in place, you can register the `CacheModule` with multiple stores, as shown below:

```typescript

import { Module } from '@nestjs/common';
import { CacheModule } from '@nestjs/cache-manager';
import { AppController } from './app.controller.js';
import { createKeyv } from '@keyv/redis';
import { Keyv } from 'keyv';
import { KeyvCacheableMemory } from 'cacheable';

@Module({
  imports: [
    CacheModule.registerAsync({
      useFactory: async () => {
        return {
          stores: [
            new Keyv({
              store: new KeyvCacheableMemory({ ttl: 60000, lruSize: 5000 }),
            }),
            createKeyv('redis://localhost:6379'),
          ],
        };
      },
    }),
  ],
  controllers: [AppController],
})
export class AppModule {}
```

This example registers two stores: `CacheableMemory` and a Redis store. `CacheableMemory` is an in-memory store created with the `KeyvCacheableMemory` storage adapter, while the Redis store is created with the `createKeyv()` helper from `@keyv/redis`. The `stores` array specifies the stores you want to use. The first store in the array is the default store, and the rest are fallback stores.

See the [Keyv documentation](https://keyv.org/docs/) for more information on the available stores.

#### Async configuration[#](/data/caching#async-configuration)

You may want to pass module options asynchronously instead of statically at compile time. In this case, use the `registerAsync()` method, which provides several ways to handle async configuration.

One approach is to use a factory function:

```typescript

CacheModule.registerAsync({
  useFactory: () => ({
    ttl: 5000,
  }),
});
```

The factory behaves like all other asynchronous module factories: it can be `async` and can inject dependencies through `inject`.

```typescript

CacheModule.registerAsync({
  imports: [ConfigModule],
  useFactory: async (configService: ConfigService) => ({
    ttl: configService.get('CACHE_TTL'),
  }),
  inject: [ConfigService],
});
```

Alternatively, you can use the `useClass` syntax:

```typescript

CacheModule.registerAsync({
  useClass: CacheConfigService,
});
```

This construction instantiates `CacheConfigService` inside `CacheModule` and uses it to get the options object. `CacheConfigService` has to implement the `CacheOptionsFactory` interface to provide the configuration options:

```typescript

@Injectable()
class CacheConfigService implements CacheOptionsFactory {
  createCacheOptions(): CacheModuleOptions {
    return {
      ttl: 5000,
    };
  }
}
```

To use an existing configuration provider imported from a different module, use the `useExisting` syntax:

```typescript

CacheModule.registerAsync({
  imports: [ConfigModule],
  useExisting: ConfigService,
});
```

This works the same as `useClass`, with one critical difference: `CacheModule` looks up imported modules to reuse an already-created `ConfigService` instead of instantiating its own.

> **Hint**`CacheModule#register`, `CacheModule#registerAsync`, and `CacheOptionsFactory` accept an optional generic (type argument) that narrows down store-specific configuration options, making them type-safe.

You can also pass `extraProviders` to the `registerAsync()` method. These providers are merged with the module's providers:

```typescript

CacheModule.registerAsync({
  imports: [ConfigModule],
  useClass: ConfigService,
  extraProviders: [MyAdditionalProvider],
});
```

This is useful when you want to provide additional dependencies to the factory function or the class constructor.

#### Example[#](/data/caching#example)

A working example is available in the [cache sample](https://github.com/nestjs/nest/tree/master/sample/20-cache).

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/data/caching.md)

----
url: https://docs.nestjs.com/v11/security/cors
----

* [CORS](https://docs.nestjs.com/v11/security/cors#cors)
* [Getting started](https://docs.nestjs.com/v11/security/cors#getting-started)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/security/cors.md "Suggest Edits")

### CORS

Cross-origin resource sharing (CORS) is a mechanism that allows resources to be requested from another domain. Under the hood, Nest makes use of the Express [cors](https://github.com/expressjs/cors) or Fastify [@fastify/cors](https://github.com/fastify/fastify-cors) packages depending on the underlying platform. These packages provide various options that you can customize based on your requirements.

#### Getting started[#](/security/cors#getting-started)

To enable CORS, call the `enableCors()` method on the Nest application object.

```typescript

const app = await NestFactory.create(AppModule);
app.enableCors();
await app.listen(process.env.PORT ?? 3000);
```

The `enableCors()` method takes an optional configuration object argument. The available properties of this object are described in the official [CORS](https://github.com/expressjs/cors#configuration-options) documentation. Another way is to pass a [callback function](https://github.com/expressjs/cors#configuring-cors-asynchronously) that lets you define the configuration object asynchronously based on the request (on the fly).

Alternatively, enable CORS via the `create()` method's options object. Set the `cors` property to `true` to enable CORS with default settings. Or, pass a [CORS configuration object](https://github.com/expressjs/cors#configuration-options) or [callback function](https://github.com/expressjs/cors#configuring-cors-asynchronously) as the `cors` property value to customize its behavior.

```typescript

const app = await NestFactory.create(AppModule, { cors: true });
await app.listen(process.env.PORT ?? 3000);
```

----
url: https://docs.nestjs.com/v11/recipes/cqrs
----

* [CQRS](https://docs.nestjs.com/v11/recipes/cqrs#cqrs)
* [Installation](https://docs.nestjs.com/v11/recipes/cqrs#installation)
* [Commands](https://docs.nestjs.com/v11/recipes/cqrs#commands)
* [Queries](https://docs.nestjs.com/v11/recipes/cqrs#queries)
* [Events](https://docs.nestjs.com/v11/recipes/cqrs#events)
* [Flexible Aggregate Roots](https://docs.nestjs.com/v11/recipes/cqrs#flexible-aggregate-roots)
* [Manual event publishing](https://docs.nestjs.com/v11/recipes/cqrs#manual-event-publishing)
* [Sagas](https://docs.nestjs.com/v11/recipes/cqrs#sagas)
* [Unhandled exceptions](https://docs.nestjs.com/v11/recipes/cqrs#unhandled-exceptions)
* [Subscribing to all events](https://docs.nestjs.com/v11/recipes/cqrs#subscribing-to-all-events)
* [Request-scoping](https://docs.nestjs.com/v11/recipes/cqrs#request-scoping)
* [Example](https://docs.nestjs.com/v11/recipes/cqrs#example)

```bash

$ npm install --save @nestjs/cqrs
```

Once the installation is complete, navigate to the root module of your application (usually `AppModule`), and import the `CqrsModule.forRoot()`:

```typescript

import { Module } from '@nestjs/common';
import { CqrsModule } from '@nestjs/cqrs';

@Module({
  imports: [CqrsModule.forRoot()],
})
export class AppModule {}
```

This module accepts an optional configuration object. The following options are available:

| Attribute                     | Description                                                                                                                  | Default                           |
| ----------------------------- | ---------------------------------------------------------------------------------------------------------------------------- | --------------------------------- |
| `commandPublisher`            | The publisher responsible for dispatching commands to the system.                                                            | `DefaultCommandPubSub`            |
| `eventPublisher`              | The publisher used to publish events, allowing them to be broadcasted or processed.                                          | `DefaultPubSub`                   |
| `queryPublisher`              | The publisher used for publishing queries, which can trigger data retrieval operations.                                      | `DefaultQueryPubSub`              |
| `unhandledExceptionPublisher` | Publisher responsible for handling unhandled exceptions, ensuring they are tracked and reported.                             | `DefaultUnhandledExceptionPubSub` |
| `eventIdProvider`             | Service that provides unique event IDs by generating or retrieving them from event instances.                                | `DefaultEventIdProvider`          |
| `rethrowUnhandled`            | Determines whether unhandled exceptions should be rethrown after being processed, useful for debugging and error management. | `false`                           |

#### Commands[#](/recipes/cqrs#commands)

Commands are used to change the application state. They should be task-based, rather than data centric. When a command is dispatched, it is handled by a corresponding **Command Handler**. The handler is responsible for updating the application state.

heroes-game.service.ts

JS TS

```typescript

@Injectable()
export class HeroesGameService {
  constructor(private commandBus: CommandBus) {}

  async killDragon(heroId: string, killDragonDto: KillDragonDto) {
    return this.commandBus.execute(
      new KillDragonCommand(heroId, killDragonDto.dragonId)
    );
  }
}
```

```typescript

@Injectable()
@Dependencies(CommandBus)
export class HeroesGameService {
  constructor(commandBus) {
    this.commandBus = commandBus;
  }

  async killDragon(heroId, killDragonDto) {
    return this.commandBus.execute(
      new KillDragonCommand(heroId, killDragonDto.dragonId)
    );
  }
}
```

In the code snippet above, we instantiate the `KillDragonCommand` class and pass it to the `CommandBus`'s `execute()` method. This is the demonstrated command class:

kill-dragon.command.ts

JS TS

```typescript

export class KillDragonCommand extends Command<{
  actionId: string // This type represents the command execution result
}> {
  constructor(
    public readonly heroId: string,
    public readonly dragonId: string,
  ) {
    super();
  }
}
```

```typescript

export class KillDragonCommand extends Command {
  constructor(heroId, dragonId) {
    this.heroId = heroId;
    this.dragonId = dragonId;
  }
}
```

As you can see, the `KillDragonCommand` class extends the `Command` class. The `Command` class is a simple utility class exported from the `@nestjs/cqrs` package that lets you define the command's return type. In this case, the return type is an object with an `actionId` property. Now, whenever the `KillDragonCommand` command is dispatched, the `CommandBus#execute()` method return-type will be inferred as `Promise<{ actionId: string }>`. This is useful when you want to return some data from the command handler.

> **Hint** Inheritance from the `Command` class is optional. It is only necessary if you want to define the return type of the command.

The `CommandBus` represents a **stream** of commands. It is responsible for dispatching commands to the appropriate handlers. The `execute()` method returns a promise, which resolves to the value returned by the handler.

Let's create a handler for the `KillDragonCommand` command.

kill-dragon.handler.ts

JS TS

```typescript

@CommandHandler(KillDragonCommand)
export class KillDragonHandler implements ICommandHandler<KillDragonCommand> {
  constructor(private repository: HeroesRepository) {}

  async execute(command: KillDragonCommand) {
    const { heroId, dragonId } = command;
    const hero = this.repository.findOneById(+heroId);

    hero.killEnemy(dragonId);
    await this.repository.persist(hero);

    // "ICommandHandler<KillDragonCommand>" forces you to return a value that matches the command's return type
    return {
      actionId: crypto.randomUUID(), // This value will be returned to the caller
    }
  }
}
```

```typescript

@CommandHandler(KillDragonCommand)
@Dependencies(HeroesRepository)
export class KillDragonHandler {
  constructor(repository) {
    this.repository = repository;
  }

  async execute(command) {
    const { heroId, dragonId } = command;
    const hero = this.repository.findOneById(+heroId);

    hero.killEnemy(dragonId);
    await this.repository.persist(hero);

    // "ICommandHandler<KillDragonCommand>" forces you to return a value that matches the command's return type
    return {
      actionId: crypto.randomUUID(), // This value will be returned to the caller
    }
  }
}
```

This handler retrieves the `Hero` entity from the repository, calls the `killEnemy()` method, and then persists the changes. The `KillDragonHandler` class implements the `ICommandHandler` interface, which requires the implementation of the `execute()` method. The `execute()` method receives the command object as an argument.

Note that `ICommandHandler<KillDragonCommand>` forces you to return a value that matches the command's return type. In this case, the return type is an object with an `actionId` property. This only applies to commands that inherit from the `Command` class. Otherwise, you can return whatever you want.

Lastly, make sure to register the `KillDragonHandler` as a provider in a module:

```typescript

providers: [KillDragonHandler];
```

#### Queries[#](/recipes/cqrs#queries)

Queries are used to retrieve data from the application state. They should be data centric, rather than task-based. When a query is dispatched, it is handled by a corresponding **Query Handler**. The handler is responsible for retrieving the data.

The `QueryBus` follows the same pattern as the `CommandBus`. Query handlers should implement the `IQueryHandler` interface and be annotated with the `@QueryHandler()` decorator. See the following example:

```typescript

export class GetHeroQuery extends Query<Hero> {
  constructor(public readonly heroId: string) {}
}
```

Similar to the `Command` class, the `Query` class is a simple utility class exported from the `@nestjs/cqrs` package that lets you define the query's return type. In this case, the return type is a `Hero` object. Now, whenever the `GetHeroQuery` query is dispatched, the `QueryBus#execute()` method return-type will be inferred as `Promise<Hero>`.

To retrieve the hero, we need to create a query handler:

get-hero.handler.ts

JS TS

```typescript

@QueryHandler(GetHeroQuery)
export class GetHeroHandler implements IQueryHandler<GetHeroQuery> {
  constructor(private repository: HeroesRepository) {}

  async execute(query: GetHeroQuery) {
    return this.repository.findOneById(query.heroId);
  }
}
```

```typescript

@QueryHandler(GetHeroQuery)
@Dependencies(HeroesRepository)
export class GetHeroHandler {
  constructor(repository) {
    this.repository = repository;
  }

  async execute(query) {
    return this.repository.findOneById(query.hero);
  }
}
```

The `GetHeroHandler` class implements the `IQueryHandler` interface, which requires the implementation of the `execute()` method. The `execute()` method receives the query object as an argument, and must return the data that matches the query's return type (in this case, a `Hero` object).

Lastly, make sure to register the `GetHeroHandler` as a provider in a module:

```typescript

providers: [GetHeroHandler];
```

Now, to dispatch the query, use the `QueryBus`:

```typescript

const hero = await this.queryBus.execute(new GetHeroQuery(heroId)); // "hero" will be auto-inferred as "Hero" type
```

#### Events[#](/recipes/cqrs#events)

Events are used to notify other parts of the application about changes in the application state. They are dispatched by **models** or directly using the `EventBus`. When an event is dispatched, it is handled by corresponding **Event Handlers**. Handlers can then, for example, update the read model.

For demonstration purposes, let's create an event class:

hero-killed-dragon.event.ts

JS TS

```typescript

export class HeroKilledDragonEvent {
  constructor(
    public readonly heroId: string,
    public readonly dragonId: string,
  ) {}
}
```

```typescript

export class HeroKilledDragonEvent {
  constructor(heroId, dragonId) {
    this.heroId = heroId;
    this.dragonId = dragonId;
  }
}
```

Now while events can be dispatched directly using the `EventBus.publish()` method, we can also dispatch them from the model. Let's update the `Hero` model to dispatch the `HeroKilledDragonEvent` event when the `killEnemy()` method is called.

hero.model.ts

JS TS

```typescript

export class Hero extends AggregateRoot {
  constructor(private id: string) {
    super();
  }

  killEnemy(enemyId: string) {
    // Business logic
    this.apply(new HeroKilledDragonEvent(this.id, enemyId));
  }
}
```

```typescript

export class Hero extends AggregateRoot {
  constructor(id) {
    super();
    this.id = id;
  }

  killEnemy(enemyId) {
    // Business logic
    this.apply(new HeroKilledDragonEvent(this.id, enemyId));
  }
}
```

The `apply()` method is used to dispatch events. It accepts an event object as an argument. However, since our model is not aware of the `EventBus`, we need to associate it with the model. We can do that by using the `EventPublisher` class.

kill-dragon.handler.ts

JS TS

```typescript

@CommandHandler(KillDragonCommand)
export class KillDragonHandler implements ICommandHandler<KillDragonCommand> {
  constructor(
    private repository: HeroesRepository,
    private publisher: EventPublisher,
  ) {}

  async execute(command: KillDragonCommand) {
    const { heroId, dragonId } = command;
    const hero = this.publisher.mergeObjectContext(
      await this.repository.findOneById(+heroId),
    );
    hero.killEnemy(dragonId);
    hero.commit();
  }
}
```

```typescript

@CommandHandler(KillDragonCommand)
@Dependencies(HeroesRepository, EventPublisher)
export class KillDragonHandler {
  constructor(repository, publisher) {
    this.repository = repository;
    this.publisher = publisher;
  }

  async execute(command) {
    const { heroId, dragonId } = command;
    const hero = this.publisher.mergeObjectContext(
      await this.repository.findOneById(+heroId),
    );
    hero.killEnemy(dragonId);
    hero.commit();
  }
}
```

The `EventPublisher#mergeObjectContext` method merges the event publisher into the provided object. This object must implement the `IAggregateRoot` interface (or extend the `AggregateRoot` class). Once merged, the object will be able to publish events to the events stream.

Notice that in this example we also call the `commit()` method on the model. This method is used to dispatch any outstanding events. To automatically dispatch events, we can set the `autoCommit` property to `true`:

```typescript

export class Hero extends AggregateRoot {
  constructor(private id: string) {
    super();
    this.autoCommit = true;
  }
}
```

In case we want to merge the event publisher into a non-existing object, but rather into a class, we can use the `EventPublisher#mergeClassContext` method:

```typescript

const HeroModel = this.publisher.mergeClassContext(Hero);
const hero = new HeroModel('id'); // <-- HeroModel is a class
```

Now every instance of the `HeroModel` class will be able to publish events without using `mergeObjectContext()` method.

#### Flexible Aggregate Roots[#](/recipes/cqrs#flexible-aggregate-roots)

The `AggregateRoot` class is a concrete implementation that you can extend to add event-driven capabilities to your domain models. However, this approach requires domain entities to directly extend `AggregateRoot`, which can be a limitation if your applications already have an established entity inheritance hierarchy (e.g., a base `Entity` class or domain-specific base classes like `Monster`, `Vehicle`, etc.).

To provide more flexibility, the `@nestjs/cqrs` package offers three different approaches to implementing aggregate roots:

**Approach 1: Traditional (Class Inheritance)**

This is the standard approach shown in the previous examples. It works perfectly for simple scenarios or greenfield projects.

```typescript

export class Hero extends AggregateRoot {
  constructor(private id: string) {
    super();
  }

  killEnemy(enemyId: string) {
    this.apply(new HeroKilledDragonEvent(this.id, enemyId));
  }
}
```

**Approach 2: Mixin (For existing hierarchies)**

If you already have a base class and cannot extend `AggregateRoot` directly, you can use the `WithAggregateRoot<EventBase, TBase>()` mixin function. This allows you to apply aggregate root behavior to any existing base class.

dragon.model.ts

JS TS

```typescript

abstract class Monster {
  constructor(protected readonly id: string) {}
  abstract roar(): void;
}

export class Dragon extends WithAggregateRoot(Monster) {
  roar(): void {
    console.log('Roarrrr!');
  }

  die(): void {
    this.roar();
    this.apply(new DragonDiedEvent(this.id)); // Now available via mixin!
  }
}
```

```typescript

abstract class Monster {
  constructor(id) {
    this.id = id;
  }
}

export class Dragon extends WithAggregateRoot(Monster) {
  roar() {
    console.log('Roarrrr!');
  }

  die() {
    this.roar();
    this.apply(new DragonDiedEvent(this.id));
  }
}
```

**Approach 3: Custom Implementation**

For maximum control, or if you want to keep your domain layer completely framework-agnostic, you can implement the `IAggregateRoot` interface directly. The `EventPublisher` accepts any object that implements this interface.

```typescript

export class CustomEntity implements IAggregateRoot {
  private events: IEvent[] = [];

  getUncommittedEvents() {
    return this.events;
  }

  publish(event: IEvent) {
    // custom logic
  }

  commit() {
    // custom logic
  }

  uncommit() {
    // custom logic
  }

  apply(event: IEvent) {
    this.events.push(event);
  }

  loadFromHistory(history: IEvent[]) {
    // custom logic
  }
}
```

All three approaches work seamlessly with `EventPublisher`, which accepts any object implementing the `IAggregateRoot` interface.

#### Manual event publishing[#](/recipes/cqrs#manual-event-publishing)

```typescript

this.eventBus.publish(new HeroKilledDragonEvent());
```

> **Hint** The `EventBus` is an injectable class.

Each event can have multiple **Event Handlers**.

hero-killed-dragon.handler.ts

JS TS

```typescript

@EventsHandler(HeroKilledDragonEvent)
export class HeroKilledDragonHandler implements IEventHandler<HeroKilledDragonEvent> {
  constructor(private repository: HeroesRepository) {}

  handle(event: HeroKilledDragonEvent) {
    // Business logic
  }
}
```

> **Hint** Be aware that when you start using event handlers you get out of the traditional HTTP web context.
>
> * Errors in `CommandHandlers` can still be caught by built-in [Exception filters](/v11/exception-filters).
> * Errors in `EventHandlers` can't be caught by Exception filters: you will have to handle them manually. Either by a simple `try/catch`, using [Sagas](/recipes/cqrs#sagas) by triggering a compensating event, or whatever other solution you choose.
> * HTTP Responses in `CommandHandlers` can still be sent back to the client.
> * HTTP Responses in `EventHandlers` cannot. If you want to send information to the client you could use [WebSocket](/v11/websockets/gateways), [SSE](/v11/techniques/server-sent-events), or whatever other solution you choose.

As with commands and queries, make sure to register the `HeroKilledDragonHandler` as a provider in a module:

```typescript

providers: [HeroKilledDragonHandler];
```

#### Sagas[#](/recipes/cqrs#sagas)

Saga is a long-running process that listens to events and may trigger new commands. It is usually used to manage complex workflows in the application. For example, when a user signs up, a saga may listen to the `UserRegisteredEvent` and send a welcome email to the user.

Sagas are an extremely powerful feature. A single saga may listen for 1..\* events. Using the [RxJS](https://github.com/ReactiveX/rxjs) library, we can filter, map, fork, and merge event streams to create sophisticated workflows. Each saga returns an Observable which produces a command instance. This command is then dispatched **asynchronously** by the `CommandBus`.

Let's create a saga that listens to the `HeroKilledDragonEvent` and dispatches the `DropAncientItemCommand` command.

heroes-game.saga.ts

JS TS

```typescript

@Injectable()
export class HeroesGameSagas {
  @Saga()
  dragonKilled = (events$: Observable<any>): Observable<ICommand> => {
    return events$.pipe(
      ofType(HeroKilledDragonEvent),
      map((event) => new DropAncientItemCommand(event.heroId, fakeItemID)),
    );
  }
}
```

```typescript

@Injectable()
export class HeroesGameSagas {
  @Saga()
  dragonKilled = (events$) => {
    return events$.pipe(
      ofType(HeroKilledDragonEvent),
      map((event) => new DropAncientItemCommand(event.heroId, fakeItemID)),
    );
  }
}
```

> **Hint** The `ofType` operator and the `@Saga()` decorator are exported from the `@nestjs/cqrs` package.

The `@Saga()` decorator marks the method as a saga. The `events$` argument is an Observable stream of all events. The `ofType` operator filters the stream by the specified event type. The `map` operator maps the event to a new command instance.

In this example, we map the `HeroKilledDragonEvent` to the `DropAncientItemCommand` command. The `DropAncientItemCommand` command is then auto-dispatched by the `CommandBus`.

As with query, command, and event handlers, make sure to register the `HeroesGameSagas` as a provider in a module:

```typescript

providers: [HeroesGameSagas];
```

#### Unhandled exceptions[#](/recipes/cqrs#unhandled-exceptions)

Event handlers are executed asynchronously, so they must always handle exceptions properly to prevent the application from entering an inconsistent state. If an exception is not handled, the `EventBus` will create an `UnhandledExceptionInfo` object and push it to the `UnhandledExceptionBus` stream. This stream is an `Observable` that can be used to process unhandled exceptions.

```typescript

private destroy$ = new Subject<void>();

constructor(private unhandledExceptionsBus: UnhandledExceptionBus) {
  this.unhandledExceptionsBus
    .pipe(takeUntil(this.destroy$))
    .subscribe((exceptionInfo) => {
      // Handle exception here
      // e.g. send it to external service, terminate process, or publish a new event
    });
}

onModuleDestroy() {
  this.destroy$.next();
  this.destroy$.complete();
}
```

To filter out exceptions, we can use the `ofType` operator, as follows:

```typescript

this.unhandledExceptionsBus
  .pipe(
    takeUntil(this.destroy$),
    UnhandledExceptionBus.ofType(TransactionNotAllowedException),
  )
  .subscribe((exceptionInfo) => {
    // Handle exception here
  });
```

Where `TransactionNotAllowedException` is the exception we want to filter out.

The `UnhandledExceptionInfo` object contains the following properties:

```typescript

export interface UnhandledExceptionInfo<
  Cause = IEvent | ICommand,
  Exception = any,
> {
  /**
   * The exception that was thrown.
   */
  exception: Exception;
  /**
   * The cause of the exception (event or command reference).
   */
  cause: Cause;
}
```

#### Subscribing to all events[#](/recipes/cqrs#subscribing-to-all-events)

`CommandBus`, `QueryBus` and `EventBus` are all **Observables**. This means that we can subscribe to the entire stream and, for example, process all events. For example, we can log all events to the console, or save them to the event store.

```typescript

private destroy$ = new Subject<void>();

constructor(private eventBus: EventBus) {
  this.eventBus
    .pipe(takeUntil(this.destroy$))
    .subscribe((event) => {
      // Save events to database
    });
}

onModuleDestroy() {
  this.destroy$.next();
  this.destroy$.complete();
}
```

#### Request-scoping[#](/recipes/cqrs#request-scoping)

For those coming from different programming language backgrounds, it may be surprising to learn that in Nest, most things are shared across incoming requests. This includes a connection pool to the database, singleton services with global state, and more. Keep in mind that Node.js does not follow the request/response multi-threaded stateless model, where each request is processed by a separate thread. As a result, using singleton instances is **safe** for our applications.

However, there are edge cases where a request-based lifetime for the handler might be desirable. This could include scenarios like per-request caching in GraphQL applications, request tracking, or multi-tenancy. You can learn more about how to control scopes [here](/v11/fundamentals/injection-scopes).

Using request-scoped providers alongside CQRS can be complex because the `CommandBus`, `QueryBus`, and `EventBus` are singletons. Thankfully, the `@nestjs/cqrs` package simplifies this by automatically creating a new instance of request-scoped handlers for each processed command, query, or event.

To make a handler request-scoped, you can either:

1. Depend on a request-scoped provider.
2. Explicitly set its scope to `REQUEST` using the `@CommandHandler`, `@QueryHandler`, or `@EventsHandler` decorator, as shown:

```typescript

@CommandHandler(KillDragonCommand, {
  scope: Scope.REQUEST,
})
export class KillDragonHandler {
  // Implementation here
}
```

To inject the request payload into any request-scoped provider, you use the `@Inject(REQUEST)` decorator. However, the nature of the request payload in CQRS depends on the context—it could be an HTTP request, a scheduled job, or any other operation that triggers a command.

The payload must be an instance of a class extending `AsyncContext` (provided by `@nestjs/cqrs`), which acts as the request context and holds data accessible throughout the request lifecycle.

```typescript

import { AsyncContext } from '@nestjs/cqrs';

export class MyRequest extends AsyncContext {
  constructor(public readonly user: User) {
    super();
  }
}
```

When executing a command, pass the custom request context as the second argument to the `CommandBus#execute` method:

```typescript

const myRequest = new MyRequest(user);
await this.commandBus.execute(
  new KillDragonCommand(heroId, killDragonDto.dragonId),
  myRequest,
);
```

This makes the `MyRequest` instance available as the `REQUEST` provider to the corresponding handler:

```typescript

@CommandHandler(KillDragonCommand, {
  scope: Scope.REQUEST,
})
export class KillDragonHandler {
  constructor(
    @Inject(REQUEST) private request: MyRequest, // Inject the request context
  ) {}

  // Handler implementation here
}
```

You can follow the same approach for queries:

```typescript

const myRequest = new MyRequest(user);
const hero = await this.queryBus.execute(new GetHeroQuery(heroId), myRequest);
```

And in the query handler:

```typescript

@QueryHandler(GetHeroQuery, {
  scope: Scope.REQUEST,
})
export class GetHeroHandler {
  constructor(
    @Inject(REQUEST) private request: MyRequest, // Inject the request context
  ) {}

  // Handler implementation here
}
```

For events, while you can pass the request provider to `EventBus#publish`, this is less common. Instead, use `EventPublisher` to merge the request provider into a model:

```typescript

const hero = this.publisher.mergeObjectContext(
  await this.repository.findOneById(+heroId),
  this.request, // Inject the request context here
);
```

Request-scoped event handlers subscribing to these events will have access to the request provider.

Sagas are always singleton instances because they manage long-running processes. However, you can retrieve the request provider from event objects:

```typescript

@Saga()
dragonKilled = (events$: Observable<any>): Observable<ICommand> => {
  return events$.pipe(
    ofType(HeroKilledDragonEvent),
    map((event) => {
      const request = AsyncContext.of(event); // Retrieve the request context
      const command = new DropAncientItemCommand(event.heroId, fakeItemID);

      AsyncContext.merge(request, command); // Merge the request context into the command
      return command;
    }),
  );
}
```

Alternatively, use the `request.attachTo(command)` method to tie the request context to the command.

#### Example[#](/recipes/cqrs#example)

A working example is available [here](https://github.com/kamilmysliwiec/nest-cqrs-example).

----
url: https://docs.nestjs.com/v11/graphql/unions-and-enums
----

* [Unions](https://docs.nestjs.com/v11/graphql/unions-and-enums#unions)
* [Code first](https://docs.nestjs.com/v11/graphql/unions-and-enums#code-first)
* [Schema first](https://docs.nestjs.com/v11/graphql/unions-and-enums#schema-first)
* [Enums](https://docs.nestjs.com/v11/graphql/unions-and-enums#enums)
* [Code first](https://docs.nestjs.com/v11/graphql/unions-and-enums#code-first-1)
* [Schema first](https://docs.nestjs.com/v11/graphql/unions-and-enums#schema-first-1)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/unions-and-enums.md "Suggest Edits")

### Unions

Union types are very similar to interfaces, but they don't get to specify any common fields between the types (read more [here](https://graphql.org/learn/schema/#union-types)). Unions are useful for returning disjoint data types from a single field.

#### Code first[#](/graphql/unions-and-enums#code-first)

To define a GraphQL union type, we must define classes that this union will be composed of. Following the [example](https://www.apollographql.com/docs/apollo-server/schema/unions-interfaces/#union-type) from the Apollo documentation, we'll create two classes. First, `Book`:

```typescript

import { Field, ObjectType } from '@nestjs/graphql';

@ObjectType()
export class Book {
  @Field()
  title: string;
}
```

And then `Author`:

```typescript

import { Field, ObjectType } from '@nestjs/graphql';

@ObjectType()
export class Author {
  @Field()
  name: string;
}
```

With this in place, register the `ResultUnion` union using the `createUnionType` function exported from the `@nestjs/graphql` package:

```typescript

export const ResultUnion = createUnionType({
  name: 'ResultUnion',
  types: () => [Author, Book] as const,
});
```

> **Warning** The array returned by the `types` property of the `createUnionType` function should be given a const assertion. If the const assertion is not given, a wrong declaration file will be generated at compile time, and an error will occur when using it from another project.

Now, we can reference the `ResultUnion` in our query:

```typescript

@Query(() => [ResultUnion])
search(): Array<typeof ResultUnion> {
  return [new Author(), new Book()];
}
```

This will result in generating the following part of the GraphQL schema in SDL:

```graphql

type Author {
  name: String!
}

type Book {
  title: String!
}

union ResultUnion = Author | Book

type Query {
  search: [ResultUnion!]!
}
```

The default `resolveType()` function generated by the library will extract the type based on the value returned from the resolver method. That means returning class instances instead of literal JavaScript object is obligatory.

To provide a customized `resolveType()` function, pass the `resolveType` property to the options object passed into the `createUnionType()` function, as follows:

```typescript

export const ResultUnion = createUnionType({
  name: 'ResultUnion',
  types: () => [Author, Book] as const,
  resolveType(value) {
    if (value.name) {
      return Author;
    }
    if (value.title) {
      return Book;
    }
    return null;
  },
});
```

#### Schema first[#](/graphql/unions-and-enums#schema-first)

To define a union in the schema first approach, simply create a GraphQL union with SDL.

```graphql

type Author {
  name: String!
}

type Book {
  title: String!
}

union ResultUnion = Author | Book
```

Then, you can use the typings generation feature (as shown in the [quick start](/v11/graphql/quick-start) chapter) to generate corresponding TypeScript definitions:

```typescript

export class Author {
  name: string;
}

export class Book {
  title: string;
}

export type ResultUnion = Author | Book;
```

Unions require an extra `__resolveType` field in the resolver map to determine which type the union should resolve to. Also, note that the `ResultUnionResolver` class has to be registered as a provider in any module. Let's create a `ResultUnionResolver` class and define the `__resolveType` method.

```typescript

@Resolver('ResultUnion')
export class ResultUnionResolver {
  @ResolveField()
  __resolveType(value) {
    if (value.name) {
      return 'Author';
    }
    if (value.title) {
      return 'Book';
    }
    return null;
  }
}
```

> **Hint** All decorators are exported from the `@nestjs/graphql` package.

### Enums

Enumeration types are a special kind of scalar that is restricted to a particular set of allowed values (read more [here](https://graphql.org/learn/schema/#enumeration-types)). This allows you to:

* validate that any arguments of this type are one of the allowed values
* communicate through the type system that a field will always be one of a finite set of values

#### Code first[#](/graphql/unions-and-enums#code-first-1)

When using the code first approach, you define a GraphQL enum type by simply creating a TypeScript enum.

```typescript

export enum AllowedColor {
  RED,
  GREEN,
  BLUE,
}
```

With this in place, register the `AllowedColor` enum using the `registerEnumType` function exported from the `@nestjs/graphql` package:

```typescript

registerEnumType(AllowedColor, {
  name: 'AllowedColor',
});
```

Now you can reference the `AllowedColor` in our types:

```typescript

@Field(type => AllowedColor)
favoriteColor: AllowedColor;
```

This will result in generating the following part of the GraphQL schema in SDL:

```graphql

enum AllowedColor {
  RED
  GREEN
  BLUE
}
```

To provide a description for the enum, pass the `description` property into the `registerEnumType()` function.

```typescript

registerEnumType(AllowedColor, {
  name: 'AllowedColor',
  description: 'The supported colors.',
});
```

To provide a description for the enum values, or to mark a value as deprecated, pass the `valuesMap` property, as follows:

```typescript

registerEnumType(AllowedColor, {
  name: 'AllowedColor',
  description: 'The supported colors.',
  valuesMap: {
    RED: {
      description: 'The default color.',
    },
    BLUE: {
      deprecationReason: 'Too blue.',
    },
  },
});
```

This will generate the following GraphQL schema in SDL:

```graphql

"""
The supported colors.
"""
enum AllowedColor {
  """
  The default color.
  """
  RED
  GREEN
  BLUE @deprecated(reason: "Too blue.")
}
```

#### Schema first[#](/graphql/unions-and-enums#schema-first-1)

To define an enumerator in the schema first approach, simply create a GraphQL enum with SDL.

```graphql

enum AllowedColor {
  RED
  GREEN
  BLUE
}
```

Then you can use the typings generation feature (as shown in the [quick start](/v11/graphql/quick-start) chapter) to generate corresponding TypeScript definitions:

```typescript

export enum AllowedColor {
  RED
  GREEN
  BLUE
}
```

Sometimes a backend forces a different value for an enum internally than in the public API. In this example the API contains `RED`, however in resolvers we may use `#f00` instead (read more [here](https://www.apollographql.com/docs/apollo-server/schema/scalars-enums/#internal-values)). To accomplish this, declare a resolver object for the `AllowedColor` enum:

```typescript

export const allowedColorResolver: Record<keyof typeof AllowedColor, any> = {
  RED: '#f00',
};
```

> **Hint** All decorators are exported from the `@nestjs/graphql` package.

Then use this resolver object together with the `resolvers` property of the `GraphQLModule#forRoot()` method, as follows:

```typescript

GraphQLModule.forRoot({
  resolvers: {
    AllowedColor: allowedColorResolver,
  },
});
```

----
url: https://docs.nestjs.com/v5/websockets/adapter
----

### Adapters

The WebSockets module is based on [socket.io](https://github.com/socketio/socket.io) package, but you can bring your own library (or even a native implementation), by making use of `WebSocketAdapter` interface. This interface forces to implement few methods described in the following table:

|                        |                                                                 |
| ---------------------- | --------------------------------------------------------------- |
| `create`               | Creates a socket instance based on passed arguments             |
| `bindClientConnect`    | Binds the client connection event                               |
| `bindClientDisconnect` | Binds the client disconnection event (optional\*)               |
| `bindMessageHandlers`  | Binds the incoming message to the corresponding message handler |
| `close`                | Terminates a server instance                                    |

#### Extend socket.io

The socket.io package is wrapped in an `IoAdapter` class. What if you would like to enhance the basic functionality of the adapter? For instance, your technical requirements require a capability to broadcast events across multiple load-balanced instances of your web service. For this, you can extend `IoAdapter` and override a single method which responsibility is to instantiate new socket.io servers. But first of all, let's install the required package.

```bash

$ npm i --save socket.io-redis
```

Once the package is installed, we can create a `RedisIoAdapter` class.

TypeScript

```typescript

import { IoAdapter } from '@nestjs/websockets';
import * as redisIoAdapter from 'socket.io-redis';

const redisAdapter = redisIoAdapter({ host: 'localhost', port: 6379 });

export class RedisIoAdapter extends IoAdapter {
  createIOServer(port: number, options?: any): any {
    const server = super.createIOServer(port, options);
    server.adapter(redisAdapter);
    return server;
  }
}
```

Afterward, simply switch to your newly created Redis adapter.

TypeScript

```typescript

const app = await NestFactory.create(ApplicationModule);
app.useWebSocketAdapter(new RedisIoAdapter(app));
```

#### Ws library

Another built-in adapter is a `WsAdapter` which in turn acts like a proxy between the framework and integrate blazing fast and thoroughly tested [ws](https://github.com/websockets/ws) library. This adapter is fully compatible with native browser WebSockets and is far faster than socket.io package. Unluckily, it has significantly fewer functionalities available out-of-the-box. In some cases, you may just don't necesserily need them though.

TypeScript

```typescript

const app = await NestFactory.create(ApplicationModule);
app.useWebSocketAdapter(new WsAdapter(app));
```

> **Hint** The `WsAdapter` is imported from `@nestjs/websockets`.

#### Advanced (custom adapter)

For demonstration purposes, we are going to handwritten integrate the [ws](https://github.com/websockets/ws) library. As mentioned, the adapter for this library is already created and is exposed from the `@nestjs/websockets` package as a `WsAdapter` class. Here is how the simplified implementation could potentialy looks like:

ws-adapter.ts

JS TS

TypeScript

```typescript

import * as WebSocket from 'ws';
import { WebSocketAdapter, MessageMappingProperties, INestApplicationContext } from '@nestjs/common';
import { Observable, fromEvent, empty } from 'rxjs';
import { mergeMap, filter, tap } from 'rxjs/operators';

export class WsAdapter implements WebSocketAdapter {
  constructor(private readonly app: INestApplicationContext) {}

  create(port: number, options: any = {}): any {
    return new ws.Server({ port, ...options });
  }

  bindClientConnect(server, callback: (...args) => void) {
    server.on('connection', callback);
  }

  bindMessageHandlers(
    client: WebSocket,
    handlers: MessageMappingProperties[],
    process: (data: any) => Observable<any>,
  ) {
    fromEvent(client, 'message')
      .pipe(
        mergeMap(data => this.bindMessageHandler(data, handlers, process)),
        filter(result => result),
      )
      .subscribe(response => client.send(JSON.stringify(response)));
  }

  bindMessageHandler(
    buffer,
    handlers: MessageMappingProperties[],
    process: (data: any) => Observable<any>,
  ): Observable<any> {
    const message = JSON.parse(buffer.data);
    const messageHandler = handlers.find(
      handler => handler.message === message.event,
    );
    if (!messageHandler) {
      return empty;
    }
    return process(messageHandler.callback(message.data));
  }

  close(server) {
    server.close();
  }
}
```

TypeScript

```typescript

import * as WebSocket from 'ws';
import { mergeMap, filter, tap } from 'rxjs/operators';
import { fromEvent, empty } from 'rxjs';

export class WsAdapter {
  constructor(app) {
    this.app = app;
  }

  create(port, options = {}) {
    return new ws.Server({ port, ...options });
  }

  bindClientConnect(server, callback) {
    server.on('connection', callback);
  }

  bindMessageHandlers(client, handlers, process) {
    fromEvent(client, 'message')
      .pipe(
        mergeMap(data => this.bindMessageHandler(data, handlers, process)),
        filter(result => !!result),
      )
      .subscribe(response => client.send(JSON.stringify(response)));
  }

  bindMessageHandler(buffer, handlers, process) {
    const message = JSON.parse(buffer.data);
    const messageHandler = handlers.find(
      handler => handler.message === message.event,
    );
    if (!messageHandler) {
      return empty;
    }
    return process(messageHandler.callback(message.data));
  }

  close(server) {
    server.close();
  }
}
```

> **Hint** When you want to take advantage of [ws](https://github.com/websockets/ws) library, use built-in `WsAdapter` instead of creating your own one.

Then, we can set up a custom adapter using `useWebSocketAdapter()` method:

main.ts

JS TS

TypeScript

```typescript

const app = await NestFactory.create(ApplicationModule);
app.useWebSocketAdapter(new WsAdapter(app));
```

#### Example

A working example that uses `WsAdapter` is available [here](https://github.com/nestjs/nest/tree/master/sample/16-gateways-ws).

* Adapters
* Extend socket.io
* Ws library
* Advanced (custom adapter)

----
url: https://docs.nestjs.com/reliability/workflows
----

[Skip to content](#content)

On this page

* [Durable workflows](https://docs.nestjs.com/reliability/workflows#durable-workflows)
* [Workflows, queues or sagas?](https://docs.nestjs.com/reliability/workflows#workflows-queues-or-sagas)
* [Installation](https://docs.nestjs.com/reliability/workflows#installation)
* [Write the workflow](https://docs.nestjs.com/reliability/workflows#write-the-workflow)
* [Start the workflow](https://docs.nestjs.com/reliability/workflows#start-the-workflow)
* [Wait for signals and timers](https://docs.nestjs.com/reliability/workflows#wait-for-signals-and-timers)
* [Cancel and operate workflows](https://docs.nestjs.com/reliability/workflows#cancel-and-operate-workflows)
* [Limits, children and batch work](https://docs.nestjs.com/reliability/workflows#limits-children-and-batch-work)
* [Deploy changes safely](https://docs.nestjs.com/reliability/workflows#deploy-changes-safely)
* [Try it and test it](https://docs.nestjs.com/reliability/workflows#try-it-and-test-it)
* [With CQRS](https://docs.nestjs.com/reliability/workflows#with-cqrs)
* [Prepare for production](https://docs.nestjs.com/reliability/workflows#prepare-for-production)
* [Reference](https://docs.nestjs.com/reliability/workflows#reference)

### Durable workflows

Some business processes take days and span several systems. In an online store for cat food and supplies, fulfilling an order means:

1. Charge the customer's card with the payment provider.
2. Reserve the items in the warehouse.
3. Wait up to 3 days for the carrier's `shipment.delivered` webhook.
4. If it never arrives, or the carrier brings the parcel back, refund the charge and release the stock. Otherwise, wait 7 days and ask the customer for a review.

The process must survive deploys and crashes, charge exactly once, undo its work when it fails, and tell support where every order stands. With `@nestjs/workflows` you write it as one `async` method on an injectable class. Each side effect runs in a journaled **step**. After a restart, the method runs again from the top, and completed steps return their recorded results instead of running twice. Waits and sleeps park the instance in your own database, where any process on any host can pick it up when it's due. There is no workflow server to run.

#### Workflows, queues or sagas?[#](/reliability/workflows#workflows-queues-or-sagas)

Nest already has two tools for work that happens later, and each stays the right choice for its job:

* **[BullMQ](/application/queues#bullmq-installation)** runs one unit of background work at a time, such as sending an email or transcoding a video, with concurrency limits, rate limits, priorities, and delayed or repeatable jobs. A process with a single delayed action ("cancel the order if it isn't paid within an hour") is a delayed job plus a status column.
* **[CQRS sagas](/recipes/cqrs#sagas)** turn events into commands inside one process. They fit reactions where losing in-flight state on a restart is acceptable. Where it isn't, the same events can start and signal workflows: see [With CQRS](/reliability/workflows#with-cqrs).
* **Workflows** fit a process with several steps that waits hours or days for timers or outside events, must survive restarts and deploys, and must undo its completed steps when it fails or is cancelled. They have concurrency limits, rate limits, priorities and schedules of their own, and a step can still hand heavy work to a BullMQ queue.

A workflow instance is a row in your application's database, so starting one can be part of the transaction that saves the order: pass the transaction to `start()` as its `transaction` option. The order and its fulfilment commit together or not at all. A job queue writes through its own connection (Redis, or BullMQ's own PostgreSQL pool), so saving an order and enqueueing its job are two writes, and a crash between them loses one. The same goes for signals: a webhook can update the order and wake its workflow in one transaction.

The tutorial below shows where queues and sagas run out: code that continues after a durable wait ([Sleep for a week, then ask for a review](/reliability/workflows#sleep-for-a-week-then-ask-for-a-review)), an event racing a deadline ([Wait for the delivery webhook](/reliability/workflows#wait-for-the-delivery-webhook)), and compensation that survives a crash ([Let customer support cancel an order](/reliability/workflows#let-customer-support-cancel-an-order)).

#### Installation[#](/reliability/workflows#installation)

To get started, install the required dependency:

```bash

$ npm i --save @nestjs/workflows
```

The tutorial keeps its workflows in PostgreSQL, with the package's own store, and uses Drizzle, registered through [`@nestjs/drizzle`](/data/drizzle). [Keep workflows in your database](/reliability/workflows#keep-workflows-in-your-database) shows the store with TypeORM too, and the package's MySQL store. The tests on this page use [PGlite](https://pglite.dev), so they need no server.

Orders live in the example application's own table, `orders`. The tutorial uses in-memory stand-ins for the payment provider's SDK (`PaymentProviderClient`), the stock table (`InventoryService`) and the mail provider (`MailService`). Like the real systems, they deduplicate requests by idempotency key. Orders have this shape:

orders/order.ts

JS TS

```typescript

export interface OrderItem {
  productId: string;
  quantity: number;
  /** Unit price in cents. */
  price: number;
}

/** How the carrier ships it. Express orders are fulfilled first. */
export type Shipping = 'standard' | 'express';

export type OrderStatus = 'placed' | 'delivered' | 'returned' | 'cancelled';

export interface Order {
  id: string;
  userId: string;
  items: OrderItem[];
  shipping: Shipping;
  /** In cents. */
  total: number;
  status: OrderStatus;
}

export class PlaceOrderDto {
  userId: string;
  items: OrderItem[];
  /** Default 'standard'. */
  shipping?: Shipping;
}

export interface FulfilmentResult {
  chargeId: string;
  trackingNumber: string;
}
```

##### Register the module[#](/reliability/workflows#register-the-module)

Import `WorkflowsModule` once, in the root module, next to [`DrizzleModule`](/data/drizzle), which registers the Drizzle database that `@InjectDrizzle()` injects. Workflow classes are ordinary providers, so they go in `providers` next to the services they inject. This is the finished module: the workflows and the controllers it lists are written in the following sections, and the first provider is the package's PostgreSQL store, which [Keep workflows in your database](/reliability/workflows#keep-workflows-in-your-database) explains.

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { DrizzleModule, getDrizzleToken } from '@nestjs/drizzle';
import { WorkflowsModule, WorkflowStorage } from '@nestjs/workflows';
import { fromDrizzle, PostgresWorkflowStore } from '@nestjs/workflows/postgres';
import { drizzle } from 'drizzle-orm/node-postgres';
import type { Database } from './database/drizzle.js';
import * as schema from './database/schema.js';
import { InventoryService } from './inventory/inventory.service.js';
import { InvoiceBatchWorkflow } from './invoices/invoice-batch.workflow.js';
import { InvoicesController } from './invoices/invoices.controller.js';
import { InvoicesService } from './invoices/invoices.service.js';
import { MailService } from './mail/mail.service.js';
import { OrderFulfilmentWorkflow } from './orders/order-fulfilment.workflow.js';
import { OrdersController } from './orders/orders.controller.js';
import { OrdersService } from './orders/orders.service.js';
import { PaymentProviderClient } from './payments/payment-provider.client.js';
import { PaymentsService } from './payments/payments.service.js';
import { CarrierWebhookController } from './shipping/carrier-webhook.controller.js';

@Module({
  imports: [
    DrizzleModule.forRootAsync({
      // Drizzle on PostgreSQL: a pg pool on DATABASE_URL, closed after the worker handed its instances back
      useFactory: () => ({ drizzle, connection: process.env.DATABASE_URL!, schema }),
    }),
    WorkflowsModule.forRoot({
      worker: {
        concurrency: 10, // instances this process executes at once
        leaseDuration: '30s', // how long a crashed process keeps its instances
        shutdownTimeout: '10s', // how long a deploy waits for running steps
      },
    }),
  ],
  controllers: [OrdersController, CarrierWebhookController, InvoicesController],
  providers: [
    {
      // Instances and journals in your database, in a schema of their own (nest_workflows)
      provide: PostgresWorkflowStore,
      inject: [getDrizzleToken(), WorkflowStorage],
      useFactory: (db: Database, workflowStorage: WorkflowStorage) =>
        new PostgresWorkflowStore({ executor: fromDrizzle(db) }, workflowStorage),
    },
    OrdersService,
    PaymentProviderClient,
    PaymentsService,
    InventoryService,
    MailService,
    InvoicesService,
    OrderFulfilmentWorkflow,
    InvoiceBatchWorkflow,
  ],
})
export class AppModule {}
```

> **Hint** The tutorial reads `process.env` directly, to stay short. In an application, load the environment through [`@nestjs/config`](/application/configuration) with a validation schema, so a missing `DATABASE_URL` stops the application at startup, and read it from `ConfigService` in the factory.

Every option is optional: `WorkflowsModule.forRoot()` works as is. To read them from `ConfigService`, use `forRootAsync()` with a factory, or with a `useClass` class that implements `WorkflowsOptionsFactory` and its `createWorkflowsOptions()` method.

The `worker` runs inside your application process. It polls for due instances every second, and a local `start()` or `signal()` wakes it immediately. It claims due instances under a lease and renews the lease every third of `leaseDuration`. If the process dies, its instances are claimable again once the lease expires. Set `worker: false` on processes that should only start, signal and inspect workflows, such as API pods. A step gets 3 attempts by default, with a backoff that starts at 1 second and doubles up to 5 minutes. A `retry` option here changes that default.

In `main.ts`, enable shutdown hooks. On `SIGTERM` the worker stops claiming, aborts the `signal` of running steps, waits up to `shutdownTimeout`, and hands the instances it stopped back to the store. Another process then picks them up at once instead of waiting for the lease.

main.ts

JS TS

```typescript

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module.js';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  // On SIGTERM, stop claiming work and hand running instances back.
  app.enableShutdownHooks();
  await app.listen(process.env.PORT ?? 3000);
}
await bootstrap();
```

##### Keep workflows in your database[#](/reliability/workflows#keep-workflows-in-your-database)

Workflow instances, their journals, the signals they wait for and the signals sent live in a **store**. Until you register one, the module keeps them in memory: fine for a first run, but a restart loses every running order, and two processes don't share them.

> **Warning** With `NODE_ENV=production` and no store registered, startup fails, unless you set `allowInMemoryStorage: true`.

On PostgreSQL, register the package's store, `PostgresWorkflowStore` from `@nestjs/workflows/postgres`. It runs its SQL through the database client your application already has, so it can join your transactions. It's an ordinary provider, registered once, in the root module, next to `WorkflowsModule`: both are application-wide. In `AppModule` above, it's the first provider: a factory that injects the Drizzle database and the `WorkflowStorage` registry, which the store registers itself with.

`fromDrizzle(db)` is the store's **executor**: it runs the store's statements through your Drizzle database, whichever driver it uses, such as `pg` or PGlite. `fromPg(pool)`, `fromTypeOrm(dataSource)`, `fromPrisma(prisma)` and `fromKysely(db)` do the same for a node-postgres pool, TypeORM, Prisma and Kysely. At startup, the module logs `WorkflowStorage: PostgresWorkflowStore`.

**The schema.** There's nothing to create for workflows: no tables, entities or Prisma models. The store keeps its tables in a schema of its own, `nest_workflows` (the `schema` option names another), and creates and migrates it itself. On MySQL, which has no schemas, they're tables of the connection's database, with the schema's name as their prefix: `nest_workflows_instances` and so on.

| Table                        | What it holds                                                                            |
| ---------------------------- | ---------------------------------------------------------------------------------------- |
| `nest_workflows.instances`   | Each workflow instance: its input, status, output or error, when it's due, and its lease |
| `nest_workflows.journal`     | Each instance's recorded steps, sleeps, waits and compensations, with their results      |
| `nest_workflows.waits`       | The signals a suspended instance waits for                                               |
| `nest_workflows.signals`     | The signals sent, until `purge()` deletes the ones no instance can take any more         |
| `nest_workflows.schedules`   | The schedules, with their spec, state and next run                                       |
| `nest_workflows.rate_limits` | The rate-limit windows, per workflow and key                                             |
| `nest_workflows.migrations`  | The versions of the store's schema applied                                               |

They belong to the store: your migrations don't create them, and your own tables can't collide with them.

**Migrations.** The package ships the schema as versioned migrations, and the store applies them itself. With the `migrate` option, it applies the ones the schema hasn't had yet at startup, before the worker runs, in one transaction that holds an advisory lock: of several processes that start together, one migrates, and the others find nothing left to do. `migrate` defaults to `true`, except with `NODE_ENV=production`. So in development and in tests, the store creates its schema on the first start, and your migrations only create your own tables, here `orders`.

In production, apply the migrations before the new version of your application starts, as you apply your own, so that no process changes the schema while it boots: in the middle of a rolling deploy, that would lock busy tables, and a least-privilege database user can't do it anyway. The package's command line does it from your deploy step, next to `npx drizzle-kit migrate`. It reads the database from `DATABASE_URL`, or from `--url`, and needs `pg` installed:

```bash

$ npx @nestjs/workflows status
Schema "nest_workflows" is at version 0; this version of @nestjs/workflows needs version 1.
$ npx @nestjs/workflows migrate
Migrated schema "nest_workflows" to version 1 (applied 1).
```

`status` exits with 1 while the schema is behind, which makes it a check for CI. To apply the migrations with your own migration tool instead, take their SQL from `npx @nestjs/workflows sql`, or from `PostgresWorkflowStore.migrationSql()` in code: the statements of every migration, one per paragraph, with the bookkeeping that records the version. Run them in one transaction, as TypeORM's and Drizzle's migrators do. With TypeORM, that's a migration of your own, next to the ones it generates for your entities:

typeorm/migrations/1790801342207-WorkflowStore.ts

JS TS

```typescript

import { PostgresWorkflowStore } from '@nestjs/workflows/postgres';
import type { MigrationInterface, QueryRunner } from 'typeorm';

export class WorkflowStore1790801342207 implements MigrationInterface {
  async up(queryRunner: QueryRunner): Promise<void> {
    await queryRunner.query(PostgresWorkflowStore.migrationSql());
  }

  async down(): Promise<void> {
    throw new Error('The workflow store has no down migrations.');
  }
}
```

With drizzle-kit, create a custom migration, and fill it with the SQL, a `--> statement-breakpoint` line between the statements: Drizzle's migrator then runs them one at a time, which PGlite requires. In code, `migrationSql()` with `statementBreakpoints: true` returns the same.

```bash

$ npx drizzle-kit generate --custom --name=workflows
$ npx @nestjs/workflows sql --statement-breakpoints > drizzle/0001_workflows.sql
```

On MySQL, `MySqlWorkflowStore.migrationStatements()` returns the statements one per string, and a TypeORM migration runs them one per call:

typeorm/mysql-migrations/1790801342207-WorkflowStore.ts

JS TS

```typescript

for (const statement of MySqlWorkflowStore.migrationStatements()) {
  await queryRunner.query(statement);
}
```

With `migrate` off, a store whose schema is behind fails the startup with a `WorkflowSchemaError` that names these three ways, and fails every call the same way until the schema catches up, which it notices without a restart. Migrations only ever add tables, columns and indexes, so during a rolling deploy, the previous version of your application keeps running on the migrated schema. There are no down migrations.

**Transactions.**`start()` and `signal()` take your transaction as their `transaction` option: with Drizzle, the `tx` that `db.transaction()` hands its callback, as [Start it with the order](/reliability/workflows#start-it-with-the-order) shows. The store runs its statements on that transaction, so they commit or roll back with your writes. It refuses the database itself, whose statements would commit on their own, with a `TypeError` that says what to pass. With the other executors, pass a node-postgres client after `BEGIN` (not the pool), TypeORM's `EntityManager` from `dataSource.transaction()`, Prisma's interactive transaction client, or a Kysely transaction.

**Isolation.** The store relies on READ COMMITTED, PostgreSQL's default isolation level: its statements race each other, and under a stricter level they would fail with serialization errors. At startup, it checks the database's `default_transaction_isolation`, and fails if it's stricter. A `signal()` in your transaction needs a READ COMMITTED transaction too, or its wake-ups could miss waits committed after the transaction's snapshot: it's refused with a `TypeError` otherwise.

**With TypeORM.**`TypeOrmModule` takes the place of `DrizzleModule` in `AppModule`, and the store runs on the `DataSource` it provides, through `fromTypeOrm()`:

typeorm/app.module.ts

JS TS

```typescript

{
  // Instances and journals in your database, in a schema of their own (nest_workflows)
  provide: PostgresWorkflowStore,
  inject: [DataSource, WorkflowStorage],
  useFactory: (dataSource: DataSource, workflowStorage: WorkflowStorage) =>
    new PostgresWorkflowStore({ executor: fromTypeOrm(dataSource) }, workflowStorage),
},
```

Where the tutorial passes Drizzle's `tx` to `start()` and `signal()`, pass the `EntityManager` that `dataSource.transaction()` hands its callback. The store refuses `dataSource.manager`, whose writes would commit on their own. This is the order service's `place()`, from [Start it with the order](/reliability/workflows#start-it-with-the-order), with TypeORM:

typeorm/orders.service.ts

JS TS

```typescript

return this.dataSource.transaction(async (manager) => {
  await manager.insert(OrderEntity, order);
  // Same transaction: the fulfilment exists if and only if the order does.
  const fulfilment = await this.workflowClient.start(OrderFulfilmentWorkflow, order, {
    id: fulfilmentId(order.id),
    transaction: manager,
  });
  return { ...order, fulfilment };
});
```

> **Hint** With Prisma, pass the client to `fromPrisma()`, and as `transaction`, the transaction client that `prisma.$transaction()` hands its callback. The store's own transactions wait up to 10 seconds for a connection and run for up to a minute, longer than Prisma's defaults: the second argument of `fromPrisma()` changes that, with `maxWait` and `timeout`. If your application signals in bursts, give its own transactions a longer `maxWait` too, since signals queue behind each other.

**With MySQL.** The package has a store for MySQL 8.4 LTS and 9.x too, `MySqlWorkflowStore` from `@nestjs/workflows/mysql`, with executors of the same names. MariaDB isn't supported yet: the store refuses it at startup. The provider is the same, with the MySQL store's class and executor. This is `AppModule` with Drizzle on a mysql2 pool, where `mode: 'default'` is Drizzle's setting for a schema on MySQL:

mysql/app.module.ts

JS TS

```typescript

import { fromDrizzle, MySqlWorkflowStore } from '@nestjs/workflows/mysql';
import { drizzle } from 'drizzle-orm/mysql2';

@Module({
  imports: [
    DrizzleModule.forRootAsync({
      // Drizzle on MySQL: a mysql2 pool on DATABASE_URL (mysql://...), whose path names the database
      useFactory: () => ({ drizzle, connection: process.env.DATABASE_URL!, schema, mode: 'default' as const }),
    }),
    // ...
  ],
  providers: [
    {
      // Instances and journals in your database, in tables of their own (nest_workflows_*)
      provide: MySqlWorkflowStore,
      inject: [getDrizzleToken(), WorkflowStorage],
      useFactory: (db: Database, workflowStorage: WorkflowStorage) =>
        new MySqlWorkflowStore({ executor: fromDrizzle(db) }, workflowStorage),
    },
    // ...
  ],
})
export class AppModule {}
```

`fromMysql2(pool)`, `fromTypeOrm(dataSource)`, `fromPrisma(prisma)` and `fromKysely(db)` do the same for a mysql2 pool, TypeORM, Prisma (through `@prisma/adapter-mariadb`) and Kysely. `start()` and `signal()` take the same transaction objects as on PostgreSQL, and with mysql2, a connection after `beginTransaction()`. What differs from PostgreSQL:

* **The tables.** MySQL has no schemas inside a database, so the store keeps its tables in the connection's database, the one the URL's path names, and the `schema` option is the prefix of their names: `nest_workflows_instances`, `nest_workflows_signals` and so on, next to `nest_workflows_migrations` and `nest_workflows_locks`, which hold its versions and its locks.
* **Bounded keys.** Ids, names and keys are indexed columns of limited length. An instance id, a workflow or signal name, a signal's `key` and `id`, and a concurrency or rate-limit key hold 255 characters, a schedule id 230, and a step, sleep or wait name 512. `start()` and `signal()` reject a longer one with a `RangeError` before anything is written. Keys still compare exactly, as on PostgreSQL.
* **Your transactions.**`start()` and `signal()` with the `transaction` option work at REPEATABLE READ, MySQL's default, and at READ COMMITTED: the wake-up reads the waits with a locking read, which also sees those committed after your transaction's snapshot. Avoid SERIALIZABLE, where MySQL turns plain reads into locking ones: a `start()` in such a transaction would hold every signal up until the transaction ends.
* **Deadlocks.** MySQL breaks a deadlock by rolling back one of the transactions, with error 1213 (`ER_LOCK_DEADLOCK`). The store runs its own transactions again. In yours, the rollback also took your writes, so the error reaches your code: run the transaction again. A transaction that writes an order and then signals, while another one signals and then writes the same order, deadlocks that way.
* **Migrations.** MySQL commits each DDL statement on its own, so the migrations can't run in one transaction. The store and `npx @nestjs/workflows migrate` apply them one statement at a time, under a lock (`GET_LOCK()`), so processes that start together still migrate once, and a run that stopped halfway resumes where it stopped. The command line takes a `mysql://` URL and then needs `mysql2`, and `npx @nestjs/workflows sql --dialect mysql` prints the SQL. With your own tool, apply the statements in order, each once, one per call, as the TypeORM migration above does: for drizzle-kit, whose MySQL migrator sends one statement per breakpoint, add `--statement-breakpoints`.

For another database, write a store of your own: [The store contract](/reliability/workflows#the-store-contract) says what it must do.

#### Write the workflow[#](/reliability/workflows#write-the-workflow)

Every side effect needs an idempotency key. A step runs **at least once**: if the process dies after the payment provider charged the card but before the result reached the journal, the step runs again. The engine hands each step an `idempotencyKey` that stays the same across attempts and processes (`<instance id>:<step name>`). Pass it to the system you call, and the effect happens once:

payments/payments.service.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { NonRetryableStepError } from '@nestjs/workflows';
import type { Order } from '../orders/order.js';
import { PaymentProviderClient } from './payment-provider.client.js';

export interface Charge {
  chargeId: string;
  amount: number;
}

@Injectable()
export class PaymentsService {
  constructor(private readonly paymentProviderClient: PaymentProviderClient) {}

  async charge(order: Order, idempotencyKey: string): Promise<Charge> {
    // The payment provider answers a repeated Idempotency-Key with the first response,
    // so a retried step never charges the card twice.
    const charge = await this.paymentProviderClient.createCharge(
      { amount: order.total, currency: 'USD', reference: order.id },
      { idempotencyKey },
    );
    if (charge.status === 'declined') {
      // Retrying won't help. Fail the step now.
      throw new NonRetryableStepError(`The payment provider declined the card for order ${order.id}.`);
    }
    return { chargeId: charge.id, amount: charge.amount };
  }

  async refund(chargeId: string, idempotencyKey: string): Promise<void> {
    await this.paymentProviderClient.createRefund({ chargeId }, { idempotencyKey });
  }
}
```

`InventoryService.reserve()` follows the same idea without an external API: it uses the key as the reservation's primary key, so a retry finds the reservation it already made. It throws `NonRetryableStepError` when a product is out of stock. `MailService` passes the key to the mail provider as the message id.

Now the workflow. Decorate a class with `@Workflow()`, give it a name, and implement `run()`:

orders/order-fulfilment.workflow\.ts

JS TS

```typescript

import { Workflow, type WorkflowContext, type WorkflowRunner } from '@nestjs/workflows';
import { InventoryService } from '../inventory/inventory.service.js';
import { MailService } from '../mail/mail.service.js';
import { PaymentsService } from '../payments/payments.service.js';
import { shipmentDelivered } from '../shipping/carrier-event.js';
import type { FulfilmentResult, Order } from './order.js';

/** One fulfilment per order: the order id is the workflow instance id. */
export const fulfilmentId = (orderId: string) => `order-${orderId}`;

@Workflow('order-fulfilment')
export class OrderFulfilmentWorkflow implements WorkflowRunner<Order, FulfilmentResult> {
  constructor(
    private readonly paymentsService: PaymentsService,
    private readonly inventoryService: InventoryService,
    private readonly mailService: MailService,
  ) {}

  async run(ctx: WorkflowContext, order: Order): Promise<FulfilmentResult> {
    const charge = await ctx.step(
      'charge-payment',
      ({ idempotencyKey }) => this.paymentsService.charge(order, idempotencyKey),
      {
        retry: { attempts: 5, backoff: { delay: '2s' } },
        compensate: (charge, { idempotencyKey }) => this.paymentsService.refund(charge.chargeId, idempotencyKey),
      },
    );

    await ctx.step(
      'reserve-stock',
      ({ idempotencyKey }) => this.inventoryService.reserve(order.items, idempotencyKey),
      { compensate: ({ reservationId }) => this.inventoryService.release(reservationId) },
    );

    // ...the delivery wait and the review request continue here
  }
}
```

`ctx.step()` runs the function once and writes its result to the journal. Whenever the instance runs again (after a wait, a sleep or a crash), `run()` starts from the top and `charge-payment` returns the journaled charge without calling the payment provider. Results must be JSON-serializable, and they come back in their JSON form, on the first run too: a `Date` is a string. The return type says so (`Journaled<Charge>`), so TypeScript flags code that treats a journaled value as a live object.

* **`retry`**: `attempts` counts the first attempt too, and `backoff` sets the wait before each retry: a `delay`, a growth `factor`, a `maxDelay` cap and optional `jitter`. A number is shorthand for the attempts, and `false` means a single attempt. A failed attempt parks the instance until the backoff has elapsed, so a retry survives a restart too. A `NonRetryableStepError`, such as a declined card, fails the step at once.
* **`compensate`**: registered when the step completes. If the workflow later fails or is cancelled, the compensations of completed steps run in reverse order. Each is journaled and retried like a step, with its own idempotency key. If `reserve-stock` fails because an item is out of stock, the charge is refunded. [Sleep for a week, then ask for a review](/reliability/workflows#sleep-for-a-week-then-ask-for-a-review) shows how to end this once the order is delivered.

Steps can also run in parallel. To reserve each item on its own, start one step per item and wait for them together. Each step has its own name, with the item's index in it, and so its own idempotency key and compensation:

orders/order-fulfilment.workflow\.ts

JS TS

```typescript

// One step per item, all at once: each reserves its item under its own key, and
// releases it if the order is undone.
await Promise.all(
  order.items.map((item, i) =>
    ctx.step(
      `reserve-item-${i}`,
      ({ idempotencyKey }) => this.inventoryService.reserve([item], idempotencyKey),
      { compensate: ({ reservationId }) => this.inventoryService.release(reservationId) },
    ),
  ),
);
```

If one item is out of stock, its step fails, the others finish, and the compensations of the ones that completed run: the reservations are released, then the charge is refunded. Compensations run in the reverse order of the `ctx.step()` calls, whichever step finished first. The rest of the tutorial keeps the single `reserve-stock` step.

The class is a singleton shared by every running order, and constructor injection works as usual. Keep per-order state in local variables, never on `this`.

#### Start the workflow[#](/reliability/workflows#start-the-workflow)

##### Start it with the order[#](/reliability/workflows#start-it-with-the-order)

An order and its fulfilment belong together: an order that nothing fulfils is as bad as a fulfilment charging for an order that was never saved. So `OrdersService` saves the order and starts the workflow in one Drizzle transaction. `WorkflowClient` starts instances; pass it the transaction's `tx`:

orders/orders.service.ts

JS TS

```typescript

import { randomUUID } from 'node:crypto';
import { Injectable, NotFoundException } from '@nestjs/common';
import { InjectDrizzle } from '@nestjs/drizzle';
import { WorkflowClient } from '@nestjs/workflows';
import { eq } from 'drizzle-orm';
import type { Database } from '../database/drizzle.js';
import { orders } from '../database/schema.js';
import { fulfilmentId, OrderFulfilmentWorkflow } from './order-fulfilment.workflow.js';
import type { Order, PlaceOrderDto } from './order.js';

@Injectable()
export class OrdersService {
  constructor(
    @InjectDrizzle() private readonly db: Database,
    private readonly workflowClient: WorkflowClient,
  ) {}

  async place(dto: PlaceOrderDto) {
    const total = dto.items.reduce((sum, item) => sum + item.price * item.quantity, 0);
    const order: Order = {
      id: randomUUID().slice(0, 8),
      userId: dto.userId,
      items: dto.items,
      shipping: dto.shipping ?? 'standard',
      total,
      status: 'placed',
    };

    return this.db.transaction(async (tx) => {
      await tx.insert(orders).values(order);
      // Same transaction: the fulfilment exists if and only if the order does.
      const fulfilment = await this.workflowClient.start(OrderFulfilmentWorkflow, order, {
        id: fulfilmentId(order.id),
        transaction: tx,
      });
      return { ...order, fulfilment };
    });
  }

  async findOne(id: string): Promise<Order> {
    const [order] = await this.db.select().from(orders).where(eq(orders.id, id));
    if (!order) {
      throw new NotFoundException(`Order ${id} not found.`);
    }
    return order;
  }

  // ...markDelivered() is added in the next section
}
```

With `transaction`, the store creates the instance through the transaction your ORM handed the callback, so it commits with the order, or rolls back with it if anything later in the callback fails. The worker only ever sees committed instances: it picks this one up at its next poll after the commit. Pass the transaction, not the database, which the store refuses: `start()` without the option writes on its own, which is the dual write the option removes. With TypeORM, pass the transaction's `EntityManager`, and with Prisma, the transaction client, as [Keep workflows in your database](/reliability/workflows#keep-workflows-in-your-database) shows.

The instance id comes from the order id, which makes `start()` idempotent. Starting the same id with the same input returns the existing instance with `created: false`, and a different input throws `WorkflowIdConflictError`. A reconciliation job can call it again for an order without charging twice.

##### Report its status[#](/reliability/workflows#report-its-status)

The controller places orders and reports where their fulfilment stands:

orders/orders.controller.ts

JS TS

```typescript

import { Body, Controller, Get, NotFoundException, Param, Post } from '@nestjs/common';
import { WorkflowClient } from '@nestjs/workflows';
import { fulfilmentId } from './order-fulfilment.workflow.js';
import { PlaceOrderDto } from './order.js';
import { OrdersService } from './orders.service.js';

@Controller('orders')
export class OrdersController {
  constructor(
    private readonly ordersService: OrdersService,
    private readonly workflowClient: WorkflowClient,
  ) {}

  @Post()
  place(@Body() dto: PlaceOrderDto) {
    return this.ordersService.place(dto);
  }

  @Get(':id/fulfilment')
  async fulfilment(@Param('id') id: string) {
    const instance = await this.workflowClient.getStatus(fulfilmentId(id), { journal: true });
    if (!instance) {
      throw new NotFoundException(`Order ${id} not found.`);
    }
    return {
      status: instance.status,
      stage: instance.customStatus,
      waitingFor: instance.waits.map((wait) => wait.signal),
      wakeAt: instance.wakeAt === null ? null : new Date(instance.wakeAt).toISOString(),
      steps: Object.fromEntries(instance.journal.map((entry) => [entry.name, entry.status])),
      error: instance.error?.message ?? null,
    };
  }

  // ...cancel() is added for customer support, below
}
```

`getStatus()` returns the instance: its `status`, `wakeAt`, the signals it `waits` for, its `error` or `output`, and, with the `journal` option, every step. The statuses are `pending`, `running`, `suspended`, `compensating`, `completed`, `failed`, `cancelled` and `compensation_failed`; [What each status means](/reliability/workflows#what-each-status-means) says what each one means and what to do about it. The endpoint maps the instance to a small view. Don't return the raw instance to customers, because it includes the input and lease details.

The `stage` comes from the workflow. `ctx.setStatus()` sets the instance's **custom status**, a JSON value of up to 16 KiB that `getStatus()` and `list()` return as `customStatus`: here, a word for where the order stands. Set it in `run()` as the order moves on, and to `delivered` once the carrier has delivered it (in [Sleep for a week, then ask for a review](/reliability/workflows#sleep-for-a-week-then-ask-for-a-review)):

orders/order-fulfilment.workflow\.ts

JS TS

```typescript

const charge = await ctx.step(
  'charge-payment',
  // ...the charge, as above
);
ctx.setStatus('paid');

await ctx.step(
  'reserve-stock',
  // ...the reservation, as above
);
ctx.setStatus('awaiting-delivery');
```

The status isn't journaled. Every execution replays `run()`, and with it the `setStatus()` calls, so each execution sets the status again on its way through, and a status set in a loop doesn't grow the journal. The workflow never reads it back, so nothing it decides depends on it. It's written with the instance's next write: when the next step starts, when the instance parks, or when it ends. So the endpoint shows `paid` while `reserve-stock` waits for a retry, and `awaiting-delivery` once the instance parks for the carrier. A status the workflow no longer changes stays, such as `awaiting-delivery` on a cancelled order: `status` tells what happened. A value that isn't JSON, or takes more than 16 KiB as JSON, fails the instance with a `TypeError`, and `undefined` clears the status. Each written change is emitted as a `custom-status` event.

#### Wait for signals and timers[#](/reliability/workflows#wait-for-signals-and-timers)

##### Wait for the delivery webhook[#](/reliability/workflows#wait-for-the-delivery-webhook)

Next, the workflow waits for the carrier. The webhook and the workflow share a signal: a name and the type of its payload, defined once, so neither side can misspell the name or send the wrong shape:

shipping/carrier-event.ts

JS TS

```typescript

import { WorkflowSignal } from '@nestjs/workflows';

/** The body the carrier POSTs to our webhook. */
export interface CarrierEvent {
  type: 'shipment.in_transit' | 'shipment.delivered' | 'shipment.returned';
  /** The store's order id. */
  reference: string;
  trackingNumber: string;
  occurredAt: string;
}

/** Sent by the webhook, awaited by the fulfilment workflow. The order id is its key. */
export const shipmentDelivered = new WorkflowSignal<CarrierEvent>('shipment.delivered');
```

Add this to `run()`, after `reserve-stock`:

orders/order-fulfilment.workflow\.ts

JS TS

```typescript

const delivery = await ctx.waitForSignal('await-delivery', shipmentDelivered, {
  key: order.id,
  timeout: '3d',
});
if (!delivery) {
  ctx.fail(`Order ${order.id} was not delivered within 3 days.`);
}
```

`waitForSignal()` records the wait and parks the instance: its status becomes `suspended` and `wakeAt` is the deadline. No memory, timer or worker is held for those 3 days. It resolves with the signal's payload, typed as a `CarrierEvent`, or with `null` once the timeout passes. `ctx.fail()` then fails the instance, and the compensations run in reverse: the stock is released, then the charge is refunded. A `match` option filters the signals further by payload, such as `match: (event) => event.trackingNumber !== ''`; it runs again on every replay, so it must be a pure function of the payload.

The webhook marks the order as delivered and sends the signal. Both happen in a new `OrdersService.markDelivered()` method, in one transaction, so the order's status and the signal commit together. Add it, and the import of the signal:

orders/orders.service.ts

JS TS

```typescript

import { shipmentDelivered, type CarrierEvent } from '../shipping/carrier-event.js';

async markDelivered(event: CarrierEvent): Promise<void> {
  await this.db.transaction(async (tx) => {
    const updated = await tx
      .update(orders)
      .set({ status: 'delivered' })
      .where(eq(orders.id, event.reference))
      .returning({ id: orders.id });
    if (updated.length === 0) {
      throw new NotFoundException(`Order ${event.reference} not found.`);
    }
    // The order's new status and the signal commit together.
    await this.workflowClient.signal(shipmentDelivered, event, { key: event.reference, transaction: tx });
  });
}
```

The controller verifies the callback and hands it over:

shipping/carrier-webhook.controller.ts

JS TS

```typescript

import { Body, Controller, HttpCode, Post } from '@nestjs/common';
import { OrdersService } from '../orders/orders.service.js';
import type { CarrierEvent } from './carrier-event.js';

@Controller('webhooks/carrier')
export class CarrierWebhookController {
  constructor(private readonly ordersService: OrdersService) {}

  @Post()
  @HttpCode(200)
  async handle(@Body() event: CarrierEvent) {
    // Verify the carrier's signature header before trusting the body.
    if (event.type === 'shipment.delivered') {
      await this.ordersService.markDelivered(event);
    }
    return { received: true };
  }
}
```

`signal()` stores the signal with a correlation `key` and wakes the instances waiting for that signal and key. Keys match exactly, so the order id keeps one order's delivery from waking another, and a wait without a key only takes signals sent without one. Signals are durable. A webhook that arrives before the workflow reaches the wait still counts, and each signal is consumed at most once per instance, so the carrier's retries are harmless. They still store a signal each, unless you pass an `id`, such as the tracking number: a signal with the same name and `id` is stored once, and a repeat returns the first one's `signalId` with `created: false`. A delivery recorded after the deadline loses to the timeout, even if no worker was running when the deadline passed.

The controller answers `200` only after the transaction has committed. A delivery for an order the store doesn't know rolls back with a `404`, leaving no signal behind, and if the database fails, the carrier gets an error and delivers the webhook again. Signals sent in a transaction queue behind each other until it ends, so keep such transactions short. On PostgreSQL, the transaction must use the default READ COMMITTED isolation; the store refuses a stricter one, which could miss a wait registered while it ran. On MySQL, the default REPEATABLE READ works as well.

##### Wait for whichever comes first[#](/reliability/workflows#wait-for-whichever-comes-first)

The carrier doesn't always deliver. When it can't, it brings the parcel back to the warehouse and reports `shipment.returned`. Declare a second signal, next to the first:

shipping/carrier-event.ts

JS TS

```typescript

/** Sent by the webhook when the carrier brings the parcel back to the warehouse. The order id is its key. */
export const shipmentReturned = new WorkflowSignal<CarrierEvent>('shipment.returned');
```

The webhook sends it as it sends the delivery. A new `OrdersService.markReturned()` sets the order's status to `returned` and sends the signal, in one transaction, like `markDelivered()`:

shipping/carrier-webhook.controller.ts

JS TS

```typescript

if (event.type === 'shipment.returned') {
  await this.ordersService.markReturned(event);
}
```

The workflow now waits for the delivery, the return or 3 days, whichever comes first. Replace the `waitForSignal()` call with `ctx.waitForAny()`:

orders/order-fulfilment.workflow\.ts

JS TS

```typescript

const outcome = await ctx.waitForAny('await-delivery', {
  delivered: ctx.signalWait(shipmentDelivered, { key: order.id }),
  returned: ctx.signalWait(shipmentReturned, { key: order.id }),
  timedOut: ctx.timer('3d'),
});
if (outcome.key === 'returned') {
  ctx.fail(`The carrier returned order ${order.id} to the warehouse.`);
}
if (outcome.key === 'timedOut') {
  ctx.fail(`Order ${order.id} was not delivered within 3 days.`);
}
const delivery = outcome.value;
```

`ctx.signalWait()` and `ctx.timer()` only describe a condition, and `waitForAny()` waits for them together. It parks the instance once, with every signal it waits for and the earliest deadline, and resolves with the `key` of the condition that happened first and its `value`: a signal's payload, or `null` for a timer. Checking `key` narrows `value`, so after the two checks `delivery` is a `CarrierEvent`. A returned parcel fails the instance, and the compensations release the stock, which is back in the warehouse, and refund the charge. The status endpoint's `waitingFor` lists both signals while the instance waits.

The outcome is journaled as one entry under the wait's name, so every later execution gets the same winner. When several conditions are ready at once, the signal recorded first wins, whichever condition it matched. A signal sent after a timer's deadline doesn't count, as with `waitForSignal()`'s `timeout`, and timers count from when the wait is first reached. Only the winning signal is taken: a return reported after the delivery would stay for a later wait of the same instance. To wait for all of several signals instead, await several `waitForSignal()` calls with `Promise.all()`: each is journaled on its own, and the instance parks once for all of them. A child workflow can be a condition too, as [Start child workflows](/reliability/workflows#start-child-workflows) shows.

##### Sleep for a week, then ask for a review[#](/reliability/workflows#sleep-for-a-week-then-ask-for-a-review)

Finish `run()` with the point of no return, a durable timer and the last step:

orders/order-fulfilment.workflow\.ts

JS TS

```typescript

// Point of no return: the parcel arrived, so nothing from here on refunds
// the charge or releases the stock, not a failure and not a cancel.
ctx.commit('delivered');
ctx.setStatus('delivered');

await ctx.sleep('before-review-request', '7d');
await ctx.step('send-review-request', ({ idempotencyKey }) =>
  this.mailService.sendReviewRequest(order, idempotencyKey),
);

return { chargeId: charge.chargeId, trackingNumber: delivery.trackingNumber };
```

`ctx.sleep()` stores a wake-up time and parks the instance, like the wait. After 7 days, any worker resumes it: never early, and usually within a poll interval of the deadline. When it resumes, `run()` replays from the top: `charge-payment` and `await-delivery` return their journaled values, so `charge` and `delivery` are in scope a week later. A delayed job can't give you that continuation. To sleep until a point in time instead, pass an object with `until`, a `Date` or epoch milliseconds, computed from journaled values such as `ctx.now()`.

`ctx.commit()` marks the point of no return. Once the parcel is delivered, refunding the charge would be wrong, whatever happens next. `commit()` discards the compensations registered so far. If the review email then fails for good, the instance ends as `failed` with the step's error, and nothing is refunded or released. A cancel past this point doesn't undo anything either. Only the steps after `commit()` register compensations that can still run. The commit point is journaled under its name, so it replays like a step, and the status endpoint lists it as `delivered`.

##### Time out the whole workflow[#](/reliability/workflows#time-out-the-whole-workflow)

A wait's `timeout` bounds one wait, and a step's `timeout` one attempt. To bound a whole instance, give the workflow a run timeout:

```typescript

@Workflow('order-fulfilment', { timeout: '30d' })
```

The deadline is the instance's start plus the timeout, stored with the instance as its `deadline`, so it holds across restarts and deploys, and a parked instance wakes for it even when its sleep or wait would end later. Once it passes, the instance stops at its next `ctx` call (a step that is running finishes first), its compensations run, and it ends as `failed` with a `WorkflowTimeoutError`. Compensations aren't bound by the deadline. Here the wait gives up after 3 days and the sleep takes 7, so 30 days is a safety net. `start()` takes a `timeout` option too, which overrides the decorator's for that instance.

#### Cancel and operate workflows[#](/reliability/workflows#cancel-and-operate-workflows)

##### Let customer support cancel an order[#](/reliability/workflows#let-customer-support-cancel-an-order)

Add a `cancel()` route to `OrdersController`, and `ConflictException` and `HttpCode` to its `@nestjs/common` import. `OrdersService.markCancelled()` sets the order's status:

orders/orders.controller.ts

JS TS

```typescript

// Customer support only: protect it with your staff guard.
@Post(':id/cancel')
@HttpCode(202)
async cancel(@Param('id') id: string, @Body('reason') reason: string) {
  const order = await this.ordersService.findOne(id);
  if (order.status === 'delivered') {
    throw new ConflictException(`Order ${id} was delivered. Start a return instead.`);
  }
  // accepted is false if the fulfilment already ended or was already cancelled.
  const { accepted } = await this.workflowClient.cancel(fulfilmentId(id), reason);
  if (accepted) {
    await this.ordersService.markCancelled(id);
  }
  return { accepted };
}
```

`cancel()` sets a flag. A parked instance wakes at once. A running one lets its current step finish and stops at its next `ctx` call. (A running instance in another process notices the flag on its next lease renewal, within a third of `leaseDuration`.) Either way, the compensations of the completed steps run in reverse, and the instance ends as `cancelled` with the reason as its error message. `cancel()` returns the instance with an `accepted` flag. It's `false` when the instance had already completed or failed, when it is already compensating a failure, or when a cancel or a terminate was already requested. A second cancel changes nothing, and the first reason is kept.

Once the carrier has reported the delivery, the route answers `409`, because support should start a return instead. The workflow doesn't rely on that check. A cancel that reaches it after `ctx.commit('delivered')` stops the review request and refunds nothing. A cancel it sees before it has consumed the delivery event still refunds, because it hasn't reached its point of no return yet.

##### What each status means[#](/reliability/workflows#what-each-status-means)

An instance's `status` says what it's doing, and whether it needs you:

| Status                | What it means                                                                                                                                                                                                           | What to do                                                                                                             |
| --------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| `pending`             | Started, and not yet claimed by a worker. One that stays `pending` waits for a concurrency slot or room in a rate-limit window, or is of a version no running worker registers                                          | Nothing while a limit holds it. Otherwise, deploy a worker with that version, or delete the instance                   |
| `running`             | A worker holds its lease and executes it                                                                                                                                                                                | Nothing. `cancel()` stops it at its next `ctx` call, and `terminate()` without compensating                            |
| `suspended`           | Parked on a sleep, a wait or a retry's backoff, until `wakeAt` or a signal                                                                                                                                              | Nothing. A signal or `cancel()` wakes it                                                                               |
| `compensating`        | Undoing its completed steps after a failure or a cancel                                                                                                                                                                 | Nothing: it ends as `failed`, `cancelled` or `compensation_failed`. `terminate()` stops the undo                       |
| `completed`           | Done, with the result of `run()` as its `output`                                                                                                                                                                        | Nothing, until retention purges it                                                                                     |
| `cancelled`           | Cancelled, after its compensations ran, or terminated without them (`error.name` is `WorkflowTerminatedError`). `error.message` is the reason                                                                           | Nothing, until retention purges it                                                                                     |
| `failed`              | A step gave up, `ctx.fail()` was called, the run timeout passed or the journal hit its limit, and then its compensations ran. Or a definition error, such as a deploy that broke replay, failed it without compensating | If no compensation ran, fix the cause and retry it. Otherwise it's done: its completed steps were undone               |
| `compensation_failed` | An undo gave up halfway. `error` is the original failure, with the compensation's own error as `error.compensation`                                                                                                     | Fix the cause, such as a warehouse API that was down, and retry it. Or finish the undo by hand and delete the instance |

##### Retry, delete or terminate[#](/reliability/workflows#retry-delete-or-terminate)

`WorkflowClient` has the actions for the table's last column. Call them from a staff-only route or a script:

```typescript

await this.workflowClient.retry(fulfilmentId(orderId));
await this.workflowClient.delete(fulfilmentId(orderId));
await this.workflowClient.terminate(fulfilmentId(orderId), 'Refunded by hand after a chargeback.');
```

* **`retry()`** runs a `failed` instance again from its journal: completed steps return their results, the step that gave up gets its attempts back, and sleeps and waits the instance left behind start over. A deploy that broke replay is retried once the fixed code runs. It refuses an instance whose compensations ran, since resuming would build on undone work: start a new instance instead. An instance past its run timeout needs a new one, as the `timeout` option (counted from now), or `false` for none. A `compensation_failed` instance runs the compensations that didn't complete again, each with its attempts back, and ends as it would have: `failed` or `cancelled`.
* **`delete()`** removes a finished instance with its journal. An unfinished one needs the `force` option, and goes without running its compensations: use it for an instance no worker can run any more, such as one of a version you no longer deploy.
* **`cancel()`**, as above, stops an instance that is still running, and runs its compensations.
* **`terminate()`** stops an instance without running its compensations, for one whose undo mustn't or can't run, such as an order support has already refunded by hand. A parked instance stops at once, a running one at its next `ctx` call, and a compensating one after the compensation it's running. It ends as `cancelled`, with a `WorkflowTerminatedError` whose message is the reason (`Terminated.` without one). It's accepted after a `cancel()` too, which it replaces, and a `cancel()` after it is refused. Its children get their `parentClose`, as for any end.

`retry()` and `delete()` throw a `WorkflowStateError`, whose `status` is `409`, for a status where they make no sense, and when another change to the instance races them. A retry is journaled as `$retry:1`, `$retry:2` and so on, with the status and error it retried, and both actions are emitted, as `workflow-retried` and `workflow-deleted`.

##### Purge finished instances[#](/reliability/workflows#purge-finished-instances)

Finished instances stay, with their journals, until you purge them. `purge()` deletes the ones that finished longer ago than its `olderThan` option, a batch at a time, and the signals no instance can take any more. An instance only takes signals sent after it started, so once every unfinished instance started after a signal, and the signal is older than `olderThan`, it goes; the newest signal always stays. `compensation_failed` instances wait for a person, so they're purged only when you list them in the `status` option. Run it every night, on one instance of your application, with `@Cron()` from `@nestjs/schedule` and `@OnOneInstance()` from [`@nestjs/locks`](/reliability/locks):

```typescript

@Injectable()
export class WorkflowRetentionJob {
  constructor(private readonly workflowClient: WorkflowClient) {}

  @Cron('30 3 * * *')
  @OnOneInstance({ key: 'workflows:purge' })
  async purge() {
    return this.workflowClient.purge({ olderThan: '30d' });
  }
}
```

`purge()` resolves with the number of `instances` and `signals` it deleted, and of the rate-limit windows that ended (`rateLimits`). A signal's `id` deduplicates for as long as the signal is stored, so keep `olderThan` longer than any sender's redelivery window, such as your carrier's webhook retries.

#### Limits, children and batch work[#](/reliability/workflows#limits-children-and-batch-work)

##### Limit how many run at once[#](/reliability/workflows#limit-how-many-run-at-once)

A worker runs every due instance it has room for. Three options decide what runs, and in what order, across every worker: a concurrency limit, a rate limit and a priority. The fulfilment sets the first two in `@Workflow()`:

orders/order-fulfilment.workflow\.ts

JS TS

```typescript

@Workflow('order-fulfilment', {
  // One execution per customer at a time, so two of their orders never charge their card at once.
  concurrency: { limit: 1, key: (order: Order) => order.userId },
  // Each execution sends the payment provider one request at most: a charge, or a refund.
  rateLimit: { max: 10, duration: '1s' },
})
```

**Concurrency.**`concurrency` caps how many instances run at once: a `limit` for the workflow, or a `limit` per key with a `key` function, here the customer's id. An array takes one of each. An instance holds a slot only while an execution runs it, compensations included, not while it sleeps or waits: a limit protects what the steps call, and an order parked for days holds up nobody. A process that crashes frees its slots once its leases expire. Instances past a limit stay due and wait for a slot, most overdue first, and a full key is passed over, so one busy customer never holds back another's order. The key is computed from the input when the instance starts, and `start()`'s `concurrencyKey` option sets another, for a workflow whose limit has a key.

**Rate limits.**`rateLimit` caps how many executions start per window: `max` per `duration` for the workflow, or per key with a `key` function, which `start()`'s `rateLimitKey` option overrides. Every execution counts, the first one and each resumption after a sleep, a signal, a retry's backoff or a cancel, because each can call what the limit protects. The fulfilment sends the payment provider one request per execution at most, so this caps its requests, and the executions that send none too. A window opens with the first execution after the previous one ended, and admits `max` executions until it closes, so two windows back to back can admit twice `max` within one `duration`. Say the payment provider allows 20 requests a second: allow 10.

**Priorities.**`start()`'s `priority` option decides what is claimed first: the lowest priority, then the most overdue. It's an integer from 1 to 2,097,151, and instances started without one go before every prioritized one. Express orders go first:

orders/orders.service.ts

JS TS

```typescript

const fulfilment = await this.workflowClient.start(OrderFulfilmentWorkflow, order, {
  id: fulfilmentId(order.id),
  transaction: tx,
  // Lower runs first: express orders before standard ones.
  priority: order.shipping === 'express' ? 1 : 2,
});
```

Since instances without a priority go first, once orders have one, other work needs one to go after them: the invoice batch's schedule gives it 10, in [Run workflows on a schedule](/reliability/workflows#run-workflows-on-a-schedule). An instance keeps its priority for every execution, and children inherit their parent's. Priorities are strict: a steady stream of express orders holds the standard ones back. `@StartOn()` takes the same option, as [With CQRS](/reliability/workflows#with-cqrs) shows.

Limits come from the highest registered version of the workflow and apply to all its versions, and each process applies the limits of the code it runs, so deploy a change to them everywhere. Claims never admit more than the limits allow, but can admit less for a moment: workers polling at the same time can take a few polls to fill a short window, and with both a concurrency key and a rate-limit key, a candidate that one kind of key passes over waits for the next claim. Claims also sort the due instances by priority, which the index on `wake_at` doesn't give them: cheap while few instances are due, noticeable with a large backlog. `drain()` stops when nothing left can start.

##### Start child workflows[#](/reliability/workflows#start-child-workflows)

Shipping grows: book the carrier's pickup, cancel it if the order is undone, then wait for the delivery or the return. It's a process of its own, with its own steps, retries and status, so give it a workflow of its own, and run it as a **child** of the fulfilment:

shipping/shipment.workflow\.ts

JS TS

```typescript

import { Workflow, type WorkflowContext, type WorkflowRunner } from '@nestjs/workflows';
import type { Order } from '../orders/order.js';
import { shipmentDelivered, shipmentReturned, type CarrierEvent } from './carrier-event.js';
import { CarrierClient } from './carrier.client.js';

/** Books the carrier's pickup, and waits for the delivery: a child of the order's fulfilment. */
@Workflow('shipment')
export class ShipmentWorkflow implements WorkflowRunner<Order, CarrierEvent> {
  constructor(private readonly carrierClient: CarrierClient) {}

  async run(ctx: WorkflowContext, order: Order): Promise<CarrierEvent> {
    await ctx.step(
      'book-pickup',
      ({ idempotencyKey }) => this.carrierClient.bookPickup(order, idempotencyKey),
      { compensate: ({ pickupId }) => this.carrierClient.cancelPickup(pickupId) },
    );

    const outcome = await ctx.waitForAny('await-delivery', {
      delivered: ctx.signalWait(shipmentDelivered, { key: order.id }),
      returned: ctx.signalWait(shipmentReturned, { key: order.id }),
      timedOut: ctx.timer('3d'),
    });
    if (outcome.key === 'returned') {
      ctx.fail(`The carrier returned order ${order.id} to the warehouse.`);
    }
    if (outcome.key === 'timedOut') {
      ctx.fail(`Order ${order.id} was not delivered within 3 days.`);
    }
    return outcome.value;
  }
}
```

`CarrierClient` is a stand-in for the carrier's booking API, which, like the payment provider, answers a repeated idempotency key with the first booking. In the fulfilment, the child takes the place of the wait:

orders/order-fulfilment.workflow\.ts

JS TS

```typescript

// Starts the shipment, and waits for it to end: its delivery, or a ChildWorkflowFailedError.
const delivery = await ctx.executeChild(ShipmentWorkflow, order);
```

Register `ShipmentWorkflow` and `CarrierClient` as providers, next to the fulfilment. The carrier's webhook doesn't change: it signals the order's id, and the shipment is now the instance waiting for it.

* **`ctx.executeChild()`** starts the child and waits for its end. Both are journaled, as `$child:<id>` and `$result:<id>`, so a replay gets the same child back instead of starting another, and the fulfilment parks in the meantime. `ctx.startChild()` only starts it, and returns a handle: its `result()` waits for the child, and the handle is a condition of `waitForAny()`, to race the child against a timer or a signal.
* **Ids.** A child's id defaults to its parent's id, the workflow's name and a count of that workflow's children in this run, such as `order-71e1973d/shipment#1`. Give children started from parallel branches an `id` option derived from your data, so that a replay, which can reach them in another order, finds each one.
* **Failures.** If the child fails, is cancelled or is terminated, `executeChild()` throws a `ChildWorkflowFailedError`, with its `status` and its error as `cause`. Left uncaught, it fails the fulfilment like any error: a returned parcel fails the shipment, whose compensation cancels its booking, and then the fulfilment, whose compensations refund the charge and release the stock. Catch it to try something else, such as another carrier.
* **`parentClose`** decides what happens to a child that is still running when its parent ends or starts compensating: `'cancel'`, the default, cancels it, and its compensations run; `'terminate'` stops it without them; `'abandon'` leaves it running. When support cancels the order, the shipment is cancelled with it, and the pickup with the shipment.
* A child inherits its parent's priority, unless `startChild()` gets one, and takes `concurrencyKey` and `rateLimitKey` options as `start()` does. `getStatus()` with the `children` option lists an instance's children, each with its `parentId`, and `list()` pages through them by `parentId`.

##### Long-running steps[#](/reliability/workflows#long-running-steps)

A step can run for hours. While it runs, the worker keeps renewing the lease in the background. For long batch work, checkpoint progress so a crash doesn't restart the job from zero. Here, a monthly batch renders invoices one page at a time:

invoices/invoice-batch.workflow\.ts

JS TS

```typescript

import { Workflow, type WorkflowContext, type WorkflowRunner, type WorkflowStepContext } from '@nestjs/workflows';
import { InvoicesService } from './invoices.service.js';

interface Checkpoint {
  cursor: number | null;
  rendered: number;
}

@Workflow('invoice-batch')
export class InvoiceBatchWorkflow implements WorkflowRunner<{ month: string }, { rendered: number }> {
  constructor(private readonly invoicesService: InvoicesService) {}

  async run(ctx: WorkflowContext, { month }: { month: string }) {
    return ctx.step(
      'render-invoices',
      async ({ progress, heartbeat, signal }: WorkflowStepContext<Checkpoint>) => {
        // After a crash, the next attempt starts from the last checkpoint.
        let { cursor, rendered } = progress ?? { cursor: 0, rendered: 0 };
        while (cursor !== null) {
          const page = await this.invoicesService.renderPage(month, cursor, signal);
          cursor = page.nextCursor;
          rendered += page.rendered;
          await heartbeat({ cursor, rendered });
        }
        return { rendered };
      },
      { heartbeatTimeout: '2m' },
    );
  }
}
```

* `heartbeat(progress)` writes the checkpoint to the journal. If the attempt dies, the next one receives it as `progress`. Annotating the parameter as `WorkflowStepContext<Checkpoint>` types both. The page that was in flight is rendered again, so `renderPage()` must overwrite rather than append.
* `heartbeatTimeout` fails an attempt that stops calling `heartbeat()`, such as one stuck on a hung socket, while the process is still alive. A `timeout` option caps the attempt's total duration.
* `signal` is aborted on shutdown, on a lost lease and on those timeouts. Pass it to your I/O.

A schedule, below, starts the batch every month. When the work belongs on processes of its own, such as a pool of PDF renderers, hand it to a [BullMQ](/application/queues) queue from a step, and wait for the job to report back with a signal. The job id is the step's `idempotencyKey`, so a retried step doesn't enqueue it twice:

```typescript

await ctx.step('enqueue-render', async ({ idempotencyKey }) => {
  await this.invoicesQueue.add('render', { month }, { jobId: idempotencyKey });
});
const rendered = await ctx.waitForSignal('await-render', invoicesRendered, { key: month, timeout: '6h' });
```

The queue's processor reports back when the job is done:

```typescript

await this.workflowClient.signal(invoicesRendered, result, { key: job.data.month, id: job.id });
```

The `id` stores the signal once when BullMQ runs the job again, and a job that finishes before the workflow reaches the wait still counts, because signals are durable.

##### Run workflows on a schedule[#](/reliability/workflows#run-workflows-on-a-schedule)

The invoices are due on the 1st of every month. Instead of a cron job that starts the batch, declare a schedule on the workflow:

invoices/invoice-batch.workflow\.ts

JS TS

```typescript

import { Workflow, type WorkflowContext, type WorkflowRunner, type WorkflowStepContext } from '@nestjs/workflows';

/** The month before the one `at` falls in, in UTC ('2026-09' in October 2026): 02:00 on the 1st in New York is the 1st in UTC too. */
const lastMonth = (at: number) => new Date(new Date(at).setUTCDate(0)).toISOString().slice(0, 7);

@Workflow('invoice-batch', {
  schedules: [
    {
      id: 'monthly-invoices',
      // At 02:00 on the 1st of every month, in the store's time zone: last month's invoices.
      cron: '0 2 1 * *',
      tz: 'America/New_York',
      // A deploy or an outage at 02:00 delays the batch instead of skipping a month.
      missed: 'once',
      // After the orders (express 1, standard 2): without a priority, it would go before them.
      priority: 10,
      input: ({ at }) => ({ month: lastMonth(at) }),
    },
  ],
})
export class InvoiceBatchWorkflow implements WorkflowRunner<{ month: string }, { rendered: number }> {
  // ...as before
}
```

Every worker whose code declares the schedule starts its occurrences, and each occurrence starts one instance, however many workers there are: its id is the schedule's id and the occurrence's time, such as `monthly-invoices@2026-10-01T06:00:00.000Z`. The `input` function receives the occurrence, its schedule's `id` and its time `at`, and so does the instance, as `ctx.schedule`, which is `null` for an instance started otherwise.

* **When.**`cron` takes 5 fields, or 6 with the seconds first, `every` a fixed interval, and `rrule` an RFC 5545 recurrence rule. Times are wall-clock times in `tz`, UTC by default, so the batch starts at 02:00 in New York before and after the clocks change. When the clocks go back, a local time that occurs twice runs once, the first time, so an hourly schedule skips the second pass of the repeated hour. When they go forward, a time that doesn't exist still runs, as much later as the clocks jumped: 02:30 runs at 03:30. `every` takes no `tz`: it repeats a fixed interval whatever the time zone. `startAt`, `endAt` and `limit` bound a schedule.
* **`missed`** says what happens to occurrences no worker was up to start, during a deploy or an outage. `'skip'`, the default, starts one only if a worker finds it within a minute of its time; `'once'` starts the latest of them; `'all'` starts each of them, the latest 100 at most, and needs `overlap: 'allow'`. The occurrences it passes over are reported in a `schedule-skipped` event.
* **`overlap`** says what an occurrence does while an instance the schedule started is unfinished: `'skip'`, the default, passes it over, with a `schedule-skipped` event; `'allow'` starts it anyway; `'cancel-previous'` cancels the running one; `'buffer-one'` starts it once the running one ends.

A declared schedule belongs to the code, also while a rolling deploy runs the old and the new code side by side. Each process saves the schedules that its workflows declare when it starts, and confirms them every minute while its worker runs. A process leaves a schedule as it is while another process confirms it, if its own code doesn't declare it or a newer version of the workflow declares it differently. Once no process has confirmed it for five minutes, a process deletes a schedule that its code doesn't declare, whether or not it runs the schedule's workflow, and replaces another declaration with its own. So an old pod that restarts mid-rollout leaves alone the schedules that the new code adds or a new version changes, a schedule that a deploy drops goes about five minutes after the last process of the old code stopped, also when the deploy removes its workflow, and a rollback brings the old declaration back.

Processes of other code on the same database, such as the workers of other workflows, also delete a schedule when no worker whose code declares it has run for five minutes, as while those workers are scaled to zero. The next process whose code declares it saves it again as it starts, and the schedule starts over: from its next occurrence, unpaused, with its runs counted from zero.

`WorkflowClient.schedules`, also injectable as `WorkflowSchedules`, handles schedules at runtime. `trigger('monthly-invoices')` starts an occurrence now, whatever `overlap` says and even while the schedule is paused, with its time as `at`. `pause()` stops the occurrences until `resume()`, which starts again from the first one after now. `preview()` returns the next occurrences, in epoch milliseconds, and `get()` and `list()` read the schedules. A schedule that isn't in the code, such as one per customer, is saved with `upsert()`, and `remove()` deletes it, leaving the instances it started running:

```typescript

await this.workflowClient.schedules.upsert(`reorder-reminder-${user.id}`, {
  workflow: ReorderReminderWorkflow,
  // Every 4 weeks, on Saturdays at 09:00 in the customer's time zone
  rrule: 'FREQ=WEEKLY;INTERVAL=4;BYDAY=SA;BYHOUR=9;BYMINUTE=0',
  tz: user.timeZone,
  input: { userId: user.id },
});
```

`upsert()` and `remove()` refuse a declared schedule, which you change in the code.

##### Wait for a result[#](/reliability/workflows#wait-for-a-result)

Most callers start a workflow and move on. Some need its result: an accountant who wants a month's invoices now, before the schedule renders them, calls a route that renders them and answers with the count. `startAndWait()` starts the instance and waits for it to end:

invoices/invoices.controller.ts

JS TS

```typescript

import { Controller, HttpCode, Param, Post, Res } from '@nestjs/common';
import { WorkflowClient, WorkflowResultTimeoutError } from '@nestjs/workflows';
import type { Response } from 'express';
import { InvoiceBatchWorkflow } from './invoice-batch.workflow.js';

@Controller('invoices')
export class InvoicesController {
  constructor(private readonly workflowClient: WorkflowClient) {}

  // Accounting only: protect it with your staff guard.
  @Post(':month')
  @HttpCode(200)
  async render(@Param('month') month: string, @Res({ passthrough: true }) response: Response) {
    try {
      // One batch per month: calling again, while it runs or after it ended, waits for the same one.
      return await this.workflowClient.startAndWait(InvoiceBatchWorkflow, { month }, { id: `invoices-${month}` }, { timeout: '30s' });
    } catch (error) {
      if (!(error instanceof WorkflowResultTimeoutError)) {
        throw error;
      }
      // The batch keeps running: answer now, and let the accountant call again later.
      response.status(202);
      return { rendering: true };
    }
  }
}
```

* `startAndWait()` is `start()`, then `result()`, which waits for an instance to end and resolves with its output. For an id that has an instance already, it waits for that one, so the accountant calling the route again, while the batch runs or after it ended, gets the same batch. The wait's options are the fourth argument: the third one's `timeout` stays the instance's run timeout.
* Past the wait's `timeout`, in wall-clock time rather than the module's clock, it rejects with `WorkflowResultTimeoutError`, and the instance keeps running: the route answers `202`. A `signal` option stops the wait when it's aborted, as when the caller goes away.
* On shutdown, a wait lasts while the worker finishes its running steps, up to `shutdownTimeout`, so an instance that ends meanwhile still answers with its result. Then the wait rejects with an `Error`, before Nest closes the HTTP server, and the route answers at once, here with a `500`, instead of holding up the shutdown until its wait's `timeout`.
* An instance that failed, was cancelled or terminated rejects with a `WorkflowFailedError`, whose `status` says how it ended and whose `cause` is its error. Here, that's a `500`.
* `result()` waits for an instance by its id, such as the one `trigger()` started, whichever process runs it. `startAndWait()` refuses the `transaction` option, since the instance only exists once your transaction commits: call `start()` in the transaction, and `result()` after the commit.

#### Deploy changes safely[#](/reliability/workflows#deploy-changes-safely)

The journal is keyed by name, so step, sleep and wait names are a contract with every instance that is still running. The name is also part of the idempotency key.

Suppose you rename `charge-payment` to `charge-card` and deploy. An order that was waiting for the carrier resumes, finds no `charge-card` entry in its journal, and would charge the card again, under a key the payment provider has never seen. Before the first new step of an execution runs, the engine checks that the code reached every step in the journal. Here it didn't, so the instance fails without charging:

```text

Instance "order-6d0f8c06" of workflow "order-fulfilment@1" does not match its journal:
"charge-payment", "reserve-stock", "await-delivery" were recorded by an earlier run but not
reached before the new step "charge-card". A deployed change renamed, removed or reordered steps.
Ship such changes as a new version (@Workflow(name, { version })) and keep the old class
registered until its instances finish.
```

Its compensations don't run either, because they're defined by the code that no longer matches. The instance is left for a person to handle. The check doesn't see a step whose name stayed the same but whose body now does something different.

Some changes don't need a new version:

* changing a step's body without changing what it means,
* adding steps after the last step, sleep or wait that any running instance has reached,
* changing retry options and timeouts.

Anything else ships as a new version. Say marketing wants an order confirmation right after payment. Inserting a step before `reserve-stock` changes what a replay sees, so copy the class and bump its version:

orders/order-fulfilment-v2.workflow\.ts

JS TS

```typescript

@Workflow('order-fulfilment', {
  version: 2,
  // The limits of the highest registered version apply to every version: keep them.
  concurrency: { limit: 1, key: (order: Order) => order.userId },
  rateLimit: { max: 10, duration: '1s' },
})
export class OrderFulfilmentWorkflowV2 implements WorkflowRunner<Order, FulfilmentResult> {
  // ...same constructor as version 1

  async run(ctx: WorkflowContext, order: Order): Promise<FulfilmentResult> {
    const charge = await ctx.step(
      'charge-payment',
      // ...unchanged
    );
    ctx.setStatus('paid');

    await ctx.step('send-order-confirmation', ({ idempotencyKey }) =>
      this.mailService.sendOrderConfirmation(order, idempotencyKey),
    );

    // ...the rest is unchanged from version 1
  }
}
```

Register both classes. An instance keeps the version it started on, and a worker only claims versions it has registered, so old and new pods can run side by side during a rolling deploy. New instances start on the highest registered version, even when the controller still passes `OrderFulfilmentWorkflow`, because the class only identifies the workflow's name. To pin one, add `version: 1` to the `start()` options. Remove version 1 once `list()` with the workflow's name, `version: 1` and the unfinished statuses (`pending`, `running`, `suspended` and `compensating`) comes back empty.

##### Rules for workflow code[#](/reliability/workflows#rules-for-workflow-code)

`run()` executes again from the top every time an instance resumes. Code between steps runs on every execution, so it must make the same decisions each time:

* Put anything that touches or reads the outside world in a step: HTTP calls, database reads and writes, feature flags.
* Outside steps, use `ctx.now()`, `ctx.random()` and `ctx.uuid()` instead of `Date.now()`, `Math.random()` and `randomUUID()`. They're journaled.
* In `run()`, only `await``ctx` operations and pure computation. Never wait on a real timer.
* Step, sleep and wait names must be unique within a run. In a loop, add the index to the name, such as `remind-1` and `remind-2`. Give children started from parallel branches an `id` of their own.
* Don't call `ctx` methods inside a step's function. The function runs once and replays only see its result, so the engine fails the instance when a step calls `ctx`. Throw a `NonRetryableStepError` from a step instead of calling `ctx.fail()` there.
* If you catch errors in `run()`, rethrow what you don't handle. `isWorkflowInterrupt()` identifies the engine's control flow. The engine doesn't depend on it: after a swallowed interrupt no step runs, `commit()` throws again, and a cancel still cancels. But `finally` blocks run at every suspension, so keep side effects out of them.
* `Promise.all()` over steps is fine, and a step in the same `Promise.all()` as a sleep or wait starts after it. `Promise.race()` and `Promise.any()` are not replay-safe.
* Inputs, step results and signal payloads must be JSON-serializable. A `Date` comes back as a string, on the first run and on every replay, and the `Journaled` types of results and payloads say so.
* Keep no per-run state on `this`: one instance of the class serves every order.

#### Try it and test it[#](/reliability/workflows#try-it-and-test-it)

##### Try it[#](/reliability/workflows#try-it)

Create the database, apply your migrations, and start the application with `DATABASE_URL` pointing at the database:

```bash

$ npm run start:dev
...
[Nest] 33662  - 09/30/2026, 1:28:30 PM     LOG [WorkflowsModule] WorkflowStorage: PostgresWorkflowStore
[Nest] 33662  - 09/30/2026, 1:28:30 PM     LOG [WorkflowsModule] PostgresWorkflowStore: migrated schema "nest_workflows" to version 1.
[Nest] 33662  - 09/30/2026, 1:28:30 PM     LOG [NestApplication] Nest application successfully started +8ms
```

The log names the store in use, not the in-memory default, and says that the store created its schema: your migrations created `orders`, and the store its own tables. Place an order, then ask where it is:

```bash

$ curl -X POST http://localhost:3000/orders -H "Content-Type: application/json" \
    -d '{"userId": "u_42", "items": [{"productId": "salmon-kibble-2kg", "quantity": 1, "price": 2499}]}'
{"id":"f7e1e1eb","userId":"u_42","items":[{"productId":"salmon-kibble-2kg","quantity":1,"price":2499}],"shipping":"standard","total":2499,"status":"placed","fulfilment":{"id":"order-f7e1e1eb","workflow":"order-fulfilment","version":1,"created":true,"status":"pending"}}

$ curl http://localhost:3000/orders/f7e1e1eb/fulfilment
{"status":"suspended","stage":"awaiting-delivery","waitingFor":["shipment.delivered","shipment.returned"],"wakeAt":"2026-10-03T11:28:42.251Z","steps":{"charge-payment":"completed","reserve-stock":"completed","await-delivery":"pending"},"error":null}
```

The order and its fulfilment were committed together, the worker picked the instance up, the card is charged, the kibble is reserved, and the instance is parked until the carrier reports the delivery or the return, or the 3-day deadline in `wakeAt` passes.

Now play the carrier and report the delivery:

```bash

$ curl -X POST http://localhost:3000/webhooks/carrier -H "Content-Type: application/json" \
    -d '{"type": "shipment.delivered", "reference": "f7e1e1eb", "trackingNumber": "TRK123456789", "occurredAt": "2026-09-30T14:05:00Z"}'
{"received":true}

$ curl http://localhost:3000/orders/f7e1e1eb/fulfilment
{"status":"suspended","stage":"delivered","waitingFor":[],"wakeAt":"2026-10-07T11:28:58.885Z","steps":{"charge-payment":"completed","reserve-stock":"completed","await-delivery":"completed","delivered":"completed","before-review-request":"pending"},"error":null}
```

The instance passed its point of no return and is sleeping until the review request is due in 7 days. Support can no longer cancel the order, and a delivery for an order the store doesn't know is refused:

```bash

$ curl -X POST http://localhost:3000/orders/f7e1e1eb/cancel -H "Content-Type: application/json" -d '{"reason": "Changed my mind."}'
{"message":"Order f7e1e1eb was delivered. Start a return instead.","error":"Conflict","statusCode":409}

$ curl -X POST http://localhost:3000/webhooks/carrier -H "Content-Type: application/json" \
    -d '{"type": "shipment.delivered", "reference": "nope", "trackingNumber": "TRK1", "occurredAt": "2026-09-30T14:05:00Z"}'
{"message":"Order nope not found.","error":"Not Found","statusCode":404}
```

Place a second order (it gets id `58b424f5` here) and cancel it while it waits for the carrier:

```bash

$ curl -X POST http://localhost:3000/orders/58b424f5/cancel -H "Content-Type: application/json" \
    -d '{"reason": "Customer ordered the wrong size."}'
{"accepted":true}

$ curl http://localhost:3000/orders/58b424f5/fulfilment
{"status":"cancelled","stage":"awaiting-delivery","waitingFor":[],"wakeAt":null,"steps":{"charge-payment":"completed","reserve-stock":"completed","await-delivery":"cancelled","$compensate:reserve-stock":"completed","$compensate:charge-payment":"completed"},"error":"Customer ordered the wrong size."}
```

The journal shows both compensations: the stock was released first, then the charge was refunded. The wait never finished, so it's marked `cancelled`, and the stage stays where the workflow last set it.

The instances are rows in your database, in the store's schema, next to the orders:

```bash

$ psql "$DATABASE_URL" -c "SELECT o.id, o.status, w.status AS fulfilment, w.runs FROM orders o JOIN nest_workflows.instances w ON w.id = 'order-' || o.id ORDER BY w.created_at"
    id    |  status   | fulfilment | runs
----------+-----------+------------+------
 f7e1e1eb | delivered | suspended  |    2
 58b424f5 | cancelled | cancelled  |    2
(2 rows)
```

Finally, restart the application and ask for the first order again. Its status hasn't changed, and the store found nothing to migrate. Start a second process on another port against the same database, and the two share the work: each instance runs on one of them at a time. To see the 3-day timeout without waiting 3 days, use a test clock, as the tests below do.

##### Test with a manual clock[#](/reliability/workflows#test-with-a-manual-clock)

Two things make workflow tests fast and deterministic:

* Every timestamp the engine uses (deadlines, retry times, lease expiry and `ctx.now()`) comes from the module's `clock`. A `ManualWorkflowClock` only moves when you call `advance()`.
* With the worker disabled, nothing runs in the background. `WorkflowWorker.drain()` runs every due instance until none is left that can start, and starts the occurrences of schedules that the clock has passed. The clock starts on 1 January 2026 at 00:00 UTC, so a test that moves it by days also starts the invoice batch's first occurrence, at 07:00 UTC.

Run the tests on PGlite, with your real migrations. Override the database `DrizzleModule` registers (`getDrizzleToken()` returns its token) with one on PGlite: the workflow store follows, because its factory injects it, and creates its schema there when the application starts. Override `WORKFLOWS_MODULE_OPTIONS` with a `ManualWorkflowClock` and a disabled worker. Share the database and the stand-ins for the external APIs between applications, because they outlive a process:

test/support.ts

JS TS

```typescript

import { fileURLToPath } from 'node:url';
import { PGlite } from '@electric-sql/pglite';
import { Test } from '@nestjs/testing';
import { ManualWorkflowClock, WORKFLOWS_MODULE_OPTIONS, WorkflowClient, WorkflowWorker } from '@nestjs/workflows';
import { drizzle } from 'drizzle-orm/pglite';
import { migrate } from 'drizzle-orm/pglite/migrator';
// ...AppModule, getDrizzleToken, the schema and the stand-in services

/**
 * PostgreSQL in-process (PGlite), with the app's migrations applied: the orders
 * table. The workflow store creates its own tables when the application starts.
 */
export async function createDatabase() {
  const client = new PGlite();
  const db = drizzle(client, { schema });
  await migrate(db, { migrationsFolder: fileURLToPath(new URL('../drizzle', import.meta.url)) });
  return { db, close: () => client.close() };
}

/** Your database and the external APIs. They outlive a process, so every "process" in a test shares them. */
export async function createWorld() {
  const database = await createDatabase();
  return {
    db: database.db,
    paymentProvider: new PaymentProviderClient(),
    inventory: new InventoryService(),
    mail: new MailService(),
    invoices: new InvoicesService(database.db as unknown as Database),
    close: database.close,
  };
}

export type World = Awaited<ReturnType<typeof createWorld>>;

export async function bootApp(clock: ManualWorkflowClock, world: World) {
  const moduleRef = await Test.createTestingModule({ imports: [AppModule] })
    .overrideProvider(getDrizzleToken())
    .useValue(world.db)
    .overrideProvider(WORKFLOWS_MODULE_OPTIONS)
    .useValue({ clock, worker: { enabled: false, shutdownTimeout: 50 } })
    .overrideProvider(PaymentProviderClient)
    .useValue(world.paymentProvider)
    .overrideProvider(InventoryService)
    .useValue(world.inventory)
    .overrideProvider(MailService)
    .useValue(world.mail)
    .overrideProvider(InvoicesService)
    .useValue(world.invoices)
    .compile();
  const app = moduleRef.createNestApplication({ logger: false });
  await app.listen(0, '127.0.0.1');
  return {
    app,
    url: await app.getUrl(),
    orders: app.get(OrdersService),
    workflows: app.get(WorkflowClient),
    worker: app.get(WorkflowWorker),
    close: () => app.close(),
  };
}

export type App = Awaited<ReturnType<typeof bootApp>>;
```

With a manual clock, the 3-day timeout is one `advance()` call:

test/order-fulfilment.spec.ts

JS TS

```typescript

describe('order fulfilment', () => {
  let clock: ManualWorkflowClock;
  let world: World;
  let node: App;

  beforeEach(async () => {
    clock = new ManualWorkflowClock();
    world = await createWorld();
    node = await bootApp(clock, world);
  });

  afterEach(async () => {
    await node.close();
    await world.close();
  });

  // ...

  it('refunds and releases the stock when the carrier never confirms delivery', async () => {
    const order = await node.orders.place({ userId: 'u_42', items: [{ productId: KIBBLE, quantity: 1, price: 2499 }] });
    await node.worker.drain(); // charge, reserve, then park for up to 3 days

    clock.advance('3d');
    await node.worker.drain(); // the wait times out and the compensations run

    const fulfilment = await node.workflows.getStatus(fulfilmentId(order.id), { journal: true });
    expect(fulfilment).toMatchObject({
      status: 'failed',
      error: { message: `Order ${order.id} was not delivered within 3 days.` },
    });
    // Compensations run in reverse: release the stock, then refund.
    expect(fulfilment!.journal.filter((entry) => entry.kind === 'compensation').map((entry) => entry.name)).toEqual([
      '$compensate:reserve-stock',
      '$compensate:charge-payment',
    ]);
    expect(world.paymentProvider.refunds).toHaveLength(1);
    expect(world.inventory.stock.get(KIBBLE)).toBe(25);
  });

  // ...

  it('saves the order and starts its fulfilment together, or neither', async () => {
    // The transaction fails after start(): say, the next statement hits a constraint.
    const original = node.workflows.start.bind(node.workflows);
    vi.spyOn(node.workflows, 'start').mockImplementationOnce(async (...args) => {
      await original(...args); // the instance is created in the transaction...
      throw new Error('insert or update on table "order_lines" violates foreign key constraint');
    });
    await expect(place()).rejects.toThrow('violates foreign key constraint');

    // ...and rolled back with it: no order, no fulfilment for the worker to charge.
    expect(await world.db.select().from(orders)).toEqual([]);
    expect(await node.workflows.list()).toEqual([]);
    expect(await node.worker.drain()).toBe(0);
    expect(world.paymentProvider.requests).toBe(0);
  });
});
```

##### Test crash recovery[#](/reliability/workflows#test-crash-recovery)

`createWorld()` creates a fresh database per test. Crash safety needs two applications on the same database. Closing an application while a step hangs simulates a crash: the shutdown timeout expires, and the dead process's lease stays in the database until it expires. The second application takes over after that:

test/crash-recovery.spec.ts

JS TS

```typescript

it('survives a crash in the middle of an order', async () => {
  const first = await bootApp(clock, world);
  const order = await first.orders.place({ userId: 'u_42', items: [{ productId: KIBBLE, quantity: 1, price: 2499 }] });

  // The process dies while reserving stock, after the payment provider charged the card.
  const reserve = vi.spyOn(world.inventory, 'reserve').mockImplementationOnce(() => new Promise<never>(() => {}));
  void first.worker.drain();
  await vi.waitFor(() => expect(reserve).toHaveBeenCalled());
  await first.close();

  // Another process on the same database takes over once the dead one's lease expires.
  const second = await bootApp(clock, world);
  clock.advance('31s');
  await second.worker.drain();

  expect(await second.workflows.getStatus(fulfilmentId(order.id))).toMatchObject({
    status: 'suspended',
    waits: [
      { signal: 'shipment.delivered', key: order.id },
      { signal: 'shipment.returned', key: order.id },
    ],
  });
  expect(world.paymentProvider.charges).toHaveLength(1); // journaled: not charged again
  expect(reserve.mock.calls.map(([, key]) => key)).toEqual([
    `order-${order.id}:reserve-stock`, // the attempt that died
    `order-${order.id}:reserve-stock`, // the retry, with the same key
  ]);
  await second.close();
});
```

The same setup covers a crash in the middle of the compensations: the next process replays the journal to rebuild the list of compensations, skips the ones already done, and continues with the rest. PGlite is a single connection, so it can't show two workers racing for the same instance; the tutorial's tests of the store run the contract's races on a PostgreSQL server, along with three applications sharing 30 orders.

To give a test its own store without overriding providers, call `registerSource()` on `moduleRef.get(WorkflowStorage)` before `init()`, with `replace: true`: without it, a second registration throws. The `clock` option takes any `WorkflowClock`, an object whose `now()` returns epoch milliseconds, so a test can drive the engine from a clock it already has.

#### With CQRS[#](/reliability/workflows#with-cqrs)

If your application follows the [CQRS recipe](/recipes/cqrs), command handlers publish events, and event handlers and sagas react to them. They react in memory: an event published just before the process stops never reaches them, and a saga that waits for a second event forgets the first one on a restart. The `@nestjs/workflows/cqrs` entry point lets the events themselves start and signal workflows, durably, while your code keeps executing commands and publishing events. It works with `@nestjs/cqrs` 11 and later, registered with `CqrsModule.forRoot()` as in the recipe.

##### Map events to workflows[#](/reliability/workflows#map-events-to-workflows)

Here the fulfilment starts when the order is placed and wakes when the carrier reports the delivery, as before, but the workflow client calls are gone from the application code. Import `WorkflowsCqrsModule` next to `CqrsModule` and `WorkflowsModule`:

app.module.ts

JS TS

```typescript

import { CqrsModule } from '@nestjs/cqrs';
import { WorkflowsModule, WorkflowStorage } from '@nestjs/workflows';
import { WorkflowsCqrsModule } from '@nestjs/workflows/cqrs';

@Module({
  imports: [
    // ...DrizzleModule, as before
    CqrsModule.forRoot(),
    WorkflowsModule.forRoot(),
    WorkflowsCqrsModule, // mapped events start and signal workflows
  ],
  controllers: [OrdersController, CarrierWebhookController],
  providers: [
    // ...the store and the services, as before
    PlaceOrderHandler,
    MarkDeliveredHandler,
    ChargePaymentHandler,
    OrderFulfilmentWorkflow,
  ],
})
export class AppModule {}
```

Then map the events on the workflow class. `@StartOn()` starts the workflow when an event is published, and `@SignalOn()` sends one of its signals:

orders/order-fulfilment.workflow\.ts

JS TS

```typescript

import { SignalOn, StartOn } from '@nestjs/workflows/cqrs';
import { OrderDeliveredEvent } from './order-delivered.event.js';
import { OrderPlacedEvent } from './order-placed.event.js';

@Workflow('order-fulfilment')
@StartOn(OrderPlacedEvent, {
  id: (event) => fulfilmentId(event.order.id),
  input: (event) => event.order,
  // Lower runs first: express orders before standard ones.
  priority: (event) => (event.order.shipping === 'express' ? 1 : 2),
})
@SignalOn(OrderDeliveredEvent, {
  signal: shipmentDelivered,
  key: (event) => event.delivery.reference,
  id: (event) => event.delivery.trackingNumber,
  payload: (event) => event.delivery,
})
export class OrderFulfilmentWorkflow implements WorkflowRunner<Order, FulfilmentResult> {
  // ...the constructor, which now injects CommandBus too, and run()
}
```

`@StartOn()`'s `id` is required. It derives the instance id from the business key, as `start()` does, so an event published twice finds the instance the first one started. It also takes `start()`'s `priority`, `concurrencyKey` and `rateLimitKey`, each as a value or a function of the event: here, express orders go first, as before. `@SignalOn()`'s `id` is optional, and becomes the signal's `id`: a delivery event published again, say for the carrier's retried webhook, stores no second signal. `input` defaults to the event itself, and a signal's `payload` too. TypeScript checks the input against `run()` and the payload against the signal's type. The events are plain classes, such as `OrderPlacedEvent` with a `readonly order: Order` constructor parameter.

The command handler saves the order and publishes the event in one transaction:

orders/place-order.handler.ts

JS TS

```typescript

import { randomUUID } from 'node:crypto';
import { CommandHandler, EventBus, type ICommandHandler } from '@nestjs/cqrs';
import { InjectDrizzle } from '@nestjs/drizzle';
import type { Database } from '../database/drizzle.js';
import { orders } from '../database/schema.js';
import type { Order } from './order.js';
import { OrderPlacedEvent } from './order-placed.event.js';
import { PlaceOrderCommand } from './place-order.command.js';

@CommandHandler(PlaceOrderCommand)
export class PlaceOrderHandler implements ICommandHandler<PlaceOrderCommand> {
  constructor(
    @InjectDrizzle() private readonly db: Database,
    private readonly eventBus: EventBus,
  ) {}

  async execute({ dto }: PlaceOrderCommand): Promise<Order> {
    const total = dto.items.reduce((sum, item) => sum + item.price * item.quantity, 0);
    const order: Order = {
      id: randomUUID().slice(0, 8),
      userId: dto.userId,
      items: dto.items,
      shipping: dto.shipping ?? 'standard',
      total,
      status: 'placed',
    };

    return this.db.transaction(async (tx) => {
      await tx.insert(orders).values(order);
      // The transaction rides along as the dispatcher context: the fulfilment
      // this event starts commits with the order, or rolls back with it.
      await this.eventBus.publish(new OrderPlacedEvent(order), { transaction: tx });
      return order;
    });
  }
}
```

The second argument of `publish()` and `publishAll()` is CQRS's dispatcher context. `WorkflowsCqrsModule` reads its `transaction` property and passes it to `start()` and `signal()`, so the instance is created through your transaction, exactly as with the `transaction` option. With TypeORM, the dispatcher context carries the `EntityManager` that `dataSource.transaction()` hands its callback, under the same `transaction` property. `publish()` resolves once the workflows are started and signalled, and only then does the event reach your event handlers and sagas. Events that no workflow maps go straight through, unchanged. The controllers execute the commands: `POST /orders` executes `PlaceOrderCommand`, and the carrier's webhook executes `MarkDeliveredCommand`, whose `MarkDeliveredHandler` does the same for the delivery: it updates the order's status and publishes `OrderDeliveredEvent` in one transaction, so the status and the signal commit together.

The module wraps whatever publisher the event bus has, so a publisher you set with `CqrsModule.forRoot()`'s `eventPublisher` option (a message broker, for example) still receives every event, after the workflows. Replacing `EventBus.publisher` after startup would bypass the workflows, so startup fails if something does. It also fails when a workflow maps events but `WorkflowsCqrsModule` isn't imported, when one class maps the same event twice, or when `@StartOn()` gives a key to a workflow without a limit per key. When two versions of a workflow are registered, the highest version's `@StartOn()` decides what starts, and a signal reaches the waiting instances of every version, sent once, so their `@SignalOn()` declarations must agree on its payload and `id`: `publish()` rejects when they don't.

The mappings live on the workflow classes, so every process that publishes mapped events registers them, including one that runs no workflows, such as an API that only places orders. Register the classes and the store there as usual, and pass `worker: false` to `WorkflowsModule.forRoot()`: the process starts and signals the workflows, and the worker processes execute them. A process that imports `WorkflowsCqrsModule` but registers no workflow that maps an event starts and signals nothing, and logs a warning at startup saying so.

##### Execute commands from steps[#](/reliability/workflows#execute-commands-from-steps)

A step can execute commands. Pass the step's idempotency key along with the command, and have the handler hand it to the system it calls:

orders/order-fulfilment.workflow\.ts

JS TS

```typescript

const charge = await ctx.step(
  'charge-payment',
  ({ idempotencyKey }) => this.commandBus.execute(new ChargePaymentCommand(order, idempotencyKey)),
  {
    retry: { attempts: 5, backoff: { delay: '2s' } },
    compensate: (charge, { idempotencyKey }) => this.paymentsService.refund(charge.chargeId, idempotencyKey),
  },
);
```

`ChargePaymentHandler` calls `PaymentsService.charge()` with the key, so a retried step never charges twice, and the command's result is journaled like any step's. A step can publish events and send signals too. It runs at least once, so an event published from a step may be published again. A mapped start finds its instance, and so does a `start()` without an `id` in a step: it gets an id derived from the step's `idempotencyKey`, the workflow's name and its place among the step's starts of that workflow, and a repeat returns the instance as first started, input included. A signal sent from inside a step, directly or through a mapped event, is stored once: without an `id` of its own, it gets one derived from the step's `idempotencyKey` and its place among the step's signals with the same name and key. Send those in a fixed order. A step that sends several with one name and key concurrently should give each its own `id`.

##### What each way of publishing guarantees[#](/reliability/workflows#what-each-way-of-publishing-guarantees)

The guarantee depends on how, and when, the event is published:

| How the event is published                                                                                                                                                       | The workflow's start or signal                                                                  | If the process dies or a write fails                                                                                                                                                                                                                         |
| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| In your transaction, with the transaction in the dispatcher context                                                                                                              | Commits with your writes, or not at all                                                         | Nothing is half done. A failed start or signal rejects `publish()`, and your transaction rolls back                                                                                                                                                          |
| An aggregate's events, from `commit()` with the transaction in the dispatcher context (`@nestjs/cqrs` 12.1 or later), or with `publishAll()` in your transaction, as shown below | Commits with your writes, or not at all                                                         | As above: a failed start or signal rejects `commit()` or `publishAll()`, and your transaction rolls back                                                                                                                                                     |
| After your transaction commits                                                                                                                                                   | Written before `publish()` resolves                                                             | A crash between your commit and the publish loses it. Publish again from a reconciliation job: the start's `id` makes that safe, and so does a signal's, if `@SignalOn()` sets one                                                                           |
| From `commit()` without a transaction, of an aggregate merged with `EventPublisher`                                                                                              | Written outside your transaction, in the background unless you await `commit()` (12.1 or later) | Lost on a crash while nothing waits for it, and left behind when your transaction rolls back. Failures go to the `UnhandledExceptionBus` and the log, and the module logs a warning once per event class                                                     |
| From `commit()` without a transaction, of a `@Publishable()` aggregate                                                                                                           | Written outside your transaction, in the background unless you await `commit()` (12.1 or later) | Lost on a crash while nothing waits for it, and left behind when your transaction rolls back. Unawaited, a failure is an unhandled promise rejection, which stops Node.js by default. Nothing tells it apart from a plain `publish()`, so there's no warning |
| From a workflow step                                                                                                                                                             | Once, however often the step runs                                                               | A retried step starts nothing new, and stores no second signal                                                                                                                                                                                               |

An aggregate merged with `EventPublisher.mergeObjectContext()` or `mergeClassContext()`, or decorated with `@Publishable()`, publishes its events from `commit()`. With `@nestjs/cqrs` 12.1 or later, `commit()` takes a dispatcher context, as `publish()` does, and returns what the event bus returns. Pass it your transaction and await it in the command handler's transaction: the aggregate's events then start and signal workflows in that transaction, and `commit()` rejects when a start or signal fails, which rolls the transaction back:

```typescript

await order.commit({ transaction: tx });
```

`commit()` clears the aggregate's events when it hands them over, before the workflows are written, so after a failure, run the command again with a freshly loaded aggregate.

Without a dispatcher context, `commit()` publishes outside your transaction: the workflows still start, but a rollback leaves them behind, and a crash before they're written loses them. Don't let it publish events that start or signal workflows. With `@nestjs/cqrs` 12.0 or earlier, `commit()` takes no context and returns nothing to wait for, so publish the aggregate's events yourself, in the command handler's transaction, and then clear them:

```typescript

await this.eventBus.publishAll(order.getUncommittedEvents(), { transaction: tx });
order.uncommit();
```

The module tells you when a mapped event arrives from a merged aggregate's `commit()` without a transaction: the first time, it logs a warning naming the event class. A `@Publishable()` aggregate's events arrive without any dispatcher context, like an ordinary `publish()` call, so they get no warning.

Your event handlers and sagas still receive every event, in memory, after the workflows. Inside a transaction they run before it commits, as they always did, so they can react to an event whose transaction then rolls back. A saga that turns one event into one command can stay a saga. A saga that remembers events, such as one that waits for the payment after the order and gives up after an hour, is a workflow in disguise: start the workflow from the first event, map the others to signals, and let `waitForSignal()` with a `timeout` do the waiting, durably.

#### Prepare for production[#](/reliability/workflows#prepare-for-production)

##### Keep journals short[#](/reliability/workflows#keep-journals-short)

Every execution loads the instance's whole journal and replays `run()` from the top. A process with a fixed number of steps keeps its journal small, but a loop with a step or a sleep per round adds entries for as long as it runs, and each execution gets slower. The module warns when a journal reaches 1,000 entries or 1 MB: once per instance, when it crosses the line, in the log and as a `journal-large` event. Once it holds 10,000 entries or 10 MB, the instance fails before it records another one: its compensations run, which may still record theirs, and it ends as `failed` with a `WorkflowJournalLimitError`. The module's `journal` option moves both lines. Size them to your longest regular workflow with room to spare, and set a limit to `Infinity` to turn it off:

```typescript

WorkflowsModule.forRoot({
  journal: { warnEntries: 500, maxEntries: 5_000 },
});
```

A process that goes on for good, such as a monthly litter subscription, continues in a new instance instead. After a year of deliveries, its last step starts the next year's instance, and the current one completes:

```typescript

async run(ctx: WorkflowContext, subscription: Subscription) {
  for (let month = 1; month <= 12; month++) {
    await ctx.step(`ship-${month}`, ({ idempotencyKey }) => this.subscriptionsService.ship(subscription, idempotencyKey));
    await ctx.sleep(`wait-${month}`, '30d');
  }

  const next = { ...subscription, year: subscription.year + 1 };
  return ctx.step('continue', async () => {
    const { id } = await this.workflowClient.start(LitterSubscriptionWorkflow, next, {
      id: `subscription-${subscription.id}-${next.year}`,
    });
    return id;
  });
}
```

The step starts the next instance once: a retried step finds the instance it started. The new instance has a fresh journal and its own id, so the finished year stays readable until retention purges it. Continuing under the same id would need every store to replace a journal in place, under the worker's lease; a new id needs nothing new from the store. When each round stands on its own, a schedule is simpler still: it starts an instance per occurrence, each with a journal of its own, as [Run workflows on a schedule](/reliability/workflows#run-workflows-on-a-schedule) shows.

##### Encrypt what workflows store[#](/reliability/workflows#encrypt-what-workflows-store)

The store keeps what your workflows handle: orders, charges, deliveries. To keep that unreadable to whoever reads the database or its backups, give the module a **payload codec**. `AesGcmPayloadCodec` encrypts with AES-256-GCM, under keys from your secret manager. Create it in the module's factory, which runs at startup:

app.module.ts

JS TS

```typescript

import { AesGcmPayloadCodec, WorkflowsModule, WorkflowStorage } from '@nestjs/workflows';

WorkflowsModule.forRootAsync({
  useFactory: () => ({
    worker: {
      // ...as before
    },
    // Encrypts what the store keeps. The key comes from your secret manager, through the environment.
    codec: new AesGcmPayloadCodec({
      keys: { '2026-09': process.env.WORKFLOWS_KEY_2026_09! },
      current: '2026-09',
    }),
  }),
}),
```

A key is 32 random bytes in base64 (`openssl rand -base64 32`), under an id of your choice. A key that is missing (an unset environment variable), isn't base64 or isn't 32 bytes fails the startup, with an error that names it.

* **What it encrypts**: everything that holds your data. Inputs and outputs, step results and checkpoints, signal payloads, custom statuses, cancel reasons, schedules' inputs, and the messages and stacks of errors. Each payload is encrypted under a key derived for it, with where it's stored as authenticated data, so a payload that was changed, or moved to another instance or field, fails to decrypt instead of being read. Payloads of 1 KiB or more are compressed first. If payloads mix secrets with data an attacker chooses, and attackers can see stored sizes, turn that off with `compress: false`.
* **What stays readable**, because the store matches, filters, orders or counts on it: ids, workflow names and versions, statuses, signal names and keys, concurrency and rate-limit keys, priorities, links to parents and schedules, journal entry names, and all times. Errors keep their names, such as `StepFailedError`. So pick ids and keys that say nothing sensitive: `order-71e1973d`, not an email address. Here the concurrency key is the customer's id, readable in `concurrency_key`.
* **Stored form**: `$wf1:aes-256-gcm:2026-09.` followed by the ciphertext, a string in the same JSON columns, so the store needs no change.

**Rotating keys.** Add a key, and make it `current`. A payload decrypts with the key that encrypted it, and everything written from then on uses the current one. Nothing is re-encrypted in bulk: payloads are rewritten as instances progress, and old ones go with purges. So keep a key listed while anything it encrypted may still be read: unfinished instances, signals not purged yet, and schedules saved under it. A declared schedule's input is saved again under the current key at startup and every minute, but an upserted one's only by its next `upsert()`: `pause()` and `resume()` keep it as stored.

```typescript

codec: new AesGcmPayloadCodec({
  keys: {
    '2027-03': process.env.WORKFLOWS_KEY_2027_03!,
    '2026-09': process.env.WORKFLOWS_KEY_2026_09!,
  },
  current: '2027-03',
}),
```

An instance whose payloads need a key that isn't listed can't be read: `getStatus()` throws an error that names the key, `list()` shows the instance without its payloads, and workers leave it alone until the key is back, then run it.

Adding a codec breaks no running instance: payloads stored before it are read as they are, and new writes are encrypted. That is also where the protection ends. Someone who can write to the database can replace an encrypted payload with a plain one, and have it read: the codec protects what it encoded against reading and tampering, not the database against its writers.

A codec of your own implements `WorkflowPayloadCodec`: an `id`, stored with each payload, and `encode()` and `decode()`, which receive the value and where it's stored. Pass its class to `codec` to have Nest create it, with its dependencies from global modules, such as a KMS client. To replace a codec, list the new one first and the old one after it: the first one encodes, and each payload is decoded by the codec whose id it carries.

##### Production checklist[#](/reliability/workflows#production-checklist)

* Pass the `idempotencyKey` to every side effect, including compensations. Steps run at least once.
* Give signals an `id` when their sender can run twice, such as a webhook the sender retries or a message consumer. Signals sent from a step get one automatically.
* Call `enableShutdownHooks()`, and keep `shutdownTimeout` below your platform's grace period (30 seconds by default on Kubernetes).
* Choose `leaseDuration` deliberately. It's how long a crashed process's instances wait before another process takes over, and a process whose event loop stalls for longer loses its instances. Lease expiry compares timestamps written by different hosts, so keep their clocks in sync (NTP) and `leaseDuration` well above any skew between them.
* Register a store on your database: `PostgresWorkflowStore`, `MySqlWorkflowStore`, or one of your own. In memory, or in a file on the container's disk, state dies with the instance: the in-memory default loses every running order on restart, and startup refuses it in production. Run the contract suite against a store of your own in CI, on its database, with `concurrent: true`.
* Apply the store's migrations before a new version starts, with `npx @nestjs/workflows migrate` or your migration tool, and check them in CI with `npx @nestjs/workflows status`. With `NODE_ENV=production`, the store doesn't migrate at startup: a schema that's behind fails it instead.
* Run as many workers as you like, on as many hosts. Size the connection pool for them: each running instance renews its lease and writes its journal through the pool, and each poll holds a connection for its claim.
* Start workflows in the transaction that writes their business rows (`transaction: tx`, or the `EntityManager` with TypeORM), so a crash between the two can't leave an order that nothing fulfils. Pass the transaction, never the root database. With CQRS, publish the events inside that transaction, with the transaction in the dispatcher context.
* Keep transactions that send signals short: signals and the suspensions that register waits queue behind them. On PostgreSQL, keep them READ COMMITTED, and the database's default isolation too: the store refuses a stricter one. On MySQL, keep them REPEATABLE READ or READ COMMITTED, and run a transaction again when it fails with a deadlock (error 1213).
* Verify webhook signatures, and return `2xx` only after the transaction with the signal has committed.
* Alert on instances that need a person. `compensation_failed` means an undo gave up halfway, and a `failed` instance with `WorkflowNonDeterminismError` means a deploy broke replay. `WorkflowClient.list()` finds them, and [What each status means](/reliability/workflows#what-each-status-means) says what to do with each: `retry()` once the cause is fixed, or `delete()`. For logs and metrics, subscribe to `WorkflowEvents.events$`, or to the `nestjs:workflows:*` diagnostics channels that tracing tools read without Nest; [Events](/reliability/workflows#events) maps them onto a trace.
* Mark your point of no return with `ctx.commit()`. Before it, every failure and cancel undoes the completed steps.
* Purge finished instances every night with `purge()`, on one instance of the application, as [Purge finished instances](/reliability/workflows#purge-finished-instances) shows. Keep its `olderThan` longer than any sender's redelivery window: a signal's `id` deduplicates only as long as the signal is stored.
* Keep journals short: bound loops, and continue one that never ends in a new instance ([Keep journals short](/reliability/workflows#keep-journals-short)). Give a process that must give up at some point a run timeout ([Time out the whole workflow](/reliability/workflows#time-out-the-whole-workflow)).
* Size concurrency and rate limits to what the steps call, and deploy a change to them to every process: each applies the limits of the code it runs. Once some instances have a priority, give the rest one too, since instances without one go first.
* Deploy a declared schedule to every process that registers its workflow: only workers whose code declares it start its occurrences. A schedule that a deploy drops, or whose workflow it removes, keeps starting on the processes of the old code, and goes about five minutes after the last of them stopped. Set `missed` for work that mustn't be skipped when no worker is up at its time. If processes of other code share the database, don't leave a schedule without a worker whose code declares it for five minutes: they delete it, and it starts over once one starts.
* Encrypt what the store keeps with a codec, with keys from your secret manager ([Encrypt what workflows store](/reliability/workflows#encrypt-what-workflows-store)). Keep an old key listed while anything it encrypted may be read, and pick ids and keys that say nothing sensitive: they stay readable.

#### Reference[#](/reliability/workflows#reference)

##### Module options[#](/reliability/workflows#module-options)

`WorkflowsModule.forRoot()` takes these options; `forRootAsync()` takes them from `useFactory`, `useClass` or `useExisting` (a class implementing `WorkflowsOptionsFactory`). The options token is `WORKFLOWS_MODULE_OPTIONS`. The store isn't an option: register it with `WorkflowStorage`, as in [Keep workflows in your database](/reliability/workflows#keep-workflows-in-your-database).

| Option                                     | Default                                             | Meaning                                                                                                                                                                                                   |
| ------------------------------------------ | --------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `worker.enabled`                           | `true`                                              | Run the polling loop. `worker: false` is shorthand for `enabled: false`: the process starts, signals and inspects workflows, and `WorkflowWorker.drain()` runs due instances on demand                    |
| `worker.id`                                | `hostname:pid:random`                               | The worker's name, shown as the instance's `leaseOwner`                                                                                                                                                   |
| `worker.concurrency`                       | `10`                                                | Instances this process executes at once                                                                                                                                                                   |
| `worker.pollInterval`                      | `'1s'`                                              | How often to look for due instances. A local `start()` or `signal()` wakes the loop at once                                                                                                               |
| `worker.leaseDuration`                     | `'30s'`                                             | How long a claim is valid without a renewal, so how long a crashed process keeps its instances                                                                                                            |
| `worker.heartbeatInterval`                 | A third of `leaseDuration`                          | How often a running instance renews its lease                                                                                                                                                             |
| `worker.shutdownTimeout`                   | `'10s'`                                             | How long shutdown waits for running executions before handing them back                                                                                                                                   |
| `retry`                                    | 3 attempts, `'1s'` doubling up to `'5m'`, no jitter | The default for every step. See the retry fields below                                                                                                                                                    |
| `journal.warnEntries`, `journal.warnBytes` | `1000`, `1000000`                                   | At either, log a warning and emit `journal-large`, once per instance ([Keep journals short](/reliability/workflows#keep-journals-short))                                                                  |
| `journal.maxEntries`, `journal.maxBytes`   | `10000`, `10000000`                                 | At either, fail the instance with a `WorkflowJournalLimitError` before it records another entry. `Infinity` turns a check off                                                                             |
| `clock`                                    | The system clock                                    | A `WorkflowClock`. Tests pass a `ManualWorkflowClock` ([Test with a manual clock](/reliability/workflows#test-with-a-manual-clock))                                                                       |
| `allowInMemoryStorage`                     | `false`                                             | With `NODE_ENV=production` and no registered store, startup fails; `true` runs on the in-memory store anyway                                                                                              |
| `codec`                                    | None                                                | A `WorkflowPayloadCodec`, its class, or a list of them: the first encodes, and each decodes the payloads it encoded ([Encrypt what workflows store](/reliability/workflows#encrypt-what-workflows-store)) |
| `isGlobal`                                 | `true`                                              | Registers the module globally. Top level of `forRoot()` and `forRootAsync()`                                                                                                                              |

A `retry` option (the module's, a step's `retry` or its `compensateRetry`) is a number of attempts, `false` for a single attempt, or an object with these fields. A step's `retry` merges over the module's field by field.

| Field              | Default     | Meaning                                                                |
| ------------------ | ----------- | ---------------------------------------------------------------------- |
| `attempts`         | `3`         | Total attempts, including the first                                    |
| `backoff.delay`    | `'1s'`      | The wait before the first retry                                        |
| `backoff.factor`   | `2`         | Growth per retry; `1` keeps the wait constant                          |
| `backoff.maxDelay` | `'5m'`      | The cap for a single wait                                              |
| `backoff.jitter`   | `'none'`    | `'full'` (zero to the wait), `'equal'` (half to all of it) or `'none'` |
| `retryIf`          | Every error | `(error, attempt) => boolean`: `false` fails the step at once          |

`backoff` can also be a function, `(attempt, error) => duration`. A `NonRetryableStepError` never retries.

##### PostgreSQL store[#](/reliability/workflows#postgresql-store)

`new PostgresWorkflowStore(options, workflowStorage)`, from `@nestjs/workflows/postgres`, takes these options:

| Option     | Default                                   | Meaning                                                                                                                                             |
| ---------- | ----------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| `executor` | Required                                  | How the store reaches the database: `fromDrizzle(db)`, `fromTypeOrm(dataSource)`, `fromPg(pool)`, `fromPrisma(prisma, options)` or `fromKysely(db)` |
| `schema`   | `'nest_workflows'`                        | The schema of its tables, which its first migration creates. Letters, digits and underscores, not starting with a digit, at most 63 characters      |
| `migrate`  | `true`, except with `NODE_ENV=production` | Apply the pending migrations when the application starts. With `false`, startup fails with a `WorkflowSchemaError` while the schema is behind       |

Each executor takes your database client, and its own kind of transaction object, which `start()` and `signal()` then take as `transaction`:

| Executor                      | Takes                                                                                                                                                                                                  | Transaction object                                                                                                    |
| ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------- |
| `fromDrizzle(db)`             | A Drizzle PostgreSQL database, whichever its driver                                                                                                                                                    | The `tx` that `db.transaction()` hands its callback                                                                   |
| `fromTypeOrm(dataSource)`     | A `DataSource` of type `postgres`, or its `manager`                                                                                                                                                    | The `EntityManager` that `dataSource.transaction()` hands its callback, or a `QueryRunner` after `startTransaction()` |
| `fromPg(pool)`                | A node-postgres `Pool`, or a connected `Client`                                                                                                                                                        | A client, such as one from `pool.connect()`, after `BEGIN`                                                            |
| `fromPrisma(prisma, options)` | A Prisma client on PostgreSQL, through a driver adapter such as `@prisma/adapter-pg` or Prisma's engine. `maxWait` (default `'10s'`) and `timeout` (default `'1m'`) limit the store's own transactions | The transaction client that `prisma.$transaction()` hands its callback                                                |
| `fromKysely(db)`              | A `Kysely` instance with a PostgreSQL dialect. The store's statements skip its plugins                                                                                                                 | The transaction that `db.transaction().execute()` hands its callback, or a controlled transaction                     |

The store's `migrate()` method applies the pending migrations at once, whatever the `migrate` option says, and resolves with the versions it applied. `PostgresWorkflowStore.migrationSql()` returns their SQL, with the bookkeeping. Its options are the `schema`, the versions to go `from` (default `0`, a new database) and `to` (default: the one the package needs), and `statementBreakpoints`, which separates the statements with drizzle-kit's `--> statement-breakpoint` lines. From version 0, it starts with `CREATE SCHEMA IF NOT EXISTS`, which needs the CREATE privilege on the database: leave it out if someone created the schema for you. `PostgresWorkflowStore.schemaVersion` is the version the package needs. A schema's own version is the highest in its `migrations` table.

##### MySQL store[#](/reliability/workflows#mysql-store)

`new MySqlWorkflowStore(options, workflowStorage)`, from `@nestjs/workflows/mysql`, runs on MySQL 8.4 LTS and 9.x, and takes these options:

| Option     | Default                                   | Meaning                                                                                                                                                                                   |
| ---------- | ----------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `executor` | Required                                  | How the store reaches the database: `fromDrizzle(db)`, `fromTypeOrm(dataSource)`, `fromMysql2(pool)`, `fromPrisma(prisma, options)` or `fromKysely(db)`, from `@nestjs/workflows/mysql`   |
| `schema`   | `'nest_workflows'`                        | The start of its tables' names (`nest_workflows_instances`...), in the connection's database. Lowercase letters, digits and underscores, not starting with a digit, at most 40 characters |
| `migrate`  | `true`, except with `NODE_ENV=production` | Apply the pending migrations when the application starts, one statement at a time. With `false`, startup fails with a `WorkflowSchemaError` while the tables are behind                   |

| Executor                      | Takes                                                                                                                                                                                                                                      | Transaction object                                                                                                    |
| ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------- |
| `fromDrizzle(db)`             | A Drizzle MySQL database (`drizzle-orm/mysql2`)                                                                                                                                                                                            | The `tx` that `db.transaction()` hands its callback                                                                   |
| `fromTypeOrm(dataSource)`     | A `DataSource` of type `mysql`, or its `manager`                                                                                                                                                                                           | The `EntityManager` that `dataSource.transaction()` hands its callback, or a `QueryRunner` after `startTransaction()` |
| `fromMysql2(pool)`            | A mysql2 pool, or a connection                                                                                                                                                                                                             | A connection, such as one from `pool.getConnection()`, after `beginTransaction()`                                     |
| `fromPrisma(prisma, options)` | A Prisma client on MySQL, through `@prisma/adapter-mariadb`. `maxWait` (default `'10s'`) and `timeout` (default `'1m'`) limit the store's own transactions, `migrate()` included: raise `timeout` for it, or migrate from the command line | The transaction client that `prisma.$transaction()` hands its callback                                                |
| `fromKysely(db)`              | A `Kysely` instance with a `MysqlDialect`. The store's statements skip its plugins                                                                                                                                                         | The transaction that `db.transaction().execute()` hands its callback, or a controlled transaction                     |

At startup, the store checks the server and the connection: MySQL, not MariaDB; a strict `sql_mode` (`STRICT_TRANS_TABLES`, MySQL's default), without which MySQL would cut a value too long for its column; and a database, where its tables go. It counts the rows an update matched, so keep mysql2's `FOUND_ROWS` flag, which is on by default (Prisma's adapter calls it `foundRows`), and leave the `NO_BACKSLASH_ESCAPES` SQL mode off.

Its ids, names and keys are indexed columns of bounded length, in characters:

| Key                                                                                                                                              | At most |
| ------------------------------------------------------------------------------------------------------------------------------------------------ | ------- |
| An instance id, including a child's (by default `<parent id>/<workflow>#<n>`) and that of an instance a schedule starts (`<schedule id>@<time>`) | 255     |
| A schedule id                                                                                                                                    | 230     |
| A workflow's name, a signal's name, `key` and `id`, a concurrency key, a rate-limit key                                                          | 255     |
| A journal entry's name: a step's, a sleep's or a wait's, and those the engine adds, such as `$compensate:<step>` and `$child:<child id>`         | 512     |

A longer one fails with a `RangeError` that names it, before any SQL. `migrate()` and `MySqlWorkflowStore.schemaVersion` are the PostgreSQL store's. `MySqlWorkflowStore.migrationSql()` takes the same options and returns the statements to apply in order, each once, and `MySqlWorkflowStore.migrationStatements()` takes the `schema`, `from` and `to` and returns them one per string, for a tool that runs one statement per call. A schema's own version is the highest one applied in its `<schema>_migrations` table.

##### Command line[#](/reliability/workflows#command-line)

`npx @nestjs/workflows` applies either store's migrations from a deploy step or checks them in CI. It takes `--url` (default `DATABASE_URL`) and `--schema` (default `nest_workflows`). The URL picks the store: `postgres://` or `postgresql://` for PostgreSQL, which needs `pg` installed, and `mysql://` for MySQL, which needs `mysql2`.

| Command   | What it does                                                                                                                                                                                         |
| --------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `migrate` | Applies the pending migrations, as `migrate: true` does at startup                                                                                                                                   |
| `status`  | Prints the schema's version and the one the package needs, and exits with 1 while the schema is behind                                                                                               |
| `sql`     | Prints the SQL of `migrationSql()`, from `--from` to `--to`, without a database: PostgreSQL's, or MySQL's with `--dialect mysql`. `--statement-breakpoints` separates the statements for drizzle-kit |

##### The store contract[#](/reliability/workflows#the-store-contract)

`PostgresWorkflowStore` and `MySqlWorkflowStore` implement the `WorkflowStore` interface. For another database, implement it in a provider of your own. The JSDoc of each method on `WorkflowStore` says what the method must do, and which race each rule prevents.

**Registration.** The store is an ordinary singleton provider that calls `registerSource(this)` on the injectable `WorkflowStorage` in its constructor. The registry checks the shape at once, refuses a second registration unless it passes `replace: true`, and locks when `WorkflowsModule` initializes, logging the store in use. A request-scoped provider, a provider in a lazy-loaded module, or a lifecycle hook registers too late, and throws. With nothing registered, the module uses `InMemoryWorkflowStore`: a restart loses every running instance, and two processes don't share them. It can't join your transaction either, so `start()` and `signal()` with `transaction` write at once, and it logs a warning the first time. With `NODE_ENV=production`, startup fails instead, with an error that names the package's stores and the interface to implement, unless you set `allowInMemoryStorage: true` in the module options.

**Atomicity.** Workers, signals, cancels, retries, purges and schedules race each other through the store. `claim()` must never lease one instance to two workers, `write()` must write only while the worker's lease holds, and `signal()` must not slip past an instance that is suspending. So every method that changes state is one conditional statement, or one transaction with the right lock, never a read followed by a write. Two methods are optional: `createInTransaction()` and `signalInTransaction()`, which `start()` and `signal()` call with your transaction object, untouched. They must write through it, and refuse the root handle, whose writes commit on their own. On PostgreSQL, `signalInTransaction()` also refuses a transaction that isn't READ COMMITTED, whose wake-up could miss waits committed after its snapshot.

**Test it** with the suite from `@nestjs/workflows/testing`. `workflowStoreContract()` returns the contract as test cases, races included, for any test runner. The tutorial's tests run it against `PostgresWorkflowStore` through Drizzle, and against `MySqlWorkflowStore` on MySQL, as you would against yours, with a function that returns a store on emptied tables:

test/drizzle-workflow\.store.spec.ts

JS TS

```typescript

// The concurrency cases run too; with one connection, PGlite runs them one statement at a time.
const cases = workflowStoreContract(() => freshStore(db), { concurrent: true, transaction: (work) => db.transaction(work) });
for (const c of cases) {
  it(c.name, c.run);
}
```

With `concurrent: true`, the suite races claims (under limits too), signals, suspensions, children's final writes, cancels and terminates, retries, purges and schedule claims against each other: 60 signals against 60 suspensions, for example. Run it on a database server with a connection pool too, where a store without the right locks fails it. With `transaction`, a function that opens one of your transactions, the cases of the two optional methods run as well. The package's own tests run the suite against a hand-written Drizzle store, as the proof that a store written against the interface passes it.

Packages built on the engine, such as a job queue, take its storage-agnostic parts (clocks, retries, payload codecs, limits, the leased worker loop and schedules) from `@nestjs/workflows/core`; applications don't need it.

##### Call options[#](/reliability/workflows#call-options)

| Call                                                                                                                               | Options                                                                                                                                                                                                                                                                                                                                                                                                                                                   | Explained in                                                                                                                                                                                                                                                                                                                 |
| ---------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `@Workflow(name, options)`                                                                                                         | `version` (default `1`), `timeout` (a run timeout; default none), `concurrency` (`limit`, and a `key` function for a limit per key; one of each in an array), `rateLimit` (`max`, `duration`, and a `key` function; one of each in an array), `schedules` (see the schedule options below)                                                                                                                                                                | [Deploy changes safely](/reliability/workflows#deploy-changes-safely), [Time out the whole workflow](/reliability/workflows#time-out-the-whole-workflow), [Limit how many run at once](/reliability/workflows#limit-how-many-run-at-once), [Run workflows on a schedule](/reliability/workflows#run-workflows-on-a-schedule) |
| `ctx.step(name, fn, options)`                                                                                                      | `retry`, `timeout`, `heartbeatTimeout`, `compensate`, `compensateRetry`                                                                                                                                                                                                                                                                                                                                                                                   | [Write the workflow](/reliability/workflows#write-the-workflow), [Long-running steps](/reliability/workflows#long-running-steps)                                                                                                                                                                                             |
| `ctx.waitForSignal(name, signal, options)`                                                                                         | `key`, `timeout` (resolves `null` when it passes), `match` (a pure filter over the payload)                                                                                                                                                                                                                                                                                                                                                               | [Wait for the delivery webhook](/reliability/workflows#wait-for-the-delivery-webhook)                                                                                                                                                                                                                                        |
| `ctx.sleep(name, duration)`                                                                                                        | A duration, or an object with `until` (a `Date` or epoch milliseconds)                                                                                                                                                                                                                                                                                                                                                                                    | [Sleep for a week, then ask for a review](/reliability/workflows#sleep-for-a-week-then-ask-for-a-review)                                                                                                                                                                                                                     |
| `ctx.waitForAny(name, conditions)`                                                                                                 | An object of conditions: `ctx.signalWait(signal, options)` (`key`, `match`), `ctx.timer(duration)` (a duration, or an object with `until`), or a child's handle. Resolves with the winner's `key` and `value`                                                                                                                                                                                                                                             | [Wait for whichever comes first](/reliability/workflows#wait-for-whichever-comes-first)                                                                                                                                                                                                                                      |
| `ctx.startChild(workflow, input, options)`, `ctx.executeChild(workflow, input, options)`                                           | `id` (default the parent's id, the workflow's name and a count, such as `order-71e1973d/shipment#1`), `version`, `timeout`, `parentClose` (`'cancel'`, `'terminate'` or `'abandon'`; default `'cancel'`), `priority` (default the parent's), `concurrencyKey`, `rateLimitKey`                                                                                                                                                                             | [Start child workflows](/reliability/workflows#start-child-workflows)                                                                                                                                                                                                                                                        |
| `ctx.setStatus(status)`                                                                                                            | A JSON value of up to 16 KiB, or `undefined` to clear it                                                                                                                                                                                                                                                                                                                                                                                                  | [Report its status](/reliability/workflows#report-its-status)                                                                                                                                                                                                                                                                |
| `ctx.schedule`                                                                                                                     | Not a call: the `id` of the schedule and the time `at` of the occurrence that started the instance, or `null`                                                                                                                                                                                                                                                                                                                                             | [Run workflows on a schedule](/reliability/workflows#run-workflows-on-a-schedule)                                                                                                                                                                                                                                            |
| `WorkflowClient.start(workflow, input, options)`                                                                                   | `id` (default a random UUID, or inside a step one derived from the step), `version` (default the highest registered), `timeout` (default the decorator's), `transaction`, `priority` (1 to 2,097,151, lower first; default none, which goes before all), `concurrencyKey`, `rateLimitKey` (instead of the keys the limits compute)                                                                                                                        | [Start it with the order](/reliability/workflows#start-it-with-the-order), [Limit how many run at once](/reliability/workflows#limit-how-many-run-at-once)                                                                                                                                                                   |
| `WorkflowClient.signal(signal, payload, options)`                                                                                  | `key`, `id` (stores a signal with the same name and id once; derived from the step inside a step), `transaction`                                                                                                                                                                                                                                                                                                                                          | [Wait for the delivery webhook](/reliability/workflows#wait-for-the-delivery-webhook), [With CQRS](/reliability/workflows#with-cqrs)                                                                                                                                                                                         |
| `WorkflowClient.startAndWait(workflow, input, options, wait)`                                                                      | `start()`'s options, but not `transaction`, and `result()`'s as `wait`                                                                                                                                                                                                                                                                                                                                                                                    | [Wait for a result](/reliability/workflows#wait-for-a-result)                                                                                                                                                                                                                                                                |
| `WorkflowClient.result(id, options)`                                                                                               | `timeout` (wall-clock; default none), `signal` (stops waiting when aborted)                                                                                                                                                                                                                                                                                                                                                                               | [Wait for a result](/reliability/workflows#wait-for-a-result)                                                                                                                                                                                                                                                                |
| `WorkflowClient.getStatus(id, options)`                                                                                            | `journal`, `children`                                                                                                                                                                                                                                                                                                                                                                                                                                     | [Report its status](/reliability/workflows#report-its-status), [Start child workflows](/reliability/workflows#start-child-workflows)                                                                                                                                                                                         |
| `WorkflowClient.cancel(id, reason)`, `terminate(id, reason)`                                                                       | None                                                                                                                                                                                                                                                                                                                                                                                                                                                      | [Let customer support cancel an order](/reliability/workflows#let-customer-support-cancel-an-order), [Retry, delete or terminate](/reliability/workflows#retry-delete-or-terminate)                                                                                                                                          |
| `WorkflowClient.list(filter)`                                                                                                      | `status` (one or a list), `workflow`, `version`, `parentId`, `scheduleId`, `limit` (default `100`), `offset`                                                                                                                                                                                                                                                                                                                                              | [Deploy changes safely](/reliability/workflows#deploy-changes-safely)                                                                                                                                                                                                                                                        |
| `WorkflowClient.retry(id, options)`                                                                                                | `timeout` (a new run timeout from now, or `false` for none; default the instance's)                                                                                                                                                                                                                                                                                                                                                                       | [Retry, delete or terminate](/reliability/workflows#retry-delete-or-terminate)                                                                                                                                                                                                                                               |
| `WorkflowClient.delete(id, options)`                                                                                               | `force` (delete an unfinished instance too; default `false`)                                                                                                                                                                                                                                                                                                                                                                                              | [Retry, delete or terminate](/reliability/workflows#retry-delete-or-terminate)                                                                                                                                                                                                                                               |
| `WorkflowClient.purge(options)`                                                                                                    | `olderThan` (required), `status` (default `completed`, `failed` and `cancelled`), `batchSize` (default `500`)                                                                                                                                                                                                                                                                                                                                             | [Purge finished instances](/reliability/workflows#purge-finished-instances)                                                                                                                                                                                                                                                  |
| `WorkflowClient.schedules`, or the injectable `WorkflowSchedules`                                                                  | `upsert(id, options)` (the schedule options, with `workflow`, and optionally `version` and a JSON `input`), `get(id)`, `list(filter)` (`workflow`, `limit`, `offset`), `remove(id)`, `pause(id)` and `resume(id)` (neither re-encrypts the stored input), `trigger(id)` (in a process that registers the workflow, unless the schedule pins a `version`), and `preview(schedule, options)` (a schedule's id or timing; `from`, and `count`, default `10`) | [Run workflows on a schedule](/reliability/workflows#run-workflows-on-a-schedule)                                                                                                                                                                                                                                            |
| `@StartOn(event, options)`                                                                                                         | `id` (required), `input` (default the event), `priority`, `concurrencyKey`, `rateLimitKey` (as `start()`'s: a value, or a function of the event, where `undefined` leaves the default)                                                                                                                                                                                                                                                                    | [With CQRS](/reliability/workflows#with-cqrs)                                                                                                                                                                                                                                                                                |
| `@SignalOn(event, options)`                                                                                                        | `signal`, `key`, `id`, `payload` (default the event)                                                                                                                                                                                                                                                                                                                                                                                                      | [With CQRS](/reliability/workflows#with-cqrs)                                                                                                                                                                                                                                                                                |
| `EventBus.publish(event, context)`, `publishAll(events, context)`, an aggregate's `commit(context)` (`@nestjs/cqrs` 12.1 or later) | `transaction`, read from the dispatcher context once `WorkflowsCqrsModule` is imported                                                                                                                                                                                                                                                                                                                                                                    | [With CQRS](/reliability/workflows#with-cqrs)                                                                                                                                                                                                                                                                                |

A step's function receives `idempotencyKey`, `attempt`, `signal`, `progress` and `heartbeat()`; a compensation receives the same, plus the reason the workflow is being undone.

A schedule, declared in `@Workflow()` or saved with `upsert()`, takes these options:

| Option                   | Default                      | Meaning                                                                                                                                              |
| ------------------------ | ---------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| `id`                     | Required in `@Workflow()`    | Unique across the application: letters, digits, `.`, `:`, `_` and `-`. `upsert()` takes it as its first argument                                     |
| `cron`, `every`, `rrule` | One of the three is required | A cron expression of 5 fields, or 6 with the seconds first; an interval of at least a second, counted from `startAt`; or an RFC 5545 recurrence rule |
| `tz`                     | `'UTC'`                      | The IANA time zone of `cron` and `rrule`. Not with `every`                                                                                           |
| `startAt`, `endAt`       | None                         | No occurrence before `startAt`, or after `endAt`                                                                                                     |
| `limit`                  | None                         | How many occurrences it starts before it ends                                                                                                        |
| `missed`                 | `'skip'`                     | Occurrences no worker was up to start: `'skip'`, `'once'` or `'all'`                                                                                 |
| `overlap`                | `'skip'`                     | An occurrence due while an instance it started is unfinished: `'skip'`, `'allow'`, `'cancel-previous'` or `'buffer-one'`                             |
| `priority`               | None                         | The priority of the instances it starts                                                                                                              |
| `input`                  | None                         | The instances' input: a JSON value, or in `@Workflow()` a function of the occurrence                                                                 |

##### Events[#](/reliability/workflows#events)

`WorkflowEvents.events$` emits each event, and publishes it on the `nestjs:workflows:<type>` diagnostics channel, for example `nestjs:workflows:step-failed`. Every payload has `type`, `id` (the instance), `workflow`, `version` and `at` (the engine's time, in milliseconds).

| Event                          | Other fields                                       | When                                                                                       |
| ------------------------------ | -------------------------------------------------- | ------------------------------------------------------------------------------------------ |
| `workflow-started`             | None                                               | The first execution of an instance began                                                   |
| `workflow-resumed`             | `run`                                              | A later execution began: after a wait, a sleep, a retry or a crash                         |
| `workflow-suspended`           | `wakeAt`, `waits`                                  | An execution parked the instance                                                           |
| `step-completed`               | `step`, `attempt`, `durationMs`                    | A step attempt succeeded                                                                   |
| `step-failed`                  | `step`, `attempt`, `error`, `retryAt`              | A step attempt failed; `retryAt` is `null` when the step gave up                           |
| `signal-received`              | `wait`, `signal`, `signalId`                       | A wait took a signal                                                                       |
| `signal-timed-out`             | `wait`, `signal`                                   | A wait's deadline passed without a matching signal                                         |
| `workflow-compensating`        | `error`                                            | The instance failed or was cancelled, and starts undoing                                   |
| `step-compensated`             | `step`, `attempt`                                  | A step's compensation completed                                                            |
| `workflow-completed`           | `output`                                           | The instance completed                                                                     |
| `workflow-failed`              | `error`                                            | The instance failed, after its compensations ran                                           |
| `workflow-cancelled`           | `error`                                            | The instance was cancelled, after its compensations ran; `error.message` is the reason     |
| `workflow-compensation-failed` | `error`                                            | A compensation gave up halfway. Needs a person                                             |
| `journal-large`                | `entries`, `bytes`                                 | The journal reached `journal.warnEntries` or `journal.warnBytes`; once per instance        |
| `workflow-retried`             | `from`, `error`                                    | `retry()` reopened a `failed` or `compensation_failed` instance; `error` is the one it had |
| `workflow-deleted`             | `status`                                           | `delete()` removed an instance; `status` is the one it had                                 |
| `custom-status`                | `status`                                           | A write changed the instance's custom status                                               |
| `child-started`                | `child`, `childWorkflow`, `childVersion`           | The instance started a child                                                               |
| `schedule-skipped`             | `reason` (`'missed'` or `'overlap'`), `from`, `to` | A schedule passed over occurrences. Its `id` is the schedule's                             |

An instance maps onto one trace, whichever processes run it over its days or weeks, so key the trace by the instance `id`. The instance is the root span, from `workflow-started` to its final event (`workflow-completed`, `workflow-failed`, `workflow-cancelled` or `workflow-compensation-failed`). Each execution is a child span, from `workflow-started` or `workflow-resumed` to `workflow-suspended` or the final event. Each step attempt is a span inside it that ends at `step-completed`, whose `durationMs` gives its start, or at `step-failed`. The other events are events on the execution's span. Tracing tools subscribe to the diagnostics channels, so this needs no code in your application.

##### Errors[#](/reliability/workflows#errors)

The package's errors extend `WorkflowError`, except the two that are control flow or yours to throw. The ones found on a failed instance are there by name, in its `error`.

| Error                         | HTTP status | Raised when                                                                                                                                                                                                                                                                                                                                                                                                 |
| ----------------------------- | ----------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `WorkflowIdConflictError`     | `409`       | `start()` with an existing id, but a different workflow or input, `signal()` with an `id` already used for the same signal with another key, or `startChild()` with an id that another workflow, parent or input uses                                                                                                                                                                                       |
| `WorkflowNotFoundError`       | `404`       | `cancel()`, `terminate()`, `retry()`, `delete()` or `result()` of an unknown id, a schedule method with an unknown schedule id, or `start()` or a schedule's `trigger()` of a workflow this application can't resolve                                                                                                                                                                                       |
| `WorkflowStateError`          | `409`       | `retry()` of an instance that isn't `failed` or `compensation_failed`, or whose compensations ran; `delete()` of an unfinished instance without `force`; either racing another change to the instance; `upsert()` or `remove()` of a declared schedule                                                                                                                                                      |
| `NonRetryableStepError`       | None        | You throw it from a step to fail the step without retrying                                                                                                                                                                                                                                                                                                                                                  |
| `StepFailedError`             | None        | Inside `run()`, a step gave up; `step`, `attempts`, and the original error's name and message as `cause`                                                                                                                                                                                                                                                                                                    |
| `StepTimeoutError`            | None        | A step attempt ran past its `timeout` or `heartbeatTimeout`. Retried                                                                                                                                                                                                                                                                                                                                        |
| `WorkflowFailedError`         | None        | `ctx.fail()` failed the instance. Also what `result()` and `startAndWait()` reject with for an instance that ended without completing, with its `instanceId`, its `status` and its error as `cause`                                                                                                                                                                                                         |
| `ChildWorkflowFailedError`    | None        | A child failed, was cancelled or was terminated: what `ctx.executeChild()` and a child's `result()` throw in the parent, with the child's `workflow`, `instanceId`, `status` and error as `cause`. Extends `WorkflowFailedError`                                                                                                                                                                            |
| `WorkflowResultTimeoutError`  | None        | `result()` or `startAndWait()` waited past its `timeout`, with the `instanceId` and `timeoutMs`. The instance keeps running                                                                                                                                                                                                                                                                                 |
| `WorkflowDefinitionError`     | None        | A name used twice in one run, or a `ctx` call inside a step. The instance fails without compensation                                                                                                                                                                                                                                                                                                        |
| `WorkflowNonDeterminismError` | None        | A deploy renamed, removed or reordered steps that running instances journaled. Extends `WorkflowDefinitionError`. [Deploy changes safely](/reliability/workflows#deploy-changes-safely)                                                                                                                                                                                                                     |
| `WorkflowInterrupt`           | None        | The engine's control flow (a suspension, a cancel). Rethrow it; `isWorkflowInterrupt()` identifies it                                                                                                                                                                                                                                                                                                       |
| `WorkflowTimeoutError`        | None        | Only by name, on an instance that ran past its run timeout: it compensated and failed                                                                                                                                                                                                                                                                                                                       |
| `WorkflowCancelledError`      | None        | Only by name, on a cancelled instance: its message is the reason                                                                                                                                                                                                                                                                                                                                            |
| `WorkflowTerminatedError`     | None        | Only by name, on a terminated instance, which ends as `cancelled`: its message is the reason                                                                                                                                                                                                                                                                                                                |
| `WorkflowDeletedError`        | None        | Only by name, as the cause of a parent's `ChildWorkflowFailedError`, when `delete()` with `force` removed the child before it ended                                                                                                                                                                                                                                                                         |
| `WorkflowJournalLimitError`   | None        | Only by name, on an instance whose journal reached `journal.maxEntries` or `journal.maxBytes`: it compensated and failed                                                                                                                                                                                                                                                                                    |
| `WorkflowSchemaError`         | None        | The schema of `PostgresWorkflowStore` or `MySqlWorkflowStore` is behind the package's migrations while `migrate` is off, or applying them failed (`cause`; on MySQL, the message names the statement where the next run resumes): startup and every call fail until it's fixed. With the `schema`, its `version` and the `requiredVersion`. From `@nestjs/workflows/postgres` and `@nestjs/workflows/mysql` |

`MySqlWorkflowStore` also rejects an id, name or key longer than its column with a `RangeError`, before any SQL ([MySQL store](/reliability/workflows#mysql-store)). A deadlock in your transaction reaches you as MySQL's error 1213, which the store doesn't retry, since it rolled back your writes too.

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/reliability/workflows.md)

----
url: https://docs.nestjs.com/graphql/sharing-models
----

[Skip to content](#content)

On this page

* [Sharing models](https://docs.nestjs.com/graphql/sharing-models#sharing-models)
* [Using the model shim](https://docs.nestjs.com/graphql/sharing-models#using-the-model-shim)

### Sharing models

> **Warning** This chapter applies only to the code first approach.

One of the biggest advantages of using TypeScript for the backend of your project is the ability to reuse the same models in a TypeScript-based frontend application through a common TypeScript package.

However, models created with the code first approach are heavily annotated with GraphQL-related decorators. Those decorators are irrelevant in the frontend and hurt its performance.

#### Using the model shim[#](/graphql/sharing-models#using-the-model-shim)

To solve this issue, Nest provides a "shim" that replaces the original decorators with inert code. The `@nestjs/graphql` package exposes the shim through the `browser` export condition, so bundlers that resolve that condition for browser builds (e.g., webpack with a `web` target) pick it up automatically.

If your bundler doesn't resolve the `browser` condition, configure an alias between the `@nestjs/graphql` package and the shim. For example, with webpack:

```typescript

resolve: { // see: https://webpack.js.org/configuration/resolve/
  alias: {
      "@nestjs/graphql": path.resolve(__dirname, "../node_modules/@nestjs/graphql/dist/extra/graphql-model-shim")
  }
}
```

> **Hint** The [TypeORM](/data/typeorm) package provides a similar [model shim](https://github.com/typeorm/typeorm/blob/master/extra/typeorm-model-shim.js).

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/sharing-models.md)

----
url: https://docs.nestjs.com/v5/fundamentals/circular-dependency
----

### Circular dependency

The circular dependency occurs when for example, class A needs class B, and class B needs class A as well. Nest permits creating **circular dependencies** between both providers and modules, but we advise you to avoid whenever it's possible. Sometimes it's really difficult to avoid this kind of the relationships, that's why we have provided some ways to deal with this issue.

#### Forward reference

The **forward reference** allows Nest referring to references which aren't defined so far. When `CatsService` and `CommonService` depend on each other, both sides of the relationship need to use `@Inject()` and the `forwardRef()` utility, otherwise Nest won't instantiate them because all of the essential metadata won't be available. Let's see the following snippet:

cats.service.ts

JS TS

TypeScript

```typescript

@Injectable()
export class CatsService {
  constructor(
    @Inject(forwardRef(() => CommonService))
    private readonly commonService: CommonService,
  ) {}
}
```

TypeScript

```typescript

@Injectable()
@Dependencies(forwardRef(() => CommonService))
export class CatsService {
  constructor(commonService) {
    this.commonService = commonService;
  }
}
```

> **Hint** The `forwardRef()` function is imported from the `@nestjs/common` package.

Here's the first side of the relationship. Now let's do the same with the `CommonService`:

common.service.ts

JS TS

TypeScript

```typescript

@Injectable()
export class CommonService {
  constructor(
    @Inject(forwardRef(() => CatsService))
    private readonly catsService: CatsService,
  ) {}
}
```

TypeScript

```typescript

@Injectable()
@Dependencies(forwardRef(() => CatsService))
export class CommonService {
  constructor(catsService) {
    this.catsService = catsService;
  }
}
```

> **Warning** You don't have a guarantee which constructor will be called first.

In order to create circular dependencies between modules you have to use the same `forwardRef()` utility on both parts of the modules association:

common.module.ts

JS TS

TypeScript

```typescript

@Module({
  imports: [forwardRef(() => CatsModule)],
})
export class CommonModule {}
```

#### Module reference

Nest provides the `ModuleRef` class that can be simply injected into any component.

cats.service.ts

JS TS

TypeScript

```typescript

@Injectable()
export class CatsService implements OnModuleInit {
  private service: Service;
  constructor(private readonly moduleRef: ModuleRef) {}

  onModuleInit() {
    this.service = this.moduleRef.get(Service);
  }
}
```

TypeScript

```typescript

@Injectable()
@Dependencies(ModuleRef)
export class CatsService {
  constructor(moduleRef) {
    this.moduleRef = moduleRef;
  }

  onModuleInit() {
    this.service = this.moduleRef.get(Service);
  }
}
```

> **Hint** The `ModuleRef` class is imported from the `@nestjs/core` package.

The module reference has a `get()` method which allows retrieving a provider available in the current module. Additionally, you can switch to a non-strict mode, which enables you to pick any existing provider across the whole app.

TypeScript

```typescript

this.moduleRef.get(Service, { strict: false });
```

* Circular dependency
* Forward reference
* Module reference

----
url: https://docs.nestjs.com/v6/cli/scripts
----

* [Nest CLI and scripts](https://docs.nestjs.com/v6/cli/scripts#nest-cli-and-scripts)
* [The nest binary](https://docs.nestjs.com/v6/cli/scripts#the-nest-binary)
* [Build](https://docs.nestjs.com/v6/cli/scripts#build)
* [Execution](https://docs.nestjs.com/v6/cli/scripts#execution)
* [Generation](https://docs.nestjs.com/v6/cli/scripts#generation)
* [Package scripts](https://docs.nestjs.com/v6/cli/scripts#package-scripts)
* [Backward compatibility](https://docs.nestjs.com/v6/cli/scripts#backward-compatibility)
* [Migration](https://docs.nestjs.com/v6/cli/scripts#migration)

### The nest binary

The `nest` command is an OS level binary (i.e., runs from the OS command line). This command actually encompasses 3 distinct areas, described below. We recommend that you run the build (`nest build`) and execution (`nest start`) sub-commands via the `package.json` scripts provided automatically when a project is scaffolded (see [typescript starter](https://github.com/nestjs/typescript-starter) if you wish to start by cloning a repo, instead of running `nest new`).

#### Build[#](/cli/scripts#build)

`nest build` is a wrapper on top of the standard `tsc` compiler (for [standard projects](https://docs.nestjs.com/cli/overview#project-structure)) or the webpack compiler (for [monorepos](https://docs.nestjs.com/cli/overview#project-structure)). It does not add any other compilation features or steps. The reason it exists is that most developers, especially when starting out with Nest, do not need to adjust compiler options (e.g., `tsconfig.json` file) which can sometimes be tricky.

See the [nest build](https://docs.nestjs.com/cli/usages#nest-build) documentation for more details.

#### Execution[#](/cli/scripts#execution)

`nest start` simply ensures the project has been built (same as `nest build`), then invokes the `node` command in a portable, easy way to execute the compiled application. As with builds, you are free to customize this process as needed, either using the `nest start` command and its options, or completely replacing it. The entire process is a standard TypeScript application build and execute pipeline, and you are free to manage the process as such.

See the [nest start](https://docs.nestjs.com/cli/usages#nest-start) documentation for more details.

#### Generation[#](/cli/scripts#generation)

The `nest generate` commands, as the name implies, generate new Nest projects, or components within them.

### Package scripts

Running the `nest` commands at the OS command level requires that the `nest` binary be installed globally. This is a standard feature of npm, and outside of Nest's direct control. One consequence of this is that the globally installed `nest` binary is **not** managed as a project dependency in `package.json`. For example, two different developers can be running two different versions of the `nest` binary. The standard solution for this is to use package scripts so that you can treat the tools used in the build and execute steps as development dependencies.

When you run `nest new`, or clone the [typescript starter](https://github.com/nestjs/typescript-starter), Nest populates the new project's `package.json` scripts with commands like `build` and `start`. It also installs the underlying compiler tools (such as `typescript`) as **dev dependencies**.

You run the build and execute scripts with commands like:

```bash

$ npm run build
```

and

```bash

$ npm run start
```

These commands use npm's script running capabilities to execute `nest build` or `nest start` using the **locally installed**`nest` binary. By using these built-in package scripts, you have full dependency management over the Nest CLI commands\*. This means that, by following this **recommended** usage, all members of your organization can be assured of running the same version of the commands.

\*This applies to the `build` and `start` commands. The `nest new` and `nest generate` commands aren't part of the build/execute pipeline, so they operate in a different context, and do not come with built-in `package.json` scripts.

For most developers/teams, it is recommended to utilize the package scripts for building and executing their Nest projects. You can fully customize the behavior of these scripts via their options (`--path`, `--webpack`, `--webpackPath`) and/or customize the `tsc` or webpack compiler options files (e.g., `tsconfig.json`) as needed. You are also free to run a completely custom build process to compile the TypeScript (or even to execute TypeScript directly with `ts-node`).

### Backward compatibility

Because Nest applications are pure TypeScript applications, previous versions of the Nest build/execute scripts will continue to operate. You are not required to upgrade them. You can choose to take advantage of the new `nest build` and `nest start` commands when you are ready, or continue running previous or customized scripts.

### Migration

While you are not required to make any changes, you may want to migrate to using the new CLI commands instead of using tools such as `tsc-watch` or `ts-node`. In this case, simply install the latest version of the `@nestjs/cli`, both globally and locally:

```bash

$ npm install -g @nestjs/cli
$ cd  /some/project/root/folder
$ npm install -D @nestjs/cli
```

You can then replace the `scripts` defined in `package.json` with the following ones:

```typescript

"build": "nest build",
"start": "nest start",
"start:dev": "nest start --watch",
"start:debug": "nest start --debug --watch",
```

----
url: https://docs.nestjs.com/v5/websockets/guards
----

### Guards

There is no difference between web sockets **guards** and the [regular guards](/v5/guards). The only thing you should be aware of is that instead of throwing `HttpException`, you should use the `WsException`.

> **Hint** The `WsException` class is exposed from `@nestjs/websockets` package.

#### Binding guards

Here is an example that makes use of a **method-scoped** guard (class-scoped works either):

TypeScript

```typescript

@UseGuards(AuthGuard)
@SubscribeMessage('events')
onEvent(client, data: any): WsResponse<any> {
  const event = 'events';
  return { event, data };
}
```

----
url: https://docs.nestjs.com/security/authorization
----

[Skip to content](#content)

On this page

* [Authorization](https://docs.nestjs.com/security/authorization#authorization)
* [Prerequisites](https://docs.nestjs.com/security/authorization#prerequisites)
* [Register the authorization module](https://docs.nestjs.com/security/authorization#register-the-authorization-module)
* [Write a policy for products](https://docs.nestjs.com/security/authorization#write-a-policy-for-products)
* [Check orders record by record](https://docs.nestjs.com/security/authorization#check-orders-record-by-record)
* [Check a route parameter](https://docs.nestjs.com/security/authorization#check-a-route-parameter)
* [Let admins through with before()](https://docs.nestjs.com/security/authorization#let-admins-through-with-before)
* [Inject a service into a policy](https://docs.nestjs.com/security/authorization#inject-a-service-into-a-policy)
* [Tell guests from forbidden users, and expose permissions](https://docs.nestjs.com/security/authorization#tell-guests-from-forbidden-users-and-expose-permissions)
* [Try it](https://docs.nestjs.com/security/authorization#try-it)
* [Testing](https://docs.nestjs.com/security/authorization#testing)
* [Production checklist](https://docs.nestjs.com/security/authorization#production-checklist)
* [Reference](https://docs.nestjs.com/security/authorization#reference)

### Authorization

`@nestjs/authorization` expresses permissions as **policies**: classes whose methods answer "may this user do this?". A policy is an ordinary provider, so it can inject services, and every check is type-checked against the policy method it calls. Policies work on any data shape, including the plain objects that Prisma, Drizzle and Kysely return.

In this tutorial, you'll add permissions to the API of an online store for cat food and supplies:

* Guests and customers browse published products. Staff also see drafts, and only staff edit the catalog.
* Customers see only their own orders. Staff see all of them.
* Only staff refund orders, only paid ones, and only up to a limit that finance sets per person. Nobody refunds an order that has shipped.
* Admins manage the catalog without restrictions.

Along the way, you'll see where each kind of check belongs (on the route or in the service), when a denial is a 401 and when it's a 403, and how to test policies.

#### Prerequisites[#](/security/authorization#prerequisites)

This tutorial continues the [Authentication](/security/authentication) tutorial: the store signs its users in with `@nestjs/authentication`, and this page decides what they may do. Install the package:

```bash

$ npm i --save @nestjs/authorization
```

If you're starting fresh, the files below are the sign-in code this page relies on: the Authentication tutorial's application once it [issues tokens to the mobile app](/security/authentication#issue-tokens-to-the-mobile-app), reduced to the mobile app's sign-in, a password for a bearer token. The user is the same plain object, as your ORM would return it:

src/users/user.ts

JS TS

```typescript

export type Role = 'customer' | 'staff' | 'admin';

export interface User {
  id: string;
  email: string;
  /** Whether the owner proved the address to us, e.g. by using a magic link. */
  emailVerified: boolean;
  roles: Role[];
}
```

Four demo accounts stand in for the users table: two customers (Alice and Bob), a staff member (Sam), and Ada, who is staff and an admin. Their ids are fixed, so the demo orders and the tests can refer to them:

src/users/demo-users.ts

JS TS

```typescript

import type { User } from './user.js';

/**
 * The demo accounts. They all sign in with the password "catnip4all", and the
 * seeded orders refer to their ids.
 */
export const alice: User = {
  id: '1f794c55-472e-42b9-8913-4114964ed6fb',
  email: 'alice@example.com',
  emailVerified: true,
  roles: ['customer'],
};

export const bob: User = {
  id: 'fc27b5c1-62b5-494e-9924-28a66d387fd1',
  email: 'bob@example.com',
  emailVerified: true,
  roles: ['customer'],
};

export const sam: User = {
  id: '208a223b-3503-4255-83e7-22d290e331c3',
  email: 'sam@example.com',
  emailVerified: true,
  roles: ['staff'],
};

export const ada: User = {
  id: 'ae34ca97-f82b-49ab-b332-8808f3b0e240',
  email: 'ada@example.com',
  emailVerified: true,
  roles: ['staff', 'admin'],
};

export const demoUsers = [alice, bob, sam, ada];
```

`UsersRepository` is the Authentication tutorial's, with the two methods this page needs. It seeds the demo accounts at startup, and only `User` objects leave it: the password hashes stay inside.

src/users/users.repository.ts

JS TS

```typescript

import { Injectable, type OnModuleInit } from '@nestjs/common';
import { PasswordHasher } from '@nestjs/authentication';
import { demoUsers } from './demo-users.js';
import type { User } from './user.js';

interface UserRow extends User {
  passwordHash: string | null;
}

/**
 * In-memory stand-in for your data layer (Prisma, Drizzle, TypeORM, ...).
 * Only `User` objects leave this class: password hashes stay inside.
 */
@Injectable()
export class UsersRepository implements OnModuleInit {
  private readonly rows = new Map<string, UserRow>();

  constructor(private readonly passwordHasher: PasswordHasher) {}

  async onModuleInit() {
    // Seeds the demo accounts, all with the password "catnip4all".
    const passwordHash = await this.passwordHasher.hash('catnip4all');
    for (const user of demoUsers) {
      this.rows.set(user.id, { ...user, passwordHash });
    }
  }

  async findById(id: string): Promise<User | null> {
    const row = this.rows.get(id);
    return row ? toUser(row) : null;
  }

  /** For password sign-in only. */
  async findCredentials(email: string): Promise<{ user: User; passwordHash: string | null } | null> {
    const row = this.findRow(email);
    return row ? { user: toUser(row), passwordHash: row.passwordHash } : null;
  }

  private findRow(email: string) {
    const normalized = normalize(email);
    return [...this.rows.values()].find((row) => row.email === normalized);
  }
}

const normalize = (email: string) => email.trim().toLowerCase();
const toUser = ({ id, email, emailVerified, roles }: UserRow): User => ({ id, email, emailVerified, roles: [...roles] });
```

src/users/users.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { UsersRepository } from './users.repository.js';

@Module({
  providers: [UsersRepository],
  exports: [UsersRepository],
})
export class UsersModule {}
```

The tokens are the ones the Authentication tutorial issues to its mobile app: short-lived JWT access tokens, described once by the `accessToken` options that the root module passes to `AuthenticationModule` below. The signing secret is the `JWT_SECRET` from the Authentication tutorial's `.env` file, at least 32 bytes:

```bash

# Generate with: openssl rand -base64 32
JWT_SECRET=
```

> **Hint** The tutorial reads `process.env` directly, to stay short. In an application, load the environment through [`@nestjs/config`](/application/configuration) with a validation schema, so a missing secret stops the application at startup, and read it from `ConfigService`.

`JwtAuth` verifies the bearer token with the `accessToken` options, and loads the token's user. It registers itself with `AuthenticationRegistry` from its constructor, which is how the guard learns about it:

src/auth/jwt-auth.provider.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { AuthenticationRegistry, JwtBearerProvider, type JwtClaims } from '@nestjs/authentication';
import type { User } from '../users/user.js';
import { UsersRepository } from '../users/users.repository.js';

@Injectable()
export class JwtAuth extends JwtBearerProvider<User> {
  constructor(
    private readonly usersRepository: UsersRepository,
    registry: AuthenticationRegistry,
  ) {
    // The key, issuer and audience come from the `accessToken` options.
    super({ realm: 'store' });
    // Adds this provider to the chain the guard runs for every request.
    registry.registerProvider(this);
  }

  // Called after the signature and claims checked out.
  // Returning null (the user was deleted) rejects the token.
  validate({ sub }: JwtClaims) {
    return sub ? this.usersRepository.findById(sub) : null;
  }
}
```

`CredentialsService` checks a password against the stored hash, with the package's `PasswordHasher`, and answers `null` for an unknown email and a wrong password alike, in the same time:

src/auth/credentials.service.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { PasswordHasher } from '@nestjs/authentication';
import type { User } from '../users/user.js';
import { UsersRepository } from '../users/users.repository.js';

@Injectable()
export class CredentialsService {
  constructor(
    private readonly usersRepository: UsersRepository,
    private readonly passwordHasher: PasswordHasher,
  ) {}

  /** The user, or `null` when the email or the password is wrong. */
  async verify(email: string, password: string): Promise<User | null> {
    const found = await this.usersRepository.findCredentials(email);
    // With no account (or no password), verify() checks a dummy hash, so the
    // response time does not reveal which emails are registered.
    const valid = await this.passwordHasher.verify(password, found?.passwordHash);
    if (!valid || !found?.passwordHash) {
      return null;
    }
    return found.user;
  }
}
```

`TokensController` exchanges an email and a password for tokens. Its request body is validated with whatever your application already uses. Every DTO on this page comes twice, as a class with decorators and as a Zod schema, so pick the style you have and skip the other listing:

src/auth/auth.dto.ts

JS TS

```typescript

import { IsEmail, IsString } from 'class-validator';

export class SignInDto {
  @IsEmail()
  email: string;

  @IsString()
  password: string;
}
```

src/auth/auth.schemas.ts

JS TS

```typescript

import { z } from 'zod';

export const signInSchema = z.object({
  email: z.email(),
  password: z.string(),
});
export type SignInDto = z.infer<typeof signInSchema>;
```

`TokenService.issue()` signs an access token with the same `accessToken` options, and returns it with a refresh token:

src/auth/tokens.controller.ts

JS TS

```typescript

import { Body, Controller, HttpCode, Post, UnauthorizedException } from '@nestjs/common';
import { Public, TokenService } from '@nestjs/authentication';
import { SignInDto } from './auth.dto.js';
import { CredentialsService } from './credentials.service.js';

@Public()
@Controller('auth/token')
export class TokensController {
  constructor(
    private readonly credentialsService: CredentialsService,
    private readonly tokenService: TokenService,
  ) {}

  @Post()
  @HttpCode(200)
  async issue(@Body() body: SignInDto) {
    const user = await this.credentialsService.verify(body.email, body.password);
    if (!user) {
      throw new UnauthorizedException('Invalid email or password');
    }
    return this.tokenService.issue(user.id, {
      method: 'password',
      // `amr` goes into this access token and into every refreshed one.
      claims: { amr: ['pwd'] },
    });
  }
}
```

With the Zod schema, the body parameter declares its schema instead of a class:

src/auth/tokens.controller.ts

JS TS

```typescript

import { signInSchema, type SignInDto } from './auth.schemas.js';
// ...
@Post()
@HttpCode(200)
async issue(@Body({ schema: signInSchema }) body: SignInDto) {
  // ...
}
```

> **Hint** The DTOs are enforced only by a validation pipe: bind `ValidationPipe` globally, as an `APP_PIPE` provider of `AppModule` or with `useGlobalPipes()` in `main.ts`. With the Zod schemas, bind `StandardSchemaValidationPipe` the same way instead. An application uses one or the other. The [validation](/application/validation) page has the options of each.

src/auth/auth.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { UsersModule } from '../users/users.module.js';
import { CredentialsService } from './credentials.service.js';
import { JwtAuth } from './jwt-auth.provider.js';
import { TokensController } from './tokens.controller.js';

@Module({
  imports: [UsersModule],
  controllers: [TokensController],
  providers: [JwtAuth, CredentialsService],
})
export class AuthModule {}
```

Authentication puts the signed-in `User` on `request.user`, and `@CurrentUser()` injects it into a handler. That's all authorization needs from it.

#### Register the authorization module[#](/security/authorization#register-the-authorization-module)

Import `AuthorizationModule` next to `AuthenticationModule` in the root module. `AuthenticationModule` is registered as in the Authentication tutorial, with the `accessToken` options; `JwtAuth` is a provider of `AuthModule`:

src/app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { AuthenticationModule } from '@nestjs/authentication';
import { AuthorizationModule } from '@nestjs/authorization';
import { AuthModule } from './auth/auth.module.js';

@Module({
  imports: [
    // Authentication first: its guard sets request.user, which authorization reads.
    AuthenticationModule.forRootAsync({
      useFactory: () => ({
        accessToken: {
          key: process.env.JWT_SECRET!,
          issuer: 'https://api.example.com',
          audience: 'mobile-app',
          ttl: '15m',
        },
      }),
    }),
    AuthorizationModule.forRoot(),
    AuthModule,
  ],
})
export class AppModule {}
```

`forRoot()` registers the module globally. It does three things:

* It provides `AuthorizationService`, which you inject wherever code checks a permission.
* It registers `AuthorizationGuard` as a global guard. The guard enforces the `@Can()` decorator you'll add in the next step, and **denies by default**: a handler runs only when it declares a check, with `@Can()`, with `@Can.Anyone()`, or with `@Public()` from `@nestjs/authentication`, which counts as `@Can.Anyone()`. `POST /auth/token` is `@Public()`, so it keeps working.
* It turns a denial that a service reports into a 401 or a 403, as [Tell guests from forbidden users, and expose permissions](/security/authorization#tell-guests-from-forbidden-users-and-expose-permissions) explains.

A route whose `@Can()` was forgotten is therefore closed, not open. At startup, the module logs every handler it will deny this way, so the list is where a migration starts. The [reference](/security/authorization#what-a-route-declares) has the full rules.

Both packages register a global guard, and **the import order matters**. Nest runs global guards in the order it scans modules, so `AuthenticationModule` has to come first. In the reverse order, the authorization guard would run before anything has set `request.user`, so every `@Can()` check would see a guest, and a signed-in staff member would get a 401 on a staff-only route. `AuthorizationModule` checks the order at startup: it recognizes `AuthenticationGuard` by a marker the guard carries, and when that guard comes second, the app refuses to start, with an error that names both guards and the fix.

> **Warning** Other authentication guards, such as a subclass of Passport's `AuthGuard()`, carry no such marker, so the check can only go by their class names. In the wrong order, it logs an error, the app starts, and every `@Can()` check treats signed-in users as guests. Register such a guard with `APP_GUARD`, not with `app.useGlobalGuards()`: Nest runs the guards added that way after every `APP_GUARD`, so they always come after the authorization guard, and the check can't see them.

> **Hint** The guard reads the user from `request.user`, and from the equivalent places for WebSockets, microservices and GraphQL. With `@nestjs/authentication`, on a WebSocket or a `graphql-ws` socket, it's the user of each message or operation, not the socket's, as the [reference](/security/authorization#reference) explains. If your authentication stores the user elsewhere, pass a `getUser` function to `forRoot()`, or return one from a `forRootAsync()` factory when it needs a provider. If you authenticate with `@UseGuards()` rather than a global guard, pass `globalGuard: false` and list `AuthorizationGuard` after your authentication guard.

#### Write a policy for products[#](/security/authorization#write-a-policy-for-products)

Products are plain objects too, identified by a slug and priced in cents, as in the Authentication tutorial:

src/products/product.ts

JS TS

```typescript

export interface Product {
  /** A slug, such as `salmon-kibble-2kg`. */
  id: string;
  name: string;
  /** In cents. */
  price: number;
  published: boolean;
}

export type ProductInput = Omit<Product, 'id'>;
```

A policy is a class decorated with `@Policy()`. Each method whose first parameter is the user and which returns `boolean` or `Promise<boolean>` is an **ability**. Only a literal `true` allows. Any other value denies, even a truthy one.

src/products/product.policy.ts

JS TS

```typescript

import { Policy } from '@nestjs/authorization';
import type { User } from '../users/user.js';
import type { Product } from './product.js';

const isStaff = (user: User | null) => !!user?.roles.includes('staff');

@Policy()
export class ProductPolicy {
  // `null` is a guest. Everyone sees published products; staff also see drafts.
  view(user: User | null, product: Product) {
    return product.published || isStaff(user);
  }

  viewDrafts(user: User | null) {
    return isStaff(user);
  }

  create(user: User | null) {
    return isStaff(user);
  }

  update(user: User | null) {
    return isStaff(user);
  }
}
```

The type of the user parameter is a decision. `User | null` means the ability also runs for guests, who arrive as `null`. Guests can browse the catalog, so every ability here accepts `null`, and `view` and `viewDrafts` give guests a real answer.

`ProductsService` uses the policy in two ways. `can()` resolves to `true` or `false`; here it decides whether the listing includes drafts. `authorize()` throws when the ability denies, so `findOne()` never returns a draft to someone who may not see it.

src/products/products.service.ts

JS TS

```typescript

import { Injectable, NotFoundException } from '@nestjs/common';
import { AuthorizationService } from '@nestjs/authorization';
import type { User } from '../users/user.js';
import type { Product, ProductInput } from './product.js';
import { ProductPolicy } from './product.policy.js';

@Injectable()
export class ProductsService {
  // Stands in for your products table.
  private readonly products: Product[] = [
    { id: 'salmon-kibble-2kg', name: 'Salmon kibble, 2 kg', price: 2499, published: true },
    { id: 'clumping-litter-10l', name: 'Clumping litter, 10 l', price: 1599, published: true },
    { id: 'heated-cat-bed', name: 'Heated cat bed', price: 5499, published: false },
  ];

  constructor(private readonly authorizationService: AuthorizationService) {}

  async findAll(user: User | null) {
    const withDrafts = await this.authorizationService.can(ProductPolicy, 'viewDrafts', user);
    return withDrafts ? this.products : this.products.filter((product) => product.published);
  }

  async findOne(user: User | null, id: string) {
    const product = this.find(id);
    await this.authorizationService.authorize(ProductPolicy, 'view', user, product);
    return product;
  }

  create(input: ProductInput) {
    const product = { ...input, id: slug(input.name) };
    this.products.push(product);
    return product;
  }

  update(id: string, changes: Partial<ProductInput>) {
    return Object.assign(this.find(id), changes);
  }

  remove(id: string) {
    this.products.splice(this.products.indexOf(this.find(id)), 1);
  }

  private find(id: string) {
    const product = this.products.find((product) => product.id === id);
    if (!product) {
      throw new NotFoundException();
    }
    return product;
  }
}

/** `Sisal scratching post` → `sisal-scratching-post`. */
const slug = (name: string) => name.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, '');
```

Creating and updating products doesn't depend on a particular record, so those checks go on the route. The bodies of those routes are DTOs, as classes or as Zod schemas; an update takes any subset of a new product's fields:

src/products/products.dto.ts

JS TS

```typescript

import { PartialType } from '@nestjs/mapped-types';
import { IsBoolean, IsPositive, IsString, MinLength } from 'class-validator';

export class CreateProductDto {
  @IsString()
  @MinLength(1)
  name: string;

  @IsPositive()
  price: number;

  @IsBoolean()
  published: boolean;
}

/** Any subset of the fields above. */
export class UpdateProductDto extends PartialType(CreateProductDto) {}
```

src/products/products.schemas.ts

JS TS

```typescript

import { z } from 'zod';

export const createProductSchema = z.object({
  name: z.string().min(1),
  price: z.number().positive(),
  published: z.boolean(),
});
export type CreateProductDto = z.infer<typeof createProductSchema>;

/** Any subset of the fields above. */
export const updateProductSchema = createProductSchema.partial();
export type UpdateProductDto = z.infer<typeof updateProductSchema>;
```

`@Can(ProductPolicy, 'create')` makes the guard call `create(user)` before the handler runs:

src/products/products.controller.ts

JS TS

```typescript

import { Body, Controller, Get, Param, Patch, Post } from '@nestjs/common';
import { Authenticate, CurrentUser } from '@nestjs/authentication';
import { Can } from '@nestjs/authorization';
import type { User } from '../users/user.js';
import { ProductPolicy } from './product.policy.js';
import { CreateProductDto, UpdateProductDto } from './products.dto.js';
import { ProductsService } from './products.service.js';

@Controller('products')
export class ProductsController {
  constructor(private readonly productsService: ProductsService) {}

  @Get()
  @Authenticate({ optional: true })
  @Can.Anyone()
  findAll(@CurrentUser() user: User | null) {
    return this.productsService.findAll(user);
  }

  @Get(':id')
  @Authenticate({ optional: true })
  @Can.Anyone()
  findOne(@CurrentUser() user: User | null, @Param('id') id: string) {
    return this.productsService.findOne(user, id);
  }

  @Post()
  @Can(ProductPolicy, 'create')
  create(@Body() input: CreateProductDto) {
    return this.productsService.create(input);
  }

  @Patch(':id')
  @Can(ProductPolicy, 'update')
  update(@Param('id') id: string, @Body() changes: UpdateProductDto) {
    return this.productsService.update(id, changes);
  }
}
```

With the Zod schemas, the body parameters declare their schema instead of a class:

src/products/products.controller.ts

JS TS

```typescript

import { createProductSchema, updateProductSchema, type CreateProductDto, type UpdateProductDto } from './products.schemas.js';
// ...
@Post()
@Can(ProductPolicy, 'create')
create(@Body({ schema: createProductSchema }) input: CreateProductDto) {
  return this.productsService.create(input);
}

@Patch(':id')
@Can(ProductPolicy, 'update')
update(@Param('id') id: string, @Body({ schema: updateProductSchema }) changes: UpdateProductDto) {
  return this.productsService.update(id, changes);
}
```

Whether a route admits guests is authentication's decision, not the policy's. The read routes use `@Authenticate()` with `optional: true`: a request with a valid token gets its user, and a request without one continues with `null`, which is what `@CurrentUser()` then injects. Without the decorator, guests would get a 401 before any policy ran. With `@Public()` instead, authentication would ignore the token entirely, so Sam would browse as a guest and never see drafts.

The read routes check in the service, so they declare `@Can.Anyone()`: anyone authentication lets through may call them, and `ProductsService` decides what each caller sees. Without it, the guard would deny them.

`@Can()` is type-checked. A misspelled ability doesn't compile:

```typescript

@Post()
@Can(ProductPolicy, 'craete')
// error TS2345: Argument of type '"craete"' is not assignable to parameter of type '"create" | "update" | "view" | "viewDrafts"'.
create(@Body() input: CreateProductDto) {}
```

The error lists the abilities that work on a route: those whose user parameter accepts `null`, since the guard can't know whether a route has a user. `view` is one of them, but `@Can(ProductPolicy, 'view')` still doesn't compile (`Expected 3 arguments, but got 2`): `view` also takes the product, and the guard has none to pass. Checks that need a record belong in the service, as in `findOne()`. A check that needs only an id from the URL can stay on the route, as [Check a route parameter](/security/authorization#check-a-route-parameter) shows.

Finally, register the policy as a provider of its feature module:

src/products/products.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { ProductPolicy } from './product.policy.js';
import { ProductsController } from './products.controller.js';
import { ProductsService } from './products.service.js';

@Module({
  controllers: [ProductsController],
  providers: [ProductsService, ProductPolicy],
})
export class ProductsModule {}
```

Add `ProductsModule` to the `imports` of `AppModule`. `@Policy()` also makes the class injectable, and the authorization module discovers every policy provider in the app, wherever it's registered. Alternatively, list policies in the `policies` option of `AuthorizationModule.forRoot()`.

> **Hint** If a `@Can()` points at a policy nobody registered, the app refuses to start, and the error names the handler.

#### Check orders record by record[#](/security/authorization#check-orders-record-by-record)

An order is the Authentication tutorial's: it belongs to a customer, by `userId`, and moves through a few states:

src/orders/order.ts

JS TS

```typescript

export interface OrderItem {
  productId: string;
  quantity: number;
}

export interface Order {
  id: string;
  userId: string;
  items: OrderItem[];
  /** In cents. */
  total: number;
  status: 'pending' | 'paid' | 'shipped' | 'refunded';
}
```

Whether Alice may view one of Bob's orders depends on that order, so these abilities take the order as a second argument:

src/orders/order.policy.ts

JS TS

```typescript

import { Policy } from '@nestjs/authorization';
import type { User } from '../users/user.js';
import type { Order } from './order.js';

@Policy()
export class OrderPolicy {
  viewAll(user: User) {
    return user.roles.includes('staff');
  }

  // Customers see their own orders; staff see everyone's.
  view(user: User, order: Order) {
    return order.userId === user.id || user.roles.includes('staff');
  }

  // Staff refund paid orders. Pending, shipped and refunded orders
  // can't be refunded by anyone.
  refund(user: User, order: Order) {
    return user.roles.includes('staff') && order.status === 'paid';
  }
}
```

These abilities take `User`, not `User | null`. Every orders route requires a signed-in user, and an ability that only services call may say so. The compiler then makes callers rule out a missing user before they check.

Four demo orders stand in for the orders table, with fixed ids like the demo accounts: Alice has a paid and a shipped order, Bob a paid one of five bags of salmon kibble (124.95, which matters when [a policy injects a service](/security/authorization#inject-a-service-into-a-policy)) and a pending one:

src/orders/demo-orders.ts

JS TS

```typescript

import { alice, bob } from '../users/demo-users.js';
import type { Order } from './order.js';

/** The demo orders: Alice has a paid and a shipped one, Bob a paid and a pending one. */
export const alicePaid: Order = {
  id: 'b69f25e7-db50-4abe-86d3-2ef2bd148009',
  userId: alice.id,
  items: [{ productId: 'salmon-kibble-2kg', quantity: 1 }],
  total: 2499,
  status: 'paid',
};

export const aliceShipped: Order = {
  id: 'd626a0c1-4122-4f83-ab7a-b009c26f35c7',
  userId: alice.id,
  items: [{ productId: 'clumping-litter-10l', quantity: 1 }],
  total: 1599,
  status: 'shipped',
};

export const bobPaid: Order = {
  id: '0ea8343b-879d-4b83-884b-6d5bb02f802f',
  userId: bob.id,
  items: [{ productId: 'salmon-kibble-2kg', quantity: 5 }],
  total: 12495,
  status: 'paid',
};

export const bobPending: Order = {
  id: '7e7023d3-cb2a-48d2-8c4e-20c07e6b8c06',
  userId: bob.id,
  items: [{ productId: 'clumping-litter-10l', quantity: 1 }],
  total: 1599,
  status: 'pending',
};

export const demoOrders = [alicePaid, aliceShipped, bobPaid, bobPending];
```

`OrdersService` loads the order, then authorizes against it:

src/orders/orders.service.ts

JS TS

```typescript

import { Injectable, NotFoundException } from '@nestjs/common';
import { AuthorizationService } from '@nestjs/authorization';
import type { User } from '../users/user.js';
import { demoOrders } from './demo-orders.js';
import type { Order } from './order.js';
import { OrderPolicy } from './order.policy.js';

@Injectable()
export class OrdersService {
  // Stands in for your orders table: copies, since a refund changes an order's status.
  private readonly orders: Order[] = demoOrders.map((order) => ({ ...order }));

  constructor(private readonly authorizationService: AuthorizationService) {}

  async findAll(user: User) {
    // Filter lists in the query; policies check one record at a time.
    return (await this.authorizationService.can(OrderPolicy, 'viewAll', user))
      ? this.orders
      : this.orders.filter((order) => order.userId === user.id);
  }

  async findOne(user: User, id: string) {
    const order = this.find(id);
    await this.authorizationService.authorize(OrderPolicy, 'view', user, order);
    return order;
  }

  async refund(user: User, id: string) {
    const order = this.find(id);
    await this.authorizationService.authorize(OrderPolicy, 'refund', user, order);
    // Refund the payment through the payment provider here, then record it.
    order.status = 'refunded';
    return order;
  }

  private find(id: string) {
    const order = this.orders.find((order) => order.id === id);
    if (!order) {
      throw new NotFoundException();
    }
    return order;
  }
}
```

Everything after the policy class is typed from the ability's signature: the ability name, the user and the order. A misspelled ability, a missing order, or an object that isn't an `Order` doesn't compile, and neither does a user that might be `null`:

```typescript

async show(user: User | null, order: Order) {
  await this.authorizationService.authorize(OrderPolicy, 'view', user, order);
  // error TS2345: Argument of type 'User | null' is not assignable to parameter of type 'User'.
}
```

The listing doesn't check orders one by one. It asks a question the query can use (may this user see every order?) and filters in the database. Checking each row after loading all of them would fetch too much and break pagination.

Checking in the service rather than in the controller means every caller gets the same rules: a controller, a GraphQL resolver, or a queue worker that processes refund requests.

The controller passes the signed-in user along. The Authentication tutorial's `OrdersService` read it from `AuthenticationContext` instead; here it's a parameter, so the service's signature says whose permissions a check is about, and a queue worker can call it for a given user. Every route checks in the service, so each declares `@Can.Anyone()`:

src/orders/orders.controller.ts

JS TS

```typescript

import { Controller, Get, HttpCode, Param, Post } from '@nestjs/common';
import { CurrentUser } from '@nestjs/authentication';
import { Can } from '@nestjs/authorization';
import type { User } from '../users/user.js';
import { OrdersService } from './orders.service.js';

@Controller('orders')
export class OrdersController {
  constructor(private readonly ordersService: OrdersService) {}

  @Get()
  @Can.Anyone()
  findAll(@CurrentUser() user: User) {
    return this.ordersService.findAll(user);
  }

  @Get(':id')
  @Can.Anyone()
  findOne(@CurrentUser() user: User, @Param('id') id: string) {
    return this.ordersService.findOne(user, id);
  }

  @Post(':id/refund')
  @HttpCode(200)
  @Can.Anyone()
  refund(@CurrentUser() user: User, @Param('id') id: string) {
    return this.ordersService.refund(user, id);
  }
}
```

src/orders/orders.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { OrderPolicy } from './order.policy.js';
import { OrdersController } from './orders.controller.js';
import { OrdersService } from './orders.service.js';

@Module({
  controllers: [OrdersController],
  providers: [OrdersService, OrderPolicy],
})
export class OrdersModule {}
```

Add `OrdersModule` to the `imports` of `AppModule`. Alice now gets her two orders from `GET /orders`, and a 403 from `GET /orders/:id` for one of Bob's.

> **Hint** A 403 confirms that the order exists. If that matters, for example when ids are sequential and guessable, check with `can()` and throw a `NotFoundException` instead.

#### Check a route parameter[#](/security/authorization#check-a-route-parameter)

Some checks need an argument but not a record. Staff look up a customer's orders at `GET /customers/:customerId/orders`, and customers may list their own there too. Whether Alice may call it depends on the id in the URL alone, so there's nothing to load before checking. Add an ability for it to `OrderPolicy`:

src/orders/order.policy.ts

JS TS

```typescript

// Customers list their own orders; staff list anyone's. A guest is denied.
viewOrdersOf(user: User | null, customerId: string) {
  return !!user && (user.id === customerId || user.roles.includes('staff'));
}
```

Unlike the other abilities of `OrderPolicy`, this one takes `User | null`, because a route ability must accept a guest. The route checks it with `@Can()`, whose third argument reads the arguments after the user from the call:

src/orders/customer-orders.controller.ts

JS TS

```typescript

import { Controller, Get, Param } from '@nestjs/common';
import { Can } from '@nestjs/authorization';
import { OrderPolicy } from './order.policy.js';
import { OrdersService } from './orders.service.js';

@Controller('customers/:customerId/orders')
export class CustomerOrdersController {
  constructor(private readonly ordersService: OrdersService) {}

  @Get()
  @Can(OrderPolicy, 'viewOrdersOf', (context) => [context.switchToHttp().getRequest().params.customerId])
  findAll(@Param('customerId') customerId: string) {
    return this.ordersService.findByCustomer(customerId);
  }
}
```

`OrdersService` gets a method that filters by customer, without a check of its own, since the route has it:

src/orders/orders.service.ts

JS TS

```typescript

findByCustomer(customerId: string) {
  return this.orders.filter((order) => order.userId === customerId);
}
```

Add the controller to the `controllers` of `OrdersModule`. Alice now gets her orders from `GET /customers/<Alice's id>/orders` and a 403 for Bob's, Sam gets either, and a guest gets a 401.

The function is typed by the ability's own parameters. Leaving it out doesn't compile when the ability takes more than the user, and neither does returning the wrong types:

```typescript

@Get()
@Can(OrderPolicy, 'viewOrdersOf')
// error TS2554: Expected 3 arguments, but got 2.
findAll() {}

@Get()
@Can(OrderPolicy, 'viewOrdersOf', () => [42])
// error TS2322: Type 'number' is not assignable to type 'string'.
findAll() {}
```

It runs in the guard, before any pipe, so it gets the values as the transport delivered them: route params are strings, and nothing is validated yet. A `ParseUUIDPipe` on `customerId` runs after the check, and an id the user may not see gets a 403, not a 400. An error the function throws, such as a `BadRequestException` for a missing param, reaches an HTTP client as it is. On WebSockets and microservices, Nest reports an `HttpException` from any guard, this function included, as an internal error, so throw a `WsException` or an `RpcException` there. A denial event carries what the function read in its `args`.

Pass identifiers and scopes, not records. Loading the order in the guard would load it twice, once for the check and once in the handler, and answer 403 before the handler could answer 404. That's why `GET /orders/:id` checks in the service instead.

A function declared on its own returns an array rather than the tuple the ability's parameters describe, so end it with `as const`. That makes a small helper reusable across routes:

src/common/param.ts

JS TS

```typescript

import type { ExecutionContext } from '@nestjs/common';

/** Reads one route param for `@Can()`. */
export const param = (name: string) => (context: ExecutionContext) =>
  [context.switchToHttp().getRequest().params[name] as string] as const;
```

```typescript

@Can(OrderPolicy, 'viewOrdersOf', param('customerId'))
```

On the other transports, read the arguments from their own context: `GqlExecutionContext.create(context).getArgs()` for a GraphQL operation's arguments, `context.switchToWs().getData()` for a WebSocket message, and `context.switchToRpc().getData()` for a microservice message.

#### Let admins through with `before()`[#](/security/authorization#let-admins-through-with-before)

Admins may do anything with the catalog, including deleting products, which nobody else may do. Rather than adding an admin check to every ability, give the policy a `before()` hook:

src/products/product.policy.ts

JS TS

```typescript

import { Policy, type PolicyBefore } from '@nestjs/authorization';
import type { User } from '../users/user.js';
import type { Product } from './product.js';

const isStaff = (user: User | null) => !!user?.roles.includes('staff');

@Policy()
export class ProductPolicy implements PolicyBefore<User> {
  // Admins pass every check below, including abilities added later.
  before(user: User | null) {
    if (user?.roles.includes('admin')) {
      return true;
    }
  }

  // `null` is a guest. Everyone sees published products; staff also see drafts.
  view(user: User | null, product: Product) {
    return product.published || isStaff(user);
  }

  viewDrafts(user: User | null) {
    return isStaff(user);
  }

  create(user: User | null) {
    return isStaff(user);
  }

  update(user: User | null) {
    return isStaff(user);
  }

  // Nobody but admins, who get through in before().
  delete(_user: User | null) {
    return false;
  }
}
```

`before()` runs ahead of every ability of its policy, for route checks and service checks alike. It receives the user, the ability name, and the ability's arguments. Return `true` to allow, `false` to deny, or nothing to let the ability decide. Guests reach `before()` too, so its user parameter must accept `null`. `before(user: User)` doesn't compile, whether or not the class implements `PolicyBefore<User>`.

Add the route that uses the new ability to `ProductsController`, and import `Delete` and `HttpCode` from `@nestjs/common`:

src/products/products.controller.ts

JS TS

```typescript

@Delete(':id')
@HttpCode(204)
@Can(ProductPolicy, 'delete')
remove(@Param('id') id: string) {
  this.productsService.remove(id);
}
```

Sam now gets a 403 from `DELETE /products/clumping-litter-10l`, and Ada gets a 204.

> **Warning**`before()` skips every ability of its policy, including rules that should bind everyone. That's why `OrderPolicy` gets no admin bypass: "nobody refunds a shipped order" has to hold for Ada too. If a policy needs both, check the ability name that `before()` receives, and return nothing for the abilities it must not skip. Implement `PolicyBefore<User, Ability<OrderPolicy>>` and type the name as `Ability<OrderPolicy>`, so a misspelled exclusion doesn't compile.

#### Inject a service into a policy[#](/security/authorization#inject-a-service-into-a-policy)

Finance caps how much each staff member may refund on their own: 100.00 by default, more for some people. The limits live outside the policy, in a service that would read a table or a config service:

src/orders/refund-limits.service.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { ada } from '../users/demo-users.js';
import type { User } from '../users/user.js';

@Injectable()
export class RefundLimitsService {
  // Per-person limits set by finance, in cents, by user id. Stands in for a table or a config service.
  private readonly limits = new Map<string, number>([[ada.id, 100_000]]);

  async maxRefundFor(user: User): Promise<number> {
    return this.limits.get(user.id) ?? 10_000;
  }
}
```

Because a policy is a provider, it injects the service through its constructor. The `refund` ability becomes `async`:

src/orders/order.policy.ts

JS TS

```typescript

import { Policy } from '@nestjs/authorization';
import type { User } from '../users/user.js';
import type { Order } from './order.js';
import { RefundLimitsService } from './refund-limits.service.js';

@Policy()
export class OrderPolicy {
  constructor(private readonly refundLimitsService: RefundLimitsService) {}

  viewAll(user: User) {
    return user.roles.includes('staff');
  }

  // Customers see their own orders; staff see everyone's.
  view(user: User, order: Order) {
    return order.userId === user.id || user.roles.includes('staff');
  }

  // Customers list their own orders; staff list anyone's. A guest is denied.
  viewOrdersOf(user: User | null, customerId: string) {
    return !!user && (user.id === customerId || user.roles.includes('staff'));
  }

  // Staff refund paid orders up to their limit. Pending, shipped and
  // refunded orders can't be refunded by anyone.
  async refund(user: User, order: Order) {
    if (!user.roles.includes('staff') || order.status !== 'paid') {
      return false;
    }
    return order.total <= (await this.refundLimitsService.maxRefundFor(user));
  }
}
```

`authorize()`, `can()` and the guard all await async abilities, so `OrdersService` doesn't change. Register the service next to the policy:

src/orders/orders.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { CustomerOrdersController } from './customer-orders.controller.js';
import { OrderPolicy } from './order.policy.js';
import { OrdersController } from './orders.controller.js';
import { OrdersService } from './orders.service.js';
import { RefundLimitsService } from './refund-limits.service.js';

@Module({
  controllers: [OrdersController, CustomerOrdersController],
  providers: [OrdersService, OrderPolicy, RefundLimitsService],
})
export class OrdersModule {}
```

Since `OrderPolicy` is registered in `OrdersModule`, it can inject that module's providers. A policy listed in the `policies` option of `forRoot()` lives in the authorization module instead, and needs the `imports` option to reach its dependencies.

Bob's paid order comes to 124.95. Sam (limit 100.00) now gets a 403 when he tries to refund it, and Ada (limit 1,000.00) succeeds.

> **Warning** Policies must be singletons. A request-scoped or transient policy, or one that depends on a request-scoped provider, throws at startup. Keep per-request state out of policies, and pass what an ability needs as arguments.

#### Tell guests from forbidden users, and expose permissions[#](/security/authorization#tell-guests-from-forbidden-users-and-expose-permissions)

A denied request gets a 401 or a 403, depending on who is asking and where:

| Caller         | Route                                                                          | Status                                             | Comes from                             |
| -------------- | ------------------------------------------------------------------------------ | -------------------------------------------------- | -------------------------------------- |
| Guest          | Requires sign-in (the default), such as `POST /products` or `GET /orders`      | 401, with `WWW-Authenticate: Bearer realm="store"` | Authentication, before any policy runs |
| Guest          | Optional authentication, and the policy denies `null`, such as a draft product | 401                                                | Authorization                          |
| Signed-in user | The policy denies, such as Alice on `POST /products` or on one of Bob's orders | 403                                                | Authorization                          |

Authorization never decides whether a route needs a user; that's authentication's job. When a policy denies a guest, the package answers 401 ("sign in and try again") rather than 403 ("never"), because signing in might change the answer.

`authorize()` itself throws an `AuthorizationError`, whose `reason` is `unauthenticated` or `forbidden`, and whose `status` is the matching 401 or 403. It isn't an HTTP exception, because the same service also runs in queue workers and WebSocket gateways. When the error leaves a handler, `AuthorizationModule` turns it into the `UnauthorizedException` or `ForbiddenException` that the guard throws, with the same bodies, so exception filters and clients handle both like any other HTTP error. In WebSocket gateways and microservice handlers, it becomes a `WsException` or an `RpcException`. The 403 body doesn't name the ability.

`can()` never throws on a denial. It resolves to `false` for guests and forbidden users alike, which makes it the tool for shaping responses. Give each order a `canRefund` flag, so the frontend shows the refund button without duplicating the rules:

src/orders/orders.service.ts

JS TS

```typescript

import { Injectable, NotFoundException } from '@nestjs/common';
import { AuthorizationService } from '@nestjs/authorization';
import type { User } from '../users/user.js';
import { demoOrders } from './demo-orders.js';
import type { Order } from './order.js';
import { OrderPolicy } from './order.policy.js';

export type OrderView = Order & { canRefund: boolean };

@Injectable()
export class OrdersService {
  // Stands in for your orders table: copies, since a refund changes an order's status.
  private readonly orders: Order[] = demoOrders.map((order) => ({ ...order }));

  constructor(private readonly authorizationService: AuthorizationService) {}

  async findAll(user: User): Promise<OrderView[]> {
    // Filter lists in the query; policies check one record at a time.
    const orders = (await this.authorizationService.can(OrderPolicy, 'viewAll', user))
      ? this.orders
      : this.orders.filter((order) => order.userId === user.id);
    return Promise.all(orders.map((order) => this.toView(user, order)));
  }

  async findOne(user: User, id: string): Promise<OrderView> {
    const order = this.find(id);
    await this.authorizationService.authorize(OrderPolicy, 'view', user, order);
    return this.toView(user, order);
  }

  async refund(user: User, id: string): Promise<OrderView> {
    const order = this.find(id);
    await this.authorizationService.authorize(OrderPolicy, 'refund', user, order);
    // Refund the payment through the payment provider here, then record it.
    order.status = 'refunded';
    return this.toView(user, order);
  }

  private async toView(user: User, order: Order): Promise<OrderView> {
    return { ...order, canRefund: await this.authorizationService.can(OrderPolicy, 'refund', user, order) };
  }

  private find(id: string) {
    const order = this.orders.find((order) => order.id === id);
    if (!order) {
      throw new NotFoundException();
    }
    return order;
  }
}
```

The flag comes from the same `refund` ability that `POST /orders/:id/refund` enforces, so the button and the endpoint can't disagree. Sam sees `canRefund: true` on Alice's paid order and `false` on Bob's, which is over his limit. Ada sees `true` on both.

#### Try it[#](/security/authorization#try-it)

Start the application with the `.env` file that holds the signing secret:

```bash

$ npm run start:dev -- --env-file .env
```

In another terminal, sign in as Alice, Sam and Ada. `--json` (curl 7.82 or later) sends a `POST` with a JSON body, and the `token` helper uses [jq](https://jqlang.org/) to extract the access token:

```bash

$ token() { curl -s localhost:3000/auth/token --json "{\"email\":\"$1@example.com\",\"password\":\"catnip4all\"}" | jq -r .accessToken; }
$ ALICE=$(token alice) SAM=$(token sam) ADA=$(token ada)
```

Guests see published products. Staff see the draft too:

```bash

$ curl localhost:3000/products
[{"id":"salmon-kibble-2kg","name":"Salmon kibble, 2 kg","price":2499,"published":true},{"id":"clumping-litter-10l","name":"Clumping litter, 10 l","price":1599,"published":true}]

$ curl -s localhost:3000/products -H "Authorization: Bearer $SAM" | jq -c '.[] | {id, published}'
{"id":"salmon-kibble-2kg","published":true}
{"id":"clumping-litter-10l","published":true}
{"id":"heated-cat-bed","published":false}
```

The draft itself is a 401 for a guest and a 403 for a customer. Response headers are trimmed here and below:

```bash

$ curl -i localhost:3000/products/heated-cat-bed
HTTP/1.1 401 Unauthorized
{"message":"Unauthorized","statusCode":401}

$ curl -i localhost:3000/products/heated-cat-bed -H "Authorization: Bearer $ALICE"
HTTP/1.1 403 Forbidden
{"message":"Forbidden","statusCode":403}
```

Only staff add products. Authentication stops the guest, and `@Can()` stops Alice:

```bash

$ curl -i localhost:3000/products --json '{"name":"Sisal scratching post","price":3999,"published":false}'
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer realm="store"
{"message":"Unauthorized","statusCode":401}

$ curl -i localhost:3000/products -H "Authorization: Bearer $ALICE" --json '{"name":"Sisal scratching post","price":3999,"published":false}'
HTTP/1.1 403 Forbidden
{"message":"Forbidden","statusCode":403}

$ curl localhost:3000/products -H "Authorization: Bearer $SAM" --json '{"name":"Sisal scratching post","price":3999,"published":false}'
{"name":"Sisal scratching post","price":3999,"published":false,"id":"sisal-scratching-post"}
```

Alice sees her own orders and can refund neither. Sam sees every order, with his own `canRefund` flags. Bob's paid order is off limits to Alice:

```bash

$ curl -s localhost:3000/orders -H "Authorization: Bearer $ALICE" | jq -c '.[] | {id, status, canRefund}'
{"id":"b69f25e7-db50-4abe-86d3-2ef2bd148009","status":"paid","canRefund":false}
{"id":"d626a0c1-4122-4f83-ab7a-b009c26f35c7","status":"shipped","canRefund":false}

$ curl -s localhost:3000/orders -H "Authorization: Bearer $SAM" | jq -c '.[] | {id, status, total, canRefund}'
{"id":"b69f25e7-db50-4abe-86d3-2ef2bd148009","status":"paid","total":2499,"canRefund":true}
{"id":"d626a0c1-4122-4f83-ab7a-b009c26f35c7","status":"shipped","total":1599,"canRefund":false}
{"id":"0ea8343b-879d-4b83-884b-6d5bb02f802f","status":"paid","total":12495,"canRefund":false}
{"id":"7e7023d3-cb2a-48d2-8c4e-20c07e6b8c06","status":"pending","total":1599,"canRefund":false}

$ curl -i localhost:3000/orders/0ea8343b-879d-4b83-884b-6d5bb02f802f -H "Authorization: Bearer $ALICE"
HTTP/1.1 403 Forbidden
{"message":"Forbidden","statusCode":403}
```

Sam refunds Alice's paid order, but not her shipped one, and not Bob's, which is over his limit. Ada can't refund the shipped order either, but Bob's is within her limit:

```bash

$ curl -s -X POST localhost:3000/orders/b69f25e7-db50-4abe-86d3-2ef2bd148009/refund -H "Authorization: Bearer $SAM" | jq -c '{id, status, canRefund}'
{"id":"b69f25e7-db50-4abe-86d3-2ef2bd148009","status":"refunded","canRefund":false}

$ curl -i -X POST localhost:3000/orders/d626a0c1-4122-4f83-ab7a-b009c26f35c7/refund -H "Authorization: Bearer $SAM"
HTTP/1.1 403 Forbidden
{"message":"Forbidden","statusCode":403}

$ curl -i -X POST localhost:3000/orders/0ea8343b-879d-4b83-884b-6d5bb02f802f/refund -H "Authorization: Bearer $SAM"
HTTP/1.1 403 Forbidden
{"message":"Forbidden","statusCode":403}

$ curl -i -X POST localhost:3000/orders/d626a0c1-4122-4f83-ab7a-b009c26f35c7/refund -H "Authorization: Bearer $ADA"
HTTP/1.1 403 Forbidden
{"message":"Forbidden","statusCode":403}

$ curl -s -X POST localhost:3000/orders/0ea8343b-879d-4b83-884b-6d5bb02f802f/refund -H "Authorization: Bearer $ADA" | jq -c '{id, status, canRefund}'
{"id":"0ea8343b-879d-4b83-884b-6d5bb02f802f","status":"refunded","canRefund":false}
```

Only an admin deletes a product:

```bash

$ curl -i -X DELETE localhost:3000/products/clumping-litter-10l -H "Authorization: Bearer $SAM"
HTTP/1.1 403 Forbidden
{"message":"Forbidden","statusCode":403}

$ curl -i -X DELETE localhost:3000/products/clumping-litter-10l -H "Authorization: Bearer $ADA"
HTTP/1.1 204 No Content
```

#### Testing[#](/security/authorization#testing)

An end-to-end test boots the whole app, signs in through the real endpoint, and checks the rules over HTTP. As in the Authentication tutorial, scrypt is slow on purpose, so the test overrides `PasswordHasher` with a cheaper one, and the application reads `JWT_SECRET` at bootstrap, so the test configuration provides one:

vitest.config.ts

JS TS

```typescript

export default defineConfig({
  // ...
  test: {
    // ...
    env: {
      JWT_SECRET: 'test-only-jwt-secret-of-at-least-32-bytes',
    },
  },
});
```

test/orders.e2e-spec.ts

JS TS

```typescript

import type { INestApplication } from '@nestjs/common';
import { PasswordHasher } from '@nestjs/authentication';
import { Test } from '@nestjs/testing';
import request from 'supertest';
import { AppModule } from '../src/app.module.js';
import { alicePaid, aliceShipped, bobPaid } from '../src/orders/demo-orders.js';

describe('Orders (e2e)', () => {
  let app: INestApplication;

  const signIn = async (email: string) => {
    const { body } = await request(app.getHttpServer())
      .post('/auth/token')
      .send({ email, password: 'catnip4all' })
      .expect(200);
    return `Bearer ${body.accessToken}`;
  };

  beforeAll(async () => {
    const moduleRef = await Test.createTestingModule({ imports: [AppModule] })
      // scrypt is slow on purpose; the tests don't need it to be.
      .overrideProvider(PasswordHasher)
      .useValue(new PasswordHasher({ logN: 11 }))
      .compile();
    app = moduleRef.createNestApplication();
    await app.listen(0, '127.0.0.1');
  });

  afterAll(() => app.close());

  it('asks guests to sign in', async () => {
    await request(app.getHttpServer()).get('/orders').expect(401);
  });

  it('shows customers only their own orders', async () => {
    const alice = await signIn('alice@example.com');
    const { body } = await request(app.getHttpServer())
      .get('/orders')
      .set('Authorization', alice)
      .expect(200);
    expect(body.map((order: { id: string }) => order.id)).toEqual([alicePaid.id, aliceShipped.id]);

    await request(app.getHttpServer()).get(`/orders/${bobPaid.id}`).set('Authorization', alice).expect(403);
  });

  it('lets staff refund a paid order once, within their limit', async () => {
    const sam = await signIn('sam@example.com');
    const refund = (id: string) =>
      request(app.getHttpServer()).post(`/orders/${id}/refund`).set('Authorization', sam);

    await refund(alicePaid.id).expect(200);
    await refund(alicePaid.id).expect(403); // already refunded
    await refund(aliceShipped.id).expect(403); // shipped
    await refund(bobPaid.id).expect(403); // over Sam's limit
  });
});
```

A policy is a plain class, so its rules are easy to unit-test without Nest. Construct the policy yourself and control its dependencies; the demo accounts and orders double as fixtures:

src/orders/order.policy.spec.ts

JS TS

```typescript

import { vi } from 'vitest';
import { alice, sam } from '../users/demo-users.js';
import { alicePaid, bobPaid } from './demo-orders.js';
import { OrderPolicy } from './order.policy.js';
import { RefundLimitsService } from './refund-limits.service.js';

describe('OrderPolicy', () => {
  // No Nest here: a policy is a class, so construct it yourself.
  const refundLimits = new RefundLimitsService();
  const policy = new OrderPolicy(refundLimits);

  it('shows customers only their own orders', () => {
    expect(policy.view(alice, alicePaid)).toBe(true);
    expect(policy.view(alice, bobPaid)).toBe(false);
    expect(policy.view(sam, bobPaid)).toBe(true);
  });

  it('lets staff refund paid orders up to their limit', async () => {
    vi.spyOn(refundLimits, 'maxRefundFor').mockResolvedValue(5000);

    expect(await policy.refund(sam, { ...alicePaid, total: 5000 })).toBe(true);
    expect(await policy.refund(sam, { ...alicePaid, total: 5001 })).toBe(false);
    expect(await policy.refund(alice, alicePaid)).toBe(false);
  });

  it('refuses refunds on orders that are not paid', async () => {
    for (const status of ['pending', 'shipped', 'refunded'] as const) {
      expect(await policy.refund(sam, { ...alicePaid, status })).toBe(false);
    }
  });
});
```

Calling an ability directly skips `before()`. The hook is just another method, so test it the same way, for example `expect(new ProductPolicy().before(ada)).toBe(true)`. To test the hook and the ability together, go through `AuthorizationService`, and to test the 401/403 mapping too, go through HTTP, as the end-to-end test does.

A service test sits in between: the real policy and `AuthorizationModule`, without HTTP or signing in. Outside a handler, a denial stays an `AuthorizationError`:

src/orders/orders.service.spec.ts

JS TS

```typescript

import { Test } from '@nestjs/testing';
import { AuthorizationError, AuthorizationModule } from '@nestjs/authorization';
import { alice, sam } from '../users/demo-users.js';
import { alicePaid, bobPaid } from './demo-orders.js';
import { OrderPolicy } from './order.policy.js';
import { OrdersService } from './orders.service.js';
import { RefundLimitsService } from './refund-limits.service.js';

describe('OrdersService', () => {
  let orders: OrdersService;

  beforeEach(async () => {
    // The real policy and module, no HTTP and no sign-in.
    const moduleRef = await Test.createTestingModule({
      imports: [AuthorizationModule.forRoot()],
      providers: [OrdersService, OrderPolicy, RefundLimitsService],
    }).compile();
    orders = moduleRef.get(OrdersService);
  });

  it("keeps Bob's order from Alice", async () => {
    await expect(orders.findOne(alice, bobPaid.id)).rejects.toThrow(AuthorizationError);
  });

  it('refunds within the limit only', async () => {
    await expect(orders.refund(sam, bobPaid.id)).rejects.toMatchObject({ reason: 'forbidden', ability: 'refund' });
    expect((await orders.refund(sam, alicePaid.id)).status).toBe('refunded');
  });
});
```

To replace a policy in a bigger test, override it like any provider, for example `.overrideProvider(OrderPolicy).useValue(...)`: every check, on routes and in services, runs against the override.

#### Production checklist[#](/security/authorization#production-checklist)

* **Keep authentication ahead of authorization.** With `AuthenticationModule`, the wrong import order stops the app at startup. With another authentication guard, it only logs an error, so have an end-to-end test sign in and call a `@Can()` route. Two registrations always run after the authorization guard, whatever the import order: a request-scoped `APP_GUARD` (the startup check says so) and `app.useGlobalGuards()` (it can't). Register authentication as a singleton `APP_GUARD`.
* **Review every `@Can.Anyone()`.** The guard denies a handler that declares no check, and logs each one at startup, so a forgotten `@Can()` closes a route. `@Can.Anyone()` opens it to everyone authentication lets through: check that its service authorizes, or that the route needs no permission. A check on an id in the URL can go on the route, with `@Can()`'s third argument, where a later edit to the handler can't drop it.
* **Connect microservices with `inheritAppConfig: true`.** In a hybrid app, Nest runs the app's global guards and interceptors on message handlers only when `connectMicroservice()` gets that option. Without it, `@Can()` on a message handler isn't enforced, and a denial from `authorize()` reaches the client as an internal error instead of a 401 or 403.
* **Put record checks in services**, after loading the record, so that controllers, resolvers and queue workers share them.
* **Don't cache responses by URL on routes that check records.** A cache such as Nest's `CacheInterceptor` answers before the handler runs, so it would serve Bob's order to Alice without asking `OrderPolicy`. Cache below the check, or per user.
* **Filter lists in the query** with a question the query can use, like `viewAll`, rather than loading every row and checking each one.
* **Re-check state when you write.** Authorization reads the order before the refund, and two concurrent requests can both see `paid`. Make the write conditional (update the status only where it's still `paid`), and send the payment provider an idempotency key, so a retry never refunds twice.
* **Choose between 403 and 404** for records whose existence is sensitive, such as other customers' orders when IDs are sequential.
* **Keep policies stateless.** They're singletons shared by all requests.
* **Watch the cost of `can()` flags.** Each flag runs the ability once per row, including any async work. Cache slow lookups like refund limits, or load them once per request.
* **Load secrets from configuration.** Read the JWT secret (at least 32 bytes) from a secret manager or `ConfigService`, not from code.
* **Check with `can()` in your own guards and middleware.** They run before any handler, so an `AuthorizationError` thrown there isn't turned into a 401 or a 403. It becomes a 500.
* **Audit denials.** Responses don't say which check refused a caller. Subscribe to `AuthorizationEvents` to log the policy, the ability and the user's ID for every denial. Each event carries the user and the record as the policy saw them, so log the fields you need rather than the whole event.

#### Reference[#](/security/authorization#reference)

##### Module options[#](/security/authorization#module-options)

`AuthorizationModule.forRoot()` takes these options. `forRootAsync()` takes `policies`, `imports`, `globalGuard` and `isGlobal` at the top level, next to `useFactory`, and its factory returns `getUser`.

| Option        | Default          | Description                                                                                                                                                                                           |
| ------------- | ---------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `getUser`     | `defaultGetUser` | A function that receives the `ExecutionContext` and returns the current user, or a promise of it. See [Register the authorization module](/security/authorization#register-the-authorization-module). |
| `policies`    | none             | Policies to register in the authorization module itself. A `@Policy()` provider of any module is found without being listed.                                                                          |
| `imports`     | none             | Modules whose exported providers the `policies` inject.                                                                                                                                               |
| `globalGuard` | `true`           | Register `AuthorizationGuard` as a global guard. With `false`, apply it with `@UseGuards()` after your authentication guard.                                                                          |
| `isGlobal`    | `true`           | Register the module globally.                                                                                                                                                                         |

`defaultGetUser` reads the user from these places. `null`, `undefined` and `false` all mean a guest.

| Context       | Source                                                                                         |
| ------------- | ---------------------------------------------------------------------------------------------- |
| HTTP          | `request.user`                                                                                 |
| GraphQL       | the user authentication recorded for this operation, else `req.user` on the GraphQL context    |
| WebSockets    | the user authentication recorded for this message, else `client.user`, then `client.data.user` |
| Microservices | `user` on the transport context, never the message payload                                     |

A WebSocket client is the connection, not the message, and over `graphql-ws` the `req` on the GraphQL context is the socket's upgrade request, which every operation on the socket shares. So `client.user` and `req.user` hold whichever message or operation authenticated last. `@nestjs/authentication` also leaves a function on the client and on `req`, under `Symbol.for('nestjs.authentication.userOf')`, which takes the `ExecutionContext` and answers with the user of that message or operation: `null` for an anonymous one, as every `@Public()` one is, or `undefined` when it has no answer. `defaultGetUser` asks it first. A `@Public()` message or operation is therefore a guest for `@Can()`, even on a socket whose handshake signed in, and a session that a sign-out everywhere revoked no longer counts. A `getUser` of your own that reads `client.user` or `req.user` on these transports sees the socket's last user instead; other authentication packages can leave the same function to be asked.

##### What a route declares[#](/security/authorization#what-a-route-declares)

The guard decides by what the handler and its class declare:

| Declaration                                                | The guard                                                                   |
| ---------------------------------------------------------- | --------------------------------------------------------------------------- |
| `@Can()`                                                   | Runs every requirement of the class, then of the method. All must pass.     |
| `@Can.Anyone()`                                            | Lets through anyone authentication lets through.                            |
| `@Public()` from `@nestjs/authentication` (0.1.0 or later) | The same as `@Can.Anyone()`.                                                |
| Nothing                                                    | Denies: 403 for a user, 401 for a guest. The startup log names the handler. |

On a method, `@Can.Anyone()` or `@Public()` lifts the class's `@Can()`, as `@Public()` lifts the class's authentication. A `@Can()` on the method itself still applies, so a `@Public()` method with a `@Can()` runs the check for a guest. On a class, neither lifts a method's `@Can()`. A method that `@Authenticate()` puts back under authentication inside a `@Public()` class isn't public, and needs a declaration of its own.

Where Nest runs no global guard, nothing is denied: on GraphQL field resolvers unless `fieldResolverEnhancers` includes `'guards'`, and on the message handlers of a hybrid app connected without `inheritAppConfig: true`. With the enhancer, every `@ResolveField()` needs a declaration too. A class-level one covers them.

##### Events[#](/security/authorization#events)

`AuthorizationEvents` exposes every denial on its `events$` observable, and publishes it on a diagnostics channel. `can()` resolving to `false` isn't a denial and emits nothing.

| Event type | Channel                       | When                                       |
| ---------- | ----------------------------- | ------------------------------------------ |
| `denied`   | `nestjs:authorization:denied` | `@Can()` or `authorize()` refused a caller |

The `AuthorizationDeniedEvent` payload has these fields:

* `type`: `'denied'`.
* `policy` and `ability`: the policy class name and the ability that denied, such as `OrderPolicy` and `refund`. Both are `null` when the guard denied a handler that declares no check.
* `reason`: `'unauthenticated'` for a guest, `'forbidden'` for a signed-in user.
* `user`: the user the policy saw, `null` for a guest.
* `args`: the ability's arguments after the user, such as the record. For `@Can()`, what its third argument read, or empty without one.
* `handler`: the handler `@Can()` guarded, such as `ProductsController.create`. Absent for `authorize()`.

##### Errors[#](/security/authorization#errors)

`authorize()` throws an `AuthorizationError` with `reason`, `status`, `policy` and `ability`. The guard's denial of a handler that declares no check carries the same error, with `policy` and `ability` set to `null`. When it leaves a handler, or when `@Can()` denies, the caller gets the transport's own error, whose body never names the policy or the ability. See [Tell guests from forbidden users, and expose permissions](/security/authorization#tell-guests-from-forbidden-users-and-expose-permissions).

| `reason`          | `status` | HTTP                    | GraphQL `extensions.code` | WebSockets and microservices                           |
| ----------------- | -------- | ----------------------- | ------------------------- | ------------------------------------------------------ |
| `unauthenticated` | 401      | `UnauthorizedException` | `UNAUTHENTICATED`         | `WsException` or `RpcException` with `statusCode: 401` |
| `forbidden`       | 403      | `ForbiddenException`    | `FORBIDDEN`               | `WsException` or `RpcException` with `statusCode: 403` |

Over `graphql-ws`, the client gets the error's message, `Unauthorized` or `Forbidden`, without `extensions.code`: the Apollo driver adds the codes in its error formatting, which doesn't run on that transport.

An `AuthorizationError` thrown outside a handler, such as in your own guard or middleware, isn't mapped and becomes a 500.

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/security/authorization.md)

----
url: https://docs.nestjs.com/v11/microservices/mqtt
----

* [MQTT](https://docs.nestjs.com/v11/microservices/mqtt#mqtt)
* [Installation](https://docs.nestjs.com/v11/microservices/mqtt#installation)
* [Overview](https://docs.nestjs.com/v11/microservices/mqtt#overview)
* [Options](https://docs.nestjs.com/v11/microservices/mqtt#options)
* [Client](https://docs.nestjs.com/v11/microservices/mqtt#client)
* [Context](https://docs.nestjs.com/v11/microservices/mqtt#context)
* [Wildcards](https://docs.nestjs.com/v11/microservices/mqtt#wildcards)
* [Quality of Service (QoS)](https://docs.nestjs.com/v11/microservices/mqtt#quality-of-service-qos)
* [Per-pattern QoS](https://docs.nestjs.com/v11/microservices/mqtt#per-pattern-qos)
* [Record builders](https://docs.nestjs.com/v11/microservices/mqtt#record-builders)
* [Instance status updates](https://docs.nestjs.com/v11/microservices/mqtt#instance-status-updates)
* [Listening to MQTT events](https://docs.nestjs.com/v11/microservices/mqtt#listening-to-mqtt-events)
* [Underlying driver access](https://docs.nestjs.com/v11/microservices/mqtt#underlying-driver-access)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/microservices/mqtt.md "Suggest Edits")

### MQTT

[MQTT](https://mqtt.org/) (Message Queuing Telemetry Transport) is an open source, lightweight messaging protocol, optimized for low latency. This protocol provides a scalable and cost-efficient way to connect devices using a **publish/subscribe** model. A communication system built on MQTT consists of the publishing server, a broker and one or more clients. It is designed for constrained devices and low-bandwidth, high-latency or unreliable networks.

#### Installation[#](/microservices/mqtt#installation)

To start building MQTT-based microservices, first install the required package:

```bash

$ npm i --save mqtt
```

#### Overview[#](/microservices/mqtt#overview)

To use the MQTT transporter, pass the following options object to the `createMicroservice()` method:

main.ts

JS TS

```typescript

const app = await NestFactory.createMicroservice<MicroserviceOptions>(AppModule, {
  transport: Transport.MQTT,
  options: {
    url: 'mqtt://localhost:1883',
  },
});
```

```typescript

const app = await NestFactory.createMicroservice(AppModule, {
  transport: Transport.MQTT,
  options: {
    url: 'mqtt://localhost:1883',
  },
});
```

> **Hint** The `Transport` enum is imported from the `@nestjs/microservices` package.

#### Options[#](/microservices/mqtt#options)

The `options` object is specific to the chosen transporter. The **MQTT** transporter exposes the properties described [here](https://github.com/mqttjs/MQTT.js/#mqttclientstreambuilder-options).

#### Client[#](/microservices/mqtt#client)

Like other microservice transporters, you have [several options](https://docs.nestjs.com/microservices/basics#client) for creating a MQTT `ClientProxy` instance.

One method for creating an instance is to use use the `ClientsModule`. To create a client instance with the `ClientsModule`, import it and use the `register()` method to pass an options object with the same properties shown above in the `createMicroservice()` method, as well as a `name` property to be used as the injection token. Read more about `ClientsModule`[here](https://docs.nestjs.com/microservices/basics#client).

```typescript

@Module({
  imports: [
    ClientsModule.register([
      {
        name: 'MATH_SERVICE',
        transport: Transport.MQTT,
        options: {
          url: 'mqtt://localhost:1883',
        }
      },
    ]),
  ]
  ...
})
```

Other options to create a client (either `ClientProxyFactory` or `@Client()`) can be used as well. You can read about them [here](https://docs.nestjs.com/microservices/basics#client).

#### Context[#](/microservices/mqtt#context)

In more complex scenarios, you may need to access additional information about the incoming request. When using the MQTT transporter, you can access the `MqttContext` object.

JS TS

```typescript

@MessagePattern('notifications')
getNotifications(@Payload() data: number[], @Ctx() context: MqttContext) {
  console.log(`Topic: ${context.getTopic()}`);
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('notifications')
getNotifications(data, context) {
  console.log(`Topic: ${context.getTopic()}`);
}
```

> **Hint**`@Payload()`, `@Ctx()` and `MqttContext` are imported from the `@nestjs/microservices` package.

To access the original mqtt [packet](https://github.com/mqttjs/mqtt-packet), use the `getPacket()` method of the `MqttContext` object, as follows:

JS TS

```typescript

@MessagePattern('notifications')
getNotifications(@Payload() data: number[], @Ctx() context: MqttContext) {
  console.log(context.getPacket());
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('notifications')
getNotifications(data, context) {
  console.log(context.getPacket());
}
```

#### Wildcards[#](/microservices/mqtt#wildcards)

A subscription may be to an explicit topic, or it may include wildcards. Two wildcards are available, `+` and `#`. `+` is a single-level wildcard, while `#` is a multi-level wildcard which covers many topic levels.

JS TS

```typescript

@MessagePattern('sensors/+/temperature/+')
getTemperature(@Ctx() context: MqttContext) {
  console.log(`Topic: ${context.getTopic()}`);
}
```

```typescript

@Bind(Ctx())
@MessagePattern('sensors/+/temperature/+')
getTemperature(context) {
  console.log(`Topic: ${context.getTopic()}`);
}
```

#### Quality of Service (QoS)[#](/microservices/mqtt#quality-of-service-qos)

Any subscription created with `@MessagePattern` or `@EventPattern` decorators will subscribe with QoS 0. If a higher QoS is required, it can be set globally using the `subscribeOptions` block when establishing the connection as follows:

main.ts

JS TS

```typescript

const app = await NestFactory.createMicroservice<MicroserviceOptions>(AppModule, {
  transport: Transport.MQTT,
  options: {
    url: 'mqtt://localhost:1883',
    subscribeOptions: {
      qos: 2
    },
  },
});
```

```typescript

const app = await NestFactory.createMicroservice(AppModule, {
  transport: Transport.MQTT,
  options: {
    url: 'mqtt://localhost:1883',
    subscribeOptions: {
      qos: 2
    },
  },
});
```

#### Per-pattern QoS[#](/microservices/mqtt#per-pattern-qos)

You can override the MQTT subscription QoS on a per-pattern basis by providing `qos` in the `extras` field of the pattern decorator. When not specified, the global `subscribeOptions.qos` is used as the default.

JS TS

```typescript

@EventPattern('critical-events', { extras: { qos: 2 } })
handleCriticalEvent(@Payload() data: any) {
  // This subscription uses QoS 2
}

@EventPattern('metrics', { extras: { qos: 0 } })
handleMetrics(@Payload() data: any) {
  // This subscription uses QoS 0
}
```

```typescript

@Bind(Payload())
@EventPattern('critical-events', { extras: { qos: 2 } })
handleCriticalEvent(data) {
  // This subscription uses QoS 2
}

@Bind(Payload())
@EventPattern('metrics', { extras: { qos: 0 } })
handleMetrics(data) {
  // This subscription uses QoS 0
}
```

> **Hint** Per-pattern QoS configuration does not affect existing behavior. When `extras.qos` is not specified, the subscription uses the global `subscribeOptions.qos` value.

#### Record builders[#](/microservices/mqtt#record-builders)

To configure message options (adjust the QoS level, set the Retain or DUP flags, or add additional properties to the payload), you can use the `MqttRecordBuilder` class. For example, to set `QoS` to `2` use the `setQoS` method, as follows:

```typescript

const userProperties = { 'x-version': '1.0.0' };
const record = new MqttRecordBuilder(':cat:')
  .setProperties({ userProperties })
  .setQoS(1)
  .build();
client.send('replace-emoji', record).subscribe(...);
```

> **Hint**`MqttRecordBuilder` class is exported from the `@nestjs/microservices` package.

And you can read these options on the server-side as well, by accessing the `MqttContext`.

JS TS

```typescript

@MessagePattern('replace-emoji')
replaceEmoji(@Payload() data: string, @Ctx() context: MqttContext): string {
  const { properties: { userProperties } } = context.getPacket();
  return userProperties['x-version'] === '1.0.0' ? '🐱' : '🐈';
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('replace-emoji')
replaceEmoji(data, context) {
  const { properties: { userProperties } } = context.getPacket();
  return userProperties['x-version'] === '1.0.0' ? '🐱' : '🐈';
}
```

In some cases you might want to configure user properties for multiple requests, you can pass these options to the `ClientProxyFactory`.

```typescript

import { Module } from '@nestjs/common';
import { ClientProxyFactory, Transport } from '@nestjs/microservices';

@Module({
  providers: [
    {
      provide: 'API_v1',
      useFactory: () =>
        ClientProxyFactory.create({
          transport: Transport.MQTT,
          options: {
            url: 'mqtt://localhost:1833',
            userProperties: { 'x-version': '1.0.0' },
          },
        }),
    },
  ],
})
export class ApiModule {}
```

#### Instance status updates[#](/microservices/mqtt#instance-status-updates)

To get real-time updates on the connection and the state of the underlying driver instance, you can subscribe to the `status` stream. This stream provides status updates specific to the chosen driver. For the MQTT driver, the `status` stream emits `connected`, `disconnected`, `reconnecting`, and `closed` events.

```typescript

this.client.status.subscribe((status: MqttStatus) => {
  console.log(status);
});
```

> **Hint** The `MqttStatus` type is imported from the `@nestjs/microservices` package.

Similarly, you can subscribe to the server's `status` stream to receive notifications about the server's status.

```typescript

const server = app.connectMicroservice<MicroserviceOptions>(...);
server.status.subscribe((status: MqttStatus) => {
  console.log(status);
});
```

#### Listening to MQTT events[#](/microservices/mqtt#listening-to-mqtt-events)

In some cases, you might want to listen to internal events emitted by the microservice. For example, you could listen for the `error` event to trigger additional operations when an error occurs. To do this, use the `on()` method, as shown below:

```typescript

this.client.on('error', (err) => {
  console.error(err);
});
```

Similarly, you can listen to the server's internal events:

```typescript

server.on<MqttEvents>('error', (err) => {
  console.error(err);
});
```

> **Hint** The `MqttEvents` type is imported from the `@nestjs/microservices` package.

#### Underlying driver access[#](/microservices/mqtt#underlying-driver-access)

For more advanced use cases, you may need to access the underlying driver instance. This can be useful for scenarios like manually closing the connection or using driver-specific methods. However, keep in mind that for most cases, you **shouldn't need** to access the driver directly.

To do so, you can use the `unwrap()` method, which returns the underlying driver instance. The generic type parameter should specify the type of driver instance you expect.

```typescript

const mqttClient = this.client.unwrap<import('mqtt').MqttClient>();
```

Similarly, you can access the server's underlying driver instance:

```typescript

const mqttClient = server.unwrap<import('mqtt').MqttClient>();
```

----
url: https://docs.nestjs.com/http/cookies
----

[Skip to content](#content)

On this page

* [Cookies](https://docs.nestjs.com/http/cookies#cookies)
* [Reading cookies](https://docs.nestjs.com/http/cookies#reading-cookies)
* [Setting and clearing cookies](https://docs.nestjs.com/http/cookies#setting-and-clearing-cookies)
* [Signing cookies](https://docs.nestjs.com/http/cookies#signing-cookies)
* [Invalid names and attributes](https://docs.nestjs.com/http/cookies#invalid-names-and-attributes)
* [Using cookie-parser or @fastify/cookie](https://docs.nestjs.com/http/cookies#using-cookie-parser-or-fastifycookie)

### Cookies

An **HTTP cookie** is a small piece of data that the user's browser stores. Cookies were designed as a reliable mechanism for websites to remember stateful information. When the user visits the website again, the browser automatically sends the cookie with the request.

Starting with NestJS v12.1, Nest supports cookies out of the box. The same API works on every HTTP adapter (Express, Fastify, or your own adapter extending `AbstractHttpAdapter`), and no extra package is needed:

* the `@Cookies()` and `@SignedCookies()` parameter decorators read the cookies sent with the request
* the HTTP adapter's `setCookie()` and `clearCookie()` methods write `Set-Cookie` response headers
* the `cookies` application option enables signed cookies, with support for rotating secrets

Applications that already use `cookie-parser` or `@fastify/cookie` keep working unchanged. See [Using cookie-parser or @fastify/cookie](/http/cookies#using-cookie-parser-or-fastifycookie) to learn how the two approaches interact.

#### Reading cookies[#](/http/cookies#reading-cookies)

Use the `@Cookies()` decorator to extract cookies from the incoming request. Pass a cookie name to extract a single cookie, or omit it to get all cookies as an object keyed by cookie name.

```typescript

import { Controller, Cookies, Get } from '@nestjs/common';

@Controller('preferences')
export class PreferencesController {
  @Get()
  findAll(@Cookies() cookies: Record<string, string>) {
    return cookies;
  }

  @Get('theme')
  findTheme(@Cookies('theme') theme?: string) {
    return theme ?? 'light';
  }
}
```

> **Hint** Import the `@Cookies()` decorator from the `@nestjs/common` package.

A named cookie that was not sent resolves to `undefined`. Nest parses the `Cookie` header only when a parameter asks for cookies, and at most once per request. Values are percent-decoded, and when the same name appears more than once, the first occurrence wins (browsers send the cookie with the most specific path first).

As with `@Query()` or `@Param()`, you can pass [pipes](/pipes) after the cookie name:

```typescript

@Get('cart')
findCart(@Cookies('cartSize', ParseIntPipe) cartSize: number) {
  return { cartSize };
}
```

With this in place, a `cartSize=abc` cookie results in a `400 Bad Request` response, and so does a missing cookie, unless you enable the pipe's `optional` option.

> **Hint** Pipes receive cookie parameters with the `type` property of `ArgumentMetadata` set to `'custom'`. As a result, a global `ValidationPipe` skips them unless you enable its `validateCustomDecorators` option.

> **Warning**`@Cookies()` does not verify signatures. Its values come straight from the client and may have been tampered with, so read any value you need to trust with `@SignedCookies()` instead (see [Signing cookies](/http/cookies#signing-cookies)).

#### Setting and clearing cookies[#](/http/cookies#setting-and-clearing-cookies)

Cookies are written through the HTTP adapter, which exposes two methods for this purpose:

* `setCookie(response, name, value, options?)` appends a `Set-Cookie` header to the response
* `clearCookie(response, name, options?)` appends a `Set-Cookie` header that expires the cookie immediately

Both methods take the native response object as their first argument. In a route handler, inject the `HttpAdapterHost` (see [HTTP adapter](/faq/http-adapter)) and get hold of the response object with the `@Res()` decorator, with its `passthrough` option enabled:

```typescript

import { Body, Controller, Delete, Put, Res } from '@nestjs/common';
import { HttpAdapterHost } from '@nestjs/core';

@Controller('preferences')
export class PreferencesController {
  constructor(private readonly adapterHost: HttpAdapterHost) {}

  @Put('theme')
  setTheme(
    @Body('theme') theme: string,
    @Res({ passthrough: true }) res: unknown,
  ) {
    this.adapterHost.httpAdapter.setCookie(res, 'theme', theme, {
      sameSite: 'lax',
      maxAge: 60 * 60 * 24 * 365, // one year, in seconds
    });
  }

  @Delete('theme')
  resetTheme(@Res({ passthrough: true }) res: unknown) {
    this.adapterHost.httpAdapter.clearCookie(res, 'theme');
  }
}
```

> **Warning** To leave the response handling logic to the framework, set the `passthrough` option to `true`, as shown above. See the [library-specific approach](/controllers#library-specific-approach) section of the Controllers chapter for details.

The controller never needs to know the type of the response object: `setCookie()` accepts whatever the underlying platform provides (an Express `Response`, a `FastifyReply`, and so on), which keeps the code platform-agnostic. Each call appends its own `Set-Cookie` header, so all the cookies set while handling a request are sent, on every platform. Because these methods only need the response object, you can also call them from a guard or an interceptor, using `context.switchToHttp().getResponse()`.

> **Hint**`setCookie()` and `clearCookie()` are optional members of the `HttpServer` interface. `AbstractHttpAdapter` implements them once, on top of its `appendHeader()` method, so every adapter that extends it (including `ExpressAdapter` and `FastifyAdapter`) supports them.

The cookie value must be a string. It is always percent-encoded with `encodeURIComponent()` (and decoded again by `@Cookies()`), so any string is safe to store. Convert other types yourself, for example with `JSON.stringify()`.

The `options` argument (the `CookieSerializeOptions` interface, exported from `@nestjs/common`) accepts the following attributes:

| Option        | Description                                                                                                          | Default |
| ------------- | -------------------------------------------------------------------------------------------------------------------- | ------- |
| `path`        | `Path` attribute.                                                                                                    | `'/'`   |
| `domain`      | `Domain` attribute. Must be a valid host name, optionally with a leading dot. When omitted, the cookie is host-only. | not set |
| `maxAge`      | `Max-Age` attribute, in **seconds**. Must be an integer.                                                             | not set |
| `expires`     | `Expires` attribute, as a `Date`. Browsers give precedence to `maxAge` when both are set.                            | not set |
| `httpOnly`    | `HttpOnly` attribute. Hides the cookie from client-side JavaScript.                                                  | `false` |
| `secure`      | `Secure` attribute. The browser only sends the cookie over HTTPS.                                                    | `false` |
| `sameSite`    | `SameSite` attribute: `'strict'`, `'lax'` or `'none'`. `'none'` requires `secure: true`.                             | not set |
| `partitioned` | `Partitioned` attribute (CHIPS). Requires `secure: true`.                                                            | `false` |
| `priority`    | `Priority` attribute (non-standard, honored by Chromium): `'low'`, `'medium'` or `'high'`.                           | not set |
| `signed`      | Signs the value with the first configured secret. See [Signing cookies](/http/cookies#signing-cookies).              | `false` |

Apart from `path`, no attribute has a default value, `httpOnly` included, which matches the behavior of Express and `@fastify/cookie`. For cookies that carry credentials or session identifiers, set `httpOnly`, `secure` and `sameSite` explicitly.

> **Warning**`maxAge` is expressed in **seconds**, as in RFC 6265 and `@fastify/cookie`. Express' `res.cookie()` method takes `maxAge` in **milliseconds**, so a value carried over from it unchanged makes the cookie live 1000 times longer. For one day, pass `60 * 60 * 24`.

`clearCookie()` writes an empty cookie with `Max-Age=0` and an `Expires` date in the past. Browsers only remove a cookie when the `path` and `domain` match the ones it was set with, so pass the same values to both methods. Since `path` defaults to `/` in both of them, `clearCookie(res, 'theme')` clears a cookie set with `setCookie(res, 'theme', value)`. The `maxAge`, `expires` and `signed` options are ignored by `clearCookie()`.

#### Signing cookies[#](/http/cookies#signing-cookies)

A signed cookie carries an HMAC signature next to its value, which lets the server detect whether the client tampered with it. To enable signing, pass a secret through the `cookies` option of the `NestFactory.create()` method:

```typescript

// main.ts
const app = await NestFactory.create(AppModule, {
  cookies: {
    secret: process.env.COOKIE_SECRET,
  },
});
```

Then, set cookies with the `signed` option and read them back with the `@SignedCookies()` decorator:

```typescript

import {
  Body,
  Controller,
  Get,
  Post,
  Res,
  SignedCookies,
  UnauthorizedException,
} from '@nestjs/common';
import { HttpAdapterHost } from '@nestjs/core';

@Controller('auth')
export class AuthController {
  constructor(
    private readonly adapterHost: HttpAdapterHost,
    private readonly authService: AuthService,
  ) {}

  @Post('login')
  async signIn(
    @Body() signInDto: SignInDto,
    @Res({ passthrough: true }) res: unknown,
  ) {
    const user = await this.authService.signIn(signInDto);
    this.adapterHost.httpAdapter.setCookie(res, 'uid', String(user.id), {
      signed: true,
      httpOnly: true,
      secure: true,
      sameSite: 'lax',
      maxAge: 60 * 60, // one hour, in seconds
    });
  }

  @Get('profile')
  getProfile(@SignedCookies('uid') userId?: string) {
    if (!userId) {
      throw new UnauthorizedException();
    }
    return this.authService.findProfile(userId);
  }

  @Post('logout')
  signOut(@Res({ passthrough: true }) res: unknown) {
    this.adapterHost.httpAdapter.clearCookie(res, 'uid');
  }
}
```

> **Hint** Import the `@SignedCookies()` decorator from the `@nestjs/common` package.

`@SignedCookies('uid')` resolves to the original, unsigned value when the signature verifies. When the cookie is missing, is not signed, was tampered with, or was signed with a secret that is not configured, it resolves to `undefined`. Called without a name, `@SignedCookies()` returns an object that contains only the cookies whose signature verifies. Like `@Cookies()`, it accepts pipes after the cookie name.

Signing fails loudly when no secret is configured: `setCookie()` with the `signed` option throws an error, and so does resolving a `@SignedCookies()` parameter (unless `cookie-parser` provides signed cookies, see [below](/http/cookies#using-cookie-parser-or-fastifycookie)), which results in a `500 Internal Server Error` response instead of every signed cookie silently reading as `undefined`. An empty secret (an empty string, an empty array, or an array with an empty entry) throws when the application is created.

> **Warning** A `secret` that is `undefined`, for example because an environment variable is not set, counts as no secret at all. The application starts, and the error only surfaces when a request sets or reads a signed cookie. Validate your configuration at startup, for example as described in the [Configuration](/application/configuration#schema-validation) chapter.

> **Warning** Signing protects the integrity of a cookie, not its confidentiality: the value is stored in plain text, and the client can read it. Do not store sensitive data in a signed cookie. Also note that, as with the `cookie-signature` package, the cookie name is not part of the signed data, so a value signed for one cookie also verifies when the client sends it under another name.

##### Rotating secrets[#](/http/cookies#rotating-secrets)

To replace a secret without invalidating the cookies signed with it, pass an array of secrets. Nest signs new cookies with the first secret and verifies incoming cookies against all of them:

```typescript

// main.ts
const app = await NestFactory.create(AppModule, {
  cookies: {
    // Signs with the first secret, verifies with all of them.
    secret: ['current-secret', 'previous-secret'],
  },
});
```

To rotate, add the new secret at the beginning of the array, and remove the previous one once every cookie signed with it has expired. Signatures are compared in constant time, and against every secret, so the response time does not reveal which secret matched.

##### Signature format[#](/http/cookies#signature-format)

Nest signs cookies in the format of the `cookie-signature` package, which `cookie-parser` and `express-session` use as well: the `s:` prefix, followed by the value, a dot, and the HMAC-SHA256 digest of the value in base64, without padding. As a result:

* cookies signed with the same secret by Express (the `signed` option of `res.cookie()`), `cookie-parser` or `express-session` keep verifying after you move to the built-in API, and `cookie-parser` can verify cookies signed by Nest
* values signed by `@fastify/cookie`, which omits the `s:` prefix, verify as well. The opposite direction does not work: the `unsignCookie()` method of `@fastify/cookie` cannot verify cookies signed by Nest, because of the `s:` prefix

#### Invalid names and attributes[#](/http/cookies#invalid-names-and-attributes)

`setCookie()` and `clearCookie()` reject invalid input instead of escaping it, so neither a cookie name nor an attribute can inject additional attributes or headers through `;`, CR or LF characters. They throw a `TypeError` when:

* the name is not a valid RFC 7230 token (for example, it contains spaces, `;`, `=` or control characters)
* `path` contains a `;`, or a character outside printable ASCII
* `domain` is not a valid host name (a leading dot is allowed)
* `maxAge` is not an integer, or `expires` is not a valid `Date`
* `sameSite` or `priority` is not one of the allowed values
* `sameSite` is `'none'`, or `partitioned` is `true`, while `secure` is not `true`. Browsers silently drop such cookies, so Nest reports the mistake instead
* the value is not a string

The content of the value is never rejected: since it is percent-encoded, a `;`, CR or LF in a value becomes `%3B`, `%0D` or `%0A`.

These errors are not HTTP exceptions, so when one is thrown from a route handler, the client receives a `500 Internal Server Error` response. If a cookie name or an attribute comes from user input, validate it before calling `setCookie()`.

> **Hint** Nest does not enforce the rules of the `__Host-` and `__Secure-` cookie name prefixes. If you use them, set the attributes they require yourself: `secure: true` for both, plus `path: '/'` and no `domain` for `__Host-`.

#### Using cookie-parser or @fastify/cookie[#](/http/cookies#using-cookie-parser-or-fastifycookie)

Before the built-in support was available, reading cookies required the `cookie-parser` middleware (Express) or the `@fastify/cookie` plugin (Fastify). Applications that use them keep working, and the built-in decorators cooperate with them:

* `@Cookies()` returns `req.cookies` as is whenever a middleware or plugin has populated it, and only parses the `Cookie` header itself otherwise. The behavior of that package therefore carries over. For example, `cookie-parser` moves signed cookies from `req.cookies` to `req.signedCookies` when it is given a secret, and turns `j:`-prefixed JSON cookies into objects.
* When the `cookies.secret` application option is set, `@SignedCookies()` always verifies the raw `Cookie` header against the Nest secrets, and ignores `req.signedCookies`. Configure the same secret (or secrets) as your middleware, so that the cookies it signed keep verifying.
* Without the `cookies.secret` option, `@SignedCookies()` falls back to the `req.signedCookies` object populated by `cookie-parser` (when it is given a secret), and treats the cookies it marked as invalid as missing. `@fastify/cookie` does not populate `req.signedCookies`, so on Fastify, `@SignedCookies()` requires the `cookies.secret` option.

Nest never assigns `req.cookies` itself. If you remove `cookie-parser` or `@fastify/cookie`, replace any code that reads `request.cookies` (or calls `reply.setCookie()`) with the built-in decorators and adapter methods. Likewise, if your application defines its own `@Cookies()` decorator with `createParamDecorator()`, you can replace it with the built-in one. When you replace `res.cookie()` calls with `setCookie()`, remember to convert `maxAge` from milliseconds to seconds.

##### Express (cookie-parser)[#](/http/cookies#express-cookie-parser)

First, install the [cookie-parser](https://github.com/expressjs/cookie-parser) package (and its types, for TypeScript users):

```shell

$ npm i cookie-parser
$ npm i -D @types/cookie-parser
```

Once the installation is complete, apply the `cookie-parser` middleware globally (for example, in your `main.ts` file):

```typescript

import cookieParser from 'cookie-parser';
// somewhere in your initialization file
app.use(cookieParser('my-secret'));
```

The first argument is an optional secret (or an array of secrets) used to verify signed cookies. The middleware parses the `Cookie` header and exposes the cookies as `req.cookies` and, if a secret was provided, the verified signed cookies as `req.signedCookies` (a signed cookie that fails verification has the value `false`). See the [cookie-parser repository](https://github.com/expressjs/cookie-parser) for the other options.

With this in place, you can read cookies with the `@Cookies()` and `@SignedCookies()` decorators, or from the request object:

```typescript

@Get()
findAll(@Req() request: Request) {
  console.log(request.cookies); // or "request.cookies['cookieKey']"
  // or console.log(request.signedCookies);
}
```

To attach a cookie to an outgoing response, use the adapter's `setCookie()` method or the `Response#cookie()` method:

```typescript

@Get()
findAll(@Res({ passthrough: true }) response: Response) {
  response.cookie('key', 'value');
}
```

> **Hint** Import the `@Req()` and `@Res()` decorators from the `@nestjs/common` package, and `Request` and `Response` from the `express` package.

##### Fastify (@fastify/cookie)[#](/http/cookies#fastify-fastifycookie)

First, install the required package:

```shell

$ npm i @fastify/cookie
```

Once the installation is complete, register the `@fastify/cookie` plugin:

```typescript

import fastifyCookie from '@fastify/cookie';

// somewhere in your initialization file
const app = await NestFactory.create<NestFastifyApplication>(AppModule, new FastifyAdapter());
await app.register(fastifyCookie, {
  secret: 'my-secret', // for cookies signature
});
```

With this in place, you can read cookies with the `@Cookies()` decorator, or from the request object:

```typescript

@Get()
findAll(@Req() request: FastifyRequest) {
  console.log(request.cookies); // or "request.cookies['cookieKey']"
}
```

To attach a cookie to an outgoing response, use the adapter's `setCookie()` method or the `FastifyReply#setCookie()` method (see the [@fastify/cookie documentation on sending cookies](https://github.com/fastify/fastify-cookie#sending)):

```typescript

@Get()
findAll(@Res({ passthrough: true }) response: FastifyReply) {
  response.setCookie('key', 'value');
}
```

> **Hint** Import the `@Req()` and `@Res()` decorators from the `@nestjs/common` package, and `FastifyRequest` and `FastifyReply` from the `fastify` package.

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/http/cookies.md)

----
url: https://docs.nestjs.com/v11/recipes/nest-commander
----

* [Nest Commander](https://docs.nestjs.com/v11/recipes/nest-commander#nest-commander)
* [Installation](https://docs.nestjs.com/v11/recipes/nest-commander#installation)
* [A Command file](https://docs.nestjs.com/v11/recipes/nest-commander#a-command-file)
* [Running the Command](https://docs.nestjs.com/v11/recipes/nest-commander#running-the-command)
* [Testing](https://docs.nestjs.com/v11/recipes/nest-commander#testing)
* [Putting it all together](https://docs.nestjs.com/v11/recipes/nest-commander#putting-it-all-together)
* [More Information](https://docs.nestjs.com/v11/recipes/nest-commander#more-information)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/recipes/nest-commander.md "Suggest Edits")

### Nest Commander

Expanding on the [standalone application](/v11/standalone-applications) docs there's also the [nest-commander](https://jmcdo29.github.io/nest-commander) package for writing command line applications in a structure similar to your typical Nest application.

> **info**`nest-commander` is a third party package and is not managed by the entirety of the NestJS core team. Please, report any issues found with the library in the [appropriate repository](https://github.com/jmcdo29/nest-commander/issues/new/choose)

#### Installation[#](/recipes/nest-commander#installation)

Just like any other package, you've got to install it before you can use it.

```bash

$ npm i nest-commander
```

#### A Command file[#](/recipes/nest-commander#a-command-file)

`nest-commander` makes it easy to write new command-line applications with [decorators](https://www.typescriptlang.org/docs/handbook/decorators.html) via the `@Command()` decorator for classes and the `@Option()` decorator for methods of that class. Every command file should implement the `CommandRunner` abstract class and should be decorated with a `@Command()` decorator.

Every command is seen as an `@Injectable()` by Nest, so your normal Dependency Injection still works as you would expect it to. The only thing to take note of is the abstract class `CommandRunner`, which should be implemented by each command. The `CommandRunner` abstract class ensures that all commands have a `run` method that returns a `Promise<void>` and takes in the parameters `string[], Record<string, any>`. The `run` command is where you can kick all of your logic off from, it will take in whatever parameters did not match option flags and pass them in as an array, just in case you are really meaning to work with multiple parameters. As for the options, the `Record<string, any>`, the names of these properties match the `name` property given to the `@Option()` decorators, while their value matches the return of the option handler. If you'd like better type safety, you are welcome to create an interface for your options as well.

#### Running the Command[#](/recipes/nest-commander#running-the-command)

Similar to how in a NestJS application we can use the `NestFactory` to create a server for us, and run it using `listen`, the `nest-commander` package exposes a simple to use API to run your server. Import the `CommandFactory` and use the `static` method `run` and pass in the root module of your application. This would probably look like below

```ts

import { CommandFactory } from 'nest-commander';
import { AppModule } from './app.module';

async function bootstrap() {
  await CommandFactory.run(AppModule);
}

bootstrap();
```

By default, Nest's logger is disabled when using the `CommandFactory`. It's possible to provide it though, as the second argument to the `run` function. You can either provide a custom NestJS logger, or an array of log levels you want to keep - it might be useful to at least provide `['error']` here, if you only want to print out Nest's error logs.

```ts

import { CommandFactory } from 'nest-commander';
import { AppModule } from './app.module';
import { LogService } from './log.service';

async function bootstrap() {
  await CommandFactory.run(AppModule, new LogService());

  // or, if you only want to print Nest's warnings and errors
  await CommandFactory.run(AppModule, ['warn', 'error']);
}

bootstrap();
```

And that's it. Under the hood, `CommandFactory` will worry about calling `NestFactory` for you and calling `app.close()` when necessary, so you shouldn't need to worry about memory leaks there. If you need to add in some error handling, there's always `try/catch` wrapping the `run` command, or you can chain on some `.catch()` method to the `bootstrap()` call.

#### Testing[#](/recipes/nest-commander#testing)

So what's the use of writing a super awesome command line script if you can't test it super easily, right? Fortunately, `nest-commander` has some utilities you can make use of that fits in perfectly with the NestJS ecosystem, it'll feel right at home to any Nestlings out there. Instead of using the `CommandFactory` for building the command in test mode, you can use `CommandTestFactory` and pass in your metadata, very similarly to how `Test.createTestingModule` from `@nestjs/testing` works. In fact, it uses this package under the hood. You're also still able to chain on the `overrideProvider` methods before calling `compile()` so you can swap out DI pieces right in the test.

#### Putting it all together[#](/recipes/nest-commander#putting-it-all-together)

The following class would equate to having a CLI command that can take in the subcommand `basic` or be called directly, with `-n`, `-s`, and `-b` (along with their long flags) all being supported and with custom parsers for each option. The `--help` flag is also supported, as is customary with commander.

```ts

import { Command, CommandRunner, Option } from 'nest-commander';
import { LogService } from './log.service';

interface BasicCommandOptions {
  string?: string;
  boolean?: boolean;
  number?: number;
}

@Command({ name: 'basic', description: 'A parameter parse' })
export class BasicCommand extends CommandRunner {
  constructor(private readonly logService: LogService) {
    super()
  }

  async run(
    passedParam: string[],
    options?: BasicCommandOptions,
  ): Promise<void> {
    if (options?.boolean !== undefined && options?.boolean !== null) {
      this.runWithBoolean(passedParam, options.boolean);
    } else if (options?.number) {
      this.runWithNumber(passedParam, options.number);
    } else if (options?.string) {
      this.runWithString(passedParam, options.string);
    } else {
      this.runWithNone(passedParam);
    }
  }

  @Option({
    flags: '-n, --number [number]',
    description: 'A basic number parser',
  })
  parseNumber(val: string): number {
    return Number(val);
  }

  @Option({
    flags: '-s, --string [string]',
    description: 'A string return',
  })
  parseString(val: string): string {
    return val;
  }

  @Option({
    flags: '-b, --boolean [boolean]',
    description: 'A boolean parser',
  })
  parseBoolean(val: string): boolean {
    return JSON.parse(val);
  }

  runWithString(param: string[], option: string): void {
    this.logService.log({ param, string: option });
  }

  runWithNumber(param: string[], option: number): void {
    this.logService.log({ param, number: option });
  }

  runWithBoolean(param: string[], option: boolean): void {
    this.logService.log({ param, boolean: option });
  }

  runWithNone(param: string[]): void {
    this.logService.log({ param });
  }
}
```

Make sure the command class is added to a module

```ts

@Module({
  providers: [LogService, BasicCommand],
})
export class AppModule {}
```

And now to be able to run the CLI in your main.ts you can do the following

```ts

async function bootstrap() {
  await CommandFactory.run(AppModule);
}

bootstrap();
```

And just like that, you've got a command line application.

#### More Information[#](/recipes/nest-commander#more-information)

Visit the [nest-commander docs site](https://jmcdo29.github.io/nest-commander) for more information, examples, and API documentation.

----
url: https://docs.nestjs.com/v10/techniques/mvc
----

* [Model-View-Controller](https://docs.nestjs.com/v10/techniques/mvc#model-view-controller)
* [Template rendering](https://docs.nestjs.com/v10/techniques/mvc#template-rendering)
* [Dynamic template rendering](https://docs.nestjs.com/v10/techniques/mvc#dynamic-template-rendering)
* [Example](https://docs.nestjs.com/v10/techniques/mvc#example)
* [Fastify](https://docs.nestjs.com/v10/techniques/mvc#fastify)
* [Example](https://docs.nestjs.com/v10/techniques/mvc#example-1)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/techniques/mvc.md "Suggest Edits")

### Model-View-Controller

Nest, by default, makes use of the [Express](https://github.com/expressjs/express) library under the hood. Hence, every technique for using the MVC (Model-View-Controller) pattern in Express applies to Nest as well.

First, let's scaffold a simple Nest application using the [CLI](https://github.com/nestjs/nest-cli) tool:

```bash

$ npm i -g @nestjs/cli
$ nest new project
```

In order to create an MVC app, we also need a [template engine](https://expressjs.com/en/guide/using-template-engines.html) to render our HTML views:

```bash

$ npm install --save hbs
```

We've used the `hbs` ([Handlebars](https://github.com/pillarjs/hbs#readme)) engine, though you can use whatever fits your requirements. Once the installation process is complete, we need to configure the express instance using the following code:

main.ts

JS TS

```typescript

import { NestFactory } from '@nestjs/core';
import { NestExpressApplication } from '@nestjs/platform-express';
import { join } from 'path';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create<NestExpressApplication>(
    AppModule,
  );

  app.useStaticAssets(join(__dirname, '..', 'public'));
  app.setBaseViewsDir(join(__dirname, '..', 'views'));
  app.setViewEngine('hbs');

  await app.listen(process.env.PORT ?? 3000);
}
bootstrap();
```

```typescript

import { NestFactory } from '@nestjs/core';
import { join } from 'path';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(
    AppModule,
  );

  app.useStaticAssets(join(__dirname, '..', 'public'));
  app.setBaseViewsDir(join(__dirname, '..', 'views'));
  app.setViewEngine('hbs');

  await app.listen(process.env.PORT ?? 3000);
}
bootstrap();
```

We told [Express](https://github.com/expressjs/express) that the `public` directory will be used for storing static assets, `views` will contain templates, and the `hbs` template engine should be used to render HTML output.

#### Template rendering[#](/techniques/mvc#template-rendering)

Now, let's create a `views` directory and `index.hbs` template inside it. In the template, we'll print a `message` passed from the controller:

```html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>App</title>
  </head>
  <body>
    {{ message }}
  </body>
</html>
```

Next, open the `app.controller` file and replace the `root()` method with the following code:

app.controller.ts

JS TS

```typescript

import { Get, Controller, Render } from '@nestjs/common';

@Controller()
export class AppController {
  @Get()
  @Render('index')
  root() {
    return { message: 'Hello world!' };
  }
}
```

In this code, we are specifying the template to use in the `@Render()` decorator, and the return value of the route handler method is passed to the template for rendering. Notice that the return value is an object with a property `message`, matching the `message` placeholder we created in the template.

While the application is running, open your browser and navigate to `http://localhost:3000`. You should see the `Hello world!` message.

#### Dynamic template rendering[#](/techniques/mvc#dynamic-template-rendering)

If the application logic must dynamically decide which template to render, then we should use the `@Res()` decorator, and supply the view name in our route handler, rather than in the `@Render()` decorator:

> **Hint** When Nest detects the `@Res()` decorator, it injects the library-specific `response` object. We can use this object to dynamically render the template. Learn more about the `response` object API [here](https://expressjs.com/en/api.html).

app.controller.ts

JS TS

```typescript

import { Get, Controller, Res, Render } from '@nestjs/common';
import { Response } from 'express';
import { AppService } from './app.service';

@Controller()
export class AppController {
  constructor(private appService: AppService) {}

  @Get()
  root(@Res() res: Response) {
    return res.render(
      this.appService.getViewName(),
      { message: 'Hello world!' },
    );
  }
}
```

#### Example[#](/techniques/mvc#example)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/15-mvc).

#### Fastify[#](/techniques/mvc#fastify)

As mentioned in this [chapter](/v10/techniques/performance), we are able to use any compatible HTTP provider together with Nest. One such library is [Fastify](https://github.com/fastify/fastify). In order to create an MVC application with Fastify, we have to install the following packages:

```bash

$ npm i --save @fastify/static @fastify/view handlebars
```

The next steps cover almost the same process used with Express, with minor differences specific to the platform. Once the installation process is complete, open the `main.ts` file and update its contents:

main.ts

JS TS

```typescript

import { NestFactory } from '@nestjs/core';
import { NestFastifyApplication, FastifyAdapter } from '@nestjs/platform-fastify';
import { AppModule } from './app.module';
import { join } from 'path';

async function bootstrap() {
  const app = await NestFactory.create<NestFastifyApplication>(
    AppModule,
    new FastifyAdapter(),
  );
  app.useStaticAssets({
    root: join(__dirname, '..', 'public'),
    prefix: '/public/',
  });
  app.setViewEngine({
    engine: {
      handlebars: require('handlebars'),
    },
    templates: join(__dirname, '..', 'views'),
  });
  await app.listen(process.env.PORT ?? 3000);
}
bootstrap();
```

```typescript

import { NestFactory } from '@nestjs/core';
import { FastifyAdapter } from '@nestjs/platform-fastify';
import { AppModule } from './app.module';
import { join } from 'path';

async function bootstrap() {
  const app = await NestFactory.create(AppModule, new FastifyAdapter());
  app.useStaticAssets({
    root: join(__dirname, '..', 'public'),
    prefix: '/public/',
  });
  app.setViewEngine({
    engine: {
      handlebars: require('handlebars'),
    },
    templates: join(__dirname, '..', 'views'),
  });
  await app.listen(process.env.PORT ?? 3000);
}
bootstrap();
```

The Fastify API has a few differences, but the end result of these method calls is the same. One notable difference is that when using Fastify, the template name you pass into the `@Render()` decorator must include the file extension.

Here’s how you can set it up:

app.controller.ts

JS TS

```typescript

import { Get, Controller, Render } from '@nestjs/common';

@Controller()
export class AppController {
  @Get()
  @Render('index.hbs')
  root() {
    return { message: 'Hello world!' };
  }
}
```

Alternatively, you can use the `@Res()` decorator to directly inject the response and specify the view you want to render, as shown below:

```typescript

import { Res } from '@nestjs/common';
import { FastifyReply } from 'fastify';

@Get()
root(@Res() res: FastifyReply) {
  return res.view('index.hbs', { title: 'Hello world!' });
}
```

While the application is running, open your browser and navigate to `http://localhost:3000`. You should see the `Hello world!` message.

#### Example[#](/techniques/mvc#example-1)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/17-mvc-fastify).

----
url: https://docs.nestjs.com/v10/openapi/migration-guide
----

* [Migration guide](https://docs.nestjs.com/v10/openapi/migration-guide#migration-guide)
* [Breaking changes](https://docs.nestjs.com/v10/openapi/migration-guide#breaking-changes)
* [New methods](https://docs.nestjs.com/v10/openapi/migration-guide#new-methods)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/openapi/migration-guide.md "Suggest Edits")

### Migration guide

If you're currently using `@nestjs/swagger@3.*`, note the following breaking/API changes in version 4.0.

#### Breaking changes[#](/openapi/migration-guide#breaking-changes)

* `@ApiOperation({ title: 'test' })` is now `@ApiOperation({ summary: 'test' })`

* `setSchemes` has been removed (use the `addServer` instead, e.g., `addServer('http://')`)

#### New methods[#](/openapi/migration-guide#new-methods)

The following methods have been added:

* `addServer`
* `addApiKey`
* `addBasicAuth`
* `addSecurity`
* `addSecurityRequirements`

## Explore your graph with NestJS Devtools

* **Graph visualizer
* **Routes navigator
* **Interactive playground
* **CI/CD integration

----
url: https://docs.nestjs.com/v8/openapi/decorators
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Decorators](https://docs.nestjs.com/v8/openapi/decorators#decorators)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/openapi/decorators.md "Suggest Edits")

### Decorators

All of the available OpenAPI decorators have an `Api` prefix to distinguish them from the core decorators. Below is a full list of the exported decorators along with a designation of the level at which the decorator may be applied.

| `@ApiBasicAuth()`         | Method / Controller |
| ------------------------- | ------------------- |
| `@ApiBearerAuth()`        | Method / Controller |
| `@ApiBody()`              | Method              |
| `@ApiConsumes()`          | Method / Controller |
| `@ApiCookieAuth()`        | Method / Controller |
| `@ApiExcludeController()` | Controller          |
| `@ApiExcludeEndpoint()`   | Method              |
| `@ApiExtension()`         | Method              |
| `@ApiExtraModels()`       | Method / Controller |
| `@ApiHeader()`            | Method / Controller |
| `@ApiHideProperty()`      | Model               |
| `@ApiOAuth2()`            | Method / Controller |
| `@ApiOperation()`         | Method              |
| `@ApiParam()`             | Method              |
| `@ApiProduces()`          | Method / Controller |
| `@ApiProperty()`          | Model               |
| `@ApiPropertyOptional()`  | Model               |
| `@ApiQuery()`             | Method              |
| `@ApiResponse()`          | Method / Controller |
| `@ApiSecurity()`          | Method / Controller |
| `@ApiTags()`              | Method / Controller |

----
url: https://docs.nestjs.com/v8/techniques/file-upload
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [File upload](https://docs.nestjs.com/v8/techniques/file-upload#file-upload)
* [Basic example](https://docs.nestjs.com/v8/techniques/file-upload#basic-example)
* [Array of files](https://docs.nestjs.com/v8/techniques/file-upload#array-of-files)
* [Multiple files](https://docs.nestjs.com/v8/techniques/file-upload#multiple-files)
* [Any files](https://docs.nestjs.com/v8/techniques/file-upload#any-files)
* [Default options](https://docs.nestjs.com/v8/techniques/file-upload#default-options)
* [Async configuration](https://docs.nestjs.com/v8/techniques/file-upload#async-configuration)
* [Example](https://docs.nestjs.com/v8/techniques/file-upload#example)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/techniques/file-upload.md "Suggest Edits")

### File upload

To handle file uploading, Nest provides a built-in module based on the [multer](https://github.com/expressjs/multer) middleware package for Express. Multer handles data posted in the `multipart/form-data` format, which is primarily used for uploading files via an HTTP `POST` request. This module is fully configurable and you can adjust its behavior to your application requirements.

> **Warning** Multer cannot process data which is not in the supported multipart format (`multipart/form-data`). Also, note that this package is not compatible with the `FastifyAdapter`.

For better type safety, let's install Multer typings package:

```shell

$ npm i -D @types/multer
```

With this package installed, we can now use the `Express.Multer.File` type (you can import this type as follows: `import { Express } from 'express'`).

#### Basic example[#](/techniques/file-upload#basic-example)

To upload a single file, simply tie the `FileInterceptor()` interceptor to the route handler and extract `file` from the `request` using the `@UploadedFile()` decorator.

JS TS

```typescript

@Post('upload')
@UseInterceptors(FileInterceptor('file'))
uploadFile(@UploadedFile() file: Express.Multer.File) {
  console.log(file);
}
```

```typescript

@Post('upload')
@UseInterceptors(FileInterceptor('file'))
@Bind(UploadedFile())
uploadFile(file) {
  console.log(file);
}
```

> **Hint** The `FileInterceptor()` decorator is exported from the `@nestjs/platform-express` package. The `@UploadedFile()` decorator is exported from `@nestjs/common`.

The `FileInterceptor()` decorator takes two arguments:

* `fieldName`: string that supplies the name of the field from the HTML form that holds a file
* `options`: optional object of type `MulterOptions`. This is the same object used by the multer constructor (more details [here](https://github.com/expressjs/multer#multeropts)).

> **Warning**`FileInterceptor()` may not be compatible with third party cloud providers like Google Firebase or others.

```typescript

@Post('upload')
@UseInterceptors(FilesInterceptor('files'))
uploadFile(@UploadedFiles() files: Array<Express.Multer.File>) {
  console.log(files);
}
```

```typescript

@Post('upload')
@UseInterceptors(FilesInterceptor('files'))
@Bind(UploadedFiles())
uploadFile(files) {
  console.log(files);
}
```

> **Hint** The `FilesInterceptor()` decorator is exported from the `@nestjs/platform-express` package. The `@UploadedFiles()` decorator is exported from `@nestjs/common`.

#### Multiple files[#](/techniques/file-upload#multiple-files)

To upload multiple fields (all with different field name keys), use the `FileFieldsInterceptor()` decorator. This decorator takes two arguments:

* `uploadedFields`: an array of objects, where each object specifies a required `name` property with a string value specifying a field name, as described above, and an optional `maxCount` property, as described above
* `options`: optional `MulterOptions` object, as described above

When using `FileFieldsInterceptor()`, extract files from the `request` with the `@UploadedFiles()` decorator.

JS TS

```typescript

@Post('upload')
@UseInterceptors(FileFieldsInterceptor([
  { name: 'avatar', maxCount: 1 },
  { name: 'background', maxCount: 1 },
]))
uploadFile(@UploadedFiles() files: { avatar?: Express.Multer.File[], background?: Express.Multer.File[] }) {
  console.log(files);
}
```

```typescript

@Post('upload')
@Bind(UploadedFiles())
@UseInterceptors(FileFieldsInterceptor([
  { name: 'avatar', maxCount: 1 },
  { name: 'background', maxCount: 1 },
]))
uploadFile(files) {
  console.log(files);
}
```

#### Any files[#](/techniques/file-upload#any-files)

To upload all fields with arbitrary field name keys, use the `AnyFilesInterceptor()` decorator. This decorator can accept an optional `options` object as described above.

When using `AnyFilesInterceptor()`, extract files from the `request` with the `@UploadedFiles()` decorator.

JS TS

```typescript

@Post('upload')
@UseInterceptors(AnyFilesInterceptor())
uploadFile(@UploadedFiles() files: Array<Express.Multer.File>) {
  console.log(files);
}
```

```typescript

@Post('upload')
@Bind(UploadedFiles())
@UseInterceptors(AnyFilesInterceptor())
uploadFile(files) {
  console.log(files);
}
```

#### Default options[#](/techniques/file-upload#default-options)

You can specify multer options in the file interceptors as described above. To set default options, you can call the static `register()` method when you import the `MulterModule`, passing in supported options. You can use all options listed [here](https://github.com/expressjs/multer#multeropts).

```typescript

MulterModule.register({
  dest: './upload',
});
```

> **Hint** The `MulterModule` class is exported from the `@nestjs/platform-express` package.

#### Async configuration[#](/techniques/file-upload#async-configuration)

When you need to set `MulterModule` options asynchronously instead of statically, use the `registerAsync()` method. As with most dynamic modules, Nest provides several techniques to deal with async configuration.

One technique is to use a factory function:

```typescript

MulterModule.registerAsync({
  useFactory: () => ({
    dest: './upload',
  }),
});
```

Like other [factory providers](https://docs.nestjs.com/fundamentals/custom-providers#factory-providers-usefactory), our factory function can be `async` and can inject dependencies through `inject`.

```typescript

MulterModule.registerAsync({
  imports: [ConfigModule],
  useFactory: async (configService: ConfigService) => ({
    dest: configService.getString('MULTER_DEST'),
  }),
  inject: [ConfigService],
});
```

Alternatively, you can configure the `MulterModule` using a class instead of a factory, as shown below:

```typescript

MulterModule.registerAsync({
  useClass: MulterConfigService,
});
```

The construction above instantiates `MulterConfigService` inside `MulterModule`, using it to create the required options object. Note that in this example, the `MulterConfigService` has to implement the `MulterOptionsFactory` interface, as shown below. The `MulterModule` will call the `createMulterOptions()` method on the instantiated object of the supplied class.

```typescript

@Injectable()
class MulterConfigService implements MulterOptionsFactory {
  createMulterOptions(): MulterModuleOptions {
    return {
      dest: './upload',
    };
  }
}
```

If you want to reuse an existing options provider instead of creating a private copy inside the `MulterModule`, use the `useExisting` syntax.

```typescript

MulterModule.registerAsync({
  imports: [ConfigModule],
  useExisting: ConfigService,
});
```

#### Example[#](/techniques/file-upload#example)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/29-file-upload).

----
url: https://docs.nestjs.com/devtools/overview
----

[Skip to content](#content)

On this page

* [Overview](https://docs.nestjs.com/devtools/overview#overview)
* [Debugging "Cannot resolve dependency" errors](https://docs.nestjs.com/devtools/overview#debugging-cannot-resolve-dependency-errors)
* [Routes explorer](https://docs.nestjs.com/devtools/overview#routes-explorer)
* [Playground](https://docs.nestjs.com/devtools/overview#playground)
* [Bootstrap performance analyzer](https://docs.nestjs.com/devtools/overview#bootstrap-performance-analyzer)
* [Audit](https://docs.nestjs.com/devtools/overview#audit)
* [Preview static files](https://docs.nestjs.com/devtools/overview#preview-static-files)

### Overview

> **Hint** This chapter covers the Nest Devtools integration with the Nest framework. If you are looking for the Devtools application, visit the [Devtools](https://devtools.nestjs.com) website.

Nest Devtools gives you an interactive, always up-to-date view of your application's internals: modules, providers, controllers, and the routes and events that tie them together. Instead of piecing that picture together from imports and constructor signatures, you get a live graph you can search, filter, and click through. This chapter walks you through connecting your local application to Devtools for the first time.

Getting started takes less than five minutes. Open your `main.ts` file and set the `snapshot` attribute to `true` in the application options object:

```typescript

async function bootstrap() {
  const app = await NestFactory.create(AppModule, {
    snapshot: true,
  });
  await app.listen(3000);
}
```

This tells Nest to collect the metadata Devtools needs to reconstruct and visualize your application's dependency graph.

Next, install the Devtools integration package:

```bash

$ npm i @nestjs/devtools-integration
```

With the package installed, open `app.module.ts` and import `DevtoolsModule`:

```typescript

@Module({
  imports: [
    DevtoolsModule.register({
      http: process.env.NODE_ENV !== 'production',
    }),
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}
```

> **Note** We check `NODE_ENV` here because `DevtoolsModule` should never run in production.

The `http` flag controls whether `DevtoolsModule` starts its introspection server at all. With the flag disabled, the module doesn't expose anything, which is the safety net you want if this configuration accidentally makes it past a review. The runtime overhead is negligible: with `snapshot` enabled, Nest collects the graph metadata once, while the application bootstraps, so your application's regular request handling is unaffected.

Once `DevtoolsModule` is imported and your application is running (`npm run start:dev`), open [Devtools](https://devtools.nestjs.com) to see your introspected graph.

> **Hint** Every module connects to `InternalCoreModule`, a global module that Nest always imports into the root module. Because it's registered globally, Nest draws an edge between it and every other module in your application. To declutter the view, select the **Hide global modules** checkbox in the sidebar.

Under the hood, `DevtoolsModule` starts a lightweight HTTP server (on port 8000 by default) that the dashboard uses to introspect your application in real time. No extra configuration is required. If port 8000 is taken, pass a different one with the `port` option of `DevtoolsModule.register()`.

To confirm everything is wired up correctly, switch the graph view to "Classes". You should see something like this:

Click any node to open a popup with a **"Focus"** button that isolates it on the graph, or use the search bar in the sidebar to jump to a specific node.

> **Hint** Clicking **Inspect** takes you to the `/debug` page with that node preselected, which is useful for digging into a specific provider or controller.

> **Hint** Need a snapshot for docs or a pull request? Click **Export as PNG** in the bottom-right corner of the graph.

The sidebar controls let you narrow down edge proximity, which helps you zoom in on a specific branch of your application:

This is a great way to onboard **new team members** by showing them exactly how the application fits together. It's equally useful when you extract a module (say, `TasksModule`) along with all of its dependencies before splitting a large application into smaller services.

Everything in Graph Explorer stays in sync with your running application: refresh, and any change you've made to your modules or providers is reflected instantly. There's no build step or separate documentation to keep up to date; the graph **is** the documentation.

See **Graph Explorer** in action:

#### Debugging "Cannot resolve dependency" errors[#](/devtools/overview#debugging-cannot-resolve-dependency-errors)

> **Note** Available for `@nestjs/core` 9.3.10 and above.

If you've worked with Nest for a while, you've probably run into the **"Cannot resolve dependency"** error. It's often the first error a new team member sees, and on a large application it can be hard to track down: the stack trace tells you what's missing, but not why, or where in a deeply nested provider chain the wiring broke. Devtools turns this from a guessing game into a quick, visual diagnosis.

Start by updating the `bootstrap()` call in `main.ts`:

```typescript

bootstrap().catch((err) => {
  writeFileSync('graph.json', PartialGraphHost.toString() ?? '');
  process.exit(1);
});
```

> **Hint**`PartialGraphHost` is exported from `@nestjs/core`, and `writeFileSync` from `node:fs`.

You also need to set `abortOnError` to `false`:

```typescript

const app = await NestFactory.create(AppModule, {
  snapshot: true,
  abortOnError: false, // <--- THIS
});
```

From now on, whenever your application fails to bootstrap with a **"Cannot resolve dependency"** error, it writes a `graph.json` file (a partial graph) to your project root. Drag and drop the file into Devtools (switch from "Interactive" to "Preview" mode first) to see exactly where things went wrong:

Once uploaded, you'll see the graph along with a dialog summarizing what happened:

The highlighted `TasksModule` is the one to look into, and the dialog gives you pointers on how to fix it.

Switching to the "Classes" view tells the full story:

The graph makes it clear: `DiagnosticsService`, which `TasksService` depends on, isn't available in the `TasksModule` context. The fix is to import `DiagnosticsModule` into `TasksModule`.

What would otherwise be a slow process of manually tracing imports across several files, hoping you didn't miss one, turns into a couple of clicks. It's a small workflow change, but it adds up quickly on a codebase with dozens of modules.

#### Routes explorer[#](/devtools/overview#routes-explorer)

The **Routes explorer** page shows every entrypoint your application registers:

> **Hint** This page isn't limited to HTTP routes. It also covers WebSockets, gRPC, GraphQL resolvers, and more.

Entrypoints are grouped by their host controllers, and you can use the search bar to jump to the one you're after.

Click any entrypoint to reveal **a flow graph** of its full execution path: every guard, interceptor, and pipe bound to that route. It's the fastest way to understand how a request travels through your application, or to find out why a specific guard, interceptor, or pipe isn't running when you expect it to.

This view pays off most on applications that have grown organically, where the same guard might be applied at the controller level in one place and per route in another. Instead of reading through decorators scattered across the codebase, you get the actual, resolved execution order for that route.

#### Playground[#](/devtools/overview#playground)

To run code against your application without redeploying, open the **Playground** page:

The Playground lets you test and debug endpoints **in real time**, so you can track down issues without reaching for a separate HTTP client. You can bypass the authentication layer entirely, skipping the extra login step or a dedicated test account. For event-driven applications, you can trigger events directly from the Playground to see exactly how your application responds.

Anything your code logs is streamed to the Playground's console, so you always know what's happening under the hood.

Run code **on the fly** and see the results instantly, with no rebuilds and no server restarts.

> **Hint** Playground requests are authenticated with a sandbox session token. `DevtoolsModule` generates a new token each time the application starts and prints it to the console (`Sandbox session token: ...`). Provide this token to Devtools to run code in the Playground.

> **Hint** Use `console.table()` (or `table()`) to pretty-print an array of objects.

See the **Playground** in action:

#### Bootstrap performance analyzer[#](/devtools/overview#bootstrap-performance-analyzer)

To find out what's slowing down your application's startup, open the **Bootstrap performance** page. It lists every class node (controllers, providers, enhancers, and more) along with its instantiation time:

It's the quickest way to spot the slowest parts of your bootstrap process. This matters most when startup time is on the critical path, such as in serverless environments where every millisecond counts.

Slow bootstraps usually have a few common causes: heavy synchronous work inside a constructor, a provider awaiting a slow external call in `onModuleInit`, or a module instantiating far more dependencies than it needs. Sorted by instantiation time, this page makes those outliers obvious at a glance, without sprinkling `console.time()` calls throughout your codebase.

#### Audit[#](/devtools/overview#audit)

Devtools automatically analyzes your serialized graph and surfaces errors, warnings, and hints that deserve your attention. You'll find them on the **Audit** page:

> **Hint** The screenshot above shows only a sample of the available audit rules.

Think of it as a linter for your application's architecture: a fast way to catch issues before they catch you. Some of the built-in rules flag problems you'd otherwise discover the hard way: a controller carrying far more routes than its neighbors, a module pulling in an unusually large number of dependencies, a provider named `SomethingGuard` that was never registered as a guard, or a request-scoped provider that's a strong candidate for [durable providers](/fundamentals/injection-scopes#durable-providers). Your test suite won't catch any of these, but they are exactly the kind of thing that slows a codebase down over time.

#### Preview static files[#](/devtools/overview#preview-static-files)

To save a serialized graph to a file, use the following code:

```typescript

await app.listen(3000); // OR await app.init()
writeFileSync('./graph.json', app.get(SerializedGraph).toString());
```

> **Hint**`SerializedGraph` is exported from `@nestjs/core`.

Then drag and drop (or upload) the file:

This is useful when you want to share a graph with a coworker, attach it to a bug report, or analyze it offline, without running your application.

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/devtools/overview.md)

----
url: https://docs.nestjs.com/v10/techniques/serialization
----

* [Serialization](https://docs.nestjs.com/v10/techniques/serialization#serialization)
* [Overview](https://docs.nestjs.com/v10/techniques/serialization#overview)
* [Exclude properties](https://docs.nestjs.com/v10/techniques/serialization#exclude-properties)
* [Expose properties](https://docs.nestjs.com/v10/techniques/serialization#expose-properties)
* [Transform](https://docs.nestjs.com/v10/techniques/serialization#transform)
* [Pass options](https://docs.nestjs.com/v10/techniques/serialization#pass-options)
* [Transform plain objects](https://docs.nestjs.com/v10/techniques/serialization#transform-plain-objects)
* [Example](https://docs.nestjs.com/v10/techniques/serialization#example)
* [WebSockets and Microservices](https://docs.nestjs.com/v10/techniques/serialization#websockets-and-microservices)
* [Learn more](https://docs.nestjs.com/v10/techniques/serialization#learn-more)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/techniques/serialization.md "Suggest Edits")

### Serialization

Serialization is a process that happens before objects are returned in a network response. This is an appropriate place to provide rules for transforming and sanitizing the data to be returned to the client. For example, sensitive data like passwords should always be excluded from the response. Or, certain properties might require additional transformation, such as sending only a subset of properties of an entity. Performing these transformations manually can be tedious and error prone, and can leave you uncertain that all cases have been covered.

#### Overview[#](/techniques/serialization#overview)

Nest provides a built-in capability to help ensure that these operations can be performed in a straightforward way. The `ClassSerializerInterceptor` interceptor uses the powerful [class-transformer](https://github.com/typestack/class-transformer) package to provide a declarative and extensible way of transforming objects. The basic operation it performs is to take the value returned by a method handler and apply the `instanceToPlain()` function from [class-transformer](https://github.com/typestack/class-transformer). In doing so, it can apply rules expressed by `class-transformer` decorators on an entity/DTO class, as described below.

> **Hint** The serialization does not apply to [StreamableFile](https://docs.nestjs.com/techniques/streaming-files#streamable-file-class) responses.

#### Exclude properties[#](/techniques/serialization#exclude-properties)

Let's assume that we want to automatically exclude a `password` property from a user entity. We annotate the entity as follows:

```typescript

import { Exclude } from 'class-transformer';

export class UserEntity {
  id: number;
  firstName: string;
  lastName: string;

  @Exclude()
  password: string;

  constructor(partial: Partial<UserEntity>) {
    Object.assign(this, partial);
  }
}
```

Now consider a controller with a method handler that returns an instance of this class.

```typescript

@UseInterceptors(ClassSerializerInterceptor)
@Get()
findOne(): UserEntity {
  return new UserEntity({
    id: 1,
    firstName: 'John',
    lastName: 'Doe',
    password: 'password',
  });
}
```

> **Warning** Note that we must return an instance of the class. If you return a plain JavaScript object, for example, `{ user: new UserEntity() }`, the object won't be properly serialized.

> **Hint** The `ClassSerializerInterceptor` is imported from `@nestjs/common`.

When this endpoint is requested, the client receives the following response:

```json

{
  "id": 1,
  "firstName": "John",
  "lastName": "Doe"
}
```

Note that the interceptor can be applied application-wide (as covered [here](https://docs.nestjs.com/interceptors#binding-interceptors)). The combination of the interceptor and the entity class declaration ensures that **any** method that returns a `UserEntity` will be sure to remove the `password` property. This gives you a measure of centralized enforcement of this business rule.

#### Expose properties[#](/techniques/serialization#expose-properties)

You can use the `@Expose()` decorator to provide alias names for properties, or to execute a function to calculate a property value (analogous to **getter** functions), as shown below.

```typescript

@Expose()
get fullName(): string {
  return `${this.firstName} ${this.lastName}`;
}
```

#### Transform[#](/techniques/serialization#transform)

You can perform additional data transformation using the `@Transform()` decorator. For example, the following construct returns the name property of the `RoleEntity` instead of returning the whole object.

```typescript

@Transform(({ value }) => value.name)
role: RoleEntity;
```

#### Pass options[#](/techniques/serialization#pass-options)

You may want to modify the default behavior of the transformation functions. To override default settings, pass them in an `options` object with the `@SerializeOptions()` decorator.

```typescript

@SerializeOptions({
  excludePrefixes: ['_'],
})
@Get()
findOne(): UserEntity {
  return new UserEntity();
}
```

> **Hint** The `@SerializeOptions()` decorator is imported from `@nestjs/common`.

Options passed via `@SerializeOptions()` are passed as the second argument of the underlying `instanceToPlain()` function. In this example, we are automatically excluding all properties that begin with the `_` prefix.

#### Transform plain objects[#](/techniques/serialization#transform-plain-objects)

You can enforce transformations at the controller level by using the `@SerializeOptions` decorator. This ensures that all responses are transformed into instances of the specified class, applying any decorators from class-validator or class-transformer, even when plain objects are returned. This approach leads to cleaner code without the need to repeatedly instantiate the class or call `plainToInstance`.

In the example below, despite returning plain JavaScript objects in both conditional branches, they will be automatically converted into `UserEntity` instances, with the relevant decorators applied:

```typescript

@UseInterceptors(ClassSerializerInterceptor)
@SerializeOptions({ type: UserEntity })
@Get()
findOne(@Query() { id }: { id: number }): UserEntity {
  if (id === 1) {
    return {
      id: 1,
      firstName: 'John',
      lastName: 'Doe',
      password: 'password',
    };
  }

  return {
    id: 2,
    firstName: 'Kamil',
    lastName: 'Mysliwiec',
    password: 'password2',
  };
}
```

> **Hint** By specifying the expected return type for the controller, you can leverage TypeScript's type-checking capabilities to ensure that the returned plain object adheres to the shape of the DTO or entity. The `plainToInstance` function doesn't provide this level of type hinting, which can lead to potential bugs if the plain object doesn't match the expected DTO or entity structure.

#### Example[#](/techniques/serialization#example)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/21-serializer).

#### WebSockets and Microservices[#](/techniques/serialization#websockets-and-microservices)

While this chapter shows examples using HTTP style applications (e.g., Express or Fastify), the `ClassSerializerInterceptor` works the same for WebSockets and Microservices, regardless of the transport method that is used.

#### Learn more[#](/techniques/serialization#learn-more)

Read more about available decorators and options as provided by the `class-transformer` package [here](https://github.com/typestack/class-transformer).

----
url: https://docs.nestjs.com/v10/techniques/validation
----

* [Validation](https://docs.nestjs.com/v10/techniques/validation#validation)
* [Overview](https://docs.nestjs.com/v10/techniques/validation#overview)
* [Using the built-in ValidationPipe](https://docs.nestjs.com/v10/techniques/validation#using-the-built-in-validationpipe)
* [Auto-validation](https://docs.nestjs.com/v10/techniques/validation#auto-validation)
* [Disable detailed errors](https://docs.nestjs.com/v10/techniques/validation#disable-detailed-errors)
* [Stripping properties](https://docs.nestjs.com/v10/techniques/validation#stripping-properties)
* [Transform payload objects](https://docs.nestjs.com/v10/techniques/validation#transform-payload-objects)
* [Explicit conversion](https://docs.nestjs.com/v10/techniques/validation#explicit-conversion)
* [Mapped types](https://docs.nestjs.com/v10/techniques/validation#mapped-types)
* [Parsing and validating arrays](https://docs.nestjs.com/v10/techniques/validation#parsing-and-validating-arrays)
* [WebSockets and Microservices](https://docs.nestjs.com/v10/techniques/validation#websockets-and-microservices)
* [Learn more](https://docs.nestjs.com/v10/techniques/validation#learn-more)

In the [Pipes](/v10/pipes) chapter, we went through the process of building simple pipes and binding them to controllers, methods or to the global app to demonstrate how the process works. Be sure to review that chapter to best understand the topics of this chapter. Here, we'll focus on various **real world** use cases of the `ValidationPipe`, and show how to use some of its advanced customization features.

#### Using the built-in ValidationPipe[#](/techniques/validation#using-the-built-in-validationpipe)

To begin using it, we first install the required dependency.

```bash

$ npm i --save class-validator class-transformer
```

> **Hint** The `ValidationPipe` is exported from the `@nestjs/common` package.

Because this pipe uses the [`class-validator`](https://github.com/typestack/class-validator) and [`class-transformer`](https://github.com/typestack/class-transformer) libraries, there are many options available. You configure these settings via a configuration object passed to the pipe. Following are the built-in options:

```typescript

export interface ValidationPipeOptions extends ValidatorOptions {
  transform?: boolean;
  disableErrorMessages?: boolean;
  exceptionFactory?: (errors: ValidationError[]) => any;
}
```

In addition to these, all `class-validator` options (inherited from the `ValidatorOptions` interface) are available:

| Option                    | Type       | Description                                                                                                                           |
| ------------------------- | ---------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| `enableDebugMessages`     | `boolean`  | If set to true, validator will print extra warning messages to the console when something is not right.                               |
| `skipUndefinedProperties` | `boolean`  | If set to true then validator will skip validation of all properties that are undefined in the validating object.                     |
| `skipNullProperties`      | `boolean`  | If set to true then validator will skip validation of all properties that are null in the validating object.                          |
| `skipMissingProperties`   | `boolean`  | If set to true then validator will skip validation of all properties that are null or undefined in the validating object.             |
| `whitelist`               | `boolean`  | If set to true, validator will strip validated (returned) object of any properties that do not use any validation decorators.         |
| `forbidNonWhitelisted`    | `boolean`  | If set to true, instead of stripping non-whitelisted properties validator will throw an exception.                                    |
| `forbidUnknownValues`     | `boolean`  | If set to true, attempts to validate unknown objects fail immediately.                                                                |
| `disableErrorMessages`    | `boolean`  | If set to true, validation errors will not be returned to the client.                                                                 |
| `errorHttpStatusCode`     | `number`   | This setting allows you to specify which exception type will be used in case of an error. By default it throws `BadRequestException`. |
| `exceptionFactory`        | `Function` | Takes an array of the validation errors and returns an exception object to be thrown.                                                 |
| `groups`                  | `string[]` | Groups to be used during validation of the object.                                                                                    |
| `always`                  | `boolean`  | Set default for `always` option of decorators. Default can be overridden in decorator options                                         |
| `strictGroups`            | `boolean`  | If `groups` is not given or is empty, ignore decorators with at least one group.                                                      |
| `dismissDefaultMessages`  | `boolean`  | If set to true, the validation will not use default messages. Error message always will be `undefined` if its not explicitly set.     |
| `validationError.target`  | `boolean`  | Indicates if target should be exposed in `ValidationError`.                                                                           |
| `validationError.value`   | `boolean`  | Indicates if validated value should be exposed in `ValidationError`.                                                                  |
| `stopAtFirstError`        | `boolean`  | When set to true, validation of the given property will stop after encountering the first error. Defaults to false.                   |

> **Notice** Find more information about the `class-validator` package in its [repository](https://github.com/typestack/class-validator).

#### Auto-validation[#](/techniques/validation#auto-validation)

We'll start by binding `ValidationPipe` at the application level, thus ensuring all endpoints are protected from receiving incorrect data.

```typescript

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.useGlobalPipes(new ValidationPipe());
  await app.listen(process.env.PORT ?? 3000);
}
bootstrap();
```

To test our pipe, let's create a basic endpoint.

```typescript

@Post()
create(@Body() createUserDto: CreateUserDto) {
  return 'This action adds a new user';
}
```

> **Hint** Since TypeScript does not store metadata about **generics or interfaces**, when you use them in your DTOs, `ValidationPipe` may not be able to properly validate incoming data. For this reason, consider using concrete classes in your DTOs.

> **Hint** When importing your DTOs, you can't use a type-only import as that would be erased at runtime, i.e. remember to `import { CreateUserDto }` instead of `import type { CreateUserDto }`.

Now we can add a few validation rules in our `CreateUserDto`. We do this using decorators provided by the `class-validator` package, described in detail [here](https://github.com/typestack/class-validator#validation-decorators). In this fashion, any route that uses the `CreateUserDto` will automatically enforce these validation rules.

```typescript

import { IsEmail, IsNotEmpty } from 'class-validator';

export class CreateUserDto {
  @IsEmail()
  email: string;

  @IsNotEmpty()
  password: string;
}
```

With these rules in place, if a request hits our endpoint with an invalid `email` property in the request body, the application will automatically respond with a `400 Bad Request` code, along with the following response body:

```json

{
  "statusCode": 400,
  "error": "Bad Request",
  "message": ["email must be an email"]
}
```

In addition to validating request bodies, the `ValidationPipe` can be used with other request object properties as well. Imagine that we would like to accept `:id` in the endpoint path. To ensure that only numbers are accepted for this request parameter, we can use the following construct:

```typescript

@Get(':id')
findOne(@Param() params: FindOneParams) {
  return 'This action returns a user';
}
```

`FindOneParams`, like a DTO, is simply a class that defines validation rules using `class-validator`. It would look like this:

```typescript

import { IsNumberString } from 'class-validator';

export class FindOneParams {
  @IsNumberString()
  id: number;
}
```

#### Disable detailed errors[#](/techniques/validation#disable-detailed-errors)

Error messages can be helpful to explain what was incorrect in a request. However, some production environments prefer to disable detailed errors. Do this by passing an options object to the `ValidationPipe`:

```typescript

app.useGlobalPipes(
  new ValidationPipe({
    disableErrorMessages: true,
  }),
);
```

As a result, detailed error messages won't be displayed in the response body.

#### Stripping properties[#](/techniques/validation#stripping-properties)

Our `ValidationPipe` can also filter out properties that should not be received by the method handler. In this case, we can **whitelist** the acceptable properties, and any property not included in the whitelist is automatically stripped from the resulting object. For example, if our handler expects `email` and `password` properties, but a request also includes an `age` property, this property can be automatically removed from the resulting DTO. To enable such behavior, set `whitelist` to `true`.

```typescript

app.useGlobalPipes(
  new ValidationPipe({
    whitelist: true,
  }),
);
```

```typescript

@Post()
@UsePipes(new ValidationPipe({ transform: true }))
async create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

To enable this behavior globally, set the option on a global pipe:

```typescript

app.useGlobalPipes(
  new ValidationPipe({
    transform: true,
  }),
);
```

With the auto-transformation option enabled, the `ValidationPipe` will also perform conversion of primitive types. In the following example, the `findOne()` method takes one argument which represents an extracted `id` path parameter:

```typescript

@Get(':id')
findOne(@Param('id') id: number) {
  console.log(typeof id === 'number'); // true
  return 'This action returns a user';
}
```

By default, every path parameter and query parameter comes over the network as a `string`. In the above example, we specified the `id` type as a `number` (in the method signature). Therefore, the `ValidationPipe` will try to automatically convert a string identifier to a number.

#### Explicit conversion[#](/techniques/validation#explicit-conversion)

In the above section, we showed how the `ValidationPipe` can implicitly transform query and path parameters based on the expected type. However, this feature requires having auto-transformation enabled.

Alternatively (with auto-transformation disabled), you can explicitly cast values using the `ParseIntPipe` or `ParseBoolPipe` (note that `ParseStringPipe` is not needed because, as mentioned earlier, every path parameter and query parameter comes over the network as a `string` by default).

```typescript

@Get(':id')
findOne(
  @Param('id', ParseIntPipe) id: number,
  @Query('sort', ParseBoolPipe) sort: boolean,
) {
  console.log(typeof id === 'number'); // true
  console.log(typeof sort === 'boolean'); // true
  return 'This action returns a user';
}
```

> **Hint** The `ParseIntPipe` and `ParseBoolPipe` are exported from the `@nestjs/common` package.

#### Mapped types[#](/techniques/validation#mapped-types)

As you build out features like **CRUD** (Create/Read/Update/Delete) it's often useful to construct variants on a base entity type. Nest provides several utility functions that perform type transformations to make this task more convenient.

> **Warning** If your application uses the `@nestjs/swagger` package, see [this chapter](/v10/openapi/mapped-types) for more information about Mapped Types. Likewise, if you use the `@nestjs/graphql` package see [this chapter](/v10/graphql/mapped-types). Both packages heavily rely on types and so they require a different import to be used. Therefore, if you used `@nestjs/mapped-types` (instead of an appropriate one, either `@nestjs/swagger` or `@nestjs/graphql` depending on the type of your app), you may face various, undocumented side-effects.

When building input validation types (also called DTOs), it's often useful to build **create** and **update** variations on the same type. For example, the **create** variant may require all fields, while the **update** variant may make all fields optional.

Nest provides the `PartialType()` utility function to make this task easier and minimize boilerplate.

The `PartialType()` function returns a type (class) with all the properties of the input type set to optional. For example, suppose we have a **create** type as follows:

```typescript

export class CreateCatDto {
  name: string;
  age: number;
  breed: string;
}
```

By default, all of these fields are required. To create a type with the same fields, but with each one optional, use `PartialType()` passing the class reference (`CreateCatDto`) as an argument:

```typescript

export class UpdateCatDto extends PartialType(CreateCatDto) {}
```

> **Hint** The `PartialType()` function is imported from the `@nestjs/mapped-types` package.

The `PickType()` function constructs a new type (class) by picking a set of properties from an input type. For example, suppose we start with a type like:

```typescript

export class CreateCatDto {
  name: string;
  age: number;
  breed: string;
}
```

We can pick a set of properties from this class using the `PickType()` utility function:

```typescript

export class UpdateCatAgeDto extends PickType(CreateCatDto, ['age'] as const) {}
```

> **Hint** The `PickType()` function is imported from the `@nestjs/mapped-types` package.

The `OmitType()` function constructs a type by picking all properties from an input type and then removing a particular set of keys. For example, suppose we start with a type like:

```typescript

export class CreateCatDto {
  name: string;
  age: number;
  breed: string;
}
```

We can generate a derived type that has every property **except**`name` as shown below. In this construct, the second argument to `OmitType` is an array of property names.

```typescript

export class UpdateCatDto extends OmitType(CreateCatDto, ['name'] as const) {}
```

> **Hint** The `OmitType()` function is imported from the `@nestjs/mapped-types` package.

The `IntersectionType()` function combines two types into one new type (class). For example, suppose we start with two types like:

```typescript

export class CreateCatDto {
  name: string;
  breed: string;
}

export class AdditionalCatInfo {
  color: string;
}
```

We can generate a new type that combines all properties in both types.

```typescript

export class UpdateCatDto extends IntersectionType(
  CreateCatDto,
  AdditionalCatInfo,
) {}
```

> **Hint** The `IntersectionType()` function is imported from the `@nestjs/mapped-types` package.

The type mapping utility functions are composable. For example, the following will produce a type (class) that has all of the properties of the `CreateCatDto` type except for `name`, and those properties will be set to optional:

```typescript

export class UpdateCatDto extends PartialType(
  OmitType(CreateCatDto, ['name'] as const),
) {}
```

#### Parsing and validating arrays[#](/techniques/validation#parsing-and-validating-arrays)

TypeScript does not store metadata about generics or interfaces, so when you use them in your DTOs, `ValidationPipe` may not be able to properly validate incoming data. For instance, in the following code, `createUserDtos` won't be correctly validated:

```typescript

@Post()
createBulk(@Body() createUserDtos: CreateUserDto[]) {
  return 'This action adds new users';
}
```

To validate the array, create a dedicated class which contains a property that wraps the array, or use the `ParseArrayPipe`.

```typescript

@Post()
createBulk(
  @Body(new ParseArrayPipe({ items: CreateUserDto }))
  createUserDtos: CreateUserDto[],
) {
  return 'This action adds new users';
}
```

In addition, the `ParseArrayPipe` may come in handy when parsing query parameters. Let's consider a `findByIds()` method that returns users based on identifiers passed as query parameters.

```typescript

@Get()
findByIds(
  @Query('ids', new ParseArrayPipe({ items: Number, separator: ',' }))
  ids: number[],
) {
  return 'This action returns users by ids';
}
```

This construction validates the incoming query parameters from an HTTP `GET` request like the following:

```bash

GET /?ids=1,2,3
```

#### WebSockets and Microservices[#](/techniques/validation#websockets-and-microservices)

While this chapter shows examples using HTTP style applications (e.g., Express or Fastify), the `ValidationPipe` works the same for WebSockets and microservices, regardless of the transport method that is used.

#### Learn more[#](/techniques/validation#learn-more)

Read more about custom validators, error messages, and available decorators as provided by the `class-validator` package [here](https://github.com/typestack/class-validator).

----
url: https://docs.nestjs.com/v8/techniques/serialization
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Serialization](https://docs.nestjs.com/v8/techniques/serialization#serialization)
* [Overview](https://docs.nestjs.com/v8/techniques/serialization#overview)
* [Exclude properties](https://docs.nestjs.com/v8/techniques/serialization#exclude-properties)
* [Expose properties](https://docs.nestjs.com/v8/techniques/serialization#expose-properties)
* [Transform](https://docs.nestjs.com/v8/techniques/serialization#transform)
* [Pass options](https://docs.nestjs.com/v8/techniques/serialization#pass-options)
* [Example](https://docs.nestjs.com/v8/techniques/serialization#example)
* [WebSockets and Microservices](https://docs.nestjs.com/v8/techniques/serialization#websockets-and-microservices)
* [Learn more](https://docs.nestjs.com/v8/techniques/serialization#learn-more)

```typescript

import { Exclude } from 'class-transformer';

export class UserEntity {
  id: number;
  firstName: string;
  lastName: string;

  @Exclude()
  password: string;

  constructor(partial: Partial<UserEntity>) {
    Object.assign(this, partial);
  }
}
```

Now consider a controller with a method handler that returns an instance of this class.

```typescript

@UseInterceptors(ClassSerializerInterceptor)
@Get()
findOne(): UserEntity {
  return new UserEntity({
    id: 1,
    firstName: 'Kamil',
    lastName: 'Mysliwiec',
    password: 'password',
  });
}
```

> **Warning** Note that we must return an instance of the class. If you return a plain JavaScript object, for example, `{ user: new UserEntity() }`, the object won't be properly serialized.

> **Hint** The `ClassSerializerInterceptor` is imported from `@nestjs/common`.

When this endpoint is requested, the client receives the following response:

```json

{
  "id": 1,
  "firstName": "Kamil",
  "lastName": "Mysliwiec"
}
```

Note that the interceptor can be applied application-wide (as covered [here](https://docs.nestjs.com/interceptors#binding-interceptors)). The combination of the interceptor and the entity class declaration ensures that **any** method that returns a `UserEntity` will be sure to remove the `password` property. This gives you a measure of centralized enforcement of this business rule.

#### Expose properties[#](/techniques/serialization#expose-properties)

You can use the `@Expose()` decorator to provide alias names for properties, or to execute a function to calculate a property value (analogous to **getter** functions), as shown below.

```typescript

@Expose()
get fullName(): string {
  return `${this.firstName} ${this.lastName}`;
}
```

#### Transform[#](/techniques/serialization#transform)

You can perform additional data transformation using the `@Transform()` decorator. For example, the following construct returns the name property of the `RoleEntity` instead of returning the whole object.

```typescript

@Transform(({ value }) => value.name)
role: RoleEntity;
```

#### Pass options[#](/techniques/serialization#pass-options)

You may want to modify the default behavior of the transformation functions. To override default settings, pass them in an `options` object with the `@SerializeOptions()` decorator.

```typescript

@SerializeOptions({
  excludePrefixes: ['_'],
})
@Get()
findOne(): UserEntity {
  return new UserEntity();
}
```

> **Hint** The `@SerializeOptions()` decorator is imported from `@nestjs/common`.

----
url: https://docs.nestjs.com/v7/microservices/redis
----

* [Redis](https://docs.nestjs.com/v7/microservices/redis#redis)
* [Installation](https://docs.nestjs.com/v7/microservices/redis#installation)
* [Overview](https://docs.nestjs.com/v7/microservices/redis#overview)
* [Options](https://docs.nestjs.com/v7/microservices/redis#options)
* [Client](https://docs.nestjs.com/v7/microservices/redis#client)
* [Context](https://docs.nestjs.com/v7/microservices/redis#context)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/microservices/redis.md "Suggest Edits")

### Redis

The [Redis](https://redis.io/) transporter implements the publish/subscribe messaging paradigm and leverages the [Pub/Sub](https://redis.io/topics/pubsub) feature of Redis. Published messages are categorized in channels, without knowing what subscribers (if any) will eventually receive the message. Each microservice can subscribe to any number of channels. In addition, more than one channel can be subscribed to at a time. Messages exchanged through channels are **fire-and-forget**, which means that if a message is published and there are no subscribers interested in it, the message is removed and cannot be recovered. Thus, you don't have a guarantee that either messages or events will be handled by at least one service. A single message can be subscribed to (and received) by multiple subscribers.

#### Installation[#](/microservices/redis#installation)

To start building Redis-based microservices, first install the required package:

```bash

$ npm i --save redis
```

#### Overview[#](/microservices/redis#overview)

To use the Redis transporter, pass the following options object to the `createMicroservice()` method:

main.ts

JS TS

```typescript

const app = await NestFactory.createMicroservice<MicroserviceOptions>(AppModule, {
  transport: Transport.REDIS,
  options: {
    url: 'redis://localhost:6379',
  },
});
```

```typescript

const app = await NestFactory.createMicroservice(AppModule, {
  transport: Transport.REDIS,
  options: {
    url: 'redis://localhost:6379',
  },
});
```

> **Hint** The `Transport` enum is imported from the `@nestjs/microservices` package.

#### Options[#](/microservices/redis#options)

The `options` property is specific to the chosen transporter. The **Redis** transporter exposes the properties described below.

|                 |                                                          |
| --------------- | -------------------------------------------------------- |
| `url`           | Connection url                                           |
| `retryAttempts` | Number of times to retry message (default: `0`)          |
| `retryDelay`    | Delay between message retry attempts (ms) (default: `0`) |

All the properties supported by the official [redis](https://www.npmjs.com/package/redis#options-object-properties) client are also supported by this transporter.

#### Client[#](/microservices/redis#client)

Like other microservice transporters, you have [several options](https://docs.nestjs.com/microservices/basics#client) for creating a Redis `ClientProxy` instance.

One method for creating an instance is to use use the `ClientsModule`. To create a client instance with the `ClientsModule`, import it and use the `register()` method to pass an options object with the same properties shown above in the `createMicroservice()` method, as well as a `name` property to be used as the injection token. Read more about `ClientsModule`[here](https://docs.nestjs.com/microservices/basics#client).

```typescript

@Module({
  imports: [
    ClientsModule.register([
      {
        name: 'MATH_SERVICE',
        transport: Transport.REDIS,
        options: {
          url: 'redis://localhost:6379',
        }
      },
    ]),
  ]
  ...
})
```

Other options to create a client (either `ClientProxyFactory` or `@Client()`) can be used as well. You can read about them [here](https://docs.nestjs.com/microservices/basics#client).

#### Context[#](/microservices/redis#context)

In more sophisticated scenarios, you may want to access more information about the incoming request. When using the Redis transporter, you can access the `RedisContext` object.

JS TS

```typescript

@MessagePattern('notifications')
getNotifications(@Payload() data: number[], @Ctx() context: RedisContext) {
  console.log(`Channel: ${context.getChannel()}`);
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('notifications')
getNotifications(data, context) {
  console.log(`Channel: ${context.getChannel()}`);
}
```

> **Hint**`@Payload()`, `@Ctx()` and `RedisContext` are imported from the `@nestjs/microservices` package.

----
url: https://docs.nestjs.com/v4/websockets/exception-filters
----

### Exception Filters

The websockets **exceptions layer** works exact same as the [prime layer](/v4/exception-filters). The only difference is that instead of throwing `HttpException`, you should throw `WsException`.

TypeScript

```typescript

throw new WsException('Invalid credentials.');
```

> **Notice** The `WsException` class is imported from the `@nestjs/websockets` package.

Nest would handle this exception and emits the `exception` message with the following data:

TypeScript

```typescript

{
  status: 'error',
  message: 'Invalid credentials.'
}
```

#### Exception Filters

The **Exception Filters** are also really similar, and works exactly in the same way as the primary ones.

ws-exception.filter.ts

JavaScript TypeScript

TypeScript

```typescript

import { Catch, WsExceptionFilter } from '@nestjs/common';
import { WsException } from '@nestjs/websockets';

@Catch(WsException)
export class ExceptionFilter implements WsExceptionFilter {
  catch(exception: WsException, client) {
    client.emit('exception', {
      status: 'error',
      message: `It's a message from the exception filter`,
    });
  }
}
```

TypeScript

```typescript

import { Catch } from '@nestjs/common';
import { WsException } from '@nestjs/websockets';

@Catch(WsException)
export class ExceptionFilter {
  catch(exception, client) {
    client.emit('exception', {
      status: 'error',
      message: `It's a message from the exception filter`,
    });
  }
}
```

> **Notice** It's impossible to set up the websockets exception filters globally.

#### Sponsors

[](https://valor-software.com/)

Nest is an MIT-licensed open source project. It can grow thanks to the support by these awesome people. If you'd like to join them, please read more [here](https://opencollective.com/nest). Thanks!

[](https://opencollective.com/nest/backer/0/website)[](https://opencollective.com/nest/backer/1/website)[](https://opencollective.com/nest/backer/2/website)[](https://opencollective.com/nest/backer/3/website)[](https://opencollective.com/nest/backer/4/website)[](https://opencollective.com/nest/backer/5/website)[](https://opencollective.com/nest/backer/6/website)[](https://opencollective.com/nest/backer/7/website)[](https://opencollective.com/nest/backer/8/website)[](https://opencollective.com/nest/backer/9/website)[](https://opencollective.com/nest/backer/10/website)[](https://opencollective.com/nest/backer/11/website)[](https://opencollective.com/nest/backer/12/website)[](https://opencollective.com/nest/backer/13/website)[](https://opencollective.com/nest/backer/14/website)[](https://opencollective.com/nest/backer/15/website)[](https://opencollective.com/nest/backer/16/website)[](https://opencollective.com/nest/backer/17/website)[](https://opencollective.com/nest/backer/18/website)[](https://opencollective.com/nest/backer/19/website)[](https://opencollective.com/nest/backer/20/website)[](https://opencollective.com/nest/backer/21/website)[](https://opencollective.com/nest/backer/22/website)[](https://opencollective.com/nest/backer/23/website)[](https://opencollective.com/nest/backer/24/website)[](https://opencollective.com/nest/backer/25/website)[](https://opencollective.com/nest/backer/26/website)[](https://opencollective.com/nest/backer/27/website)[](https://opencollective.com/nest/backer/28/website)[](https://opencollective.com/nest/backer/29/website)

[Become a sponsor](https://opencollective.com/nest)

----
url: https://docs.nestjs.com/recipes/hot-reload
----

[Skip to content](#content)

On this page

* [Hot Reload](https://docs.nestjs.com/recipes/hot-reload#hot-reload)
* [With CLI](https://docs.nestjs.com/recipes/hot-reload#with-cli)
* [Installation](https://docs.nestjs.com/recipes/hot-reload#installation)
* [Configuration](https://docs.nestjs.com/recipes/hot-reload#configuration)
* [Hot-Module Replacement](https://docs.nestjs.com/recipes/hot-reload#hot-module-replacement)
* [Without CLI](https://docs.nestjs.com/recipes/hot-reload#without-cli)
* [Installation](https://docs.nestjs.com/recipes/hot-reload#installation-1)
* [Configuration](https://docs.nestjs.com/recipes/hot-reload#configuration-1)
* [Hot-Module Replacement](https://docs.nestjs.com/recipes/hot-reload#hot-module-replacement-1)
* [Example](https://docs.nestjs.com/recipes/hot-reload#example)

### Hot Reload

**TypeScript compilation** has the biggest impact on your application's bootstrapping time. With [webpack](https://github.com/webpack/webpack) HMR (Hot-Module Replacement), you don't need to recompile the entire project each time a change occurs. This significantly decreases the time it takes to instantiate your application and makes iterative development much faster.

> **Warning**`webpack` doesn't automatically copy your assets (e.g., `graphql` files) to the `dist` folder. Similarly, `webpack` isn't compatible with static glob paths (e.g., the `entities` property in `TypeOrmModule`).

> **Warning** As of NestJS v12, the webpack builder is **deprecated** and Rspack is the default bundler for monorepos. This recipe targets webpack-based CommonJS projects, which is why the examples below use `module.hot` and a plain `bootstrap()` call rather than the ESM top-level `await` used elsewhere in these docs. For new projects, prefer `--builder rspack`.

### With CLI

If you use the [Nest CLI](/cli/overview), the configuration process is straightforward. The CLI wraps `webpack`, which lets you use the `HotModuleReplacementPlugin`.

#### Installation[#](/recipes/hot-reload#installation)

First, install the required packages:

```bash

$ npm i --save-dev webpack-node-externals run-script-webpack-plugin webpack
```

> **Hint** If you use **Yarn Berry** (not classic Yarn), install the `webpack-pnp-externals` package instead of `webpack-node-externals`.

#### Configuration[#](/recipes/hot-reload#configuration)

Once the installation is complete, create a `webpack-hmr.config.js` file in the root directory of your application:

```typescript

const nodeExternals = require('webpack-node-externals');
const { RunScriptWebpackPlugin } = require('run-script-webpack-plugin');

module.exports = function (options, webpack) {
  return {
    ...options,
    entry: ['webpack/hot/poll?100', options.entry],
    externals: [
      nodeExternals({
        allowlist: ['webpack/hot/poll?100'],
      }),
    ],
    plugins: [
      ...options.plugins,
      new webpack.HotModuleReplacementPlugin(),
      new webpack.WatchIgnorePlugin({
        paths: [/\.js$/, /\.d\.ts$/],
      }),
      new RunScriptWebpackPlugin({ name: options.output.filename, autoRestart: false }),
    ],
  };
};
```

> **Hint** With **Yarn Berry** (not classic Yarn), instead of using `nodeExternals` in the `externals` configuration property, use `WebpackPnpExternals` from the `webpack-pnp-externals` package: `WebpackPnpExternals({ exclude: ['webpack/hot/poll?100'] })`.

This function takes the original object containing the default webpack configuration as its first argument, and a reference to the underlying `webpack` package used by the Nest CLI as its second argument. It returns a modified webpack configuration with the `HotModuleReplacementPlugin`, `WatchIgnorePlugin`, and `RunScriptWebpackPlugin` plugins.

#### Hot-Module Replacement[#](/recipes/hot-reload#hot-module-replacement)

To enable **HMR**, open the application entry file (`main.ts`) and add the following webpack-related instructions:

```typescript

declare const module: any;

async function bootstrap() {
  if (module.hot?.data?.closePromise) {
    // wait for the previous application instance to fully shut down
    await module.hot.data.closePromise;
  }

  const app = await NestFactory.create(AppModule, {
    forceCloseConnections: !!module.hot,
  });
  await app.listen(process.env.PORT ?? 3000);

  if (module.hot) {
    module.hot.accept();
    module.hot.dispose((data: any) => {
      data.closePromise = app.close();
    });
  }
}
bootstrap();
```

> **Hint**`app.close()` is asynchronous, but webpack does not await the `dispose()` callback. Stashing the returned promise on `module.hot.data` lets the next application instance await it before binding to the port again, which (together with `forceCloseConnections`) prevents `EADDRINUSE` errors on reload.

To simplify the execution process, add a script to your `package.json` file:

```json

"start:dev": "nest build --webpack --webpackPath webpack-hmr.config.js --watch"
```

Then run the following command:

```bash

$ npm run start:dev
```

### Without CLI

If you don't use the [Nest CLI](/cli/overview), the configuration is slightly more complex and requires more manual steps.

#### Installation[#](/recipes/hot-reload#installation-1)

First, install the required packages:

```bash

$ npm i --save-dev webpack webpack-cli webpack-node-externals ts-loader run-script-webpack-plugin
```

> **Hint** If you use **Yarn Berry** (not classic Yarn), install the `webpack-pnp-externals` package instead of `webpack-node-externals`.

#### Configuration[#](/recipes/hot-reload#configuration-1)

Once the installation is complete, create a `webpack.config.js` file in the root directory of your application:

```typescript

const webpack = require('webpack');
const path = require('path');
const nodeExternals = require('webpack-node-externals');
const { RunScriptWebpackPlugin } = require('run-script-webpack-plugin');

module.exports = {
  entry: ['webpack/hot/poll?100', './src/main.ts'],
  target: 'node',
  externals: [
    nodeExternals({
      allowlist: ['webpack/hot/poll?100'],
    }),
  ],
  module: {
    rules: [
      {
        test: /.tsx?$/,
        use: 'ts-loader',
        exclude: /node_modules/,
      },
    ],
  },
  mode: 'development',
  resolve: {
    extensions: ['.tsx', '.ts', '.js'],
  },
  plugins: [new webpack.HotModuleReplacementPlugin(), new RunScriptWebpackPlugin({ name: 'server.js', autoRestart: false })],
  output: {
    path: path.join(__dirname, 'dist'),
    filename: 'server.js',
  },
};
```

> **Hint** With **Yarn Berry** (not classic Yarn), instead of using `nodeExternals` in the `externals` configuration property, use `WebpackPnpExternals` from the `webpack-pnp-externals` package: `WebpackPnpExternals({ exclude: ['webpack/hot/poll?100'] })`.

This configuration tells webpack a few essential things about your application: the location of the entry file, the directory that holds the **compiled** files, and the loader used to compile source files. You can generally use this file as-is, even if you don't fully understand all of the options.

#### Hot-Module Replacement[#](/recipes/hot-reload#hot-module-replacement-1)

To enable **HMR**, open the application entry file (`main.ts`) and add the following webpack-related instructions:

```typescript

declare const module: any;

async function bootstrap() {
  if (module.hot?.data?.closePromise) {
    // wait for the previous application instance to fully shut down
    await module.hot.data.closePromise;
  }

  const app = await NestFactory.create(AppModule, {
    forceCloseConnections: !!module.hot,
  });
  await app.listen(process.env.PORT ?? 3000);

  if (module.hot) {
    module.hot.accept();
    module.hot.dispose((data: any) => {
      data.closePromise = app.close();
    });
  }
}
bootstrap();
```

> **Hint**`app.close()` is asynchronous, but webpack does not await the `dispose()` callback. Stashing the returned promise on `module.hot.data` lets the next application instance await it before binding to the port again, which (together with `forceCloseConnections`) prevents `EADDRINUSE` errors on reload.

To simplify the execution process, add a script to your `package.json` file:

```json

"start:dev": "webpack --config webpack.config.js --watch"
```

Then run the following command:

```bash

$ npm run start:dev
```

#### Example[#](/recipes/hot-reload#example)

A working example is available in the [webpack sample](https://github.com/nestjs/nest/tree/master/sample/08-webpack) on GitHub.

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/recipes/hot-reload.md)

----
url: https://docs.nestjs.com/v11/graphql/scalars
----

* [Scalars](https://docs.nestjs.com/v11/graphql/scalars#scalars)
* [Code first](https://docs.nestjs.com/v11/graphql/scalars#code-first)
* [Override a default scalar](https://docs.nestjs.com/v11/graphql/scalars#override-a-default-scalar)
* [Import a custom scalar](https://docs.nestjs.com/v11/graphql/scalars#import-a-custom-scalar)
* [Create a custom scalar](https://docs.nestjs.com/v11/graphql/scalars#create-a-custom-scalar)
* [Schema first](https://docs.nestjs.com/v11/graphql/scalars#schema-first)

```typescript

GraphQLModule.forRoot({
  buildSchemaOptions: {
    dateScalarMode: 'timestamp',
  }
}),
```

Likewise, the `GraphQLFloat` is used by default to represent the `number` type. To use the `GraphQLInt` instead, set the `numberScalarMode` of the `buildSchemaOptions` object to `'integer'` as follows:

```typescript

GraphQLModule.forRoot({
  buildSchemaOptions: {
    numberScalarMode: 'integer',
  }
}),
```

In addition, you can create custom scalars.

#### Override a default scalar[#](/graphql/scalars#override-a-default-scalar)

To create a custom implementation for the `Date` scalar, simply create a new class.

```typescript

import { Scalar, CustomScalar } from '@nestjs/graphql';
import { Kind, ValueNode } from 'graphql';

@Scalar('Date', () => Date)
export class DateScalar implements CustomScalar<number, Date> {
  description = 'Date custom scalar type';

  parseValue(value: number): Date {
    return new Date(value); // value from the client
  }

  serialize(value: Date): number {
    return value.getTime(); // value sent to the client
  }

  parseLiteral(ast: ValueNode): Date {
    if (ast.kind === Kind.INT) {
      return new Date(ast.value);
    }
    return null;
  }
}
```

With this in place, register `DateScalar` as a provider.

```typescript

@Module({
  providers: [DateScalar],
})
export class CommonModule {}
```

Now we can use the `Date` type in our classes.

```typescript

@Field()
creationDate: Date;
```

#### Import a custom scalar[#](/graphql/scalars#import-a-custom-scalar)

To use a custom scalar, import and register it as a resolver. We’ll use the `graphql-type-json` package for demonstration purposes. This npm package defines a `JSON` GraphQL scalar type.

Start by installing the package:

```bash

$ npm i --save graphql-type-json
```

Once the package is installed, we pass a custom resolver to the `forRoot()` method:

```typescript

import GraphQLJSON from 'graphql-type-json';

@Module({
  imports: [
    GraphQLModule.forRoot({
      resolvers: { JSON: GraphQLJSON },
    }),
  ],
})
export class AppModule {}
```

Now we can use the `JSON` type in our classes.

```typescript

@Field(() => GraphQLJSON)
info: JSON;
```

For a suite of useful scalars, take a look at the [graphql-scalars](https://www.npmjs.com/package/graphql-scalars) package.

#### Create a custom scalar[#](/graphql/scalars#create-a-custom-scalar)

To define a custom scalar, create a new `GraphQLScalarType` instance. We'll create a custom `UUID` scalar.

```typescript

const regex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;

function validate(uuid: unknown): string | never {
  if (typeof uuid !== 'string' || !regex.test(uuid)) {
    throw new Error('invalid uuid');
  }
  return uuid;
}

export const CustomUuidScalar = new GraphQLScalarType({
  name: 'UUID',
  description: 'A simple UUID parser',
  serialize: (value) => validate(value),
  parseValue: (value) => validate(value),
  parseLiteral: (ast) => validate(ast.value),
});
```

We pass a custom resolver to the `forRoot()` method:

```typescript

@Module({
  imports: [
    GraphQLModule.forRoot({
      resolvers: { UUID: CustomUuidScalar },
    }),
  ],
})
export class AppModule {}
```

Now we can use the `UUID` type in our classes.

```typescript

@Field(() => CustomUuidScalar)
uuid: string;
```

#### Schema first[#](/graphql/scalars#schema-first)

To define a custom scalar (read more about scalars [here](https://www.apollographql.com/docs/graphql-tools/scalars.html)), create a type definition and a dedicated resolver. Here (as in the official documentation), we’ll use the `graphql-type-json` package for demonstration purposes. This npm package defines a `JSON` GraphQL scalar type.

Start by installing the package:

```bash

$ npm i --save graphql-type-json
```

Once the package is installed, we pass a custom resolver to the `forRoot()` method:

```typescript

import GraphQLJSON from 'graphql-type-json';

@Module({
  imports: [
    GraphQLModule.forRoot({
      typePaths: ['./**/*.graphql'],
      resolvers: { JSON: GraphQLJSON },
    }),
  ],
})
export class AppModule {}
```

Now we can use the `JSON` scalar in our type definitions:

```graphql

scalar JSON

type Foo {
  field: JSON
}
```

Another method to define a scalar type is to create a simple class. Assume we want to enhance our schema with the `Date` type.

```typescript

import { Scalar, CustomScalar } from '@nestjs/graphql';
import { Kind, ValueNode } from 'graphql';

@Scalar('Date')
export class DateScalar implements CustomScalar<number, Date> {
  description = 'Date custom scalar type';

  parseValue(value: number): Date {
    return new Date(value); // value from the client
  }

  serialize(value: Date): number {
    return value.getTime(); // value sent to the client
  }

  parseLiteral(ast: ValueNode): Date {
    if (ast.kind === Kind.INT) {
      return new Date(ast.value);
    }
    return null;
  }
}
```

With this in place, register `DateScalar` as a provider.

```typescript

@Module({
  providers: [DateScalar],
})
export class CommonModule {}
```

Now we can use the `Date` scalar in type definitions.

```graphql

scalar Date
```

By default, the generated TypeScript definition for all scalars is `any` - which isn't particularly typesafe. But, you can configure how Nest generates typings for your custom scalars when you specify how to generate types:

```typescript

import { GraphQLDefinitionsFactory } from '@nestjs/graphql';
import { join } from 'path';

const definitionsFactory = new GraphQLDefinitionsFactory();

definitionsFactory.generate({
  typePaths: ['./src/**/*.graphql'],
  path: join(process.cwd(), 'src/graphql.ts'),
  outputAs: 'class',
  defaultScalarType: 'unknown',
  customScalarTypeMapping: {
    DateTime: 'Date',
    BigNumber: '_BigNumber',
  },
  additionalHeader: "import _BigNumber from 'bignumber.js'",
});
```

> **Hint** Alternatively, you can use a type reference instead, for example: `DateTime: Date`. In this case, `GraphQLDefinitionsFactory` will extract the name property of the specified type (`Date.name`) to generate TS definitions. Note: adding an import statement for non-built-in types (custom types) is required.

Now, given the following GraphQL custom scalar types:

```graphql

scalar DateTime
scalar BigNumber
scalar Payload
```

We will now see the following generated TypeScript definitions in `src/graphql.ts`:

```typescript

import _BigNumber from 'bignumber.js';

export type DateTime = Date;
export type BigNumber = _BigNumber;
export type Payload = unknown;
```

Here, we've used the `customScalarTypeMapping` property to supply a map of the types we wish to declare for our custom scalars. We've also provided an `additionalHeader` property so that we can add any imports required for these type definitions. Lastly, we've added a `defaultScalarType` of `'unknown'`, so that any custom scalars not specified in `customScalarTypeMapping` will be aliased to `unknown` instead of `any` (which [TypeScript recommends](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-0.html#new-unknown-top-type) using since 3.0 for added type safety).

> **Hint** Note that we've imported `_BigNumber` from `bignumber.js`; this is to avoid [circular type references](https://github.com/Microsoft/TypeScript/issues/12525#issuecomment-263166239).

----
url: https://docs.nestjs.com/v11/faq/multiple-servers
----

* [HTTPS](https://docs.nestjs.com/v11/faq/multiple-servers#https)
* [Multiple simultaneous servers](https://docs.nestjs.com/v11/faq/multiple-servers#multiple-simultaneous-servers)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/faq/multiple-servers.md "Suggest Edits")

### HTTPS

To create an application that uses the HTTPS protocol, set the `httpsOptions` property in the options object passed to the `create()` method of the `NestFactory` class:

```typescript

const httpsOptions = {
  key: fs.readFileSync('./secrets/private-key.pem'),
  cert: fs.readFileSync('./secrets/public-certificate.pem'),
};
const app = await NestFactory.create(AppModule, {
  httpsOptions,
});
await app.listen(process.env.PORT ?? 3000);
```

If you use the `FastifyAdapter`, create the application as follows:

```typescript

const app = await NestFactory.create<NestFastifyApplication>(
  AppModule,
  new FastifyAdapter({ https: httpsOptions }),
);
```

#### Multiple simultaneous servers[#](/faq/multiple-servers#multiple-simultaneous-servers)

The following recipe shows how to instantiate a Nest application that listens on multiple ports (for example, on a non-HTTPS port and an HTTPS port) simultaneously.

```typescript

const httpsOptions = {
  key: fs.readFileSync('./secrets/private-key.pem'),
  cert: fs.readFileSync('./secrets/public-certificate.pem'),
};

const server = express();
const app = await NestFactory.create(AppModule, new ExpressAdapter(server));
await app.init();

const httpServer = http.createServer(server).listen(3000);
const httpsServer = https.createServer(httpsOptions, server).listen(443);
```

Because we called `http.createServer` / `https.createServer` ourselves, NestJS doesn't close them when calling `app.close` / on termination signal. We need to do this ourselves:

```typescript

@Injectable()
export class ShutdownObserver implements OnApplicationShutdown {
  private httpServers: http.Server[] = [];

  public addHttpServer(server: http.Server): void {
    this.httpServers.push(server);
  }

  public async onApplicationShutdown(): Promise<void> {
    await Promise.all(
      this.httpServers.map(
        (server) =>
          new Promise((resolve, reject) => {
            server.close((error) => {
              if (error) {
                reject(error);
              } else {
                resolve(null);
              }
            });
          }),
      ),
    );
  }
}

const shutdownObserver = app.get(ShutdownObserver);
shutdownObserver.addHttpServer(httpServer);
shutdownObserver.addHttpServer(httpsServer);
```

> **Hint** The `ExpressAdapter` is imported from the `@nestjs/platform-express` package. The `http` and `https` packages are native Node.js packages.

> **Warning** This recipe does not work with [GraphQL Subscriptions](/v11/graphql/subscriptions).

----
url: https://docs.nestjs.com/v9/cli/monorepo
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Workspaces](https://docs.nestjs.com/v9/cli/monorepo#workspaces)
* [Standard mode](https://docs.nestjs.com/v9/cli/monorepo#standard-mode)
* [Monorepo mode](https://docs.nestjs.com/v9/cli/monorepo#monorepo-mode)
* [Workspace projects](https://docs.nestjs.com/v9/cli/monorepo#workspace-projects)
* [Applications](https://docs.nestjs.com/v9/cli/monorepo#applications)
* [Libraries](https://docs.nestjs.com/v9/cli/monorepo#libraries)
* [CLI properties](https://docs.nestjs.com/v9/cli/monorepo#cli-properties)
* [Global compiler options](https://docs.nestjs.com/v9/cli/monorepo#global-compiler-options)
* [Global generate options](https://docs.nestjs.com/v9/cli/monorepo#global-generate-options)
* [Project-specific generate options](https://docs.nestjs.com/v9/cli/monorepo#project-specific-generate-options)
* [Specified compiler](https://docs.nestjs.com/v9/cli/monorepo#specified-compiler)
* [Webpack options](https://docs.nestjs.com/v9/cli/monorepo#webpack-options)
* [Assets](https://docs.nestjs.com/v9/cli/monorepo#assets)
* [Project properties](https://docs.nestjs.com/v9/cli/monorepo#project-properties)

```bash

$ nest new my-project
```

```bash

$ cd my-project
$ nest generate app my-app
```

> **Warning** The conversion of a standard mode structure to monorepo only works for projects that have followed the canonical Nest project structure. Specifically, during conversion, the schematic attempts to relocate the `src` and `test` folders in a project folder beneath the `apps` folder in the root. If a project does not use this structure, the conversion will fail or produce unreliable results.

#### Workspace projects[#](/cli/monorepo#workspace-projects)

A monorepo uses the concept of a workspace to manage its member entities. Workspaces are composed of **projects**. A project may be either:

* an **application**: a full Nest application including a `main.ts` file to bootstrap the application. Aside from compile and build considerations, an application-type project within a workspace is functionally identical to an application within a *standard mode* structure.
* a **library**: a library is a way of packaging a general purpose set of features (modules, providers, controllers, etc.) that can be used within other projects. A library cannot run on its own, and has no `main.ts` file. Read more about libraries [here](/v9/cli/libraries).

All workspaces have a **default project** (which should be an application-type project). This is defined by the top-level `"root"` property in the `nest-cli.json` file, which points at the root of the default project (see [CLI properties](/cli/monorepo#cli-properties) below for more details). Usually, this is the **standard mode** application you started with, and later converted to a monorepo using `nest generate app`. When you follow these steps, this property is populated automatically.

Default projects are used by `nest` commands like `nest build` and `nest start` when a project name is not supplied.

For example, in the above monorepo structure, running

```bash

$ nest start
```

will start up the `my-project` app. To start `my-app`, we'd use:

```bash

$ nest start my-app
```

#### Applications[#](/cli/monorepo#applications)

Application-type projects, or what we might informally refer to as just "applications", are complete Nest applications that you can run and deploy. You generate an application-type project with `nest generate app`.

This command automatically generates a project skeleton, including the standard `src` and `test` folders from the [typescript starter](https://github.com/nestjs/typescript-starter). Unlike standard mode, an application project in a monorepo does not have any of the package dependency (`package.json`) or other project configuration artifacts like `.prettierrc` and `.eslintrc.js`. Instead, the monorepo-wide dependencies and config files are used.

However, the schematic does generate a project-specific `tsconfig.app.json` file in the root folder of the project. This config file automatically sets appropriate build options, including setting the compilation output folder properly. The file extends the top-level (monorepo) `tsconfig.json` file, so you can manage global settings monorepo-wide, but override them if needed at the project level.

#### Libraries[#](/cli/monorepo#libraries)

As mentioned, library-type projects, or simply "libraries", are packages of Nest components that need to be composed into applications in order to run. You generate a library-type project with `nest generate library`. Deciding what belongs in a library is an architectural design decision. We discuss libraries in depth in the [libraries](/v9/cli/libraries) chapter.

#### CLI properties[#](/cli/monorepo#cli-properties)

Nest keeps the metadata needed to organize, build and deploy both standard and monorepo structured projects in the `nest-cli.json` file. Nest automatically adds to and updates this file as you add projects, so you usually do not have to think about it or edit its contents. However, there are some settings you may want to change manually, so it's helpful to have an overview understanding of the file.

After running the steps above to create a monorepo, our `nest-cli.json` file looks like this:

```javascript

{
  "collection": "@nestjs/schematics",
  "sourceRoot": "apps/my-project/src",
  "monorepo": true,
  "root": "apps/my-project",
  "compilerOptions": {
    "webpack": true,
    "tsConfigPath": "apps/my-project/tsconfig.app.json"
  },
  "projects": {
    "my-project": {
      "type": "application",
      "root": "apps/my-project",
      "entryFile": "main",
      "sourceRoot": "apps/my-project/src",
      "compilerOptions": {
        "tsConfigPath": "apps/my-project/tsconfig.app.json"
      }
    },
    "my-app": {
      "type": "application",
      "root": "apps/my-app",
      "entryFile": "main",
      "sourceRoot": "apps/my-app/src",
      "compilerOptions": {
        "tsConfigPath": "apps/my-app/tsconfig.app.json"
      }
    }
  }
}
```

| Property Name       | Property Value Type | Description                                                                                                                                                                                                                           |
| ------------------- | ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `webpack`           | boolean             | If `true`, use [webpack compiler](https://webpack.js.org/). If `false` or not present, use `tsc`. In monorepo mode, the default is `true` (use webpack), in standard mode, the default is `false` (use `tsc`). See below for details. |
| `tsConfigPath`      | string              | (**monorepo only**) Points at the file containing the `tsconfig.json` settings that will be used when `nest build` or `nest start` is called without a `project` option (e.g., when the default project is built or started).         |
| `webpackConfigPath` | string              | Points at a webpack options file. If not specified, Nest looks for the file `webpack.config.js`. See below for more details.                                                                                                          |
| `deleteOutDir`      | boolean             | If `true`, whenever the compiler is invoked, it will first remove the compilation output directory (as configured in `tsconfig.json`, where the default is `./dist`).                                                                 |
| `assets`            | array               | Enables automatically distributing non-TypeScript assets whenever a compilation step begins (asset distribution does **not** happen on incremental compiles in `--watch` mode). See below for details.                                |
| `watchAssets`       | boolean             | If `true`, run in watch-mode, watching **all** non-TypeScript assets. (For more fine-grained control of the assets to watch, see [Assets](cli/monorepo#assets) section below).                                                        |
| `manualRestart`     | boolean             | If `true`, enables the shortcut `rs` to manually restart the server. Default value is `false`.                                                                                                                                        |

#### Global generate options[#](/cli/monorepo#global-generate-options)

These properties specify the default generate options to be used by the `nest generate` command.

| Property Name | Property Value Type | Description                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| ------------- | ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `spec`        | boolean *or* object | If the value is boolean, a value of `true` enables `spec` generation by default and a value of `false` disables it. A flag passed on the CLI command line overrides this setting, as does a project-specific `generateOptions` setting (more below). If the value is an object, each key represents a schematic name, and the boolean value determines whether the default spec generation is enabled / disabled for that specific schematic. |
| `flat`        | boolean             | If true, all generate commands will generate a flat structure                                                                                                                                                                                                                                                                                                                                                                                 |

The following example uses a boolean value to specify that spec file generation should be disabled by default for all projects:

```javascript

{
  "generateOptions": {
    "spec": false
  },
  ...
}
```

The following example uses a boolean value to specify flat file generation should be the default for all projects:

```javascript

{
  "generateOptions": {
    "flat": true
  },
  ...
}
```

In the following example, `spec` file generation is disabled only for `service` schematics (e.g., `nest generate service...`):

```javascript

{
  "generateOptions": {
    "spec": {
      "service": false
    }
  },
  ...
}
```

> **Warning** When specifying the `spec` as an object, the key for the generation schematic does not currently support automatic alias handling. This means that specifying a key as for example `service: false` and trying to generate a service via the alias `s`, the spec would still be generated. To make sure both the normal schematic name and the alias work as intended, specify both the normal command name as well as the alias, as seen below.
>
> ```javascript
>
> {
>   "generateOptions": {
>     "spec": {
>       "service": false,
>       "s": false
>     }
>   },
>   ...
> }
> ```

#### Project-specific generate options[#](/cli/monorepo#project-specific-generate-options)

In addition to providing global generate options, you may also specify project-specific generate options. The project specific generate options follow the exact same format as the global generate options, but are specified directly on each project.

Project-specific generate options override global generate options.

```javascript

{
  "projects": {
    "cats-project": {
      "generateOptions": {
        "spec": {
          "service": false
        }
      },
      ...
    }
  },
  ...
}
```

> **Warning** The order of precedence for generate options is as follows. Options specified on the CLI command line take precedence over project-specific options. Project-specific options override global options.

#### Specified compiler[#](/cli/monorepo#specified-compiler)

The reason for the different default compilers is that for larger projects (e.g., more typical in a monorepo) webpack can have significant advantages in build times and in producing a single file bundling all project components together. If you wish to generate individual files, set `"webpack"` to `false`, which will cause the build process to use `tsc`.

#### Webpack options[#](/cli/monorepo#webpack-options)

The webpack options file can contain standard [webpack configuration options](https://webpack.js.org/configuration/). For example, to tell webpack to bundle `node_modules` (which are excluded by default), add the following to `webpack.config.js`:

```javascript

module.exports = {
  externals: [],
};
```

Since the webpack config file is a JavaScript file, you can even expose a function that takes default options and returns a modified object:

```javascript

module.exports = function (options) {
  return {
    ...options,
    externals: [],
  };
};
```

#### Assets[#](/cli/monorepo#assets)

TypeScript compilation automatically distributes compiler output (`.js` and `.d.ts` files) to the specified output directory. It can also be convenient to distribute non-TypeScript files, such as `.graphql` files, `images`, `.html` files and other assets. This allows you to treat `nest build` (and any initial compilation step) as a lightweight **development build** step, where you may be editing non-TypeScript files and iteratively compiling and testing. The assets should be located in the `src` folder otherwise they will not be copied.

The value of the `assets` key should be an array of elements specifying the files to be distributed. The elements can be simple strings with `glob`-like file specs, for example:

```typescript

"assets": ["**/*.graphql"],
"watchAssets": true,
```

For finer control, the elements can be objects with the following keys:

* `"include"`: `glob`-like file specifications for the assets to be distributed
* `"exclude"`: `glob`-like file specifications for assets to be **excluded** from the `include` list
* `"outDir"`: a string specifying the path (relative to the root folder) where the assets should be distributed. Defaults to the same output directory configured for compiler output.
* `"watchAssets"`: boolean; if `true`, run in watch mode watching specified assets

For example:

```typescript

"assets": [
  { "include": "**/*.graphql", "exclude": "**/omitted.graphql", "watchAssets": true },
]
```

> **Warning** Setting `watchAssets` in a top-level `compilerOptions` property overrides any `watchAssets` settings within the `assets` property.

#### Project properties[#](/cli/monorepo#project-properties)

This element exists only for monorepo-mode structures. You generally should not edit these properties, as they are used by Nest to locate projects and their configuration options within the monorepo.

----
url: https://docs.nestjs.com/v7/microservices/kafka
----

* [Kafka](https://docs.nestjs.com/v7/microservices/kafka#kafka)
* [Installation](https://docs.nestjs.com/v7/microservices/kafka#installation)
* [Overview](https://docs.nestjs.com/v7/microservices/kafka#overview)
* [Options](https://docs.nestjs.com/v7/microservices/kafka#options)
* [Client](https://docs.nestjs.com/v7/microservices/kafka#client)
* [Message response subscription](https://docs.nestjs.com/v7/microservices/kafka#message-response-subscription)
* [Message pattern](https://docs.nestjs.com/v7/microservices/kafka#message-pattern)
* [Incoming](https://docs.nestjs.com/v7/microservices/kafka#incoming)
* [Outgoing](https://docs.nestjs.com/v7/microservices/kafka#outgoing)
* [Context](https://docs.nestjs.com/v7/microservices/kafka#context)
* [Naming conventions](https://docs.nestjs.com/v7/microservices/kafka#naming-conventions)

```bash

$ npm i --save kafkajs
```

#### Overview[#](/microservices/kafka#overview)

Like other Nest microservice transport layer implementations, you select the Kafka transporter mechanism using the `transport` property of the options object passed to the `createMicroservice()` method, along with an optional `options` property, as shown below:

main.ts

JS TS

```typescript

const app = await NestFactory.createMicroservice<MicroserviceOptions>(AppModule, {
  transport: Transport.KAFKA,
  options: {
    client: {
      brokers: ['localhost:9092'],
    }
  }
});
```

```typescript

const app = await NestFactory.createMicroservice(AppModule, {
  transport: Transport.KAFKA,
  options: {
    client: {
      brokers: ['localhost:9092'],
    }
  }
});
```

> **Hint** The `Transport` enum is imported from the `@nestjs/microservices` package.

#### Options[#](/microservices/kafka#options)

The `options` property is specific to the chosen transporter. The **Kafka** transporter exposes the properties described below.

|             |                                                                                                                 |
| ----------- | --------------------------------------------------------------------------------------------------------------- |
| `client`    | Client configuration options (read more [here](https://kafka.js.org/docs/configuration))                        |
| `consumer`  | Consumer configuration options (read more [here](https://kafka.js.org/docs/consuming#a-name-options-a-options)) |
| `run`       | Run configuration options (read more [here](https://kafka.js.org/docs/consuming))                               |
| `subscribe` | Subscribe configuration options (read more [here](https://kafka.js.org/docs/consuming#frombeginning))           |
| `producer`  | Producer configuration options (read more [here](https://kafka.js.org/docs/producing#options))                  |
| `send`      | Send configuration options (read more [here](https://kafka.js.org/docs/producing#options))                      |

#### Client[#](/microservices/kafka#client)

There is a small difference in Kafka compared to other microservice transporters. Instead of the `ClientProxy` class, we use the `ClientKafka` class.

Like other microservice transporters, you have [several options](https://docs.nestjs.com/microservices/basics#client) for creating a `ClientKafka` instance.

One method for creating an instance is to use use the `ClientsModule`. To create a client instance with the `ClientsModule`, import it and use the `register()` method to pass an options object with the same properties shown above in the `createMicroservice()` method, as well as a `name` property to be used as the injection token. Read more about `ClientsModule`[here](https://docs.nestjs.com/microservices/basics#client).

```typescript

@Module({
  imports: [
    ClientsModule.register([
      {
        name: 'HERO_SERVICE',
        transport: Transport.KAFKA,
        options: {
          client: {
            clientId: 'hero',
            brokers: ['localhost:9092'],
          },
          consumer: {
            groupId: 'hero-consumer'
          }
        }
      },
    ]),
  ]
  ...
})
```

Other options to create a client (either `ClientProxyFactory` or `@Client()`) can be used as well. You can read about them [here](https://docs.nestjs.com/microservices/basics#client).

Use the `@Client()` decorator as follows:

```typescript

@Client({
  transport: Transport.KAFKA,
  options: {
    client: {
      clientId: 'hero',
      brokers: ['localhost:9092'],
    },
    consumer: {
      groupId: 'hero-consumer'
    }
  }
})
client: ClientKafka;
```

#### Message response subscription[#](/microservices/kafka#message-response-subscription)

The `ClientKafka` class provides the `subscribeToResponseOf()` method. The `subscribeToResponseOf()` method takes a request's topic name as an argument and adds the derived reply topic name to a collection of reply topics. This method is required when implementing the message pattern.

heroes.controller.ts

JS TS

```typescript

onModuleInit() {
  this.client.subscribeToResponseOf('hero.kill.dragon');
}
```

If the `ClientKafka` instance is created asynchronously, the `subscribeToResponseOf()` method must be called before calling the `connect()` method.

heroes.controller.ts

JS TS

```typescript

async onModuleInit() {
  this.client.subscribeToResponseOf('hero.kill.dragon');
  await this.client.connect();
}
```

heroes.controller.ts

JS TS

```typescript

@Controller()
export class HeroesController {
  @MessagePattern('hero.kill.dragon')
  killDragon(@Payload() message: KillDragonMessage): any {
    const dragonId = message.dragonId;
    const items = [
      { id: 1, name: 'Mythical Sword' },
      { id: 2, name: 'Key to Dungeon' },
    ];
    return items;
  }
}
```

> **Hint**`@Payload()` is imported from the `@nestjs/microservices`.

Outgoing messages can also be keyed by passing an object with the `key` and `value` properties. Keying messages is important for meeting the [co-partitioning requirement](https://docs.confluent.io/current/ksql/docs/developer-guide/partition-data.html#co-partitioning-requirements).

heroes.controller.ts

JS TS

```typescript

@Controller()
export class HeroesController {
  @MessagePattern('hero.kill.dragon')
  killDragon(@Payload() message: KillDragonMessage): any {
    const realm = 'Nest';
    const heroId = message.heroId;
    const dragonId = message.dragonId;

    const items = [
      { id: 1, name: 'Mythical Sword' },
      { id: 2, name: 'Key to Dungeon' },
    ];

    return {
      headers: {
        realm
      },
      key: heroId,
      value: items
    }
  }
}
```

Additionally, messages passed in this format can also contain custom headers set in the `headers` hash property. Header hash property values must be either of type `string` or type `Buffer`.

heroes.controller.ts

JS TS

```typescript

@Controller()
export class HeroesController {
  @MessagePattern('hero.kill.dragon')
  killDragon(@Payload() message: KillDragonMessage): any {
    const realm = 'Nest';
    const heroId = message.heroId;
    const dragonId = message.dragonId;

    const items = [
      { id: 1, name: 'Mythical Sword' },
      { id: 2, name: 'Key to Dungeon' },
    ];

    return {
      headers: {
        kafka_nestRealm: realm
      },
      key: heroId,
      value: items
    }
  }
}
```

#### Context[#](/microservices/kafka#context)

In more sophisticated scenarios, you may want to access more information about the incoming request. When using the Kafka transporter, you can access the `KafkaContext` object.

JS TS

```typescript

@MessagePattern('hero.kill.dragon')
killDragon(@Payload() message: KillDragonMessage, @Ctx() context: KafkaContext) {
  console.log(`Topic: ${context.getTopic()}`);
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('hero.kill.dragon')
killDragon(message, context) {
  console.log(`Topic: ${context.getTopic()}`);
}
```

> **Hint**`@Payload()`, `@Ctx()` and `KafkaContext` are imported from the `@nestjs/microservices` package.

To access the original Kafka `IncomingMessage` object, use the `getMessage()` method of the `KafkaContext` object, as follows:

JS TS

```typescript

@MessagePattern('hero.kill.dragon')
killDragon(@Payload() message: KillDragonMessage, @Ctx() context: KafkaContext) {
  const originalMessage = context.getMessage();
  const { headers, partition, timestamp } = originalMessage;
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('hero.kill.dragon')
killDragon(message, context) {
  const originalMessage = context.getMessage();
  const { headers, partition, timestamp } = originalMessage;
}
```

Where the `IncomingMessage` fulfills the following interface:

```typescript

interface IncomingMessage {
  topic: string;
  partition: number;
  timestamp: string;
  size: number;
  attributes: number;
  offset: string;
  key: any;
  value: any;
  headers: Record<string, any>;
}
```

#### Naming conventions[#](/microservices/kafka#naming-conventions)

The Kafka microservice components append a description of their respective role onto the `client.clientId` and `consumer.groupId` options to prevent collisions between Nest microservice client and server components. By default the `ClientKafka` components append `-client` and the `ServerKafka` components append `-server` to both of these options. Note how the provided values below are transformed in that way (as shown in the comments).

main.ts

JS TS

```typescript

const app = await NestFactory.createMicroservice(AppModule, {
  transport: Transport.KAFKA,
  options: {
    client: {
      clientId: 'hero', // hero-server
      brokers: ['localhost:9092'],
    },
    consumer: {
      groupId: 'hero-consumer' // hero-consumer-server
    },
  }
});
```

And for the client:

heroes.controller.ts

JS TS

```typescript

@Client({
  transport: Transport.KAFKA,
  options: {
    client: {
      clientId: 'hero', // hero-client
      brokers: ['localhost:9092'],
    },
    consumer: {
      groupId: 'hero-consumer' // hero-consumer-client
    }
  }
})
client: ClientKafka;
```

> **Hint** Kafka client and consumer naming conventions can be customized by extending `ClientKafka` and `KafkaServer` in your own custom provider and overriding the constructor.

Since the Kafka microservice message pattern utilizes two topics for the request and reply channels, a reply pattern should be derived from the request topic. By default, the name of the reply topic is the composite of the request topic name with `.reply` appended.

heroes.controller.ts

JS TS

```typescript

onModuleInit() {
  this.client.subscribeToResponseOf('hero.get'); // hero.get.reply
}
```

> **Hint** Kafka reply topic naming conventions can be customized by extending `ClientKafka` in your own custom provider and overriding the `getResponsePatternName` method.

----
url: https://docs.nestjs.com/v11/techniques/task-scheduling
----

* [Task scheduling](https://docs.nestjs.com/v11/techniques/task-scheduling#task-scheduling)
* [Installation](https://docs.nestjs.com/v11/techniques/task-scheduling#installation)
* [Declarative cron jobs](https://docs.nestjs.com/v11/techniques/task-scheduling#declarative-cron-jobs)
* [Declarative intervals](https://docs.nestjs.com/v11/techniques/task-scheduling#declarative-intervals)
* [Declarative timeouts](https://docs.nestjs.com/v11/techniques/task-scheduling#declarative-timeouts)
* [Dynamic schedule module API](https://docs.nestjs.com/v11/techniques/task-scheduling#dynamic-schedule-module-api)
* [Dynamic cron jobs](https://docs.nestjs.com/v11/techniques/task-scheduling#dynamic-cron-jobs)
* [Dynamic intervals](https://docs.nestjs.com/v11/techniques/task-scheduling#dynamic-intervals)
* [Dynamic timeouts](https://docs.nestjs.com/v11/techniques/task-scheduling#dynamic-timeouts)
* [Example](https://docs.nestjs.com/v11/techniques/task-scheduling#example)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/techniques/task-scheduling.md "Suggest Edits")

### Task scheduling

Task scheduling allows you to schedule arbitrary code (methods/functions) to execute at a fixed date/time, at recurring intervals, or once after a specified interval. In the Linux world, this is often handled by packages like [cron](https://en.wikipedia.org/wiki/Cron) at the OS level. For Node.js apps, there are several packages that emulate cron-like functionality. Nest provides the `@nestjs/schedule` package, which integrates with the popular Node.js [cron](https://github.com/kelektiv/node-cron) package. We'll cover this package in the current chapter.

#### Installation[#](/techniques/task-scheduling#installation)

To begin using it, we first install the required dependencies.

```bash

$ npm install --save @nestjs/schedule
```

To activate job scheduling, import the `ScheduleModule` into the root `AppModule` and run the `forRoot()` static method as shown below:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { ScheduleModule } from '@nestjs/schedule';

@Module({
  imports: [
    ScheduleModule.forRoot()
  ],
})
export class AppModule {}
```

The `.forRoot()` call initializes the scheduler and registers any declarative [cron jobs](techniques/task-scheduling#declarative-cron-jobs), [timeouts](techniques/task-scheduling#declarative-timeouts) and [intervals](techniques/task-scheduling#declarative-intervals) that exist within your app. Registration occurs when the `onApplicationBootstrap` lifecycle hook occurs, ensuring that all modules have loaded and declared any scheduled jobs.

#### Declarative cron jobs[#](/techniques/task-scheduling#declarative-cron-jobs)

A cron job schedules an arbitrary function (method call) to run automatically. Cron jobs can run:

* Once, at a specified date/time.
* On a recurring basis; recurring jobs can run at a specified instant within a specified interval (for example, once per hour, once per week, once every 5 minutes)

Declare a cron job with the `@Cron()` decorator preceding the method definition containing the code to be executed, as follows:

```typescript

import { Injectable, Logger } from '@nestjs/common';
import { Cron } from '@nestjs/schedule';

@Injectable()
export class TasksService {
  private readonly logger = new Logger(TasksService.name);

  @Cron('45 * * * * *')
  handleCron() {
    this.logger.debug('Called when the current second is 45');
  }
}
```

In this example, the `handleCron()` method will be called each time the current second is `45`. In other words, the method will be run once per minute, at the 45 second mark.

The `@Cron()` decorator supports the following standard [cron patterns](http://crontab.org/):

* Asterisk (e.g. `*`)
* Ranges (e.g. `1-3,5`)
* Steps (e.g. `*/2`)

In the example above, we passed `45 * * * * *` to the decorator. The following key shows how each position in the cron pattern string is interpreted:

```javascript

* * * * * *
| | | | | |
| | | | | day of week
| | | | months
| | | day of month
| | hours
| minutes
seconds (optional)
```

Some sample cron patterns are:

|                     |                                             |
| ------------------- | ------------------------------------------- |
| `* * * * * *`       | every second                                |
| `45 * * * * *`      | every minute, on the 45th second            |
| `0 10 * * * *`      | every hour, at the start of the 10th minute |
| `0 */30 9-17 * * *` | every 30 minutes between 9am and 5pm        |
| `0 30 11 * * 1-5`   | Monday to Friday at 11:30am                 |

The `@nestjs/schedule` package provides a convenient enum with commonly used cron patterns. You can use this enum as follows:

```typescript

import { Injectable, Logger } from '@nestjs/common';
import { Cron, CronExpression } from '@nestjs/schedule';

@Injectable()
export class TasksService {
  private readonly logger = new Logger(TasksService.name);

  @Cron(CronExpression.EVERY_30_SECONDS)
  handleCron() {
    this.logger.debug('Called every 30 seconds');
  }
}
```

In this example, the `handleCron()` method will be called every `30` seconds. If an exception occurs, it will be logged to the console, as every method annotated with `@Cron()` is automatically wrapped in a `try-catch` block.

Alternatively, you can supply a JavaScript `Date` object to the `@Cron()` decorator. Doing so causes the job to execute exactly once, at the specified date.

> **Hint** Use JavaScript date arithmetic to schedule jobs relative to the current date. For example, `@Cron(new Date(Date.now() + 10 * 1000))` to schedule a job to run 10 seconds after the app starts.

Also, you can supply additional options as the second parameter to the `@Cron()` decorator.

|                     |                                                                                                                                                                                                                                                        |
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `name`              | Useful to access and control a cron job after it's been declared.                                                                                                                                                                                      |
| `timeZone`          | Specify the timezone for the execution. This will modify the actual time relative to your timezone. If the timezone is invalid, an error is thrown. You can check all timezones available at [Moment Timezone](http://momentjs.com/timezone/) website. |
| `utcOffset`         | This allows you to specify the offset of your timezone rather than using the `timeZone` param.                                                                                                                                                         |
| `waitForCompletion` | If `true`, no additional instances of the cron job will run until the current onTick callback has been completed. Any new scheduled executions that occur while the current cron job is running will be skipped entirely.                              |
| `disabled`          | This indicates whether the job will be executed at all.                                                                                                                                                                                                |

```typescript

import { Injectable } from '@nestjs/common';
import { Cron, CronExpression } from '@nestjs/schedule';

@Injectable()
export class NotificationService {
  @Cron('* * 0 * * *', {
    name: 'notifications',
    timeZone: 'Europe/Paris',
  })
  triggerNotifications() {}
}
```

You can access and control a cron job after it's been declared, or dynamically create a cron job (where its cron pattern is defined at runtime) with the [Dynamic API](/techniques/task-scheduling#dynamic-schedule-module-api). To access a declarative cron job via the API, you must associate the job with a name by passing the `name` property in an optional options object as the second argument of the decorator.

#### Declarative intervals[#](/techniques/task-scheduling#declarative-intervals)

To declare that a method should run at a (recurring) specified interval, prefix the method definition with the `@Interval()` decorator. Pass the interval value, as a number in milliseconds, to the decorator as shown below:

```typescript

@Interval(10000)
handleInterval() {
  this.logger.debug('Called every 10 seconds');
}
```

> **Hint** This mechanism uses the JavaScript `setInterval()` function under the hood. You can also utilize a cron job to schedule recurring jobs.

If you want to control your declarative interval from outside the declaring class via the [Dynamic API](/techniques/task-scheduling#dynamic-schedule-module-api), associate the interval with a name using the following construction:

```typescript

@Interval('notifications', 2500)
handleInterval() {}
```

```typescript

@Timeout(5000)
handleTimeout() {
  this.logger.debug('Called once after 5 seconds');
}
```

> **Hint** This mechanism uses the JavaScript `setTimeout()` function under the hood.

If an exception occurs, it will be logged to the console, as every method annotated with `@Timeout()` is automatically wrapped in a `try-catch` block.

If you want to control your declarative timeout from outside the declaring class via the [Dynamic API](/techniques/task-scheduling#dynamic-schedule-module-api), associate the timeout with a name using the following construction:

```typescript

@Timeout('notifications', 2500)
handleTimeout() {}
```

The [Dynamic API](techniques/task-scheduling#dynamic-timeouts) also enables **creating** dynamic timeouts, where the timeout's properties are defined at runtime, and **listing and deleting** them.

#### Dynamic schedule module API[#](/techniques/task-scheduling#dynamic-schedule-module-api)

The `@nestjs/schedule` module provides a dynamic API that enables managing declarative [cron jobs](techniques/task-scheduling#declarative-cron-jobs), [timeouts](techniques/task-scheduling#declarative-timeouts) and [intervals](techniques/task-scheduling#declarative-intervals). The API also enables creating and managing **dynamic** cron jobs, timeouts and intervals, where the properties are defined at runtime.

#### Dynamic cron jobs[#](/techniques/task-scheduling#dynamic-cron-jobs)

Obtain a reference to a `CronJob` instance by name from anywhere in your code using the `SchedulerRegistry` API. First, inject `SchedulerRegistry` using standard constructor injection:

```typescript

constructor(private schedulerRegistry: SchedulerRegistry) {}
```

> **Hint** Import the `SchedulerRegistry` from the `@nestjs/schedule` package.

Then use it in a class as follows. Assume a cron job was created with the following declaration:

```typescript

@Cron('* * 8 * * *', {
  name: 'notifications',
})
triggerNotifications() {}
```

Access this job using the following:

```typescript

const job = this.schedulerRegistry.getCronJob('notifications');

job.stop();
console.log(job.lastDate());
```

> **Hint** Use `toJSDate()` on `DateTime` objects to render them as a JavaScript Date equivalent to this DateTime.

**Create** a new cron job dynamically using the `SchedulerRegistry#addCronJob` method, as follows:

```typescript

addCronJob(name: string, seconds: string) {
  const job = new CronJob(`${seconds} * * * * *`, () => {
    this.logger.warn(`time (${seconds}) for job ${name} to run!`);
  });

  this.schedulerRegistry.addCronJob(name, job);
  job.start();

  this.logger.warn(
    `job ${name} added for each minute at ${seconds} seconds!`,
  );
}
```

In this code, we use the `CronJob` object from the `cron` package to create the cron job. The `CronJob` constructor takes a cron pattern (just like the `@Cron()`[decorator](techniques/task-scheduling#declarative-cron-jobs)) as its first argument, and a callback to be executed when the cron timer fires as its second argument. The `SchedulerRegistry#addCronJob` method takes two arguments: a name for the `CronJob`, and the `CronJob` object itself.

> **Warning** Remember to inject the `SchedulerRegistry` before accessing it. Import `CronJob` from the `cron` package.

**Delete** a named cron job using the `SchedulerRegistry#deleteCronJob` method, as follows:

```typescript

deleteCron(name: string) {
  this.schedulerRegistry.deleteCronJob(name);
  this.logger.warn(`job ${name} deleted!`);
}
```

**List** all cron jobs using the `SchedulerRegistry#getCronJobs` method as follows:

```typescript

getCrons() {
  const jobs = this.schedulerRegistry.getCronJobs();
  jobs.forEach((value, key, map) => {
    let next;
    try {
      next = value.nextDate().toJSDate();
    } catch (e) {
      next = 'error: next fire date is in the past!';
    }
    this.logger.log(`job: ${key} -> next: ${next}`);
  });
}
```

The `getCronJobs()` method returns a `map`. In this code, we iterate over the map and attempt to access the `nextDate()` method of each `CronJob`. In the `CronJob` API, if a job has already fired and has no future firing date, it throws an exception.

#### Dynamic intervals[#](/techniques/task-scheduling#dynamic-intervals)

Obtain a reference to an interval with the `SchedulerRegistry#getInterval` method. As above, inject `SchedulerRegistry` using standard constructor injection:

```typescript

constructor(private schedulerRegistry: SchedulerRegistry) {}
```

And use it as follows:

```typescript

const interval = this.schedulerRegistry.getInterval('notifications');
clearInterval(interval);
```

**Create** a new interval dynamically using the `SchedulerRegistry#addInterval` method, as follows:

```typescript

addInterval(name: string, milliseconds: number) {
  const callback = () => {
    this.logger.warn(`Interval ${name} executing at time (${milliseconds})!`);
  };

  const interval = setInterval(callback, milliseconds);
  this.schedulerRegistry.addInterval(name, interval);
}
```

In this code, we create a standard JavaScript interval, then pass it to the `SchedulerRegistry#addInterval` method. That method takes two arguments: a name for the interval, and the interval itself.

**Delete** a named interval using the `SchedulerRegistry#deleteInterval` method, as follows:

```typescript

deleteInterval(name: string) {
  this.schedulerRegistry.deleteInterval(name);
  this.logger.warn(`Interval ${name} deleted!`);
}
```

**List** all intervals using the `SchedulerRegistry#getIntervals` method as follows:

```typescript

getIntervals() {
  const intervals = this.schedulerRegistry.getIntervals();
  intervals.forEach(key => this.logger.log(`Interval: ${key}`));
}
```

#### Dynamic timeouts[#](/techniques/task-scheduling#dynamic-timeouts)

Obtain a reference to a timeout with the `SchedulerRegistry#getTimeout` method. As above, inject `SchedulerRegistry` using standard constructor injection:

```typescript

constructor(private readonly schedulerRegistry: SchedulerRegistry) {}
```

And use it as follows:

```typescript

const timeout = this.schedulerRegistry.getTimeout('notifications');
clearTimeout(timeout);
```

**Create** a new timeout dynamically using the `SchedulerRegistry#addTimeout` method, as follows:

```typescript

addTimeout(name: string, milliseconds: number) {
  const callback = () => {
    this.logger.warn(`Timeout ${name} executing after (${milliseconds})!`);
  };

  const timeout = setTimeout(callback, milliseconds);
  this.schedulerRegistry.addTimeout(name, timeout);
}
```

In this code, we create a standard JavaScript timeout, then pass it to the `SchedulerRegistry#addTimeout` method. That method takes two arguments: a name for the timeout, and the timeout itself.

**Delete** a named timeout using the `SchedulerRegistry#deleteTimeout` method, as follows:

```typescript

deleteTimeout(name: string) {
  this.schedulerRegistry.deleteTimeout(name);
  this.logger.warn(`Timeout ${name} deleted!`);
}
```

**List** all timeouts using the `SchedulerRegistry#getTimeouts` method as follows:

```typescript

getTimeouts() {
  const timeouts = this.schedulerRegistry.getTimeouts();
  timeouts.forEach(key => this.logger.log(`Timeout: ${key}`));
}
```

#### Example[#](/techniques/task-scheduling#example)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/27-scheduling).

----
url: https://docs.nestjs.com/v8/microservices/interceptors
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Interceptors](https://docs.nestjs.com/v8/microservices/interceptors#interceptors)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/microservices/interceptors.md "Suggest Edits")

### Interceptors

There is no difference between [regular interceptors](/v8/interceptors) and microservices interceptors. The following example uses a manually instantiated method-scoped interceptor. Just as with HTTP based applications, you can also use controller-scoped interceptors (i.e., prefix the controller class with a `@UseInterceptors()` decorator).

JS TS

```typescript

@UseInterceptors(new TransformInterceptor())
@MessagePattern({ cmd: 'sum' })
accumulate(data: number[]): number {
  return (data || []).reduce((a, b) => a + b);
}
```

```typescript

@UseInterceptors(new TransformInterceptor())
@MessagePattern({ cmd: 'sum' })
accumulate(data) {
  return (data || []).reduce((a, b) => a + b);
}
```

----
url: https://docs.nestjs.com/v5/microservices/nats
----

### NATS

The [NATS](https://nats.io) is a simple, high performance open source messaging system.

#### Installation

Before we start, we have to install required package:

```bash

$ npm i --save nats
```

#### Overview

In order to switch to **NATS** transporter, we need to modify an options object passed to the `createMicroservice()` method.

main.ts

JS TS

TypeScript

```typescript

const app = await NestFactory.createMicroservice(ApplicationModule, {
  transport: Transport.NATS,
  options: {
    url: 'nats://localhost:4222',
  },
});
```

#### Options

There are a bunch of available options that determine a transporter behavior. They are well-described [here](https://github.com/nats-io/node-nats#connect-options). Also, there is an additional `queue` property which allows you specifying a name of the queue that your server should subscribe to (leave `undefined` if you don't want use any particular queue)

* NATS

----
url: https://docs.nestjs.com/v4/middlewares
----

### Middlewares

The middleware is a function, which is called **before** the route handler. Middleware functions have access to the [request](http://expressjs.com/en/4x/api.html#req) and [response](http://expressjs.com/en/4x/api.html#res) objects, and the `next` middleware function in the application’s request-response cycle. The **next** middleware function is commonly denoted by a variable named `next`.

The Nest middlewares are equal to [express](http://expressjs.com/en/guide/using-middleware.html) middlewares. In fact, here's a great list of the middleware capabilities copied from the official express documentation:

> Middleware functions can perform the following tasks:
>
> * Execute any code.
> * Make changes to the request and the response objects.
> * End the request-response cycle.
> * Call the next middleware function in the stack.
> * If the current middleware function does not end the request-response cycle, it must call `next()` to pass control to the next middleware function. Otherwise, the request will be left hanging.

The Nest middleware is a class with a `@Middleware()` decorator. This class should implement the `NestMiddleware` interface. Let's create an example, the `LoggerMiddleware` class.

logger.middleware.ts

JavaScript TypeScript

TypeScript

```typescript

import { Middleware, NestMiddleware, ExpressMiddleware } from '@nestjs/common';

@Middleware()
export class LoggerMiddleware implements NestMiddleware {
  resolve(...args: any[]): ExpressMiddleware {
    return (req, res, next) => {
      console.log('Request...');
      next();
    };
  }
}
```

TypeScript

```typescript

import { Middleware } from '@nestjs/common';

@Middleware()
export class LoggerMiddleware {
  resolve(...args) {
    return (req, res, next) => {
      console.log('Request...');
      next();
    };
  }
}
```

The `resolve()` method has to return a regular express middleware `(req, res, next) => void`.

#### Dependency Injection

There's no exception when it comes to the middlewares. Same as components and controllers, they can **inject dependencies** through the `constructor` that belongs to the same module.

#### Where to put the middlewares?

The middlewares can't be listed in the `@Module()` decorator. We have to set them up using the `configure()` method of the module class. Modules that include middlewares have to implement the `NestModule` interface. Let's set up the `LoggerMiddleware` at the `ApplicationModule` level.

app.module.ts

JavaScript TypeScript

TypeScript

```typescript

import { Module, NestModule, MiddlewaresConsumer, RequestMethod } from '@nestjs/common';
import { LoggerMiddleware } from './common/middlewares/logger.middleware';
import { CatsModule } from './cats/cats.module';

@Module({
    imports: [CatsModule],
})
export class ApplicationModule implements NestModule {
    configure(consumer: MiddlewaresConsumer): void {
        consumer.apply(LoggerMiddleware).forRoutes(
            { path: '/cats', method: RequestMethod.GET },
            { path: '/cats', method: RequestMethod.POST },
        );
    }
}
```

TypeScript

```typescript

import { Module, RequestMethod } from '@nestjs/common';
import { LoggerMiddleware } from './common/middlewares/logger.middleware';
import { CatsModule } from './cats/cats.module';

@Module({
    imports: [CatsModule],
})
export class ApplicationModule {
    configure(consumer) {
        consumer.apply(LoggerMiddleware).forRoutes(
            { path: '/cats', method: RequestMethod.GET },
            { path: '/cats', method: RequestMethod.POST },
        );
    }
}
```

> **Hint** We could pass here (inside `forRoutes()`) a single object and just use `RequestMethod.ALL`.

In the above example we have set up the `LoggerMiddleware` for `/cats` route handlers, which we've registered inside the `CatsController`. The `MiddlewareConsumer` is a helper class. It provides several methods to work with the middlewares. All of them can be simply **chained**. Let's go over these methods.

The `forRoutes()` can take a single object, multiple objects, a controller class and even multiple controller classes. In most cases you'll probably just pass the **controllers** and separate them by a comma. Below is an example with a single controller:

app.module.ts

JavaScript TypeScript

TypeScript

```typescript

import { Module, NestModule, MiddlewaresConsumer, RequestMethod } from '@nestjs/common';
import { LoggerMiddleware } from './common/middlewares/logger.middleware';
import { CatsModule } from './cats/cats.module';

@Module({
    imports: [CatsModule],
})
export class ApplicationModule implements NestModule {
    configure(consumer: MiddlewaresConsumer): void {
        consumer.apply(LoggerMiddleware).forRoutes(CatsController);
    }
}
```

TypeScript

```typescript

import { Module, RequestMethod } from '@nestjs/common';
import { LoggerMiddleware } from './common/middlewares/logger.middleware';
import { CatsModule } from './cats/cats.module';

@Module({
    imports: [CatsModule],
})
export class ApplicationModule {
    configure(consumer) {
        consumer.apply(LoggerMiddleware).forRoutes(CatsController);
    }
}
```

> **Hint** The `apply()` method can take a single middleware or an **array of middlewares**.

#### Pass arguments to the middleware

Sometimes the behaviour of the middleware depends on the custom values e.g. an array of user roles, options object etc. We can pass additional arguments to the `resolve()` using the `with()` method. See an example below:

app.module.ts

JavaScript TypeScript

TypeScript

```typescript

import { Module, NestModule, MiddlewaresConsumer } from '@nestjs/common';
import { LoggerMiddleware } from './common/middlewares/logger.middleware';
import { CatsModule } from './cats/cats.module';
import { CatsController } from './cats/cats.controller';

@Module({
    imports: [CatsModule],
})
export class ApplicationModule implements NestModule {
    configure(consumer: MiddlewaresConsumer): void {
        consumer.apply(LoggerMiddleware)
            .with('ApplicationModule')
            .forRoutes(CatsController);
    }
}
```

TypeScript

```typescript

import { Module } from '@nestjs/common';
import { LoggerMiddleware } from './common/middlewares/logger.middleware';
import { CatsModule } from './cats/cats.module';
import { CatsController } from './cats/cats.controller';

@Module({
    imports: [CatsModule],
})
export class ApplicationModule {
    configure(consumer) {
        consumer.apply(LoggerMiddleware)
            .with('ApplicationModule')
            .forRoutes(CatsController);
    }
}
```

We have passed a custom string - `ApplicationModule` to the `with()` method. Now we have to adjust the `resolve()` method of the `LoggerMiddleware`.

logger.middleware.ts

JavaScript TypeScript

TypeScript

```typescript

import { Middleware, NestMiddleware, ExpressMiddleware } from '@nestjs/common';

@Middleware()
export class LoggerMiddleware implements NestMiddleware {
  resolve(name: string): ExpressMiddleware {
    return (req, res, next) => {
      console.log(`[${name}] Request...`); // [ApplicationModule] Request...
      next();
    };
 }
}
```

TypeScript

```typescript

import { Middleware } from '@nestjs/common';

@Middleware()
export class LoggerMiddleware {
  resolve(name) {
    return (req, res, next) => {
      console.log(`[${name}] Request...`); // [ApplicationModule] Request...
      next();
    };
 }
}
```

The value of the `name` property will be `ApplicationModule`.

#### Async Middlewares

There are no contraindications to return the `async` function from the `resolve()` method. Also, it's possible to make the `resolve()` method `async` too. This pattern is called **deffered middleware**.

logger.middleware.ts

JavaScript TypeScript

TypeScript

```typescript

import { Middleware, NestMiddleware, ExpressMiddleware } from '@nestjs/common';

@Middleware()
export class LoggerMiddleware implements NestMiddleware {
  async resolve(name: string): Promise<ExpressMiddleware> {
    await someAsyncFn();

    return async (req, res, next) => {
      await someAsyncFn();
      console.log(`[${name}] Request...`); // [ApplicationModule] Request...
      next();
    };
 }
}
```

TypeScript

```typescript

import { Middleware } from '@nestjs/common';

@Middleware()
export class LoggerMiddleware {
  async resolve(name) {
    await someAsyncFn();

    return async (req, res, next) => {
      await someAsyncFn();
      console.log(`[${name}] Request...`); // [ApplicationModule] Request...
      next();
    };
  }
}
```

#### Functional Middlewares

The `LoggerMiddleware` is quite short. It has no members, no additional methods, no dependencies. Why can't we just use a simple function? It's a good question, cause in fact - we can. This type of the middleware is called **functional middleware**. Let's transform the logger into a function.

logger.middleware.ts

JavaScript TypeScript

TypeScript

```typescript

export const loggerMiddleware = (req, res, next) => {
  console.log(`Request...`);
  next();
};
```

Now use it within the `ApplicationModule`.

app.module.ts

JavaScript TypeScript

TypeScript

```typescript

import { Module, NestModule, MiddlewaresConsumer } from '@nestjs/common';
import { loggerMiddleware } from './common/middlewares/logger.middleware';
import { CatsModule } from './cats/cats.module';
import { CatsController } from './cats/cats.controller';

@Module({
  imports: [CatsModule],
})
export class ApplicationModule implements NestModule {
  configure(consumer: MiddlewaresConsumer): void {
    consumer.apply(loggerMiddleware).forRoutes(CatsController);
  }
}
```

TypeScript

```typescript

import { Module } from '@nestjs/common';
import { loggerMiddleware } from './common/middlewares/logger.middleware';
import { CatsModule } from './cats/cats.module';
import { CatsController } from './cats/cats.controller';

@Module({
  imports: [CatsModule],
})
export class ApplicationModule {
  configure(consumer) {
    consumer.apply(loggerMiddleware).forRoutes(CatsController);
  }
}
```

> **Hint** Let's consider using **functional middlewares** every time when your middleware doesn't have any dependencies.

#### Sponsors

[](https://valor-software.com/)

Nest is an MIT-licensed open source project. It can grow thanks to the support by these awesome people. If you'd like to join them, please read more [here](https://opencollective.com/nest). Thanks!

[](https://opencollective.com/nest/backer/0/website)[](https://opencollective.com/nest/backer/1/website)[](https://opencollective.com/nest/backer/2/website)[](https://opencollective.com/nest/backer/3/website)[](https://opencollective.com/nest/backer/4/website)[](https://opencollective.com/nest/backer/5/website)[](https://opencollective.com/nest/backer/6/website)[](https://opencollective.com/nest/backer/7/website)[](https://opencollective.com/nest/backer/8/website)[](https://opencollective.com/nest/backer/9/website)[](https://opencollective.com/nest/backer/10/website)[](https://opencollective.com/nest/backer/11/website)[](https://opencollective.com/nest/backer/12/website)[](https://opencollective.com/nest/backer/13/website)[](https://opencollective.com/nest/backer/14/website)[](https://opencollective.com/nest/backer/15/website)[](https://opencollective.com/nest/backer/16/website)[](https://opencollective.com/nest/backer/17/website)[](https://opencollective.com/nest/backer/18/website)[](https://opencollective.com/nest/backer/19/website)[](https://opencollective.com/nest/backer/20/website)[](https://opencollective.com/nest/backer/21/website)[](https://opencollective.com/nest/backer/22/website)[](https://opencollective.com/nest/backer/23/website)[](https://opencollective.com/nest/backer/24/website)[](https://opencollective.com/nest/backer/25/website)[](https://opencollective.com/nest/backer/26/website)[](https://opencollective.com/nest/backer/27/website)[](https://opencollective.com/nest/backer/28/website)[](https://opencollective.com/nest/backer/29/website)

[Become a sponsor](https://opencollective.com/nest)

----
url: https://docs.nestjs.com/devtools/ci-cd-integration
----

[Skip to content](#content)

On this page

* [CI/CD integration](https://docs.nestjs.com/devtools/ci-cd-integration#cicd-integration)
* [Publishing graphs](https://docs.nestjs.com/devtools/ci-cd-integration#publishing-graphs)
* [Reports](https://docs.nestjs.com/devtools/ci-cd-integration#reports)
* [Build preview](https://docs.nestjs.com/devtools/ci-cd-integration#build-preview)
* [Integrations: GitHub Actions](https://docs.nestjs.com/devtools/ci-cd-integration#integrations-github-actions)
* [Integrations: Gitlab Pipelines](https://docs.nestjs.com/devtools/ci-cd-integration#integrations-gitlab-pipelines)
* [Other CI/CD tools](https://docs.nestjs.com/devtools/ci-cd-integration#other-cicd-tools)

### CI/CD integration

> **Hint** This chapter covers the Nest Devtools integration with the Nest framework. If you are looking for the Devtools application, visit the [Devtools](https://devtools.nestjs.com) website. CI/CD integration is available on the **[Enterprise](https://devtools.nestjs.com/settings)** plan.

Local usage is great for exploring your application as you build it, but the real payoff comes when Devtools becomes part of your delivery pipeline. CI/CD integration publishes a snapshot of your application's graph on every build. You get a running history of how your architecture evolves and, more importantly, an automatic report on every pull request that shows exactly what changed structurally. It's the difference between hoping a refactor didn't break anything and knowing it didn't.

See why teams rely on CI/CD integration to catch architectural drift before it ships:

#### Publishing graphs[#](/devtools/ci-cd-integration#publishing-graphs)

First, wire up the application bootstrap file (`main.ts`) to use the `GraphPublisher` class, exported from `@nestjs/devtools-integration` (see the [Devtools overview](/devtools/overview) if you haven't installed it yet):

```typescript

async function bootstrap() {
  const shouldPublishGraph = process.env.PUBLISH_GRAPH === 'true';

  const app = await NestFactory.create(AppModule, {
    snapshot: true,
    preview: shouldPublishGraph,
  });

  if (shouldPublishGraph) {
    await app.init();

    const publishOptions = { ... } // NOTE: this options object will vary depending on the CI/CD provider you're using
    const graphPublisher = new GraphPublisher(app);
    await graphPublisher.publish(publishOptions);

    await app.close();
  } else {
    await app.listen(3000);
  }
}
```

Here, `GraphPublisher` pushes your serialized graph to the centralized registry. `PUBLISH_GRAPH` is a custom environment variable that distinguishes a CI/CD publish run from a regular application bootstrap. Setting `preview` to `true` bootstraps the application in preview mode, which means the constructors and lifecycle hooks of your controllers, enhancers, and providers don't execute. This isn't **required**, but it keeps CI runs fast and simple (no database connection needed, for example).

The shape of `publishOptions` depends on your CI/CD provider. The sections below cover the most popular ones. If your provider isn't listed, the underlying fields are the same everywhere, so you can adapt the configuration in minutes.

Once your graph publishes successfully, you'll see output like this in your workflow logs:

Every published graph shows up as a new entry on the project's page:

#### Reports[#](/devtools/ci-cd-integration#reports)

Devtools generates a report for every build, **as long as** a matching snapshot already exists in the registry. If you open a pull request against `master` and a graph for `master` was already published, Devtools detects the differences and builds a report automatically. Otherwise, there's nothing to compare against yet.

Find your reports on the project's page (see [organizations](https://devtools.nestjs.com/organizations)).

This is where Devtools really earns its keep: catching changes that slip past code review. Say someone quietly changes the scope of a **deeply nested provider**. That's easy to miss in a diff, and impossible to miss in a report. Remove a guard from an endpoint, and it shows up as an affected change immediately. If integration or e2e tests didn't cover that route, you might not have noticed until it was too late. Devtools catches it at review time instead.

The same goes for **large codebases**: make a module global, and you immediately see how many new edges landed on the graph, usually a strong signal that something needs a second look.

Reports are also a great artifact to link in your pull request description. Instead of asking a reviewer to trust that "this only touches the billing module," you can point them at the exact set of nodes and edges that changed, turning an architectural claim into something they can verify in seconds.

#### Build preview[#](/devtools/ci-cd-integration#build-preview)

You can replay every published graph: click **Preview** to see exactly how it looked at that point in time. When a report is available, differences are highlighted directly on the graph:

* green nodes represent added elements
* light white nodes represent updated elements
* red nodes represent deleted elements

Here's what that looks like:

Being able to rewind and compare graphs makes troubleshooting straightforward, with no more guessing what changed and when. Set things up so that every pull request (or even every commit) gets its own snapshot in the registry, and you'll always have a clear trail to follow. Think of Devtools as version control that understands how Nest assembles your application, and can **show you** the difference instead of just describing it.

#### Integrations: GitHub Actions[#](/devtools/ci-cd-integration#integrations-github-actions)

Create a new workflow file in `.github/workflows` (for example, `publish-graph.yml`) with the following content:

```yaml

name: Devtools

on:
  push:
    branches:
      - master
  pull_request:
    branches:
      - '*'

jobs:
  publish:
    if: github.actor != 'dependabot[bot]'
    name: Publish graph
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: '22'
          cache: 'npm'
      - name: Install dependencies
        run: npm ci
      - name: Setup Environment (PR)
        if: ${{ github.event_name == 'pull_request' }}
        shell: bash
        run: |
          echo "COMMIT_SHA=${{ github.event.pull_request.head.sha }}" >>\${GITHUB_ENV}
      - name: Setup Environment (Push)
        if: ${{ github.event_name == 'push' }}
        shell: bash
        run: |
          echo "COMMIT_SHA=\${GITHUB_SHA}" >> \${GITHUB_ENV}
      - name: Publish
        run: PUBLISH_GRAPH=true npm run start
        env:
          DEVTOOLS_API_KEY: CHANGE_THIS_TO_YOUR_API_KEY
          REPOSITORY_NAME: ${{ github.event.repository.name }}
          BRANCH_NAME: ${{ github.head_ref || github.ref_name }}
          TARGET_SHA: ${{ github.event.pull_request.base.sha }}
```

> **Hint** For better security, store `DEVTOOLS_API_KEY` as a GitHub secret instead of hardcoding it. See [Creating secrets for a repository](https://docs.github.com/en/actions/security-guides/encrypted-secrets#creating-encrypted-secrets-for-a-repository).

This workflow runs on every pull request and on direct pushes to `master`. Adapt it to your project's needs; the one requirement is to provide the environment variables that `GraphPublisher` relies on.

Before the workflow can run, fill in the one remaining variable: `DEVTOOLS_API_KEY`. Generate a dedicated API key for your project on the **[API keys page](https://devtools.nestjs.com/settings/manage-api-keys)**.

Finally, go back to `main.ts` and fill in the `publishOptions` object we left empty earlier:

```typescript

const publishOptions = {
  apiKey: process.env.DEVTOOLS_API_KEY,
  repository: process.env.REPOSITORY_NAME,
  owner: process.env.GITHUB_REPOSITORY_OWNER,
  sha: process.env.COMMIT_SHA,
  target: process.env.TARGET_SHA,
  trigger: process.env.GITHUB_BASE_REF ? 'pull' : 'push',
  branch: process.env.BRANCH_NAME,
};
```

For the smoothest experience, we also recommend installing the **GitHub application** for your project by clicking "Integrate GitHub app" (see below). It's optional, but well worth it.

With the app installed, you see the status of your preview and report generation right inside the pull request:

#### Integrations: Gitlab Pipelines[#](/devtools/ci-cd-integration#integrations-gitlab-pipelines)

Create a `.gitlab-ci.yml` file in your project root with the following definition:

```yaml

image: node:22

stages:
  - build

cache:
  key:
    files:
      - package-lock.json
  paths:
    - node_modules/

workflow:
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
      when: always
    - if: $CI_COMMIT_BRANCH == "master" && $CI_PIPELINE_SOURCE == "push"
      when: always
    - when: never

install_dependencies:
  stage: build
  script:
    - npm ci

publish_graph:
  stage: build
  needs:
    - install_dependencies
  script: npm run start
  variables:
    PUBLISH_GRAPH: 'true'
    DEVTOOLS_API_KEY: 'CHANGE_THIS_TO_YOUR_API_KEY'
```

> **Hint** As with GitHub, we recommend storing `DEVTOOLS_API_KEY` as a CI/CD secret instead of committing it.

This pipeline runs on every merge request and on direct pushes to `master`. Adjust it to fit your project, but make sure the environment variables that `GraphPublisher` needs are always present.

One variable in this definition still needs a real value: `DEVTOOLS_API_KEY`. Generate a dedicated API key for your project on the **[API keys page](https://devtools.nestjs.com/settings/manage-api-keys)**.

Finally, go back to `main.ts` and fill in the `publishOptions` object we left empty earlier:

```typescript

const publishOptions = {
  apiKey: process.env.DEVTOOLS_API_KEY,
  repository: process.env.CI_PROJECT_NAME,
  owner: process.env.CI_PROJECT_ROOT_NAMESPACE,
  sha: process.env.CI_COMMIT_SHA,
  target: process.env.CI_MERGE_REQUEST_DIFF_BASE_SHA,
  trigger: process.env.CI_MERGE_REQUEST_DIFF_BASE_SHA ? 'pull' : 'push',
  branch:
    process.env.CI_COMMIT_BRANCH ??
    process.env.CI_MERGE_REQUEST_SOURCE_BRANCH_NAME,
};
```

#### Other CI/CD tools[#](/devtools/ci-cd-integration#other-cicd-tools)

The integration doesn't depend on GitHub or GitLab. All `GraphPublisher` needs is a handful of values that describe the current build (what triggered it, which commit, which branch), so it works with any provider, including [Bitbucket Pipelines](https://bitbucket.org/product/features/pipelines), [CircleCI](https://circleci.com/), and more.

Here's the full `publishOptions` shape and what each field represents, so you can wire up any pipeline:

```typescript

const publishOptions = {
  apiKey: process.env.DEVTOOLS_API_KEY, // This is your Nest Devtools API key
  repository: '?', // This is your repository name, for example, "my-api-repository"
  owner: '?', // This is your organization/team name, for example, "nestjs" OR in case of personal projects - your username
  sha: '?', // This represents the "current" commit SHA that triggered the workflow/pipeline
  target: '?', // This represents the "target" commit SHA (e.g., the last commit SHA of the "master" branch)
  // New build will be compared to the "target" build to generate a report
  // NOTE: Some CI/CD tools don't provide you with this information so instead, you can use the "targetBranch" property.
  // NOTE: In this case, the "target" commit SHA will be automatically resolved to the last commit SHA of the "targetBranch" stored in the database.
  // targetBranch: "master",
  trigger: isPr ? 'pull' : 'push', // Depending on whether the pipeline is triggered by a pull request or a regular push commit, you should set "pull" or "push"
  branch: '?', // This is the current branch name, for example, "develop" OR "feat/my-new-feature"
};
```

Most of these values are available in your CI/CD provider's built-in environment variables. See the [CircleCI built-in environment variables](https://circleci.com/docs/variables/#built-in-environment-variables) and [Bitbucket variables and secrets](https://support.atlassian.com/bitbucket-cloud/docs/variables-and-secrets/) references as a starting point.

For your pipeline triggers, we recommend the following setup:

* `push`: only for branches that represent a deployment environment, e.g., `master`, `main`, `staging`, or `production`.
* `pull request`: always, or at least when the **target branch** is a deployment environment (see above).

This combination keeps your registry populated with a snapshot of every deployable state of `master`, while still generating a report on every pull request that targets it. That pairing is what makes reports useful in the first place.

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/devtools/ci-cd.md)

----
url: https://docs.nestjs.com/v10/techniques/task-scheduling
----

* [Task Scheduling](https://docs.nestjs.com/v10/techniques/task-scheduling#task-scheduling)
* [Installation](https://docs.nestjs.com/v10/techniques/task-scheduling#installation)
* [Declarative cron jobs](https://docs.nestjs.com/v10/techniques/task-scheduling#declarative-cron-jobs)
* [Declarative intervals](https://docs.nestjs.com/v10/techniques/task-scheduling#declarative-intervals)
* [Declarative timeouts](https://docs.nestjs.com/v10/techniques/task-scheduling#declarative-timeouts)
* [Dynamic schedule module API](https://docs.nestjs.com/v10/techniques/task-scheduling#dynamic-schedule-module-api)
* [Dynamic cron jobs](https://docs.nestjs.com/v10/techniques/task-scheduling#dynamic-cron-jobs)
* [Dynamic intervals](https://docs.nestjs.com/v10/techniques/task-scheduling#dynamic-intervals)
* [Dynamic timeouts](https://docs.nestjs.com/v10/techniques/task-scheduling#dynamic-timeouts)
* [Example](https://docs.nestjs.com/v10/techniques/task-scheduling#example)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/techniques/task-scheduling.md "Suggest Edits")

### Task Scheduling

Task scheduling allows you to schedule arbitrary code (methods/functions) to execute at a fixed date/time, at recurring intervals, or once after a specified interval. In the Linux world, this is often handled by packages like [cron](https://en.wikipedia.org/wiki/Cron) at the OS level. For Node.js apps, there are several packages that emulate cron-like functionality. Nest provides the `@nestjs/schedule` package, which integrates with the popular Node.js [cron](https://github.com/kelektiv/node-cron) package. We'll cover this package in the current chapter.

#### Installation[#](/techniques/task-scheduling#installation)

To begin using it, we first install the required dependencies.

```bash

$ npm install --save @nestjs/schedule
```

To activate job scheduling, import the `ScheduleModule` into the root `AppModule` and run the `forRoot()` static method as shown below:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { ScheduleModule } from '@nestjs/schedule';

@Module({
  imports: [
    ScheduleModule.forRoot()
  ],
})
export class AppModule {}
```

The `.forRoot()` call initializes the scheduler and registers any declarative [cron jobs](techniques/task-scheduling#declarative-cron-jobs), [timeouts](techniques/task-scheduling#declarative-timeouts) and [intervals](techniques/task-scheduling#declarative-intervals) that exist within your app. Registration occurs when the `onApplicationBootstrap` lifecycle hook occurs, ensuring that all modules have loaded and declared any scheduled jobs.

#### Declarative cron jobs[#](/techniques/task-scheduling#declarative-cron-jobs)

A cron job schedules an arbitrary function (method call) to run automatically. Cron jobs can run:

* Once, at a specified date/time.
* On a recurring basis; recurring jobs can run at a specified instant within a specified interval (for example, once per hour, once per week, once every 5 minutes)

Declare a cron job with the `@Cron()` decorator preceding the method definition containing the code to be executed, as follows:

```typescript

import { Injectable, Logger } from '@nestjs/common';
import { Cron } from '@nestjs/schedule';

@Injectable()
export class TasksService {
  private readonly logger = new Logger(TasksService.name);

  @Cron('45 * * * * *')
  handleCron() {
    this.logger.debug('Called when the current second is 45');
  }
}
```

In this example, the `handleCron()` method will be called each time the current second is `45`. In other words, the method will be run once per minute, at the 45 second mark.

The `@Cron()` decorator supports the following standard [cron patterns](http://crontab.org/):

* Asterisk (e.g. `*`)
* Ranges (e.g. `1-3,5`)
* Steps (e.g. `*/2`)

In the example above, we passed `45 * * * * *` to the decorator. The following key shows how each position in the cron pattern string is interpreted:

```javascript

* * * * * *
| | | | | |
| | | | | day of week
| | | | months
| | | day of month
| | hours
| minutes
seconds (optional)
```

Some sample cron patterns are:

|                     |                                             |
| ------------------- | ------------------------------------------- |
| `* * * * * *`       | every second                                |
| `45 * * * * *`      | every minute, on the 45th second            |
| `0 10 * * * *`      | every hour, at the start of the 10th minute |
| `0 */30 9-17 * * *` | every 30 minutes between 9am and 5pm        |
| `0 30 11 * * 1-5`   | Monday to Friday at 11:30am                 |

The `@nestjs/schedule` package provides a convenient enum with commonly used cron patterns. You can use this enum as follows:

```typescript

import { Injectable, Logger } from '@nestjs/common';
import { Cron, CronExpression } from '@nestjs/schedule';

@Injectable()
export class TasksService {
  private readonly logger = new Logger(TasksService.name);

  @Cron(CronExpression.EVERY_30_SECONDS)
  handleCron() {
    this.logger.debug('Called every 30 seconds');
  }
}
```

In this example, the `handleCron()` method will be called every `30` seconds. If an exception occurs, it will be logged to the console, as every method annotated with `@Cron()` is automatically wrapped in a `try-catch` block.

Alternatively, you can supply a JavaScript `Date` object to the `@Cron()` decorator. Doing so causes the job to execute exactly once, at the specified date.

> **Hint** Use JavaScript date arithmetic to schedule jobs relative to the current date. For example, `@Cron(new Date(Date.now() + 10 * 1000))` to schedule a job to run 10 seconds after the app starts.

Also, you can supply additional options as the second parameter to the `@Cron()` decorator.

|             |                                                                                                                                                                                                                                                        |
| ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `name`      | Useful to access and control a cron job after it's been declared.                                                                                                                                                                                      |
| `timeZone`  | Specify the timezone for the execution. This will modify the actual time relative to your timezone. If the timezone is invalid, an error is thrown. You can check all timezones available at [Moment Timezone](http://momentjs.com/timezone/) website. |
| `utcOffset` | This allows you to specify the offset of your timezone rather than using the `timeZone` param.                                                                                                                                                         |
| `disabled`  | This indicates whether the job will be executed at all.                                                                                                                                                                                                |

```typescript

import { Injectable } from '@nestjs/common';
import { Cron, CronExpression } from '@nestjs/schedule';

@Injectable()
export class NotificationService {
  @Cron('* * 0 * * *', {
    name: 'notifications',
    timeZone: 'Europe/Paris',
  })
  triggerNotifications() {}
}
```

You can access and control a cron job after it's been declared, or dynamically create a cron job (where its cron pattern is defined at runtime) with the [Dynamic API](/techniques/task-scheduling#dynamic-schedule-module-api). To access a declarative cron job via the API, you must associate the job with a name by passing the `name` property in an optional options object as the second argument of the decorator.

#### Declarative intervals[#](/techniques/task-scheduling#declarative-intervals)

To declare that a method should run at a (recurring) specified interval, prefix the method definition with the `@Interval()` decorator. Pass the interval value, as a number in milliseconds, to the decorator as shown below:

```typescript

@Interval(10000)
handleInterval() {
  this.logger.debug('Called every 10 seconds');
}
```

> **Hint** This mechanism uses the JavaScript `setInterval()` function under the hood. You can also utilize a cron job to schedule recurring jobs.

If you want to control your declarative interval from outside the declaring class via the [Dynamic API](/techniques/task-scheduling#dynamic-schedule-module-api), associate the interval with a name using the following construction:

```typescript

@Interval('notifications', 2500)
handleInterval() {}
```

```typescript

@Timeout(5000)
handleTimeout() {
  this.logger.debug('Called once after 5 seconds');
}
```

> **Hint** This mechanism uses the JavaScript `setTimeout()` function under the hood.

If an exception occurs, it will be logged to the console, as every method annotated with `@Timeout()` is automatically wrapped in a `try-catch` block.

If you want to control your declarative timeout from outside the declaring class via the [Dynamic API](/techniques/task-scheduling#dynamic-schedule-module-api), associate the timeout with a name using the following construction:

```typescript

@Timeout('notifications', 2500)
handleTimeout() {}
```

The [Dynamic API](techniques/task-scheduling#dynamic-timeouts) also enables **creating** dynamic timeouts, where the timeout's properties are defined at runtime, and **listing and deleting** them.

#### Dynamic schedule module API[#](/techniques/task-scheduling#dynamic-schedule-module-api)

The `@nestjs/schedule` module provides a dynamic API that enables managing declarative [cron jobs](techniques/task-scheduling#declarative-cron-jobs), [timeouts](techniques/task-scheduling#declarative-timeouts) and [intervals](techniques/task-scheduling#declarative-intervals). The API also enables creating and managing **dynamic** cron jobs, timeouts and intervals, where the properties are defined at runtime.

#### Dynamic cron jobs[#](/techniques/task-scheduling#dynamic-cron-jobs)

Obtain a reference to a `CronJob` instance by name from anywhere in your code using the `SchedulerRegistry` API. First, inject `SchedulerRegistry` using standard constructor injection:

```typescript

constructor(private schedulerRegistry: SchedulerRegistry) {}
```

> **Hint** Import the `SchedulerRegistry` from the `@nestjs/schedule` package.

Then use it in a class as follows. Assume a cron job was created with the following declaration:

```typescript

@Cron('* * 8 * * *', {
  name: 'notifications',
})
triggerNotifications() {}
```

Access this job using the following:

```typescript

const job = this.schedulerRegistry.getCronJob('notifications');

job.stop();
console.log(job.lastDate());
```

> **Hint** Use `toJSDate()` on `DateTime` objects to render them as a JavaScript Date equivalent to this DateTime.

**Create** a new cron job dynamically using the `SchedulerRegistry#addCronJob` method, as follows:

```typescript

addCronJob(name: string, seconds: string) {
  const job = new CronJob(`${seconds} * * * * *`, () => {
    this.logger.warn(`time (${seconds}) for job ${name} to run!`);
  });

  this.schedulerRegistry.addCronJob(name, job);
  job.start();

  this.logger.warn(
    `job ${name} added for each minute at ${seconds} seconds!`,
  );
}
```

In this code, we use the `CronJob` object from the `cron` package to create the cron job. The `CronJob` constructor takes a cron pattern (just like the `@Cron()`[decorator](techniques/task-scheduling#declarative-cron-jobs)) as its first argument, and a callback to be executed when the cron timer fires as its second argument. The `SchedulerRegistry#addCronJob` method takes two arguments: a name for the `CronJob`, and the `CronJob` object itself.

> **Warning** Remember to inject the `SchedulerRegistry` before accessing it. Import `CronJob` from the `cron` package.

**Delete** a named cron job using the `SchedulerRegistry#deleteCronJob` method, as follows:

```typescript

deleteCron(name: string) {
  this.schedulerRegistry.deleteCronJob(name);
  this.logger.warn(`job ${name} deleted!`);
}
```

**List** all cron jobs using the `SchedulerRegistry#getCronJobs` method as follows:

```typescript

getCrons() {
  const jobs = this.schedulerRegistry.getCronJobs();
  jobs.forEach((value, key, map) => {
    let next;
    try {
      next = value.nextDate().toJSDate();
    } catch (e) {
      next = 'error: next fire date is in the past!';
    }
    this.logger.log(`job: ${key} -> next: ${next}`);
  });
}
```

The `getCronJobs()` method returns a `map`. In this code, we iterate over the map and attempt to access the `nextDate()` method of each `CronJob`. In the `CronJob` API, if a job has already fired and has no future firing date, it throws an exception.

#### Dynamic intervals[#](/techniques/task-scheduling#dynamic-intervals)

Obtain a reference to an interval with the `SchedulerRegistry#getInterval` method. As above, inject `SchedulerRegistry` using standard constructor injection:

```typescript

constructor(private schedulerRegistry: SchedulerRegistry) {}
```

And use it as follows:

```typescript

const interval = this.schedulerRegistry.getInterval('notifications');
clearInterval(interval);
```

**Create** a new interval dynamically using the `SchedulerRegistry#addInterval` method, as follows:

```typescript

addInterval(name: string, milliseconds: number) {
  const callback = () => {
    this.logger.warn(`Interval ${name} executing at time (${milliseconds})!`);
  };

  const interval = setInterval(callback, milliseconds);
  this.schedulerRegistry.addInterval(name, interval);
}
```

In this code, we create a standard JavaScript interval, then pass it to the `SchedulerRegistry#addInterval` method. That method takes two arguments: a name for the interval, and the interval itself.

**Delete** a named interval using the `SchedulerRegistry#deleteInterval` method, as follows:

```typescript

deleteInterval(name: string) {
  this.schedulerRegistry.deleteInterval(name);
  this.logger.warn(`Interval ${name} deleted!`);
}
```

**List** all intervals using the `SchedulerRegistry#getIntervals` method as follows:

```typescript

getIntervals() {
  const intervals = this.schedulerRegistry.getIntervals();
  intervals.forEach(key => this.logger.log(`Interval: ${key}`));
}
```

#### Dynamic timeouts[#](/techniques/task-scheduling#dynamic-timeouts)

Obtain a reference to a timeout with the `SchedulerRegistry#getTimeout` method. As above, inject `SchedulerRegistry` using standard constructor injection:

```typescript

constructor(private readonly schedulerRegistry: SchedulerRegistry) {}
```

And use it as follows:

```typescript

const timeout = this.schedulerRegistry.getTimeout('notifications');
clearTimeout(timeout);
```

**Create** a new timeout dynamically using the `SchedulerRegistry#addTimeout` method, as follows:

```typescript

addTimeout(name: string, milliseconds: number) {
  const callback = () => {
    this.logger.warn(`Timeout ${name} executing after (${milliseconds})!`);
  };

  const timeout = setTimeout(callback, milliseconds);
  this.schedulerRegistry.addTimeout(name, timeout);
}
```

In this code, we create a standard JavaScript timeout, then pass it to the `SchedulerRegistry#addTimeout` method. That method takes two arguments: a name for the timeout, and the timeout itself.

**Delete** a named timeout using the `SchedulerRegistry#deleteTimeout` method, as follows:

```typescript

deleteTimeout(name: string) {
  this.schedulerRegistry.deleteTimeout(name);
  this.logger.warn(`Timeout ${name} deleted!`);
}
```

**List** all timeouts using the `SchedulerRegistry#getTimeouts` method as follows:

```typescript

getTimeouts() {
  const timeouts = this.schedulerRegistry.getTimeouts();
  timeouts.forEach(key => this.logger.log(`Timeout: ${key}`));
}
```

#### Example[#](/techniques/task-scheduling#example)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/27-scheduling).

----
url: https://docs.nestjs.com/v8/faq/raw-body
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Raw body](https://docs.nestjs.com/v8/faq/raw-body#raw-body)
* [Use with Express](https://docs.nestjs.com/v8/faq/raw-body#use-with-express)
* [Use with Fastify](https://docs.nestjs.com/v8/faq/raw-body#use-with-fastify)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/faq/raw-body.md "Suggest Edits")

### Raw body

One of the most common use-case for having access to the raw request body is performing webhook signature verifications. Usually to perform webhook signature validations the unserialized request body is required to calculate an HMAC hash.

#### Use with Express

First enable the option when creating your Nest Express application:

```typescript

const app = await NestFactory.create(AppModule, {
  rawBody: true,
});
await app.listen(3000);
```

To access the raw request body in a controller, a convenience interface `RawBodyRequest` is provided to expose a `rawBody` field on the request: use the interface `RawBodyRequest` type:

```typescript

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

@Controller('cats')
class CatsController {
  @Post()
  create(@Req() req: RawBodyRequest<Request>) {
    const raw = req.rawBody; // returns a `Buffer`.
  }
}
```

#### Use with Fastify

First enable the option when creating your Nest Fastify application:

```typescript

const app = await NestFactory.create<NestFastifyApplication>(
  AppModule,
  new FastifyAdapter()
  {
    rawBody: true,
  }
);
await app.listen(3000);
```

To access the raw request body in a controller, a convenience interface `RawBodyRequest` is provided to expose a `rawBody` field on the request: use the interface `RawBodyRequest` type:

```typescript

import { Controller, Post, RawBodyRequest, Req } from '@nestjs/common';
import { FastifyRequest } from 'fastify';

@Controller('cats')
class CatsController {
  @Post()
  create(@Req() req: RawBodyRequest<FastifyRequest>) {
    const raw = req.rawBody; // returns a `Buffer`.
  }
}
```

----
url: https://docs.nestjs.com/v8/techniques/validation
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Validation](https://docs.nestjs.com/v8/techniques/validation#validation)
* [Overview](https://docs.nestjs.com/v8/techniques/validation#overview)
* [Using the built-in ValidationPipe](https://docs.nestjs.com/v8/techniques/validation#using-the-built-in-validationpipe)
* [Auto-validation](https://docs.nestjs.com/v8/techniques/validation#auto-validation)
* [Disable detailed errors](https://docs.nestjs.com/v8/techniques/validation#disable-detailed-errors)
* [Stripping properties](https://docs.nestjs.com/v8/techniques/validation#stripping-properties)
* [Transform payload objects](https://docs.nestjs.com/v8/techniques/validation#transform-payload-objects)
* [Explicit conversion](https://docs.nestjs.com/v8/techniques/validation#explicit-conversion)
* [Mapped types](https://docs.nestjs.com/v8/techniques/validation#mapped-types)
* [Parsing and validating arrays](https://docs.nestjs.com/v8/techniques/validation#parsing-and-validating-arrays)
* [WebSockets and Microservices](https://docs.nestjs.com/v8/techniques/validation#websockets-and-microservices)
* [Learn more](https://docs.nestjs.com/v8/techniques/validation#learn-more)

In the [Pipes](/v8/pipes) chapter, we went through the process of building simple pipes and binding them to controllers, methods or to the global app to demonstrate how the process works. Be sure to review that chapter to best understand the topics of this chapter. Here, we'll focus on various **real world** use cases of the `ValidationPipe`, and show how to use some of its advanced customization features.

#### Using the built-in ValidationPipe[#](/techniques/validation#using-the-built-in-validationpipe)

To begin using it, we first install the required dependency.

```bash

$ npm i --save class-validator class-transformer
```

> **Hint** The `ValidationPipe` is exported from the `@nestjs/common` package.

Because this pipe uses the [`class-validator`](https://github.com/typestack/class-validator) and [`class-transformer`](https://github.com/typestack/class-transformer) libraries, there are many options available. You configure these settings via a configuration object passed to the pipe. Following are the built-in options:

```typescript

export interface ValidationPipeOptions extends ValidatorOptions {
  transform?: boolean;
  disableErrorMessages?: boolean;
  exceptionFactory?: (errors: ValidationError[]) => any;
}
```

In addition to these, all `class-validator` options (inherited from the `ValidatorOptions` interface) are available:

| Option                    | Type       | Description                                                                                                                           |
| ------------------------- | ---------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| `enableDebugMessages`     | `boolean`  | If set to true, validator will print extra warning messages to the console when something is not right.                               |
| `skipUndefinedProperties` | `boolean`  | If set to true then validator will skip validation of all properties that are undefined in the validating object.                     |
| `skipNullProperties`      | `boolean`  | If set to true then validator will skip validation of all properties that are null in the validating object.                          |
| `skipMissingProperties`   | `boolean`  | If set to true then validator will skip validation of all properties that are null or undefined in the validating object.             |
| `whitelist`               | `boolean`  | If set to true, validator will strip validated (returned) object of any properties that do not use any validation decorators.         |
| `forbidNonWhitelisted`    | `boolean`  | If set to true, instead of stripping non-whitelisted properties validator will throw an exception.                                    |
| `forbidUnknownValues`     | `boolean`  | If set to true, attempts to validate unknown objects fail immediately.                                                                |
| `disableErrorMessages`    | `boolean`  | If set to true, validation errors will not be returned to the client.                                                                 |
| `errorHttpStatusCode`     | `number`   | This setting allows you to specify which exception type will be used in case of an error. By default it throws `BadRequestException`. |
| `exceptionFactory`        | `Function` | Takes an array of the validation errors and returns an exception object to be thrown.                                                 |
| `groups`                  | `string[]` | Groups to be used during validation of the object.                                                                                    |
| `always`                  | `boolean`  | Set default for `always` option of decorators. Default can be overridden in decorator options                                         |
| `strictGroups`            | `boolean`  | If `groups` is not given or is empty, ignore decorators with at least one group.                                                      |
| `dismissDefaultMessages`  | `boolean`  | If set to true, the validation will not use default messages. Error message always will be `undefined` if its not explicitly set.     |
| `validationError.target`  | `boolean`  | Indicates if target should be exposed in `ValidationError`.                                                                           |
| `validationError.value`   | `boolean`  | Indicates if validated value should be exposed in `ValidationError`.                                                                  |
| `stopAtFirstError`        | `boolean`  | When set to true, validation of the given property will stop after encountering the first error. Defaults to false.                   |

> **Notice** Find more information about the `class-validator` package in its [repository](https://github.com/typestack/class-validator).

#### Auto-validation[#](/techniques/validation#auto-validation)

We'll start by binding `ValidationPipe` at the application level, thus ensuring all endpoints are protected from receiving incorrect data.

```typescript

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.useGlobalPipes(new ValidationPipe());
  await app.listen(3000);
}
bootstrap();
```

To test our pipe, let's create a basic endpoint.

```typescript

@Post()
create(@Body() createUserDto: CreateUserDto) {
  return 'This action adds a new user';
}
```

> **Hint** Since TypeScript does not store metadata about **generics or interfaces**, when you use them in your DTOs, `ValidationPipe` may not be able to properly validate incoming data. For this reason, consider using concrete classes in your DTOs.

> **Hint** When importing your DTOs, you can't use a type-only import as that would be erased at runtime, i.e. remember to `import { CreateUserDto }` instead of `import type { CreateUserDto }`.

Now we can add a few validation rules in our `CreateUserDto`. We do this using decorators provided by the `class-validator` package, described in detail [here](https://github.com/typestack/class-validator#validation-decorators). In this fashion, any route that uses the `CreateUserDto` will automatically enforce these validation rules.

```typescript

import { IsEmail, IsNotEmpty } from 'class-validator';

export class CreateUserDto {
  @IsEmail()
  email: string;

  @IsNotEmpty()
  password: string;
}
```

With these rules in place, if a request hits our endpoint with an invalid `email` property in the request body, the application will automatically respond with a `400 Bad Request` code, along with the following response body:

```json

{
  "statusCode": 400,
  "error": "Bad Request",
  "message": ["email must be an email"]
}
```

In addition to validating request bodies, the `ValidationPipe` can be used with other request object properties as well. Imagine that we would like to accept `:id` in the endpoint path. To ensure that only numbers are accepted for this request parameter, we can use the following construct:

```typescript

@Get(':id')
findOne(@Param() params: FindOneParams) {
  return 'This action returns a user';
}
```

`FindOneParams`, like a DTO, is simply a class that defines validation rules using `class-validator`. It would look like this:

```typescript

import { IsNumberString } from 'class-validator';

export class FindOneParams {
  @IsNumberString()
  id: number;
}
```

#### Disable detailed errors[#](/techniques/validation#disable-detailed-errors)

Error messages can be helpful to explain what was incorrect in a request. However, some production environments prefer to disable detailed errors. Do this by passing an options object to the `ValidationPipe`:

```typescript

app.useGlobalPipes(
  new ValidationPipe({
    disableErrorMessages: true,
  }),
);
```

As a result, detailed error messages won't be displayed in the response body.

#### Stripping properties[#](/techniques/validation#stripping-properties)

Our `ValidationPipe` can also filter out properties that should not be received by the method handler. In this case, we can **whitelist** the acceptable properties, and any property not included in the whitelist is automatically stripped from the resulting object. For example, if our handler expects `email` and `password` properties, but a request also includes an `age` property, this property can be automatically removed from the resulting DTO. To enable such behavior, set `whitelist` to `true`.

```typescript

app.useGlobalPipes(
  new ValidationPipe({
    whitelist: true,
  }),
);
```

```typescript

@Post()
@UsePipes(new ValidationPipe({ transform: true }))
async create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

To enable this behavior globally, set the option on a global pipe:

```typescript

app.useGlobalPipes(
  new ValidationPipe({
    transform: true,
  }),
);
```

With the auto-transformation option enabled, the `ValidationPipe` will also perform conversion of primitive types. In the following example, the `findOne()` method takes one argument which represents an extracted `id` path parameter:

```typescript

@Get(':id')
findOne(@Param('id') id: number) {
  console.log(typeof id === 'number'); // true
  return 'This action returns a user';
}
```

By default, every path parameter and query parameter comes over the network as a `string`. In the above example, we specified the `id` type as a `number` (in the method signature). Therefore, the `ValidationPipe` will try to automatically convert a string identifier to a number.

#### Explicit conversion[#](/techniques/validation#explicit-conversion)

In the above section, we showed how the `ValidationPipe` can implicitly transform query and path parameters based on the expected type. However, this feature requires having auto-transformation enabled.

Alternatively (with auto-transformation disabled), you can explicitly cast values using the `ParseIntPipe` or `ParseBoolPipe` (note that `ParseStringPipe` is not needed because, as mentioned earlier, every path parameter and query parameter comes over the network as a `string` by default).

```typescript

@Get(':id')
findOne(
  @Param('id', ParseIntPipe) id: number,
  @Query('sort', ParseBoolPipe) sort: boolean,
) {
  console.log(typeof id === 'number'); // true
  console.log(typeof sort === 'boolean'); // true
  return 'This action returns a user';
}
```

> **Hint** The `ParseIntPipe` and `ParseBoolPipe` are exported from the `@nestjs/common` package.

#### Mapped types[#](/techniques/validation#mapped-types)

As you build out features like **CRUD** (Create/Read/Update/Delete) it's often useful to construct variants on a base entity type. Nest provides several utility functions that perform type transformations to make this task more convenient.

> **Warning** If your application uses the `@nestjs/swagger` package, see [this chapter](/v8/openapi/mapped-types) for more information about Mapped Types. Likewise, if you use the `@nestjs/graphql` package see [this chapter](/v8/graphql/mapped-types). Both packages heavily rely on types and so they require a different import to be used. Therefore, if you used `@nestjs/mapped-types` (instead of an appropriate one, either `@nestjs/swagger` or `@nestjs/graphql` depending on the type of your app), you may face various, undocumented side-effects.

When building input validation types (also called DTOs), it's often useful to build **create** and **update** variations on the same type. For example, the **create** variant may require all fields, while the **update** variant may make all fields optional.

Nest provides the `PartialType()` utility function to make this task easier and minimize boilerplate.

The `PartialType()` function returns a type (class) with all the properties of the input type set to optional. For example, suppose we have a **create** type as follows:

```typescript

export class CreateCatDto {
  name: string;
  age: number;
  breed: string;
}
```

By default, all of these fields are required. To create a type with the same fields, but with each one optional, use `PartialType()` passing the class reference (`CreateCatDto`) as an argument:

```typescript

export class UpdateCatDto extends PartialType(CreateCatDto) {}
```

> **Hint** The `PartialType()` function is imported from the `@nestjs/mapped-types` package.

The `PickType()` function constructs a new type (class) by picking a set of properties from an input type. For example, suppose we start with a type like:

```typescript

export class CreateCatDto {
  name: string;
  age: number;
  breed: string;
}
```

We can pick a set of properties from this class using the `PickType()` utility function:

```typescript

export class UpdateCatAgeDto extends PickType(CreateCatDto, ['age'] as const) {}
```

> **Hint** The `PickType()` function is imported from the `@nestjs/mapped-types` package.

The `OmitType()` function constructs a type by picking all properties from an input type and then removing a particular set of keys. For example, suppose we start with a type like:

```typescript

export class CreateCatDto {
  name: string;
  age: number;
  breed: string;
}
```

We can generate a derived type that has every property **except**`name` as shown below. In this construct, the second argument to `OmitType` is an array of property names.

```typescript

export class UpdateCatDto extends OmitType(CreateCatDto, ['name'] as const) {}
```

> **Hint** The `OmitType()` function is imported from the `@nestjs/mapped-types` package.

The `IntersectionType()` function combines two types into one new type (class). For example, suppose we start with two types like:

```typescript

export class CreateCatDto {
  name: string;
  breed: string;
}

export class AdditionalCatInfo {
  color: string;
}
```

We can generate a new type that combines all properties in both types.

```typescript

export class UpdateCatDto extends IntersectionType(
  CreateCatDto,
  AdditionalCatInfo,
) {}
```

> **Hint** The `IntersectionType()` function is imported from the `@nestjs/mapped-types` package.

The type mapping utility functions are composable. For example, the following will produce a type (class) that has all of the properties of the `CreateCatDto` type except for `name`, and those properties will be set to optional:

```typescript

export class UpdateCatDto extends PartialType(
  OmitType(CreateCatDto, ['name'] as const),
) {}
```

#### Parsing and validating arrays[#](/techniques/validation#parsing-and-validating-arrays)

TypeScript does not store metadata about generics or interfaces, so when you use them in your DTOs, `ValidationPipe` may not be able to properly validate incoming data. For instance, in the following code, `createUserDtos` won't be correctly validated:

```typescript

@Post()
createBulk(@Body() createUserDtos: CreateUserDto[]) {
  return 'This action adds new users';
}
```

To validate the array, create a dedicated class which contains a property that wraps the array, or use the `ParseArrayPipe`.

```typescript

@Post()
createBulk(
  @Body(new ParseArrayPipe({ items: CreateUserDto }))
  createUserDtos: CreateUserDto[],
) {
  return 'This action adds new users';
}
```

In addition, the `ParseArrayPipe` may come in handy when parsing query parameters. Let's consider a `findByIds()` method that returns users based on identifiers passed as query parameters.

```typescript

@Get()
findByIds(
  @Query('ids', new ParseArrayPipe({ items: Number, separator: ',' }))
  ids: number[],
) {
  return 'This action returns users by ids';
}
```

This construction validates the incoming query parameters from an HTTP `GET` request like the following:

```bash

GET /?ids=1,2,3
```

#### WebSockets and Microservices[#](/techniques/validation#websockets-and-microservices)

While this chapter shows examples using HTTP style applications (e.g., Express or Fastify), the `ValidationPipe` works the same for WebSockets and microservices, regardless of the transport method that is used.

#### Learn more[#](/techniques/validation#learn-more)

Read more about custom validators, error messages, and available decorators as provided by the `class-validator` package [here](https://github.com/typestack/class-validator).

----
url: https://docs.nestjs.com/v5/graphql/quick-start
----

### Quick start

GraphQL is a query language for APIs and a runtime for fulfilling those queries with your existing data. It is an elegant approach that solves many of these problems that we have with typical REST apis. There is a great [comparison](https://dev-blog.apollodata.com/graphql-vs-rest-5d425123e34b) between GraphQL and REST. In this set of articles, we're not going to explain what the GraphQL is, but rather show how to work with the dedicated `@nestjs/graphql` module. This chapter assumes that you are already familiar with GraphQL essentials.

The `GraphQLModule` is nothing more than a wrapper around the [Apollo](https://www.apollographql.com/) server. We don't reinvent the wheel but provide a ready to use module instead, that brings a clean way to play with the GraphQL and Nest together.

#### Installation

Firstly, we need to install the required packages:

TypeScript

```typescript

$ npm i --save @nestjs/graphql apollo-server-express graphql-tools graphql
```

#### Getting started

Once the packages are installed, we can register the `GraphQlModule`.

app.module.ts

JS TS

TypeScript

```typescript

import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';

@Module({
  imports: [
    GraphQLModule.forRoot({
      typePaths: ['./**/*.graphql'],
    }),
  ],
})
export class ApplicationModule {}
```

The `typePaths` property indicates where the `GraphQLModule` should look for the GraphQL files. Besides, all options will be passed down to the underlying Apollo instance (read more about available settings [here](https://www.apollographql.com/docs/apollo-server/v2/api/apollo-server.html#constructor-options-lt-ApolloServer-gt)). For instance, if you want to disable the `playground` and turn off the `debug` mode, simply pass below options:

app.module.ts

JS TS

TypeScript

```typescript

import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';

@Module({
  imports: [
    GraphQLModule.forRoot({
      typePaths: ['./**/*.graphql'],
      debug: false,
      playground: false,
    }),
  ],
})
export class ApplicationModule {}
```

As mentioned, all these settings will be forwarded to the `ApolloServer` constructor.

#### Playground

The playground is a graphical, interactive, in-browser GraphQL IDE, available by default on the same URL as the GraphQL server itself. Whilst your application is running in the background, open your web browser and navigate to `http://localhost:3000/graphql` (host and port may vary depending on your configuration).

#### Multiple endpoints

Another useful feature of this module is a capability to serve multiple endpoints at once. Thanks to that, you can decide which modules should be included in which endpoint. By default, `GraphQL` searches for resolvers throughout the whole app. To limit only a subset of modules, you can use the `include` property.

TypeScript

```typescript

GraphQLModule.forRoot({
  include: [CatsModule],
})
```

#### Async configuration

Quite often you might want to asynchronously pass your module options instead of passing them beforehand. In such case, use `forRootAsync()` method, that provides a couple of various ways to deal with async data.

First possible approach is to use a factory function:

TypeScript

```typescript

GraphQLModule.forRootAsync({
  useFactory: () => ({
    typePaths: ['./**/*.graphql'],
  }),
})
```

Obviously, our factory behaves like every other one (might be `async` and is able to inject dependencies through `inject`).

TypeScript

```typescript

GraphQLModule.forRootAsync({
  imports: [ConfigModule],
  useFactory: async (configService: ConfigService) => ({
    typePaths: configService.getString('GRAPHQL_TYPE_PATHS'),
  }),
  inject: [ConfigService],
})
```

Alternatively, you are able to use class instead of a factory.

TypeScript

```typescript

GraphQLModule.forRootAsync({
  useClass: GqlConfigService,
})
```

Above construction will instantiate `GqlConfigService` inside `GraphQLModule` and will leverage it to create options object. The `GqlConfigService` has to implement `GqlOptionsFactory` interface.

TypeScript

```typescript

@Injectable()
class GqlConfigService implements GqlOptionsFactory {
  createGqlOptions(): GqlModuleOptions {
    return {
      typePaths: ['./**/*.graphql'],
    };
  }
}
```

In order to prevent the creation of `GqlConfigService` inside `GraphQLModule` and use a provider imported from a different module, you can use the `useExisting` syntax.

TypeScript

```typescript

GraphQLModule.forRootAsync({
  imports: [ConfigModule],
  useExisting: ConfigService,
})
```

It works the same as `useClass` with one critical difference - `GraphQLModule` will lookup imported modules to reuse already created `ConfigService`, instead of instantiating it on its own.

#### Example

A fully working sample is available [here](https://github.com/nestjs/nest/tree/master/sample/12-graphql-apollo).

* Quick start
* Installation
* Getting started
* Playground
* Multiple endpoints

----
url: https://docs.nestjs.com/microservices/basics
----

[Skip to content](#content)

On this page

* [Overview](https://docs.nestjs.com/microservices/basics#overview)
* [Installation](https://docs.nestjs.com/microservices/basics#installation)
* [Getting started](https://docs.nestjs.com/microservices/basics#getting-started)
* [Message and Event Patterns](https://docs.nestjs.com/microservices/basics#message-and-event-patterns)
* [Request-response](https://docs.nestjs.com/microservices/basics#request-response)
* [Asynchronous responses](https://docs.nestjs.com/microservices/basics#asynchronous-responses)
* [Event-based](https://docs.nestjs.com/microservices/basics#event-based)
* [Additional request details](https://docs.nestjs.com/microservices/basics#additional-request-details)
* [Client (producer class)](https://docs.nestjs.com/microservices/basics#client-producer-class)
* [Sending messages](https://docs.nestjs.com/microservices/basics#sending-messages)
* [Publishing events](https://docs.nestjs.com/microservices/basics#publishing-events)
* [Request-scoping](https://docs.nestjs.com/microservices/basics#request-scoping)
* [Instance status updates](https://docs.nestjs.com/microservices/basics#instance-status-updates)
* [Listening to internal events](https://docs.nestjs.com/microservices/basics#listening-to-internal-events)
* [Underlying driver access](https://docs.nestjs.com/microservices/basics#underlying-driver-access)
* [Handling timeouts](https://docs.nestjs.com/microservices/basics#handling-timeouts)
* [Tracing a request across services](https://docs.nestjs.com/microservices/basics#tracing-a-request-across-services)
* [TLS support](https://docs.nestjs.com/microservices/basics#tls-support)
* [Dynamic configuration](https://docs.nestjs.com/microservices/basics#dynamic-configuration)

### Overview

In addition to traditional (sometimes called monolithic) application architectures, Nest natively supports the microservice architectural style of development. Most of the concepts discussed elsewhere in this documentation, such as dependency injection, decorators, exception filters, pipes, guards, and interceptors, apply equally to microservices. Wherever possible, Nest abstracts implementation details so that the same components can run across HTTP-based platforms, WebSockets, and microservices. This section covers the aspects of Nest that are specific to microservices.

In Nest, a microservice is fundamentally an application that uses a different **transport** layer than HTTP.

Nest supports several built-in transport layer implementations, called **transporters**, which are responsible for transmitting messages between different microservice instances. Most transporters natively support both **request-response** and **event-based** message styles. Nest abstracts the implementation details of each transporter behind a canonical interface for both styles. This lets you switch from one transport layer to another (e.g., to take advantage of the reliability or performance features of a particular transport layer) without changing your application code.

#### Installation[#](/microservices/basics#installation)

To start building microservices, first install the required package:

```bash

$ npm i --save @nestjs/microservices
```

#### Getting started[#](/microservices/basics#getting-started)

To instantiate a microservice, use the `createMicroservice()` method of the `NestFactory` class:

main.ts

JS TS

```typescript

import { NestFactory } from '@nestjs/core';
import { Transport, MicroserviceOptions } from '@nestjs/microservices';
import { AppModule } from './app.module.js';

async function bootstrap() {
  const app = await NestFactory.createMicroservice<MicroserviceOptions>(
    AppModule,
    {
      transport: Transport.TCP,
    },
  );
  await app.listen();
}
await bootstrap();
```

```typescript

import { NestFactory } from '@nestjs/core';
import { Transport } from '@nestjs/microservices';
import { AppModule } from './app.module.js';

async function bootstrap() {
  const app = await NestFactory.createMicroservice(AppModule, {
    transport: Transport.TCP,
  });
  await app.listen();
}
await bootstrap();
```

> **Hint** Microservices use the **TCP** transport layer by default.

The second argument of the `createMicroservice()` method is an `options` object with two members:

|             |                                                                            |
| ----------- | -------------------------------------------------------------------------- |
| `transport` | Specifies the transporter (e.g., `Transport.NATS`)                         |
| `options`   | A transporter-specific options object that determines transporter behavior |

The `options` object is specific to the chosen transporter. The **TCP** transporter exposes the properties described below. For other transporters (e.g., Redis or MQTT), see the relevant chapter for a description of the available options.

|                            |                                                                                                                                                                 |
| -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `host`                     | Connection hostname                                                                                                                                             |
| `port`                     | Connection port                                                                                                                                                 |
| `retryAttempts`            | Number of times the server tries to listen again after it closes unexpectedly (default: `0`)                                                                    |
| `retryDelay`               | Delay between those attempts (ms) (default: `0`)                                                                                                                |
| `serializer`               | Custom [serializer](https://github.com/nestjs/nest/blob/master/packages/microservices/interfaces/serializer.interface.ts) for outgoing messages                 |
| `deserializer`             | Custom [deserializer](https://github.com/nestjs/nest/blob/master/packages/microservices/interfaces/deserializer.interface.ts) for incoming messages             |
| `socketClass`              | A custom Socket that extends `TcpSocket` (default: `JsonSocket`)                                                                                                |
| `tlsOptions`               | Options to configure the TLS protocol (see [TLS support](/microservices/basics#tls-support))                                                                    |
| `maxBufferSize`            | Maximum size of the buffer for incoming messages, in characters (default: `(512 * 1024 * 1024) / 4`)                                                            |
| `incompleteMessageTimeout` | How long (ms) a peer may stay silent in the middle of a packet before the connection is dropped. Set to `0` to disable (default: `30000`)                       |
| `maxSendBufferSize`        | Maximum number of response bytes that may be queued for a peer that isn't reading them before the connection is dropped. Set to `0` to disable (default: 128MB) |

#### Message and Event Patterns[#](/microservices/basics#message-and-event-patterns)

Microservices recognize both messages and events by **patterns**. A pattern is a plain value, e.g., a literal object or a string. Patterns are automatically serialized and sent over the network along with the data portion of a message. This way, message senders and consumers can coordinate which requests are consumed by which handlers.

#### Request-response[#](/microservices/basics#request-response)

The request-response message style is useful when you need to **exchange** messages between services. It ensures that the service has actually received the message, without requiring you to implement an acknowledgment protocol manually. However, request-response isn't always the best fit. For example, streaming platforms that use log-based persistence, such as [Kafka](https://docs.confluent.io/3.0.0/streams/) or [NATS JetStream](https://docs.nats.io/nats-concepts/jetstream), are optimized for a different set of challenges, more aligned with the event messaging paradigm (see [event-based messaging](/microservices/basics#event-based) for more details).

To enable the request-response message type, Nest creates two logical channels: one for transferring data and another for waiting for incoming responses. For some underlying transports, like [NATS](https://nats.io/), this dual-channel support is provided out of the box. For others, Nest compensates by creating separate channels manually, which can introduce some overhead. If you don't need the request-response message style, consider using the event-based method instead.

To create a message handler based on the request-response paradigm, use the `@MessagePattern()` decorator, which is imported from the `@nestjs/microservices` package. Use this decorator only within [controller](/controllers) classes, as they serve as the entry points for your application. The Nest runtime ignores it in providers.

math.controller.ts

JS TS

```typescript

import { Controller } from '@nestjs/common';
import { MessagePattern } from '@nestjs/microservices';

@Controller()
export class MathController {
  @MessagePattern({ cmd: 'sum' })
  accumulate(data: number[]): number {
    return (data || []).reduce((a, b) => a + b);
  }
}
```

```typescript

import { Controller } from '@nestjs/common';
import { MessagePattern } from '@nestjs/microservices';

@Controller()
export class MathController {
  @MessagePattern({ cmd: 'sum' })
  accumulate(data) {
    return (data || []).reduce((a, b) => a + b);
  }
}
```

In the above code, the `accumulate()`**message handler** listens for messages that match the `{ cmd: 'sum' }` message pattern. The message handler takes a single argument, the `data` passed from the client. In this case, the data is an array of numbers to be accumulated.

#### Asynchronous responses[#](/microservices/basics#asynchronous-responses)

Message handlers can respond either synchronously or **asynchronously**, so `async` methods are supported.

JS TS

```typescript

@MessagePattern({ cmd: 'sum' })
async accumulate(data: number[]): Promise<number> {
  return (data || []).reduce((a, b) => a + b);
}
```

```typescript

@MessagePattern({ cmd: 'sum' })
async accumulate(data) {
  return (data || []).reduce((a, b) => a + b);
}
```

A message handler can also return an `Observable`, in which case the result values are emitted until the stream completes.

JS TS

```typescript

@MessagePattern({ cmd: 'sum' })
accumulate(data: number[]): Observable<number> {
  return from([1, 2, 3]);
}
```

```typescript

@MessagePattern({ cmd: 'sum' })
accumulate(data) {
  return from([1, 2, 3]);
}
```

In the example above, the message handler responds **three times**, once for each item in the array.

#### Event-based[#](/microservices/basics#event-based)

While the request-response method works well for exchanging messages between services, it is less suited to event-based messaging, where you want to publish **events** without waiting for a response. In such cases, the overhead of maintaining two channels for request-response is unnecessary.

For example, if you want to notify another service that a specific condition has occurred in this part of the system, use the event-based message style.

To create an event handler, use the `@EventPattern()` decorator, which is imported from the `@nestjs/microservices` package.

JS TS

```typescript

@EventPattern('user_created')
async handleUserCreated(data: Record<string, unknown>) {
  // business logic
}
```

```typescript

@EventPattern('user_created')
async handleUserCreated(data) {
  // business logic
}
```

> **Hint** You can register multiple event handlers for a **single** event pattern, and Nest triggers all of them in parallel.

The `handleUserCreated()`**event handler** listens for the `'user_created'` event. The event handler takes a single argument, the `data` passed from the client (in this case, an event payload sent over the network).

In more advanced scenarios, you might need additional details about the incoming request. For instance, when using NATS with wildcard subscriptions, you may want to retrieve the original subject that the producer sent the message to. Similarly, with Kafka, you may need to access the message headers. To do so, use the built-in decorators shown below:

JS TS

```typescript

@MessagePattern('time.us.*')
getDate(@Payload() data: number[], @Ctx() context: NatsContext) {
  console.log(`Subject: ${context.getSubject()}`); // e.g. "time.us.east"
  return new Date().toLocaleTimeString(...);
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('time.us.*')
getDate(data, context) {
  console.log(`Subject: ${context.getSubject()}`); // e.g. "time.us.east"
  return new Date().toLocaleTimeString(...);
}
```

> **Hint**`@Payload()`, `@Ctx()`, and `NatsContext` are imported from `@nestjs/microservices`.

> **Hint** You can also pass a property key to the `@Payload()` decorator to extract a specific property from the incoming payload object, e.g., `@Payload('id')`. To validate the payload against a schema, see [microservice pipes](/microservices/pipes).

#### Client (producer class)[#](/microservices/basics#client-producer-class)

A client Nest application can exchange messages with, or publish events to, a Nest microservice using the `ClientProxy` class. This class provides several methods for communicating with a remote microservice, such as `send()` (for request-response messaging) and `emit()` (for event-driven messaging). You can obtain an instance of this class in the following ways.

One approach is to import the `ClientsModule`, which exposes the static `register()` method. This method takes an array of objects representing microservice transporters. Each object must include a `name` property, and can include a `transport` property (if omitted, Nest uses `Transport.TCP`) and an `options` property.

The `name` property acts as an **injection token**, which you can use to inject an instance of `ClientProxy` wherever needed. Its value can be any string or JavaScript symbol, as described in [non-class-based provider tokens](/fundamentals/custom-providers#non-class-based-provider-tokens).

The `options` property is an object with the same properties we saw in the `createMicroservice()` method earlier.

```typescript

@Module({
  imports: [
    ClientsModule.register([
      { name: 'MATH_SERVICE', transport: Transport.TCP },
    ]),
  ],
})
```

Alternatively, use the `registerAsync()` method if you need to provide configuration or perform other asynchronous processes during setup.

```typescript

@Module({
  imports: [
    ClientsModule.registerAsync([
      {
        imports: [ConfigModule],
        name: 'MATH_SERVICE',
        useFactory: async (configService: ConfigService) => ({
          transport: Transport.TCP,
          options: {
            host: configService.get('HOST'),
            port: configService.get('PORT'),
          },
        }),
        inject: [ConfigService],
      },
    ]),
  ],
})
```

Once the module has been imported, use the `@Inject()` decorator to inject the `ClientProxy` instance configured for the `'MATH_SERVICE'` transporter.

```typescript

constructor(
  @Inject('MATH_SERVICE') private client: ClientProxy,
) {}
```

> **Hint** The `ClientsModule` and `ClientProxy` classes are imported from the `@nestjs/microservices` package.

At times, you may need to fetch the transporter configuration from another service (such as a `ConfigService`) rather than hard-coding it in your client application. To do so, register a [custom provider](/fundamentals/custom-providers) using the `ClientProxyFactory` class. This class provides a static `create()` method that accepts a transporter options object and returns a customized `ClientProxy` instance.

```typescript

@Module({
  providers: [
    {
      provide: 'MATH_SERVICE',
      useFactory: (configService: ConfigService) => {
        const mathSvcOptions = configService.getMathSvcOptions();
        return ClientProxyFactory.create(mathSvcOptions);
      },
      inject: [ConfigService],
    }
  ]
  ...
})
```

> **Hint** The `ClientProxyFactory` class is imported from the `@nestjs/microservices` package.

Another option is to use the `@Client()` property decorator.

```typescript

@Client({ transport: Transport.TCP })
client: ClientProxy;
```

> **Hint** The `@Client()` decorator is imported from the `@nestjs/microservices` package.

The `@Client()` decorator isn't the preferred technique, because a client created this way is harder to test and harder to share.

The `ClientProxy` is **lazy**. It doesn't initiate a connection immediately. Instead, the connection is established before the first microservice call and reused for each subsequent call. If you want to delay the application bootstrapping process until a connection is established, initiate the connection manually with the `ClientProxy` object's `connect()` method inside the `onApplicationBootstrap()` lifecycle hook.

JS TS

```typescript

async onApplicationBootstrap() {
  await this.client.connect();
}
```

If the connection can't be created, the `connect()` method rejects with the corresponding error object.

#### Sending messages[#](/microservices/basics#sending-messages)

The `ClientProxy` exposes a `send()` method, which calls the microservice and returns an `Observable` with its response.

JS TS

```typescript

accumulate(): Observable<number> {
  const pattern = { cmd: 'sum' };
  const payload = [1, 2, 3];
  return this.client.send<number>(pattern, payload);
}
```

```typescript

accumulate() {
  const pattern = { cmd: 'sum' };
  const payload = [1, 2, 3];
  return this.client.send(pattern, payload);
}
```

The `send()` method takes two arguments, `pattern` and `payload`. The `pattern` should match one defined in a `@MessagePattern()` decorator. The `payload` is the message to transmit to the remote microservice. This method returns a **cold `Observable`**, which means that you have to subscribe to it explicitly before the message is sent.

#### Publishing events[#](/microservices/basics#publishing-events)

To send an event, use the `ClientProxy` object's `emit()` method. This method publishes an event to the message broker.

JS TS

```typescript

async publish() {
  this.client.emit<number>('user_created', new UserCreatedEvent());
}
```

```typescript

async publish() {
  this.client.emit('user_created', new UserCreatedEvent());
}
```

The `emit()` method takes two arguments, `pattern` and `payload`. The `pattern` should match one defined in an `@EventPattern()` decorator, while the `payload` is the event data to transmit to the remote microservice. This method returns a **hot `Observable`** (in contrast to the cold `Observable` returned by `send()`), which means that the proxy immediately attempts to deliver the event, whether or not you subscribe to the observable.

## Debug production with NestJS Observe

* Every request traced
* Errors with source code
* Logs in context
* Zero config, free plan

[Start for free](https://observe.nestjs.com "Observe | NestJS - A progressive Node.js framework")

#### Request-scoping[#](/microservices/basics#request-scoping)

If you come from a different programming language background, it may be surprising that in Nest, most things are shared across incoming requests. This includes the database connection pool, singleton services with global state, and more. Node.js doesn't follow the request/response multi-threaded stateless model, in which each request is processed by a separate thread. As a result, using singleton instances is **safe** for your applications.

However, there are edge cases where a request-based lifetime for the handler might be desirable, such as per-request caching in GraphQL applications, request tracking, or multi-tenancy. Learn how to control scopes in the [injection scopes](/fundamentals/injection-scopes) chapter.

Request-scoped handlers and providers can inject `RequestContext` using the `@Inject()` decorator in combination with the `CONTEXT` token:

```typescript

import { Injectable, Scope, Inject } from '@nestjs/common';
import { CONTEXT, RequestContext } from '@nestjs/microservices';

@Injectable({ scope: Scope.REQUEST })
export class CatsService {
  constructor(@Inject(CONTEXT) private ctx: RequestContext) {}
}
```

This provides access to the `RequestContext` object, which has the following shape:

```typescript

export interface RequestContext<TData = any, TContext extends BaseRpcContext = any> {
  pattern: string | Record<string, any>;
  data: TData;
  context?: TContext;
  getData(): TData;
  getPattern(): string | Record<string, any>;
  getContext(): TContext;
}
```

The `data` property is the message payload sent by the message producer. The `pattern` property is the pattern used to identify the handler for the incoming message. The `context` property holds the transporter-specific context object (e.g., `NatsContext`), the same object that the `@Ctx()` decorator injects.

#### Instance status updates[#](/microservices/basics#instance-status-updates)

To get real-time updates on the connection and the state of the underlying driver instance, subscribe to the `status` stream. This stream provides status updates specific to the chosen driver. For instance, with the TCP transporter (the default), the `status` stream emits `connected` and `disconnected` events.

```typescript

this.client.status.subscribe((status: TcpStatus) => {
  console.log(status);
});
```

> **Hint** The `TcpStatus` type is imported from the `@nestjs/microservices` package.

Similarly, you can subscribe to the server's `status` stream to receive notifications about the server's status.

```typescript

const server = app.connectMicroservice<MicroserviceOptions>(...);
server.status.subscribe((status: TcpStatus) => {
  console.log(status);
});
```

#### Listening to internal events[#](/microservices/basics#listening-to-internal-events)

In some cases, you might want to listen to internal events emitted by the microservice. For example, you could listen for the `error` event to trigger additional operations when an error occurs. To do this, use the `on()` method:

```typescript

this.client.on('error', (err) => {
  console.error(err);
});
```

Similarly, you can listen to the server's internal events:

```typescript

server.on<TcpEvents>('error', (err) => {
  console.error(err);
});
```

> **Hint** The `TcpEvents` type is imported from the `@nestjs/microservices` package.

With the TCP transporter, starting with NestJS v12.1.1, listeners registered with the client's `on()` method stay registered until you call `close()`, so they are also attached to the new socket the client opens on the next `send()` or `emit()` call after the connection was closed. Registrations are not deduplicated, so register each listener once rather than again from its callback or after each reconnect.

#### Underlying driver access[#](/microservices/basics#underlying-driver-access)

For more advanced use cases, you may need to access the underlying driver instance, for example, to close the connection manually or to use driver-specific methods. In most cases, however, you **shouldn't need** to access the driver directly.

To do so, use the `unwrap()` method, which returns the underlying driver instance. The generic type parameter specifies the type of driver instance you expect.

```typescript

const netServer = this.client.unwrap<Server>();
```

Here, `Server` is a type imported from the `net` module.

Similarly, you can access the server's underlying driver instance:

```typescript

const netServer = server.unwrap<Server>();
```

#### Handling timeouts[#](/microservices/basics#handling-timeouts)

In distributed systems, microservices are sometimes down or unavailable. To avoid waiting indefinitely, apply a timeout to your microservice calls with the [RxJS](https://rxjs.dev)`timeout` operator. If the microservice doesn't respond within the specified time, an error is thrown, which you can catch and handle appropriately.

Apply the `timeout` operator within the pipe:

JS TS

```typescript

this.client
  .send<TResult, TInput>(pattern, data)
  .pipe(timeout(5000));
```

```typescript

this.client
  .send(pattern, data)
  .pipe(timeout(5000));
```

> **Hint** The `timeout` operator is imported from the `rxjs/operators` package.

If the microservice doesn't respond within 5 seconds, the `Observable` errors with a `TimeoutError`.

#### Tracing a request across services[#](/microservices/basics#tracing-a-request-across-services)

Timeouts tell you that a call failed to come back in time. They don't tell you *where* the time went, and in a system of five services talking over TCP, NATS, and Kafka, that is the question that matters. A gateway request that takes 3 seconds might spend 2.9 of them in a downstream service that nobody suspected, while each service's own logs show that everything looked fine.

The usual fix is to propagate a correlation ID by hand through every transport, then stitch the timelines back together after the fact. [NestJS Observe](https://www.observe.nestjs.com/ "NestJS Observe") does that stitching for you. Instrument each service with the `@nestjs/observe` SDK and forward the trace ID on whatever channel the transport already has (a Kafka header, a NATS header, or a field on the TCP payload), and the dashboard reassembles one waterfall spanning every service that participated:

From there, the timeout stops being a mystery. You can see the gateway's `send()` waiting, the consumer picking up the message (and how long the message waited before that), the query inside the handler that ran long, and the error it eventually threw, with its source lines, all on one clock. Message and event handlers are instrumented automatically, so `@MessagePattern()` and `@EventPattern()` handlers show up as operations without any manual span wiring.

Forwarding the trace ID is the one piece that requires application code, because only you know which channel your transport leaves free. See [Distributed tracing](/observability/distributed-tracing) for the pattern per transport, and the [Observability](/observability/overview) chapter to get set up.

#### TLS support[#](/microservices/basics#tls-support)

When communicating outside of a private network, encrypt the traffic. The TCP transporter has built-in support for TLS, based on Node's [TLS](https://nodejs.org/api/tls.html) module, which lets you encrypt communication between microservices and their clients.

To enable TLS for a TCP server, you need both a private key and a certificate in PEM format. Add them to the server's options with the `tlsOptions` property:

```typescript

import * as fs from 'node:fs';
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module.js';
import { MicroserviceOptions, Transport } from '@nestjs/microservices';

async function bootstrap() {
  const key = fs.readFileSync('<pathToKeyFile>', 'utf8').toString();
  const cert = fs.readFileSync('<pathToCertFile>', 'utf8').toString();

  const app = await NestFactory.createMicroservice<MicroserviceOptions>(
    AppModule,
    {
      transport: Transport.TCP,
      options: {
        tlsOptions: {
          key,
          cert,
        },
      },
    },
  );

  await app.listen();
}
await bootstrap();
```

For a client to communicate securely over TLS, define the `tlsOptions` object as well, this time with the CA certificate, i.e., the certificate of the authority that signed the server's certificate. This ensures that the client trusts the server's certificate and can establish a secure connection.

```typescript

import * as fs from 'node:fs';
import { Module } from '@nestjs/common';
import { ClientsModule, Transport } from '@nestjs/microservices';

@Module({
  imports: [
    ClientsModule.register([
      {
        name: 'MATH_SERVICE',
        transport: Transport.TCP,
        options: {
          tlsOptions: {
            ca: [fs.readFileSync('<pathToCaFile>', 'utf-8').toString()],
          },
        },
      },
    ]),
  ],
})
export class AppModule {}
```

The `ca` property accepts an array, so you can list several CAs if your setup involves multiple trusted authorities.

Once everything is set up, inject the `ClientProxy` as usual with the `@Inject()` decorator. Communication between your microservices is then encrypted, with Node's TLS module handling the encryption details.

For more information, refer to Node's [TLS documentation](https://nodejs.org/api/tls.html).

#### Dynamic configuration[#](/microservices/basics#dynamic-configuration)

A microservice's transport options are passed to `createMicroservice()`, before any provider (such as the `ConfigService` from the `@nestjs/config` package) can be injected. To configure the microservice with injected providers, pass `AsyncMicroserviceOptions` instead: Nest resolves the providers listed in `inject` and passes them to the `useFactory` function, which returns the transport options.

```typescript

import { NestFactory } from '@nestjs/core';
import { ConfigService } from '@nestjs/config';
import { AsyncMicroserviceOptions, Transport } from '@nestjs/microservices';
import { AppModule } from './app.module.js';

async function bootstrap() {
  const app = await NestFactory.createMicroservice<AsyncMicroserviceOptions>(
    AppModule,
    {
      useFactory: (configService: ConfigService) => ({
        transport: Transport.TCP,
        options: {
          host: configService.get<string>('HOST'),
          port: configService.get<number>('PORT'),
        },
      }),
      inject: [ConfigService],
    },
  );

  await app.listen();
}
await bootstrap();
```

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/microservices/basics.md)

----
url: https://docs.nestjs.com/data/drizzle
----

[Skip to content](#content)

On this page

* [Drizzle](https://docs.nestjs.com/data/drizzle#drizzle)
* [Schema](https://docs.nestjs.com/data/drizzle#schema)
* [Registering the database](https://docs.nestjs.com/data/drizzle#registering-the-database)
* [Queries](https://docs.nestjs.com/data/drizzle#queries)
* [Relations](https://docs.nestjs.com/data/drizzle#relations)
* [Drizzle Transactions](https://docs.nestjs.com/data/drizzle#drizzle-transactions)
* [Custom repositories](https://docs.nestjs.com/data/drizzle#custom-repositories)
* [Migrations](https://docs.nestjs.com/data/drizzle#migrations)
* [Multiple databases](https://docs.nestjs.com/data/drizzle#multiple-databases)
* [Testing](https://docs.nestjs.com/data/drizzle#testing)
* [Async configuration](https://docs.nestjs.com/data/drizzle#async-configuration)

### Drizzle

As an alternative to TypeORM, you can use [Drizzle ORM](https://orm.drizzle.team/) with the `@nestjs/drizzle` package. Drizzle is a lightweight, TypeScript-first ORM. You declare tables with plain functions and write queries with a SQL-like query builder (or the relational query API for nested reads), and Drizzle infers every result type from the schema. There are no entity classes, decorators, or code generation steps.

To get started, install the required dependencies. This chapter uses [PostgreSQL](https://www.postgresql.org/) with the `node-postgres` driver, but Drizzle supports many other databases, including MySQL, SQLite, and Microsoft SQL Server, as well as serverless databases such as Neon, Turso, and Cloudflare D1. The steps in this chapter are the same for every database Drizzle supports: install the driver for your database, and import `drizzle()` from the matching [entry point](https://orm.drizzle.team/docs/connect-overview) (e.g., `drizzle-orm/mysql2` or `drizzle-orm/libsql`) instead of `drizzle-orm/node-postgres`.

```bash

$ npm install --save @nestjs/drizzle drizzle-orm@rc pg
$ npm install --save-dev drizzle-kit@rc @types/pg
```

> **Hint** This chapter uses Drizzle ORM v1, currently published under the `rc` tag. The Drizzle documentation is written for this version. `@nestjs/drizzle` also supports Drizzle v0.35 and later. With v0.x, only relations and relational queries work differently from this chapter (see [Upgrading to v1](https://orm.drizzle.team/docs/upgrade-v1)).

#### Schema[#](/data/drizzle#schema)

With Drizzle, you write the database schema in TypeScript. You declare each table with a function such as `pgTable()` and export it from a schema file. Let's define the `users` table:

db/schema.ts

JS TS

```typescript

import { boolean, integer, pgTable, text } from 'drizzle-orm/pg-core';

export const users = pgTable('users', {
  id: integer().primaryKey().generatedAlwaysAsIdentity(),
  firstName: text('first_name').notNull(),
  lastName: text('last_name').notNull(),
  isActive: boolean('is_active').notNull().default(true),
});

export type User = typeof users.$inferSelect;
export type NewUser = typeof users.$inferInsert;
```

The `$inferSelect` and `$inferInsert` helpers derive the row types from the table definition, so there's no separate model class to keep in sync with the schema. For the available column types, see [Schema declaration](https://orm.drizzle.team/docs/sql-schema-declaration) in the Drizzle documentation.

#### Registering the database[#](/data/drizzle#registering-the-database)

Once the dependencies are installed and the schema is defined, import the `DrizzleModule` into the root `AppModule`:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { DrizzleModule } from '@nestjs/drizzle';
import { drizzle } from 'drizzle-orm/node-postgres';

@Module({
  imports: [
    DrizzleModule.forRoot({
      drizzle,
      connection: process.env.DATABASE_URL!,
    }),
  ],
})
export class AppModule {}
```

The `drizzle` option takes the `drizzle()` function of your driver. `DrizzleModule` calls it with the `connection` and the other Drizzle options once for each application instance. Every application, including each one your e2e tests create, therefore gets its own connection pool, which is closed when that application shuts down. Because you pass the function, every driver Drizzle supports works the same way, and TypeScript checks `connection` and the other options against that driver's `drizzle()` signature.

The `forRoot()` method supports the following options:

|                       |                                                                                                             |
| --------------------- | ----------------------------------------------------------------------------------------------------------- |
| `drizzle`             | The `drizzle()` function of your driver, e.g., the one exported by `drizzle-orm/node-postgres`              |
| `connection`          | A connection string, or the driver's connection options (e.g., a `pg` pool configuration)                   |
| `db`                  | A database instance that you created, used instead of `drizzle` and `connection` (see below)                |
| `autoCloseConnection` | If `true`, the database's client (`db.$client`) is closed when the application shuts down (default: `true`) |

Other options, such as `relations`, `logger`, or `casing`, are passed to `drizzle()` as well.

> **Hint** Like the options of any module, the `forRoot()` options are evaluated when the `AppModule` file is imported, so `process.env.DATABASE_URL` must already be set at that point (e.g., by starting Node.js with the `--env-file=.env` flag). To read the connection string through `ConfigService` instead, use `forRootAsync()`, described in the "Async configuration" section below.

> **Hint** The client is closed when you call `app.close()`, or when the process receives a termination signal if [shutdown hooks](/fundamentals/lifecycle-events#application-shutdown) are enabled. Pool-based clients (e.g., `node-postgres`, `postgres.js`, `mysql2`) are closed with `end()`, and others (e.g., `better-sqlite3`, `libsql`, PGlite) with `close()`. For a database created with Drizzle's [`withReplicas()`](https://orm.drizzle.team/docs/read-replicas) function, the clients of the primary and all replica databases are closed (with Drizzle v0.44.6 and later; earlier versions don't expose the replicas, so only the primary's client is closed). A client registered under several names is closed only once.

Once the module is registered, you can inject the database anywhere in the project (without importing any modules) with the `@InjectDrizzle()` decorator. For example:

app.service.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { InjectDrizzle } from '@nestjs/drizzle';
import type { NodePgDatabase } from 'drizzle-orm/node-postgres';

@Injectable()
export class AppService {
  constructor(
    @InjectDrizzle()
    private readonly db: NodePgDatabase,
  ) {}
}
```

```typescript

import { Injectable, Dependencies } from '@nestjs/common';
import { getDrizzleToken } from '@nestjs/drizzle';

@Injectable()
@Dependencies(getDrizzleToken())
export class AppService {
  constructor(db) {
    this.db = db;
  }
}
```

To register a database that you create yourself, e.g., one that routes reads to replicas with Drizzle's `withReplicas()` function, pass it as `db` instead. Create it in a `forRootAsync()` factory, which runs once for each application:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { DrizzleModule } from '@nestjs/drizzle';
import { drizzle } from 'drizzle-orm/node-postgres';
import { withReplicas } from 'drizzle-orm/pg-core';

@Module({
  imports: [
    DrizzleModule.forRootAsync({
      useFactory: () => ({
        db: withReplicas(drizzle(process.env.DATABASE_URL!), [
          drizzle(process.env.REPLICA_DATABASE_URL!),
        ]),
      }),
    }),
  ],
})
export class AppModule {}
```

> **Warning** You can also pass a `db` instance to `forRoot()`, e.g., one exported by a `db` file that your seed scripts import too. Such an instance is created once, when its file is first imported. Every application created from `AppModule` shares it, and the first application to shut down closes it, which breaks e2e test suites that create a new application for each test. In that case, set `autoCloseConnection` to `false` and close the client yourself.

#### Queries[#](/data/drizzle#queries)

Unlike the TypeORM integration, Drizzle has no `forFeature()` step. Drizzle tables are plain objects that you import wherever you build queries, and the database is registered globally, so any provider can inject it. Let's implement the `UsersService`:

users.service.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { InjectDrizzle } from '@nestjs/drizzle';
import { eq } from 'drizzle-orm';
import type { NodePgDatabase } from 'drizzle-orm/node-postgres';
import { users, type NewUser, type User } from '../db/schema.js';

@Injectable()
export class UsersService {
  constructor(
    @InjectDrizzle()
    private readonly db: NodePgDatabase,
  ) {}

  findAll(): Promise<User[]> {
    return this.db.select().from(users);
  }

  async findOne(id: number): Promise<User | undefined> {
    const [user] = await this.db.select().from(users).where(eq(users.id, id));
    return user;
  }

  async create(user: NewUser): Promise<User> {
    const [createdUser] = await this.db.insert(users).values(user).returning();
    return createdUser;
  }

  async remove(id: number): Promise<void> {
    await this.db.delete(users).where(eq(users.id, id));
  }
}
```

```typescript

import { Injectable, Dependencies } from '@nestjs/common';
import { getDrizzleToken } from '@nestjs/drizzle';
import { eq } from 'drizzle-orm';
import { users } from '../db/schema.js';

@Injectable()
@Dependencies(getDrizzleToken())
export class UsersService {
  constructor(db) {
    this.db = db;
  }

  findAll() {
    return this.db.select().from(users);
  }

  async findOne(id) {
    const [user] = await this.db.select().from(users).where(eq(users.id, id));
    return user;
  }

  async create(user) {
    const [createdUser] = await this.db.insert(users).values(user).returning();
    return createdUser;
  }

  async remove(id) {
    await this.db.delete(users).where(eq(users.id, id));
  }
}
```

A Drizzle query runs when it's awaited (or returned from an `async` function), and its result type is inferred from the columns it selects. The Drizzle documentation covers [selecting](https://orm.drizzle.team/docs/select), [inserting](https://orm.drizzle.team/docs/insert), [updating](https://orm.drizzle.team/docs/update), and [deleting](https://orm.drizzle.team/docs/delete) rows in detail.

#### Relations[#](/data/drizzle#relations)

Relations are associations between two or more tables, based on common fields, usually primary and foreign keys. Drizzle's [relational queries](https://orm.drizzle.team/docs/rqb-v2) use them to fetch nested data, such as users together with their photos, without writing joins by hand.

Let's add a `photos` table whose `userId` column references the `users` table:

db/schema.ts

JS TS

```typescript

export const photos = pgTable('photos', {
  id: integer().primaryKey().generatedAlwaysAsIdentity(),
  url: text().notNull(),
  userId: integer('user_id')
    .notNull()
    .references(() => users.id),
});
```

You declare the relations for the whole schema at once, with the `defineRelations()` function. For example, each user can have many photos, and each photo belongs to one user:

db/relations.ts

JS TS

```typescript

import { defineRelations } from 'drizzle-orm';
import * as schema from './schema.js';

export const relations = defineRelations(schema, (r) => ({
  users: {
    photos: r.many.photos(),
  },
  photos: {
    user: r.one.users({
      from: r.photos.userId,
      to: r.users.id,
    }),
  },
}));
```

To make the relations available to relational queries, pass them to `drizzle()` with the `relations` option:

```typescript

DrizzleModule.forRoot({
  drizzle,
  connection: process.env.DATABASE_URL!,
  relations,
}),
```

The database type now depends on the relations, so declare it once and reuse it wherever you inject the database:

db/database.ts

JS TS

```typescript

import type { NodePgDatabase } from 'drizzle-orm/node-postgres';
import type { relations } from './relations.js';

export type Database = NodePgDatabase<typeof relations>;
```

With that in place, the `db.query` API is fully typed:

users.service.ts

JS TS

```typescript

@Injectable()
export class UsersService {
  constructor(
    @InjectDrizzle()
    private readonly db: Database,
  ) {}

  findOneWithPhotos(id: number) {
    return this.db.query.users.findFirst({
      where: { id },
      with: { photos: true },
    });
  }
}
```

> **Hint** Relations only drive relational queries. Foreign key constraints come from `references()` in the table definition. To learn more, see [Relations](https://orm.drizzle.team/docs/relations-v2) in the Drizzle documentation.

#### Drizzle Transactions[#](/data/drizzle#drizzle-transactions)

A database transaction is a unit of work that the database management system treats as a whole, independently of other transactions: either all of its changes are applied, or none of them are. To learn more, see [Database transaction](https://en.wikipedia.org/wiki/Database_transaction) on Wikipedia.

To start a [Drizzle transaction](https://orm.drizzle.team/docs/transactions), call the `transaction()` method of the injected database. The callback receives a transaction object (`tx`) that exposes the same query API as the database:

```typescript

async deactivate(id: number) {
  await this.db.transaction(async (tx) => {
    await tx.update(users).set({ isActive: false }).where(eq(users.id, id));
    await tx.delete(photos).where(eq(photos.userId, id));
  });
}
```

If the callback throws or calls `tx.rollback()`, the transaction is rolled back and `transaction()` rejects with the error. Otherwise, the transaction is committed, and `transaction()` resolves with the value the callback returned. Queries that belong to the transaction must run through `tx`, not through the injected database.

> **Hint** To run code from several providers in one transaction without passing `tx` around, propagate the transaction with `AsyncLocalStorage`. The [`nestjs-cls`](/recipes/async-local-storage#nestjs-cls) package provides a transactional plugin with a [Drizzle adapter](https://papooch.github.io/nestjs-cls/plugins/available-plugins/transactional/drizzle-orm-adapter) that does this.

#### Custom repositories[#](/data/drizzle#custom-repositories)

Drizzle has no repository layer: you build queries from the injected database and the table definitions. To keep the queries for a table in one place, and to make the classes that use them easy to unit test, you can write a repository yourself as a regular provider:

users.repository.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { InjectDrizzle } from '@nestjs/drizzle';
import { eq } from 'drizzle-orm';
import type { Database } from '../db/database.js';
import { users, type User } from '../db/schema.js';

@Injectable()
export class UsersRepository {
  constructor(
    @InjectDrizzle()
    private readonly db: Database,
  ) {}

  findActive(): Promise<User[]> {
    return this.db.select().from(users).where(eq(users.isActive, true));
  }

  async deactivate(id: number): Promise<void> {
    await this.db.update(users).set({ isActive: false }).where(eq(users.id, id));
  }
}
```

Register `UsersRepository` in the `providers` array of `UsersModule`, and inject it into `UsersService` instead of the database. In unit tests, replace it with a [custom provider](/fundamentals/custom-providers) whose `useValue` is an object implementing the methods your service calls, such as `findActive()`.

> **Warning** Repository methods query the injected database, not a transaction's `tx`. With a connection pool, they run on a different connection than a transaction started elsewhere with `db.transaction()`, so they aren't part of it. To run them in a transaction, accept `tx` as a parameter, or propagate the transaction with `nestjs-cls` as described above.

#### Migrations[#](/data/drizzle#migrations)

[Migrations](https://orm.drizzle.team/docs/migrations) incrementally update the database schema to keep it in sync with the application's data model, while preserving the existing data. To generate and run migrations, Drizzle provides a dedicated CLI, [Drizzle Kit](https://orm.drizzle.team/docs/kit-overview), which reads its settings from a `drizzle.config.ts` file in the root directory of your project:

drizzle.config.ts

JS TS

```typescript

import { defineConfig } from 'drizzle-kit';

export default defineConfig({
  dialect: 'postgresql',
  schema: './src/db/schema.ts',
  out: './drizzle',
  dbCredentials: {
    url: process.env.DATABASE_URL!,
  },
});
```

With that file in place, `npx drizzle-kit generate` creates SQL migration files from your schema changes, and `npx drizzle-kit migrate` applies them to the database.

Drizzle Kit runs outside your Nest application, so migrations can't use dependency injection or other Nest-specific features. Drizzle Kit loads the `.env` file from the directory you run it in, so `process.env.DATABASE_URL` is available in `drizzle.config.ts` without `ConfigModule`. Variables already set in the environment take precedence over the file.

To apply pending migrations when the application starts instead, create the database in a `forRootAsync()` factory and apply them there. The factory can be `async`, and Nest doesn't create the providers that inject the database until it resolves:

```typescript

import { drizzle } from 'drizzle-orm/node-postgres';
import { migrate } from 'drizzle-orm/node-postgres/migrator';

DrizzleModule.forRootAsync({
  useFactory: async () => {
    const db = drizzle(process.env.DATABASE_URL!, { relations });
    await migrate(db, { migrationsFolder: './drizzle' });
    return { db };
  },
}),
```

> **Warning** When several instances of your application start at the same time, each of them tries to apply the migrations. In such deployments, run `drizzle-kit migrate` as a separate step of your release process instead.

## Learn the right way!

* 80+ chapters
* 5+ hours of videos
* Official certificate
* Deep-dive sessions

[Explore official courses](https://courses.nestjs.com "Courses | NestJS - A node.js framework built on top of TypeScript")

#### Multiple databases[#](/data/drizzle#multiple-databases)

Some projects require multiple database connections, and the `DrizzleModule` supports this as well. Register each database with its own `DrizzleModule` import. In this case, every database except one must have a name:

```typescript

@Module({
  imports: [
    DrizzleModule.forRoot({
      drizzle,
      connection: process.env.DATABASE_URL!,
      relations,
    }),
    DrizzleModule.forRoot({
      name: 'analytics',
      drizzle,
      connection: process.env.ANALYTICS_DATABASE_URL!,
    }),
  ],
})
export class AppModule {}
```

> **Notice** A database registered without a `name` is named `default`. Don't register multiple databases without a name, or with the same name: they would share one injection token, and only one of them would be injected.

The databases don't have to share a driver: `analytics` could just as well be a SQLite file opened with the `drizzle()` function from `drizzle-orm/better-sqlite3`. To inject a database other than the default one, pass its name to the `@InjectDrizzle()` decorator:

```typescript

@Injectable()
export class ReportsService {
  constructor(
    @InjectDrizzle('analytics')
    private readonly analyticsDb: NodePgDatabase,
  ) {}
}
```

You can also inject any database into a factory provider with the `getDrizzleToken()` function, which returns the injection token of the database with the given name:

```typescript

@Module({
  providers: [
    {
      provide: ReportsService,
      useFactory: (analyticsDb: NodePgDatabase) => {
        return new ReportsService(analyticsDb);
      },
      inject: [getDrizzleToken('analytics')],
    },
  ],
})
export class ReportsModule {}
```

#### Testing[#](/data/drizzle#testing)

When unit testing an application, you usually want to avoid connecting to a database, to keep test suites independent and fast. However, your classes depend on the database injected with `@InjectDrizzle()`. To solve this, replace the database with a mock, using a [custom provider](/fundamentals/custom-providers). The `getDrizzleToken()` function returns the injection token of the default database (or of the database whose name you pass):

```typescript

@Module({
  providers: [
    UsersService,
    {
      provide: getDrizzleToken(),
      useValue: mockDb,
    },
  ],
})
export class UsersModule {}
```

Nest now injects the `mockDb` object wherever a class requests the database with the `@InjectDrizzle()` decorator. Drizzle's query builder is chainable (e.g., `select().from().where()`), so a mock has to implement every method in the chain your code calls. For anything beyond simple queries, either move the queries into [custom repositories](/data/drizzle#custom-repositories) and mock those, or run these tests against a real database.

#### Async configuration[#](/data/drizzle#async-configuration)

To pass the `DrizzleModule` options asynchronously instead of statically, use the `forRootAsync()` method. It supports several ways to provide the options.

One approach is a factory function. The factory behaves like any other [asynchronous provider](/fundamentals/async-providers): it can be `async`, and it can inject dependencies through `inject`. It returns the same options as `forRoot()` (except `name`), either `drizzle` and `connection` or a `db` instance:

```typescript

DrizzleModule.forRootAsync({
  imports: [ConfigModule],
  useFactory: (configService: ConfigService) => ({
    drizzle,
    connection: configService.getOrThrow<string>('DATABASE_URL'),
    relations,
  }),
  inject: [ConfigService],
});
```

Alternatively, you can use the `useClass` syntax:

```typescript

DrizzleModule.forRootAsync({
  imports: [ConfigModule],
  useClass: DrizzleConfigService,
});
```

With this construction, `DrizzleModule` instantiates `DrizzleConfigService`, resolving its dependencies from the modules in `imports`, and calls its `createDrizzleOptions()` method to get the options. `DrizzleConfigService` must therefore implement the `DrizzleOptionsFactory` interface:

```typescript

@Injectable()
class DrizzleConfigService implements DrizzleOptionsFactory {
  constructor(private readonly configService: ConfigService) {}

  createDrizzleOptions(): DrizzleModuleFactoryOptions {
    return {
      drizzle,
      connection: this.configService.getOrThrow<string>('DATABASE_URL'),
      relations,
    };
  }
}
```

> **Hint**`createDrizzleOptions()` receives the name of the database being registered (`undefined` for the default one), so a single class can configure several databases.

To reuse a provider from another module instead of instantiating `DrizzleConfigService` inside `DrizzleModule`, use the `useExisting` syntax:

```typescript

DrizzleModule.forRootAsync({
  imports: [DatabaseConfigModule],
  useExisting: DrizzleConfigService,
});
```

This works like `useClass`, with one critical difference: `DrizzleModule` reuses the `DrizzleConfigService` instance exported by an imported module (here, `DatabaseConfigModule`) instead of creating a new one.

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/data/drizzle.md)

----
url: https://docs.nestjs.com/v7/techniques/logger
----

* [Logger](https://docs.nestjs.com/v7/techniques/logger#logger)
* [Basic customization](https://docs.nestjs.com/v7/techniques/logger#basic-customization)
* [Custom implementation](https://docs.nestjs.com/v7/techniques/logger#custom-implementation)
* [Extend built-in logger](https://docs.nestjs.com/v7/techniques/logger#extend-built-in-logger)
* [Dependency injection](https://docs.nestjs.com/v7/techniques/logger#dependency-injection)
* [Using the logger for application logging](https://docs.nestjs.com/v7/techniques/logger#using-the-logger-for-application-logging)
* [Injecting a custom logger](https://docs.nestjs.com/v7/techniques/logger#injecting-a-custom-logger)
* [Use external logger](https://docs.nestjs.com/v7/techniques/logger#use-external-logger)

```typescript

const app = await NestFactory.create(ApplicationModule, {
  logger: false,
});
await app.listen(3000);
```

To enable specific logging levels, set the `logger` property to an array of strings specifying the log levels to display, as follows:

```typescript

const app = await NestFactory.create(ApplicationModule, {
  logger: ['error', 'warn'],
});
await app.listen(3000);
```

Values in the array can be any combination of `'log'`, `'error'`, `'warn'`, `'debug'`, and `'verbose'`.

> **Hint** To disable color in the default logger's messages, set the `NO_COLOR` environment variable.

#### Custom implementation[#](/techniques/logger#custom-implementation)

You can provide a custom logger implementation to be used by Nest for system logging by setting the value of the `logger` property to an object that fulfills the `LoggerService` interface. For example, you can tell Nest to use the built-in global JavaScript `console` object (which implements the `LoggerService` interface), as follows:

```typescript

const app = await NestFactory.create(ApplicationModule, {
  logger: console,
});
await app.listen(3000);
```

Implementing your own custom logger is straightforward. Simply implement each of the methods of the `LoggerService` interface as shown below.

```typescript

import { LoggerService } from '@nestjs/common';

export class MyLogger implements LoggerService {
  log(message: string) {
    /* your implementation */
  }
  error(message: string, trace: string) {
    /* your implementation */
  }
  warn(message: string) {
    /* your implementation */
  }
  debug(message: string) {
    /* your implementation */
  }
  verbose(message: string) {
    /* your implementation */
  }
}
```

You can then supply an instance of `MyLogger` via the `logger` property of the Nest application options object.

```typescript

const app = await NestFactory.create(ApplicationModule, {
  logger: new MyLogger(),
});
await app.listen(3000);
```

This technique, while simple, doesn't utilize dependency injection for the `MyLogger` class. This can pose some challenges, particularly for testing, and limit the reusability of `MyLogger`. For a better solution, see the [Dependency Injection](techniques/logger#dependency-injection) section below.

#### Extend built-in logger[#](/techniques/logger#extend-built-in-logger)

Rather than writing a logger from scratch, you may be able to meet your needs by extending the built-in `Logger` class and overriding selected behavior of the default implementation.

```typescript

import { Logger } from '@nestjs/common';

export class MyLogger extends Logger {
  error(message: string, trace: string) {
    // add your tailored logic here
    super.error(message, trace);
  }
}
```

You can use such an extended logger in your feature modules as described in the [Using the logger for application logging](techniques/logger#using-the-logger-for-application-logging) section below.

You can tell Nest to use your extended logger for system logging by passing an instance of it via the `logger` property of the application options object (as shown in the [Custom implementation](techniques/logger#custom-logger-implementation) section above), or by using the technique shown in the [Dependency Injection](techniques/logger#dependency-injection) section below. If you do so, you should take care to call `super`, as shown in the sample code above, to delegate the specific log method call to the parent (built-in) class so that Nest can rely on the built-in features it expects.

## Learn the right way!

* 80+ chapters
* 5+ hours of videos
* Official certificate
* Deep-dive sessions

[Explore official courses](https://courses.nestjs.com "Courses | NestJS - A node.js framework built on top of TypeScript")

#### Dependency injection[#](/techniques/logger#dependency-injection)

For more advanced logging functionality, you'll want to take advantage of dependency injection. For example, you may want to inject a `ConfigService` into your logger to customize it, and in turn inject your custom logger into other controllers and/or providers. To enable dependency injection for your custom logger, create a class that implements `LoggerService` and register that class as a provider in some module. For example, you can

1. Define a `MyLogger` class that either extends the built-in `Logger` or completely overrides it, as shown in previous sections. Be sure to implement the `LoggerService` interface.
2. Create a `LoggerModule` as shown below, and provide `MyLogger` from that module.

```typescript

import { Module } from '@nestjs/common';
import { MyLogger } from './my-logger.service';

@Module({
  providers: [MyLogger],
  exports: [MyLogger],
})
export class LoggerModule {}
```

With this construct, you are now providing your custom logger for use by any other module. Because your `MyLogger` class is part of a module, it can use dependency injection (for example, to inject a `ConfigService`). There's one more technique needed to provide this custom logger for use by Nest for system logging (e.g., for bootstrapping and error handling).

Because application instantiation (`NestFactory.create()`) happens outside the context of any module, it doesn't participate in the normal Dependency Injection phase of initialization. So we must ensure that at least one application module imports the `LoggerModule` to trigger Nest to instantiate a singleton instance of our `MyLogger` class. We can then instruct Nest to use the same singleton instance of `MyLogger` with the following construction:

```typescript

const app = await NestFactory.create(ApplicationModule, {
  logger: false,
});
app.useLogger(app.get(MyLogger));
await app.listen(3000);
```

Here we use the `get()` method on the `NestApplication` instance to retrieve the singleton instance of the `MyLogger` object. This technique is essentially a way to "inject" an instance of a logger for use by Nest. The `app.get()` call retrieves the singleton instance of `MyLogger`, and depends on that instance being first injected in another module, as described above.

The only downside of this solution is that your first initialization messages won't be printed anywhere at all, so in rare cases you may miss some important initialization errors. Alternatively you can print first initialization messages using default logger, and then switch to your custom one:

```typescript

const app = await NestFactory.create(ApplicationModule);
app.useLogger(app.get(MyLogger));
await app.listen(3000);
```

You can also inject this `MyLogger` provider in your feature classes, thus ensuring consistent logging behavior across both Nest system logging and application logging. See [Using the logger for application logging](techniques/logger#using-the-logger-for-application-logging) and [Injecting a custom logger](techniques/logger#injecting-a-custom-logger) below for more information.

#### Using the logger for application logging[#](/techniques/logger#using-the-logger-for-application-logging)

We can combine several of the techniques above to provide consistent behavior and formatting across both Nest system logging and our own application event/message logging.

A good practice is to instantiate `Logger` class from `@nestjs/common` in each of our services. We can supply our service name as the `context` argument in the `Logger` constructor, like so:

```typescript

import { Logger, Injectable } from '@nestjs/common';

@Injectable()
class MyService {
  private readonly logger = new Logger(MyService.name);
  
  doSomething() {
    this.logger.log('Doing something...');
  }
}
```

In the default logger implementation, `context` is printed in the square brackets, like `NestFactory` in the example below:

```bash

[Nest] 19096   - 12/08/2019, 7:12:59 AM   [NestFactory] Starting Nest application...
```

If we supply a custom logger via `app.useLogger()`, it will actually be used by Nest internally. That means that our code remains implementation agnostic, while we can easily substitute the default logger for our custom one by calling `app.useLogger()`.

That way if we follow the steps from the previous section and call `app.useLogger(app.get(MyLogger))`, the following calls to `this.logger.log()` from `MyService` would result in calls to method `log` from `MyLogger` instance.

This should be suitable for most cases. But if you need more customization (like adding and calling custom methods), move to the next section.

#### Injecting a custom logger[#](/techniques/logger#injecting-a-custom-logger)

To start, extend the built-in logger with code like the following. We supply the `scope` option as configuration metadata for the `Logger` class, specifying a [transient](/v7/fundamentals/injection-scopes) scope, to ensure that we'll have a unique instance of the `MyLogger` in each feature module. In this example, we do not extend the individual `Logger` methods (like `log()`, `warn()`, etc.), though you may choose to do so.

```typescript

import { Injectable, Scope, Logger } from '@nestjs/common';

@Injectable({ scope: Scope.TRANSIENT })
export class MyLogger extends Logger {
  customLog() {
    this.log('Please feed the cat!');
  }
}
```

Next, create a `LoggerModule` with a construction like this:

```typescript

import { Module } from '@nestjs/common';
import { MyLogger } from './my-logger.service';

@Module({
  providers: [MyLogger],
  exports: [MyLogger],
})
export class LoggerModule {}
```

Next, import the `LoggerModule` into your feature module. Since we extended default `Logger` we have the convenience of using `setContext` method. So we can start using the context-aware custom logger, like this:

```typescript

import { Injectable } from '@nestjs/common';
import { MyLogger } from './my-logger.service';

@Injectable()
export class CatsService {
  private readonly cats: Cat[] = [];

  constructor(private myLogger: MyLogger) {
    // Due to transient scope, CatsService has its own unique instance of MyLogger,
    // so setting context here will not affect other instances in other services 
    this.myLogger.setContext('CatsService');
  }

  findAll(): Cat[] {
    // You can call all the default methods
    this.myLogger.warn('About to return cats!');
    // And your custom methods
    this.myLogger.customLog();
    return this.cats;
  }
}
```

Finally, instruct Nest to use an instance of the custom logger in your `main.ts` file as shown below. Of course in this example, we haven't actually customized the logger behavior (by extending the `Logger` methods like `log()`, `warn()`, etc.), so this step isn't actually needed. But it **would** be needed if you added custom logic to those methods and wanted Nest to use the same implementation.

```typescript

const app = await NestFactory.create(ApplicationModule, {
  logger: false,
});
app.useLogger(new MyLogger());
await app.listen(3000);
```

Be mindful that if you supply `logger: false` to `NestFactory.create`, nothing will be logged until you call `useLogger`, so you may miss some important initialization errors. If you don't mind that some of your initial messages will be logged with the default logger, you can just omit the `logger: false` option.

#### Use external logger[#](/techniques/logger#use-external-logger)

Production applications often have specific logging requirements, including advanced filtering, formatting and centralized logging. Nest's built-in logger is used for monitoring Nest system behavior, and can also be useful for basic formatted text logging in your feature modules while in development, but production applications often take advantage of dedicated logging modules like [Winston](https://github.com/winstonjs/winston). As with any standard Node.js application, you can take full advantage of such modules in Nest.

----
url: https://docs.nestjs.com/v7/microservices/exception-filters
----

* [Exception filters](https://docs.nestjs.com/v7/microservices/exception-filters#exception-filters)
* [Filters](https://docs.nestjs.com/v7/microservices/exception-filters#filters)
* [Inheritance](https://docs.nestjs.com/v7/microservices/exception-filters#inheritance)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/microservices/exception-filters.md "Suggest Edits")

### Exception filters

The only difference between the HTTP [exception filter](/v7/exception-filters) layer and the corresponding microservices layer is that instead of throwing `HttpException`, you should use `RpcException`.

```typescript

throw new RpcException('Invalid credentials.');
```

> **Hint** The `RpcException` class is imported from the `@nestjs/microservices` package.

With the sample above, Nest will handle the thrown exception and return the `error` object with the following structure:

```json

{
  "status": "error",
  "message": "Invalid credentials."
}
```

#### Filters[#](/microservices/exception-filters#filters)

Microservice exception filters behave similarly to HTTP exception filters, with one small difference. The `catch()` method must return an `Observable`.

rpc-exception.filter.ts

JS TS

```typescript

import { Catch, RpcExceptionFilter, ArgumentsHost } from '@nestjs/common';
import { Observable, throwError } from 'rxjs';
import { RpcException } from '@nestjs/microservices';

@Catch(RpcException)
export class ExceptionFilter implements RpcExceptionFilter<RpcException> {
  catch(exception: RpcException, host: ArgumentsHost): Observable<any> {
    return throwError(exception.getError());
  }
}
```

```typescript

import { Catch } from '@nestjs/common';
import { throwError } from 'rxjs';

@Catch(RpcException)
export class ExceptionFilter {
  catch(exception, host) {
    return throwError(exception.getError());
  }
}
```

> **Warning** You cannot set up global microservice exception filters when using a [hybrid application](/v7/faq/hybrid-application).

The following example uses a manually instantiated method-scoped filter. Just as with HTTP based applications, you can also use controller-scoped filters (i.e., prefix the controller class with a `@UseFilters()` decorator).

JS TS

```typescript

@UseFilters(new ExceptionFilter())
@MessagePattern({ cmd: 'sum' })
accumulate(data: number[]): number {
  return (data || []).reduce((a, b) => a + b);
}
```

```typescript

@UseFilters(new ExceptionFilter())
@MessagePattern({ cmd: 'sum' })
accumulate(data) {
  return (data || []).reduce((a, b) => a + b);
}
```

#### Inheritance[#](/microservices/exception-filters#inheritance)

Typically, you'll create fully customized exception filters crafted to fulfill your application requirements. However, there might be use-cases when you would like to simply extend the **core exception filter**, and override the behavior based on certain factors.

In order to delegate exception processing to the base filter, you need to extend `BaseExceptionFilter` and call the inherited `catch()` method.

JS TS

```typescript

import { Catch, ArgumentsHost } from '@nestjs/common';
import { BaseRpcExceptionFilter } from '@nestjs/microservices';

@Catch()
export class AllExceptionsFilter extends BaseRpcExceptionFilter {
  catch(exception: any, host: ArgumentsHost) {
    return super.catch(exception, host);
  }
}
```

```typescript

import { Catch } from '@nestjs/common';
import { BaseRpcExceptionFilter } from '@nestjs/microservices';

@Catch()
export class AllExceptionsFilter extends BaseRpcExceptionFilter {
  catch(exception, host) {
    return super.catch(exception, host);
  }
}
```

----
url: https://docs.nestjs.com/v4/graphql/resolvers-map
----

### Resolvers Map

When using `graphql-tools`, you have to create a resolvers map manually. The following example is copied & pasted from the [Apollo documentation](https://www.apollographql.com/docs/graphql-tools/generate-schema.html) where you can read more about it:

JavaScript TypeScript

TypeScript

```typescript

import { find, filter } from 'lodash';

// example data
const authors = [
  { id: 1, firstName: 'Tom', lastName: 'Coleman' },
  { id: 2, firstName: 'Sashko', lastName: 'Stubailo' },
  { id: 3, firstName: 'Mikhail', lastName: 'Novikov' },
];
const posts = [
  { id: 1, authorId: 1, title: 'Introduction to GraphQL', votes: 2 },
  { id: 2, authorId: 2, title: 'Welcome to Meteor', votes: 3 },
  { id: 3, authorId: 2, title: 'Advanced GraphQL', votes: 1 },
  { id: 4, authorId: 3, title: 'Launchpad is Cool', votes: 7 },
];

const resolverMap = {
  Query: {
    author(obj, args, context, info) {
      return find(authors, { id: args.id });
    },
  },
  Author: {
    posts(author) {
      return filter(posts, { authorId: author.id });
    },
  },
};
```

With the `@nestjs/graphql` package, the resolvers map is generated automatically using the metadata. Let's rewrite the above example with the **equivalent** Nest-way code.

JavaScript TypeScript

TypeScript

```typescript

import { Query, Resolver, ResolveProperty } from '@nestjs/graphql';
import { find, filter } from 'lodash';

// example data
const authors = [
  { id: 1, firstName: 'Tom', lastName: 'Coleman' },
  { id: 2, firstName: 'Sashko', lastName: 'Stubailo' },
  { id: 3, firstName: 'Mikhail', lastName: 'Novikov' },
];
const posts = [
  { id: 1, authorId: 1, title: 'Introduction to GraphQL', votes: 2 },
  { id: 2, authorId: 2, title: 'Welcome to Meteor', votes: 3 },
  { id: 3, authorId: 2, title: 'Advanced GraphQL', votes: 1 },
  { id: 4, authorId: 3, title: 'Launchpad is Cool', votes: 7 },
];

@Resolver('Author')
export class AuthorResolver {
  @Query()
  author(obj, args, context, info) {
    return find(authors, { id: args.id });
  }

  @ResolveProperty()
  posts(author) {
    return filter(posts, { authorId: author.id });
  }
}
```

The `@Resolver()` decorator doesn't affect either queries and mutations. It only tells Nest that each `@ResolveProperty()` has a parent, which is an `Author` in this case.

> **Hint** If we are using the `@Resolver()` decorator, we don't have to mark a class as a `@Component()`, otherwise, it's necessary.

Normally, we would use something like a `getAuthor()` or `getPosts()` as a method names. We can do that easily as well:

JavaScript TypeScript

TypeScript

```typescript

import { Query, Resolver, ResolveProperty } from '@nestjs/graphql';
import { find, filter } from 'lodash';

// example data
const authors = [
  { id: 1, firstName: 'Tom', lastName: 'Coleman' },
  { id: 2, firstName: 'Sashko', lastName: 'Stubailo' },
  { id: 3, firstName: 'Mikhail', lastName: 'Novikov' },
];
const posts = [
  { id: 1, authorId: 1, title: 'Introduction to GraphQL', votes: 2 },
  { id: 2, authorId: 2, title: 'Welcome to Meteor', votes: 3 },
  { id: 3, authorId: 2, title: 'Advanced GraphQL', votes: 1 },
  { id: 4, authorId: 3, title: 'Launchpad is Cool', votes: 7 },
];

@Resolver('Author')
export class AuthorResolver {
  @Query('author')
  getAuthor(obj, args, context, info) {
    return find(authors, { id: args.id });
  }

  @ResolveProperty('posts')
  getPosts(author) {
    return filter(posts, { authorId: author.id });
  }
}
```

> **Hint** The `@Resolver()` decorator can be used at the method-level as well.

#### Refactor

The idea behind the above code is to show the differences between the Apollo and the Nest-way, to allow for a simple transition of your code. Right now, we're gonna do a small refactor to take advantages of the Nest architecture, to make it a **real-world** example.

JavaScript TypeScript

TypeScript

```typescript

@Resolver('Author')
export class AuthorResolver {
  constructor(
    private readonly authorsService: AuthorsService,
    private readonly postsService: PostsService,
  ) {}

  @Query('author')
  async getAuthor(obj, args, context, info) {
    const { id } = args;
    return await this.authorsService.findOneById(id);
  }

  @ResolveProperty('posts')
  async getPosts(author) {
    const { id } = author;
    return await this.postsService.findAll({ authorId: id });
  }
}
```

TypeScript

```typescript

@Resolver('Author')
@Dependencies(AuthorsService, PostsService)
export class AuthorResolver {
  constructor(authorsService, postsService) {
    this.authorsService = authorsService;
    this.postsService = postsService;
  }

  @Query('author')
  async getAuthor(obj, args, context, info) {
    const { id } = args;
    return await this.authorsService.findOneById(id);
  }

  @ResolveProperty('posts')
  async getPosts(author) {
    const { id } = author;
    return await this.postsService.findAll({ authorId: id });
  }
}
```

Now we have to register the `AuthorResolver` somewhere, for example inside the newly created `AuthorsModule`.

JavaScript TypeScript

TypeScript

```typescript

@Module({
  imports: [PostsModule],
  components: [AuthorsService, AuthorResolver],
})
export class AuthorsModule {}
```

The `GraphQLModule` will take care of reflecting the metadata and transforming class into the correct resolvers map automatically. The only thing you have to do is to import this module somewhere, therefore Nest will know that `AuthorsModule` exists.

#### Type definitions

The last missing piece is a type definitions ([read more](http://graphql.org/learn/schema/#type-language)) file. Let's create it near to the resolver class.

author-types.graphql

Java

```java

type Author {
  id: Int!
  firstName: String
  lastName: String
  posts: [Post]
}

type Post {
  id: Int!
  title: String
  votes: Int
}

type Query {
  author(id: Int!): Author
}
```

That's all. We created a single `author(id: Int!)` query.

> **Hint** Learn more about GraphQL queries [here](http://graphql.org/learn/queries/).

#### Sponsors

[](https://valor-software.com/)

Nest is an MIT-licensed open source project. It can grow thanks to the support by these awesome people. If you'd like to join them, please read more [here](https://opencollective.com/nest). Thanks!

[](https://opencollective.com/nest/backer/0/website)[](https://opencollective.com/nest/backer/1/website)[](https://opencollective.com/nest/backer/2/website)[](https://opencollective.com/nest/backer/3/website)[](https://opencollective.com/nest/backer/4/website)[](https://opencollective.com/nest/backer/5/website)[](https://opencollective.com/nest/backer/6/website)[](https://opencollective.com/nest/backer/7/website)[](https://opencollective.com/nest/backer/8/website)[](https://opencollective.com/nest/backer/9/website)[](https://opencollective.com/nest/backer/10/website)[](https://opencollective.com/nest/backer/11/website)[](https://opencollective.com/nest/backer/12/website)[](https://opencollective.com/nest/backer/13/website)[](https://opencollective.com/nest/backer/14/website)[](https://opencollective.com/nest/backer/15/website)[](https://opencollective.com/nest/backer/16/website)[](https://opencollective.com/nest/backer/17/website)[](https://opencollective.com/nest/backer/18/website)[](https://opencollective.com/nest/backer/19/website)[](https://opencollective.com/nest/backer/20/website)[](https://opencollective.com/nest/backer/21/website)[](https://opencollective.com/nest/backer/22/website)[](https://opencollective.com/nest/backer/23/website)[](https://opencollective.com/nest/backer/24/website)[](https://opencollective.com/nest/backer/25/website)[](https://opencollective.com/nest/backer/26/website)[](https://opencollective.com/nest/backer/27/website)[](https://opencollective.com/nest/backer/28/website)[](https://opencollective.com/nest/backer/29/website)

[Become a sponsor](https://opencollective.com/nest)

----
url: https://docs.nestjs.com/migration-guide
----

[Skip to content](#content)

On this page

* [Migration guide](https://docs.nestjs.com/migration-guide#migration-guide)
* [Upgrading packages](https://docs.nestjs.com/migration-guide#upgrading-packages)
* [Node.js requirements](https://docs.nestjs.com/migration-guide#nodejs-requirements)
* [ESM packages](https://docs.nestjs.com/migration-guide#esm-packages)
* [New project defaults](https://docs.nestjs.com/migration-guide#new-project-defaults)
* [Testing stack](https://docs.nestjs.com/migration-guide#testing-stack)
* [Linting defaults](https://docs.nestjs.com/migration-guide#linting-defaults)
* [Route decorator schemas](https://docs.nestjs.com/migration-guide#route-decorator-schemas)
* [Standard Schema serialization](https://docs.nestjs.com/migration-guide#standard-schema-serialization)
* [GraphQL IDE configuration](https://docs.nestjs.com/migration-guide#graphql-ide-configuration)
* [GraphQL subscriptions transport](https://docs.nestjs.com/migration-guide#graphql-subscriptions-transport)
* [NATS v3](https://docs.nestjs.com/migration-guide#nats-v3)
* [Lifecycle hook ordering](https://docs.nestjs.com/migration-guide#lifecycle-hook-ordering)
* [@Optional() is no longer inherited](https://docs.nestjs.com/migration-guide#optional-is-no-longer-inherited)
* [class-validator and class-transformer](https://docs.nestjs.com/migration-guide#class-validator-and-class-transformer)
* [Config module](https://docs.nestjs.com/migration-guide#config-module)
* [Terminus module](https://docs.nestjs.com/migration-guide#terminus-module)
* [Webpack deprecation in CLI workflows](https://docs.nestjs.com/migration-guide#webpack-deprecation-in-cli-workflows)
* [New CLI commands and flags](https://docs.nestjs.com/migration-guide#new-cli-commands-and-flags)
* [Route conflict diagnostics](https://docs.nestjs.com/migration-guide#route-conflict-diagnostics)
* [Machine-readable error codes](https://docs.nestjs.com/migration-guide#machine-readable-error-codes)
* [Structured logging params](https://docs.nestjs.com/migration-guide#structured-logging-params)
* [Native observability support](https://docs.nestjs.com/migration-guide#native-observability-support)
* [Other notable release changes](https://docs.nestjs.com/migration-guide#other-notable-release-changes)
* [Switching your project to ESM](https://docs.nestjs.com/migration-guide#switching-your-project-to-esm)
* [Moving your own code to ESM](https://docs.nestjs.com/migration-guide#moving-your-own-code-to-esm)

### Migration guide

This article walks you through migrating from NestJS version 11 to version 12. Version 12 centers on ESM packages, updated CLI defaults, first-class support for [Standard Schema](https://standardschema.dev/)-based validation and serialization, and native [observability](/observability/overview) support.

#### Upgrading packages[#](/migration-guide#upgrading-packages)

Start by upgrading the Nest CLI itself, because the upgrade command used below ships with it:

```bash

$ npm i -g @nestjs/cli@latest @nestjs/schematics@latest
```

If your project keeps the CLI as a local dev dependency, update it there as well:

```bash

$ npm i -D @nestjs/cli@latest @nestjs/schematics@latest
```

With the latest CLI in place, run `nest upgrade` from the root of your project:

```bash

$ nest upgrade
```

The command moves every recognized `@nestjs/*` package to its v12-compatible major at once, so the framework, platform adapters, and companion packages stay in sync, and then installs them. It also bumps TypeScript to v6 and applies the mechanical parts of the migration described in this guide (`nest-cli.json` webpack options, the GraphQL `playground` and subscriptions transport changes, the NATS package swap, and `@nestjs/config` validation options). Finally, it prints a report of everything it changed, plus notes on the behavioral changes it can't migrate for you. To see that report without touching your files, run the command with `--dry-run` first. See [nest upgrade](/cli/usages#nest-upgrade) for the full list of steps and options.

> **Hint**`nest upgrade` replaces the manual [npm-check-updates (ncu)](https://npmjs.com/package/npm-check-updates) flow previously recommended here. You can still upgrade packages manually if you prefer; what matters is that every Nest package moves to the same major at once. The command only bumps the CLI dependency inside your project, which is why you upgrade the global binary first.

#### Node.js requirements[#](/migration-guide#nodejs-requirements)

The Node.js requirement differs depending on whether you are **running** an application or **generating** code with the CLI:

| What you are doing                                                 | Minimum Node.js                              |
| ------------------------------------------------------------------ | -------------------------------------------- |
| Running a Nest 12 application                                      | **v20.19+**, or **v22.12+** on the 22.x line |
| `nest new`, `nest generate`, `nest upgrade` (`@nestjs/schematics`) | **v22.22.3+**, **v24.15+**, or **v26+**      |

`@nestjs/core` itself still declares `>= 20`, but the v12 packages are ESM-only, and consuming them from a CommonJS application relies on `require(esm)`, which is unflagged only from Node.js 20.19 and 22.12 onwards. The 21.x line never received it and is not supported. `nest upgrade` enforces exactly this and refuses to run on an older release.

AWS Lambda disables `require(esm)` by default on its Node.js 20, 22, and 24 runtimes, even when the corresponding upstream Node.js release enables it. To run a CommonJS Nest 12 application on these Lambda runtimes, enable it through the function's `NODE_OPTIONS` environment variable:

```text

NODE_OPTIONS=--experimental-require-module
```

If `NODE_OPTIONS` already contains other flags, append this flag to the existing value. See the [AWS Lambda documentation](https://docs.aws.amazon.com/lambda/latest/dg/lambda-nodejs.html#nodejs-experimental) for details and for the support limitations of experimental features.

The CLI's schematics have a higher floor of their own: `@nestjs/schematics` requires **Node.js v22.22.3+, v24.15+, or v26+**, inherited from the Angular devkit it builds on. Scaffolding and upgrading therefore need a newer runtime than running the framework does. The 23.x and 25.x lines, as well as earlier 22.x and 24.x releases, are excluded.

> **Hint** The simplest way to satisfy every requirement is to run the latest active LTS release. Pick the bare minimum only if you have a specific reason to stay there. If you do, keep in mind that Node.js 20.19 is enough to run your application, but not to use the CLI's generators.

#### ESM packages[#](/migration-guide#esm-packages)

All core Nest packages now ship as ESM. For most existing applications, this is much less disruptive than it would have been a few years ago, because modern Node.js releases support `require(esm)`.

> **Hint** Migrating **your own** application to ESM is entirely optional and **not** part of upgrading to v12. Because Nest's ESM packages can be consumed from CommonJS through `require(esm)`, a CommonJS application can upgrade to v12 and stay CommonJS for as long as you like; `nest upgrade` deliberately leaves your module format alone. Whether you switch is a matter of preference. If you decide to, the last two sections of this guide, [Switching your project to ESM](/migration-guide#switching-your-project-to-esm) and [Moving your own code to ESM](/migration-guide#moving-your-own-code-to-esm), walk you through it.

In practice, this means:

* Many existing CommonJS applications continue to work without a full rewrite
* Review custom bootstrapping scripts, build tooling, and test runners if they make assumptions about CommonJS-only packages
* If you maintain a custom bundler or runtime configuration, make sure it matches the module format your project actually uses

For new projects, the CLI now lets you choose between a CommonJS and an ESM project layout.

#### New project defaults[#](/migration-guide#new-project-defaults)

`nest new` now prompts you to choose whether to generate a CommonJS or an ESM project.

* ESM projects use Vitest by default (CommonJS projects use Jest)
* All generated projects use oxlint by default

This only changes what the CLI scaffolds for you. Existing projects can keep their current tooling and migrate on their own schedule.

#### Testing stack[#](/migration-guide#testing-stack)

Nest's testing utilities remain the same. The main change is the default stack used by generated ESM projects and by the framework's own repositories and samples: Vitest is now the primary default for ESM workflows.

If your application already uses a different test runner, you don't need to migrate immediately. `@nestjs/testing` remains test-runner agnostic.

> **Warning** If you stay on Jest, note that it can load the ESM-only v12 packages only on Node.js v24.9 or later (older versions fail with `ERR_REQUIRE_ASYNC_MODULE`). Run your test suite on Node.js v24.9+, or consider migrating to Vitest. `nest upgrade` bumps Jest to v30 and warns about this.

When you do decide to migrate:

* Update your `test`, `test:watch`, `test:cov`, and `test:e2e` scripts
* Review any runner-specific globals and replace them with Vitest equivalents where needed
* Check your `supertest` imports in E2E tests if your Vitest setup expects default imports

#### Linting defaults[#](/migration-guide#linting-defaults)

Newly generated projects use oxlint by default. You only need to migrate if you want your repository to match the new CLI scaffolding.

#### Route decorator schemas[#](/migration-guide#route-decorator-schemas)

Nest adds a new `schema` option to route parameter decorators such as `@Body()`, `@Query()`, `@Param()`, and `@RawBody()`. The schema metadata is designed for [Standard Schema](https://standardschema.dev/)-compatible libraries such as Zod, Valibot, and ArkType.

For example:

```typescript

@Post()
create(@Body({ schema: createUserSchema }) body: CreateUserDto) {
  return this.usersService.create(body);
}

@Get(':id')
findOne(@Param('id', { schema: z.coerce.number().int().positive() }) id: number) {
  return this.usersService.findOne(id);
}
```

On its own, the decorator only attaches schema metadata. To validate against it, register the built-in `StandardSchemaValidationPipe`:

```typescript

app.useGlobalPipes(new StandardSchemaValidationPipe());
```

This is a schema-first alternative to the traditional `ValidationPipe` plus `class-validator` flow. The same schemas can also feed OpenAPI generation (see [Standard Schema (Zod, Valibot)](/openapi/introduction#standard-schema-zod-valibot)).

The existing decorator-based approach remains fully supported, and there are no plans to remove it. The `schema` option is an additional choice for teams that prefer schema-first libraries such as Zod.

#### Standard Schema serialization[#](/migration-guide#standard-schema-serialization)

Nest also introduces `StandardSchemaSerializerInterceptor`, which validates and transforms outgoing responses with the same Standard Schema ecosystem.

```typescript

@UseInterceptors(StandardSchemaSerializerInterceptor)
@SerializeOptions({ schema: userResponseSchema })
@Get(':id')
findOne(@Param('id') id: string) {
  return this.usersService.findOne(id);
}
```

Use it when you want a schema, instead of `class-transformer` decorators, to drive response shaping.

#### GraphQL IDE configuration[#](/migration-guide#graphql-ide-configuration)

GraphiQL is now the default GraphQL IDE. If you need to customize it, pass a `graphiql` options object instead of setting `graphiql: true`.

```typescript

GraphQLModule.forRoot<ApolloDriverConfig>({
  driver: ApolloDriver,
  graphiql: {
    url: '/graphql',
    headers: {
      authorization: 'Bearer <token>',
    },
    shouldPersistHeaders: true,
    isHeadersEditorEnabled: true,
  },
});
```

This customizes the IDE endpoint and editor behavior while keeping GraphiQL enabled.

#### GraphQL subscriptions transport[#](/migration-guide#graphql-subscriptions-transport)

The latest `@nestjs/graphql` release removes support for `subscriptions-transport-ws`. Use `graphql-ws` for GraphQL subscriptions instead.

```typescript

GraphQLModule.forRoot<ApolloDriverConfig>({
  driver: ApolloDriver,
  subscriptions: {
    'graphql-ws': true,
  },
});
```

If your application still depends on `subscriptions-transport-ws`, plan that migration as part of your GraphQL package upgrade.

#### NATS v3[#](/migration-guide#nats-v3)

The microservices package now targets NATS v3, which includes a breaking dependency change. If you use the NATS transport, replace the old `nats` package with `@nats-io/transport-node`:

```bash

$ npm uninstall nats
$ npm install @nats-io/transport-node
```

If your application imports NATS helpers directly, install `@nats-io/nats-core` as well and update those imports. NATS v3 also dropped the `StringCodec` and `JSONCodec` helpers. For example, the `headers()` helper now comes from `@nats-io/nats-core`:

```typescript

import * as nats from '@nats-io/nats-core';
import { NatsRecordBuilder } from '@nestjs/microservices';

const headers = nats.headers();
headers.set('x-version', '1.0.0');

const record = new NatsRecordBuilder(payload).setHeaders(headers).build();
return this.client.send('record-builder-duplex', record);
```

Also review any custom serializers or deserializers. Nest now serializes NATS packets as JSON strings, and custom NATS deserializers receive the full NATS message object instead of a raw `Uint8Array`. In practice, custom deserializers should read the payload with `msg.json()` instead of decoding bytes manually.

#### Lifecycle hook ordering[#](/migration-guide#lifecycle-hook-ordering)

Lifecycle hooks are now called by component hierarchy level. This can change the execution order of hooks such as `onModuleInit`, `onApplicationBootstrap`, and the shutdown hooks when multiple providers or modules depend on one another.

If your application relies on a specific hook order between related providers, review that flow during the upgrade and update any assumptions in initialization logic, teardown logic, or tests.

#### `@Optional()` is no longer inherited[#](/migration-guide#optional-is-no-longer-inherited)

Nest now reads the optional markers of constructor parameters with `Reflect.getOwnMetadata`, so a subclass no longer inherits the markers its parent declared. Parameter types are still inherited. As a result, a subclass without its own constructor keeps its parent's parameters but loses their optional status, and Nest throws `UnknownDependenciesException` where v11 resolved the parameter as `undefined`.

This is deliberate: a dependency that was genuinely missing used to resolve to `undefined` silently. Give the subclass its own constructor and declare the marker again:

```typescript

@Injectable()
class Child extends Base {
  constructor(@Optional() options?: Options) {
    super(options);
  }
}
```

#### class-validator and class-transformer[#](/migration-guide#class-validator-and-class-transformer)

The existing decorator-based workflow still works in v12. `ValidationPipe` and `ClassSerializerInterceptor` remain supported and are still a good fit for class-based DTO projects.

Version 12 broadens the built-in options rather than replacing the existing ones:

* Use `ValidationPipe` when your DTOs are class-based and rely on decorators
* Use `StandardSchemaValidationPipe` when your validation library already exposes a Standard Schema-compatible schema
* Use `ClassSerializerInterceptor` when your response shaping is based on `class-transformer`
* Use `StandardSchemaSerializerInterceptor` when your response shape should be derived from a schema

#### Config module[#](/migration-guide#config-module)

`@nestjs/config` moves from Joi-specific validation to [Standard Schema](https://standardschema.dev/). The `validationSchema` option now accepts any Standard Schema-compatible schema, such as Zod, Valibot, or ArkType.

```typescript

import { z } from 'zod';

ConfigModule.forRoot({
  validationSchema: z.object({
    NODE_ENV: z
      .enum(['development', 'production', 'test', 'provision'])
      .default('development'),
    PORT: z.coerce.number().default(3000),
  }),
});
```

Because validation is no longer tied to a single library, we now recommend a modern Standard Schema library such as Zod for new projects, and the [Configuration chapter](/application/configuration#schema-validation) has been rewritten around it.

Your existing Joi schemas still work, with two caveats:

* You must upgrade to **Joi v18 or later**, which implements the Standard Schema specification
* Library-specific settings previously passed directly under `validationOptions` now go under `validationOptions.libraryOptions`

```typescript

// Before
validationOptions: {
  allowUnknown: false,
  abortEarly: true,
},

// After
validationOptions: {
  libraryOptions: {
    allowUnknown: false,
    abortEarly: true,
  },
},
```

For Joi schemas, `@nestjs/config` keeps its historical defaults of `allowUnknown: true` and `abortEarly: false`, and merges anything you pass on top of them.

#### Terminus module[#](/migration-guide#terminus-module)

The legacy health indicator API, deprecated in version 11, has been removed. If your custom health indicators still extend `HealthIndicator` or throw a `HealthCheckError`, migrate them to `HealthIndicatorService`.

**Previous Approach**

Before version 12, a custom health indicator could report an unhealthy state by throwing a `HealthCheckError`:

```typescript

@Injectable()
export class DogHealthIndicator extends HealthIndicator {
  constructor(private readonly dogService: DogService) {
    super();
  }

  async isHealthy(key: string) {
    const badboys = await this.dogService.getBadboys();
    const isHealthy = badboys.length === 0;
    const result = this.getStatus(key, isHealthy, { badboys: badboys.length });

    if (!isHealthy) {
      throw new HealthCheckError('Dog check failed', result);
    }

    return result;
  }
}
```

**Updated Approach (NestJS Terminus v12)**

In version 12, the health indicator returns its result in both cases. Throwing is no longer a way to report an unhealthy state. The indicator either returns `up()` / `down()` explicitly, or hands the operation to `attempt()`, which marks the indicator as `'down'` when the operation throws:

```typescript

@Injectable()
export class DogHealthIndicator {
  constructor(
    private readonly dogService: DogService,
    // Inject the `HealthIndicatorService` provided by the `TerminusModule`
    private readonly healthIndicatorService: HealthIndicatorService,
  ) {}

  async isHealthy(key: string) {
    const indicator = this.healthIndicatorService.check(key);
    const badboys = await this.dogService.getBadboys();

    if (badboys.length > 0) {
      // Mark the indicator as "down" and add additional info to the response
      return indicator.down({ badboys: badboys.length });
    }

    // Mark the health indicator as "up"
    return indicator.up();
  }
}
```

If the indicator only needs to know whether an operation succeeded (e.g., that the dog service is reachable), `attempt()` is the shorter form:

```typescript

isHealthy(key: string) {
  return this.healthIndicatorService
    .check(key)
    .attempt(() => this.dogService.ping())
    .withTimeout(1000);
}
```

The `timeout` option of the built-in database, microservice, and gRPC indicators (e.g., `db.pingCheck('database', { timeout: 1500 })`) is deprecated. Chain `.withTimeout(1500)` on the returned attempt instead. See the [Terminus chapter](/reliability/terminus#timeouts-and-caching) for details.

#### Webpack deprecation in CLI workflows[#](/migration-guide#webpack-deprecation-in-cli-workflows)

The v12 release also marks the shift away from webpack-centric CLI workflows. Rspack is now the default bundler for monorepos, and the `--webpack` / `--webpackPath` CLI flags (and their `webpack` / `webpackConfigPath` counterparts in `nest-cli.json`) are deprecated in favor of `--builder rspack`. If your project generation or build setup relies on webpack, plan to migrate it over time.

The CLI also adds `bun` as a supported package manager, and the `decorator` schematic now generates decorators in the `Reflector.createDecorator()` form. The `angular` schematic has been removed.

#### New CLI commands and flags[#](/migration-guide#new-cli-commands-and-flags)

The CLI gains a `deploy` command that forwards to [Mau](https://mau.nestjs.com/), installing `@nestjs/mau` as a dev dependency on first use:

```bash

$ nest deploy
```

`nest build` and `nest start` also pick up several new options:

* `--rspackPath [path]`: path to a Rspack configuration file, the counterpart to the deprecated `--webpackPath`
* `--emit-declarations`: emit `.d.ts` files when using the SWC builder (also available as `emitDeclarations` in `nest-cli.json`)
* `--no-type-check`: explicitly disable SWC type checking
* `--silent`: suppress informational compiler logs

`nest build` also supports `--parallel [concurrency]`, which builds monorepo projects in parallel when combined with `--all`. In addition, `nest-cli.json` gains an `includeLibraryAssets` property for copying library assets into an application build.

#### Route conflict diagnostics[#](/migration-guide#route-conflict-diagnostics)

Nest registers routes in declaration order. On order-sensitive adapters such as Express, this means `@Get(':id')` can silently shadow a `@Get('me')` declared after it. v12 adds two **opt-in** options to `NestApplicationOptions` to address this:

```typescript

const app = await NestFactory.create(AppModule, {
  routeConflictPolicy: { duplicate: 'error', shadow: 'warn' },
  routeResolutionStrategy: 'specificity',
});
```

Both default to the previous behavior, so existing applications are unaffected unless you set them. See the [Controllers chapter](/controllers#route-conflicts-and-resolution-order) for the full description.

#### Machine-readable error codes[#](/migration-guide#machine-readable-error-codes)

`HttpExceptionOptions` accepts a new `errorCode` property. It is serialized into the response body, so clients can branch on a stable identifier instead of parsing the message string:

```typescript

throw new BadRequestException('Password is too weak', {
  errorCode: 'WEAK_PASSWORD',
});
```

See [Machine-readable error codes](/exception-filters#machine-readable-error-codes) in the Exception filters chapter.

#### Structured logging params[#](/migration-guide#structured-logging-params)

`ConsoleLogger` now treats plain objects passed after the message as structured params attached to the same log entry, instead of emitting them as separate records:

```typescript

logger.log('User created', { userId: 1, email: 'foo@bar.com' });
```

In JSON mode, they are nested under a `params` key, or spread into the root object if you enable `flattenParams`. This behavior is on by default in v12; set `structuredParams: false` to restore the previous behavior. See [Structured logging params](/application/logger#structured-logging-params) in the Logger chapter.

#### Native observability support[#](/migration-guide#native-observability-support)

Version 12 adds first-class observability support through the official [`@nestjs/observe`](/observability/overview) SDK. Instead of attaching a generic Node.js APM agent to the HTTP server, the SDK plugs into Nest's own request lifecycle through the `instrument` application option. As a result, requests, jobs, errors, and traces are reported in terms of your controllers, providers, resolvers, and queue consumers.

```typescript

// app.module.ts
import { Module } from '@nestjs/common';
import { createObserveModule } from '@nestjs/observe';

export const { ObserveModule, ObserveInstrument } = createObserveModule();

@Module({
  imports: [ObserveModule.forRoot({ serviceId: 'cats-app' })],
})
export class AppModule {}
```

```typescript

// main.ts
import { NestFactory } from '@nestjs/core';
import { AppModule, ObserveInstrument } from './app.module.js';

const app = await NestFactory.create(AppModule, {
  instrument: ObserveInstrument,
});
```

There is nothing to migrate here: it is a new, opt-in capability. See the [Observability chapter](/observability/overview) for what auto-instrumentation covers, and the [SDK reference](/observability/sdk) for configuration options.

#### Other notable release changes[#](/migration-guide#other-notable-release-changes)

Depending on which Nest packages you use, you may also want to review the following changes:

* **Pipe transform signatures** have been refined for stronger type safety, and `ArgumentMetadata` now takes a generic parameter. Custom pipes with hand-written signatures may need their types adjusted.
* **`ValidationPipe` error format**: the new `errorFormat` option (`'list'` or `'grouped'`) controls the shape of validation error responses.
* **gRPC exception filter**: `GrpcExceptionFilter`, plus a family of status-specific exceptions, maps errors to the proper gRPC status codes instead of `UNKNOWN`. See the [gRPC chapter](/microservices/grpc#exception-handling).
* **Regex Kafka patterns**: `@MessagePattern()` and `@EventPattern()` now accept a `RegExp` on the Kafka transport. See the [Kafka chapter](/microservices/kafka#regular-expression-patterns).
* **Request-scoped WebSocket gateways**: gateways now support request-scoped providers, with the socket injectable through the `REQUEST` token. See the [Gateways chapter](/websockets/gateways#request-scoped-gateways).
* **WebSocket disconnect reason**: `handleDisconnect` can now receive the reason for the disconnection.
* **Microservices pre-request hook**: a new hook runs before a message handler is invoked.
* **Express graceful shutdown**: the Express adapter now drains in-flight requests on shutdown.
* **HTTP adapter error mapping** has been reworked across the core, Express, and Fastify adapters.

If you depend on one of these areas, verify the corresponding behavior with your test suite after upgrading.

#### Switching your project to ESM[#](/migration-guide#switching-your-project-to-esm)

> **Optional** This section and the next one are **not** part of upgrading to v12, which is why they come last. A CommonJS application runs on v12 unchanged: `nest upgrade` doesn't touch your module format, and nothing in the framework requires you to switch. Read on only if you *want* to move your project to ESM, on whatever schedule suits you.

The switch itself happens in `package.json`, not in `tsconfig.json`. Add a `type` field set to `module`:

```json

{
  "name": "my-app",
  "type": "module"
}
```

That single field tells Node.js (and, through `"module": "nodenext"`, TypeScript) to treat your `.js` output as ESM.

Whether you also need to change `tsconfig.json` depends on how old your project is:

* **Projects generated with a recent v11 CLI** (`@nestjs/schematics` 11.0.6 or later) already use `"module": "nodenext"` and `"moduleResolution": "nodenext"`. Nothing in `tsconfig.json` needs to change; adding `"type": "module"` is enough.
* **Projects generated with earlier releases** (v10, or early v11) typically still have `"module": "commonjs"` and no `moduleResolution` entry. Update both before adding `"type": "module"`:

```json

{
  "compilerOptions": {
    "module": "nodenext",
    "moduleResolution": "nodenext",
    "resolvePackageJsonExports": true,
    "target": "ES2023"
  }
}
```

For reference, this is the complete `compilerOptions` set used by the ESM project that `nest new` generates:

```json

{
  "compilerOptions": {
    "module": "nodenext",
    "moduleResolution": "nodenext",
    "resolvePackageJsonExports": true,
    "esModuleInterop": true,
    "isolatedModules": true,
    "declaration": true,
    "removeComments": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "allowSyntheticDefaultImports": true,
    "target": "ES2023",
    "sourceMap": true,
    "outDir": "./dist",
    "rootDir": ".",
    "incremental": true,
    "skipLibCheck": true,
    "strict": true,
    "strictPropertyInitialization": false,
    "types": ["vitest/globals", "node"]
  }
}
```

> **Hint**`nest-cli.json` and `tsconfig.build.json` are identical in the CommonJS and ESM project variants, so neither needs changes. The `types` entry above differs only because ESM projects default to Vitest; a CommonJS project on Jest uses `["node", "jest"]` instead.

> **Warning**`"module": "nodenext"` derives the module format of each file from the nearest `package.json`. Adding `"type": "module"` therefore changes how **every**`.ts` file in the project is emitted, and TypeScript starts reporting the missing import extensions described below. Expect to fix them in the same pass rather than incrementally.

#### Moving your own code to ESM[#](/migration-guide#moving-your-own-code-to-esm)

With the configuration in place, the two things in your own code that most often need attention are relative imports and CommonJS-only globals.

Relative imports must carry a file extension:

```typescript

// Before
import { AppModule } from './app.module';

// After
import { AppModule } from './app.module.js';
```

The extension is `.js` even though the source file is `.ts`, because the specifier refers to the emitted file.

`__dirname` and `__filename` do not exist in ESM. Use `import.meta.dirname` instead (or `import.meta.url` with `fileURLToPath` on older Node.js versions):

```typescript

// Before
protoPath: join(__dirname, 'hero/hero.proto'),

// After
protoPath: join(import.meta.dirname, 'hero/hero.proto'),
```

Similarly, `require()` is unavailable. If you need it for interop, create it explicitly with `createRequire(import.meta.url)` from `node:module`.

> **Hint** Many code samples throughout these docs use the ESM conventions above. If your project is still CommonJS, drop the `.js` extensions, keep `__dirname`, and call `bootstrap()` without `await`.

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/migration.md)

----
url: https://docs.nestjs.com/http/mvc
----

[Skip to content](#content)

On this page

* [Model-View-Controller](https://docs.nestjs.com/http/mvc#model-view-controller)
* [Template rendering](https://docs.nestjs.com/http/mvc#template-rendering)
* [Adding a layout](https://docs.nestjs.com/http/mvc#adding-a-layout)
* [Dynamic template rendering](https://docs.nestjs.com/http/mvc#dynamic-template-rendering)
* [Example](https://docs.nestjs.com/http/mvc#example)
* [Fastify](https://docs.nestjs.com/http/mvc#fastify)
* [Example](https://docs.nestjs.com/http/mvc#example-1)

### Model-View-Controller

By default, Nest uses the [Express](https://github.com/expressjs/express) library under the hood. As a result, every technique for using the MVC (Model-View-Controller) pattern in Express applies to Nest as well.

First, scaffold a new Nest application using the [CLI](https://github.com/nestjs/nest-cli) tool:

```bash

$ npm i -g @nestjs/cli
$ nest new project
```

To create an MVC app, you also need a [template engine](https://expressjs.com/en/guide/using-template-engines.html) to render HTML views:

```bash

$ npm install --save hbs
```

This example uses the `hbs` ([Handlebars](https://github.com/pillarjs/hbs#readme)) engine, but you can use whichever engine fits your requirements. Once the installation process is complete, configure the Express instance using the following code:

main.ts

JS TS

```typescript

import { NestFactory } from '@nestjs/core';
import { NestExpressApplication } from '@nestjs/platform-express';
import { join } from 'node:path';
import { AppModule } from './app.module.js';

async function bootstrap() {
  const app = await NestFactory.create<NestExpressApplication>(
    AppModule,
  );

  app.useStaticAssets(join(import.meta.dirname, '..', 'public'));
  app.setBaseViewsDir(join(import.meta.dirname, '..', 'views'));
  app.setViewEngine('hbs');

  await app.listen(process.env.PORT ?? 3000);
}
await bootstrap();
```

```typescript

import { NestFactory } from '@nestjs/core';
import { join } from 'node:path';
import { AppModule } from './app.module.js';

async function bootstrap() {
  const app = await NestFactory.create(
    AppModule,
  );

  app.useStaticAssets(join(import.meta.dirname, '..', 'public'));
  app.setBaseViewsDir(join(import.meta.dirname, '..', 'views'));
  app.setViewEngine('hbs');

  await app.listen(process.env.PORT ?? 3000);
}
await bootstrap();
```

This tells Express that the `public` directory stores static assets, the `views` directory contains templates, and the `hbs` template engine renders HTML output.

#### Template rendering[#](/http/mvc#template-rendering)

Now, create a `views` directory with an `index.hbs` template inside it. The template prints a `message` passed from the controller:

```html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>App</title>
  </head>
  <body>
    {{ message }}
  </body>
</html>
```

Next, open the `app.controller` file and replace its contents with the following code:

app.controller.ts

JS TS

```typescript

import { Get, Controller, Render } from '@nestjs/common';

@Controller()
export class AppController {
  @Get()
  @Render('index')
  root() {
    return { message: 'Hello world!' };
  }
}
```

This code specifies the template to use in the `@Render()` decorator, and the return value of the route handler method is passed to the template for rendering. The return value is an object with a `message` property, matching the `message` placeholder in the template.

While the application is running, open your browser and navigate to `http://localhost:3000`. You should see the `Hello world!` message.

#### Adding a layout[#](/http/mvc#adding-a-layout)

The `hbs` engine supports layouts: shared wrapper templates that individual views are rendered into. To use one, set the `layout` local variable with the `setLocal()` method (Nest's wrapper around Express's [app.locals](https://expressjs.com/en/5x/api.html#app.locals)). Modify the previous code as follows:

main.ts

JS TS

```typescript

import { NestFactory } from '@nestjs/core';
import { NestExpressApplication } from '@nestjs/platform-express';
import { join } from 'node:path';
import { AppModule } from './app.module.js';

async function bootstrap() {
  const app = await NestFactory.create<NestExpressApplication>(
    AppModule,
  );

  app.setLocal('layout', 'layouts/app');
  app.useStaticAssets(join(import.meta.dirname, '..', 'public'));
  app.setBaseViewsDir(join(import.meta.dirname, '..', 'views'));
  app.setViewEngine('hbs');

  await app.listen(process.env.PORT ?? 3000);
}
await bootstrap();
```

```typescript

import { NestFactory } from '@nestjs/core';
import { join } from 'node:path';
import { AppModule } from './app.module.js';

async function bootstrap() {
  const app = await NestFactory.create(
    AppModule,
  );

  app.setLocal('layout', 'layouts/app');
  app.useStaticAssets(join(import.meta.dirname, '..', 'public'));
  app.setBaseViewsDir(join(import.meta.dirname, '..', 'views'));
  app.setViewEngine('hbs');

  await app.listen(process.env.PORT ?? 3000);
}
await bootstrap();
```

Next, create a `layouts` folder inside `views` and add an `app.hbs` file with the following content:

```html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>App</title>
  </head>
  <body>
    {{{body}}}
  </body>
</html>
```

Then, update the `index.hbs` file to:

```html

{{ message }}
```

The resulting file structure looks as follows:

views

layouts

app.hbs

index.hbs

#### Dynamic template rendering[#](/http/mvc#dynamic-template-rendering)

If the application logic must dynamically decide which template to render, use the `@Res()` decorator and supply the view name in the route handler, rather than in the `@Render()` decorator:

> **Hint** When Nest detects the `@Res()` decorator, it injects the library-specific `response` object, which you can use to render the template dynamically. See the [Express API reference](https://expressjs.com/en/api.html) to learn more about the `response` object.

app.controller.ts

JS TS

```typescript

import { Get, Controller, Res, Render } from '@nestjs/common';
import { Response } from 'express';
import { AppService } from './app.service.js';

@Controller()
export class AppController {
  constructor(private appService: AppService) {}

  @Get()
  root(@Res() res: Response) {
    return res.render(
      this.appService.getViewName(),
      { message: 'Hello world!' },
    );
  }
}
```

#### Example[#](/http/mvc#example)

A working example is available in the [15-mvc sample](https://github.com/nestjs/nest/tree/master/sample/15-mvc).

#### Fastify[#](/http/mvc#fastify)

As mentioned in the [Performance (Fastify)](/http/performance) chapter, you can use any compatible HTTP provider with Nest. One such library is [Fastify](https://github.com/fastify/fastify). To create an MVC application with Fastify, install the following packages:

```bash

$ npm i --save @fastify/static @fastify/view handlebars
```

The next steps follow almost the same process as with Express, with minor platform-specific differences. Once the installation process is complete, open the `main.ts` file and update its contents:

main.ts

JS TS

```typescript

import { NestFactory } from '@nestjs/core';
import { NestFastifyApplication, FastifyAdapter } from '@nestjs/platform-fastify';
import { AppModule } from './app.module.js';
import { join } from 'node:path';
import Handlebars from 'handlebars';

async function bootstrap() {
  const app = await NestFactory.create<NestFastifyApplication>(
    AppModule,
    new FastifyAdapter(),
  );
  app.useStaticAssets({
    root: join(import.meta.dirname, '..', 'public'),
    prefix: '/public/',
  });
  app.setViewEngine({
    engine: {
      handlebars: Handlebars,
    },
    templates: join(import.meta.dirname, '..', 'views'),
  });
  await app.listen(process.env.PORT ?? 3000);
}
await bootstrap();
```

```typescript

import { NestFactory } from '@nestjs/core';
import { FastifyAdapter } from '@nestjs/platform-fastify';
import { AppModule } from './app.module.js';
import { join } from 'node:path';
import Handlebars from 'handlebars';

async function bootstrap() {
  const app = await NestFactory.create(AppModule, new FastifyAdapter());
  app.useStaticAssets({
    root: join(import.meta.dirname, '..', 'public'),
    prefix: '/public/',
  });
  app.setViewEngine({
    engine: {
      handlebars: Handlebars,
    },
    templates: join(import.meta.dirname, '..', 'views'),
  });
  await app.listen(process.env.PORT ?? 3000);
}
await bootstrap();
```

The Fastify API has a few differences, but the end result of these method calls is the same. One notable difference is that with Fastify, the template name you pass to the `@Render()` decorator must include the file extension:

app.controller.ts

JS TS

```typescript

import { Get, Controller, Render } from '@nestjs/common';

@Controller()
export class AppController {
  @Get()
  @Render('index.hbs')
  root() {
    return { message: 'Hello world!' };
  }
}
```

Alternatively, you can use the `@Res()` decorator to inject the response directly and specify the view you want to render, as shown below:

```typescript

import { Get, Res } from '@nestjs/common';
import { FastifyReply } from 'fastify';

@Get()
root(@Res() res: FastifyReply) {
  return res.view('index.hbs', { message: 'Hello world!' });
}
```

While the application is running, open your browser and navigate to `http://localhost:3000`. You should see the `Hello world!` message.

#### Example[#](/http/mvc#example-1)

A working example is available in the [17-mvc-fastify sample](https://github.com/nestjs/nest/tree/master/sample/17-mvc-fastify).

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/http/mvc.md)

----
url: https://docs.nestjs.com/http/compression
----

[Skip to content](#content)

On this page

* [Compression](https://docs.nestjs.com/http/compression#compression)
* [Use with Express (default)](https://docs.nestjs.com/http/compression#use-with-express-default)
* [Use with Fastify](https://docs.nestjs.com/http/compression#use-with-fastify)

### Compression

Compression can significantly reduce the size of the response body, which makes a web app faster to load.

For **high-traffic** websites in production, we strongly recommend offloading compression from the application server, typically to a reverse proxy (e.g., Nginx). In that case, don't use compression middleware.

#### Use with Express (default)[#](/http/compression#use-with-express-default)

Use the [compression](https://github.com/expressjs/compression) middleware package to enable response compression. It supports the gzip, deflate, and Brotli encodings, and picks one based on the request's `Accept-Encoding` header.

First, install the required packages:

```bash

$ npm i --save compression
$ npm i --save-dev @types/compression
```

Once the installation is complete, apply the compression middleware globally:

```typescript

import compression from 'compression';
// somewhere in your initialization file
app.use(compression());
```

#### Use with Fastify[#](/http/compression#use-with-fastify)

If you use the `FastifyAdapter`, use the [@fastify/compress](https://github.com/fastify/fastify-compress) plugin instead:

```bash

$ npm i --save @fastify/compress
```

Once the installation is complete, register the `@fastify/compress` plugin. It compresses all eligible responses by default.

> **Warning** Make sure you pass the `NestFastifyApplication` type when creating the application. Otherwise, the `register()` method isn't available to apply the plugin.

```typescript

import { FastifyAdapter, NestFastifyApplication } from '@nestjs/platform-fastify';

import compression from '@fastify/compress';

// inside bootstrap()
const app = await NestFactory.create<NestFastifyApplication>(AppModule, new FastifyAdapter());
await app.register(compression);
```

By default, `@fastify/compress` uses the first encoding the client accepts, in this order of preference: `zstd` (on Node.js versions that support it), `br` (Brotli), `gzip`, and `deflate`. Brotli achieves a high compression ratio, but higher quality levels are slow. The plugin sets the Brotli quality (`BROTLI_PARAM_QUALITY`) to 4 by default instead of zlib's default of 11. You can set it anywhere from 0 (fastest) to 11 (smallest output), trading compression time against response size. Tune this value for your workload. The following example sets the quality explicitly:

```typescript

import { constants } from 'node:zlib';
// somewhere in your initialization file
await app.register(compression, { brotliOptions: { params: { [constants.BROTLI_PARAM_QUALITY]: 4 } } });
```

Alternatively, you can restrict `@fastify/compress` to gzip and deflate. Responses may be larger, but they are compressed faster.

To specify the encodings, pass the `encodings` option in the second argument to `app.register()`:

```typescript

await app.register(compression, { encodings: ['gzip', 'deflate'] });
```

This configuration tells `@fastify/compress` to use only the gzip and deflate encodings, preferring gzip when the client supports both.

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/http/compression.md)

----
url: https://docs.nestjs.com/data/typeorm
----

[Skip to content](#content)

On this page

* [TypeORM](https://docs.nestjs.com/data/typeorm#typeorm)
* [Repository pattern](https://docs.nestjs.com/data/typeorm#repository-pattern)
* [Relations](https://docs.nestjs.com/data/typeorm#relations)
* [Auto-load entities](https://docs.nestjs.com/data/typeorm#auto-load-entities)
* [Separating entity definition](https://docs.nestjs.com/data/typeorm#separating-entity-definition)
* [TypeORM Transactions](https://docs.nestjs.com/data/typeorm#typeorm-transactions)
* [Subscribers](https://docs.nestjs.com/data/typeorm#subscribers)
* [Migrations](https://docs.nestjs.com/data/typeorm#migrations)
* [Multiple databases](https://docs.nestjs.com/data/typeorm#multiple-databases)
* [Testing](https://docs.nestjs.com/data/typeorm#testing)
* [Async configuration](https://docs.nestjs.com/data/typeorm#async-configuration)
* [Custom DataSource Factory](https://docs.nestjs.com/data/typeorm#custom-datasource-factory)
* [Example](https://docs.nestjs.com/data/typeorm#example)

[](https://srv.carbonads.net/ads/click/x/GTND4277CVSIC2JEFTBLYKQUF67D62Q7CEAD5Z3JCAAI6KQJFTSDLKQKC6ADVKJUCE7IPK7IFTYDKKQYC6YDE2Q7HEYI55QLCAYD653ECTNCYBZ52K)[Enterprise feature management: cloud, compliance, security & governance built in. ](https://srv.carbonads.net/ads/click/x/GTND4277CVSIC2JEFTBLYKQUF67D62Q7CEAD5Z3JCAAI6KQJFTSDLKQKC6ADVKJUCE7IPK7IFTYDKKQYC6YDE2Q7HEYI55QLCAYD653ECTNCYBZ52K)[ads via Carbon](http://carbonads.net/?utm_source=nestjscom\&utm_medium=ad_via_link\&utm_campaign=in_unit\&utm_term=carbon)

### TypeORM

The `@nestjs/typeorm` package integrates [TypeORM](https://github.com/typeorm/typeorm) with Nest. TypeORM is one of the most mature Object Relational Mappers (ORMs) available for TypeScript. Because it's written in TypeScript, it integrates well with Nest.

To get started, install the required dependencies. This chapter uses [MySQL](https://www.mysql.com/), but TypeORM supports many other relational databases, such as PostgreSQL, Oracle, Microsoft SQL Server, and SQLite, as well as NoSQL databases like MongoDB. The steps in this chapter are the same for every database TypeORM supports; you only need to install the client library for your database.

```bash

$ npm install --save @nestjs/typeorm typeorm mysql2
```

Once the installation is complete, import `TypeOrmModule` into the root `AppModule`:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';

@Module({
  imports: [
    TypeOrmModule.forRoot({
      type: 'mysql',
      host: 'localhost',
      port: 3306,
      username: 'root',
      password: 'root',
      database: 'test',
      entities: [],
      synchronize: true,
    }),
  ],
})
export class AppModule {}
```

> **Warning** Don't use `synchronize: true` in production; otherwise, you can lose production data.

The `forRoot()` method accepts all the configuration properties supported by the TypeORM [`DataSource` constructor](https://typeorm.io/docs/data-source/data-source-options#common-data-source-options). It also accepts the following extra properties:

|                        |                                                                                                                                                                                                                                    |
| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `retryAttempts`        | Number of attempts to connect to the database (default: `10`)                                                                                                                                                                      |
| `retryDelay`           | Delay between connection retry attempts, in milliseconds (default: `3000`)                                                                                                                                                         |
| `toRetry`              | Function that receives the connection error and returns whether to retry. By default, every error is retried                                                                                                                       |
| `verboseRetryLog`      | If `true`, the error message is included in the log entry for each connection retry (default: `false`)                                                                                                                             |
| `autoLoadEntities`     | If `true`, entities are loaded automatically (default: `false`). See [Auto-load entities](/data/typeorm#auto-load-entities)                                                                                                        |
| `manualInitialization` | If `true`, the data source isn't initialized during module initialization, so no connection is established and no migrations run. You must call `DataSource.initialize()` yourself and handle retries if needed (default: `false`) |

> **Hint** Learn more about the available options in the [TypeORM data source options](https://typeorm.io/docs/data-source/data-source-options) documentation.

Once this is done, you can inject the TypeORM `DataSource` and `EntityManager` objects anywhere in the project, without importing any modules. For example:

app.module.ts

JS TS

```typescript

import { DataSource } from 'typeorm';

@Module({
  imports: [TypeOrmModule.forRoot(), UsersModule],
})
export class AppModule {
  constructor(private dataSource: DataSource) {}
}
```

```typescript

import { DataSource } from 'typeorm';

@Dependencies(DataSource)
@Module({
  imports: [TypeOrmModule.forRoot(), UsersModule],
})
export class AppModule {
  constructor(dataSource) {
    this.dataSource = dataSource;
  }
}
```

#### Repository pattern[#](/data/typeorm#repository-pattern)

[TypeORM](https://github.com/typeorm/typeorm) supports the **repository design pattern**, so each entity has its own repository. You obtain these repositories from the data source.

To continue the example, we need at least one entity. Let's define the `User` entity.

user.entity.ts

JS TS

```typescript

import { Entity, Column, PrimaryGeneratedColumn } from 'typeorm';

@Entity()
export class User {
  @PrimaryGeneratedColumn()
  id: number;

  @Column()
  firstName: string;

  @Column()
  lastName: string;

  @Column({ default: true })
  isActive: boolean;
}
```

> **Hint** Learn more about entities in the [TypeORM documentation](https://typeorm.io/docs/entity/entities/).

The `User` entity file sits in the `users` directory, which contains all files related to the `UsersModule`. You can keep your model files wherever you like, but we recommend placing them near their **domain**, in the corresponding module directory.

To start using the `User` entity, let TypeORM know about it by adding it to the `entities` array in the `forRoot()` options (unless you use a static glob path):

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { User } from './users/user.entity.js';

@Module({
  imports: [
    TypeOrmModule.forRoot({
      type: 'mysql',
      host: 'localhost',
      port: 3306,
      username: 'root',
      password: 'root',
      database: 'test',
      entities: [User],
      synchronize: true,
    }),
  ],
})
export class AppModule {}
```

Next, let's look at the `UsersModule`:

users.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { UsersService } from './users.service.js';
import { UsersController } from './users.controller.js';
import { User } from './user.entity.js';

@Module({
  imports: [TypeOrmModule.forFeature([User])],
  providers: [UsersService],
  controllers: [UsersController],
})
export class UsersModule {}
```

This module uses the `forFeature()` method to define which repositories are registered in the current scope. With that in place, you can inject the `User` repository into `UsersService` with the `@InjectRepository()` decorator:

users.service.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { User } from './user.entity.js';

@Injectable()
export class UsersService {
  constructor(
    @InjectRepository(User)
    private usersRepository: Repository<User>,
  ) {}

  findAll(): Promise<User[]> {
    return this.usersRepository.find();
  }

  findOne(id: number): Promise<User | null> {
    return this.usersRepository.findOneBy({ id });
  }

  async remove(id: number): Promise<void> {
    await this.usersRepository.delete(id);
  }
}
```

```typescript

import { Injectable, Dependencies } from '@nestjs/common';
import { getRepositoryToken } from '@nestjs/typeorm';
import { User } from './user.entity.js';

@Injectable()
@Dependencies(getRepositoryToken(User))
export class UsersService {
  constructor(usersRepository) {
    this.usersRepository = usersRepository;
  }

  findAll() {
    return this.usersRepository.find();
  }

  findOne(id) {
    return this.usersRepository.findOneBy({ id });
  }

  async remove(id) {
    await this.usersRepository.delete(id);
  }
}
```

> **Notice** Don't forget to import the `UsersModule` into the root `AppModule`.

To use the repository outside the module that imports `TypeOrmModule.forFeature()`, re-export the providers it generates. You can do this by exporting the whole module:

users.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { User } from './user.entity.js';

@Module({
  imports: [TypeOrmModule.forFeature([User])],
  exports: [TypeOrmModule]
})
export class UsersModule {}
```

Now, if you import `UsersModule` into `UserHttpModule`, you can use `@InjectRepository(User)` in the latter module's providers:

users-http.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { UsersModule } from './users.module.js';
import { UsersService } from './users.service.js';
import { UsersController } from './users.controller.js';

@Module({
  imports: [UsersModule],
  providers: [UsersService],
  controllers: [UsersController]
})
export class UserHttpModule {}
```

#### Relations[#](/data/typeorm#relations)

Relations are associations between two or more tables, based on common fields from each table, often involving primary and foreign keys.

There are three types of relations:

|                             |                                                                                                                                                                                                                              |
| --------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `One-to-one`                | Every row in the primary table has one and only one associated row in the foreign table. Use the `@OneToOne()` decorator to define this type of relation.                                                                    |
| `One-to-many / Many-to-one` | Every row in the primary table has one or more related rows in the foreign table. Use the `@OneToMany()` and `@ManyToOne()` decorators to define this type of relation.                                                      |
| `Many-to-many`              | Every row in the primary table has many related rows in the foreign table, and every row in the foreign table has many related rows in the primary table. Use the `@ManyToMany()` decorator to define this type of relation. |

To define relations in entities, use the corresponding **decorators**. For example, to define that each `User` can have multiple photos, use the `@OneToMany()` decorator.

user.entity.ts

JS TS

```typescript

import { Entity, Column, PrimaryGeneratedColumn, OneToMany } from 'typeorm';
import { Photo } from '../photos/photo.entity.js';

@Entity()
export class User {
  @PrimaryGeneratedColumn()
  id: number;

  @Column()
  firstName: string;

  @Column()
  lastName: string;

  @Column({ default: true })
  isActive: boolean;

  @OneToMany(type => Photo, photo => photo.user)
  photos: Photo[];
}
```

> **Hint** To learn more about relations in TypeORM, visit the [TypeORM documentation](https://typeorm.io/docs/relations/relations).

#### Auto-load entities[#](/data/typeorm#auto-load-entities)

Manually adding entities to the `entities` array of the data source options can be tedious. In addition, referencing entities from the root module breaks application domain boundaries and leaks implementation details to other parts of the application. To avoid this, set the `autoLoadEntities` property of the options object passed to `forRoot()` to `true`:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';

@Module({
  imports: [
    TypeOrmModule.forRoot({
      ...
      autoLoadEntities: true,
    }),
  ],
})
export class AppModule {}
```

With this option enabled, every entity registered through the `forFeature()` method is automatically added to the `entities` array of the data source options.

> **Warning** Entities that aren't registered through `forFeature()`, and are only referenced from another entity (via a relation), aren't included by the `autoLoadEntities` setting.

#### Separating entity definition[#](/data/typeorm#separating-entity-definition)

You can define an entity and its columns directly in the model class, using decorators. Alternatively, you can define entities and their columns in separate files using [entity schemas](https://typeorm.io/docs/entity/separating-entity-definition).

```typescript

import { EntitySchema } from 'typeorm';
import { User } from './user.entity.js';

export const UserSchema = new EntitySchema<User>({
  name: 'User',
  target: User,
  columns: {
    id: {
      type: Number,
      primary: true,
      generated: true,
    },
    firstName: {
      type: String,
    },
    lastName: {
      type: String,
    },
    isActive: {
      type: Boolean,
      default: true,
    },
  },
  relations: {
    photos: {
      type: 'one-to-many',
      target: 'Photo', // the name of the PhotoSchema
    },
  },
});
```

> **Warning** If you provide the `target` option, the `name` option must match the name of the target class. If you don't provide `target`, you can use any name.

Nest lets you use an `EntitySchema` instance wherever an entity class is expected. For example:

```typescript

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { UserSchema } from './user.schema.js';
import { UsersController } from './users.controller.js';
import { UsersService } from './users.service.js';

@Module({
  imports: [TypeOrmModule.forFeature([UserSchema])],
  providers: [UsersService],
  controllers: [UsersController],
})
export class UsersModule {}
```

#### TypeORM Transactions[#](/data/typeorm#typeorm-transactions)

A [database transaction](https://en.wikipedia.org/wiki/Database_transaction) is a unit of work performed against a database and treated in a coherent and reliable way, independent of other transactions. A transaction generally represents any change in a database.

There are several strategies for handling [TypeORM transactions](https://typeorm.io/docs/advanced-topics/transactions/). We recommend the `QueryRunner` class, because it gives you full control over the transaction.

First, inject the `DataSource` object into a class as usual:

```typescript

@Injectable()
export class UsersService {
  constructor(private dataSource: DataSource) {}
}
```

> **Hint** The `DataSource` class is imported from the `typeorm` package.

Then use it to create a transaction:

```typescript

async createMany(users: User[]) {
  const queryRunner = this.dataSource.createQueryRunner();

  await queryRunner.connect();
  await queryRunner.startTransaction();
  try {
    await queryRunner.manager.save(users[0]);
    await queryRunner.manager.save(users[1]);

    await queryRunner.commitTransaction();
  } catch (err) {
    // since we have errors, roll back the changes we made
    await queryRunner.rollbackTransaction();
  } finally {
    // you need to release a manually instantiated query runner
    await queryRunner.release();
  }
}
```

> **Hint** The `dataSource` is used only to create the `QueryRunner`. However, testing this class would require mocking the entire `DataSource` object, which exposes many methods. Instead, we recommend a helper factory class (e.g., `QueryRunnerFactory`) that implements an interface with only the methods needed to manage transactions. This makes those methods straightforward to mock.

## Debug production with NestJS Observe

* Every request traced
* Errors with source code
* Logs in context
* Zero config, free plan

[Start for free](https://observe.nestjs.com "Observe | NestJS - A progressive Node.js framework")

Alternatively, you can use the callback-style `transaction()` method of the `DataSource` object (see [Creating and using transactions](https://typeorm.io/docs/advanced-topics/transactions/#creating-and-using-transactions) in the TypeORM documentation):

```typescript

async createMany(users: User[]) {
  await this.dataSource.transaction(async manager => {
    await manager.save(users[0]);
    await manager.save(users[1]);
  });
}
```

#### Subscribers[#](/data/typeorm#subscribers)

With TypeORM [subscribers](https://typeorm.io/docs/advanced-topics/listeners-and-subscribers#what-is-a-subscriber), you can listen to specific entity events.

```typescript

import {
  DataSource,
  EntitySubscriberInterface,
  EventSubscriber,
  InsertEvent,
} from 'typeorm';
import { User } from './user.entity.js';

@EventSubscriber()
export class UserSubscriber implements EntitySubscriberInterface<User> {
  constructor(dataSource: DataSource) {
    dataSource.subscribers.push(this);
  }

  listenTo() {
    return User;
  }

  beforeInsert(event: InsertEvent<User>) {
    console.log(`BEFORE USER INSERTED: `, event.entity);
  }
}
```

> **Warning** Event subscribers cannot be [request-scoped](/fundamentals/injection-scopes).

Now, add the `UserSubscriber` class to the `providers` array:

```typescript

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { User } from './user.entity.js';
import { UsersController } from './users.controller.js';
import { UsersService } from './users.service.js';
import { UserSubscriber } from './user.subscriber.js';

@Module({
  imports: [TypeOrmModule.forFeature([User])],
  providers: [UsersService, UserSubscriber],
  controllers: [UsersController],
})
export class UsersModule {}
```

#### Migrations[#](/data/typeorm#migrations)

[Migrations](https://typeorm.io/docs/advanced-topics/migrations/) provide a way to incrementally update the database schema to keep it in sync with the application's data model while preserving existing data in the database. To generate, run, and revert migrations, TypeORM provides a dedicated [CLI](https://typeorm.io/docs/advanced-topics/migrations/#creating-a-new-migration).

Migration classes are separate from the Nest application source code, and TypeORM manages their lifecycle. Therefore, you can't use dependency injection or other Nest-specific features in migrations. To learn more, see the [migrations guide](https://typeorm.io/docs/advanced-topics/migrations/) in the TypeORM documentation.

#### Multiple databases[#](/data/typeorm#multiple-databases)

Some projects require multiple database connections, which this module also supports. To work with multiple connections, first create them. In this case, every data source other than the default one must have a unique **name**.

Suppose you have an `Album` entity stored in its own database.

```typescript

const defaultOptions = {
  type: 'postgres' as const,
  port: 5432,
  username: 'user',
  password: 'password',
  database: 'db',
  synchronize: true,
};

@Module({
  imports: [
    TypeOrmModule.forRoot({
      ...defaultOptions,
      host: 'user_db_host',
      entities: [User],
    }),
    TypeOrmModule.forRoot({
      ...defaultOptions,
      name: 'albumsConnection',
      host: 'album_db_host',
      entities: [Album],
    }),
  ],
})
export class AppModule {}
```

> **Notice** If you don't set a `name` for a data source, its name is `default`. Don't register multiple data sources without a name, or with the same name; otherwise, they override each other.

> **Notice** If you use `TypeOrmModule.forRootAsync()`, you must **also** set the data source name outside `useFactory`. For example:
>
> ```typescript
>
> TypeOrmModule.forRootAsync({
>   name: 'albumsConnection',
>   useFactory: ...,
>   inject: ...,
> }),
> ```
>
> For more details, see [nestjs/typeorm issue #86](https://github.com/nestjs/typeorm/issues/86).

At this point, the `User` and `Album` entities are each registered with their own data source. With this setup, you have to tell the `TypeOrmModule.forFeature()` method and the `@InjectRepository()` decorator which data source to use. If you don't pass a data source name, the `default` data source is used.

```typescript

@Module({
  imports: [
    TypeOrmModule.forFeature([User]),
    TypeOrmModule.forFeature([Album], 'albumsConnection'),
  ],
})
export class AppModule {}
```

You can also inject the `DataSource` or `EntityManager` for a given data source:

```typescript

@Injectable()
export class AlbumsService {
  constructor(
    @InjectDataSource('albumsConnection')
    private dataSource: DataSource,
    @InjectEntityManager('albumsConnection')
    private entityManager: EntityManager,
  ) {}
}
```

You can also inject any `DataSource` into a factory provider by using the `getDataSourceToken()` function:

```typescript

@Module({
  providers: [
    {
      provide: AlbumsService,
      useFactory: (albumsConnection: DataSource) => {
        return new AlbumsService(albumsConnection);
      },
      inject: [getDataSourceToken('albumsConnection')],
    },
  ],
})
export class AlbumsModule {}
```

#### Testing[#](/data/typeorm#testing)

When unit testing an application, you usually want to avoid connecting to a database, to keep test suites independent and as fast as possible. However, your classes might depend on repositories obtained from the data source instance. The solution is to create mock repositories using [custom providers](/fundamentals/custom-providers). Each registered repository is automatically represented by an `<EntityName>Repository` token, where `EntityName` is the name of your entity class.

The `@nestjs/typeorm` package exports the `getRepositoryToken()` function, which returns this token for a given entity. For a named data source, pass the data source name as the second argument.

```typescript

@Module({
  providers: [
    UsersService,
    {
      provide: getRepositoryToken(User),
      useValue: mockRepository,
    },
  ],
})
export class UsersModule {}
```

Now `mockRepository` is used as the `User` repository. Whenever a class injects it with `@InjectRepository(User)`, Nest provides the registered `mockRepository` object.

#### Async configuration[#](/data/typeorm#async-configuration)

You may want to pass the module options asynchronously instead of statically. In this case, use the `forRootAsync()` method, which supports several ways to provide async configuration.

One approach is to use a factory function:

```typescript

TypeOrmModule.forRootAsync({
  useFactory: () => ({
    type: 'mysql',
    host: 'localhost',
    port: 3306,
    username: 'root',
    password: 'root',
    database: 'test',
    entities: [],
    synchronize: true,
  }),
});
```

The factory behaves like any other [asynchronous provider](/fundamentals/async-providers) (e.g., it can be `async`, and it can inject dependencies through `inject`).

```typescript

TypeOrmModule.forRootAsync({
  imports: [ConfigModule],
  useFactory: (configService: ConfigService) => ({
    type: 'mysql',
    host: configService.get('HOST'),
    port: +configService.get('PORT'),
    username: configService.get('USERNAME'),
    password: configService.get('PASSWORD'),
    database: configService.get('DATABASE'),
    entities: [],
    synchronize: true,
  }),
  inject: [ConfigService],
});
```

Alternatively, you can use the `useClass` syntax:

```typescript

TypeOrmModule.forRootAsync({
  useClass: TypeOrmConfigService,
});
```

The construction above instantiates `TypeOrmConfigService` inside `TypeOrmModule` and uses it to create the options object by calling `createTypeOrmOptions()`. This means that `TypeOrmConfigService` has to implement the `TypeOrmOptionsFactory` interface:

```typescript

@Injectable()
export class TypeOrmConfigService implements TypeOrmOptionsFactory {
  createTypeOrmOptions(): TypeOrmModuleOptions {
    return {
      type: 'mysql',
      host: 'localhost',
      port: 3306,
      username: 'root',
      password: 'root',
      database: 'test',
      entities: [],
      synchronize: true,
    };
  }
}
```

To reuse a provider imported from a different module instead of creating `TypeOrmConfigService` inside `TypeOrmModule`, use the `useExisting` syntax:

```typescript

TypeOrmModule.forRootAsync({
  imports: [ConfigModule],
  useExisting: ConfigService,
});
```

This works the same as `useClass`, with one critical difference: `TypeOrmModule` looks up imported modules to reuse an existing `ConfigService` instead of instantiating a new one.

> **Hint** Define the `name` property at the same level as the `useFactory`, `useClass`, or `useExisting` property. This lets Nest register the data source under the appropriate injection token.

#### Custom DataSource Factory[#](/data/typeorm#custom-datasource-factory)

Together with async configuration (`useFactory`, `useClass`, or `useExisting`), you can optionally specify a `dataSourceFactory` function to provide your own TypeORM data source instead of letting `TypeOrmModule` create it.

`dataSourceFactory` receives the TypeORM `DataSourceOptions` resolved by the async configuration and returns a `Promise` that resolves to a TypeORM `DataSource`. If the returned data source isn't initialized yet, `TypeOrmModule` initializes it (unless `manualInitialization` is set).

```typescript

TypeOrmModule.forRootAsync({
  imports: [ConfigModule],
  inject: [ConfigService],
  // Use useFactory, useClass, or useExisting
  // to configure the DataSourceOptions.
  useFactory: (configService: ConfigService) => ({
    type: 'mysql',
    host: configService.get('HOST'),
    port: +configService.get('PORT'),
    username: configService.get('USERNAME'),
    password: configService.get('PASSWORD'),
    database: configService.get('DATABASE'),
    entities: [],
    synchronize: true,
  }),
  // dataSourceFactory receives the configured DataSourceOptions
  // and returns a Promise<DataSource>.
  dataSourceFactory: async (options) => {
    const dataSource = await new DataSource(options!).initialize();
    return dataSource;
  },
});
```

> **Hint** The `DataSource` class is imported from the `typeorm` package.

#### Example[#](/data/typeorm#example)

A working example is available in the [TypeORM sample application](https://github.com/nestjs/nest/tree/master/sample/05-sql-typeorm) in the NestJS repository.

## Official enterprise support

* Providing technical guidance
* Performing in-depth code reviews
* Mentoring team members
* Advising best practices

[Explore more](https://enterprise.nestjs.com "Enterprise | NestJS - A progressive Node.js framework")

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/data/typeorm.md)

----
url: https://docs.nestjs.com/v7/graphql/extensions
----

* [Extensions](https://docs.nestjs.com/v7/graphql/extensions#extensions)
* [Adding custom metadata](https://docs.nestjs.com/v7/graphql/extensions#adding-custom-metadata)
* [Using custom metadata](https://docs.nestjs.com/v7/graphql/extensions#using-custom-metadata)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/extensions.md "Suggest Edits")

### Extensions

> **Warning** This chapter applies only to the code first approach.

Extensions is an **advanced, low-level feature** that lets you define arbitrary data in the types configuration. Attaching custom metadata to certain fields allows you to create more sophisticated, generic solutions. For example, with extensions, you can define field-level roles required to access particular fields. Such roles can be reflected at runtime to determine whether the caller has sufficient permissions to retrieve a specific field.

#### Adding custom metadata[#](/graphql/extensions#adding-custom-metadata)

To attach custom metadata for a field, use the `@Extensions()` decorator exported from the `@nestjs/graphql` package.

```typescript

@Field()
@Extensions({ role: Role.ADMIN })
password: string;
```

In the example above, we assigned the `role` metadata property the value of `Role.ADMIN`. `Role` is a simple TypeScript enum that groups all the user roles available in our system.

Note, in addition to setting metadata on fields, you can use the `@Extensions()` decorator at the class level and method level (e.g., on the query handler).

#### Using custom metadata[#](/graphql/extensions#using-custom-metadata)

Logic that leverages the custom metadata can be as complex as needed. For example, you can create a simple interceptor that stores/logs events per method invocation, or a [field middleware](/v7/graphql/field-middleware) that matches roles required to retrieve a field with the caller permissions (field-level permissions system).

For illustration purposes, let's define a `checkRoleMiddleware` that compares a user's role (hardcoded here) with a role required to access a target field:

```typescript

export const checkRoleMiddleware: FieldMiddleware = async (
  ctx: MiddlewareContext,
  next: NextFn,
) => {
  const { info } = ctx;
  const { extensions } = info.parentType.getFields()[info.fieldName];

  /**
   * In a real-world application, the "userRole" variable
   * should represent the caller's (user) role (for example, "ctx.user.role").
   */
  const userRole = Role.USER;
  if (userRole === extensions.role) {
    // or just "return null" to ignore
    throw new ForbiddenException(
      `User does not have sufficient permissions to access "${info.fieldName}" field.`,
    );
  }
  return next();
};
```

With this in place, we can register a middleware for the `password` field, as follows:

```typescript

@Field({ middleware: [checkRoleMiddleware] })
@Extensions({ role: Role.ADMIN })
password: string;
```

----
url: https://docs.nestjs.com/v5/microservices/redis
----

### Redis

A second built-in transporter is based on [Redis](https://redis.io/) database. This transporter takes advantage of **publish/subscribe** feature.

#### Installation

Before we start, we have to install required package:

```bash

$ npm i --save redis
```

#### Overview

In order to switch from TCP transport strategy to Redis **pub/sub**, we need to change an options object passed to the `createMicroservice()` method.

main.ts

JS TS

TypeScript

```typescript

const app = await NestFactory.createMicroservice(ApplicationModule, {
  transport: Transport.REDIS,
  options: {
    url: 'redis://localhost:6379',
  },
});
```

#### Options

There are a bunch of available options that determine a transporter behaviour.

|                 |                                       |
| --------------- | ------------------------------------- |
| `url`           | Connection url                        |
| `retryAttempts` | A total amount of connection attempts |
| `retryDelay`    | A connection retrying delay (ms)      |

* Redis

----
url: https://docs.nestjs.com/v7/cli/scripts
----

* [Nest CLI and scripts](https://docs.nestjs.com/v7/cli/scripts#nest-cli-and-scripts)
* [The nest binary](https://docs.nestjs.com/v7/cli/scripts#the-nest-binary)
* [Build](https://docs.nestjs.com/v7/cli/scripts#build)
* [Execution](https://docs.nestjs.com/v7/cli/scripts#execution)
* [Generation](https://docs.nestjs.com/v7/cli/scripts#generation)
* [Package scripts](https://docs.nestjs.com/v7/cli/scripts#package-scripts)
* [Backward compatibility](https://docs.nestjs.com/v7/cli/scripts#backward-compatibility)
* [Migration](https://docs.nestjs.com/v7/cli/scripts#migration)

```bash

$ npm run build
```

and

```bash

$ npm run start
```

```bash

$ npm install -g @nestjs/cli
$ cd  /some/project/root/folder
$ npm install -D @nestjs/cli
```

You can then replace the `scripts` defined in `package.json` with the following ones:

```typescript

"build": "nest build",
"start": "nest start",
"start:dev": "nest start --watch",
"start:debug": "nest start --debug --watch",
```

----
url: https://docs.nestjs.com/v8
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Introduction](https://docs.nestjs.com/v8/#introduction)
* [Philosophy](https://docs.nestjs.com/v8/#philosophy)
* [Installation](https://docs.nestjs.com/v8/#installation)
* [Alternatives](https://docs.nestjs.com/v8/#alternatives)

To get started, you can either scaffold the project with the [Nest CLI](/v8/cli/overview), or clone a starter project (both will produce the same outcome).

To scaffold the project with the Nest CLI, run the following commands. This will create a new project directory, and populate the directory with the initial core Nest files and supporting modules, creating a conventional base structure for your project. Creating a new project with the **Nest CLI** is recommended for first-time users. We'll continue with this approach in [First Steps](/v8/first-steps).

```bash

$ npm i -g @nestjs/cli
$ nest new project-name
```

#### Alternatives[#](/#alternatives)

Alternatively, to install the TypeScript starter project with **Git**:

```bash

$ git clone https://github.com/nestjs/typescript-starter.git project
$ cd project
$ npm install
$ npm run start
```

> **Hint** If you'd like to clone the repository without the git history, you can use [degit](https://github.com/Rich-Harris/degit).

Open your browser and navigate to [`http://localhost:3000/`](http://localhost:3000/).

To install the JavaScript flavor of the starter project, use `javascript-starter.git` in the command sequence above.

You can also manually create a new project from scratch by installing the core and supporting files with **npm** (or **yarn**). In this case, of course, you'll be responsible for creating the project boilerplate files yourself.

```bash

$ npm i --save @nestjs/core @nestjs/common rxjs reflect-metadata
```

----
url: https://docs.nestjs.com/fundamentals/async-providers
----

[Skip to content](#content)

On this page

* [Asynchronous providers](https://docs.nestjs.com/fundamentals/async-providers#asynchronous-providers)
* [Injection](https://docs.nestjs.com/fundamentals/async-providers#injection)

### Asynchronous providers

Sometimes the application start should be delayed until one or more **asynchronous tasks** complete. For example, you may not want to start accepting requests until the connection to the database has been established. Asynchronous providers let you do this.

To create one, use `async/await` with the `useFactory` syntax. The factory returns a `Promise`, and the factory function can `await` asynchronous tasks. Nest awaits resolution of the promise before instantiating any class that depends on (injects) such a provider.

```typescript

{
  provide: 'ASYNC_CONNECTION',
  useFactory: async () => {
    const connection = await createConnection(options);
    return connection;
  },
}
```

> **Hint** Learn more about the custom provider syntax in the [custom providers](/fundamentals/custom-providers) chapter.

#### Injection[#](/fundamentals/async-providers#injection)

Asynchronous providers are injected into other components by their tokens, like any other provider. In the example above, you would use `@Inject('ASYNC_CONNECTION')`.

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/fundamentals/async-components.md)

----
url: https://docs.nestjs.com/v9/techniques/versioning
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Versioning](https://docs.nestjs.com/v9/techniques/versioning#versioning)
* [URI Versioning Type](https://docs.nestjs.com/v9/techniques/versioning#uri-versioning-type)
* [Header Versioning Type](https://docs.nestjs.com/v9/techniques/versioning#header-versioning-type)
* [Media Type Versioning Type](https://docs.nestjs.com/v9/techniques/versioning#media-type-versioning-type)
* [Custom Versioning Type](https://docs.nestjs.com/v9/techniques/versioning#custom-versioning-type)
* [Usage](https://docs.nestjs.com/v9/techniques/versioning#usage)
* [Controller versions](https://docs.nestjs.com/v9/techniques/versioning#controller-versions)
* [Route versions](https://docs.nestjs.com/v9/techniques/versioning#route-versions)
* [Multiple versions](https://docs.nestjs.com/v9/techniques/versioning#multiple-versions)
* [Version "Neutral"](https://docs.nestjs.com/v9/techniques/versioning#version-neutral)
* [Global default version](https://docs.nestjs.com/v9/techniques/versioning#global-default-version)
* [Middleware versioning](https://docs.nestjs.com/v9/techniques/versioning#middleware-versioning)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/techniques/versioning.md "Suggest Edits")

### Versioning

> **Hint** This chapter is only relevant to HTTP-based applications.

Versioning allows you to have **different versions** of your controllers or individual routes running within the same application. Applications change very often and it is not unusual that there are breaking changes that you need to make while still needing to support the previous version of the application.

There are 4 types of versioning that are supported:

|                                                                             |                                                                                                                            |
| --------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- |
| [`URI Versioning`](techniques/versioning#uri-versioning-type)               | The version will be passed within the URI of the request (default)                                                         |
| [`Header Versioning`](techniques/versioning#header-versioning-type)         | A custom request header will specify the version                                                                           |
| [`Media Type Versioning`](techniques/versioning#media-type-versioning-type) | The `Accept` header of the request will specify the version                                                                |
| [`Custom Versioning`](techniques/versioning#custom-versioning-type)         | Any aspect of the request may be used to specify the version(s). A custom function is provided to extract said version(s). |

#### URI Versioning Type[#](/techniques/versioning#uri-versioning-type)

URI Versioning uses the version passed within the URI of the request, such as `https://example.com/v1/route` and `https://example.com/v2/route`.

> **Notice** With URI Versioning the version will be automatically added to the URI after the [global path prefix](faq/global-prefix) (if one exists), and before any controller or route paths.

To enable URI Versioning for your application, do the following:

main.ts

JS TS

```typescript

const app = await NestFactory.create(AppModule);
// or "app.enableVersioning()"
app.enableVersioning({
  type: VersioningType.URI,
});
await app.listen(3000);
```

> **Notice** The version in the URI will be automatically prefixed with `v` by default, however the prefix value can be configured by setting the `prefix` key to your desired prefix or `false` if you wish to disable it.

> **Hint** The `VersioningType` enum is available to use for the `type` property and is imported from the `@nestjs/common` package.

#### Header Versioning Type[#](/techniques/versioning#header-versioning-type)

Header Versioning uses a custom, user specified, request header to specify the version where the value of the header will be the version to use for the request.

Example HTTP Requests for Header Versioning:

To enable **Header Versioning** for your application, do the following:

main.ts

JS TS

```typescript

const app = await NestFactory.create(AppModule);
app.enableVersioning({
  type: VersioningType.HEADER,
  header: 'Custom-Header',
});
await app.listen(3000);
```

The `header` property should be the name of the header that will contain the version of the request.

> **Hint** The `VersioningType` enum is available to use for the `type` property and is imported from the `@nestjs/common` package.

#### Media Type Versioning Type[#](/techniques/versioning#media-type-versioning-type)

Media Type Versioning uses the `Accept` header of the request to specify the version.

Within the `Accept` header, the version will be separated from the media type with a semi-colon, `;`. It should then contain a key-value pair that represents the version to use for the request, such as `Accept: application/json;v=2`. They key is treated more as a prefix when determining the version will to be configured to include the key and separator.

To enable **Media Type Versioning** for your application, do the following:

main.ts

JS TS

```typescript

const app = await NestFactory.create(AppModule);
app.enableVersioning({
  type: VersioningType.MEDIA_TYPE,
  key: 'v=',
});
await app.listen(3000);
```

The `key` property should be the key and separator of the key-value pair that contains the version. For the example `Accept: application/json;v=2`, the `key` property would be set to `v=`.

> **Hint** The `VersioningType` enum is available to use for the `type` property and is imported from the `@nestjs/common` package.

#### Custom Versioning Type[#](/techniques/versioning#custom-versioning-type)

Custom Versioning uses any aspect of the request to specify the version (or versions). The incoming request is analyzed using an `extractor` function that returns a string or array of strings.

If multiple versions are provided by the requester, the extractor function can return an array of strings, sorted in order of greatest/highest version to smallest/lowest version. Versions are matched to routes in order from highest to lowest.

If an empty string or array is returned from the `extractor`, no routes are matched and a 404 is returned.

For example, if an incoming request specifies it supports versions `1`, `2`, and `3`, the `extractor`**MUST** return `[3, 2, 1]`. This ensures that the highest possible route version is selected first.

If versions `[3, 2, 1]` are extracted, but routes only exist for version `2` and `1`, the route that matches version `2` is selected (version `3` is automatically ignored).

> **Notice** Selecting the highest matching version based on the array returned from `extractor` > **does not reliably work** with the Express adapter due to design limitations. A single version (either a string or array of 1 element) works just fine in Express. Fastify correctly supports both highest matching version selection and single version selection.

To enable **Custom Versioning** for your application, create an `extractor` function and pass it into your application like so:

main.ts

JS TS

```typescript

// Example extractor that pulls out a list of versions from a custom header and turns it into a sorted array.
// This example uses Fastify, but Express requests can be processed in a similar way.
const extractor = (request: FastifyRequest): string | string[] =>
  [request.headers['custom-versioning-field'] ?? '']
     .flatMap(v => v.split(','))
     .filter(v => !!v)
     .sort()
     .reverse()

const app = await NestFactory.create(AppModule);
app.enableVersioning({
  type: VersioningType.CUSTOM,
  extractor,
});
await app.listen(3000);
```

#### Usage[#](/techniques/versioning#usage)

Versioning allows you to version controllers, individual routes, and also provides a way for certain resources to opt-out of versioning. The usage of versioning is the same regardless of the Versioning Type your application uses.

> **Notice** If versioning is enabled for the application but the controller or route does not specify the version, any requests to that controller/route will be returned a `404` response status. Similarly, if a request is received containing a version that does not have a corresponding controller or route, it will also be returned a `404` response status.

#### Controller versions[#](/techniques/versioning#controller-versions)

A version can be applied to a controller, setting the version for all routes within the controller.

To add a version to a controller do the following:

cats.controller.ts

JS TS

```typescript

@Controller({
  version: '1',
})
export class CatsControllerV1 {
  @Get('cats')
  findAll(): string {
    return 'This action returns all cats for version 1';
  }
}
```

```typescript

@Controller({
  version: '1',
})
export class CatsControllerV1 {
  @Get('cats')
  findAll() {
    return 'This action returns all cats for version 1';
  }
}
```

#### Route versions[#](/techniques/versioning#route-versions)

A version can be applied to an individual route. This version will override any other version that would effect the route, such as the Controller Version.

To add a version to an individual route do the following:

cats.controller.ts

JS TS

```typescript

import { Controller, Get, Version } from '@nestjs/common';

@Controller()
export class CatsController {
  @Version('1')
  @Get('cats')
  findAllV1(): string {
    return 'This action returns all cats for version 1';
  }

  @Version('2')
  @Get('cats')
  findAllV2(): string {
    return 'This action returns all cats for version 2';
  }
}
```

```typescript

import { Controller, Get, Version } from '@nestjs/common';

@Controller()
export class CatsController {
  @Version('1')
  @Get('cats')
  findAllV1() {
    return 'This action returns all cats for version 1';
  }

  @Version('2')
  @Get('cats')
  findAllV2() {
    return 'This action returns all cats for version 2';
  }
}
```

#### Multiple versions[#](/techniques/versioning#multiple-versions)

Multiple versions can be applied to a controller or route. To use multiple versions, you would set the version to be an Array.

To add multiple versions do the following:

cats.controller.ts

JS TS

```typescript

@Controller({
  version: ['1', '2'],
})
export class CatsController {
  @Get('cats')
  findAll(): string {
    return 'This action returns all cats for version 1 or 2';
  }
}
```

```typescript

@Controller({
  version: ['1', '2'],
})
export class CatsController {
  @Get('cats')
  findAll() {
    return 'This action returns all cats for version 1 or 2';
  }
}
```

#### Version "Neutral"[#](/techniques/versioning#version-neutral)

Some controllers or routes may not care about the version and would have the same functionality regardless of the version. To accommodate this, the version can be set to `VERSION_NEUTRAL` symbol.

An incoming request will be mapped to a `VERSION_NEUTRAL` controller or route regardless of the version sent in the request in addition to if the request does not contain a version at all.

> **Notice** For URI Versioning, a `VERSION_NEUTRAL` resource would not have the version present in the URI.

To add a version neutral controller or route do the following:

cats.controller.ts

JS TS

```typescript

import { Controller, Get, VERSION_NEUTRAL } from '@nestjs/common';

@Controller({
  version: VERSION_NEUTRAL,
})
export class CatsController {
  @Get('cats')
  findAll(): string {
    return 'This action returns all cats regardless of version';
  }
}
```

```typescript

import { Controller, Get, VERSION_NEUTRAL } from '@nestjs/common';

@Controller({
  version: VERSION_NEUTRAL,
})
export class CatsController {
  @Get('cats')
  findAll() {
    return 'This action returns all cats regardless of version';
  }
}
```

#### Global default version[#](/techniques/versioning#global-default-version)

If you do not want to provide a version for each controller/or individual routes, or if you want to have a specific version set as the default version for every controller/route that don't have the version specified, you could set the `defaultVersion` as follows:

main.ts

JS TS

```typescript

app.enableVersioning({
  // ...
  defaultVersion: '1'
  // or
  defaultVersion: ['1', '2']
  // or
  defaultVersion: VERSION_NEUTRAL
});
```

#### Middleware versioning[#](/techniques/versioning#middleware-versioning)

[Middlewares](https://docs.nestjs.com/middleware) can also use versioning metadata to configure the middleware for a specific route's version. To do so, provide the version number as one of the parameters for the `MiddlewareConsumer.forRoutes()` method:

app.module.ts

JS TS

```typescript

import { Module, NestModule, MiddlewareConsumer } from '@nestjs/common';
import { LoggerMiddleware } from './common/middleware/logger.middleware';
import { CatsModule } from './cats/cats.module';
import { CatsController } from './cats/cats.controller';

@Module({
  imports: [CatsModule],
})
export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer
      .apply(LoggerMiddleware)
      .forRoutes({ path: 'cats', method: RequestMethod.GET, version: '2' });
  }
}
```

With the code above, the `LoggerMiddleware` will only be applied to the version '2' of `/cats` endpoint.

> **Notice** Middlewares work with any versioning type described in the this section: `URI`, `Header`, `Media Type` or `Custom`.

----
url: https://docs.nestjs.com/application/file-storage
----

[Skip to content](#content)

On this page

* [File storage](https://docs.nestjs.com/application/file-storage#file-storage)
* [Installation](https://docs.nestjs.com/application/file-storage#installation)
* [Configure the disks](https://docs.nestjs.com/application/file-storage#configure-the-disks)
* [Upload product photos](https://docs.nestjs.com/application/file-storage#upload-product-photos)
* [Keep invoices private](https://docs.nestjs.com/application/file-storage#keep-invoices-private)
* [Serve signed URLs in development](https://docs.nestjs.com/application/file-storage#serve-signed-urls-in-development)
* [Upload straight to storage from the mobile app](https://docs.nestjs.com/application/file-storage#upload-straight-to-storage-from-the-mobile-app)
* [Use S3 or R2 in production](https://docs.nestjs.com/application/file-storage#use-s3-or-r2-in-production)
* [Try it](https://docs.nestjs.com/application/file-storage#try-it)
* [Testing](https://docs.nestjs.com/application/file-storage#testing)
* [Production checklist](https://docs.nestjs.com/application/file-storage#production-checklist)
* [Reference](https://docs.nestjs.com/application/file-storage#reference)

### File storage

An online store for cat food and supplies keeps three kinds of files. Product photos are uploaded by staff and shown to everyone. Invoices are PDF files that only the customer who paid should be able to download. And the warehouse team photographs products with the store's mobile app, which uploads large photos that shouldn't have to pass through the order API.

In development, all of this should work from a folder on the laptop. In production, the files go to S3 or Cloudflare R2, because the API runs on several instances and none of them has a disk that lasts. The code that stores and serves files should be the same in both.

`@nestjs/storage` gives each place files live a name, a **disk**, and one API for all of them: `put()`, `get()`, `list()`, `delete()`, public URLs and signed URLs. It ships a local disk, an S3 disk that works with AWS S3 and S3-compatible stores (Cloudflare R2, MinIO, Backblaze B2), and an in-memory disk for tests. It talks to S3 over `fetch`, with no AWS SDK, and depends only on `@nestjs/common` and `@nestjs/core`.

It doesn't parse uploads. multer on Express and `@nestjs/platform-fastify/multipart` on Fastify keep doing that, with `FileInterceptor()` as usual. This package is where the files end up: it provides a storage engine that streams each upload straight onto a disk.

In this tutorial, you'll:

* configure a public disk for photos and a private disk for everything else,
* stream photo uploads onto the photos disk, with the type and size checked before anything is written,
* store invoices privately and hand out download links that expire after five minutes,
* let the mobile app upload photos directly to storage, with a signed upload URL,
* switch from local disks to S3 or R2 with configuration alone,
* test all of it against in-memory disks.

#### Installation[#](/application/file-storage#installation)

To get started, install the required dependencies:

```bash

$ npm i --save @nestjs/storage @nestjs/config
```

#### Configure the disks[#](/application/file-storage#configure-the-disks)

The app needs two disks. `photos` holds product photos, which anyone may see, so it has a public URL. `private` holds invoices and uploads that haven't been checked yet, and is only reachable through signed URLs. Keeping public and private files on separate disks (separate buckets, in production) means a file never becomes public by accident.

Start with the configuration, a [custom configuration file](/application/configuration#custom-configuration-files) for `@nestjs/config`. `STORAGE_DRIVER` will pick local disks or S3 [in production](/application/file-storage#use-s3-or-r2-in-production); until then, everything is local:

config/configuration.ts

JS TS

```typescript

export default () => ({
  appUrl: process.env.APP_URL ?? 'http://localhost:3000',
  storage: {
    // 'local' in development, 's3' in production (AWS S3, Cloudflare R2, MinIO...)
    driver: process.env.STORAGE_DRIVER ?? 'local',
    root: process.env.STORAGE_ROOT ?? 'storage',
    signingKey: process.env.STORAGE_SIGNING_KEY,
    s3: {
      endpoint: process.env.S3_ENDPOINT,
      region: process.env.S3_REGION ?? 'auto',
      photosBucket: process.env.S3_PHOTOS_BUCKET ?? 'store-photos',
      privateBucket: process.env.S3_PRIVATE_BUCKET ?? 'store-private',
      photosUrl: process.env.PHOTOS_CDN_URL,
    },
  },
});
```

The disks are built from that configuration by a factory function:

storage/storage.config.ts

JS TS

```typescript

import { ConfigService } from '@nestjs/config';
import { LocalDisk, type StorageModuleOptions } from '@nestjs/storage';

export function createStorageOptions(config: ConfigService): StorageModuleOptions {
  const appUrl = config.getOrThrow<string>('appUrl');
  const root = config.getOrThrow<string>('storage.root');
  return {
    default: 'private',
    disks: {
      // Product photos: public, served by the app in development
      photos: new LocalDisk({ root: `${root}/photos`, publicUrl: `${appUrl}/photos` }),
      // Invoices and uploads in progress: only reachable through signed URLs
      private: new LocalDisk({
        root: `${root}/private`,
        signedUrls: {
          baseUrl: `${appUrl}/files`,
          keys: [config.getOrThrow<string>('storage.signingKey')],
        },
      }),
    },
  };
}
```

A `LocalDisk` keeps files in a directory, which it creates at startup. `publicUrl` is where the files can be fetched publicly: the photos disk's `url(key)` returns URLs under it. In development, the app itself will serve that path (see [Upload product photos](/application/file-storage#upload-product-photos)); in production, a CDN will.

A local directory can't produce signed URLs the way S3 does, so the private disk signs its own: with `signedUrls`, its `signedUrl()` returns URLs under `baseUrl`, signed with HMAC-SHA256, which the app verifies and serves (see [Serve signed URLs in development](/application/file-storage#serve-signed-urls-in-development)). `keys` takes one or more keys. The first signs, and all of them verify, so you can rotate a key by putting the new one first and removing the old one once the links it signed have expired. A key must have at least 32 characters.

Register the module with `forRootAsync()`, so the factory can read `ConfigService`:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { StorageModule } from '@nestjs/storage';
import configuration from './config/configuration.js';
import { createStorageOptions } from './storage/storage.config.js';

@Module({
  imports: [
    ConfigModule.forRoot({ isGlobal: true, load: [configuration] }),
    StorageModule.forRootAsync({
      inject: [ConfigService],
      useFactory: createStorageOptions,
    }),
  ],
})
export class AppModule {}
```

`StorageModule` is global. Services inject a disk in one of three ways:

| Injection                                                    | Gives you                                                                   |
| ------------------------------------------------------------ | --------------------------------------------------------------------------- |
| `private readonly files: StorageDisk`                        | The default disk, here `private`                                            |
| `@InjectDisk('photos') private readonly photos: StorageDisk` | The disk called `photos`                                                    |
| `private readonly storage: Storage`                          | Every disk: `storage.disk('photos')`, for code that picks a disk at runtime |

Configuration mistakes stop the application at startup. Without `STORAGE_SIGNING_KEY`, `getOrThrow()` reports the missing key; with a short one, the error says the signing key must have at least 32 characters. The same goes for a `default` that names no disk, and for a class that injects a disk name no configuration provides:

```text

PhotosService injects the disk "photos" (@InjectDisk('photos')), but StorageModule has no disk by that name. Configured disks: private.
```

#### Upload product photos[#](/application/file-storage#upload-product-photos)

Photos may be JPEG, PNG or WebP images of up to 5 MiB. The rules are shared by the upload endpoint below and the [mobile uploads](/application/file-storage#upload-straight-to-storage-from-the-mobile-app) further down:

products/photo-rules.ts

JS TS

```typescript

/** What a product photo may be, wherever it is uploaded from. */
export const PHOTO_TYPES = ['image/jpeg', 'image/png', 'image/webp'];
export const MAX_PHOTO_SIZE = 5 * 1024 * 1024; // 5 MiB
/** Every photo gets a new key, so browsers and the CDN may cache it forever. */
export const PHOTO_CACHE_CONTROL = 'public, max-age=31536000, immutable';
```

The upload endpoint uses `FileInterceptor()` from `@nestjs/platform-express`, as any upload does. The difference is the `storage` option: `uploadToDisk()` is a multer storage engine that streams the file onto a disk instead of into memory or a temp folder:

products/photos.controller.ts

JS TS

```typescript

import { BadRequestException, Controller, Get, Param, Post, Req, Res, UploadedFile, UseInterceptors } from '@nestjs/common';
import { FileInterceptor } from '@nestjs/platform-express';
import { InjectDisk, serveFile, StorageDisk, uploadToDisk, type StoredUpload } from '@nestjs/storage';
import type { Request, Response } from 'express';
import { MAX_PHOTO_SIZE, PHOTO_CACHE_CONTROL, PHOTO_TYPES } from './photo-rules.js';
import { PhotosService } from './photos.service.js';

@Controller()
export class PhotosController {
  constructor(
    private readonly photosService: PhotosService,
    @InjectDisk('photos') private readonly photos: StorageDisk,
  ) {}

  @Post('products/:id/photo')
  @UseInterceptors(
    FileInterceptor('photo', {
      storage: uploadToDisk({ disk: 'photos', contentTypes: PHOTO_TYPES, cacheControl: PHOTO_CACHE_CONTROL }),
      limits: { fileSize: MAX_PHOTO_SIZE, files: 1 },
    }),
  )
  upload(@Param('id') id: string, @UploadedFile() file: StoredUpload | undefined) {
    if (!file) {
      throw new BadRequestException('Attach the image as the "photo" field');
    }
    return this.photosService.replace(id, file.key);
  }

  // Development only: in production a CDN serves the photos bucket at `publicUrl`
  @Get('photos/:file')
  serve(@Param('file') file: string, @Req() req: Request, @Res({ passthrough: true }) res: Response) {
    return serveFile(this.photos, file, { req, res, disposition: 'inline' });
  }
}
```

By the time the handler runs, the photo is stored. `uploadToDisk()` has done three things on the way:

* **It checked what the file is, not what the client says it is.** A browser sends the type it guesses from the file name, and a script can send anything, so a file declared `image/png` may well be an HTML page or an SVG with a script in it. The engine reads the first bytes of the stream, detects the type from their signature (JPEG, PNG, GIF, WebP, AVIF, HEIC and PDF are built in; [other formats](/application/file-storage#accept-csv-and-other-text-formats) take a detector of your own), and refuses anything not in `contentTypes` with a `415` before a byte is written. The stored content type is the detected one, never the client's.
* **It enforced the size limit without leaving a partial file.** multer stops reading at `limits.fileSize`. The engine then refuses to commit what it received: the request fails with `413 File too large`, nothing is stored, and no file is replaced.
* **It picked the key.** By default, a random UUID and the extension of the detected type, such as `2f1c0d6e-….png`. Unique keys matter: an upload never overwrites another, and a cached photo never goes stale.

`@UploadedFile()` returns a `StoredUpload`: multer's usual fields (`fieldname`, `originalname`, `mimetype`, `size`) plus `key`, `disk`, `contentType` and `etag`. `mimetype` is still the client's claim; use `contentType`.

> **Hint**`ParseFilePipe` and its validators run after the interceptor, when a streamed file is already stored, and `FileTypeValidator` needs the file in memory to check its bytes. With `uploadToDisk()`, check type and size in the engine, as above. On Fastify, import `FileInterceptor` from `@nestjs/platform-fastify/multipart` and register `@fastify/multipart`; `uploadToDisk()` works the same with both.

Products have this shape, and the application's `ProductsService` has `findOne(id)`, which throws `NotFoundException` for an unknown id, and `setPhoto(id, key)`:

products/product.ts

JS TS

```typescript

export interface Product {
  id: string;
  name: string;
  /** Price in cents */
  price: number;
  /** Where the photo lives on the `photos` disk */
  photoKey?: string;
}
```

The service records the new photo, and deletes the previous one:

products/photos.service.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { InjectDisk, StorageDisk } from '@nestjs/storage';
import { ProductsService } from './products.service.js';

@Injectable()
export class PhotosService {
  constructor(
    private readonly productsService: ProductsService,
    @InjectDisk('photos') private readonly photos: StorageDisk,
  ) {}

  async replace(productId: string, key: string): Promise<{ id: string; photoUrl: string }> {
    let previous: string | undefined;
    try {
      previous = this.productsService.findOne(productId).photoKey;
      this.productsService.setPhoto(productId, key);
    } catch (error) {
      // The upload is already stored: don't leave it behind for a product that doesn't exist
      await this.photos.delete(key);
      throw error;
    }
    if (previous) {
      await this.photos.delete(previous);
    }
    return { id: productId, photoUrl: this.photos.url(key) };
  }
}
```

The interceptor runs before the handler, so the file is stored even when the product turns out not to exist. The service deletes it in that case, which keeps a mistyped id from leaving orphans behind. `url(key)` builds the public URL from the disk's `publicUrl`.

The `GET photos/:file` route serves photos in development. `serveFile()` streams a file from a disk as the response, with `Content-Type`, `Content-Length`, `ETag`, `Last-Modified`, the `Cache-Control` stored with the file (`private` when none is, so a shared cache never keeps a file that may be one user's), and `X-Content-Type-Options: nosniff`, so the browser never second-guesses the type. `disposition: 'inline'` lets the browser show the image; for types that could run script in your origin, such as HTML or SVG, `serveFile()` sends `Content-Disposition: attachment` regardless. It answers `Range` requests with `206`, `If-None-Match` with `304`, and a missing file with `404`.

Register the feature module, and import `ProductsModule` in `AppModule`:

products/products.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { PhotosController } from './photos.controller.js';
import { PhotosService } from './photos.service.js';
import { ProductsService } from './products.service.js';

@Module({
  controllers: [PhotosController],
  providers: [ProductsService, PhotosService],
})
export class ProductsModule {}
```

##### Accept CSV and other text formats[#](/application/file-storage#accept-csv-and-other-text-formats)

Built-in detection recognizes formats by the fixed bytes they start with. A CSV file has no such signature, so `contentTypes: ['text/csv']` on its own refuses every CSV with a `415`. For a format like that, pass `detectContentType`: a function that receives the start of the file and returns its type, or `undefined` when it doesn't recognize it.

Staff update prices by uploading a spreadsheet export. The app recognizes one by its header row:

products/price-list.ts

JS TS

```typescript

/** The header row of a price list exported from the spreadsheet */
const PRICE_LIST_HEADER = 'sku,price';

/** Recognizes a price list by its first line. It doesn't check the rows. */
export function detectPriceList(bytes: Buffer): string | undefined {
  // Spreadsheet apps often start a UTF-8 export with a byte order mark: TextDecoder drops it
  const text = new TextDecoder().decode(bytes);
  const header = text.split(/\r?\n/, 1)[0];
  return header === PRICE_LIST_HEADER ? 'text/csv; charset=utf-8' : undefined;
}
```

The upload endpoint allows `text/csv` and passes the function to `uploadToDisk()`. Price lists go to the private disk, because nobody has checked their rows yet:

products/price-lists.controller.ts

JS TS

```typescript

@Post('products/price-lists')
@UseInterceptors(
  FileInterceptor('prices', {
    storage: uploadToDisk({
      disk: 'private',
      key: (file) => `price-lists/${randomUUID()}${file.extension}`,
      contentTypes: ['text/csv'],
      detectContentType: detectPriceList,
    }),
    limits: { fileSize: 1024 * 1024, files: 1 },
  }),
)
importPrices(@UploadedFile() file: StoredUpload | undefined) {
  if (!file) {
    throw new BadRequestException('Attach the price list as the "prices" field');
  }
  return this.priceListsService.import(file.key);
}
```

* **Built-in detection comes first.** The function only runs when the file isn't one of the built-in formats. A PNG renamed to `prices.csv` is still detected as a PNG, and refused. Passing the exported `detectContentType()` helper as the option does nothing, because that's the check that already ran.
* **It sees the start of the file.**`bytes` holds the first 4 KiB, or the whole file when it's smaller. To change that, set `contentTypeSampleBytes` to a whole number from 1 byte to 64 KiB (it requires `detectContentType`). The second argument has `originalname` and `mimetype`, but they're the client's claims, so decide from the bytes.
* **What it returns is checked against `contentTypes`.** Types are compared without their parameters: `text/csv` in the list allows `text/csv; charset=utf-8`. When the function returns `undefined`, or a type that isn't in the list, the upload is refused with a `415` before a byte is written. Without `contentTypes`, any returned type is accepted, and an unrecognized file is stored as `application/octet-stream`.
* **The returned type is the one the file is stored and served with.** Include the charset for text formats. It also sets the extension: `file.extension` is `.csv` in `key()` above, and the default key ends with it too.
* **It may be async.** The engine waits for the promise while it holds the request, so it must settle quickly. Return `undefined` for a file you don't recognize rather than throwing: an error fails the upload as it would anywhere else in the request, so anything but an `HttpException` becomes a `500` instead of a `415`. So does returning anything but a string or `undefined`.

> **Warning** The function classifies the start of the file. It doesn't validate the file: a price list with the right header can hold anything after it. `PriceListsService.import()` must read the whole file, check every row, and delete `file.key` when it rejects the list, as with any check that runs after the interceptor.

#### Keep invoices private[#](/application/file-storage#keep-invoices-private)

An invoice is generated the first time a customer asks for it and stored on the private disk. A real app renders the PDF with a library or a rendering service; this stand-in is enough to follow the flow:

invoices/render-invoice.ts

JS TS

```typescript

import type { Order } from '../orders/order.interface.js';

const usd = (cents: number) => (cents / 100).toFixed(2);

/** A stand-in for a real PDF renderer (pdfkit, a headless browser, a rendering service). */
export function renderInvoice(order: Order): Buffer {
  const lines = order.items.map((item) => `% ${item.quantity} x ${item.name}  ${usd(item.price)}`);
  return Buffer.from(
    ['%PDF-1.7', `% Invoice for ${order.id}`, ...lines, `% Total ${usd(order.total)} USD`, '%%EOF', ''].join('\n'),
  );
}
```

The service reads the order with the application's `OrdersService`, in which order `ord_1000` has been paid and `ord_1001` hasn't, stores the invoice once, and returns a signed link to it:

invoices/invoices.service.ts

JS TS

```typescript

import { ConflictException, Injectable } from '@nestjs/common';
import { StorageDisk } from '@nestjs/storage';
import { OrdersService } from '../orders/orders.service.js';
import { renderInvoice } from './render-invoice.js';

@Injectable()
export class InvoicesService {
  constructor(
    private readonly ordersService: OrdersService,
    // No name: the default disk, `private`
    private readonly storageDisk: StorageDisk,
  ) {}

  async downloadUrl(orderId: string) {
    const order = this.ordersService.findOne(orderId);
    if (order.status === 'pending') {
      throw new ConflictException(`Order ${orderId} has not been paid yet`);
    }
    const key = `invoices/${order.id}.pdf`;
    if (!(await this.storageDisk.exists(key))) {
      await this.storageDisk.put(key, renderInvoice(order), {
        contentType: 'application/pdf',
        metadata: { orderId: order.id },
      });
    }
    const url = await this.storageDisk.signedUrl(key, {
      expiresIn: '5m',
      filename: `invoice-${order.id}.pdf`,
    });
    return { url };
  }
}
```

`put()` takes a `Buffer`, a string, a `Uint8Array`, a Node stream, a web `ReadableStream`, or any async iterable of bytes. On every disk, a write is atomic: a reader sees the old file or the new one, never half of one, and a write that fails leaves nothing behind. `metadata` stores your own string values with the file; `stat()` and `get()` return them.

For `LocalDisk`, a failed filesystem write removes the temporary file and preserves any existing file. If writing makes no progress, or the persisted size differs from the bytes written, `put()` rejects with `StorageError`.

`signedUrl()` returns a link that works without any other credentials until it expires. `expiresIn` is a duration: `'5m'`, `'1h'`, or milliseconds, 15 minutes by default and at most 7 days, S3's limit. `filename` sets the name the browser saves the file under.

The endpoint returns the link rather than the file, which lets a web page or the mobile app open it directly:

orders/orders.controller.ts

JS TS

```typescript

import { Controller, Get, Param } from '@nestjs/common';
import { InvoicesService } from '../invoices/invoices.service.js';

@Controller('orders')
export class OrdersController {
  constructor(private readonly invoicesService: InvoicesService) {}

  @Get(':id/invoice')
  invoice(@Param('id') id: string) {
    return this.invoicesService.downloadUrl(id);
  }
}
```

Register `OrdersController`, `OrdersService` and `InvoicesService` in an `OrdersModule`. In a real app, the endpoint also checks that the invoice belongs to the signed-in customer, for instance with a policy from the [authorization](/security/authorization) tutorial. The link itself needs no check: whoever holds it may download that one file until it expires.

#### Serve signed URLs in development[#](/application/file-storage#serve-signed-urls-in-development)

With a local disk, the signed link points at the app itself, `http://localhost:3000/files?key=…&expires=…&signature=…`, so the app needs a route that verifies and serves it:

files/files.controller.ts

JS TS

```typescript

import { Controller, Get, Req, Res } from '@nestjs/common';
import { serveSignedUrl, StorageDisk } from '@nestjs/storage';
import type { Request, Response } from 'express';

/**
 * Serves the private disk's signed URLs when it is a local disk. With S3, the URLs point at
 * the bucket and this route answers 404.
 */
@Controller('files')
export class FilesController {
  constructor(private readonly storageDisk: StorageDisk) {}

  @Get()
  download(@Req() req: Request, @Res({ passthrough: true }) res: Response) {
    return serveSignedUrl(this.storageDisk, { req, res });
  }
}
```

`serveSignedUrl()` checks the signature, the expiry and the method, then answers like `serveFile()`, with the file name the link was signed with. The signature covers the route (`baseUrl`), the key, the expiry and the file name, so changing any of them is a `403 Invalid signed URL`, a link past its expiry is a `403 The signed URL has expired`, and a link issued for one disk's route is refused by another's, even when both use the same signing key. Download managers can resume a large file with `Range` requests.

Register the controller in a `FilesModule`, and import it in `AppModule` along with the other features:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { StorageModule } from '@nestjs/storage';
import configuration from './config/configuration.js';
import { FilesModule } from './files/files.module.js';
import { OrdersModule } from './orders/orders.module.js';
import { ProductsModule } from './products/products.module.js';
import { createStorageOptions } from './storage/storage.config.js';

@Module({
  imports: [
    ConfigModule.forRoot({ isGlobal: true, load: [configuration] }),
    StorageModule.forRootAsync({
      inject: [ConfigService],
      useFactory: createStorageOptions,
    }),
    ProductsModule,
    OrdersModule,
    FilesModule,
  ],
})
export class AppModule {}
```

The route stays in the app in production. There, the private disk is an S3 disk whose signed URLs point at the bucket, so `serveSignedUrl()` has nothing to serve and answers `404`.

#### Upload straight to storage from the mobile app[#](/application/file-storage#upload-straight-to-storage-from-the-mobile-app)

The warehouse team photographs products with the mobile app. Photos are large, and phones are often on slow connections, so an upload through the API would hold a connection and a request for as long as it takes. Instead, the app asks the API for an upload URL, sends the photo straight to storage, and then tells the API it is done:

1. `POST /products/:id/photo/uploads` with the photo's type and size returns a signed upload URL.
2. The app sends the photo to that URL with `PUT`.
3. `PUT /products/:id/photo` with the upload's key makes it the product's photo.

The upload goes to the private disk, under `incoming/`, because the API hasn't looked at it yet. Only after checking it does the API copy it to the photos disk:

products/photos.service.ts

JS TS

```typescript

@Injectable()
export class PhotosService {
  constructor(
    private readonly productsService: ProductsService,
    @InjectDisk('photos') private readonly photos: StorageDisk,
    @InjectDisk('private') private readonly uploads: StorageDisk,
  ) {}

  // ...

  async createUpload(productId: string, contentType: string, size: number) {
    this.productsService.findOne(productId);
    if (!PHOTO_TYPES.includes(contentType)) {
      throw new UnsupportedMediaTypeException(`A photo must be one of: ${PHOTO_TYPES.join(', ')}`);
    }
    if (!Number.isSafeInteger(size) || size < 1 || size > MAX_PHOTO_SIZE) {
      throw new BadRequestException(`size must be between 1 and ${MAX_PHOTO_SIZE} bytes`);
    }
    // Private until checked; the product id in the key ties the upload to this product
    const key = `incoming/${productId}/${randomUUID()}`;
    const upload = await this.uploads.signedUpload(key, { contentType, contentLength: size, expiresIn: '10m' });
    return { key, ...upload };
  }

  async completeUpload(productId: string, key: string) {
    this.productsService.findOne(productId);
    // Only keys this endpoint handed out for this product: never copy an arbitrary private
    // file (an invoice) to the public photos disk.
    const prefix = `incoming/${productId}/`;
    if (typeof key !== 'string' || !key.startsWith(prefix) || !/^[0-9a-f-]{36}$/.test(key.slice(prefix.length))) {
      throw new BadRequestException('Unknown upload');
    }
    const file = await this.uploads.stat(key).catch((error: unknown) => {
      if (error instanceof StorageFileNotFoundError) {
        throw new BadRequestException('Upload the file first');
      }
      throw error;
    });
    if (file.size > MAX_PHOTO_SIZE) {
      await this.uploads.delete(key);
      throw new PayloadTooLargeException('File too large');
    }
    // The client chose the Content-Type: check what the bytes are
    const head = await this.uploads.get(key, { range: { start: 0, end: 15 } });
    const type = detectContentType(await buffer(head.body));
    if (!type || !PHOTO_TYPES.includes(type)) {
      await this.uploads.delete(key);
      throw new UnsupportedMediaTypeException(`A photo must be one of: ${PHOTO_TYPES.join(', ')}`);
    }
    // Stream it from the private disk to the public one
    const photoKey = `${randomUUID()}${EXTENSIONS[type]}`;
    const { body } = await this.uploads.get(key);
    await this.photos.put(photoKey, body, {
      contentType: type,
      contentLength: file.size,
      cacheControl: PHOTO_CACHE_CONTROL,
    });
    await this.uploads.delete(key);
    return this.replace(productId, photoKey);
  }
}
```

`signedUpload()` returns the URL, the method (`PUT`), the headers the client must send, and when the URL expires. The URL is signed for exactly the declared content type and size: a different `Content-Type`, or a body of another length, is refused by the storage (`403`), so the app can't send a 2 GB video where it announced a 2 MB photo.

The declared type is still the client's claim. `completeUpload()` therefore treats the upload as untrusted:

* **The key must be one it handed out for this product.** Without that check, a client could submit `invoices/ord_1000.pdf` and have the API copy someone's invoice to the public photos disk.
* **The size is checked again** with `stat()`, which returns the file's metadata without its body.
* **The bytes are checked** by reading only the first 16, with a ranged `get()`, and passing them to `detectContentType()`, which recognizes JPEG, PNG, GIF, WebP, AVIF, HEIC and PDF.

Only then is the photo streamed from one disk to the other: `get()` returns the body as a Node stream, and `put()` accepts it, so the file never sits in memory whole. On S3, that is a download and an upload through the API instance, which is fine for photos; for very large files, you would process them where they are, for instance with a job.

The two routes in the controller pass the request on:

products/photos.controller.ts

JS TS

```typescript

// The mobile app asks for an upload URL, sends the photo there, then submits its key
@Post('products/:id/photo/uploads')
createUpload(@Param('id') id: string, @Body() body: { contentType: string; size: number }) {
  return this.photosService.createUpload(id, body.contentType, body.size);
}

@Put('products/:id/photo')
completeUpload(@Param('id') id: string, @Body('key') key: string) {
  return this.photosService.completeUpload(id, key);
}
```

With a local disk, the upload URL points at the app again, so `FilesController` receives the `PUT` too. `receiveSignedUpload()` does what S3 does with a presigned URL: it checks the signature, the expiry, the content type and the length, and streams the body onto the disk:

files/files.controller.ts

JS TS

```typescript

import { Controller, Get, Put, Req, Res } from '@nestjs/common';
import { receiveSignedUpload, serveSignedUrl, StorageDisk } from '@nestjs/storage';
import type { Request, Response } from 'express';

/**
 * Serves the private disk's signed URLs when it is a local disk. With S3, the URLs point at
 * the bucket and this route answers 404.
 */
@Controller('files')
export class FilesController {
  constructor(private readonly storageDisk: StorageDisk) {}

  @Get()
  download(@Req() req: Request, @Res({ passthrough: true }) res: Response) {
    return serveSignedUrl(this.storageDisk, { req, res });
  }

  @Put()
  upload(@Req() req: Request, @Res({ passthrough: true }) res: Response) {
    return receiveSignedUpload(this.storageDisk, { req, res });
  }
}
```

> **Hint** On Fastify, the upload's body must reach the handler unread. Fastify only parses JSON and plain text by default and answers other content types with `415`, so register a catch-all parser that leaves the body alone: `app.getHttpAdapter().getInstance().addContentTypeParser('*', (req, payload, done) => done(null))`.

Uploads that are never completed stay under `incoming/`. On S3, a lifecycle rule deletes them after a day (see the production checklist).

#### Use S3 or R2 in production[#](/application/file-storage#use-s3-or-r2-in-production)

In production, both disks become S3 disks. A local disk can't serve there: a container's file system is discarded when the task is replaced (a deploy, a scale-in, a failed node), taking the files with it, and other instances can't read them. Only the factory changes; every service, controller and signed URL keeps working:

storage/storage.config.ts

JS TS

```typescript

import { ConfigService } from '@nestjs/config';
import { LocalDisk, S3Disk, type StorageModuleOptions } from '@nestjs/storage';

export function createStorageOptions(config: ConfigService): StorageModuleOptions {
  if (config.get('storage.driver') === 's3') {
    const s3 = {
      endpoint: config.get<string>('storage.s3.endpoint'),
      region: config.getOrThrow<string>('storage.s3.region'),
    };
    return {
      default: 'private',
      disks: {
        photos: new S3Disk({
          ...s3,
          bucket: config.getOrThrow<string>('storage.s3.photosBucket'),
          publicUrl: config.getOrThrow<string>('storage.s3.photosUrl'),
        }),
        private: new S3Disk({
          ...s3,
          bucket: config.getOrThrow<string>('storage.s3.privateBucket'),
        }),
      },
    };
  }

  // ... the local disks from before
}
```

`S3Disk` reads credentials from the standard `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY` and `AWS_SESSION_TOKEN` variables, unless you pass `credentials`, either an object or a function that returns them (called before every request, for credentials that rotate). Without credentials, the app doesn't start. The same class covers several services:

| Service              | Settings                                                                                     |
| -------------------- | -------------------------------------------------------------------------------------------- |
| AWS S3               | `region`, such as `eu-central-1`. No `endpoint`                                              |
| Cloudflare R2        | `endpoint: 'https://<account id>.r2.cloudflarestorage.com'`, `region: 'auto'`                |
| MinIO                | `endpoint: 'http://minio:9000'`, `forcePathStyle: true`                                      |
| Backblaze B2         | `endpoint: 'https://s3.<region>.backblazeb2.com'`, `region`                                  |
| Google Cloud Storage | `endpoint: 'https://storage.googleapis.com'`, HMAC keys as credentials, `batchDelete: false` |

With S3, `signedUrl()` and `signedUpload()` return presigned URLs, signed with the credentials, which the bucket verifies itself: the app's `/files` route isn't involved. `url()` returns URLs under `publicUrl`, typically a CDN or R2's public bucket domain in front of the photos bucket.

Uploads stream to S3 too. A file up to 8 MiB goes up in one request; a longer one, or a stream whose length isn't known, goes up as a multipart upload, four 8 MiB parts at a time, and is aborted if anything fails, so a failed upload never becomes a file. Requests that fail with a network error, a timeout, throttling (`429`, `SlowDown`) or a `5xx` are retried with backoff, up to 3 attempts in all. `multipart`, `retry` and `timeout` tune this per disk.

> **Hint** Every S3 request is signed with Signature Version 4, implemented on `node:crypto`. It is checked against the AWS Signature Version 4 test suite and the examples in the Amazon S3 API reference, so there is no AWS SDK to install.

#### Try it[#](/application/file-storage#try-it)

Start the app with a signing key, in a directory with a `kibble.png`, a `scratching-post.jpg` and a `notes.txt`:

```bash

$ export STORAGE_SIGNING_KEY=$(openssl rand -hex 32)
$ npm run start
```

Upload a photo. Then try a text file declared as an image, which the app refuses without storing it:

```bash

$ curl -F photo=@kibble.png localhost:3000/products/salmon-kibble-2kg/photo
{"id":"salmon-kibble-2kg","photoUrl":"http://localhost:3000/photos/b098be38-74b4-427a-8239-0ab3dc3a31d2.png"}

$ curl -F 'photo=@notes.txt;type=image/png' localhost:3000/products/salmon-kibble-2kg/photo
{"message":"File type not allowed. Allowed types: image/jpeg, image/png, image/webp","error":"Unsupported Media Type","statusCode":415}
```

Fetch a photo's headers:

```bash

$ PHOTO=$(curl -s -F photo=@kibble.png localhost:3000/products/salmon-kibble-2kg/photo | jq -r .photoUrl)
$ curl -sI "$PHOTO" | grep -iE '^(content-|cache-control|x-content)'
X-Content-Type-Options: nosniff
Cache-Control: public, max-age=31536000, immutable
Content-Type: image/png
Content-Disposition: inline; filename="fc54756b-b451-41a8-82c9-2b979f99849a.png"
Content-Length: 70
```

Get a signed link to an invoice, download it, and try the same link for another order:

```bash

$ curl localhost:3000/orders/ord_1000/invoice
{"url":"http://localhost:3000/files?key=invoices%2Ford_1000.pdf&expires=1790319338&disposition=attachment%3B+filename%3D%22invoice-ord_1000.pdf%22&signature=w1O_KuRThM1epUeyqpsbXNGfECkQ9605tZzNjVFMsy8"}

$ INVOICE=$(curl -s localhost:3000/orders/ord_1000/invoice | jq -r .url)
$ curl -sOJ "$INVOICE"
$ head -c 8 invoice-ord_1000.pdf
%PDF-1.7

$ curl "${INVOICE/ord_1000/ord_1001}"
{"message":"Invalid signed URL","error":"Forbidden","statusCode":403}
```

Finally, upload a photo the way the mobile app does. Ask for an upload URL, send the file there, and submit its key:

```bash

$ curl -s localhost:3000/products/sisal-scratching-post/photo/uploads --json "{\"contentType\":\"image/jpeg\",\"size\":$(wc -c < scratching-post.jpg)}" | tee upload.json | jq
{
  "key": "incoming/sisal-scratching-post/7fe80da3-4710-4940-a904-4a1756280440",
  "url": "http://localhost:3000/files?key=incoming%2Fsisal-scratching-post%2F7fe80da3-4710-4940-a904-4a1756280440&expires=1790319638&method=PUT&type=image%2Fjpeg&length=2011&signature=vx-LwzqLUUeTQevHKTDjguRTM3c_FWOjCbik1Uo6Ojg",
  "method": "PUT",
  "headers": {
    "content-type": "image/jpeg"
  },
  "expiresAt": "2026-09-25T07:00:38.736Z"
}

$ curl -T scratching-post.jpg -H 'content-type: image/jpeg' "$(jq -r .url upload.json)"
{"key":"incoming/sisal-scratching-post/7fe80da3-4710-4940-a904-4a1756280440","size":2011,"contentType":"image/jpeg","etag":"\"7db-65c4922577c58\""}

$ curl -X PUT localhost:3000/products/sisal-scratching-post/photo --json "$(jq -c '{key}' upload.json)"
{"id":"sisal-scratching-post","photoUrl":"http://localhost:3000/photos/5329e44d-7a45-49a5-96eb-6ea0016da7eb.jpg"}
```

The files are in `storage/photos` and `storage/private`, as plain files: `storage/private/invoices/ord_1000.pdf` is the invoice. The `.nest-storage` folder in each holds temporary files during writes, and the metadata that a file name can't carry.

#### Testing[#](/application/file-storage#testing)

`InMemoryDisk` keeps files in memory and behaves like the other disks: the same key rules, ranges, listings, metadata and signed URLs. Like S3, it can hold both `a` and `a/b`, which a local disk refuses with `StorageKeyConflictError`. In an end-to-end test, replace the disks by overriding `STORAGE_MODULE_OPTIONS`, the options the factory would have returned:

test/photos.e2e-spec.ts

JS TS

```typescript

import type { INestApplication } from '@nestjs/common';
import { InMemoryDisk, STORAGE_MODULE_OPTIONS } from '@nestjs/storage';
import { Test } from '@nestjs/testing';
import request from 'supertest';
import { AppModule } from '../src/app.module.js';

const PNG = Buffer.from('89504e470d0a1a0a0000000d49484452', 'hex');

describe('Product photos', () => {
  let app: INestApplication;
  const photos = new InMemoryDisk({ publicUrl: 'https://photos.example.com' });
  const files = new InMemoryDisk({
    signedUrls: { baseUrl: 'https://api.example.com/files', keys: ['test-signing-key-0123456789abcdef'] },
  });

  beforeAll(async () => {
    const moduleRef = await Test.createTestingModule({ imports: [AppModule] })
      .overrideProvider(STORAGE_MODULE_OPTIONS)
      .useValue({ default: 'private', disks: { photos, private: files } })
      .compile();
    app = moduleRef.createNestApplication();
    await app.init();
  });

  afterAll(() => app.close());
  beforeEach(() => photos.clear());

  it('stores the photo and returns its public URL', async () => {
    const res = await request(app.getHttpServer())
      .post('/products/salmon-kibble-2kg/photo')
      .attach('photo', PNG, 'photo.png')
      .expect(201);

    const [key] = photos.keys();
    expect(res.body.photoUrl).toBe(`https://photos.example.com/${key}`);
    expect(await photos.getBuffer(key)).toEqual(PNG);
  });

  it('refuses a file that is not an image', async () => {
    await request(app.getHttpServer())
      .post('/products/salmon-kibble-2kg/photo')
      .attach('photo', Buffer.from('<html></html>'), 'photo.png')
      .expect(415);

    expect(photos.keys()).toEqual([]);
  });
});
```

The overridden options replace the factory's result, so the test needs no signing key and touches no file system. `keys()` lists what a disk holds and `clear()` empties it. The upload goes through multer and `uploadToDisk()` as in production; only the place the bytes land differs.

To test what reaches a real file system, use a `LocalDisk` on a temporary directory instead. For S3-specific behavior, such as presigned URLs or multipart uploads, point an `S3Disk` at MinIO or another S3-compatible server running locally.

#### Production checklist[#](/application/file-storage#production-checklist)

* **Keep public and private files in separate buckets.** Give the photos bucket public read access, or put a CDN in front of it and point `publicUrl` at the CDN. Keep the private bucket fully private: invoices and uploads are only reachable through signed URLs. There is no per-file public flag, because new S3 buckets have object ACLs disabled, and a flag on one file is easy to get wrong.
* **Expire abandoned uploads.** Add a lifecycle rule to the private bucket that deletes objects under `incoming/` after a day, and one that aborts incomplete multipart uploads after a day.
* **Allow direct uploads from browsers with CORS.** The mobile app doesn't need it, but a web page that sends a `PUT` to a presigned URL does: allow `PUT` from your site's origin, with the `Content-Type` header.
* **Grant the app only what it uses.** An IAM policy with `s3:GetObject`, `s3:PutObject`, `s3:DeleteObject` and `s3:ListBucket` on the two buckets is enough. Keep `s3:ListBucket`: without it, S3 answers a request for a missing file with `403` instead of `404`, and `exists()` fails instead of returning `false`. For short-lived credentials, pass a `credentials` function that returns them.
* **Encrypt at rest.** S3 encrypts new objects by default; for a KMS key of your own, set `serverSideEncryption: 'aws:kms'` and `kmsKeyId` on the disk. R2 always encrypts.
* **Keep links short-lived.** Five minutes is plenty for a link a user clicks right away. A signed URL can't be revoked: it stays valid until it expires (or, on S3, until the credentials that signed it expire or lose access), so whoever it leaks to can use it until then.
* **Set a signing key per environment** for local disks (development and CI), from a secret, with at least 32 characters, and rotate it by putting the new key first in `keys`.
* **Don't use a local disk in production.** Files written to a container's disk vanish when the task is replaced, and other instances can't read them. Use S3, R2 or another object store (see [Use S3 or R2 in production](/application/file-storage#use-s3-or-r2-in-production)); local disks are for development and tests, and the module logs a warning at startup when it finds one with `NODE_ENV=production`.
* **Treat every key built from user input with care.** Keys are validated on every disk (no `..`, no absolute paths, no control characters), so user input can't escape a disk, but it can still name any file on it. Build keys from ids you control, as the upload endpoints above do.

#### Reference[#](/application/file-storage#reference)

##### Module options[#](/application/file-storage#module-options)

`StorageModule.forRoot()` takes these options, and a `forRootAsync()` factory returns `default` and disk instances. Disk classes, `imports` and `isGlobal` sit next to `useFactory`, `useClass` or `useExisting`. The options are provided as `STORAGE_MODULE_OPTIONS`.

| Option     | Default         | Description                                                                                                                                                            |
| ---------- | --------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `disks`    | none (required) | Disks by name: instances, or `StorageDisk` classes that Nest instantiates, which can inject. See [Configure the disks](/application/file-storage#configure-the-disks). |
| `default`  | the only disk   | The disk that `StorageDisk` and `storage.disk()` resolve to. Required with more than one disk.                                                                         |
| `imports`  | none            | Modules whose exports the disk classes inject.                                                                                                                         |
| `isGlobal` | `true`          | Registers `Storage`, `StorageDisk` and the named disks globally.                                                                                                       |

##### Disk methods[#](/application/file-storage#disk-methods)

Every disk has the same methods, key rules and errors. A key is a relative, `/`-separated path of at most 1024 UTF-8 bytes, without empty, `.` or `..` segments, backslashes or control characters.

| Method                              | Description                                                                                                                                                                                                                                                              |
| ----------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `put(key, body, options)`           | Writes a file atomically. Options: `contentType` (inferred from the extension by default), `cacheControl`, `contentDisposition`, `metadata` (string values, 2 KB in total), `contentLength`, `signal`. Resolves to `key`, `size`, `contentType` and `etag`.              |
| `get(key, options)`                 | The file's metadata and its `body` as a Node stream. `range` takes `start` and an inclusive `end`, or `suffix`.                                                                                                                                                          |
| `getBuffer(key)`, `getText(key)`    | The whole file.                                                                                                                                                                                                                                                          |
| `stat(key)`, `exists(key)`          | The metadata without the body, or whether the file exists.                                                                                                                                                                                                               |
| `delete(keys)`                      | One key or an array. Missing keys are ignored.                                                                                                                                                                                                                           |
| `list(options)`, `listAll(options)` | A page of `key`, `size`, `lastModified` and `etag` in UTF-8 byte order, with a `cursor`. Options: `prefix`, `cursor`, `limit` (up to 1000, the default). `listAll()` iterates every page.                                                                                |
| `copy(from, to)`, `move(from, to)`  | Within the disk, metadata included.                                                                                                                                                                                                                                      |
| `url(key)`                          | The public URL under `publicUrl`. Throws without one.                                                                                                                                                                                                                    |
| `signedUrl(key, options)`           | A download link. Options: `expiresIn` (default 15 minutes, at most 7 days), `filename`, `disposition`. See [Keep invoices private](/application/file-storage#keep-invoices-private).                                                                                     |
| `signedUpload(key, options)`        | `url`, `method` (`PUT`), `headers` and `expiresAt` for a direct upload. Options: `contentType` (required), `contentLength`, `expiresIn`. See [Upload straight to storage from the mobile app](/application/file-storage#upload-straight-to-storage-from-the-mobile-app). |

##### Disks[#](/application/file-storage#disks)

| Disk           | Options                                                                                                                                                                                                                                                                                 |
| -------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `LocalDisk`    | `root` (required, created at startup), `publicUrl`, `signedUrls`. For development and tests. `path(key)` returns a file's absolute path.                                                                                                                                                |
| `S3Disk`       | `bucket` (required), `region`, `endpoint`, `forcePathStyle`, `credentials`, `prefix`, `serverSideEncryption`, `kmsKeyId`, `multipart`, `retry`, `timeout`, `batchDelete`, `fetch`, `publicUrl`. See [Use S3 or R2 in production](/application/file-storage#use-s3-or-r2-in-production). |
| `InMemoryDisk` | `publicUrl`, `signedUrls`. For tests, with `keys()` and `clear()`. See [Testing](/application/file-storage#testing).                                                                                                                                                                    |

`signedUrls` takes `baseUrl`, the route that serves the URLs, and `keys`, signing keys of at least 32 characters. The first key signs, and all of them verify. `S3Disk` defaults: `region` from `AWS_REGION`, then `AWS_DEFAULT_REGION`, then `us-east-1`; credentials from `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY` and `AWS_SESSION_TOKEN`; `multipart` with a `partSize` of 8 MiB and a `concurrency` of 4; `retry: 3`, with backoff from 100 ms doubling to 20 seconds; no `timeout`; `batchDelete: true`.

##### HTTP helpers[#](/application/file-storage#http-helpers)

| Helper                               | Options                                                                                                                                                                                                                         | Description                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| ------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `uploadToDisk(options)`              | `disk` (a name or an instance, default the default disk), `contentTypes`, `detectContentType`, `contentTypeSampleBytes` (default 4 KiB, from 1 byte to 64 KiB, requires `detectContentType`), `cacheControl`, `key`, `metadata` | A storage engine for `FileInterceptor()`. `key` and `metadata` are functions of the file and the request. `detectContentType(bytes, file)` returns the type of a file the built-in detection doesn't recognize, or `undefined`, and may return a promise. See [Upload product photos](/application/file-storage#upload-product-photos) and [Accept CSV and other text formats](/application/file-storage#accept-csv-and-other-text-formats). |
| `serveFile(disk, key, options)`      | `res` (required), `req`, `disposition` (default `attachment`), `filename`, `cacheControl`                                                                                                                                       | Streams a file as the response, with `Range` and `If-None-Match` support when given `req`.                                                                                                                                                                                                                                                                                                                                                   |
| `serveSignedUrl(disk, options)`      | `req`, `res`, `cacheControl`                                                                                                                                                                                                    | Verifies and serves an app-served signed download URL. See [Serve signed URLs in development](/application/file-storage#serve-signed-urls-in-development).                                                                                                                                                                                                                                                                                   |
| `receiveSignedUpload(disk, options)` | `req`, `res`, `maxSize`                                                                                                                                                                                                         | Verifies an app-served signed upload URL and streams the `PUT` body onto the disk. `maxSize` limits uploads signed without a `contentLength`.                                                                                                                                                                                                                                                                                                |
| `detectContentType(bytes)`           | none                                                                                                                                                                                                                            | The type of a file from its first 16 bytes: JPEG, PNG, GIF, WebP, AVIF, HEIC or PDF, else `undefined`. It's the built-in detection `uploadToDisk()` runs, and knows nothing of the `detectContentType` option.                                                                                                                                                                                                                               |

##### Errors[#](/application/file-storage#errors)

Every error extends `StorageError`. Outside the HTTP helpers, they aren't `HttpException`s, so map them in your own code where they mean something to your API.

| Error                             | `status` | When                                                                                                                                  |
| --------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| `StorageFileNotFoundError`        | 404      | `get()`, `stat()`, `copy()` or `move()` of a missing key. Has `key`.                                                                  |
| `StorageInvalidKeyError`          | 400      | A key that breaks the key rules. Has `reason`.                                                                                        |
| `StorageBodyLengthError`          | 400      | The body didn't match `contentLength`. Has `expected` and `received`.                                                                 |
| `StorageRangeNotSatisfiableError` | 416      | A range that starts past the end of the file. Has `size`.                                                                             |
| `StorageKeyConflictError`         | 409      | A local disk can't hold both `a` and `a/b`.                                                                                           |
| `StorageSignedUrlError`           | 403      | A signed URL failed verification. `reason` is `missing`, `invalid`, `expired` or `method`.                                            |
| `StorageServiceError`             | none     | The object store refused or failed. Has `code` (such as `AccessDenied` or `SlowDown`), `upstreamStatus`, `requestId` and `operation`. |

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/application/file-storage.md)

----
url: https://docs.nestjs.com/v11/security/authentication
----

* [Authentication](https://docs.nestjs.com/v11/security/authentication#authentication)
* [Creating an authentication module](https://docs.nestjs.com/v11/security/authentication#creating-an-authentication-module)
* [Implementing the "Sign in" endpoint](https://docs.nestjs.com/v11/security/authentication#implementing-the-sign-in-endpoint)
* [JWT token](https://docs.nestjs.com/v11/security/authentication#jwt-token)
* [Implementing the authentication guard](https://docs.nestjs.com/v11/security/authentication#implementing-the-authentication-guard)
* [Enable authentication globally](https://docs.nestjs.com/v11/security/authentication#enable-authentication-globally)
* [Passport integration](https://docs.nestjs.com/v11/security/authentication#passport-integration)
* [Example](https://docs.nestjs.com/v11/security/authentication#example)

```bash

$ nest g module auth
$ nest g controller auth
$ nest g service auth
```

As we implement the `AuthService`, we'll find it useful to encapsulate user operations in a `UsersService`, so let's generate that module and service now:

```bash

$ nest g module users
$ nest g service users
```

Replace the default contents of these generated files as shown below. For our sample app, the `UsersService` simply maintains a hard-coded in-memory list of users, and a find method to retrieve one by username. In a real app, this is where you'd build your user model and persistence layer, using your library of choice (e.g., TypeORM, Sequelize, Mongoose, etc.).

users/users.service.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';

// This should be a real class/interface representing a user entity
export type User = any;

@Injectable()
export class UsersService {
  private readonly users = [
    {
      userId: 1,
      username: 'john',
      password: 'changeme',
    },
    {
      userId: 2,
      username: 'maria',
      password: 'guess',
    },
  ];

  async findOne(username: string): Promise<User | undefined> {
    return this.users.find(user => user.username === username);
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';

@Injectable()
export class UsersService {
  constructor() {
    this.users = [
      {
        userId: 1,
        username: 'john',
        password: 'changeme',
      },
      {
        userId: 2,
        username: 'maria',
        password: 'guess',
      },
    ];
  }

  async findOne(username) {
    return this.users.find(user => user.username === username);
  }
}
```

In the `UsersModule`, the only change needed is to add the `UsersService` to the exports array of the `@Module` decorator so that it is visible outside this module (we'll soon use it in our `AuthService`).

users/users.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { UsersService } from './users.service';

@Module({
  providers: [UsersService],
  exports: [UsersService],
})
export class UsersModule {}
```

```typescript

import { Module } from '@nestjs/common';
import { UsersService } from './users.service';

@Module({
  providers: [UsersService],
  exports: [UsersService],
})
export class UsersModule {}
```

#### Implementing the "Sign in" endpoint[#](/security/authentication#implementing-the-sign-in-endpoint)

Our `AuthService` has the job of retrieving a user and verifying the password. We create a `signIn()` method for this purpose. In the code below, we use a convenient ES6 spread operator to strip the password property from the user object before returning it. This is a common practice when returning user objects, as you don't want to expose sensitive fields like passwords or other security keys.

auth/auth.service.ts

JS TS

```typescript

import { Injectable, UnauthorizedException } from '@nestjs/common';
import { UsersService } from '../users/users.service';

@Injectable()
export class AuthService {
  constructor(private readonly usersService: UsersService) {}

  async signIn(username: string, pass: string): Promise<any> {
    const user = await this.usersService.findOne(username);
    if (user?.password !== pass) {
      throw new UnauthorizedException();
    }
    const { password, ...result } = user;
    // TODO: Generate a JWT and return it here
    // instead of the user object
    return result;
  }
}
```

```typescript

import { Injectable, Dependencies, UnauthorizedException } from '@nestjs/common';
import { UsersService } from '../users/users.service';

@Injectable()
@Dependencies(UsersService)
export class AuthService {
  constructor(usersService) {
    this.usersService = usersService;
  }

  async signIn(username: string, pass: string) {
    const user = await this.usersService.findOne(username);
    if (user?.password !== pass) {
      throw new UnauthorizedException();
    }
    const { password, ...result } = user;
    // TODO: Generate a JWT and return it here
    // instead of the user object
    return result;
  }
}
```

> **Warning** Of course in a real application, you wouldn't store a password in plain text. You'd instead use a library like [bcrypt](https://github.com/kelektiv/node.bcrypt.js#readme), with a salted one-way hash algorithm. With that approach, you'd only store hashed passwords, and then compare the stored password to a hashed version of the **incoming** password, thus never storing or exposing user passwords in plain text. To keep our sample app simple, we violate that absolute mandate and use plain text. **Don't do this in your real app!**

Now, we update our `AuthModule` to import the `UsersModule`.

auth/auth.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { AuthController } from './auth.controller';
import { UsersModule } from '../users/users.module';

@Module({
  imports: [UsersModule],
  providers: [AuthService],
  controllers: [AuthController],
})
export class AuthModule {}
```

```typescript

import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { AuthController } from './auth.controller';
import { UsersModule } from '../users/users.module';

@Module({
  imports: [UsersModule],
  providers: [AuthService],
  controllers: [AuthController],
})
export class AuthModule {}
```

With this in place, let's open up the `AuthController` and add a `signIn()` method to it. This method will be called by the client to authenticate a user. It will receive the username and password in the request body, and will return a JWT token if the user is authenticated.

auth/auth.controller.ts

JS TS

```typescript

import { Body, Controller, Post, HttpCode, HttpStatus } from '@nestjs/common';
import { AuthService } from './auth.service';

@Controller('auth')
export class AuthController {
  constructor(private readonly authService: AuthService) {}

  @HttpCode(HttpStatus.OK)
  @Post('login')
  signIn(@Body() signInDto: Record<string, any>) {
    return this.authService.signIn(signInDto.username, signInDto.password);
  }
}
```

> **Hint** Ideally, instead of using the `Record<string, any>` type, we should use a DTO class to define the shape of the request body. See the [validation](/v11/techniques/validation) chapter for more information.

```bash

$ npm install --save @nestjs/jwt
```

> **Hint** The `@nestjs/jwt` package (see more [here](https://github.com/nestjs/jwt)) is a utility package that helps with JWT manipulation. This includes generating and verifying JWT tokens.

To keep our services cleanly modularized, we'll handle generating the JWT in the `authService`. Open the `auth.service.ts` file in the `auth` folder, inject the `JwtService`, and update the `signIn` method to generate a JWT token as shown below:

auth/auth.service.ts

JS TS

```typescript

import { Injectable, UnauthorizedException } from '@nestjs/common';
import { UsersService } from '../users/users.service';
import { JwtService } from '@nestjs/jwt';

@Injectable()
export class AuthService {
  constructor(
    private usersService: UsersService,
    private jwtService: JwtService
  ) {}

  async signIn(
    username: string,
    pass: string,
  ): Promise<{ access_token: string }> {
    const user = await this.usersService.findOne(username);
    if (user?.password !== pass) {
      throw new UnauthorizedException();
    }
    const payload = { sub: user.userId, username: user.username };
    return {
      // 💡 Here the JWT secret key that's used for signing the payload 
      // is the key that was passed in the JwtModule
      access_token: await this.jwtService.signAsync(payload),
    };
  }
}
```

```typescript

import { Injectable, Dependencies, UnauthorizedException } from '@nestjs/common';
import { UsersService } from '../users/users.service';
import { JwtService } from '@nestjs/jwt';

@Dependencies(UsersService, JwtService)
@Injectable()
export class AuthService {
  constructor(usersService, jwtService) {
    this.usersService = usersService;
    this.jwtService = jwtService;
  }

  async signIn(username, pass) {
    const user = await this.usersService.findOne(username);
    if (user?.password !== pass) {
      throw new UnauthorizedException();
    }
    const payload = { username: user.username, sub: user.userId };
    return {
      // 💡 Here the JWT secret key that's used for signing the payload 
      // is the key that was passed in the JwtModule
      access_token: await this.jwtService.signAsync(payload),
    };
  }
}
```

We're using the `@nestjs/jwt` library, which supplies a `signAsync()` function to generate our JWT from a subset of the `user` object properties, which we then return as a simple object with a single `access_token` property. Note: we choose a property name of `sub` to hold our `userId` value to be consistent with JWT standards.

We now need to update the `AuthModule` to import the new dependencies and configure the `JwtModule`.

First, create `constants.ts` in the `auth` folder, and add the following code:

auth/constants.ts

JS TS

```typescript

export const jwtConstants = {
  secret: 'DO NOT USE THIS VALUE. INSTEAD, CREATE A COMPLEX SECRET AND KEEP IT SAFE OUTSIDE OF THE SOURCE CODE.',
};
```

```typescript

export const jwtConstants = {
  secret: 'DO NOT USE THIS VALUE. INSTEAD, CREATE A COMPLEX SECRET AND KEEP IT SAFE OUTSIDE OF THE SOURCE CODE.',
};
```

We'll use this to share our key between the JWT signing and verifying steps.

> **Warning****Do not expose this key publicly**. We have done so here to make it clear what the code is doing, but in a production system **you must protect this key** using appropriate measures such as a secrets vault, environment variable, or configuration service.

Now, open `auth.module.ts` in the `auth` folder and update it to look like this:

auth/auth.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { UsersModule } from '../users/users.module';
import { JwtModule } from '@nestjs/jwt';
import { AuthController } from './auth.controller';
import { jwtConstants } from './constants';

@Module({
  imports: [
    UsersModule,
    JwtModule.register({
      global: true,
      secret: jwtConstants.secret,
      signOptions: { expiresIn: '60s' },
    }),
  ],
  providers: [AuthService],
  controllers: [AuthController],
  exports: [AuthService],
})
export class AuthModule {}
```

```typescript

import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { UsersModule } from '../users/users.module';
import { JwtModule } from '@nestjs/jwt';
import { AuthController } from './auth.controller';
import { jwtConstants } from './constants';

@Module({
  imports: [
    UsersModule,
    JwtModule.register({
      global: true,
      secret: jwtConstants.secret,
      signOptions: { expiresIn: '60s' },
    }),
  ],
  providers: [AuthService],
  controllers: [AuthController],
  exports: [AuthService],
})
export class AuthModule {}
```

> **Hint** We're registering the `JwtModule` as global to make things easier for us. This means that we don't need to import the `JwtModule` anywhere else in our application.

We configure the `JwtModule` using `register()`, passing in a configuration object. See [here](https://github.com/nestjs/jwt/blob/master/README.md) for more on the Nest `JwtModule` and [here](https://github.com/auth0/node-jsonwebtoken#usage) for more details on the available configuration options.

Let's go ahead and test our routes using cURL again. You can test with any of the `user` objects hard-coded in the `UsersService`.

```bash

$ # POST to /auth/login
$ curl -X POST http://localhost:3000/auth/login -d '{"username": "john", "password": "changeme"}' -H "Content-Type: application/json"
{"access_token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."}
$ # Note: above JWT truncated
```

#### Implementing the authentication guard[#](/security/authentication#implementing-the-authentication-guard)

We can now address our final requirement: protecting endpoints by requiring a valid JWT be present on the request. We'll do this by creating an `AuthGuard` that we can use to protect our routes.

auth/auth.guard.ts

JS TS

```typescript

import {
  CanActivate,
  ExecutionContext,
  Injectable,
  UnauthorizedException,
} from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
import { Request } from 'express';

@Injectable()
export class AuthGuard implements CanActivate {
  constructor(private readonly jwtService: JwtService) {}

  async canActivate(context: ExecutionContext): Promise<boolean> {
    const request = context.switchToHttp().getRequest();
    const token = this.extractTokenFromHeader(request);
    if (!token) {
      throw new UnauthorizedException();
    }
    try {
      // 💡 Here the JWT secret key that's used for verifying the payload 
      // is the key that was passed in the JwtModule
      const payload = await this.jwtService.verifyAsync(token);
      // 💡 We're assigning the payload to the request object here
      // so that we can access it in our route handlers
      request['user'] = payload;
    } catch {
      throw new UnauthorizedException();
    }
    return true;
  }

  private extractTokenFromHeader(request: Request): string | undefined {
    const [type, token] = request.headers.authorization?.split(' ') ?? [];
    return type === 'Bearer' ? token : undefined;
  }
}
```

We can now implement our protected route and register our `AuthGuard` to protect it.

Open the `auth.controller.ts` file and update it as shown below:

auth.controller.ts

JS TS

```typescript

import {
  Body,
  Controller,
  Get,
  HttpCode,
  HttpStatus,
  Post,
  Request,
  UseGuards
} from '@nestjs/common';
import { AuthGuard } from './auth.guard';
import { AuthService } from './auth.service';

@Controller('auth')
export class AuthController {
  constructor(private readonly authService: AuthService) {}

  @HttpCode(HttpStatus.OK)
  @Post('login')
  signIn(@Body() signInDto: Record<string, any>) {
    return this.authService.signIn(signInDto.username, signInDto.password);
  }

  @UseGuards(AuthGuard)
  @Get('profile')
  getProfile(@Request() req) {
    return req.user;
  }
}
```

We're applying the `AuthGuard` that we just created to the `GET /profile` route so that it will be protected.

Ensure the app is running, and test the routes using `cURL`.

```bash

$ # GET /profile
$ curl http://localhost:3000/auth/profile
{"statusCode":401,"message":"Unauthorized"}

$ # POST /auth/login
$ curl -X POST http://localhost:3000/auth/login -d '{"username": "john", "password": "changeme"}' -H "Content-Type: application/json"
{"access_token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2Vybm..."}

$ # GET /profile using access_token returned from previous step as bearer code
$ curl http://localhost:3000/auth/profile -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2Vybm..."
{"sub":1,"username":"john","iat":...,"exp":...}
```

Note that in the `AuthModule`, we configured the JWT to have an expiration of `60 seconds`. This is too short an expiration, and dealing with the details of token expiration and refresh is beyond the scope of this article. However, we chose that to demonstrate an important quality of JWTs. If you wait 60 seconds after authenticating before attempting a `GET /auth/profile` request, you'll receive a `401 Unauthorized` response. This is because `@nestjs/jwt` automatically checks the JWT for its expiration time, saving you the trouble of doing so in your application.

We've now completed our JWT authentication implementation. JavaScript clients (such as Angular/React/Vue), and other JavaScript apps, can now authenticate and communicate securely with our API Server.

#### Enable authentication globally[#](/security/authentication#enable-authentication-globally)

If the vast majority of your endpoints should be protected by default, you can register the authentication guard as a [global guard](/guards#binding-guards) and instead of using `@UseGuards()` decorator on top of each controller, you could simply flag which routes should be public.

First, register the `AuthGuard` as a global guard using the following construction (in any module, for example, in the `AuthModule`):

```typescript

providers: [
  {
    provide: APP_GUARD,
    useClass: AuthGuard,
  },
],
```

With this in place, Nest will automatically bind `AuthGuard` to all endpoints.

Now we must provide a mechanism for declaring routes as public. For this, we can create a custom decorator using the `SetMetadata` decorator factory function.

```typescript

import { SetMetadata } from '@nestjs/common';

export const IS_PUBLIC_KEY = 'isPublic';
export const Public = () => SetMetadata(IS_PUBLIC_KEY, true);
```

In the file above, we exported two constants. One being our metadata key named `IS_PUBLIC_KEY`, and the other being our new decorator itself that we’re going to call `Public` (you can alternatively name it `SkipAuth` or `AllowAnon`, whatever fits your project).

Now that we have a custom `@Public()` decorator, we can use it to decorate any method, as follows:

```typescript

@Public()
@Get()
findAll() {
  return [];
}
```

Lastly, we need the `AuthGuard` to return `true` when the `"isPublic"` metadata is found. For this, we'll use the `Reflector` class (read more [here](/guards#putting-it-all-together)).

```typescript

@Injectable()
export class AuthGuard implements CanActivate {
  constructor(private readonly jwtService: JwtService, private reflector: Reflector) {}

  async canActivate(context: ExecutionContext): Promise<boolean> {
    const isPublic = this.reflector.getAllAndOverride<boolean>(IS_PUBLIC_KEY, [
      context.getHandler(),
      context.getClass(),
    ]);
    if (isPublic) {
      // 💡 See this condition
      return true;
    }

    const request = context.switchToHttp().getRequest();
    const token = this.extractTokenFromHeader(request);
    if (!token) {
      throw new UnauthorizedException();
    }
    try {
      // 💡 Here the JWT secret key that's used for verifying the payload 
      // is the key that was passed in the JwtModule
      const payload = await this.jwtService.verifyAsync(token);
      // 💡 We're assigning the payload to the request object here
      // so that we can access it in our route handlers
      request['user'] = payload;
    } catch {
      throw new UnauthorizedException();
    }
    return true;
  }

  private extractTokenFromHeader(request: Request): string | undefined {
    const [type, token] = request.headers.authorization?.split(' ') ?? [];
    return type === 'Bearer' ? token : undefined;
  }
}
```

#### Passport integration[#](/security/authentication#passport-integration)

[Passport](https://github.com/jaredhanson/passport) is the most popular node.js authentication library, well-known by the community and successfully used in many production applications. It's straightforward to integrate this library with a **Nest** application using the `@nestjs/passport` module.

To learn how you can integrate Passport with NestJS, check out this [chapter](/v11/recipes/passport).

#### Example[#](/security/authentication#example)

You can find a complete version of the code in this chapter [here](https://github.com/nestjs/nest/tree/master/sample/19-auth-jwt).

----
url: https://docs.nestjs.com/v11/openapi/security
----

* [Security](https://docs.nestjs.com/v11/openapi/security#security)
* [Basic authentication](https://docs.nestjs.com/v11/openapi/security#basic-authentication)
* [Bearer authentication](https://docs.nestjs.com/v11/openapi/security#bearer-authentication)
* [OAuth2 authentication](https://docs.nestjs.com/v11/openapi/security#oauth2-authentication)
* [Cookie authentication](https://docs.nestjs.com/v11/openapi/security#cookie-authentication)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/openapi/security.md "Suggest Edits")

### Security

To define which security mechanisms should be used for a specific operation, use the `@ApiSecurity()` decorator.

```typescript

@ApiSecurity('basic')
@Controller('cats')
export class CatsController {}
```

Before you run your application, remember to add the security definition to your base document using `DocumentBuilder`:

```typescript

const options = new DocumentBuilder().addSecurity('basic', {
  type: 'http',
  scheme: 'basic',
});
```

Some of the most popular authentication techniques are built-in (e.g., `basic` and `bearer`) and therefore you don't have to define security mechanisms manually as shown above.

#### Basic authentication[#](/openapi/security#basic-authentication)

To enable basic authentication, use `@ApiBasicAuth()`.

```typescript

@ApiBasicAuth()
@Controller('cats')
export class CatsController {}
```

Before you run your application, remember to add the security definition to your base document using `DocumentBuilder`:

```typescript

const options = new DocumentBuilder().addBasicAuth();
```

#### Bearer authentication[#](/openapi/security#bearer-authentication)

To enable bearer authentication, use `@ApiBearerAuth()`.

```typescript

@ApiBearerAuth()
@Controller('cats')
export class CatsController {}
```

Before you run your application, remember to add the security definition to your base document using `DocumentBuilder`:

```typescript

const options = new DocumentBuilder().addBearerAuth();
```

#### OAuth2 authentication[#](/openapi/security#oauth2-authentication)

To enable OAuth2, use `@ApiOAuth2()`.

```typescript

@ApiOAuth2(['pets:write'])
@Controller('cats')
export class CatsController {}
```

Before you run your application, remember to add the security definition to your base document using `DocumentBuilder`:

```typescript

const options = new DocumentBuilder().addOAuth2();
```

#### Cookie authentication[#](/openapi/security#cookie-authentication)

To enable cookie authentication, use `@ApiCookieAuth()`.

```typescript

@ApiCookieAuth()
@Controller('cats')
export class CatsController {}
```

Before you run your application, remember to add the security definition to your base document using `DocumentBuilder`:

```typescript

const options = new DocumentBuilder().addCookieAuth('optional-session-id');
```

----
url: https://docs.nestjs.com/v10/techniques/events
----

* [Events](https://docs.nestjs.com/v10/techniques/events#events)
* [Getting started](https://docs.nestjs.com/v10/techniques/events#getting-started)
* [Dispatching events](https://docs.nestjs.com/v10/techniques/events#dispatching-events)
* [Listening to events](https://docs.nestjs.com/v10/techniques/events#listening-to-events)
* [Preventing event loss](https://docs.nestjs.com/v10/techniques/events#preventing-event-loss)
* [Example](https://docs.nestjs.com/v10/techniques/events#example)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/techniques/events.md "Suggest Edits")

### Events

[Event Emitter](https://www.npmjs.com/package/@nestjs/event-emitter) package (`@nestjs/event-emitter`) provides a simple observer implementation, allowing you to subscribe and listen for various events that occur in your application. Events serve as a great way to decouple various aspects of your application, since a single event can have multiple listeners that do not depend on each other.

`EventEmitterModule` internally uses the [eventemitter2](https://github.com/EventEmitter2/EventEmitter2) package.

#### Getting started[#](/techniques/events#getting-started)

First install the required package:

```shell

$ npm i --save @nestjs/event-emitter
```

Once the installation is complete, import the `EventEmitterModule` into the root `AppModule` and run the `forRoot()` static method as shown below:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { EventEmitterModule } from '@nestjs/event-emitter';

@Module({
  imports: [
    EventEmitterModule.forRoot()
  ],
})
export class AppModule {}
```

The `.forRoot()` call initializes the event emitter and registers any declarative event listeners that exist within your app. Registration occurs when the `onApplicationBootstrap` lifecycle hook occurs, ensuring that all modules have loaded and declared any scheduled jobs.

To configure the underlying `EventEmitter` instance, pass the configuration object to the `.forRoot()` method, as follows:

```typescript

EventEmitterModule.forRoot({
  // set this to `true` to use wildcards
  wildcard: false,
  // the delimiter used to segment namespaces
  delimiter: '.',
  // set this to `true` if you want to emit the newListener event
  newListener: false,
  // set this to `true` if you want to emit the removeListener event
  removeListener: false,
  // the maximum amount of listeners that can be assigned to an event
  maxListeners: 10,
  // show event name in memory leak message when more than maximum amount of listeners is assigned
  verboseMemoryLeak: false,
  // disable throwing uncaughtException if an error event is emitted and it has no listeners
  ignoreErrors: false,
});
```

#### Dispatching events[#](/techniques/events#dispatching-events)

To dispatch (i.e., fire) an event, first inject `EventEmitter2` using standard constructor injection:

```typescript

constructor(private eventEmitter: EventEmitter2) {}
```

> **Hint** Import the `EventEmitter2` from the `@nestjs/event-emitter` package.

Then use it in a class as follows:

```typescript

this.eventEmitter.emit(
  'order.created',
  new OrderCreatedEvent({
    orderId: 1,
    payload: {},
  }),
);
```

#### Listening to events[#](/techniques/events#listening-to-events)

To declare an event listener, decorate a method with the `@OnEvent()` decorator preceding the method definition containing the code to be executed, as follows:

```typescript

@OnEvent('order.created')
handleOrderCreatedEvent(payload: OrderCreatedEvent) {
  // handle and process "OrderCreatedEvent" event
}
```

> **Warning** Event subscribers cannot be request-scoped.

The first argument can be a `string` or `symbol` for a simple event emitter and a `string | symbol | Array<string | symbol>` in a case of a wildcard emitter.

The second argument (optional) is a listener options object as follows:

```typescript

export type OnEventOptions = OnOptions & {
  /**
   * If "true", prepends (instead of append) the given listener to the array of listeners.
   *
   * @see https://github.com/EventEmitter2/EventEmitter2#emitterprependlistenerevent-listener-options
   *
   * @default false
   */
  prependListener?: boolean;

  /**
   * If "true", the onEvent callback will not throw an error while handling the event. Otherwise, if "false" it will throw an error.
   *
   * @default true
   */
  suppressErrors?: boolean;
};
```

> **Hint** Read more about the `OnOptions` options object from [`eventemitter2`](https://github.com/EventEmitter2/EventEmitter2#emitteronevent-listener-options-objectboolean).

```typescript

@OnEvent('order.created', { async: true })
handleOrderCreatedEvent(payload: OrderCreatedEvent) {
  // handle and process "OrderCreatedEvent" event
}
```

To use namespaces/wildcards, pass the `wildcard` option into the `EventEmitterModule#forRoot()` method. When namespaces/wildcards are enabled, events can either be strings (`foo.bar`) separated by a delimiter or arrays (`['foo', 'bar']`). The delimiter is also configurable as a configuration property (`delimiter`). With namespaces feature enabled, you can subscribe to events using a wildcard:

```typescript

@OnEvent('order.*')
handleOrderEvents(payload: OrderCreatedEvent | OrderRemovedEvent | OrderUpdatedEvent) {
  // handle and process an event
}
```

Note that such a wildcard only applies to one block. The argument `order.*` will match, for example, the events `order.created` and `order.shipped` but not `order.delayed.out_of_stock`. In order to listen to such events, use the `multilevel wildcard` pattern (i.e, `**`), described in the `EventEmitter2`[documentation](https://github.com/EventEmitter2/EventEmitter2#multi-level-wildcards).

With this pattern, you can, for example, create an event listener that catches all events.

```typescript

@OnEvent('**')
handleEverything(payload: any) {
  // handle and process an event
}
```

> **Hint**`EventEmitter2` class provides several useful methods for interacting with events, like `waitFor` and `onAny`. You can read more about them [here](https://github.com/EventEmitter2/EventEmitter2).

#### Preventing event loss[#](/techniques/events#preventing-event-loss)

Events triggered before or during the `onApplicationBootstrap` lifecycle hook—such as those from module constructors or the `onModuleInit` method—may be missed because the `EventSubscribersLoader` might not have finished setting up the listeners.

To avoid this issue, you can use the `waitUntilReady` method of the `EventEmitterReadinessWatcher`, which returns a promise that resolves once all listeners have been registered. This method can be called in the `onApplicationBootstrap` lifecycle hook of a module to ensure that all events are properly captured.

```typescript

await this.eventEmitterReadinessWatcher.waitUntilReady();
await this.eventEmitter.emit(
  'order.created',
  new OrderCreatedEvent({ orderId: 1, payload: {} }),
);
```

> **Note** This is only necessary for events emitted before the `onApplicationBootstrap` lifecycle hook is complete.

#### Example[#](/techniques/events#example)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/30-event-emitter).

----
url: https://docs.nestjs.com/v8/websockets/exception-filters
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Exception filters](https://docs.nestjs.com/v8/websockets/exception-filters#exception-filters)
* [Filters](https://docs.nestjs.com/v8/websockets/exception-filters#filters)
* [Inheritance](https://docs.nestjs.com/v8/websockets/exception-filters#inheritance)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/websockets/exception-filters.md "Suggest Edits")

### Exception filters

The only difference between the HTTP [exception filter](/v8/exception-filters) layer and the corresponding web sockets layer is that instead of throwing `HttpException`, you should use `WsException`.

```typescript

throw new WsException('Invalid credentials.');
```

> **Hint** The `WsException` class is imported from the `@nestjs/websockets` package.

With the sample above, Nest will handle the thrown exception and emit the `exception` message with the following structure:

```typescript

{
  status: 'error',
  message: 'Invalid credentials.'
}
```

#### Filters[#](/websockets/exception-filters#filters)

Web sockets exception filters behave equivalently to HTTP exception filters. The following example uses a manually instantiated method-scoped filter. Just as with HTTP based applications, you can also use gateway-scoped filters (i.e., prefix the gateway class with a `@UseFilters()` decorator).

```typescript

@UseFilters(new WsExceptionFilter())
@SubscribeMessage('events')
onEvent(client, data: any): WsResponse<any> {
  const event = 'events';
  return { event, data };
}
```

#### Inheritance[#](/websockets/exception-filters#inheritance)

Typically, you'll create fully customized exception filters crafted to fulfill your application requirements. However, there might be use-cases when you would like to simply extend the **core exception filter**, and override the behavior based on certain factors.

In order to delegate exception processing to the base filter, you need to extend `BaseWsExceptionFilter` and call the inherited `catch()` method.

JS TS

```typescript

import { Catch, ArgumentsHost } from '@nestjs/common';
import { BaseWsExceptionFilter } from '@nestjs/websockets';

@Catch()
export class AllExceptionsFilter extends BaseWsExceptionFilter {
  catch(exception: unknown, host: ArgumentsHost) {
    super.catch(exception, host);
  }
}
```

```typescript

import { Catch } from '@nestjs/common';
import { BaseWsExceptionFilter } from '@nestjs/websockets';

@Catch()
export class AllExceptionsFilter extends BaseWsExceptionFilter {
  catch(exception, host) {
    super.catch(exception, host);
  }
}
```

The above implementation is just a shell demonstrating the approach. Your implementation of the extended exception filter would include your tailored **business logic** (e.g., handling various conditions).

----
url: https://docs.nestjs.com/v4/recipes/swagger
----

### OpenAPI (Swagger)

##### This chapter applies only to TypeScript

The [OpenAPI](https://swagger.io/specification/) (Swagger) specification is a powerful definition format to describe RESTful APIs. Nest provides a dedicated [module](https://github.com/nestjs/swagger) to work with it.

#### Installation

Firstly you have to install the module:

TypeScript

```typescript

$ npm install --save @nestjs/swagger
```

#### Bootstrap

Once the installation process is done, open your bootstrap file (mostly ``) and initialize the Swagger using `SwaggerModule` class:

TypeScript

```typescript

import { NestFactory } from '@nestjs/core';
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
import { ApplicationModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(ApplicationModule);

  const options = new DocumentBuilder()
    .setTitle('Cats example')
    .setDescription('The cats API description')
    .setVersion('1.0')
    .addTag('cats')
    .build();
  const document = SwaggerModule.createDocument(app, options);
  SwaggerModule.setup('/api', app, document);

  await app.listen(3001);
}
bootstrap();
```

The `DocumentBuilder` is a helper class, which helps to structure a base document for the `SwaggerModule`. It contains several methods that allow setting such properties like title, description, version etc.

To create a full document (with defined HTTP routes) we are using the `createDocument()` method of the `SwaggerModule` class. This method accepts two arguments - the application instance and the base Swagger options.

The last step is to use `setup()`. It accepts sequentially **(1)** path to mount the Swagger, **(2)** application instance, and **(3)** the document that describes the Nest application.

Now you can run the following command to start the HTTP server:

```bash

$ npm run start
```

While the application is running, open your browser and navigate to `http://localhost:3000/api`. You should see similar page:

The `SwaggerModule` automatically reflects all of your endpoints. In the background, it's making use of `swagger-ui-express` and creates a live documentation.

#### Body, query, path parameters

During the examination of the defined controllers, the `SwaggerModule` is looking for all used `@Body()`, `@Query()`, and `@Param()` decorators in the route handlers. Thanks to them, the valid document can be created.

Moreover, the module creates the **models' definitions** by taking advantage of the **reflection**. Take a look at the following code:

TypeScript

```typescript

@Post()
async create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

> **Notice** To implicitly set the body definition you can use the `@ApiImplicitBody()` decorator (`@nestjs/swagger` package).

Based on the `CreateCatDto`, the module definition will be created:

As you can see, the definition's empty although the class has few declared properties. To make the class properties accessible to the `SwaggerModule`, we have to mark all of them with `@ApiModelProperty()` decorator:

TypeScript

```typescript

import { ApiModelProperty } from '@nestjs/swagger';

export class CreateCatDto {
  @ApiModelProperty()
  readonly name: string;

  @ApiModelProperty()
  readonly age: number;

  @ApiModelProperty()
  readonly breed: string;
}
```

Let's open the browser and verify the generated `CreateCatDto` model:

The `@ApiModelProperty()` decorator accepts options object:

TypeScript

```typescript

export declare const ApiModelProperty: (metadata?: {
  description?: string;
  required?: boolean;
  type?: any;
  isArray?: boolean;
  default?: any;
}) => PropertyDecorator;
```

> **Hint** There's an `@ApiModelPropertyOptional()` shortcut decorator which helps to avoid continuous typing `@ApiModelProperty({ required: false })`.

Thanks to that we can simply set the **default** value, determine whether the property is required or explicitly set the type.

#### Working with arrays

We have to manually indicate the type and set the `isArray` property to true when the property is actually an array:

TypeScript

```typescript

@ApiModelProperty({ type: String, isArray: true })
readonly names: string[];
```

#### Tags

At the beginning, we have created a `cats` tag (by making use of `DocumentBuilder`). To attach the controller to the specified tag, we need to use `@ApiUseTags(...tags)` decorator.

TypeScript

```typescript

@ApiUseTags('cats')
@Controller('cats')
export class CatsController {}
```

#### Responses

To define a custom HTTP response, we use `@ApiResponse()` decorator.

TypeScript

```typescript

@Post()
@ApiResponse({ status: 201, description: 'The record has been successfully created.'})
@ApiResponse({ status: 403, description: 'Forbidden.'})
async create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

#### Authentication

You can enable the bearer authorization using `addBearerAuth()` method of the `DocumentBuilder` class. Then to restrict the chosen route or entire controller, use `@ApiBearerAuth()` decorator.

TypeScript

```typescript

@ApiUseTags('cats')
@ApiBearerAuth()
@Controller('cats')
export class CatsController {}
```

That's how the OpenAPI documentation should look like now:

#### Decorators

All of the available OpenAPI decorators has an `Api` prefix to be clearly distinguishable from the core decorators. Below is a full list of the exported decorators with a defined use-level (where might be applied).

|                               |                     |
| ----------------------------- | ------------------- |
| `@ApiOperation()`             | Method              |
| `@ApiResponse()`              | Method / Controller |
| `@ApiProduces()`              | Method / Controller |
| `@ApiConsumes()`              | Method / Controller |
| `@ApiBearerAuth()`            | Method / Controller |
| `@ApiImplicitBody()`          | Method              |
| `@ApiImplicitParam()`         | Method              |
| `@ApiImplicitQuery()`         | Method              |
| `@ApiImplicitHeader()`        | Method              |
| `@ApiUseTags()`               | Method / Controller |
| `@ApiModelProperty()`         | Model               |
| `@ApiModelPropertyOptional()` | Model               |

The full source code's available [here](https://github.com/nestjs/nest/tree/master/examples/11-swagger).

#### Sponsors

[](https://valor-software.com/)

Nest is an MIT-licensed open source project. It can grow thanks to the support by these awesome people. If you'd like to join them, please read more [here](https://opencollective.com/nest). Thanks!

[](https://opencollective.com/nest/backer/0/website)[](https://opencollective.com/nest/backer/1/website)[](https://opencollective.com/nest/backer/2/website)[](https://opencollective.com/nest/backer/3/website)[](https://opencollective.com/nest/backer/4/website)[](https://opencollective.com/nest/backer/5/website)[](https://opencollective.com/nest/backer/6/website)[](https://opencollective.com/nest/backer/7/website)[](https://opencollective.com/nest/backer/8/website)[](https://opencollective.com/nest/backer/9/website)[](https://opencollective.com/nest/backer/10/website)[](https://opencollective.com/nest/backer/11/website)[](https://opencollective.com/nest/backer/12/website)[](https://opencollective.com/nest/backer/13/website)[](https://opencollective.com/nest/backer/14/website)[](https://opencollective.com/nest/backer/15/website)[](https://opencollective.com/nest/backer/16/website)[](https://opencollective.com/nest/backer/17/website)[](https://opencollective.com/nest/backer/18/website)[](https://opencollective.com/nest/backer/19/website)[](https://opencollective.com/nest/backer/20/website)[](https://opencollective.com/nest/backer/21/website)[](https://opencollective.com/nest/backer/22/website)[](https://opencollective.com/nest/backer/23/website)[](https://opencollective.com/nest/backer/24/website)[](https://opencollective.com/nest/backer/25/website)[](https://opencollective.com/nest/backer/26/website)[](https://opencollective.com/nest/backer/27/website)[](https://opencollective.com/nest/backer/28/website)[](https://opencollective.com/nest/backer/29/website)

[Become a sponsor](https://opencollective.com/nest)

----
url: https://docs.nestjs.com/v9/recipes/async-local-storage
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Async Local Storage](https://docs.nestjs.com/v9/recipes/async-local-storage#async-local-storage)
* [Custom implementation](https://docs.nestjs.com/v9/recipes/async-local-storage#custom-implementation)
* [NestJS CLS](https://docs.nestjs.com/v9/recipes/async-local-storage#nestjs-cls)
* [Installation](https://docs.nestjs.com/v9/recipes/async-local-storage#installation)
* [Usage](https://docs.nestjs.com/v9/recipes/async-local-storage#usage)
* [Testing](https://docs.nestjs.com/v9/recipes/async-local-storage#testing)
* [More information](https://docs.nestjs.com/v9/recipes/async-local-storage#more-information)

> **info** For a ready-made [dedicated package](recipes/async-local-storage#nestjs-cls), continue reading below.

1. First, create a new instance of the `AsyncLocalStorage` in some shared source file. Since we're using NestJS, let's also turn it into a module with a custom provider.

als.module.ts

JS TS

```ts

@Module({
  providers: [
    {
      provide: AsyncLocalStorage,
      useValue: new AsyncLocalStorage(),
    },
  ],
  exports: [AsyncLocalStorage],
})
export class AlsModule {}
```

> **Hint**`AsyncLocalStorage` is imported from `async_hooks`.

2. We're only concerned with HTTP, so let's use a middleware to wrap the `next` function with `AsyncLocalStorage#run`. Since a middleware is the first thing that the request hits, this will make the `store` available in all enhancers and the rest of the system.

app.module.ts

JS TS

```typescript

@Module({
  imports: [AlsModule]
  providers: [CatService],
  controllers: [CatController],
})
export class AppModule implements NestModule {
  constructor(
    // inject the AsyncLocalStorage in the module constructor,
    private readonly als: AsyncLocalStorage
  ) {}

  configure(consumer: MiddlewareConsumer) {
    // bind the middleware,
    consumer
      .apply((req, res, next) => {
        // populate the store with some default values
        // based on the request,
        const store = {
          userId: req.headers['x-user-id'],
        };
        // and pass the "next" function as callback
        // to the "als.run" method together with the store.
        als.run(store, () => next());
      })
      // and register it for all routes (in case of Fastify use '(.*)')
      .forRoutes('*');
  }
}
```

```typescript

@Module({
  imports: [AlsModule]
  providers: [CatService],
  controllers: [CatController],
})
@Dependencies(AsyncLocalStorage)
export class AppModule {
  constructor(als) {
    // inject the AsyncLocalStorage in the module constructor,
    this.als = als
  }

  configure(consumer) {
    // bind the middleware,
    consumer
      .apply((req, res, next) => {
        // populate the store with some default values
        // based on the request,
        const store = {
          userId: req.headers['x-user-id'],
        };
        // and pass the "next" function as callback
        // to the "als.run" method together with the store.
        als.run(store, () => next());
      })
      // and register it for all routes (in case of Fastify use '(.*)')
      .forRoutes('*');
  }
}
```

3. Now, anywhere within the lifecycle of a request, we can access the local store instance.

cat.service.ts

JS TS

```typescript

@Injectable()
export class CatService {
  constructor(
    // We can inject the provided ALS instance.
    private readonly als: AsyncLocalStorage,
    private readonly catRepository: CatRepository,
  ) {}

  getCatForUser() {
    // The "getStore" method will always return the
    // store instance associated with the given request.
    const userId = this.als.getStore()["userId"] as number;
    return this.catRepository.getForUser(userId);
  }
}
```

```typescript

@Injectable()
@Dependencies(AsyncLocalStorage, CatRepository)
export class CatService {
  constructor(als, catRepository) {
    // We can inject the provided ALS instance.
    this.als = als
    this.catRepository = catRepository
  }

  getCatForUser() {
    // The "getStore" method will always return the
    // store instance associated with the given request.
    const userId = this.als.getStore()["userId"] as number;
    return this.catRepository.getForUser(userId);
  }
}
```

4. That's it. Now we have a way to share request related state without needing to inject the whole `REQUEST` object.

> **warning** Please be aware that while the technique is useful for many use-cases, it inherently obfuscates the code flow (creating implicit context), so use it responsibly and especially avoid creating contextual "[God objects](https://en.wikipedia.org/wiki/God_object)".

### NestJS CLS

The [nestjs-cls](https://github.com/Papooch/nestjs-cls) package provides several DX improvements over using plain `AsyncLocalStorage` (`CLS` is an abbreviation of the term *continuation-local storage*). It abstracts the implementation into a `ClsModule` that offers various ways of initializing the `store` for different transports (not only HTTP), as well as a strong-typing support.

The store can then be accessed with an injectable `ClsService`, or entirely abstracted away from the business logic by using [Proxy Providers](https://www.npmjs.com/package/nestjs-cls#proxy-providers).

> **info**`nestjs-cls` is a third party package and is not managed by the NestJS core team. Please, report any issues found with the library in the [appropriate repository](https://github.com/Papooch/nestjs-cls/issues).

#### Installation[#](/recipes/async-local-storage#installation)

Apart from a peer dependency on the `@nestjs` libs, it only uses the built-in Node.js API. Install it as any other package.

```bash

npm i nestjs-cls
```

#### Usage[#](/recipes/async-local-storage#usage)

A similar functionality as described [above](#custom-implementation) can be implemented using `nestjs-cls` as follows:

1. Import the `ClsModule` in the root module.

app.module.ts

JS TS

```ts

@Module({
  imports: [
    // Register the ClsModule,
    ClsModule.forRoot({
      middleware: {
        // automatically mount the
        // ClsMiddleware for all routes
        mount: true,
        // and use the setup method to
        // provide default store values.
        setup: (cls, req) => {
          cls.set('userId', req.headers['x-user-id']);
        },
      },
    }),
  ],
  providers: [CatService],
  controllers: [CatController],
})
export class AppModule {}
```

2. And then can use the `ClsService` to access the store values.

cat.service.ts

JS TS

```typescript

@Injectable()
export class CatService {
  constructor(
    // We can inject the provided ClsService instance,
    private readonly cls: ClsService,
    private readonly catRepository: CatRepository,
  ) {}

  getCatForUser() {
    // and use the "get" method to retrieve any stored value.
    const userId = this.cls.get('userId');
    return this.catRepository.getForUser(userId);
  }
}
```

```typescript

@Injectable()
@Dependencies(AsyncLocalStorage, CatRepository)
export class CatService {
  constructor(als, catRepository) {
    // We can inject the provided ClsService instance,
    this.als = als
    this.catRepository = catRepository
  }

  getCatForUser() {
    // and use the "get" method to retrieve any stored value.
    const userId = this.cls.get('userId');
    return this.catRepository.getForUser(userId);
  }
}
```

3. To get strong typing of the store values managed by the `ClsService` (and also get auto-suggestions of the string keys), we can use an optional type parameter `ClsService<MyClsStore>` when injecting it.

```ts

export interface MyClsStore extends ClsStore {
  userId: number
}
```

> **hint** It it also possible to let the package automatically generate a Request ID and access it later with `cls.getId()`, or to get the whole Request object using `cls.get(CLS_REQ)`.

#### Testing[#](/recipes/async-local-storage#testing)

Since the `ClsService` is just another injectable provider, it can be entirely mocked out in unit tests.

However, in certain integration tests, we might still want to use the real `ClsService` implementation. In that case, we will need to wrap the context-aware piece of code with a call to `ClsService#run` or `ClsService#runWith`.

```ts

describe('CatService', () => {
  let service: CatService
  let cls: ClsService
  const mockCatRepository = createMock<CatRepository>()

  beforeEach(async () => {
    const module = await Test.createTestingModule({
      // Set up most of the testing module as we normally would.
      providers: [
        CatService,
        {
          provide: CatRepository
          useValue: mockCatRepository
        }
      ],
      imports: [
        // Import the static version of ClsModule which only provides
        // the ClsService, but does not set up the store in any way.
        ClsModule
      ],
    }).compile()

    service = module.get(CatService)

    // Also retrieve the ClsService for later use.
    cls = module.get(ClsService)
  })

  describe('getCatForUser', () => {
    it('retrieves cat based on user id', async () => {
      const expectedUserId = 42
      mockCatRepository.getForUser.mockImplementationOnce(
        (id) => ({ userId: id })
      )

      // Wrap the test call in the `runWith` method
      // in which we can pass hand-crafted store values.
      const cat = await cls.runWith(
        { userId: expectedUserId },
        () => service.getCatForUser()
      )

      expect(cat.userId).toEqual(expectedUserId)
    })
  })
})
```

#### More information[#](/recipes/async-local-storage#more-information)

Visit the [NestJS CLS GitHub Page](https://github.com/Papooch/nestjs-cls) for the full API documentation and more code examples.

----
url: https://docs.nestjs.com/v9/security/authorization
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Authorization](https://docs.nestjs.com/v9/security/authorization#authorization)
* [Basic RBAC implementation](https://docs.nestjs.com/v9/security/authorization#basic-rbac-implementation)
* [Claims-based authorization](https://docs.nestjs.com/v9/security/authorization#claims-based-authorization)
* [Integrating CASL](https://docs.nestjs.com/v9/security/authorization#integrating-casl)
* [Advanced: Implementing a PoliciesGuard](https://docs.nestjs.com/v9/security/authorization#advanced-implementing-a-policiesguard)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/security/authorization.md "Suggest Edits")

### Authorization

**Authorization** refers to the process that determines what a user is able to do. For example, an administrative user is allowed to create, edit, and delete posts. A non-administrative user is only authorized to read the posts.

Authorization is orthogonal and independent from authentication. However, authorization requires an authentication mechanism.

There are many different approaches and strategies to handle authorization. The approach taken for any project depends on its particular application requirements. This chapter presents a few approaches to authorization that can be adapted to a variety of different requirements.

#### Basic RBAC implementation[#](/security/authorization#basic-rbac-implementation)

Role-based access control (**RBAC**) is a policy-neutral access-control mechanism defined around roles and privileges. In this section, we'll demonstrate how to implement a very basic RBAC mechanism using Nest [guards](/v9/guards).

First, let's create a `Role` enum representing roles in the system:

role.enum.ts

JS TS

```typescript

export enum Role {
  User = 'user',
  Admin = 'admin',
}
```

> **Hint** In more sophisticated systems, you may store roles within a database, or pull them from the external authentication provider.

With this in place, we can create a `@Roles()` decorator. This decorator allows specifying what roles are required to access specific resources.

roles.decorator.ts

JS TS

```typescript

import { SetMetadata } from '@nestjs/common';
import { Role } from '../enums/role.enum';

export const ROLES_KEY = 'roles';
export const Roles = (...roles: Role[]) => SetMetadata(ROLES_KEY, roles);
```

```typescript

import { SetMetadata } from '@nestjs/common';

export const ROLES_KEY = 'roles';
export const Roles = (...roles) => SetMetadata(ROLES_KEY, roles);
```

Now that we have a custom `@Roles()` decorator, we can use it to decorate any route handler.

cats.controller.ts

JS TS

```typescript

@Post()
@Roles(Role.Admin)
create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

```typescript

@Post()
@Roles(Role.Admin)
@Bind(Body())
create(createCatDto) {
  this.catsService.create(createCatDto);
}
```

Finally, we create a `RolesGuard` class which will compare the roles assigned to the current user to the actual roles required by the current route being processed. In order to access the route's role(s) (custom metadata), we'll use the `Reflector` helper class, which is provided out of the box by the framework and exposed from the `@nestjs/core` package.

roles.guard.ts

JS TS

```typescript

import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
import { Reflector } from '@nestjs/core';

@Injectable()
export class RolesGuard implements CanActivate {
  constructor(private reflector: Reflector) {}

  canActivate(context: ExecutionContext): boolean {
    const requiredRoles = this.reflector.getAllAndOverride<Role[]>(ROLES_KEY, [
      context.getHandler(),
      context.getClass(),
    ]);
    if (!requiredRoles) {
      return true;
    }
    const { user } = context.switchToHttp().getRequest();
    return requiredRoles.some((role) => user.roles?.includes(role));
  }
}
```

```typescript

import { Injectable, Dependencies } from '@nestjs/common';
import { Reflector } from '@nestjs/core';

@Injectable()
@Dependencies(Reflector)
export class RolesGuard {
  constructor(reflector) {
    this.reflector = reflector;
  }

  canActivate(context) {
    const requiredRoles = this.reflector.getAllAndOverride(ROLES_KEY, [
      context.getHandler(),
      context.getClass(),
    ]);
    if (!requiredRoles) {
      return true;
    }
    const { user } = context.switchToHttp().getRequest();
    return requiredRoles.some((role) => user.roles.includes(role));
  }
}
```

> **Hint** Refer to the [Reflection and metadata](/fundamentals/execution-context#reflection-and-metadata) section of the Execution context chapter for more details on utilizing `Reflector` in a context-sensitive way.

> **Notice** This example is named "**basic**" as we only check for the presence of roles on the route handler level. In real-world applications, you may have endpoints/handlers that involve several operations, in which each of them requires a specific set of permissions. In this case, you'll have to provide a mechanism to check roles somewhere within your business-logic, making it somewhat harder to maintain as there will be no centralized place that associates permissions with specific actions.

In this example, we assumed that `request.user` contains the user instance and allowed roles (under the `roles` property). In your app, you will probably make that association in your custom **authentication guard** - see [authentication](/v9/security/authentication) chapter for more details.

To make sure this example works, your `User` class must look as follows:

```typescript

class User {
  // ...other properties
  roles: Role[];
}
```

Lastly, make sure to register the `RolesGuard`, for example, at the controller level, or globally:

```typescript

providers: [
  {
    provide: APP_GUARD,
    useClass: RolesGuard,
  },
],
```

When a user with insufficient privileges requests an endpoint, Nest automatically returns the following response:

```typescript

{
  "statusCode": 403,
  "message": "Forbidden resource",
  "error": "Forbidden"
}
```

> **Hint** If you want to return a different error response, you should throw your own specific exception instead of returning a boolean value.

```typescript

@Post()
@RequirePermissions(Permission.CREATE_CAT)
create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

```typescript

@Post()
@RequirePermissions(Permission.CREATE_CAT)
@Bind(Body())
create(createCatDto) {
  this.catsService.create(createCatDto);
}
```

> **Hint** In the example above, `Permission` (similar to `Role` we have shown in RBAC section) is a TypeScript enum that contains all the permissions available in your system.

#### Integrating CASL[#](/security/authorization#integrating-casl)

[CASL](https://casl.js.org/) is an isomorphic authorization library which restricts what resources a given client is allowed to access. It's designed to be incrementally adoptable and can easily scale between a simple claim based and fully featured subject and attribute based authorization.

To start, first install the `@casl/ability` package:

```bash

$ npm i @casl/ability
```

> **Hint** In this example, we chose CASL, but you can use any other library like `accesscontrol` or `acl`, depending on your preferences and project needs.

Once the installation is complete, for the sake of illustrating the mechanics of CASL, we'll define two entity classes: `User` and `Article`.

```typescript

class User {
  id: number;
  isAdmin: boolean;
}
```

`User` class consists of two properties, `id`, which is a unique user identifier, and `isAdmin`, indicating whether a user has administrator privileges.

```typescript

class Article {
  id: number;
  isPublished: boolean;
  authorId: number;
}
```

```typescript

export enum Action {
  Manage = 'manage',
  Create = 'create',
  Read = 'read',
  Update = 'update',
  Delete = 'delete',
}
```

> **Notice**`manage` is a special keyword in CASL which represents "any" action.

To encapsulate CASL library, let's generate the `CaslModule` and `CaslAbilityFactory` now.

```bash

$ nest g module casl
$ nest g class casl/casl-ability.factory
```

With this in place, we can define the `createForUser()` method on the `CaslAbilityFactory`. This method will create the `Ability` object for a given user:

```typescript

type Subjects = InferSubjects<typeof Article | typeof User> | 'all';

export type AppAbility = Ability<[Action, Subjects]>;

@Injectable()
export class CaslAbilityFactory {
  createForUser(user: User) {
    const { can, cannot, build } = new AbilityBuilder<
      Ability<[Action, Subjects]>
    >(Ability as AbilityClass<AppAbility>);

    if (user.isAdmin) {
      can(Action.Manage, 'all'); // read-write access to everything
    } else {
      can(Action.Read, 'all'); // read-only access to everything
    }

    can(Action.Update, Article, { authorId: user.id });
    cannot(Action.Delete, Article, { isPublished: true });

    return build({
      // Read https://casl.js.org/v5/en/guide/subject-type-detection#use-classes-as-subject-types for details
      detectSubjectType: (item) =>
        item.constructor as ExtractSubjectType<Subjects>,
    });
  }
}
```

> **Notice**`all` is a special keyword in CASL that represents "any subject".

> **Hint**`Ability`, `AbilityBuilder`, `AbilityClass`, and `ExtractSubjectType` classes are exported from the `@casl/ability` package.

> **Hint**`detectSubjectType` option let CASL understand how to get subject type out of an object. For more information read [CASL documentation](https://casl.js.org/v5/en/guide/subject-type-detection#use-classes-as-subject-types) for details.

In the example above, we created the `Ability` instance using the `AbilityBuilder` class. As you probably guessed, `can` and `cannot` accept the same arguments but have different meanings, `can` allows to do an action on the specified subject and `cannot` forbids. Both may accept up to 4 arguments. To learn more about these functions, visit the official [CASL documentation](https://casl.js.org/v5/en/guide/intro).

Lastly, make sure to add the `CaslAbilityFactory` to the `providers` and `exports` arrays in the `CaslModule` module definition:

```typescript

import { Module } from '@nestjs/common';
import { CaslAbilityFactory } from './casl-ability.factory';

@Module({
  providers: [CaslAbilityFactory],
  exports: [CaslAbilityFactory],
})
export class CaslModule {}
```

With this in place, we can inject the `CaslAbilityFactory` to any class using standard constructor injection as long as the `CaslModule` is imported in the host context:

```typescript

constructor(private caslAbilityFactory: CaslAbilityFactory) {}
```

Then use it in a class as follows.

```typescript

const ability = this.caslAbilityFactory.createForUser(user);
if (ability.can(Action.Read, 'all')) {
  // "user" has read access to everything
}
```

> **Hint** Learn more about the `Ability` class in the official [CASL documentation](https://casl.js.org/v5/en/guide/intro).

For example, let's say we have a user who is not an admin. In this case, the user should be able to read articles, but creating new ones or removing the existing articles should be prohibited.

```typescript

const user = new User();
user.isAdmin = false;

const ability = this.caslAbilityFactory.createForUser(user);
ability.can(Action.Read, Article); // true
ability.can(Action.Delete, Article); // false
ability.can(Action.Create, Article); // false
```

> **Hint** Although both `Ability` and `AbilityBuilder` classes provide `can` and `cannot` methods, they have different purposes and accept slightly different arguments.

Also, as we have specified in our requirements, the user should be able to update its articles:

```typescript

const user = new User();
user.id = 1;

const article = new Article();
article.authorId = user.id;

const ability = this.caslAbilityFactory.createForUser(user);
ability.can(Action.Update, article); // true

article.authorId = 2;
ability.can(Action.Update, article); // false
```

As you can see, `Ability` instance allows us to check permissions in pretty readable way. Likewise, `AbilityBuilder` allows us to define permissions (and specify various conditions) in a similar fashion. To find more examples, visit the official documentation.

#### Advanced: Implementing a `PoliciesGuard`[#](/security/authorization#advanced-implementing-a-policiesguard)

In this section, we'll demonstrate how to build a somewhat more sophisticated guard, which checks if a user meets specific **authorization policies** that can be configured on the method-level (you can extend it to respect policies configured on the class-level too). In this example, we are going to use the CASL package just for illustration purposes, but using this library is not required. Also, we will use the `CaslAbilityFactory` provider that we've created in the previous section.

First, let's flesh out the requirements. The goal is to provide a mechanism that allows specifying policy checks per route handler. We will support both objects and functions (for simpler checks and for those who prefer more functional-style code).

Let's start off by defining interfaces for policy handlers:

```typescript

import { AppAbility } from '../casl/casl-ability.factory';

interface IPolicyHandler {
  handle(ability: AppAbility): boolean;
}

type PolicyHandlerCallback = (ability: AppAbility) => boolean;

export type PolicyHandler = IPolicyHandler | PolicyHandlerCallback;
```

As mentioned above, we provided two possible ways of defining a policy handler, an object (instance of a class that implements the `IPolicyHandler` interface) and a function (which meets the `PolicyHandlerCallback` type).

With this in place, we can create a `@CheckPolicies()` decorator. This decorator allows specifying what policies have to be met to access specific resources.

```typescript

export const CHECK_POLICIES_KEY = 'check_policy';
export const CheckPolicies = (...handlers: PolicyHandler[]) =>
  SetMetadata(CHECK_POLICIES_KEY, handlers);
```

Now let's create a `PoliciesGuard` that will extract and execute all the policy handlers bound to a route handler.

```typescript

@Injectable()
export class PoliciesGuard implements CanActivate {
  constructor(
    private reflector: Reflector,
    private caslAbilityFactory: CaslAbilityFactory,
  ) {}

  async canActivate(context: ExecutionContext): Promise<boolean> {
    const policyHandlers =
      this.reflector.get<PolicyHandler[]>(
        CHECK_POLICIES_KEY,
        context.getHandler(),
      ) || [];

    const { user } = context.switchToHttp().getRequest();
    const ability = this.caslAbilityFactory.createForUser(user);

    return policyHandlers.every((handler) =>
      this.execPolicyHandler(handler, ability),
    );
  }

  private execPolicyHandler(handler: PolicyHandler, ability: AppAbility) {
    if (typeof handler === 'function') {
      return handler(ability);
    }
    return handler.handle(ability);
  }
}
```

> **Hint** In this example, we assumed that `request.user` contains the user instance. In your app, you will probably make that association in your custom **authentication guard** - see [authentication](/v9/security/authentication) chapter for more details.

Let's break this example down. The `policyHandlers` is an array of handlers assigned to the method through the `@CheckPolicies()` decorator. Next, we use the `CaslAbilityFactory#create` method which constructs the `Ability` object, allowing us to verify whether a user has sufficient permissions to perform specific actions. We are passing this object to the policy handler which is either a function or an instance of a class that implements the `IPolicyHandler`, exposing the `handle()` method that returns a boolean. Lastly, we use the `Array#every` method to make sure that every handler returned `true` value.

Finally, to test this guard, bind it to any route handler, and register an inline policy handler (functional approach), as follows:

```typescript

@Get()
@UseGuards(PoliciesGuard)
@CheckPolicies((ability: AppAbility) => ability.can(Action.Read, Article))
findAll() {
  return this.articlesService.findAll();
}
```

Alternatively, we can define a class which implements the `IPolicyHandler` interface:

```typescript

export class ReadArticlePolicyHandler implements IPolicyHandler {
  handle(ability: AppAbility) {
    return ability.can(Action.Read, Article);
  }
}
```

And use it as follows:

```typescript

@Get()
@UseGuards(PoliciesGuard)
@CheckPolicies(new ReadArticlePolicyHandler())
findAll() {
  return this.articlesService.findAll();
}
```

> **Notice** Since we must instantiate the policy handler in-place using the `new` keyword, `ReadArticlePolicyHandler` class cannot use the Dependency Injection. This can be addressed with the `ModuleRef#get` method (read more [here](/v9/fundamentals/module-ref)). Basically, instead of registering functions and instances through the `@CheckPolicies()` decorator, you must allow passing a `Type<IPolicyHandler>`. Then, inside your guard, you could retrieve an instance using a type reference: `moduleRef.get(YOUR_HANDLER_TYPE)` or even dynamically instantiate it using the `ModuleRef#create` method.

----
url: https://docs.nestjs.com/openapi/types-and-parameters
----

[Skip to content](#content)

On this page

* [Types and parameters](https://docs.nestjs.com/openapi/types-and-parameters#types-and-parameters)
* [Arrays](https://docs.nestjs.com/openapi/types-and-parameters#arrays)
* [Circular dependencies](https://docs.nestjs.com/openapi/types-and-parameters#circular-dependencies)
* [Generics and interfaces](https://docs.nestjs.com/openapi/types-and-parameters#generics-and-interfaces)
* [Enums](https://docs.nestjs.com/openapi/types-and-parameters#enums)
* [Enums schema](https://docs.nestjs.com/openapi/types-and-parameters#enums-schema)
* [Property value examples](https://docs.nestjs.com/openapi/types-and-parameters#property-value-examples)
* [Raw definitions](https://docs.nestjs.com/openapi/types-and-parameters#raw-definitions)
* [Extra models](https://docs.nestjs.com/openapi/types-and-parameters#extra-models)
* [oneOf, anyOf, allOf](https://docs.nestjs.com/openapi/types-and-parameters#oneof-anyof-allof)
* [Schema name and description](https://docs.nestjs.com/openapi/types-and-parameters#schema-name-and-description)

### Types and parameters

The `SwaggerModule` searches for all `@Body()`, `@Query()`, `@Param()`, and `@Headers()` decorators in route handlers to generate the API document. It also uses reflection to create the corresponding model definitions. Consider the following code:

```typescript

@Post()
async create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

> **Hint** To set the body definition explicitly, use the `@ApiBody()` decorator (imported from the `@nestjs/swagger` package).

Based on the `CreateCatDto`, Swagger UI shows the following model definition:

The definition is empty, even though the class declares a few properties. To make the class properties visible to the `SwaggerModule`, either annotate them with the `@ApiProperty()` decorator or use the [CLI plugin](/openapi/cli-plugin), which does this automatically:

```typescript

import { ApiProperty } from '@nestjs/swagger';

export class CreateCatDto {
  @ApiProperty()
  name: string;

  @ApiProperty()
  age: number;

  @ApiProperty()
  breed: string;
}
```

> **Hint** Instead of manually annotating each property, consider using the [Swagger plugin](/openapi/cli-plugin), which adds these annotations for you.

Open the browser and verify the generated `CreateCatDto` model:

The `@ApiProperty()` decorator also lets you set various [Schema Object](https://swagger.io/specification/#schemaObject) properties:

```typescript

@ApiProperty({
  description: 'The age of a cat',
  minimum: 1,
  default: 1,
})
age: number;
```

> **Hint** Instead of explicitly typing `@ApiProperty({ required: false })`, you can use the `@ApiPropertyOptional()` shorthand decorator.

To set the type of the property explicitly, use the `type` key:

```typescript

@ApiProperty({
  type: Number,
})
age: number;
```

#### Arrays[#](/openapi/types-and-parameters#arrays)

When the property is an array, you must indicate the array type manually, as shown below:

```typescript

@ApiProperty({ type: [String] })
names: string[];
```

> **Hint** Consider using the [Swagger plugin](/openapi/cli-plugin), which detects arrays automatically.

Either pass the type as the first element of an array (as shown above) or set the `isArray` property to `true`.

## Official enterprise support

* **Providing technical guidance
* **Performing in-depth code reviews
* **Mentoring team members
* **Advising best practices

[Explore more](https://enterprise.nestjs.com "Enterprise | NestJS - A progressive Node.js framework")

#### Circular dependencies[#](/openapi/types-and-parameters#circular-dependencies)

When you have circular dependencies between classes, use a lazy function to provide the `SwaggerModule` with type information:

```typescript

@ApiProperty({ type: () => Node })
node: Node;
```

> **Hint** Consider using the [Swagger plugin](/openapi/cli-plugin), which detects circular dependencies automatically.

#### Generics and interfaces[#](/openapi/types-and-parameters#generics-and-interfaces)

TypeScript doesn't store metadata about generics or interfaces, so when you use them in your DTOs, the `SwaggerModule` may not be able to generate model definitions correctly at runtime. For instance, the Swagger module can't correctly inspect the following code:

```typescript

createBulk(@Body() usersDto: CreateUserDto[])
```

To overcome this limitation, set the type explicitly:

```typescript

@ApiBody({ type: [CreateUserDto] })
createBulk(@Body() usersDto: CreateUserDto[])
```

#### Enums[#](/openapi/types-and-parameters#enums)

To identify an `enum`, set the `enum` property of `@ApiProperty()` to an array of values:

```typescript

@ApiProperty({ enum: ['Admin', 'Moderator', 'User']})
role: UserRole;
```

Alternatively, define an actual TypeScript enum as follows:

```typescript

export enum UserRole {
  Admin = 'Admin',
  Moderator = 'Moderator',
  User = 'User',
}
```

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

```typescript

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

With `isArray` set to `true`, the `enum` values can be selected in a **multi-select**:

#### Enums schema[#](/openapi/types-and-parameters#enums-schema)

By default, the `enum` property adds a raw [enum](https://swagger.io/docs/specification/data-models/enums/) definition to the `parameter`:

```yaml

- breed:
    type: 'string'
    enum:
      - Persian
      - Tabby
      - Siamese
```

This specification works for most cases. However, if you use a tool that takes the specification as **input** and generates **client-side** code, the generated code may contain duplicated `enums`. Consider the following code snippet:

```typescript

// generated client-side code
export class CatDetail {
  breed: CatDetailEnum;
}

export class CatInformation {
  breed: CatInformationEnum;
}

export enum CatDetailEnum {
  Persian = 'Persian',
  Tabby = 'Tabby',
  Siamese = 'Siamese',
}

export enum CatInformationEnum {
  Persian = 'Persian',
  Tabby = 'Tabby',
  Siamese = 'Siamese',
}
```

> **Hint** The above snippet is generated using a tool called [NSwag](https://github.com/RicoSuter/NSwag).

The result contains two identical `enums`. To address this issue, pass an `enumName` along with the `enum` property in your decorator:

```typescript

export class CatDetail {
  @ApiProperty({ enum: CatBreed, enumName: 'CatBreed' })
  breed: CatBreed;
}
```

The `enumName` property makes `@nestjs/swagger` turn `CatBreed` into its own `schema`, which makes the `CatBreed` enum reusable. The specification looks like the following:

```yaml

CatDetail:
  type: 'object'
  properties:
    ...
    - breed:
        schema:
          $ref: '#/components/schemas/CatBreed'
CatBreed:
  type: string
  enum:
    - Persian
    - Tabby
    - Siamese
```

> **Hint** The `@ApiQuery()` and `@ApiParam()` decorators also accept `enumName` alongside `enum`.

#### Property value examples[#](/openapi/types-and-parameters#property-value-examples)

To set a single example for a property, use the `example` key:

```typescript

@ApiProperty({
  example: 'persian',
})
breed: string;
```

To provide multiple examples, use the `examples` key and pass an object structured like this:

```typescript

@ApiProperty({
  examples: {
    Persian: { value: 'persian' },
    Tabby: { value: 'tabby' },
    Siamese: { value: 'siamese' },
    'Scottish Fold': { value: 'scottish_fold' },
  },
})
breed: string;
```

#### Raw definitions[#](/openapi/types-and-parameters#raw-definitions)

In certain cases, such as deeply nested arrays or matrices, you may need to define your type manually:

```typescript

@ApiProperty({
  type: 'array',
  items: {
    type: 'array',
    items: {
      type: 'number',
    },
  },
})
coords: number[][];
```

You can also specify raw object schemas:

```typescript

@ApiProperty({
  type: 'object',
  properties: {
    name: {
      type: 'string',
      example: 'Error'
    },
    status: {
      type: 'number',
      example: 400
    }
  },
  required: ['name', 'status']
})
rawDefinition: Record<string, any>;
```

To manually define input/output content in controller classes, use the `schema` property:

```typescript

@ApiBody({
  schema: {
    type: 'array',
    items: {
      type: 'array',
      items: {
        type: 'number',
      },
    },
  },
})
async create(@Body() coords: number[][]) {}
```

#### Extra models[#](/openapi/types-and-parameters#extra-models)

To define additional models that your controllers don't reference directly but the Swagger module should inspect, use the `@ApiExtraModels()` decorator:

```typescript

@ApiExtraModels(ExtraModel)
export class CreateCatDto {}
```

> **Hint** You only need to use `@ApiExtraModels()` once for a specific model class.

Alternatively, pass an options object with the `extraModels` property to the `SwaggerModule.createDocument()` method:

```typescript

const documentFactory = () =>
  SwaggerModule.createDocument(app, options, {
    extraModels: [ExtraModel],
  });
```

To get a reference (`$ref`) to your model, use the `getSchemaPath(ExtraModel)` function:

```typescript

'application/vnd.api+json': {
   schema: { $ref: getSchemaPath(ExtraModel) },
},
```

#### oneOf, anyOf, allOf[#](/openapi/types-and-parameters#oneof-anyof-allof)

To combine schemas, use the `oneOf`, `anyOf`, or `allOf` keywords (see [oneOf, anyOf, allOf, not](https://swagger.io/docs/specification/data-models/oneof-anyof-allof-not/) in the Swagger documentation):

```typescript

@ApiProperty({
  oneOf: [
    { $ref: getSchemaPath(Cat) },
    { $ref: getSchemaPath(Dog) },
  ],
})
pet: Cat | Dog;
```

To define a polymorphic array (i.e., an array whose members span multiple schemas), use a raw definition (see above) to define your type by hand:

```typescript

type Pet = Cat | Dog;

@ApiProperty({
  type: 'array',
  items: {
    oneOf: [
      { $ref: getSchemaPath(Cat) },
      { $ref: getSchemaPath(Dog) },
    ],
  },
})
pets: Pet[];
```

> **Hint** The `getSchemaPath()` function is imported from `@nestjs/swagger`.

Both `Cat` and `Dog` must be defined as extra models with the `@ApiExtraModels()` decorator (at the class level).

#### Schema name and description[#](/openapi/types-and-parameters#schema-name-and-description)

The name of the generated schema is based on the name of the original model class (for example, the `CreateCatDto` model generates a `CreateCatDto` schema). To change the schema name, use the `@ApiSchema()` decorator:

```typescript

@ApiSchema({ name: 'CreateCatRequest' })
class CreateCatDto {}
```

The model above is translated into the `CreateCatRequest` schema.

By default, the generated schema has no description. To add one, use the `description` attribute:

```typescript

@ApiSchema({ description: 'Description of the CreateCatDto schema' })
class CreateCatDto {}
```

The description is then included in the schema:

```yaml

schemas:
  CreateCatDto:
    type: object
    description: Description of the CreateCatDto schema
```

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/openapi/types-and-parameters.md)

----
url: https://docs.nestjs.com/recipes/router-module
----

[Skip to content](#content)

On this page

* [Router module](https://docs.nestjs.com/recipes/router-module#router-module)

### Router module

> **Hint** This chapter is only relevant to HTTP-based applications.

In an HTTP application (e.g., a REST API), the route path for a handler is determined by concatenating the (optional) prefix declared for the controller (inside the `@Controller()` decorator) and any path specified in the method's decorator (e.g., `@Get('users')`). You can learn more about this in the [routing](/controllers#routing) section of the controllers chapter. Additionally, you can define a [global prefix](/faq/global-prefix) for all routes registered in your application, or enable [versioning](/http/versioning).

In some cases, it's useful to define a prefix at the module level, which then applies to all controllers registered inside that module. For example, imagine a REST application that exposes several endpoints used by a specific part of your application called "Dashboard". Instead of repeating the `/dashboard` prefix in each controller, you can use the `RouterModule`, as follows:

```typescript

@Module({
  imports: [
    DashboardModule,
    RouterModule.register([
      {
        path: 'dashboard',
        module: DashboardModule,
      },
    ]),
  ],
})
export class AppModule {}
```

> **Hint** The `RouterModule` class is exported from the `@nestjs/core` package.

You can also define hierarchical structures, in which each module has `children` modules. The child modules inherit their parent's prefix. In the following example, the `AdminModule` is registered as the parent module of `DashboardModule` and `MetricsModule`:

```typescript

@Module({
  imports: [
    AdminModule,
    DashboardModule,
    MetricsModule,
    RouterModule.register([
      {
        path: 'admin',
        module: AdminModule,
        children: [
          {
            path: 'dashboard',
            module: DashboardModule,
          },
          {
            path: 'metrics',
            module: MetricsModule,
          },
        ],
      },
    ]),
  ],
})
export class AppModule {}
```

> **Hint** Use this feature carefully, as overusing it can make code difficult to maintain over time.

In the example above, every controller registered inside the `DashboardModule` gets an extra `/admin/dashboard` prefix, because the module concatenates paths recursively from top to bottom, parent to children. Likewise, every controller defined inside the `MetricsModule` gets the additional module-level prefix `/admin/metrics`.

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/recipes/router-module.md)

----
url: https://docs.nestjs.com/v5/techniques/performance
----

### Performance (Fastify)

Under the hood, Nest makes use of [Express](https://expressjs.com/), but as mentioned already, provides compatibility with a wide range of other libraries, like e.g. [Fastify](https://github.com/fastify/fastify). How does it work? In fact, what Nest needs to use your favorite library, is a compatible adapter, that primarily proxies corresponding handlers to appropriate library-specific methods. Additionally, your library has to provide at least similar request-response cycle management as express.

A [Fastify](https://github.com/fastify/fastify) fits here very well because it solves design issues in a similar manner as express does. However, fastify is much **faster**, achieving almost two times better benchmarks results. The question, why Nest still uses express as a default HTTP provider then? Because express is widely-used, well-known, and has a huge set of compatible middleware.

But we don't lock people in a single paradigm. We let them use whatever they need. Fastify is a better choice when you care about really good performance, that's why we provide a built-in `FastifyAdapter` that helps to integrate this library with Nest.

#### Installation

Firstly, we need to install required packages:

```bash

$ npm i --save fastify fastify-formbody
```

#### Adapter

Once fastify is installed, we can use a `FastifyAdapter`.

TypeScript

```typescript

import { NestFactory, FastifyAdapter } from '@nestjs/core';
import { ApplicationModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(ApplicationModule, new FastifyAdapter());
  await app.listen(3000);
}
bootstrap();
```

If you're running your Nest instance inside of a **docker container** you will need to specify the host, like so:

TypeScript

```typescript

await app.listen(3000, '0.0.0.0');
```

And that's all. Also, you are able to pass options into fastify constructor through `FastifyAdapter` constructor. Keep in mind that now, Nest uses fastify as an **HTTP provider**, meaning, each recipe that relays on express won't work anymore. You should rather use fastify equivalent packages.

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/10-fastify).

* Performance (Fastify)
* Installation
* Adapter

----
url: https://docs.nestjs.com/v11/migration-guide
----

* [Migration guide](https://docs.nestjs.com/v11/migration-guide#migration-guide)
* [Upgrading packages](https://docs.nestjs.com/v11/migration-guide#upgrading-packages)
* [Express v5](https://docs.nestjs.com/v11/migration-guide#express-v5)
* [Query parameters parsing](https://docs.nestjs.com/v11/migration-guide#query-parameters-parsing)
* [Fastify v5](https://docs.nestjs.com/v11/migration-guide#fastify-v5)
* [Fastify CORS](https://docs.nestjs.com/v11/migration-guide#fastify-cors)
* [Fastify middleware registration](https://docs.nestjs.com/v11/migration-guide#fastify-middleware-registration)
* [Module resolution algorithm](https://docs.nestjs.com/v11/migration-guide#module-resolution-algorithm)
* [Reflector type inference](https://docs.nestjs.com/v11/migration-guide#reflector-type-inference)
* [Lifecycle hooks execution order](https://docs.nestjs.com/v11/migration-guide#lifecycle-hooks-execution-order)
* [Middleware registration order](https://docs.nestjs.com/v11/migration-guide#middleware-registration-order)
* [Cache module](https://docs.nestjs.com/v11/migration-guide#cache-module)
* [Config module](https://docs.nestjs.com/v11/migration-guide#config-module)
* [Terminus module](https://docs.nestjs.com/v11/migration-guide#terminus-module)
* [Node.js v16 and v18 no longer supported](https://docs.nestjs.com/v11/migration-guide#nodejs-v16-and-v18-no-longer-supported)
* [Mau official deployment platform](https://docs.nestjs.com/v11/migration-guide#mau-official-deployment-platform)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/migration.md "Suggest Edits")

### Migration guide

This article offers a comprehensive guide for migrating from NestJS version 10 to version 11. To explore the new features introduced in v11, take a look at [this article](https://trilon.io/blog/announcing-nestjs-11-whats-new). While the update includes a few minor breaking changes, they are unlikely to impact most users. You can review the complete list of changes [here](https://github.com/nestjs/nest/releases/tag/v11.0.0).

#### Upgrading packages[#](/migration-guide#upgrading-packages)

Although you can manually upgrade your packages, we recommend using [npm-check-updates (ncu)](https://npmjs.com/package/npm-check-updates) for a more streamlined process.

#### Express v5[#](/migration-guide#express-v5)

After years of development, Express v5 was officially released in 2024 and became a stable version in 2025. With NestJS 11, Express v5 is now the default version integrated into the framework. While this update is seamless for most users, it’s important to be aware that Express v5 introduces some breaking changes. For detailed guidance, refer to the [Express v5 migration guide](https://expressjs.com/en/guide/migrating-5.html).

One of the most notable updates in Express v5 is the revised path route matching algorithm. The following changes have been introduced to how path strings are matched with incoming requests:

* The wildcard `*` must have a name, matching the behavior of parameters: use `/*splat` or `/{*splat}` instead of `/*`. `splat` is simply the name of the wildcard parameter and has no special meaning. You can name it anything you like, for example, `*wildcard`
* The optional character `?` is no longer supported, use braces instead: `/:file{.:ext}`.
* Regexp characters are not supported.
* Some characters have been reserved to avoid confusion during upgrade `(()[]?+!)`, use `\` to escape them.
* Parameter names now support valid JavaScript identifiers, or quoted like `:"this"`.

That said, routes that previously worked in Express v4 may not work in Express v5. For example:

```typescript

@Get('users/*')
findAll() {
  // In NestJS 11, this will be automatically converted to a valid Express v5 route.
  // While it may still work, it's no longer advisable to use this wildcard syntax in Express v5.
  return 'This route should not work in Express v5';
}
```

To fix this issue, you can update the route to use a named wildcard:

```typescript

@Get('users/*splat')
findAll() {
  return 'This route will work in Express v5';
}
```

> **Warning** Note that `*splat` is a named wildcard that matches any path without the root path. If you need to match the root path as well (`/users`), you can use `/users/{*splat}`, wrapping the wildcard in braces (optional group). Note that `splat` is simply the name of the wildcard parameter and has no special meaning. You can name it anything you like, for example, `*wildcard`.

Similarly, if you have a middleware that runs on all routes, you may need to update the path to use a named wildcard:

```typescript

// In NestJS 11, this will be automatically converted to a valid Express v5 route.
// While it may still work, it's no longer advisable to use this wildcard syntax in Express v5.
forRoutes('*'); // <-- This should not work in Express v5
```

Instead, you can update the path to use a named wildcard:

```typescript

forRoutes('{*splat}'); // <-- This will work in Express v5
```

Note that `{*splat}` is a named wildcard that matches any path including the root path. Outer braces make path optional.

#### Query parameters parsing[#](/migration-guide#query-parameters-parsing)

> **Note** This change only applies to Express v5.

In Express v5, query parameters are no longer parsed using the `qs` library by default. Instead, the `simple` parser is used, which does not support nested objects or arrays.

As a result, query strings like these:

```plaintext

?filter[where][name]=John&filter[where][age]=30
?item[]=1&item[]=2
```

will no longer be parsed as expected. To revert to the previous behavior, you can configure Express to use the `extended` parser (the default in Express v4) by setting the `query parser` option to `extended`:

```typescript

import { NestFactory } from '@nestjs/core';
import { NestExpressApplication } from '@nestjs/platform-express';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create<NestExpressApplication>(AppModule); // <-- Make sure to use <NestExpressApplication>
  app.set('query parser', 'extended'); // <-- Add this line
  await app.listen(3000);
}
bootstrap();
```

#### Fastify v5[#](/migration-guide#fastify-v5)

`@nestjs/platform-fastify` v11 now finally supports Fastify v5. This update should be seamless for most users; however, Fastify v5 introduces a few breaking changes, though these are unlikely to affect the majority of NestJS users. For more detailed information, refer to the [Fastify v5 migration guide](https://fastify.dev/docs/v5.1.x/Guides/Migration-Guide-V5/).

> **Hint** There have been no changes to path matching in Fastify v5 (except for middleware, see the section below), so you can continue using the wildcard syntax as you did before. The behavior remains the same, and routes defined with wildcards (like `*`) will still work as expected.

#### Fastify CORS[#](/migration-guide#fastify-cors)

By default, only [CORS-safelisted methods](https://fetch.spec.whatwg.org/#methods) are allowed. If you need to enable additional methods (such as `PUT`, `PATCH`, or `DELETE`), you must explicitly define them in the `methods` option.

```typescript

const methods = ['GET', 'POST', 'PUT', 'PATCH', 'DELETE']; // OR comma-delimited string 'GET,POST,PUT,PATCH,DELETE'

const app = await NestFactory.create<NestFastifyApplication>(
  AppModule,
  new FastifyAdapter(),
  { cors: { methods } },
);

// OR alternatively, you can use the `enableCors` method
const app = await NestFactory.create<NestFastifyApplication>(
  AppModule,
  new FastifyAdapter(),
);
app.enableCors({ methods });
```

#### Fastify middleware registration[#](/migration-guide#fastify-middleware-registration)

NestJS 11 now uses the latest version of the [path-to-regexp](https://www.npmjs.com/package/path-to-regexp) package to match **middleware paths** in `@nestjs/platform-fastify`. As a result, the `(.*)` syntax for matching all paths is no longer supported. Instead, you should use named wildcards.

For example, if you have a middleware that applies to all routes:

```typescript

// In NestJS 11, this will automatically be converted to a valid route, even if you don't update it.
.forRoutes('(.*)');
```

You'll need to update it to use a named wildcard instead:

```typescript

.forRoutes('*splat');
```

Where `splat` is just an arbitrary name for the wildcard parameter. You can name it anything you like.

#### Module resolution algorithm[#](/migration-guide#module-resolution-algorithm)

Starting with NestJS 11, the module resolution algorithm has been improved to enhance performance and reduce memory usage for most applications. This change does not require any manual intervention, but there are some edge cases where the behavior may differ from previous versions.

In NestJS v10 and earlier, dynamic modules were assigned a unique opaque key generated from the module's dynamic metadata. This key was used to identify the module in the module registry. For example, if you included `TypeOrmModule.forFeature([User])` in multiple modules, NestJS would deduplicate the modules and treat them as a single module node in the registry. This process is known as node deduplication.

With the release of NestJS v11, we no longer generate predictable hashes for dynamic modules. Instead, object references are now used to determine if one module is equivalent to another. To share the same dynamic module across multiple modules, simply assign it to a variable and import it wherever needed. This new approach provides more flexibility and ensures that dynamic modules are handled more efficiently.

This new algorithm might impact your integration tests if you use a lot of dynamic modules, because without the manually deduplication mentioned above, your TestingModule could have multiple instances of a dependency. This makes it a bit trickier to stub a method, because you'll need to target the correct instance. Your options are to either:

* Deduplicate the dynamic module you'd like to stub
* Use `module.select(ParentModule).get(Target)` to find the correct instance
* Stub all instances using `module.get(Target, { each: true })`
* Or switch your test back to the old algorithm using `Test.createTestingModule({}, { moduleIdGeneratorAlgorithm: 'deep-hash' })`

#### Reflector type inference[#](/migration-guide#reflector-type-inference)

NestJS 11 introduces several improvements to the `Reflector` class, enhancing its functionality and type inference for metadata values. These updates provide a more intuitive and robust experience when working with metadata.

1. `getAllAndMerge` now returns an object rather than an array containing a single element when there is only one metadata entry, and the `value` is of type `object`. This change improves consistency when dealing with object-based metadata.
2. The `getAllAndOverride` return type has been updated to `T | undefined` instead of `T`. This update better reflects the possibility of no metadata being found and ensures proper handling of undefined cases.
3. The `ReflectableDecorator`'s transformed type argument is now properly inferred across all methods.

These enhancements improve the overall developer experience by providing better type safety and handling of metadata in NestJS 11.

#### Lifecycle hooks execution order[#](/migration-guide#lifecycle-hooks-execution-order)

Termination lifecycle hooks are now executed in the reverse order to their initialization counterparts. That said, hooks like `OnModuleDestroy`, `BeforeApplicationShutdown`, and `OnApplicationShutdown` are now executed in the reverse order.

Imagine the following scenario:

```plaintext

// Where A, B, and C are modules and "->" represents the module dependency.
A -> B -> C
```

In this case, the `OnModuleInit` hooks are executed in the following order:

```plaintext

C -> B -> A
```

While the `OnModuleDestroy` hooks are executed in the reverse order:

```plaintext

A -> B -> C
```

> **Hint** Global modules are treated as a dependency of all other modules. This means that global modules are initialized first and destroyed last.

#### Middleware registration order[#](/migration-guide#middleware-registration-order)

In NestJS v11, the behavior of middleware registration has been updated. Previously, the order of middleware registration was determined by the topological sort of the module dependency graph, where the distance from the root module defined the order of middleware registration, regardless of whether the middleware was registered in a global module or a regular module. Global modules were treated like regular modules in this respect, which led to inconsistent behavior, especially when compared to other framework features.

From v11 onwards, middleware registered in global modules is now **executed first**, regardless of its position in the module dependency graph. This change ensures that global middleware always runs before any middleware from imported modules, maintaining a consistent and predictable order.

#### Cache module[#](/migration-guide#cache-module)

The `CacheModule` (from the `@nestjs/cache-manager` package) has been updated to support the latest version of the `cache-manager` package. This update brings a few breaking changes, including a migration to [Keyv](https://keyv.org/), which offers a unified interface for key-value storage across multiple backend stores through storage adapters.

The key difference between the previous version and the new version lies in the configuration of external stores. In the previous version, to register a Redis store, you would have likely configured it like this:

```ts

// Old version - no longer supported
CacheModule.registerAsync({
  useFactory: async () => {
    const store = await redisStore({
      socket: {
        host: 'localhost',
        port: 6379,
      },
    });

    return {
      store,
    };
  },
}),
```

In the new version, you should use the `Keyv` adapter to configure the store:

```ts

// New version - supported
CacheModule.registerAsync({
  useFactory: async () => {
    return {
      stores: [
        new KeyvRedis('redis://localhost:6379'),
      ],
    };
  },
}),
```

Where `KeyvRedis` is imported from the `@keyv/redis` package. See the [Caching documentation](/v11/techniques/caching) to learn more.

> **Warning** In this update, cached data handled by the Keyv library is now structured as an object containing `value` and `expires` fields, for example: `{"value": "yourData", "expires": 1678901234567}`. While Keyv automatically retrieves the `value` field when accessing data through its API, it’s important to note this change if you interact with the cache data directly (e.g., outside of the cache-manager API) or need to support data written using the previous version of `@nestjs/cache-manager`.

#### Config module[#](/migration-guide#config-module)

If you're using the `ConfigModule` from the `@nestjs/config` package, be aware of several breaking changes introduced in `@nestjs/config@4.0.0`. Most notably, the order in which configuration variables are read by the `ConfigService#get` method has been updated. The new order is:

* Internal configuration (config namespaces and custom config files)
* Validated environment variables (if validation is enabled and a schema is provided)
* The `process.env` object

Previously, validated environment variables and the `process.env` object were read first, preventing them from being overridden by internal configuration. With this update, internal configuration will now always take precedence over environment variables.

Additionally, the `ignoreEnvVars` configuration option, which previously allowed disabling validation of the `process.env` object, has been deprecated. Instead, use the `validatePredefined` option (set to `false` to disable validation of predefined environment variables). Predefined environment variables refer to `process.env` variables that were set before the module was imported. For example, if you start your application with `PORT=3000 node main.js`, the `PORT` variable is considered predefined. However, variables loaded by the `ConfigModule` from a `.env` file are not classified as predefined.

A new `skipProcessEnv` option has also been introduced. This option allows you to prevent the `ConfigService#get` method from accessing the `process.env` object entirely, which can be helpful when you want to restrict the service from reading environment variables directly.

#### Terminus module[#](/migration-guide#terminus-module)

If you are using the `TerminusModule` and have built your own custom health indicator, a new API has been introduced in version 11. The new `HealthIndicatorService` is designed to enhance the readability and testability of custom health indicators.

Before version 11, a health indicator might have looked like this:

```typescript

@Injectable()
export class DogHealthIndicator extends HealthIndicator {
  constructor(private readonly httpService: HttpService) {
    super();
  }

  async isHealthy(key: string) {
    try {
      const badboys = await this.getBadboys();
      const isHealthy = badboys.length === 0;

      const result = this.getStatus(key, isHealthy, {
        badboys: badboys.length,
      });

      if (!isHealthy) {
        throw new HealthCheckError('Dog check failed', result);
      }

      return result;
    } catch (error) {
      const result = this.getStatus(key, isHealthy);
      throw new HealthCheckError('Dog check failed', result);
    }
  }

  private getBadboys() {
    return firstValueFrom(
      this.httpService.get<Dog[]>('https://example.com/dog').pipe(
        map((response) => response.data),
        map((dogs) => dogs.filter((dog) => dog.state === DogState.BAD_BOY)),
      ),
    );
  }
}
```

Starting with version 11, it is recommended to use the new `HealthIndicatorService` API, which streamlines the implementation process. Here's how the same health indicator can now be implemented:

```typescript

@Injectable()
export class DogHealthIndicator {
  constructor(
    private readonly httpService: HttpService,
    //  Inject the `HealthIndicatorService` provided by the `TerminusModule`
    private readonly healthIndicatorService: HealthIndicatorService,
  ) {}

  async isHealthy(key: string) {
    // Start the health indicator check for the given key
    const indicator = this.healthIndicatorService.check(key);

    try {
      const badboys = await this.getBadboys();
      const isHealthy = badboys.length === 0;

      if (!isHealthy) {
        // Mark the indicator as "down" and add additional info to the response
        return indicator.down({ badboys: badboys.length });
      }

      // Mark the health indicator as up
      return indicator.up();
    } catch (error) {
      return indicator.down('Unable to retrieve dogs');
    }
  }

  private getBadboys() {
    // ...
  }
}
```

Key changes:

* The `HealthIndicatorService` replaces the legacy `HealthIndicator` and `HealthCheckError` classes, providing a cleaner API for health checks.
* The `check` method allows for easy state tracking (`up` or `down`) while supporting the inclusion of additional metadata in health check responses.

> **Info** Please note that the `HealthIndicator` and `HealthCheckError` classes have been marked as deprecated and are scheduled for removal in the next major release.

#### Node.js v16 and v18 no longer supported[#](/migration-guide#nodejs-v16-and-v18-no-longer-supported)

Starting with NestJS 11, Node.js v16 is no longer supported, as it reached its end-of-life (EOL) on September 11, 2023. Likewise, the security support is scheduled to end on April 30, 2025 for Node.js v18, so we went ahead and dropped support for it as well.

NestJS 11 now requires **Node.js v20 or higher**.

To ensure the best experience, we strongly recommend using the latest LTS version of Node.js.

#### Mau official deployment platform[#](/migration-guide#mau-official-deployment-platform)

In case you missed the announcement, we launched our official deployment platform, [Mau](https://www.mau.nestjs.com/), in 2024. Mau is a fully managed platform that simplifies the deployment process for NestJS applications. With Mau, you can deploy your applications to the cloud (**AWS**; Amazon Web Services) with a single command, manage your environment variables, and monitor your application's performance in real-time.

Mau makes provisioning and maintaining your infrastructure as simple as clicking just a few buttons. Mau is designed to be simple and intuitive, so you can focus on building your applications and not worry about the underlying infrastructure. Under the hood, we use Amazon Web Services to provide you with a powerful and reliable platform, while abstracting away all the complexity of AWS. We take care of all the heavy lifting for you, so you can focus on building your applications and growing your business.

```bash

$ npm install -g @nestjs/mau
$ mau deploy
```

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

----
url: https://docs.nestjs.com/v9/graphql/sharing-models
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Sharing models](https://docs.nestjs.com/v9/graphql/sharing-models#sharing-models)
* [Using the model shim](https://docs.nestjs.com/v9/graphql/sharing-models#using-the-model-shim)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/sharing-models.md "Suggest Edits")

### Sharing models

> **Warning** This chapter applies only to the code first approach.

One of the biggest advantages of using Typescript for the backend of your project is the ability to reuse the same models in a Typescript-based frontend application, by using a common Typescript package.

But there's a problem: the models created using the code first approach are heavily decorated with GraphQL related decorators. Those decorators are irrelevant in the frontend, negatively impacting performance.

#### Using the model shim[#](/graphql/sharing-models#using-the-model-shim)

To solve this issue, NestJS provides a "shim" which allows you to replace the original decorators with inert code by using a `webpack` (or similar) configuration. To use this shim, configure an alias between the `@nestjs/graphql` package and the shim.

For example, for webpack this is resolved this way:

```typescript

resolve: { // see: https://webpack.js.org/configuration/resolve/
  alias: {
      "@nestjs/graphql": path.resolve(__dirname, "../node_modules/@nestjs/graphql/dist/extra/graphql-model-shim")
  }
}
```

> **Hint** The [TypeORM](/v9/techniques/database) package has a similar shim that can be found [here](https://github.com/typeorm/typeorm/blob/master/extra/typeorm-model-shim.js).

----
url: https://docs.nestjs.com/v7/techniques/performance
----

* [Performance (Fastify)](https://docs.nestjs.com/v7/techniques/performance#performance-fastify)
* [Installation](https://docs.nestjs.com/v7/techniques/performance#installation)
* [Adapter](https://docs.nestjs.com/v7/techniques/performance#adapter)
* [Platform specific packages](https://docs.nestjs.com/v7/techniques/performance#platform-specific-packages)
* [Redirect response](https://docs.nestjs.com/v7/techniques/performance#redirect-response)
* [Fastify options](https://docs.nestjs.com/v7/techniques/performance#fastify-options)
* [Example](https://docs.nestjs.com/v7/techniques/performance#example)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/techniques/performance.md "Suggest Edits")

### Performance (Fastify)

By default, Nest makes use of the [Express](https://expressjs.com/) framework. As mentioned earlier, Nest also provides compatibility with other libraries such as, for example, [Fastify](https://github.com/fastify/fastify). Nest achieves this framework independence by implementing a framework adapter whose primary function is to proxy middleware and handlers to appropriate library-specific implementations.

> **Hint** Note that in order for a framework adapter to be implemented, the target library has to provide similar request/response pipeline processing as found in Express.

[Fastify](https://github.com/fastify/fastify) provides a good alternative framework for Nest because it solves design issues in a similar manner to Express. However, fastify is much **faster** than Express, achieving almost two times better benchmarks results. A fair question is why does Nest use Express as the default HTTP provider? The reason is that Express is widely-used, well-known, and has an enormous set of compatible middleware, which is available to Nest users out-of-the-box.

But since Nest provides framework-independence, you can easily migrate between them. Fastify can be a better choice when you place high value on very fast performance. To utilize Fastify, simply choose the built-in `FastifyAdapter` as shown in this chapter.

#### Installation[#](/techniques/performance#installation)

First, we need to install the required package:

```bash

$ npm i --save @nestjs/platform-fastify
```

> **Warning** When using `@nestjs/platform-fastify` version `>=7.5.0` and `apollo-server-fastify`, GraphQL playground may not work due to incompatibility with `fastify` version `^3.0.0`. You may want to use the unstable `apollo-server-fastify` version `^3.0.0-alpha.3` or temporarily choose express instead.

#### Adapter[#](/techniques/performance#adapter)

Once the Fastify platform is installed, we can use the `FastifyAdapter`.

```typescript

import { NestFactory } from '@nestjs/core';
import {
  FastifyAdapter,
  NestFastifyApplication,
} from '@nestjs/platform-fastify';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create<NestFastifyApplication>(
    AppModule,
    new FastifyAdapter()
  );
  await app.listen(3000);
}
bootstrap();
```

By default, Fastify listens only on the `localhost 127.0.0.1` interface ([read more](https://www.fastify.io/docs/latest/Getting-Started/#your-first-server)). If you want to accept connections on other hosts, you should specify `'0.0.0.0'` in the `listen()` call:

```typescript

async function bootstrap() {
  const app = await NestFactory.create<NestFastifyApplication>(
    AppModule,
    new FastifyAdapter()
  );
  await app.listen(3000, '0.0.0.0');
}
```

#### Platform specific packages[#](/techniques/performance#platform-specific-packages)

Keep in mind that when you use the `FastifyAdapter`, Nest uses Fastify as the **HTTP provider**. This means that each recipe that relies on Express may no longer work. You should, instead, use Fastify equivalent packages.

#### Redirect response[#](/techniques/performance#redirect-response)

Fastify handles redirect responses slightly differently than Express. To do a proper redirect with Fastify, return both the status code and the URL, as follows:

```typescript

@Get()
index(@Res() res) {
  res.status(302).redirect('/login');
}
```

#### Fastify options[#](/techniques/performance#fastify-options)

You can pass options into the Fastify constructor through the `FastifyAdapter` constructor. For example:

```typescript

new FastifyAdapter({ logger: true });
```

#### Example[#](/techniques/performance#example)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/10-fastify).

----
url: https://docs.nestjs.com/v6/exception-filters
----

* [Exception filters](https://docs.nestjs.com/v6/exception-filters#exception-filters)
* [Throwing standard exceptions](https://docs.nestjs.com/v6/exception-filters#throwing-standard-exceptions)
* [Custom exceptions](https://docs.nestjs.com/v6/exception-filters#custom-exceptions)
* [Built-in HTTP exceptions](https://docs.nestjs.com/v6/exception-filters#built-in-http-exceptions)
* [Exception filters](https://docs.nestjs.com/v6/exception-filters#exception-filters-1)
* [Arguments host](https://docs.nestjs.com/v6/exception-filters#arguments-host)
* [Binding filters](https://docs.nestjs.com/v6/exception-filters#binding-filters)
* [Catch everything](https://docs.nestjs.com/v6/exception-filters#catch-everything)
* [Inheritance](https://docs.nestjs.com/v6/exception-filters#inheritance)

[](https://srv.carbonads.net/ads/click/x/GTND4277CVSIC2JEFTBLYKQUF67D62Q7CTYDVZ3JCAAI6KQJFTBIE27KCKBIVK3WCWBI42JNCKBIPKQNCTBIV53KC6SILKJUCT7DEK3EHJNCLSIZ)[Veilige opslag die meegroeit met je data. Ontdek OVHcloud Object Storage. ](https://srv.carbonads.net/ads/click/x/GTND4277CVSIC2JEFTBLYKQUF67D62Q7CTYDVZ3JCAAI6KQJFTBIE27KCKBIVK3WCWBI42JNCKBIPKQNCTBIV53KC6SILKJUCT7DEK3EHJNCLSIZ)[ads via Carbon](http://carbonads.net/?utm_source=nestjscom\&utm_medium=ad_via_link\&utm_campaign=in_unit\&utm_term=carbon)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/exception-filters.md "Suggest Edits")

### Exception filters

Nest comes with a built-in **exceptions layer** which is responsible for processing all unhandled exceptions across an application. When an exception is not handled by your application code, it is caught by this layer, which then automatically sends an appropriate user-friendly response.

Out of the box, this action is performed by a built-in **global exception filter**, which handles exceptions of type `HttpException` (and subclasses of it). When an exception is **unrecognized** (is neither `HttpException` nor a class that inherits from `HttpException`), the built-in exception filter generates the following default JSON response:

```json

{
  "statusCode": 500,
  "message": "Internal server error"
}
```

#### Throwing standard exceptions[#](/exception-filters#throwing-standard-exceptions)

Nest provides a built-in `HttpException` class, exposed from the `@nestjs/common` package. For typical HTTP REST/GraphQL API based applications, it's best practice to send standard HTTP response objects when certain error conditions occur.

For example, in the `CatsController`, we have a `findAll()` method (a `GET` route handler). Let's assume that this route handler throws an exception for some reason. To demonstrate this, we'll hard-code it as follows:

cats.controller.ts

JS TS

```typescript

@Get()
async findAll() {
  throw new HttpException('Forbidden', HttpStatus.FORBIDDEN);
}
```

> **Hint** We used the `HttpStatus` here. This is a helper enum imported from the `@nestjs/common` package.

When the client calls this endpoint, the response looks like this:

```json

{
  "statusCode": 403,
  "message": "Forbidden"
}
```

```typescript

@Get()
async findAll() {
  throw new HttpException({
    status: HttpStatus.FORBIDDEN,
    error: 'This is a custom message',
  }, 403);
}
```

Using the above, this is how the response would look:

```json

{
  "status": 403,
  "error": "This is a custom message"
}
```

#### Custom exceptions[#](/exception-filters#custom-exceptions)

In many cases, you will not need to write custom exceptions, and can use the built-in Nest HTTP exception, as described in the next section. If you do need to create customized exceptions, it's good practice to create your own **exceptions hierarchy**, where your custom exceptions inherit from the base `HttpException` class. With this approach, Nest will recognize your exceptions, and automatically take care of the error responses. Let's implement such a custom exception:

forbidden.exception.ts

JS TS

```typescript

export class ForbiddenException extends HttpException {
  constructor() {
    super('Forbidden', HttpStatus.FORBIDDEN);
  }
}
```

Since `ForbiddenException` extends the base `HttpException`, it will work seamlessly with the built-in exception handler, and therefore we can use it inside the `findAll()` method.

cats.controller.ts

JS TS

```typescript

@Get()
async findAll() {
  throw new ForbiddenException();
}
```

#### Built-in HTTP exceptions[#](/exception-filters#built-in-http-exceptions)

Nest provides a set of standard exceptions that inherit from the base `HttpException`. These are exposed from the `@nestjs/common` package, and represent many of the most common HTTP exceptions:

#### Exception filters[#](/exception-filters#exception-filters-1)

While the base (built-in) exception filter can automatically handle many cases for you, you may want **full control** over the exceptions layer. For example, you may want to add logging or use a different JSON schema based on some dynamic factors. **Exception filters** are designed for exactly this purpose. They let you control the exact flow of control and the content of the response sent back to the client.

Let's create an exception filter that is responsible for catching exceptions which are an instance of the `HttpException` class, and implementing custom response logic for them. To do this, we'll need to access the underlying platform `Request` and `Response` objects. We'll access the `Request` object so we can pull out the original `url` and include that in the logging information. We'll use the `Response` object to take direct control of the response that is sent, using the `response.json()` method.

http-exception.filter.ts

JS TS

```typescript

import { ExceptionFilter, Catch, ArgumentsHost, HttpException } from '@nestjs/common';
import { Request, Response } from 'express';

@Catch(HttpException)
export class HttpExceptionFilter implements ExceptionFilter {
  catch(exception: HttpException, host: ArgumentsHost) {
    const ctx = host.switchToHttp();
    const response = ctx.getResponse<Response>();
    const request = ctx.getRequest<Request>();
    const status = exception.getStatus();

    response
      .status(status)
      .json({
        statusCode: status,
        timestamp: new Date().toISOString(),
        path: request.url,
      });
  }
}
```

```typescript

import { Catch, HttpException } from '@nestjs/common';

@Catch(HttpException)
export class HttpExceptionFilter {
  catch(exception, host) {
    const ctx = host.switchToHttp();
    const response = ctx.getResponse();
    const request = ctx.getRequest();
    const status = exception.getStatus();

    response
      .status(status)
      .json({
        statusCode: status,
        timestamp: new Date().toISOString(),
        path: request.url,
      });
  }
}
```

> **Hint** All exception filters should implement the generic `ExceptionFilter<T>` interface. This requires you to provide the `catch(exception: T, host: ArgumentsHost)` method with its indicated signature. `T` indicates the type of the exception.

The `@Catch(HttpException)` decorator binds the required metadata to the exception filter, telling Nest that this particular filter is looking for exceptions of type `HttpException` and nothing else. The `@Catch()` decorator may take a single parameter, or a comma-separated list. This lets you set up the filter for several types of exceptions at once.

#### Arguments host[#](/exception-filters#arguments-host)

Let's look at the parameters of the `catch()` method. The `exception` parameter is the exception object currently being processed. The `host` parameter is an `ArgumentsHost` object. `ArgumentsHost` is a powerful utility object that we'll examine further in the [execution context chapter](/v6/fundamentals/execution-context)\*. In this code sample, we use it to obtain a reference to the `Request` and `Response` objects that are being passed to the original request handler (in the controller where the exception originates). In this code sample, we've used some helper methods on `ArgumentsHost` to get the desired `Request` and `Response` objects. Learn more about `ArgumentsHost`[here](/v6/fundamentals/execution-context).

\*The reason for this level of abstraction is that `ArgumentsHost` functions in all contexts (e.g., the HTTP server context we're working with now, but also Microservices and WebSockets). In the execution context chapter we'll see how we can access the appropriate [underlying arguments](https://docs.nestjs.com/fundamentals/execution-context#host-methods) for **any** execution context with the power of `ArgumentsHost` and its helper functions. This will allow us to write generic exception filters that operate across all contexts.

## Learn the right way!

* 60+ chapters
* 4+ hours of videos
* Official certificate
* Deep-dive sessions

[Explore official courses](https://courses.nestjs.com "Courses | NestJS - A node.js framework built on top of TypeScript")

#### Binding filters[#](/exception-filters#binding-filters)

Let's tie our new `HttpExceptionFilter` to the `CatsController`'s `create()` method.

cats.controller.ts

JS TS

```typescript

@Post()
@UseFilters(new HttpExceptionFilter())
async create(@Body() createCatDto: CreateCatDto) {
  throw new ForbiddenException();
}
```

```typescript

@Post()
@UseFilters(new HttpExceptionFilter())
@Bind(Body())
async create(createCatDto) {
  throw new ForbiddenException();
}
```

> **Hint** The `@UseFilters()` decorator is imported from the `@nestjs/common` package.

We have used the `@UseFilters()` decorator here. Similar to the `@Catch()` decorator, it can take a single filter instance, or a comma-separated list of filter instances. Here, we created the instance of `HttpExceptionFilter` in place. Alternatively, you may pass the class (instead of an instance), leaving responsibility for instantiation to the framework, and enabling **dependency injection**.

cats.controller.ts

JS TS

```typescript

@Post()
@UseFilters(HttpExceptionFilter)
async create(@Body() createCatDto: CreateCatDto) {
  throw new ForbiddenException();
}
```

```typescript

@Post()
@UseFilters(HttpExceptionFilter)
@Bind(Body())
async create(createCatDto) {
  throw new ForbiddenException();
}
```

> **Hint** Prefer applying filters by using classes instead of instances when possible. It reduces **memory usage** since Nest can easily reuse instances of the same class across your entire module.

In the example above, the `HttpExceptionFilter` is applied only to the single `create()` route handler, making it method-scoped. Exception filters can be scoped at different levels: method-scoped, controller-scoped, or global-scoped. For example, to set up a filter as controller-scoped, you would do the following:

cats.controller.ts

JS TS

```typescript

@UseFilters(new HttpExceptionFilter())
export class CatsController {}
```

This construction sets up the `HttpExceptionFilter` for every route handler defined inside the `CatsController`.

To create a global-scoped filter, you would do the following:

main.ts

JS TS

```typescript

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.useGlobalFilters(new HttpExceptionFilter());
  await app.listen(3000);
}
bootstrap();
```

> **Warning** The `useGlobalFilters()` method does not set up filters for gateways or hybrid applications.

Global-scoped filters are used across the whole application, for every controller and every route handler. In terms of dependency injection, global filters registered from outside of any module (with `useGlobalFilters()` as in the example above) cannot inject dependencies since this is done outside the context of any module. In order to solve this issue, you can register a global-scoped filter **directly from any module** using the following construction:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { APP_FILTER } from '@nestjs/core';

@Module({
  providers: [
    {
      provide: APP_FILTER,
      useClass: HttpExceptionFilter,
    },
  ],
})
export class AppModule {}
```

> **Hint** When using this approach to perform dependency injection for the filter, note that regardless of the module where this construction is employed, the filter is, in fact, global. Where should this be done? Choose the module where the filter (`HttpExceptionFilter` in the example above) is defined. Also, `useClass` is not the only way of dealing with custom provider registration. Learn more [here](/v6/fundamentals/custom-providers).

You can add as many filters with this technique as needed; simply add each to the providers array.

#### Catch everything[#](/exception-filters#catch-everything)

In order to catch **every** unhandled exception (regardless of the exception type), leave the `@Catch()` decorator's parameter list empty, e.g., `@Catch()`.

```typescript

import {
  ExceptionFilter,
  Catch,
  ArgumentsHost,
  HttpException,
  HttpStatus,
} from '@nestjs/common';

@Catch()
export class AllExceptionsFilter implements ExceptionFilter {
  catch(exception: unknown, host: ArgumentsHost) {
    const ctx = host.switchToHttp();
    const response = ctx.getResponse();
    const request = ctx.getRequest();

    const status =
      exception instanceof HttpException
        ? exception.getStatus()
        : HttpStatus.INTERNAL_SERVER_ERROR;

    response.status(status).json({
      statusCode: status,
      timestamp: new Date().toISOString(),
      path: request.url,
    });
  }
}
```

In the example above the filter will catch each exception thrown, regardless of its type (class).

#### Inheritance[#](/exception-filters#inheritance)

Typically, you'll create fully customized exception filters crafted to fulfill your application requirements. However, there might be use-cases when you would like to simply extend the built-in default **global exception filter**, and override the behavior based on certain factors.

In order to delegate exception processing to the base filter, you need to extend `BaseExceptionFilter` and call the inherited `catch()` method.

all-exceptions.filter.ts

JS TS

```typescript

import { Catch, ArgumentsHost } from '@nestjs/common';
import { BaseExceptionFilter } from '@nestjs/core';

@Catch()
export class AllExceptionsFilter extends BaseExceptionFilter {
  catch(exception: unknown, host: ArgumentsHost) {
    super.catch(exception, host);
  }
}
```

```typescript

import { Catch } from '@nestjs/common';
import { BaseExceptionFilter } from '@nestjs/core';

@Catch()
export class AllExceptionsFilter extends BaseExceptionFilter {
  catch(exception, host) {
    super.catch(exception, host);
  }
}
```

> **Warning** Method-scoped and Controller-scoped filters that extend the `BaseExceptionFilter` should not be instantiated with `new`. Instead, let the framework instantiate them automatically.

The above implementation is just a shell demonstrating the approach. Your implementation of the extended exception filter would include your tailored **business** logic (e.g., handling various conditions).

Global filters **can** extend the base filter. This can be done in either of two ways.

The first method is to inject the `HttpServer` reference when instantiating the custom global filter:

```typescript

async function bootstrap() {
  const app = await NestFactory.create(AppModule);

  const { httpAdapter } = app.get(HttpAdapterHost);
  app.useGlobalFilters(new AllExceptionsFilter(httpAdapter));

  await app.listen(3000);
}
bootstrap();
```

The second method is to use the `APP_FILTER` token [as shown here](exception-filters#binding-filters).

----
url: https://docs.nestjs.com/v4/recipes/cqrs
----

### Command Query Responsibility Segregation

The flow of the simplest [CRUD](https://en.wikipedia.org/wiki/Create,_read,_update_and_delete) applications could be described using the following steps:

1. Controllers layer handle **HTTP requests** and delegate tasks to the services.
2. Services layer is the place, where the most of the business logic is being done.
3. **Services** uses Repositories / DAOs to change / persist entities.
4. Entities are our models - just containers for the values, with setters and getters.

Is it a good approach? Yes, for sure. In most cases, there's no reason to make small and medium-sized applications more complicated. But sometimes it's not enough, and when our needs becomes **more sophisticated** we wanna have scalable systems with straightforward data flow.

That's why Nest provides a lightweight [CQRS module](https://github.com/nestjs/cqrs), which components are well-described below.

#### Commands

To make the application easier to understand, each change has to be preceded by **Command**. When any command is dispatched - the application has to react on it. Commands might be dispatched from the services and consumed in appropriate **Command Handlers**.

heroes-game.service.ts

JavaScript TypeScript

TypeScript

```typescript

@Component()
export class HeroesGameService {
  constructor(private readonly commandBus: CommandBus) {}

  async killDragon(heroId: string, killDragonDto: KillDragonDto) {
    return await this.commandBus.execute(
      new KillDragonCommand(heroId, killDragonDto.dragonId)
    );
  }
}
```

TypeScript

```typescript

@Component()
@Dependencies(CommandBus)
export class HeroesGameService {
  constructor(commandBus) {
    this.commandBus = commandBus;
  }

  async killDragon(heroId, killDragonDto) {
    return await this.commandBus.execute(
      new KillDragonCommand(heroId, killDragonDto.dragonId)
    );
  }
}
```

Here's a sample service, which dispatches `KillDragonCommand`. Let's see how the command looks like:

kill-dragon.command.ts

JavaScript TypeScript

TypeScript

```typescript

export class KillDragonCommand implements ICommand {
  constructor(
    public readonly heroId: string,
    public readonly dragonId: string) {}
}
```

TypeScript

```typescript

export class KillDragonCommand {
  constructor(heroId, dragonId) {
    this.heroId = heroId;
    this.dragonId = dragonId;
  }
}
```

The `CommandBus` is a commands **stream**. It delegates commands to the equivalent handlers. Each Command has to have corresponding **Command Handler**:

kill-dragon.handler.ts

JavaScript TypeScript

TypeScript

```typescript

@CommandHandler(KillDragonCommand)
export class KillDragonHandler implements ICommandHandler<KillDragonCommand> {
  constructor(private readonly repository: HeroRepository) {}

  async execute(command: KillDragonCommand, resolve: (value?) => void) {
    const { heroId, dragonId } = command;
    const hero = this.repository.findOneById(+heroId);

    hero.killEnemy(dragonId);
    await this.repository.persist(hero);
    resolve();
  }
}
```

TypeScript

```typescript

@CommandHandler(KillDragonCommand)
@Dependencies(HeroRepository)
export class KillDragonHandler {
  constructor(repository) {
    this.repository = repository;
  }

  async execute(command, resolve) {
    const { heroId, dragonId } = command;
    const hero = this.repository.findOneById(+heroId);

    hero.killEnemy(dragonId);
    await this.repository.persist(hero);
    resolve();
  }
}
```

Now, every application state change is a result of the **Command** occurrence. The logic's encapsulated in handlers. If we want we can simply add logging here or even more - we can persist our commands in the database (e.g. for the diagnostics purposes).

Why do we need `resolve()` function? Sometimes we might wanna return a message from handler to the service. Also, we can just call this function at the beginning of the `execute()` method, so the application would first turn back into the service and return a response to the client and then **asynchronously** come back here to process the dispatched command.

#### Events

Since we've encapsulated commands in the handlers, we prevent interaction between them - the application structure's still not flexible, not **reactive**. The solution's to use **events**.

hero-killed-dragon.event.ts

JavaScript TypeScript

TypeScript

```typescript

export class HeroKilledDragonEvent implements IEvent {
  constructor(
    public readonly heroId: string,
    public readonly dragonId: string) {}
}
```

TypeScript

```typescript

export class HeroKilledDragonEvent {
  constructor(heroId, dragonId) {
    this.heroId = heroId;
    this.dragonId = dragonId;
  }
}
```

Events are asynchronous. They're dispatched by **models**. Models have to extend the `AggregateRoot` class.

hero.model.ts

JavaScript TypeScript

TypeScript

```typescript

export class Hero extends AggregateRoot {
  constructor(private readonly id: string) {
    super();
  }

  killEnemy(enemyId: string) {
    // logic
    this.apply(new HeroKilledDragonEvent(this.id, enemyId));
  }
}
```

TypeScript

```typescript

export class Hero extends AggregateRoot {
  constructor(id) {
    super();
    this.id = id;
  }

  killEnemy(enemyId) {
    // logic
    this.apply(new HeroKilledDragonEvent(this.id, enemyId));
  }
}
```

The `apply()` method does not dispatch events yet because there's no relationship between model and the `EventPublisher` class. How to tell the model about the publisher? We need to use a publisher `mergeObjectContext()` method inside our command handler.

kill-dragon.handler.ts

JavaScript TypeScript

TypeScript

```typescript

@CommandHandler(KillDragonCommand)
export class KillDragonHandler implements ICommandHandler<KillDragonCommand> {
  constructor(
    private readonly repository: HeroRepository,
    private readonly publisher: EventPublisher,
  ) {}

  async execute(command: KillDragonCommand, resolve: (value?) => void) {
    const { heroId, dragonId } = command;
    const hero = this.publisher.mergeObjectContext(
      await this.repository.findOneById(+heroId),
    );
    hero.killEnemy(dragonId);
    hero.commit();
    resolve();
  }
}
```

TypeScript

```typescript

@CommandHandler(KillDragonCommand)
@Dependencies(HeroRepository, EventPublisher)
export class KillDragonHandler {
  constructor(repository, publisher) {
    this.repository = repository;
    this.publisher = publisher;
  }

  async execute(command, resolve) {
    const { heroId, dragonId } = command;
    const hero = this.publisher.mergeObjectContext(
      await this.repository.findOneById(+heroId),
    );
    hero.killEnemy(dragonId);
    hero.commit();
    resolve();
  }
}
```

Now, everything works as we expected. Notice that we need to `commit()` events since they're not dispatching immediately. Of course, an object doesn't have to exist already. We can easily merge type context also:

TypeScript

```typescript

const HeroModel = this.publisher.mergeContext(Hero);
new HeroModel('id');
```

That's it. A model has an ability to publish events now. We have to handle them.

Each event can have a lot of **Event Handlers**. They don't have to know about each other.

hero-killed-dragon.handler.ts

JavaScript TypeScript

TypeScript

```typescript

@EventsHandler(HeroKilledDragonEvent)
export class HeroKilledDragonHandler implements IEventHandler<HeroKilledDragonEvent> {
  constructor(private readonly repository: HeroRepository) {}

  handle(event: HeroKilledDragonEvent) {
    // logic
  }
}
```

TypeScript

```typescript

@EventsHandler(HeroKilledDragonEvent)
@Dependencies(HeroRepository)
export class HeroKilledDragonHandler {
  constructor(repository) {
    this.repository = repository;
  }

  handle(event) {
    // logic
  }
}
```

Now we can move the **write logic** into the event handlers.

#### Sagas

This type of **Event-Driven Architecture** improves application **reactiveness and scalability**. Now, when we have events, we can simply react to them in various manners. The **Sagas** are the last building block from the architecture point of view.

The sagas are an incredibly powerful feature. Single saga may listen for 1..\* events. It can combine, merge, filter \[...] events streams. [RxJS](https://github.com/ReactiveX/rxjs) library is the place where the magic comes from. In simple words, each saga has to return an Observable which contains a command. This command is dispatched **asynchronously**.

heroes-game.saga.ts

JavaScript TypeScript

TypeScript

```typescript

@Component()
export class HeroesGameSagas {
  dragonKilled = (events$: EventObservable<any>): Observable<ICommand> => {
    return events$.ofType(HeroKilledDragonEvent)
        .map((event) => new DropAncientItemCommand(event.heroId, fakeItemID));
  }
}
```

TypeScript

```typescript

@Component()
export class HeroesGameSagas {
  dragonKilled = (events$) => {
    return events$.ofType(HeroKilledDragonEvent)
        .map((event) => new DropAncientItemCommand(event.heroId, fakeItemID));
  }
}
```

We declared a rule that when any hero kills the dragon - it should obtain the ancient item. Then the `DropAncientItemCommand` will be dispatched and processed by the appropriate handler.

#### Setup

The last thing, which we have to take care of is to set up the entire mechanism.

heroes-game.module.ts

JavaScript TypeScript

TypeScript

```typescript

export const CommandHandlers = [KillDragonHandler, DropAncientItemHandler];
export const EventHandlers =  [HeroKilledDragonHandler, HeroFoundItemHandler];

@Module({
  imports: [CQRSModule],
  controllers: [HeroesGameController],
  components: [
    HeroesGameService,
    HeroesGameSagas,
    ...CommandHandlers,
    ...EventHandlers,
    HeroRepository,
  ]
})
export class HeroesGameModule implements OnModuleInit {
  constructor(
    private readonly moduleRef: ModuleRef,
    private readonly command$: CommandBus,
    private readonly event$: EventBus,
    private readonly heroesGameSagas: HeroesGameSagas) {}

  onModuleInit() {
    this.command$.setModuleRef(this.moduleRef);
    this.event$.setModuleRef(this.moduleRef);

    this.event$.register(EventHandlers);
    this.command$.register(CommandHandlers);
    this.event$.combineSagas([
        this.heroesGameSagas.dragonKilled,
    ]);
  }
}
```

TypeScript

```typescript

export const CommandHandlers = [KillDragonHandler, DropAncientItemHandler];
export const EventHandlers =  [HeroKilledDragonHandler, HeroFoundItemHandler];

@Module({
  imports: [CQRSModule],
  controllers: [HeroesGameController],
  components: [
    HeroesGameService,
    HeroesGameSagas,
    ...CommandHandlers,
    ...EventHandlers,
    HeroRepository,
  ]
})
@Dependencies(ModuleRef, CommandBus, EventBus, HeroesGameSagas)
export class HeroesGameModule {
  constructor(moduleRef, command$, event$, heroesGameSagas) {
    this.moduleRef = moduleRef;
    this.command$ = command$;
    this.event$ = event$;
    this.heroesGameSagas = heroesGameSagas;
  }

  onModuleInit() {
    this.command$.setModuleRef(this.moduleRef);
    this.event$.setModuleRef(this.moduleRef);

    this.event$.register(EventHandlers);
    this.command$.register(CommandHandlers);
    this.event$.combineSagas([
        this.heroesGameSagas.dragonKilled,
    ]);
  }
}
```

#### Summary

Both `CommandBus` and `EventBus` are **Observables**. It means that you can easily subscribe to the whole stream and enrich your application with **Event Sourcing**.

The full source code's available [here](https://github.com/kamilmysliwiec/nest-cqrs-example).

#### Sponsors

[](https://valor-software.com/)

Nest is an MIT-licensed open source project. It can grow thanks to the support by these awesome people. If you'd like to join them, please read more [here](https://opencollective.com/nest). Thanks!

[](https://opencollective.com/nest/backer/0/website)[](https://opencollective.com/nest/backer/1/website)[](https://opencollective.com/nest/backer/2/website)[](https://opencollective.com/nest/backer/3/website)[](https://opencollective.com/nest/backer/4/website)[](https://opencollective.com/nest/backer/5/website)[](https://opencollective.com/nest/backer/6/website)[](https://opencollective.com/nest/backer/7/website)[](https://opencollective.com/nest/backer/8/website)[](https://opencollective.com/nest/backer/9/website)[](https://opencollective.com/nest/backer/10/website)[](https://opencollective.com/nest/backer/11/website)[](https://opencollective.com/nest/backer/12/website)[](https://opencollective.com/nest/backer/13/website)[](https://opencollective.com/nest/backer/14/website)[](https://opencollective.com/nest/backer/15/website)[](https://opencollective.com/nest/backer/16/website)[](https://opencollective.com/nest/backer/17/website)[](https://opencollective.com/nest/backer/18/website)[](https://opencollective.com/nest/backer/19/website)[](https://opencollective.com/nest/backer/20/website)[](https://opencollective.com/nest/backer/21/website)[](https://opencollective.com/nest/backer/22/website)[](https://opencollective.com/nest/backer/23/website)[](https://opencollective.com/nest/backer/24/website)[](https://opencollective.com/nest/backer/25/website)[](https://opencollective.com/nest/backer/26/website)[](https://opencollective.com/nest/backer/27/website)[](https://opencollective.com/nest/backer/28/website)[](https://opencollective.com/nest/backer/29/website)

[Become a sponsor](https://opencollective.com/nest)

----
url: https://docs.nestjs.com/v4/faq/lifecycle-events
----

### Lifecycle Events

There're 2 module lifecycle events, the `OnModuleInit` and `OnModuleDestroy`. It's a good practice to use them for all the initialization stuff and avoid to put anything directly in the constructor. The constructor should be used only to initialize the class members and inject the required dependencies.

JavaScript TypeScript

TypeScript

```typescript

import { Component, OnModuleInit, OnModuleDestroy } from '@nestjs/common';

@Component()
export class UsersService implements OnModuleInit, OnModuleDestroy {
  onModuleInit() {
    console.log(`Module's initialized...`);
  }
  onModuleDestroy() {
    console.log(`Module's destroyed...`);
  }
}
```

TypeScript

```typescript

import { Component } from '@nestjs/common';

@Component()
export class UsersService {
  onModuleInit() {
    console.log(`Module's initialized...`);
  }
  onModuleDestroy() {
    console.log(`Module's destroyed...`);
  }
}
```

#### Sponsors

[](https://valor-software.com/)

Nest is an MIT-licensed open source project. It can grow thanks to the support by these awesome people. If you'd like to join them, please read more [here](https://opencollective.com/nest). Thanks!

[](https://opencollective.com/nest/backer/0/website)[](https://opencollective.com/nest/backer/1/website)[](https://opencollective.com/nest/backer/2/website)[](https://opencollective.com/nest/backer/3/website)[](https://opencollective.com/nest/backer/4/website)[](https://opencollective.com/nest/backer/5/website)[](https://opencollective.com/nest/backer/6/website)[](https://opencollective.com/nest/backer/7/website)[](https://opencollective.com/nest/backer/8/website)[](https://opencollective.com/nest/backer/9/website)[](https://opencollective.com/nest/backer/10/website)[](https://opencollective.com/nest/backer/11/website)[](https://opencollective.com/nest/backer/12/website)[](https://opencollective.com/nest/backer/13/website)[](https://opencollective.com/nest/backer/14/website)[](https://opencollective.com/nest/backer/15/website)[](https://opencollective.com/nest/backer/16/website)[](https://opencollective.com/nest/backer/17/website)[](https://opencollective.com/nest/backer/18/website)[](https://opencollective.com/nest/backer/19/website)[](https://opencollective.com/nest/backer/20/website)[](https://opencollective.com/nest/backer/21/website)[](https://opencollective.com/nest/backer/22/website)[](https://opencollective.com/nest/backer/23/website)[](https://opencollective.com/nest/backer/24/website)[](https://opencollective.com/nest/backer/25/website)[](https://opencollective.com/nest/backer/26/website)[](https://opencollective.com/nest/backer/27/website)[](https://opencollective.com/nest/backer/28/website)[](https://opencollective.com/nest/backer/29/website)

[Become a sponsor](https://opencollective.com/nest)

----
url: https://docs.nestjs.com/v11/cli/scripts
----

* [Nest CLI and scripts](https://docs.nestjs.com/v11/cli/scripts#nest-cli-and-scripts)
* [The nest binary](https://docs.nestjs.com/v11/cli/scripts#the-nest-binary)
* [Build](https://docs.nestjs.com/v11/cli/scripts#build)
* [Execution](https://docs.nestjs.com/v11/cli/scripts#execution)
* [Generation](https://docs.nestjs.com/v11/cli/scripts#generation)
* [Package scripts](https://docs.nestjs.com/v11/cli/scripts#package-scripts)
* [Backward compatibility](https://docs.nestjs.com/v11/cli/scripts#backward-compatibility)
* [Migration](https://docs.nestjs.com/v11/cli/scripts#migration)

```bash

$ npm run build
```

and

```bash

$ npm run start
```

```bash

$ npm install -g @nestjs/cli
$ cd  /some/project/root/folder
$ npm install -D @nestjs/cli
```

You can then replace the `scripts` defined in `package.json` with the following ones:

```typescript

"build": "nest build",
"start": "nest start",
"start:dev": "nest start --watch",
"start:debug": "nest start --debug --watch",
```

----
url: https://docs.nestjs.com/v10/websockets/gateways
----

* [Gateways](https://docs.nestjs.com/v10/websockets/gateways#gateways)
* [Installation](https://docs.nestjs.com/v10/websockets/gateways#installation)
* [Overview](https://docs.nestjs.com/v10/websockets/gateways#overview)
* [Multiple responses](https://docs.nestjs.com/v10/websockets/gateways#multiple-responses)
* [Asynchronous responses](https://docs.nestjs.com/v10/websockets/gateways#asynchronous-responses)
* [Lifecycle hooks](https://docs.nestjs.com/v10/websockets/gateways#lifecycle-hooks)
* [Server and Namespace](https://docs.nestjs.com/v10/websockets/gateways#server-and-namespace)
* [Example](https://docs.nestjs.com/v10/websockets/gateways#example)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/websockets/gateways.md "Suggest Edits")

### Gateways

Most of the concepts discussed elsewhere in this documentation, such as dependency injection, decorators, exception filters, pipes, guards and interceptors, apply equally to gateways. Wherever possible, Nest abstracts implementation details so that the same components can run across HTTP-based platforms, WebSockets, and Microservices. This section covers the aspects of Nest that are specific to WebSockets.

In Nest, a gateway is simply a class annotated with `@WebSocketGateway()` decorator. Technically, gateways are platform-agnostic which makes them compatible with any WebSockets library once an adapter is created. There are two WS platforms supported out-of-the-box: [socket.io](https://github.com/socketio/socket.io) and [ws](https://github.com/websockets/ws). You can choose the one that best suits your needs. Also, you can build your own adapter by following this [guide](/v10/websockets/adapter).

> **Hint** Gateways can be treated as [providers](/v10/providers); this means they can inject dependencies through the class constructor. Also, gateways can be injected by other classes (providers and controllers) as well.

#### Installation[#](/websockets/gateways#installation)

To start building WebSockets-based applications, first install the required package:

JS TS

```typescript

$ npm i --save @nestjs/websockets @nestjs/platform-socket.io
```

```typescript

$ npm i --save @nestjs/websockets @nestjs/platform-socket.io
```

#### Overview[#](/websockets/gateways#overview)

In general, each gateway is listening on the same port as the **HTTP server**, unless your app is not a web application, or you have changed the port manually. This default behavior can be modified by passing an argument to the `@WebSocketGateway(80)` decorator where `80` is a chosen port number. You can also set a [namespace](https://socket.io/docs/v4/namespaces/) used by the gateway using the following construction:

```typescript

@WebSocketGateway(80, { namespace: 'events' })
```

> **Warning** Gateways are not instantiated until they are referenced in the providers array of an existing module.

You can pass any supported [option](https://socket.io/docs/v4/server-options/) to the socket constructor with the second argument to the `@WebSocketGateway()` decorator, as shown below:

```typescript

@WebSocketGateway(81, { transports: ['websocket'] })
```

The gateway is now listening, but we have not yet subscribed to any incoming messages. Let's create a handler that will subscribe to the `events` messages and respond to the user with the exact same data.

events.gateway.ts

JS TS

```typescript

@SubscribeMessage('events')
handleEvent(@MessageBody() data: string): string {
  return data;
}
```

```typescript

@Bind(MessageBody())
@SubscribeMessage('events')
handleEvent(data) {
  return data;
}
```

> **Hint**`@SubscribeMessage()` and `@MessageBody()` decorators are imported from `@nestjs/websockets` package.

Once the gateway is created, we can register it in our module.

events.module.ts

JS TS

```typescript

@Module({
  providers: [EventsGateway]
})
export class EventsModule {}
```

You can also pass in a property key to the decorator to extract it from the incoming message body:

events.gateway.ts

JS TS

```typescript

@SubscribeMessage('events')
handleEvent(@MessageBody('id') id: number): number {
  // id === messageBody.id
  return id;
}
```

```typescript

@Bind(MessageBody('id'))
@SubscribeMessage('events')
handleEvent(id) {
  // id === messageBody.id
  return id;
}
```

If you would prefer not to use decorators, the following code is functionally equivalent:

events.gateway.ts

JS TS

```typescript

@SubscribeMessage('events')
handleEvent(client: Socket, data: string): string {
  return data;
}
```

```typescript

@SubscribeMessage('events')
handleEvent(client, data) {
  return data;
}
```

In the example above, the `handleEvent()` function takes two arguments. The first one is a platform-specific [socket instance](https://socket.io/docs/v4/server-api/#socket), while the second one is the data received from the client. This approach is not recommended though, because it requires mocking the `socket` instance in each unit test.

Once the `events` message is received, the handler sends an acknowledgment with the same data that was sent over the network. In addition, it's possible to emit messages using a library-specific approach, for example, by making use of `client.emit()` method. In order to access a connected socket instance, use `@ConnectedSocket()` decorator.

events.gateway.ts

JS TS

```typescript

@SubscribeMessage('events')
handleEvent(
  @MessageBody() data: string,
  @ConnectedSocket() client: Socket,
): string {
  return data;
}
```

```typescript

@Bind(MessageBody(), ConnectedSocket())
@SubscribeMessage('events')
handleEvent(data, client) {
  return data;
}
```

> **Hint**`@ConnectedSocket()` decorator is imported from `@nestjs/websockets` package.

However, in this case, you won't be able to leverage interceptors. If you don't want to respond to the user, you can simply skip the `return` statement (or explicitly return a "falsy" value, e.g. `undefined`).

Now when a client emits the message as follows:

```typescript

socket.emit('events', { name: 'Nest' });
```

The `handleEvent()` method will be executed. In order to listen for messages emitted from within the above handler, the client has to attach a corresponding acknowledgment listener:

```typescript

socket.emit('events', { name: 'Nest' }, (data) => console.log(data));
```

#### Multiple responses[#](/websockets/gateways#multiple-responses)

The acknowledgment is dispatched only once. Furthermore, it is not supported by native WebSockets implementation. To solve this limitation, you may return an object which consists of two properties. The `event` which is a name of the emitted event and the `data` that has to be forwarded to the client.

events.gateway.ts

JS TS

```typescript

@SubscribeMessage('events')
handleEvent(@MessageBody() data: unknown): WsResponse<unknown> {
  const event = 'events';
  return { event, data };
}
```

```typescript

@Bind(MessageBody())
@SubscribeMessage('events')
handleEvent(data) {
  const event = 'events';
  return { event, data };
}
```

> **Hint** The `WsResponse` interface is imported from `@nestjs/websockets` package.

> **Warning** You should return a class instance that implements `WsResponse` if your `data` field relies on `ClassSerializerInterceptor`, as it ignores plain JavaScript object responses.

In order to listen for the incoming response(s), the client has to apply another event listener.

```typescript

socket.on('events', (data) => console.log(data));
```

#### Asynchronous responses[#](/websockets/gateways#asynchronous-responses)

Message handlers are able to respond either synchronously or **asynchronously**. Hence, `async` methods are supported. A message handler is also able to return an `Observable`, in which case the result values will be emitted until the stream is completed.

events.gateway.ts

JS TS

```typescript

@SubscribeMessage('events')
onEvent(@MessageBody() data: unknown): Observable<WsResponse<number>> {
  const event = 'events';
  const response = [1, 2, 3];

  return from(response).pipe(
    map(data => ({ event, data })),
  );
}
```

```typescript

@Bind(MessageBody())
@SubscribeMessage('events')
onEvent(data) {
  const event = 'events';
  const response = [1, 2, 3];

  return from(response).pipe(
    map(data => ({ event, data })),
  );
}
```

In the example above, the message handler will respond **3 times** (with each item from the array).

#### Lifecycle hooks[#](/websockets/gateways#lifecycle-hooks)

There are 3 useful lifecycle hooks available. All of them have corresponding interfaces and are described in the following table:

|                       |                                                                                                                                         |
| --------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| `OnGatewayInit`       | Forces to implement the `afterInit()` method. Takes library-specific server instance as an argument (and spreads the rest if required). |
| `OnGatewayConnection` | Forces to implement the `handleConnection()` method. Takes library-specific client socket instance as an argument.                      |
| `OnGatewayDisconnect` | Forces to implement the `handleDisconnect()` method. Takes library-specific client socket instance as an argument.                      |

> **Hint** Each lifecycle interface is exposed from `@nestjs/websockets` package.

#### Server and Namespace[#](/websockets/gateways#server-and-namespace)

Occasionally, you may want to have a direct access to the native, **platform-specific** server instance. The reference to this object is passed as an argument to the `afterInit()` method (`OnGatewayInit` interface). Another option is to use the `@WebSocketServer()` decorator.

```typescript

@WebSocketServer()
server: Server;
```

Also, you can retrieve the corresponding namespace using the `namespace` attribute, as follows:

```typescript

@WebSocketServer({ namespace: 'my-namespace' })
namespace: Namespace;
```

> **Notice** The `@WebSocketServer()` decorator is imported from the `@nestjs/websockets` package.

----
url: https://docs.nestjs.com/v11/cli/usages
----

* [CLI command reference](https://docs.nestjs.com/v11/cli/usages#cli-command-reference)
* [nest new](https://docs.nestjs.com/v11/cli/usages#nest-new)
* [nest generate](https://docs.nestjs.com/v11/cli/usages#nest-generate)
* [nest build](https://docs.nestjs.com/v11/cli/usages#nest-build)
* [nest start](https://docs.nestjs.com/v11/cli/usages#nest-start)
* [nest add](https://docs.nestjs.com/v11/cli/usages#nest-add)
* [nest info](https://docs.nestjs.com/v11/cli/usages#nest-info)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/cli/usages.md "Suggest Edits")

### CLI command reference

#### nest new[#](/cli/usages#nest-new)

Creates a new (standard mode) Nest project.

```bash

$ nest new <name> [options]
$ nest n <name> [options]
```

| Argument | Description                 |
| -------- | --------------------------- |
| `<name>` | The name of the new project |

##### Options

| Option                                | Description                                                                                                                                                                                          |
| ------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--dry-run`                           | Reports changes that would be made, but does not change the filesystem. Alias: `-d`                                                                                                                  |
| `--skip-git`                          | Skip git repository initialization. Alias: `-g`                                                                                                                                                      |
| `--skip-install`                      | Skip package installation. Alias: `-s`                                                                                                                                                               |
| `--package-manager [package-manager]` | Specify package manager. Use `npm`, `yarn`, or `pnpm`. Package manager must be installed globally. Alias: `-p`                                                                                       |
| `--language [language]`               | Specify programming language (`TS` or `JS`). Alias: `-l`                                                                                                                                             |
| `--collection [collectionName]`       | Specify schematics collection. Use package name of installed npm package containing schematic. Alias: `-c`                                                                                           |
| `--strict`                            | Start the project with the following TypeScript compiler flags enabled: `strictNullChecks`, `noImplicitAny`, `strictBindCallApply`, `forceConsistentCasingInFileNames`, `noFallthroughCasesInSwitch` |

#### nest generate[#](/cli/usages#nest-generate)

Generates and/or modifies files based on a schematic

```bash

$ nest generate <schematic> <name> [options]
$ nest g <schematic> <name> [options]
```

##### Arguments

| Argument      | Description                                                                                              |
| ------------- | -------------------------------------------------------------------------------------------------------- |
| `<schematic>` | The `schematic` or `collection:schematic` to generate. See the table below for the available schematics. |
| `<name>`      | The name of the generated component.                                                                     |

##### Schematics

| Name          | Alias | Description                                                                                                                |
| ------------- | ----- | -------------------------------------------------------------------------------------------------------------------------- |
| `app`         |       | Generate a new application within a monorepo (converting to monorepo if it's a standard structure).                        |
| `library`     | `lib` | Generate a new library within a monorepo (converting to monorepo if it's a standard structure).                            |
| `class`       | `cl`  | Generate a new class.                                                                                                      |
| `controller`  | `co`  | Generate a controller declaration.                                                                                         |
| `decorator`   | `d`   | Generate a custom decorator.                                                                                               |
| `filter`      | `f`   | Generate a filter declaration.                                                                                             |
| `gateway`     | `ga`  | Generate a gateway declaration.                                                                                            |
| `guard`       | `gu`  | Generate a guard declaration.                                                                                              |
| `interface`   | `itf` | Generate an interface.                                                                                                     |
| `interceptor` | `itc` | Generate an interceptor declaration.                                                                                       |
| `middleware`  | `mi`  | Generate a middleware declaration.                                                                                         |
| `module`      | `mo`  | Generate a module declaration.                                                                                             |
| `pipe`        | `pi`  | Generate a pipe declaration.                                                                                               |
| `provider`    | `pr`  | Generate a provider declaration.                                                                                           |
| `resolver`    | `r`   | Generate a resolver declaration.                                                                                           |
| `resource`    | `res` | Generate a new CRUD resource. See the [CRUD (resource) generator](/v11/recipes/crud-generator) for more details. (TS only) |
| `service`     | `s`   | Generate a service declaration.                                                                                            |

##### Options

| Option                          | Description                                                                                                |
| ------------------------------- | ---------------------------------------------------------------------------------------------------------- |
| `--dry-run`                     | Reports changes that would be made, but does not change the filesystem. Alias: `-d`                        |
| `--project [project]`           | Project that element should be added to. Alias: `-p`                                                       |
| `--flat`                        | Do not generate a folder for the element.                                                                  |
| `--collection [collectionName]` | Specify schematics collection. Use package name of installed npm package containing schematic. Alias: `-c` |
| `--spec`                        | Enforce spec files generation (default)                                                                    |
| `--no-spec`                     | Disable spec files generation                                                                              |

#### nest build[#](/cli/usages#nest-build)

Compiles an application or workspace into an output folder.

Also, the `build` command is responsible for:

* mapping paths (if using path aliases) via `tsconfig-paths`
* annotating DTOs with OpenAPI decorators (if `@nestjs/swagger` CLI plugin is enabled)
* annotating DTOs with GraphQL decorators (if `@nestjs/graphql` CLI plugin is enabled)

```bash

$ nest build <name> [options]
```

##### Arguments

| Argument | Description                       |
| -------- | --------------------------------- |
| `<name>` | The name of the project to build. |

##### Options

| Option                  | Description                                                                                                                                                                     |
| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--path [path]`         | Path to `tsconfig` file. Alias `-p`                                                                                                                                             |
| `--config [path]`       | Path to `nest-cli` configuration file. Alias `-c`                                                                                                                               |
| `--watch`               | Run in watch mode (live-reload). If you're using `tsc` for compilation, you can type `rs` to restart the application (when `manualRestart` option is set to `true`). Alias `-w` |
| `--builder [name]`      | Specify the builder to use for compilation (`tsc`, `swc`, or `webpack`). Alias `-b`                                                                                             |
| `--webpack`             | Use webpack for compilation (deprecated: use `--builder webpack` instead).                                                                                                      |
| `--webpackPath`         | Path to webpack configuration.                                                                                                                                                  |
| `--tsc`                 | Force use `tsc` for compilation.                                                                                                                                                |
| `--watchAssets`         | Watch non-TS files (assets like `.graphql` etc.). See [Assets](cli/monorepo#assets) for more details.                                                                           |
| `--type-check`          | Enable type checking (when SWC is used).                                                                                                                                        |
| `--all`                 | Build all projects in a monorepo.                                                                                                                                               |
| `--preserveWatchOutput` | Keep outdated console output in watch mode instead of clearing the screen. (`tsc` watch mode only)                                                                              |

#### nest start[#](/cli/usages#nest-start)

Compiles and runs an application (or default project in a workspace).

```bash

$ nest start <name> [options]
```

##### Arguments

| Argument | Description                     |
| -------- | ------------------------------- |
| `<name>` | The name of the project to run. |

##### Options

| Option                  | Description                                                                                                                        |
| ----------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| `--path [path]`         | Path to `tsconfig` file. Alias `-p`                                                                                                |
| `--config [path]`       | Path to `nest-cli` configuration file. Alias `-c`                                                                                  |
| `--watch`               | Run in watch mode (live-reload) Alias `-w`                                                                                         |
| `--builder [name]`      | Specify the builder to use for compilation (`tsc`, `swc`, or `webpack`). Alias `-b`                                                |
| `--preserveWatchOutput` | Keep outdated console output in watch mode instead of clearing the screen. (`tsc` watch mode only)                                 |
| `--watchAssets`         | Run in watch mode (live-reload), watching non-TS files (assets). See [Assets](cli/monorepo#assets) for more details.               |
| `--debug [hostport]`    | Run in debug mode (with --inspect flag) Alias `-d`                                                                                 |
| `--webpack`             | Use webpack for compilation. (deprecated: use `--builder webpack` instead)                                                         |
| `--webpackPath`         | Path to webpack configuration.                                                                                                     |
| `--tsc`                 | Force use `tsc` for compilation.                                                                                                   |
| `--exec [binary]`       | Binary to run (default: `node`). Alias `-e`                                                                                        |
| `--no-shell`            | Do not spawn child processes within a shell (see node's `child_process.spawn()` method docs).                                      |
| `--env-file`            | Loads environment variables from a file relative to the current directory, making them available to applications on `process.env`. |
| `-- [key=value]`        | Command-line arguments that can be referenced with `process.argv`.                                                                 |

#### nest add[#](/cli/usages#nest-add)

Imports a library that has been packaged as a **nest library**, running its install schematic.

```bash

$ nest add <name> [options]
```

##### Arguments

| Argument | Description                        |
| -------- | ---------------------------------- |
| `<name>` | The name of the library to import. |

#### nest info[#](/cli/usages#nest-info)

Displays information about installed nest packages and other helpful system info. For example:

```bash

$ nest info
```

```bash

 _   _             _      ___  _____  _____  _     _____
| \ | |           | |    |_  |/  ___|/  __ \| |   |_   _|
|  \| |  ___  ___ | |_     | |\ `--. | /  \/| |     | |
| . ` | / _ \/ __|| __|    | | `--. \| |    | |     | |
| |\  ||  __/\__ \| |_ /\__/ //\__/ /| \__/\| |_____| |_
\_| \_/ \___||___/ \__|\____/ \____/  \____/\_____/\___/

[System Information]
OS Version : macOS High Sierra
NodeJS Version : v20.18.0
[Nest Information]
microservices version : 10.0.0
websockets version : 10.0.0
testing version : 10.0.0
common version : 10.0.0
core version : 10.0.0
```

----
url: https://docs.nestjs.com/v10/support
----

* [Support](https://docs.nestjs.com/v10/support#support)
* [How can you help?](https://docs.nestjs.com/v10/support#how-can-you-help)

----
url: https://docs.nestjs.com/v8/security/authorization
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Authorization](https://docs.nestjs.com/v8/security/authorization#authorization)
* [Basic RBAC implementation](https://docs.nestjs.com/v8/security/authorization#basic-rbac-implementation)
* [Claims-based authorization](https://docs.nestjs.com/v8/security/authorization#claims-based-authorization)
* [Integrating CASL](https://docs.nestjs.com/v8/security/authorization#integrating-casl)
* [Advanced: Implementing a PoliciesGuard](https://docs.nestjs.com/v8/security/authorization#advanced-implementing-a-policiesguard)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/security/authorization.md "Suggest Edits")

### Authorization

**Authorization** refers to the process that determines what a user is able to do. For example, an administrative user is allowed to create, edit, and delete posts. A non-administrative user is only authorized to read the posts.

Authorization is orthogonal and independent from authentication. However, authorization requires an authentication mechanism.

There are many different approaches and strategies to handle authorization. The approach taken for any project depends on its particular application requirements. This chapter presents a few approaches to authorization that can be adapted to a variety of different requirements.

#### Basic RBAC implementation[#](/security/authorization#basic-rbac-implementation)

Role-based access control (**RBAC**) is a policy-neutral access-control mechanism defined around roles and privileges. In this section, we'll demonstrate how to implement a very basic RBAC mechanism using Nest [guards](/v8/guards).

First, let's create a `Role` enum representing roles in the system:

role.enum.ts

JS TS

```typescript

export enum Role {
  User = 'user',
  Admin = 'admin',
}
```

> **Hint** In more sophisticated systems, you may store roles within a database, or pull them from the external authentication provider.

With this in place, we can create a `@Roles()` decorator. This decorator allows specifying what roles are required to access specific resources.

roles.decorator.ts

JS TS

```typescript

import { SetMetadata } from '@nestjs/common';
import { Role } from '../enums/role.enum';

export const ROLES_KEY = 'roles';
export const Roles = (...roles: Role[]) => SetMetadata(ROLES_KEY, roles);
```

```typescript

import { SetMetadata } from '@nestjs/common';

export const ROLES_KEY = 'roles';
export const Roles = (...roles) => SetMetadata(ROLES_KEY, roles);
```

Now that we have a custom `@Roles()` decorator, we can use it to decorate any route handler.

cats.controller.ts

JS TS

```typescript

@Post()
@Roles(Role.Admin)
create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

```typescript

@Post()
@Roles(Role.Admin)
@Bind(Body())
create(createCatDto) {
  this.catsService.create(createCatDto);
}
```

Finally, we create a `RolesGuard` class which will compare the roles assigned to the current user to the actual roles required by the current route being processed. In order to access the route's role(s) (custom metadata), we'll use the `Reflector` helper class, which is provided out of the box by the framework and exposed from the `@nestjs/core` package.

roles.guard.ts

JS TS

```typescript

import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
import { Reflector } from '@nestjs/core';

@Injectable()
export class RolesGuard implements CanActivate {
  constructor(private reflector: Reflector) {}

  canActivate(context: ExecutionContext): boolean {
    const requiredRoles = this.reflector.getAllAndOverride<Role[]>(ROLES_KEY, [
      context.getHandler(),
      context.getClass(),
    ]);
    if (!requiredRoles) {
      return true;
    }
    const { user } = context.switchToHttp().getRequest();
    return requiredRoles.some((role) => user.roles?.includes(role));
  }
}
```

```typescript

import { Injectable, Dependencies } from '@nestjs/common';
import { Reflector } from '@nestjs/core';

@Injectable()
@Dependencies(Reflector)
export class RolesGuard {
  constructor(reflector) {
    this.reflector = reflector;
  }

  canActivate(context) {
    const requiredRoles = this.reflector.getAllAndOverride(ROLES_KEY, [
      context.getHandler(),
      context.getClass(),
    ]);
    if (!requiredRoles) {
      return true;
    }
    const { user } = context.switchToHttp().getRequest();
    return requiredRoles.some((role) => user.roles.includes(role));
  }
}
```

> **Hint** Refer to the [Reflection and metadata](/fundamentals/execution-context#reflection-and-metadata) section of the Execution context chapter for more details on utilizing `Reflector` in a context-sensitive way.

> **Notice** This example is named "**basic**" as we only check for the presence of roles on the route handler level. In real-world applications, you may have endpoints/handlers that involve several operations, in which each of them requires a specific set of permissions. In this case, you'll have to provide a mechanism to check roles somewhere within your business-logic, making it somewhat harder to maintain as there will be no centralized place that associates permissions with specific actions.

In this example, we assumed that `request.user` contains the user instance and allowed roles (under the `roles` property). In your app, you will probably make that association in your custom **authentication guard** - see [authentication](/v8/security/authentication) chapter for more details.

To make sure this example works, your `User` class must look as follows:

```typescript

class User {
  // ...other properties
  roles: Role[];
}
```

Lastly, make sure to register the `RolesGuard`, for example, at the controller level, or globally:

```typescript

providers: [
  {
    provide: APP_GUARD,
    useClass: RolesGuard,
  },
],
```

When a user with insufficient privileges requests an endpoint, Nest automatically returns the following response:

```typescript

{
  "statusCode": 403,
  "message": "Forbidden resource",
  "error": "Forbidden"
}
```

> **Hint** If you want to return a different error response, you should throw your own specific exception instead of returning a boolean value.

#### Claims-based authorization[#](/security/authorization#claims-based-authorization)

When an identity is created it may be assigned one or more claims issued by a trusted party. A claim is a name-value pair that represents what the subject can do, not what the subject is.

To implement a Claims-based authorization in Nest, you can follow the same steps we have shown above in the [RBAC](/security/authorization#basic-rbac-implementation) section with one significant difference: instead of checking for specific roles, you should compare **permissions**. Every user would have a set of permissions assigned. Likewise, each resource/endpoint would define what permissions are required (for example, through a dedicated `@RequirePermissions()` decorator) to access them.

cats.controller.ts

JS TS

```typescript

@Post()
@RequirePermissions(Permission.CREATE_CAT)
create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

```typescript

@Post()
@RequirePermissions(Permission.CREATE_CAT)
@Bind(Body())
create(createCatDto) {
  this.catsService.create(createCatDto);
}
```

> **Hint** In the example above, `Permission` (similar to `Role` we have shown in RBAC section) is a TypeScript enum that contains all the permissions available in your system.

#### Integrating CASL[#](/security/authorization#integrating-casl)

[CASL](https://casl.js.org/) is an isomorphic authorization library which restricts what resources a given client is allowed to access. It's designed to be incrementally adoptable and can easily scale between a simple claim based and fully featured subject and attribute based authorization.

To start, first install the `@casl/ability` package:

```bash

$ npm i @casl/ability
```

> **Hint** In this example, we chose CASL, but you can use any other library like `accesscontrol` or `acl`, depending on your preferences and project needs.

Once the installation is complete, for the sake of illustrating the mechanics of CASL, we'll define two entity classes: `User` and `Article`.

```typescript

class User {
  id: number;
  isAdmin: boolean;
}
```

`User` class consists of two properties, `id`, which is a unique user identifier, and `isAdmin`, indicating whether a user has administrator privileges.

```typescript

class Article {
  id: number;
  isPublished: boolean;
  authorId: number;
}
```

```typescript

export enum Action {
  Manage = 'manage',
  Create = 'create',
  Read = 'read',
  Update = 'update',
  Delete = 'delete',
}
```

> **Notice**`manage` is a special keyword in CASL which represents "any" action.

To encapsulate CASL library, let's generate the `CaslModule` and `CaslAbilityFactory` now.

```bash

$ nest g module casl
$ nest g class casl/casl-ability.factory
```

With this in place, we can define the `createForUser()` method on the `CaslAbilityFactory`. This method will create the `Ability` object for a given user:

```typescript

type Subjects = InferSubjects<typeof Article | typeof User> | 'all';

export type AppAbility = Ability<[Action, Subjects]>;

@Injectable()
export class CaslAbilityFactory {
  createForUser(user: User) {
    const { can, cannot, build } = new AbilityBuilder<
      Ability<[Action, Subjects]>
    >(Ability as AbilityClass<AppAbility>);

    if (user.isAdmin) {
      can(Action.Manage, 'all'); // read-write access to everything
    } else {
      can(Action.Read, 'all'); // read-only access to everything
    }

    can(Action.Update, Article, { authorId: user.id });
    cannot(Action.Delete, Article, { isPublished: true });

    return build({
      // Read https://casl.js.org/v5/en/guide/subject-type-detection#use-classes-as-subject-types for details
      detectSubjectType: (item) =>
        item.constructor as ExtractSubjectType<Subjects>,
    });
  }
}
```

> **Notice**`all` is a special keyword in CASL that represents "any subject".

> **Hint**`Ability`, `AbilityBuilder`, `AbilityClass`, and `ExtractSubjectType` classes are exported from the `@casl/ability` package.

> **Hint**`detectSubjectType` option let CASL understand how to get subject type out of an object. For more information read [CASL documentation](https://casl.js.org/v5/en/guide/subject-type-detection#use-classes-as-subject-types) for details.

In the example above, we created the `Ability` instance using the `AbilityBuilder` class. As you probably guessed, `can` and `cannot` accept the same arguments but has different meanings, `can` allows to do an action on the specified subject and `cannot` forbids. Both may accept up to 4 arguments. To learn more about these functions, visit the official [CASL documentation](https://casl.js.org/v5/en/guide/intro).

Lastly, make sure to add the `CaslAbilityFactory` to the `providers` and `exports` arrays in the `CaslModule` module definition:

```typescript

import { Module } from '@nestjs/common';
import { CaslAbilityFactory } from './casl-ability.factory';

@Module({
  providers: [CaslAbilityFactory],
  exports: [CaslAbilityFactory],
})
export class CaslModule {}
```

With this in place, we can inject the `CaslAbilityFactory` to any class using standard constructor injection as long as the `CaslModule` is imported in the host context:

```typescript

constructor(private caslAbilityFactory: CaslAbilityFactory) {}
```

Then use it in a class as follows.

```typescript

const ability = this.caslAbilityFactory.createForUser(user);
if (ability.can(Action.Read, 'all')) {
  // "user" has read access to everything
}
```

> **Hint** Learn more about the `Ability` class in the official [CASL documentation](https://casl.js.org/v5/en/guide/intro).

For example, let's say we have a user who is not an admin. In this case, the user should be able to read articles, but creating new ones or removing the existing articles should be prohibited.

```typescript

const user = new User();
user.isAdmin = false;

const ability = this.caslAbilityFactory.createForUser(user);
ability.can(Action.Read, Article); // true
ability.can(Action.Delete, Article); // false
ability.can(Action.Create, Article); // false
```

> **Hint** Although both `Ability` and `AbilityBuilder` classes provide `can` and `cannot` methods, they have different purposes and accept slightly different arguments.

Also, as we have specified in our requirements, the user should be able to update its articles:

```typescript

const user = new User();
user.id = 1;

const article = new Article();
article.authorId = user.id;

const ability = this.caslAbilityFactory.createForUser(user);
ability.can(Action.Update, article); // true

article.authorId = 2;
ability.can(Action.Update, article); // false
```

As you can see, `Ability` instance allows us to check permissions in pretty readable way. Likewise, `AbilityBuilder` allows us to define permissions (and specify various conditions) in a similar fashion. To find more examples, visit the official documentation.

#### Advanced: Implementing a `PoliciesGuard`[#](/security/authorization#advanced-implementing-a-policiesguard)

In this section, we'll demonstrate how to build a somewhat more sophisticated guard, which checks if a user meets specific **authorization policies** that can be configured on the method-level (you can extend it to respect policies configured on the class-level too). In this example, we are going to use the CASL package just for illustration purposes, but using this library is not required. Also, we will use the `CaslAbilityFactory` provider that we've created in the previous section.

First, let's flesh out the requirements. The goal is to provide a mechanism that allows specifying policy checks per route handler. We will support both objects and functions (for simpler checks and for those who prefer more functional-style code).

Let's start off by defining interfaces for policy handlers:

```typescript

import { AppAbility } from '../casl/casl-ability.factory';

interface IPolicyHandler {
  handle(ability: AppAbility): boolean;
}

type PolicyHandlerCallback = (ability: AppAbility) => boolean;

export type PolicyHandler = IPolicyHandler | PolicyHandlerCallback;
```

As mentioned above, we provided two possible ways of defining a policy handler, an object (instance of a class that implements the `IPolicyHandler` interface) and a function (which meets the `PolicyHandlerCallback` type).

With this in place, we can create a `@CheckPolicies()` decorator. This decorator allows specifying what policies have to be met to access specific resources.

```typescript

export const CHECK_POLICIES_KEY = 'check_policy';
export const CheckPolicies = (...handlers: PolicyHandler[]) =>
  SetMetadata(CHECK_POLICIES_KEY, handlers);
```

Now let's create a `PoliciesGuard` that will extract and execute all the policy handlers bound to a route handler.

```typescript

@Injectable()
export class PoliciesGuard implements CanActivate {
  constructor(
    private reflector: Reflector,
    private caslAbilityFactory: CaslAbilityFactory,
  ) {}

  async canActivate(context: ExecutionContext): Promise<boolean> {
    const policyHandlers =
      this.reflector.get<PolicyHandler[]>(
        CHECK_POLICIES_KEY,
        context.getHandler(),
      ) || [];

    const { user } = context.switchToHttp().getRequest();
    const ability = this.caslAbilityFactory.createForUser(user);

    return policyHandlers.every((handler) =>
      this.execPolicyHandler(handler, ability),
    );
  }

  private execPolicyHandler(handler: PolicyHandler, ability: AppAbility) {
    if (typeof handler === 'function') {
      return handler(ability);
    }
    return handler.handle(ability);
  }
}
```

> **Hint** In this example, we assumed that `request.user` contains the user instance. In your app, you will probably make that association in your custom **authentication guard** - see [authentication](/v8/security/authentication) chapter for more details.

Let's break this example down. The `policyHandlers` is an array of handlers assigned to the method through the `@CheckPolicies()` decorator. Next, we use the `CaslAbilityFactory#create` method which constructs the `Ability` object, allowing us to verify whether a user has sufficient permissions to perform specific actions. We are passing this object to the policy handler which is either a function or an instance of a class that implements the `IPolicyHandler`, exposing the `handle()` method that returns a boolean. Lastly, we use the `Array#every` method to make sure that every handler returned `true` value.

Finally, to test this guard, bind it to any route handler, and register an inline policy handler (functional approach), as follows:

```typescript

@Get()
@UseGuards(PoliciesGuard)
@CheckPolicies((ability: AppAbility) => ability.can(Action.Read, Article))
findAll() {
  return this.articlesService.findAll();
}
```

Alternatively, we can define a class which implements the `IPolicyHandler` interface:

```typescript

export class ReadArticlePolicyHandler implements IPolicyHandler {
  handle(ability: AppAbility) {
    return ability.can(Action.Read, Article);
  }
}
```

And use it as follows:

```typescript

@Get()
@UseGuards(PoliciesGuard)
@CheckPolicies(new ReadArticlePolicyHandler())
findAll() {
  return this.articlesService.findAll();
}
```

> **Notice** Since we must instantiate the policy handler in-place using the `new` keyword, `ReadArticlePolicyHandler` class cannot use the Dependency Injection. This can be addressed with the `ModuleRef#get` method (read more [here](/v8/fundamentals/module-ref)). Basically, instead of registering functions and instances through the `@CheckPolicies()` decorator, you must allow passing a `Type<IPolicyHandler>`. Then, inside your guard, you could retrieve an instance using a type reference: `moduleRef.get(YOUR_HANDLER_TYPE)` or even dynamically instantiate it using the `ModuleRef#create` method.

----
url: https://docs.nestjs.com/v8/providers
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Providers](https://docs.nestjs.com/v8/providers#providers)
* [Services](https://docs.nestjs.com/v8/providers#services)
* [Dependency injection](https://docs.nestjs.com/v8/providers#dependency-injection)
* [Scopes](https://docs.nestjs.com/v8/providers#scopes)
* [Custom providers](https://docs.nestjs.com/v8/providers#custom-providers)
* [Optional providers](https://docs.nestjs.com/v8/providers#optional-providers)
* [Property-based injection](https://docs.nestjs.com/v8/providers#property-based-injection)
* [Provider registration](https://docs.nestjs.com/v8/providers#provider-registration)
* [Manual instantiation](https://docs.nestjs.com/v8/providers#manual-instantiation)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/components.md "Suggest Edits")

### Providers

Providers are a fundamental concept in Nest. Many of the basic Nest classes may be treated as a provider – services, repositories, factories, helpers, and so on. The main idea of a provider is that it can be **injected** as a dependency; this means objects can create various relationships with each other, and the function of "wiring up" instances of objects can largely be delegated to the Nest runtime system.

In the previous chapter, we built a simple `CatsController`. Controllers should handle HTTP requests and delegate more complex tasks to **providers**. Providers are plain JavaScript classes that are declared as `providers` in a [module](/v8/modules).

> **Hint** Since Nest enables the possibility to design and organize dependencies in a more OO way, we strongly recommend following the [SOLID](https://en.wikipedia.org/wiki/SOLID) principles.

#### Services[#](/providers#services)

Let's start by creating a simple `CatsService`. This service will be responsible for data storage and retrieval, and is designed to be used by the `CatsController`, so it's a good candidate to be defined as a provider.

cats.service.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { Cat } from './interfaces/cat.interface';

@Injectable()
export class CatsService {
  private readonly cats: Cat[] = [];

  create(cat: Cat) {
    this.cats.push(cat);
  }

  findAll(): Cat[] {
    return this.cats;
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';

@Injectable()
export class CatsService {
  constructor() {
    this.cats = [];
  }

  create(cat) {
    this.cats.push(cat);
  }

  findAll() {
    return this.cats;
  }
}
```

> **Hint** To create a service using the CLI, simply execute the `$ nest g service cats` command.

Our `CatsService` is a basic class with one property and two methods. The only new feature is that it uses the `@Injectable()` decorator. The `@Injectable()` decorator attaches metadata, which declares that `CatsService` is a class that can be managed by the Nest [IoC](https://en.wikipedia.org/wiki/Inversion_of_control) container. By the way, this example also uses a `Cat` interface, which probably looks something like this:

interfaces/cat.interface.ts

JS TS

```typescript

export interface Cat {
  name: string;
  age: number;
  breed: string;
}
```

Now that we have a service class to retrieve cats, let's use it inside the `CatsController`:

cats.controller.ts

JS TS

```typescript

import { Controller, Get, Post, Body } from '@nestjs/common';
import { CreateCatDto } from './dto/create-cat.dto';
import { CatsService } from './cats.service';
import { Cat } from './interfaces/cat.interface';

@Controller('cats')
export class CatsController {
  constructor(private catsService: CatsService) {}

  @Post()
  async create(@Body() createCatDto: CreateCatDto) {
    this.catsService.create(createCatDto);
  }

  @Get()
  async findAll(): Promise<Cat[]> {
    return this.catsService.findAll();
  }
}
```

```typescript

import { Controller, Get, Post, Body, Bind, Dependencies } from '@nestjs/common';
import { CatsService } from './cats.service';

@Controller('cats')
@Dependencies(CatsService)
export class CatsController {
  constructor(catsService) {
    this.catsService = catsService;
  }

  @Post()
  @Bind(Body())
  async create(createCatDto) {
    this.catsService.create(createCatDto);
  }

  @Get()
  async findAll() {
    return this.catsService.findAll();
  }
}
```

The `CatsService` is **injected** through the class constructor. Notice the use of the `private` syntax. This shorthand allows us to both declare and initialize the `catsService` member immediately in the same location.

#### Dependency injection[#](/providers#dependency-injection)

Nest is built around the strong design pattern commonly known as **Dependency injection**. We recommend reading a great article about this concept in the official [Angular](https://angular.io/guide/dependency-injection) documentation.

In Nest, thanks to TypeScript capabilities, it's extremely easy to manage dependencies because they are resolved just by type. In the example below, Nest will resolve the `catsService` by creating and returning an instance of `CatsService` (or, in the normal case of a singleton, returning the existing instance if it has already been requested elsewhere). This dependency is resolved and passed to your controller's constructor (or assigned to the indicated property):

```typescript

constructor(private catsService: CatsService) {}
```

#### Scopes[#](/providers#scopes)

Providers normally have a lifetime ("scope") synchronized with the application lifecycle. When the application is bootstrapped, every dependency must be resolved, and therefore every provider has to be instantiated. Similarly, when the application shuts down, each provider will be destroyed. However, there are ways to make your provider lifetime **request-scoped** as well. You can read more about these techniques [here](/v8/fundamentals/injection-scopes).

Nest has a built-in inversion of control ("IoC") container that resolves relationships between providers. This feature underlies the dependency injection feature described above, but is in fact far more powerful than what we've described so far. There are several ways to define a provider: you can use plain values, classes, and either asynchronous or synchronous factories. More examples are provided [here](/v8/fundamentals/dependency-injection).

#### Optional providers[#](/providers#optional-providers)

Occasionally, you might have dependencies which do not necessarily have to be resolved. For instance, your class may depend on a **configuration object**, but if none is passed, the default values should be used. In such a case, the dependency becomes optional, because lack of the configuration provider wouldn't lead to errors.

To indicate a provider is optional, use the `@Optional()` decorator in the constructor's signature.

```typescript

import { Injectable, Optional, Inject } from '@nestjs/common';

@Injectable()
export class HttpService<T> {
  constructor(@Optional() @Inject('HTTP_OPTIONS') private httpClient: T) {}
}
```

Note that in the example above we are using a custom provider, which is the reason we include the `HTTP_OPTIONS` custom **token**. Previous examples showed constructor-based injection indicating a dependency through a class in the constructor. Read more about custom providers and their associated tokens [here](/v8/fundamentals/custom-providers).

#### Property-based injection[#](/providers#property-based-injection)

The technique we've used so far is called constructor-based injection, as providers are injected via the constructor method. In some very specific cases, **property-based injection** might be useful. For instance, if your top-level class depends on either one or multiple providers, passing them all the way up by calling `super()` in sub-classes from the constructor can be very tedious. In order to avoid this, you can use the `@Inject()` decorator at the property level.

```typescript

import { Injectable, Inject } from '@nestjs/common';

@Injectable()
export class HttpService<T> {
  @Inject('HTTP_OPTIONS')
  private readonly httpClient: T;
}
```

> **Warning** If your class doesn't extend another provider, you should always prefer using **constructor-based** injection.

#### Provider registration[#](/providers#provider-registration)

Now that we have defined a provider (`CatsService`), and we have a consumer of that service (`CatsController`), we need to register the service with Nest so that it can perform the injection. We do this by editing our module file (`app.module.ts`) and adding the service to the `providers` array of the `@Module()` decorator.

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { CatsController } from './cats/cats.controller';
import { CatsService } from './cats/cats.service';

@Module({
  controllers: [CatsController],
  providers: [CatsService],
})
export class AppModule {}
```

----
url: https://docs.nestjs.com/observability/mcp-server
----

[Skip to content](#content)

On this page

* [MCP server](https://docs.nestjs.com/observability/mcp-server#mcp-server)
* [Getting a token](https://docs.nestjs.com/observability/mcp-server#getting-a-token)
* [Connecting a client](https://docs.nestjs.com/observability/mcp-server#connecting-a-client)
* [An example investigation](https://docs.nestjs.com/observability/mcp-server#an-example-investigation)
* [Available tools](https://docs.nestjs.com/observability/mcp-server#available-tools)
* [Setting up a service](https://docs.nestjs.com/observability/mcp-server#setting-up-a-service)

### MCP server

NestJS Observe exposes an [MCP](https://modelcontextprotocol.io/) server, so an MCP-compatible client (Claude Code, Claude Desktop, Cursor, VS Code, or an agent you wrote yourself) can query your projects directly instead of you copying dashboard data into a prompt. Regressions, slow operations, error groups, traces, jobs, and alerts are available: the same data the dashboard shows, scoped to exactly what you can see.

The MCP server is included in every paid plan (Pro and above). It follows the plan that pays for each project: a member on a Free account who is invited into a paid team's projects can use it on those projects.

> **Hint** MCP is one of two ways to get telemetry to an agent. The **Copy agent prompt** button (see [Dashboard](/observability/dashboard#handing-a-failure-to-a-coding-agent)) packages one page as text for a single paste. MCP is for an agent that needs to keep asking questions (follow a trace, check whether the error is still firing) without you relaying each answer.

The endpoint speaks Streamable HTTP at `POST https://<api-host>/mcp`. It's stateless: there's no session to open, nothing to keep alive, and no setup beyond the request itself. The exact host is shown next to your tokens in the dashboard.

#### Getting a token[#](/observability/mcp-server#getting-a-token)

Personal MCP tokens are minted in the dashboard under **MCP tokens**.

* Click **Create token**, give it a name, and optionally set an expiry. A token with no expiry never expires, because MCP clients have no refresh flow.
* The secret (`omcp_...`) is shown **once**, in the response to creating it. Copy it immediately; only its hash is stored, so it cannot be retrieved again. If you lose it, revoke the token and mint another.
* Tokens act **as the user who created them**, with their exact project permissions. There is nothing to scope: if you can see it in the dashboard, the token can read it over MCP, and if you can't, neither can the token.

Revoking a token from the same page cuts it off immediately. Token management itself is deliberately dashboard-only: an MCP token cannot mint or revoke MCP tokens, so a leaked credential can't extend its own life.

#### Connecting a client[#](/observability/mcp-server#connecting-a-client)

Any client that speaks Streamable HTTP can connect with one URL and one header, and no OAuth flow. Clients differ only in where the config file lives and what its keys are called.

**Claude Code**

```bash

$ claude mcp add observe --transport http https://<api-host>/mcp --header "Authorization: Bearer <token>"
```

**Claude Desktop, and other `mcpServers` clients**

```json

{
  "mcpServers": {
    "observe": {
      "url": "https://<api-host>/mcp",
      "headers": { "Authorization": "Bearer <token>" }
    }
  }
}
```

**Cursor** uses the same `mcpServers` shape in `~/.cursor/mcp.json` (every project) or `.cursor/mcp.json` (one project), and expands `${env:...}` inside `url` and `headers`, which is how you keep the token out of a file you might commit:

```json

{
  "mcpServers": {
    "observe": {
      "url": "https://<api-host>/mcp",
      "headers": { "Authorization": "Bearer ${env:OBSERVE_MCP_TOKEN}" }
    }
  }
}
```

**VS Code (Copilot agent mode)** uses `servers` rather than `mcpServers`, wants an explicit `type`, and can prompt for the token once and store it encrypted. In `.vscode/mcp.json` for one workspace, or your user `mcp.json` for all of them:

```json

{
  "inputs": [
    {
      "type": "promptString",
      "id": "observe-token",
      "description": "NestJS Observe MCP token",
      "password": true
    }
  ],
  "servers": {
    "observe": {
      "type": "http",
      "url": "https://<api-host>/mcp",
      "headers": { "Authorization": "Bearer ${input:observe-token}" }
    }
  }
}
```

**Your own agent.** With the official TypeScript SDK, the endpoint is a `StreamableHTTPClientTransport` and the token goes in `requestInit.headers`:

```typescript

const client = new Client({ name: 'my-agent', version: '1.0.0' });

await client.connect(
  new StreamableHTTPClientTransport(new URL('https://<api-host>/mcp'), {
    requestInit: {
      headers: { Authorization: `Bearer ${process.env.OBSERVE_MCP_TOKEN}` },
    },
  }),
);

const { tools } = await client.listTools();
```

Before debugging a client's config, confirm that the endpoint and token work. This command lists the tools the server advertises:

```bash

$ curl -s https://<api-host>/mcp \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
```

If you get a tool list back, the credential is valid and anything still broken is client-side. A **401** means the token is missing, expired, or revoked, or the header is malformed. A **405** means the client sent `GET` or `DELETE`; every MCP request to this endpoint must be a `POST`.

#### An example investigation[#](/observability/mcp-server#an-example-investigation)

The tools are shaped around investigations rather than endpoints, so each answer carries the key the next question needs. Suppose a deploy went out and something seems wrong:

1. **"What regressed after the last deploy?"** - `find_regressions` compares error rate and latency either side of each release boundary (your `serviceVersion` values) and names the release that made things worse, along with the operations it degraded.
2. **"Show me that operation."** - `get_operation_details` returns the route's latency and error summary plus recent individual requests, each with a `traceId`.
3. **"What did that request actually do?"** - `get_trace` resolves the trace id into the waterfall: every execution under it, across services, with span trees.
4. **"What did the code say while it happened?"** - `get_trace_logs` returns every log line emitted under the same trace id, in order.

Errors and background jobs follow the same shape: `list_error_groups` → `get_error_details` → `get_trace`, and `list_jobs` → `get_job_details` → `get_trace`. In every case, start with `list_projects`, since almost every diagnostic tool takes a `projectId`.

#### Available tools[#](/observability/mcp-server#available-tools)

Almost every tool is read-only; the ones that write are listed under [Setting up a service](/observability/mcp-server#setting-up-a-service). Most diagnostic tools share a scope: a required `projectId`, an optional `applicationId` to narrow to one service, and an optional `timeInterval` look-back window (`1h`, `3h`, `12h`, `1d`, `3d`, `7d`, `30d`), defaulting to `1d`.

| Tool                                    | What it answers                                                                                                                                      |
| --------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| `list_projects`                         | Every project you're a member of, with team and application counts. Start here to resolve project ids.                                               |
| `get_project`                           | One project by id, including your access level and subscription state.                                                                               |
| `search`                                | Full-text search over your projects, applications, alert rules, SLOs, and issues.                                                                    |
| `find_regressions`                      | Releases that made things worse: error rate and latency before vs. after each release boundary, with the specific operations each one degraded.      |
| `list_slow_operations`                  | The slowest HTTP operations in the window, ranked by p95, with volume alongside, so effort goes to what's slow *and* hot.                            |
| `get_operation_details`                 | One route: latency and error summary plus recent individual requests, each with duration, status, and `traceId`.                                     |
| `get_trace`                             | A `traceId` resolved to every execution that ran under it - across services, requests, and jobs - each with its span tree.                           |
| `get_trace_logs`                        | Every log line emitted under a `traceId`, in order.                                                                                                  |
| `list_error_groups`                     | Errors grouped by fingerprint, ranked by occurrence count, with class, sample message and stack trace, first/last seen, and the introducing release. |
| `get_error_details`                     | Recent occurrences of one error class: per-occurrence message, status, user, and `traceId`, plus a summary.                                          |
| `get_error_trend`                       | Whether errors are growing or decaying over the window, already classified as a direction.                                                           |
| `get_affected_users`                    | The blast radius of one error class: which end users hit it and how often.                                                                           |
| `list_jobs`                             | Background job performance in the window, per job name and queue: volume, duration, and failure counts.                                              |
| `get_job_details`                       | One job name on one queue: duration and wait-time summaries plus recent individual executions, each with status and `traceId`.                       |
| `list_issues`, `get_issue`              | Issues across your projects, and one issue with its comments and activity.                                                                           |
| `list_slos`                             | A project's SLOs with current status and error-budget burn.                                                                                          |
| `list_alert_rules`, `list_alert_events` | Alert rules across every project you can see, and their firing history.                                                                              |

Apart from setting up a service and resolving an issue, nothing can be created or changed through MCP, including alert rules and error-group status. Those stay in the dashboard. Tool results also omit the time-bucketed chart series the dashboard endpoints return, because hundreds of bucket values cost context and say less than the summary derived from them.

#### Setting up a service[#](/observability/mcp-server#setting-up-a-service)

These are the tools that write. Each goes through the same service as the matching dashboard button, so your role on the project and your plan's limits apply exactly as they do there, and a refusal comes back as the tool's answer. Nothing can be deleted, renamed, or revoked over MCP.

| Tool                 | What it does                                                                                                                                                              |
| -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `list_applications`  | The applications of one project. Check it before creating a duplicate.                                                                                                    |
| `create_project`     | Creates a project, in an existing team (pass its id) or a new one named after the project.                                                                                |
| `create_application` | Registers one NestJS service in a project. The name can't be changed over MCP and should match the `serviceId` you give the SDK.                                          |
| `create_api_key`     | Issues the key pair the SDK authenticates with. The secret is returned once; a well-behaved client writes it to your git-ignored environment file and does not repeat it. |
| `resolve_issue`      | Marks an issue resolved after a fix ships, which starts verification against the pre-incident baseline.                                                                   |

With these tools, an agent can take a repository from "not instrumented" to "reporting" in one request: *"Set up NestJS Observe for this service"* becomes `list_projects` → `create_application` → `create_api_key`, followed by the install and the three code edits from the [SDK guide](/observability/sdk).

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/observability/mcp-server.md)

----
url: https://docs.nestjs.com/v6/microservices/kafka
----

* [Kafka](https://docs.nestjs.com/v6/microservices/kafka#kafka)
* [Installation](https://docs.nestjs.com/v6/microservices/kafka#installation)
* [Overview](https://docs.nestjs.com/v6/microservices/kafka#overview)
* [Options](https://docs.nestjs.com/v6/microservices/kafka#options)
* [Client](https://docs.nestjs.com/v6/microservices/kafka#client)
* [Message response subscription](https://docs.nestjs.com/v6/microservices/kafka#message-response-subscription)
* [Message pattern](https://docs.nestjs.com/v6/microservices/kafka#message-pattern)
* [Incoming](https://docs.nestjs.com/v6/microservices/kafka#incoming)
* [Outgoing](https://docs.nestjs.com/v6/microservices/kafka#outgoing)
* [Context](https://docs.nestjs.com/v6/microservices/kafka#context)
* [Naming conventions](https://docs.nestjs.com/v6/microservices/kafka#naming-conventions)

```bash

$ npm i --save kafkajs
```

#### Overview[#](/microservices/kafka#overview)

Like other Nest microservices transport layer implementations, you select the Kafka transporter mechanism using the `transport` property of the options object passed to the `createMicroservice()` method, along with an optional `options` property, as shown below:

main.ts

JS TS

```typescript

const app = await NestFactory.createMicroservice(ApplicationModule, {
  transport: Transport.KAFKA,
  options: {
    client: {
      brokers: ['localhost:9092'],
    }
  }
});
```

> **Hint** The `Transport` enum is imported from the `@nestjs/microservices` package.

#### Options[#](/microservices/kafka#options)

The `options` property is specific to the chosen transporter. The **Kafka** transporter exposes the properties described below.

|             |                                                                                                                 |
| ----------- | --------------------------------------------------------------------------------------------------------------- |
| `client`    | Client configuration options (read more [here](https://kafka.js.org/docs/configuration))                        |
| `consumer`  | Consumer configuration options (read more [here](https://kafka.js.org/docs/consuming#a-name-options-a-options)) |
| `run`       | Run configuration options (read more [here](https://kafka.js.org/docs/consuming))                               |
| `subscribe` | Subscribe configuration options (read more [here](https://kafka.js.org/docs/consuming#frombeginning))           |
| `producer`  | Producer configuration options (read more [here](https://kafka.js.org/docs/producing#options))                  |
| `send`      | Send configuration options (read more [here](https://kafka.js.org/docs/producing#options))                      |

#### Client[#](/microservices/kafka#client)

There is a small difference in Kafka compared to other microservice transporters. Instead of the `ClientProxy` class, we use the `ClientKafka` class.

Like other microservice transporters, you have [several options](https://docs.nestjs.com/microservices/basics#client) for creating a `ClientKafka` instance.

One method for creating an instance is to use use the `ClientsModule`. To create a client instance with the `ClientsModule`, import it and use the `register()` method to pass an options object with the same properties shown above in the `createMicroservice()` method, as well as a `name` property to be used as the injection token. Read more about `ClientsModule`[here](https://docs.nestjs.com/microservices/basics#client).

```typescript

@Module({
  imports: [
    ClientsModule.register([
      {
        name: 'HERO_SERVICE',
        transport: Transport.KAFKA,
        options: {
          client: {
            clientId: 'hero',
            brokers: ['localhost:9092'],
          },
          consumer: {
            groupId: 'hero-consumer'
          }
        }
      },
    ]),
  ]
  ...
})
```

Other options to create a client (either `ClientProxyFactory` or `@Client()`) can be used as well. You can read about them [here](https://docs.nestjs.com/microservices/basics#client).

Use the `@Client()` decorator as follows:

```typescript

@Client({
  transport: Transport.KAFKA,
  options: {
    client: {
      clientId: 'hero',
      brokers: ['localhost:9092'],
    },
    consumer: {
      groupId: 'hero-consumer'
    }
  }
})
client: ClientKafka;
```

#### Message response subscription[#](/microservices/kafka#message-response-subscription)

The `ClientKafka` class provides the `subscribeToResponseOf()` method. The `subscribeToResponseOf()` method takes a request's topic name as an argument and adds the derived reply topic name to a collection of reply topics. This method is required when implementing the message pattern.

hero.controller.ts

JS TS

```typescript

onModuleInit() {
  this.client.subscribeToResponseOf('hero.kill.dragon');
}
```

If the `ClientKafka` instance is created asynchronously, the `subscribeToResponseOf()` method must be called before calling the `connect()` method.

hero.controller.ts

JS TS

```typescript

async onModuleInit() {
  this.client.subscribeToResponseOf('hero.kill.dragon');
  await this.client.connect();
}
```

hero.controller.ts

JS TS

```typescript

@Controller()
export class HeroController {
  @MessagePattern('hero.kill.dragon')
  killDragon(@Payload() message: KillDragonMessage): any {
    const dragonId = message.dragonId;
    const items = [
      { id: 1, name: 'Mythical Sword' },
      { id: 2, name: 'Key to Dungeon' },
    ];
    return items;
  }
}
```

> **Hint**`@Payload()` is imported from the `@nestjs/microservices`.

Outgoing messages can also be keyed by passing an object with the `key` and `value` properties. Keying messages is important for meeting the [co-partitioning requirement](https://docs.confluent.io/current/ksql/docs/developer-guide/partition-data.html#co-partitioning-requirements).

hero.controller.ts

JS TS

```typescript

@Controller()
export class HeroController {
  @MessagePattern('hero.kill.dragon')
  killDragon(@Payload() message: KillDragonMessage): any {
    const realm = 'Nest';
    const heroId = message.heroId;
    const dragonId = message.dragonId;

    const items = [
      { id: 1, name: 'Mythical Sword' },
      { id: 2, name: 'Key to Dungeon' },
    ];

    return {
      headers: {
        realm
      },
      key: heroId,
      value: items
    }
  }
}
```

Additionally, messages passed in this format can also contain custom headers set in the `headers` hash property. Header hash property values must be either of type `string` or type `Buffer`.

hero.controller.ts

JS TS

```typescript

@Controller()
export class HeroController {
  @MessagePattern('hero.kill.dragon')
  killDragon(@Payload() message: KillDragonMessage): any {
    const realm = 'Nest';
    const heroId = message.heroId;
    const dragonId = message.dragonId;

    const items = [
      { id: 1, name: 'Mythical Sword' },
      { id: 2, name: 'Key to Dungeon' },
    ];

    return {
      headers: {
        kafka_nestRealm: realm
      },
      key: heroId,
      value: items
    }
  }
}
```

#### Context[#](/microservices/kafka#context)

In more sophisticated scenarios, you may want to access more information about the incoming request. When using the Kafka transporter, you can access the `KafkaContext` object.

JS TS

```typescript

@MessagePattern('hero.kill.dragon')
killDragon(@Payload() message: KillDragonMessage, @Ctx() context: KafkaContext) {
  console.log(`Topic: ${context.getTopic()}`);
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('hero.kill.dragon')
killDragon(message, context) {
  console.log(`Topic: ${context.getTopic()}`);
}
```

> **Hint**`@Payload()`, `@Ctx()` and `KafkaContext` are imported from the `@nestjs/microservices` package.

To access the original Kafka `IncomingMessage` object, use the `getMessage()` method of the `KafkaContext` object, as follows:

JS TS

```typescript

@MessagePattern('hero.kill.dragon')
killDragon(@Payload() message: KillDragonMessage, @Ctx() context: KafkaContext) {
  const originalMessage = context.getMessage();
  const { headers, partition, timestamp } = originalMessage;
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('hero.kill.dragon')
killDragon(message, context) {
  const originalMessage = context.getMessage();
  const { headers, partition, timestamp } = originalMessage;
}
```

Where the `IncomingMessage` fulfills the following interface:

```typescript

interface IncomingMessage {
  topic: string;
  partition: number;
  timestamp: string;
  size: number;
  attributes: number;
  offset: string;
  key: any;
  value: any;
  headers: Record<string, any>;
}
```

#### Naming conventions[#](/microservices/kafka#naming-conventions)

The Kafka microservice components append a description of their respective role onto the `client.clientId` and `consumer.groupId` options to prevent collisions between Nest microservice client and server components. By default the `ClientKafka` components append `-client` and the `ServerKafka` components append `-server` to both of these options. Note how the provided values below are transformed in that way (as shown in the comments).

main.ts

JS TS

```typescript

const app = await NestFactory.createMicroservice(ApplicationModule, {
  transport: Transport.KAFKA,
  options: {
    client: {
      clientId: 'hero', // hero-server
      brokers: ['localhost:9092'],
    },
    consumer: {
      groupId: 'hero-consumer' // hero-consumer-server
    },
  }
});
```

And for the client:

hero.controller.ts

JS TS

```typescript

@Client({
  transport: Transport.KAFKA,
  options: {
    client: {
      clientId: 'hero', // hero-client
      brokers: ['localhost:9092'],
    },
    consumer: {
      groupId: 'hero-consumer' // hero-consumer-client
    }
  }
})
client: ClientKafka;
```

> **Hint** Kafka client and consumer naming conventions can be customized by extending `ClientKafka` and `KafkaServer` in your own custom provider and overriding the constructor.

Since the Kafka microservice message pattern utilizes two topics for the request and reply channels, a reply pattern should be derived from the request topic. By default, the name of the reply topic is the composite of the request topic name with `.reply` appended.

hero.controller.ts

JS TS

```typescript

onModuleInit() {
  this.client.subscribeToResponseOf('hero.get'); // hero.get.reply
}
```

> **Hint** Kafka reply topic naming conventions can be customized by extending `ClientKafka` in your own custom provider and overriding the `getResponsePatternName` method.

----
url: https://docs.nestjs.com/v4/fundamentals/circular-dependency
----

### Circular Dependency

The circular dependency means that class A needs class B, and class B needs class A. Nest permits to create **circular dependencies** between both components and modules, but we advise you not to use it too much. Sometimes it's really difficult to avoid these types of the relationships, that's why we provided some ways to deal with this issue.

#### Forward reference

The **forward reference** allows Nest refer to references which are not yet defined. When `CatsService` and `CommonService` depend on each other, both sides of the relationship need to use `@Inject()` and the `forwardRef()` utility, otherwise Nest won't create your components instances because all of the essential metadata would be not available. Let's see the following snippet:

cats.service.ts

JavaScript TypeScript

TypeScript

```typescript

@Component()
export class CatsService {
  constructor(
    @Inject(forwardRef(() => CommonService))
    private readonly commonService: CommonService,
  ) {}
}
```

TypeScript

```typescript

@Component()
@Dependencies(forwardRef(() => CommonService))
export class CatsService {
  constructor(commonService) {
    this.commonService = commonService;
  }
}
```

> **Notice** The `forwardRef()` function is imported from the `@nestjs/common` package.

Here's the first side of the relationship. Now let's do the same with the `CommonService`:

common.service.ts

JavaScript TypeScript

TypeScript

```typescript

@Component()
export class CommonService {
  constructor(
    @Inject(forwardRef(() => CatsService))
    private readonly catsService: CatsService,
  ) {}
}
```

TypeScript

```typescript

@Component()
@Dependencies(forwardRef(() => CatsService))
export class CommonService {
  constructor(catsService) {
    this.catsService = catsService;
  }
}
```

> **Hint** You never know which constructor will be called first.

To create circular dependencies between modules you have to use the same `forwardRef()` utility on the both parts of the modules association:

common.module.ts

JavaScript TypeScript

TypeScript

```typescript

@Module({
  imports: [forwardRef(() => CatsModule)],
})
export class CommonModule {}
```

#### Module reference

Nest provides the `ModuleRef` class, which might be simply injected into each component.

cats.service.ts

JavaScript TypeScript

TypeScript

```typescript

@Component()
export class CatsService implements OnModuleInit {
  private service: Service;
  constructor(private readonly moduleRef: ModuleRef) {}

  onModuleInit() {
    this.service = this.moduleRef.get<Service>(Service);
  }
}
```

TypeScript

```typescript

@Component()
@Dependencies(ModuleRef)
export class CatsService {
  constructor(moduleRef) {
    this.moduleRef = moduleRef;
  }

  onModuleInit() {
    this.service = this.moduleRef.get(Service);
  }
}
```

> **Notice** The `ModuleRef` class is imported from the `@nestjs/core` package.

The module reference has a `get()` method, which allows to retrieve any component available in the current module.

#### Sponsors

[](https://valor-software.com/)

Nest is an MIT-licensed open source project. It can grow thanks to the support by these awesome people. If you'd like to join them, please read more [here](https://opencollective.com/nest). Thanks!

[](https://opencollective.com/nest/backer/0/website)[](https://opencollective.com/nest/backer/1/website)[](https://opencollective.com/nest/backer/2/website)[](https://opencollective.com/nest/backer/3/website)[](https://opencollective.com/nest/backer/4/website)[](https://opencollective.com/nest/backer/5/website)[](https://opencollective.com/nest/backer/6/website)[](https://opencollective.com/nest/backer/7/website)[](https://opencollective.com/nest/backer/8/website)[](https://opencollective.com/nest/backer/9/website)[](https://opencollective.com/nest/backer/10/website)[](https://opencollective.com/nest/backer/11/website)[](https://opencollective.com/nest/backer/12/website)[](https://opencollective.com/nest/backer/13/website)[](https://opencollective.com/nest/backer/14/website)[](https://opencollective.com/nest/backer/15/website)[](https://opencollective.com/nest/backer/16/website)[](https://opencollective.com/nest/backer/17/website)[](https://opencollective.com/nest/backer/18/website)[](https://opencollective.com/nest/backer/19/website)[](https://opencollective.com/nest/backer/20/website)[](https://opencollective.com/nest/backer/21/website)[](https://opencollective.com/nest/backer/22/website)[](https://opencollective.com/nest/backer/23/website)[](https://opencollective.com/nest/backer/24/website)[](https://opencollective.com/nest/backer/25/website)[](https://opencollective.com/nest/backer/26/website)[](https://opencollective.com/nest/backer/27/website)[](https://opencollective.com/nest/backer/28/website)[](https://opencollective.com/nest/backer/29/website)

[Become a sponsor](https://opencollective.com/nest)

----
url: https://docs.nestjs.com/v10/controllers
----

* [Controllers](https://docs.nestjs.com/v10/controllers#controllers)
* [Routing](https://docs.nestjs.com/v10/controllers#routing)
* [Request object](https://docs.nestjs.com/v10/controllers#request-object)
* [Resources](https://docs.nestjs.com/v10/controllers#resources)
* [Route wildcards](https://docs.nestjs.com/v10/controllers#route-wildcards)
* [Status code](https://docs.nestjs.com/v10/controllers#status-code)
* [Headers](https://docs.nestjs.com/v10/controllers#headers)
* [Redirection](https://docs.nestjs.com/v10/controllers#redirection)
* [Route parameters](https://docs.nestjs.com/v10/controllers#route-parameters)
* [Sub-Domain Routing](https://docs.nestjs.com/v10/controllers#sub-domain-routing)
* [Scopes](https://docs.nestjs.com/v10/controllers#scopes)
* [Asynchronicity](https://docs.nestjs.com/v10/controllers#asynchronicity)
* [Request payloads](https://docs.nestjs.com/v10/controllers#request-payloads)
* [Handling errors](https://docs.nestjs.com/v10/controllers#handling-errors)
* [Full resource sample](https://docs.nestjs.com/v10/controllers#full-resource-sample)
* [Getting up and running](https://docs.nestjs.com/v10/controllers#getting-up-and-running)
* [Library-specific approach](https://docs.nestjs.com/v10/controllers#library-specific-approach)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/controllers.md "Suggest Edits")

### Controllers

Controllers are responsible for handling incoming **requests** and returning **responses** to the client.

A controller's purpose is to receive specific requests for the application. The **routing** mechanism controls which controller receives which requests. Frequently, each controller has more than one route, and different routes can perform different actions.

In order to create a basic controller, we use classes and **decorators**. Decorators associate classes with required metadata and enable Nest to create a routing map (tie requests to the corresponding controllers).

> **Hint** For quickly creating a CRUD controller with the [validation](https://docs.nestjs.com/techniques/validation) built-in, you may use the CLI's [CRUD generator](https://docs.nestjs.com/recipes/crud-generator#crud-generator): `nest g resource [name]`.

#### Routing[#](/controllers#routing)

In the following example we'll use the `@Controller()` decorator, which is **required** to define a basic controller. We'll specify an optional route path prefix of `cats`. Using a path prefix in a `@Controller()` decorator allows us to easily group a set of related routes, and minimize repetitive code. For example, we may choose to group a set of routes that manage interactions with a cat entity under the route `/cats`. In that case, we could specify the path prefix `cats` in the `@Controller()` decorator so that we don't have to repeat that portion of the path for each route in the file.

cats.controller.ts

JS TS

```typescript

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

@Controller('cats')
export class CatsController {
  @Get()
  findAll(): string {
    return 'This action returns all cats';
  }
}
```

```typescript

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

@Controller('cats')
export class CatsController {
  @Get()
  findAll() {
    return 'This action returns all cats';
  }
}
```

> **Hint** To create a controller using the CLI, simply execute the `$ nest g controller [name]` command.

The `@Get()` HTTP request method decorator before the `findAll()` method tells Nest to create a handler for a specific endpoint for HTTP requests. The endpoint corresponds to the HTTP request method (GET in this case) and the route path. What is the route path? The route path for a handler is determined by concatenating the (optional) prefix declared for the controller, and any path specified in the method's decorator. Since we've declared a prefix for every route ( `cats`), and haven't added any path information in the decorator, Nest will map `GET /cats` requests to this handler. As mentioned, the path includes both the optional controller path prefix **and** any path string declared in the request method decorator. For example, a path prefix of `cats` combined with the decorator `@Get('breed')` would produce a route mapping for requests like `GET /cats/breed`.

In our example above, when a GET request is made to this endpoint, Nest routes the request to our user-defined `findAll()` method. Note that the method name we choose here is completely arbitrary. We obviously must declare a method to bind the route to, but Nest doesn't attach any significance to the method name chosen.

This method will return a 200 status code and the associated response, which in this case is just a string. Why does that happen? To explain, we'll first introduce the concept that Nest employs two **different** options for manipulating responses:

|                        |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Standard (recommended) | Using this built-in method, when a request handler returns a JavaScript object or array, it will **automatically** be serialized to JSON. When it returns a JavaScript primitive type (e.g., `string`, `number`, `boolean`), however, Nest will send just the value without attempting to serialize it. This makes response handling simple: just return the value, and Nest takes care of the rest. Furthermore, the response's **status code** is always 200 by default, except for POST requests which use 201. We can easily change this behavior by adding the `@HttpCode(...)` decorator at a handler-level (see [Status codes](controllers#status-code)). |
| Library-specific       | We can use the library-specific (e.g., Express) [response object](https://expressjs.com/en/api.html#res), which can be injected using the `@Res()` decorator in the method handler signature (e.g., `findAll(@Res() response)`). With this approach, you have the ability to use the native response handling methods exposed by that object. For example, with Express, you can construct responses using code like `response.status(200).send()`.                                                                                                                                                                                                              |

> **Warning** Nest detects when the handler is using either `@Res()` or `@Next()`, indicating you have chosen the library-specific option. If both approaches are used at the same time, the Standard approach is **automatically disabled** for this single route and will no longer work as expected. To use both approaches at the same time (for example, by injecting the response object to only set cookies/headers but still leave the rest to the framework), you must set the `passthrough` option to `true` in the `@Res({ passthrough: true })` decorator.

```typescript

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

@Controller('cats')
export class CatsController {
  @Get()
  findAll(@Req() request: Request): string {
    return 'This action returns all cats';
  }
}
```

```typescript

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

@Controller('cats')
export class CatsController {
  @Get()
  @Bind(Req())
  findAll(request) {
    return 'This action returns all cats';
  }
}
```

> **Hint** In order to take advantage of `express` typings (as in the `request: Request` parameter example above), install `@types/express` package.

The request object represents the HTTP request and has properties for the request query string, parameters, HTTP headers, and body (read more [here](https://expressjs.com/en/api.html#req)). In most cases, it's not necessary to grab these properties manually. We can use dedicated decorators instead, such as `@Body()` or `@Query()`, which are available out of the box. Below is a list of the provided decorators and the plain platform-specific objects they represent.

|                           |                                     |
| ------------------------- | ----------------------------------- |
| `@Request(), @Req()`      | `req`                               |
| `@Response(), @Res()`\*   | `res`                               |
| `@Next()`                 | `next`                              |
| `@Session()`              | `req.session`                       |
| `@Param(key?: string)`    | `req.params` / `req.params[key]`    |
| `@Body(key?: string)`     | `req.body` / `req.body[key]`        |
| `@Query(key?: string)`    | `req.query` / `req.query[key]`      |
| `@Headers(name?: string)` | `req.headers` / `req.headers[name]` |
| `@Ip()`                   | `req.ip`                            |
| `@HostParam()`            | `req.hosts`                         |

\* For compatibility with typings across underlying HTTP platforms (e.g., Express and Fastify), Nest provides `@Res()` and `@Response()` decorators. `@Res()` is simply an alias for `@Response()`. Both directly expose the underlying native platform `response` object interface. When using them, you should also import the typings for the underlying library (e.g., `@types/express`) to take full advantage. Note that when you inject either `@Res()` or `@Response()` in a method handler, you put Nest into **Library-specific mode** for that handler, and you become responsible for managing the response. When doing so, you must issue some kind of response by making a call on the `response` object (e.g., `res.json(...)` or `res.send(...)`), or the HTTP server will hang.

> **Hint** To learn how to create your own custom decorators, visit [this](/v10/custom-decorators) chapter.

#### Resources[#](/controllers#resources)

Earlier, we defined an endpoint to fetch the cats resource (**GET** route). We'll typically also want to provide an endpoint that creates new records. For this, let's create the **POST** handler:

cats.controller.ts

JS TS

```typescript

import { Controller, Get, Post } from '@nestjs/common';

@Controller('cats')
export class CatsController {
  @Post()
  create(): string {
    return 'This action adds a new cat';
  }

  @Get()
  findAll(): string {
    return 'This action returns all cats';
  }
}
```

```typescript

import { Controller, Get, Post } from '@nestjs/common';

@Controller('cats')
export class CatsController {
  @Post()
  create() {
    return 'This action adds a new cat';
  }

  @Get()
  findAll() {
    return 'This action returns all cats';
  }
}
```

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.

#### Route wildcards[#](/controllers#route-wildcards)

Pattern based routes are supported as well. For instance, the asterisk is used as a wildcard, and will match any combination of characters.

```typescript

@Get('ab*cd')
findAll() {
  return 'This route uses a wildcard';
}
```

The `'ab*cd'` route path will match `abcd`, `ab_cd`, `abecd`, and so on. The characters `?`, `+`, `*`, and `()` may be used in a route path, and are subsets of their regular expression counterparts. The hyphen ( `-`) and the dot (`.`) are interpreted literally by string-based paths.

> **Warning** A wildcard in the middle of the route is only supported by express.

#### Status code[#](/controllers#status-code)

As mentioned, the response **status code** is always **200** by default, except for POST requests which are **201**. We can easily change this behavior by adding the `@HttpCode(...)` decorator at a handler level.

```typescript

@Post()
@HttpCode(204)
create() {
  return 'This action adds a new cat';
}
```

> **Hint** Import `HttpCode` from the `@nestjs/common` package.

Often, your status code isn't static but depends on various factors. In that case, you can use a library-specific **response** (inject using `@Res()`) object (or, in case of an error, throw an exception).

#### Headers[#](/controllers#headers)

To specify a custom response header, you can either use a `@Header()` decorator or a library-specific response object (and call `res.header()` directly).

```typescript

@Post()
@Header('Cache-Control', 'no-store')
create() {
  return 'This action adds a new cat';
}
```

> **Hint** Import `Header` from the `@nestjs/common` package.

#### Redirection[#](/controllers#redirection)

To redirect a response to a specific URL, you can either use a `@Redirect()` decorator or a library-specific response object (and call `res.redirect()` directly).

`@Redirect()` takes two arguments, `url` and `statusCode`, both are optional. The default value of `statusCode` is `302` (`Found`) if omitted.

```typescript

@Get()
@Redirect('https://nestjs.com', 301)
```

> **Hint** Sometimes you may want to determine the HTTP status code or the redirect URL dynamically. Do this by returning an object following the `HttpRedirectResponse` interface (from `@nestjs/common`).

Returned values will override any arguments passed to the `@Redirect()` decorator. For example:

```typescript

@Get('docs')
@Redirect('https://docs.nestjs.com', 302)
getDocs(@Query('version') version) {
  if (version && version === '5') {
    return { url: 'https://docs.nestjs.com/v5/' };
  }
}
```

#### Route parameters[#](/controllers#route-parameters)

Routes with static paths won't work when you need to accept **dynamic data** as part of the request (e.g., `GET /cats/1` to get cat with id `1`). In order to define routes with parameters, we can add route parameter **tokens** in the path of the route to capture the dynamic value at that position in the request URL. The route parameter token in the `@Get()` decorator example below demonstrates this usage. Route parameters declared in this way can be accessed using the `@Param()` decorator, which should be added to the method signature.

> **Hint** Routes with parameters should be declared after any static paths. This prevents the parameterized paths from intercepting traffic destined for the static paths.

JS TS

```typescript

@Get(':id')
findOne(@Param() params: any): string {
  console.log(params.id);
  return `This action returns a #${params.id} cat`;
}
```

```typescript

@Get(':id')
@Bind(Param())
findOne(params) {
  console.log(params.id);
  return `This action returns a #${params.id} cat`;
}
```

`@Param()` is used to decorate a method parameter (`params` in the example above), and makes the **route** parameters available as properties of that decorated method parameter inside the body of the method. As seen in the code above, we can access the `id` parameter by referencing `params.id`. You can also pass in a particular parameter token to the decorator, and then reference the route parameter directly by name in the method body.

> **Hint** Import `Param` from the `@nestjs/common` package.

JS TS

```typescript

@Get(':id')
findOne(@Param('id') id: string): string {
  return `This action returns a #${id} cat`;
}
```

```typescript

@Get(':id')
@Bind(Param('id'))
findOne(id) {
  return `This action returns a #${id} cat`;
}
```

#### Sub-Domain Routing[#](/controllers#sub-domain-routing)

The `@Controller` decorator can take a `host` option to require that the HTTP host of the incoming requests matches some specific value.

```typescript

@Controller({ host: 'admin.example.com' })
export class AdminController {
  @Get()
  index(): string {
    return 'Admin page';
  }
}
```

> **Warning** Since **Fastify** lacks support for nested routers, when using sub-domain routing, the (default) Express adapter should be used instead.

Similar to a route `path`, the `hosts` option can use tokens to capture the dynamic value at that position in the host name. The host parameter token in the `@Controller()` decorator example below demonstrates this usage. Host parameters declared in this way can be accessed using the `@HostParam()` decorator, which should be added to the method signature.

```typescript

@Controller({ host: ':account.example.com' })
export class AccountController {
  @Get()
  getInfo(@HostParam('account') account: string) {
    return account;
  }
}
```

#### Scopes[#](/controllers#scopes)

For people coming from different programming language backgrounds, it might be unexpected to learn that in Nest, almost everything is shared across incoming requests. We have a connection pool to the database, singleton services with global state, etc. Remember that Node.js doesn't follow the request/response Multi-Threaded Stateless Model in which every request is processed by a separate thread. Hence, using singleton instances is fully **safe** for our applications.

However, there are edge-cases when request-based lifetime of the controller may be the desired behavior, for instance per-request caching in GraphQL applications, request tracking or multi-tenancy. Learn how to control scopes [here](/v10/fundamentals/injection-scopes).

#### Asynchronicity[#](/controllers#asynchronicity)

We love modern JavaScript and we know that data extraction is mostly **asynchronous**. That's why Nest supports and works well with `async` functions.

> **Hint** Learn more about `async / await` feature [here](https://kamilmysliwiec.com/typescript-2-1-introduction-async-await)

Every async function has to return a `Promise`. This means that you can return a deferred value that Nest will be able to resolve by itself. Let's see an example of this:

cats.controller.ts

JS TS

```typescript

@Get()
async findAll(): Promise<any[]> {
  return [];
}
```

```typescript

@Get()
async findAll() {
  return [];
}
```

The above code is fully valid. Furthermore, Nest route handlers are even more powerful by being able to return RxJS [observable streams](https://rxjs-dev.firebaseapp.com/guide/observable). Nest will automatically subscribe to the source underneath and take the last emitted value (once the stream is completed).

cats.controller.ts

JS TS

```typescript

@Get()
findAll(): Observable<any[]> {
  return of([]);
}
```

```typescript

@Get()
findAll() {
  return of([]);
}
```

```typescript

export class CreateCatDto {
  name: string;
  age: number;
  breed: string;
}
```

It has only three basic properties. Thereafter we can use the newly created DTO inside the `CatsController`:

cats.controller.ts

JS TS

```typescript

@Post()
async create(@Body() createCatDto: CreateCatDto) {
  return 'This action adds a new cat';
}
```

```typescript

@Post()
@Bind(Body())
async create(createCatDto) {
  return 'This action adds a new cat';
}
```

> **Hint** Our `ValidationPipe` can filter out properties that should not be received by the method handler. In this case, we can whitelist the acceptable properties, and any property not included in the whitelist is automatically stripped from the resulting object. In the `CreateCatDto` example, our whitelist is the `name`, `age`, and `breed` properties. Learn more [here](https://docs.nestjs.com/techniques/validation#stripping-properties).

#### Handling errors[#](/controllers#handling-errors)

There's a separate chapter about handling errors (i.e., working with exceptions) [here](/v10/exception-filters).

#### Full resource sample[#](/controllers#full-resource-sample)

Below is an example that makes use of several of the available decorators to create a basic controller. This controller exposes a couple of methods to access and manipulate internal data.

cats.controller.ts

JS TS

```typescript

import { Controller, Get, Query, Post, Body, Put, Param, Delete } from '@nestjs/common';
import { CreateCatDto, UpdateCatDto, ListAllEntities } from './dto';

@Controller('cats')
export class CatsController {
  @Post()
  create(@Body() createCatDto: CreateCatDto) {
    return 'This action adds a new cat';
  }

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

  @Get(':id')
  findOne(@Param('id') id: string) {
    return `This action returns a #${id} cat`;
  }

  @Put(':id')
  update(@Param('id') id: string, @Body() updateCatDto: UpdateCatDto) {
    return `This action updates a #${id} cat`;
  }

  @Delete(':id')
  remove(@Param('id') id: string) {
    return `This action removes a #${id} cat`;
  }
}
```

```typescript

import { Controller, Get, Query, Post, Body, Put, Param, Delete, Bind } from '@nestjs/common';

@Controller('cats')
export class CatsController {
  @Post()
  @Bind(Body())
  create(createCatDto) {
    return 'This action adds a new cat';
  }

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

  @Get(':id')
  @Bind(Param('id'))
  findOne(id) {
    return `This action returns a #${id} cat`;
  }

  @Put(':id')
  @Bind(Param('id'), Body())
  update(id, updateCatDto) {
    return `This action updates a #${id} cat`;
  }

  @Delete(':id')
  @Bind(Param('id'))
  remove(id) {
    return `This action removes a #${id} cat`;
  }
}
```

> **Hint** Nest CLI provides a generator (schematic) that automatically generates **all the boilerplate code** to help us avoid doing all of this, and make the developer experience much simpler. Read more about this feature [here](/v10/recipes/crud-generator).

#### Getting up and running[#](/controllers#getting-up-and-running)

With the above controller fully defined, Nest still doesn't know that `CatsController` exists and as a result won't create an instance of this class.

Controllers always belong to a module, which is why we include the `controllers` array within the `@Module()` decorator. Since we haven't yet defined any other modules except the root `AppModule`, we'll use that to introduce the `CatsController`:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { CatsController } from './cats/cats.controller';

@Module({
  controllers: [CatsController],
})
export class AppModule {}
```

We attached the metadata to the module class using the `@Module()` decorator, and Nest can now easily reflect which controllers have to be mounted.

#### Library-specific approach[#](/controllers#library-specific-approach)

So far we've discussed the Nest standard way of manipulating responses. The second way of manipulating the response is to use a library-specific [response object](https://expressjs.com/en/api.html#res). In order to inject a particular response object, we need to use the `@Res()` decorator. To show the differences, let's rewrite the `CatsController` to the following:

JS TS

```typescript

import { Controller, Get, Post, Res, HttpStatus } from '@nestjs/common';
import { Response } from 'express';

@Controller('cats')
export class CatsController {
  @Post()
  create(@Res() res: Response) {
    res.status(HttpStatus.CREATED).send();
  }

  @Get()
  findAll(@Res() res: Response) {
     res.status(HttpStatus.OK).json([]);
  }
}
```

```typescript

import { Controller, Get, Post, Bind, Res, Body, HttpStatus } from '@nestjs/common';

@Controller('cats')
export class CatsController {
  @Post()
  @Bind(Res(), Body())
  create(res, createCatDto) {
    res.status(HttpStatus.CREATED).send();
  }

  @Get()
  @Bind(Res())
  findAll(res) {
     res.status(HttpStatus.OK).json([]);
  }
}
```

Though this approach works, and does in fact allow for more flexibility in some ways by providing full control of the response object (headers manipulation, library-specific features, and so on), it should be used with care. In general, the approach is much less clear and does have some disadvantages. The main disadvantage is that your code becomes platform-dependent (as underlying libraries may have different APIs on the response object), and harder to test (you'll have to mock the response object, etc.).

Also, in the example above, you lose compatibility with Nest features that depend on Nest standard response handling, such as Interceptors and `@HttpCode()` / `@Header()` decorators. To fix this, you can set the `passthrough` option to `true`, as follows:

JS TS

```typescript

@Get()
findAll(@Res({ passthrough: true }) res: Response) {
  res.status(HttpStatus.OK);
  return [];
}
```

```typescript

@Get()
@Bind(Res({ passthrough: true }))
findAll(res) {
  res.status(HttpStatus.OK);
  return [];
}
```

Now you can interact with the native response object (for example, set cookies or headers depending on certain conditions), but leave the rest to the framework.

----
url: https://docs.nestjs.com/v10/modules
----

* [Modules](https://docs.nestjs.com/v10/modules#modules)
* [Feature modules](https://docs.nestjs.com/v10/modules#feature-modules)
* [Shared modules](https://docs.nestjs.com/v10/modules#shared-modules)
* [Module re-exporting](https://docs.nestjs.com/v10/modules#module-re-exporting)
* [Dependency injection](https://docs.nestjs.com/v10/modules#dependency-injection)
* [Global modules](https://docs.nestjs.com/v10/modules#global-modules)
* [Dynamic modules](https://docs.nestjs.com/v10/modules#dynamic-modules)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/modules.md "Suggest Edits")

### Modules

A module is a class annotated with a `@Module()` decorator. The `@Module()` decorator provides metadata that **Nest** makes use of to organize the application structure.

Each application has at least one module, a **root module**. The root module is the starting point Nest uses to build the **application graph** - the internal data structure Nest uses to resolve module and provider relationships and dependencies. While very small applications may theoretically have just the root module, this is not the typical case. We want to emphasize that modules are **strongly** recommended as an effective way to organize your components. Thus, for most applications, the resulting architecture will employ multiple modules, each encapsulating a closely related set of **capabilities**.

The `@Module()` decorator takes a single object whose properties describe the module:

| `providers`   | the providers that will be instantiated by the Nest injector and that may be shared at least across this module                                                                                          |
| ------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `controllers` | the set of controllers defined in this module which have to be instantiated                                                                                                                              |
| `imports`     | the list of imported modules that export the providers which are required in this module                                                                                                                 |
| `exports`     | the subset of `providers` that are provided by this module and should be available in other modules which import this module. You can use either the provider itself or just its token (`provide` value) |

The module **encapsulates** providers by default. This means that it's impossible to inject providers that are neither directly part of the current module nor exported from the imported modules. Thus, you may consider the exported providers from a module as the module's public interface, or API.

#### Feature modules[#](/modules#feature-modules)

The `CatsController` and `CatsService` belong to the same application domain. As they are closely related, it makes sense to move them into a feature module. A feature module simply organizes code relevant for a specific feature, keeping code organized and establishing clear boundaries. This helps us manage complexity and develop with [SOLID](https://en.wikipedia.org/wiki/SOLID) principles, especially as the size of the application and/or team grows.

To demonstrate this, we'll create the `CatsModule`.

cats/cats.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

@Module({
  controllers: [CatsController],
  providers: [CatsService],
})
export class CatsModule {}
```

> **Hint** To create a module using the CLI, simply execute the `$ nest g module cats` command.

Above, we defined the `CatsModule` in the `cats.module.ts` file, and moved everything related to this module into the `cats` directory. The last thing we need to do is import this module into the root module (the `AppModule`, defined in the `app.module.ts` file).

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { CatsModule } from './cats/cats.module';

@Module({
  imports: [CatsModule],
})
export class AppModule {}
```

```typescript

import { Module } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

@Module({
  controllers: [CatsController],
  providers: [CatsService],
  exports: [CatsService]
})
export class CatsModule {}
```

Now any module that imports the `CatsModule` has access to the `CatsService` and will share the same instance with all other modules that import it as well.

If we were to directly register the `CatsService` in every module that requires it, it would indeed work, but it would result in each module getting its own separate instance of the `CatsService`. This can lead to increased memory usage since multiple instances of the same service are created, and it could also cause unexpected behavior, such as state inconsistency if the service maintains any internal state.

By encapsulating the `CatsService` inside a module, such as the `CatsModule`, and exporting it, we ensure that the same instance of `CatsService` is reused across all modules that import `CatsModule`. This not only reduces memory consumption but also leads to more predictable behavior, as all modules share the same instance, making it easier to manage shared states or resources. This is one of the key benefits of modularity and dependency injection in frameworks like NestJS—allowing services to be efficiently shared throughout the application.

```typescript

@Module({
  imports: [CommonModule],
  exports: [CommonModule],
})
export class CoreModule {}
```

#### Dependency injection[#](/modules#dependency-injection)

A module class can **inject** providers as well (e.g., for configuration purposes):

cats.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

@Module({
  controllers: [CatsController],
  providers: [CatsService],
})
export class CatsModule {
  constructor(private catsService: CatsService) {}
}
```

```typescript

import { Module, Dependencies } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

@Module({
  controllers: [CatsController],
  providers: [CatsService],
})
@Dependencies(CatsService)
export class CatsModule {
  constructor(catsService) {
    this.catsService = catsService;
  }
}
```

However, module classes themselves cannot be injected as providers due to [circular dependency](/v10/fundamentals/circular-dependency) .

#### Global modules[#](/modules#global-modules)

If you have to import the same set of modules everywhere, it can get tedious. Unlike in Nest, [Angular](https://angular.dev)`providers` are registered in the global scope. Once defined, they're available everywhere. Nest, however, encapsulates providers inside the module scope. You aren't able to use a module's providers elsewhere without first importing the encapsulating module.

When you want to provide a set of providers which should be available everywhere out-of-the-box (e.g., helpers, database connections, etc.), make the module **global** with the `@Global()` decorator.

```typescript

import { Module, Global } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

@Global()
@Module({
  controllers: [CatsController],
  providers: [CatsService],
  exports: [CatsService],
})
export class CatsModule {}
```

The `@Global()` decorator makes the module global-scoped. Global modules should be registered **only once**, generally by the root or core module. In the above example, the `CatsService` provider will be ubiquitous, and modules that wish to inject the service will not need to import the `CatsModule` in their imports array.

> **Hint** Making everything global is not a good design decision. Global modules are available to reduce the amount of necessary boilerplate. The `imports` array is generally the preferred way to make the module's API available to consumers.

#### Dynamic modules[#](/modules#dynamic-modules)

The Nest module system includes a powerful feature called **dynamic modules**. This feature enables you to easily create customizable modules that can register and configure providers dynamically. Dynamic modules are covered extensively [here](/v10/fundamentals/dynamic-modules). In this chapter, we'll give a brief overview to complete the introduction to modules.

Following is an example of a dynamic module definition for a `DatabaseModule`:

JS TS

```typescript

import { Module, DynamicModule } from '@nestjs/common';
import { createDatabaseProviders } from './database.providers';
import { Connection } from './connection.provider';

@Module({
  providers: [Connection],
  exports: [Connection],
})
export class DatabaseModule {
  static forRoot(entities = [], options?): DynamicModule {
    const providers = createDatabaseProviders(options, entities);
    return {
      module: DatabaseModule,
      providers: providers,
      exports: providers,
    };
  }
}
```

```typescript

import { Module } from '@nestjs/common';
import { createDatabaseProviders } from './database.providers';
import { Connection } from './connection.provider';

@Module({
  providers: [Connection],
  exports: [Connection],
})
export class DatabaseModule {
  static forRoot(entities = [], options) {
    const providers = createDatabaseProviders(options, entities);
    return {
      module: DatabaseModule,
      providers: providers,
      exports: providers,
    };
  }
}
```

> **Hint** The `forRoot()` method may return a dynamic module either synchronously or asynchronously (i.e., via a `Promise`).

This module defines the `Connection` provider by default (in the `@Module()` decorator metadata), but additionally - depending on the `entities` and `options` objects passed into the `forRoot()` method - exposes a collection of providers, for example, repositories. Note that the properties returned by the dynamic module **extend** (rather than override) the base module metadata defined in the `@Module()` decorator. That's how both the statically declared `Connection` provider **and** the dynamically generated repository providers are exported from the module.

If you want to register a dynamic module in the global scope, set the `global` property to `true`.

```typescript

{
  global: true,
  module: DatabaseModule,
  providers: providers,
  exports: providers,
}
```

> **Warning** As mentioned above, making everything global **is not a good design decision**.

The `DatabaseModule` can be imported and configured in the following manner:

```typescript

import { Module } from '@nestjs/common';
import { DatabaseModule } from './database/database.module';
import { User } from './users/entities/user.entity';

@Module({
  imports: [DatabaseModule.forRoot([User])],
})
export class AppModule {}
```

If you want to in turn re-export a dynamic module, you can omit the `forRoot()` method call in the exports array:

```typescript

import { Module } from '@nestjs/common';
import { DatabaseModule } from './database/database.module';
import { User } from './users/entities/user.entity';

@Module({
  imports: [DatabaseModule.forRoot([User])],
  exports: [DatabaseModule],
})
export class AppModule {}
```

The [Dynamic modules](/v10/fundamentals/dynamic-modules) chapter covers this topic in greater detail, and includes a [working example](https://github.com/nestjs/nest/tree/master/sample/25-dynamic-modules).

> **Hint** Learn how to build highly customizable dynamic modules with the use of `ConfigurableModuleBuilder` here in [this chapter](/fundamentals/dynamic-modules#configurable-module-builder).

----
url: https://docs.nestjs.com/v10/graphql/federation
----

* [Federation](https://docs.nestjs.com/v10/graphql/federation#federation)
* [Federation with Apollo](https://docs.nestjs.com/v10/graphql/federation#federation-with-apollo)
* [Schema first](https://docs.nestjs.com/v10/graphql/federation#schema-first)
* [Code first](https://docs.nestjs.com/v10/graphql/federation#code-first)
* [Federated example: Posts](https://docs.nestjs.com/v10/graphql/federation#federated-example-posts)
* [Schema first](https://docs.nestjs.com/v10/graphql/federation#schema-first-1)
* [Code first](https://docs.nestjs.com/v10/graphql/federation#code-first-1)
* [Federated example: Gateway](https://docs.nestjs.com/v10/graphql/federation#federated-example-gateway)
* [Federation with Mercurius](https://docs.nestjs.com/v10/graphql/federation#federation-with-mercurius)
* [Schema first](https://docs.nestjs.com/v10/graphql/federation#schema-first-2)
* [Code first](https://docs.nestjs.com/v10/graphql/federation#code-first-2)
* [Federated example: Posts](https://docs.nestjs.com/v10/graphql/federation#federated-example-posts-1)
* [Schema first](https://docs.nestjs.com/v10/graphql/federation#schema-first-3)
* [Code first](https://docs.nestjs.com/v10/graphql/federation#code-first-3)
* [Federated example: Gateway](https://docs.nestjs.com/v10/graphql/federation#federated-example-gateway-1)
* [Federation 2](https://docs.nestjs.com/v10/graphql/federation#federation-2)
* [Federated example: Users](https://docs.nestjs.com/v10/graphql/federation#federated-example-users)
* [Schema first](https://docs.nestjs.com/v10/graphql/federation#schema-first-4)
* [Code first](https://docs.nestjs.com/v10/graphql/federation#code-first-4)
* [Federated example: Posts](https://docs.nestjs.com/v10/graphql/federation#federated-example-posts-2)
* [Schema first](https://docs.nestjs.com/v10/graphql/federation#schema-first-5)
* [Code first](https://docs.nestjs.com/v10/graphql/federation#code-first-5)

> **Warning** Federation currently does not support subscriptions.

In the following sections, we'll set up a demo application that consists of a gateway and two federated endpoints: Users service and Posts service.

#### Federation with Apollo[#](/graphql/federation#federation-with-apollo)

Start by installing the required dependencies:

```bash

$ npm install --save @apollo/subgraph
```

#### Schema first[#](/graphql/federation#schema-first)

The "User service" provides a simple schema. Note the `@key` directive: it instructs the Apollo query planner that a particular instance of `User` can be fetched if you specify its `id`. Also, note that we `extend` the `Query` type.

```graphql

type User @key(fields: "id") {
  id: ID!
  name: String!
}

extend type Query {
  getUser(id: ID!): User
}
```

Resolver provides one additional method named `resolveReference()`. This method is triggered by the Apollo Gateway whenever a related resource requires a User instance. We'll see an example of this in the Posts service later. Please note that the method must be annotated with the `@ResolveReference()` decorator.

```typescript

import { Args, Query, Resolver, ResolveReference } from '@nestjs/graphql';
import { UsersService } from './users.service';

@Resolver('User')
export class UsersResolver {
  constructor(private usersService: UsersService) {}

  @Query()
  getUser(@Args('id') id: string) {
    return this.usersService.findById(id);
  }

  @ResolveReference()
  resolveReference(reference: { __typename: string; id: string }) {
    return this.usersService.findById(reference.id);
  }
}
```

Finally, we hook everything up by registering the `GraphQLModule` passing the `ApolloFederationDriver` driver in the configuration object:

```typescript

import {
  ApolloFederationDriver,
  ApolloFederationDriverConfig,
} from '@nestjs/apollo';
import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';
import { UsersResolver } from './users.resolver';

@Module({
  imports: [
    GraphQLModule.forRoot<ApolloFederationDriverConfig>({
      driver: ApolloFederationDriver,
      typePaths: ['**/*.graphql'],
    }),
  ],
  providers: [UsersResolver],
})
export class AppModule {}
```

#### Code first[#](/graphql/federation#code-first)

Start by adding some extra decorators to the `User` entity.

```ts

import { Directive, Field, ID, ObjectType } from '@nestjs/graphql';

@ObjectType()
@Directive('@key(fields: "id")')
export class User {
  @Field(() => ID)
  id: number;

  @Field()
  name: string;
}
```

Resolver provides one additional method named `resolveReference()`. This method is triggered by the Apollo Gateway whenever a related resource requires a User instance. We'll see an example of this in the Posts service later. Please note that the method must be annotated with the `@ResolveReference()` decorator.

```ts

import { Args, Query, Resolver, ResolveReference } from '@nestjs/graphql';
import { User } from './user.entity';
import { UsersService } from './users.service';

@Resolver(() => User)
export class UsersResolver {
  constructor(private usersService: UsersService) {}

  @Query(() => User)
  getUser(@Args('id') id: number): User {
    return this.usersService.findById(id);
  }

  @ResolveReference()
  resolveReference(reference: { __typename: string; id: number }): User {
    return this.usersService.findById(reference.id);
  }
}
```

Finally, we hook everything up by registering the `GraphQLModule` passing the `ApolloFederationDriver` driver in the configuration object:

```typescript

import {
  ApolloFederationDriver,
  ApolloFederationDriverConfig,
} from '@nestjs/apollo';
import { Module } from '@nestjs/common';
import { UsersResolver } from './users.resolver';
import { UsersService } from './users.service'; // Not included in this example

@Module({
  imports: [
    GraphQLModule.forRoot<ApolloFederationDriverConfig>({
      driver: ApolloFederationDriver,
      autoSchemaFile: true,
    }),
  ],
  providers: [UsersResolver, UsersService],
})
export class AppModule {}
```

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/31-graphql-federation-code-first/users-application) in code first mode and [here](https://github.com/nestjs/nest/tree/master/sample/32-graphql-federation-schema-first/users-application) in schema first mode.

#### Federated example: Posts[#](/graphql/federation#federated-example-posts)

Post service is supposed to serve aggregated posts through the `getPosts` query, but also extend our `User` type with the `user.posts` field.

#### Schema first[#](/graphql/federation#schema-first-1)

"Posts service" references the `User` type in its schema by marking it with the `extend` keyword. It also declares one additional property on the `User` type (`posts`). Note the `@key` directive used for matching instances of User, and the `@external` directive indicating that the `id` field is managed elsewhere.

```graphql

type Post @key(fields: "id") {
  id: ID!
  title: String!
  body: String!
  user: User
}

extend type User @key(fields: "id") {
  id: ID! @external
  posts: [Post]
}

extend type Query {
  getPosts: [Post]
}
```

In the following example, the `PostsResolver` provides the `getUser()` method that returns a reference containing `__typename` and some additional properties your application may need to resolve the reference, in this case `id`. `__typename` is used by the GraphQL Gateway to pinpoint the microservice responsible for the User type and retrieve the corresponding instance. The "Users service" described above will be requested upon execution of the `resolveReference()` method.

```typescript

import { Query, Resolver, Parent, ResolveField } from '@nestjs/graphql';
import { PostsService } from './posts.service';
import { Post } from './posts.interfaces';

@Resolver('Post')
export class PostsResolver {
  constructor(private postsService: PostsService) {}

  @Query('getPosts')
  getPosts() {
    return this.postsService.findAll();
  }

  @ResolveField('user')
  getUser(@Parent() post: Post) {
    return { __typename: 'User', id: post.userId };
  }
}
```

Lastly, we must register the `GraphQLModule`, similarly to what we did in the "Users service" section.

```typescript

import {
  ApolloFederationDriver,
  ApolloFederationDriverConfig,
} from '@nestjs/apollo';
import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';
import { PostsResolver } from './posts.resolver';

@Module({
  imports: [
    GraphQLModule.forRoot<ApolloFederationDriverConfig>({
      driver: ApolloFederationDriver,
      typePaths: ['**/*.graphql'],
    }),
  ],
  providers: [PostsResolvers],
})
export class AppModule {}
```

#### Code first[#](/graphql/federation#code-first-1)

First, we will have to declare a class representing the `User` entity. Although the entity itself lives in another service, we will be using it (extending its definition) here. Note the `@extends` and `@external` directives.

```ts

import { Directive, ObjectType, Field, ID } from '@nestjs/graphql';
import { Post } from './post.entity';

@ObjectType()
@Directive('@extends')
@Directive('@key(fields: "id")')
export class User {
  @Field(() => ID)
  @Directive('@external')
  id: number;

  @Field(() => [Post])
  posts?: Post[];
}
```

Now let's create the corresponding resolver for our extension on the `User` entity, as follows:

```ts

import { Parent, ResolveField, Resolver } from '@nestjs/graphql';
import { PostsService } from './posts.service';
import { Post } from './post.entity';
import { User } from './user.entity';

@Resolver(() => User)
export class UsersResolver {
  constructor(private readonly postsService: PostsService) {}

  @ResolveField(() => [Post])
  public posts(@Parent() user: User): Post[] {
    return this.postsService.forAuthor(user.id);
  }
}
```

We also have to define the `Post` entity class:

```ts

import { Directive, Field, ID, Int, ObjectType } from '@nestjs/graphql';
import { User } from './user.entity';

@ObjectType()
@Directive('@key(fields: "id")')
export class Post {
  @Field(() => ID)
  id: number;

  @Field()
  title: string;

  @Field(() => Int)
  authorId: number;

  @Field(() => User)
  user?: User;
}
```

And its resolver:

```ts

import { Query, Args, ResolveField, Resolver, Parent } from '@nestjs/graphql';
import { PostsService } from './posts.service';
import { Post } from './post.entity';
import { User } from './user.entity';

@Resolver(() => Post)
export class PostsResolver {
  constructor(private readonly postsService: PostsService) {}

  @Query(() => Post)
  findPost(@Args('id') id: number): Post {
    return this.postsService.findOne(id);
  }

  @Query(() => [Post])
  getPosts(): Post[] {
    return this.postsService.all();
  }

  @ResolveField(() => User)
  user(@Parent() post: Post): any {
    return { __typename: 'User', id: post.authorId };
  }
}
```

And finally, tie it together in a module. Note the schema build options, where we specify that `User` is an orphaned (external) type.

```ts

import {
  ApolloFederationDriver,
  ApolloFederationDriverConfig,
} from '@nestjs/apollo';
import { Module } from '@nestjs/common';
import { User } from './user.entity';
import { PostsResolvers } from './posts.resolvers';
import { UsersResolvers } from './users.resolvers';
import { PostsService } from './posts.service'; // Not included in example

@Module({
  imports: [
    GraphQLModule.forRoot<ApolloFederationDriverConfig>({
      driver: ApolloFederationDriver,
      autoSchemaFile: true,
      buildSchemaOptions: {
        orphanedTypes: [User],
      },
    }),
  ],
  providers: [PostsResolver, UsersResolver, PostsService],
})
export class AppModule {}
```

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/31-graphql-federation-code-first/posts-application) for the code first mode and [here](https://github.com/nestjs/nest/tree/master/sample/32-graphql-federation-schema-first/posts-application) for the schema first mode.

#### Federated example: Gateway[#](/graphql/federation#federated-example-gateway)

Start by installing the required dependency:

```bash

$ npm install --save @apollo/gateway
```

The gateway requires a list of endpoints to be specified and it will auto-discover the corresponding schemas. Therefore the implementation of the gateway service will remain the same for both code and schema first approaches.

```typescript

import { IntrospectAndCompose } from '@apollo/gateway';
import { ApolloGatewayDriver, ApolloGatewayDriverConfig } from '@nestjs/apollo';
import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';

@Module({
  imports: [
    GraphQLModule.forRoot<ApolloGatewayDriverConfig>({
      driver: ApolloGatewayDriver,
      server: {
        // ... Apollo server options
        cors: true,
      },
      gateway: {
        supergraphSdl: new IntrospectAndCompose({
          subgraphs: [
            { name: 'users', url: 'http://user-service/graphql' },
            { name: 'posts', url: 'http://post-service/graphql' },
          ],
        }),
      },
    }),
  ],
})
export class AppModule {}
```

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/31-graphql-federation-code-first/gateway) for the code first mode and [here](https://github.com/nestjs/nest/tree/master/sample/32-graphql-federation-schema-first/gateway) for the schema first mode.

#### Federation with Mercurius[#](/graphql/federation#federation-with-mercurius)

Start by installing the required dependencies:

```bash

$ npm install --save @apollo/subgraph @nestjs/mercurius
```

> **Note** The `@apollo/subgraph` package is required to build a subgraph schema (`buildSubgraphSchema`, `printSubgraphSchema` functions).

#### Schema first[#](/graphql/federation#schema-first-2)

The "User service" provides a simple schema. Note the `@key` directive: it instructs the Mercurius query planner that a particular instance of `User` can be fetched if you specify its `id`. Also, note that we `extend` the `Query` type.

```graphql

type User @key(fields: "id") {
  id: ID!
  name: String!
}

extend type Query {
  getUser(id: ID!): User
}
```

Resolver provides one additional method named `resolveReference()`. This method is triggered by the Mercurius Gateway whenever a related resource requires a User instance. We'll see an example of this in the Posts service later. Please note that the method must be annotated with the `@ResolveReference()` decorator.

```typescript

import { Args, Query, Resolver, ResolveReference } from '@nestjs/graphql';
import { UsersService } from './users.service';

@Resolver('User')
export class UsersResolver {
  constructor(private usersService: UsersService) {}

  @Query()
  getUser(@Args('id') id: string) {
    return this.usersService.findById(id);
  }

  @ResolveReference()
  resolveReference(reference: { __typename: string; id: string }) {
    return this.usersService.findById(reference.id);
  }
}
```

Finally, we hook everything up by registering the `GraphQLModule` passing the `MercuriusFederationDriver` driver in the configuration object:

```typescript

import {
  MercuriusFederationDriver,
  MercuriusFederationDriverConfig,
} from '@nestjs/mercurius';
import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';
import { UsersResolver } from './users.resolver';

@Module({
  imports: [
    GraphQLModule.forRoot<MercuriusFederationDriverConfig>({
      driver: MercuriusFederationDriver,
      typePaths: ['**/*.graphql'],
      federationMetadata: true,
    }),
  ],
  providers: [UsersResolver],
})
export class AppModule {}
```

#### Code first[#](/graphql/federation#code-first-2)

Start by adding some extra decorators to the `User` entity.

```ts

import { Directive, Field, ID, ObjectType } from '@nestjs/graphql';

@ObjectType()
@Directive('@key(fields: "id")')
export class User {
  @Field(() => ID)
  id: number;

  @Field()
  name: string;
}
```

Resolver provides one additional method named `resolveReference()`. This method is triggered by the Mercurius Gateway whenever a related resource requires a User instance. We'll see an example of this in the Posts service later. Please note that the method must be annotated with the `@ResolveReference()` decorator.

```ts

import { Args, Query, Resolver, ResolveReference } from '@nestjs/graphql';
import { User } from './user.entity';
import { UsersService } from './users.service';

@Resolver(() => User)
export class UsersResolver {
  constructor(private usersService: UsersService) {}

  @Query(() => User)
  getUser(@Args('id') id: number): User {
    return this.usersService.findById(id);
  }

  @ResolveReference()
  resolveReference(reference: { __typename: string; id: number }): User {
    return this.usersService.findById(reference.id);
  }
}
```

Finally, we hook everything up by registering the `GraphQLModule` passing the `MercuriusFederationDriver` driver in the configuration object:

```typescript

import {
  MercuriusFederationDriver,
  MercuriusFederationDriverConfig,
} from '@nestjs/mercurius';
import { Module } from '@nestjs/common';
import { UsersResolver } from './users.resolver';
import { UsersService } from './users.service'; // Not included in this example

@Module({
  imports: [
    GraphQLModule.forRoot<MercuriusFederationDriverConfig>({
      driver: MercuriusFederationDriver,
      autoSchemaFile: true,
      federationMetadata: true,
    }),
  ],
  providers: [UsersResolver, UsersService],
})
export class AppModule {}
```

#### Federated example: Posts[#](/graphql/federation#federated-example-posts-1)

Post service is supposed to serve aggregated posts through the `getPosts` query, but also extend our `User` type with the `user.posts` field.

#### Schema first[#](/graphql/federation#schema-first-3)

"Posts service" references the `User` type in its schema by marking it with the `extend` keyword. It also declares one additional property on the `User` type (`posts`). Note the `@key` directive used for matching instances of User, and the `@external` directive indicating that the `id` field is managed elsewhere.

```graphql

type Post @key(fields: "id") {
  id: ID!
  title: String!
  body: String!
  user: User
}

extend type User @key(fields: "id") {
  id: ID! @external
  posts: [Post]
}

extend type Query {
  getPosts: [Post]
}
```

In the following example, the `PostsResolver` provides the `getUser()` method that returns a reference containing `__typename` and some additional properties your application may need to resolve the reference, in this case `id`. `__typename` is used by the GraphQL Gateway to pinpoint the microservice responsible for the User type and retrieve the corresponding instance. The "Users service" described above will be requested upon execution of the `resolveReference()` method.

```typescript

import { Query, Resolver, Parent, ResolveField } from '@nestjs/graphql';
import { PostsService } from './posts.service';
import { Post } from './posts.interfaces';

@Resolver('Post')
export class PostsResolver {
  constructor(private postsService: PostsService) {}

  @Query('getPosts')
  getPosts() {
    return this.postsService.findAll();
  }

  @ResolveField('user')
  getUser(@Parent() post: Post) {
    return { __typename: 'User', id: post.userId };
  }
}
```

Lastly, we must register the `GraphQLModule`, similarly to what we did in the "Users service" section.

```typescript

import {
  MercuriusFederationDriver,
  MercuriusFederationDriverConfig,
} from '@nestjs/mercurius';
import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';
import { PostsResolver } from './posts.resolver';

@Module({
  imports: [
    GraphQLModule.forRoot<MercuriusFederationDriverConfig>({
      driver: MercuriusFederationDriver,
      federationMetadata: true,
      typePaths: ['**/*.graphql'],
    }),
  ],
  providers: [PostsResolvers],
})
export class AppModule {}
```

#### Code first[#](/graphql/federation#code-first-3)

First, we will have to declare a class representing the `User` entity. Although the entity itself lives in another service, we will be using it (extending its definition) here. Note the `@extends` and `@external` directives.

```ts

import { Directive, ObjectType, Field, ID } from '@nestjs/graphql';
import { Post } from './post.entity';

@ObjectType()
@Directive('@extends')
@Directive('@key(fields: "id")')
export class User {
  @Field(() => ID)
  @Directive('@external')
  id: number;

  @Field(() => [Post])
  posts?: Post[];
}
```

Now let's create the corresponding resolver for our extension on the `User` entity, as follows:

```ts

import { Parent, ResolveField, Resolver } from '@nestjs/graphql';
import { PostsService } from './posts.service';
import { Post } from './post.entity';
import { User } from './user.entity';

@Resolver(() => User)
export class UsersResolver {
  constructor(private readonly postsService: PostsService) {}

  @ResolveField(() => [Post])
  public posts(@Parent() user: User): Post[] {
    return this.postsService.forAuthor(user.id);
  }
}
```

We also have to define the `Post` entity class:

```ts

import { Directive, Field, ID, Int, ObjectType } from '@nestjs/graphql';
import { User } from './user.entity';

@ObjectType()
@Directive('@key(fields: "id")')
export class Post {
  @Field(() => ID)
  id: number;

  @Field()
  title: string;

  @Field(() => Int)
  authorId: number;

  @Field(() => User)
  user?: User;
}
```

And its resolver:

```ts

import { Query, Args, ResolveField, Resolver, Parent } from '@nestjs/graphql';
import { PostsService } from './posts.service';
import { Post } from './post.entity';
import { User } from './user.entity';

@Resolver(() => Post)
export class PostsResolver {
  constructor(private readonly postsService: PostsService) {}

  @Query(() => Post)
  findPost(@Args('id') id: number): Post {
    return this.postsService.findOne(id);
  }

  @Query(() => [Post])
  getPosts(): Post[] {
    return this.postsService.all();
  }

  @ResolveField(() => User)
  user(@Parent() post: Post): any {
    return { __typename: 'User', id: post.authorId };
  }
}
```

And finally, tie it together in a module. Note the schema build options, where we specify that `User` is an orphaned (external) type.

```ts

import {
  MercuriusFederationDriver,
  MercuriusFederationDriverConfig,
} from '@nestjs/mercurius';
import { Module } from '@nestjs/common';
import { User } from './user.entity';
import { PostsResolvers } from './posts.resolvers';
import { UsersResolvers } from './users.resolvers';
import { PostsService } from './posts.service'; // Not included in example

@Module({
  imports: [
    GraphQLModule.forRoot<MercuriusFederationDriverConfig>({
      driver: MercuriusFederationDriver,
      autoSchemaFile: true,
      federationMetadata: true,
      buildSchemaOptions: {
        orphanedTypes: [User],
      },
    }),
  ],
  providers: [PostsResolver, UsersResolver, PostsService],
})
export class AppModule {}
```

#### Federated example: Gateway[#](/graphql/federation#federated-example-gateway-1)

The gateway requires a list of endpoints to be specified and it will auto-discover the corresponding schemas. Therefore the implementation of the gateway service will remain the same for both code and schema first approaches.

```typescript

import {
  MercuriusGatewayDriver,
  MercuriusGatewayDriverConfig,
} from '@nestjs/mercurius';
import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';

@Module({
  imports: [
    GraphQLModule.forRoot<MercuriusGatewayDriverConfig>({
      driver: MercuriusGatewayDriver,
      gateway: {
        services: [
          { name: 'users', url: 'http://user-service/graphql' },
          { name: 'posts', url: 'http://post-service/graphql' },
        ],
      },
    }),
  ],
})
export class AppModule {}
```

### Federation 2

To quote the [Apollo docs](https://www.apollographql.com/docs/federation/federation-2/new-in-federation-2), Federation 2 improves developer experience from the original Apollo Federation (called Federation 1 in this doc), which is backward compatible with most original supergraphs.

> **Warning** Mercurius doesn't fully support Federation 2. You can see the list of libraries that support Federation 2 [here](https://www.apollographql.com/docs/federation/supported-subgraphs#javascript--typescript).

In the following sections, we'll upgrade the previous example to Federation 2.

#### Federated example: Users[#](/graphql/federation#federated-example-users)

One change in Federation 2 is that entities have no originating subgraph, so we don't need to extend `Query` anymore. For more detail please refer to [the entities topic](https://www.apollographql.com/docs/federation/federation-2/new-in-federation-2#entities) in Apollo Federation 2 docs.

#### Schema first[#](/graphql/federation#schema-first-4)

We can simply remove `extend` keyword from the schema.

```graphql

type User @key(fields: "id") {
  id: ID!
  name: String!
}

type Query {
  getUser(id: ID!): User
}
```

#### Code first[#](/graphql/federation#code-first-4)

To use Federation 2, we need to specify the federation version in `autoSchemaFile` option.

```ts

import {
  ApolloFederationDriver,
  ApolloFederationDriverConfig,
} from '@nestjs/apollo';
import { Module } from '@nestjs/common';
import { UsersResolver } from './users.resolver';
import { UsersService } from './users.service'; // Not included in this example

@Module({
  imports: [
    GraphQLModule.forRoot<ApolloFederationDriverConfig>({
      driver: ApolloFederationDriver,
      autoSchemaFile: {
        federation: 2,
      },
    }),
  ],
  providers: [UsersResolver, UsersService],
})
export class AppModule {}
```

#### Federated example: Posts[#](/graphql/federation#federated-example-posts-2)

With the same reason as above, we don't need to extend `User` and `Query` anymore.

#### Schema first[#](/graphql/federation#schema-first-5)

We can simply remove `extend` and `external` directives from the schema

```graphql

type Post @key(fields: "id") {
  id: ID!
  title: String!
  body: String!
  user: User
}

type User @key(fields: "id") {
  id: ID!
  posts: [Post]
}

type Query {
  getPosts: [Post]
}
```

#### Code first[#](/graphql/federation#code-first-5)

Since we don't extend `User` entity anymore, we can simply remove `extends` and `external` directives from `User`.

```ts

import { Directive, ObjectType, Field, ID } from '@nestjs/graphql';
import { Post } from './post.entity';

@ObjectType()
@Directive('@key(fields: "id")')
export class User {
  @Field(() => ID)
  id: number;

  @Field(() => [Post])
  posts?: Post[];
}
```

Also, similarly to the User service, we need to specify in the `GraphQLModule` to use Federation 2.

```ts

import {
  ApolloFederationDriver,
  ApolloFederationDriverConfig,
} from '@nestjs/apollo';
import { Module } from '@nestjs/common';
import { User } from './user.entity';
import { PostsResolvers } from './posts.resolvers';
import { UsersResolvers } from './users.resolvers';
import { PostsService } from './posts.service'; // Not included in example

@Module({
  imports: [
    GraphQLModule.forRoot<ApolloFederationDriverConfig>({
      driver: ApolloFederationDriver,
      autoSchemaFile: {
        federation: 2,
      },
      buildSchemaOptions: {
        orphanedTypes: [User],
      },
    }),
  ],
  providers: [PostsResolver, UsersResolver, PostsService],
})
export class AppModule {}
```

----
url: https://docs.nestjs.com/v9/websockets/gateways
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Gateways](https://docs.nestjs.com/v9/websockets/gateways#gateways)
* [Installation](https://docs.nestjs.com/v9/websockets/gateways#installation)
* [Overview](https://docs.nestjs.com/v9/websockets/gateways#overview)
* [Multiple responses](https://docs.nestjs.com/v9/websockets/gateways#multiple-responses)
* [Asynchronous responses](https://docs.nestjs.com/v9/websockets/gateways#asynchronous-responses)
* [Lifecycle hooks](https://docs.nestjs.com/v9/websockets/gateways#lifecycle-hooks)
* [Server](https://docs.nestjs.com/v9/websockets/gateways#server)
* [Example](https://docs.nestjs.com/v9/websockets/gateways#example)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/websockets/gateways.md "Suggest Edits")

### Gateways

Most of the concepts discussed elsewhere in this documentation, such as dependency injection, decorators, exception filters, pipes, guards and interceptors, apply equally to gateways. Wherever possible, Nest abstracts implementation details so that the same components can run across HTTP-based platforms, WebSockets, and Microservices. This section covers the aspects of Nest that are specific to WebSockets.

In Nest, a gateway is simply a class annotated with `@WebSocketGateway()` decorator. Technically, gateways are platform-agnostic which makes them compatible with any WebSockets library once an adapter is created. There are two WS platforms supported out-of-the-box: [socket.io](https://github.com/socketio/socket.io) and [ws](https://github.com/websockets/ws). You can choose the one that best suits your needs. Also, you can build your own adapter by following this [guide](/v9/websockets/adapter).

> **Hint** Gateways can be treated as [providers](/v9/providers); this means they can inject dependencies through the class constructor. Also, gateways can be injected by other classes (providers and controllers) as well.

#### Installation[#](/websockets/gateways#installation)

To start building WebSockets-based applications, first install the required package:

JS TS

```typescript

$ npm i --save @nestjs/websockets @nestjs/platform-socket.io
```

```typescript

$ npm i --save @nestjs/websockets @nestjs/platform-socket.io
```

#### Overview[#](/websockets/gateways#overview)

In general, each gateway is listening on the same port as the **HTTP server**, unless your app is not a web application, or you have changed the port manually. This default behavior can be modified by passing an argument to the `@WebSocketGateway(80)` decorator where `80` is a chosen port number. You can also set a [namespace](https://socket.io/docs/v4/namespaces/) used by the gateway using the following construction:

```typescript

@WebSocketGateway(80, { namespace: 'events' })
```

> **Warning** Gateways are not instantiated until they are referenced in the providers array of an existing module.

You can pass any supported [option](https://socket.io/docs/v4/server-options/) to the socket constructor with the second argument to the `@WebSocketGateway()` decorator, as shown below:

```typescript

@WebSocketGateway(81, { transports: ['websocket'] })
```

The gateway is now listening, but we have not yet subscribed to any incoming messages. Let's create a handler that will subscribe to the `events` messages and respond to the user with the exact same data.

events.gateway.ts

JS TS

```typescript

@SubscribeMessage('events')
handleEvent(@MessageBody() data: string): string {
  return data;
}
```

```typescript

@Bind(MessageBody())
@SubscribeMessage('events')
handleEvent(data) {
  return data;
}
```

> **Hint**`@SubscribeMessage()` and `@MessageBody()` decorators are imported from `@nestjs/websockets` package.

Once the gateway is created, we can register it in our module.

events.module.ts

JS TS

```typescript

@Module({
  providers: [EventsGateway]
})
export class EventsModule {}
```

You can also pass in a property key to the decorator to extract it from the incoming message body:

events.gateway.ts

JS TS

```typescript

@SubscribeMessage('events')
handleEvent(@MessageBody('id') id: number): number {
  // id === messageBody.id
  return id;
}
```

```typescript

@Bind(MessageBody('id'))
@SubscribeMessage('events')
handleEvent(id) {
  // id === messageBody.id
  return id;
}
```

If you would prefer not to use decorators, the following code is functionally equivalent:

events.gateway.ts

JS TS

```typescript

@SubscribeMessage('events')
handleEvent(client: Socket, data: string): string {
  return data;
}
```

```typescript

@SubscribeMessage('events')
handleEvent(client, data) {
  return data;
}
```

In the example above, the `handleEvent()` function takes two arguments. The first one is a platform-specific [socket instance](https://socket.io/docs/v4/server-api/#socket), while the second one is the data received from the client. This approach is not recommended though, because it requires mocking the `socket` instance in each unit test.

Once the `events` message is received, the handler sends an acknowledgment with the same data that was sent over the network. In addition, it's possible to emit messages using a library-specific approach, for example, by making use of `client.emit()` method. In order to access a connected socket instance, use `@ConnectedSocket()` decorator.

events.gateway.ts

JS TS

```typescript

@SubscribeMessage('events')
handleEvent(
  @MessageBody() data: string,
  @ConnectedSocket() client: Socket,
): string {
  return data;
}
```

```typescript

@Bind(MessageBody(), ConnectedSocket())
@SubscribeMessage('events')
handleEvent(data, client) {
  return data;
}
```

> **Hint**`@ConnectedSocket()` decorator is imported from `@nestjs/websockets` package.

However, in this case, you won't be able to leverage interceptors. If you don't want to respond to the user, you can simply skip the `return` statement (or explicitly return a "falsy" value, e.g. `undefined`).

Now when a client emits the message as follows:

```typescript

socket.emit('events', { name: 'Nest' });
```

The `handleEvent()` method will be executed. In order to listen for messages emitted from within the above handler, the client has to attach a corresponding acknowledgment listener:

```typescript

socket.emit('events', { name: 'Nest' }, (data) => console.log(data));
```

#### Multiple responses[#](/websockets/gateways#multiple-responses)

The acknowledgment is dispatched only once. Furthermore, it is not supported by native WebSockets implementation. To solve this limitation, you may return an object which consists of two properties. The `event` which is a name of the emitted event and the `data` that has to be forwarded to the client.

events.gateway.ts

JS TS

```typescript

@SubscribeMessage('events')
handleEvent(@MessageBody() data: unknown): WsResponse<unknown> {
  const event = 'events';
  return { event, data };
}
```

```typescript

@Bind(MessageBody())
@SubscribeMessage('events')
handleEvent(data) {
  const event = 'events';
  return { event, data };
}
```

> **Hint** The `WsResponse` interface is imported from `@nestjs/websockets` package.

> **Warning** You should return a class instance that implements `WsResponse` if your `data` field relies on `ClassSerializerInterceptor`, as it ignores plain JavaScript object responses.

In order to listen for the incoming response(s), the client has to apply another event listener.

```typescript

socket.on('events', (data) => console.log(data));
```

#### Asynchronous responses[#](/websockets/gateways#asynchronous-responses)

Message handlers are able to respond either synchronously or **asynchronously**. Hence, `async` methods are supported. A message handler is also able to return an `Observable`, in which case the result values will be emitted until the stream is completed.

events.gateway.ts

JS TS

```typescript

@SubscribeMessage('events')
onEvent(@MessageBody() data: unknown): Observable<WsResponse<number>> {
  const event = 'events';
  const response = [1, 2, 3];

  return from(response).pipe(
    map(data => ({ event, data })),
  );
}
```

```typescript

@Bind(MessageBody())
@SubscribeMessage('events')
onEvent(data) {
  const event = 'events';
  const response = [1, 2, 3];

  return from(response).pipe(
    map(data => ({ event, data })),
  );
}
```

In the example above, the message handler will respond **3 times** (with each item from the array).

#### Lifecycle hooks[#](/websockets/gateways#lifecycle-hooks)

There are 3 useful lifecycle hooks available. All of them have corresponding interfaces and are described in the following table:

|                       |                                                                                                                                         |
| --------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| `OnGatewayInit`       | Forces to implement the `afterInit()` method. Takes library-specific server instance as an argument (and spreads the rest if required). |
| `OnGatewayConnection` | Forces to implement the `handleConnection()` method. Takes library-specific client socket instance as an argument.                      |
| `OnGatewayDisconnect` | Forces to implement the `handleDisconnect()` method. Takes library-specific client socket instance as an argument.                      |

> **Hint** Each lifecycle interface is exposed from `@nestjs/websockets` package.

#### Server[#](/websockets/gateways#server)

Occasionally, you may want to have a direct access to the native, **platform-specific** server instance. The reference to this object is passed as an argument to the `afterInit()` method (`OnGatewayInit` interface). Another option is to use the `@WebSocketServer()` decorator.

```typescript

@WebSocketServer()
server: Server;
```

> **Notice** The `@WebSocketServer()` decorator is imported from the `@nestjs/websockets` package.

----
url: https://docs.nestjs.com/v4/websockets/gateways
----

### Gateways

Gateway is a class with `@WebSocketGateway()` decorator. In fact, the Gateway is an encapsulated [socket.io](https://github.com/socketio/socket.io) server instance adjusted to the framework architecture.

> **Hint** Gateway is a **component**, so it can inject dependencies through constructor. Also, gateway might be injected by another component.

By default, each Gateway is listening to the same port as **HTTP server** is running on (unless your app is not a web application). We can change this behaviour by passing the argument to the `@WebSocketGateway(81)` decorator. Additionally, you can force a [namespace](https://socket.io/docs/rooms-and-namespaces/) used by this gateway with the following construction:

TypeScript

```typescript

@WebSocketGateway({ port: 81, namespace: 'events' })
```

> **Notice** Gateway won't start until you place it inside `components` array.

The Gateway is listening now, but we're not subscribing to the incoming messages yet. Let's create a handler, which will subscribe to the `events` messages and respond to the user with the exact same data.

events.gateway.ts

JavaScript TypeScript

TypeScript

```typescript

@SubscribeMessage('events')
onEvent(client, data): WsResponse<any> {
  const event = 'events';
  return { event, data };
}
```

TypeScript

```typescript

@SubscribeMessage('events')
onEvent(client, data) {
  const event = 'events';
  return { event, data };
}
```

> **Notice** The `WsResponse` interface is imported from `@nestjs/common` package, while `@SubscribeMessage()` decorator from `@nestjs/websockets`.

The `onEvent()` function takes 2 arguments. First one is a [native socket instance](https://socket.io/docs/server-api/#socket), and the second one - `data` is the data passed from the client. Object returned from the function must have 2 members. The `event`, which is a name of the emitted event, and the `data`. Also, it's possible to emit messages using standard socket.io approach, so using `client.emit()` function, but then it's impossible to make use of interceptors. If you don't want to respond to the user, just don't return anything.

#### Asynchronous responses

Each message handler can be `async`, thereby you're able to return the `Promise`. Moreover, you can return the [RxJS](https://github.com/reactivex/rxjs) `Observable`, so the values would be emitted until the stream is completed.

events.gateway.ts

JavaScript TypeScript

TypeScript

```typescript

@SubscribeMessage('events')
onEvent(client, data): Observable<WsResponse<number>> {
  const event = 'events';
  const response = [1, 2, 3];

  return Observable.from(response)
    .map((res) => ({ event, data: res }));
}
```

TypeScript

```typescript

@SubscribeMessage('events')
onEvent(client, data) {
  const event = 'events';
  const response = [1, 2, 3];

  return Observable.from(response)
    .map((res) => ({ event, data: res }));
}
```

Above message handler will respond **3 times** (with each item from the `response` array).

#### Lifecycle Hooks

There're 3 useful lifecycle hooks. All of them have a corresponding interfaces, and are described in the following table:

|                       |                                                                                                          |
| --------------------- | -------------------------------------------------------------------------------------------------------- |
| `OnGatewayInit`       | Forces to implement the `afterInit()` method. Takes native socket.io server instance as an argument.     |
| `OnGatewayConnection` | Forces to implement the `handleConnection()` method. Takes native client socket instance as an argument. |
| `OnGatewayDisconnect` | Forces to implement the `handleDisconnect()` method. Takes native client socket instance as an argument. |

> **Notice** Each lifecycle interface is available within `@nestjs/websockets` package.

#### Native server instance

Sometimes you might wanna have a direct access to the native socket.io **server instance**. The reference to this object is passed as an argument to the `afterInit()` method (`OnGatewayInit` interface). The second approach is to make use of `@WebSocketServer()` decorator.

TypeScript

```typescript

@WebSocketServer() server;
```

Nest will automatically assign the server instance to this property when it's ready to use.

> **Notice** The `@WebSocketServer()` decorator is imported from the `@nestjs/websockets` package.

#### Sponsors

[](https://valor-software.com/)

Nest is an MIT-licensed open source project. It can grow thanks to the support by these awesome people. If you'd like to join them, please read more [here](https://opencollective.com/nest). Thanks!

[](https://opencollective.com/nest/backer/0/website)[](https://opencollective.com/nest/backer/1/website)[](https://opencollective.com/nest/backer/2/website)[](https://opencollective.com/nest/backer/3/website)[](https://opencollective.com/nest/backer/4/website)[](https://opencollective.com/nest/backer/5/website)[](https://opencollective.com/nest/backer/6/website)[](https://opencollective.com/nest/backer/7/website)[](https://opencollective.com/nest/backer/8/website)[](https://opencollective.com/nest/backer/9/website)[](https://opencollective.com/nest/backer/10/website)[](https://opencollective.com/nest/backer/11/website)[](https://opencollective.com/nest/backer/12/website)[](https://opencollective.com/nest/backer/13/website)[](https://opencollective.com/nest/backer/14/website)[](https://opencollective.com/nest/backer/15/website)[](https://opencollective.com/nest/backer/16/website)[](https://opencollective.com/nest/backer/17/website)[](https://opencollective.com/nest/backer/18/website)[](https://opencollective.com/nest/backer/19/website)[](https://opencollective.com/nest/backer/20/website)[](https://opencollective.com/nest/backer/21/website)[](https://opencollective.com/nest/backer/22/website)[](https://opencollective.com/nest/backer/23/website)[](https://opencollective.com/nest/backer/24/website)[](https://opencollective.com/nest/backer/25/website)[](https://opencollective.com/nest/backer/26/website)[](https://opencollective.com/nest/backer/27/website)[](https://opencollective.com/nest/backer/28/website)[](https://opencollective.com/nest/backer/29/website)

[Become a sponsor](https://opencollective.com/nest)

----
url: https://docs.nestjs.com/v8/security/cors
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [CORS](https://docs.nestjs.com/v8/security/cors#cors)
* [Getting started](https://docs.nestjs.com/v8/security/cors#getting-started)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/security/cors.md "Suggest Edits")

### CORS

Cross-origin resource sharing (CORS) is a mechanism that allows resources to be requested from another domain. Under the hood, Nest makes use of the Express [cors](https://github.com/expressjs/cors) package. This package provides various options that you can customize based on your requirements.

#### Getting started[#](/security/cors#getting-started)

To enable CORS, call the `enableCors()` method on the Nest application object.

```typescript

const app = await NestFactory.create(AppModule);
app.enableCors();
await app.listen(3000);
```

The `enableCors()` method takes an optional configuration object argument. The available properties of this object are described in the official [CORS](https://github.com/expressjs/cors#configuration-options) documentation. Another way is to pass a [callback function](https://github.com/expressjs/cors#configuring-cors-asynchronously) that lets you define the configuration object asynchronously based on the request (on the fly).

Alternatively, enable CORS via the `create()` method's options object. Set the `cors` property to `true` to enable CORS with default settings. Or, pass a [CORS configuration object](https://github.com/expressjs/cors#configuration-options) or [callback function](https://github.com/expressjs/cors#configuring-cors-asynchronously) as the `cors` property value to customize its behavior.

```typescript

const app = await NestFactory.create(AppModule, { cors: true });
await app.listen(3000);
```

Above method only applies to REST endpoints.

To enable CORS in GraphQL, set `cors` property to `true` or pass [CORS configuration object](https://github.com/expressjs/cors#configuration-options) or a [callback function](https://github.com/expressjs/cors#configuring-cors-asynchronously) as the `cors` property value when you import GraphQL module.

> **Warning**`CorsOptionsDelegate` solution is not working with the `apollo-server-fastify` package yet.

```typescript

GraphQLModule.forRoot({
  cors: {
    origin: 'http://localhost:3000',
    credentials: true,
  },
}),
```

----
url: https://docs.nestjs.com/v7/security/helmet
----

* [Helmet](https://docs.nestjs.com/v7/security/helmet#helmet)
* [Use with Express (default)](https://docs.nestjs.com/v7/security/helmet#use-with-express-default)
* [Use with Fastify](https://docs.nestjs.com/v7/security/helmet#use-with-fastify)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/security/helmet.md "Suggest Edits")

### Helmet

[Helmet](https://github.com/helmetjs/helmet) can help protect your app from some well-known web vulnerabilities by setting HTTP headers appropriately. Generally, Helmet is just a collection of 14 smaller middleware functions that set security-related HTTP headers (read [more](https://github.com/helmetjs/helmet#how-it-works)).

> **Hint** Note that applying `helmet` as global or registering it must come before other calls to `app.use()` or setup functions that may call `app.use()`). This is due to the way the underlying platform (i.e., Express or Fastify) works, where the order that middleware/routes are defined matters. If you use middleware like `helmet` or `cors` after you define a route, then that middleware will not apply to that route, it will only apply to middleware defined after the route.

#### Use with Express (default)[#](/security/helmet#use-with-express-default)

Start by installing the required package.

```bash

$ npm i --save helmet
```

Once the installation is complete, apply it as a global middleware.

```typescript

import * as helmet from 'helmet';
// somewhere in your initialization file
app.use(helmet());
```

> **Hint** If you are getting the `This expression is not callable` error while trying to import `Helmet`, you very likely have the `allowSyntheticDefaultImports` and `esModuleInterop` options set to `true` in your project's `tsconfig.json` file. If that's the case, change the import statement to: `import helmet from 'helmet'` instead.

#### Use with Fastify[#](/security/helmet#use-with-fastify)

If you are using the `FastifyAdapter`, install the [fastify-helmet](https://github.com/fastify/fastify-helmet) package:

```bash

$ npm i --save fastify-helmet
```

[fastify-helmet](https://github.com/fastify/fastify-helmet) should not be used as a middleware, but as a [Fastify plugin](https://www.fastify.io/docs/latest/Plugins/), i.e., by using `app.register()`:

```typescript

import * as helmet from 'fastify-helmet';
// somewhere in your initialization file
app.register(helmet);
```

> **Warning** When using `apollo-server-fastify` and `fastify-helmet`, there may be a problem with [CSP](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP) on the GraphQL playground, to solve this collision, configure the CSP as shown below:
>
> ```typescript
>
> app.register(helmet, {
>   contentSecurityPolicy: {
>     directives: {
>       defaultSrc: [`'self'`],
>       styleSrc: [`'self'`, `'unsafe-inline'`, 'cdn.jsdelivr.net', 'fonts.googleapis.com'],
>       fontSrc: [`'self'`, 'fonts.gstatic.com'],
>       imgSrc: [`'self'`, 'data:', 'cdn.jsdelivr.net'],
>       scriptSrc: [`'self'`, `https: 'unsafe-inline'`, `cdn.jsdelivr.net`],
>     },
>   },
> });
>
> // If you are not going to use CSP at all, you can use this:
> app.register(helmet, {
>   contentSecurityPolicy: false,
> });
> ```

----
url: https://docs.nestjs.com/websockets/gateways
----

[Skip to content](#content)

On this page

* [Gateways](https://docs.nestjs.com/websockets/gateways#gateways)
* [Installation](https://docs.nestjs.com/websockets/gateways#installation)
* [Overview](https://docs.nestjs.com/websockets/gateways#overview)
* [Multiple responses](https://docs.nestjs.com/websockets/gateways#multiple-responses)
* [Asynchronous responses](https://docs.nestjs.com/websockets/gateways#asynchronous-responses)
* [Lifecycle hooks](https://docs.nestjs.com/websockets/gateways#lifecycle-hooks)
* [Server and Namespace](https://docs.nestjs.com/websockets/gateways#server-and-namespace)
* [Request-scoped gateways](https://docs.nestjs.com/websockets/gateways#request-scoped-gateways)
* [Example](https://docs.nestjs.com/websockets/gateways#example)

### Gateways

Most of the concepts discussed elsewhere in this documentation, such as dependency injection, decorators, exception filters, pipes, guards, and interceptors, apply equally to gateways. Wherever possible, Nest abstracts implementation details so that the same components can run across HTTP-based platforms, WebSockets, and microservices. This section covers the aspects of Nest that are specific to WebSockets.

In Nest, a gateway is a class annotated with the `@WebSocketGateway()` decorator. Gateways are platform-agnostic, so they work with any WebSockets library once an adapter exists for it. Nest supports two WebSocket platforms out of the box: [socket.io](https://github.com/socketio/socket.io) and [ws](https://github.com/websockets/ws). Choose the one that best suits your needs. You can also build your own adapter by following the [adapters guide](/websockets/adapter).

> **Hint** Gateways are [providers](/providers): they can inject dependencies through the class constructor, and other classes (providers and controllers) can inject them.

#### Installation[#](/websockets/gateways#installation)

To start building WebSockets-based applications, first install the required package:

JS TS

```typescript

$ npm i --save @nestjs/websockets @nestjs/platform-socket.io
```

```typescript

$ npm i --save @nestjs/websockets @nestjs/platform-socket.io
```

#### Overview[#](/websockets/gateways#overview)

By default, each gateway listens on the same port as the **HTTP server**. To use a different port, pass it as the first argument to the decorator, e.g., `@WebSocketGateway(80)`, where `80` is the chosen port number. You can also set the [namespace](https://socket.io/docs/v4/namespaces/) used by the gateway:

```typescript

@WebSocketGateway(80, { namespace: 'events' })
```

> **Warning** Gateways are not instantiated until they are referenced in the providers array of an existing module.

The second argument of the `@WebSocketGateway()` decorator passes any supported [server option](https://socket.io/docs/v4/server-options/) to the socket server constructor. If you don't need a custom port, pass the options object as the only argument.

```typescript

@WebSocketGateway(81, { transports: ['websocket'] })
```

The gateway is now listening, but it doesn't subscribe to any incoming messages yet. Let's create a handler that subscribes to `events` messages and responds to the client with the same data.

events.gateway.ts

JS TS

```typescript

@SubscribeMessage('events')
handleEvent(@MessageBody() data: string): string {
  return data;
}
```

```typescript

@Bind(MessageBody())
@SubscribeMessage('events')
handleEvent(data) {
  return data;
}
```

> **Hint** The `@SubscribeMessage()` and `@MessageBody()` decorators are imported from the `@nestjs/websockets` package.

Once the gateway is created, register it in a module.

events.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { EventsGateway } from './events.gateway.js';

@Module({
  providers: [EventsGateway]
})
export class EventsModule {}
```

You can also pass a property key to the `@MessageBody()` decorator to extract that property from the incoming message body:

events.gateway.ts

JS TS

```typescript

@SubscribeMessage('events')
handleEvent(@MessageBody('id') id: number): number {
  // id === messageBody.id
  return id;
}
```

```typescript

@Bind(MessageBody('id'))
@SubscribeMessage('events')
handleEvent(id) {
  // id === messageBody.id
  return id;
}
```

If you prefer not to use decorators, the following code is functionally equivalent:

events.gateway.ts

JS TS

```typescript

@SubscribeMessage('events')
handleEvent(client: Socket, data: string): string {
  return data;
}
```

```typescript

@SubscribeMessage('events')
handleEvent(client, data) {
  return data;
}
```

In the example above, the `handleEvent()` method takes two arguments. The first is a platform-specific [socket instance](https://socket.io/docs/v4/server-api/#socket), and the second is the data received from the client. This approach isn't recommended, because it requires mocking the `socket` instance in each unit test.

When the `events` message is received, the handler sends an acknowledgment with the same data that was sent over the network. You can also emit messages with a library-specific API, e.g., the `client.emit()` method. To access the connected socket instance, use the `@ConnectedSocket()` decorator.

events.gateway.ts

JS TS

```typescript

@SubscribeMessage('events')
handleEvent(
  @MessageBody() data: string,
  @ConnectedSocket() client: Socket,
): string {
  return data;
}
```

```typescript

@Bind(MessageBody(), ConnectedSocket())
@SubscribeMessage('events')
handleEvent(data, client) {
  return data;
}
```

> **Hint** The `@ConnectedSocket()` decorator is imported from the `@nestjs/websockets` package.

However, messages you emit directly through the socket bypass interceptors, which only see the handler's return value. If you don't want to respond to the client, omit the `return` statement (or return `null` or `undefined`). Other falsy values, such as `false` or `0`, are still sent as a response.

When a client emits the message as follows, the `handleEvent()` method is executed:

```typescript

socket.emit('events', { name: 'Nest' });
```

To receive the response sent by the handler above, the client must attach a corresponding acknowledgment callback:

```typescript

socket.emit('events', { name: 'Nest' }, (data) => console.log(data));
```

Returning a value from a message handler implicitly sends an acknowledgment, but advanced scenarios often require direct control over the acknowledgment callback.

The `@Ack()` parameter decorator injects the `ack` callback function directly into a message handler. When you use it, Nest doesn't send an acknowledgment based on the return value, so you must call `ack()` yourself. Without the decorator, the callback is passed as the third argument of the method.

events.gateway.ts

JS TS

```typescript

@SubscribeMessage('events')
handleEvent(
  @MessageBody() data: string,
  @Ack() ack: (response: { status: string; data: string }) => void,
) {
  ack({ status: 'received', data });
}
```

```typescript

@Bind(MessageBody(), Ack())
@SubscribeMessage('events')
handleEvent(data, ack) {
  ack({ status: 'received', data });
}
```

#### Multiple responses[#](/websockets/gateways#multiple-responses)

The acknowledgment is dispatched only once, and native WebSocket implementations don't support it. To work around these limitations, return an object with two properties: `event`, the name of the emitted event, and `data`, the payload to forward to the client.

events.gateway.ts

JS TS

```typescript

@SubscribeMessage('events')
handleEvent(@MessageBody() data: unknown): WsResponse<unknown> {
  const event = 'events';
  return { event, data };
}
```

```typescript

@Bind(MessageBody())
@SubscribeMessage('events')
handleEvent(data) {
  const event = 'events';
  return { event, data };
}
```

> **Hint** The `WsResponse` interface is imported from the `@nestjs/websockets` package.

> **Warning** If your `data` field relies on `ClassSerializerInterceptor`, return a class instance that implements `WsResponse`, because the interceptor ignores plain JavaScript object responses.

To receive the incoming response(s), the client must add another event listener.

```typescript

socket.on('events', (data) => console.log(data));
```

#### Asynchronous responses[#](/websockets/gateways#asynchronous-responses)

Message handlers can respond either synchronously or **asynchronously**, so `async` methods are supported. A message handler can also return an `Observable`, in which case each emitted value is sent to the client until the stream completes.

events.gateway.ts

JS TS

```typescript

@SubscribeMessage('events')
onEvent(@MessageBody() data: unknown): Observable<WsResponse<number>> {
  const event = 'events';
  const response = [1, 2, 3];

  return from(response).pipe(
    map(data => ({ event, data })),
  );
}
```

```typescript

@Bind(MessageBody())
@SubscribeMessage('events')
onEvent(data) {
  const event = 'events';
  const response = [1, 2, 3];

  return from(response).pipe(
    map(data => ({ event, data })),
  );
}
```

In the example above, the message handler responds **3 times** (once for each item in the array).

#### Lifecycle hooks[#](/websockets/gateways#lifecycle-hooks)

Gateways support three lifecycle hooks. Each has a corresponding interface, described in the following table:

|                       |                                                                                                                             |
| --------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| `OnGatewayInit`       | Requires the `afterInit()` method, which receives the library-specific server instance as an argument.                      |
| `OnGatewayConnection` | Requires the `handleConnection()` method, which receives the library-specific client socket instance as its first argument. |
| `OnGatewayDisconnect` | Requires the `handleDisconnect()` method, which receives the library-specific client socket instance as its first argument. |

> **Hint** Each lifecycle interface is exposed from the `@nestjs/websockets` package.

> **Warning** Nest doesn't wait for an async `handleConnection()` to finish before it handles the client's messages, so the hook isn't a gate: messages that arrive before it disconnects the client are still handled. To check each message, bind [guards](/websockets/guards) to the message handlers. To reject a client before any of its messages are handled, use connection-level middleware instead: socket.io's `server.use()` in `afterInit()`, or, with `WsAdapter`, a `verifyClient` function in the `@WebSocketGateway()` options.

#### Server and Namespace[#](/websockets/gateways#server-and-namespace)

Occasionally, you may need direct access to the native, **platform-specific** server instance. Nest passes it as an argument to the `afterInit()` method (`OnGatewayInit` interface). Alternatively, use the `@WebSocketServer()` decorator.

```typescript

@WebSocketServer()
server: Server;
```

You can also retrieve the corresponding namespace:

```typescript

@WebSocketGateway({ namespace: 'my-namespace' })
export class EventsGateway {
  @WebSocketServer()
  namespace: Namespace;
}
```

The `@WebSocketServer()` decorator injects a server instance based on the metadata stored by the `@WebSocketGateway()` decorator. If you pass the `namespace` option to `@WebSocketGateway()`, `@WebSocketServer()` injects a `Namespace` instance instead of a `Server` instance.

> **Notice** The `@WebSocketServer()` decorator is imported from the `@nestjs/websockets` package.

Nest assigns the server instance to this property once it's ready to use.

## Official enterprise support

* Providing technical guidance
* Performing in-depth code reviews
* Mentoring team members
* Advising best practices

[Explore more](https://enterprise.nestjs.com "Enterprise | NestJS - A progressive Node.js framework")

#### Request-scoped gateways[#](/websockets/gateways#request-scoped-gateways)

Starting with NestJS v12, gateways support [request-scoped](/fundamentals/injection-scopes) providers. Nest creates a new instance of every request-scoped dependency per connected socket. That instance lives as long as the connection does, so it can safely hold per-connection state.

Inject the socket itself with the `REQUEST` token, the same way you inject the HTTP request into a request-scoped HTTP provider:

connection-state.service.ts

JS TS

```typescript

import { Inject, Injectable, Scope } from '@nestjs/common';
import { REQUEST } from '@nestjs/core';
import { Socket } from 'socket.io';

@Injectable({ scope: Scope.REQUEST })
export class ConnectionStateService {
  private sequence = 0;

  constructor(@Inject(REQUEST) private readonly client: Socket) {}

  next() {
    return { clientId: this.client.id, sequence: ++this.sequence };
  }
}
```

The gateway then injects it like any other provider:

events.gateway.ts

JS TS

```typescript

@WebSocketGateway()
export class EventsGateway {
  constructor(private readonly connectionState: ConnectionStateService) {}

  handleConnection(client: Socket) {
    client.emit('connected', this.connectionState.next());
  }

  @SubscribeMessage('state')
  onState() {
    return { event: 'state', data: this.connectionState.next() };
  }
}
```

Because the scope is tied to the connection rather than to a single message, the `sequence` counter above increments across every message received on that socket, while a second client gets its own independent instance. Nest tears the request-scoped instances down when the socket disconnects.

> **Notice** As with HTTP, request-scoped providers add per-connection instantiation overhead. Use the default singleton scope unless you need per-connection state.

#### Example[#](/websockets/gateways#example)

A working example is available in the [02-gateways sample](https://github.com/nestjs/nest/tree/master/sample/02-gateways).

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/websockets/gateways.md)

----
url: https://docs.nestjs.com/v9/techniques/cookies
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Cookies](https://docs.nestjs.com/v9/techniques/cookies#cookies)
* [Use with Express (default)](https://docs.nestjs.com/v9/techniques/cookies#use-with-express-default)
* [Use with Fastify](https://docs.nestjs.com/v9/techniques/cookies#use-with-fastify)
* [Creating a custom decorator (cross-platform)](https://docs.nestjs.com/v9/techniques/cookies#creating-a-custom-decorator-cross-platform)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/techniques/cookies.md "Suggest Edits")

### Cookies

An **HTTP cookie** is a small piece of data stored by the user's browser. Cookies were designed to be a reliable mechanism for websites to remember stateful information. When the user visits the website again, the cookie is automatically sent with the request.

#### Use with Express (default)[#](/techniques/cookies#use-with-express-default)

First install the [required package](https://github.com/expressjs/cookie-parser) (and its types for TypeScript users):

```shell

$ npm i cookie-parser
$ npm i -D @types/cookie-parser
```

Once the installation is complete, apply the `cookie-parser` middleware as global middleware (for example, in your `main.ts` file).

```typescript

import cookieParser from 'cookie-parser';
// somewhere in your initialization file
app.use(cookieParser());
```

You can pass several options to the `cookieParser` middleware:

* `secret` a string or array used for signing cookies. This is optional and if not specified, will not parse signed cookies. If a string is provided, this is used as the secret. If an array is provided, an attempt will be made to unsign the cookie with each secret in order.
* `options` an object that is passed to `cookie.parse` as the second option. See [cookie](https://www.npmjs.org/package/cookie) for more information.

The middleware will parse the `Cookie` header on the request and expose the cookie data as the property `req.cookies` and, if a secret was provided, as the property `req.signedCookies`. These properties are name value pairs of the cookie name to cookie value.

When secret is provided, this module will unsign and validate any signed cookie values and move those name value pairs from req.cookies into `req.signedCookies`. A signed cookie is a cookie that has a value prefixed with `s:`. Signed cookies that fail signature validation will have the value `false` instead of the tampered value.

With this in place, you can now read cookies from within the route handlers, as follows:

```typescript

@Get()
findAll(@Req() request: Request) {
  console.log(request.cookies); // or "request.cookies['cookieKey']"
  // or console.log(request.signedCookies);
}
```

> **Hint** The `@Req()` decorator is imported from the `@nestjs/common`, while `Request` from the `express` package.

To attach a cookie to an outgoing response, use the `Response#cookie()` method:

```typescript

@Get()
findAll(@Res({ passthrough: true }) response: Response) {
  response.cookie('key', 'value')
}
```

> **Warning** If you want to leave the response handling logic to the framework, remember to set the `passthrough` option to `true`, as shown above. Read more [here](/controllers#appendix-library-specific-approach).

> **Hint** The `@Res()` decorator is imported from the `@nestjs/common`, while `Response` from the `express` package.

#### Use with Fastify[#](/techniques/cookies#use-with-fastify)

First install the required package:

```shell

$ npm i @fastify/cookie
```

Once the installation is complete, register the `@fastify/cookie` plugin:

```typescript

import fastifyCookie from '@fastify/cookie';

// somewhere in your initialization file
const app = await NestFactory.create<NestFastifyApplication>(
  AppModule,
  new FastifyAdapter(),
);
await app.register(fastifyCookie, {
  secret: 'my-secret', // for cookies signature
});
```

With this in place, you can now read cookies from within the route handlers, as follows:

```typescript

@Get()
findAll(@Req() request: FastifyRequest) {
  console.log(request.cookies); // or "request.cookies['cookieKey']"
}
```

> **Hint** The `@Req()` decorator is imported from the `@nestjs/common`, while `FastifyRequest` from the `fastify` package.

To attach a cookie to an outgoing response, use the `FastifyReply#setCookie()` method:

```typescript

@Get()
findAll(@Res({ passthrough: true }) response: FastifyReply) {
  response.setCookie('key', 'value')
}
```

To read more about `FastifyReply#setCookie()` method, check out this [page](https://github.com/fastify/fastify-cookie#sending).

> **Warning** If you want to leave the response handling logic to the framework, remember to set the `passthrough` option to `true`, as shown above. Read more [here](/controllers#appendix-library-specific-approach).

> **Hint** The `@Res()` decorator is imported from the `@nestjs/common`, while `FastifyReply` from the `fastify` package.

#### Creating a custom decorator (cross-platform)[#](/techniques/cookies#creating-a-custom-decorator-cross-platform)

To provide a convenient, declarative way of accessing incoming cookies, we can create a [custom decorator](/v9/custom-decorators).

```typescript

import { createParamDecorator, ExecutionContext } from '@nestjs/common';

export const Cookies = createParamDecorator(
  (data: string, ctx: ExecutionContext) => {
    const request = ctx.switchToHttp().getRequest();
    return data ? request.cookies?.[data] : request.cookies;
  },
);
```

The `@Cookies()` decorator will extract all cookies, or a named cookie from the `req.cookies` object and populate the decorated parameter with that value.

With this in place, we can now use the decorator in a route handler signature, as follows:

```typescript

@Get()
findAll(@Cookies('name') name: string) {}
```

----
url: https://docs.nestjs.com/v8/graphql/other-features
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Other features](https://docs.nestjs.com/v8/graphql/other-features#other-features)
* [Overview](https://docs.nestjs.com/v8/graphql/other-features#overview)
* [Execution context](https://docs.nestjs.com/v8/graphql/other-features#execution-context)
* [Exception filters](https://docs.nestjs.com/v8/graphql/other-features#exception-filters)
* [Custom decorators](https://docs.nestjs.com/v8/graphql/other-features#custom-decorators)
* [Execute enhancers at the field resolver level](https://docs.nestjs.com/v8/graphql/other-features#execute-enhancers-at-the-field-resolver-level)
* [Creating a custom driver](https://docs.nestjs.com/v8/graphql/other-features#creating-a-custom-driver)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/guards-interceptors.md "Suggest Edits")

### Other features

In the GraphQL world, there is a lot of debate about handling issues like **authentication**, or **side-effects** of operations. Should we handle things inside the business logic? Should we use a higher-order function to enhance queries and mutations with authorization logic? Or should we use [schema directives](https://www.apollographql.com/docs/apollo-server/schema/directives/)? There is no single one-size-fits-all answer to these questions.

Nest helps address these issues with its cross-platform features like [guards](/v8/guards) and [interceptors](/v8/interceptors). The philosophy is to reduce redundancy and provide tooling that helps create well-structured, readable, and consistent applications.

#### Overview[#](/graphql/other-features#overview)

You can use standard [guards](/v8/guards), [interceptors](/v8/interceptors), [filters](/v8/exception-filters) and [pipes](/v8/pipes) in the same fashion with GraphQL as with any RESTful application. Additionally, you can easily create your own decorators by leveraging the [custom decorators](/v8/custom-decorators) feature. Let's take a look at a sample GraphQL query handler.

```typescript

@Query('author')
@UseGuards(AuthGuard)
async getAuthor(@Args('id', ParseIntPipe) id: number) {
  return this.authorsService.findOneById(id);
}
```

As you can see, GraphQL works with both guards and pipes in the same way as HTTP REST handlers. Because of this, you can move your authentication logic to a guard; you can even reuse the same guard class across both a REST and GraphQL API interface. Similarly, interceptors work across both types of applications in the same way:

```typescript

@Mutation()
@UseInterceptors(EventsInterceptor)
async upvotePost(@Args('postId') postId: number) {
  return this.postsService.upvoteById({ id: postId });
}
```

#### Execution context[#](/graphql/other-features#execution-context)

Since GraphQL receives a different type of data in the incoming request, the [execution context](https://docs.nestjs.com/fundamentals/execution-context) received by both guards and interceptors is somewhat different with GraphQL vs. REST. GraphQL resolvers have a distinct set of arguments: `root`, `args`, `context`, and `info`. Thus guards and interceptors must transform the generic `ExecutionContext` to a `GqlExecutionContext`. This is straightforward:

```typescript

import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common';
import { GqlExecutionContext } from '@nestjs/graphql';

@Injectable()
export class AuthGuard implements CanActivate {
  canActivate(context: ExecutionContext): boolean {
    const ctx = GqlExecutionContext.create(context);
    return true;
  }
}
```

The GraphQL context object returned by `GqlExecutionContext.create()` exposes a **get** method for each GraphQL resolver argument (e.g., `getArgs()`, `getContext()`, etc). Once transformed, we can easily pick out any GraphQL argument for the current request.

#### Exception filters[#](/graphql/other-features#exception-filters)

Nest standard [exception filters](/v8/exception-filters) are compatible with GraphQL applications as well. As with `ExecutionContext`, GraphQL apps should transform the `ArgumentsHost` object to a `GqlArgumentsHost` object.

```typescript

@Catch(HttpException)
export class HttpExceptionFilter implements GqlExceptionFilter {
  catch(exception: HttpException, host: ArgumentsHost) {
    const gqlHost = GqlArgumentsHost.create(host);
    return exception;
  }
}
```

> **Hint** Both `GqlExceptionFilter` and `GqlArgumentsHost` are imported from the `@nestjs/graphql` package.

Note that unlike the REST case, you don't use the native `response` object to generate a response.

#### Custom decorators[#](/graphql/other-features#custom-decorators)

As mentioned, the [custom decorators](/v8/custom-decorators) feature works as expected with GraphQL resolvers.

```typescript

export const User = createParamDecorator(
  (data: unknown, ctx: ExecutionContext) =>
    GqlExecutionContext.create(ctx).getContext().user,
);
```

Use the `@User()` custom decorator as follows:

```typescript

@Mutation()
async upvotePost(
  @User() user: UserEntity,
  @Args('postId') postId: number,
) {}
```

> **Hint** In the above example, we have assumed that the `user` object is assigned to the context of your GraphQL application.

#### Execute enhancers at the field resolver level[#](/graphql/other-features#execute-enhancers-at-the-field-resolver-level)

In the GraphQL context, Nest does not run **enhancers** (the generic name for interceptors, guards and filters) at the field level [see this issue](https://github.com/nestjs/graphql/issues/320#issuecomment-511193229): they only run for the top level `@Query()`/`@Mutation()` method. You can tell Nest to execute interceptors, guards or filters for methods annotated with `@ResolveField()` by setting the `fieldResolverEnhancers` option in `GqlModuleOptions`. Pass it a list of `'interceptors'`, `'guards'`, and/or `'filters'` as appropriate:

```typescript

GraphQLModule.forRoot({
  fieldResolverEnhancers: ['interceptors']
}),
```

> **Warning** Enabling enhancers for field resolvers can cause performance issues when you are returning lots of records and your field resolver is executed thousands of times. For this reason, when you enable `fieldResolverEnhancers`, we advise you to skip execution of enhancers that are not strictly necessary for your field resolvers. You can do this using the following helper function:

```typescript

export function isResolvingGraphQLField(context: ExecutionContext): boolean {
  if (context.getType<GqlContextType>() === 'graphql') {
    const gqlContext = GqlExecutionContext.create(context);
    const info = gqlContext.getInfo();
    const parentType = info.parentType.name;
    return parentType !== 'Query' && parentType !== 'Mutation';
  }
  return false;
}
```

#### Creating a custom driver[#](/graphql/other-features#creating-a-custom-driver)

Nest provides two official drivers out-of-the-box: `@nestjs/apollo` and `@nestjs/mercurius`, as well as an API allowing developers to build new **custom drivers**. With a custom driver, you can integrate any GraphQL library or extend the existing integration, adding extra features on top.

For example, to integrate the `express-graphql` package, you could create the following driver class:

```typescript

import { AbstractGraphQLDriver, GqlModuleOptions } from '@nestjs/graphql';
import { graphqlHTTP } from 'express-graphql';

class ExpressGraphQLDriver extends AbstractGraphQLDriver {
  async start(options: GqlModuleOptions<any>): Promise<void> {
    options = await this.graphQlFactory.mergeWithSchema(options);

    const { httpAdapter } = this.httpAdapterHost;
    httpAdapter.use(
      '/graphql',
      graphqlHTTP({
        schema: options.schema,
        graphiql: true,
      }),
    );
  }

  async stop() {}
}
```

And then use it as follows:

```typescript

GraphQLModule.forRoot({
  driver: ExpressGraphQLDriver,
});
```

----
url: https://docs.nestjs.com/custom-decorators
----

[Skip to content](#content)

On this page

* [Custom route decorators](https://docs.nestjs.com/custom-decorators#custom-route-decorators)
* [Param decorators](https://docs.nestjs.com/custom-decorators#param-decorators)
* [Passing data](https://docs.nestjs.com/custom-decorators#passing-data)
* [Working with pipes](https://docs.nestjs.com/custom-decorators#working-with-pipes)
* [Decorator composition](https://docs.nestjs.com/custom-decorators#decorator-composition)

### Custom route decorators

Nest is built around a language feature called **decorators**. Decorators are well established in many programming languages but are still relatively new to JavaScript. For a deeper look at how decorators work, see [this article](https://medium.com/google-developers/exploring-es7-decorators-76ecb65fb841). Here's a simple definition:

> An ES2016 decorator is an expression which returns a function and can take a target, name and property descriptor as arguments. You apply it by prefixing the decorator with an `@` character and placing this at the very top of what you are trying to decorate. Decorators can be defined for either a class, a method or a property.

#### Param decorators[#](/custom-decorators#param-decorators)

Nest provides a set of **param decorators** that you can use in HTTP route handlers. The following table lists them along with the plain Express (or Fastify) objects they represent:

|                              |                                      |
| ---------------------------- | ------------------------------------ |
| `@Request(), @Req()`         | `req`                                |
| `@Response(), @Res()`        | `res`                                |
| `@Next()`                    | `next`                               |
| `@Session()`                 | `req.session`                        |
| `@Param(param?: string)`     | `req.params` / `req.params[param]`   |
| `@Body(param?: string)`      | `req.body` / `req.body[param]`       |
| `@Query(param?: string)`     | `req.query` / `req.query[param]`     |
| `@Headers(param?: string)`   | `req.headers` / `req.headers[param]` |
| `@Ip()`                      | `req.ip`                             |
| `@HostParam(param?: string)` | `req.hosts` / `req.hosts[param]`     |

You can also create your own **custom decorators**. To see why this is useful, consider a common pattern in Node.js applications: properties are attached to the **request** object and then extracted manually in each route handler, with code like the following:

```typescript

const user = req.user;
```

To make your code more readable and transparent, you can create a `@User()` decorator and reuse it across all of your controllers:

user.decorator.ts

JS TS

```typescript

import { createParamDecorator, ExecutionContext } from '@nestjs/common';

export const User = createParamDecorator(
  (data: unknown, ctx: ExecutionContext) => {
    const request = ctx.switchToHttp().getRequest();
    return request.user;
  },
);
```

You can then use it wherever you need it:

JS TS

```typescript

@Get()
async findOne(@User() user: UserEntity) {
  console.log(user);
}
```

```typescript

@Get()
@Bind(User())
async findOne(user) {
  console.log(user);
}
```

#### Passing data[#](/custom-decorators#passing-data)

When the behavior of your decorator depends on some condition, use the `data` parameter to pass an argument to the decorator's factory function. One use case is a custom decorator that extracts a property from the request object by key. Suppose, for example, that your [authentication layer](/security/authentication#read-the-current-user) validates requests and attaches a user entity to the request object. The user entity for an authenticated request might look like this:

```json

{
  "id": 101,
  "firstName": "Alan",
  "lastName": "Turing",
  "email": "alan@email.com",
  "roles": ["admin"]
}
```

Let's define a decorator that takes a property name as a key and returns the associated value if it exists (or `undefined` if it doesn't, or if the `user` object has not been created):

user.decorator.ts

JS TS

```typescript

import { createParamDecorator, ExecutionContext } from '@nestjs/common';

export const User = createParamDecorator(
  (data: string, ctx: ExecutionContext) => {
    const request = ctx.switchToHttp().getRequest();
    const user = request.user;

    return data ? user?.[data] : user;
  },
);
```

```typescript

import { createParamDecorator } from '@nestjs/common';

export const User = createParamDecorator((data, ctx) => {
  const request = ctx.switchToHttp().getRequest();
  const user = request.user;

  return data ? user && user[data] : user;
});
```

You can then access a particular property through the `@User()` decorator in the controller:

JS TS

```typescript

@Get()
async findOne(@User('firstName') firstName: string) {
  console.log(`Hello ${firstName}`);
}
```

```typescript

@Get()
@Bind(User('firstName'))
async findOne(firstName) {
  console.log(`Hello ${firstName}`);
}
```

You can use the same decorator with different keys to access different properties. If the `user` object is deep or complex, this keeps route handler implementations simpler and more readable.

> **Hint**`createParamDecorator<T>()` is generic, so you can enforce type safety explicitly, e.g., `createParamDecorator<string>((data, ctx) => ...)`. Alternatively, specify a parameter type in the factory function, e.g., `createParamDecorator((data: string, ctx) => ...)`. If you omit both, `data` is typed as `any`.

#### Working with pipes[#](/custom-decorators#working-with-pipes)

Nest treats custom param decorators the same way as the built-in ones (`@Body()`, `@Param()`, and `@Query()`). This means pipes also run for parameters annotated with custom decorators (in our examples, the `user` argument). You can also apply a pipe directly to the custom decorator:

JS TS

```typescript

@Get()
async findOne(
  @User(new ValidationPipe({ validateCustomDecorators: true }))
  user: UserEntity,
) {
  console.log(user);
}
```

```typescript

@Get()
@Bind(User(new ValidationPipe({ validateCustomDecorators: true })))
async findOne(user) {
  console.log(user);
}
```

> **Hint** By default, `ValidationPipe` does not validate arguments annotated with custom decorators. That's why the example above sets the `validateCustomDecorators` option to `true`.

Custom decorators also accept the `schema` option of the built-in parameter decorators. Pass a [Standard Schema](https://standardschema.dev/) compatible schema, such as a Zod schema, and a `StandardSchemaValidationPipe` with the `validateCustomDecorators` option enabled validates the decorator's value against it:

```typescript

@Get()
async findOne(@User('email', { schema: z.email() }) email: string) {
  console.log(email);
}
```

See [Validating custom decorators](/application/validation#validating-custom-decorators) for details.

#### Decorator composition[#](/custom-decorators#decorator-composition)

Nest provides the `applyDecorators()` helper to compose multiple decorators. For example, suppose you want to combine all authentication-related decorators into a single decorator:

auth.decorator.ts

JS TS

```typescript

import { applyDecorators, SetMetadata, UseGuards } from '@nestjs/common';
import { ApiBearerAuth, ApiUnauthorizedResponse } from '@nestjs/swagger';

export function Auth(...roles: Role[]) {
  return applyDecorators(
    SetMetadata('roles', roles),
    UseGuards(AuthGuard, RolesGuard),
    ApiBearerAuth(),
    ApiUnauthorizedResponse({ description: 'Unauthorized' }),
  );
}
```

```typescript

import { applyDecorators, SetMetadata, UseGuards } from '@nestjs/common';
import { ApiBearerAuth, ApiUnauthorizedResponse } from '@nestjs/swagger';

export function Auth(...roles) {
  return applyDecorators(
    SetMetadata('roles', roles),
    UseGuards(AuthGuard, RolesGuard),
    ApiBearerAuth(),
    ApiUnauthorizedResponse({ description: 'Unauthorized' }),
  );
}
```

You can then use this custom `@Auth()` decorator as follows:

```typescript

@Get('users')
@Auth('admin')
findAllUsers() {}
```

This applies all four decorators with a single declaration.

> **Warning** The `@ApiHideProperty()` decorator from the `@nestjs/swagger` package is not composable and does not work correctly with the `applyDecorators()` function.

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/custom-decorators.md)

----
url: https://docs.nestjs.com/websockets/interceptors
----

[Skip to content](#content)

On this page

* [Interceptors](https://docs.nestjs.com/websockets/interceptors#interceptors)

[](https://srv.carbonads.net/ads/click/x/GTND4277CVSD527IF6BLYKQUF67D62JJCWBIKZ3JCAAI623ICYSD553KC6YD4K3EF6YDE5QWCTBDK23MCT7D4K77HEYI55QLCYAILKJECTNCYBZ52K)[Take a tutorial on how to deploy VMs, load balancers, Java apps, websites or LAMP stacks. ](https://srv.carbonads.net/ads/click/x/GTND4277CVSD527IF6BLYKQUF67D62JJCWBIKZ3JCAAI623ICYSD553KC6YD4K3EF6YDE5QWCTBDK23MCT7D4K77HEYI55QLCYAILKJECTNCYBZ52K)[ads via Carbon](http://carbonads.net/?utm_source=nestjscom\&utm_medium=ad_via_link\&utm_campaign=in_unit\&utm_term=carbon)

### Interceptors

There is no difference between [regular interceptors](/interceptors) and WebSocket interceptors. The following example uses a manually instantiated method-scoped interceptor. As with HTTP-based applications, you can also use gateway-scoped interceptors (i.e., decorate the gateway class with `@UseInterceptors()`). Global interceptors registered with `app.useGlobalInterceptors()` or the `APP_INTERCEPTOR` token apply to gateways as well.

JS TS

```typescript

@UseInterceptors(new TransformInterceptor())
@SubscribeMessage('events')
handleEvent(client: Client, data: unknown): WsResponse<unknown> {
  const event = 'events';
  return { event, data };
}
```

```typescript

@UseInterceptors(new TransformInterceptor())
@SubscribeMessage('events')
handleEvent(client, data) {
  const event = 'events';
  return { event, data };
}
```

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/websockets/interceptors.md)

----
url: https://docs.nestjs.com/v11/websockets/pipes
----

* [Pipes](https://docs.nestjs.com/v11/websockets/pipes#pipes)
* [Binding pipes](https://docs.nestjs.com/v11/websockets/pipes#binding-pipes)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/websockets/pipes.md "Suggest Edits")

### Pipes

There is no fundamental difference between [regular pipes](/v11/pipes) and web sockets pipes. The only difference is that instead of throwing `HttpException`, you should use `WsException`. In addition, all pipes will be only applied to the `data` parameter (because validating or transforming `client` instance is useless).

> **Hint** The `WsException` class is exposed from `@nestjs/websockets` package.

#### Binding pipes[#](/websockets/pipes#binding-pipes)

The following example uses a manually instantiated method-scoped pipe. Just as with HTTP based applications, you can also use gateway-scoped pipes (i.e., prefix the gateway class with a `@UsePipes()` decorator).

JS TS

```typescript

@UsePipes(new ValidationPipe({ exceptionFactory: (errors) => new WsException(errors) }))
@SubscribeMessage('events')
handleEvent(client: Client, data: unknown): WsResponse<unknown> {
  const event = 'events';
  return { event, data };
}
```

```typescript

@UsePipes(new ValidationPipe({ exceptionFactory: (errors) => new WsException(errors) }))
@SubscribeMessage('events')
handleEvent(client, data) {
  const event = 'events';
  return { event, data };
}
```

----
url: https://docs.nestjs.com/v8/fundamentals/platform-agnosticism
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Platform agnosticism](https://docs.nestjs.com/v8/fundamentals/platform-agnosticism#platform-agnosticism)
* [Build once, use everywhere](https://docs.nestjs.com/v8/fundamentals/platform-agnosticism#build-once-use-everywhere)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/fundamentals/platform-agnosticism.md "Suggest Edits")

### Platform agnosticism

Nest is a platform-agnostic framework. This means you can develop **reusable logical parts** that can be used across different types of applications. For example, most components can be re-used without change across different underlying HTTP server frameworks (e.g., Express and Fastify), and even across different *types* of applications (e.g., HTTP server frameworks, Microservices with different transport layers, and Web Sockets).

#### Build once, use everywhere[#](/fundamentals/platform-agnosticism#build-once-use-everywhere)

The **Overview** section of the documentation primarily shows coding techniques using HTTP server frameworks (e.g., apps providing a REST API or providing an MVC-style server-side rendered app). However, all those building blocks can be used on top of different transport layers ([microservices](/v8/microservices/basics) or [websockets](/v8/websockets/gateways)).

Furthermore, Nest comes with a dedicated [GraphQL](/v8/graphql/quick-start) module. You can use GraphQL as your API layer interchangeably with providing a REST API.

In addition, the [application context](/v8/application-context) feature helps to create any kind of Node.js application - including things like CRON jobs and CLI apps - on top of Nest.

Nest aspires to be a full-fledged platform for Node.js apps that brings a higher-level of modularity and reusability to your applications. Build once, use everywhere!

----
url: https://docs.nestjs.com/v7/microservices/custom-transport
----

* [Custom transporters](https://docs.nestjs.com/v7/microservices/custom-transport#custom-transporters)
* [Creating a strategy](https://docs.nestjs.com/v7/microservices/custom-transport#creating-a-strategy)
* [Client proxy](https://docs.nestjs.com/v7/microservices/custom-transport#client-proxy)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/microservices/custom-transport.md "Suggest Edits")

### Custom transporters

Nest provides a variety of **transporters** out-of-the-box, as well as an API allowing developers to build new custom transport strategies. Transporters enable you to connect components over a network using a pluggable communications layer and a very simple application-level message protocol (read full [article](https://dev.to/nestjs/integrate-nestjs-with-external-services-using-microservice-transporters-part-1-p3)).

> **Hint** Building a microservice with Nest does not necessarily mean you must use the `@nestjs/microservices` package. For example, if you want to communicate with external services (let's say other microservices written in different languages), you may not need all the features provided by `@nestjs/microservice` library. In fact, if you don't need decorators (`@EventPattern` or `@MessagePattern`) that let you declaratively define subscribers, running a [Standalone Application](/v7/application-context) and manually maintaining connection/subscribing to channels should be enough for most use-cases and will provide you with more flexibility.

With a custom transporter, you can integrate any messaging system/protocol (including Google Cloud Pub/Sub, Amazon Kinesis, and others) or extend the existing one, adding extra features on top (for example, [QoS](https://github.com/mqttjs/MQTT.js/blob/master/README.md#qos) for MQTT).

> **Hint** To better understand how Nest microservices work and how you can extend the capabilities of existing transporters, we recommend reading the [NestJS Microservices in Action](https://dev.to/johnbiundo/series/4724) and [Advanced NestJS Microservices](https://dev.to/nestjs/part-1-introduction-and-setup-1a2l) article series.

#### Creating a strategy[#](/microservices/custom-transport#creating-a-strategy)

First, let's define a class representing our custom transporter.

```typescript

import { CustomTransportStrategy, Server } from '@nestjs/microservices';

class GoogleCloudPubSubServer
  extends Server
  implements CustomTransportStrategy {
  /**
   * This method is triggered when you run "app.listen()".
   */
  listen(callback: () => void) {
    callback();
  }

  /**
   * This method is triggered on application shutdown.
   */
  close() {}
}
```

> **Warning** Please, note we won't be implementing a fully-featured Google Cloud Pub/Sub server in this chapter as this would require diving into transporter specific technical details.

In our example above, we declared the `GoogleCloudPubSubServer` class and provided `listen()` and `close()` methods enforced by the `CustomTransportStrategy` interface. Also, our class extends the `Server` class imported from the `@nestjs/microservices` package that provides a few useful methods, for example, methods used by Nest runtime to register message handlers. Alternatively, in case you want to extend the capabilities of an existing transport strategy, you could extend the corresponding server class, for example, `ServerRedis`. Conventionally, we added the `"Server"` suffix to our class as it will be responsible for subscribing to messages/events (and responding to them, if necessary).

With this in place, we can now use our custom strategy instead of using a built-in transporter, as follows:

```typescript

const app = await NestFactory.createMicroservice<MicroserviceOptions>(
  AppModule,
  {
    strategy: new GoogleCloudPubSubServer(),
  },
);
```

Basically, instead of passing the normal transporter options object with `transport` and `options` properties, we pass a single property, `strategy`, whose value is an instance of our custom transporter class.

Back to our `GoogleCloudPubSubServer` class, in a real-world application, we would be establishing a connection to our message broker/external service and registering subscribers/listening to specific channels in `listen()` method (and then removing subscriptions & closing the connection in the `close()` teardown method), but since this requires a good understanding of how Nest microservices communicate with each other, we recommend reading this [article series](https://dev.to/nestjs/part-1-introduction-and-setup-1a2l). In this chapter instead, we'll focus on the capabilities the `Server` class provides and how you can leverage them to build custom strategies.

For example, let's say that somewhere in our application, the following message handler is defined:

```typescript

@MessagePattern('echo')
echo(@Payload() data: object) {
  return data;
}
```

This message handler will be automatically registered by Nest runtime. With `Server` class, you can see what message patterns have been registered and also, access and execute the actual methods that were assigned to them. To test this out, let's add a simple `console.log` inside `listen()` method before `callback` function is called:

```typescript

listen(callback: () => void) {
  console.log(this.messageHandlers);
  callback();
}
```

After your application restarts, you'll see the following log in your terminal:

```typescript

Map { 'echo' => [AsyncFunction] { isEventHandler: false } }
```

> **Hint** If we used the `@EventPattern` decorator, you would see the same output, but with the `isEventHandler` property set to `true`.

As you can see, the `messageHandlers` property is a `Map` collection of all message (and event) handlers, in which patterns are being used as keys. Now, you can use a key (for example, `"echo"`) to receive a reference to the message handler:

```typescript

async listen(callback: () => void) {
  const echoHandler = this.messageHandlers.get('echo');
  console.log(await echoHandler('Hello world!'));
  callback();
}
```

Once we execute the `echoHandler` passing an arbitrary string as an argument (`"Hello world!"` here), we should see it in the console:

```json

Hello world!
```

Which means that our method handler was properly executed.

#### Client proxy[#](/microservices/custom-transport#client-proxy)

As we mentioned in the first section, you don't necessarily need to use the `@nestjs/microservices` package to create microservices, but if you decide to do so and you need to integrate a custom strategy, you will need to provide a "client" class too.

> **Hint** Again, implementing a fully-featured client class compatible with all `@nestjs/microservices` features (e.g., streaming) requires a good understading of communication techniques used by the framework. To learn more, check out this [article](https://dev.to/nestjs/part-4-basic-client-component-16f9).

To communicate with an external service/emit & publish messages (or events) you can either use a library-specific SDK package, or implement a custom client class that extends the `ClientProxy`, as follows:

```typescript

import { ClientProxy, ReadPacket, WritePacket } from '@nestjs/microservices';

class GoogleCloudPubSubClient extends ClientProxy {
  async connect(): Promise<any> {}
  async close() {}
  async dispatchEvent(packet: ReadPacket<any>): Promise<any> {}
  publish(
    packet: ReadPacket<any>,
    callback: (packet: WritePacket<any>) => void,
  ): Function {}
}
```

> **Warning** Please, note we won't be implementing a fully-featured Google Cloud Pub/Sub client in this chapter as this would require diving into transporter specific technical details.

As you can see, `ClientProxy` class requires us to provide several methods for establishing & closing the connection and publishing messages (`publish`) and events (`dispatchEvent`). Note, if you don't need a request-response communication style support, you can leave the `publish()` method empty. Likewise, if you don't need to support event-based communication, skip the `dispatchEvent()` method.

To observe what and when those methods are executed, let's add multiple `console.log` calls, as follows:

```typescript

class GoogleCloudPubSubClient extends ClientProxy {
  async connect(): Promise<any> {
    console.log('connect');
  }

  async close() {
    console.log('close');
  }

  async dispatchEvent(packet: ReadPacket<any>): Promise<any> {
    return console.log('event to dispatch: ', packet);
  }

  publish(
    packet: ReadPacket<any>,
    callback: (packet: WritePacket<any>) => void,
  ): Function {
    console.log('message:', packet);

    // In a real-world application, the "callback" function should be executed
    // with payload sent back from the responder. Here, we'll simply simulate (5 seconds delay)
    // that response came through by passing the same "data" as we've originally passed in.
    setTimeout(() => callback({ response: packet.data }), 5000);

    return () => console.log('teardown');
  }
}
```

With this in place, let's create an instance of `GoogleCloudPubSubClient` class and run the `send()` method (which you might have seen in earlier chapters), subscribing to the returned observable stream.

```typescript

const googlePubSubClient = new GoogleCloudPubSubClient();
googlePubSubClient
  .send('pattern', 'Hello world!')
  .subscribe((response) => console.log(response));
```

Now, you should see the following output in your terminal:

```typescript

connect
message: { pattern: 'pattern', data: 'Hello world!' }
Hello world! // <-- after 5 seconds
```

To test if our "teardown" method (which our `publish()` method returns) is properly executed, let's apply a timeout operator to our stream, setting it to 2 seconds to make sure it throws earlier then our `setTimeout` calls the `callback` function.

```typescript

const googlePubSubClient = new GoogleCloudPubSubClient();
googlePubSubClient
  .send('pattern', 'Hello world!')
  .pipe(timeout(2000))
  .subscribe(
    (response) => console.log(response),
    (error) => console.error(error.message),
  );
```

> **Hint** The `timeout` operator is imported from the `rxjs/operators` package.

With `timeout` operator applied, your terminal output should look as follows:

```typescript

connect
message: { pattern: 'pattern', data: 'Hello world!' }
teardown // <-- teardown
Timeout has occurred
```

To dispatch an event (instead of sending a message), use the `emit()` method:

```typescript

googlePubSubClient.emit('event', 'Hello world!');
```

And that's what you should see in the console:

```typescript

connect
event to dispatch:  { pattern: 'event', data: 'Hello world!' }
```

----
url: https://docs.nestjs.com/v5/techniques/http-module
----

### HTTP module

[Axios](https://github.com/axios/axios) is rich-feature HTTP client that is widely used in dozens of applications. That's why Nest wraps this package and exposes it by default as a built-in `HttpModule`. The `HttpModule` exports `HttpService` that simply exposes axios-based methods to perform HTTP request, but also, transforms return types into `Observables`.

In order to use a `HttpService`, we need to import `HttpModule`.

TypeScript

```typescript

@Module({
  imports: [HttpModule],
  providers: [CatsService],
})
export class CatsModule {}
```

> **Hint** The `HttpModule` is exposed from `@nestjs/common` package.

Then, you can inject `HttpService`. This class is easily accessible from `@nestjs/common` package.

JS TS

TypeScript

```typescript

@Injectable()
export class CatsService {
  constructor(private readonly httpService: HttpService) {}

  findAll(): Observable<AxiosResponse<Cat[]>> {
    return this.httpService.get('http://localhost:3000/cats');
  }
}
```

TypeScript

```typescript

@Injectable()
@Dependencies(HttpService)
export class CatsService {
  constructor(httpService) {
    this.httpService = httpService;
  }

  findAll() {
    return this.httpService.get('http://localhost:3000/cats');
  }
}
```

All methods return `AxiosResponse` wrapped with `Observable` object.

#### Configuration

[Axios](https://github.com/axios/axios) gives a bunch of options that you may take advantage of to make your `HttpService` even more powerful. Read more about them [here](https://github.com/axios/axios#request-config). To configure underlying library instance, use `register()` method of `HttpModule`.

TypeScript

```typescript

@Module({
  imports: [HttpModule.register({
    timeout: 5000,
    maxRedirects: 5,
  })],
  providers: [CatsService],
})
export class CatsModule {}
```

All these properties will be passed down to the **axios** constructor.

* HTTP module
* Configuration

----
url: https://docs.nestjs.com/observability/dashboard
----

[Skip to content](#content)

On this page

* [Dashboard](https://docs.nestjs.com/observability/dashboard#dashboard)
* [How the views nest](https://docs.nestjs.com/observability/dashboard#how-the-views-nest)
* [Telemetry views](https://docs.nestjs.com/observability/dashboard#telemetry-views)
* [Queries, outbound calls, and captured requests](https://docs.nestjs.com/observability/dashboard#queries-outbound-calls-and-captured-requests)
* [The service map](https://docs.nestjs.com/observability/dashboard#the-service-map)
* [Handing a failure to a coding agent](https://docs.nestjs.com/observability/dashboard#handing-a-failure-to-a-coding-agent)
* [Alerts](https://docs.nestjs.com/observability/dashboard#alerts)
* [SLOs](https://docs.nestjs.com/observability/dashboard#slos)
* [Issues](https://docs.nestjs.com/observability/dashboard#issues)
* [A worked path through the dashboard](https://docs.nestjs.com/observability/dashboard#a-worked-path-through-the-dashboard)

### Dashboard

Once an application is instrumented and sending data, its project dashboard fills in automatically, with no queries to write and no dashboards to build. This chapter covers what each view shows, how the views relate to each other, and how the features built on top of the telemetry (alerts, SLOs, issues, and the agent handoff) fit together. For the full reference, see the [NestJS Observe documentation](https://www.observe.nestjs.com/documentation "NestJS Observe documentation").

> **Hint** Every view described below can be clicked through in the [live demo](https://www.observe-demo.nestjs.com/dashboard "NestJS Observe live demo"), which runs the dashboard over a generated dataset from a busy service: realistic request volumes, traces with waterfalls, errors, jobs, and alerts. It needs no account and runs entirely in your browser.

#### How the views nest[#](/observability/dashboard#how-the-views-nest)

Almost every telemetry view belongs to one of three levels, and you move between them by clicking through:

1. **Analytics** - the list view. Every route, job, span, or metric your applications reported in the selected window, aggregated: throughput, latency, failure rate. This is where you notice something.
2. **Operation** - one route (`GET /orders/:id`), one job name, one span name. The same numbers over time, plus the list of individual executions behind them. This is where you confirm the shape of a problem: constant or spiky, everywhere or one release.
3. **Execution** - a single request, a single job run, a single span invocation. Its exact duration, status, user, tags, the error it raised, the waterfall of everything it did, and the logs it wrote. This is where you diagnose.

Aggregates tell you *that* something is wrong and how much it matters; a single execution tells you *why*. Every view shares one control bar (a time range and an optional application filter), and everything on the page follows it.

#### Telemetry views[#](/observability/dashboard#telemetry-views)

| View         | What it shows                                                                                                                                                                                                                                                                                                                                                            |
| ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **Requests** | Every HTTP, GraphQL, gRPC, microservice and WebSocket gateway request, broken down by operation. A request detail page compares the call against the route's own baseline ("slower than 95% of calls") and, when the process was struggling, states by how much host pressure slowed this operation.                                                                     |
| **Services** | Time spent per NestJS **class and method**, split into own time (with everything awaited subtracted out) and total time. Only instrumented classes appear, so a short list means low coverage, not low traffic.                                                                                                                                                          |
| **Errors**   | Every unhandled error, grouped by operation, with the failure leading the page: class, message, stack trace, and source code. The **Group into defects** switch collapses occurrences with the same class and stack shape into one fingerprinted group with first/last seen and the release that introduced it. See [Error monitoring](/observability/error-monitoring). |
| **Jobs**     | Background work - queue consumers, cron runs - with queue wait time, attempt number, and failure reason alongside duration and failure rate.                                                                                                                                                                                                                             |
| **Spans**    | Analytics over span names across every route that calls them - "how slow is `OrdersService.recalculate` everywhere", rather than "how slow is this one endpoint".                                                                                                                                                                                                        |
| **Traces**   | The waterfall for a trace id, across every service that shares it - see [Distributed tracing](/observability/distributed-tracing).                                                                                                                                                                                                                                       |
| **Users**    | Per-user activity when `getUserId` is configured: failure rate per user, calls grouped into the actions they performed, a replay of each action, and the paths between them. A **Group by customer** switch rolls identities up by email domain.                                                                                                                         |
| **Custom**   | Counters, gauges, and summaries reported through [`TracerService`](/observability/manual-instrumentation#custom-metrics), grouped by metric name and labels.                                                                                                                                                                                                             |
| **Releases** | Each `serviceVersion` compared against the one before it - error rate, latency, and throughput side by side.                                                                                                                                                                                                                                                             |
| **Logs**     | Everything your services logged (with `forwardLogs` on), correlated to the traces they ran in. On an execution page, each line is placed on the trace's clock next to the span that was in flight.                                                                                                                                                                       |
| **Profiler** | CPU, memory, event loop delay and utilization, and garbage collection per application, with per-instance comparison when an application runs on more than one node. Click a spike on the Memory or Event loop delay chart to see which operations ran at that moment, ranked by deviation from their baseline.                                                           |

#### Queries, outbound calls, and captured requests[#](/observability/dashboard#queries-outbound-calls-and-captured-requests)

In a trace's waterfall, a database query or an outbound HTTP request is a row of its own under the method that made it: an icon, the operation (`SELECT orders`, `POST api.stripe.com`), and the statement or URL beside it, visible without hovering. The row's caret opens the full statement laid out by clause, with its placeholders highlighted and a copy button. Values never appear, because the agent removes them before anything is sent. The spans table beneath lists only your application's methods; the agent's query spans are left out and their time counts as the calling method's own, so the table still answers "which of my methods took the time". The **Services** page follows the same rule: drivers (`pg`, `mysql2`, `mongodb`, `http`) are not listed as classes, and a query's wait counts as the own time of the method that ran it.

When the agent kept a request's own inputs (because it failed, or ran past the [`slowerThanMs`](/observability/sdk#capturing-failed-and-slow-requests) threshold you configured), the request's **Details** card has two extra folded rows, *Request headers* and *Request body*. A request with nothing captured has no such rows.

#### The service map[#](/observability/dashboard#the-service-map)

A project's **Activity → Map** page shows how its applications, queues, and databases talk to each other. Applications and queues run left to right in call order, and the databases and external services each one depends on hang beneath it. A line's thickness and the speed of the traffic along it show volume. Soft red marks an error rate above 1%, full red above 5%, and teal means healthy. Hover over any node to isolate what it touches, and click it for its numbers: for a database, the statements the time went to; for an application, what it calls and what calls it, with a link to its requests.

The map needs no configuration and collects nothing new. Databases and external hosts come from the agent's [query and outbound-HTTP spans](/observability/sdk#database-queries-and-outbound-http), queues from the jobs an application works, and the dashed lines between applications from executions that share a [trace id](/observability/distributed-tracing). Each application gets one database node per driver, so two services on Postgres usually show as two databases, since nothing on the wire says they share one. An external host, by contrast, is a single node shared by every caller, up to the eight busiest per application.

An application with no lines at all is almost always running an SDK older than `0.3.0`, which does not report queries or outbound calls.

> **Hint** Links between applications are inferred from the most recent requests rather than counted over the whole window. Read a dashed line as "this calls that", not as an exact total.

#### Handing a failure to a coding agent[#](/observability/dashboard#handing-a-failure-to-a-coding-agent)

Reading a trace tells you what happened. The next step is always the same: find that code and change it. The **Copy agent prompt** button does that handoff in one click. It copies the entire page as a self-contained markdown prompt, ready to paste into Claude Code, Cursor, or any other tool that has your repository open.

The button appears only where there is something to investigate: a request or job that failed or ran slower than 95% of its peers, or a trace containing an error. The prompt carries the task framing, the operation context, the error with its trimmed stack trace and source lines (paths rewritten relative to your project root, so `src/orders/orders.service.ts:35` rather than `/var/app/current/dist/orders/orders.service.js:35`), how the call compares to the operation's average and p95, the top spans by self time, up to 40 log lines chosen errors-first, and closing instructions asking the agent to explain the root cause from the code and propose a fix as a diff with tests.

For an agent that needs to keep asking questions (follow a trace into its logs, check whether an error is still firing), connect it to the [MCP server](/observability/mcp-server) instead.

#### Alerts[#](/observability/dashboard#alerts)

Alerts notify you when your telemetry crosses a threshold you care about, so you don't find out from a customer. A rule watches one metric from one of these families:

| Family  | Metrics                                          | Scoped to                                           |
| ------- | ------------------------------------------------ | --------------------------------------------------- |
| Request | Error rate, p95 latency, avg latency, throughput | An application, and optionally one route + method   |
| Job     | Job failure rate, job throughput, p95 queue wait | An application, and optionally one job name + queue |
| Absence | Telemetry silence, job silence                   | An application, or one job name + queue             |
| Logs    | Matching log lines                               | A pattern, and optionally levels + logger context   |
| Errors  | New error groups                                 | An application, or the whole project                |
| Runtime | Event loop delay, CPU usage, memory usage        | An application (sampled per process)                |
| Custom  | Any custom metric your application reports       | A metric name, and optionally one label             |
| SLO     | SLO burn rate                                    | The SLO itself                                      |

Every rule runs in one of two modes: a **fixed threshold** ("error rate above 5%"), or **anomaly detection**, which fires when the metric deviates from its own recent baseline by more than a sensitivity you set. Anomaly mode is often the better choice for runtime metrics: a fixed CPU threshold that's right for one service is wrong for the next, but "unlike its own recent baseline" applies to both.

Two families depend directly on SDK instrumentation:

* **Absence detection.** A **Telemetry silence** rule watches the runtime heartbeat the SDK's `runtimeMetrics` sampler emits even when the application is otherwise idle, and fires once it has been silent longer than a tolerance you set (2 minutes to 7 days). A **Job silence** rule does the same for one named job, e.g., a cron that didn't run. The same mechanism gives you both lightweight uptime monitoring without an external probe and cron monitoring. A scope that has never reported anything doesn't fire: "not yet integrated" isn't "down".
* **Log-pattern alerts** count log lines containing a substring within the window ("alert me when `payment declined` appears more than 10 times in 15 minutes"), and require `forwardLogs` to be on.

A rule can notify through **email**, **Slack** (incoming webhook), a generic **webhook**, an **in-app** notification, or by **creating an issue** pre-filled with the rule's severity and scope. Rules can carry a recurring mute schedule for quiet hours, and every state transition (OK → Firing → Resolved) is recorded with per-channel delivery status.

**New errors.** A *new error groups* rule fires when an error Observe has never seen before appears. It counts unhandled failures only: a group whose first occurrence answered with a 5xx, or failed on an entry point with no HTTP status (an RPC handler, a gateway message). An error your code threw on purpose, such as a `NotFoundException` or a failed validation, still appears in the Errors view but doesn't count as a new bug. Every plan, Free included, also gets a built-in **new-error email** without creating a rule: one email per project listing the new errors, at most six a day. Each person can switch it off under **Settings → New error emails**.

#### SLOs[#](/observability/dashboard#slos)

SLOs turn "error rate above 5%" into "we promised 99.9% and we're spending the budget too fast". They're objectives over telemetry you already collect, so no new instrumentation is required. An SLO is built from three layered concepts:

* **SLI (service level indicator)**: a ratio of good events to total events over a window, measuring availability (requests without an unhandled error), latency (requests under a threshold you set), or job success.
* **Objective**: the SLI plus a target percentage (90-99.999%) over a rolling compliance window of 7, 14, 28, or 30 days.
* **Error budget**: how much room you have to miss the target (`1 − target`), and **burn rate**, how fast that budget is being spent. A burn rate of 1.0 spends it exactly on schedule; 14.4 means a 28-day budget would be gone in about two days.

A burn-rate alert is a regular alert rule pointed at an SLO instead of a raw metric. Typical starting points are a fast-burn rule (1 hour window, 14.4×), a slow-burn rule (6 hours, 6×), and a trickle rule (3 days, 1×). A compliance window can't exceed how long your plan retains telemetry.

#### Issues[#](/observability/dashboard#issues)

Issues are lightweight, project-scoped tracking for the work that comes out of your telemetry, such as a recurring error worth fixing or a latency regression to investigate. Create them by hand from any execution page, promote an error group into one, or let a firing alert open one automatically. An issue links to the request, error, job, or trace it came from, so anyone opening it later has the telemetry in context, not only a description of it.

When you mark an issue resolved and it names something measurable (an operation, an alert rule's scope), the dashboard watches that operation's telemetry against its pre-incident baseline and tells you whether the fix held. It moves the issue to **Verifying**, then either closes it on its own or moves it back to **Open** with the reading that broke it. If you name the release the fix shipped in (your `serviceVersion`), verification waits until that release shows up in telemetry.

#### A worked path through the dashboard[#](/observability/dashboard#a-worked-path-through-the-dashboard)

The views are designed to be used in order. A typical investigation:

1. An alert fires, or the **Requests** chart shows p95 climbing.
2. Sort the route list by duration or failure rate to find which operation moved.
3. Open the operation. Is it constant or spiky? Did it start at a deploy? Check **Releases**.
4. Open a single execution from the tail of the distribution, e.g., one the baseline card calls *slower than 95% of calls*.
5. Read the **waterfall**: which span holds the self time?
6. If it failed, read the **error card** - stack trace and the source lines around the throw.
7. Check the **logs** for that trace, hovering lines to line them up with the spans.
8. **Copy the agent prompt** and hand the whole thing to a coding agent, or open an **issue** linked to the execution so whoever picks it up starts where you stopped.

The same path is available to an agent over the [MCP server](/observability/mcp-server), one tool per step, when you'd rather ask questions than click through views.

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/observability/dashboard.md)

----
url: https://docs.nestjs.com/v11/guards
----

* [Guards](https://docs.nestjs.com/v11/guards#guards)
* [Authorization guard](https://docs.nestjs.com/v11/guards#authorization-guard)
* [Execution context](https://docs.nestjs.com/v11/guards#execution-context)
* [Role-based authentication](https://docs.nestjs.com/v11/guards#role-based-authentication)
* [Binding guards](https://docs.nestjs.com/v11/guards#binding-guards)
* [Setting roles per handler](https://docs.nestjs.com/v11/guards#setting-roles-per-handler)
* [Putting it all together](https://docs.nestjs.com/v11/guards#putting-it-all-together)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/guards.md "Suggest Edits")

### Guards

A guard is a class annotated with the `@Injectable()` decorator, which implements the `CanActivate` interface.

Guards have a **single responsibility**. They determine whether a given request will be handled by the route handler or not, depending on certain conditions (like permissions, roles, ACLs, etc.) present at run-time. This is often referred to as **authorization**. Authorization (and its cousin, **authentication**, with which it usually collaborates) has typically been handled by [middleware](/v11/middleware) in traditional Express applications. Middleware is a fine choice for authentication, since things like token validation and attaching properties to the `request` object are not strongly connected with a particular route context (and its metadata).

But middleware, by its nature, is dumb. It doesn't know which handler will be executed after calling the `next()` function. On the other hand, **Guards** have access to the `ExecutionContext` instance, and thus know exactly what's going to be executed next. They're designed, much like exception filters, pipes, and interceptors, to let you interpose processing logic at exactly the right point in the request/response cycle, and to do so declaratively. This helps keep your code DRY and declarative.

> **Hint** Guards are executed **after** all middleware, but **before** any interceptor or pipe.

#### Authorization guard[#](/guards#authorization-guard)

As mentioned, **authorization** is a great use case for Guards because specific routes should be available only when the caller (usually a specific authenticated user) has sufficient permissions. The `AuthGuard` that we'll build now assumes an authenticated user (and that, therefore, a token is attached to the request headers). It will extract and validate the token, and use the extracted information to determine whether the request can proceed or not.

auth.guard.ts

JS TS

```typescript

import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
import { Observable } from 'rxjs';

@Injectable()
export class AuthGuard implements CanActivate {
  canActivate(
    context: ExecutionContext,
  ): boolean | Promise<boolean> | Observable<boolean> {
    const request = context.switchToHttp().getRequest();
    return validateRequest(request);
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';

@Injectable()
export class AuthGuard {
  async canActivate(context) {
    const request = context.switchToHttp().getRequest();
    return validateRequest(request);
  }
}
```

> **Hint** If you are looking for a real-world example on how to implement an authentication mechanism in your application, visit [this chapter](/v11/security/authentication). Likewise, for more sophisticated authorization example, check [this page](/v11/security/authorization).

The logic inside the `validateRequest()` function can be as simple or sophisticated as needed. The main point of this example is to show how guards fit into the request/response cycle.

Every guard must implement a `canActivate()` function. This function should return a boolean, indicating whether the current request is allowed or not. It can return the response either synchronously or asynchronously (via a `Promise` or `Observable`). Nest uses the return value to control the next action:

* if it returns `true`, the request will be processed.
* if it returns `false`, Nest will deny the request.

## Official enterprise support

* **Providing technical guidance
* **Performing in-depth code reviews
* **Mentoring team members
* **Advising best practices

[Explore more](https://enterprise.nestjs.com "Enterprise | NestJS - A progressive Node.js framework")

#### Execution context[#](/guards#execution-context)

The `canActivate()` function takes a single argument, the `ExecutionContext` instance. The `ExecutionContext` inherits from `ArgumentsHost`. We saw `ArgumentsHost` previously in the exception filters chapter. In the sample above, we are just using the same helper methods defined on `ArgumentsHost` that we used earlier, to get a reference to the `Request` object. You can refer back to the **Arguments host** section of the [exception filters](https://docs.nestjs.com/exception-filters#arguments-host) chapter for more on this topic.

By extending `ArgumentsHost`, `ExecutionContext` also adds several new helper methods that provide additional details about the current execution process. These details can be helpful in building more generic guards that can work across a broad set of controllers, methods, and execution contexts. Learn more about `ExecutionContext`[here](/v11/fundamentals/execution-context).

#### Role-based authentication[#](/guards#role-based-authentication)

Let's build a more functional guard that permits access only to users with a specific role. We'll start with a basic guard template, and build on it in the coming sections. For now, it allows all requests to proceed:

roles.guard.ts

JS TS

```typescript

import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
import { Observable } from 'rxjs';

@Injectable()
export class RolesGuard implements CanActivate {
  canActivate(
    context: ExecutionContext,
  ): boolean | Promise<boolean> | Observable<boolean> {
    return true;
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';

@Injectable()
export class RolesGuard {
  canActivate(context) {
    return true;
  }
}
```

#### Binding guards[#](/guards#binding-guards)

Like pipes and exception filters, guards can be **controller-scoped**, method-scoped, or global-scoped. Below, we set up a controller-scoped guard using the `@UseGuards()` decorator. This decorator may take a single argument, or a comma-separated list of arguments. This lets you easily apply the appropriate set of guards with one declaration.

JS TS

```typescript

@Controller('cats')
@UseGuards(RolesGuard)
export class CatsController {}
```

> **Hint** The `@UseGuards()` decorator is imported from the `@nestjs/common` package.

Above, we passed the `RolesGuard` class (instead of an instance), leaving responsibility for instantiation to the framework and enabling dependency injection. As with pipes and exception filters, we can also pass an in-place instance:

JS TS

```typescript

@Controller('cats')
@UseGuards(new RolesGuard())
export class CatsController {}
```

The construction above attaches the guard to every handler declared by this controller. If we wish the guard to apply only to a single method, we apply the `@UseGuards()` decorator at the **method level**.

In order to set up a global guard, use the `useGlobalGuards()` method of the Nest application instance:

JS TS

```typescript

const app = await NestFactory.create(AppModule);
app.useGlobalGuards(new RolesGuard());
```

> **Notice** In the case of hybrid apps the `useGlobalGuards()` method doesn't set up guards for gateways and microservices by default (see [Hybrid application](/v11/faq/hybrid-application) for information on how to change this behavior). For "standard" (non-hybrid) microservice apps, `useGlobalGuards()` does mount the guards globally.

Global guards are used across the whole application, for every controller and every route handler. In terms of dependency injection, global guards registered from outside of any module (with `useGlobalGuards()` as in the example above) cannot inject dependencies since this is done outside the context of any module. In order to solve this issue, you can set up a guard directly from any module using the following construction:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { APP_GUARD } from '@nestjs/core';

@Module({
  providers: [
    {
      provide: APP_GUARD,
      useClass: RolesGuard,
    },
  ],
})
export class AppModule {}
```

> **Hint** When using this approach to perform dependency injection for the guard, note that regardless of the module where this construction is employed, the guard is, in fact, global. Where should this be done? Choose the module where the guard (`RolesGuard` in the example above) is defined. Also, `useClass` is not the only way of dealing with custom provider registration. Learn more [here](/v11/fundamentals/custom-providers).

#### Setting roles per handler[#](/guards#setting-roles-per-handler)

Our `RolesGuard` is working, but it's not very smart yet. We're not yet taking advantage of the most important guard feature - the [execution context](/v11/fundamentals/execution-context). It doesn't yet know about roles, or which roles are allowed for each handler. The `CatsController`, for example, could have different permission schemes for different routes. Some might be available only for an admin user, and others could be open for everyone. How can we match roles to routes in a flexible and reusable way?

This is where **custom metadata** comes into play (learn more [here](https://docs.nestjs.com/fundamentals/execution-context#reflection-and-metadata)). Nest provides the ability to attach custom **metadata** to route handlers through either decorators created via `Reflector.createDecorator` static method, or the built-in `@SetMetadata()` decorator.

For example, let's create a `@Roles()` decorator using the `Reflector.createDecorator` method that will attach the metadata to the handler. `Reflector` is provided out of the box by the framework and exposed from the `@nestjs/core` package.

roles.decorator.ts

JS TS

```ts

import { Reflector } from '@nestjs/core';

export const Roles = Reflector.createDecorator<string[]>();
```

The `Roles` decorator here is a function that takes a single argument of type `string[]`.

Now, to use this decorator, we simply annotate the handler with it:

cats.controller.ts

JS TS

```typescript

@Post()
@Roles(['admin'])
async create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

```typescript

@Post()
@Roles(['admin'])
@Bind(Body())
async create(createCatDto) {
  this.catsService.create(createCatDto);
}
```

Here we've attached the `Roles` decorator metadata to the `create()` method, indicating that only users with the `admin` role should be allowed to access this route.

Alternatively, instead of using the `Reflector.createDecorator` method, we could use the built-in `@SetMetadata()` decorator. Learn more about [here](/fundamentals/execution-context#low-level-approach).

#### Putting it all together[#](/guards#putting-it-all-together)

Let's now go back and tie this together with our `RolesGuard`. Currently, it simply returns `true` in all cases, allowing every request to proceed. We want to make the return value conditional based on comparing the **roles assigned to the current user** to the actual roles required by the current route being processed. In order to access the route's role(s) (custom metadata), we'll use the `Reflector` helper class again, as follows:

roles.guard.ts

JS TS

```typescript

import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
import { Reflector } from '@nestjs/core';
import { Roles } from './roles.decorator';

@Injectable()
export class RolesGuard implements CanActivate {
  constructor(private reflector: Reflector) {}

  canActivate(context: ExecutionContext): boolean {
    const roles = this.reflector.get(Roles, context.getHandler());
    if (!roles) {
      return true;
    }
    const request = context.switchToHttp().getRequest();
    const user = request.user;
    return matchRoles(roles, user.roles);
  }
}
```

```typescript

import { Injectable, Dependencies } from '@nestjs/common';
import { Reflector } from '@nestjs/core';
import { Roles } from './roles.decorator';

@Injectable()
@Dependencies(Reflector)
export class RolesGuard {
  constructor(reflector) {
    this.reflector = reflector;
  }

  canActivate(context) {
    const roles = this.reflector.get(Roles, context.getHandler());
    if (!roles) {
      return true;
    }
    const request = context.switchToHttp().getRequest();
    const user = request.user;
    return matchRoles(roles, user.roles);
  }
}
```

> **Hint** In the node.js world, it's common practice to attach the authorized user to the `request` object. Thus, in our sample code above, we are assuming that `request.user` contains the user instance and allowed roles. In your app, you will probably make that association in your custom **authentication guard** (or middleware). Check [this chapter](/v11/security/authentication) for more information on this topic.

> **Warning** The logic inside the `matchRoles()` function can be as simple or sophisticated as needed. The main point of this example is to show how guards fit into the request/response cycle.

Refer to the [Reflection and metadata](https://docs.nestjs.com/fundamentals/execution-context#reflection-and-metadata) section of the **Execution context** chapter for more details on utilizing `Reflector` in a context-sensitive way.

When a user with insufficient privileges requests an endpoint, Nest automatically returns the following response:

```typescript

{
  "statusCode": 403,
  "message": "Forbidden resource",
  "error": "Forbidden"
}
```

Note that behind the scenes, when a guard returns `false`, the framework throws a `ForbiddenException`. If you want to return a different error response, you should throw your own specific exception. For example:

```typescript

throw new UnauthorizedException();
```

Any exception thrown by a guard will be handled by the [exceptions layer](/v11/exception-filters) (global exceptions filter and any exceptions filters that are applied to the current context).

> **Hint** If you are looking for a real-world example on how to implement authorization, check [this chapter](/v11/security/authorization).

----
url: https://docs.nestjs.com/v11/discover/companies
----

* [Who is using Nest?](https://docs.nestjs.com/v11/discover/companies#who-is-using-nest)
* [Companies](https://docs.nestjs.com/v11/discover/companies#companies)

### Who is using Nest?

We are proudly helping various companies building their products at scale. If you are using Nest and would you like to be listed here, see this [thread](https://github.com/nestjs/nest/issues/1006). We are willing to put your logo here!

#### Companies[#](/discover/companies#companies)

According to our knowledge, all the following companies have built awesome projects on top of our framework:

[](https://roche.com)[](https://adidas.com)[](https://capgemini.com)[](https://www.societegenerale.fr/)[](https://rewe-digital.com/)[](https://www.decathlon.com/)[](https://www.autodesk.com/)[](https://www.neo4j.com/)[](https://bmw.com)[](https://gitlab.com/)[](https://www.ibm.com/)[](https://www.jetbrains.com/)[](https://www.mercedes-benz.com/)[](https://totalenergies.com/)[](https://www.bytedance.com)[](https://www.shipt.com/)[](https://github.com/Sanofi-IADC)[](https://sitepen.com)[](https://trilon.io)[](https://www.vuestorefront.io/)[](https://hingehealth.com)[](https://whiskeyhouse.com)

|                                     |
| ----------------------------------- |
| <https://gorrion.io/>               |
| <http://balticdatascience.com/>     |
| <https://prohabits.com/>            |
| <https://komed-health.com/>         |
| <https://kerberus.com.co/>          |
| <http://xtremis.com/>               |
| <https://notadd.com/>               |
| <http://jsdaddy.io/>                |
| <https://yumpingo.com/>             |
| <https://analytics-importer.cz/>    |
| <https://dayzim.com/>               |
| <https://wizkids.co.uk/>            |
| <https://pilvia.com/>               |
| <https://wi-q.com/>                 |
| <http://agrofel.com.br>             |
| <https://societegenerale.com/>      |
| <https://trashpanda.hulan.nl/>      |
| <https://bytedance.com/>            |
| <https://votercircle.com>           |
| <https://erento.com>                |
| <https://ideas.manticore-labs.com/> |
| <https://smartexlab.com/>           |
| <https://automama.ru/>              |
| <https://iflix.com/>                |
| <https://frontendwatch.com/>        |
| <https://mobilejazz.com/>           |
| <https://cgiandi.com/>              |
| <https://www.titlex.com.au/>        |
| <https://codengage.com/>            |
| <https://budacode.com/>             |
| <https://blueanchor.io/>            |
| <https://www.easymetrics.com/>      |
| <https://getapollo.io/>             |
| <https://big-bench.com/>            |
| <https://www.qingtui.cn/>           |
| <https://www.rosebayconsult.com/>   |
| <https://www.patrocinium.com/>      |
| <https://creatorsdaily.com>         |
| <https://autoscar.com.br>           |
| <https://www.mediktiv.com>          |
| <https://harmonize.health>          |
| <https://accerlery.be>              |
| <https://www.facile.it>             |
| <https://shopback.com>              |
| <https://www.ottonova.de>           |
| <https://www.radity.com>            |
| <https://globalctoforum.org>        |
| <https://halojasa.com>              |
| <https://hexito.com>                |
| <https://rivvy.app>                 |
| <https://padfever.com/>             |
| <https://datenlotse.org>            |
| <https://bemum.co>                  |
| <https://weoptimeye.ai>             |
| <https://nemovote.com>              |
| <https://selleo.com>                |
| <https://pchas.ir>                  |
| <https://tayeh.ir>                  |
| <https://forwardigital.co.uk>       |
| <https://rozetka.com.ua>            |
| <https://www.itrio.net>             |
| <https://alexishr.com>              |
| <https://dyrector.io>               |
| <https://stijlbreuk.nl>             |
| <https://polygon-software.ch>       |
| <https://bewith.io>                 |
| <https://swetrix.com>               |
| <https://swyftlogistics.com>        |
| <https://evershop.io>               |
| <https://e-design.ca>               |
| <https://growthmill.com>            |
| <https://tarken.com.br>             |
| <https://remato.com>                |
| <https://remberg.de/en>             |
| <https://uninterrupted.tech>        |
| <https://www.digando.com>           |
| <https://novu.co>                   |
| <https://aqreach.com>               |
| <https://phalco.de>                 |
| <https://www.tesseractpro.io>       |
| <https://www.kwanso.com>            |
| <https://cmdn.io>                   |
| <https://ayo.so>                    |
| <https://devitjobs.com>             |
| <https://formation.tech>            |
| <https://gofirmex.com>              |
| <https://vbdhub.org>                |
| <https://www.arven-tech.com>        |
| <https://runsystem.net>             |
| <https://zenobank.io>               |

and a lot more but we don't have enough time to update above list. Feel free to create a [pull request](https://github.com/nestjs/docs.nestjs.com/pulls) though!

----
url: https://docs.nestjs.com/v10/recipes/mikroorm
----

* [MikroORM](https://docs.nestjs.com/v10/recipes/mikroorm#mikroorm)
* [Installation](https://docs.nestjs.com/v10/recipes/mikroorm#installation)
* [Repositories](https://docs.nestjs.com/v10/recipes/mikroorm#repositories)
* [Using custom repositories](https://docs.nestjs.com/v10/recipes/mikroorm#using-custom-repositories)
* [Load entities automatically](https://docs.nestjs.com/v10/recipes/mikroorm#load-entities-automatically)
* [Serialization](https://docs.nestjs.com/v10/recipes/mikroorm#serialization)
* [Request scoped handlers in queues](https://docs.nestjs.com/v10/recipes/mikroorm#request-scoped-handlers-in-queues)
* [Testing](https://docs.nestjs.com/v10/recipes/mikroorm#testing)
* [Example](https://docs.nestjs.com/v10/recipes/mikroorm#example)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/recipes/mikroorm.md "Suggest Edits")

### MikroORM

This recipe is here to help users get started with MikroORM in Nest. MikroORM is the TypeScript ORM for Node.js based on Data Mapper, Unit of Work and Identity Map patterns. It is a great alternative to TypeORM and migration from TypeORM should be fairly easy. The complete documentation on MikroORM can be found [here](https://mikro-orm.io/docs).

> **info**`@mikro-orm/nestjs` is a third party package and is not managed by the NestJS core team. Please report any issues found with the library in the [appropriate repository](https://github.com/mikro-orm/nestjs).

#### Installation[#](/recipes/mikroorm#installation)

Easiest way to integrate MikroORM to Nest is via [`@mikro-orm/nestjs` module](https://github.com/mikro-orm/nestjs). Simply install it next to Nest, MikroORM and underlying driver:

```bash

$ npm i @mikro-orm/core @mikro-orm/nestjs @mikro-orm/sqlite
```

MikroORM also supports `postgres`, `sqlite`, and `mongo`. See the [official docs](https://mikro-orm.io/docs/usage-with-sql/) for all drivers.

Once the installation process is completed, we can import the `MikroOrmModule` into the root `AppModule`.

```typescript

import { SqliteDriver } from '@mikro-orm/sqlite';

@Module({
  imports: [
    MikroOrmModule.forRoot({
      entities: ['./dist/entities'],
      entitiesTs: ['./src/entities'],
      dbName: 'my-db-name.sqlite3',
      driver: SqliteDriver,
    }),
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {
}
```

The `forRoot()` method accepts the same configuration object as `init()` from the MikroORM package. Check [this page](https://mikro-orm.io/docs/configuration) for the complete configuration documentation.

Alternatively we can [configure the CLI](https://mikro-orm.io/docs/installation#setting-up-the-commandline-tool) by creating a configuration file `mikro-orm.config.ts` and then call the `forRoot()` without any arguments.

```typescript

@Module({
  imports: [
    MikroOrmModule.forRoot(),
  ],
  ...
})
export class AppModule {}
```

But this won't work when you use a build tools that use tree shaking, for that it is better to provide the config explicitly:

```typescript

import config from './mikro-orm.config'; // your ORM config

@Module({
  imports: [
    MikroOrmModule.forRoot(config),
  ],
  ...
})
export class AppModule {}
```

Afterward, the `EntityManager` will be available to inject across the entire project (without importing any module elsewhere).

```ts

// Import everytyhing from your driver package or `@mikro-orm/knex`
import { EntityManager, MikroORM } from '@mikro-orm/sqlite';

@Injectable()
export class MyService {
  constructor(
    private readonly orm: MikroORM,
    private readonly em: EntityManager,
  ) {}
}
```

> **info** Notice that the `EntityManager` is imported from the `@mikro-orm/driver` package, where driver is `mysql`, `sqlite`, `postgres` or what driver you are using. In case you have `@mikro-orm/knex` installed as a dependency, you can also import the `EntityManager` from there.

#### Repositories[#](/recipes/mikroorm#repositories)

MikroORM supports the repository design pattern. For every entity, we can create a repository. Read the complete documentation on repositories [here](https://mikro-orm.io/docs/repositories). To define which repositories should be registered in the current scope you can use the `forFeature()` method. For example, in this way:

> **info** You should **not** register your base entities via `forFeature()`, as there are no repositories for those. On the other hand, base entities need to be part of the list in `forRoot()` (or in the ORM config in general).

```typescript

// photo.module.ts
@Module({
  imports: [MikroOrmModule.forFeature([Photo])],
  providers: [PhotoService],
  controllers: [PhotoController],
})
export class PhotoModule {}
```

and import it into the root `AppModule`:

```typescript

// app.module.ts
@Module({
  imports: [MikroOrmModule.forRoot(...), PhotoModule],
})
export class AppModule {}
```

In this way we can inject the `PhotoRepository` to the `PhotoService` using the `@InjectRepository()` decorator:

```typescript

@Injectable()
export class PhotoService {
  constructor(
    @InjectRepository(Photo)
    private readonly photoRepository: EntityRepository<Photo>,
  ) {}
}
```

#### Using custom repositories[#](/recipes/mikroorm#using-custom-repositories)

When using custom repositories, we no longer need the `@InjectRepository()` decorator, as Nest DI resolved based on the class references.

```ts

// `**./author.entity.ts**`
@Entity({ repository: () => AuthorRepository })
export class Author {
  // to allow inference in `em.getRepository()`
  [EntityRepositoryType]?: AuthorRepository;
}

// `**./author.repository.ts**`
export class AuthorRepository extends EntityRepository<Author> {
  // your custom methods...
}
```

As the custom repository name is the same as what `getRepositoryToken()` would return, we do not need the `@InjectRepository()` decorator anymore:

```ts

@Injectable()
export class MyService {
  constructor(private readonly repo: AuthorRepository) {}
}
```

#### Load entities automatically[#](/recipes/mikroorm#load-entities-automatically)

Manually adding entities to the entities array of the connection options can be tedious. In addition, referencing entities from the root module breaks application domain boundaries and causes leaking implementation details to other parts of the application. To solve this issue, static glob paths can be used.

Note, however, that glob paths are not supported by webpack, so if you are building your application within a monorepo, you won't be able to use them. To address this issue, an alternative solution is provided. To automatically load entities, set the `autoLoadEntities` property of the configuration object (passed into the `forRoot()` method) to `true`, as shown below:

```ts

@Module({
  imports: [
    MikroOrmModule.forRoot({
      ...
      autoLoadEntities: true,
    }),
  ],
})
export class AppModule {}
```

With that option specified, every entity registered through the `forFeature()` method will be automatically added to the entities array of the configuration object.

> **info** Note that entities that aren't registered through the `forFeature()` method, but are only referenced from the entity (via a relationship), won't be included by way of the `autoLoadEntities` setting.

> **info** Using `autoLoadEntities` also has no effect on the MikroORM CLI - for that we still need CLI config with the full list of entities. On the other hand, we can use globs there, as the CLI won't go thru webpack.

#### Serialization[#](/recipes/mikroorm#serialization)

> **Note** MikroORM wraps every single entity relation in a `Reference<T>` or a `Collection<T>` object, in order to provide better type-safety. This will make [Nest's built-in serializer](/techniques/serialization) blind to any wrapped relations. In other words, if you return MikroORM entities from your HTTP or WebSocket handlers, all of their relations will NOT be serialized.

Luckily, MikroORM provides a [serialization API](https://mikro-orm.io/docs/serializing) which can be used in lieu of `ClassSerializerInterceptor`.

```typescript

@Entity()
export class Book {
  @Property({ hidden: true }) // Equivalent of class-transformer's `@Exclude`
  hiddenField = Date.now();

  @Property({ persist: false }) // Similar to class-transformer's `@Expose()`. Will only exist in memory, and will be serialized.
  count?: number;

  @ManyToOne({
    serializer: (value) => value.name,
    serializedName: 'authorName',
  }) // Equivalent of class-transformer's `@Transform()`
  author: Author;
}
```

#### Request scoped handlers in queues[#](/recipes/mikroorm#request-scoped-handlers-in-queues)

As mentioned in the [docs](https://mikro-orm.io/docs/identity-map), we need a clean state for each request. That is handled automatically thanks to the `RequestContext` helper registered via middleware.

But middlewares are executed only for regular HTTP request handles, what if we need a request scoped method outside of that? One example of that is queue handlers or scheduled tasks.

We can use the `@CreateRequestContext()` decorator. It requires you to first inject the `MikroORM` instance to current context, it will be then used to create the context for you. Under the hood, the decorator will register new request context for your method and execute it inside the context.

```ts

@Injectable()
export class MyService {
  constructor(private readonly orm: MikroORM) {}

  @CreateRequestContext()
  async doSomething() {
    // this will be executed in a separate context
  }
}
```

> **Note** As the name suggests, this decorator always creates new context, as opposed to its alternative `@EnsureRequestContext` that only creates it if it's already not inside another one.

#### Testing[#](/recipes/mikroorm#testing)

The `@mikro-orm/nestjs` package exposes `getRepositoryToken()` function that returns prepared token based on a given entity to allow mocking the repository.

```typescript

@Module({
  providers: [
    PhotoService,
    {
      // or when you have a custom repository: `provide: PhotoRepository`
      provide: getRepositoryToken(Photo), 
      useValue: mockedRepository,
    },
  ],
})
export class PhotoModule {}
```

#### Example[#](/recipes/mikroorm#example)

A real world example of NestJS with MikroORM can be found [here](https://github.com/mikro-orm/nestjs-realworld-example-app)

----
url: https://docs.nestjs.com/v8/techniques/database
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Database](https://docs.nestjs.com/v8/techniques/database#database)
* [TypeORM Integration](https://docs.nestjs.com/v8/techniques/database#typeorm-integration)
* [Repository pattern](https://docs.nestjs.com/v8/techniques/database#repository-pattern)
* [Relations](https://docs.nestjs.com/v8/techniques/database#relations)
* [Auto-load entities](https://docs.nestjs.com/v8/techniques/database#auto-load-entities)
* [Separating entity definition](https://docs.nestjs.com/v8/techniques/database#separating-entity-definition)
* [Transactions](https://docs.nestjs.com/v8/techniques/database#transactions)
* [Subscribers](https://docs.nestjs.com/v8/techniques/database#subscribers)
* [Migrations](https://docs.nestjs.com/v8/techniques/database#migrations)
* [Multiple databases](https://docs.nestjs.com/v8/techniques/database#multiple-databases)
* [Testing](https://docs.nestjs.com/v8/techniques/database#testing)
* [Async configuration](https://docs.nestjs.com/v8/techniques/database#async-configuration)
* [Custom DataSource Factory](https://docs.nestjs.com/v8/techniques/database#custom-datasource-factory)
* [Example](https://docs.nestjs.com/v8/techniques/database#example)
* [Sequelize Integration](https://docs.nestjs.com/v8/techniques/database#sequelize-integration)
* [Models](https://docs.nestjs.com/v8/techniques/database#models)
* [Relations](https://docs.nestjs.com/v8/techniques/database#relations-1)
* [Auto-load models](https://docs.nestjs.com/v8/techniques/database#auto-load-models)
* [Transactions](https://docs.nestjs.com/v8/techniques/database#transactions-1)
* [Migrations](https://docs.nestjs.com/v8/techniques/database#migrations-1)
* [Multiple databases](https://docs.nestjs.com/v8/techniques/database#multiple-databases-1)
* [Testing](https://docs.nestjs.com/v8/techniques/database#testing-1)
* [Async configuration](https://docs.nestjs.com/v8/techniques/database#async-configuration-1)
* [Example](https://docs.nestjs.com/v8/techniques/database#example-1)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/techniques/sql.md "Suggest Edits")

### Database

Nest is database agnostic, allowing you to easily integrate with any SQL or NoSQL database. You have a number of options available to you, depending on your preferences. At the most general level, connecting Nest to a database is simply a matter of loading an appropriate Node.js driver for the database, just as you would with [Express](https://expressjs.com/en/guide/database-integration.html) or Fastify.

You can also directly use any general purpose Node.js database integration **library** or ORM, such as [MikroORM](https://mikro-orm.io/) also check the [recipe here](/v8/recipes/mikroorm), [Sequelize](https://sequelize.org/) (navigate to the [Sequelize integration](/techniques/database#sequelize-integration) section), [Knex.js](https://knexjs.org/) ([tutorial](https://dev.to/nestjs/build-a-nestjs-module-for-knex-js-or-other-resource-based-libraries-in-5-minutes-12an)), [TypeORM](https://github.com/typeorm/typeorm), and [Prisma](https://www.github.com/prisma/prisma) ([recipe](/v8/recipes/prisma)) , to operate at a higher level of abstraction.

For convenience, Nest provides tight integration with TypeORM and Sequelize out-of-the-box with the `@nestjs/typeorm` and `@nestjs/sequelize` packages respectively, which we'll cover in the current chapter, and Mongoose with `@nestjs/mongoose`, which is covered in [this chapter](/v8/techniques/mongodb). These integrations provide additional NestJS-specific features, such as model/repository injection, testability, and asynchronous configuration to make accessing your chosen database even easier.

### TypeORM Integration

For integrating with SQL and NoSQL databases, Nest provides the `@nestjs/typeorm` package. Nest uses [TypeORM](https://github.com/typeorm/typeorm) because it's the most mature Object Relational Mapper (ORM) available for TypeScript. Since it's written in TypeScript, it integrates well with the Nest framework.

To begin using it, we first install the required dependencies. In this chapter, we'll demonstrate using the popular [MySQL](https://www.mysql.com/) Relational DBMS, but TypeORM provides support for many relational databases, such as PostgreSQL, Oracle, Microsoft SQL Server, SQLite, and even NoSQL databases like MongoDB. The procedure we walk through in this chapter will be the same for any database supported by TypeORM. You'll simply need to install the associated client API libraries for your selected database.

```bash

$ npm install --save @nestjs/typeorm typeorm mysql2
```

Once the installation process is complete, we can import the `TypeOrmModule` into the root `AppModule`.

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';

@Module({
  imports: [
    TypeOrmModule.forRoot({
      type: 'mysql',
      host: 'localhost',
      port: 3306,
      username: 'root',
      password: 'root',
      database: 'test',
      entities: [],
      synchronize: true,
    }),
  ],
})
export class AppModule {}
```

> **Warning** Setting `synchronize: true` shouldn't be used in production - otherwise you can lose production data.

The `forRoot()` method supports all the configuration properties exposed by the `DataSource` constructor from the [TypeORM](https://typeorm.io/data-source-options#common-data-source-options) package. In addition, there are several extra configuration properties described below.

|                    |                                                                     |
| ------------------ | ------------------------------------------------------------------- |
| `retryAttempts`    | Number of attempts to connect to the database (default: `10`)       |
| `retryDelay`       | Delay between connection retry attempts (ms) (default: `3000`)      |
| `autoLoadEntities` | If `true`, entities will be loaded automatically (default: `false`) |

> **Hint** Learn more about the data source options [here](https://typeorm.io/data-source-options).

Once this is done, the TypeORM `DataSource` and `EntityManager` objects will be available to inject across the entire project (without needing to import any modules), for example:

app.module.ts

JS TS

```typescript

import { DataSource } from 'typeorm';

@Module({
  imports: [TypeOrmModule.forRoot(), UsersModule],
})
export class AppModule {
  constructor(private dataSource: DataSource) {}
}
```

```typescript

import { DataSource } from 'typeorm';

@Dependencies(DataSource)
@Module({
  imports: [TypeOrmModule.forRoot(), UsersModule],
})
export class AppModule {
  constructor(dataSource) {
    this.dataSource = dataSource;
  }
}
```

#### Repository pattern[#](/techniques/database#repository-pattern)

[TypeORM](https://github.com/typeorm/typeorm) supports the **repository design pattern**, so each entity has its own repository. These repositories can be obtained from the database data source.

To continue the example, we need at least one entity. Let's define the `User` entity.

user.entity.ts

JS TS

```typescript

import { Entity, Column, PrimaryGeneratedColumn } from 'typeorm';

@Entity()
export class User {
  @PrimaryGeneratedColumn()
  id: number;

  @Column()
  firstName: string;

  @Column()
  lastName: string;

  @Column({ default: true })
  isActive: boolean;
}
```

> **Hint** Learn more about entities in the [TypeORM documentation](https://typeorm.io/#/entities).

The `User` entity file sits in the `users` directory. This directory contains all files related to the `UsersModule`. You can decide where to keep your model files, however, we recommend creating them near their **domain**, in the corresponding module directory.

To begin using the `User` entity, we need to let TypeORM know about it by inserting it into the `entities` array in the module `forRoot()` method options (unless you use a static glob path):

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { User } from './users/user.entity';

@Module({
  imports: [
    TypeOrmModule.forRoot({
      type: 'mysql',
      host: 'localhost',
      port: 3306,
      username: 'root',
      password: 'root',
      database: 'test',
      entities: [User],
      synchronize: true,
    }),
  ],
})
export class AppModule {}
```

Next, let's look at the `UsersModule`:

users.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { UsersService } from './users.service';
import { UsersController } from './users.controller';
import { User } from './user.entity';

@Module({
  imports: [TypeOrmModule.forFeature([User])],
  providers: [UsersService],
  controllers: [UsersController],
})
export class UsersModule {}
```

This module uses the `forFeature()` method to define which repositories are registered in the current scope. With that in place, we can inject the `UsersRepository` into the `UsersService` using the `@InjectRepository()` decorator:

users.service.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { User } from './user.entity';

@Injectable()
export class UsersService {
  constructor(
    @InjectRepository(User)
    private usersRepository: Repository<User>,
  ) {}

  findAll(): Promise<User[]> {
    return this.usersRepository.find();
  }

  findOne(id: string): Promise<User> {
    return this.usersRepository.findOneBy({ id });
  }

  async remove(id: string): Promise<void> {
    await this.usersRepository.delete(id);
  }
}
```

```typescript

import { Injectable, Dependencies } from '@nestjs/common';
import { getRepositoryToken } from '@nestjs/typeorm';
import { User } from './user.entity';

@Injectable()
@Dependencies(getRepositoryToken(User))
export class UsersService {
  constructor(usersRepository) {
    this.usersRepository = usersRepository;
  }

  findAll() {
    return this.usersRepository.find();
  }

  findOne(id) {
    return this.usersRepository.findOneBy({ id });
  }

  async remove(id) {
    await this.usersRepository.delete(id);
  }
}
```

> **Notice** Don't forget to import the `UsersModule` into the root `AppModule`.

If you want to use the repository outside of the module which imports `TypeOrmModule.forFeature`, you'll need to re-export the providers generated by it. You can do this by exporting the whole module, like this:

users.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { User } from './user.entity';

@Module({
  imports: [TypeOrmModule.forFeature([User])],
  exports: [TypeOrmModule]
})
export class UsersModule {}
```

Now if we import `UsersModule` in `UserHttpModule`, we can use `@InjectRepository(User)` in the providers of the latter module.

users-http.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { UsersModule } from './users.module';
import { UsersService } from './users.service';
import { UsersController } from './users.controller';

@Module({
  imports: [UsersModule],
  providers: [UsersService],
  controllers: [UsersController]
})
export class UserHttpModule {}
```

#### Relations[#](/techniques/database#relations)

Relations are associations established between two or more tables. Relations are based on common fields from each table, often involving primary and foreign keys.

There are three types of relations:

|                             |                                                                                                                                                                                                                                 |
| --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `One-to-one`                | Every row in the primary table has one and only one associated row in the foreign table. Use the `@OneToOne()` decorator to define this type of relation.                                                                       |
| `One-to-many / Many-to-one` | Every row in the primary table has one or more related rows in the foreign table. Use the `@OneToMany()` and `@ManyToOne()` decorators to define this type of relation.                                                         |
| `Many-to-many`              | Every row in the primary table has many related rows in the foreign table, and every record in the foreign table has many related rows in the primary table. Use the `@ManyToMany()` decorator to define this type of relation. |

To define relations in entities, use the corresponding **decorators**. For example, to define that each `User` can have multiple photos, use the `@OneToMany()` decorator.

user.entity.ts

JS TS

```typescript

import { Entity, Column, PrimaryGeneratedColumn, OneToMany } from 'typeorm';
import { Photo } from '../photos/photo.entity';

@Entity()
export class User {
  @PrimaryGeneratedColumn()
  id: number;

  @Column()
  firstName: string;

  @Column()
  lastName: string;

  @Column({ default: true })
  isActive: boolean;

  @OneToMany(type => Photo, photo => photo.user)
  photos: Photo[];
}
```

> **Hint** To learn more about relations in TypeORM, visit the [TypeORM documentation](https://typeorm.io/#/relations).

#### Auto-load entities[#](/techniques/database#auto-load-entities)

Manually adding entities to the `entities` array of the data source options can be tedious. In addition, referencing entities from the root module breaks application domain boundaries and causes leaking implementation details to other parts of the application. To address this issue, an alternative solution is provided. To automatically load entities, set the `autoLoadEntities` property of the configuration object (passed into the `forRoot()` method) to `true`, as shown below:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';

@Module({
  imports: [
    TypeOrmModule.forRoot({
      ...
      autoLoadEntities: true,
    }),
  ],
})
export class AppModule {}
```

With that option specified, every entity registered through the `forFeature()` method will be automatically added to the `entities` array of the configuration object.

> **Warning** Note that entities that aren't registered through the `forFeature()` method, but are only referenced from the entity (via a relationship), won't be included by way of the `autoLoadEntities` setting.

#### Separating entity definition[#](/techniques/database#separating-entity-definition)

You can define an entity and its columns right in the model, using decorators. But some people prefer to define entities and their columns inside separate files using the ["entity schemas"](https://typeorm.io/#/separating-entity-definition).

```typescript

import { EntitySchema } from 'typeorm';
import { User } from './user.entity';

export const UserSchema = new EntitySchema<User>({
  name: 'User',
  target: User,
  columns: {
    id: {
      type: Number,
      primary: true,
      generated: true,
    },
    firstName: {
      type: String,
    },
    lastName: {
      type: String,
    },
    isActive: {
      type: Boolean,
      default: true,
    },
  },
  relations: {
    photos: {
      type: 'one-to-many',
      target: 'Photo', // the name of the PhotoSchema
    },
  },
});
```

> **Warning** If you provide the `target` option, the `name` option value has to be the same as the name of the target class. If you do not provide the `target` you can use any name.

Nest allows you to use an `EntitySchema` instance wherever an `Entity` is expected, for example:

```typescript

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { UserSchema } from './user.schema';
import { UsersController } from './users.controller';
import { UsersService } from './users.service';

@Module({
  imports: [TypeOrmModule.forFeature([UserSchema])],
  providers: [UsersService],
  controllers: [UsersController],
})
export class UsersModule {}
```

#### Transactions[#](/techniques/database#transactions)

A database transaction symbolizes a unit of work performed within a database management system against a database, and treated in a coherent and reliable way independent of other transactions. A transaction generally represents any change in a database ([learn more](https://en.wikipedia.org/wiki/Database_transaction)).

There are many different strategies to handle [TypeORM transactions](https://typeorm.io/#/transactions). We recommend using the `QueryRunner` class because it gives full control over the transaction.

First, we need to inject the `DataSource` object into a class in the normal way:

```typescript

@Injectable()
export class UsersService {
  constructor(private dataSource: DataSource) {}
}
```

> **Hint** The `DataSource` class is imported from the `typeorm` package.

Now, we can use this object to create a transaction.

```typescript

async createMany(users: User[]) {
  const queryRunner = this.dataSource.createQueryRunner();

  await queryRunner.connect();
  await queryRunner.startTransaction();
  try {
    await queryRunner.manager.save(users[0]);
    await queryRunner.manager.save(users[1]);

    await queryRunner.commitTransaction();
  } catch (err) {
    // since we have errors lets rollback the changes we made
    await queryRunner.rollbackTransaction();
  } finally {
    // you need to release a queryRunner which was manually instantiated
    await queryRunner.release();
  }
}
```

> **Hint** Note that the `dataSource` is used only to create the `QueryRunner`. However, to test this class would require mocking the entire `DataSource` object (which exposes several methods). Thus, we recommend using a helper factory class (e.g., `QueryRunnerFactory`) and defining an interface with a limited set of methods required to maintain transactions. This technique makes mocking these methods pretty straightforward.

Alternatively, you can use the callback-style approach with the `transaction` method of the `DataSource` object ([read more](https://typeorm.io/#/transactions/creating-and-using-transactions)).

```typescript

async createMany(users: User[]) {
  await this.dataSource.transaction(async manager => {
    await manager.save(users[0]);
    await manager.save(users[1]);
  });
}
```

Using decorators to control the transaction (`@Transaction()` and `@TransactionManager()`) is not recommended.

## Hoodies, T-shirts, and accessories!

Support our future development by shopping in the official store!

[See more](https://nestjs.threadless.com/ "Shop | NestJS - A node.js framework built on top of TypeScript")

#### Subscribers[#](/techniques/database#subscribers)

With TypeORM [subscribers](https://typeorm.io/#/listeners-and-subscribers/what-is-a-subscriber), you can listen to specific entity events.

```typescript

import {
  DataSource,
  EntitySubscriberInterface,
  EventSubscriber,
  InsertEvent,
} from 'typeorm';
import { User } from './user.entity';

@EventSubscriber()
export class UserSubscriber implements EntitySubscriberInterface<User> {
  constructor(dataSource: DataSource) {
    dataSource.subscribers.push(this);
  }

  listenTo() {
    return User;
  }

  beforeInsert(event: InsertEvent<User>) {
    console.log(`BEFORE USER INSERTED: `, event.entity);
  }
}
```

> **Warning** Event subscribers can not be [request-scoped](/v8/fundamentals/injection-scopes).

Now, add the `UserSubscriber` class to the `providers` array:

```typescript

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { User } from './user.entity';
import { UsersController } from './users.controller';
import { UsersService } from './users.service';
import { UserSubscriber } from './user.subscriber';

@Module({
  imports: [TypeOrmModule.forFeature([User])],
  providers: [UsersService, UserSubscriber],
  controllers: [UsersController],
})
export class UsersModule {}
```

> **Hint** Learn more about entity subscribers [here](https://typeorm.io/#/listeners-and-subscribers/what-is-a-subscriber).

#### Migrations[#](/techniques/database#migrations)

[Migrations](https://typeorm.io/#/migrations) provide a way to incrementally update the database schema to keep it in sync with the application's data model while preserving existing data in the database. To generate, run, and revert migrations, TypeORM provides a dedicated [CLI](https://typeorm.io/#/migrations/creating-a-new-migration).

Migration classes are separate from the Nest application source code. Their lifecycle is maintained by the TypeORM CLI. Therefore, you are not able to leverage dependency injection and other Nest specific features with migrations. To learn more about migrations, follow the guide in the [TypeORM documentation](https://typeorm.io/#/migrations/creating-a-new-migration).

#### Multiple databases[#](/techniques/database#multiple-databases)

Some projects require multiple database connections. This can also be achieved with this module. To work with multiple connections, first create the connections. In this case, data source naming becomes **mandatory**.

Suppose you have an `Album` entity stored in its own database.

```typescript

const defaultOptions = {
  type: 'postgres',
  port: 5432,
  username: 'user',
  password: 'password',
  database: 'db',
  synchronize: true,
};

@Module({
  imports: [
    TypeOrmModule.forRoot({
      ...defaultOptions,
      host: 'user_db_host',
      entities: [User],
    }),
    TypeOrmModule.forRoot({
      ...defaultOptions,
      name: 'albumsConnection',
      host: 'album_db_host',
      entities: [Album],
    }),
  ],
})
export class AppModule {}
```

> **Notice** If you don't set the `name` for a data source, its name is set to `default`. Please note that you shouldn't have multiple connections without a name, or with the same name, otherwise they will get overridden.

> **Notice** If you are using `TypeOrmModule.forRootAsync`, you have to set the data source name outside `useFactory`. For example:
>
> ```typescript
>
> TypeOrmModule.forRootAsync({
>   name: 'albumsConnection',
>   useFactory: ...,
>   inject: ...,
> }),
> ```
>
> See [this issue](https://github.com/nestjs/typeorm/issues/86) for more details.

At this point, you have `User` and `Album` entities registered with their own data source. With this setup, you have to tell the `TypeOrmModule.forFeature()` method and the `@InjectRepository()` decorator which data source should be used. If you do not pass any data source name, the `default` data source is used.

```typescript

@Module({
  imports: [
    TypeOrmModule.forFeature([User]),
    TypeOrmModule.forFeature([Album], 'albumsConnection'),
  ],
})
export class AppModule {}
```

You can also inject the `DataSource` or `EntityManager` for a given data source:

```typescript

@Injectable()
export class AlbumsService {
  constructor(
    @InjectConnection('albumsConnection')
    private dataSource: DataSource,
    @InjectEntityManager('albumsConnection')
    private entityManager: EntityManager,
  ) {}
}
```

It's also possible to inject any `DataSource` to the providers:

```typescript

@Module({
  providers: [
    {
      provide: AlbumsService,
      useFactory: (albumsConnection: DataSource) => {
        return new AlbumsService(albumsConnection);
      },
      inject: [getDataSourceToken('albumsConnection')],
    },
  ],
})
export class AlbumsModule {}
```

#### Testing[#](/techniques/database#testing)

When it comes to unit testing an application, we usually want to avoid making a database connection, keeping our test suites independent and their execution process as fast as possible. But our classes might depend on repositories that are pulled from the data source (connection) instance. How do we handle that? The solution is to create mock repositories. In order to achieve that, we set up [custom providers](/v8/fundamentals/custom-providers). Each registered repository is automatically represented by an `<EntityName>Repository` token, where `EntityName` is the name of your entity class.

The `@nestjs/typeorm` package exposes the `getRepositoryToken()` function which returns a prepared token based on a given entity.

```typescript

@Module({
  providers: [
    UsersService,
    {
      provide: getRepositoryToken(User),
      useValue: mockRepository,
    },
  ],
})
export class UsersModule {}
```

Now a substitute `mockRepository` will be used as the `UsersRepository`. Whenever any class asks for `UsersRepository` using an `@InjectRepository()` decorator, Nest will use the registered `mockRepository` object.

#### Async configuration[#](/techniques/database#async-configuration)

You may want to pass your repository module options asynchronously instead of statically. In this case, use the `forRootAsync()` method, which provides several ways to deal with async configuration.

One approach is to use a factory function:

```typescript

TypeOrmModule.forRootAsync({
  useFactory: () => ({
    type: 'mysql',
    host: 'localhost',
    port: 3306,
    username: 'root',
    password: 'root',
    database: 'test',
    entities: [],
    synchronize: true,
  }),
});
```

Our factory behaves like any other [asynchronous provider](https://docs.nestjs.com/fundamentals/async-providers) (e.g., it can be `async` and it's able to inject dependencies through `inject`).

```typescript

TypeOrmModule.forRootAsync({
  imports: [ConfigModule],
  useFactory: (configService: ConfigService) => ({
    type: 'mysql',
    host: configService.get('HOST'),
    port: +configService.get('PORT'),
    username: configService.get('USERNAME'),
    password: configService.get('PASSWORD'),
    database: configService.get('DATABASE'),
    entities: [],
    synchronize: true,
  }),
  inject: [ConfigService],
});
```

Alternatively, you can use the `useClass` syntax:

```typescript

TypeOrmModule.forRootAsync({
  useClass: TypeOrmConfigService,
});
```

The construction above will instantiate `TypeOrmConfigService` inside `TypeOrmModule` and use it to provide an options object by calling `createTypeOrmOptions()`. Note that this means that the `TypeOrmConfigService` has to implement the `TypeOrmOptionsFactory` interface, as shown below:

```typescript

@Injectable()
class TypeOrmConfigService implements TypeOrmOptionsFactory {
  createTypeOrmOptions(): TypeOrmModuleOptions {
    return {
      type: 'mysql',
      host: 'localhost',
      port: 3306,
      username: 'root',
      password: 'root',
      database: 'test',
      entities: [],
      synchronize: true,
    };
  }
}
```

In order to prevent the creation of `TypeOrmConfigService` inside `TypeOrmModule` and use a provider imported from a different module, you can use the `useExisting` syntax.

```typescript

TypeOrmModule.forRootAsync({
  imports: [ConfigModule],
  useExisting: ConfigService,
});
```

This construction works the same as `useClass` with one critical difference - `TypeOrmModule` will lookup imported modules to reuse an existing `ConfigService` instead of instantiating a new one.

> **Hint** Make sure that the `name` property is defined at the same level as the `useFactory`, `useClass`, or `useValue` property. This will allow Nest to properly register the data source under the appropriate injection token.

#### Custom DataSource Factory[#](/techniques/database#custom-datasource-factory)

In conjunction with async configuration using `useFactory`, `useClass`, or `useExisting`, you can optionally specify a `dataSourceFactory` function which will allow you to provide your own TypeORM data source rather than allowing `TypeOrmModule` to create the data source.

`dataSourceFactory` receives the TypeORM `DataSourceOptions` configured during async configuration using `useFactory`, `useClass`, or `useExisting` and returns a `Promise` that resolves a TypeORM `DataSource`.

```typescript

TypeOrmModule.forRootAsync({
  imports: [ConfigModule],
  inject: [ConfigService],
  // Use useFactory, useClass, or useExisting
  // to configure the DataSourceOptions.
  useFactory: (configService: ConfigService) => ({
    type: 'mysql',
    host: configService.get('HOST'),
    port: +configService.get('PORT'),
    username: configService.get('USERNAME'),
    password: configService.get('PASSWORD'),
    database: configService.get('DATABASE'),
    entities: [],
    synchronize: true,
  }),
  // dataSource receives the configured DataSourceOptions
  // and returns a Promise<DataSource>.
  dataSourceFactory: async (options) => {
    const dataSource = await new DataSource(options).initialize();
    return dataSource;
  },
});
```

> **Hint** The `DataSource` class is imported from the `typeorm` package.

```bash

$ npm install --save @nestjs/sequelize sequelize sequelize-typescript mysql2
$ npm install --save-dev @types/sequelize
```

Once the installation process is complete, we can import the `SequelizeModule` into the root `AppModule`.

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { SequelizeModule } from '@nestjs/sequelize';

@Module({
  imports: [
    SequelizeModule.forRoot({
      dialect: 'mysql',
      host: 'localhost',
      port: 3306,
      username: 'root',
      password: 'root',
      database: 'test',
      models: [],
    }),
  ],
})
export class AppModule {}
```

The `forRoot()` method supports all the configuration properties exposed by the Sequelize constructor ([read more](https://sequelize.org/v5/manual/getting-started.html#setting-up-a-connection)). In addition, there are several extra configuration properties described below.

|                       |                                                                                         |
| --------------------- | --------------------------------------------------------------------------------------- |
| `retryAttempts`       | Number of attempts to connect to the database (default: `10`)                           |
| `retryDelay`          | Delay between connection retry attempts (ms) (default: `3000`)                          |
| `autoLoadModels`      | If `true`, models will be loaded automatically (default: `false`)                       |
| `keepConnectionAlive` | If `true`, connection will not be closed on the application shutdown (default: `false`) |
| `synchronize`         | If `true`, automatically loaded models will be synchronized (default: `true`)           |

Once this is done, the `Sequelize` object will be available to inject across the entire project (without needing to import any modules), for example:

app.service.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { Sequelize } from 'sequelize-typescript';

@Injectable()
export class AppService {
  constructor(private sequelize: Sequelize) {}
}
```

```typescript

import { Injectable } from '@nestjs/common';
import { Sequelize } from 'sequelize-typescript';

@Dependencies(Sequelize)
@Injectable()
export class AppService {
  constructor(sequelize) {
    this.sequelize = sequelize;
  }
}
```

#### Models[#](/techniques/database#models)

Sequelize implements the Active Record pattern. With this pattern, you use model classes directly to interact with the database. To continue the example, we need at least one model. Let's define the `User` model.

user.model.ts

JS TS

```typescript

import { Column, Model, Table } from 'sequelize-typescript';

@Table
export class User extends Model {
  @Column
  firstName: string;

  @Column
  lastName: string;

  @Column({ defaultValue: true })
  isActive: boolean;
}
```

> **Hint** Learn more about the available decorators [here](https://github.com/RobinBuschmann/sequelize-typescript#column).

The `User` model file sits in the `users` directory. This directory contains all files related to the `UsersModule`. You can decide where to keep your model files, however, we recommend creating them near their **domain**, in the corresponding module directory.

To begin using the `User` model, we need to let Sequelize know about it by inserting it into the `models` array in the module `forRoot()` method options:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { SequelizeModule } from '@nestjs/sequelize';
import { User } from './users/user.model';

@Module({
  imports: [
    SequelizeModule.forRoot({
      dialect: 'mysql',
      host: 'localhost',
      port: 3306,
      username: 'root',
      password: 'root',
      database: 'test',
      models: [User],
    }),
  ],
})
export class AppModule {}
```

Next, let's look at the `UsersModule`:

users.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { SequelizeModule } from '@nestjs/sequelize';
import { User } from './user.model';
import { UsersController } from './users.controller';
import { UsersService } from './users.service';

@Module({
  imports: [SequelizeModule.forFeature([User])],
  providers: [UsersService],
  controllers: [UsersController],
})
export class UsersModule {}
```

This module uses the `forFeature()` method to define which models are registered in the current scope. With that in place, we can inject the `UserModel` into the `UsersService` using the `@InjectModel()` decorator:

users.service.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { InjectModel } from '@nestjs/sequelize';
import { User } from './user.model';

@Injectable()
export class UsersService {
  constructor(
    @InjectModel(User)
    private userModel: typeof User,
  ) {}

  async findAll(): Promise<User[]> {
    return this.userModel.findAll();
  }

  findOne(id: string): Promise<User> {
    return this.userModel.findOne({
      where: {
        id,
      },
    });
  }

  async remove(id: string): Promise<void> {
    const user = await this.findOne(id);
    await user.destroy();
  }
}
```

```typescript

import { Injectable, Dependencies } from '@nestjs/common';
import { getModelToken } from '@nestjs/sequelize';
import { User } from './user.model';

@Injectable()
@Dependencies(getModelToken(User))
export class UsersService {
  constructor(usersRepository) {
    this.usersRepository = usersRepository;
  }

  async findAll() {
    return this.userModel.findAll();
  }

  findOne(id) {
    return this.userModel.findOne({
      where: {
        id,
      },
    });
  }

  async remove(id) {
    const user = await this.findOne(id);
    await user.destroy();
  }
}
```

> **Notice** Don't forget to import the `UsersModule` into the root `AppModule`.

If you want to use the repository outside of the module which imports `SequelizeModule.forFeature`, you'll need to re-export the providers generated by it. You can do this by exporting the whole module, like this:

users.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { SequelizeModule } from '@nestjs/sequelize';
import { User } from './user.entity';

@Module({
  imports: [SequelizeModule.forFeature([User])],
  exports: [SequelizeModule]
})
export class UsersModule {}
```

Now if we import `UsersModule` in `UserHttpModule`, we can use `@InjectModel(User)` in the providers of the latter module.

users-http.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { UsersModule } from './users.module';
import { UsersService } from './users.service';
import { UsersController } from './users.controller';

@Module({
  imports: [UsersModule],
  providers: [UsersService],
  controllers: [UsersController]
})
export class UserHttpModule {}
```

#### Relations[#](/techniques/database#relations-1)

Relations are associations established between two or more tables. Relations are based on common fields from each table, often involving primary and foreign keys.

There are three types of relations:

|                             |                                                                                                                                                             |
| --------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `One-to-one`                | Every row in the primary table has one and only one associated row in the foreign table                                                                     |
| `One-to-many / Many-to-one` | Every row in the primary table has one or more related rows in the foreign table                                                                            |
| `Many-to-many`              | Every row in the primary table has many related rows in the foreign table, and every record in the foreign table has many related rows in the primary table |

To define relations in entities, use the corresponding **decorators**. For example, to define that each `User` can have multiple photos, use the `@HasMany()` decorator.

user.entity.ts

JS TS

```typescript

import { Column, Model, Table, HasMany } from 'sequelize-typescript';
import { Photo } from '../photos/photo.model';

@Table
export class User extends Model {
  @Column
  firstName: string;

  @Column
  lastName: string;

  @Column({ defaultValue: true })
  isActive: boolean;

  @HasMany(() => Photo)
  photos: Photo[];
}
```

> **Hint** To learn more about associations in Sequelize, read [this](https://github.com/RobinBuschmann/sequelize-typescript#model-association) chapter.

#### Auto-load models[#](/techniques/database#auto-load-models)

Manually adding models to the `models` array of the connection options can be tedious. In addition, referencing models from the root module breaks application domain boundaries and causes leaking implementation details to other parts of the application. To solve this issue, automatically load models by setting both `autoLoadModels` and `synchronize` properties of the configuration object (passed into the `forRoot()` method) to `true`, as shown below:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { SequelizeModule } from '@nestjs/sequelize';

@Module({
  imports: [
    SequelizeModule.forRoot({
      ...
      autoLoadModels: true,
      synchronize: true,
    }),
  ],
})
export class AppModule {}
```

With that option specified, every model registered through the `forFeature()` method will be automatically added to the `models` array of the configuration object.

> **Warning** Note that models that aren't registered through the `forFeature()` method, but are only referenced from the model (via an association), won't be included.

#### Transactions[#](/techniques/database#transactions-1)

A database transaction symbolizes a unit of work performed within a database management system against a database, and treated in a coherent and reliable way independent of other transactions. A transaction generally represents any change in a database ([learn more](https://en.wikipedia.org/wiki/Database_transaction)).

There are many different strategies to handle [Sequelize transactions](https://sequelize.org/v5/manual/transactions.html). Below is a sample implementation of a managed transaction (auto-callback).

First, we need to inject the `Sequelize` object into a class in the normal way:

```typescript

@Injectable()
export class UsersService {
  constructor(private sequelize: Sequelize) {}
}
```

> **Hint** The `Sequelize` class is imported from the `sequelize-typescript` package.

Now, we can use this object to create a transaction.

```typescript

async createMany() {
  try {
    await this.sequelize.transaction(async t => {
      const transactionHost = { transaction: t };

      await this.userModel.create(
          { firstName: 'Abraham', lastName: 'Lincoln' },
          transactionHost,
      );
      await this.userModel.create(
          { firstName: 'John', lastName: 'Boothe' },
          transactionHost,
      );
    });
  } catch (err) {
    // Transaction has been rolled back
    // err is whatever rejected the promise chain returned to the transaction callback
  }
}
```

> **Hint** Note that the `Sequelize` instance is used only to start the transaction. However, to test this class would require mocking the entire `Sequelize` object (which exposes several methods). Thus, we recommend using a helper factory class (e.g., `TransactionRunner`) and defining an interface with a limited set of methods required to maintain transactions. This technique makes mocking these methods pretty straightforward.

```typescript

const defaultOptions = {
  dialect: 'postgres',
  port: 5432,
  username: 'user',
  password: 'password',
  database: 'db',
  synchronize: true,
};

@Module({
  imports: [
    SequelizeModule.forRoot({
      ...defaultOptions,
      host: 'user_db_host',
      models: [User],
    }),
    SequelizeModule.forRoot({
      ...defaultOptions,
      name: 'albumsConnection',
      host: 'album_db_host',
      models: [Album],
    }),
  ],
})
export class AppModule {}
```

> **Notice** If you don't set the `name` for a connection, its name is set to `default`. Please note that you shouldn't have multiple connections without a name, or with the same name, otherwise they will get overridden.

At this point, you have `User` and `Album` models registered with their own connection. With this setup, you have to tell the `SequelizeModule.forFeature()` method and the `@InjectModel()` decorator which connection should be used. If you do not pass any connection name, the `default` connection is used.

```typescript

@Module({
  imports: [
    SequelizeModule.forFeature([User]),
    SequelizeModule.forFeature([Album], 'albumsConnection'),
  ],
})
export class AppModule {}
```

You can also inject the `Sequelize` instance for a given connection:

```typescript

@Injectable()
export class AlbumsService {
  constructor(
    @InjectConnection('albumsConnection')
    private sequelize: Sequelize,
  ) {}
}
```

It's also possible to inject any `Sequelize` instance to the providers:

```typescript

@Module({
  providers: [
    {
      provide: AlbumsService,
      useFactory: (albumsSequelize: Sequelize) => {
        return new AlbumsService(albumsSequelize);
      },
      inject: [getConnectionToken('albumsConnection')],
    },
  ],
})
export class AlbumsModule {}
```

#### Testing[#](/techniques/database#testing-1)

When it comes to unit testing an application, we usually want to avoid making a database connection, keeping our test suites independent and their execution process as fast as possible. But our classes might depend on models that are pulled from the connection instance. How do we handle that? The solution is to create mock models. In order to achieve that, we set up [custom providers](/v8/fundamentals/custom-providers). Each registered model is automatically represented by a `<ModelName>Model` token, where `ModelName` is the name of your model class.

The `@nestjs/sequelize` package exposes the `getModelToken()` function which returns a prepared token based on a given model.

```typescript

@Module({
  providers: [
    UsersService,
    {
      provide: getModelToken(User),
      useValue: mockModel,
    },
  ],
})
export class UsersModule {}
```

Now a substitute `mockModel` will be used as the `UserModel`. Whenever any class asks for `UserModel` using an `@InjectModel()` decorator, Nest will use the registered `mockModel` object.

#### Async configuration[#](/techniques/database#async-configuration-1)

You may want to pass your `SequelizeModule` options asynchronously instead of statically. In this case, use the `forRootAsync()` method, which provides several ways to deal with async configuration.

One approach is to use a factory function:

```typescript

SequelizeModule.forRootAsync({
  useFactory: () => ({
    dialect: 'mysql',
    host: 'localhost',
    port: 3306,
    username: 'root',
    password: 'root',
    database: 'test',
    models: [],
  }),
});
```

Our factory behaves like any other [asynchronous provider](https://docs.nestjs.com/fundamentals/async-providers) (e.g., it can be `async` and it's able to inject dependencies through `inject`).

```typescript

SequelizeModule.forRootAsync({
  imports: [ConfigModule],
  useFactory: (configService: ConfigService) => ({
    dialect: 'mysql',
    host: configService.get('HOST'),
    port: +configService.get('PORT'),
    username: configService.get('USERNAME'),
    password: configService.get('PASSWORD'),
    database: configService.get('DATABASE'),
    models: [],
  }),
  inject: [ConfigService],
});
```

Alternatively, you can use the `useClass` syntax:

```typescript

SequelizeModule.forRootAsync({
  useClass: SequelizeConfigService,
});
```

The construction above will instantiate `SequelizeConfigService` inside `SequelizeModule` and use it to provide an options object by calling `createSequelizeOptions()`. Note that this means that the `SequelizeConfigService` has to implement the `SequelizeOptionsFactory` interface, as shown below:

```typescript

@Injectable()
class SequelizeConfigService implements SequelizeOptionsFactory {
  createSequelizeOptions(): SequelizeModuleOptions {
    return {
      dialect: 'mysql',
      host: 'localhost',
      port: 3306,
      username: 'root',
      password: 'root',
      database: 'test',
      models: [],
    };
  }
}
```

In order to prevent the creation of `SequelizeConfigService` inside `SequelizeModule` and use a provider imported from a different module, you can use the `useExisting` syntax.

```typescript

SequelizeModule.forRootAsync({
  imports: [ConfigModule],
  useExisting: ConfigService,
});
```

This construction works the same as `useClass` with one critical difference - `SequelizeModule` will lookup imported modules to reuse an existing `ConfigService` instead of instantiating a new one.

#### Example[#](/techniques/database#example-1)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/07-sequelize).

----
url: https://docs.nestjs.com/v6/cli/libraries
----

* [Libraries](https://docs.nestjs.com/v6/cli/libraries#libraries)
* [Nest libraries](https://docs.nestjs.com/v6/cli/libraries#nest-libraries)
* [Creating libraries](https://docs.nestjs.com/v6/cli/libraries#creating-libraries)
* [Using libraries](https://docs.nestjs.com/v6/cli/libraries#using-libraries)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/cli/libraries.md "Suggest Edits")

### Libraries

Many applications need to solve the same general problems, or re-use a modular component in several different contexts. Nest has a few ways of addressing this, but each works at a different level to solve the problem in a way that helps meet different architectural and organizational objectives.

Nest [modules](/v6/modules) are useful for providing an execution context that enables sharing components within a single application. Modules can also be packaged with [npm](https://npmjs.com) to create a reusable library that can be installed in different projects. This can be an effective way to distribute configurable, re-usable libraries that can be used by different, loosely connected or unafilliated organizations (e.g., by distributing/installing 3rd party libraries).

For sharing code within closely organized groups (e.g., within company/project boundaries), it can be useful to have a more lightweight approach to sharing components. Monorepo's have arisen as a construct to enable that, and within a monorepo, a **library** provides a way to share code in an easy, lightweight fashion. In a Nest monorepo, using libraries enables easy assembly of applications that share components. In fact, this encourages decomposition of monolithic applications and development processes to focus on building and composing modular components.

#### Nest libraries[#](/cli/libraries#nest-libraries)

A Nest library is a Nest project that differs from an application in that it cannot run on its own. A library must be imported into a containing application in order for its code to execute. The built-in support for libraries described in this section is only available for **monorepos** (standard mode projects can achieve similar functionality using npm packages).

For example, an organization may develop an `AuthModule` that manages authentication by implementing company policies that govern all internal applications. Rather than build that module separately for each application, or physically packaging the code with npm and requiring each project to install it, a monorepo can define this module as a library. When organized this way, all consumers of the library module can see an up-to-date version of the `AuthModule` as it is committed. This can have significant benefits for coordinating component development and assembly, and simplifying end-to-end testing.

#### Creating libraries[#](/cli/libraries#creating-libraries)

Any functionality that is suitable for re-use is a candidate for being managed as a library. Deciding what should be a library, and what should be part of an application, is an architectural design decision. Creating libraries involves more than simply copying code from an existing application to a new library. When packaged as a library, the library code must be decoupled from the application. This may require **more** time up front and force some design decisions that you may not face with more tightly coupled code. But this additional effort can pay off when the library can be used to enable more rapid application assembly across multiple applications.

To get started with creating a library, run the following command:

```bash

nest g library my-library
```

When you run the command, the `library` schematic prompts you for a prefix (AKA alias) for the library:

```bash

What prefix would you like to use for the library (default: @app)?
```

```javascript

...
{
    "my-library": {
      "type": "library",
      "root": "libs/my-library",
      "entryFile": "index",
      "sourceRoot": "libs/my-library/src",
      "compilerOptions": {
        "tsConfigPath": "libs/my-library/tsconfig.lib.json"
      }
}
...
```

There are two differences in `nest-cli.json` metadata between libraries and applications:

* the `"type"` property is set to `"library"` instead of `"application"`
* the `"entryFile"` property is set to `"index"` instead of `"main"`

These differences key the build process to handle libraries appropriately. For example, a library exports its functions through the `index.js` file.

As with application-type projects, libraries each have their own `tsconfig.lib.json` file that extends the root (monorepo-wide) `tsconfig.json` file. You can modify this file, if necessary, to provide library-specific compiler options.

You can build the library with the CLI command:

```bash

nest build my-library
```

#### Using libraries[#](/cli/libraries#using-libraries)

With the automatically generated configuration files in place, using libraries is straightforward. How would we import `MyLibraryService` from the `my-library` library into the `my-project` application?

First, note that using library modules is the same as using any other Nest module. What the monorepo does is manage paths in a way that importing libraries and generating builds is now transparent. To use `MyLibraryService`, we need to import its declaring module. We can modify `my-project/src/app.module.ts` as follows to import `MyLibraryModule`.

```typescript

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { MyLibraryModule } from '@app/my-library';

@Module({
  imports: [MyLibraryModule],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}
```

Notice above that we've used a path alias of `@app` in the ES module `import` line, which was the `prefix` we supplied with the `nest g library` command above. Under the covers, Nest handles this through tsconfig path mapping. When adding a library, Nest updates the global (monorepo) `tsconfig.json` file's `"paths"` key like this:

```javascript

"paths": {
    "@app/my-library": [
        "libs/my-library/src"
    ],
    "@app/my-library/*": [
        "libs/my-library/src/*"
    ]
}
```

So, in a nutshell, the combination of the monorepo and library features has made it easy and intuitive to include library modules into applications.

This same mechanism enables building and deploying applications that compose libraries. Once you've imported the `MyLibraryModule`, running `nest build` handles all the module resolution automatically and bundles the app along with any library dependencies, for deployment. The default compiler for a monorepo is **webpack**, so the resulting distribution file is a single file that bundles all of the transpiled JavaScript files into a single file. You can also switch to `tsc` as described [here](https://docs.nestjs.com/cli/monorepo#global-compiler-options).

----
url: https://docs.nestjs.com/v4/fundamentals/dependency-injection
----

### Dependency Injection

There's a lot of scenarios when you'd wanna bind something directly to the Nest container. The only thing you should know is that Nest is injecting dependencies by **tokens**. Usually, the token is just a type. If you wanna provide custom component, you'd need to create a token. Mostly, the custom tokens are plain strings. Following best practices, you should hold this token in the separated file, for example, `constants.ts`.

Let's go through the available options:

#### Use Value

TypeScript

```typescript

const connectionProvider = { provide: 'ConnectionToken', useValue: null };

@Module({
  components: [connectionProvider],
})
```

> **Hint** It's a good practice to keep custom providers inside separated file, for example `cats.providers.ts`.

Use cases:

* bind specific value to the container, for example 3rd party library

#### Use Factory

JavaScript TypeScript

TypeScript

```typescript

const connectionFactory = {
  provide: 'ConnectionToken',
  useFactory: (optionsProvider: OptionsProvider) => {
    const options = optionsProvider.get();
    return new DatabaseConnection(options);
  },
  inject: [OptionsProvider],
};

@Module({
  components: [connectionFactory],
})
```

TypeScript

```typescript

const connectionFactory = {
  provide: 'ConnectionToken',
  useFactory: (optionsProvider) => {
    const options = optionsProvider.get();
    return new DatabaseConnection(options);
  },
  inject: [OptionsProvider],
};

@Module({
  components: [connectionFactory],
})
```

> **Notice** If you wanna use components from module, you have to pass them inside `inject` array. Nest will pass instances as an arguments of the function in the same order.

Use cases:

* provide a value, which has to be calculated using other components (or custom packages features)
* provide a deffered value, for example database connection (read more about [async components](/v4/fundamentals/async-components))

#### Use Class

TypeScript

```typescript

const configServiceProvider = {
  provide: ConfigService,
  useClass: DevelopmentConfigService,
};

@Module({
  components: [configServiceProvider],
})
```

> **Notice** Instead of a custom token, we have used the `ConfigService` class, so in fact, we have overrided the default implementation.

Use cases:

* override default class implementation

#### Injection

To inject custom component through constructor, we're using the `@Inject()` decorator. This decorator takes 1 argument - the token.

JavaScript TypeScript

TypeScript

```typescript

@Component()
class CatsRepository {
  constructor(@Inject('ConnectionToken') connection: Connection) {}
}
```

TypeScript

```typescript

@Component()
@Dependencies('ConnectionToken')
class CatsRepository {
  constructor(connection) {}
}
```

> **Notice** The `@Inject()` decorator is imported from `@nestjs/common` package.

#### Sponsors

[](https://valor-software.com/)

Nest is an MIT-licensed open source project. It can grow thanks to the support by these awesome people. If you'd like to join them, please read more [here](https://opencollective.com/nest). Thanks!

[](https://opencollective.com/nest/backer/0/website)[](https://opencollective.com/nest/backer/1/website)[](https://opencollective.com/nest/backer/2/website)[](https://opencollective.com/nest/backer/3/website)[](https://opencollective.com/nest/backer/4/website)[](https://opencollective.com/nest/backer/5/website)[](https://opencollective.com/nest/backer/6/website)[](https://opencollective.com/nest/backer/7/website)[](https://opencollective.com/nest/backer/8/website)[](https://opencollective.com/nest/backer/9/website)[](https://opencollective.com/nest/backer/10/website)[](https://opencollective.com/nest/backer/11/website)[](https://opencollective.com/nest/backer/12/website)[](https://opencollective.com/nest/backer/13/website)[](https://opencollective.com/nest/backer/14/website)[](https://opencollective.com/nest/backer/15/website)[](https://opencollective.com/nest/backer/16/website)[](https://opencollective.com/nest/backer/17/website)[](https://opencollective.com/nest/backer/18/website)[](https://opencollective.com/nest/backer/19/website)[](https://opencollective.com/nest/backer/20/website)[](https://opencollective.com/nest/backer/21/website)[](https://opencollective.com/nest/backer/22/website)[](https://opencollective.com/nest/backer/23/website)[](https://opencollective.com/nest/backer/24/website)[](https://opencollective.com/nest/backer/25/website)[](https://opencollective.com/nest/backer/26/website)[](https://opencollective.com/nest/backer/27/website)[](https://opencollective.com/nest/backer/28/website)[](https://opencollective.com/nest/backer/29/website)

[Become a sponsor](https://opencollective.com/nest)

----
url: https://docs.nestjs.com/faq/http-adapter
----

[Skip to content](#content)

On this page

* [HTTP adapter](https://docs.nestjs.com/faq/http-adapter#http-adapter)
* [Outside application context strategy](https://docs.nestjs.com/faq/http-adapter#outside-application-context-strategy)
* [As injectable](https://docs.nestjs.com/faq/http-adapter#as-injectable)
* [Listening event](https://docs.nestjs.com/faq/http-adapter#listening-event)

### HTTP adapter

Occasionally, you may need to access the underlying HTTP server, either from within the Nest application context or from outside of it.

Every native (platform-specific) HTTP server or library instance (e.g., Express or Fastify) is wrapped in an **adapter**. The adapter is registered as a globally available provider, so you can retrieve it from the application context or inject it into other providers.

#### Outside application context strategy[#](/faq/http-adapter#outside-application-context-strategy)

To get a reference to the `HttpAdapter` from outside of the application context, call the `getHttpAdapter()` method:

JS TS

```typescript

const app = await NestFactory.create(AppModule);
const httpAdapter = app.getHttpAdapter();
```

#### As injectable[#](/faq/http-adapter#as-injectable)

To get a reference to the `HttpAdapterHost` from within the application context, inject it like any other provider (e.g., using constructor injection):

JS TS

```typescript

export class CatsService {
  constructor(private adapterHost: HttpAdapterHost) {}
}
```

```typescript

@Dependencies(HttpAdapterHost)
export class CatsService {
  constructor(adapterHost) {
    this.adapterHost = adapterHost;
  }
}
```

> **Hint** The `HttpAdapterHost` is imported from the `@nestjs/core` package.

The `HttpAdapterHost` is **not** an actual `HttpAdapter`. To get the actual `HttpAdapter` instance, read its `httpAdapter` property:

```typescript

const adapterHost = app.get(HttpAdapterHost);
const httpAdapter = adapterHost.httpAdapter;
```

The `httpAdapter` is the HTTP adapter instance that wraps the underlying framework. It is an instance of either `ExpressAdapter` or `FastifyAdapter` (both classes extend `AbstractHttpAdapter`).

The adapter object exposes several methods for interacting with the HTTP server. To access the library instance (e.g., the Express instance) directly, call the `getInstance()` method:

```typescript

const instance = httpAdapter.getInstance();
```

#### Listening event[#](/faq/http-adapter#listening-event)

To run code when the server starts listening for incoming requests, subscribe to the `listen$` stream:

```typescript

this.httpAdapterHost.listen$.subscribe(() =>
  console.log('HTTP server is listening'),
);
```

The `HttpAdapterHost` also exposes a `listening` boolean property that indicates whether the server is currently listening:

```typescript

if (this.httpAdapterHost.listening) {
  console.log('HTTP server is listening');
}
```

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/faq/http-adapter.md)

----
url: https://docs.nestjs.com/v11/graphql/cli-plugin
----

* [CLI Plugin](https://docs.nestjs.com/v11/graphql/cli-plugin#cli-plugin)
* [Overview](https://docs.nestjs.com/v11/graphql/cli-plugin#overview)
* [Comments introspection](https://docs.nestjs.com/v11/graphql/cli-plugin#comments-introspection)
* [Using the CLI plugin](https://docs.nestjs.com/v11/graphql/cli-plugin#using-the-cli-plugin)
* [SWC builder](https://docs.nestjs.com/v11/graphql/cli-plugin#swc-builder)
* [Integration with ts-jest (e2e tests)](https://docs.nestjs.com/v11/graphql/cli-plugin#integration-with-ts-jest-e2e-tests)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/cli-plugin.md "Suggest Edits")

### CLI Plugin

> **Warning** This chapter applies only to the code first approach.

TypeScript's metadata reflection system has several limitations which make it impossible to, for instance, determine what properties a class consists of or recognize whether a given property is optional or required. However, some of these constraints can be addressed at compilation time. Nest provides a plugin that enhances the TypeScript compilation process to reduce the amount of boilerplate code required.

> **Hint** This plugin is **opt-in**. If you prefer, you can declare all decorators manually, or only specific decorators where you need them.

```typescript

@ObjectType()
export class Author {
  @Field(type => ID)
  id: number;

  @Field({ nullable: true })
  firstName?: string;

  @Field({ nullable: true })
  lastName?: string;

  @Field(type => [Post])
  posts: Post[];
}
```

While not a significant issue with medium-sized projects, it becomes verbose & hard to maintain once you have a large set of classes.

By enabling the GraphQL plugin, the above class definition can be declared simply:

authors/models/author.model.ts

JS TS

```typescript

@ObjectType()
export class Author {
  @Field(type => ID)
  id: number;
  firstName?: string;
  lastName?: string;
  posts: Post[];
}
```

The plugin adds appropriate decorators on-the-fly based on the **Abstract Syntax Tree**. Thus, you won't have to struggle with `@Field` decorators scattered throughout the code.

> **Hint** The plugin will automatically generate any missing GraphQL properties, but if you need to override them, simply set them explicitly via `@Field()`.

#### Comments introspection[#](/graphql/cli-plugin#comments-introspection)

With the comments introspection feature enabled, CLI plugin will generate descriptions for fields based on comments.

For example, given an example `roles` property:

```typescript

/**
 * A list of user's roles
 */
@Field(() => [String], {
  description: `A list of user's roles`
})
roles: string[];
```

You must duplicate description values. With `introspectComments` enabled, the CLI plugin can extract these comments and automatically provide descriptions for properties. Now, the above field can be declared simply as follows:

```typescript

/**
 * A list of user's roles
 */
roles: string[];
```

#### Using the CLI plugin[#](/graphql/cli-plugin#using-the-cli-plugin)

To enable the plugin, open `nest-cli.json` (if you use [Nest CLI](/v11/cli/overview)) and add the following `plugins` configuration:

```javascript

{
  "collection": "@nestjs/schematics",
  "sourceRoot": "src",
  "compilerOptions": {
    "plugins": ["@nestjs/graphql"]
  }
}
```

You can use the `options` property to customize the behavior of the plugin.

```javascript

{
  "collection": "@nestjs/schematics",
  "sourceRoot": "src",
  "compilerOptions": {
    "plugins": [
      {
        "name": "@nestjs/graphql",
        "options": {
          "typeFileNameSuffix": [".input.ts", ".args.ts"],
          "introspectComments": true
        }
      }
    ]
  }
}
```

The `options` property has to fulfill the following interface:

```typescript

export interface PluginOptions {
  typeFileNameSuffix?: string[];
  introspectComments?: boolean;
}
```

| Option               | Default                                                | Description                                                                        |
| -------------------- | ------------------------------------------------------ | ---------------------------------------------------------------------------------- |
| `typeFileNameSuffix` | `['.input.ts', '.args.ts', '.entity.ts', '.model.ts']` | GraphQL types files suffix                                                         |
| `introspectComments` | `false`                                                | If set to true, plugin will generate descriptions for properties based on comments |

If you don't use the CLI but instead have a custom `webpack` configuration, you can use this plugin in combination with `ts-loader`:

```javascript

getCustomTransformers: (program: any) => ({
  before: [require('@nestjs/graphql/plugin').before({}, program)]
}),
```

#### SWC builder[#](/graphql/cli-plugin#swc-builder)

For standard setups (non-monorepo), to use CLI Plugins with the SWC builder, you need to enable type checking, as described [here](/recipes/swc#type-checking).

```bash

$ nest start -b swc --type-check
```

For monorepo setups, follow the instructions [here](/recipes/swc#monorepo-and-cli-plugins).

```bash

$ npx ts-node src/generate-metadata.ts
# OR npx ts-node apps/{YOUR_APP}/src/generate-metadata.ts
```

Now, the serialized metadata file must be loaded by the `GraphQLModule` method, as shown below:

```typescript

import metadata from './metadata'; // <-- file auto-generated by the "PluginMetadataGenerator"

GraphQLModule.forRoot<...>({
  ..., // other options
  metadata,
}),
```

#### Integration with `ts-jest` (e2e tests)[#](/graphql/cli-plugin#integration-with-ts-jest-e2e-tests)

When running e2e tests with this plugin enabled, you may run into issues with compiling schema. For example, one of the most common errors is:

```json

Object type <name> must define one or more fields.
```

This happens because `jest` configuration does not import `@nestjs/graphql/plugin` plugin anywhere.

To fix this, create the following file in your e2e tests directory:

```javascript

const transformer = require('@nestjs/graphql/plugin');

module.exports.name = 'nestjs-graphql-transformer';
// you should change the version number anytime you change the configuration below - otherwise, jest will not detect changes
module.exports.version = 1;

module.exports.factory = (cs) => {
  return transformer.before(
    {
      // @nestjs/graphql/plugin options (can be empty)
    },
    cs.program, // "cs.tsCompiler.program" for older versions of Jest (<= v27)
  );
};
```

With this in place, import AST transformer within your `jest` configuration file. By default (in the starter application), e2e tests configuration file is located under the `test` folder and is named `jest-e2e.json`.

```json

{
  ... // other configuration
  "globals": {
    "ts-jest": {
      "astTransformers": {
        "before": ["<path to the file created above>"]
      }
    }
  }
}
```

If you use `jest@^29`, then use the snippet below, as the previous approach got deprecated.

```json

{
  ... // other configuration
  "transform": {
    "^.+\\.(t|j)s$": [
      "ts-jest",
      {
        "astTransformers": {
          "before": ["<path to the file created above>"]
        }
      }
    ]
  }
}
```

----
url: https://docs.nestjs.com/v6/microservices/basics
----

* [Overview](https://docs.nestjs.com/v6/microservices/basics#overview)
* [Installation](https://docs.nestjs.com/v6/microservices/basics#installation)
* [Getting started](https://docs.nestjs.com/v6/microservices/basics#getting-started)
* [Patterns](https://docs.nestjs.com/v6/microservices/basics#patterns)
* [Request-response](https://docs.nestjs.com/v6/microservices/basics#request-response)
* [Asynchronous responses](https://docs.nestjs.com/v6/microservices/basics#asynchronous-responses)
* [Event-based](https://docs.nestjs.com/v6/microservices/basics#event-based)
* [Decorators](https://docs.nestjs.com/v6/microservices/basics#decorators)
* [Client](https://docs.nestjs.com/v6/microservices/basics#client)
* [Sending messages](https://docs.nestjs.com/v6/microservices/basics#sending-messages)
* [Publishing events](https://docs.nestjs.com/v6/microservices/basics#publishing-events)
* [Scopes](https://docs.nestjs.com/v6/microservices/basics#scopes)

```bash

$ npm i --save @nestjs/microservices
```

#### Getting started[#](/microservices/basics#getting-started)

To instantiate a microservice, use the `createMicroservice()` method of the `NestFactory` class:

main.ts

JS TS

```typescript

import { NestFactory } from '@nestjs/core';
import { Transport } from '@nestjs/microservices';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.createMicroservice(AppModule, {
    transport: Transport.TCP,
  });
  app.listen(() => console.log('Microservice is listening'));
}
bootstrap();
```

> **Hint** Microservices use the **TCP** transport layer by default.

The second argument of the `createMicroservice()` method is an `options` object. This object may consist of two members:

|             |                                                                            |
| ----------- | -------------------------------------------------------------------------- |
| `transport` | Specifies the transporter (for example, `Transport.NATS`)                  |
| `options`   | A transporter-specific options object that determines transporter behavior |

The `options` object is specific to the chosen transporter. The **TCP** transporter exposes the properties described below. For other transporters (e.g, Redis, MQTT, etc.), see the relevant chapter for a description of the available options.

|                 |                                                          |
| --------------- | -------------------------------------------------------- |
| `host`          | Connection hostname                                      |
| `port`          | Connection port                                          |
| `retryAttempts` | Number of times to retry message (default: `0`)          |
| `retryDelay`    | Delay between message retry attempts (ms) (default: `0`) |

#### Patterns[#](/microservices/basics#patterns)

Microservices recognize both messages and events by **patterns**. A pattern is a plain value, for example, a literal object or a string. Patterns are automatically serialized and sent over the network along with the data portion of a message. In this way, message senders and consumers can coordinate which requests are consumed by which handlers.

#### Request-response[#](/microservices/basics#request-response)

The request-response message style is useful when you need to **exchange** messages between various external services. With this paradigm, you can be certain that the service has actually received the message (without the need to manually implement a message ACK protocol). However, the request-response paradigm is not always the best choice. For example, streaming transporters that use log-based persistence, such as [Kafka](https://docs.confluent.io/3.0.0/streams/) or [NATS streaming](https://github.com/nats-io/node-nats-streaming), are optimized for solving a different range of issues, more aligned with an event messaging paradigm (see [event-based messaging](https://docs.nestjs.com/microservices/basics#event-based) below for more details).

To enable the request-response message type, Nest creates two logical channels - one is responsible for transferring the data while the other waits for incoming responses. For some underlying transports, such as [NATS](https://nats.io/), this dual-channel support is provided out-of-the-box. For others, Nest compensates by manually creating separate channels. There can be overhead for this, so if you do not require a request-response message style, you should consider using the event-based method.

To create a message handler based on the request-response paradigm use the `@MessagePattern()` decorator, which is imported from the `@nestjs/microservices` package.

math.controller.ts

JS TS

```typescript

import { Controller } from '@nestjs/common';
import { MessagePattern } from '@nestjs/microservices';

@Controller()
export class MathController {
  @MessagePattern({ cmd: 'sum' })
  accumulate(data: number[]): number {
    return (data || []).reduce((a, b) => a + b);
  }
}
```

```typescript

import { Controller } from '@nestjs/common';
import { MessagePattern } from '@nestjs/microservices';

@Controller()
export class MathController {
  @MessagePattern({ cmd: 'sum' })
  accumulate(data) {
    return (data || []).reduce((a, b) => a + b);
  }
}
```

In the above code, the `accumulate()`**message handler** listens for messages that fulfill the `{ cmd: 'sum' }` message pattern. The message handler takes a single argument, the `data` passed from the client. In this case, the data is an array of numbers which are to be accumulated.

#### Asynchronous responses[#](/microservices/basics#asynchronous-responses)

Message handlers are able to respond either synchronously or **asynchronously**. Hence, `async` methods are supported.

JS TS

```typescript

@MessagePattern({ cmd: 'sum' })
async accumulate(data: number[]): Promise<number> {
  return (data || []).reduce((a, b) => a + b);
}
```

```typescript

@MessagePattern({ cmd: 'sum' })
async accumulate(data) {
  return (data || []).reduce((a, b) => a + b);
}
```

A message handler is also able to return an `Observable`, in which case the result values will be emitted until the stream is completed.

JS TS

```typescript

@MessagePattern({ cmd: 'sum' })
accumulate(data: number[]): Observable<number> {
  return from([1, 2, 3]);
}
```

```typescript

@MessagePattern({ cmd: 'sum' })
accumulate(data: number[]): Observable<number> {
  return from([1, 2, 3]);
}
```

In the example above, the message handler will respond **3 times** (with each item from the array).

#### Event-based[#](/microservices/basics#event-based)

While the request-response method is ideal for exchanging messages between services, it is less suitable when your message style is event-based - when you just want to publish **events** without waiting for a response. In that case, you do not want the overhead required by request-response for maintaining two channels.

Suppose you would like to simply notify another service that a certain condition has occurred in this part of the system. This is the ideal use case for the event-based message style.

To create an event handler, we use the `@EventPattern()` decorator, which is imported from the `@nestjs/microservices` package.

JS TS

```typescript

@EventPattern('user_created')
async handleUserCreated(data: Record<string, unknown>) {
  // business logic
}
```

```typescript

@EventPattern('user_created')
async handleUserCreated(data) {
  // business logic
}
```

```typescript

@MessagePattern('time.us.*')
getDate(@Payload() data: number[], @Ctx() context: NatsContext) {
  console.log(`Subject: ${context.getSubject()}`); // e.g. "time.us.east"
  return new Date().toLocaleTimeString(...);
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('time.us.*')
getDate(data, context) {
  console.log(`Subject: ${context.getSubject()}`); // e.g. "time.us.east"
  return new Date().toLocaleTimeString(...);
}
```

> **Hint**`@Payload()`, `@Ctx()` and `NatsContext` are imported from `@nestjs/microservices`.

#### Client[#](/microservices/basics#client)

A client Nest application can exchange messages or publish events to a Nest microservice using the `ClientProxy` class. This class defines several methods, such as `send()` (for request-response messaging) and `emit()` (for event-driven messaging) that let you communicate with a remote microservice. Obtain an instance of this class in one of the following ways.

One technique is to import the `ClientsModule`, which exposes the static `register()` method. This method takes an argument which is an array of objects representing microservice transporters. Each such object has a `name` property, an optional `transport` property (default is `Transport.TCP`), and an optional transporter-specific `options` property.

The `name` property serves as an **injection token** that can be used to inject an instance of a `ClientProxy` where needed. The value of the `name` property, as an injection token, can be an arbitrary string or JavaScript symbol, as described [here](https://docs.nestjs.com/fundamentals/custom-providers#non-class-based-provider-tokens).

The `options` property is an object with the same properties we saw in the `createMicroservice()` method earlier.

```typescript

@Module({
  imports: [
    ClientsModule.register([
      { name: 'MATH_SERVICE', transport: Transport.TCP },
    ]),
  ]
  ...
})
```

Once the module has been imported, we can inject an instance of the `ClientProxy` configured as specified via the `'MATH_SERVICE'` transporter options shown above, using the `@Inject()` decorator.

```typescript

constructor(
  @Inject('MATH_SERVICE') private readonly client: ClientProxy,
) {}
```

> **Hint** The `ClientsModule` and `ClientProxy` classes are imported from the `@nestjs/microservices` package.

At times we may need to fetch the transporter configuration from another service (say a `ConfigService`), rather than hard-coding it in our client application. To do this, we can register a [custom provider](/v6/techniques/custom-providers) using the `ClientProxyFactory` class. This class has a static `create()` method, which accepts a transporter options object, and returns a customized `ClientProxy` instance.

```typescript

@Module({
  providers: [
    {
      provide: 'MATH_SERVICE',
      useFactory: (configService: ConfigService) => {
        const mathSvcOptions = configService.getMathSvcOptions();
        return ClientProxyFactory.create(mathSvcOptions);
      },
      inject: [ConfigService],
    }
  ]
  ...
})
```

> **Hint** The `ClientProxyFactory` is imported from the `@nestjs/microservices` package.

Another option is to use the `@Client()` property decorator.

```typescript

@Client({ transport: Transport.TCP })
client: ClientProxy;
```

> **Hint** The `@Client()` decorator is imported from the `@nestjs/microservices` package.

Using the `@Client()` decorator is not the preferred technique, as it is harder to test and harder to share a client instance.

The `ClientProxy` is **lazy**. It doesn't initiate a connection immediately. Instead, it will be established before the first microservice call, and then reused across each subsequent call. However, if you want to delay the application bootstrapping process until a connection is established, you can manually initiate a connection using the `ClientProxy` object's `connect()` method inside the `OnApplicationBootstrap` lifecycle hook.

JS TS

```typescript

async onApplicationBootstrap() {
  await this.client.connect();
}
```

If the connection cannot be created, the `connect()` method will reject with the corresponding error object.

#### Sending messages[#](/microservices/basics#sending-messages)

The `ClientProxy` exposes a `send()` method. This method is intended to call the microservice and returns an `Observable` with its response. Thus, we can subscribe to the emitted values easily.

JS TS

```typescript

accumulate(): Observable<number> {
  const pattern = { cmd: 'sum' };
  const payload = [1, 2, 3];
  return this.client.send<number>(pattern, payload);
}
```

```typescript

accumulate() {
  const pattern = { cmd: 'sum' };
  const payload = [1, 2, 3];
  return this.client.send(pattern, payload);
}
```

The `send()` method takes two arguments, `pattern` and `payload`. The `pattern` should match one defined in a `@MessagePattern()` decorator. The `payload` is a message that we want to transmit to the remote microservice. This method returns a **cold `Observable`**, which means that you have to explicitly subscribe to it before the message will be sent.

#### Publishing events[#](/microservices/basics#publishing-events)

To send an event, use the `ClientProxy` object's `emit()` method. This method publishes an event to the message broker.

JS TS

```typescript

async publish() {
  this.client.emit<number>('user_created', new UserCreatedEvent());
}
```

```typescript

async publish() {
  this.client.emit('user_created', new UserCreatedEvent());
}
```

The `emit()` method takes two arguments, `pattern` and `payload`. The `pattern`should match one defined in an `@EventPattern()` decorator. The `payload` is an event payload that we want to transmit to the remote microservice. This method returns a **hot `Observable`** (unlike the cold `Observable` returned by `send()`), which means that whether or not you explicitly subscribe to the observable, the proxy will immediately try to deliver the event.

## Hoodies, T-shirts, and accessories!

Support our future development by shopping in the official store!

[See more](https://nestjs.threadless.com/ "Shop | NestJS - A node.js framework built on top of TypeScript")

#### Scopes[#](/microservices/basics#scopes)

For people coming from different programming language backgrounds, it might be unexpected to learn that in Nest, almost everything is shared across incoming requests. We have a connection pool to the database, singleton services with global state, etc. Remember that Node.js doesn't follow the request/response Multi-Threaded Stateless Model in which every request is processed by a separate thread. Hence, using singleton instances is fully **safe** for our applications.

However, there are edge-cases when request-based lifetime of the handler may be the desired behavior, for instance per-request caching in GraphQL applications, request tracking or multi-tenancy. Learn how to control scopes [here](/v6/fundamentals/injection-scopes).

Request-scoped handlers and providers can inject `RequestContext` using the `@Inject()` decorator in combination with `CONTEXT` token:

```typescript

import { Injectable, Scope, Inject } from '@nestjs/common';
import { CONTEXT, RequestContext } from '@nestjs/microservices';

@Injectable({ scope: Scope.REQUEST })
export class CatsService {
  constructor(@Inject(CONTEXT) private readonly ctx: RequestContext) {}
}
```

This provides access to the `RequestContext` object, which has two properties:

```typescript

export interface RequestContext<T = any> {
  pattern: string | Record<string, any>;
  data: T;
}
```

The `data` property is the message payload sent by the message producer. The `pattern` property is the pattern used to identify an appropriate handler to handle the incoming message.

----
url: https://docs.nestjs.com/v10/graphql/unions-and-enums
----

* [Unions](https://docs.nestjs.com/v10/graphql/unions-and-enums#unions)
* [Code first](https://docs.nestjs.com/v10/graphql/unions-and-enums#code-first)
* [Schema first](https://docs.nestjs.com/v10/graphql/unions-and-enums#schema-first)
* [Enums](https://docs.nestjs.com/v10/graphql/unions-and-enums#enums)
* [Code first](https://docs.nestjs.com/v10/graphql/unions-and-enums#code-first-1)
* [Schema first](https://docs.nestjs.com/v10/graphql/unions-and-enums#schema-first-1)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/unions-and-enums.md "Suggest Edits")

### Unions

Union types are very similar to interfaces, but they don't get to specify any common fields between the types (read more [here](https://graphql.org/learn/schema/#union-types)). Unions are useful for returning disjoint data types from a single field.

#### Code first[#](/graphql/unions-and-enums#code-first)

To define a GraphQL union type, we must define classes that this union will be composed of. Following the [example](https://www.apollographql.com/docs/apollo-server/schema/unions-interfaces/#union-type) from the Apollo documentation, we'll create two classes. First, `Book`:

```typescript

import { Field, ObjectType } from '@nestjs/graphql';

@ObjectType()
export class Book {
  @Field()
  title: string;
}
```

And then `Author`:

```typescript

import { Field, ObjectType } from '@nestjs/graphql';

@ObjectType()
export class Author {
  @Field()
  name: string;
}
```

With this in place, register the `ResultUnion` union using the `createUnionType` function exported from the `@nestjs/graphql` package:

```typescript

export const ResultUnion = createUnionType({
  name: 'ResultUnion',
  types: () => [Author, Book] as const,
});
```

> **Warning** The array returned by the `types` property of the `createUnionType` function should be given a const assertion. If the const assertion is not given, a wrong declaration file will be generated at compile time, and an error will occur when using it from another project.

Now, we can reference the `ResultUnion` in our query:

```typescript

@Query(() => [ResultUnion])
search(): Array<typeof ResultUnion> {
  return [new Author(), new Book()];
}
```

This will result in generating the following part of the GraphQL schema in SDL:

```graphql

type Author {
  name: String!
}

type Book {
  title: String!
}

union ResultUnion = Author | Book

type Query {
  search: [ResultUnion!]!
}
```

The default `resolveType()` function generated by the library will extract the type based on the value returned from the resolver method. That means returning class instances instead of literal JavaScript object is obligatory.

To provide a customized `resolveType()` function, pass the `resolveType` property to the options object passed into the `createUnionType()` function, as follows:

```typescript

export const ResultUnion = createUnionType({
  name: 'ResultUnion',
  types: () => [Author, Book] as const,
  resolveType(value) {
    if (value.name) {
      return Author;
    }
    if (value.title) {
      return Book;
    }
    return null;
  },
});
```

#### Schema first[#](/graphql/unions-and-enums#schema-first)

To define a union in the schema first approach, simply create a GraphQL union with SDL.

```graphql

type Author {
  name: String!
}

type Book {
  title: String!
}

union ResultUnion = Author | Book
```

Then, you can use the typings generation feature (as shown in the [quick start](/v10/graphql/quick-start) chapter) to generate corresponding TypeScript definitions:

```typescript

export class Author {
  name: string;
}

export class Book {
  title: string;
}

export type ResultUnion = Author | Book;
```

Unions require an extra `__resolveType` field in the resolver map to determine which type the union should resolve to. Also, note that the `ResultUnionResolver` class has to be registered as a provider in any module. Let's create a `ResultUnionResolver` class and define the `__resolveType` method.

```typescript

@Resolver('ResultUnion')
export class ResultUnionResolver {
  @ResolveField()
  __resolveType(value) {
    if (value.name) {
      return 'Author';
    }
    if (value.title) {
      return 'Book';
    }
    return null;
  }
}
```

> **Hint** All decorators are exported from the `@nestjs/graphql` package.

### Enums

Enumeration types are a special kind of scalar that is restricted to a particular set of allowed values (read more [here](https://graphql.org/learn/schema/#enumeration-types)). This allows you to:

* validate that any arguments of this type are one of the allowed values
* communicate through the type system that a field will always be one of a finite set of values

#### Code first[#](/graphql/unions-and-enums#code-first-1)

When using the code first approach, you define a GraphQL enum type by simply creating a TypeScript enum.

```typescript

export enum AllowedColor {
  RED,
  GREEN,
  BLUE,
}
```

With this in place, register the `AllowedColor` enum using the `registerEnumType` function exported from the `@nestjs/graphql` package:

```typescript

registerEnumType(AllowedColor, {
  name: 'AllowedColor',
});
```

Now you can reference the `AllowedColor` in our types:

```typescript

@Field(type => AllowedColor)
favoriteColor: AllowedColor;
```

This will result in generating the following part of the GraphQL schema in SDL:

```graphql

enum AllowedColor {
  RED
  GREEN
  BLUE
}
```

To provide a description for the enum, pass the `description` property into the `registerEnumType()` function.

```typescript

registerEnumType(AllowedColor, {
  name: 'AllowedColor',
  description: 'The supported colors.',
});
```

To provide a description for the enum values, or to mark a value as deprecated, pass the `valuesMap` property, as follows:

```typescript

registerEnumType(AllowedColor, {
  name: 'AllowedColor',
  description: 'The supported colors.',
  valuesMap: {
    RED: {
      description: 'The default color.',
    },
    BLUE: {
      deprecationReason: 'Too blue.',
    },
  },
});
```

This will generate the following GraphQL schema in SDL:

```graphql

"""
The supported colors.
"""
enum AllowedColor {
  """
  The default color.
  """
  RED
  GREEN
  BLUE @deprecated(reason: "Too blue.")
}
```

#### Schema first[#](/graphql/unions-and-enums#schema-first-1)

To define an enumerator in the schema first approach, simply create a GraphQL enum with SDL.

```graphql

enum AllowedColor {
  RED
  GREEN
  BLUE
}
```

Then you can use the typings generation feature (as shown in the [quick start](/v10/graphql/quick-start) chapter) to generate corresponding TypeScript definitions:

```typescript

export enum AllowedColor {
  RED
  GREEN
  BLUE
}
```

Sometimes a backend forces a different value for an enum internally than in the public API. In this example the API contains `RED`, however in resolvers we may use `#f00` instead (read more [here](https://www.apollographql.com/docs/apollo-server/schema/scalars-enums/#internal-values)). To accomplish this, declare a resolver object for the `AllowedColor` enum:

```typescript

export const allowedColorResolver: Record<keyof typeof AllowedColor, any> = {
  RED: '#f00',
};
```

> **Hint** All decorators are exported from the `@nestjs/graphql` package.

Then use this resolver object together with the `resolvers` property of the `GraphQLModule#forRoot()` method, as follows:

```typescript

GraphQLModule.forRoot({
  resolvers: {
    AllowedColor: allowedColorResolver,
  },
});
```

----
url: https://docs.nestjs.com/v10/faq/http-adapter
----

* [HTTP adapter](https://docs.nestjs.com/v10/faq/http-adapter#http-adapter)
* [Outside application context strategy](https://docs.nestjs.com/v10/faq/http-adapter#outside-application-context-strategy)
* [As injectable](https://docs.nestjs.com/v10/faq/http-adapter#as-injectable)
* [Listening event](https://docs.nestjs.com/v10/faq/http-adapter#listening-event)

```typescript

const app = await NestFactory.create(AppModule);
const httpAdapter = app.getHttpAdapter();
```

#### As injectable[#](/faq/http-adapter#as-injectable)

To get a reference to the `HttpAdapterHost` from within the application context, inject it using the same technique as any other existing provider (e.g., using constructor injection).

JS TS

```typescript

export class CatsService {
  constructor(private adapterHost: HttpAdapterHost) {}
}
```

```typescript

@Dependencies(HttpAdapterHost)
export class CatsService {
  constructor(adapterHost) {
    this.adapterHost = adapterHost;
  }
}
```

> **Hint** The `HttpAdapterHost` is imported from the `@nestjs/core` package.

The `HttpAdapterHost` is **not** an actual `HttpAdapter`. To get the actual `HttpAdapter` instance, simply access the `httpAdapter` property.

```typescript

const adapterHost = app.get(HttpAdapterHost);
const httpAdapter = adapterHost.httpAdapter;
```

The `httpAdapter` is the actual instance of the HTTP adapter used by the underlying framework. It is an instance of either `ExpressAdapter` or `FastifyAdapter` (both classes extend `AbstractHttpAdapter`).

The adapter object exposes several useful methods to interact with the HTTP server. However, if you want to access the library instance (e.g., the Express instance) directly, call the `getInstance()` method.

```typescript

const instance = httpAdapter.getInstance();
```

#### Listening event[#](/faq/http-adapter#listening-event)

To execute an action when the server begins listening for incoming requests, you can subscribe to the `listen$` stream, as demonstrated below:

```typescript

this.httpAdapterHost.listen$.subscribe(() =>
  console.log('HTTP server is listening'),
);
```

Additionally, the `HttpAdapterHost` provides a `listening` boolean property that indicates whether the server is currently active and listening:

```typescript

if (this.httpAdapterHost.listening) {
  console.log('HTTP server is listening');
}
```

----
url: https://docs.nestjs.com/v9/microservices/interceptors
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Interceptors](https://docs.nestjs.com/v9/microservices/interceptors#interceptors)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/microservices/interceptors.md "Suggest Edits")

### Interceptors

There is no difference between [regular interceptors](/v9/interceptors) and microservices interceptors. The following example uses a manually instantiated method-scoped interceptor. Just as with HTTP based applications, you can also use controller-scoped interceptors (i.e., prefix the controller class with a `@UseInterceptors()` decorator).

JS TS

```typescript

@UseInterceptors(new TransformInterceptor())
@MessagePattern({ cmd: 'sum' })
accumulate(data: number[]): number {
  return (data || []).reduce((a, b) => a + b);
}
```

```typescript

@UseInterceptors(new TransformInterceptor())
@MessagePattern({ cmd: 'sum' })
accumulate(data) {
  return (data || []).reduce((a, b) => a + b);
}
```

----
url: https://docs.nestjs.com/v5/techniques/mvc
----

### Model-View-Controller

Nest, by default, makes use of [express](https://github.com/expressjs/express) library under the hood. Hence, every tutorial about MVC (Model-View-Controller) pattern in express concerns Nest as well. Firstly, let's scaffold a simple Nest application using [CLI](https://github.com/nestjs/nest-cli) tool:

```bash

$ npm i -g @nestjs/cli
$ nest new project
```

In order to create a MVC app, we have to install a [template engine](http://expressjs.com/en/guide/using-template-engines.html):

```bash

$ npm install --save hbs
```

We decided to use a `hbs` engine, though, you can use whatever fits your requirements. Once the installation process is completed, we need to configure the express instance using following code:

main.ts

JS TS

TypeScript

```typescript

import { NestFactory } from '@nestjs/core';
import { join } from 'path';
import { ApplicationModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(ApplicationModule);

  app.useStaticAssets(join(__dirname, '..', 'public'));
  app.setBaseViewsDir(join(__dirname, '..', 'views'));
  app.setViewEngine('hbs');

  await app.listen(3000);
}
bootstrap();
```

We told [express](https://github.com/expressjs/express) that the `public` directory will be used for storing static assets, `views` will contain templates, and a `hbs` template engine should be used to render an HTML output.

Now, let's create a `views` directory and `index.hbs` template inside it. In the template, we are gonna print a `message` passed from the controller:

index.hbs

HTML

```html

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>App</title>
</head>
<body>
  {{ message }}
</body>
</html>
```

Afterward, open the `app.controller` file and replace the `root()` method with the following code:

app.controller.ts

JS TS

TypeScript

```typescript

import { Get, Controller, Render } from '@nestjs/common';

@Controller()
export class AppController {
  @Get()
  @Render('index')
  root() {
    return { message: 'Hello world!' };
  }
}
```

TypeScript

```typescript

import { Get, Controller, Render } from '@nestjs/common';

@Controller()
export class AppController {
  @Get()
  @Render('index')
  root() {
    return { message: 'Hello world!' };
  }
}
```

> **Hint** In fact, when Nest detects `@Res()` decorator, it injects library-specific `response` object. Learn more about its abilities [here](http://expressjs.com/en/api.html).

While the application is running, open your browser and navigate to `http://localhost:3000/`. You should see the `Hello world!` message.

#### Example

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/15-mvc).

#### Fastify

As mentioned in this [chapter](/v5/techniques/http-performance), we are able to use any compatible HTTP provider together with Nest. One of them is a [fastify](https://github.com/fastify/fastify) library. In order to create a MVC application with fastify, we have to install following packages:

```bash

$ npm i --save fastify point-of-view handlebars
```

The next steps cover almost the same stuff as in case of express library (with small differences). Once the installation process is completed, we need to open `main.ts` file and update its contents:

main.ts

JS TS

TypeScript

```typescript

import { NestFactory, FastifyAdapter } from '@nestjs/core';
import { ApplicationModule } from './app.module';
import { join } from 'path';

async function bootstrap() {
  const app = await NestFactory.create(ApplicationModule, new FastifyAdapter());
  app.useStaticAssets({
    root: join(__dirname, '..', public'),
    prefix: '/public/',
  });
  app.setViewEngine({
    engine: {
      handlebars: require('handlebars'),
    },
    templates: join(__dirname, '..', 'views'),
  });
  await app.listen(3000);
}
bootstrap();
```

The API is different a little but the idea that sits behind those methods calls remains the same. Also, we have to ensure that the template name passed into the `@Render()` decorators include a file extension.

app.controller.ts

JS TS

TypeScript

```typescript

import { Get, Controller, Render } from '@nestjs/common';

@Controller()
export class AppController {
  @Get()
  @Render('index.hbs')
  root() {
    return { message: 'Hello world!' };
  }
}
```

While the application is running, open your browser and navigate to `http://localhost:3000/`. You should see the `Hello world!` message.

#### Example

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/17-mvc-fastify).

* Model-View-Controller
* Example
* Fastify

----
url: https://docs.nestjs.com/v4/faq/express-instance
----

### Express Instance

Sometimes you might wanna have a full control of the `express` instance lifecycle. It's pretty easy since `NestFactory.create()` method takes the express instance as a second argument.

TypeScript

```typescript

const server = express();
const app = await NestFactory.create(ApplicationModule, server);
```

#### Sponsors

[](https://valor-software.com/)

Nest is an MIT-licensed open source project. It can grow thanks to the support by these awesome people. If you'd like to join them, please read more [here](https://opencollective.com/nest). Thanks!

[](https://opencollective.com/nest/backer/0/website)[](https://opencollective.com/nest/backer/1/website)[](https://opencollective.com/nest/backer/2/website)[](https://opencollective.com/nest/backer/3/website)[](https://opencollective.com/nest/backer/4/website)[](https://opencollective.com/nest/backer/5/website)[](https://opencollective.com/nest/backer/6/website)[](https://opencollective.com/nest/backer/7/website)[](https://opencollective.com/nest/backer/8/website)[](https://opencollective.com/nest/backer/9/website)[](https://opencollective.com/nest/backer/10/website)[](https://opencollective.com/nest/backer/11/website)[](https://opencollective.com/nest/backer/12/website)[](https://opencollective.com/nest/backer/13/website)[](https://opencollective.com/nest/backer/14/website)[](https://opencollective.com/nest/backer/15/website)[](https://opencollective.com/nest/backer/16/website)[](https://opencollective.com/nest/backer/17/website)[](https://opencollective.com/nest/backer/18/website)[](https://opencollective.com/nest/backer/19/website)[](https://opencollective.com/nest/backer/20/website)[](https://opencollective.com/nest/backer/21/website)[](https://opencollective.com/nest/backer/22/website)[](https://opencollective.com/nest/backer/23/website)[](https://opencollective.com/nest/backer/24/website)[](https://opencollective.com/nest/backer/25/website)[](https://opencollective.com/nest/backer/26/website)[](https://opencollective.com/nest/backer/27/website)[](https://opencollective.com/nest/backer/28/website)[](https://opencollective.com/nest/backer/29/website)

[Become a sponsor](https://opencollective.com/nest)

----
url: https://docs.nestjs.com/v11/techniques/file-upload
----

* [File upload](https://docs.nestjs.com/v11/techniques/file-upload#file-upload)
* [Basic example](https://docs.nestjs.com/v11/techniques/file-upload#basic-example)
* [File validation](https://docs.nestjs.com/v11/techniques/file-upload#file-validation)
* [Array of files](https://docs.nestjs.com/v11/techniques/file-upload#array-of-files)
* [Multiple files](https://docs.nestjs.com/v11/techniques/file-upload#multiple-files)
* [Any files](https://docs.nestjs.com/v11/techniques/file-upload#any-files)
* [No files](https://docs.nestjs.com/v11/techniques/file-upload#no-files)
* [Default options](https://docs.nestjs.com/v11/techniques/file-upload#default-options)
* [Async configuration](https://docs.nestjs.com/v11/techniques/file-upload#async-configuration)
* [Example](https://docs.nestjs.com/v11/techniques/file-upload#example)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/techniques/file-upload.md "Suggest Edits")

### File upload

To handle file uploading, Nest provides a built-in module based on the [multer](https://github.com/expressjs/multer) middleware package for Express. Multer handles data posted in the `multipart/form-data` format, which is primarily used for uploading files via an HTTP `POST` request. This module is fully configurable and you can adjust its behavior to your application requirements.

> **Warning** Multer cannot process data which is not in the supported multipart format (`multipart/form-data`). Also, note that this package is not compatible with the `FastifyAdapter`.

For better type safety, let's install Multer typings package:

```shell

$ npm i -D @types/multer
```

With this package installed, we can now use the `Express.Multer.File` type (you can import this type as follows: `import { Express } from 'express'`).

#### Basic example[#](/techniques/file-upload#basic-example)

To upload a single file, simply tie the `FileInterceptor()` interceptor to the route handler and extract `file` from the `request` using the `@UploadedFile()` decorator.

JS TS

```typescript

@Post('upload')
@UseInterceptors(FileInterceptor('file'))
uploadFile(@UploadedFile() file: Express.Multer.File) {
  console.log(file);
}
```

```typescript

@Post('upload')
@UseInterceptors(FileInterceptor('file'))
@Bind(UploadedFile())
uploadFile(file) {
  console.log(file);
}
```

> **Hint** The `FileInterceptor()` decorator is exported from the `@nestjs/platform-express` package. The `@UploadedFile()` decorator is exported from `@nestjs/common`.

The `FileInterceptor()` decorator takes two arguments:

* `fieldName`: string that supplies the name of the field from the HTML form that holds a file
* `options`: optional object of type `MulterOptions`. This is the same object used by the multer constructor (more details [here](https://github.com/expressjs/multer#multeropts)).

> **Warning**`FileInterceptor()` may not be compatible with third party cloud providers like Google Firebase or others.

#### File validation[#](/techniques/file-upload#file-validation)

Often times it can be useful to validate incoming file metadata, like file size or file mime-type. For this, you can create your own [Pipe](https://docs.nestjs.com/pipes) and bind it to the parameter annotated with the `UploadedFile` decorator. The example below demonstrates how a basic file size validator pipe could be implemented:

```typescript

import { PipeTransform, Injectable, ArgumentMetadata } from '@nestjs/common';

@Injectable()
export class FileSizeValidationPipe implements PipeTransform {
  transform(value: any, metadata: ArgumentMetadata) {
    // "value" is an object containing the file's attributes and metadata
    const oneKb = 1000;
    return value.size < oneKb;
  }
}
```

This can be used in conjunction with the `FileInterceptor` as follows:

```typescript

@Post('file')
@UseInterceptors(FileInterceptor('file'))
uploadFileAndValidate(@UploadedFile(
  new FileSizeValidationPipe(),
  // other pipes can be added here
) file: Express.Multer.File, ) {
  return file;
}
```

Nest provides a built-in pipe to handle common use cases and facilitate/standardize the addition of new ones. This pipe is called `ParseFilePipe`, and you can use it as follows:

```typescript

@Post('file')
uploadFileAndPassValidation(
  @Body() body: SampleDto,
  @UploadedFile(
    new ParseFilePipe({
      validators: [
        // ... Set of file validator instances here
      ]
    })
  )
  file: Express.Multer.File,
) {
  return {
    body,
    file: file.buffer.toString(),
  };
}
```

As you can see, it's required to specify an array of file validators that will be executed by the `ParseFilePipe`. We'll discuss the interface of a validator, but it's worth mentioning this pipe also has two additional **optional** options:

|                       |                                                                                                   |
| --------------------- | ------------------------------------------------------------------------------------------------- |
| `errorHttpStatusCode` | The HTTP status code to be thrown in case **any** validator fails. Default is `400` (BAD REQUEST) |
| `exceptionFactory`    | A factory which receives the error message and returns an error.                                  |

Now, back to the `FileValidator` interface. To integrate validators with this pipe, you have to either use built-in implementations or provide your own custom `FileValidator`. See example below:

```typescript

export abstract class FileValidator<TValidationOptions = Record<string, any>> {
  constructor(protected readonly validationOptions: TValidationOptions) {}

  /**
   * Indicates if this file should be considered valid, according to the options passed in the constructor.
   * @param file the file from the request object
   */
  abstract isValid(file?: any): boolean | Promise<boolean>;

  /**
   * Builds an error message in case the validation fails.
   * @param file the file from the request object
   */
  abstract buildErrorMessage(file: any): string;
}
```

> **Hint** The `FileValidator` interfaces supports async validation via its `isValid` function. To leverage type security, you can also type the `file` parameter as `Express.Multer.File` in case you are using express (default) as a driver.

`FileValidator` is a regular class that has access to the file object and validates it according to the options provided by the client. Nest has two built-in `FileValidator` implementations you can use in your project:

* `MaxFileSizeValidator` - Checks if a given file's size is less than the provided value (measured in `bytes`)
* `FileTypeValidator` - Checks if a given file's mime-type matches a given string or RegExp. By default, validates the mime-type using file content [magic number](https://www.ibm.com/support/pages/what-magic-number)

To understand how these can be used in conjunction with the aforementioned `ParseFilePipe`, we'll use an altered snippet of the last presented example:

```typescript

@UploadedFile(
  new ParseFilePipe({
    validators: [
      new MaxFileSizeValidator({ maxSize: 1000 }),
      new FileTypeValidator({ fileType: 'image/jpeg' }),
    ],
  }),
)
file: Express.Multer.File,
```

> **Hint** If the number of validators increase largely or their options are cluttering the file, you can define this array in a separate file and import it here as a named constant like `fileValidators`.

Finally, you can use the special `ParseFilePipeBuilder` class that lets you compose & construct your validators. By using it as shown below you can avoid manual instantiation of each validator and just pass their options directly:

```typescript

@UploadedFile(
  new ParseFilePipeBuilder()
    .addFileTypeValidator({
      fileType: 'jpeg',
    })
    .addMaxSizeValidator({
      maxSize: 1000
    })
    .build({
      errorHttpStatusCode: HttpStatus.UNPROCESSABLE_ENTITY
    }),
)
file: Express.Multer.File,
```

> **Hint** File presence is required by default, but you can make it optional by adding `fileIsRequired: false` parameter inside `build` function options (at the same level as `errorHttpStatusCode`).

```typescript

@Post('upload')
@UseInterceptors(FilesInterceptor('files'))
uploadFile(@UploadedFiles() files: Array<Express.Multer.File>) {
  console.log(files);
}
```

```typescript

@Post('upload')
@UseInterceptors(FilesInterceptor('files'))
@Bind(UploadedFiles())
uploadFile(files) {
  console.log(files);
}
```

> **Hint** The `FilesInterceptor()` decorator is exported from the `@nestjs/platform-express` package. The `@UploadedFiles()` decorator is exported from `@nestjs/common`.

#### Multiple files[#](/techniques/file-upload#multiple-files)

To upload multiple files (all with different field name keys), use the `FileFieldsInterceptor()` decorator. This decorator takes two arguments:

* `uploadedFields`: an array of objects, where each object specifies a required `name` property with a string value specifying a field name, as described above, and an optional `maxCount` property, as described above
* `options`: optional `MulterOptions` object, as described above

When using `FileFieldsInterceptor()`, extract files from the `request` with the `@UploadedFiles()` decorator.

JS TS

```typescript

@Post('upload')
@UseInterceptors(FileFieldsInterceptor([
  { name: 'avatar', maxCount: 1 },
  { name: 'background', maxCount: 1 },
]))
uploadFile(@UploadedFiles() files: { avatar?: Express.Multer.File[], background?: Express.Multer.File[] }) {
  console.log(files);
}
```

```typescript

@Post('upload')
@Bind(UploadedFiles())
@UseInterceptors(FileFieldsInterceptor([
  { name: 'avatar', maxCount: 1 },
  { name: 'background', maxCount: 1 },
]))
uploadFile(files) {
  console.log(files);
}
```

#### Any files[#](/techniques/file-upload#any-files)

To upload all fields with arbitrary field name keys, use the `AnyFilesInterceptor()` decorator. This decorator can accept an optional `options` object as described above.

When using `AnyFilesInterceptor()`, extract files from the `request` with the `@UploadedFiles()` decorator.

JS TS

```typescript

@Post('upload')
@UseInterceptors(AnyFilesInterceptor())
uploadFile(@UploadedFiles() files: Array<Express.Multer.File>) {
  console.log(files);
}
```

```typescript

@Post('upload')
@Bind(UploadedFiles())
@UseInterceptors(AnyFilesInterceptor())
uploadFile(files) {
  console.log(files);
}
```

#### No files[#](/techniques/file-upload#no-files)

To accept `multipart/form-data` but not allow any files to be uploaded, use the `NoFilesInterceptor`. This sets multipart data as attributes on the request body. Any files sent with the request will throw a `BadRequestException`.

```typescript

@Post('upload')
@UseInterceptors(NoFilesInterceptor())
handleMultiPartData(@Body() body) {
  console.log(body)
}
```

#### Default options[#](/techniques/file-upload#default-options)

You can specify multer options in the file interceptors as described above. To set default options, you can call the static `register()` method when you import the `MulterModule`, passing in supported options. You can use all options listed [here](https://github.com/expressjs/multer#multeropts).

```typescript

MulterModule.register({
  dest: './upload',
});
```

> **Hint** The `MulterModule` class is exported from the `@nestjs/platform-express` package.

#### Async configuration[#](/techniques/file-upload#async-configuration)

When you need to set `MulterModule` options asynchronously instead of statically, use the `registerAsync()` method. As with most dynamic modules, Nest provides several techniques to deal with async configuration.

One technique is to use a factory function:

```typescript

MulterModule.registerAsync({
  useFactory: () => ({
    dest: './upload',
  }),
});
```

Like other [factory providers](https://docs.nestjs.com/fundamentals/custom-providers#factory-providers-usefactory), our factory function can be `async` and can inject dependencies through `inject`.

```typescript

MulterModule.registerAsync({
  imports: [ConfigModule],
  useFactory: async (configService: ConfigService) => ({
    dest: configService.get<string>('MULTER_DEST'),
  }),
  inject: [ConfigService],
});
```

Alternatively, you can configure the `MulterModule` using a class instead of a factory, as shown below:

```typescript

MulterModule.registerAsync({
  useClass: MulterConfigService,
});
```

The construction above instantiates `MulterConfigService` inside `MulterModule`, using it to create the required options object. Note that in this example, the `MulterConfigService` has to implement the `MulterOptionsFactory` interface, as shown below. The `MulterModule` will call the `createMulterOptions()` method on the instantiated object of the supplied class.

```typescript

@Injectable()
class MulterConfigService implements MulterOptionsFactory {
  createMulterOptions(): MulterModuleOptions {
    return {
      dest: './upload',
    };
  }
}
```

If you want to reuse an existing options provider instead of creating a private copy inside the `MulterModule`, use the `useExisting` syntax.

```typescript

MulterModule.registerAsync({
  imports: [ConfigModule],
  useExisting: ConfigService,
});
```

You can also pass so-called `extraProviders` to the `registerAsync()` method. These providers will be merged with the module providers.

```typescript

MulterModule.registerAsync({
  imports: [ConfigModule],
  useClass: ConfigService,
  extraProviders: [MyAdditionalProvider],
});
```

This is useful when you want to provide additional dependencies to the factory function or the class constructor.

#### Example[#](/techniques/file-upload#example)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/29-file-upload).

----
url: https://docs.nestjs.com/v11/faq/keep-alive-connections
----

* [Keep alive connections](https://docs.nestjs.com/v11/faq/keep-alive-connections#keep-alive-connections)
* [Usage](https://docs.nestjs.com/v11/faq/keep-alive-connections#usage)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/faq/keep-alive-connections.md "Suggest Edits")

### Keep alive connections

By default, the HTTP adapters of NestJS will wait until the response is finished before closing the application. But sometimes, this behavior is not desired, or unexpected. There might be some requests that use `Connection: Keep-Alive` headers that live for a long time.

For these scenarios where you always want your application to exit without waiting for requests to end, you can enable the `forceCloseConnections` option when creating your NestJS application.

> **Tip** Most users will not need to enable this option. But the symptom of needing this option is that your application will not exit when you expect it to. Usually when `app.enableShutdownHooks()` is enabled and you notice that the application is not restarting/exiting. Most likely while running the NestJS application during development with `--watch`.

#### Usage[#](/faq/keep-alive-connections#usage)

In your `main.ts` file, enable the option when creating your NestJS application:

```typescript

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule, {
    forceCloseConnections: true,
  });
  await app.listen(process.env.PORT ?? 3000);
}

bootstrap();
```

----
url: https://docs.nestjs.com/v10/graphql/field-middleware
----

* [Field middleware](https://docs.nestjs.com/v10/graphql/field-middleware#field-middleware)
* [Getting started](https://docs.nestjs.com/v10/graphql/field-middleware#getting-started)
* [Global field middleware](https://docs.nestjs.com/v10/graphql/field-middleware#global-field-middleware)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/field-middleware.md "Suggest Edits")

### Field middleware

> **Warning** This chapter applies only to the code first approach.

Field Middleware lets you run arbitrary code **before or after** a field is resolved. A field middleware can be used to convert the result of a field, validate the arguments of a field, or even check field-level roles (for example, required to access a target field for which a middleware function is executed).

You can connect multiple middleware functions to a field. In this case, they will be called sequentially along the chain where the previous middleware decides to call the next one. The order of the middleware functions in the `middleware` array is important. The first resolver is the "most-outer" layer, so it gets executed first and last (similarly to the `graphql-middleware` package). The second resolver is the "second-outer" layer, so it gets executed second and second to last.

#### Getting started[#](/graphql/field-middleware#getting-started)

Let's start off by creating a simple middleware that will log a field value before it's sent back to the client:

```typescript

import { FieldMiddleware, MiddlewareContext, NextFn } from '@nestjs/graphql';

const loggerMiddleware: FieldMiddleware = async (
  ctx: MiddlewareContext,
  next: NextFn,
) => {
  const value = await next();
  console.log(value);
  return value;
};
```

> **Hint** The `MiddlewareContext` is an object that consist of the same arguments that are normally received by the GraphQL resolver function (`{ source, args, context, info }`), while `NextFn` is a function that let you execute the next middleware in the stack (bound to this field) or the actual field resolver.

> **Warning** Field middleware functions cannot inject dependencies nor access Nest's DI container as they are designed to be very lightweight and shouldn't perform any potentially time-consuming operations (like retrieving data from the database). If you need to call external services/query data from the data source, you should do it in a guard/interceptor bounded to a root query/mutation handler and assign it to `context` object which you can access from within the field middleware (specifically, from the `MiddlewareContext` object).

Note that field middleware must match the `FieldMiddleware` interface. In the example above, we first run the `next()` function (which executes the actual field resolver and returns a field value) and then, we log this value to our terminal. Also, the value returned from the middleware function completely overrides the previous value and since we don't want to perform any changes, we simply return the original value.

With this in place, we can register our middleware directly in the `@Field()` decorator, as follows:

```typescript

@ObjectType()
export class Recipe {
  @Field({ middleware: [loggerMiddleware] })
  title: string;
}
```

Now whenever we request the `title` field of `Recipe` object type, the original field's value will be logged to the console.

> **Hint** To learn how you can implement a field-level permissions system with the use of [extensions](/v10/graphql/extensions) feature, check out this [section](/graphql/extensions#using-custom-metadata).

> **Warning** Field middleware can be applied only to `ObjectType` classes. For more details, check out this [issue](https://github.com/nestjs/graphql/issues/2446).

Also, as mentioned above, we can control the field's value from within the middleware function. For demonstration purposes, let's capitalise a recipe's title (if present):

```typescript

const value = await next();
return value?.toUpperCase();
```

In this case, every title will be automatically uppercased, when requested.

Likewise, you can bind a field middleware to a custom field resolver (a method annotated with the `@ResolveField()` decorator), as follows:

```typescript

@ResolveField(() => String, { middleware: [loggerMiddleware] })
title() {
  return 'Placeholder';
}
```

> **Warning** In case enhancers are enabled at the field resolver level ([read more](/graphql/other-features#execute-enhancers-at-the-field-resolver-level)), field middleware functions will run before any interceptors, guards, etc., **bounded to the method** (but after the root-level enhancers registered for query or mutation handlers).

#### Global field middleware[#](/graphql/field-middleware#global-field-middleware)

In addition to binding a middleware directly to a specific field, you can also register one or multiple middleware functions globally. In this case, they will be automatically connected to all fields of your object types.

```typescript

GraphQLModule.forRoot({
  autoSchemaFile: 'schema.gql',
  buildSchemaOptions: {
    fieldMiddleware: [loggerMiddleware],
  },
}),
```

> **Hint** Globally registered field middleware functions will be executed **before** locally registered ones (those bound directly to specific fields).

----
url: https://docs.nestjs.com/v4/pipes
----

### Pipes

A pipe is a class with `@Pipe()` decorator. The pipe should implements the `PipeTransform` interface.

A pipe **transforms** the input data to the desired output. Also, it could take care of the **validation**, since it's possible to throw an exception when the data is incorrect.

> **Hint** The pipe runs inside the exceptions zone. This means that when exceptions are thrown they are handled by the core exceptions handler and [exceptions filters](/v4/exception-filters) are applied to the current context.

#### Built-in pipes

Nest comes with two pipes available right out-of-the-box, `ValidationPipe` and `ParseIntPipe`. They're exported from the `@nestjs/common` package. To better understand how they work, we're gonna built them from scratch.

#### What does it look like?

Let's start with the `ValidationPipe`. Now it only takes a value and returns the same value.

validation.pipe.ts

TypeScript

```typescript

import { PipeTransform, Pipe, ArgumentMetadata } from '@nestjs/common';

@Pipe()
export class ValidationPipe implements PipeTransform<any> {
  transform(value: any, metadata: ArgumentMetadata) {
    return value;
  }
}
```

> **Notice** The `ValidationPipe` only works with **TypeScript**. If you are using plain JavaScript, I'd recommend using the [Joi](https://github.com/hapijs/joi) library.

Every pipe has to provide the `transform()` method. This method takes two arguments:

* `value`
* `metadata`

The `value` is the current processed parameter, while `metadata` is its metadata. The metadata object holds a few properties:

TypeScript

```typescript

export interface ArgumentMetadata {
    type: 'body' | 'query' | 'param' | 'custom';
    metatype?: new (...args) => any;
    data?: string;
}
```

These properties describe the parameter.

|            |                                                                                                                                                       |
| ---------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
| `type`     | Tells us whether the property is a body `@Body()`, query `@Query()`, param `@Param()`, or custom parameter (read more [here](/v4/custom-decorators)). |
| `metatype` | The metatype of the property, for example `String`. It's `undefined` if you would omit the type declaration in the function signature.                |
| `data`     | The string passed to the decorator, for example `@Body('string')`. It's `undefined` if you would leave the brackets empty.                            |

> **Notice** The TypeScript interfaces disappear during the transpilation, so if you'd use an interface instead of a class, the `metatype` value will be an `Object`.

#### How does it work?

Let's focus on the `create()` method of the `CatsController`:

cats.controler.ts

TypeScript

```typescript

@Post()
async create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

There's a `CreateCatDto` body parameter.

create-cat.dto.ts

TypeScript

```typescript

export class CreateCatDto {
  readonly name: string;
  readonly age: number;
  readonly breed: string;
}
```

This object always has to be correct, thus we have to validate these three members. We could do this inside the route handler method, but we'd break the **single responsibility rule** (SRP). The second idea is to create a **validator class** and delegate the task there, but we'll have to use this validator every time at the beginning of the method. So what about the validation middleware? It's a good idea, but it's not possible to create a **generic middleware**, which could be used across the entire application.

That's the first use-case, when you should consider to use a **Pipe**.

#### Class validator

##### This section applies only to TypeScript.

Nest works well with the [class-validator](https://github.com/pleerock/class-validator), this amazing library allows you to use decorator-based validation. Decorator based validation is really powerful with the **pipe** capabilities since we have access to the `metatype` of the processed property. Let's add a few decorators to the `CreateCatDto`.

create-cat.dto.ts

TypeScript

```typescript

import { IsString, IsInt } from 'class-validator';

export class CreateCatDto {
  @IsString()
  readonly name: string;

  @IsInt()
  readonly age: number;

  @IsString()
  readonly breed: string;
}
```

Now it's time to finish the `ValidationPipe` class.

validation.pipe.ts

TypeScript

```typescript

import { PipeTransform, Pipe, ArgumentMetadata, BadRequestException } from '@nestjs/common';
import { validate } from 'class-validator';
import { plainToClass } from 'class-transformer';

@Pipe()
export class ValidationPipe implements PipeTransform<any> {
    async transform(value, metadata: ArgumentMetadata) {
      const { metatype } = metadata;
      if (!metatype || !this.toValidate(metatype)) {
          return value;
      }
      const object = plainToClass(metatype, value);
      const errors = await validate(object);
      if (errors.length > 0) {
          throw new BadRequestException('Validation failed');
      }
      return value;
    }

    private toValidate(metatype): boolean {
      const types = [String, Boolean, Number, Array, Object];
      return !types.find((type) => metatype === type);
    }
}
```

> **Notice** I've used the [class-transformer](https://github.com/pleerock/class-transformer) library. It's made by the same author as the **class-validator** library, so they play well together.

Let's go through this code. Firstly, note that the `transform()` function is `async`. It's possible because Nest supports both synchronous and **asynchronous** pipes. Also, there's a helper function - `toValidate()`. It's responsible to exclude the native JavaScript types from the validation process. The last important thing is that we have to return the same value. This pipe is a validation specific pipe, so we need to return the exact same property to avoid **overriding**.

The last step is to set up the `ValidationPipe`. Pipes, same as [exception filters](/v4/exception-filters) they can be method-scoped, controller-scoped and global-scoped. Additionally, a pipe may be param-scoped. We can directly bind the pipe instance to the route param decorator, for example `@Body()`. Let's have a look at the below example:

cats.controler.ts

TypeScript

```typescript

@Post()
async create(@Body(new ValidationPipe()) createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

The param-scoped pipes are useful when the validation logic concerns only one, specified parameter. To set up a pipe at a method level, you'll need the `UsePipes()` decorator.

cats.controler.ts

TypeScript

```typescript

@Post()
@UsePipes(new ValidationPipe())
async create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

> **Notice** The `@UsePipes()` decorator is imported from the `@nestjs/common` package.

Since the `ValidationPipe` was created to be as generic as possible, we're gonna set it up as a **global-scoped** pipe, for every route handler across the entire application.

main.ts

TypeScript

```typescript

async function bootstrap() {
  const app = await NestFactory.create(ApplicationModule);
  app.useGlobalPipes(new ValidationPipe());
  await app.listen(3000);
}
bootstrap();
```

> **Notice** The `useGlobalPipes()` method doesn't setup pipes for gateways and micro services.

#### Transformer Pipe

Validation isn't the sole use case. At the beginning of this chapter, I've mentioned that a pipe can also **transform** the input data to the desired output. It's true because the value returned from the `transform` function completely overrides the previous value of the argument. Sometimes the data passed from the client needs to undergo some changes. Also, some parts could be missed, so we must apply the default values. The **transformer pipes** fill the gap between the request of the client and the request handler.

parse-int.pipe.ts

JavaScript TypeScript

TypeScript

```typescript

import { PipeTransform, Pipe, ArgumentMetadata, HttpStatus, BadRequestException } from '@nestjs/common';

@Pipe()
export class ParseIntPipe implements PipeTransform<string> {
  async transform(value: string, metadata: ArgumentMetadata) {
    const val = parseInt(value, 10);
    if (isNaN(val)) {
      throw new BadRequestException('Validation failed');
    }
    return val;
  }
}
```

TypeScript

```typescript

import { Pipe, HttpStatus, BadRequestException} from '@nestjs/common';

@Pipe()
export class ParseIntPipe {
  async transform(value, metadata) {
    const val = parseInt(value, 10);
    if (isNaN(val)) {
      throw new BadRequestException('Validation failed');
    }
    return val;
  }
}
```

Here's a `ParseIntPipe` which is responsible to parse a string into an integer value. Now let's bind the pipe to the selected param:

JavaScript TypeScript

TypeScript

```typescript

@Get(':id')
async findOne(@Param('id', new ParseIntPipe()) id) {
  return await this.catsService.findOne(id);
}
```

TypeScript

```typescript

@Get(':id')
@Bind(Param('id', new ParseIntPipe()))
async findOne(id) {
  return await this.catsService.findOne(id);
}
```

#### Global pipes

The global pipes don't belong to any scope. They live outside modules, thus as a result - they can't inject dependencies. We need to create an instance immediately. But sometimes, global pipes depend on other objects. How do we solve this?

The solution is pretty easy. Each Nest application instance is in fact, a created **Nest context**. The Nest context is a wrapper around the Nest container, which holds all instantiated classes. We can grab any existing instance from within any imported module directly using the application object.

Let's assume that we have a `ValidationPipe` registered in the `SharedModule`. This `SharedModule` is imported into the **root module**. We can pick the `ValidationPipe` instance using following syntax:

TypeScript

```typescript

const app = await NestFactory.create(ApplicationModule);
const validationPipe = app
  .select(SharedModule)
  .get(ValidationPipe);

app.useGlobalPipes(validationPipe);
```

To grab the `ValidationPipe` instance we have to use 2 methods, well-described in the table below:

|            |                                                                                                                        |
| ---------- | ---------------------------------------------------------------------------------------------------------------------- |
| `get()`    | Makes it possible to retrieve the instance of the component or controller available inside the processed module.       |
| `select()` | Allows you to navigate through the module tree, for example, to pull out a specific instance from the selected module. |

> **Hint** The root module is selected by default. To select any other module, you need to go through the entire modules stack (step by step).

#### Sponsors

[](https://valor-software.com/)

Nest is an MIT-licensed open source project. It can grow thanks to the support by these awesome people. If you'd like to join them, please read more [here](https://opencollective.com/nest). Thanks!

[](https://opencollective.com/nest/backer/0/website)[](https://opencollective.com/nest/backer/1/website)[](https://opencollective.com/nest/backer/2/website)[](https://opencollective.com/nest/backer/3/website)[](https://opencollective.com/nest/backer/4/website)[](https://opencollective.com/nest/backer/5/website)[](https://opencollective.com/nest/backer/6/website)[](https://opencollective.com/nest/backer/7/website)[](https://opencollective.com/nest/backer/8/website)[](https://opencollective.com/nest/backer/9/website)[](https://opencollective.com/nest/backer/10/website)[](https://opencollective.com/nest/backer/11/website)[](https://opencollective.com/nest/backer/12/website)[](https://opencollective.com/nest/backer/13/website)[](https://opencollective.com/nest/backer/14/website)[](https://opencollective.com/nest/backer/15/website)[](https://opencollective.com/nest/backer/16/website)[](https://opencollective.com/nest/backer/17/website)[](https://opencollective.com/nest/backer/18/website)[](https://opencollective.com/nest/backer/19/website)[](https://opencollective.com/nest/backer/20/website)[](https://opencollective.com/nest/backer/21/website)[](https://opencollective.com/nest/backer/22/website)[](https://opencollective.com/nest/backer/23/website)[](https://opencollective.com/nest/backer/24/website)[](https://opencollective.com/nest/backer/25/website)[](https://opencollective.com/nest/backer/26/website)[](https://opencollective.com/nest/backer/27/website)[](https://opencollective.com/nest/backer/28/website)[](https://opencollective.com/nest/backer/29/website)

[Become a sponsor](https://opencollective.com/nest)

----
url: https://docs.nestjs.com/fundamentals/discovery-service
----

[Skip to content](#content)

On this page

* [Discovery service](https://docs.nestjs.com/fundamentals/discovery-service#discovery-service)
* [Getting started](https://docs.nestjs.com/fundamentals/discovery-service#getting-started)
* [Discovering providers and controllers](https://docs.nestjs.com/fundamentals/discovery-service#discovering-providers-and-controllers)
* [Extracting metadata](https://docs.nestjs.com/fundamentals/discovery-service#extracting-metadata)
* [Conclusion](https://docs.nestjs.com/fundamentals/discovery-service#conclusion)

### Discovery service

The `DiscoveryService`, provided by the `@nestjs/core` package, lets you dynamically inspect and retrieve providers, controllers, and their metadata within a NestJS application. This is particularly useful when building plugins, decorators, or advanced features that rely on runtime introspection, and lets you build more flexible, modular architectures with automated, dynamic behavior.

#### Getting started[#](/fundamentals/discovery-service#getting-started)

Before using `DiscoveryService`, import the `DiscoveryModule` into the module where you intend to use it. This makes the service available for dependency injection:

```typescript

import { Module } from '@nestjs/common';
import { DiscoveryModule } from '@nestjs/core';
import { ExampleService } from './example.service.js';

@Module({
  imports: [DiscoveryModule],
  providers: [ExampleService],
})
export class ExampleModule {}
```

Once the module is set up, you can inject `DiscoveryService` into any provider that needs dynamic discovery:

example.service.ts

JS TS

```typescript

@Injectable()
export class ExampleService {
  constructor(private readonly discoveryService: DiscoveryService) {}
}
```

```typescript

@Injectable()
@Dependencies(DiscoveryService)
export class ExampleService {
  constructor(discoveryService) {
    this.discoveryService = discoveryService;
  }
}
```

#### Discovering providers and controllers[#](/fundamentals/discovery-service#discovering-providers-and-controllers)

A key capability of `DiscoveryService` is retrieving all registered providers in the application, which is useful for dynamically processing providers based on specific conditions. The following snippet retrieves all providers:

```typescript

const providers = this.discoveryService.getProviders();
console.log(providers);
```

Each returned object is an `InstanceWrapper`, which holds information such as the provider's instance, token, and class (`metatype`). Similarly, to retrieve all registered controllers within the application, use:

```typescript

const controllers = this.discoveryService.getControllers();
console.log(controllers);
```

This is useful when controllers need to be processed dynamically, e.g., for analytics tracking or automatic registration mechanisms.

Both methods accept an optional options object. Pass an `include` array of module classes to limit discovery to those modules:

```typescript

const providers = this.discoveryService.getProviders({
  include: [CatsModule],
});
```

#### Extracting metadata[#](/fundamentals/discovery-service#extracting-metadata)

Beyond discovering providers and controllers, `DiscoveryService` also retrieves metadata attached to these components. This is particularly valuable when working with custom decorators that store metadata at runtime.

For example, consider a custom decorator used to tag providers with specific metadata:

```typescript

import { DiscoveryService } from '@nestjs/core';

export const FeatureFlag = DiscoveryService.createDecorator();
```

Applying this decorator to a service stores metadata that can later be queried:

```typescript

import { Injectable } from '@nestjs/common';
import { FeatureFlag } from './custom-metadata.decorator.js';

@Injectable()
@FeatureFlag('experimental')
export class CustomService {}
```

Once metadata is attached to providers this way, you can use `DiscoveryService` to filter providers based on the assigned metadata. The following snippet retrieves a provider tagged with a specific metadata value:

```typescript

const providers = this.discoveryService.getProviders();

const [provider] = providers.filter(
  (item) =>
    this.discoveryService.getMetadataByDecorator(FeatureFlag, item) ===
    'experimental',
);

console.log(
  'Providers with the "experimental" feature flag metadata:',
  provider,
);
```

Decorators created with `DiscoveryService.createDecorator()` also register the classes they decorate, so you can retrieve only those classes by passing the decorator's `KEY` as the `metadataKey` option, instead of filtering all providers yourself:

```typescript

const providers = this.discoveryService.getProviders({
  metadataKey: FeatureFlag.KEY,
});
```

The same decorator can also be applied to methods. To read method-level metadata, pass the method name as the third argument to `getMetadataByDecorator()`.

#### Conclusion[#](/fundamentals/discovery-service#conclusion)

`DiscoveryService` enables runtime introspection in NestJS applications. By discovering providers, controllers, and their metadata dynamically, it serves as a building block for extensible frameworks, plugins, and automation-driven features, whether you need to scan and process providers, extract metadata for further processing, or build modular architectures.

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/fundamentals/discovery-service.md)

----
url: https://docs.nestjs.com/v11/recipes/repl
----

* [Read-Eval-Print-Loop (REPL)](https://docs.nestjs.com/v11/recipes/repl#read-eval-print-loop-repl)
* [Usage](https://docs.nestjs.com/v11/recipes/repl#usage)
* [Native functions](https://docs.nestjs.com/v11/recipes/repl#native-functions)
* [Watch mode](https://docs.nestjs.com/v11/recipes/repl#watch-mode)

```typescript

import { repl } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
  await repl(AppModule);
}
bootstrap();
```

```typescript

import { repl } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
  await repl(AppModule);
}
bootstrap();
```

Now in your terminal, start the REPL with the following command:

```bash

$ npm run start -- --entryFile repl
```

> **Hint**`repl` returns a [Node.js REPL server](https://nodejs.org/api/repl.html) object.

Once it's up and running, you should see the following message in your console:

```bash

LOG [NestFactory] Starting Nest application...
LOG [InstanceLoader] AppModule dependencies initialized
LOG REPL initialized
```

And now you can start interacting with your dependencies graph. For instance, you can retrieve an `AppService` (we are using the starter project as an example here) and call the `getHello()` method:

```typescript

> get(AppService).getHello()
'Hello World!'
```

You can execute any JavaScript code from within your terminal, for example, assign an instance of the `AppController` to a local variable, and use `await` to call an asynchronous method:

```typescript

> appController = get(AppController)
AppController { appService: AppService {} }
> await appController.getHello()
'Hello World!'
```

To display all public methods available on a given provider or controller, use the `methods()` function, as follows:

```typescript

> methods(AppController)

Methods:
 ◻ getHello
```

To print all registered modules as a list together with their controllers and providers, use `debug()`.

```typescript

> debug()

AppModule:
 - controllers:
  ◻ AppController
 - providers:
  ◻ AppService
```

Quick demo:

You can find more information about the existing, predefined native methods in the section below.

#### Native functions[#](/recipes/repl#native-functions)

The built-in NestJS REPL comes with a few native functions that are globally available when you start REPL. You can call `help()` to list them out.

If you don't recall what's the signature (ie: expected parameters and a return type) of a function, you can call `<function_name>.help`. For instance:

```text

> $.help
Retrieves an instance of either injectable or controller, otherwise, throws exception.
Interface: $(token: InjectionToken) => any
```

> **Hint** Those function interfaces are written in [TypeScript function type expression syntax](https://www.typescriptlang.org/docs/handbook/2/functions.html#function-type-expressions).

| Function     | Description                                                                                                        | Signature                                                             |
| ------------ | ------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------- |
| `debug`      | Print all registered modules as a list together with their controllers and providers.                              | `debug(moduleCls?: ClassRef \| string) => void`                       |
| `get` or `$` | Retrieves an instance of either injectable or controller, otherwise, throws exception.                             | `get(token: InjectionToken) => any`                                   |
| `methods`    | Display all public methods available on a given provider or controller.                                            | `methods(token: ClassRef \| string) => void`                          |
| `resolve`    | Resolves transient or request-scoped instance of either injectable or controller, otherwise, throws exception.     | `resolve(token: InjectionToken, contextId: any) => Promise<any>`      |
| `select`     | Allows navigating through the modules tree, for example, to pull out a specific instance from the selected module. | `select(token: DynamicModule \| ClassRef) => INestApplicationContext` |

#### Watch mode[#](/recipes/repl#watch-mode)

During development it is useful to run REPL in a watch mode to reflect all the code changes automatically:

```bash

$ npm run start -- --watch --entryFile repl
```

This has one flaw, the REPL's command history is discarded after each reload which might be cumbersome. Fortunately, there is a very simple solution. Modify your `bootstrap` function like this:

```typescript

async function bootstrap() {
  const replServer = await repl(AppModule);
  replServer.setupHistory(".nestjs_repl_history", (err) => {
    if (err) {
      console.error(err);
    }
  });
}
```

Now the history is preserved between the runs/reloads.

----
url: https://docs.nestjs.com/v10/fundamentals/testing
----

* [Testing](https://docs.nestjs.com/v10/fundamentals/testing#testing)
* [Installation](https://docs.nestjs.com/v10/fundamentals/testing#installation)
* [Unit testing](https://docs.nestjs.com/v10/fundamentals/testing#unit-testing)
* [Testing utilities](https://docs.nestjs.com/v10/fundamentals/testing#testing-utilities)
* [Auto mocking](https://docs.nestjs.com/v10/fundamentals/testing#auto-mocking)
* [End-to-end testing](https://docs.nestjs.com/v10/fundamentals/testing#end-to-end-testing)
* [Overriding globally registered enhancers](https://docs.nestjs.com/v10/fundamentals/testing#overriding-globally-registered-enhancers)
* [Testing request-scoped instances](https://docs.nestjs.com/v10/fundamentals/testing#testing-request-scoped-instances)

```bash

$ npm i --save-dev @nestjs/testing
```

#### Unit testing[#](/fundamentals/testing#unit-testing)

In the following example, we test two classes: `CatsController` and `CatsService`. As mentioned, [Jest](https://github.com/facebook/jest) is provided as the default testing framework. It serves as a test-runner and also provides assert functions and test-double utilities that help with mocking, spying, etc. In the following basic test, we manually instantiate these classes, and ensure that the controller and service fulfill their API contract.

cats.controller.spec.ts

JS TS

```typescript

import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

describe('CatsController', () => {
  let catsController: CatsController;
  let catsService: CatsService;

  beforeEach(() => {
    catsService = new CatsService();
    catsController = new CatsController(catsService);
  });

  describe('findAll', () => {
    it('should return an array of cats', async () => {
      const result = ['test'];
      jest.spyOn(catsService, 'findAll').mockImplementation(() => result);

      expect(await catsController.findAll()).toBe(result);
    });
  });
});
```

```typescript

import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

describe('CatsController', () => {
  let catsController;
  let catsService;

  beforeEach(() => {
    catsService = new CatsService();
    catsController = new CatsController(catsService);
  });

  describe('findAll', () => {
    it('should return an array of cats', async () => {
      const result = ['test'];
      jest.spyOn(catsService, 'findAll').mockImplementation(() => result);

      expect(await catsController.findAll()).toBe(result);
    });
  });
});
```

> **Hint** Keep your test files located near the classes they test. Testing files should have a `.spec` or `.test` suffix.

Because the above sample is trivial, we aren't really testing anything Nest-specific. Indeed, we aren't even using dependency injection (notice that we pass an instance of `CatsService` to our `catsController`). This form of testing - where we manually instantiate the classes being tested - is often called **isolated testing** as it is independent from the framework. Let's introduce some more advanced capabilities that help you test applications that make more extensive use of Nest features.

#### Testing utilities[#](/fundamentals/testing#testing-utilities)

The `@nestjs/testing` package provides a set of utilities that enable a more robust testing process. Let's rewrite the previous example using the built-in `Test` class:

cats.controller.spec.ts

JS TS

```typescript

import { Test } from '@nestjs/testing';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

describe('CatsController', () => {
  let catsController: CatsController;
  let catsService: CatsService;

  beforeEach(async () => {
    const moduleRef = await Test.createTestingModule({
        controllers: [CatsController],
        providers: [CatsService],
      }).compile();

    catsService = moduleRef.get(CatsService);
    catsController = moduleRef.get(CatsController);
  });

  describe('findAll', () => {
    it('should return an array of cats', async () => {
      const result = ['test'];
      jest.spyOn(catsService, 'findAll').mockImplementation(() => result);

      expect(await catsController.findAll()).toBe(result);
    });
  });
});
```

```typescript

import { Test } from '@nestjs/testing';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

describe('CatsController', () => {
  let catsController;
  let catsService;

  beforeEach(async () => {
    const moduleRef = await Test.createTestingModule({
        controllers: [CatsController],
        providers: [CatsService],
      }).compile();

    catsService = moduleRef.get(CatsService);
    catsController = moduleRef.get(CatsController);
  });

  describe('findAll', () => {
    it('should return an array of cats', async () => {
      const result = ['test'];
      jest.spyOn(catsService, 'findAll').mockImplementation(() => result);

      expect(await catsController.findAll()).toBe(result);
    });
  });
});
```

The `Test` class is useful for providing an application execution context that essentially mocks the full Nest runtime, but gives you hooks that make it easy to manage class instances, including mocking and overriding. The `Test` class has a `createTestingModule()` method that takes a module metadata object as its argument (the same object you pass to the `@Module()` decorator). This method returns a `TestingModule` instance which in turn provides a few methods. For unit tests, the important one is the `compile()` method. This method bootstraps a module with its dependencies (similar to the way an application is bootstrapped in the conventional `main.ts` file using `NestFactory.create()`), and returns a module that is ready for testing.

> **Hint** The `compile()` method is **asynchronous** and therefore has to be awaited. Once the module is compiled you can retrieve any **static** instance it declares (controllers and providers) using the `get()` method.

`TestingModule` inherits from the [module reference](/v10/fundamentals/module-ref) class, and therefore its ability to dynamically resolve scoped providers (transient or request-scoped). Do this with the `resolve()` method (the `get()` method can only retrieve static instances).

```typescript

const moduleRef = await Test.createTestingModule({
  controllers: [CatsController],
  providers: [CatsService],
}).compile();

catsService = await moduleRef.resolve(CatsService);
```

> **Warning** The `resolve()` method returns a unique instance of the provider, from its own **DI container sub-tree**. Each sub-tree has a unique context identifier. Thus, if you call this method more than once and compare instance references, you will see that they are not equal.

> **Hint** Learn more about the module reference features [here](/v10/fundamentals/module-ref).

Instead of using the production version of any provider, you can override it with a [custom provider](/v10/fundamentals/custom-providers) for testing purposes. For example, you can mock a database service instead of connecting to a live database. We'll cover overrides in the next section, but they're available for unit tests as well.

```typescript

// ...
import { ModuleMocker, MockFunctionMetadata } from 'jest-mock';

const moduleMocker = new ModuleMocker(global);

describe('CatsController', () => {
  let controller: CatsController;

  beforeEach(async () => {
    const moduleRef = await Test.createTestingModule({
      controllers: [CatsController],
    })
      .useMocker((token) => {
        const results = ['test1', 'test2'];
        if (token === CatsService) {
          return { findAll: jest.fn().mockResolvedValue(results) };
        }
        if (typeof token === 'function') {
          const mockMetadata = moduleMocker.getMetadata(
            token,
          ) as MockFunctionMetadata<any, any>;
          const Mock = moduleMocker.generateFromMetadata(mockMetadata);
          return new Mock();
        }
      })
      .compile();

    controller = moduleRef.get(CatsController);
  });
});
```

You can also retrieve these mocks out of the testing container as you normally would custom providers, `moduleRef.get(CatsService)`.

> **Hint** A general mock factory, like `createMock` from [`@golevelup/ts-jest`](https://github.com/golevelup/nestjs/tree/master/packages/testing) can also be passed directly.

> **Hint**`REQUEST` and `INQUIRER` providers cannot be auto-mocked because they're already pre-defined in the context. However, they can be *overwritten* using the custom provider syntax or by utilizing the `.overrideProvider` method.

#### End-to-end testing[#](/fundamentals/testing#end-to-end-testing)

Unlike unit testing, which focuses on individual modules and classes, end-to-end (e2e) testing covers the interaction of classes and modules at a more aggregate level -- closer to the kind of interaction that end-users will have with the production system. As an application grows, it becomes hard to manually test the end-to-end behavior of each API endpoint. Automated end-to-end tests help us ensure that the overall behavior of the system is correct and meets project requirements. To perform e2e tests we use a similar configuration to the one we just covered in **unit testing**. In addition, Nest makes it easy to use the [Supertest](https://github.com/visionmedia/supertest) library to simulate HTTP requests.

cats.e2e-spec.ts

JS TS

```typescript

import * as request from 'supertest';
import { Test } from '@nestjs/testing';
import { CatsModule } from '../../src/cats/cats.module';
import { CatsService } from '../../src/cats/cats.service';
import { INestApplication } from '@nestjs/common';

describe('Cats', () => {
  let app: INestApplication;
  let catsService = { findAll: () => ['test'] };

  beforeAll(async () => {
    const moduleRef = await Test.createTestingModule({
      imports: [CatsModule],
    })
      .overrideProvider(CatsService)
      .useValue(catsService)
      .compile();

    app = moduleRef.createNestApplication();
    await app.init();
  });

  it(`/GET cats`, () => {
    return request(app.getHttpServer())
      .get('/cats')
      .expect(200)
      .expect({
        data: catsService.findAll(),
      });
  });

  afterAll(async () => {
    await app.close();
  });
});
```

```typescript

import * as request from 'supertest';
import { Test } from '@nestjs/testing';
import { CatsModule } from '../../src/cats/cats.module';
import { CatsService } from '../../src/cats/cats.service';
import { INestApplication } from '@nestjs/common';

describe('Cats', () => {
  let app: INestApplication;
  let catsService = { findAll: () => ['test'] };

  beforeAll(async () => {
    const moduleRef = await Test.createTestingModule({
      imports: [CatsModule],
    })
      .overrideProvider(CatsService)
      .useValue(catsService)
      .compile();

    app = moduleRef.createNestApplication();
    await app.init();
  });

  it(`/GET cats`, () => {
    return request(app.getHttpServer())
      .get('/cats')
      .expect(200)
      .expect({
        data: catsService.findAll(),
      });
  });

  afterAll(async () => {
    await app.close();
  });
});
```

> **Hint** If you're using [Fastify](/v10/techniques/performance) as your HTTP adapter, it requires a slightly different configuration, and has built-in testing capabilities:
>
> ```ts
>
> let app: NestFastifyApplication;
>
> beforeAll(async () => {
>   app = moduleRef.createNestApplication<NestFastifyApplication>(
>     new FastifyAdapter(),
>   );
>
>   await app.init();
>   await app.getHttpAdapter().getInstance().ready();
> });
>
> it(`/GET cats`, () => {
>   return app
>     .inject({
>       method: 'GET',
>       url: '/cats',
>     })
>     .then((result) => {
>       expect(result.statusCode).toEqual(200);
>       expect(result.payload).toEqual(/* expectedPayload */);
>     });
> });
>
> afterAll(async () => {
>   await app.close();
> });
> ```

```typescript

const moduleRef = await Test.createTestingModule({
  imports: [AppModule],
})
  .overrideModule(CatsModule)
  .useModule(AlternateCatsModule)
  .compile();
```

Each of the override method types, in turn, returns the `TestingModule` instance, and can thus be chained with other methods in the [fluent style](https://en.wikipedia.org/wiki/Fluent_interface). You should use `compile()` at the end of such a chain to cause Nest to instantiate and initialize the module.

Also, sometimes you may want to provide a custom logger e.g. when the tests are run (for example, on a CI server). Use the `setLogger()` method and pass an object that fulfills the `LoggerService` interface to instruct the `TestModuleBuilder` how to log during tests (by default, only "error" logs will be logged to the console).

The compiled module has several useful methods, as described in the following table:

|                            |                                                                                                                                                                                                                                                   |
| -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `createNestApplication()`  | Creates and returns a Nest application (`INestApplication` instance) based on the given module. Note that you must manually initialize the application using the `init()` method.                                                                 |
| `createNestMicroservice()` | Creates and returns a Nest microservice (`INestMicroservice` instance) based on the given module.                                                                                                                                                 |
| `get()`                    | Retrieves a static instance of a controller or provider (including guards, filters, etc.) available in the application context. Inherited from the [module reference](/fundamentals/module-ref) class.                                            |
| `resolve()`                | Retrieves a dynamically created scoped instance (request or transient) of a controller or provider (including guards, filters, etc.) available in the application context. Inherited from the [module reference](/fundamentals/module-ref) class. |
| `select()`                 | Navigates through the module's dependency graph; can be used to retrieve a specific instance from the selected module (used along with strict mode (`strict: true`) in `get()` method).                                                           |

> **Hint** Keep your e2e test files inside the `test` directory. The testing files should have a `.e2e-spec` suffix.

#### Overriding globally registered enhancers[#](/fundamentals/testing#overriding-globally-registered-enhancers)

If you have a globally registered guard (or pipe, interceptor, or filter), you need to take a few more steps to override that enhancer. To recap the original registration looks like this:

```typescript

providers: [
  {
    provide: APP_GUARD,
    useClass: JwtAuthGuard,
  },
],
```

This is registering the guard as a "multi"-provider through the `APP_*` token. To be able to replace the `JwtAuthGuard` here, the registration needs to use an existing provider in this slot:

```typescript

providers: [
  {
    provide: APP_GUARD,
    useExisting: JwtAuthGuard,
    // ^^^^^^^^ notice the use of 'useExisting' instead of 'useClass'
  },
  JwtAuthGuard,
],
```

> **Hint** Change the `useClass` to `useExisting` to reference a registered provider instead of having Nest instantiate it behind the token.

Now the `JwtAuthGuard` is visible to Nest as a regular provider that can be overridden when creating the `TestingModule`:

```typescript

const moduleRef = await Test.createTestingModule({
  imports: [AppModule],
})
  .overrideProvider(JwtAuthGuard)
  .useClass(MockAuthGuard)
  .compile();
```

Now all your tests will use the `MockAuthGuard` on every request.

#### Testing request-scoped instances[#](/fundamentals/testing#testing-request-scoped-instances)

[Request-scoped](/v10/fundamentals/injection-scopes) providers are created uniquely for each incoming **request**. The instance is garbage-collected after the request has completed processing. This poses a problem, because we can't access a dependency injection sub-tree generated specifically for a tested request.

We know (based on the sections above) that the `resolve()` method can be used to retrieve a dynamically instantiated class. Also, as described [here](https://docs.nestjs.com/fundamentals/module-ref#resolving-scoped-providers), we know we can pass a unique context identifier to control the lifecycle of a DI container sub-tree. How do we leverage this in a testing context?

The strategy is to generate a context identifier beforehand and force Nest to use this particular ID to create a sub-tree for all incoming requests. In this way we'll be able to retrieve instances created for a tested request.

To accomplish this, use `jest.spyOn()` on the `ContextIdFactory`:

```typescript

const contextId = ContextIdFactory.create();
jest
  .spyOn(ContextIdFactory, 'getByRequest')
  .mockImplementation(() => contextId);
```

Now we can use the `contextId` to access a single generated DI container sub-tree for any subsequent request.

```typescript

catsService = await moduleRef.resolve(CatsService, contextId);
```

----
url: https://docs.nestjs.com/v10/security/authorization
----

* [Authorization](https://docs.nestjs.com/v10/security/authorization#authorization)
* [Basic RBAC implementation](https://docs.nestjs.com/v10/security/authorization#basic-rbac-implementation)
* [Claims-based authorization](https://docs.nestjs.com/v10/security/authorization#claims-based-authorization)
* [Integrating CASL](https://docs.nestjs.com/v10/security/authorization#integrating-casl)
* [Advanced: Implementing a PoliciesGuard](https://docs.nestjs.com/v10/security/authorization#advanced-implementing-a-policiesguard)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/security/authorization.md "Suggest Edits")

### Authorization

**Authorization** refers to the process that determines what a user is able to do. For example, an administrative user is allowed to create, edit, and delete posts. A non-administrative user is only authorized to read the posts.

Authorization is orthogonal and independent from authentication. However, authorization requires an authentication mechanism.

There are many different approaches and strategies to handle authorization. The approach taken for any project depends on its particular application requirements. This chapter presents a few approaches to authorization that can be adapted to a variety of different requirements.

#### Basic RBAC implementation[#](/security/authorization#basic-rbac-implementation)

Role-based access control (**RBAC**) is a policy-neutral access-control mechanism defined around roles and privileges. In this section, we'll demonstrate how to implement a very basic RBAC mechanism using Nest [guards](/v10/guards).

First, let's create a `Role` enum representing roles in the system:

role.enum.ts

JS TS

```typescript

export enum Role {
  User = 'user',
  Admin = 'admin',
}
```

> **Hint** In more sophisticated systems, you may store roles within a database, or pull them from the external authentication provider.

With this in place, we can create a `@Roles()` decorator. This decorator allows specifying what roles are required to access specific resources.

roles.decorator.ts

JS TS

```typescript

import { SetMetadata } from '@nestjs/common';
import { Role } from '../enums/role.enum';

export const ROLES_KEY = 'roles';
export const Roles = (...roles: Role[]) => SetMetadata(ROLES_KEY, roles);
```

```typescript

import { SetMetadata } from '@nestjs/common';

export const ROLES_KEY = 'roles';
export const Roles = (...roles) => SetMetadata(ROLES_KEY, roles);
```

Now that we have a custom `@Roles()` decorator, we can use it to decorate any route handler.

cats.controller.ts

JS TS

```typescript

@Post()
@Roles(Role.Admin)
create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

```typescript

@Post()
@Roles(Role.Admin)
@Bind(Body())
create(createCatDto) {
  this.catsService.create(createCatDto);
}
```

Finally, we create a `RolesGuard` class which will compare the roles assigned to the current user to the actual roles required by the current route being processed. In order to access the route's role(s) (custom metadata), we'll use the `Reflector` helper class, which is provided out of the box by the framework and exposed from the `@nestjs/core` package.

roles.guard.ts

JS TS

```typescript

import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
import { Reflector } from '@nestjs/core';

@Injectable()
export class RolesGuard implements CanActivate {
  constructor(private reflector: Reflector) {}

  canActivate(context: ExecutionContext): boolean {
    const requiredRoles = this.reflector.getAllAndOverride<Role[]>(ROLES_KEY, [
      context.getHandler(),
      context.getClass(),
    ]);
    if (!requiredRoles) {
      return true;
    }
    const { user } = context.switchToHttp().getRequest();
    return requiredRoles.some((role) => user.roles?.includes(role));
  }
}
```

```typescript

import { Injectable, Dependencies } from '@nestjs/common';
import { Reflector } from '@nestjs/core';

@Injectable()
@Dependencies(Reflector)
export class RolesGuard {
  constructor(reflector) {
    this.reflector = reflector;
  }

  canActivate(context) {
    const requiredRoles = this.reflector.getAllAndOverride(ROLES_KEY, [
      context.getHandler(),
      context.getClass(),
    ]);
    if (!requiredRoles) {
      return true;
    }
    const { user } = context.switchToHttp().getRequest();
    return requiredRoles.some((role) => user.roles.includes(role));
  }
}
```

> **Hint** Refer to the [Reflection and metadata](/fundamentals/execution-context#reflection-and-metadata) section of the Execution context chapter for more details on utilizing `Reflector` in a context-sensitive way.

> **Notice** This example is named "**basic**" as we only check for the presence of roles on the route handler level. In real-world applications, you may have endpoints/handlers that involve several operations, in which each of them requires a specific set of permissions. In this case, you'll have to provide a mechanism to check roles somewhere within your business-logic, making it somewhat harder to maintain as there will be no centralized place that associates permissions with specific actions.

In this example, we assumed that `request.user` contains the user instance and allowed roles (under the `roles` property). In your app, you will probably make that association in your custom **authentication guard** - see [authentication](/v10/security/authentication) chapter for more details.

To make sure this example works, your `User` class must look as follows:

```typescript

class User {
  // ...other properties
  roles: Role[];
}
```

Lastly, make sure to register the `RolesGuard`, for example, at the controller level, or globally:

```typescript

providers: [
  {
    provide: APP_GUARD,
    useClass: RolesGuard,
  },
],
```

When a user with insufficient privileges requests an endpoint, Nest automatically returns the following response:

```typescript

{
  "statusCode": 403,
  "message": "Forbidden resource",
  "error": "Forbidden"
}
```

> **Hint** If you want to return a different error response, you should throw your own specific exception instead of returning a boolean value.

```typescript

@Post()
@RequirePermissions(Permission.CREATE_CAT)
create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

```typescript

@Post()
@RequirePermissions(Permission.CREATE_CAT)
@Bind(Body())
create(createCatDto) {
  this.catsService.create(createCatDto);
}
```

> **Hint** In the example above, `Permission` (similar to `Role` we have shown in RBAC section) is a TypeScript enum that contains all the permissions available in your system.

#### Integrating CASL[#](/security/authorization#integrating-casl)

[CASL](https://casl.js.org/) is an isomorphic authorization library which restricts what resources a given client is allowed to access. It's designed to be incrementally adoptable and can easily scale between a simple claim based and fully featured subject and attribute based authorization.

To start, first install the `@casl/ability` package:

```bash

$ npm i @casl/ability
```

> **Hint** In this example, we chose CASL, but you can use any other library like `accesscontrol` or `acl`, depending on your preferences and project needs.

Once the installation is complete, for the sake of illustrating the mechanics of CASL, we'll define two entity classes: `User` and `Article`.

```typescript

class User {
  id: number;
  isAdmin: boolean;
}
```

`User` class consists of two properties, `id`, which is a unique user identifier, and `isAdmin`, indicating whether a user has administrator privileges.

```typescript

class Article {
  id: number;
  isPublished: boolean;
  authorId: number;
}
```

```typescript

export enum Action {
  Manage = 'manage',
  Create = 'create',
  Read = 'read',
  Update = 'update',
  Delete = 'delete',
}
```

> **Notice**`manage` is a special keyword in CASL which represents "any" action.

To encapsulate CASL library, let's generate the `CaslModule` and `CaslAbilityFactory` now.

```bash

$ nest g module casl
$ nest g class casl/casl-ability.factory
```

With this in place, we can define the `createForUser()` method on the `CaslAbilityFactory`. This method will create the `Ability` object for a given user:

```typescript

type Subjects = InferSubjects<typeof Article | typeof User> | 'all';

export type AppAbility = Ability<[Action, Subjects]>;

@Injectable()
export class CaslAbilityFactory {
  createForUser(user: User) {
    const { can, cannot, build } = new AbilityBuilder<
      Ability<[Action, Subjects]>
    >(Ability as AbilityClass<AppAbility>);

    if (user.isAdmin) {
      can(Action.Manage, 'all'); // read-write access to everything
    } else {
      can(Action.Read, 'all'); // read-only access to everything
    }

    can(Action.Update, Article, { authorId: user.id });
    cannot(Action.Delete, Article, { isPublished: true });

    return build({
      // Read https://casl.js.org/v6/en/guide/subject-type-detection#use-classes-as-subject-types for details
      detectSubjectType: (item) =>
        item.constructor as ExtractSubjectType<Subjects>,
    });
  }
}
```

> **Notice**`all` is a special keyword in CASL that represents "any subject".

> **Hint**`Ability`, `AbilityBuilder`, `AbilityClass`, and `ExtractSubjectType` classes are exported from the `@casl/ability` package.

> **Hint**`detectSubjectType` option let CASL understand how to get subject type out of an object. For more information read [CASL documentation](https://casl.js.org/v6/en/guide/subject-type-detection#use-classes-as-subject-types) for details.

In the example above, we created the `Ability` instance using the `AbilityBuilder` class. As you probably guessed, `can` and `cannot` accept the same arguments but have different meanings, `can` allows to do an action on the specified subject and `cannot` forbids. Both may accept up to 4 arguments. To learn more about these functions, visit the official [CASL documentation](https://casl.js.org/v6/en/guide/intro).

Lastly, make sure to add the `CaslAbilityFactory` to the `providers` and `exports` arrays in the `CaslModule` module definition:

```typescript

import { Module } from '@nestjs/common';
import { CaslAbilityFactory } from './casl-ability.factory';

@Module({
  providers: [CaslAbilityFactory],
  exports: [CaslAbilityFactory],
})
export class CaslModule {}
```

With this in place, we can inject the `CaslAbilityFactory` to any class using standard constructor injection as long as the `CaslModule` is imported in the host context:

```typescript

constructor(private caslAbilityFactory: CaslAbilityFactory) {}
```

Then use it in a class as follows.

```typescript

const ability = this.caslAbilityFactory.createForUser(user);
if (ability.can(Action.Read, 'all')) {
  // "user" has read access to everything
}
```

> **Hint** Learn more about the `Ability` class in the official [CASL documentation](https://casl.js.org/v6/en/guide/intro).

For example, let's say we have a user who is not an admin. In this case, the user should be able to read articles, but creating new ones or removing the existing articles should be prohibited.

```typescript

const user = new User();
user.isAdmin = false;

const ability = this.caslAbilityFactory.createForUser(user);
ability.can(Action.Read, Article); // true
ability.can(Action.Delete, Article); // false
ability.can(Action.Create, Article); // false
```

> **Hint** Although both `Ability` and `AbilityBuilder` classes provide `can` and `cannot` methods, they have different purposes and accept slightly different arguments.

Also, as we have specified in our requirements, the user should be able to update its articles:

```typescript

const user = new User();
user.id = 1;

const article = new Article();
article.authorId = user.id;

const ability = this.caslAbilityFactory.createForUser(user);
ability.can(Action.Update, article); // true

article.authorId = 2;
ability.can(Action.Update, article); // false
```

As you can see, `Ability` instance allows us to check permissions in pretty readable way. Likewise, `AbilityBuilder` allows us to define permissions (and specify various conditions) in a similar fashion. To find more examples, visit the official documentation.

#### Advanced: Implementing a `PoliciesGuard`[#](/security/authorization#advanced-implementing-a-policiesguard)

In this section, we'll demonstrate how to build a somewhat more sophisticated guard, which checks if a user meets specific **authorization policies** that can be configured on the method-level (you can extend it to respect policies configured on the class-level too). In this example, we are going to use the CASL package just for illustration purposes, but using this library is not required. Also, we will use the `CaslAbilityFactory` provider that we've created in the previous section.

First, let's flesh out the requirements. The goal is to provide a mechanism that allows specifying policy checks per route handler. We will support both objects and functions (for simpler checks and for those who prefer more functional-style code).

Let's start off by defining interfaces for policy handlers:

```typescript

import { AppAbility } from '../casl/casl-ability.factory';

interface IPolicyHandler {
  handle(ability: AppAbility): boolean;
}

type PolicyHandlerCallback = (ability: AppAbility) => boolean;

export type PolicyHandler = IPolicyHandler | PolicyHandlerCallback;
```

As mentioned above, we provided two possible ways of defining a policy handler, an object (instance of a class that implements the `IPolicyHandler` interface) and a function (which meets the `PolicyHandlerCallback` type).

With this in place, we can create a `@CheckPolicies()` decorator. This decorator allows specifying what policies have to be met to access specific resources.

```typescript

export const CHECK_POLICIES_KEY = 'check_policy';
export const CheckPolicies = (...handlers: PolicyHandler[]) =>
  SetMetadata(CHECK_POLICIES_KEY, handlers);
```

Now let's create a `PoliciesGuard` that will extract and execute all the policy handlers bound to a route handler.

```typescript

@Injectable()
export class PoliciesGuard implements CanActivate {
  constructor(
    private reflector: Reflector,
    private caslAbilityFactory: CaslAbilityFactory,
  ) {}

  async canActivate(context: ExecutionContext): Promise<boolean> {
    const policyHandlers =
      this.reflector.get<PolicyHandler[]>(
        CHECK_POLICIES_KEY,
        context.getHandler(),
      ) || [];

    const { user } = context.switchToHttp().getRequest();
    const ability = this.caslAbilityFactory.createForUser(user);

    return policyHandlers.every((handler) =>
      this.execPolicyHandler(handler, ability),
    );
  }

  private execPolicyHandler(handler: PolicyHandler, ability: AppAbility) {
    if (typeof handler === 'function') {
      return handler(ability);
    }
    return handler.handle(ability);
  }
}
```

> **Hint** In this example, we assumed that `request.user` contains the user instance. In your app, you will probably make that association in your custom **authentication guard** - see [authentication](/v10/security/authentication) chapter for more details.

Let's break this example down. The `policyHandlers` is an array of handlers assigned to the method through the `@CheckPolicies()` decorator. Next, we use the `CaslAbilityFactory#create` method which constructs the `Ability` object, allowing us to verify whether a user has sufficient permissions to perform specific actions. We are passing this object to the policy handler which is either a function or an instance of a class that implements the `IPolicyHandler`, exposing the `handle()` method that returns a boolean. Lastly, we use the `Array#every` method to make sure that every handler returned `true` value.

Finally, to test this guard, bind it to any route handler, and register an inline policy handler (functional approach), as follows:

```typescript

@Get()
@UseGuards(PoliciesGuard)
@CheckPolicies((ability: AppAbility) => ability.can(Action.Read, Article))
findAll() {
  return this.articlesService.findAll();
}
```

Alternatively, we can define a class which implements the `IPolicyHandler` interface:

```typescript

export class ReadArticlePolicyHandler implements IPolicyHandler {
  handle(ability: AppAbility) {
    return ability.can(Action.Read, Article);
  }
}
```

And use it as follows:

```typescript

@Get()
@UseGuards(PoliciesGuard)
@CheckPolicies(new ReadArticlePolicyHandler())
findAll() {
  return this.articlesService.findAll();
}
```

> **Notice** Since we must instantiate the policy handler in-place using the `new` keyword, `ReadArticlePolicyHandler` class cannot use the Dependency Injection. This can be addressed with the `ModuleRef#get` method (read more [here](/v10/fundamentals/module-ref)). Basically, instead of registering functions and instances through the `@CheckPolicies()` decorator, you must allow passing a `Type<IPolicyHandler>`. Then, inside your guard, you could retrieve an instance using a type reference: `moduleRef.get(YOUR_HANDLER_TYPE)` or even dynamically instantiate it using the `ModuleRef#create` method.

----
url: https://docs.nestjs.com/v8/fundamentals/custom-providers
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Custom providers](https://docs.nestjs.com/v8/fundamentals/custom-providers#custom-providers)
* [DI fundamentals](https://docs.nestjs.com/v8/fundamentals/custom-providers#di-fundamentals)
* [Standard providers](https://docs.nestjs.com/v8/fundamentals/custom-providers#standard-providers)
* [Custom providers](https://docs.nestjs.com/v8/fundamentals/custom-providers#custom-providers-1)
* [Value providers: useValue](https://docs.nestjs.com/v8/fundamentals/custom-providers#value-providers-usevalue)
* [Non-class-based provider tokens](https://docs.nestjs.com/v8/fundamentals/custom-providers#non-class-based-provider-tokens)
* [Class providers: useClass](https://docs.nestjs.com/v8/fundamentals/custom-providers#class-providers-useclass)
* [Factory providers: useFactory](https://docs.nestjs.com/v8/fundamentals/custom-providers#factory-providers-usefactory)
* [Alias providers: useExisting](https://docs.nestjs.com/v8/fundamentals/custom-providers#alias-providers-useexisting)
* [Non-service based providers](https://docs.nestjs.com/v8/fundamentals/custom-providers#non-service-based-providers)
* [Export custom provider](https://docs.nestjs.com/v8/fundamentals/custom-providers#export-custom-provider)

```typescript

import { Injectable } from '@nestjs/common';
import { Cat } from './interfaces/cat.interface';

@Injectable()
export class CatsService {
  private readonly cats: Cat[] = [];

  findAll(): Cat[] {
    return this.cats;
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';

@Injectable()
export class CatsService {
  constructor() {
    this.cats = [];
  }

  findAll() {
    return this.cats;
  }
}
```

Then we request that Nest inject the provider into our controller class:

cats.controller.ts

JS TS

```typescript

import { Controller, Get } from '@nestjs/common';
import { CatsService } from './cats.service';
import { Cat } from './interfaces/cat.interface';

@Controller('cats')
export class CatsController {
  constructor(private catsService: CatsService) {}

  @Get()
  async findAll(): Promise<Cat[]> {
    return this.catsService.findAll();
  }
}
```

```typescript

import { Controller, Get, Bind, Dependencies } from '@nestjs/common';
import { CatsService } from './cats.service';

@Controller('cats')
@Dependencies(CatsService)
export class CatsController {
  constructor(catsService) {
    this.catsService = catsService;
  }

  @Get()
  async findAll() {
    return this.catsService.findAll();
  }
}
```

Finally, we register the provider with the Nest IoC container:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { CatsController } from './cats/cats.controller';
import { CatsService } from './cats/cats.service';

@Module({
  controllers: [CatsController],
  providers: [CatsService],
})
export class AppModule {}
```

What exactly is happening under the covers to make this work? There are three key steps in the process:

1. In `cats.service.ts`, the `@Injectable()` decorator declares the `CatsService` class as a class that can be managed by the Nest IoC container.
2. In `cats.controller.ts`, `CatsController` declares a dependency on the `CatsService` token with constructor injection:

```typescript

  constructor(private catsService: CatsService)
```

```typescript

@Module({
  controllers: [CatsController],
  providers: [CatsService],
})
```

The `providers` property takes an array of `providers`. So far, we've supplied those providers via a list of class names. In fact, the syntax `providers: [CatsService]` is short-hand for the more complete syntax:

```typescript

providers: [
  {
    provide: CatsService,
    useClass: CatsService,
  },
];
```

> **Hint** If you are having problems with dependency resolution you can set the `NEST_DEBUG` environment variable and get extra dependency resolution logs during startup.

#### Value providers: `useValue`[#](/fundamentals/custom-providers#value-providers-usevalue)

The `useValue` syntax is useful for injecting a constant value, putting an external library into the Nest container, or replacing a real implementation with a mock object. Let's say you'd like to force Nest to use a mock `CatsService` for testing purposes.

```typescript

import { CatsService } from './cats.service';

const mockCatsService = {
  /* mock implementation
  ...
  */
};

@Module({
  imports: [CatsModule],
  providers: [
    {
      provide: CatsService,
      useValue: mockCatsService,
    },
  ],
})
export class AppModule {}
```

In this example, the `CatsService` token will resolve to the `mockCatsService` mock object. `useValue` requires a value - in this case a literal object that has the same interface as the `CatsService` class it is replacing. Because of TypeScript's [structural typing](https://www.typescriptlang.org/docs/handbook/type-compatibility.html), you can use any object that has a compatible interface, including a literal object or a class instance instantiated with `new`.

#### Non-class-based provider tokens[#](/fundamentals/custom-providers#non-class-based-provider-tokens)

So far, we've used class names as our provider tokens (the value of the `provide` property in a provider listed in the `providers` array). This is matched by the standard pattern used with [constructor based injection](https://docs.nestjs.com/providers#dependency-injection), where the token is also a class name. (Refer back to [DI Fundamentals](/fundamentals/custom-providers#di-fundamentals) for a refresher on tokens if this concept isn't entirely clear). Sometimes, we may want the flexibility to use strings or symbols as the DI token. For example:

```typescript

import { connection } from './connection';

@Module({
  providers: [
    {
      provide: 'CONNECTION',
      useValue: connection,
    },
  ],
})
export class AppModule {}
```

In this example, we are associating a string-valued token (`'CONNECTION'`) with a pre-existing `connection` object we've imported from an external file.

> **Notice** In addition to using strings as token values, you can also use JavaScript [symbols](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol) or TypeScript [enums](https://www.typescriptlang.org/docs/handbook/enums.html).

We've previously seen how to inject a provider using the standard [constructor based injection](https://docs.nestjs.com/providers#dependency-injection) pattern. This pattern **requires** that the dependency be declared with a class name. The `'CONNECTION'` custom provider uses a string-valued token. Let's see how to inject such a provider. To do so, we use the `@Inject()` decorator. This decorator takes a single argument - the token.

JS TS

```typescript

@Injectable()
export class CatsRepository {
  constructor(@Inject('CONNECTION') connection: Connection) {}
}
```

```typescript

@Injectable()
@Dependencies('CONNECTION')
export class CatsRepository {
  constructor(connection) {}
}
```

> **Hint** The `@Inject()` decorator is imported from `@nestjs/common` package.

While we directly use the string `'CONNECTION'` in the above examples for illustration purposes, for clean code organization, it's best practice to define tokens in a separate file, such as `constants.ts`. Treat them much as you would symbols or enums that are defined in their own file and imported where needed.

#### Class providers: `useClass`[#](/fundamentals/custom-providers#class-providers-useclass)

The `useClass` syntax allows you to dynamically determine a class that a token should resolve to. For example, suppose we have an abstract (or default) `ConfigService` class. Depending on the current environment, we want Nest to provide a different implementation of the configuration service. The following code implements such a strategy.

```typescript

const configServiceProvider = {
  provide: ConfigService,
  useClass:
    process.env.NODE_ENV === 'development'
      ? DevelopmentConfigService
      : ProductionConfigService,
};

@Module({
  providers: [configServiceProvider],
})
export class AppModule {}
```

```typescript

const connectionFactory = {
  provide: 'CONNECTION',
  useFactory: (optionsProvider: OptionsProvider, optionalProvider?: string) => {
    const options = optionsProvider.get();
    return new DatabaseConnection(options);
  },
  inject: [OptionsProvider, { token: 'SomeOptionalProvider', optional: true }],
  //       \_____________/            \__________________/
  //        This provider              The provider with this
  //        is mandatory.              token can resolves to `undefined`.
};

@Module({
  providers: [
    connectionFactory,
    OptionsProvider,
    // { provide: 'SomeOptionalProvider', useValue: 'anything' },
  ],
})
export class AppModule {}
```

```typescript

const connectionFactory = {
  provide: 'CONNECTION',
  useFactory: (optionsProvider, optionalProvider) => {
    const options = optionsProvider.get();
    return new DatabaseConnection(options);
  },
  inject: [OptionsProvider, { token: 'SomeOptionalProvider', optional: true }],
  //       \_____________/            \__________________/
  //        This provider              The provider with this
  //        is mandatory.              token can resolves to `undefined`.
};

@Module({
  providers: [
    connectionFactory,
    OptionsProvider,
    // { provide: 'SomeOptionalProvider', useValue: 'anything' },
  ],
})
export class AppModule {}
```

#### Alias providers: `useExisting`[#](/fundamentals/custom-providers#alias-providers-useexisting)

The `useExisting` syntax allows you to create aliases for existing providers. This creates two ways to access the same provider. In the example below, the (string-based) token `'AliasedLoggerService'` is an alias for the (class-based) token `LoggerService`. Assume we have two different dependencies, one for `'AliasedLoggerService'` and one for `LoggerService`. If both dependencies are specified with `SINGLETON` scope, they'll both resolve to the same instance.

```typescript

@Injectable()
class LoggerService {
  /* implementation details */
}

const loggerAliasProvider = {
  provide: 'AliasedLoggerService',
  useExisting: LoggerService,
};

@Module({
  providers: [LoggerService, loggerAliasProvider],
})
export class AppModule {}
```

#### Non-service based providers[#](/fundamentals/custom-providers#non-service-based-providers)

While providers often supply services, they are not limited to that usage. A provider can supply **any** value. For example, a provider may supply an array of configuration objects based on the current environment, as shown below:

```typescript

const configFactory = {
  provide: 'CONFIG',
  useFactory: () => {
    return process.env.NODE_ENV === 'development' ? devConfig : prodConfig;
  },
};

@Module({
  providers: [configFactory],
})
export class AppModule {}
```

#### Export custom provider[#](/fundamentals/custom-providers#export-custom-provider)

Like any provider, a custom provider is scoped to its declaring module. To make it visible to other modules, it must be exported. To export a custom provider, we can either use its token or the full provider object.

The following example shows exporting using the token:

JS TS

```typescript

const connectionFactory = {
  provide: 'CONNECTION',
  useFactory: (optionsProvider: OptionsProvider) => {
    const options = optionsProvider.get();
    return new DatabaseConnection(options);
  },
  inject: [OptionsProvider],
};

@Module({
  providers: [connectionFactory],
  exports: ['CONNECTION'],
})
export class AppModule {}
```

```typescript

const connectionFactory = {
  provide: 'CONNECTION',
  useFactory: (optionsProvider) => {
    const options = optionsProvider.get();
    return new DatabaseConnection(options);
  },
  inject: [OptionsProvider],
};

@Module({
  providers: [connectionFactory],
  exports: ['CONNECTION'],
})
export class AppModule {}
```

Alternatively, export with the full provider object:

JS TS

```typescript

const connectionFactory = {
  provide: 'CONNECTION',
  useFactory: (optionsProvider: OptionsProvider) => {
    const options = optionsProvider.get();
    return new DatabaseConnection(options);
  },
  inject: [OptionsProvider],
};

@Module({
  providers: [connectionFactory],
  exports: [connectionFactory],
})
export class AppModule {}
```

```typescript

const connectionFactory = {
  provide: 'CONNECTION',
  useFactory: (optionsProvider) => {
    const options = optionsProvider.get();
    return new DatabaseConnection(options);
  },
  inject: [OptionsProvider],
};

@Module({
  providers: [connectionFactory],
  exports: [connectionFactory],
})
export class AppModule {}
```

----
url: https://docs.nestjs.com/v8/microservices/exception-filters
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Exception filters](https://docs.nestjs.com/v8/microservices/exception-filters#exception-filters)
* [Filters](https://docs.nestjs.com/v8/microservices/exception-filters#filters)
* [Inheritance](https://docs.nestjs.com/v8/microservices/exception-filters#inheritance)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/microservices/exception-filters.md "Suggest Edits")

### Exception filters

The only difference between the HTTP [exception filter](/v8/exception-filters) layer and the corresponding microservices layer is that instead of throwing `HttpException`, you should use `RpcException`.

```typescript

throw new RpcException('Invalid credentials.');
```

> **Hint** The `RpcException` class is imported from the `@nestjs/microservices` package.

With the sample above, Nest will handle the thrown exception and return the `error` object with the following structure:

```json

{
  "status": "error",
  "message": "Invalid credentials."
}
```

#### Filters[#](/microservices/exception-filters#filters)

Microservice exception filters behave similarly to HTTP exception filters, with one small difference. The `catch()` method must return an `Observable`.

rpc-exception.filter.ts

JS TS

```typescript

import { Catch, RpcExceptionFilter, ArgumentsHost } from '@nestjs/common';
import { Observable, throwError } from 'rxjs';
import { RpcException } from '@nestjs/microservices';

@Catch(RpcException)
export class ExceptionFilter implements RpcExceptionFilter<RpcException> {
  catch(exception: RpcException, host: ArgumentsHost): Observable<any> {
    return throwError(() => exception.getError());
  }
}
```

```typescript

import { Catch } from '@nestjs/common';
import { throwError } from 'rxjs';

@Catch(RpcException)
export class ExceptionFilter {
  catch(exception, host) {
    return throwError(() => exception.getError());
  }
}
```

> **Warning** Global microservice exception filters aren't enabled by default when using a [hybrid application](/v8/faq/hybrid-application).

The following example uses a manually instantiated method-scoped filter. Just as with HTTP based applications, you can also use controller-scoped filters (i.e., prefix the controller class with a `@UseFilters()` decorator).

JS TS

```typescript

@UseFilters(new ExceptionFilter())
@MessagePattern({ cmd: 'sum' })
accumulate(data: number[]): number {
  return (data || []).reduce((a, b) => a + b);
}
```

```typescript

@UseFilters(new ExceptionFilter())
@MessagePattern({ cmd: 'sum' })
accumulate(data) {
  return (data || []).reduce((a, b) => a + b);
}
```

#### Inheritance[#](/microservices/exception-filters#inheritance)

Typically, you'll create fully customized exception filters crafted to fulfill your application requirements. However, there might be use-cases when you would like to simply extend the **core exception filter**, and override the behavior based on certain factors.

In order to delegate exception processing to the base filter, you need to extend `BaseExceptionFilter` and call the inherited `catch()` method.

JS TS

```typescript

import { Catch, ArgumentsHost } from '@nestjs/common';
import { BaseRpcExceptionFilter } from '@nestjs/microservices';

@Catch()
export class AllExceptionsFilter extends BaseRpcExceptionFilter {
  catch(exception: any, host: ArgumentsHost) {
    return super.catch(exception, host);
  }
}
```

```typescript

import { Catch } from '@nestjs/common';
import { BaseRpcExceptionFilter } from '@nestjs/microservices';

@Catch()
export class AllExceptionsFilter extends BaseRpcExceptionFilter {
  catch(exception, host) {
    return super.catch(exception, host);
  }
}
```

The above implementation is just a shell demonstrating the approach. Your implementation of the extended exception filter would include your tailored **business logic** (e.g., handling various conditions).

----
url: https://docs.nestjs.com/v10/microservices/kafka
----

* [Kafka](https://docs.nestjs.com/v10/microservices/kafka#kafka)
* [Installation](https://docs.nestjs.com/v10/microservices/kafka#installation)
* [Overview](https://docs.nestjs.com/v10/microservices/kafka#overview)
* [Options](https://docs.nestjs.com/v10/microservices/kafka#options)
* [Client](https://docs.nestjs.com/v10/microservices/kafka#client)
* [Message pattern](https://docs.nestjs.com/v10/microservices/kafka#message-pattern)
* [Message response subscription](https://docs.nestjs.com/v10/microservices/kafka#message-response-subscription)
* [Incoming](https://docs.nestjs.com/v10/microservices/kafka#incoming)
* [Outgoing](https://docs.nestjs.com/v10/microservices/kafka#outgoing)
* [Event-based](https://docs.nestjs.com/v10/microservices/kafka#event-based)
* [Context](https://docs.nestjs.com/v10/microservices/kafka#context)
* [Naming conventions](https://docs.nestjs.com/v10/microservices/kafka#naming-conventions)
* [Retriable exceptions](https://docs.nestjs.com/v10/microservices/kafka#retriable-exceptions)
* [Commit offsets](https://docs.nestjs.com/v10/microservices/kafka#commit-offsets)

```bash

$ npm i --save kafkajs
```

#### Overview[#](/microservices/kafka#overview)

Like other Nest microservice transport layer implementations, you select the Kafka transporter mechanism using the `transport` property of the options object passed to the `createMicroservice()` method, along with an optional `options` property, as shown below:

main.ts

JS TS

```typescript

const app = await NestFactory.createMicroservice<MicroserviceOptions>(AppModule, {
  transport: Transport.KAFKA,
  options: {
    client: {
      brokers: ['localhost:9092'],
    }
  }
});
```

```typescript

const app = await NestFactory.createMicroservice(AppModule, {
  transport: Transport.KAFKA,
  options: {
    client: {
      brokers: ['localhost:9092'],
    }
  }
});
```

> **Hint** The `Transport` enum is imported from the `@nestjs/microservices` package.

#### Options[#](/microservices/kafka#options)

The `options` property is specific to the chosen transporter. The **Kafka** transporter exposes the properties described below.

|                    |                                                                                                                 |
| ------------------ | --------------------------------------------------------------------------------------------------------------- |
| `client`           | Client configuration options (read more [here](https://kafka.js.org/docs/configuration))                        |
| `consumer`         | Consumer configuration options (read more [here](https://kafka.js.org/docs/consuming#a-name-options-a-options)) |
| `run`              | Run configuration options (read more [here](https://kafka.js.org/docs/consuming))                               |
| `subscribe`        | Subscribe configuration options (read more [here](https://kafka.js.org/docs/consuming#frombeginning))           |
| `producer`         | Producer configuration options (read more [here](https://kafka.js.org/docs/producing#options))                  |
| `send`             | Send configuration options (read more [here](https://kafka.js.org/docs/producing#options))                      |
| `producerOnlyMode` | Feature flag to skip consumer group registration and only act as a producer (`boolean`)                         |
| `postfixId`        | Change suffix of clientId value (`string`)                                                                      |

#### Client[#](/microservices/kafka#client)

There is a small difference in Kafka compared to other microservice transporters. Instead of the `ClientProxy` class, we use the `ClientKafka` class.

Like other microservice transporters, you have [several options](https://docs.nestjs.com/microservices/basics#client) for creating a `ClientKafka` instance.

One method for creating an instance is to use the `ClientsModule`. To create a client instance with the `ClientsModule`, import it and use the `register()` method to pass an options object with the same properties shown above in the `createMicroservice()` method, as well as a `name` property to be used as the injection token. Read more about `ClientsModule`[here](https://docs.nestjs.com/microservices/basics#client).

```typescript

@Module({
  imports: [
    ClientsModule.register([
      {
        name: 'HERO_SERVICE',
        transport: Transport.KAFKA,
        options: {
          client: {
            clientId: 'hero',
            brokers: ['localhost:9092'],
          },
          consumer: {
            groupId: 'hero-consumer'
          }
        }
      },
    ]),
  ]
  ...
})
```

Other options to create a client (either `ClientProxyFactory` or `@Client()`) can be used as well. You can read about them [here](https://docs.nestjs.com/microservices/basics#client).

Use the `@Client()` decorator as follows:

```typescript

@Client({
  transport: Transport.KAFKA,
  options: {
    client: {
      clientId: 'hero',
      brokers: ['localhost:9092'],
    },
    consumer: {
      groupId: 'hero-consumer'
    }
  }
})
client: ClientKafka;
```

> **Note** This section is only relevant if you use [request-response](/microservices/basics#request-response) message style (with the `@MessagePattern` decorator and the `ClientKafka#send` method). Subscribing to the response topic is not necessary for the [event-based](/microservices/basics#event-based) communication (`@EventPattern` decorator and `ClientKafka#emit` method).

The `ClientKafka` class provides the `subscribeToResponseOf()` method. The `subscribeToResponseOf()` method takes a request's topic name as an argument and adds the derived reply topic name to a collection of reply topics. This method is required when implementing the message pattern.

heroes.controller.ts

JS TS

```typescript

onModuleInit() {
  this.client.subscribeToResponseOf('hero.kill.dragon');
}
```

If the `ClientKafka` instance is created asynchronously, the `subscribeToResponseOf()` method must be called before calling the `connect()` method.

heroes.controller.ts

JS TS

```typescript

async onModuleInit() {
  this.client.subscribeToResponseOf('hero.kill.dragon');
  await this.client.connect();
}
```

#### Incoming[#](/microservices/kafka#incoming)

Nest receives incoming Kafka messages as an object with `key`, `value`, and `headers` properties that have values of type `Buffer`. Nest then parses these values by transforming the buffers into strings. If the string is "object like", Nest attempts to parse the string as `JSON`. The `value` is then passed to its associated handler.

#### Outgoing[#](/microservices/kafka#outgoing)

Nest sends outgoing Kafka messages after a serialization process when publishing events or sending messages. This occurs on arguments passed to the `ClientKafka``emit()` and `send()` methods or on values returned from a `@MessagePattern` method. This serialization "stringifies" objects that are not strings or buffers by using `JSON.stringify()` or the `toString()` prototype method.

heroes.controller.ts

JS TS

```typescript

@Controller()
export class HeroesController {
  @MessagePattern('hero.kill.dragon')
  killDragon(@Payload() message: KillDragonMessage): any {
    const dragonId = message.dragonId;
    const items = [
      { id: 1, name: 'Mythical Sword' },
      { id: 2, name: 'Key to Dungeon' },
    ];
    return items;
  }
}
```

> **Hint**`@Payload()` is imported from the `@nestjs/microservices` package.

Outgoing messages can also be keyed by passing an object with the `key` and `value` properties. Keying messages is important for meeting the [co-partitioning requirement](https://docs.confluent.io/current/ksql/docs/developer-guide/partition-data.html#co-partitioning-requirements).

heroes.controller.ts

JS TS

```typescript

@Controller()
export class HeroesController {
  @MessagePattern('hero.kill.dragon')
  killDragon(@Payload() message: KillDragonMessage): any {
    const realm = 'Nest';
    const heroId = message.heroId;
    const dragonId = message.dragonId;

    const items = [
      { id: 1, name: 'Mythical Sword' },
      { id: 2, name: 'Key to Dungeon' },
    ];

    return {
      headers: {
        realm
      },
      key: heroId,
      value: items
    }
  }
}
```

Additionally, messages passed in this format can also contain custom headers set in the `headers` hash property. Header hash property values must be either of type `string` or type `Buffer`.

heroes.controller.ts

JS TS

```typescript

@Controller()
export class HeroesController {
  @MessagePattern('hero.kill.dragon')
  killDragon(@Payload() message: KillDragonMessage): any {
    const realm = 'Nest';
    const heroId = message.heroId;
    const dragonId = message.dragonId;

    const items = [
      { id: 1, name: 'Mythical Sword' },
      { id: 2, name: 'Key to Dungeon' },
    ];

    return {
      headers: {
        kafka_nestRealm: realm
      },
      key: heroId,
      value: items
    }
  }
}
```

#### Event-based[#](/microservices/kafka#event-based)

While the request-response method is ideal for exchanging messages between services, it is less suitable when your message style is event-based (which in turn is ideal for Kafka) - when you just want to publish events **without waiting for a response**. In that case, you do not want the overhead required by request-response for maintaining two topics.

Check out these two sections to learn more about this: [Overview: Event-based](/microservices/basics#event-based) and [Overview: Publishing events](/microservices/basics#publishing-events).

#### Context[#](/microservices/kafka#context)

In more sophisticated scenarios, you may want to access more information about the incoming request. When using the Kafka transporter, you can access the `KafkaContext` object.

JS TS

```typescript

@MessagePattern('hero.kill.dragon')
killDragon(@Payload() message: KillDragonMessage, @Ctx() context: KafkaContext) {
  console.log(`Topic: ${context.getTopic()}`);
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('hero.kill.dragon')
killDragon(message, context) {
  console.log(`Topic: ${context.getTopic()}`);
}
```

> **Hint**`@Payload()`, `@Ctx()` and `KafkaContext` are imported from the `@nestjs/microservices` package.

To access the original Kafka `IncomingMessage` object, use the `getMessage()` method of the `KafkaContext` object, as follows:

JS TS

```typescript

@MessagePattern('hero.kill.dragon')
killDragon(@Payload() message: KillDragonMessage, @Ctx() context: KafkaContext) {
  const originalMessage = context.getMessage();
  const partition = context.getPartition();
  const { headers, timestamp } = originalMessage;
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('hero.kill.dragon')
killDragon(message, context) {
  const originalMessage = context.getMessage();
  const partition = context.getPartition();
  const { headers, timestamp } = originalMessage;
}
```

Where the `IncomingMessage` fulfills the following interface:

```typescript

interface IncomingMessage {
  topic: string;
  partition: number;
  timestamp: string;
  size: number;
  attributes: number;
  offset: string;
  key: any;
  value: any;
  headers: Record<string, any>;
}
```

If your handler involves a slow processing time for each received message you should consider using the `heartbeat` callback. To retrieve the `heartbeat` function, use the `getHeartbeat()` method of the `KafkaContext`, as follows:

JS TS

```typescript

@MessagePattern('hero.kill.dragon')
async killDragon(@Payload() message: KillDragonMessage, @Ctx() context: KafkaContext) {
  const heartbeat = context.getHeartbeat();

  // Do some slow processing
  await doWorkPart1();

  // Send heartbeat to not exceed the sessionTimeout
  await heartbeat();

  // Do some slow processing again
  await doWorkPart2();
}
```

#### Naming conventions[#](/microservices/kafka#naming-conventions)

The Kafka microservice components append a description of their respective role onto the `client.clientId` and `consumer.groupId` options to prevent collisions between Nest microservice client and server components. By default the `ClientKafka` components append `-client` and the `ServerKafka` components append `-server` to both of these options. Note how the provided values below are transformed in that way (as shown in the comments).

main.ts

JS TS

```typescript

const app = await NestFactory.createMicroservice<MicroserviceOptions>(AppModule, {
  transport: Transport.KAFKA,
  options: {
    client: {
      clientId: 'hero', // hero-server
      brokers: ['localhost:9092'],
    },
    consumer: {
      groupId: 'hero-consumer' // hero-consumer-server
    },
  }
});
```

And for the client:

heroes.controller.ts

JS TS

```typescript

@Client({
  transport: Transport.KAFKA,
  options: {
    client: {
      clientId: 'hero', // hero-client
      brokers: ['localhost:9092'],
    },
    consumer: {
      groupId: 'hero-consumer' // hero-consumer-client
    }
  }
})
client: ClientKafka;
```

> **Hint** Kafka client and consumer naming conventions can be customized by extending `ClientKafka` and `KafkaServer` in your own custom provider and overriding the constructor.

Since the Kafka microservice message pattern utilizes two topics for the request and reply channels, a reply pattern should be derived from the request topic. By default, the name of the reply topic is the composite of the request topic name with `.reply` appended.

heroes.controller.ts

JS TS

```typescript

onModuleInit() {
  this.client.subscribeToResponseOf('hero.get'); // hero.get.reply
}
```

> **Hint** Kafka reply topic naming conventions can be customized by extending `ClientKafka` in your own custom provider and overriding the `getResponsePatternName` method.

#### Retriable exceptions[#](/microservices/kafka#retriable-exceptions)

Similar to other transporters, all unhandled exceptions are automatically wrapped into an `RpcException` and converted to a "user-friendly" format. However, there are edge-cases when you might want to bypass this mechanism and let exceptions be consumed by the `kafkajs` driver instead. Throwing an exception when processing a message instructs `kafkajs` to **retry** it (redeliver it) which means that even though the message (or event) handler was triggered, the offset won't be committed to Kafka.

> **Warning** For event handlers (event-based communication), all unhandled exceptions are considered **retriable exceptions** by default.

For this, you can use a dedicated class called `KafkaRetriableException`, as follows:

```typescript

throw new KafkaRetriableException('...');
```

> **Hint**`KafkaRetriableException` class is exported from the `@nestjs/microservices` package.

#### Commit offsets[#](/microservices/kafka#commit-offsets)

Committing offsets is essential when working with Kafka. Per default, messages will be automatically committed after a specific time. For more information visit [KafkaJS docs](https://kafka.js.org/docs/consuming#autocommit). `KafkaContext` offers a way to access the active consumer for manually committing offsets. The consumer is the KafkaJS consumer and works as the [native KafkaJS implementation](https://kafka.js.org/docs/consuming#manual-committing).

JS TS

```typescript

@EventPattern('user.created')
async handleUserCreated(@Payload() data: IncomingMessage, @Ctx() context: KafkaContext) {
  // business logic
  
  const { offset } = context.getMessage();
  const partition = context.getPartition();
  const topic = context.getTopic();
  const consumer = context.getConsumer();
  await consumer.commitOffsets([{ topic, partition, offset }])
}
```

```typescript

@Bind(Payload(), Ctx())
@EventPattern('user.created')
async handleUserCreated(data, context) {
  // business logic

  const { offset } = context.getMessage();
  const partition = context.getPartition();
  const topic = context.getTopic();
  const consumer = context.getConsumer();
  await consumer.commitOffsets([{ topic, partition, offset }])
}
```

To disable auto-committing of messages set `autoCommit: false` in the `run` configuration, as follows:

main.ts

JS TS

```typescript

const app = await NestFactory.createMicroservice<MicroserviceOptions>(AppModule, {
  transport: Transport.KAFKA,
  options: {
    client: {
      brokers: ['localhost:9092'],
    },
    run: {
      autoCommit: false
    }
  }
});
```

```typescript

const app = await NestFactory.createMicroservice(AppModule, {
  transport: Transport.KAFKA,
  options: {
    client: {
      brokers: ['localhost:9092'],
    },
    run: {
      autoCommit: false
    }
  }
});
```

----
url: https://docs.nestjs.com/v10/faq/global-prefix
----

* [Global prefix](https://docs.nestjs.com/v10/faq/global-prefix#global-prefix)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/faq/global-prefix.md "Suggest Edits")

### Global prefix

To set a prefix for **every route** registered in an HTTP application, use the `setGlobalPrefix()` method of the `INestApplication` instance.

```typescript

const app = await NestFactory.create(AppModule);
app.setGlobalPrefix('v1');
```

You can exclude routes from the global prefix using the following construction:

```typescript

app.setGlobalPrefix('v1', {
  exclude: [{ path: 'health', method: RequestMethod.GET }],
});
```

Alternatively, you can specify route as a string (it will apply to every request method):

```typescript

app.setGlobalPrefix('v1', { exclude: ['cats'] });
```

> **Hint** The `path` property supports wildcard parameters using the [path-to-regexp](https://github.com/pillarjs/path-to-regexp#parameters) package. Note: this does not accept wildcard asterisks `*`. Instead, you must use parameters (e.g., `(.*)`, `:splat*`).

----
url: https://docs.nestjs.com/v8/microservices/grpc
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [gRPC](https://docs.nestjs.com/v8/microservices/grpc#grpc)
* [Installation](https://docs.nestjs.com/v8/microservices/grpc#installation)
* [Overview](https://docs.nestjs.com/v8/microservices/grpc#overview)
* [Options](https://docs.nestjs.com/v8/microservices/grpc#options)
* [Sample gRPC service](https://docs.nestjs.com/v8/microservices/grpc#sample-grpc-service)
* [Client](https://docs.nestjs.com/v8/microservices/grpc#client)
* [Example](https://docs.nestjs.com/v8/microservices/grpc#example)
* [gRPC Streaming](https://docs.nestjs.com/v8/microservices/grpc#grpc-streaming)
* [Streaming sample](https://docs.nestjs.com/v8/microservices/grpc#streaming-sample)
* [Subject strategy](https://docs.nestjs.com/v8/microservices/grpc#subject-strategy)
* [Call stream handler](https://docs.nestjs.com/v8/microservices/grpc#call-stream-handler)
* [gRPC Metadata](https://docs.nestjs.com/v8/microservices/grpc#grpc-metadata)

```bash

$ npm i --save @grpc/grpc-js @grpc/proto-loader
```

#### Overview[#](/microservices/grpc#overview)

Like other Nest microservices transport layer implementations, you select the gRPC transporter mechanism using the `transport` property of the options object passed to the `createMicroservice()` method. In the following example, we'll set up a hero service. The `options` property provides metadata about that service; its properties are described [below](microservices/grpc#options).

main.ts

JS TS

```typescript

const app = await NestFactory.createMicroservice<MicroserviceOptions>(AppModule, {
  transport: Transport.GRPC,
  options: {
    package: 'hero',
    protoPath: join(__dirname, 'hero/hero.proto'),
  },
});
```

```typescript

const app = await NestFactory.createMicroservice(AppModule, {
  transport: Transport.GRPC,
  options: {
    package: 'hero',
    protoPath: join(__dirname, 'hero/hero.proto'),
  },
});
```

> **Hint** The `join()` function is imported from the `path` package; the `Transport` enum is imported from the `@nestjs/microservices` package.

In the `nest-cli.json` file, we add the `assets` property that allows us to distribute non-TypeScript files, and `watchAssets` - to turn on watching all non-TypeScript assets. In our case, we want `.proto` files to be automatically copied to the `dist` folder.

```json

{
  "compilerOptions": {
    "assets": ["**/*.proto"],
    "watchAssets": true
  }
}
```

#### Options[#](/microservices/grpc#options)

The **gRPC** transporter options object exposes the properties described below.

|               |                                                                                                                                                                                                                          |
| ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `package`     | Protobuf package name (matches `package` setting from `.proto` file). Required                                                                                                                                           |
| `protoPath`   | Absolute (or relative to the root dir) path to the `.proto` file. Required                                                                                                                                               |
| `url`         | Connection url. String in the format `ip address/dns name:port` (for example, `'localhost:50051'`) defining the address/port on which the transporter establishes a connection. Optional. Defaults to `'localhost:5000'` |
| `protoLoader` | NPM package name for the utility to load `.proto` files. Optional. Defaults to `'@grpc/proto-loader'`                                                                                                                    |
| `loader`      | `@grpc/proto-loader` options. These provide detailed control over the behavior of `.proto` files. Optional. See [here](https://github.com/grpc/grpc-node/blob/master/packages/proto-loader/README.md) for more details   |
| `credentials` | Server credentials. Optional. [Read more here](https://grpc.io/grpc/node/grpc.ServerCredentials.html)                                                                                                                    |

#### Sample gRPC service[#](/microservices/grpc#sample-grpc-service)

Let's define our sample gRPC service called `HeroesService`. In the above `options` object, the`protoPath` property sets a path to the `.proto` definitions file `hero.proto`. The `hero.proto` file is structured using [protocol buffers](https://developers.google.com/protocol-buffers). Here's what it looks like:

```typescript

// hero/hero.proto
syntax = "proto3";

package hero;

service HeroesService {
  rpc FindOne (HeroById) returns (Hero) {}
}

message HeroById {
  int32 id = 1;
}

message Hero {
  int32 id = 1;
  string name = 2;
}
```

Our `HeroesService` exposes a `FindOne()` method. This method expects an input argument of type `HeroById` and returns a `Hero` message (protocol buffers use `message` elements to define both parameter types and return types).

Next, we need to implement the service. To define a handler that fulfills this definition, we use the `@GrpcMethod()` decorator in a controller, as shown below. This decorator provides the metadata needed to declare a method as a gRPC service method.

> **Hint** The `@MessagePattern()` decorator ([read more](microservices/basics#request-response)) introduced in previous microservices chapters is not used with gRPC-based microservices. The `@GrpcMethod()` decorator effectively takes its place for gRPC-based microservices.

heroes.controller.ts

JS TS

```typescript

@Controller()
export class HeroesController {
  @GrpcMethod('HeroesService', 'FindOne')
  findOne(data: HeroById, metadata: Metadata, call: ServerUnaryCall<any, any>): Hero {
    const items = [
      { id: 1, name: 'John' },
      { id: 2, name: 'Doe' },
    ];
    return items.find(({ id }) => id === data.id);
  }
}
```

```typescript

@Controller()
export class HeroesController {
  @GrpcMethod('HeroesService', 'FindOne')
  findOne(data, metadata, call) {
    const items = [
      { id: 1, name: 'John' },
      { id: 2, name: 'Doe' },
    ];
    return items.find(({ id }) => id === data.id);
  }
}
```

> **Hint** The `@GrpcMethod()` decorator is imported from the `@nestjs/microservices` package, while `Metadata` and `ServerUnaryCall` from the `grpc` package.

The decorator shown above takes two arguments. The first is the service name (e.g., `'HeroesService'`), corresponding to the `HeroesService` service definition in `hero.proto`. The second (the string `'FindOne'`) corresponds to the `FindOne()` rpc method defined within `HeroesService` in the `hero.proto` file.

The `findOne()` handler method takes three arguments, the `data` passed from the caller, `metadata` that stores gRPC request metadata and `call` to obtain the `GrpcCall` object properties such as `sendMetadata` for send metadata to client.

Both `@GrpcMethod()` decorator arguments are optional. If called without the second argument (e.g., `'FindOne'`), Nest will automatically associate the `.proto` file rpc method with the handler based on converting the handler name to upper camel case (e.g., the `findOne` handler is associated with the `FindOne` rpc call definition). This is shown below.

heroes.controller.ts

JS TS

```typescript

@Controller()
export class HeroesController {
  @GrpcMethod('HeroesService')
  findOne(data: HeroById, metadata: Metadata, call: ServerUnaryCall<any, any>): Hero {
    const items = [
      { id: 1, name: 'John' },
      { id: 2, name: 'Doe' },
    ];
    return items.find(({ id }) => id === data.id);
  }
}
```

```typescript

@Controller()
export class HeroesController {
  @GrpcMethod('HeroesService')
  findOne(data, metadata, call) {
    const items = [
      { id: 1, name: 'John' },
      { id: 2, name: 'Doe' },
    ];
    return items.find(({ id }) => id === data.id);
  }
}
```

You can also omit the first `@GrpcMethod()` argument. In this case, Nest automatically associates the handler with the service definition from the proto definitions file based on the **class** name where the handler is defined. For example, in the following code, class `HeroesService` associates its handler methods with the `HeroesService` service definition in the `hero.proto` file based on the matching of the name `'HeroesService'`.

heroes.controller.ts

JS TS

```typescript

@Controller()
export class HeroesService {
  @GrpcMethod()
  findOne(data: HeroById, metadata: Metadata, call: ServerUnaryCall<any, any>): Hero {
    const items = [
      { id: 1, name: 'John' },
      { id: 2, name: 'Doe' },
    ];
    return items.find(({ id }) => id === data.id);
  }
}
```

```typescript

@Controller()
export class HeroesService {
  @GrpcMethod()
  findOne(data, metadata, call) {
    const items = [
      { id: 1, name: 'John' },
      { id: 2, name: 'Doe' },
    ];
    return items.find(({ id }) => id === data.id);
  }
}
```

#### Client[#](/microservices/grpc#client)

Nest applications can act as gRPC clients, consuming services defined in `.proto` files. You access remote services through a `ClientGrpc` object. You can obtain a `ClientGrpc` object in several ways.

The preferred technique is to import the `ClientsModule`. Use the `register()` method to bind a package of services defined in a `.proto` file to an injection token, and to configure the service. The `name` property is the injection token. For gRPC services, use `transport: Transport.GRPC`. The `options` property is an object with the same properties described [above](microservices/grpc#options).

```typescript

imports: [
  ClientsModule.register([
    {
      name: 'HERO_PACKAGE',
      transport: Transport.GRPC,
      options: {
        package: 'hero',
        protoPath: join(__dirname, 'hero/hero.proto'),
      },
    },
  ]),
];
```

> **Hint** The `register()` method takes an array of objects. Register multiple packages by providing a comma separated list of registration objects.

Once registered, we can inject the configured `ClientGrpc` object with `@Inject()`. Then we use the `ClientGrpc` object's `getService()` method to retrieve the service instance, as shown below.

```typescript

@Injectable()
export class AppService implements OnModuleInit {
  private heroesService: HeroesService;

  constructor(@Inject('HERO_PACKAGE') private client: ClientGrpc) {}

  onModuleInit() {
    this.heroesService = this.client.getService<HeroesService>('HeroesService');
  }

  getHero(): Observable<string> {
    return this.heroesService.findOne({ id: 1 });
  }
}
```

> **Warning** gRPC Client will not send fields that contain underscore `_` in their names unless the `keepCase` options is set to `true` in the proto loader configuration (`options.loader.keepcase` in the microservice transporter configuration).

Notice that there is a small difference compared to the technique used in other microservice transport methods. Instead of the `ClientProxy` class, we use the `ClientGrpc` class, which provides the `getService()` method. The `getService()` generic method takes a service name as an argument and returns its instance (if available).

Alternatively, you can use the `@Client()` decorator to instantiate a `ClientGrpc` object, as follows:

```typescript

@Injectable()
export class AppService implements OnModuleInit {
  @Client({
    transport: Transport.GRPC,
    options: {
      package: 'hero',
      protoPath: join(__dirname, 'hero/hero.proto'),
    },
  })
  client: ClientGrpc;

  private heroesService: HeroesService;

  onModuleInit() {
    this.heroesService = this.client.getService<HeroesService>('HeroesService');
  }

  getHero(): Observable<string> {
    return this.heroesService.findOne({ id: 1 });
  }
}
```

Finally, for more complex scenarios, we can inject a dynamically configured client using the `ClientProxyFactory` class as described [here](/microservices/basics#client).

In either case, we end up with a reference to our `HeroesService` proxy object, which exposes the same set of methods that are defined inside the `.proto` file. Now, when we access this proxy object (i.e., `heroesService`), the gRPC system automatically serializes requests, forwards them to the remote system, returns a response, and deserializes the response. Because gRPC shields us from these network communication details, `heroesService` looks and acts like a local provider.

Note, all service methods are **lower camel cased** (in order to follow the natural convention of the language). So, for example, while our `.proto` file `HeroesService` definition contains the `FindOne()` function, the `heroesService` instance will provide the `findOne()` method.

```typescript

interface HeroesService {
  findOne(data: { id: number }): Observable<any>;
}
```

A message handler is also able to return an `Observable`, in which case the result values will be emitted until the stream is completed.

heroes.controller.ts

JS TS

```typescript

@Get()
call(): Observable<any> {
  return this.heroesService.findOne({ id: 1 });
}
```

```typescript

@Get()
call() {
  return this.heroesService.findOne({ id: 1 });
}
```

To send gRPC metadata (along with the request), you can pass a second argument, as follows:

```typescript

call(): Observable<any> {
  const metadata = new Metadata();
  metadata.add('Set-Cookie', 'yummy_cookie=choco');

  return this.heroesService.findOne({ id: 1 }, metadata);
}
```

> **Hint** The `Metadata` class is imported from the `grpc` package.

Please note that this would require updating the `HeroesService` interface that we've defined a few steps earlier.

#### Example[#](/microservices/grpc#example)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/04-grpc).

```typescript

// hello/hello.proto
syntax = "proto3";

package hello;

service HelloService {
  rpc BidiHello(stream HelloRequest) returns (stream HelloResponse);
  rpc LotsOfGreetings(stream HelloRequest) returns (HelloResponse);
}

message HelloRequest {
  string greeting = 1;
}

message HelloResponse {
  string reply = 1;
}
```

> **Hint** The `LotsOfGreetings` method can be simply implemented with the `@GrpcMethod` decorator (as in the examples above) since the returned stream can emit multiple values.

Based on this `.proto` file, let's define the `HelloService` interface:

```typescript

interface HelloService {
  bidiHello(upstream: Observable<HelloRequest>): Observable<HelloResponse>;
  lotsOfGreetings(
    upstream: Observable<HelloRequest>,
  ): Observable<HelloResponse>;
}

interface HelloRequest {
  greeting: string;
}

interface HelloResponse {
  reply: string;
}
```

> **Hint** The proto interface can be automatically generated by the [ts-proto](https://github.com/stephenh/ts-proto) package, learn more [here](https://github.com/stephenh/ts-proto/blob/main/NESTJS.markdown).

#### Subject strategy[#](/microservices/grpc#subject-strategy)

The `@GrpcStreamMethod()` decorator provides the function parameter as an RxJS `Observable`. Thus, we can receive and process multiple messages.

```typescript

@GrpcStreamMethod()
bidiHello(messages: Observable<any>, metadata: Metadata, call: ServerDuplexStream<any, any>): Observable<any> {
  const subject = new Subject();

  const onNext = message => {
    console.log(message);
    subject.next({
      reply: 'Hello, world!'
    });
  };
  const onComplete = () => subject.complete();
  messages.subscribe({
    next: onNext,
    complete: onComplete,
  });


  return subject.asObservable();
}
```

> **Warning** For supporting full-duplex interaction with the `@GrpcStreamMethod()` decorator, the controller method must return an RxJS `Observable`.

> **Hint** The `Metadata` and `ServerUnaryCall` classes/interfaces are imported from the `grpc` package.

According to the service definition (in the `.proto` file), the `BidiHello` method should stream requests to the service. To send multiple asynchronous messages to the stream from a client, we leverage an RxJS `ReplaySubject` class.

```typescript

const helloService = this.client.getService<HelloService>('HelloService');
const helloRequest$ = new ReplaySubject<HelloRequest>();

helloRequest$.next({ greeting: 'Hello (1)!' });
helloRequest$.next({ greeting: 'Hello (2)!' });
helloRequest$.complete();

return helloService.bidiHello(helloRequest$);
```

In the example above, we wrote two messages to the stream (`next()` calls) and notified the service that we've completed sending the data (`complete()` call).

#### Call stream handler[#](/microservices/grpc#call-stream-handler)

When the method return value is defined as `stream`, the `@GrpcStreamCall()` decorator provides the function parameter as `grpc.ServerDuplexStream`, which supports standard methods like `.on('data', callback)`, `.write(message)` or `.cancel()`. Full documentation on available methods can be found [here](https://grpc.github.io/grpc/node/grpc-ClientDuplexStream.html).

Alternatively, when the method return value is not a `stream`, the `@GrpcStreamCall()` decorator provides two function parameters, respectively `grpc.ServerReadableStream` (read more [here](https://grpc.github.io/grpc/node/grpc-ServerReadableStream.html)) and `callback`.

Let's start with implementing the `BidiHello` which should support a full-duplex interaction.

```typescript

@GrpcStreamCall()
bidiHello(requestStream: any) {
  requestStream.on('data', message => {
    console.log(message);
    requestStream.write({
      reply: 'Hello, world!'
    });
  });
}
```

> **Hint** This decorator does not require any specific return parameter to be provided. It is expected that the stream will be handled similar to any other standard stream type.

In the example above, we used the `write()` method to write objects to the response stream. The callback passed into the `.on()` method as a second parameter will be called every time our service receives a new chunk of data.

Let's implement the `LotsOfGreetings` method.

```typescript

@GrpcStreamCall()
lotsOfGreetings(requestStream: any, callback: (err: unknown, value: HelloResponse) => void) {
  requestStream.on('data', message => {
    console.log(message);
  });
  requestStream.on('end', () => callback(null, { reply: 'Hello, world!' }));
}
```

```typescript

@Controller()
export class HeroesService {
  @GrpcMethod()
  findOne(data: HeroById, metadata: Metadata, call: ServerUnaryCall<any, any>): Hero {
    const serverMetadata = new Metadata();
    const items = [
      { id: 1, name: 'John' },
      { id: 2, name: 'Doe' },
    ];

    serverMetadata.add('Set-Cookie', 'yummy_cookie=choco');
    call.sendMetadata(serverMetadata);

    return items.find(({ id }) => id === data.id);
  }
}
```

```typescript

@Controller()
export class HeroesService {
  @GrpcMethod()
  findOne(data, metadata, call) {
    const serverMetadata = new Metadata();
    const items = [
      { id: 1, name: 'John' },
      { id: 2, name: 'Doe' },
    ];

    serverMetadata.add('Set-Cookie', 'yummy_cookie=choco');
    call.sendMetadata(serverMetadata);

    return items.find(({ id }) => id === data.id);
  }
}
```

Likewise, to read the metadata in handlers annotated with the `@GrpcStreamMethod()` handler ([subject strategy](microservices/grpc#subject-strategy)), use the second argument (metadata), which is of type `Metadata` (imported from the `grpc` package).

To send back metadata from the handler, use the `ServerDuplexStream#sendMetadata()` method (third handler argument).

To read metadata from within the [call stream handlers](microservices/grpc#call-stream-handler) (handlers annotated with `@GrpcStreamCall()` decorator), listen to the `metadata` event on the `requestStream` reference, as follows:

```typescript

requestStream.on('metadata', (metadata: Metadata) => {
  const meta = metadata.get('X-Meta');
});
```

----
url: https://docs.nestjs.com/v6/custom-decorators
----

* [Custom route decorators](https://docs.nestjs.com/v6/custom-decorators#custom-route-decorators)
* [Param decorators](https://docs.nestjs.com/v6/custom-decorators#param-decorators)
* [Passing data](https://docs.nestjs.com/v6/custom-decorators#passing-data)
* [Working with pipes](https://docs.nestjs.com/v6/custom-decorators#working-with-pipes)
* [Decorator composition](https://docs.nestjs.com/v6/custom-decorators#decorator-composition)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/custom-decorators.md "Suggest Edits")

### Custom route decorators

Nest is built around a language feature called **decorators**. Decorators are a well-known concept in a lot of commonly used programming languages, but in the JavaScript world, they're still relatively new. In order to better understand how decorators work, we recommend reading [this article](https://medium.com/google-developers/exploring-es7-decorators-76ecb65fb841). Here's a simple definition:

> An ES2016 decorator is an expression which returns a function and can take a target, name and property descriptor as arguments. You apply it by prefixing the decorator with an `@` character and placing this at the very top of what you are trying to decorate. Decorators can be defined for either a class or a property.

#### Param decorators[#](/custom-decorators#param-decorators)

Nest provides a set of useful **param decorators** that you can use together with the HTTP route handlers. Below is a list of the provided decorators and the plain Express (or Fastify) objects they represent

|                            |                                      |
| -------------------------- | ------------------------------------ |
| `@Request()`               | `req`                                |
| `@Response()`              | `res`                                |
| `@Next()`                  | `next`                               |
| `@Session()`               | `req.session`                        |
| `@Param(param?: string)`   | `req.params` / `req.params[param]`   |
| `@Body(param?: string)`    | `req.body` / `req.body[param]`       |
| `@Query(param?: string)`   | `req.query` / `req.query[param]`     |
| `@Headers(param?: string)` | `req.headers` / `req.headers[param]` |
| `@Ip()`                    | `req.ip`                             |

Additionally, you can create your own **custom decorators**. Why is this useful?

In the node.js world, it's common practice to attach properties to the **request** object. Then you manually extract them in each route handler, using code like the following:

```typescript

const user = req.user;
```

In order to make your code more readable and transparent, you can create a `@User()` decorator and reuse it across all of your controllers.

user.decorator.ts

JS TS

```typescript

import { createParamDecorator } from '@nestjs/common';

export const User = createParamDecorator((data, req) => {
  return req.user;
});
```

Then, you can simply use it wherever it fits your requirements.

JS TS

```typescript

@Get()
async findOne(@User() user: UserEntity) {
  console.log(user);
}
```

```typescript

@Get()
@Bind(User())
async findOne(user) {
  console.log(user);
}
```

#### Passing data[#](/custom-decorators#passing-data)

When the behavior of your decorator depends on some conditions, you can use the `data` parameter to pass an argument to the decorator's factory function. One use case for this is a custom decorator that extracts properties from the request object by key. Let's assume, for example, that our [authentication layer](techniques/authentication#implementing-passport-strategies) validates requests and attaches a user entity to the request object. The user entity for an authenticated request might look like:

```json

{
  "id": 101,
  "firstName": "Alan",
  "lastName": "Turing",
  "email": "alan@email.com",
  "roles": ["admin"]
}
```

Let's define a decorator that takes a property name as key, and returns the associated value if it exists (or undefined if it doesn't exist, or if the `user` object has not been created).

user.decorator.ts

JS TS

```typescript

import { createParamDecorator } from '@nestjs/common';

export const User = createParamDecorator((data: string, req) => {
  return data ? req.user && req.user[data] : req.user;
});
```

```typescript

import { createParamDecorator } from '@nestjs/common';

export const User = createParamDecorator((data, req) => {
  return data ? req.user && req.user[data] : req.user;
});
```

Here's how you could then access a particular property via the `@User()` decorator in the controller:

JS TS

```typescript

@Get()
async findOne(@User('firstName') firstName: string) {
  console.log(`Hello ${firstName}`);
}
```

```typescript

@Get()
@Bind(User('firstName'))
async findOne(firstName) {
  console.log(`Hello ${firstName}`);
}
```

You can use this same decorator with different keys to access different properties. If the `user` object is deep or complex, this can make for easier and more readable request handler implementations.

> **Hint** For TypeScript users, note that `createParamDecorator<T>()` is a generic. This means you can explicitly enforce type safety, for example `createParamDecorator<string>((data, req) => ...)`. Alternatively, specify a parameter type in the factory function, for example `createParamDecorator((data: string, req) => ...)`. If you omit both, the type for `data` will be `any`.

#### Working with pipes[#](/custom-decorators#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:

JS TS

```typescript

@Get()
async findOne(@User(new ValidationPipe()) user: UserEntity) {
  console.log(user);
}
```

```typescript

@Get()
@Bind(User(new ValidationPipe()))
async findOne(user) {
  console.log(user);
}
```

#### Decorator composition[#](/custom-decorators#decorator-composition)

Nest provides a helper method to compose multiple decorators. For example, suppose you want to combine all decorators related to authentication into a single decorator. This could be done with the following construction:

```typescript

import { applyDecorators } from '@nestjs/common';

export function Auth(...roles: Role[]) {
  return applyDecorators(
    SetMetadata('roles', roles),
    UseGuards(AuthGuard, RolesGuard),
    ApiBearerAuth(),
    ApiUnauthorizedResponse({ description: 'Unauthorized"' }),
  );
}
```

You can then use this custom `@Auth()` decorator as follows:

```typescript

@Get('users')
@Auth('admin')
findAllUsers() {}
```

This has the effect of applying all four decorators with a single declaration.

> **Warning** The `@ApiHideProperty()` decorator from the `@nestjs/swagger` package is not composable and won't work properly with the `applyDecorators` function.

----
url: https://docs.nestjs.com/v10/fundamentals/circular-dependency
----

* [Circular dependency](https://docs.nestjs.com/v10/fundamentals/circular-dependency#circular-dependency)
* [Forward reference](https://docs.nestjs.com/v10/fundamentals/circular-dependency#forward-reference)
* [ModuleRef class alternative](https://docs.nestjs.com/v10/fundamentals/circular-dependency#moduleref-class-alternative)
* [Module forward reference](https://docs.nestjs.com/v10/fundamentals/circular-dependency#module-forward-reference)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/fundamentals/circular-dependency.md "Suggest Edits")

### Circular dependency

A circular dependency occurs when two classes depend on each other. For example, class A needs class B, and class B also needs class A. Circular dependencies can arise in Nest between modules and between providers.

While circular dependencies should be avoided where possible, you can't always do so. In such cases, Nest enables resolving circular dependencies between providers in two ways. In this chapter, we describe using **forward referencing** as one technique, and using the **ModuleRef** class to retrieve a provider instance from the DI container as another.

We also describe resolving circular dependencies between modules.

> **Warning** A circular dependency might also be caused when using "barrel files"/index.ts files to group imports. Barrel files should be omitted when it comes to module/provider classes. For example, barrel files should not be used when importing files within the same directory as the barrel file, i.e. `cats/cats.controller` should not import `cats` to import the `cats/cats.service` file. For more details please also see [this github issue](https://github.com/nestjs/nest/issues/1181#issuecomment-430197191).

#### Forward reference[#](/fundamentals/circular-dependency#forward-reference)

A **forward reference** allows Nest to reference classes which aren't yet defined using the `forwardRef()` utility function. For example, if `CatsService` and `CommonService` depend on each other, both sides of the relationship can use `@Inject()` and the `forwardRef()` utility to resolve the circular dependency. Otherwise Nest won't instantiate them because all of the essential metadata won't be available. Here's an example:

cats.service.ts

JS TS

```typescript

@Injectable()
export class CatsService {
  constructor(
    @Inject(forwardRef(() => CommonService))
    private commonService: CommonService,
  ) {}
}
```

```typescript

@Injectable()
@Dependencies(forwardRef(() => CommonService))
export class CatsService {
  constructor(commonService) {
    this.commonService = commonService;
  }
}
```

> **Hint** The `forwardRef()` function is imported from the `@nestjs/common` package.

That covers one side of the relationship. Now let's do the same with `CommonService`:

common.service.ts

JS TS

```typescript

@Injectable()
export class CommonService {
  constructor(
    @Inject(forwardRef(() => CatsService))
    private catsService: CatsService,
  ) {}
}
```

```typescript

@Injectable()
@Dependencies(forwardRef(() => CatsService))
export class CommonService {
  constructor(catsService) {
    this.catsService = catsService;
  }
}
```

> **Warning** The order of instantiation is indeterminate. Make sure your code does not depend on which constructor is called first. Having circular dependencies depend on providers with `Scope.REQUEST` can lead to undefined dependencies. More information available [here](https://github.com/nestjs/nest/issues/5778)

#### ModuleRef class alternative[#](/fundamentals/circular-dependency#moduleref-class-alternative)

An alternative to using `forwardRef()` is to refactor your code and use the `ModuleRef` class to retrieve a provider on one side of the (otherwise) circular relationship. Learn more about the `ModuleRef` utility class [here](/v10/fundamentals/module-ref).

#### Module forward reference[#](/fundamentals/circular-dependency#module-forward-reference)

In order to resolve circular dependencies between modules, use the same `forwardRef()` utility function on both sides of the modules association. For example:

common.module.ts

JS TS

```typescript

@Module({
  imports: [forwardRef(() => CatsModule)],
})
export class CommonModule {}
```

That covers one side of the relationship. Now let's do the same with `CatsModule`:

cats.module.ts

JS TS

```typescript

@Module({
  imports: [forwardRef(() => CommonModule)],
})
export class CatsModule {}
```

----
url: https://docs.nestjs.com/graphql/scalars
----

[Skip to content](#content)

On this page

* [Scalars](https://docs.nestjs.com/graphql/scalars#scalars)
* [Code first](https://docs.nestjs.com/graphql/scalars#code-first)
* [Override a default scalar](https://docs.nestjs.com/graphql/scalars#override-a-default-scalar)
* [Import a custom scalar](https://docs.nestjs.com/graphql/scalars#import-a-custom-scalar)
* [Create a custom scalar](https://docs.nestjs.com/graphql/scalars#create-a-custom-scalar)
* [Schema first](https://docs.nestjs.com/graphql/scalars#schema-first)

### Scalars

A GraphQL object type has a name and fields, but at some point those fields have to resolve to some concrete data. Scalar types provide that data: they represent the leaves of the query (see [scalar types](https://graphql.org/learn/schema/#scalar-types) in the GraphQL documentation). GraphQL includes the following built-in scalar types: `Int`, `Float`, `String`, `Boolean`, and `ID`. In addition to these, you may need to support custom atomic data types (e.g., `Date`).

#### Code first[#](/graphql/scalars#code-first)

The code first approach ships with five scalars, three of which are aliases for the existing GraphQL types:

* `ID` (alias for `GraphQLID`): a unique identifier, often used to refetch an object or as the key for a cache
* `Int` (alias for `GraphQLInt`): a signed 32-bit integer
* `Float` (alias for `GraphQLFloat`): a signed double-precision floating-point value
* `GraphQLISODateTime`: a date-time string in UTC (used by default to represent the `Date` type)
* `GraphQLTimestamp`: a signed integer that represents a date and time as the number of milliseconds since the start of the Unix epoch

By default, `GraphQLISODateTime` (e.g., `2019-12-03T09:54:33Z`) represents the `Date` type. To use `GraphQLTimestamp` instead, set the `dateScalarMode` property of the `buildSchemaOptions` object to `'timestamp'`:

```typescript

GraphQLModule.forRoot({
  buildSchemaOptions: {
    dateScalarMode: 'timestamp',
  }
}),
```

Likewise, `GraphQLFloat` represents the `number` type by default. To use `GraphQLInt` instead, set the `numberScalarMode` property of the `buildSchemaOptions` object to `'integer'`:

```typescript

GraphQLModule.forRoot({
  buildSchemaOptions: {
    numberScalarMode: 'integer',
  }
}),
```

You can also create custom scalars.

#### Override a default scalar[#](/graphql/scalars#override-a-default-scalar)

To create a custom implementation of the `Date` scalar, create a new class:

```typescript

import { Scalar, CustomScalar } from '@nestjs/graphql';
import { Kind, ValueNode } from 'graphql';

@Scalar('Date', () => Date)
export class DateScalar implements CustomScalar<number, Date> {
  description = 'Date custom scalar type';

  parseValue(value: unknown): Date {
    return new Date(value as number); // value from the client
  }

  serialize(value: unknown): number {
    return (value as Date).getTime(); // value sent to the client
  }

  parseLiteral(ast: ValueNode): Date | null {
    if (ast.kind === Kind.INT) {
      return new Date(parseInt(ast.value, 10));
    }
    return null;
  }
}
```

With this in place, register `DateScalar` as a provider:

```typescript

@Module({
  providers: [DateScalar],
})
export class CommonModule {}
```

Now you can use the `Date` type in your classes:

```typescript

@Field()
creationDate: Date;
```

#### Import a custom scalar[#](/graphql/scalars#import-a-custom-scalar)

To use a custom scalar, import it and register it as a resolver. For demonstration purposes, we'll use the `graphql-type-json` package, which defines a `JSON` GraphQL scalar type.

Start by installing the package:

```bash

$ npm i --save graphql-type-json
```

Once the package is installed, pass a custom resolver to the `forRoot()` method:

```typescript

import GraphQLJSON from 'graphql-type-json';

@Module({
  imports: [
    GraphQLModule.forRoot({
      resolvers: { JSON: GraphQLJSON },
    }),
  ],
})
export class AppModule {}
```

Now you can use the `JSON` type in your classes:

```typescript

@Field(() => GraphQLJSON)
info: JSON;
```

For a suite of ready-made scalars, see the [graphql-scalars](https://www.npmjs.com/package/graphql-scalars) package.

#### Create a custom scalar[#](/graphql/scalars#create-a-custom-scalar)

To define a custom scalar, create a new `GraphQLScalarType` instance. The following example creates a custom `UUID` scalar:

```typescript

import { GraphQLScalarType, Kind } from 'graphql';

const regex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;

function validate(uuid: unknown): string | never {
  if (typeof uuid !== 'string' || !regex.test(uuid)) {
    throw new Error('invalid uuid');
  }
  return uuid;
}

export const CustomUuidScalar = new GraphQLScalarType({
  name: 'UUID',
  description: 'A simple UUID parser',
  serialize: (value) => validate(value),
  parseValue: (value) => validate(value),
  parseLiteral: (ast) =>
    validate(ast.kind === Kind.STRING ? ast.value : undefined),
});
```

Then pass a custom resolver to the `forRoot()` method:

```typescript

@Module({
  imports: [
    GraphQLModule.forRoot({
      resolvers: { UUID: CustomUuidScalar },
    }),
  ],
})
export class AppModule {}
```

Now you can use the `UUID` type in your classes:

```typescript

@Field(() => CustomUuidScalar)
uuid: string;
```

#### Schema first[#](/graphql/scalars#schema-first)

To define a custom scalar (see [custom scalars](https://www.apollographql.com/docs/graphql-tools/scalars.html) in the GraphQL Tools documentation), create a type definition and a dedicated resolver. As in the official documentation, we'll use the `graphql-type-json` package, which defines a `JSON` GraphQL scalar type.

Start by installing the package:

```bash

$ npm i --save graphql-type-json
```

Once the package is installed, pass a custom resolver to the `forRoot()` method:

```typescript

import GraphQLJSON from 'graphql-type-json';

@Module({
  imports: [
    GraphQLModule.forRoot({
      typePaths: ['./**/*.graphql'],
      resolvers: { JSON: GraphQLJSON },
    }),
  ],
})
export class AppModule {}
```

Now we can use the `JSON` scalar in our type definitions:

```graphql

scalar JSON

type Foo {
  field: JSON
}
```

Another way to define a scalar type is to create a class. Suppose you want to add a `Date` type to your schema:

```typescript

import { Scalar, CustomScalar } from '@nestjs/graphql';
import { Kind, ValueNode } from 'graphql';

@Scalar('Date')
export class DateScalar implements CustomScalar<number, Date> {
  description = 'Date custom scalar type';

  parseValue(value: unknown): Date {
    return new Date(value as number); // value from the client
  }

  serialize(value: unknown): number {
    return (value as Date).getTime(); // value sent to the client
  }

  parseLiteral(ast: ValueNode): Date | null {
    if (ast.kind === Kind.INT) {
      return new Date(parseInt(ast.value, 10));
    }
    return null;
  }
}
```

With this in place, register `DateScalar` as a provider:

```typescript

@Module({
  providers: [DateScalar],
})
export class CommonModule {}
```

Now you can use the `Date` scalar in your type definitions:

```graphql

scalar Date
```

By default, the generated TypeScript definition for every custom scalar is `any`, which isn't type-safe. You can configure how Nest generates typings for your custom scalars when you specify how to generate types:

```typescript

import { GraphQLDefinitionsFactory } from '@nestjs/graphql';
import { join } from 'node:path';

const definitionsFactory = new GraphQLDefinitionsFactory();

definitionsFactory.generate({
  typePaths: ['./src/**/*.graphql'],
  path: join(process.cwd(), 'src/graphql.ts'),
  outputAs: 'class',
  defaultScalarType: 'unknown',
  customScalarTypeMapping: {
    DateTime: 'Date',
    BigNumber: '_BigNumber',
  },
  additionalHeader: "import _BigNumber from 'bignumber.js'",
});
```

> **Hint** Alternatively, you can use a type reference, for example, `DateTime: Date`. In this case, `GraphQLDefinitionsFactory` uses the `name` property of the specified type (`Date.name`) to generate the TypeScript definitions. For custom (non-built-in) types, you must also add an import statement.

Now, given the following GraphQL custom scalar types:

```graphql

scalar DateTime
scalar BigNumber
scalar Payload
```

Nest generates the following TypeScript definitions in `src/graphql.ts`:

```typescript

import _BigNumber from 'bignumber.js';

export type DateTime = Date;
export type BigNumber = _BigNumber;
export type Payload = unknown;
```

Here, the `customScalarTypeMapping` property maps each custom scalar to the TypeScript type to declare for it. The `additionalHeader` property adds any imports these type definitions require. Lastly, setting `defaultScalarType` to `'unknown'` aliases any custom scalar not listed in `customScalarTypeMapping` to `unknown` instead of `any`, which [TypeScript recommends](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-0.html#new-unknown-top-type) since version 3.0 for added type safety.

> **Hint** The example imports `_BigNumber` from `bignumber.js` under an alias to avoid [circular type references](https://github.com/Microsoft/TypeScript/issues/12525#issuecomment-263166239).

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/scalars.md)

----
url: https://docs.nestjs.com/v11/security/authorization
----

* [Authorization](https://docs.nestjs.com/v11/security/authorization#authorization)
* [Basic RBAC implementation](https://docs.nestjs.com/v11/security/authorization#basic-rbac-implementation)
* [Claims-based authorization](https://docs.nestjs.com/v11/security/authorization#claims-based-authorization)
* [Integrating CASL](https://docs.nestjs.com/v11/security/authorization#integrating-casl)
* [Advanced: Implementing a PoliciesGuard](https://docs.nestjs.com/v11/security/authorization#advanced-implementing-a-policiesguard)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/security/authorization.md "Suggest Edits")

### Authorization

**Authorization** refers to the process that determines what a user is able to do. For example, an administrative user is allowed to create, edit, and delete posts. A non-administrative user is only authorized to read the posts.

Authorization is orthogonal and independent from authentication. However, authorization requires an authentication mechanism.

There are many different approaches and strategies to handle authorization. The approach taken for any project depends on its particular application requirements. This chapter presents a few approaches to authorization that can be adapted to a variety of different requirements.

#### Basic RBAC implementation[#](/security/authorization#basic-rbac-implementation)

Role-based access control (**RBAC**) is a policy-neutral access-control mechanism defined around roles and privileges. In this section, we'll demonstrate how to implement a very basic RBAC mechanism using Nest [guards](/v11/guards).

First, let's create a `Role` enum representing roles in the system:

role.enum.ts

JS TS

```typescript

export enum Role {
  User = 'user',
  Admin = 'admin',
}
```

> **Hint** In more sophisticated systems, you may store roles within a database, or pull them from the external authentication provider.

With this in place, we can create a `@Roles()` decorator. This decorator allows specifying what roles are required to access specific resources.

roles.decorator.ts

JS TS

```typescript

import { SetMetadata } from '@nestjs/common';
import { Role } from '../enums/role.enum';

export const ROLES_KEY = 'roles';
export const Roles = (...roles: Role[]) => SetMetadata(ROLES_KEY, roles);
```

```typescript

import { SetMetadata } from '@nestjs/common';

export const ROLES_KEY = 'roles';
export const Roles = (...roles) => SetMetadata(ROLES_KEY, roles);
```

Now that we have a custom `@Roles()` decorator, we can use it to decorate any route handler.

cats.controller.ts

JS TS

```typescript

@Post()
@Roles(Role.Admin)
create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

```typescript

@Post()
@Roles(Role.Admin)
@Bind(Body())
create(createCatDto) {
  this.catsService.create(createCatDto);
}
```

Finally, we create a `RolesGuard` class which will compare the roles assigned to the current user to the actual roles required by the current route being processed. In order to access the route's role(s) (custom metadata), we'll use the `Reflector` helper class, which is provided out of the box by the framework and exposed from the `@nestjs/core` package.

roles.guard.ts

JS TS

```typescript

import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
import { Reflector } from '@nestjs/core';

@Injectable()
export class RolesGuard implements CanActivate {
  constructor(private reflector: Reflector) {}

  canActivate(context: ExecutionContext): boolean {
    const requiredRoles = this.reflector.getAllAndOverride<Role[]>(ROLES_KEY, [
      context.getHandler(),
      context.getClass(),
    ]);
    if (!requiredRoles) {
      return true;
    }
    const { user } = context.switchToHttp().getRequest();
    return requiredRoles.some((role) => user.roles?.includes(role));
  }
}
```

```typescript

import { Injectable, Dependencies } from '@nestjs/common';
import { Reflector } from '@nestjs/core';

@Injectable()
@Dependencies(Reflector)
export class RolesGuard {
  constructor(reflector) {
    this.reflector = reflector;
  }

  canActivate(context) {
    const requiredRoles = this.reflector.getAllAndOverride(ROLES_KEY, [
      context.getHandler(),
      context.getClass(),
    ]);
    if (!requiredRoles) {
      return true;
    }
    const { user } = context.switchToHttp().getRequest();
    return requiredRoles.some((role) => user.roles.includes(role));
  }
}
```

> **Hint** Refer to the [Reflection and metadata](/fundamentals/execution-context#reflection-and-metadata) section of the Execution context chapter for more details on utilizing `Reflector` in a context-sensitive way.

> **Notice** This example is named "**basic**" as we only check for the presence of roles on the route handler level. In real-world applications, you may have endpoints/handlers that involve several operations, in which each of them requires a specific set of permissions. In this case, you'll have to provide a mechanism to check roles somewhere within your business-logic, making it somewhat harder to maintain as there will be no centralized place that associates permissions with specific actions.

In this example, we assumed that `request.user` contains the user instance and allowed roles (under the `roles` property). In your app, you will probably make that association in your custom **authentication guard** - see [authentication](/v11/security/authentication) chapter for more details.

To make sure this example works, your `User` class must look as follows:

```typescript

class User {
  // ...other properties
  roles: Role[];
}
```

Lastly, make sure to register the `RolesGuard`, for example, at the controller level, or globally:

```typescript

providers: [
  {
    provide: APP_GUARD,
    useClass: RolesGuard,
  },
],
```

When a user with insufficient privileges requests an endpoint, Nest automatically returns the following response:

```typescript

{
  "statusCode": 403,
  "message": "Forbidden resource",
  "error": "Forbidden"
}
```

> **Hint** If you want to return a different error response, you should throw your own specific exception instead of returning a boolean value.

```typescript

@Post()
@RequirePermissions(Permission.CREATE_CAT)
create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

```typescript

@Post()
@RequirePermissions(Permission.CREATE_CAT)
@Bind(Body())
create(createCatDto) {
  this.catsService.create(createCatDto);
}
```

> **Hint** In the example above, `Permission` (similar to `Role` we have shown in RBAC section) is a TypeScript enum that contains all the permissions available in your system.

#### Integrating CASL[#](/security/authorization#integrating-casl)

[CASL](https://casl.js.org/) is an isomorphic authorization library which restricts what resources a given client is allowed to access. It's designed to be incrementally adoptable and can easily scale between a simple claim based and fully featured subject and attribute based authorization.

To start, first install the `@casl/ability` package:

```bash

$ npm i @casl/ability
```

> **Hint** In this example, we chose CASL, but you can use any other library like `accesscontrol` or `acl`, depending on your preferences and project needs.

Once the installation is complete, for the sake of illustrating the mechanics of CASL, we'll define two entity classes: `User` and `Article`.

```typescript

class User {
  id: number;
  isAdmin: boolean;
}
```

`User` class consists of two properties, `id`, which is a unique user identifier, and `isAdmin`, indicating whether a user has administrator privileges.

```typescript

class Article {
  id: number;
  isPublished: boolean;
  authorId: number;
}
```

```typescript

export enum Action {
  Manage = 'manage',
  Create = 'create',
  Read = 'read',
  Update = 'update',
  Delete = 'delete',
}
```

> **Notice**`manage` is a special keyword in CASL which represents "any action".

To encapsulate CASL library, let's generate the `CaslModule` and `CaslAbilityFactory` now.

```bash

$ nest g module casl
$ nest g class casl/casl-ability.factory
```

With this in place, we can define the `createForUser()` method on the `CaslAbilityFactory`. This method will create the `Ability` object for a given user:

```typescript

type Subjects = InferSubjects<typeof Article | typeof User> | 'all';

export type AppAbility = MongoAbility<[Action, Subjects]>;

@Injectable()
export class CaslAbilityFactory {
  createForUser(user: User) {
    const { can, cannot, build } = new AbilityBuilder(createMongoAbility);

    if (user.isAdmin) {
      can(Action.Manage, 'all'); // read-write access to everything
    } else {
      can(Action.Read, 'all'); // read-only access to everything
    }

    can(Action.Update, Article, { authorId: user.id });
    cannot(Action.Delete, Article, { isPublished: true });

    return build({
      // Read https://casl.js.org/v6/en/guide/subject-type-detection#use-classes-as-subject-types for details
      detectSubjectType: (item) =>
        item.constructor as ExtractSubjectType<Subjects>,
    });
  }
}
```

> **Notice**`all` is a special keyword in CASL that represents "any subject".

> **Hint** Since CASL v6, `MongoAbility` serves as the default ability class, replacing the legacy `Ability` to better support condition-based permissions using MongoDB-like syntax. Despite the name, it is not tied to MongoDB — it works with any kind of data by simply comparing objects against conditions written in Mongo-like syntax.

> **Hint**`MongoAbility`, `AbilityBuilder`, `AbilityClass`, and `ExtractSubjectType` classes are exported from the `@casl/ability` package.

> **Hint** The `detectSubjectType` option lets CASL understand how to get the subject type out of an object. For more information, read the [CASL documentation](https://casl.js.org/v6/en/guide/subject-type-detection#use-classes-as-subject-types).

In the example above, we created the `MongoAbility` instance using the `AbilityBuilder` class. As you probably guessed, `can` and `cannot` accept the same arguments but have different meanings, `can` allows you to perform an action on the specified subject and `cannot` forbids it. Both may accept up to 4 arguments. To learn more about these functions, visit the official [CASL documentation](https://casl.js.org/v6/en/guide/intro).

Lastly, make sure to add the `CaslAbilityFactory` to the `providers` and `exports` arrays in the `CaslModule` module definition:

```typescript

import { Module } from '@nestjs/common';
import { CaslAbilityFactory } from './casl-ability.factory';

@Module({
  providers: [CaslAbilityFactory],
  exports: [CaslAbilityFactory],
})
export class CaslModule {}
```

With this in place, we can inject the `CaslAbilityFactory` to any class using standard constructor injection as long as the `CaslModule` is imported in the host context:

```typescript

constructor(private caslAbilityFactory: CaslAbilityFactory) {}
```

Then use it in a class as follows.

```typescript

const ability = this.caslAbilityFactory.createForUser(user);
if (ability.can(Action.Read, 'all')) {
  // "user" has read access to everything
}
```

> **Hint** Learn more about the `MongoAbility` class in the official [CASL documentation](https://casl.js.org/v6/en/guide/intro).

For example, let's say we have a user who is not an admin. In this case, the user should be able to read articles, but creating new ones or removing the existing articles should be prohibited.

```typescript

const user = new User();
user.isAdmin = false;

const ability = this.caslAbilityFactory.createForUser(user);
ability.can(Action.Read, Article); // true
ability.can(Action.Delete, Article); // false
ability.can(Action.Create, Article); // false
```

> **Hint** Although both `MongoAbility` and `AbilityBuilder` classes provide `can` and `cannot` methods, they have different purposes and accept slightly different arguments.

Also, as we have specified in our requirements, the user should be able to update its articles:

```typescript

const user = new User();
user.id = 1;

const article = new Article();
article.authorId = user.id;

const ability = this.caslAbilityFactory.createForUser(user);
ability.can(Action.Update, article); // true

article.authorId = 2;
ability.can(Action.Update, article); // false
```

As you can see, `MongoAbility` instance allows us to check permissions in pretty readable way. Likewise, `AbilityBuilder` allows us to define permissions (and specify various conditions) in a similar fashion. To find more examples, visit the official documentation.

#### Advanced: Implementing a `PoliciesGuard`[#](/security/authorization#advanced-implementing-a-policiesguard)

In this section, we'll demonstrate how to build a somewhat more sophisticated guard, which checks if a user meets specific **authorization policies** that can be configured on the method-level (you can extend it to respect policies configured on the class-level too). In this example, we are going to use the CASL package just for illustration purposes, but using this library is not required. Also, we will use the `CaslAbilityFactory` provider that we've created in the previous section.

First, let's flesh out the requirements. The goal is to provide a mechanism that allows specifying policy checks per route handler. We will support both objects and functions (for simpler checks and for those who prefer more functional-style code).

Let's start off by defining interfaces for policy handlers:

```typescript

import { AppAbility } from '../casl/casl-ability.factory';

interface IPolicyHandler {
  handle(ability: AppAbility): boolean;
}

type PolicyHandlerCallback = (ability: AppAbility) => boolean;

export type PolicyHandler = IPolicyHandler | PolicyHandlerCallback;
```

As mentioned above, we provided two possible ways of defining a policy handler, an object (instance of a class that implements the `IPolicyHandler` interface) and a function (which meets the `PolicyHandlerCallback` type).

With this in place, we can create a `@CheckPolicies()` decorator. This decorator allows specifying what policies have to be met to access specific resources.

```typescript

export const CHECK_POLICIES_KEY = 'check_policy';
export const CheckPolicies = (...handlers: PolicyHandler[]) =>
  SetMetadata(CHECK_POLICIES_KEY, handlers);
```

Now let's create a `PoliciesGuard` that will extract and execute all the policy handlers bound to a route handler.

```typescript

@Injectable()
export class PoliciesGuard implements CanActivate {
  constructor(
    private reflector: Reflector,
    private caslAbilityFactory: CaslAbilityFactory,
  ) {}

  async canActivate(context: ExecutionContext): Promise<boolean> {
    const policyHandlers =
      this.reflector.get<PolicyHandler[]>(
        CHECK_POLICIES_KEY,
        context.getHandler(),
      ) || [];

    const { user } = context.switchToHttp().getRequest();
    const ability = this.caslAbilityFactory.createForUser(user);

    return policyHandlers.every((handler) =>
      this.execPolicyHandler(handler, ability),
    );
  }

  private execPolicyHandler(handler: PolicyHandler, ability: AppAbility) {
    if (typeof handler === 'function') {
      return handler(ability);
    }
    return handler.handle(ability);
  }
}
```

> **Hint** In this example, we assumed that `request.user` contains the user instance. In your app, you will probably make that association in your custom **authentication guard** - see [authentication](/v11/security/authentication) chapter for more details.

Let's break this example down. The `policyHandlers` is an array of handlers assigned to the method through the `@CheckPolicies()` decorator. Next, we use the `CaslAbilityFactory#create` method which constructs the `Ability` object, allowing us to verify whether a user has sufficient permissions to perform specific actions. We are passing this object to the policy handler which is either a function or an instance of a class that implements the `IPolicyHandler`, exposing the `handle()` method that returns a boolean. Lastly, we use the `Array#every` method to make sure that every handler returned `true` value.

Finally, to test this guard, bind it to any route handler, and register an inline policy handler (functional approach), as follows:

```typescript

@Get()
@UseGuards(PoliciesGuard)
@CheckPolicies((ability: AppAbility) => ability.can(Action.Read, Article))
findAll() {
  return this.articlesService.findAll();
}
```

Alternatively, we can define a class which implements the `IPolicyHandler` interface:

```typescript

export class ReadArticlePolicyHandler implements IPolicyHandler {
  handle(ability: AppAbility) {
    return ability.can(Action.Read, Article);
  }
}
```

And use it as follows:

```typescript

@Get()
@UseGuards(PoliciesGuard)
@CheckPolicies(new ReadArticlePolicyHandler())
findAll() {
  return this.articlesService.findAll();
}
```

> **Notice** Since we must instantiate the policy handler in-place using the `new` keyword, `ReadArticlePolicyHandler` class cannot use the Dependency Injection. This can be addressed with the `ModuleRef#get` method (read more [here](/v11/fundamentals/module-ref)). Basically, instead of registering functions and instances through the `@CheckPolicies()` decorator, you must allow passing a `Type<IPolicyHandler>`. Then, inside your guard, you could retrieve an instance using a type reference: `moduleRef.get(YOUR_HANDLER_TYPE)` or even dynamically instantiate it using the `ModuleRef#create` method.

----
url: https://docs.nestjs.com/v8/techniques/versioning
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Versioning](https://docs.nestjs.com/v8/techniques/versioning#versioning)
* [URI Versioning Type](https://docs.nestjs.com/v8/techniques/versioning#uri-versioning-type)
* [Header Versioning Type](https://docs.nestjs.com/v8/techniques/versioning#header-versioning-type)
* [Media Type Versioning Type](https://docs.nestjs.com/v8/techniques/versioning#media-type-versioning-type)
* [Custom Versioning Type](https://docs.nestjs.com/v8/techniques/versioning#custom-versioning-type)
* [Usage](https://docs.nestjs.com/v8/techniques/versioning#usage)
* [Controller versions](https://docs.nestjs.com/v8/techniques/versioning#controller-versions)
* [Route versions](https://docs.nestjs.com/v8/techniques/versioning#route-versions)
* [Multiple versions](https://docs.nestjs.com/v8/techniques/versioning#multiple-versions)
* [Version "Neutral"](https://docs.nestjs.com/v8/techniques/versioning#version-neutral)
* [Global default version](https://docs.nestjs.com/v8/techniques/versioning#global-default-version)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/techniques/versioning.md "Suggest Edits")

### Versioning

> **Hint** This chapter is only relevant to HTTP-based applications.

Versioning allows you to have **different versions** of your controllers or individual routes running within the same application. Applications change very often and it is not unusual that there are breaking changes that you need to make while still needing to support the previous version of the application.

There are 4 types of versioning that are supported:

|                                                                             |                                                                                                                            |
| --------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- |
| [`URI Versioning`](techniques/versioning#uri-versioning-type)               | The version will be passed within the URI of the request (default)                                                         |
| [`Header Versioning`](techniques/versioning#header-versioning-type)         | A custom request header will specify the version                                                                           |
| [`Media Type Versioning`](techniques/versioning#media-type-versioning-type) | The `Accept` header of the request will specify the version                                                                |
| [`Custom Versioning`](techniques/versioning#custom-versioning-type)         | Any aspect of the request may be used to specify the version(s). A custom function is provided to extract said version(s). |

#### URI Versioning Type[#](/techniques/versioning#uri-versioning-type)

URI Versioning uses the version passed within the URI of the request, such as `https://example.com/v1/route` and `https://example.com/v2/route`.

> **Notice** With URI Versioning the version will be automatically added to the URI after the [global path prefix](faq/global-prefix) (if one exists), and before any controller or route paths.

To enable URI Versioning for your application, do the following:

main.ts

JS TS

```typescript

const app = await NestFactory.create(AppModule);
// or "app.enableVersioning()"
app.enableVersioning({
  type: VersioningType.URI,
});
await app.listen(3000);
```

> **Notice** The version in the URI will be automatically prefixed with `v` by default, however the prefix value can be configured by setting the `prefix` key to your desired prefix or `false` if you wish to disable it.

> **Hint** The `VersioningType` enum is available to use for the `type` property and is imported from the `@nestjs/common` package.

#### Header Versioning Type[#](/techniques/versioning#header-versioning-type)

Header Versioning uses a custom, user specified, request header to specify the version where the value of the header will be the version to use for the request.

Example HTTP Requests for Header Versioning:

To enable **Header Versioning** for your application, do the following:

main.ts

JS TS

```typescript

const app = await NestFactory.create(AppModule);
app.enableVersioning({
  type: VersioningType.HEADER,
  header: 'Custom-Header',
});
await app.listen(3000);
```

The `header` property should be the name of the header that will contain the version of the request.

> **Hint** The `VersioningType` enum is available to use for the `type` property and is imported from the `@nestjs/common` package.

#### Media Type Versioning Type[#](/techniques/versioning#media-type-versioning-type)

Media Type Versioning uses the `Accept` header of the request to specify the version.

Within the `Accept` header, the version will be separated from the media type with a semi-colon, `;`. It should then contain a key-value pair that represents the version to use for the request, such as `Accept: application/json;v=2`. They key is treated more as a prefix when determining the version will to be configured to include the key and separator.

To enable **Media Type Versioning** for your application, do the following:

main.ts

JS TS

```typescript

const app = await NestFactory.create(AppModule);
app.enableVersioning({
  type: VersioningType.MEDIA_TYPE,
  key: 'v=',
});
await app.listen(3000);
```

The `key` property should be the key and separator of the key-value pair that contains the version. For the example `Accept: application/json;v=2`, the `key` property would be set to `v=`.

> **Hint** The `VersioningType` enum is available to use for the `type` property and is imported from the `@nestjs/common` package.

#### Custom Versioning Type[#](/techniques/versioning#custom-versioning-type)

Custom Versioning uses any aspect of the request to specify the version (or versions). The incoming request is analyzed using an `extractor` function that returns a string or array of strings.

If multiple versions are provided by the requester, the extractor function can return an array of strings, sorted in order of greatest/highest version to smallest/lowest version. Versions are matched to routes in order from highest to lowest.

If an empty string or array is returned from the `extractor`, no routes are matched and a 404 is returned.

For example, if an incoming request specifies it supports versions `1`, `2`, and `3`, the `extractor`**MUST** return `[3, 2, 1]`. This ensures that the highest possible route version is selected first.

If versions `[3, 2, 1]` are extracted, but routes only exist for version `2` and `1`, the route that matches version `2` is selected (version `3` is automatically ignored).

> **Notice** Selecting the highest matching version based on the array returned from `extractor` > **does not reliably work** with the Express adapter due to design limitations. A single version (either a string or array of 1 element) works just fine in Express. Fastify correctly supports both highest matching version selection and single version selection.

To enable **Custom Versioning** for your application, create an `extractor` function and pass it into your application like so:

main.ts

JS TS

```typescript

// Example extractor that pulls out a list of versions from a custom header and turns it into a sorted array.
// This example uses Fastify, but Express requests can be processed in a similar way.
const extractor = (request: FastifyRequest): string | string[] =>
  [request.headers['custom-versioning-field'] ?? '']
     .flatMap(v => v.split(','))
     .filter(v => !!v)
     .sort()
     .reverse()

const app = await NestFactory.create(AppModule);
app.enableVersioning({
  type: VersioningType.CUSTOM,
  extractor,
});
await app.listen(3000);
```

#### Usage[#](/techniques/versioning#usage)

Versioning allows you to version controllers, individual routes, and also provides a way for certain resources to opt-out of versioning. The usage of versioning is the same regardless of the Versioning Type your application uses.

> **Notice** If versioning is enabled for the application but the controller or route does not specify the version, any requests to that controller/route will be returned a `404` response status. Similarly, if a request is received containing a version that does not have a corresponding controller or route, it will also be returned a `404` response status.

#### Controller versions[#](/techniques/versioning#controller-versions)

A version can be applied to a controller, setting the version for all routes within the controller.

To add a version to a controller do the following:

cats.controller.ts

JS TS

```typescript

@Controller({
  version: '1',
})
export class CatsControllerV1 {
  @Get('cats')
  findAll(): string {
    return 'This action returns all cats for version 1';
  }
}
```

```typescript

@Controller({
  version: '1',
})
export class CatsControllerV1 {
  @Get('cats')
  findAll() {
    return 'This action returns all cats for version 1';
  }
}
```

#### Route versions[#](/techniques/versioning#route-versions)

A version can be applied to an individual route. This version will override any other version that would effect the route, such as the Controller Version.

To add a version to an individual route do the following:

cats.controller.ts

JS TS

```typescript

import { Controller, Get, Version } from '@nestjs/common';

@Controller()
export class CatsController {
  @Version('1')
  @Get('cats')
  findAllV1(): string {
    return 'This action returns all cats for version 1';
  }

  @Version('2')
  @Get('cats')
  findAllV2(): string {
    return 'This action returns all cats for version 2';
  }
}
```

```typescript

import { Controller, Get, Version } from '@nestjs/common';

@Controller()
export class CatsController {
  @Version('1')
  @Get('cats')
  findAllV1() {
    return 'This action returns all cats for version 1';
  }

  @Version('2')
  @Get('cats')
  findAllV2() {
    return 'This action returns all cats for version 2';
  }
}
```

#### Multiple versions[#](/techniques/versioning#multiple-versions)

Multiple versions can be applied to a controller or route. To use multiple versions, you would set the version to be an Array.

To add multiple versions do the following:

cats.controller.ts

JS TS

```typescript

@Controller({
  version: ['1', '2'],
})
export class CatsController {
  @Get('cats')
  findAll(): string {
    return 'This action returns all cats for version 1 or 2';
  }
}
```

```typescript

@Controller({
  version: ['1', '2'],
})
export class CatsController {
  @Get('cats')
  findAll() {
    return 'This action returns all cats for version 1 or 2';
  }
}
```

#### Version "Neutral"[#](/techniques/versioning#version-neutral)

Some controllers or routes may not care about the version and would have the same functionality regardless of the version. To accommodate this, the version can be set to `VERSION_NEUTRAL` symbol.

An incoming request will be mapped to a `VERSION_NEUTRAL` controller or route regardless of the version sent in the request in addition to if the request does not contain a version at all.

> **Notice** For URI Versioning, a `VERSION_NEUTRAL` resource would not have the version present in the URI.

To add a version neutral controller or route do the following:

cats.controller.ts

JS TS

```typescript

import { Controller, Get, VERSION_NEUTRAL } from '@nestjs/common';

@Controller({
  version: VERSION_NEUTRAL,
})
export class CatsController {
  @Get('cats')
  findAll(): string {
    return 'This action returns all cats regardless of version';
  }
}
```

```typescript

import { Controller, Get, VERSION_NEUTRAL } from '@nestjs/common';

@Controller({
  version: VERSION_NEUTRAL,
})
export class CatsController {
  @Get('cats')
  findAll() {
    return 'This action returns all cats regardless of version';
  }
}
```

#### Global default version[#](/techniques/versioning#global-default-version)

If you do not want to provide a version for each controller/or individual routes, or if you want to have a specific version set as the default version for every controller/route that don't have the version specified, you could set the `defaultVersion` as follows:

main.ts

JS TS

```typescript

app.enableVersioning({
  // ...
  defaultVersion: '1'
  // or
  defaultVersion: ['1', '2']
  // or
  defaultVersion: VERSION_NEUTRAL
});
```

----
url: https://docs.nestjs.com/v7/faq/http-adapter
----

* [HTTP adapter](https://docs.nestjs.com/v7/faq/http-adapter#http-adapter)
* [Outside application context strategy](https://docs.nestjs.com/v7/faq/http-adapter#outside-application-context-strategy)
* [In-context strategy](https://docs.nestjs.com/v7/faq/http-adapter#in-context-strategy)

```typescript

const app = await NestFactory.create(AppModule);
const httpAdapter = app.getHttpAdapter();
```

#### In-context strategy[#](/faq/http-adapter#in-context-strategy)

To get a reference to the `HttpAdapterHost` from within the application context, inject it using the same technique as any other existing provider (e.g., using constructor injection).

JS TS

```typescript

export class CatsService {
  constructor(private adapterHost: HttpAdapterHost) {}
}
```

```typescript

@Dependencies(HttpAdapterHost)
export class CatsService {
  constructor(adapterHost) {
    this.adapterHost = adapterHost;
  }
}
```

> **Hint** The `HttpAdapterHost` is imported from the `@nestjs/core` package.

The `HttpAdapterHost` is **not** an actual `HttpAdapter`. To get the actual `HttpAdapter` instance, simply access the `httpAdapter` property.

```typescript

const adapterHost = app.get(HttpAdapterHost);
const httpAdapter = adapterHost.httpAdapter;
```

The `httpAdapter` is the actual instance of the HTTP adapter used by the underlying framework. It is an instance of either `ExpressAdapter` or `FastifyAdapter` (both classes extend `AbstractHttpAdapter`).

The adapter object exposes several useful methods to interact with the HTTP server. However, if you want to access the library instance (e.g., the Express instance) directly, call the `getInstance()` method.

```typescript

const instance = httpAdapter.getInstance();
```

----
url: https://docs.nestjs.com/v4/graphql/schema-stitching
----

### Schema Stitching

The schema stitching is a feature that allows creating a single GraphQL schema from multiple underlying GraphQL APIs. You can read more about it [here](https://www.apollographql.com/docs/graphql-tools/schema-stitching.html).

#### Proxying

To add the ability to proxy fields between schemas, you need to create additional resolvers between them. Let's have a look on the example from the [Apollo](https://www.apollographql.com/docs/graphql-tools/schema-stitching.html#adding-resolvers) documentation:

JavaScript TypeScript

TypeScript

```typescript

mergeInfo => ({
  User: {
    chirps: {
      fragment: `fragment UserFragment on User { id }`,
      resolve(parent, args, context, info) {
        const authorId = parent.id;
        return mergeInfo.delegate(
          'query',
          'chirpsByAuthorId',
          {
            authorId,
          },
          context,
          info,
        );
      },
    },
  }
})
```

Here we **delegate** `chirps` property of `User` to another GraphQL API. To achieve the same result in Nest-way, we use `@DelegateProperty()` decorator.

JavaScript TypeScript

TypeScript

```typescript

@Resolver('User')
@DelegateProperty('chirps')
findChirpsByUserId() {
  return (mergeInfo: MergeInfo) => ({
    fragment: `fragment UserFragment on User { id }`,
    resolve(parent, args, context, info) {
      const authorId = parent.id;
      return mergeInfo.delegate(
        'query',
        'chirpsByAuthorId',
        {
          authorId,
        },
        context,
        info,
      );
    },
  });
}
```

> **Hint** The `@Resolver()` decorator is used here at the method-level, but you can use it at top (class) level as well.

Now let's take a step back to the `graphqlExpress` middleware. We need to merge our schemas and add delegates between them. To create delegates we use `createDelegates()` method of `GraphQLFactory` class.

app.module.ts

JavaScript TypeScript

TypeScript

```typescript

configure(consumer) {
  const typeDefs = this.graphQLFactory.mergeTypesByPaths('./**/*.graphql');
  const localSchema = this.graphQLFactory.createSchema({ typeDefs });
  const delegates = this.graphQLFactory.createDelegates();
  const schema = mergeSchemas({
    schemas: [localSchema, chirpSchema, linkTypeDefs],
    resolvers: delegates,
  });

  consumer
    .apply(graphqlExpress(req => ({ schema, rootValue: req })))
    .forRoutes({ path: '/graphql', method: RequestMethod.ALL });
}
```

In order to merge schemas, we have used `mergeSchemas()` function ([read more](https://www.apollographql.com/docs/graphql-tools/schema-stitching.html#mergeSchemas)). Moreover, there're `chirpsSchema` and `linkTypeDefs` variables. They're copied & pasted directly from the [Apollo](https://www.apollographql.com/docs/graphql-tools/schema-stitching.html) documentation.

JavaScript TypeScript

TypeScript

```typescript

import { makeExecutableSchema } from 'graphql-tools';
    
const chirpSchema = makeExecutableSchema({
  typeDefs: `
    type Chirp {
      id: ID!
      text: String
      authorId: ID!
    }

    type Query {
      chirpById(id: ID!): Chirp
      chirpsByAuthorId(authorId: ID!): [Chirp]
    }
  `
});
const linkTypeDefs = `
  extend type User {
    chirps: [Chirp]
  }

  extend type Chirp {
    author: User
  }
`;
```

That's all.

#### Sponsors

[](https://valor-software.com/)

Nest is an MIT-licensed open source project. It can grow thanks to the support by these awesome people. If you'd like to join them, please read more [here](https://opencollective.com/nest). Thanks!

[](https://opencollective.com/nest/backer/0/website)[](https://opencollective.com/nest/backer/1/website)[](https://opencollective.com/nest/backer/2/website)[](https://opencollective.com/nest/backer/3/website)[](https://opencollective.com/nest/backer/4/website)[](https://opencollective.com/nest/backer/5/website)[](https://opencollective.com/nest/backer/6/website)[](https://opencollective.com/nest/backer/7/website)[](https://opencollective.com/nest/backer/8/website)[](https://opencollective.com/nest/backer/9/website)[](https://opencollective.com/nest/backer/10/website)[](https://opencollective.com/nest/backer/11/website)[](https://opencollective.com/nest/backer/12/website)[](https://opencollective.com/nest/backer/13/website)[](https://opencollective.com/nest/backer/14/website)[](https://opencollective.com/nest/backer/15/website)[](https://opencollective.com/nest/backer/16/website)[](https://opencollective.com/nest/backer/17/website)[](https://opencollective.com/nest/backer/18/website)[](https://opencollective.com/nest/backer/19/website)[](https://opencollective.com/nest/backer/20/website)[](https://opencollective.com/nest/backer/21/website)[](https://opencollective.com/nest/backer/22/website)[](https://opencollective.com/nest/backer/23/website)[](https://opencollective.com/nest/backer/24/website)[](https://opencollective.com/nest/backer/25/website)[](https://opencollective.com/nest/backer/26/website)[](https://opencollective.com/nest/backer/27/website)[](https://opencollective.com/nest/backer/28/website)[](https://opencollective.com/nest/backer/29/website)

[Become a sponsor](https://opencollective.com/nest)

----
url: https://docs.nestjs.com/v10/faq/serverless
----

* [Serverless](https://docs.nestjs.com/v10/faq/serverless#serverless)
* [Cold start](https://docs.nestjs.com/v10/faq/serverless#cold-start)
* [Benchmarks](https://docs.nestjs.com/v10/faq/serverless#benchmarks)
* [Runtime optimizations](https://docs.nestjs.com/v10/faq/serverless#runtime-optimizations)
* [Example integration](https://docs.nestjs.com/v10/faq/serverless#example-integration)
* [Using standalone application feature](https://docs.nestjs.com/v10/faq/serverless#using-standalone-application-feature)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/faq/serverless.md "Suggest Edits")

### Serverless

Serverless computing is a cloud computing execution model in which the cloud provider allocates machine resources on-demand, taking care of the servers on behalf of their customers. When an app is not in use, there are no computing resources allocated to the app. Pricing is based on the actual amount of resources consumed by an application ([source](https://en.wikipedia.org/wiki/Serverless_computing)).

With a **serverless architecture**, you focus purely on the individual functions in your application code. Services such as AWS Lambda, Google Cloud Functions, and Microsoft Azure Functions take care of all the physical hardware, virtual machine operating system, and web server software management.

> **Hint** This chapter does not cover the pros and cons of serverless functions nor dives into the specifics of any cloud providers.

#### Cold start[#](/faq/serverless#cold-start)

A cold start is the first time your code has been executed in a while. Depending on a cloud provider you use, it may span several different operations, from downloading the code and bootstrapping the runtime to eventually running your code. This process adds **significant latency** depending on several factors, the language, the number of packages your application require, etc.

The cold start is important and although there are things which are beyond our control, there's still a lot of things we can do on our side to make it as short as possible.

While you can think of Nest as a fully-fledged framework designed to be used in complex, enterprise applications, it is also **suitable for much "simpler" applications** (or scripts). For example, with the use of [Standalone applications](/v10/standalone-applications) feature, you can take advantage of Nest's DI system in simple workers, CRON jobs, CLIs, or serverless functions.

#### Benchmarks[#](/faq/serverless#benchmarks)

To better understand what's the cost of using Nest or other, well-known libraries (like `express`) in the context of serverless functions, let's compare how much time Node runtime needs to run the following scripts:

```typescript

// #1 Express
import * as express from 'express';

async function bootstrap() {
  const app = express();
  app.get('/', (req, res) => res.send('Hello world!'));
  await new Promise<void>((resolve) => app.listen(3000, resolve));
}
bootstrap();

// #2 Nest (with @nestjs/platform-express)
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule, { logger: ['error'] });
  await app.listen(process.env.PORT ?? 3000);
}
bootstrap();

// #3 Nest as a Standalone application (no HTTP server)
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { AppService } from './app.service';

async function bootstrap() {
  const app = await NestFactory.createApplicationContext(AppModule, {
    logger: ['error'],
  });
  console.log(app.get(AppService).getHello());
}
bootstrap();

// #4 Raw Node.js script
async function bootstrap() {
  console.log('Hello world!');
}
bootstrap();
```

For all these scripts, we used the `tsc` (TypeScript) compiler and so the code remains unbundled (`webpack` isn't used).

| Express                              | 0.0079s (7.9ms)   |
| ------------------------------------ | ----------------- |
| Nest with `@nestjs/platform-express` | 0.1974s (197.4ms) |
| Nest (standalone application)        | 0.1117s (111.7ms) |
| Raw Node.js script                   | 0.0071s (7.1ms)   |

> **Note** Machine: MacBook Pro Mid 2014, 2.5 GHz Quad-Core Intel Core i7, 16 GB 1600 MHz DDR3, SSD.

Now, let's repeat all benchmarks but this time, using `webpack` (if you have [Nest CLI](/v10/cli/overview) installed, you can run `nest build --webpack`) to bundle our application into a single executable JavaScript file. However, instead of using the default `webpack` configuration that Nest CLI ships with, we'll make sure to bundle all dependencies (`node_modules`) together, as follows:

```javascript

module.exports = (options, webpack) => {
  const lazyImports = [
    '@nestjs/microservices/microservices-module',
    '@nestjs/websockets/socket-module',
  ];

  return {
    ...options,
    externals: [],
    plugins: [
      ...options.plugins,
      new webpack.IgnorePlugin({
        checkResource(resource) {
          if (lazyImports.includes(resource)) {
            try {
              require.resolve(resource);
            } catch (err) {
              return true;
            }
          }
          return false;
        },
      }),
    ],
  };
};
```

> **Hint** To instruct Nest CLI to use this configuration, create a new `webpack.config.js` file in the root directory of your project.

With this configuration, we received the following results:

| Express                              | 0.0068s (6.8ms)  |
| ------------------------------------ | ---------------- |
| Nest with `@nestjs/platform-express` | 0.0815s (81.5ms) |
| Nest (standalone application)        | 0.0319s (31.9ms) |
| Raw Node.js script                   | 0.0066s (6.6ms)  |

> **Note** Machine: MacBook Pro Mid 2014, 2.5 GHz Quad-Core Intel Core i7, 16 GB 1600 MHz DDR3, SSD.

> **Hint** You could optimize it even further by applying additional code minification & optimization techniques (using `webpack` plugins, etc.).

As you can see, the way you compile (and whether you bundle your code) is crucial and has a significant impact on the overall startup time. With `webpack`, you can get the bootstrap time of a standalone Nest application (starter project with one module, controller, and service) down to \~32ms on average, and down to \~81.5ms for a regular HTTP, express-based NestJS app.

For more complicated Nest applications, for example, with 10 resources (generated through `$ nest g resource` schematic = 10 modules, 10 controllers, 10 services, 20 DTO classes, 50 HTTP endpoints + `AppModule`), the overall startup on MacBook Pro Mid 2014, 2.5 GHz Quad-Core Intel Core i7, 16 GB 1600 MHz DDR3, SSD is approximately 0.1298s (129.8ms). Running a monolithic application as a serverless function typically doesn't make too much sense anyway, so think of this benchmark more as an example of how the bootstrap time may potentially increase as your application grows.

#### Runtime optimizations[#](/faq/serverless#runtime-optimizations)

Thus far we covered compile-time optimizations. These are unrelated to the way you define providers and load Nest modules in your application, and that plays an essential role as your application gets bigger.

For example, imagine having a database connection defined as an [asynchronous provider](/v10/fundamentals/async-providers). Async providers are designed to delay the application start until one or more asynchronous tasks are completed. That means, if your serverless function on average requires 2s to connect to the database (on bootstrap), your endpoint will need at least two extra seconds (because it must wait till the connection is established) to send a response back (when it's a cold start and your application wasn't running already).

As you can see, the way you structure your providers is somewhat different in a **serverless environment** where bootstrap time is important. Another good example is if you use Redis for caching, but only in certain scenarios. Perhaps, in this case, you should not define a Redis connection as an async provider, as it would slow down the bootstrap time, even if it's not required for this specific function invocation.

Also, sometimes you could lazy load entire modules, using the `LazyModuleLoader` class, as described in [this chapter](/v10/fundamentals/lazy-loading-modules). Caching is a great example here too. Imagine that your application has, let's say, `CacheModule` which internally connects to Redis and also, exports the `CacheService` to interact with the Redis storage. If you don't need it for all potential function invocations, you can just load it on-demand, lazily. This way you'll get a faster startup time (when a cold start occurs) for all invocations that don't require caching.

```typescript

if (request.method === RequestMethod[RequestMethod.GET]) {
  const { CacheModule } = await import('./cache.module');
  const moduleRef = await this.lazyModuleLoader.load(() => CacheModule);

  const { CacheService } = await import('./cache.service');
  const cacheService = moduleRef.get(CacheService);

  return cacheService.get(ENDPOINT_KEY);
}
```

Another great example is a webhook or worker, which depending on some specific conditions (e.g., input arguments), may perform different operations. In such a case, you could specify a condition inside your route handler that lazily loads an appropriate module for the specific function invocation, and just load every other module lazily.

```typescript

if (workerType === WorkerType.A) {
  const { WorkerAModule } = await import('./worker-a.module');
  const moduleRef = await this.lazyModuleLoader.load(() => WorkerAModule);
  // ...
} else if (workerType === WorkerType.B) {
  const { WorkerBModule } = await import('./worker-b.module');
  const moduleRef = await this.lazyModuleLoader.load(() => WorkerBModule);
  // ...
}
```

#### Example integration[#](/faq/serverless#example-integration)

The way your application's entry file (typically `main.ts` file) is supposed to look like **depends on several factors** and so **there's no single template** that just works for every scenario. For example, the initialization file required to spin up your serverless function varies by cloud providers (AWS, Azure, GCP, etc.). Also, depending on whether you want to run a typical HTTP application with multiple routes/endpoints or just provide a single route (or execute a specific portion of code), your application's code will look different (for example, for the endpoint-per-function approach you could use the `NestFactory.createApplicationContext` instead of booting the HTTP server, setting up middleware, etc.).

Just for illustration purposes, we'll integrate Nest (using `@nestjs/platform-express` and so spinning up the whole, fully functional HTTP router) with the [Serverless](https://www.serverless.com/) framework (in this case, targeting AWS Lambda). As we've mentioned earlier, your code will differ depending on the cloud provider you choose, and many other factors.

First, let's install the required packages:

```bash

$ npm i @codegenie/serverless-express aws-lambda
$ npm i -D @types/aws-lambda serverless-offline
```

> **Hint** To speed up development cycles, we install the `serverless-offline` plugin which emulates AWS λ and API Gateway.

Once the installation process is complete, let's create the `serverless.yml` file to configure the Serverless framework:

```yaml

service: serverless-example

plugins:
  - serverless-offline

provider:
  name: aws
  runtime: nodejs14.x

functions:
  main:
    handler: dist/main.handler
    events:
      - http:
          method: ANY
          path: /
      - http:
          method: ANY
          path: '{proxy+}'
```

> **Hint** To learn more about the Serverless framework, visit the [official documentation](https://www.serverless.com/framework/docs/).

With this in place, we can now navigate to the `main.ts` file and update our bootstrap code with the required boilerplate:

```typescript

import { NestFactory } from '@nestjs/core';
import serverlessExpress from '@codegenie/serverless-express';
import { Callback, Context, Handler } from 'aws-lambda';
import { AppModule } from './app.module';

let server: Handler;

async function bootstrap(): Promise<Handler> {
  const app = await NestFactory.create(AppModule);
  await app.init();

  const expressApp = app.getHttpAdapter().getInstance();
  return serverlessExpress({ app: expressApp });
}

export const handler: Handler = async (
  event: any,
  context: Context,
  callback: Callback,
) => {
  server = server ?? (await bootstrap());
  return server(event, context, callback);
};
```

> **Hint** For creating multiple serverless functions and sharing common modules between them, we recommend using the [CLI Monorepo mode](/cli/monorepo#monorepo-mode).

> **Warning** If you use `@nestjs/swagger` package, there are a few additional steps required to make it work properly in the context of serverless function. Check out this [thread](https://github.com/nestjs/swagger/issues/199) for more information.

Next, open up the `tsconfig.json` file and make sure to enable the `esModuleInterop` option to make the `@codegenie/serverless-express` package load properly.

```json

{
  "compilerOptions": {
    ...
    "esModuleInterop": true
  }
}
```

Now we can build our application (with `nest build` or `tsc`) and use the `serverless` CLI to start our lambda function locally:

```bash

$ npm run build
$ npx serverless offline
```

Once the application is running, open your browser and navigate to `http://localhost:3000/dev/[ANY_ROUTE]` (where `[ANY_ROUTE]` is any endpoint registered in your application).

In the sections above, we've shown that using `webpack` and bundling your app can have significant impact on the overall bootstrap time. However, to make it work with our example, there are a few additional configurations you must add in your `webpack.config.js` file. Generally, to make sure our `handler` function will be picked up, we must change the `output.libraryTarget` property to `commonjs2`.

```javascript

return {
  ...options,
  externals: [],
  output: {
    ...options.output,
    libraryTarget: 'commonjs2',
  },
  // ... the rest of the configuration
};
```

With this in place, you can now use `$ nest build --webpack` to compile your function's code (and then `$ npx serverless offline` to test it).

It's also recommended (but **not required** as it will slow down your build process) to install the `terser-webpack-plugin` package and override its configuration to keep classnames intact when minifying your production build. Not doing so can result in incorrect behavior when using `class-validator` within your application.

```javascript

const TerserPlugin = require('terser-webpack-plugin');

return {
  ...options,
  externals: [],
  optimization: {
    minimizer: [
      new TerserPlugin({
        terserOptions: {
          keep_classnames: true,
        },
      }),
    ],
  },
  output: {
    ...options.output,
    libraryTarget: 'commonjs2',
  },
  // ... the rest of the configuration
};
```

#### Using standalone application feature[#](/faq/serverless#using-standalone-application-feature)

Alternatively, if you want to keep your function very lightweight and you don't need any HTTP-related features (routing, but also guards, interceptors, pipes, etc.), you can just use `NestFactory.createApplicationContext` (as mentioned earlier) instead of running the entire HTTP server (and `express` under the hood), as follows:

main.ts

JS TS

```typescript

import { HttpStatus } from '@nestjs/common';
import { NestFactory } from '@nestjs/core';
import { Callback, Context, Handler } from 'aws-lambda';
import { AppModule } from './app.module';
import { AppService } from './app.service';

export const handler: Handler = async (
  event: any,
  context: Context,
  callback: Callback,
) => {
  const appContext = await NestFactory.createApplicationContext(AppModule);
  const appService = appContext.get(AppService);

  return {
    body: appService.getHello(),
    statusCode: HttpStatus.OK,
  };
};
```

> **Hint** Be aware that `NestFactory.createApplicationContext` does not wrap controller methods with enhancers (guard, interceptors, etc.). For this, you must use the `NestFactory.create` method.

You could also pass the `event` object down to, let's say, `EventsService` provider that could process it and return a corresponding value (depending on the input value and your business logic).

```typescript

export const handler: Handler = async (
  event: any,
  context: Context,
  callback: Callback,
) => {
  const appContext = await NestFactory.createApplicationContext(AppModule);
  const eventsService = appContext.get(EventsService);
  return eventsService.process(event);
};
```

----
url: https://docs.nestjs.com/v10
----

* [Introduction](https://docs.nestjs.com/v10/#introduction)
* [Philosophy](https://docs.nestjs.com/v10/#philosophy)
* [Installation](https://docs.nestjs.com/v10/#installation)
* [Alternatives](https://docs.nestjs.com/v10/#alternatives)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/introduction.md "Suggest Edits")

### Introduction

Nest (NestJS) is a framework for building efficient, scalable [Node.js](https://nodejs.org/) server-side applications. It uses progressive JavaScript, is built with and fully supports [TypeScript](http://www.typescriptlang.org/) (yet still enables developers to code in pure JavaScript) and combines elements of OOP (Object Oriented Programming), FP (Functional Programming), and FRP (Functional Reactive Programming).

Under the hood, Nest makes use of robust HTTP Server frameworks like [Express](https://expressjs.com/) (the default) and optionally can be configured to use [Fastify](https://github.com/fastify/fastify) as well!

Nest provides a level of abstraction above these common Node.js frameworks (Express/Fastify), but also exposes their APIs directly to the developer. This gives developers the freedom to use the myriad of third-party modules which are available for the underlying platform.

#### Philosophy[#](/#philosophy)

In recent years, thanks to Node.js, JavaScript has become the “lingua franca” of the web for both front and backend applications. This has given rise to awesome projects like [Angular](https://angular.dev/), [React](https://github.com/facebook/react) and [Vue](https://github.com/vuejs/vue), which improve developer productivity and enable the creation of fast, testable, and extensible frontend applications. However, while plenty of superb libraries, helpers, and tools exist for Node (and server-side JavaScript), none of them effectively solve the main problem of **architecture**.

Nest provides an out-of-the-box application architecture which allows developers and teams to create highly testable, scalable, loosely coupled, and easily maintainable applications. The architecture is heavily inspired by Angular.

#### Installation[#](/#installation)

To get started, you can either scaffold the project with the [Nest CLI](/v10/cli/overview), or [clone a starter project](#alternatives) (both will produce the same outcome).

To scaffold the project with the Nest CLI, run the following commands. This will create a new project directory, and populate the directory with the initial core Nest files and supporting modules, creating a conventional base structure for your project. Creating a new project with the **Nest CLI** is recommended for first-time users. We'll continue with this approach in [First Steps](/v10/first-steps).

```bash

$ npm i -g @nestjs/cli
$ nest new project-name
```

> **Hint** To create a new TypeScript project with stricter feature set, pass the `--strict` flag to the `nest new` command.

#### Alternatives[#](/#alternatives)

Alternatively, to install the TypeScript starter project with **Git**:

```bash

$ git clone https://github.com/nestjs/typescript-starter.git project
$ cd project
$ npm install
$ npm run start
```

> **Hint** If you'd like to clone the repository without the git history, you can use [degit](https://github.com/Rich-Harris/degit).

Open your browser and navigate to [`http://localhost:3000/`](http://localhost:3000/).

To install the JavaScript flavor of the starter project, use `javascript-starter.git` in the command sequence above.

You can also start a new project from scratch by installing the core and supporting packages. Keep in mind that you'll need to set up the project boilerplate files on your own. At a minimum, you'll need these dependencies: `@nestjs/core`, `@nestjs/common`, `rxjs`, and `reflect-metadata`. Check out this short article on how to create a complete project: [5 steps to create a bare minimum NestJS app from scratch!](https://dev.to/micalevisk/5-steps-to-create-a-bare-minimum-nestjs-app-from-scratch-5c3b).

----
url: https://docs.nestjs.com/v10/graphql/plugins
----

* [Plugins with Apollo](https://docs.nestjs.com/v10/graphql/plugins#plugins-with-apollo)
* [Custom plugins](https://docs.nestjs.com/v10/graphql/plugins#custom-plugins)
* [Using external plugins](https://docs.nestjs.com/v10/graphql/plugins#using-external-plugins)
* [Plugins with Mercurius](https://docs.nestjs.com/v10/graphql/plugins#plugins-with-mercurius)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/plugins.md "Suggest Edits")

### Plugins with Apollo

Plugins enable you to extend Apollo Server's core functionality by performing custom operations in response to certain events. Currently, these events correspond to individual phases of the GraphQL request lifecycle, and to the startup of Apollo Server itself (read more [here](https://www.apollographql.com/docs/apollo-server/integrations/plugins/)). For example, a basic logging plugin might log the GraphQL query string associated with each request that's sent to Apollo Server.

#### Custom plugins[#](/graphql/plugins#custom-plugins)

To create a plugin, declare a class annotated with the `@Plugin` decorator exported from the `@nestjs/apollo` package. Also, for better code autocompletion, implement the `ApolloServerPlugin` interface from the `@apollo/server` package.

```typescript

import { ApolloServerPlugin, GraphQLRequestListener } from '@apollo/server';
import { Plugin } from '@nestjs/apollo';

@Plugin()
export class LoggingPlugin implements ApolloServerPlugin {
  async requestDidStart(): Promise<GraphQLRequestListener<any>> {
    console.log('Request started');
    return {
      async willSendResponse() {
        console.log('Will send response');
      },
    };
  }
}
```

With this in place, we can register the `LoggingPlugin` as a provider.

```typescript

@Module({
  providers: [LoggingPlugin],
})
export class CommonModule {}
```

Nest will automatically instantiate a plugin and apply it to the Apollo Server.

#### Using external plugins[#](/graphql/plugins#using-external-plugins)

There are several plugins provided out-of-the-box. To use an existing plugin, simply import it and add it to the `plugins` array:

```typescript

GraphQLModule.forRoot({
  // ...
  plugins: [ApolloServerOperationRegistry({ /* options */})]
}),
```

> **Hint** The `ApolloServerOperationRegistry` plugin is exported from the `@apollo/server-plugin-operation-registry` package.

#### Plugins with Mercurius[#](/graphql/plugins#plugins-with-mercurius)

Some of the existing mercurius-specific Fastify plugins must be loaded after the mercurius plugin (read more [here](https://mercurius.dev/#/docs/plugins)) on the plugin tree.

> **Warning**[mercurius-upload](https://github.com/mercurius-js/mercurius-upload) is an exception and should be registered in the main file.

For this, `MercuriusDriver` exposes an optional `plugins` configuration option. It represents an array of objects that consist of two attributes: `plugin` and its `options`. Therefore, registering the [cache plugin](https://github.com/mercurius-js/cache) would look like this:

```typescript

GraphQLModule.forRoot({
  driver: MercuriusDriver,
  // ...
  plugins: [
    {
      plugin: cache,
      options: {
        ttl: 10,
        policy: {
          Query: {
            add: true
          }
        }
      },
    }
  ]
}),
```

----
url: https://docs.nestjs.com/v9/graphql/quick-start
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Installation](https://docs.nestjs.com/v9/graphql/quick-start#installation)
* [Overview](https://docs.nestjs.com/v9/graphql/quick-start#overview)
* [Getting started with GraphQL & TypeScript](https://docs.nestjs.com/v9/graphql/quick-start#getting-started-with-graphql--typescript)
* [GraphQL playground](https://docs.nestjs.com/v9/graphql/quick-start#graphql-playground)
* [Multiple endpoints](https://docs.nestjs.com/v9/graphql/quick-start#multiple-endpoints)
* [Code first](https://docs.nestjs.com/v9/graphql/quick-start#code-first)
* [Example](https://docs.nestjs.com/v9/graphql/quick-start#example)
* [Schema first](https://docs.nestjs.com/v9/graphql/quick-start#schema-first)
* [Apollo Sandbox](https://docs.nestjs.com/v9/graphql/quick-start#apollo-sandbox)
* [Example](https://docs.nestjs.com/v9/graphql/quick-start#example-1)
* [Accessing generated schema](https://docs.nestjs.com/v9/graphql/quick-start#accessing-generated-schema)
* [Async configuration](https://docs.nestjs.com/v9/graphql/quick-start#async-configuration)
* [Mercurius integration](https://docs.nestjs.com/v9/graphql/quick-start#mercurius-integration)
* [Third-party integrations](https://docs.nestjs.com/v9/graphql/quick-start#third-party-integrations)
* [Example](https://docs.nestjs.com/v9/graphql/quick-start#example-2)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/quick-start.md "Suggest Edits")

## Harnessing the power of TypeScript & GraphQL

[GraphQL](https://graphql.org/) is a powerful query language for APIs and a runtime for fulfilling those queries with your existing data. It's an elegant approach that solves many problems typically found with REST APIs. For background, we suggest reading this [comparison](https://dev-blog.apollodata.com/graphql-vs-rest-5d425123e34b) between GraphQL and REST. GraphQL combined with [TypeScript](https://www.typescriptlang.org/) helps you develop better type safety with your GraphQL queries, giving you end-to-end typing.

In this chapter, we assume a basic understanding of GraphQL, and focus on how to work with the built-in `@nestjs/graphql` module. The `GraphQLModule` can be configured to use [Apollo](https://www.apollographql.com/) server (with the `@nestjs/apollo` driver) and [Mercurius](https://github.com/mercurius-js/mercurius) (with the `@nestjs/mercurius`). We provide official integrations for these proven GraphQL packages to provide a simple way to use GraphQL with Nest (see more integrations [here](https://docs.nestjs.com/graphql/quick-start#third-party-integrations)).

You can also build your own dedicated driver (read more on that [here](/graphql/other-features#creating-a-custom-driver)).

#### Installation[#](/graphql/quick-start#installation)

Start by installing the required packages:

```bash

# For Express and Apollo (default)
$ npm i @nestjs/graphql @nestjs/apollo @apollo/server graphql

# For Fastify and Apollo
# npm i @nestjs/graphql @nestjs/apollo @apollo/server @as-integrations/fastify graphql

# For Fastify and Mercurius
# npm i @nestjs/graphql @nestjs/mercurius graphql mercurius
```

> **Warning**`@nestjs/graphql@>=9` and `@nestjs/apollo^10` packages are compatible with **Apollo v3** (check out Apollo Server 3 [migration guide](https://www.apollographql.com/docs/apollo-server/migration/) for more details), while `@nestjs/graphql@^8` only supports **Apollo v2** (e.g., `apollo-server-express@2.x.x` package).

> **Hint** In the following chapters, we'll be integrating the `@nestjs/apollo` package. If you want to use `mercurius` package instead, navigate to [this section](/graphql/quick-start#mercurius-integration).

Once the packages are installed, we can import the `GraphQLModule` and configure it with the `forRoot()` static method.

JS TS

```typescript

import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';
import { ApolloDriver, ApolloDriverConfig } from '@nestjs/apollo';

@Module({
  imports: [
    GraphQLModule.forRoot<ApolloDriverConfig>({
      driver: ApolloDriver,
    }),
  ],
})
export class AppModule {}
```

> **Hint** For `mercurius` integration, you should be using the `MercuriusDriver` and `MercuriusDriverConfig` instead. Both are exported from the `@nestjs/mercurius` package.

The `forRoot()` method takes an options object as an argument. These options are passed through to the underlying driver instance (read more about available settings here: [Apollo](https://www.apollographql.com/docs/apollo-server/v2/api/apollo-server.html#constructor-options-lt-ApolloServer-gt) and [Mercurius](https://github.com/mercurius-js/mercurius/blob/master/docs/api/options.md#plugin-options)). For example, if you want to disable the `playground` and turn off `debug` mode (for Apollo), pass the following options:

JS TS

```typescript

import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';
import { ApolloDriver, ApolloDriverConfig } from '@nestjs/apollo';

@Module({
  imports: [
    GraphQLModule.forRoot<ApolloDriverConfig>({
      driver: ApolloDriver,
      playground: false,
    }),
  ],
})
export class AppModule {}
```

In this case, these options will be forwarded to the `ApolloServer` constructor.

#### GraphQL playground[#](/graphql/quick-start#graphql-playground)

The playground is a graphical, interactive, in-browser GraphQL IDE, available by default on the same URL as the GraphQL server itself. To access the playground, you need a basic GraphQL server configured and running. To see it now, you can install and build the [working example here](https://github.com/nestjs/nest/tree/master/sample/23-graphql-code-first). Alternatively, if you're following along with these code samples, once you've completed the steps in the [Resolvers chapter](/v9/graphql/resolvers-map), you can access the playground.

With that in place, and with your application running in the background, you can then open your web browser and navigate to `http://localhost:3000/graphql` (host and port may vary depending on your configuration). You will then see the GraphQL playground, as shown below.

> **Note**`@nestjs/mercurius` integration does not ship with the built-in GraphQL Playground integration. Instead, you can use [GraphiQL](https://github.com/graphql/graphiql) (set `graphiql: true`).

#### Multiple endpoints[#](/graphql/quick-start#multiple-endpoints)

Another useful feature of the `@nestjs/graphql` module is the ability to serve multiple endpoints at once. This lets you decide which modules should be included in which endpoint. By default, `GraphQL` searches for resolvers throughout the whole app. To limit this scan to only a subset of modules, use the `include` property.

```typescript

GraphQLModule.forRoot({
  include: [CatsModule],
}),
```

> **Warning** If you use the `@apollo/server` with `@as-integrations/fastify` package with multiple GraphQL endpoints in a single application, make sure to enable the `disableHealthCheck` setting in the `GraphQLModule` configuration.

#### Code first[#](/graphql/quick-start#code-first)

In the **code first** approach, you use decorators and TypeScript classes to generate the corresponding GraphQL schema.

To use the code first approach, start by adding the `autoSchemaFile` property to the options object:

```typescript

GraphQLModule.forRoot<ApolloDriverConfig>({
  driver: ApolloDriver,
  autoSchemaFile: join(process.cwd(), 'src/schema.gql'),
}),
```

The `autoSchemaFile` property value is the path where your automatically generated schema will be created. Alternatively, the schema can be generated on-the-fly in memory. To enable this, set the `autoSchemaFile` property to `true`:

```typescript

GraphQLModule.forRoot<ApolloDriverConfig>({
  driver: ApolloDriver,
  autoSchemaFile: true,
}),
```

By default, the types in the generated schema will be in the order they are defined in the included modules. To sort the schema lexicographically, set the `sortSchema` property to `true`:

```typescript

GraphQLModule.forRoot<ApolloDriverConfig>({
  driver: ApolloDriver,
  autoSchemaFile: join(process.cwd(), 'src/schema.gql'),
  sortSchema: true,
}),
```

#### Example[#](/graphql/quick-start#example)

A fully working code first sample is available [here](https://github.com/nestjs/nest/tree/master/sample/23-graphql-code-first).

#### Schema first[#](/graphql/quick-start#schema-first)

To use the schema first approach, start by adding a `typePaths` property to the options object. The `typePaths` property indicates where the `GraphQLModule` should look for GraphQL SDL schema definition files you'll be writing. These files will be combined in memory; this allows you to split your schemas into several files and locate them near their resolvers.

```typescript

GraphQLModule.forRoot<ApolloDriverConfig>({
  driver: ApolloDriver,
  typePaths: ['./**/*.graphql'],
}),
```

You will typically also need to have TypeScript definitions (classes and interfaces) that correspond to the GraphQL SDL types. Creating the corresponding TypeScript definitions by hand is redundant and tedious. It leaves us without a single source of truth -- each change made within SDL forces us to adjust TypeScript definitions as well. To address this, the `@nestjs/graphql` package can **automatically generate** TypeScript definitions from the abstract syntax tree ([AST](https://en.wikipedia.org/wiki/Abstract_syntax_tree)). To enable this feature, add the `definitions` options property when configuring the `GraphQLModule`.

```typescript

GraphQLModule.forRoot<ApolloDriverConfig>({
  driver: ApolloDriver,
  typePaths: ['./**/*.graphql'],
  definitions: {
    path: join(process.cwd(), 'src/graphql.ts'),
  },
}),
```

The path property of the `definitions` object indicates where to save generated TypeScript output. By default, all generated TypeScript types are created as interfaces. To generate classes instead, specify the `outputAs` property with a value of `'class'`.

```typescript

GraphQLModule.forRoot<ApolloDriverConfig>({
  driver: ApolloDriver,
  typePaths: ['./**/*.graphql'],
  definitions: {
    path: join(process.cwd(), 'src/graphql.ts'),
    outputAs: 'class',
  },
}),
```

The above approach dynamically generates TypeScript definitions each time the application starts. Alternatively, it may be preferable to build a simple script to generate these on demand. For example, assume we create the following script as `generate-typings.ts`:

```typescript

import { GraphQLDefinitionsFactory } from '@nestjs/graphql';
import { join } from 'path';

const definitionsFactory = new GraphQLDefinitionsFactory();
definitionsFactory.generate({
  typePaths: ['./src/**/*.graphql'],
  path: join(process.cwd(), 'src/graphql.ts'),
  outputAs: 'class',
});
```

Now you can run this script on demand:

```bash

$ ts-node generate-typings
```

> **Hint** You can compile the script beforehand (e.g., with `tsc`) and use `node` to execute it.

To enable watch mode for the script (to automatically generate typings whenever any `.graphql` file changes), pass the `watch` option to the `generate()` method.

```typescript

definitionsFactory.generate({
  typePaths: ['./src/**/*.graphql'],
  path: join(process.cwd(), 'src/graphql.ts'),
  outputAs: 'class',
  watch: true,
});
```

To automatically generate the additional `__typename` field for every object type, enable the `emitTypenameField` option.

```typescript

definitionsFactory.generate({
  // ...,
  emitTypenameField: true,
});
```

To generate resolvers (queries, mutations, subscriptions) as plain fields without arguments, enable the `skipResolverArgs` option.

```typescript

definitionsFactory.generate({
  // ...,
  skipResolverArgs: true,
});
```

#### Apollo Sandbox[#](/graphql/quick-start#apollo-sandbox)

To use [Apollo Sandbox](https://www.apollographql.com/blog/announcement/platform/apollo-sandbox-an-open-graphql-ide-for-local-development/) instead of the `graphql-playground` as a GraphQL IDE for local development, use the following configuration:

```typescript

import { ApolloDriver, ApolloDriverConfig } from '@nestjs/apollo';
import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';
import { ApolloServerPluginLandingPageLocalDefault } from '@apollo/server/plugin/landingPage/default';

@Module({
  imports: [
    GraphQLModule.forRoot<ApolloDriverConfig>({
      driver: ApolloDriver,
      playground: false,
      plugins: [ApolloServerPluginLandingPageLocalDefault()],
    }),
  ],
})
export class AppModule {}
```

#### Example[#](/graphql/quick-start#example-1)

A fully working schema first sample is available [here](https://github.com/nestjs/nest/tree/master/sample/12-graphql-schema-first).

#### Accessing generated schema[#](/graphql/quick-start#accessing-generated-schema)

In some circumstances (for example end-to-end tests), you may want to get a reference to the generated schema object. In end-to-end tests, you can then run queries using the `graphql` object without using any HTTP listeners.

You can access the generated schema (in either the code first or schema first approach), using the `GraphQLSchemaHost` class:

```typescript

const { schema } = app.get(GraphQLSchemaHost);
```

> **Hint** You must call the `GraphQLSchemaHost#schema` getter after the application has been initialized (after the `onModuleInit` hook has been triggered by either the `app.listen()` or `app.init()` method).

#### Async configuration[#](/graphql/quick-start#async-configuration)

When you need to pass module options asynchronously instead of statically, use the `forRootAsync()` method. As with most dynamic modules, Nest provides several techniques to deal with async configuration.

One technique is to use a factory function:

```typescript

 GraphQLModule.forRootAsync<ApolloDriverConfig>({
  driver: ApolloDriver,
  useFactory: () => ({
    typePaths: ['./**/*.graphql'],
  }),
}),
```

Like other factory providers, our factory function can be [async](https://docs.nestjs.com/fundamentals/custom-providers#factory-providers-usefactory) and can inject dependencies through `inject`.

```typescript

GraphQLModule.forRootAsync<ApolloDriverConfig>({
  driver: ApolloDriver,
  imports: [ConfigModule],
  useFactory: async (configService: ConfigService) => ({
    typePaths: configService.get<string>('GRAPHQL_TYPE_PATHS'),
  }),
  inject: [ConfigService],
}),
```

Alternatively, you can configure the `GraphQLModule` using a class instead of a factory, as shown below:

```typescript

GraphQLModule.forRootAsync<ApolloDriverConfig>({
  driver: ApolloDriver,
  useClass: GqlConfigService,
}),
```

The construction above instantiates `GqlConfigService` inside `GraphQLModule`, using it to create options object. Note that in this example, the `GqlConfigService` has to implement the `GqlOptionsFactory` interface, as shown below. The `GraphQLModule` will call the `createGqlOptions()` method on the instantiated object of the supplied class.

```typescript

@Injectable()
class GqlConfigService implements GqlOptionsFactory {
  createGqlOptions(): ApolloDriverConfig {
    return {
      typePaths: ['./**/*.graphql'],
    };
  }
}
```

If you want to reuse an existing options provider instead of creating a private copy inside the `GraphQLModule`, use the `useExisting` syntax.

```typescript

GraphQLModule.forRootAsync<ApolloDriverConfig>({
  imports: [ConfigModule],
  useExisting: ConfigService,
}),
```

#### Mercurius integration[#](/graphql/quick-start#mercurius-integration)

Instead of using Apollo, Fastify users (read more [here](/v9/techniques/performance)) can alternatively use the `@nestjs/mercurius` driver.

JS TS

```typescript

import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';
import { MercuriusDriver, MercuriusDriverConfig } from '@nestjs/mercurius';

@Module({
  imports: [
    GraphQLModule.forRoot<MercuriusDriverConfig>({
      driver: MercuriusDriver,
      graphiql: true,
    }),
  ],
})
export class AppModule {}
```

> **Hint** Once the application is running, open your browser and navigate to `http://localhost:3000/graphiql`. You should see the [GraphQL IDE](https://github.com/graphql/graphiql).

The `forRoot()` method takes an options object as an argument. These options are passed through to the underlying driver instance. Read more about available settings [here](https://github.com/mercurius-js/mercurius/blob/master/docs/api/options.md#plugin-options).

#### Third-party integrations[#](/graphql/quick-start#third-party-integrations)

* [GraphQL Yoga](https://github.com/charlypoly/graphql-yoga-nestjs)

#### Example[#](/graphql/quick-start#example-2)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/33-graphql-mercurius).

----
url: https://docs.nestjs.com/v10/recipes/async-local-storage
----

* [Async Local Storage](https://docs.nestjs.com/v10/recipes/async-local-storage#async-local-storage)
* [Custom implementation](https://docs.nestjs.com/v10/recipes/async-local-storage#custom-implementation)
* [NestJS CLS](https://docs.nestjs.com/v10/recipes/async-local-storage#nestjs-cls)
* [Installation](https://docs.nestjs.com/v10/recipes/async-local-storage#installation)
* [Usage](https://docs.nestjs.com/v10/recipes/async-local-storage#usage)
* [Testing](https://docs.nestjs.com/v10/recipes/async-local-storage#testing)
* [More information](https://docs.nestjs.com/v10/recipes/async-local-storage#more-information)

> **info** For a ready-made [dedicated package](recipes/async-local-storage#nestjs-cls), continue reading below.

1. First, create a new instance of the `AsyncLocalStorage` in some shared source file. Since we're using NestJS, let's also turn it into a module with a custom provider.

als.module.ts

JS TS

```ts

@Module({
  providers: [
    {
      provide: AsyncLocalStorage,
      useValue: new AsyncLocalStorage(),
    },
  ],
  exports: [AsyncLocalStorage],
})
export class AlsModule {}
```

> **Hint**`AsyncLocalStorage` is imported from `async_hooks`.

2. We're only concerned with HTTP, so let's use a middleware to wrap the `next` function with `AsyncLocalStorage#run`. Since a middleware is the first thing that the request hits, this will make the `store` available in all enhancers and the rest of the system.

app.module.ts

JS TS

```typescript

@Module({
  imports: [AlsModule]
  providers: [CatService],
  controllers: [CatController],
})
export class AppModule implements NestModule {
  constructor(
    // inject the AsyncLocalStorage in the module constructor,
    private readonly als: AsyncLocalStorage
  ) {}

  configure(consumer: MiddlewareConsumer) {
    // bind the middleware,
    consumer
      .apply((req, res, next) => {
        // populate the store with some default values
        // based on the request,
        const store = {
          userId: req.headers['x-user-id'],
        };
        // and pass the "next" function as callback
        // to the "als.run" method together with the store.
        this.als.run(store, () => next());
      })
      // and register it for all routes (in case of Fastify use '(.*)')
      .forRoutes('*');
  }
}
```

```typescript

@Module({
  imports: [AlsModule]
  providers: [CatService],
  controllers: [CatController],
})
@Dependencies(AsyncLocalStorage)
export class AppModule {
  constructor(als) {
    // inject the AsyncLocalStorage in the module constructor,
    this.als = als
  }

  configure(consumer) {
    // bind the middleware,
    consumer
      .apply((req, res, next) => {
        // populate the store with some default values
        // based on the request,
        const store = {
          userId: req.headers['x-user-id'],
        };
        // and pass the "next" function as callback
        // to the "als.run" method together with the store.
        this.als.run(store, () => next());
      })
      // and register it for all routes (in case of Fastify use '(.*)')
      .forRoutes('*');
  }
}
```

3. Now, anywhere within the lifecycle of a request, we can access the local store instance.

cat.service.ts

JS TS

```typescript

@Injectable()
export class CatService {
  constructor(
    // We can inject the provided ALS instance.
    private readonly als: AsyncLocalStorage,
    private readonly catRepository: CatRepository,
  ) {}

  getCatForUser() {
    // The "getStore" method will always return the
    // store instance associated with the given request.
    const userId = this.als.getStore()["userId"] as number;
    return this.catRepository.getForUser(userId);
  }
}
```

```typescript

@Injectable()
@Dependencies(AsyncLocalStorage, CatRepository)
export class CatService {
  constructor(als, catRepository) {
    // We can inject the provided ALS instance.
    this.als = als
    this.catRepository = catRepository
  }

  getCatForUser() {
    // The "getStore" method will always return the
    // store instance associated with the given request.
    const userId = this.als.getStore()["userId"] as number;
    return this.catRepository.getForUser(userId);
  }
}
```

4. That's it. Now we have a way to share request related state without needing to inject the whole `REQUEST` object.

> **warning** Please be aware that while the technique is useful for many use-cases, it inherently obfuscates the code flow (creating implicit context), so use it responsibly and especially avoid creating contextual "[God objects](https://en.wikipedia.org/wiki/God_object)".

### NestJS CLS

The [nestjs-cls](https://github.com/Papooch/nestjs-cls) package provides several DX improvements over using plain `AsyncLocalStorage` (`CLS` is an abbreviation of the term *continuation-local storage*). It abstracts the implementation into a `ClsModule` that offers various ways of initializing the `store` for different transports (not only HTTP), as well as a strong-typing support.

The store can then be accessed with an injectable `ClsService`, or entirely abstracted away from the business logic by using [Proxy Providers](https://www.npmjs.com/package/nestjs-cls#proxy-providers).

> **info**`nestjs-cls` is a third party package and is not managed by the NestJS core team. Please, report any issues found with the library in the [appropriate repository](https://github.com/Papooch/nestjs-cls/issues).

#### Installation[#](/recipes/async-local-storage#installation)

Apart from a peer dependency on the `@nestjs` libs, it only uses the built-in Node.js API. Install it as any other package.

```bash

npm i nestjs-cls
```

#### Usage[#](/recipes/async-local-storage#usage)

A similar functionality as described [above](recipes/async-local-storage#custom-implementation) can be implemented using `nestjs-cls` as follows:

1. Import the `ClsModule` in the root module.

app.module.ts

JS TS

```ts

@Module({
  imports: [
    // Register the ClsModule,
    ClsModule.forRoot({
      middleware: {
        // automatically mount the
        // ClsMiddleware for all routes
        mount: true,
        // and use the setup method to
        // provide default store values.
        setup: (cls, req) => {
          cls.set('userId', req.headers['x-user-id']);
        },
      },
    }),
  ],
  providers: [CatService],
  controllers: [CatController],
})
export class AppModule {}
```

2. And then can use the `ClsService` to access the store values.

cat.service.ts

JS TS

```typescript

@Injectable()
export class CatService {
  constructor(
    // We can inject the provided ClsService instance,
    private readonly cls: ClsService,
    private readonly catRepository: CatRepository,
  ) {}

  getCatForUser() {
    // and use the "get" method to retrieve any stored value.
    const userId = this.cls.get('userId');
    return this.catRepository.getForUser(userId);
  }
}
```

```typescript

@Injectable()
@Dependencies(AsyncLocalStorage, CatRepository)
export class CatService {
  constructor(cls, catRepository) {
    // We can inject the provided ClsService instance,
    this.cls = cls
    this.catRepository = catRepository
  }

  getCatForUser() {
    // and use the "get" method to retrieve any stored value.
    const userId = this.cls.get('userId');
    return this.catRepository.getForUser(userId);
  }
}
```

3. To get strong typing of the store values managed by the `ClsService` (and also get auto-suggestions of the string keys), we can use an optional type parameter `ClsService<MyClsStore>` when injecting it.

```ts

export interface MyClsStore extends ClsStore {
  userId: number;
}
```

> **hint** It it also possible to let the package automatically generate a Request ID and access it later with `cls.getId()`, or to get the whole Request object using `cls.get(CLS_REQ)`.

#### Testing[#](/recipes/async-local-storage#testing)

Since the `ClsService` is just another injectable provider, it can be entirely mocked out in unit tests.

However, in certain integration tests, we might still want to use the real `ClsService` implementation. In that case, we will need to wrap the context-aware piece of code with a call to `ClsService#run` or `ClsService#runWith`.

```ts

describe('CatService', () => {
  let service: CatService
  let cls: ClsService
  const mockCatRepository = createMock<CatRepository>()

  beforeEach(async () => {
    const module = await Test.createTestingModule({
      // Set up most of the testing module as we normally would.
      providers: [
        CatService,
        {
          provide: CatRepository
          useValue: mockCatRepository
        }
      ],
      imports: [
        // Import the static version of ClsModule which only provides
        // the ClsService, but does not set up the store in any way.
        ClsModule
      ],
    }).compile()

    service = module.get(CatService)

    // Also retrieve the ClsService for later use.
    cls = module.get(ClsService)
  })

  describe('getCatForUser', () => {
    it('retrieves cat based on user id', async () => {
      const expectedUserId = 42
      mockCatRepository.getForUser.mockImplementationOnce(
        (id) => ({ userId: id })
      )

      // Wrap the test call in the `runWith` method
      // in which we can pass hand-crafted store values.
      const cat = await cls.runWith(
        { userId: expectedUserId },
        () => service.getCatForUser()
      )

      expect(cat.userId).toEqual(expectedUserId)
    })
  })
})
```

#### More information[#](/recipes/async-local-storage#more-information)

Visit the [NestJS CLS GitHub Page](https://github.com/Papooch/nestjs-cls) for the full API documentation and more code examples.

----
url: https://docs.nestjs.com/v9/recipes/sql-typeorm
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [SQL (TypeORM)](https://docs.nestjs.com/v9/recipes/sql-typeorm#sql-typeorm)
* [Getting started](https://docs.nestjs.com/v9/recipes/sql-typeorm#getting-started)
* [Repository pattern](https://docs.nestjs.com/v9/recipes/sql-typeorm#repository-pattern)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/recipes/sql-typeorm.md "Suggest Edits")

### SQL (TypeORM)

##### This chapter applies only to TypeScript

> **Warning** In this article, you'll learn how to create a `DatabaseModule` based on the **TypeORM** package from scratch using custom providers mechanism. As a consequence, this solution contains a lot of overhead that you can omit using ready to use and available out-of-the-box dedicated `@nestjs/typeorm` package. To learn more, see [here](/v9/techniques/sql).

[TypeORM](https://github.com/typeorm/typeorm) is definitely the most mature Object Relational Mapper (ORM) available in the node.js world. Since it's written in TypeScript, it works pretty well with the Nest framework.

#### Getting started[#](/recipes/sql-typeorm#getting-started)

To start the adventure with this library we have to install all required dependencies:

```bash

$ npm install --save typeorm mysql2
```

The first step we need to do is to establish the connection with our database using `new DataSource().initialize()` class imported from the `typeorm` package. The `initialize()` function returns a `Promise`, and therefore we have to create an [async provider](/v9/fundamentals/async-components).

database.providers.ts

JS TS

```typescript

import { DataSource } from 'typeorm';

export const databaseProviders = [
  {
    provide: 'DATA_SOURCE',
    useFactory: async () => {
      const dataSource = new DataSource({
        type: 'mysql',
        host: 'localhost',
        port: 3306,
        username: 'root',
        password: 'root',
        database: 'test',
        entities: [
            __dirname + '/../**/*.entity{.ts,.js}',
        ],
        synchronize: true,
      });

      return dataSource.initialize();
    },
  },
];
```

> **Warning** Setting `synchronize: true` shouldn't be used in production - otherwise you can lose production data.

> **Hint** Following best practices, we declared the custom provider in the separated file which has a `*.providers.ts` suffix.

Then, we need to export these providers to make them **accessible** for the rest of the application.

database.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { databaseProviders } from './database.providers';

@Module({
  providers: [...databaseProviders],
  exports: [...databaseProviders],
})
export class DatabaseModule {}
```

Now we can inject the `DATA_SOURCE` object using `@Inject()` decorator. Each class that would depend on the `DATA_SOURCE` async provider will wait until a `Promise` is resolved.

#### Repository pattern[#](/recipes/sql-typeorm#repository-pattern)

The [TypeORM](https://github.com/typeorm/typeorm) supports the repository design pattern, thus each entity has its own Repository. These repositories can be obtained from the database connection.

But firstly, we need at least one entity. We are going to reuse the `Photo` entity from the official documentation.

photo.entity.ts

JS TS

```typescript

import { Entity, Column, PrimaryGeneratedColumn } from 'typeorm';

@Entity()
export class Photo {
  @PrimaryGeneratedColumn()
  id: number;

  @Column({ length: 500 })
  name: string;

  @Column('text')
  description: string;

  @Column()
  filename: string;

  @Column('int')
  views: number;

  @Column()
  isPublished: boolean;
}
```

The `Photo` entity belongs to the `photo` directory. This directory represents the `PhotoModule`. Now, let's create a **Repository** provider:

photo.providers.ts

JS TS

```typescript

import { DataSource } from 'typeorm';
import { Photo } from './photo.entity';

export const photoProviders = [
  {
    provide: 'PHOTO_REPOSITORY',
    useFactory: (dataSource: DataSource) => dataSource.getRepository(Photo),
    inject: ['DATA_SOURCE'],
  },
];
```

> **Warning** In the real-world applications you should avoid **magic strings**. Both `PHOTO_REPOSITORY` and `DATA_SOURCE` should be kept in the separated `constants.ts` file.

Now we can inject the `Repository<Photo>` to the `PhotoService` using the `@Inject()` decorator:

photo.service.ts

JS TS

```typescript

import { Injectable, Inject } from '@nestjs/common';
import { Repository } from 'typeorm';
import { Photo } from './photo.entity';

@Injectable()
export class PhotoService {
  constructor(
    @Inject('PHOTO_REPOSITORY')
    private photoRepository: Repository<Photo>,
  ) {}

  async findAll(): Promise<Photo[]> {
    return this.photoRepository.find();
  }
}
```

The database connection is **asynchronous**, but Nest makes this process completely invisible for the end-user. The `PhotoRepository` is waiting for the db connection, and the `PhotoService` is delayed until repository is ready to use. The entire application can start when each class is instantiated.

Here is a final `PhotoModule`:

photo.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { DatabaseModule } from '../database/database.module';
import { photoProviders } from './photo.providers';
import { PhotoService } from './photo.service';

@Module({
  imports: [DatabaseModule],
  providers: [
    ...photoProviders,
    PhotoService,
  ],
})
export class PhotoModule {}
```

> **Hint** Do not forget to import the `PhotoModule` into the root `AppModule`.

----
url: https://docs.nestjs.com/v6/websockets/adapter
----

* [Adapters](https://docs.nestjs.com/v6/websockets/adapter#adapters)
* [Extend socket.io](https://docs.nestjs.com/v6/websockets/adapter#extend-socketio)
* [Ws library](https://docs.nestjs.com/v6/websockets/adapter#ws-library)
* [Advanced (custom adapter)](https://docs.nestjs.com/v6/websockets/adapter#advanced-custom-adapter)
* [Example](https://docs.nestjs.com/v6/websockets/adapter#example)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/websockets/adapter.md "Suggest Edits")

### Adapters

The WebSockets module is platform-agnostic, hence, you can bring your own library (or even a native implementation) by making use of `WebSocketAdapter` interface. This interface forces to implement few methods described in the following table:

|                        |                                                                 |
| ---------------------- | --------------------------------------------------------------- |
| `create`               | Creates a socket instance based on passed arguments             |
| `bindClientConnect`    | Binds the client connection event                               |
| `bindClientDisconnect` | Binds the client disconnection event (optional\*)               |
| `bindMessageHandlers`  | Binds the incoming message to the corresponding message handler |
| `close`                | Terminates a server instance                                    |

#### Extend socket.io[#](/websockets/adapter#extend-socketio)

The [socket.io](https://github.com/socketio/socket.io) package is wrapped in an `IoAdapter` class. What if you would like to enhance the basic functionality of the adapter? For instance, your technical requirements require a capability to broadcast events across multiple load-balanced instances of your web service. For this, you can extend `IoAdapter` and override a single method which responsibility is to instantiate new socket.io servers. But first of all, let's install the required package.

```bash

$ npm i --save socket.io-redis
```

Once the package is installed, we can create a `RedisIoAdapter` class.

```typescript

import { IoAdapter } from '@nestjs/platform-socket.io';
import * as redisIoAdapter from 'socket.io-redis';

const redisAdapter = redisIoAdapter({ host: 'localhost', port: 6379 });

export class RedisIoAdapter extends IoAdapter {
  createIOServer(port: number, options?: any): any {
    const server = super.createIOServer(port, options);
    server.adapter(redisAdapter);
    return server;
  }
}
```

Afterward, simply switch to your newly created Redis adapter.

```typescript

const app = await NestFactory.create(ApplicationModule);
app.useWebSocketAdapter(new RedisIoAdapter(app));
```

#### Ws library[#](/websockets/adapter#ws-library)

Another available adapter is a `WsAdapter` which in turn acts like a proxy between the framework and integrate blazing fast and thoroughly tested [ws](https://github.com/websockets/ws) library. This adapter is fully compatible with native browser WebSockets and is far faster than socket.io package. Unluckily, it has significantly fewer functionalities available out-of-the-box. In some cases, you may just don't necessarily need them though.

In order to use `ws`, we firstly have to install the required package:

```bash

$ npm i --save @nestjs/platform-ws
```

Once the package is installed, we can switch an adapter:

```typescript

const app = await NestFactory.create(ApplicationModule);
app.useWebSocketAdapter(new WsAdapter(app));
```

> **Hint** The `WsAdapter` is imported from `@nestjs/platform-ws`.

#### Advanced (custom adapter)[#](/websockets/adapter#advanced-custom-adapter)

For demonstration purposes, we are going to integrate the [ws](https://github.com/websockets/ws) library manually. As mentioned, the adapter for this library is already created and is exposed from the `@nestjs/platform-ws` package as a `WsAdapter` class. Here is how the simplified implementation could potentially look like:

ws-adapter.ts

JS TS

```typescript

import * as WebSocket from 'ws';
import { WebSocketAdapter, INestApplicationContext } from '@nestjs/common';
import { MessageMappingProperties } from '@nestjs/websockets';
import { Observable, fromEvent, EMPTY } from 'rxjs';
import { mergeMap, filter } from 'rxjs/operators';

export class WsAdapter implements WebSocketAdapter {
  constructor(private readonly app: INestApplicationContext) {}

  create(port: number, options: any = {}): any {
    return new ws.Server({ port, ...options });
  }

  bindClientConnect(server, callback: Function) {
    server.on('connection', callback);
  }

  bindMessageHandlers(
    client: WebSocket,
    handlers: MessageMappingProperties[],
    process: (data: any) => Observable<any>,
  ) {
    fromEvent(client, 'message')
      .pipe(
        mergeMap(data => this.bindMessageHandler(data, handlers, process)),
        filter(result => result),
      )
      .subscribe(response => client.send(JSON.stringify(response)));
  }

  bindMessageHandler(
    buffer,
    handlers: MessageMappingProperties[],
    process: (data: any) => Observable<any>,
  ): Observable<any> {
    const message = JSON.parse(buffer.data);
    const messageHandler = handlers.find(
      handler => handler.message === message.event,
    );
    if (!messageHandler) {
      return EMPTY;
    }
    return process(messageHandler.callback(message.data));
  }

  close(server) {
    server.close();
  }
}
```

> **Hint** When you want to take advantage of [ws](https://github.com/websockets/ws) library, use built-in `WsAdapter` instead of creating your own one.

Then, we can set up a custom adapter using `useWebSocketAdapter()` method:

main.ts

JS TS

```typescript

const app = await NestFactory.create(ApplicationModule);
app.useWebSocketAdapter(new WsAdapter(app));
```

#### Example[#](/websockets/adapter#example)

A working example that uses `WsAdapter` is available [here](https://github.com/nestjs/nest/tree/master/sample/16-gateways-ws).

----
url: https://docs.nestjs.com/v11/cli/libraries
----

* [Libraries](https://docs.nestjs.com/v11/cli/libraries#libraries)
* [Nest libraries](https://docs.nestjs.com/v11/cli/libraries#nest-libraries)
* [Creating libraries](https://docs.nestjs.com/v11/cli/libraries#creating-libraries)
* [Using libraries](https://docs.nestjs.com/v11/cli/libraries#using-libraries)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/cli/libraries.md "Suggest Edits")

### Libraries

Many applications need to solve the same general problems, or re-use a modular component in several different contexts. Nest has a few ways of addressing this, but each works at a different level to solve the problem in a way that helps meet different architectural and organizational objectives.

Nest [modules](/v11/modules) are useful for providing an execution context that enables sharing components within a single application. Modules can also be packaged with [npm](https://npmjs.com) to create a reusable library that can be installed in different projects. This can be an effective way to distribute configurable, re-usable libraries that can be used by different, loosely connected or unaffiliated organizations (e.g., by distributing/installing 3rd party libraries).

```bash

$ nest g library my-library
```

When you run the command, the `library` schematic prompts you for a prefix (AKA alias) for the library:

```bash

What prefix would you like to use for the library (default: @app)?
```

```javascript

...
{
    "my-library": {
      "type": "library",
      "root": "libs/my-library",
      "entryFile": "index",
      "sourceRoot": "libs/my-library/src",
      "compilerOptions": {
        "tsConfigPath": "libs/my-library/tsconfig.lib.json"
      }
}
...
```

There are two differences in `nest-cli.json` metadata between libraries and applications:

* the `"type"` property is set to `"library"` instead of `"application"`
* the `"entryFile"` property is set to `"index"` instead of `"main"`

These differences key the build process to handle libraries appropriately. For example, a library exports its functions through the `index.js` file.

As with application-type projects, libraries each have their own `tsconfig.lib.json` file that extends the root (monorepo-wide) `tsconfig.json` file. You can modify this file, if necessary, to provide library-specific compiler options.

You can build the library with the CLI command:

```bash

$ nest build my-library
```

#### Using libraries[#](/cli/libraries#using-libraries)

With the automatically generated configuration files in place, using libraries is straightforward. How would we import `MyLibraryService` from the `my-library` library into the `my-project` application?

First, note that using library modules is the same as using any other Nest module. What the monorepo does is manage paths in a way that importing libraries and generating builds is now transparent. To use `MyLibraryService`, we need to import its declaring module. We can modify `my-project/src/app.module.ts` as follows to import `MyLibraryModule`.

```typescript

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { MyLibraryModule } from '@app/my-library';

@Module({
  imports: [MyLibraryModule],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}
```

Notice above that we've used a path alias of `@app` in the ES module `import` line, which was the `prefix` we supplied with the `nest g library` command above. Under the covers, Nest handles this through tsconfig path mapping. When adding a library, Nest updates the global (monorepo) `tsconfig.json` file's `"paths"` key like this:

```javascript

"paths": {
    "@app/my-library": [
        "libs/my-library/src"
    ],
    "@app/my-library/*": [
        "libs/my-library/src/*"
    ]
}
```

So, in a nutshell, the combination of the monorepo and library features has made it easy and intuitive to include library modules into applications.

This same mechanism enables building and deploying applications that compose libraries. Once you've imported the `MyLibraryModule`, running `nest build` handles all the module resolution automatically and bundles the app along with any library dependencies, for deployment. The default compiler for a monorepo is **webpack**, so the resulting distribution file is a single file that bundles all of the transpiled JavaScript files into a single file. You can also switch to `tsc` as described [here](https://docs.nestjs.com/cli/monorepo#global-compiler-options).

----
url: https://docs.nestjs.com/v9/application-context
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)



[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/application-context.md "Suggest Edits")

### Standalone applications

There are several ways of mounting a Nest application. You can create a web app, a microservice or just a bare Nest **standalone application** (without any network listeners). The Nest standalone application is a wrapper around the Nest **IoC container**, which holds all instantiated classes. We can obtain a reference to any existing instance from within any imported module directly using the standalone application object. Thus, you can take advantage of the Nest framework anywhere, including, for example, scripted **CRON** jobs. You can even build a **CLI** on top of it.

#### Getting started[#](/standalone-applications#getting-started)

To create a Nest standalone application, use the following construction:

JS TS

```typescript

async function bootstrap() {
  const app = await NestFactory.createApplicationContext(AppModule);
  // application logic...
}
bootstrap();
```

The standalone application object allows you to obtain a reference to any instance registered within the Nest application. Let's imagine that we have a `TasksService` in the `TasksModule`. This class provides a set of methods that we want to call from within a CRON job.

JS TS

```typescript

const app = await NestFactory.createApplicationContext(AppModule);
const tasksService = app.get(TasksService);
```

To access the `TasksService` instance we use the `get()` method. The `get()` method acts like a **query** that searches for an instance in each registered module. Alternatively, for strict context checking, pass an options object with the `strict: true` property. With this option in effect, you have to navigate through specific modules to obtain a particular instance from the selected context.

JS TS

```typescript

const app = await NestFactory.createApplicationContext(AppModule);
const tasksService = app.select(TasksModule).get(TasksService, { strict: true });
```

Following is a summary of the methods available for retrieving instance references from the standalone application object.

|            |                                                                                                                                                  |
| ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| `get()`    | Retrieves an instance of a controller or provider (including guards, filters, and so on) available in the application context.                   |
| `select()` | Navigates through the module's graph to pull out a specific instance of the selected module (used together with strict mode as described above). |

> **Hint** In non-strict mode, the root module is selected by default. To select any other module, you need to navigate the modules graph manually, step by step.

If you want the node application to close after the script finishes (e.g., for a script running CRON jobs), add `await app.close()` to the end of your `bootstrap` function:

JS TS

```typescript

async function bootstrap() {
  const app = await NestFactory.createApplicationContext(AppModule);
  // application logic...
  await app.close();
}
bootstrap();
```

#### Example[#](/standalone-applications#example)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/18-context).

----
url: https://docs.nestjs.com/v11/faq/serverless
----

* [Serverless](https://docs.nestjs.com/v11/faq/serverless#serverless)
* [Cold start](https://docs.nestjs.com/v11/faq/serverless#cold-start)
* [Benchmarks](https://docs.nestjs.com/v11/faq/serverless#benchmarks)
* [Runtime optimizations](https://docs.nestjs.com/v11/faq/serverless#runtime-optimizations)
* [Example integration](https://docs.nestjs.com/v11/faq/serverless#example-integration)
* [Using standalone application feature](https://docs.nestjs.com/v11/faq/serverless#using-standalone-application-feature)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/faq/serverless.md "Suggest Edits")

### Serverless

Serverless computing is a cloud computing execution model in which the cloud provider allocates machine resources on-demand, taking care of the servers on behalf of their customers. When an app is not in use, there are no computing resources allocated to the app. Pricing is based on the actual amount of resources consumed by an application ([source](https://en.wikipedia.org/wiki/Serverless_computing)).

With a **serverless architecture**, you focus purely on the individual functions in your application code. Services such as AWS Lambda, Google Cloud Functions, and Microsoft Azure Functions take care of all the physical hardware, virtual machine operating system, and web server software management.

> **Hint** This chapter does not cover the pros and cons of serverless functions nor dives into the specifics of any cloud providers.

#### Cold start[#](/faq/serverless#cold-start)

A cold start is the first time your code has been executed in a while. Depending on a cloud provider you use, it may span several different operations, from downloading the code and bootstrapping the runtime to eventually running your code. This process adds **significant latency** depending on several factors, the language, the number of packages your application require, etc.

The cold start is important and although there are things which are beyond our control, there's still a lot of things we can do on our side to make it as short as possible.

While you can think of Nest as a fully-fledged framework designed to be used in complex, enterprise applications, it is also **suitable for much "simpler" applications** (or scripts). For example, with the use of [Standalone applications](/v11/standalone-applications) feature, you can take advantage of Nest's DI system in simple workers, CRON jobs, CLIs, or serverless functions.

#### Benchmarks[#](/faq/serverless#benchmarks)

To better understand what's the cost of using Nest or other, well-known libraries (like `express`) in the context of serverless functions, let's compare how much time Node runtime needs to run the following scripts:

```typescript

// #1 Express
import * as express from 'express';

async function bootstrap() {
  const app = express();
  app.get('/', (req, res) => res.send('Hello world!'));
  await new Promise<void>((resolve) => app.listen(3000, resolve));
}
bootstrap();

// #2 Nest (with @nestjs/platform-express)
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule, { logger: ['error'] });
  await app.listen(process.env.PORT ?? 3000);
}
bootstrap();

// #3 Nest as a Standalone application (no HTTP server)
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { AppService } from './app.service';

async function bootstrap() {
  const app = await NestFactory.createApplicationContext(AppModule, {
    logger: ['error'],
  });
  console.log(app.get(AppService).getHello());
}
bootstrap();

// #4 Raw Node.js script
async function bootstrap() {
  console.log('Hello world!');
}
bootstrap();
```

For all these scripts, we used the `tsc` (TypeScript) compiler and so the code remains unbundled (`webpack` isn't used).

| Express                              | 0.0079s (7.9ms)   |
| ------------------------------------ | ----------------- |
| Nest with `@nestjs/platform-express` | 0.1974s (197.4ms) |
| Nest (standalone application)        | 0.1117s (111.7ms) |
| Raw Node.js script                   | 0.0071s (7.1ms)   |

> **Note** Machine: MacBook Pro Mid 2014, 2.5 GHz Quad-Core Intel Core i7, 16 GB 1600 MHz DDR3, SSD.

Now, let's repeat all benchmarks but this time, using `webpack` (if you have [Nest CLI](/v11/cli/overview) installed, you can run `nest build --webpack`) to bundle our application into a single executable JavaScript file. However, instead of using the default `webpack` configuration that Nest CLI ships with, we'll make sure to bundle all dependencies (`node_modules`) together, as follows:

```javascript

module.exports = (options, webpack) => {
  const lazyImports = [
    '@nestjs/microservices/microservices-module',
    '@nestjs/websockets/socket-module',
  ];

  return {
    ...options,
    externals: [],
    plugins: [
      ...options.plugins,
      new webpack.IgnorePlugin({
        checkResource(resource) {
          if (lazyImports.includes(resource)) {
            try {
              require.resolve(resource);
            } catch (err) {
              return true;
            }
          }
          return false;
        },
      }),
    ],
  };
};
```

> **Hint** To instruct Nest CLI to use this configuration, create a new `webpack.config.js` file in the root directory of your project.

With this configuration, we received the following results:

| Express                              | 0.0068s (6.8ms)  |
| ------------------------------------ | ---------------- |
| Nest with `@nestjs/platform-express` | 0.0815s (81.5ms) |
| Nest (standalone application)        | 0.0319s (31.9ms) |
| Raw Node.js script                   | 0.0066s (6.6ms)  |

> **Note** Machine: MacBook Pro Mid 2014, 2.5 GHz Quad-Core Intel Core i7, 16 GB 1600 MHz DDR3, SSD.

> **Hint** You could optimize it even further by applying additional code minification & optimization techniques (using `webpack` plugins, etc.).

As you can see, the way you compile (and whether you bundle your code) is crucial and has a significant impact on the overall startup time. With `webpack`, you can get the bootstrap time of a standalone Nest application (starter project with one module, controller, and service) down to \~32ms on average, and down to \~81.5ms for a regular HTTP, express-based NestJS app.

For more complicated Nest applications, for example, with 10 resources (generated through `$ nest g resource` schematic = 10 modules, 10 controllers, 10 services, 20 DTO classes, 50 HTTP endpoints + `AppModule`), the overall startup on MacBook Pro Mid 2014, 2.5 GHz Quad-Core Intel Core i7, 16 GB 1600 MHz DDR3, SSD is approximately 0.1298s (129.8ms). Running a monolithic application as a serverless function typically doesn't make too much sense anyway, so think of this benchmark more as an example of how the bootstrap time may potentially increase as your application grows.

#### Runtime optimizations[#](/faq/serverless#runtime-optimizations)

Thus far we covered compile-time optimizations. These are unrelated to the way you define providers and load Nest modules in your application, and that plays an essential role as your application gets bigger.

For example, imagine having a database connection defined as an [asynchronous provider](/v11/fundamentals/async-providers). Async providers are designed to delay the application start until one or more asynchronous tasks are completed. That means, if your serverless function on average requires 2s to connect to the database (on bootstrap), your endpoint will need at least two extra seconds (because it must wait till the connection is established) to send a response back (when it's a cold start and your application wasn't running already).

As you can see, the way you structure your providers is somewhat different in a **serverless environment** where bootstrap time is important. Another good example is if you use Redis for caching, but only in certain scenarios. Perhaps, in this case, you should not define a Redis connection as an async provider, as it would slow down the bootstrap time, even if it's not required for this specific function invocation.

Also, sometimes you could lazy load entire modules, using the `LazyModuleLoader` class, as described in [this chapter](/v11/fundamentals/lazy-loading-modules). Caching is a great example here too. Imagine that your application has, let's say, `CacheModule` which internally connects to Redis and also, exports the `CacheService` to interact with the Redis storage. If you don't need it for all potential function invocations, you can just load it on-demand, lazily. This way you'll get a faster startup time (when a cold start occurs) for all invocations that don't require caching.

```typescript

if (request.method === RequestMethod[RequestMethod.GET]) {
  const { CacheModule } = await import('./cache.module');
  const moduleRef = await this.lazyModuleLoader.load(() => CacheModule);

  const { CacheService } = await import('./cache.service');
  const cacheService = moduleRef.get(CacheService);

  return cacheService.get(ENDPOINT_KEY);
}
```

Another great example is a webhook or worker, which depending on some specific conditions (e.g., input arguments), may perform different operations. In such a case, you could specify a condition inside your route handler that lazily loads an appropriate module for the specific function invocation, and just load every other module lazily.

```typescript

if (workerType === WorkerType.A) {
  const { WorkerAModule } = await import('./worker-a.module');
  const moduleRef = await this.lazyModuleLoader.load(() => WorkerAModule);
  // ...
} else if (workerType === WorkerType.B) {
  const { WorkerBModule } = await import('./worker-b.module');
  const moduleRef = await this.lazyModuleLoader.load(() => WorkerBModule);
  // ...
}
```

#### Example integration[#](/faq/serverless#example-integration)

The way your application's entry file (typically `main.ts` file) is supposed to look like **depends on several factors** and so **there's no single template** that just works for every scenario. For example, the initialization file required to spin up your serverless function varies by cloud providers (AWS, Azure, GCP, etc.). Also, depending on whether you want to run a typical HTTP application with multiple routes/endpoints or just provide a single route (or execute a specific portion of code), your application's code will look different (for example, for the endpoint-per-function approach you could use the `NestFactory.createApplicationContext` instead of booting the HTTP server, setting up middleware, etc.).

Just for illustration purposes, we'll integrate Nest (using `@nestjs/platform-express` and so spinning up the whole, fully functional HTTP router) with the [Serverless](https://www.serverless.com/) framework (in this case, targeting AWS Lambda). As we've mentioned earlier, your code will differ depending on the cloud provider you choose, and many other factors.

First, let's install the required packages:

```bash

$ npm i @codegenie/serverless-express aws-lambda
$ npm i -D @types/aws-lambda serverless-offline
```

> **Hint** To speed up development cycles, we install the `serverless-offline` plugin which emulates AWS λ and API Gateway.

Once the installation process is complete, let's create the `serverless.yml` file to configure the Serverless framework:

```yaml

service: serverless-example

plugins:
  - serverless-offline

provider:
  name: aws
  runtime: nodejs14.x

functions:
  main:
    handler: dist/main.handler
    events:
      - http:
          method: ANY
          path: /
      - http:
          method: ANY
          path: '{proxy+}'
```

> **Hint** To learn more about the Serverless framework, visit the [official documentation](https://www.serverless.com/framework/docs/).

With this in place, we can now navigate to the `main.ts` file and update our bootstrap code with the required boilerplate:

```typescript

import { NestFactory } from '@nestjs/core';
import serverlessExpress from '@codegenie/serverless-express';
import { Callback, Context, Handler } from 'aws-lambda';
import { AppModule } from './app.module';

let server: Handler;

async function bootstrap(): Promise<Handler> {
  const app = await NestFactory.create(AppModule);
  await app.init();

  const expressApp = app.getHttpAdapter().getInstance();
  return serverlessExpress({ app: expressApp });
}

export const handler: Handler = async (
  event: any,
  context: Context,
  callback: Callback,
) => {
  server = server ?? (await bootstrap());
  return server(event, context, callback);
};
```

> **Hint** For creating multiple serverless functions and sharing common modules between them, we recommend using the [CLI Monorepo mode](/cli/monorepo#monorepo-mode).

> **Warning** If you use `@nestjs/swagger` package, there are a few additional steps required to make it work properly in the context of serverless function. Check out this [thread](https://github.com/nestjs/swagger/issues/199) for more information.

Next, open up the `tsconfig.json` file and make sure to enable the `esModuleInterop` option to make the `@codegenie/serverless-express` package load properly.

```json

{
  "compilerOptions": {
    ...
    "esModuleInterop": true
  }
}
```

Now we can build our application (with `nest build` or `tsc`) and use the `serverless` CLI to start our lambda function locally:

```bash

$ npm run build
$ npx serverless offline
```

Once the application is running, open your browser and navigate to `http://localhost:3000/dev/[ANY_ROUTE]` (where `[ANY_ROUTE]` is any endpoint registered in your application).

In the sections above, we've shown that using `webpack` and bundling your app can have significant impact on the overall bootstrap time. However, to make it work with our example, there are a few additional configurations you must add in your `webpack.config.js` file. Generally, to make sure our `handler` function will be picked up, we must change the `output.libraryTarget` property to `commonjs2`.

```javascript

return {
  ...options,
  externals: [],
  output: {
    ...options.output,
    libraryTarget: 'commonjs2',
  },
  // ... the rest of the configuration
};
```

With this in place, you can now use `$ nest build --webpack` to compile your function's code (and then `$ npx serverless offline` to test it).

It's also recommended (but **not required** as it will slow down your build process) to install the `terser-webpack-plugin` package and override its configuration to keep classnames intact when minifying your production build. Not doing so can result in incorrect behavior when using `class-validator` within your application.

```javascript

const TerserPlugin = require('terser-webpack-plugin');

return {
  ...options,
  externals: [],
  optimization: {
    minimizer: [
      new TerserPlugin({
        terserOptions: {
          keep_classnames: true,
        },
      }),
    ],
  },
  output: {
    ...options.output,
    libraryTarget: 'commonjs2',
  },
  // ... the rest of the configuration
};
```

#### Using standalone application feature[#](/faq/serverless#using-standalone-application-feature)

Alternatively, if you want to keep your function very lightweight and you don't need any HTTP-related features (routing, but also guards, interceptors, pipes, etc.), you can just use `NestFactory.createApplicationContext` (as mentioned earlier) instead of running the entire HTTP server (and `express` under the hood), as follows:

main.ts

JS TS

```typescript

import { HttpStatus } from '@nestjs/common';
import { NestFactory } from '@nestjs/core';
import { Callback, Context, Handler } from 'aws-lambda';
import { AppModule } from './app.module';
import { AppService } from './app.service';

export const handler: Handler = async (
  event: any,
  context: Context,
  callback: Callback,
) => {
  const appContext = await NestFactory.createApplicationContext(AppModule);
  const appService = appContext.get(AppService);

  return {
    body: appService.getHello(),
    statusCode: HttpStatus.OK,
  };
};
```

> **Hint** Be aware that `NestFactory.createApplicationContext` does not wrap controller methods with enhancers (guard, interceptors, etc.). For this, you must use the `NestFactory.create` method.

You could also pass the `event` object down to, let's say, `EventsService` provider that could process it and return a corresponding value (depending on the input value and your business logic).

```typescript

export const handler: Handler = async (
  event: any,
  context: Context,
  callback: Callback,
) => {
  const appContext = await NestFactory.createApplicationContext(AppModule);
  const eventsService = appContext.get(EventsService);
  return eventsService.process(event);
};
```

----
url: https://docs.nestjs.com/v10/microservices/guards
----

* [Guards](https://docs.nestjs.com/v10/microservices/guards#guards)
* [Binding guards](https://docs.nestjs.com/v10/microservices/guards#binding-guards)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/microservices/guards.md "Suggest Edits")

### Guards

There is no fundamental difference between microservices guards and [regular HTTP application guards](/v10/guards). The only difference is that instead of throwing `HttpException`, you should use `RpcException`.

> **Hint** The `RpcException` class is exposed from `@nestjs/microservices` package.

#### Binding guards[#](/microservices/guards#binding-guards)

The following example uses a method-scoped guard. Just as with HTTP based applications, you can also use controller-scoped guards (i.e., prefix the controller class with a `@UseGuards()` decorator).

JS TS

```typescript

@UseGuards(AuthGuard)
@MessagePattern({ cmd: 'sum' })
accumulate(data: number[]): number {
  return (data || []).reduce((a, b) => a + b);
}
```

```typescript

@UseGuards(AuthGuard)
@MessagePattern({ cmd: 'sum' })
accumulate(data) {
  return (data || []).reduce((a, b) => a + b);
}
```

----
url: https://docs.nestjs.com/v5/microservices/rabbitmq
----

### RabbitMQ

The [RabbitMQ](https://www.rabbitmq.com/) is the most widely deployed open source message broker.

#### Installation

Before we start, we have to install required packages:

```bash

$ npm i --save amqplib amqp-connection-manager
```

#### Transporter

In order to switch to **RabbitMQ** transporter, we need to modify an options object passed to the `createMicroservice()` method.

main.ts

JS TS

TypeScript

```typescript

const app = await NestFactory.createMicroservice(ApplicationModule, {
  transport: Transport.RMQ,
  options: {
    urls: [`amqp://localhost:5672`],
    queue: 'my_queue',
    queueOptions: { durable: false },
  },
});
```

#### Options

There are a bunch of available options that determine a transporter behavior.

|                         |                                                                                                                               |
| ----------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| `urls`                  | Connection urls                                                                                                               |
| `queue`                 | Queue name which your server will listen to                                                                                   |
| `prefetchCount`         | Sets the prefetch count for the channel                                                                                       |
| `isGlobalPrefetchCount` | Enables per channel prefetching                                                                                               |
| `queueOptions`          | Additional queue options. They are well-described [here](https://www.squaremobius.net/amqp.node/channel_api.html#assertQueue) |

* RabbitMQ
* Installation
* Transporter
* Options

----
url: https://docs.nestjs.com/v11/techniques/versioning
----

* [Versioning](https://docs.nestjs.com/v11/techniques/versioning#versioning)
* [URI Versioning Type](https://docs.nestjs.com/v11/techniques/versioning#uri-versioning-type)
* [Header Versioning Type](https://docs.nestjs.com/v11/techniques/versioning#header-versioning-type)
* [Media Type Versioning Type](https://docs.nestjs.com/v11/techniques/versioning#media-type-versioning-type)
* [Custom Versioning Type](https://docs.nestjs.com/v11/techniques/versioning#custom-versioning-type)
* [Usage](https://docs.nestjs.com/v11/techniques/versioning#usage)
* [Controller versions](https://docs.nestjs.com/v11/techniques/versioning#controller-versions)
* [Route versions](https://docs.nestjs.com/v11/techniques/versioning#route-versions)
* [Multiple versions](https://docs.nestjs.com/v11/techniques/versioning#multiple-versions)
* [Version "Neutral"](https://docs.nestjs.com/v11/techniques/versioning#version-neutral)
* [Global default version](https://docs.nestjs.com/v11/techniques/versioning#global-default-version)
* [Middleware versioning](https://docs.nestjs.com/v11/techniques/versioning#middleware-versioning)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/techniques/versioning.md "Suggest Edits")

### Versioning

> **Hint** This chapter is only relevant to HTTP-based applications.

Versioning allows you to have **different versions** of your controllers or individual routes running within the same application. Applications change very often and it is not unusual that there are breaking changes that you need to make while still needing to support the previous version of the application.

There are 4 types of versioning that are supported:

|                                                                             |                                                                                                                            |
| --------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- |
| [`URI Versioning`](techniques/versioning#uri-versioning-type)               | The version will be passed within the URI of the request (default)                                                         |
| [`Header Versioning`](techniques/versioning#header-versioning-type)         | A custom request header will specify the version                                                                           |
| [`Media Type Versioning`](techniques/versioning#media-type-versioning-type) | The `Accept` header of the request will specify the version                                                                |
| [`Custom Versioning`](techniques/versioning#custom-versioning-type)         | Any aspect of the request may be used to specify the version(s). A custom function is provided to extract said version(s). |

#### URI Versioning Type[#](/techniques/versioning#uri-versioning-type)

URI Versioning uses the version passed within the URI of the request, such as `https://example.com/v1/route` and `https://example.com/v2/route`.

> **Notice** With URI Versioning the version will be automatically added to the URI after the [global path prefix](faq/global-prefix) (if one exists), and before any controller or route paths.

To enable URI Versioning for your application, do the following:

main.ts

JS TS

```typescript

const app = await NestFactory.create(AppModule);
// or "app.enableVersioning()"
app.enableVersioning({
  type: VersioningType.URI,
});
await app.listen(process.env.PORT ?? 3000);
```

> **Notice** The version in the URI will be automatically prefixed with `v` by default, however the prefix value can be configured by setting the `prefix` key to your desired prefix or `false` if you wish to disable it.

> **Hint** The `VersioningType` enum is available to use for the `type` property and is imported from the `@nestjs/common` package.

#### Header Versioning Type[#](/techniques/versioning#header-versioning-type)

Header Versioning uses a custom, user specified, request header to specify the version where the value of the header will be the version to use for the request.

Example HTTP Requests for Header Versioning:

To enable **Header Versioning** for your application, do the following:

main.ts

JS TS

```typescript

const app = await NestFactory.create(AppModule);
app.enableVersioning({
  type: VersioningType.HEADER,
  header: 'Custom-Header',
});
await app.listen(process.env.PORT ?? 3000);
```

The `header` property should be the name of the header that will contain the version of the request.

> **Hint** The `VersioningType` enum is available to use for the `type` property and is imported from the `@nestjs/common` package.

#### Media Type Versioning Type[#](/techniques/versioning#media-type-versioning-type)

Media Type Versioning uses the `Accept` header of the request to specify the version.

Within the `Accept` header, the version will be separated from the media type with a semi-colon, `;`. It should then contain a key-value pair that represents the version to use for the request, such as `Accept: application/json;v=2`. They key is treated more as a prefix when determining the version will to be configured to include the key and separator.

To enable **Media Type Versioning** for your application, do the following:

main.ts

JS TS

```typescript

const app = await NestFactory.create(AppModule);
app.enableVersioning({
  type: VersioningType.MEDIA_TYPE,
  key: 'v=',
});
await app.listen(process.env.PORT ?? 3000);
```

The `key` property should be the key and separator of the key-value pair that contains the version. For the example `Accept: application/json;v=2`, the `key` property would be set to `v=`.

> **Hint** The `VersioningType` enum is available to use for the `type` property and is imported from the `@nestjs/common` package.

#### Custom Versioning Type[#](/techniques/versioning#custom-versioning-type)

Custom Versioning uses any aspect of the request to specify the version (or versions). The incoming request is analyzed using an `extractor` function that returns a string or array of strings.

If multiple versions are provided by the requester, the extractor function can return an array of strings, sorted in order of greatest/highest version to smallest/lowest version. Versions are matched to routes in order from highest to lowest.

If an empty string or array is returned from the `extractor`, no routes are matched and a 404 is returned.

For example, if an incoming request specifies it supports versions `1`, `2`, and `3`, the `extractor`**MUST** return `[3, 2, 1]`. This ensures that the highest possible route version is selected first.

If versions `[3, 2, 1]` are extracted, but routes only exist for version `2` and `1`, the route that matches version `2` is selected (version `3` is automatically ignored).

> **Notice** Selecting the highest matching version based on the array returned from `extractor` > **does not reliably work** with the Express adapter due to design limitations. A single version (either a string or array of 1 element) works just fine in Express. Fastify correctly supports both highest matching version selection and single version selection.

To enable **Custom Versioning** for your application, create an `extractor` function and pass it into your application like so:

main.ts

JS TS

```typescript

// Example extractor that pulls out a list of versions from a custom header and turns it into a sorted array.
// This example uses Fastify, but Express requests can be processed in a similar way.
const extractor = (request: FastifyRequest): string | string[] =>
  [request.headers['custom-versioning-field'] ?? '']
     .flatMap(v => v.split(','))
     .filter(v => !!v)
     .sort()
     .reverse()

const app = await NestFactory.create(AppModule);
app.enableVersioning({
  type: VersioningType.CUSTOM,
  extractor,
});
await app.listen(process.env.PORT ?? 3000);
```

#### Usage[#](/techniques/versioning#usage)

Versioning allows you to version controllers, individual routes, and also provides a way for certain resources to opt-out of versioning. The usage of versioning is the same regardless of the Versioning Type your application uses.

> **Notice** If versioning is enabled for the application but the controller or route does not specify the version, any requests to that controller/route will be returned a `404` response status. Similarly, if a request is received containing a version that does not have a corresponding controller or route, it will also be returned a `404` response status.

#### Controller versions[#](/techniques/versioning#controller-versions)

A version can be applied to a controller, setting the version for all routes within the controller.

To add a version to a controller do the following:

cats.controller.ts

JS TS

```typescript

@Controller({
  version: '1',
})
export class CatsControllerV1 {
  @Get('cats')
  findAll(): string {
    return 'This action returns all cats for version 1';
  }
}
```

```typescript

@Controller({
  version: '1',
})
export class CatsControllerV1 {
  @Get('cats')
  findAll() {
    return 'This action returns all cats for version 1';
  }
}
```

#### Route versions[#](/techniques/versioning#route-versions)

A version can be applied to an individual route. This version will override any other version that would effect the route, such as the Controller Version.

To add a version to an individual route do the following:

cats.controller.ts

JS TS

```typescript

import { Controller, Get, Version } from '@nestjs/common';

@Controller()
export class CatsController {
  @Version('1')
  @Get('cats')
  findAllV1(): string {
    return 'This action returns all cats for version 1';
  }

  @Version('2')
  @Get('cats')
  findAllV2(): string {
    return 'This action returns all cats for version 2';
  }
}
```

```typescript

import { Controller, Get, Version } from '@nestjs/common';

@Controller()
export class CatsController {
  @Version('1')
  @Get('cats')
  findAllV1() {
    return 'This action returns all cats for version 1';
  }

  @Version('2')
  @Get('cats')
  findAllV2() {
    return 'This action returns all cats for version 2';
  }
}
```

#### Multiple versions[#](/techniques/versioning#multiple-versions)

Multiple versions can be applied to a controller or route. To use multiple versions, you would set the version to be an Array.

To add multiple versions do the following:

cats.controller.ts

JS TS

```typescript

@Controller({
  version: ['1', '2'],
})
export class CatsController {
  @Get('cats')
  findAll(): string {
    return 'This action returns all cats for version 1 or 2';
  }
}
```

```typescript

@Controller({
  version: ['1', '2'],
})
export class CatsController {
  @Get('cats')
  findAll() {
    return 'This action returns all cats for version 1 or 2';
  }
}
```

#### Version "Neutral"[#](/techniques/versioning#version-neutral)

Some controllers or routes may not care about the version and would have the same functionality regardless of the version. To accommodate this, the version can be set to `VERSION_NEUTRAL` symbol.

An incoming request will be mapped to a `VERSION_NEUTRAL` controller or route regardless of the version sent in the request in addition to if the request does not contain a version at all.

> **Notice** For URI Versioning, a `VERSION_NEUTRAL` resource would not have the version present in the URI.

To add a version neutral controller or route do the following:

cats.controller.ts

JS TS

```typescript

import { Controller, Get, VERSION_NEUTRAL } from '@nestjs/common';

@Controller({
  version: VERSION_NEUTRAL,
})
export class CatsController {
  @Get('cats')
  findAll(): string {
    return 'This action returns all cats regardless of version';
  }
}
```

```typescript

import { Controller, Get, VERSION_NEUTRAL } from '@nestjs/common';

@Controller({
  version: VERSION_NEUTRAL,
})
export class CatsController {
  @Get('cats')
  findAll() {
    return 'This action returns all cats regardless of version';
  }
}
```

#### Global default version[#](/techniques/versioning#global-default-version)

If you do not want to provide a version for each controller/or individual routes, or if you want to have a specific version set as the default version for every controller/route that don't have the version specified, you could set the `defaultVersion` as follows:

main.ts

JS TS

```typescript

app.enableVersioning({
  // ...
  defaultVersion: '1'
  // or
  defaultVersion: ['1', '2']
  // or
  defaultVersion: VERSION_NEUTRAL
});
```

#### Middleware versioning[#](/techniques/versioning#middleware-versioning)

[Middlewares](https://docs.nestjs.com/middleware) can also use versioning metadata to configure the middleware for a specific route's version. To do so, provide the version number as one of the parameters for the `MiddlewareConsumer.forRoutes()` method:

app.module.ts

JS TS

```typescript

import { Module, NestModule, MiddlewareConsumer } from '@nestjs/common';
import { LoggerMiddleware } from './common/middleware/logger.middleware';
import { CatsModule } from './cats/cats.module';
import { CatsController } from './cats/cats.controller';

@Module({
  imports: [CatsModule],
})
export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer
      .apply(LoggerMiddleware)
      .forRoutes({ path: 'cats', method: RequestMethod.GET, version: '2' });
  }
}
```

With the code above, the `LoggerMiddleware` will only be applied to the version '2' of `/cats` endpoint.

> **Notice** Middlewares work with any versioning type described in the this section: `URI`, `Header`, `Media Type` or `Custom`.

----
url: https://docs.nestjs.com/fundamentals/platform-agnosticism
----

[Skip to content](#content)

On this page

* [Platform agnosticism](https://docs.nestjs.com/fundamentals/platform-agnosticism#platform-agnosticism)
* [Build once, use everywhere](https://docs.nestjs.com/fundamentals/platform-agnosticism#build-once-use-everywhere)

### Platform agnosticism

Nest is a platform-agnostic framework. You can develop **reusable logical parts** and use them across different types of applications. For example, most components can be reused without change across different underlying HTTP server frameworks (e.g., Express and Fastify), and even across different *types* of applications (e.g., HTTP servers, microservices with different transport layers, and WebSockets).

#### Build once, use everywhere[#](/fundamentals/platform-agnosticism#build-once-use-everywhere)

The **Overview** section of the documentation primarily shows coding techniques using HTTP server frameworks (e.g., apps providing a REST API or an MVC-style server-side rendered app). However, all those building blocks can be used on top of different transport layers ([microservices](/microservices/basics) or [WebSockets](/websockets/gateways)).

Nest also comes with a dedicated [GraphQL](/graphql/quick-start) module. You can use GraphQL as your API layer interchangeably with a REST API.

In addition, the [application context](/application-context) feature lets you build any kind of Node.js application on top of Nest, including cron jobs and CLI apps.

Nest aims to be a full-fledged platform for Node.js apps that brings a higher level of modularity and reusability to your applications. Build once, use everywhere.

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/fundamentals/platform-agnosticism.md)

----
url: https://docs.nestjs.com/v8/interceptors
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Interceptors](https://docs.nestjs.com/v8/interceptors#interceptors)
* [Basics](https://docs.nestjs.com/v8/interceptors#basics)
* [Execution context](https://docs.nestjs.com/v8/interceptors#execution-context)
* [Call handler](https://docs.nestjs.com/v8/interceptors#call-handler)
* [Aspect interception](https://docs.nestjs.com/v8/interceptors#aspect-interception)
* [Binding interceptors](https://docs.nestjs.com/v8/interceptors#binding-interceptors)
* [Response mapping](https://docs.nestjs.com/v8/interceptors#response-mapping)
* [Exception mapping](https://docs.nestjs.com/v8/interceptors#exception-mapping)
* [Stream overriding](https://docs.nestjs.com/v8/interceptors#stream-overriding)
* [More operators](https://docs.nestjs.com/v8/interceptors#more-operators)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/interceptors.md "Suggest Edits")

### Interceptors

An interceptor is a class annotated with the `@Injectable()` decorator, which implements the `NestInterceptor` interface.

Each interceptor implements the `intercept()` method, which takes two arguments. The first one is the `ExecutionContext` instance (exactly the same object as for [guards](/v8/guards)). The `ExecutionContext` inherits from `ArgumentsHost`. We saw `ArgumentsHost` before in the exception filters chapter. There, we saw that it's a wrapper around arguments that have been passed to the original handler, and contains different arguments arrays based on the type of the application. You can refer back to the [exception filters](https://docs.nestjs.com/exception-filters#arguments-host) for more on this topic.

#### Execution context[#](/interceptors#execution-context)

By extending `ArgumentsHost`, `ExecutionContext` also adds several new helper methods that provide additional details about the current execution process. These details can be helpful in building more generic interceptors that can work across a broad set of controllers, methods, and execution contexts. Learn more about `ExecutionContext`[here](/v8/fundamentals/execution-context).

```typescript

import { Injectable, NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
import { Observable } from 'rxjs';
import { tap } from 'rxjs/operators';

@Injectable()
export class LoggingInterceptor implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    console.log('Before...');

    const now = Date.now();
    return next
      .handle()
      .pipe(
        tap(() => console.log(`After... ${Date.now() - now}ms`)),
      );
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';
import { Observable } from 'rxjs';
import { tap } from 'rxjs/operators';

@Injectable()
export class LoggingInterceptor {
  intercept(context, next) {
    console.log('Before...');

    const now = Date.now();
    return next
      .handle()
      .pipe(
        tap(() => console.log(`After... ${Date.now() - now}ms`)),
      );
  }
}
```

> **Hint** The `NestInterceptor<T, R>` is a generic interface in which `T` indicates the type of an `Observable<T>` (supporting the response stream), and `R` is the type of the value wrapped by `Observable<R>`.

> **Notice** Interceptors, like controllers, providers, guards, and so on, can **inject dependencies** through their `constructor`.

Since `handle()` returns an RxJS `Observable`, we have a wide choice of operators we can use to manipulate the stream. In the example above, we used the `tap()` operator, which invokes our anonymous logging function upon graceful or exceptional termination of the observable stream, but doesn't otherwise interfere with the response cycle.

#### Binding interceptors[#](/interceptors#binding-interceptors)

In order to set up the interceptor, we use the `@UseInterceptors()` decorator imported from the `@nestjs/common` package. Like [pipes](/v8/pipes) and [guards](/v8/guards), interceptors can be controller-scoped, method-scoped, or global-scoped.

cats.controller.ts

JS TS

```typescript

@UseInterceptors(LoggingInterceptor)
export class CatsController {}
```

> **Hint** The `@UseInterceptors()` decorator is imported from the `@nestjs/common` package.

Using the above construction, each route handler defined in `CatsController` will use `LoggingInterceptor`. When someone calls the `GET /cats` endpoint, you'll see the following output in your standard output:

```typescript

Before...
After... 1ms
```

Note that we passed the `LoggingInterceptor` type (instead of an instance), leaving responsibility for instantiation to the framework and enabling dependency injection. As with pipes, guards, and exception filters, we can also pass an in-place instance:

cats.controller.ts

JS TS

```typescript

@UseInterceptors(new LoggingInterceptor())
export class CatsController {}
```

As mentioned, the construction above attaches the interceptor to every handler declared by this controller. If we want to restrict the interceptor's scope to a single method, we simply apply the decorator at the **method level**.

In order to set up a global interceptor, we use the `useGlobalInterceptors()` method of the Nest application instance:

```typescript

const app = await NestFactory.create(AppModule);
app.useGlobalInterceptors(new LoggingInterceptor());
```

Global interceptors are used across the whole application, for every controller and every route handler. In terms of dependency injection, global interceptors registered from outside of any module (with `useGlobalInterceptors()`, as in the example above) cannot inject dependencies since this is done outside the context of any module. In order to solve this issue, you can set up an interceptor **directly from any module** using the following construction:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { APP_INTERCEPTOR } from '@nestjs/core';

@Module({
  providers: [
    {
      provide: APP_INTERCEPTOR,
      useClass: LoggingInterceptor,
    },
  ],
})
export class AppModule {}
```

> **Hint** When using this approach to perform dependency injection for the interceptor, note that regardless of the module where this construction is employed, the interceptor is, in fact, global. Where should this be done? Choose the module where the interceptor (`LoggingInterceptor` in the example above) is defined. Also, `useClass` is not the only way of dealing with custom provider registration. Learn more [here](/v8/fundamentals/custom-providers).

#### Response mapping[#](/interceptors#response-mapping)

We already know that `handle()` returns an `Observable`. The stream contains the value **returned** from the route handler, and thus we can easily mutate it using RxJS's `map()` operator.

> **Warning** The response mapping feature doesn't work with the library-specific response strategy (using the `@Res()` object directly is forbidden).

Let's create the `TransformInterceptor`, which will modify each response in a trivial way to demonstrate the process. It will use RxJS's `map()` operator to assign the response object to the `data` property of a newly created object, returning the new object to the client.

transform.interceptor.ts

JS TS

```typescript

import { Injectable, NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';

export interface Response<T> {
  data: T;
}

@Injectable()
export class TransformInterceptor<T> implements NestInterceptor<T, Response<T>> {
  intercept(context: ExecutionContext, next: CallHandler): Observable<Response<T>> {
    return next.handle().pipe(map(data => ({ data })));
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';
import { map } from 'rxjs/operators';

@Injectable()
export class TransformInterceptor {
  intercept(context, next) {
    return next.handle().pipe(map(data => ({ data })));
  }
}
```

> **Hint** Nest interceptors work with both synchronous and asynchronous `intercept()` methods. You can simply switch the method to `async` if necessary.

With the above construction, when someone calls the `GET /cats` endpoint, the response would look like the following (assuming that route handler returns an empty array `[]`):

```json

{
  "data": []
}
```

Interceptors have great value in creating re-usable solutions to requirements that occur across an entire application. For example, imagine we need to transform each occurrence of a `null` value to an empty string `''`. We can do it using one line of code and bind the interceptor globally so that it will automatically be used by each registered handler.

JS TS

```typescript

import { Injectable, NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';

@Injectable()
export class ExcludeNullInterceptor implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    return next
      .handle()
      .pipe(map(value => value === null ? '' : value ));
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';
import { map } from 'rxjs/operators';

@Injectable()
export class ExcludeNullInterceptor {
  intercept(context, next) {
    return next
      .handle()
      .pipe(map(value => value === null ? '' : value ));
  }
}
```

#### Exception mapping[#](/interceptors#exception-mapping)

Another interesting use-case is to take advantage of RxJS's `catchError()` operator to override thrown exceptions:

errors.interceptor.ts

JS TS

```typescript

import {
  Injectable,
  NestInterceptor,
  ExecutionContext,
  BadGatewayException,
  CallHandler,
} from '@nestjs/common';
import { Observable, throwError } from 'rxjs';
import { catchError } from 'rxjs/operators';

@Injectable()
export class ErrorsInterceptor implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    return next
      .handle()
      .pipe(
        catchError(err => throwError(() => new BadGatewayException())),
      );
  }
}
```

```typescript

import { Injectable, BadGatewayException } from '@nestjs/common';
import { throwError } from 'rxjs';
import { catchError } from 'rxjs/operators';

@Injectable()
export class ErrorsInterceptor {
  intercept(context, next) {
    return next
      .handle()
      .pipe(
        catchError(err => throwError(() => new BadGatewayException())),
      );
  }
}
```

#### Stream overriding[#](/interceptors#stream-overriding)

There are several reasons why we may sometimes want to completely prevent calling the handler and return a different value instead. An obvious example is to implement a cache to improve response time. Let's take a look at a simple **cache interceptor** that returns its response from a cache. In a realistic example, we'd want to consider other factors like TTL, cache invalidation, cache size, etc., but that's beyond the scope of this discussion. Here we'll provide a basic example that demonstrates the main concept.

cache.interceptor.ts

JS TS

```typescript

import { Injectable, NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
import { Observable, of } from 'rxjs';

@Injectable()
export class CacheInterceptor implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    const isCached = true;
    if (isCached) {
      return of([]);
    }
    return next.handle();
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';
import { of } from 'rxjs';

@Injectable()
export class CacheInterceptor {
  intercept(context, next) {
    const isCached = true;
    if (isCached) {
      return of([]);
    }
    return next.handle();
  }
}
```

Our `CacheInterceptor` has a hardcoded `isCached` variable and a hardcoded response `[]` as well. The key point to note is that we return a new stream here, created by the RxJS `of()` operator, therefore the route handler **won't be called** at all. When someone calls an endpoint that makes use of `CacheInterceptor`, the response (a hardcoded, empty array) will be returned immediately. In order to create a generic solution, you can take advantage of `Reflector` and create a custom decorator. The `Reflector` is well described in the [guards](/v8/guards) chapter.

#### More operators[#](/interceptors#more-operators)

The possibility of manipulating the stream using RxJS operators gives us many capabilities. Let's consider another common use case. Imagine you would like to handle **timeouts** on route requests. When your endpoint doesn't return anything after a period of time, you want to terminate with an error response. The following construction enables this:

timeout.interceptor.ts

JS TS

```typescript

import { Injectable, NestInterceptor, ExecutionContext, CallHandler, RequestTimeoutException } from '@nestjs/common';
import { Observable, throwError, TimeoutError } from 'rxjs';
import { catchError, timeout } from 'rxjs/operators';

@Injectable()
export class TimeoutInterceptor implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    return next.handle().pipe(
      timeout(5000),
      catchError(err => {
        if (err instanceof TimeoutError) {
          return throwError(() => new RequestTimeoutException());
        }
        return throwError(() => err);
      }),
    );
  };
};
```

```typescript

import { Injectable, RequestTimeoutException } from '@nestjs/common';
import { Observable, throwError, TimeoutError } from 'rxjs';
import { catchError, timeout } from 'rxjs/operators';

@Injectable()
export class TimeoutInterceptor {
  intercept(context, next) {
    return next.handle().pipe(
      timeout(5000),
      catchError(err => {
        if (err instanceof TimeoutError) {
          return throwError(() => new RequestTimeoutException());
        }
        return throwError(() => err);
      }),
    );
  };
};
```

After 5 seconds, request processing will be canceled. You can also add custom logic before throwing `RequestTimeoutException` (e.g. release resources).

----
url: https://docs.nestjs.com/v6/recipes/terminus
----

* [Health checks (Terminus)](https://docs.nestjs.com/v6/recipes/terminus#health-checks-terminus)
* [Getting started](https://docs.nestjs.com/v6/recipes/terminus#getting-started)
* [Setting up a health check](https://docs.nestjs.com/v6/recipes/terminus#setting-up-a-health-check)
* [DNS Health Check](https://docs.nestjs.com/v6/recipes/terminus#dns-health-check)
* [Custom health indicator](https://docs.nestjs.com/v6/recipes/terminus#custom-health-indicator)
* [Custom Logger](https://docs.nestjs.com/v6/recipes/terminus#custom-logger)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/recipes/terminus.md "Suggest Edits")

### Health checks (Terminus)

The [terminus](https://github.com/godaddy/terminus) offers hooks to react on graceful shutdowns and supports you creating proper [Kubernetes](https://kubernetes.io/) readiness / liveness checks for any HTTP application. The module [@nestjs/terminus](https://github.com/nestjs/terminus) integrates the terminus library with the Nest ecosystem.

#### Getting started[#](/recipes/terminus#getting-started)

To get started with `@nestjs/terminus` we need to install the required dependencies.

```bash

$ npm install --save @nestjs/terminus @godaddy/terminus
```

#### Setting up a health check[#](/recipes/terminus#setting-up-a-health-check)

A health check represents a summary of **health indicators**. A health indicator executes a check of a service, whether it is in a healthy state or not. A health check is positive, if all the assigned health indicators are up and running. Because a lot of applications will need similar health indicators, [@nestjs/terminus](https://github.com/nestjs/terminus) provides a set of predefined health indicators, such as:

* `DNSHealthIndicator`
* `TypeOrmHealthIndicator`
* `MongooseHealthIndicator`
* `MicroserviceHealthIndicator`
* `MemoryHealthIndicator`
* `DiskHealthIndicator`

#### DNS Health Check[#](/recipes/terminus#dns-health-check)

The first step to get started with our first health check, is to setup a service which will associate health indicators to an endpoint.

terminus-options.service.ts

JS TS

```typescript

import {
  TerminusEndpoint,
  TerminusOptionsFactory,
  DNSHealthIndicator,
  TerminusModuleOptions
} from '@nestjs/terminus';
import { Injectable } from '@nestjs/common';

@Injectable()
export class TerminusOptionsService implements TerminusOptionsFactory {
  constructor(
    private readonly dns: DNSHealthIndicator,
  ) {}

  createTerminusOptions(): TerminusModuleOptions {
    const healthEndpoint: TerminusEndpoint = {
      url: '/health',
      healthIndicators: [
        async () => this.dns.pingCheck('google', 'https://google.com'),
      ],
    };
    return {
      endpoints: [healthEndpoint],
    };
  }
}
```

```typescript

import { Injectable, Dependencies } from '@nestjs/common';
import { DNSHealthIndicator } from '@nestjs/terminus';

@Injectable()
@Dependencies(DNSHealthIndicator)
export class TerminusOptionsService {
  constructor(dns) {
    this.dns = dns;
  }

  createTerminusOptions() {
    const healthEndpoint = {
      url: '/health',
      healthIndicators: [
        async () => this.dns.pingCheck('google', 'https://google.com'),
      ],
    };
    return {
      endpoints: [healthEndpoint],
    };
  }
}
```

Once we have set up our `TerminusOptionsService`, we can import the `TerminusModule` into the root `ApplicationModule`. The `TerminusOptionsService` will provide the settings, which in turn will be used by the `TerminusModule`.

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { TerminusModule } from '@nestjs/terminus';
import { TerminusOptionsService } from './terminus-options.service';

@Module({
  imports: [
    TerminusModule.forRootAsync({
      useClass: TerminusOptionsService,
    }),
  ],
})
export class ApplicationModule { }
```

> **Hint** If done correctly, Nest will expose the defined health check(s), which are reachable through a GET request to the defined route. For example `curl -X GET 'http://localhost:3000/health'`

#### Custom health indicator[#](/recipes/terminus#custom-health-indicator)

In some cases, the predefined health indicators provided by `@nestjs/terminus` do not cover all of your health check requirements. In this case you can set up a custom health indicator according to your needs.

Let's get started by creating a service which will represent our custom health indicator. To get a basic understanding how a health indicator is structured, we will create an example `DogHealthIndicator`. This health indicator should have the state "up", if every `Dog` object has the type `goodboy`, otherwise it will throw an error, which then the health indicator will be seen as "down".

dog.health.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { HealthCheckError } from '@godaddy/terminus';
import { HealthIndicator, HealthIndicatorResult } from '@nestjs/terminus';

export interface Dog {
  name: string;
  type: string;
}

@Injectable()
export class DogHealthIndicator extends HealthIndicator {
  private readonly dogs: Dog[] = [
    { name: 'Fido', type: 'goodboy' },
    { name: 'Rex', type: 'badboy' },
  ];

  async isHealthy(key: string): Promise<HealthIndicatorResult> {
    const badboys = this.dogs.filter(dog => dog.type === 'badboy');
    const isHealthy = badboys.length === 0;
    const result = this.getStatus(key, isHealthy, { badboys: badboys.length });

    if (isHealthy) {
      return result;
    }
    throw new HealthCheckError('Dogcheck failed', result);
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';
import { HealthCheckError } from '@godaddy/terminus';

@Injectable()
export class DogHealthIndicator extends HealthIndicator {
  dogs = [
    { name: 'Fido', type: 'goodboy' },
    { name: 'Rex', type: 'badboy' },
  ];

  async isHealthy(key) {
    const badboys = this.dogs.filter(dog => dog.type === 'badboy');
    const isHealthy = badboys.length === 0;
    const result = this.getStatus(key, isHealthy, { badboys: badboys.length });

    if (isHealthy) {
      return result;
    }
    throw new HealthCheckError('Dogcheck failed', result);
  }
}
```

The next thing we need to do is registering the health indicator as a provider.

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { TerminusModule } from '@nestjs/terminus';
import { TerminusOptionsService } from './terminus-options.service';
import { DogHealthIndicator } from './dog.health';

@Module({
  imports: [
    TerminusModule.forRootAsync({
      imports: [ApplicationModule],
      useClass: TerminusOptionsService,
    }),
  ],
  providers: [DogHealthIndicator],
  exports: [DogHealthIndicator],
})
export class ApplicationModule { }
```

> **Hint** In a real world application the `DogHealthIndicator` should be provided in a separate module, for example `DogsModule`, which then will be imported by the `ApplicationModule`. But keep in mind to add the `DogHealthIndicator` to the `exports` array of the `DogModule` and add the `DogModule` in `imports` array of the `TerminusModule.forRootAsync()` parameter object.

The last required thing to do is to add the now available health indicator in the required health check endpoint. For that we go back to our `TerminusOptionsService` and implement it to the `/health` endpoint.

terminus-options.service.ts

JS TS

```typescript

import {
  TerminusEndpoint,
  TerminusOptionsFactory,
  DNSHealthIndicator,
  TerminusModuleOptions
} from '@nestjs/terminus';
import { Injectable } from '@nestjs/common';
import { DogHealthIndicator } from './dog.health';

@Injectable()
export class TerminusOptionsService implements TerminusOptionsFactory {
  constructor(
    private readonly dogHealthIndicator: DogHealthIndicator
  ) {}

  createTerminusOptions(): TerminusModuleOptions {
    const healthEndpoint: TerminusEndpoint = {
      url: '/health',
      healthIndicators: [
        async () => this.dogHealthIndicator.isHealthy('dog'),
      ],
    };
    return {
      endpoints: [healthEndpoint],
    };
  }
}
```

```typescript

import { DogHealthIndicator } from './dog.health';
import { Injectable, Dependencies } from '@nestjs/common';

@Injectable()
@Dependencies(DogHealthIndicator)
export class TerminusOptionsService {
  constructor(dogHealthIndicator) {
    this.dogHealthIndicator = dogHealthIndicator;
  }

  createTerminusOptions() {
    const healthEndpoint = {
      url: '/health',
      healthIndicators: [
        async () => this.dogHealthIndicator.isHealthy('dog'),
      ],
    };
    return {
      endpoints: [healthEndpoint],
    };
  }
}
```

If everything has been done correctly, the `/health` endpoint should respond with a `503` response code and the following data.

```json

{
  "status": "error",
  "error": {
    "dog": {
      "status": "down",
      "badboys": 1
    }
  }
}
```

You can view working examples in the `@nestjs/terminus`[repository](https://github.com/nestjs/terminus/tree/master/sample).

#### Custom Logger[#](/recipes/terminus#custom-logger)

The `Terminus` module automatically logs every error during a health check request. By default, it will use the globally defined Nest logger. You can read more about the global logger in the [Logger chapter](https://docs.nestjs.com/techniques/logger). In some cases, you want to handle the logs of `Terminus` explicitly. In this case, the `TerminusModule.forRoot[Async]` function offers an option for a custom logger.

```typescript


TerminusModule.forRootAsync({
  logger: (message: string, error: Error) => console.error(message, error),
  endpoints: [
    ...
  ]
})
```

The logger can also be disabled by setting the logger option to `null`.

```typescript


TerminusModule.forRootAsync({
  logger: null,
  endpoints: [
    ...
  ]
})
```

----
url: https://docs.nestjs.com/v7/techniques/serialization
----

* [Serialization](https://docs.nestjs.com/v7/techniques/serialization#serialization)
* [Overview](https://docs.nestjs.com/v7/techniques/serialization#overview)
* [Exclude properties](https://docs.nestjs.com/v7/techniques/serialization#exclude-properties)
* [Expose properties](https://docs.nestjs.com/v7/techniques/serialization#expose-properties)
* [Transform](https://docs.nestjs.com/v7/techniques/serialization#transform)
* [Pass options](https://docs.nestjs.com/v7/techniques/serialization#pass-options)
* [Example](https://docs.nestjs.com/v7/techniques/serialization#example)
* [WebSockets and Microservices](https://docs.nestjs.com/v7/techniques/serialization#websockets-and-microservices)
* [Learn more](https://docs.nestjs.com/v7/techniques/serialization#learn-more)

```typescript

import { Exclude } from 'class-transformer';

export class UserEntity {
  id: number;
  firstName: string;
  lastName: string;

  @Exclude()
  password: string;

  constructor(partial: Partial<UserEntity>) {
    Object.assign(this, partial);
  }
}
```

Now consider a controller with a method handler that returns an instance of this class.

```typescript

@UseInterceptors(ClassSerializerInterceptor)
@Get()
findOne(): UserEntity {
  return new UserEntity({
    id: 1,
    firstName: 'Kamil',
    lastName: 'Mysliwiec',
    password: 'password',
  });
}
```

> **Warning** Note that we must return an instance of the class. If you return a plain JavaScript object, for example, `{ user: new UserEntity() }`, the object won't be properly serialized.

> **Hint** The `ClassSerializerInterceptor` is imported from `@nestjs/common`.

When this endpoint is requested, the client receives the following response:

```json

{
  "id": 1,
  "firstName": "Kamil",
  "lastName": "Mysliwiec"
}
```

Note that the interceptor can be applied application-wide (as covered [here](https://docs.nestjs.com/interceptors#binding-interceptors)). The combination of the interceptor and the entity class declaration ensures that **any** method that returns a `UserEntity` will be sure to remove the `password` property. This gives you a measure of centralized enforcement of this business rule.

#### Expose properties[#](/techniques/serialization#expose-properties)

You can use the `@Expose()` decorator to provide alias names for properties, or to execute a function to calculate a property value (analogous to **getter** functions), as shown below.

```typescript

@Expose()
get fullName(): string {
  return `${this.firstName} ${this.lastName}`;
}
```

#### Transform[#](/techniques/serialization#transform)

You can perform additional data transformation using the `@Transform()` decorator. For example, the following construct returns the name property of the `RoleEntity` instead of returning the whole object.

```typescript

@Transform(role => role.name)
role: RoleEntity;
```

#### Pass options[#](/techniques/serialization#pass-options)

You may want to modify the default behavior of the transformation functions. To override default settings, pass them in an `options` object with the `@SerializeOptions()` decorator.

```typescript

@SerializeOptions({
  excludePrefixes: ['_'],
})
@Get()
findOne(): UserEntity {
  return new UserEntity();
}
```

> **Hint** The `@SerializeOptions()` decorator is imported from `@nestjs/common`.

----
url: https://docs.nestjs.com/v7/graphql/unions-and-enums
----

* [Unions](https://docs.nestjs.com/v7/graphql/unions-and-enums#unions)
* [Code first](https://docs.nestjs.com/v7/graphql/unions-and-enums#code-first)
* [Schema first](https://docs.nestjs.com/v7/graphql/unions-and-enums#schema-first)
* [Enums](https://docs.nestjs.com/v7/graphql/unions-and-enums#enums)
* [Code first](https://docs.nestjs.com/v7/graphql/unions-and-enums#code-first-1)
* [Schema first](https://docs.nestjs.com/v7/graphql/unions-and-enums#schema-first-1)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/unions-and-enums.md "Suggest Edits")

### Unions

Union types are very similar to interfaces, but they don't get to specify any common fields between the types (read more [here](https://graphql.org/learn/schema/#union-types)). Unions are useful for returning disjoint data types from a single field.

#### Code first[#](/graphql/unions-and-enums#code-first)

To define a GraphQL union type, we must define classes that this union will be composed of. Following the [example](https://www.apollographql.com/docs/apollo-server/schema/unions-interfaces/#union-type) from the Apollo documentation, we'll create two classes. First, `Book`:

```typescript

import { Field, ObjectType } from '@nestjs/graphql';

@ObjectType()
export class Book {
  @Field()
  title: string;
}
```

And then `Author`:

```typescript

import { Field, ObjectType } from '@nestjs/graphql';

@ObjectType()
export class Author {
  @Field()
  name: string;
}
```

With this in place, register the `ResultUnion` union using the `createUnionType` function exported from the `@nestjs/graphql` package:

```typescript

export const ResultUnion = createUnionType({
  name: 'ResultUnion',
  types: () => [Author, Book],
});
```

Now, we can reference the `ResultUnion` in our query:

```typescript

@Query(returns => [ResultUnion])
search(): Array<typeof ResultUnion> {
  return [new Author(), new Book()];
}
```

This will result in generating the following part of the GraphQL schema in SDL:

```graphql

type Author {
  name: String!
}

type Book {
  title: String!
}

union ResultUnion = Author | Book

type Query {
  search: [ResultUnion!]!
}
```

The default `resolveType()` function generated by the library will extract the type based on the value returned from the resolver method. That means returning class instances instead of literal JavaScript object is obligatory.

To provide a customized `resolveType()` function, pass the `resolveType` property to the options object passed into the `createUnionType()` function, as follows:

```typescript

export const ResultUnion = createUnionType({
  name: 'ResultUnion',
  types: () => [Author, Book],
  resolveType(value) {
    if (value.name) {
      return Author;
    }
    if (value.title) {
      return Book;
    }
    return null;
  },
});
```

#### Schema first[#](/graphql/unions-and-enums#schema-first)

To define a union in the schema first approach, simply create a GraphQL union with SDL.

```graphql

type Author {
  name: String!
}

type Book {
  title: String!
}

union ResultUnion = Author | Book
```

Then, you can use the typings generation feature (as shown in the [quick start](/v7/graphql/quick-start) chapter) to generate corresponding TypeScript definitions:

```typescript

export class Author {
  name: string;
}

export class Book {
  title: string;
}

export type ResultUnion = Author | Book;
```

Unions require an extra `__resolveType` field in the resolver map to determine which type the union should resolve to. Also, note that the `ResultUnionResolver` class has to be registered as a provider in any module. Let's create a `ResultUnionResolver` class and define the `__resolveType` method.

```typescript

@Resolver('ResultUnion')
export class ResultUnionResolver {
  @ResolveField()
  __resolveType(value) {
    if (value.name) {
      return 'Author';
    }
    if (value.title) {
      return 'Book';
    }
    return null;
  }
}
```

> **Hint** All decorators are exported from the `@nestjs/graphql` package.

### Enums

Enumeration types are a special kind of scalar that is restricted to a particular set of allowed values (read more [here](https://graphql.org/learn/schema/#enumeration-types)). This allows you to:

* validate that any arguments of this type are one of the allowed values
* communicate through the type system that a field will always be one of a finite set of values

#### Code first[#](/graphql/unions-and-enums#code-first-1)

When using the code first approach, you define a GraphQL enum type by simply creating a TypeScript enum.

```typescript

export enum AllowedColor {
  RED,
  GREEN,
  BLUE,
}
```

With this in place, register the `AllowedColor` enum using the `registerEnumType` function exported from the `@nestjs/graphql` package:

```typescript

registerEnumType(AllowedColor, {
  name: 'AllowedColor',
});
```

Now you can reference the `AllowedColor` in our types:

```typescript

@Field(type => AllowedColor)
favoriteColor: AllowedColor;
```

This will result in generating the following part of the GraphQL schema in SDL:

```graphql

enum AllowedColor {
  RED
  GREEN
  BLUE
}
```

To provide a description for the enum, pass the `description` property into the `registerEnumType()` function.

```typescript

registerEnumType(AllowedColor, {
  name: 'AllowedColor',
  description: 'The supported colors.',
});
```

To provide a description for the enum values, or to mark a value as deprecated, pass the `valuesMap` property, as follows:

```typescript

registerEnumType(AllowedColor, {
  name: 'AllowedColor',
  description: 'The supported colors.',
  valuesMap: {
    RED: {
      description: 'The default color.',
    },
    BLUE: {
      deprecationReason: 'Too blue.',
    },
  },
});
```

This will generate the following GraphQL schema in SDL:

```graphql

"""
The supported colors.
"""
enum AllowedColor {
  """
  The default color.
  """
  RED
  GREEN
  BLUE @deprecated(reason: "Too blue.")
}
```

#### Schema first[#](/graphql/unions-and-enums#schema-first-1)

To define an enumerator in the schema first approach, simply create a GraphQL enum with SDL.

```graphql

enum AllowedColor {
  RED
  GREEN
  BLUE
}
```

Then you can use the typings generation feature (as shown in the [quick start](/v7/graphql/quick-start) chapter) to generate corresponding TypeScript definitions:

```typescript

export enum AllowedColor {
  RED
  GREEN
  BLUE
}
```

Sometimes a backend forces a different value for an enum internally than in the public API. In this example the API contains `RED`, however in resolvers we may use `#f00` instead (read more [here](https://www.apollographql.com/docs/apollo-server/schema/scalars-enums/#internal-values)). To accomplish this, declare a resolver object for the `AllowedColor` enum:

```typescript

export const allowedColorResolver: Record<keyof typeof AllowedColor, any> = {
  RED: '#f00',
};
```

> **Hint** All decorators are exported from the `@nestjs/graphql` package.

Then use this resolver object together with the `resolvers` property of the `GraphQLModule#forRoot()` method, as follows:

```typescript

GraphQLModule.forRoot({
  resolvers: {
    AllowedColor: allowedColorResolver,
  },
});
```

----
url: https://docs.nestjs.com/v10/recipes/swc
----

* [SWC](https://docs.nestjs.com/v10/recipes/swc#swc)
* [Installation](https://docs.nestjs.com/v10/recipes/swc#installation)
* [Getting started](https://docs.nestjs.com/v10/recipes/swc#getting-started)
* [Type checking](https://docs.nestjs.com/v10/recipes/swc#type-checking)
* [CLI Plugins (SWC)](https://docs.nestjs.com/v10/recipes/swc#cli-plugins-swc)
* [SWC configuration](https://docs.nestjs.com/v10/recipes/swc#swc-configuration)
* [Monorepo](https://docs.nestjs.com/v10/recipes/swc#monorepo)
* [Monorepo and CLI plugins](https://docs.nestjs.com/v10/recipes/swc#monorepo-and-cli-plugins)
* [Common pitfalls](https://docs.nestjs.com/v10/recipes/swc#common-pitfalls)
* [Jest + SWC](https://docs.nestjs.com/v10/recipes/swc#jest--swc)
* [Vitest](https://docs.nestjs.com/v10/recipes/swc#vitest)
* [Installation](https://docs.nestjs.com/v10/recipes/swc#installation-1)
* [Configuration](https://docs.nestjs.com/v10/recipes/swc#configuration)
* [Update imports in E2E tests](https://docs.nestjs.com/v10/recipes/swc#update-imports-in-e2e-tests)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/recipes/swc.md "Suggest Edits")

### SWC

[SWC](https://swc.rs/) (Speedy Web Compiler) is an extensible Rust-based platform that can be used for both compilation and bundling. Using SWC with Nest CLI is a great and simple way to significantly speed up your development process.

> **Hint** SWC is approximately **x20 times faster** than the default TypeScript compiler.

#### Installation[#](/recipes/swc#installation)

To get started, first install a few packages:

```bash

$ npm i --save-dev @swc/cli @swc/core
```

#### Getting started[#](/recipes/swc#getting-started)

Once the installation process is complete, you can use the `swc` builder with Nest CLI, as follows:

```bash

$ nest start -b swc
# OR nest start --builder swc
```

> **Hint** If your repository is a monorepo, check out [this section](/recipes/swc#monorepo).

Instead of passing the `-b` flag you can also just set the `compilerOptions.builder` property to `"swc"` in your `nest-cli.json` file, like so:

```json

{
  "compilerOptions": {
    "builder": "swc"
  }
}
```

To customize builder's behavior, you can pass an object containing two attributes, `type` (`"swc"`) and `options`, as follows:

```json

"compilerOptions": {
  "builder": {
    "type": "swc",
    "options": {
      "swcrcPath": "infrastructure/.swcrc",
    }
  }
}
```

To run the application in watch mode, use the following command:

```bash

$ nest start -b swc -w
# OR nest start --builder swc --watch
```

#### Type checking[#](/recipes/swc#type-checking)

SWC does not perform any type checking itself (as opposed to the default TypeScript compiler), so to turn it on, you need to use the `--type-check` flag:

```bash

$ nest start -b swc --type-check
```

This command will instruct the Nest CLI to run `tsc` in `noEmit` mode alongside SWC, which will asynchronously perform type checking. Again, instead of passing the `--type-check` flag you can also just set the `compilerOptions.typeCheck` property to `true` in your `nest-cli.json` file, like so:

```json

{
  "compilerOptions": {
    "builder": "swc",
    "typeCheck": true
  }
}
```

#### CLI Plugins (SWC)[#](/recipes/swc#cli-plugins-swc)

The `--type-check` flag will automatically execute **NestJS CLI plugins** and produce a serialized metadata file which then can be loaded by the application at runtime.

#### SWC configuration[#](/recipes/swc#swc-configuration)

SWC builder is pre-configured to match the requirements of NestJS applications. However, you can customize the configuration by creating a `.swcrc` file in the root directory and tweaking the options as you wish.

```json

{
  "$schema": "https://json.schemastore.org/swcrc",
  "sourceMaps": true,
  "jsc": {
    "parser": {
      "syntax": "typescript",
      "decorators": true,
      "dynamicImport": true
    },
    "baseUrl": "./"
  },
  "minify": false
}
```

#### Monorepo[#](/recipes/swc#monorepo)

If your repository is a monorepo, then instead of using `swc` builder you have to configure `webpack` to use `swc-loader`.

First, let's install the required package:

```bash

$ npm i --save-dev swc-loader
```

Once the installation is complete, create a `webpack.config.js` file in the root directory of your application with the following content:

```js

const swcDefaultConfig = require('@nestjs/cli/lib/compiler/defaults/swc-defaults').swcDefaultsFactory().swcOptions;

module.exports = {
  module: {
    rules: [
      {
        test: /\.ts$/,
        exclude: /node_modules/,
        use: {
          loader: 'swc-loader',
          options: swcDefaultConfig,
        },
      },
    ],
  },
};
```

#### Monorepo and CLI plugins[#](/recipes/swc#monorepo-and-cli-plugins)

Now if you use CLI plugins, `swc-loader` will not load them automatically. Instead, you have to create a separate file that will load them manually. To do so, declare a `generate-metadata.ts` file near the `main.ts` file with the following content:

```ts

import { PluginMetadataGenerator } from '@nestjs/cli/lib/compiler/plugins/plugin-metadata-generator';
import { ReadonlyVisitor } from '@nestjs/swagger/dist/plugin';

const generator = new PluginMetadataGenerator();
generator.generate({
  visitors: [new ReadonlyVisitor({ introspectComments: true, pathToSource: __dirname })],
  outputDir: __dirname,
  watch: true,
  tsconfigPath: 'apps/<name>/tsconfig.app.json',
});
```

> **Hint** In this example we used `@nestjs/swagger` plugin, but you can use any plugin of your choice.

The `generate()` method accepts the following options:

| `watch`            | Whether to watch the project for changes.                                                      |
| ------------------ | ---------------------------------------------------------------------------------------------- |
| `tsconfigPath`     | Path to the `tsconfig.json` file. Relative to the current working directory (`process.cwd()`). |
| `outputDir`        | Path to the directory where the metadata file will be saved.                                   |
| `visitors`         | An array of visitors that will be used to generate metadata.                                   |
| `filename`         | The name of the metadata file. Defaults to `metadata.ts`.                                      |
| `printDiagnostics` | Whether to print diagnostics to the console. Defaults to `true`.                               |

Finally, you can run the `generate-metadata` script in a separate terminal window with the following command:

```bash

$ npx ts-node src/generate-metadata.ts
# OR npx ts-node apps/{YOUR_APP}/src/generate-metadata.ts
```

#### Common pitfalls[#](/recipes/swc#common-pitfalls)

If you use TypeORM/MikroORM or any other ORM in your application, you may stumble upon circular import issues. SWC doesn't handle **circular imports** well, so you should use the following workaround:

```typescript

@Entity()
export class User {
  @OneToOne(() => Profile, (profile) => profile.user)
  profile: Relation<Profile>; // <--- see "Relation<>" type here instead of just "Profile"
}
```

> **Hint**`Relation` type is exported from the `typeorm` package.

Doing this prevents the type of the property from being saved in the transpiled code in the property metadata, preventing circular dependency issues.

If your ORM does not provide a similar workaround, you can define the wrapper type yourself:

```typescript

/**
 * Wrapper type used to circumvent ESM modules circular dependency issue
 * caused by reflection metadata saving the type of the property.
 */
export type WrapperType<T> = T; // WrapperType === Relation
```

For all [circular dependency injections](/v10/fundamentals/circular-dependency) in your project, you will also need to use the custom wrapper type described above:

```typescript

@Injectable()
export class UserService {
  constructor(
    @Inject(forwardRef(() => ProfileService))
    private readonly profileService: WrapperType<ProfileService>,
  ) {};
}
```

### Jest + SWC

To use SWC with Jest, you need to install the following packages:

```bash

$ npm i --save-dev jest @swc/core @swc/jest
```

Once the installation is complete, update the `package.json`/`jest.config.js` file (depending on your configuration) with the following content:

```json

{
  "jest": {
    "transform": {
      "^.+\\.(t|j)s?$": ["@swc/jest"]
    }
  }
}
```

Additionally you would need to add the following `transform` properties to your `.swcrc` file: `legacyDecorator`, `decoratorMetadata`:

```json

{
  "$schema": "https://json.schemastore.org/swcrc",
  "sourceMaps": true,
  "jsc": {
    "parser": {
      "syntax": "typescript",
      "decorators": true,
      "dynamicImport": true
    },
    "transform": {
      "legacyDecorator": true,
      "decoratorMetadata": true
    },
    "baseUrl": "./"
  },
  "minify": false
}
```

If you use NestJS CLI Plugins in your project, you'll have to run `PluginMetadataGenerator` manually. Navigate to [this section](/recipes/swc#monorepo-and-cli-plugins) to learn more.

### Vitest

[Vitest](https://vitest.dev/) is a fast and lightweight test runner designed to work with Vite. It provides a modern, fast, and easy-to-use testing solution that can be integrated with NestJS projects.

#### Installation[#](/recipes/swc#installation-1)

To get started, first install the required packages:

```bash

$ npm i --save-dev vitest unplugin-swc @swc/core @vitest/coverage-v8
```

#### Configuration[#](/recipes/swc#configuration)

Create a `vitest.config.ts` file in the root directory of your application with the following content:

```ts

import swc from 'unplugin-swc';
import { defineConfig } from 'vitest/config';

export default defineConfig({
  test: {
    globals: true,
    root: './',
  },
  plugins: [
    // This is required to build the test files with SWC
    swc.vite({
      // Explicitly set the module type to avoid inheriting this value from a `.swcrc` config file
      module: { type: 'es6' },
    }),
  ],
});
```

This configuration file sets up the Vitest environment, root directory, and SWC plugin. You should also create a separate configuration file for e2e tests, with an additional `include` field that specifies the test path regex:

```ts

import swc from 'unplugin-swc';
import { defineConfig } from 'vitest/config';

export default defineConfig({
  test: {
    include: ['**/*.e2e-spec.ts'],
    globals: true,
    root: './',
  },
  plugins: [swc.vite()],
});
```

Additionally, you can set the `alias` options to support TypeScript paths in your tests:

```ts

import swc from 'unplugin-swc';
import { defineConfig } from 'vitest/config';

export default defineConfig({
  test: {
    include: ['**/*.e2e-spec.ts'],
    globals: true,
    alias: {
      '@src': './src',
      '@test': './test',
    },
    root: './',
  },
  resolve: {
    alias: {
      '@src': './src',
      '@test': './test',
    },
  },
  plugins: [swc.vite()],
});
```

#### Update imports in E2E tests[#](/recipes/swc#update-imports-in-e2e-tests)

Change any E2E test imports using `import * as request from 'supertest'` to `import request from 'supertest'`. This is necessary because Vitest, when bundled with Vite, expects a default import for supertest. Using a namespace import may cause issues in this specific setup.

Lastly, update the test scripts in your package.json file to the following:

```json

{
  "scripts": {
    "test": "vitest run",
    "test:watch": "vitest",
    "test:cov": "vitest run --coverage",
    "test:debug": "vitest --inspect-brk --inspect --logHeapUsage --threads=false",
    "test:e2e": "vitest run --config ./vitest.config.e2e.ts"
  }
}
```

These scripts configure Vitest for running tests, watching for changes, generating code coverage reports, and debugging. The test:e2e script is specifically for running E2E tests with a custom configuration file.

With this setup, you can now enjoy the benefits of using Vitest in your NestJS project, including faster test execution and a more modern testing experience.

> **Hint** You can check out a working example in this [repository](https://github.com/TrilonIO/nest-vitest)

----
url: https://docs.nestjs.com/v8/graphql/quick-start
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Installation](https://docs.nestjs.com/v8/graphql/quick-start#installation)
* [Overview](https://docs.nestjs.com/v8/graphql/quick-start#overview)
* [Getting started with GraphQL & TypeScript](https://docs.nestjs.com/v8/graphql/quick-start#getting-started-with-graphql--typescript)
* [GraphQL playground](https://docs.nestjs.com/v8/graphql/quick-start#graphql-playground)
* [Multiple endpoints](https://docs.nestjs.com/v8/graphql/quick-start#multiple-endpoints)
* [Code first](https://docs.nestjs.com/v8/graphql/quick-start#code-first)
* [Example](https://docs.nestjs.com/v8/graphql/quick-start#example)
* [Schema first](https://docs.nestjs.com/v8/graphql/quick-start#schema-first)
* [Apollo Sandbox](https://docs.nestjs.com/v8/graphql/quick-start#apollo-sandbox)
* [Example](https://docs.nestjs.com/v8/graphql/quick-start#example-1)
* [Accessing generated schema](https://docs.nestjs.com/v8/graphql/quick-start#accessing-generated-schema)
* [Async configuration](https://docs.nestjs.com/v8/graphql/quick-start#async-configuration)
* [Mercurius integration](https://docs.nestjs.com/v8/graphql/quick-start#mercurius-integration)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/quick-start.md "Suggest Edits")

## Harnessing the power of TypeScript & GraphQL

[GraphQL](https://graphql.org/) is a powerful query language for APIs and a runtime for fulfilling those queries with your existing data. It's an elegant approach that solves many problems typically found with REST APIs. For background, we suggest reading this [comparison](https://dev-blog.apollodata.com/graphql-vs-rest-5d425123e34b) between GraphQL and REST. GraphQL combined with [TypeScript](https://www.typescriptlang.org/) helps you develop better type safety with your GraphQL queries, giving you end-to-end typing.

In this chapter, we assume a basic understanding of GraphQL, and focus on how to work with the built-in `@nestjs/graphql` module. The `GraphQLModule` can be configured to use [Apollo](https://www.apollographql.com/) server (with the `@nestjs/apollo` driver) and [Mercurius](https://github.com/mercurius-js/mercurius) (with the `@nestjs/mercurius`). We provide official integrations for these proven GraphQL packages to provide a simple way to use GraphQL with Nest. You can also build your own dedicated driver (read more on that [here](/graphql/other-features#creating-a-custom-driver)).

#### Installation[#](/graphql/quick-start#installation)

Start by installing the required packages:

```bash

# For Express and Apollo (default)
$ npm i @nestjs/graphql @nestjs/apollo graphql apollo-server-express

# For Fastify and Apollo
# npm i @nestjs/graphql @nestjs/apollo graphql apollo-server-fastify

# For Fastify and Mercurius
# npm i @nestjs/graphql @nestjs/mercurius graphql mercurius@^9
```

> **Warning**`@nestjs/graphql@>=9` and `@nestjs/apollo^10` packages are compatible with **Apollo v3** (check out Apollo Server 3 [migration guide](https://www.apollographql.com/docs/apollo-server/migration/) for more details), while `@nestjs/graphql@^8` only supports **Apollo v2** (e.g., `apollo-server-express@2.x.x` package).

#### Overview[#](/graphql/quick-start#overview)

Nest offers two ways of building GraphQL applications, the **code first** and the **schema first** methods. You should choose the one that works best for you. Most of the chapters in this GraphQL section are divided into two main parts: one you should follow if you adopt **code first**, and the other to be used if you adopt **schema first**.

In the **code first** approach, you use decorators and TypeScript classes to generate the corresponding GraphQL schema. This approach is useful if you prefer to work exclusively with TypeScript and avoid context switching between language syntaxes.

In the **schema first** approach, the source of truth is GraphQL SDL (Schema Definition Language) files. SDL is a language-agnostic way to share schema files between different platforms. Nest automatically generates your TypeScript definitions (using either classes or interfaces) based on the GraphQL schemas to reduce the need to write redundant boilerplate code.

#### Getting started with GraphQL & TypeScript[#](/graphql/quick-start#getting-started-with-graphql--typescript)

> **Hint** In the following chapters, we'll be integrating the `@nestjs/apollo` package. If you want to use `mercurius` package instead, navigate to [this section](/graphql/quick-start#mercurius-integration).

Once the packages are installed, we can import the `GraphQLModule` and configure it with the `forRoot()` static method.

JS TS

```typescript

import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';
import { ApolloDriver, ApolloDriverConfig } from '@nestjs/apollo';

@Module({
  imports: [
    GraphQLModule.forRoot<ApolloDriverConfig>({
      driver: ApolloDriver,
    }),
  ],
})
export class AppModule {}
```

> **Hint** For `mercurius` integration, you should be using the `MercuriusDriver` and `MercuriusDriverConfig` instead. Both are exported from the `@nestjs/mercurius` package.

The `forRoot()` method takes an options object as an argument. These options are passed through to the underlying driver instance (read more about available settings here: [Apollo](https://www.apollographql.com/docs/apollo-server/v2/api/apollo-server.html#constructor-options-lt-ApolloServer-gt) and [Mercurius](https://github.com/mercurius-js/mercurius/blob/master/docs/api/options.md#plugin-options)). For example, if you want to disable the `playground` and turn off `debug` mode (for Apollo), pass the following options:

JS TS

```typescript

import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';
import { ApolloDriver, ApolloDriverConfig } from '@nestjs/apollo';

@Module({
  imports: [
    GraphQLModule.forRoot<ApolloDriverConfig>({
      driver: ApolloDriver,
      debug: false,
      playground: false,
    }),
  ],
})
export class AppModule {}
```

In this case, these options will be forwarded to the `ApolloServer` constructor.

## Official enterprise support

* **Providing technical guidance
* **Performing in-depth code reviews
* **Mentoring team members
* **Advising best practices

[Explore more](https://enterprise.nestjs.com "Enterprise | NestJS - A progressive Node.js framework")

#### GraphQL playground[#](/graphql/quick-start#graphql-playground)

The playground is a graphical, interactive, in-browser GraphQL IDE, available by default on the same URL as the GraphQL server itself. To access the playground, you need a basic GraphQL server configured and running. To see it now, you can install and build the [working example here](https://github.com/nestjs/nest/tree/master/sample/23-graphql-code-first). Alternatively, if you're following along with these code samples, once you've completed the steps in the [Resolvers chapter](/v8/graphql/resolvers-map), you can access the playground.

With that in place, and with your application running in the background, you can then open your web browser and navigate to `http://localhost:3000/graphql` (host and port may vary depending on your configuration). You will then see the GraphQL playground, as shown below.

> **Note**`@nestjs/mercurius` integration does not ship with the built-in GraphQL Playground integration. Instead, you can use [GraphiQL](https://github.com/graphql/graphiql) (set `graphiql: true`).

#### Multiple endpoints[#](/graphql/quick-start#multiple-endpoints)

Another useful feature of the `@nestjs/graphql` module is the ability to serve multiple endpoints at once. This lets you decide which modules should be included in which endpoint. By default, `GraphQL` searches for resolvers throughout the whole app. To limit this scan to only a subset of modules, use the `include` property.

```typescript

GraphQLModule.forRoot({
  include: [CatsModule],
}),
```

> **Warning** If you use the `apollo-server-fastify` package with multiple GraphQL endpoints in a single application, make sure to enable the `disableHealthCheck` setting in the `GraphQLModule` configuration.

#### Code first[#](/graphql/quick-start#code-first)

In the **code first** approach, you use decorators and TypeScript classes to generate the corresponding GraphQL schema.

To use the code first approach, start by adding the `autoSchemaFile` property to the options object:

```typescript

GraphQLModule.forRoot<ApolloDriverConfig>({
  driver: ApolloDriver,
  autoSchemaFile: join(process.cwd(), 'src/schema.gql'),
}),
```

The `autoSchemaFile` property value is the path where your automatically generated schema will be created. Alternatively, the schema can be generated on-the-fly in memory. To enable this, set the `autoSchemaFile` property to `true`:

```typescript

GraphQLModule.forRoot<ApolloDriverConfig>({
  driver: ApolloDriver,
  autoSchemaFile: true,
}),
```

By default, the types in the generated schema will be in the order they are defined in the included modules. To sort the schema lexicographically, set the `sortSchema` property to `true`:

```typescript

GraphQLModule.forRoot<ApolloDriverConfig>({
  driver: ApolloDriver,
  autoSchemaFile: join(process.cwd(), 'src/schema.gql'),
  sortSchema: true,
}),
```

#### Example[#](/graphql/quick-start#example)

A fully working code first sample is available [here](https://github.com/nestjs/nest/tree/master/sample/23-graphql-code-first).

#### Schema first[#](/graphql/quick-start#schema-first)

To use the schema first approach, start by adding a `typePaths` property to the options object. The `typePaths` property indicates where the `GraphQLModule` should look for GraphQL SDL schema definition files you'll be writing. These files will be combined in memory; this allows you to split your schemas into several files and locate them near their resolvers.

```typescript

GraphQLModule.forRoot<ApolloDriverConfig>({
  driver: ApolloDriver,
  typePaths: ['./**/*.graphql'],
}),
```

You will typically also need to have TypeScript definitions (classes and interfaces) that correspond to the GraphQL SDL types. Creating the corresponding TypeScript definitions by hand is redundant and tedious. It leaves us without a single source of truth -- each change made within SDL forces us to adjust TypeScript definitions as well. To address this, the `@nestjs/graphql` package can **automatically generate** TypeScript definitions from the abstract syntax tree ([AST](https://en.wikipedia.org/wiki/Abstract_syntax_tree)). To enable this feature, add the `definitions` options property when configuring the `GraphQLModule`.

```typescript

GraphQLModule.forRoot<ApolloDriverConfig>({
  driver: ApolloDriver,
  typePaths: ['./**/*.graphql'],
  definitions: {
    path: join(process.cwd(), 'src/graphql.ts'),
  },
}),
```

The path property of the `definitions` object indicates where to save generated TypeScript output. By default, all generated TypeScript types are created as interfaces. To generate classes instead, specify the `outputAs` property with a value of `'class'`.

```typescript

GraphQLModule.forRoot<ApolloDriverConfig>({
  driver: ApolloDriver,
  typePaths: ['./**/*.graphql'],
  definitions: {
    path: join(process.cwd(), 'src/graphql.ts'),
    outputAs: 'class',
  },
}),
```

The above approach dynamically generates TypeScript definitions each time the application starts. Alternatively, it may be preferable to build a simple script to generate these on demand. For example, assume we create the following script as `generate-typings.ts`:

```typescript

import { GraphQLDefinitionsFactory } from '@nestjs/graphql';
import { join } from 'path';

const definitionsFactory = new GraphQLDefinitionsFactory();
definitionsFactory.generate({
  typePaths: ['./src/**/*.graphql'],
  path: join(process.cwd(), 'src/graphql.ts'),
  outputAs: 'class',
});
```

Now you can run this script on demand:

```bash

$ ts-node generate-typings
```

> **Hint** You can compile the script beforehand (e.g., with `tsc`) and use `node` to execute it.

To enable watch mode for the script (to automatically generate typings whenever any `.graphql` file changes), pass the `watch` option to the `generate()` method.

```typescript

definitionsFactory.generate({
  typePaths: ['./src/**/*.graphql'],
  path: join(process.cwd(), 'src/graphql.ts'),
  outputAs: 'class',
  watch: true,
});
```

To automatically generate the additional `__typename` field for every object type, enable the `emitTypenameField` option.

```typescript

definitionsFactory.generate({
  // ...,
  emitTypenameField: true,
});
```

To generate resolvers (queries, mutations, subscriptions) as plain fields without arguments, enable the `skipResolverArgs` option.

```typescript

definitionsFactory.generate({
  // ...,
  skipResolverArgs: true,
});
```

#### Apollo Sandbox[#](/graphql/quick-start#apollo-sandbox)

To use [Apollo Sandbox](https://www.apollographql.com/blog/announcement/platform/apollo-sandbox-an-open-graphql-ide-for-local-development/) instead of the `graphql-playground` as a GraphQL IDE for local development, use the following configuration:

```typescript

import { ApolloDriver, ApolloDriverConfig } from '@nestjs/apollo';
import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';
import { ApolloServerPluginLandingPageLocalDefault } from 'apollo-server-core';

@Module({
  imports: [
    GraphQLModule.forRoot<ApolloDriverConfig>({
      driver: ApolloDriver,
      playground: false,
      plugins: [ApolloServerPluginLandingPageLocalDefault()],
    }),
  ],
})
export class AppModule {}
```

#### Example[#](/graphql/quick-start#example-1)

A fully working schema first sample is available [here](https://github.com/nestjs/nest/tree/master/sample/12-graphql-schema-first).

#### Accessing generated schema[#](/graphql/quick-start#accessing-generated-schema)

In some circumstances (for example end-to-end tests), you may want to get a reference to the generated schema object. In end-to-end tests, you can then run queries using the `graphql` object without using any HTTP listeners.

You can access the generated schema (in either the code first or schema first approach), using the `GraphQLSchemaHost` class:

```typescript

const { schema } = app.get(GraphQLSchemaHost);
```

> **Hint** You must call the `GraphQLSchemaHost#schema` getter after the application has been initialized (after the `onModuleInit` hook has been triggered by either the `app.listen()` or `app.init()` method).

#### Async configuration[#](/graphql/quick-start#async-configuration)

When you need to pass module options asynchronously instead of statically, use the `forRootAsync()` method. As with most dynamic modules, Nest provides several techniques to deal with async configuration.

One technique is to use a factory function:

```typescript

 GraphQLModule.forRootAsync<ApolloDriverConfig>({
  driver: ApolloDriver,
  useFactory: () => ({
    typePaths: ['./**/*.graphql'],
  }),
}),
```

Like other factory providers, our factory function can be [async](https://docs.nestjs.com/fundamentals/custom-providers#factory-providers-usefactory) and can inject dependencies through `inject`.

```typescript

GraphQLModule.forRootAsync<ApolloDriverConfig>({
  driver: ApolloDriver,
  imports: [ConfigModule],
  useFactory: async (configService: ConfigService) => ({
    typePaths: configService.getString('GRAPHQL_TYPE_PATHS'),
  }),
  inject: [ConfigService],
}),
```

Alternatively, you can configure the `GraphQLModule` using a class instead of a factory, as shown below:

```typescript

GraphQLModule.forRootAsync<ApolloDriverConfig>({
  driver: ApolloDriver,
  useClass: GqlConfigService,
}),
```

The construction above instantiates `GqlConfigService` inside `GraphQLModule`, using it to create options object. Note that in this example, the `GqlConfigService` has to implement the `GqlOptionsFactory` interface, as shown below. The `GraphQLModule` will call the `createGqlOptions()` method on the instantiated object of the supplied class.

```typescript

@Injectable()
class GqlConfigService implements GqlOptionsFactory {
  createGqlOptions(): ApolloDriverConfig {
    return {
      typePaths: ['./**/*.graphql'],
    };
  }
}
```

If you want to reuse an existing options provider instead of creating a private copy inside the `GraphQLModule`, use the `useExisting` syntax.

```typescript

GraphQLModule.forRootAsync<ApolloDriverConfig>({
  imports: [ConfigModule],
  useExisting: ConfigService,
}),
```

#### Mercurius integration[#](/graphql/quick-start#mercurius-integration)

Instead of using Apollo, Fastify users (read more [here](/v8/techniques/performance)) can alternatively use the `@nestjs/mercurius` driver.

JS TS

```typescript

import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';
import { MercuriusDriver, MercuriusDriverConfig } from '@nestjs/mercurius';

@Module({
  imports: [
    GraphQLModule.forRoot<MercuriusDriverConfig>({
      driver: MercuriusDriver,
      graphiql: true,
    }),
  ],
})
export class AppModule {}
```

> **Hint** Once the application is running, open your browser and navigate to `http://localhost:3000/graphiql`. You should see the [GraphQL IDE](https://github.com/graphql/graphiql).

The `forRoot()` method takes an options object as an argument. These options are passed through to the underlying driver instance. Read more about available settings [here](https://github.com/mercurius-js/mercurius/blob/master/docs/api/options.md#plugin-options).

----
url: https://docs.nestjs.com/openapi/decorators
----

[Skip to content](#content)

On this page

* [Decorators](https://docs.nestjs.com/openapi/decorators#decorators)

### Decorators

All OpenAPI decorators have an `Api` prefix to distinguish them from the core decorators. The table below lists the exported decorators, along with the level at which each one can be applied.

| `@ApiBasicAuth()`         | Method / Controller         |
| ------------------------- | --------------------------- |
| `@ApiBearerAuth()`        | Method / Controller         |
| `@ApiBody()`              | Method                      |
| `@ApiConsumes()`          | Method / Controller         |
| `@ApiCookieAuth()`        | Method / Controller         |
| `@ApiExcludeController()` | Controller                  |
| `@ApiExcludeEndpoint()`   | Method                      |
| `@ApiDefaultGetter()`     | Method                      |
| `@ApiExtension()`         | Method / Controller         |
| `@ApiExtraModels()`       | Method / Controller / Model |
| `@ApiHeader()`            | Method / Controller         |
| `@ApiHeaders()`           | Method / Controller         |
| `@ApiHideProperty()`      | Model                       |
| `@ApiIncludeEndpoint()`   | Method                      |
| `@ApiLink()`              | Method                      |
| `@ApiOAuth2()`            | Method / Controller         |
| `@ApiOperation()`         | Method                      |
| `@ApiParam()`             | Method / Controller         |
| `@ApiProduces()`          | Method / Controller         |
| `@ApiSchema()`            | Model                       |
| `@ApiProperty()`          | Model                       |
| `@ApiPropertyOptional()`  | Model                       |
| `@ApiQuery()`             | Method / Controller         |
| `@ApiResponse()`          | Method / Controller         |
| `@ApiResponseProperty()`  | Model                       |
| `@ApiSecurity()`          | Method / Controller         |
| `@ApiTags()`              | Method / Controller         |
| `@ApiCallbacks()`         | Method / Controller         |
| `@ApiWebhook()`           | Method                      |

The shorthand response decorators (e.g., `@ApiOkResponse()` and `@ApiNotFoundResponse()`, listed in the [operations](/openapi/operations#responses) chapter) can be applied at the same levels as `@ApiResponse()`.

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/openapi/decorators.md)

----
url: https://docs.nestjs.com/v8/security/rate-limiting
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Rate Limiting](https://docs.nestjs.com/v8/security/rate-limiting#rate-limiting)
* [Customization](https://docs.nestjs.com/v8/security/rate-limiting#customization)
* [Proxies](https://docs.nestjs.com/v8/security/rate-limiting#proxies)
* [Websockets](https://docs.nestjs.com/v8/security/rate-limiting#websockets)
* [GraphQL](https://docs.nestjs.com/v8/security/rate-limiting#graphql)
* [Configuration](https://docs.nestjs.com/v8/security/rate-limiting#configuration)
* [Async Configuration](https://docs.nestjs.com/v8/security/rate-limiting#async-configuration)
* [Storages](https://docs.nestjs.com/v8/security/rate-limiting#storages)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/security/rate-limiting.md "Suggest Edits")

### Rate Limiting

A common technique to protect applications from brute-force attacks is **rate-limiting**. To get started, you'll need to install the `@nestjs/throttler` package.

```bash

$ npm i --save @nestjs/throttler
```

Once the installation is complete, the `ThrottlerModule` can be configured as any other Nest package with `forRoot` or `forRootAsync` methods.

```typescript

@Module({
  imports: [
    ThrottlerModule.forRoot({
      ttl: 60,
      limit: 10,
    }),
  ],
})
export class AppModule {}
```

The above will set the global options for the `ttl`, the time to live, and the `limit`, the maximum number of requests within the ttl, for the routes of your application that are guarded.

Once the module has been imported, you can then choose how you would like to bind the `ThrottlerGuard`. Any kind of binding as mentioned in the [guards](https://docs.nestjs.com/guards) section is fine. If you wanted to bind the guard globally, for example, you could do so by adding this provider to any module:

```typescript

{
  provide: APP_GUARD,
  useClass: ThrottlerGuard
}
```

#### Customization[#](/security/rate-limiting#customization)

There may be a time where you want to bind the guard to a controller or globally, but want to disable rate limiting for one or more of your endpoints. For that, you can use the `@SkipThrottle()` decorator, to negate the throttler for an entire class or a single route. The `@SkipThrottle()` decorator can also take in a boolean for if there is a case where you want to exclude *most* of a controller, but not every route.

```typescript

@SkipThrottle()
@Controller('users')
export class UsersController {}
```

This `@SkipThrottle()` decorator can be used to skip a route or a class or to negate the skipping of a route in a class that is skipped.

```typescript

@SkipThrottle()
@Controller('users')
export class UsersController {
  // Rate limiting is applied to this route.
  @SkipThrottle(false)
  dontSkip() {
    return "List users work with Rate limiting.";
  }
  // This route will skip rate limiting.
  doSkip() {
    return "List users work without Rate limiting.";
  }
}
```

There is also the `@Throttle()` decorator which can be used to override the `limit` and `ttl` set in the global module, to give tighter or looser security options. This decorator can be used on a class or a function as well. The order for this decorator does matter, as the arguments are in the order of `limit, ttl`. You have to configure it like this:

```typescript

// Override default configuration for Rate limiting and duration.
@Throttle(3, 60)
@Get()
findAll() {
  return "List users works with custom rate limiting.";
}
```

#### Proxies[#](/security/rate-limiting#proxies)

If your application runs behind a proxy server, check the specific HTTP adapter options ([express](http://expressjs.com/en/guide/behind-proxies.html) and [fastify](https://www.fastify.io/docs/latest/Reference/Server/#trustproxy)) for the `trust proxy` option and enable it. Doing so will allow you to get the original IP address from the `X-Forwarded-For` header, and you can override the `getTracker()` method to pull the value from the header rather than from `req.ip`. The following example works with both express and fastify:

```typescript

// throttler-behind-proxy.guard.ts
import { ThrottlerGuard } from '@nestjs/throttler';
import { Injectable } from '@nestjs/common';

@Injectable()
export class ThrottlerBehindProxyGuard extends ThrottlerGuard {
  protected getTracker(req: Record<string, any>): string {
    return req.ips.length ? req.ips[0] : req.ip; // individualize IP extraction to meet your own needs
  }
}

// app.controller.ts
import { ThrottlerBehindProxyGuard } from './throttler-behind-proxy.guard';

@UseGuards(ThrottlerBehindProxyGuard)
```

> **Hint** You can find the API of the `req` Request object for express [here](https://expressjs.com/en/api.html#req.ips) and for fastify [here](https://www.fastify.io/docs/latest/Reference/Request/).

#### Websockets[#](/security/rate-limiting#websockets)

This module can work with websockets, but it requires some class extension. You can extend the `ThrottlerGuard` and override the `handleRequest` method like so:

```typescript

@Injectable()
export class WsThrottlerGuard extends ThrottlerGuard {
  async handleRequest(
    context: ExecutionContext,
    limit: number,
    ttl: number,
  ): Promise<boolean> {
    const client = context.switchToWs().getClient();
    const ip = client.conn.remoteAddress;
    const key = this.generateKey(context, ip);
    const ttls = await this.storageService.getRecord(key);

    if (ttls.length >= limit) {
      throw new ThrottlerException();
    }

    await this.storageService.addRecord(key, ttl);
    return true;
  }
}
```

> **Hint** If you are using the `@nestjs/platform-ws` package you can use `client._socket.remoteAddress` instead.

#### GraphQL[#](/security/rate-limiting#graphql)

The `ThrottlerGuard` can also be used to work with GraphQL requests. Again, the guard can be extended, but this time the `getRequestResponse` method will be overridden

```typescript

@Injectable()
export class GqlThrottlerGuard extends ThrottlerGuard {
  getRequestResponse(context: ExecutionContext) {
    const gqlCtx = GqlExecutionContext.create(context);
    const ctx = gqlCtx.getContext();
    return { req: ctx.req, res: ctx.res };
  }
}
```

#### Configuration[#](/security/rate-limiting#configuration)

The following options are valid for the `ThrottlerModule`:

|                    |                                                                                               |
| ------------------ | --------------------------------------------------------------------------------------------- |
| `ttl`              | the number of seconds that each request will last in storage                                  |
| `limit`            | the maximum number of requests within the TTL limit                                           |
| `ignoreUserAgents` | an array of regular expressions of user-agents to ignore when it comes to throttling requests |
| `storage`          | the storage setting for how to keep track of the requests                                     |

#### Async Configuration[#](/security/rate-limiting#async-configuration)

You may want to get your rate-limiting configuration asynchronously instead of synchronously. You can use the `forRootAsync()` method, which allows for dependency injection and `async` methods.

One approach would be to use a factory function:

```typescript

@Module({
  imports: [
    ThrottlerModule.forRootAsync({
      imports: [ConfigModule],
      inject: [ConfigService],
      useFactory: (config: ConfigService) => ({
        ttl: config.get('THROTTLE_TTL'),
        limit: config.get('THROTTLE_LIMIT'),
      }),
    }),
  ],
})
export class AppModule {}
```

You can also use the `useClass` syntax:

```typescript

@Module({
  imports: [
    ThrottlerModule.forRootAsync({
      imports: [ConfigModule],
      useClass: ThrottlerConfigService,
    }),
  ],
})
export class AppModule {}
```

This is doable, as long as `ThrottlerConfigService` implements the interface `ThrottlerOptionsFactory`.

#### Storages[#](/security/rate-limiting#storages)

The built in storage is an in memory cache that keeps track of the requests made until they have passed the TTL set by the global options. You can drop in your own storage option to the `storage` option of the `ThrottlerModule` so long as the class implements the `ThrottlerStorage` interface.

For distributed servers you could use the community storage provider for [Redis](https://github.com/kkoomen/nestjs-throttler-storage-redis) to have a single source of truth.

> **Note**`ThrottlerStorage` can be imported from `@nestjs/throttler`.

----
url: https://docs.nestjs.com/v7/guards
----

* [Guards](https://docs.nestjs.com/v7/guards#guards)
* [Authorization guard](https://docs.nestjs.com/v7/guards#authorization-guard)
* [Execution context](https://docs.nestjs.com/v7/guards#execution-context)
* [Role-based authentication](https://docs.nestjs.com/v7/guards#role-based-authentication)
* [Binding guards](https://docs.nestjs.com/v7/guards#binding-guards)
* [Setting roles per handler](https://docs.nestjs.com/v7/guards#setting-roles-per-handler)
* [Putting it all together](https://docs.nestjs.com/v7/guards#putting-it-all-together)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/guards.md "Suggest Edits")

### Guards

A guard is a class annotated with the `@Injectable()` decorator. Guards should implement the `CanActivate` interface.

Guards have a **single responsibility**. They determine whether a given request will be handled by the route handler or not, depending on certain conditions (like permissions, roles, ACLs, etc.) present at run-time. This is often referred to as **authorization**. Authorization (and its cousin, **authentication**, with which it usually collaborates) has typically been handled by [middleware](/v7/middleware) in traditional Express applications. Middleware is a fine choice for authentication, since things like token validation and attaching properties to the `request` object are not strongly connected with a particular route context (and its metadata).

But middleware, by its nature, is dumb. It doesn't know which handler will be executed after calling the `next()` function. On the other hand, **Guards** have access to the `ExecutionContext` instance, and thus know exactly what's going to be executed next. They're designed, much like exception filters, pipes, and interceptors, to let you interpose processing logic at exactly the right point in the request/response cycle, and to do so declaratively. This helps keep your code DRY and declarative.

> **Hint** Guards are executed **after** each middleware, but **before** any interceptor or pipe.

#### Authorization guard[#](/guards#authorization-guard)

As mentioned, **authorization** is a great use case for Guards because specific routes should be available only when the caller (usually a specific authenticated user) has sufficient permissions. The `AuthGuard` that we'll build now assumes an authenticated user (and that, therefore, a token is attached to the request headers). It will extract and validate the token, and use the extracted information to determine whether the request can proceed or not.

auth.guard.ts

JS TS

```typescript

import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
import { Observable } from 'rxjs';

@Injectable()
export class AuthGuard implements CanActivate {
  canActivate(
    context: ExecutionContext,
  ): boolean | Promise<boolean> | Observable<boolean> {
    const request = context.switchToHttp().getRequest();
    return validateRequest(request);
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';

@Injectable()
export class AuthGuard {
  async canActivate(context) {
    const request = context.switchToHttp().getRequest();
    return validateRequest(request);
  }
}
```

> **Hint** If you are looking for a real-world example on how to implement an authentication mechanism in your application, visit [this chapter](/v7/security/authentication). Likewise, for more sophisticated authorization example, check [this page](/v7/security/authorization).

By extending `ArgumentsHost`, `ExecutionContext` also adds several new helper methods that provide additional details about the current execution process. These details can be helpful in building more generic guards that can work across a broad set of controllers, methods, and execution contexts. Learn more about `ExecutionContext`[here](/v7/fundamentals/execution-context).

#### Role-based authentication[#](/guards#role-based-authentication)

Let's build a more functional guard that permits access only to users with a specific role. We'll start with a basic guard template, and build on it in the coming sections. For now, it allows all requests to proceed:

roles.guard.ts

JS TS

```typescript

import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
import { Observable } from 'rxjs';

@Injectable()
export class RolesGuard implements CanActivate {
  canActivate(
    context: ExecutionContext,
  ): boolean | Promise<boolean> | Observable<boolean> {
    return true;
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';

@Injectable()
export class RolesGuard {
  canActivate(context) {
    return true;
  }
}
```

#### Binding guards[#](/guards#binding-guards)

Like pipes and exception filters, guards can be **controller-scoped**, method-scoped, or global-scoped. Below, we set up a controller-scoped guard using the `@UseGuards()` decorator. This decorator may take a single argument, or a comma-separated list of arguments. This lets you easily apply the appropriate set of guards with one declaration.

JS TS

```typescript

@Controller('cats')
@UseGuards(RolesGuard)
export class CatsController {}
```

> **Hint** The `@UseGuards()` decorator is imported from the `@nestjs/common` package.

Above, we passed the `RolesGuard` type (instead of an instance), leaving responsibility for instantiation to the framework and enabling dependency injection. As with pipes and exception filters, we can also pass an in-place instance:

JS TS

```typescript

@Controller('cats')
@UseGuards(new RolesGuard())
export class CatsController {}
```

The construction above attaches the guard to every handler declared by this controller. If we wish the guard to apply only to a single method, we apply the `@UseGuards()` decorator at the **method level**.

In order to set up a global guard, use the `useGlobalGuards()` method of the Nest application instance:

JS TS

```typescript

const app = await NestFactory.create(AppModule);
app.useGlobalGuards(new RolesGuard());
```

> **Notice** In the case of hybrid apps the `useGlobalGuards()` method doesn't set up guards for gateways and micro services by default (see [Hybrid application](/v7/faq/hybrid-application) for information on how to change this behavior). For "standard" (non-hybrid) microservice apps, `useGlobalGuards()` does mount the guards globally.

Global guards are used across the whole application, for every controller and every route handler. In terms of dependency injection, global guards registered from outside of any module (with `useGlobalGuards()` as in the example above) cannot inject dependencies since this is done outside the context of any module. In order to solve this issue, you can set up a guard directly from any module using the following construction:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { APP_GUARD } from '@nestjs/core';

@Module({
  providers: [
    {
      provide: APP_GUARD,
      useClass: RolesGuard,
    },
  ],
})
export class AppModule {}
```

> **Hint** When using this approach to perform dependency injection for the guard, note that regardless of the module where this construction is employed, the guard is, in fact, global. Where should this be done? Choose the module where the guard (`RolesGuard` in the example above) is defined. Also, `useClass` is not the only way of dealing with custom provider registration. Learn more [here](/v7/fundamentals/custom-providers).

#### Setting roles per handler[#](/guards#setting-roles-per-handler)

Our `RolesGuard` is working, but it's not very smart yet. We're not yet taking advantage of the most important guard feature - the [execution context](/v7/fundamentals/execution-context). It doesn't yet know about roles, or which roles are allowed for each handler. The `CatsController`, for example, could have different permission schemes for different routes. Some might be available only for an admin user, and others could be open for everyone. How can we match roles to routes in a flexible and reusable way?

This is where **custom metadata** comes into play (learn more [here](https://docs.nestjs.com/fundamentals/execution-context#reflection-and-metadata)). Nest provides the ability to attach custom **metadata** to route handlers through the `@SetMetadata()` decorator. This metadata supplies our missing `role` data, which a smart guard needs to make decisions. Let's take a look at using `@SetMetadata()`:

cats.controller.ts

JS TS

```typescript

@Post()
@SetMetadata('roles', ['admin'])
async create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

```typescript

@Post()
@SetMetadata('roles', ['admin'])
@Bind(Body())
async create(createCatDto) {
  this.catsService.create(createCatDto);
}
```

> **Hint** The `@SetMetadata()` decorator is imported from the `@nestjs/common` package.

With the construction above, we attached the `roles` metadata (`roles` is a key, while `['admin']` is a particular value) to the `create()` method. While this works, it's not good practice to use `@SetMetadata()` directly in your routes. Instead, create your own decorators, as shown below:

roles.decorator.ts

JS TS

```typescript

import { SetMetadata } from '@nestjs/common';

export const Roles = (...roles: string[]) => SetMetadata('roles', roles);
```

```typescript

import { SetMetadata } from '@nestjs/common';

export const Roles = (...roles) => SetMetadata('roles', roles);
```

This approach is much cleaner and more readable, and is strongly typed. Now that we have a custom `@Roles()` decorator, we can use it to decorate the `create()` method.

cats.controller.ts

JS TS

```typescript

@Post()
@Roles('admin')
async create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

```typescript

@Post()
@Roles('admin')
@Bind(Body())
async create(createCatDto) {
  this.catsService.create(createCatDto);
}
```

#### Putting it all together[#](/guards#putting-it-all-together)

Let's now go back and tie this together with our `RolesGuard`. Currently, it simply returns `true` in all cases, allowing every request to proceed. We want to make the return value conditional based on the comparing the **roles assigned to the current user** to the actual roles required by the current route being processed. In order to access the route's role(s) (custom metadata), we'll use the `Reflector` helper class, which is provided out of the box by the framework and exposed from the `@nestjs/core` package.

roles.guard.ts

JS TS

```typescript

import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
import { Reflector } from '@nestjs/core';

@Injectable()
export class RolesGuard implements CanActivate {
  constructor(private reflector: Reflector) {}

  canActivate(context: ExecutionContext): boolean {
    const roles = this.reflector.get<string[]>('roles', context.getHandler());
    if (!roles) {
      return true;
    }
    const request = context.switchToHttp().getRequest();
    const user = request.user;
    return matchRoles(roles, user.roles);
  }
}
```

```typescript

import { Injectable, Dependencies } from '@nestjs/common';
import { Reflector } from '@nestjs/core';

@Injectable()
@Dependencies(Reflector)
export class RolesGuard {
  constructor(reflector) {
    this.reflector = reflector;
  }

  canActivate(context) {
    const roles = this.reflector.get('roles', context.getHandler());
    if (!roles) {
      return true;
    }
    const request = context.switchToHttp().getRequest();
    const user = request.user;
    return matchRoles(roles, user.roles);
  }
}
```

> **Hint** In the node.js world, it's common practice to attach the authorized user to the `request` object. Thus, in our sample code above, we are assuming that `request.user` contains the user instance and allowed roles. In your app, you will probably make that association in your custom **authentication guard** (or middleware). Check [this chapter](/v7/security/authentication) for more information on this topic.

> **Warning** The logic inside the `matchRoles()` function can be as simple or sophisticated as needed. The main point of this example is to show how guards fit into the request/response cycle.

Refer to the [Reflection and metadata](https://docs.nestjs.com/fundamentals/execution-context#reflection-and-metadata) section of the **Execution context** chapter for more details on utilizing `Reflector` in a context-sensitive way.

When a user with insufficient privileges requests an endpoint, Nest automatically returns the following response:

```typescript

{
  "statusCode": 403,
  "message": "Forbidden resource",
  "error": "Forbidden"
}
```

Note that behind the scenes, when a guard returns `false`, the framework throws a `ForbiddenException`. If you want to return a different error response, you should throw your own specific exception. For example:

```typescript

throw new UnauthorizedException();
```

Any exception thrown by a guard will be handled by the [exceptions layer](/v7/exception-filters) (global exceptions filter and any exceptions filters that are applied to the current context).

> **Hint** If you are looking for a real-world example on how to implement authorization, check [this chapter](/v7/security/authorization).

----
url: https://docs.nestjs.com/v7/middleware
----

* [Middleware](https://docs.nestjs.com/v7/middleware#middleware)
* [Dependency injection](https://docs.nestjs.com/v7/middleware#dependency-injection)
* [Applying middleware](https://docs.nestjs.com/v7/middleware#applying-middleware)
* [Route wildcards](https://docs.nestjs.com/v7/middleware#route-wildcards)
* [Middleware consumer](https://docs.nestjs.com/v7/middleware#middleware-consumer)
* [Excluding routes](https://docs.nestjs.com/v7/middleware#excluding-routes)
* [Functional middleware](https://docs.nestjs.com/v7/middleware#functional-middleware)
* [Multiple middleware](https://docs.nestjs.com/v7/middleware#multiple-middleware)
* [Global middleware](https://docs.nestjs.com/v7/middleware#global-middleware)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/middlewares.md "Suggest Edits")

### Middleware

Middleware is a function which is called **before** the route handler. Middleware functions have access to the [request](https://expressjs.com/en/4x/api.html#req) and [response](https://expressjs.com/en/4x/api.html#res) objects, and the `next()` middleware function in the application’s request-response cycle. The **next** middleware function is commonly denoted by a variable named `next`.

Nest middleware are, by default, equivalent to [express](https://expressjs.com/en/guide/using-middleware.html) middleware. The following description from the official express documentation describes the capabilities of middleware:

> Middleware functions can perform the following tasks:
>
> * execute any code.
> * make changes to the request and the response objects.
> * end the request-response cycle.
> * call the next middleware function in the stack.
> * if the current middleware function does not end the request-response cycle, it must call `next()` to pass control to the next middleware function. Otherwise, the request will be left hanging.

You implement custom Nest middleware in either a function, or in a class with an `@Injectable()` decorator. The class should implement the `NestMiddleware` interface, while the function does not have any special requirements. Let's start by implementing a simple middleware feature using the class method.

logger.middleware.ts

JS TS

```typescript

import { Injectable, NestMiddleware } from '@nestjs/common';
import { Request, Response, NextFunction } from 'express';

@Injectable()
export class LoggerMiddleware implements NestMiddleware {
  use(req: Request, res: Response, next: NextFunction) {
    console.log('Request...');
    next();
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';

@Injectable()
export class LoggerMiddleware {
  use(req, res, next) {
    console.log('Request...');
    next();
  }
}
```

#### Dependency injection[#](/middleware#dependency-injection)

Nest middleware fully supports Dependency Injection. Just as with providers and controllers, they are able to **inject dependencies** that are available within the same module. As usual, this is done through the `constructor`.

#### Applying middleware[#](/middleware#applying-middleware)

There is no place for middleware in the `@Module()` decorator. Instead, we set them up using the `configure()` method of the module class. Modules that include middleware have to implement the `NestModule` interface. Let's set up the `LoggerMiddleware` at the `AppModule` level.

app.module.ts

JS TS

```typescript

import { Module, NestModule, MiddlewareConsumer } from '@nestjs/common';
import { LoggerMiddleware } from './common/middleware/logger.middleware';
import { CatsModule } from './cats/cats.module';

@Module({
  imports: [CatsModule],
})
export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer
      .apply(LoggerMiddleware)
      .forRoutes('cats');
  }
}
```

```typescript

import { Module } from '@nestjs/common';
import { LoggerMiddleware } from './common/middleware/logger.middleware';
import { CatsModule } from './cats/cats.module';

@Module({
  imports: [CatsModule],
})
export class AppModule {
  configure(consumer) {
    consumer
      .apply(LoggerMiddleware)
      .forRoutes('cats');
  }
}
```

In the above example we have set up the `LoggerMiddleware` for the `/cats` route handlers that were previously defined inside the `CatsController`. We may also further restrict a middleware to a particular request method by passing an object containing the route `path` and request `method` to the `forRoutes()` method when configuring the middleware. In the example below, notice that we import the `RequestMethod` enum to reference the desired request method type.

app.module.ts

JS TS

```typescript

import { Module, NestModule, RequestMethod, MiddlewareConsumer } from '@nestjs/common';
import { LoggerMiddleware } from './common/middleware/logger.middleware';
import { CatsModule } from './cats/cats.module';

@Module({
  imports: [CatsModule],
})
export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer
      .apply(LoggerMiddleware)
      .forRoutes({ path: 'cats', method: RequestMethod.GET });
  }
}
```

```typescript

import { Module, RequestMethod } from '@nestjs/common';
import { LoggerMiddleware } from './common/middleware/logger.middleware';
import { CatsModule } from './cats/cats.module';

@Module({
  imports: [CatsModule],
})
export class AppModule {
  configure(consumer) {
    consumer
      .apply(LoggerMiddleware)
      .forRoutes({ path: 'cats', method: RequestMethod.GET });
  }
}
```

> **Hint** The `configure()` method can be made asynchronous using `async/await` (e.g., you can `await` completion of an asynchronous operation inside the `configure()` method body).

#### Route wildcards[#](/middleware#route-wildcards)

Pattern based routes are supported as well. For instance, the asterisk is used as a **wildcard**, and will match any combination of characters:

```typescript

forRoutes({ path: 'ab*cd', method: RequestMethod.ALL });
```

The `'ab*cd'` route path will match `abcd`, `ab_cd`, `abecd`, and so on. The characters `?`, `+`, `*`, and `()` may be used in a route path, and are subsets of their regular expression counterparts. The hyphen ( `-`) and the dot (`.`) are interpreted literally by string-based paths.

> **Warning** The `fastify` package uses the latest version of the `path-to-regexp` package, which no longer supports wildcard asterisks `*`. Instead, you must use parameters (e.g., `(.*)`, `:splat*`).

#### Middleware consumer[#](/middleware#middleware-consumer)

The `MiddlewareConsumer` is a helper class. It provides several built-in methods to manage middleware. All of them can be simply **chained** in the [fluent style](https://en.wikipedia.org/wiki/Fluent_interface). The `forRoutes()` method can take a single string, multiple strings, a `RouteInfo` object, a controller class and even multiple controller classes. In most cases you'll probably just pass a list of **controllers** separated by commas. Below is an example with a single controller:

app.module.ts

JS TS

```typescript

import { Module, NestModule, MiddlewareConsumer } from '@nestjs/common';
import { LoggerMiddleware } from './common/middleware/logger.middleware';
import { CatsModule } from './cats/cats.module';
import { CatsController } from './cats/cats.controller.ts';

@Module({
  imports: [CatsModule],
})
export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer
      .apply(LoggerMiddleware)
      .forRoutes(CatsController);
  }
}
```

```typescript

import { Module } from '@nestjs/common';
import { LoggerMiddleware } from './common/middleware/logger.middleware';
import { CatsModule } from './cats/cats.module';
import { CatsController } from './cats/cats.controller.ts';

@Module({
  imports: [CatsModule],
})
export class AppModule {
  configure(consumer) {
    consumer
      .apply(LoggerMiddleware)
      .forRoutes(CatsController);
  }
}
```

> **Hint** The `apply()` method may either take a single middleware, or multiple arguments to specify [multiple middlewares](/middleware#multiple-middleware).

#### Excluding routes[#](/middleware#excluding-routes)

At times we want to **exclude** certain routes from having the middleware applied. We can easily exclude certain routes with the `exclude()` method. This method can take a single string, multiple strings, or a `RouteInfo` object identifying routes to be excluded, as shown below:

```typescript

consumer
  .apply(LoggerMiddleware)
  .exclude(
    { path: 'cats', method: RequestMethod.GET },
    { path: 'cats', method: RequestMethod.POST },
    'cats/(.*)',
  )
  .forRoutes(CatsController);
```

> **Hint** The `exclude()` method supports wildcard parameters using the [path-to-regexp](https://github.com/pillarjs/path-to-regexp#parameters) package.

With the example above, `LoggerMiddleware` will be bound to all routes defined inside `CatsController`**except** the three passed to the `exclude()` method.

#### Functional middleware[#](/middleware#functional-middleware)

The `LoggerMiddleware` class we've been using is quite simple. It has no members, no additional methods, and no dependencies. Why can't we just define it in a simple function instead of a class? In fact, we can. This type of middleware is called **functional middleware**. Let's transform the logger middleware from class-based into functional middleware to illustrate the difference:

logger.middleware.ts

JS TS

```typescript

import { Request, Response, NextFunction } from 'express';

export function logger(req: Request, res: Response, next: NextFunction) {
  console.log(`Request...`);
  next();
};
```

```typescript

export function logger(req, res, next) {
  console.log(`Request...`);
  next();
};
```

And use it within the `AppModule`:

app.module.ts

JS TS

```typescript

consumer
  .apply(logger)
  .forRoutes(CatsController);
```

> **Hint** Consider using the simpler **functional middleware** alternative any time your middleware doesn't need any dependencies.

#### Multiple middleware[#](/middleware#multiple-middleware)

As mentioned above, in order to bind multiple middleware that are executed sequentially, simply provide a comma separated list inside the `apply()` method:

```typescript

consumer.apply(cors(), helmet(), logger).forRoutes(CatsController);
```

#### Global middleware[#](/middleware#global-middleware)

If we want to bind middleware to every registered route at once, we can use the `use()` method that is supplied by the `INestApplication` instance:

```typescript

const app = await NestFactory.create(AppModule);
app.use(logger);
await app.listen(3000);
```

----
url: https://docs.nestjs.com/v11/techniques/performance
----

* [Performance (Fastify)](https://docs.nestjs.com/v11/techniques/performance#performance-fastify)
* [Installation](https://docs.nestjs.com/v11/techniques/performance#installation)
* [Adapter](https://docs.nestjs.com/v11/techniques/performance#adapter)
* [Platform specific packages](https://docs.nestjs.com/v11/techniques/performance#platform-specific-packages)
* [Redirect response](https://docs.nestjs.com/v11/techniques/performance#redirect-response)
* [Fastify options](https://docs.nestjs.com/v11/techniques/performance#fastify-options)
* [Middleware](https://docs.nestjs.com/v11/techniques/performance#middleware)
* [Route Config](https://docs.nestjs.com/v11/techniques/performance#route-config)
* [Route Constraints](https://docs.nestjs.com/v11/techniques/performance#route-constraints)
* [Example](https://docs.nestjs.com/v11/techniques/performance#example)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/techniques/performance.md "Suggest Edits")

### Performance (Fastify)

By default, Nest makes use of the [Express](https://expressjs.com/) framework. As mentioned earlier, Nest also provides compatibility with other libraries such as, for example, [Fastify](https://github.com/fastify/fastify). Nest achieves this framework independence by implementing a framework adapter whose primary function is to proxy middleware and handlers to appropriate library-specific implementations.

> **Hint** Note that in order for a framework adapter to be implemented, the target library has to provide similar request/response pipeline processing as found in Express.

[Fastify](https://github.com/fastify/fastify) provides a good alternative framework for Nest because it solves design issues in a similar manner to Express. However, fastify is much **faster** than Express, achieving almost two times better benchmarks results. A fair question is why does Nest use Express as the default HTTP provider? The reason is that Express is widely-used, well-known, and has an enormous set of compatible middleware, which is available to Nest users out-of-the-box.

But since Nest provides framework-independence, you can easily migrate between them. Fastify can be a better choice when you place high value on very fast performance. To utilize Fastify, simply choose the built-in `FastifyAdapter` as shown in this chapter.

#### Installation[#](/techniques/performance#installation)

First, we need to install the required package:

```bash

$ npm i --save @nestjs/platform-fastify
```

#### Adapter[#](/techniques/performance#adapter)

Once the Fastify platform is installed, we can use the `FastifyAdapter`.

main.ts

JS TS

```typescript

import { NestFactory } from '@nestjs/core';
import {
  FastifyAdapter,
  NestFastifyApplication,
} from '@nestjs/platform-fastify';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create<NestFastifyApplication>(
    AppModule,
    new FastifyAdapter()
  );
  await app.listen(process.env.PORT ?? 3000);
}
bootstrap();
```

By default, Fastify listens only on the `localhost 127.0.0.1` interface ([read more](https://fastify.dev/docs/latest/Guides/Getting-Started/#your-first-server)). If you want to accept connections on other hosts, you should specify `'0.0.0.0'` in the `listen()` call:

```typescript

async function bootstrap() {
  const app = await NestFactory.create<NestFastifyApplication>(
    AppModule,
    new FastifyAdapter(),
  );
  await app.listen(3000, '0.0.0.0');
}
```

#### Platform specific packages[#](/techniques/performance#platform-specific-packages)

Keep in mind that when you use the `FastifyAdapter`, Nest uses Fastify as the **HTTP provider**. This means that each recipe that relies on Express may no longer work. You should, instead, use Fastify equivalent packages.

#### Redirect response[#](/techniques/performance#redirect-response)

Fastify handles redirect responses slightly differently than Express. To do a proper redirect with Fastify, return both the status code and the URL, as follows:

```typescript

@Get()
index(@Res() res) {
  res.status(302).redirect('/login');
}
```

#### Fastify options[#](/techniques/performance#fastify-options)

You can pass options into the Fastify constructor through the `FastifyAdapter` constructor. For example:

```typescript

new FastifyAdapter({ logger: true });
```

#### Middleware[#](/techniques/performance#middleware)

Middleware functions retrieve the raw `req` and `res` objects instead of Fastify's wrappers. This is how the `middie` package works (that's used under the hood) and `fastify` - check out this [page](https://fastify.dev/docs/latest/Reference/Middleware/) for more information,

logger.middleware.ts

JS TS

```typescript

import { Injectable, NestMiddleware } from '@nestjs/common';
import { FastifyRequest, FastifyReply } from 'fastify';

@Injectable()
export class LoggerMiddleware implements NestMiddleware {
  use(req: FastifyRequest['raw'], res: FastifyReply['raw'], next: () => void) {
    console.log('Request...');
    next();
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';

@Injectable()
export class LoggerMiddleware {
  use(req, res, next) {
    console.log('Request...');
    next();
  }
}
```

#### Route Config[#](/techniques/performance#route-config)

You can use the [route config](https://fastify.dev/docs/latest/Reference/Routes/#config) feature of Fastify with the `@RouteConfig()` decorator.

```typescript

@RouteConfig({ output: 'hello world' })
@Get()
index(@Req() req) {
  return req.routeConfig.output;
}
```

#### Route Constraints[#](/techniques/performance#route-constraints)

As of v10.3.0, `@nestjs/platform-fastify` supports [route constraints](https://fastify.dev/docs/latest/Reference/Routes/#constraints) feature of Fastify with `@RouteConstraints` decorator.

```typescript

@RouteConstraints({ version: '1.2.x' })
newFeature() {
  return 'This works only for version >= 1.2.x';
}
```

> **Hint**`@RouteConfig()` and `@RouteConstraints` are imported from `@nestjs/platform-fastify`.

#### Example[#](/techniques/performance#example)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/10-fastify).

----
url: https://docs.nestjs.com/v10/fundamentals/injection-scopes
----

* [Injection scopes](https://docs.nestjs.com/v10/fundamentals/injection-scopes#injection-scopes)
* [Provider scope](https://docs.nestjs.com/v10/fundamentals/injection-scopes#provider-scope)
* [Usage](https://docs.nestjs.com/v10/fundamentals/injection-scopes#usage)
* [Controller scope](https://docs.nestjs.com/v10/fundamentals/injection-scopes#controller-scope)
* [Scope hierarchy](https://docs.nestjs.com/v10/fundamentals/injection-scopes#scope-hierarchy)
* [Request provider](https://docs.nestjs.com/v10/fundamentals/injection-scopes#request-provider)
* [Inquirer provider](https://docs.nestjs.com/v10/fundamentals/injection-scopes#inquirer-provider)
* [Performance](https://docs.nestjs.com/v10/fundamentals/injection-scopes#performance)
* [Durable providers](https://docs.nestjs.com/v10/fundamentals/injection-scopes#durable-providers)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/fundamentals/provider-scopes.md "Suggest Edits")

### Injection scopes

For people coming from different programming language backgrounds, it might be unexpected to learn that in Nest, almost everything is shared across incoming requests. We have a connection pool to the database, singleton services with global state, etc. Remember that Node.js doesn't follow the request/response Multi-Threaded Stateless Model in which every request is processed by a separate thread. Hence, using singleton instances is fully **safe** for our applications.

However, there are edge cases when request-based lifetime may be the desired behavior, for instance, per-request caching in GraphQL applications, request tracking, and multi-tenancy. Injection scopes provide a mechanism to obtain the desired provider lifetime behavior.

#### Provider scope[#](/fundamentals/injection-scopes#provider-scope)

A provider can have any of the following scopes:

|             |                                                                                                                                                                                                                                                                            |
| ----------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `DEFAULT`   | A single instance of the provider is shared across the entire application. The instance lifetime is tied directly to the application lifecycle. Once the application has bootstrapped, all singleton providers have been instantiated. Singleton scope is used by default. |
| `REQUEST`   | A new instance of the provider is created exclusively for each incoming **request**. The instance is garbage-collected after the request has completed processing.                                                                                                         |
| `TRANSIENT` | Transient providers are not shared across consumers. Each consumer that injects a transient provider will receive a new, dedicated instance.                                                                                                                               |

> **Hint** Using singleton scope is **recommended** for most use cases. Sharing providers across consumers and across requests means that an instance can be cached and its initialization occurs only once, during application startup.

#### Usage[#](/fundamentals/injection-scopes#usage)

Specify injection scope by passing the `scope` property to the `@Injectable()` decorator options object:

```typescript

import { Injectable, Scope } from '@nestjs/common';

@Injectable({ scope: Scope.REQUEST })
export class CatsService {}
```

Similarly, for [custom providers](/v10/fundamentals/custom-providers), set the `scope` property in the long-hand form for a provider registration:

```typescript

{
  provide: 'CACHE_MANAGER',
  useClass: CacheManager,
  scope: Scope.TRANSIENT,
}
```

> **Hint** Import the `Scope` enum from `@nestjs/common`

Singleton scope is used by default and does not need be declared. If you do want to declare a provider as singleton scoped, use the `Scope.DEFAULT` value for the `scope` property.

> **Notice** Websocket Gateways should not use request-scoped providers because they must act as singletons. Each gateway encapsulates a real socket and cannot be instantiated multiple times. The limitation also applies to some other providers, like [*Passport strategies*](../security/authentication#request-scoped-strategies) or *Cron controllers*.

#### Controller scope[#](/fundamentals/injection-scopes#controller-scope)

Controllers can also have scope, which applies to all request method handlers declared in that controller. Like provider scope, the scope of a controller declares its lifetime. For a request-scoped controller, a new instance is created for each inbound request, and garbage-collected when the request has completed processing.

Declare controller scope with the `scope` property of the `ControllerOptions` object:

```typescript

@Controller({
  path: 'cats',
  scope: Scope.REQUEST,
})
export class CatsController {}
```

```typescript

import { Injectable, Scope, Inject } from '@nestjs/common';
import { REQUEST } from '@nestjs/core';
import { Request } from 'express';

@Injectable({ scope: Scope.REQUEST })
export class CatsService {
  constructor(@Inject(REQUEST) private request: Request) {}
}
```

Because of underlying platform/protocol differences, you access the inbound request slightly differently for Microservice or GraphQL applications. In [GraphQL](/v10/graphql/quick-start) applications, you inject `CONTEXT` instead of `REQUEST`:

```typescript

import { Injectable, Scope, Inject } from '@nestjs/common';
import { CONTEXT } from '@nestjs/graphql';

@Injectable({ scope: Scope.REQUEST })
export class CatsService {
  constructor(@Inject(CONTEXT) private context) {}
}
```

You then configure your `context` value (in the `GraphQLModule`) to contain `request` as its property.

#### Inquirer provider[#](/fundamentals/injection-scopes#inquirer-provider)

If you want to get the class where a provider was constructed, for instance in logging or metrics providers, you can inject the `INQUIRER` token.

```typescript

import { Inject, Injectable, Scope } from '@nestjs/common';
import { INQUIRER } from '@nestjs/core';

@Injectable({ scope: Scope.TRANSIENT })
export class HelloService {
  constructor(@Inject(INQUIRER) private parentClass: object) {}

  sayHello(message: string) {
    console.log(`${this.parentClass?.constructor?.name}: ${message}`);
  }
}
```

And then use it as follows:

```typescript

import { Injectable } from '@nestjs/common';
import { HelloService } from './hello.service';

@Injectable()
export class AppService {
  constructor(private helloService: HelloService) {}

  getRoot(): string {
    this.helloService.sayHello('My name is getRoot');

    return 'Hello world!';
  }
}
```

In the example above when `AppService#getRoot` is called, `"AppService: My name is getRoot"` will be logged to the console.

#### Performance[#](/fundamentals/injection-scopes#performance)

Using request-scoped providers will have an impact on application performance. While Nest tries to cache as much metadata as possible, it will still have to create an instance of your class on each request. Hence, it will slow down your average response time and overall benchmarking result. Unless a provider must be request-scoped, it is strongly recommended that you use the default singleton scope.

> **Hint** Although it all sounds quite intimidating, a properly designed application that leverages request-scoped providers should not slow down by more than \~5% latency-wise.

```typescript

import {
  HostComponentInfo,
  ContextId,
  ContextIdFactory,
  ContextIdStrategy,
} from '@nestjs/core';
import { Request } from 'express';

const tenants = new Map<string, ContextId>();

export class AggregateByTenantContextIdStrategy implements ContextIdStrategy {
  attach(contextId: ContextId, request: Request) {
    const tenantId = request.headers['x-tenant-id'] as string;
    let tenantSubTreeId: ContextId;

    if (tenants.has(tenantId)) {
      tenantSubTreeId = tenants.get(tenantId);
    } else {
      tenantSubTreeId = ContextIdFactory.create();
      tenants.set(tenantId, tenantSubTreeId);
    }

    // If tree is not durable, return the original "contextId" object
    return (info: HostComponentInfo) =>
      info.isTreeDurable ? tenantSubTreeId : contextId;
  }
}
```

> **Hint** Similar to the request scope, durability bubbles up the injection chain. That means if A depends on B which is flagged as `durable`, A implicitly becomes durable too (unless `durable` is explicitly set to `false` for A provider).

> **Warning** Note this strategy is not ideal for applications operating with a large number of tenants.

The value returned from the `attach` method instructs Nest what context identifier should be used for a given host. In this case, we specified that the `tenantSubTreeId` should be used instead of the original, auto-generated `contextId` object, when the host component (e.g., request-scoped controller) is flagged as durable (you can learn how to mark providers as durable below). Also, in the above example, **no payload** would be registered (where payload = `REQUEST`/`CONTEXT` provider that represents the "root" - parent of the sub-tree).

If you want to register the payload for a durable tree, use the following construction instead:

```typescript

// The return of `AggregateByTenantContextIdStrategy#attach` method:
return {
  resolve: (info: HostComponentInfo) =>
    info.isTreeDurable ? tenantSubTreeId : contextId,
  payload: { tenantId },
};
```

Now whenever you inject the `REQUEST` provider (or `CONTEXT` for GraphQL applications) using the `@Inject(REQUEST)`/`@Inject(CONTEXT)`, the `payload` object would be injected (consisting of a single property - `tenantId` in this case).

Alright so with this strategy in place, you can register it somewhere in your code (as it applies globally anyway), so for example, you could place it in the `main.ts` file:

```typescript

ContextIdFactory.apply(new AggregateByTenantContextIdStrategy());
```

> **Hint** The `ContextIdFactory` class is imported from the `@nestjs/core` package.

As long as the registration occurs before any request hits your application, everything will work as intended.

Lastly, to turn a regular provider into a durable provider, simply set the `durable` flag to `true` and change its scope to `Scope.REQUEST` (not needed if the REQUEST scope is in the injection chain already):

```typescript

import { Injectable, Scope } from '@nestjs/common';

@Injectable({ scope: Scope.REQUEST, durable: true })
export class CatsService {}
```

Similarly, for [custom providers](/v10/fundamentals/custom-providers), set the `durable` property in the long-hand form for a provider registration:

```typescript

{
  provide: 'foobar',
  useFactory: () => { ... },
  scope: Scope.REQUEST,
  durable: true,
}
```

----
url: https://docs.nestjs.com/v10/microservices/rabbitmq
----

* [RabbitMQ](https://docs.nestjs.com/v10/microservices/rabbitmq#rabbitmq)
* [Installation](https://docs.nestjs.com/v10/microservices/rabbitmq#installation)
* [Overview](https://docs.nestjs.com/v10/microservices/rabbitmq#overview)
* [Options](https://docs.nestjs.com/v10/microservices/rabbitmq#options)
* [Client](https://docs.nestjs.com/v10/microservices/rabbitmq#client)
* [Context](https://docs.nestjs.com/v10/microservices/rabbitmq#context)
* [Message acknowledgement](https://docs.nestjs.com/v10/microservices/rabbitmq#message-acknowledgement)
* [Record builders](https://docs.nestjs.com/v10/microservices/rabbitmq#record-builders)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/microservices/rabbitmq.md "Suggest Edits")

### RabbitMQ

[RabbitMQ](https://www.rabbitmq.com/) is an open-source and lightweight message broker which supports multiple messaging protocols. It can be deployed in distributed and federated configurations to meet high-scale, high-availability requirements. In addition, it's the most widely deployed message broker, used worldwide at small startups and large enterprises.

#### Installation[#](/microservices/rabbitmq#installation)

To start building RabbitMQ-based microservices, first install the required packages:

```bash

$ npm i --save amqplib amqp-connection-manager
```

#### Overview[#](/microservices/rabbitmq#overview)

To use the RabbitMQ transporter, pass the following options object to the `createMicroservice()` method:

main.ts

JS TS

```typescript

const app = await NestFactory.createMicroservice<MicroserviceOptions>(AppModule, {
  transport: Transport.RMQ,
  options: {
    urls: ['amqp://localhost:5672'],
    queue: 'cats_queue',
    queueOptions: {
      durable: false
    },
  },
});
```

```typescript

const app = await NestFactory.createMicroservice(AppModule, {
  transport: Transport.RMQ,
  options: {
    urls: ['amqp://localhost:5672'],
    queue: 'cats_queue',
    queueOptions: {
      durable: false
    },
  },
});
```

> **Hint** The `Transport` enum is imported from the `@nestjs/microservices` package.

#### Options[#](/microservices/rabbitmq#options)

The `options` property is specific to the chosen transporter. The **RabbitMQ** transporter exposes the properties described below.

|                         |                                                                                                                       |
| ----------------------- | --------------------------------------------------------------------------------------------------------------------- |
| `urls`                  | Connection urls                                                                                                       |
| `queue`                 | Queue name which your server will listen to                                                                           |
| `prefetchCount`         | Sets the prefetch count for the channel                                                                               |
| `isGlobalPrefetchCount` | Enables per channel prefetching                                                                                       |
| `noAck`                 | If `false`, manual acknowledgment mode enabled                                                                        |
| `consumerTag`           | Consumer Tag Identifier (read more [here](https://amqp-node.github.io/amqplib/channel_api.html#channel_consume))      |
| `queueOptions`          | Additional queue options (read more [here](https://amqp-node.github.io/amqplib/channel_api.html#channel_assertQueue)) |
| `socketOptions`         | Additional socket options (read more [here](https://amqp-node.github.io/amqplib/channel_api.html#connect))            |
| `headers`               | Headers to be sent along with every message                                                                           |

#### Client[#](/microservices/rabbitmq#client)

Like other microservice transporters, you have [several options](https://docs.nestjs.com/microservices/basics#client) for creating a RabbitMQ `ClientProxy` instance.

One method for creating an instance is to use the `ClientsModule`. To create a client instance with the `ClientsModule`, import it and use the `register()` method to pass an options object with the same properties shown above in the `createMicroservice()` method, as well as a `name` property to be used as the injection token. Read more about `ClientsModule`[here](https://docs.nestjs.com/microservices/basics#client).

```typescript

@Module({
  imports: [
    ClientsModule.register([
      {
        name: 'MATH_SERVICE',
        transport: Transport.RMQ,
        options: {
          urls: ['amqp://localhost:5672'],
          queue: 'cats_queue',
          queueOptions: {
            durable: false
          },
        },
      },
    ]),
  ]
  ...
})
```

Other options to create a client (either `ClientProxyFactory` or `@Client()`) can be used as well. You can read about them [here](https://docs.nestjs.com/microservices/basics#client).

#### Context[#](/microservices/rabbitmq#context)

In more sophisticated scenarios, you may want to access more information about the incoming request. When using the RabbitMQ transporter, you can access the `RmqContext` object.

JS TS

```typescript

@MessagePattern('notifications')
getNotifications(@Payload() data: number[], @Ctx() context: RmqContext) {
  console.log(`Pattern: ${context.getPattern()}`);
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('notifications')
getNotifications(data, context) {
  console.log(`Pattern: ${context.getPattern()}`);
}
```

> **Hint**`@Payload()`, `@Ctx()` and `RmqContext` are imported from the `@nestjs/microservices` package.

To access the original RabbitMQ message (with the `properties`, `fields`, and `content`), use the `getMessage()` method of the `RmqContext` object, as follows:

JS TS

```typescript

@MessagePattern('notifications')
getNotifications(@Payload() data: number[], @Ctx() context: RmqContext) {
  console.log(context.getMessage());
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('notifications')
getNotifications(data, context) {
  console.log(context.getMessage());
}
```

To retrieve a reference to the RabbitMQ [channel](https://www.rabbitmq.com/channels.html), use the `getChannelRef` method of the `RmqContext` object, as follows:

JS TS

```typescript

@MessagePattern('notifications')
getNotifications(@Payload() data: number[], @Ctx() context: RmqContext) {
  console.log(context.getChannelRef());
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('notifications')
getNotifications(data, context) {
  console.log(context.getChannelRef());
}
```

#### Message acknowledgement[#](/microservices/rabbitmq#message-acknowledgement)

To make sure a message is never lost, RabbitMQ supports [message acknowledgements](https://www.rabbitmq.com/confirms.html). An acknowledgement is sent back by the consumer to tell RabbitMQ that a particular message has been received, processed and that RabbitMQ is free to delete it. If a consumer dies (its channel is closed, connection is closed, or TCP connection is lost) without sending an ack, RabbitMQ will understand that a message wasn't processed fully and will re-queue it.

To enable manual acknowledgment mode, set the `noAck` property to `false`:

```typescript

options: {
  urls: ['amqp://localhost:5672'],
  queue: 'cats_queue',
  noAck: false,
  queueOptions: {
    durable: false
  },
},
```

When manual consumer acknowledgements are turned on, we must send a proper acknowledgement from the worker to signal that we are done with a task.

JS TS

```typescript

@MessagePattern('notifications')
getNotifications(@Payload() data: number[], @Ctx() context: RmqContext) {
  const channel = context.getChannelRef();
  const originalMsg = context.getMessage();

  channel.ack(originalMsg);
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('notifications')
getNotifications(data, context) {
  const channel = context.getChannelRef();
  const originalMsg = context.getMessage();

  channel.ack(originalMsg);
}
```

#### Record builders[#](/microservices/rabbitmq#record-builders)

To configure message options, you can use the `RmqRecordBuilder` class (note: this is doable for event-based flows as well). For example, to set `headers` and `priority` properties, use the `setOptions` method, as follows:

```typescript

const message = ':cat:';
const record = new RmqRecordBuilder(message)
  .setOptions({
    headers: {
      ['x-version']: '1.0.0',
    },
    priority: 3,
  })
  .build();

this.client.send('replace-emoji', record).subscribe(...);
```

> **Hint**`RmqRecordBuilder` class is exported from the `@nestjs/microservices` package.

And you can read these values on the server-side as well, by accessing the `RmqContext`, as follows:

JS TS

```typescript

@MessagePattern('replace-emoji')
replaceEmoji(@Payload() data: string, @Ctx() context: RmqContext): string {
  const { properties: { headers } } = context.getMessage();
  return headers['x-version'] === '1.0.0' ? '🐱' : '🐈';
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('replace-emoji')
replaceEmoji(data, context) {
  const { properties: { headers } } = context.getMessage();
  return headers['x-version'] === '1.0.0' ? '🐱' : '🐈';
}
```

----
url: https://docs.nestjs.com/v10/deployment
----

* [Deployment](https://docs.nestjs.com/v10/deployment#deployment)
* [Prerequisites](https://docs.nestjs.com/v10/deployment#prerequisites)
* [Building your application](https://docs.nestjs.com/v10/deployment#building-your-application)
* [Production environment](https://docs.nestjs.com/v10/deployment#production-environment)
* [NODE\_ENV=production](https://docs.nestjs.com/v10/deployment#node_envproduction)
* [Running your application](https://docs.nestjs.com/v10/deployment#running-your-application)
* [Health checks](https://docs.nestjs.com/v10/deployment#health-checks)
* [Logging](https://docs.nestjs.com/v10/deployment#logging)
* [Scaling up or out](https://docs.nestjs.com/v10/deployment#scaling-up-or-out)
* [Some other tips](https://docs.nestjs.com/v10/deployment#some-other-tips)
* [Dockerizing your application](https://docs.nestjs.com/v10/deployment#dockerizing-your-application)
* [Easy deployment with Mau](https://docs.nestjs.com/v10/deployment#easy-deployment-with-mau)

> **Hint** If you are looking for a cloud-based platform to deploy your NestJS application, check out [Mau](https://mau.nestjs.com/ "Deploy Nest"), our official platform for deploying NestJS applications on AWS. With Mau, deploying your NestJS application is as simple as clicking a few buttons and running a single command:
>
> ```bash
>
> $ npm install -g @nestjs/mau
> $ mau deploy
> ```
>
> Once the deployment is complete, you'll have your NestJS application up and running on AWS in seconds!

#### Building your application[#](/deployment#building-your-application)

To build your NestJS application, you need to compile your TypeScript code into JavaScript. This process generates a `dist` directory containing the compiled files. You can build your application by running the following command:

```bash

$ npm run build
```

This command typically runs the `nest build` command under the hood, which is basically a wrapper around the TypeScript compiler with some additional features (assets copying, etc.). In case you have a custom build script, you can run it directly. Also, for NestJS CLI mono-repos, make sure to pass the name of the project to build as an argument (`npm run build my-app`).

Upon successful compilation, you should see a `dist` directory in your project root containing the compiled files, with the entry point being `main.js`. If you have any `.ts` files located in the root directory of your project (and your `tsconfig.json` configured to compile them), they will be copied to the `dist` directory as well, modifying the directory structure a bit (instead of `dist/main.js`, you will have `dist/src/main.js` so keep that in mind when configuring your server).

#### Production environment[#](/deployment#production-environment)

Your production environment is where your application will be accessible to external users. This could be a cloud-based platform like [AWS](https://aws.amazon.com/) (with EC2, ECS, etc.), [Azure](https://azure.microsoft.com/), or [Google Cloud](https://cloud.google.com/), or even a dedicated server you manage, such as [Hetzner](https://www.hetzner.com/).

To simplify the deployment process and avoid manual setup, you can use a service like [Mau](https://mau.nestjs.com/ "Deploy Nest"), our official platform for deploying NestJS applications on AWS. For more details, check out [this section](/v10/deployment/todo).

```bash

$ NODE_ENV=production node dist/main.js
```

Or just set it in your cloud provider's/Mau dashboard.

#### Running your application[#](/deployment#running-your-application)

To run your NestJS application in production, just use the following command:

```bash

$ node dist/main.js # Adjust this based on your entry point location
```

This command starts your application, which will listen on the specified port (usually `3000` by default). Ensure that this matches the port you’ve configured in your application.

Alternatively, you can use the `nest start` command. This command is a wrapper around `node dist/main.js`, but it has one key difference: it automatically runs `nest build` before starting the application, so you don’t need to manually execute `npm run build`.

#### Health checks[#](/deployment#health-checks)

Health checks are essential for monitoring the health and status of your NestJS application in production. By setting up a health check endpoint, you can regularly verify that your app is running as expected and respond to issues before they become critical.

In NestJS, you can easily implement health checks using the **@nestjs/terminus** package, which provides a powerful tool for adding health checks, including database connections, external services, and custom checks.

Check out [this guide](/v10/recipes/terminus) to learn how to implement health checks in your NestJS application, and ensure your app is always monitored and responsive.

> **Hint** If you're using [AWS](https://aws.amazon.com/) (with [Mau](https://mau.nestjs.com/ "Deploy Nest") or directly), consider JSON logging to make it easier to parse and analyze your logs.

For distributed applications, using a centralized logging service like ElasticSearch, Loggly, or Datadog can be incredibly useful. These tools offer powerful features like log aggregation, search, and visualization, making it easier to monitor and analyze your application's performance and behavior.

> **Hint**[Mau](https://mau.nestjs.com/ "Deploy Nest") offers built-in support for horizontal scaling on AWS, allowing you to easily deploy multiple instances of your NestJS application and manage them with just a few clicks.

* **Rate limiting**: Implement rate limiting to prevent abuse and protect your application from DDoS attacks. Check out [Rate limiting chapter](/v10/security/rate-limiting) for more details, or use a service like [AWS WAF](https://aws.amazon.com/waf/) for advanced protection.

```bash

# Use the official Node.js image as the base image
FROM node:20

# Set the working directory inside the container
WORKDIR /usr/src/app

# Copy package.json and package-lock.json to the working directory
COPY package*.json ./

# Install the application dependencies
RUN npm install

# Copy the rest of the application files
COPY . .

# Build the NestJS application
RUN npm run build

# Expose the application port
EXPOSE 3000

# Command to run the application
CMD ["node", "dist/main"]
```

> **Hint** Make sure to replace `node:20` with the appropriate Node.js version you're using in your project. You can find the available Node.js Docker images on the [official Docker Hub repository](https://hub.docker.com/_/node).

This is a basic Dockerfile that sets up a Node.js environment, installs the application dependencies, builds the NestJS application, and runs it. You can customize this file based on your project requirements (e.g., use different base images, optimize the build process, only install production dependencies, etc.).

Let's also create a `.dockerignore` file to specify which files and directories Docker should ignore when building the image. Create a `.dockerignore` file in your project root:

```bash

node_modules
dist
*.log
*.md
.git
```

This file ensures that unnecessary files are not included in the container image, keeping it lightweight. Now that you have your Dockerfile set up, you can build your Docker image. Open your terminal, navigate to your project directory, and run the following command:

```bash

docker build -t my-nestjs-app .
```

In this command:

* `-t my-nestjs-app`: Tags the image with the name `my-nestjs-app`.
* `.`: Indicates the current directory as the build context.

After building the image, you can run it as a container. Execute the following command:

```bash

docker run -p 3000:3000 my-nestjs-app
```

In this command:

* `-p 3000:3000`: Maps port 3000 on your host machine to port 3000 in the container.
* `my-nestjs-app`: Specifies the image to run.

Your NestJS application should now be running inside a Docker container.

If you want to deploy your Docker image to a cloud provider or share it with others, you'll need to push it to a Docker registry (like [Docker Hub](https://hub.docker.com/), [AWS ECR](https://aws.amazon.com/ecr/), or [Google Container Registry](https://cloud.google.com/container-registry)).

Once you decide on a registry, you can push your image by following these steps:

```bash

docker login # Log in to your Docker registry
docker tag my-nestjs-app your-dockerhub-username/my-nestjs-app # Tag your image
docker push your-dockerhub-username/my-nestjs-app # Push your image
```

```bash

$ npm install -g @nestjs/mau
$ mau deploy
```

Sign up today and [Deploy with Mau](https://mau.nestjs.com/ "Deploy Nest") to get your NestJS applications up and running on AWS in minutes!

----
url: https://docs.nestjs.com/v10/recipes/sql-typeorm
----

* [SQL (TypeORM)](https://docs.nestjs.com/v10/recipes/sql-typeorm#sql-typeorm)
* [Getting started](https://docs.nestjs.com/v10/recipes/sql-typeorm#getting-started)
* [Repository pattern](https://docs.nestjs.com/v10/recipes/sql-typeorm#repository-pattern)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/recipes/sql-typeorm.md "Suggest Edits")

### SQL (TypeORM)

##### This chapter applies only to TypeScript

> **Warning** In this article, you'll learn how to create a `DatabaseModule` based on the **TypeORM** package from scratch using custom providers mechanism. As a consequence, this solution contains a lot of overhead that you can omit using ready to use and available out-of-the-box dedicated `@nestjs/typeorm` package. To learn more, see [here](/v10/techniques/sql).

[TypeORM](https://github.com/typeorm/typeorm) is definitely the most mature Object Relational Mapper (ORM) available in the node.js world. Since it's written in TypeScript, it works pretty well with the Nest framework.

#### Getting started[#](/recipes/sql-typeorm#getting-started)

To start the adventure with this library we have to install all required dependencies:

```bash

$ npm install --save typeorm mysql2
```

The first step we need to do is to establish the connection with our database using `new DataSource().initialize()` class imported from the `typeorm` package. The `initialize()` function returns a `Promise`, and therefore we have to create an [async provider](/v10/fundamentals/async-components).

database.providers.ts

JS TS

```typescript

import { DataSource } from 'typeorm';

export const databaseProviders = [
  {
    provide: 'DATA_SOURCE',
    useFactory: async () => {
      const dataSource = new DataSource({
        type: 'mysql',
        host: 'localhost',
        port: 3306,
        username: 'root',
        password: 'root',
        database: 'test',
        entities: [
            __dirname + '/../**/*.entity{.ts,.js}',
        ],
        synchronize: true,
      });

      return dataSource.initialize();
    },
  },
];
```

> **Warning** Setting `synchronize: true` shouldn't be used in production - otherwise you can lose production data.

> **Hint** Following best practices, we declared the custom provider in the separated file which has a `*.providers.ts` suffix.

Then, we need to export these providers to make them **accessible** for the rest of the application.

database.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { databaseProviders } from './database.providers';

@Module({
  providers: [...databaseProviders],
  exports: [...databaseProviders],
})
export class DatabaseModule {}
```

Now we can inject the `DATA_SOURCE` object using `@Inject()` decorator. Each class that would depend on the `DATA_SOURCE` async provider will wait until a `Promise` is resolved.

#### Repository pattern[#](/recipes/sql-typeorm#repository-pattern)

The [TypeORM](https://github.com/typeorm/typeorm) supports the repository design pattern, thus each entity has its own Repository. These repositories can be obtained from the database connection.

But firstly, we need at least one entity. We are going to reuse the `Photo` entity from the official documentation.

photo.entity.ts

JS TS

```typescript

import { Entity, Column, PrimaryGeneratedColumn } from 'typeorm';

@Entity()
export class Photo {
  @PrimaryGeneratedColumn()
  id: number;

  @Column({ length: 500 })
  name: string;

  @Column('text')
  description: string;

  @Column()
  filename: string;

  @Column('int')
  views: number;

  @Column()
  isPublished: boolean;
}
```

The `Photo` entity belongs to the `photo` directory. This directory represents the `PhotoModule`. Now, let's create a **Repository** provider:

photo.providers.ts

JS TS

```typescript

import { DataSource } from 'typeorm';
import { Photo } from './photo.entity';

export const photoProviders = [
  {
    provide: 'PHOTO_REPOSITORY',
    useFactory: (dataSource: DataSource) => dataSource.getRepository(Photo),
    inject: ['DATA_SOURCE'],
  },
];
```

> **Warning** In the real-world applications you should avoid **magic strings**. Both `PHOTO_REPOSITORY` and `DATA_SOURCE` should be kept in the separated `constants.ts` file.

Now we can inject the `Repository<Photo>` to the `PhotoService` using the `@Inject()` decorator:

photo.service.ts

JS TS

```typescript

import { Injectable, Inject } from '@nestjs/common';
import { Repository } from 'typeorm';
import { Photo } from './photo.entity';

@Injectable()
export class PhotoService {
  constructor(
    @Inject('PHOTO_REPOSITORY')
    private photoRepository: Repository<Photo>,
  ) {}

  async findAll(): Promise<Photo[]> {
    return this.photoRepository.find();
  }
}
```

The database connection is **asynchronous**, but Nest makes this process completely invisible for the end-user. The `PhotoRepository` is waiting for the db connection, and the `PhotoService` is delayed until repository is ready to use. The entire application can start when each class is instantiated.

Here is a final `PhotoModule`:

photo.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { DatabaseModule } from '../database/database.module';
import { photoProviders } from './photo.providers';
import { PhotoService } from './photo.service';

@Module({
  imports: [DatabaseModule],
  providers: [
    ...photoProviders,
    PhotoService,
  ],
})
export class PhotoModule {}
```

> **Hint** Do not forget to import the `PhotoModule` into the root `AppModule`.

----
url: https://docs.nestjs.com/v8/faq/hybrid-application
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Hybrid application](https://docs.nestjs.com/v8/faq/hybrid-application#hybrid-application)
* [Sharing configuration](https://docs.nestjs.com/v8/faq/hybrid-application#sharing-configuration)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/faq/hybrid-application.md "Suggest Edits")

### Hybrid application

A hybrid application is one that both listens for HTTP requests, as well as makes use of connected microservices. The `INestApplication` instance can be connected with `INestMicroservice` instances through the `connectMicroservice()` method.

```typescript

const app = await NestFactory.create(AppModule);
const microservice = app.connectMicroservice({
  transport: Transport.TCP,
});

await app.startAllMicroservices();
await app.listen(3001);
```

To connect multiple microservice instances, issue the call to `connectMicroservice()` for each microservice:

```typescript

const app = await NestFactory.create(AppModule);
// microservice #1
const microserviceTcp = app.connectMicroservice<MicroserviceOptions>({
  transport: Transport.TCP,
  options: {
    port: 3001,
  },
});
// microservice #2
const microserviceRedis = app.connectMicroservice<MicroserviceOptions>({
  transport: Transport.REDIS,
  options: {
    url: 'redis://localhost:6379',
  },
});

await app.startAllMicroservices();
await app.listen(3001);
```

To bind `@MessagePattern()` to only one transport strategy (for example, MQTT) in a hybrid application with multiple microservices, we can pass the second argument of type `Transport` which is an enum with all the built-in transport strategies defined.

JS TS

```typescript

@MessagePattern('time.us.*', Transport.NATS)
getDate(@Payload() data: number[], @Ctx() context: NatsContext) {
  console.log(`Subject: ${context.getSubject()}`); // e.g. "time.us.east"
  return new Date().toLocaleTimeString(...);
}
@MessagePattern({ cmd: 'time.us' }, Transport.TCP)
getTCPDate(@Payload() data: number[]) {
  return new Date().toLocaleTimeString(...);
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('time.us.*', Transport.NATS)
getDate(data, context) {
  console.log(`Subject: ${context.getSubject()}`); // e.g. "time.us.east"
  return new Date().toLocaleTimeString(...);
}
@Bind(Payload(), Ctx())
@MessagePattern({ cmd: 'time.us' }, Transport.TCP)
getTCPDate(data, context) {
  return new Date().toLocaleTimeString(...);
}
```

> **Hint**`@Payload()`, `@Ctx()`, `Transport` and `NatsContext` are imported from `@nestjs/microservices`.

#### Sharing configuration[#](/faq/hybrid-application#sharing-configuration)

By default a hybrid application will not inherit global pipes, interceptors, guards and filters configured for the main (HTTP-based) application. To inherit these configuration properties from the main application, set the `inheritAppConfig` property in the second argument (an optional options object) of the `connectMicroservice()` call, as follow:

```typescript

const microservice = app.connectMicroservice({
  transport: Transport.TCP
}, { inheritAppConfig: true });
```

----
url: https://docs.nestjs.com/v7/security/rate-limiting
----

* [Rate Limiting](https://docs.nestjs.com/v7/security/rate-limiting#rate-limiting)
* [Customization](https://docs.nestjs.com/v7/security/rate-limiting#customization)
* [Websockets](https://docs.nestjs.com/v7/security/rate-limiting#websockets)
* [GraphQL](https://docs.nestjs.com/v7/security/rate-limiting#graphql)
* [Configuration](https://docs.nestjs.com/v7/security/rate-limiting#configuration)
* [Async Configuration](https://docs.nestjs.com/v7/security/rate-limiting#async-configuration)
* [Storages](https://docs.nestjs.com/v7/security/rate-limiting#storages)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/security/rate-limiting.md "Suggest Edits")

### Rate Limiting

A common technique to protect applications from brute-force attacks is **rate-limiting**. To get started, you'll need to install the `@nestjs/throttler` package.

```bash

$ npm i --save @nestjs/throttler
```

Once the installation is complete, the `ThrottlerModule` can be configured as any other Nest package with `forRoot` or `forRootAsync` methods.

```typescript

@Module({
  imports: [
    ThrottlerModule.forRoot({
      ttl: 60,
      limit: 10,
    }),
  ]
})
export class AppModule {}
```

The above will set the global options for the `ttl`, the time to live, and the `limit`, the maximum number of requests within the ttl, for the routes of your application that are guarded.

Once the module has been imported, you can then choose how you would like to bind the `ThrottlerGuard`. Any kind of binding as mentioned in the [guards](https://docs.nestjs.com/guards) section is fine. If you wanted to bind the guard globally, for example, you could do so by adding this provider to any module:

```typescript

{
  provide: APP_GUARD,
  useClass: ThrottlerGuard
}
```

#### Customization[#](/security/rate-limiting#customization)

There may be a time where you want to bind the guard to a controller or globally, but want to disable rate limiting for one or more of your endpoints. For that, you can use the `@SkipThrottle()` decorator, to negate the throttler for an entire class or a single route. The `@SkipThrottle()` decorator can also take in a boolean for if there is a case where you want to exclude *most* of a controller, but not every route.

There is also the `@Throttle()` decorator which can be used to override the `limit` and `ttl` set in the global module, to give tighter or looser security options. This decorator can be used on a class or a function as well. The order for this decorator does matter, as the arguments are in the order of `limit, ttl`.

#### Websockets[#](/security/rate-limiting#websockets)

This module can work with websockets, but it requires some class extension. You can extend the `ThrottlerGuard` and override the `handleRequest` method like so:

```typescript

@Injectable()
export class WsThrottlerGuard extends ThrottlerGuard {
  async handleRequest(context: ExecutionContext, limit: number, ttl: number): Promise<boolean> {
    const client = context.switchToWs().getClient();
    const ip = client.conn.remoteAddress; 
    const key = this.generateKey(context, ip);
    const ttls = await this.storageService.getRecord(key);

    if (ttls.length >= limit) {
      throw new ThrottlerException();
    }

    await this.storageService.addRecord(key, ttl);
    return true;
  }
}
```

> **Hint** If you are using the `@nestjs/platform-ws` package you can use `client._socket.remoteAddress` instead.

#### GraphQL[#](/security/rate-limiting#graphql)

The `ThrottlerGuard` can also be used to work with GraphQL requests. Again, the guard can be extended, but this tme the `getRequestResponse` method will be overridden

```typescript

@Injectable()
export class GqlThrottlerGuard extends ThrottlerGuard {
  getRequestResponse(context: ExecutionContext) {
    const gqlCtx = GqlExecutionContext.create(context);
    const ctx = gql.getContext();
    return { req, ctx.req, res: ctx.res }
  }
}
```

#### Configuration[#](/security/rate-limiting#configuration)

The following options are valid for the `ThrottlerModule`:

|                    |                                                                                               |
| ------------------ | --------------------------------------------------------------------------------------------- |
| `ttl`              | the number of seconds that each request will last in storage                                  |
| `limit`            | the maximum number of requests within the TTL limit                                           |
| `ignoreUserAgents` | an array of regular expressions of user-agents to ignore when it comes to throttling requests |
| `storage`          | the storage setting for how to keep track of the requests                                     |

#### Async Configuration[#](/security/rate-limiting#async-configuration)

You may want to get your rate-limiting configuration asynchronously instead of synchronously. You can use the `forRootAsync()` method, which allows for dependency injection and `async` methods.

One approach would be to use a factory function:

```typescript

@Module({
  imports: [
    ThrottlerModule.forRootAsync({
      imports: [ConfigModule],
      inject: [ConfigService],
      useFactory: (config: ConfigService) => ({
        ttl: config.get('THROTTLE_TTL'),
        limit: config.get('THROTTLE_LIMIT'),
      }),
    }),
  ],
})
export class AppModule {}
```

You can also use the `useClass` syntax:

```typescript

@Module({
  imports: [
    ThrottlerModule.forRootASync({
      imports: [ConfigModule],
      useClass: ThrottlerConfigService,
    }),
  ],
})
export class AppModule {}
```

This is doable, as long as `ThrottlerConfigService` implements the interface `ThrottlerOptionsFactory`.

#### Storages[#](/security/rate-limiting#storages)

The built in storage is an in memory cache that keeps track of the requests made until they have passed the TTL set by the global options. You can drop in your own storage option to the `storage` option of the `ThrottlerModule` so long as the class implements the `ThrottlerStorage` interface.

> **Note**`ThrottlerStorage` can be imported from `@nestjs/throttler`.

----
url: https://docs.nestjs.com/v7/techniques/compression
----

* [Compression](https://docs.nestjs.com/v7/techniques/compression#compression)
* [Use with Express (default)](https://docs.nestjs.com/v7/techniques/compression#use-with-express-default)
* [Use with Fastify](https://docs.nestjs.com/v7/techniques/compression#use-with-fastify)

[](https://srv.carbonads.net/ads/click/x/GTND4277CVSIC2JEFTBLYKQUF67D62Q7CTSDCZ3JCAAI623WCTADK53KCEAI627NCTADL5QUF6SDEKJNCVAIE23KC6SILKJUCT7DEK3EHJNCLSIZ)[AMD EPYC 4005 dedicated servers, klaar in enkele minuten met 99,95% SLA. Configureer uw server vandaag. ](https://srv.carbonads.net/ads/click/x/GTND4277CVSIC2JEFTBLYKQUF67D62Q7CTSDCZ3JCAAI623WCTADK53KCEAI627NCTADL5QUF6SDEKJNCVAIE23KC6SILKJUCT7DEK3EHJNCLSIZ)[ads via Carbon](http://carbonads.net/?utm_source=nestjscom\&utm_medium=ad_via_link\&utm_campaign=in_unit\&utm_term=carbon)

```bash

$ npm i --save compression
```

Once the installation is complete, apply the compression middleware as global middleware.

```typescript

import * as compression from 'compression';
// somewhere in your initialization file
app.use(compression());
```

#### Use with Fastify[#](/techniques/compression#use-with-fastify)

If using the `FastifyAdapter`, you'll want to use [fastify-compress](https://github.com/fastify/fastify-compress):

```bash

$ npm i --save fastify-compress
```

Once the installation is complete, apply the fastify-compress middleware as global middleware.

```typescript

import compression from 'fastify-compress';
// somewhere in your initialization file
app.register(compression);
```

By default, fastify-compress will use Brotli compression (on Node >= 11.7.0) when browsers indicate support for the encoding. While Brotli is quite efficient in terms of compression ratio, it's also quite slow. Due to this, you may want to tell fastify-compress to only use deflate and gzip to compress responses; you'll end up with larger responses but they'll be delivered much more quickly.

To specify encodings, provide a second argument to `app.register`:

```typescript

app.register(compression, { encodings: ['gzip', 'deflate'] });
```

The above tells `fastify-compress` to only use gzip and deflate encodings, preferring gzip if the client supports both.

----
url: https://docs.nestjs.com/v5/first-steps
----

### First steps

In this set of articles, you'll learn the **core fundamentals** of Nest. To get familiar with the essential building-blocks of Nest applications, we'll build a basic CRUD application with features that cover a lot of ground at an introductory level.

#### Language

We're in love with [TypeScript](http://www.typescriptlang.org/), but above all - we love [Node.js](https://nodejs.org/en/). That's why Nest is compatible with both TypeScript and **pure JavaScript**. Nest is taking advantage of latest language features, so to use a framework with simple JavaScript we need a [Babel](http://babeljs.io/) compiler.

We'll mostly use TypeScript in the examples we provide, but you can always **switch the code snippets** to vanilla JavaScript syntax.

#### Prerequisites

Please make sure that [Node.js](https://nodejs.org/)**(>= 8.9.0)** is installed on your operating system.

#### Setup

Setting up a new project is quite simple with the [Nest CLI](/v5/cli/overview). With [npm](https://www.npmjs.com/) installed, you can create a new Nest project with the following commands in your OS terminal:

```bash

$ npm i -g @nestjs/cli
$ nest new project
```

The `project` directory will be scaffolded with several core files being located within a `src/` directory.

src

app.controller.ts

app.module.ts

main.ts

Following the convention, newly created modules should have their dedicated directory.

|                     |                                                                                                   |
| ------------------- | ------------------------------------------------------------------------------------------------- |
| `main.ts`           | The entry file of the application. It uses `NestFactory` to create the Nest application instance. |
| `app.module.ts`     | Defines `AppModule`, the root module of the application.                                          |
| `app.controller.ts` | Basic controller sample with a single route.                                                      |

The `main.ts` includes an async function, which will **bootstrap** our application:

main.ts

JS TS

TypeScript

```typescript

import { NestFactory } from '@nestjs/core';
import { ApplicationModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(ApplicationModule);
  await app.listen(3000);
}
bootstrap();
```

To create a Nest application instance, we are using the `NestFactory`. `NestFactory` is one of the most fundamental classes, it exposes a few static methods that allows creating application instance. The `create()` method returns an object, which fulfills the `INestApplication` interface, and provides a set of usable methods which are well described in the next chapters.

#### Running application

Once the installation process is complete, you can run the following command to start the HTTP server:

```bash

$ npm run start
```

This command starts the HTTP server on the port defined inside the `src/main.ts` file. While the application is running, open your browser and navigate to `http://localhost:3000/`. You should see the `Hello world!` message.

* First steps
* Language
* Prerequisites
* Setup
* Running application

----
url: https://docs.nestjs.com/v9/graphql/extensions
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Extensions](https://docs.nestjs.com/v9/graphql/extensions#extensions)
* [Adding custom metadata](https://docs.nestjs.com/v9/graphql/extensions#adding-custom-metadata)
* [Using custom metadata](https://docs.nestjs.com/v9/graphql/extensions#using-custom-metadata)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/extensions.md "Suggest Edits")

### Extensions

> **Warning** This chapter applies only to the code first approach.

Extensions is an **advanced, low-level feature** that lets you define arbitrary data in the types configuration. Attaching custom metadata to certain fields allows you to create more sophisticated, generic solutions. For example, with extensions, you can define field-level roles required to access particular fields. Such roles can be reflected at runtime to determine whether the caller has sufficient permissions to retrieve a specific field.

#### Adding custom metadata[#](/graphql/extensions#adding-custom-metadata)

To attach custom metadata for a field, use the `@Extensions()` decorator exported from the `@nestjs/graphql` package.

```typescript

@Field()
@Extensions({ role: Role.ADMIN })
password: string;
```

In the example above, we assigned the `role` metadata property the value of `Role.ADMIN`. `Role` is a simple TypeScript enum that groups all the user roles available in our system.

Note, in addition to setting metadata on fields, you can use the `@Extensions()` decorator at the class level and method level (e.g., on the query handler).

#### Using custom metadata[#](/graphql/extensions#using-custom-metadata)

Logic that leverages the custom metadata can be as complex as needed. For example, you can create a simple interceptor that stores/logs events per method invocation, or a [field middleware](/v9/graphql/field-middleware) that matches roles required to retrieve a field with the caller permissions (field-level permissions system).

For illustration purposes, let's define a `checkRoleMiddleware` that compares a user's role (hardcoded here) with a role required to access a target field:

```typescript

export const checkRoleMiddleware: FieldMiddleware = async (
  ctx: MiddlewareContext,
  next: NextFn,
) => {
  const { info } = ctx;
  const { extensions } = info.parentType.getFields()[info.fieldName];

  /**
   * In a real-world application, the "userRole" variable
   * should represent the caller's (user) role (for example, "ctx.user.role").
   */
  const userRole = Role.USER;
  if (userRole === extensions.role) {
    // or just "return null" to ignore
    throw new ForbiddenException(
      `User does not have sufficient permissions to access "${info.fieldName}" field.`,
    );
  }
  return next();
};
```

With this in place, we can register a middleware for the `password` field, as follows:

```typescript

@Field({ middleware: [checkRoleMiddleware] })
@Extensions({ role: Role.ADMIN })
password: string;
```

----
url: https://docs.nestjs.com/v6/microservices/exception-filters
----

* [Exception filters](https://docs.nestjs.com/v6/microservices/exception-filters#exception-filters)
* [Filters](https://docs.nestjs.com/v6/microservices/exception-filters#filters)
* [Inheritance](https://docs.nestjs.com/v6/microservices/exception-filters#inheritance)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/microservices/exception-filters.md "Suggest Edits")

### Exception filters

The only difference between the HTTP [exception filter](/v6/exception-filters) layer and the corresponding microservices layer is that instead of throwing `HttpException`, you should use `RpcException`.

```typescript

throw new RpcException('Invalid credentials.');
```

> **Hint** The `RpcException` class is imported from the `@nestjs/microservices` package.

With the sample above, Nest will handle the thrown exception and return the `error` object with the following structure:

```json

{
  "status": "error",
  "message": "Invalid credentials."
}
```

#### Filters[#](/microservices/exception-filters#filters)

Microservice exception filters behave similarly to HTTP exception filters, with one small difference. The `catch()` method must return an `Observable`.

rpc-exception.filter.ts

JS TS

```typescript

import { Catch, RpcExceptionFilter, ArgumentsHost } from '@nestjs/common';
import { Observable, throwError } from 'rxjs';
import { RpcException } from '@nestjs/microservices';

@Catch(RpcException)
export class ExceptionFilter implements RpcExceptionFilter<RpcException> {
  catch(exception: RpcException, host: ArgumentsHost): Observable<any> {
    return throwError(exception.getError());
  }
}
```

```typescript

import { Catch } from '@nestjs/common';
import { throwError } from 'rxjs';

@Catch(RpcException)
export class ExceptionFilter {
  catch(exception, host) {
    return throwError(exception.getError());
  }
}
```

> **Warning** You cannot set up global microservice exception filters when using a [hybrid application](/v6/faq/hybrid-application).

The following example uses a manually instantiated method-scoped filter. Just as with HTTP based applications, you can also use controller-scoped filters (i.e., prefix the controller class with a `@UseFilters()` decorator).

JS TS

```typescript

@UseFilters(new ExceptionFilter())
@MessagePattern({ cmd: 'sum' })
accumulate(data: number[]): number {
  return (data || []).reduce((a, b) => a + b);
}
```

```typescript

@UseFilters(new ExceptionFilter())
@MessagePattern({ cmd: 'sum' })
accumulate(data) {
  return (data || []).reduce((a, b) => a + b);
}
```

#### Inheritance[#](/microservices/exception-filters#inheritance)

Typically, you'll create fully customized exception filters crafted to fulfill your application requirements. However, there might be use-cases when you would like to simply extend the **core exception filter**, and override the behavior based on certain factors.

In order to delegate exception processing to the base filter, you need to extend `BaseExceptionFilter` and call the inherited `catch()` method.

JS TS

```typescript

import { Catch, ArgumentsHost } from '@nestjs/common';
import { BaseRpcExceptionFilter } from '@nestjs/microservices';

@Catch()
export class AllExceptionsFilter extends BaseRpcExceptionFilter {
  catch(exception: any, host: ArgumentsHost) {
    return super.catch(exception, host);
  }
}
```

```typescript

import { Catch } from '@nestjs/common';
import { BaseRpcExceptionFilter } from '@nestjs/microservices';

@Catch()
export class AllExceptionsFilter extends BaseRpcExceptionFilter {
  catch(exception, host) {
    return super.catch(exception, host);
  }
}
```

The above implementation is just a shell demonstrating the approach. Your implementation of the extended exception filter would include your tailored **business logic** (e.g., handling various conditions).

----
url: https://docs.nestjs.com/v11/microservices/redis
----

* [Redis](https://docs.nestjs.com/v11/microservices/redis#redis)
* [Installation](https://docs.nestjs.com/v11/microservices/redis#installation)
* [Overview](https://docs.nestjs.com/v11/microservices/redis#overview)
* [Options](https://docs.nestjs.com/v11/microservices/redis#options)
* [Client](https://docs.nestjs.com/v11/microservices/redis#client)
* [Context](https://docs.nestjs.com/v11/microservices/redis#context)
* [Wildcards](https://docs.nestjs.com/v11/microservices/redis#wildcards)
* [Instance status updates](https://docs.nestjs.com/v11/microservices/redis#instance-status-updates)
* [Listening to Redis events](https://docs.nestjs.com/v11/microservices/redis#listening-to-redis-events)
* [Underlying driver access](https://docs.nestjs.com/v11/microservices/redis#underlying-driver-access)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/microservices/redis.md "Suggest Edits")

### Redis

The [Redis](https://redis.io/) transporter implements the publish/subscribe messaging paradigm and leverages the [Pub/Sub](https://redis.io/topics/pubsub) feature of Redis. Published messages are categorized in channels, without knowing what subscribers (if any) will eventually receive the message. Each microservice can subscribe to any number of channels. In addition, more than one channel can be subscribed to at a time. Messages exchanged through channels are **fire-and-forget**, which means that if a message is published and there are no subscribers interested in it, the message is removed and cannot be recovered. Thus, you don't have a guarantee that either messages or events will be handled by at least one service. A single message can be subscribed to (and received) by multiple subscribers.

#### Installation[#](/microservices/redis#installation)

To start building Redis-based microservices, first install the required package:

```bash

$ npm i --save ioredis
```

#### Overview[#](/microservices/redis#overview)

To use the Redis transporter, pass the following options object to the `createMicroservice()` method:

main.ts

JS TS

```typescript

const app = await NestFactory.createMicroservice<MicroserviceOptions>(AppModule, {
  transport: Transport.REDIS,
  options: {
    host: 'localhost',
    port: 6379,
  },
});
```

```typescript

const app = await NestFactory.createMicroservice(AppModule, {
  transport: Transport.REDIS,
  options: {
    host: 'localhost',
    port: 6379,
  },
});
```

> **Hint** The `Transport` enum is imported from the `@nestjs/microservices` package.

#### Options[#](/microservices/redis#options)

The `options` property is specific to the chosen transporter. The **Redis** transporter exposes the properties described below.

|                 |                                                                                                                                 |
| --------------- | ------------------------------------------------------------------------------------------------------------------------------- |
| `host`          | Connection url                                                                                                                  |
| `port`          | Connection port                                                                                                                 |
| `retryAttempts` | Number of times to retry message (default: `0`)                                                                                 |
| `retryDelay`    | Delay between message retry attempts (ms) (default: `0`)                                                                        |
| `wildcards`     | Enables Redis wildcard subscriptions, instructing transporter to use `psubscribe`/`pmessage` under the hood. (default: `false`) |

All the properties supported by the official [ioredis](https://redis.github.io/ioredis/index.html#RedisOptions) client are also supported by this transporter.

#### Client[#](/microservices/redis#client)

Like other microservice transporters, you have [several options](https://docs.nestjs.com/microservices/basics#client) for creating a Redis `ClientProxy` instance.

One method for creating an instance is to use the `ClientsModule`. To create a client instance with the `ClientsModule`, import it and use the `register()` method to pass an options object with the same properties shown above in the `createMicroservice()` method, as well as a `name` property to be used as the injection token. Read more about `ClientsModule`[here](https://docs.nestjs.com/microservices/basics#client).

```typescript

@Module({
  imports: [
    ClientsModule.register([
      {
        name: 'MATH_SERVICE',
        transport: Transport.REDIS,
        options: {
          host: 'localhost',
          port: 6379,
        }
      },
    ]),
  ]
  ...
})
```

Other options to create a client (either `ClientProxyFactory` or `@Client()`) can be used as well. You can read about them [here](https://docs.nestjs.com/microservices/basics#client).

#### Context[#](/microservices/redis#context)

In more complex scenarios, you may need to access additional information about the incoming request. When using the Redis transporter, you can access the `RedisContext` object.

JS TS

```typescript

@MessagePattern('notifications')
getNotifications(@Payload() data: number[], @Ctx() context: RedisContext) {
  console.log(`Channel: ${context.getChannel()}`);
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('notifications')
getNotifications(data, context) {
  console.log(`Channel: ${context.getChannel()}`);
}
```

> **Hint**`@Payload()`, `@Ctx()` and `RedisContext` are imported from the `@nestjs/microservices` package.

#### Wildcards[#](/microservices/redis#wildcards)

To enable wildcards support, set the `wildcards` option to `true`. This instructs the transporter to use `psubscribe` and `pmessage` under the hood.

```typescript

const app = await NestFactory.createMicroservice(AppModule, {
  transport: Transport.REDIS,
  options: {
    // Other options
    wildcards: true,
  },
});
```

Make sure to pass the `wildcards` option when creating a client instance as well.

With this option enabled, you can use wildcards in your message and event patterns. For example, to subscribe to all channels starting with `notifications`, you can use the following pattern:

```typescript

@EventPattern('notifications.*')
```

#### Instance status updates[#](/microservices/redis#instance-status-updates)

To get real-time updates on the connection and the state of the underlying driver instance, you can subscribe to the `status` stream. This stream provides status updates specific to the chosen driver. For the Redis driver, the `status` stream emits `connected`, `disconnected`, and `reconnecting` events.

```typescript

this.client.status.subscribe((status: RedisStatus) => {
  console.log(status);
});
```

> **Hint** The `RedisStatus` type is imported from the `@nestjs/microservices` package.

Similarly, you can subscribe to the server's `status` stream to receive notifications about the server's status.

```typescript

const server = app.connectMicroservice<MicroserviceOptions>(...);
server.status.subscribe((status: RedisStatus) => {
  console.log(status);
});
```

#### Listening to Redis events[#](/microservices/redis#listening-to-redis-events)

In some cases, you might want to listen to internal events emitted by the microservice. For example, you could listen for the `error` event to trigger additional operations when an error occurs. To do this, use the `on()` method, as shown below:

```typescript

this.client.on('error', (err) => {
  console.error(err);
});
```

Similarly, you can listen to the server's internal events:

```typescript

server.on<RedisEvents>('error', (err) => {
  console.error(err);
});
```

> **Hint** The `RedisEvents` type is imported from the `@nestjs/microservices` package.

#### Underlying driver access[#](/microservices/redis#underlying-driver-access)

For more advanced use cases, you may need to access the underlying driver instance. This can be useful for scenarios like manually closing the connection or using driver-specific methods. However, keep in mind that for most cases, you **shouldn't need** to access the driver directly.

To do so, you can use the `unwrap()` method, which returns the underlying driver instance. The generic type parameter should specify the type of driver instance you expect.

```typescript

const [pub, sub] =
  this.client.unwrap<[import('ioredis').Redis, import('ioredis').Redis]>();
```

Similarly, you can access the server's underlying driver instance:

```typescript

const [pub, sub] =
  server.unwrap<[import('ioredis').Redis, import('ioredis').Redis]>();
```

Note that, in contrary to other transporters, the Redis transporter returns a tuple of two `ioredis` instances: the first one is used for publishing messages, and the second one is used for subscribing to messages.

----
url: https://docs.nestjs.com/v10/middleware
----

* [Middleware](https://docs.nestjs.com/v10/middleware#middleware)
* [Dependency injection](https://docs.nestjs.com/v10/middleware#dependency-injection)
* [Applying middleware](https://docs.nestjs.com/v10/middleware#applying-middleware)
* [Route wildcards](https://docs.nestjs.com/v10/middleware#route-wildcards)
* [Middleware consumer](https://docs.nestjs.com/v10/middleware#middleware-consumer)
* [Excluding routes](https://docs.nestjs.com/v10/middleware#excluding-routes)
* [Functional middleware](https://docs.nestjs.com/v10/middleware#functional-middleware)
* [Multiple middleware](https://docs.nestjs.com/v10/middleware#multiple-middleware)
* [Global middleware](https://docs.nestjs.com/v10/middleware#global-middleware)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/middlewares.md "Suggest Edits")

### Middleware

Middleware is a function which is called **before** the route handler. Middleware functions have access to the [request](https://expressjs.com/en/4x/api.html#req) and [response](https://expressjs.com/en/4x/api.html#res) objects, and the `next()` middleware function in the application’s request-response cycle. The **next** middleware function is commonly denoted by a variable named `next`.

Nest middleware are, by default, equivalent to [express](https://expressjs.com/en/guide/using-middleware.html) middleware. The following description from the official express documentation describes the capabilities of middleware:

> Middleware functions can perform the following tasks:
>
> * execute any code.
> * make changes to the request and the response objects.
> * end the request-response cycle.
> * call the next middleware function in the stack.
> * if the current middleware function does not end the request-response cycle, it must call `next()` to pass control to the next middleware function. Otherwise, the request will be left hanging.

You implement custom Nest middleware in either a function, or in a class with an `@Injectable()` decorator. The class should implement the `NestMiddleware` interface, while the function does not have any special requirements. Let's start by implementing a simple middleware feature using the class method.

> **Warning**`Express` and `fastify` handle middleware differently and provide different method signatures, read more [here](/techniques/performance#middleware).

logger.middleware.ts

JS TS

```typescript

import { Injectable, NestMiddleware } from '@nestjs/common';
import { Request, Response, NextFunction } from 'express';

@Injectable()
export class LoggerMiddleware implements NestMiddleware {
  use(req: Request, res: Response, next: NextFunction) {
    console.log('Request...');
    next();
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';

@Injectable()
export class LoggerMiddleware {
  use(req, res, next) {
    console.log('Request...');
    next();
  }
}
```

#### Dependency injection[#](/middleware#dependency-injection)

Nest middleware fully supports Dependency Injection. Just as with providers and controllers, they are able to **inject dependencies** that are available within the same module. As usual, this is done through the `constructor`.

#### Applying middleware[#](/middleware#applying-middleware)

There is no place for middleware in the `@Module()` decorator. Instead, we set them up using the `configure()` method of the module class. Modules that include middleware have to implement the `NestModule` interface. Let's set up the `LoggerMiddleware` at the `AppModule` level.

app.module.ts

JS TS

```typescript

import { Module, NestModule, MiddlewareConsumer } from '@nestjs/common';
import { LoggerMiddleware } from './common/middleware/logger.middleware';
import { CatsModule } from './cats/cats.module';

@Module({
  imports: [CatsModule],
})
export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer
      .apply(LoggerMiddleware)
      .forRoutes('cats');
  }
}
```

```typescript

import { Module } from '@nestjs/common';
import { LoggerMiddleware } from './common/middleware/logger.middleware';
import { CatsModule } from './cats/cats.module';

@Module({
  imports: [CatsModule],
})
export class AppModule {
  configure(consumer) {
    consumer
      .apply(LoggerMiddleware)
      .forRoutes('cats');
  }
}
```

In the above example we have set up the `LoggerMiddleware` for the `/cats` route handlers that were previously defined inside the `CatsController`. We may also further restrict a middleware to a particular request method by passing an object containing the route `path` and request `method` to the `forRoutes()` method when configuring the middleware. In the example below, notice that we import the `RequestMethod` enum to reference the desired request method type.

app.module.ts

JS TS

```typescript

import { Module, NestModule, RequestMethod, MiddlewareConsumer } from '@nestjs/common';
import { LoggerMiddleware } from './common/middleware/logger.middleware';
import { CatsModule } from './cats/cats.module';

@Module({
  imports: [CatsModule],
})
export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer
      .apply(LoggerMiddleware)
      .forRoutes({ path: 'cats', method: RequestMethod.GET });
  }
}
```

```typescript

import { Module, RequestMethod } from '@nestjs/common';
import { LoggerMiddleware } from './common/middleware/logger.middleware';
import { CatsModule } from './cats/cats.module';

@Module({
  imports: [CatsModule],
})
export class AppModule {
  configure(consumer) {
    consumer
      .apply(LoggerMiddleware)
      .forRoutes({ path: 'cats', method: RequestMethod.GET });
  }
}
```

> **Hint** The `configure()` method can be made asynchronous using `async/await` (e.g., you can `await` completion of an asynchronous operation inside the `configure()` method body).

> **Warning** When using the `express` adapter, the NestJS app will register `json` and `urlencoded` from the package `body-parser` by default. This means if you want to customize that middleware via the `MiddlewareConsumer`, you need to turn off the global middleware by setting the `bodyParser` flag to `false` when creating the application with `NestFactory.create()`.

#### Route wildcards[#](/middleware#route-wildcards)

Pattern based routes are supported as well. For instance, the asterisk is used as a **wildcard**, and will match any combination of characters:

```typescript

forRoutes({
  path: 'ab*cd',
  method: RequestMethod.ALL,
});
```

The `'ab*cd'` route path will match `abcd`, `ab_cd`, `abecd`, and so on. The characters `?`, `+`, `*`, and `()` may be used in a route path, and are subsets of their regular expression counterparts. The hyphen ( `-`) and the dot (`.`) are interpreted literally by string-based paths.

> **Warning** The `fastify` package uses the latest version of the `path-to-regexp` package, which no longer supports wildcard asterisks `*`. Instead, you must use parameters (e.g., `(.*)`, `:splat*`).

#### Middleware consumer[#](/middleware#middleware-consumer)

The `MiddlewareConsumer` is a helper class. It provides several built-in methods to manage middleware. All of them can be simply **chained** in the [fluent style](https://en.wikipedia.org/wiki/Fluent_interface). The `forRoutes()` method can take a single string, multiple strings, a `RouteInfo` object, a controller class and even multiple controller classes. In most cases you'll probably just pass a list of **controllers** separated by commas. Below is an example with a single controller:

app.module.ts

JS TS

```typescript

import { Module, NestModule, MiddlewareConsumer } from '@nestjs/common';
import { LoggerMiddleware } from './common/middleware/logger.middleware';
import { CatsModule } from './cats/cats.module';
import { CatsController } from './cats/cats.controller';

@Module({
  imports: [CatsModule],
})
export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer
      .apply(LoggerMiddleware)
      .forRoutes(CatsController);
  }
}
```

```typescript

import { Module } from '@nestjs/common';
import { LoggerMiddleware } from './common/middleware/logger.middleware';
import { CatsModule } from './cats/cats.module';
import { CatsController } from './cats/cats.controller';

@Module({
  imports: [CatsModule],
})
export class AppModule {
  configure(consumer) {
    consumer
      .apply(LoggerMiddleware)
      .forRoutes(CatsController);
  }
}
```

> **Hint** The `apply()` method may either take a single middleware, or multiple arguments to specify [multiple middlewares](/middleware#multiple-middleware).

#### Excluding routes[#](/middleware#excluding-routes)

At times we want to **exclude** certain routes from having the middleware applied. We can easily exclude certain routes with the `exclude()` method. This method can take a single string, multiple strings, or a `RouteInfo` object identifying routes to be excluded, as shown below:

```typescript

consumer
  .apply(LoggerMiddleware)
  .exclude(
    { path: 'cats', method: RequestMethod.GET },
    { path: 'cats', method: RequestMethod.POST },
    'cats/(.*)',
  )
  .forRoutes(CatsController);
```

> **Hint** The `exclude()` method supports wildcard parameters using the [path-to-regexp](https://github.com/pillarjs/path-to-regexp#parameters) package.

With the example above, `LoggerMiddleware` will be bound to all routes defined inside `CatsController`**except** the three passed to the `exclude()` method.

#### Functional middleware[#](/middleware#functional-middleware)

The `LoggerMiddleware` class we've been using is quite simple. It has no members, no additional methods, and no dependencies. Why can't we just define it in a simple function instead of a class? In fact, we can. This type of middleware is called **functional middleware**. Let's transform the logger middleware from class-based into functional middleware to illustrate the difference:

logger.middleware.ts

JS TS

```typescript

import { Request, Response, NextFunction } from 'express';

export function logger(req: Request, res: Response, next: NextFunction) {
  console.log(`Request...`);
  next();
};
```

```typescript

export function logger(req, res, next) {
  console.log(`Request...`);
  next();
};
```

And use it within the `AppModule`:

app.module.ts

JS TS

```typescript

consumer
  .apply(logger)
  .forRoutes(CatsController);
```

> **Hint** Consider using the simpler **functional middleware** alternative any time your middleware doesn't need any dependencies.

#### Multiple middleware[#](/middleware#multiple-middleware)

As mentioned above, in order to bind multiple middleware that are executed sequentially, simply provide a comma separated list inside the `apply()` method:

```typescript

consumer.apply(cors(), helmet(), logger).forRoutes(CatsController);
```

#### Global middleware[#](/middleware#global-middleware)

If we want to bind middleware to every registered route at once, we can use the `use()` method that is supplied by the `INestApplication` instance:

main.ts

JS TS

```typescript

const app = await NestFactory.create(AppModule);
app.use(logger);
await app.listen(process.env.PORT ?? 3000);
```

> **Hint** Accessing the DI container in a global middleware is not possible. You can use a [functional middleware](middleware#functional-middleware) instead when using `app.use()`. Alternatively, you can use a class middleware and consume it with `.forRoutes('*')` within the `AppModule` (or any other module).

----
url: https://docs.nestjs.com/v7/websockets/exception-filters
----

* [Exception filters](https://docs.nestjs.com/v7/websockets/exception-filters#exception-filters)
* [Filters](https://docs.nestjs.com/v7/websockets/exception-filters#filters)
* [Inheritance](https://docs.nestjs.com/v7/websockets/exception-filters#inheritance)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/websockets/exception-filters.md "Suggest Edits")

### Exception filters

The only difference between the HTTP [exception filter](/v7/exception-filters) layer and the corresponding web sockets layer is that instead of throwing `HttpException`, you should use `WsException`.

```typescript

throw new WsException('Invalid credentials.');
```

> **Hint** The `WsException` class is imported from the `@nestjs/websockets` package.

With the sample above, Nest will handle the thrown exception and emit the `exception` message with the following structure:

```typescript

{
  status: 'error',
  message: 'Invalid credentials.'
}
```

#### Filters[#](/websockets/exception-filters#filters)

Web sockets exception filters behave equivalently to HTTP exception filters. The following example uses a manually instantiated method-scoped filter. Just as with HTTP based applications, you can also use gateway-scoped filters (i.e., prefix the gateway class with a `@UseFilters()` decorator).

```typescript

@UseFilters(new WsExceptionFilter())
@SubscribeMessage('events')
onEvent(client, data: any): WsResponse<any> {
  const event = 'events';
  return { event, data };
}
```

#### Inheritance[#](/websockets/exception-filters#inheritance)

Typically, you'll create fully customized exception filters crafted to fulfill your application requirements. However, there might be use-cases when you would like to simply extend the **core exception filter**, and override the behavior based on certain factors.

In order to delegate exception processing to the base filter, you need to extend `BaseWsExceptionFilter` and call the inherited `catch()` method.

JS TS

```typescript

import { Catch, ArgumentsHost } from '@nestjs/common';
import { BaseWsExceptionFilter } from '@nestjs/websockets';

@Catch()
export class AllExceptionsFilter extends BaseWsExceptionFilter {
  catch(exception: unknown, host: ArgumentsHost) {
    super.catch(exception, host);
  }
}
```

```typescript

import { Catch } from '@nestjs/common';
import { BaseWsExceptionFilter } from '@nestjs/websockets';

@Catch()
export class AllExceptionsFilter extends BaseWsExceptionFilter {
  catch(exception, host) {
    super.catch(exception, host);
  }
}
```

----
url: https://docs.nestjs.com/cli/monorepo
----

[Skip to content](#content)

On this page

* [Workspaces](https://docs.nestjs.com/cli/monorepo#workspaces)
* [Standard mode](https://docs.nestjs.com/cli/monorepo#standard-mode)
* [Monorepo mode](https://docs.nestjs.com/cli/monorepo#monorepo-mode)
* [Workspace projects](https://docs.nestjs.com/cli/monorepo#workspace-projects)
* [Applications](https://docs.nestjs.com/cli/monorepo#applications)
* [Libraries](https://docs.nestjs.com/cli/monorepo#libraries)
* [CLI properties](https://docs.nestjs.com/cli/monorepo#cli-properties)
* [Global compiler options](https://docs.nestjs.com/cli/monorepo#global-compiler-options)
* [Global generate options](https://docs.nestjs.com/cli/monorepo#global-generate-options)
* [Project-specific generate options](https://docs.nestjs.com/cli/monorepo#project-specific-generate-options)
* [Specified compiler](https://docs.nestjs.com/cli/monorepo#specified-compiler)
* [Assets](https://docs.nestjs.com/cli/monorepo#assets)
* [Project properties](https://docs.nestjs.com/cli/monorepo#project-properties)

### Workspaces

Nest has two modes for organizing code:

* **standard mode**: suited to individual, project-focused applications that have their own dependencies and settings and don't need to optimize for sharing modules or for complex builds. This is the default mode.
* **monorepo mode**: treats code artifacts as part of a lightweight **monorepo**, and may be more appropriate for teams of developers and/or multi-project environments. It automates parts of the build process to make it easy to create and compose modular components. It promotes code reuse, makes integration testing easier, makes it easy to share project-wide artifacts such as lint rules and other configuration policies, and is easier to use than alternatives such as Git submodules. Monorepo mode uses the concept of a **workspace**, represented in the `nest-cli.json` file, to coordinate the relationships between the components of the monorepo.

Virtually all of Nest's features are independent of your code organization mode. The **only** effect of this choice is how your projects are composed and how build artifacts are generated. All other functionality, from the CLI to core modules to add-on modules, works the same in either mode.

You can also switch from **standard mode** to **monorepo mode** at any time, so you can delay this decision until the benefits of one approach or the other become clearer.

#### Standard mode[#](/cli/monorepo#standard-mode)

When you run `nest new`, Nest creates a new **project** using a built-in schematic. Nest does the following:

1. Creates a new folder named after the `name` argument you pass to `nest new`.
2. Populates that folder with the default files of a minimal Nest application. You can examine these files in the [typescript-starter](https://github.com/nestjs/typescript-starter) repository.
3. Adds files such as `nest-cli.json`, `package.json`, and `tsconfig.json` that configure the tools for compiling, testing, and serving your application.

From there, you can modify the starter files, add new components and dependencies (e.g., `npm install`), and develop your application as described in the rest of this documentation.

#### Monorepo mode[#](/cli/monorepo#monorepo-mode)

To enable monorepo mode, start with a *standard mode* structure and add **projects**. A project can be a full **application** (which you add to the workspace with `nest generate app`) or a **library** (which you add with `nest generate library`). We discuss these project types below. The key point for now is that the **act of adding a project** to an existing standard mode structure **converts it** to monorepo mode. Let's look at an example.

If we run:

```bash

$ nest new my-project
```

we get a *standard mode* structure with the following folders and files:

lint config

We can convert this to a monorepo mode structure as follows:

```bash

$ cd my-project
$ nest generate app my-app
```

At this point, `nest` converts the existing structure to a **monorepo mode** structure, which results in a few important changes. The folder structure now looks like this:

apps

my-app

src

my-app.controller.ts

my-app.module.ts

my-app.service.ts

lint config

The `generate app` schematic has reorganized the code: it moved each **application** project under the `apps` folder and added a project-specific `tsconfig.app.json` file to each project's root folder. Our original `my-project` app has become the **default project** for the monorepo, and is now a peer of the newly added `my-app`, under the `apps` folder. We cover default projects below.

> **Warning** Converting a standard mode structure to a monorepo only works for projects that follow the canonical Nest project structure. During conversion, the schematic moves the project's `src` and `test` folders into a project folder beneath the root `apps` folder. If a project doesn't use this structure, the conversion fails or produces unreliable results.

#### Workspace projects[#](/cli/monorepo#workspace-projects)

A monorepo uses the concept of a workspace to manage its members. Workspaces are composed of **projects**. A project is either:

* an **application**: a full Nest application, including a `main.ts` file that bootstraps it. Aside from compile and build considerations, an application-type project within a workspace is functionally identical to an application in a *standard mode* structure.
* a **library**: a package of general-purpose features (modules, providers, controllers, etc.) that other projects can use. A library cannot run on its own and has no `main.ts` file. See [Libraries](/cli/libraries) for details.

Every workspace has a **default project**, which should be an application-type project. It is defined by the top-level `"root"` property in the `nest-cli.json` file, which points at the root of the default project (see [CLI properties](/cli/monorepo#cli-properties) below). Usually, this is the **standard mode** application you started with and later converted to a monorepo using `nest generate app`. In that case, the property is populated automatically.

`nest` commands such as `nest build` and `nest start` use the default project when you don't supply a project name.

For example, in the monorepo structure above, running

```bash

$ nest start
```

starts the `my-project` app. To start `my-app`, run:

```bash

$ nest start my-app
```

#### Applications[#](/cli/monorepo#applications)

Application-type projects, informally called "applications", are complete Nest applications that you can run and deploy. You generate one with `nest generate app`.

This command generates a project skeleton, including the standard `src` and `test` folders from the [typescript starter](https://github.com/nestjs/typescript-starter). Unlike in standard mode, an application project in a monorepo has no package dependency file (`package.json`) and no other project configuration artifacts, such as `.prettierrc` or the lint configuration file. Instead, it uses the monorepo-wide dependencies and configuration files.

The schematic does, however, generate a project-specific `tsconfig.app.json` file in the project's root folder. This file sets the appropriate build options, including the compilation output folder. It extends the top-level (monorepo) `tsconfig.json` file, so you can manage global settings monorepo-wide and override them at the project level when needed.

#### Libraries[#](/cli/monorepo#libraries)

Library-type projects, or simply "libraries", are packages of Nest components that must be composed into applications to run. You generate one with `nest generate library`. Deciding what belongs in a library is an architectural design decision. We discuss libraries in depth in the [Libraries](/cli/libraries) chapter.

#### CLI properties[#](/cli/monorepo#cli-properties)

Nest keeps the metadata needed to organize, build, and deploy both standard and monorepo projects in the `nest-cli.json` file. Nest updates this file automatically as you add projects, so you usually don't have to edit it. However, you may want to change some settings manually, so it helps to understand the file's structure.

After the steps above, the `nest-cli.json` file looks like this:

```javascript

{
  "$schema": "https://json.schemastore.org/nest-cli",
  "collection": "@nestjs/schematics",
  "sourceRoot": "apps/my-project/src",
  "compilerOptions": {
    "deleteOutDir": true,
    "builder": "rspack",
    "tsConfigPath": "apps/my-project/tsconfig.app.json"
  },
  "monorepo": true,
  "root": "apps/my-project",
  "projects": {
    "my-app": {
      "type": "application",
      "root": "apps/my-app",
      "entryFile": "main",
      "sourceRoot": "apps/my-app/src",
      "compilerOptions": {
        "tsConfigPath": "apps/my-app/tsconfig.app.json"
      }
    },
    "my-project": {
      "type": "application",
      "root": "apps/my-project",
      "entryFile": "main",
      "sourceRoot": "apps/my-project/src",
      "compilerOptions": {
        "tsConfigPath": "apps/my-project/tsconfig.app.json"
      }
    }
  }
}
```

The file is divided into sections:

* a global section with top-level properties that control standard and monorepo-wide settings
* a top-level property (`"projects"`) with metadata about each project. This section is present only in monorepo mode structures.

The top-level properties are as follows:

* `"collection"`: points at the collection of schematics used to generate components; you generally shouldn't change this value
* `"sourceRoot"`: points at the root of the source code for the single project in standard mode structures, or the *default project* in monorepo mode structures
* `"compilerOptions"`: a map with keys specifying compiler options and values specifying the option setting; see details below
* `"generateOptions"`: a map with keys specifying global generate options and values specifying the option setting; see details below
* `"monorepo"`: (monorepo only) always `true` for a monorepo mode structure
* `"root"`: (monorepo only) points at the project root of the *default project*

#### Global compiler options[#](/cli/monorepo#global-compiler-options)

These properties specify the compiler to use, as well as options that affect **any** compilation step, whether it runs as part of `nest build` or `nest start`, and whichever compiler you use (`tsc`, `swc`, or Rspack).

| Property Name          | Property Value Type | Description                                                                                                                                                                                                                   |
| ---------------------- | ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `webpack`              | boolean             | Deprecated legacy flag for webpack-based compilation. Use `builder` instead.                                                                                                                                                  |
| `tsConfigPath`         | string              | (**monorepo only**) Points at the file containing the `tsconfig.json` settings that will be used when `nest build` or `nest start` is called without a `project` option (e.g., when the default project is built or started). |
| `webpackConfigPath`    | string              | Deprecated legacy path for webpack options. Use `builder.options.configPath` instead.                                                                                                                                         |
| `deleteOutDir`         | boolean             | If `true`, the compiler first removes the compilation output directory (as configured in `tsconfig.json`; the default is `./dist`) every time it is invoked.                                                                  |
| `assets`               | array               | Enables automatic distribution of non-TypeScript assets whenever a compilation step begins (assets are **not** distributed on incremental compiles in `--watch` mode). See below for details.                                 |
| `watchAssets`          | boolean             | If `true`, runs in watch mode, watching **all** non-TypeScript assets. (For finer-grained control over which assets to watch, see the [Assets](/cli/monorepo#assets) section below.)                                          |
| `manualRestart`        | boolean             | If `true`, enables the `rs` shortcut to restart the server manually. Defaults to `false`.                                                                                                                                     |
| `builder`              | string/object       | The builder the CLI uses to compile the project (`tsc`, `swc`, or `rspack`). To customize the builder's behavior, pass an object with two attributes: `type` (`tsc`, `swc`, or `rspack`) and `options`.                       |
| `typeCheck`            | boolean             | If `true`, enables type checking for SWC-driven projects (when `builder` is `swc`). Defaults to `false`.                                                                                                                      |
| `emitDeclarations`     | boolean             | If `true`, emits declaration files (`.d.ts`) when using the SWC builder. Defaults to `false`.                                                                                                                                 |
| `includeLibraryAssets` | array               | (**monorepo only**) List of library project names whose assets should also be copied when building this application.                                                                                                          |

> **Warning** In monorepo mode, a project's `compilerOptions` are not merged with the top-level `compilerOptions`. For example, a project-level `assets` array replaces the top-level `assets` array instead of adding to it. To also copy a library's assets when building an application, list the library in `includeLibraryAssets`.

#### Global generate options[#](/cli/monorepo#global-generate-options)

These properties specify the default options for the `nest generate` command.

| Property Name | Property Value Type | Description                                                                                                                                                                                                                                                                                                                                                                |
| ------------- | ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `spec`        | boolean *or* object | If the value is a boolean, `true` enables `spec` generation by default and `false` disables it. A flag passed on the command line overrides this setting, as does a project-specific `generateOptions` setting (see below). If the value is an object, each key is a schematic name, and its boolean value enables or disables default spec generation for that schematic. |
| `flat`        | boolean             | If `true`, all generate commands generate a flat structure.                                                                                                                                                                                                                                                                                                                |

The following example uses a boolean value to disable spec file generation by default for all projects:

```javascript

{
  "generateOptions": {
    "spec": false
  },
  ...
}
```

The following example uses a boolean value to make flat file generation the default for all projects:

```javascript

{
  "generateOptions": {
    "flat": true
  },
  ...
}
```

In the following example, `spec` file generation is disabled only for `service` schematics (e.g., `nest generate service...`):

```javascript

{
  "generateOptions": {
    "spec": {
      "service": false
    }
  },
  ...
}
```

> **Warning** When you specify `spec` as an object, the schematic keys don't support aliases. For example, if you set `service: false` and then generate a service through its alias `s`, the spec file is still generated. To cover both the schematic name and its alias, specify both, as shown below.
>
> ```javascript
>
> {
>   "generateOptions": {
>     "spec": {
>       "service": false,
>       "s": false
>     }
>   },
>   ...
> }
> ```

#### Project-specific generate options[#](/cli/monorepo#project-specific-generate-options)

In addition to global generate options, you can specify project-specific generate options. They use the same format as the global options, but you set them directly on each project.

Project-specific generate options override global generate options.

```javascript

{
  "projects": {
    "cats-project": {
      "generateOptions": {
        "spec": {
          "service": false
        }
      },
      ...
    }
  },
  ...
}
```

> **Warning** Generate options are applied in the following order of precedence: options passed on the command line take precedence over project-specific options, which in turn override global options.

#### Specified compiler[#](/cli/monorepo#specified-compiler)

Standard mode and monorepo mode use different default compilers because, for larger projects (more typical in a monorepo), Rspack can significantly reduce build times and produces a single file that bundles all project components together. To generate individual files instead, set the builder to `tsc` or `swc`.

#### Assets[#](/cli/monorepo#assets)

TypeScript compilation automatically distributes compiler output (`.js` and `.d.ts` files) to the specified output directory. It can also be convenient to distribute non-TypeScript files, such as `.graphql` files, images, `.html` files, and other assets. This lets you treat `nest build` (and any initial compilation step) as a lightweight **development build** step, in which you edit non-TypeScript files and compile and test iteratively. Assets must be located in the `src` folder; otherwise, they are not copied.

The value of the `assets` key is an array of elements that specify the files to distribute. The elements can be simple strings with `glob`-like file specs, for example:

```typescript

"assets": ["**/*.graphql"],
"watchAssets": true,
```

For finer control, the elements can be objects with the following keys:

* `"include"`: `glob`-like file specifications for the assets to be distributed
* `"exclude"`: `glob`-like file specifications for assets to **exclude** from the `include` list
* `"outDir"`: the path (relative to the root folder) to distribute the assets to. Defaults to the output directory configured for compiler output.
* `"watchAssets"`: boolean; if `true`, runs in watch mode, watching the specified assets

For example:

```typescript

"assets": [
  { "include": "**/*.graphql", "exclude": "**/omitted.graphql", "watchAssets": true },
]
```

> **Warning** Setting `watchAssets` in a top-level `compilerOptions` property overrides any `watchAssets` settings within the `assets` property.

#### Project properties[#](/cli/monorepo#project-properties)

This element exists only in monorepo mode structures. You generally shouldn't edit these properties, because Nest uses them to locate projects and their configuration options within the monorepo.

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/cli/workspaces.md)

----
url: https://docs.nestjs.com/v11/graphql/extensions
----

* [Extensions](https://docs.nestjs.com/v11/graphql/extensions#extensions)
* [Adding custom metadata](https://docs.nestjs.com/v11/graphql/extensions#adding-custom-metadata)
* [Using custom metadata](https://docs.nestjs.com/v11/graphql/extensions#using-custom-metadata)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/extensions.md "Suggest Edits")

### Extensions

> **Warning** This chapter applies only to the code first approach.

Extensions is an **advanced, low-level feature** that lets you define arbitrary data in the types configuration. Attaching custom metadata to certain fields allows you to create more sophisticated, generic solutions. For example, with extensions, you can define field-level roles required to access particular fields. Such roles can be reflected at runtime to determine whether the caller has sufficient permissions to retrieve a specific field.

#### Adding custom metadata[#](/graphql/extensions#adding-custom-metadata)

To attach custom metadata for a field, use the `@Extensions()` decorator exported from the `@nestjs/graphql` package.

```typescript

@Field()
@Extensions({ role: Role.ADMIN })
password: string;
```

In the example above, we assigned the `role` metadata property the value of `Role.ADMIN`. `Role` is a simple TypeScript enum that groups all the user roles available in our system.

Note, in addition to setting metadata on fields, you can use the `@Extensions()` decorator at the class level and method level (e.g., on the query handler).

#### Using custom metadata[#](/graphql/extensions#using-custom-metadata)

Logic that leverages the custom metadata can be as complex as needed. For example, you can create a simple interceptor that stores/logs events per method invocation, or a [field middleware](/v11/graphql/field-middleware) that matches roles required to retrieve a field with the caller permissions (field-level permissions system).

For illustration purposes, let's define a `checkRoleMiddleware` that compares a user's role (hardcoded here) with a role required to access a target field:

```typescript

export const checkRoleMiddleware: FieldMiddleware = async (
  ctx: MiddlewareContext,
  next: NextFn,
) => {
  const { info } = ctx;
  const { extensions } = info.parentType.getFields()[info.fieldName];

  /**
   * In a real-world application, the "userRole" variable
   * should represent the caller's (user) role (for example, "ctx.user.role").
   */
  const userRole = Role.USER;
  if (userRole === extensions.role) {
    // or just "return null" to ignore
    throw new ForbiddenException(
      `User does not have sufficient permissions to access "${info.fieldName}" field.`,
    );
  }
  return next();
};
```

With this in place, we can register a middleware for the `password` field, as follows:

```typescript

@Field({ middleware: [checkRoleMiddleware] })
@Extensions({ role: Role.ADMIN })
password: string;
```

----
url: https://docs.nestjs.com/v10/techniques/logger
----

* [Logger](https://docs.nestjs.com/v10/techniques/logger#logger)
* [Basic customization](https://docs.nestjs.com/v10/techniques/logger#basic-customization)
* [Custom implementation](https://docs.nestjs.com/v10/techniques/logger#custom-implementation)
* [Extend built-in logger](https://docs.nestjs.com/v10/techniques/logger#extend-built-in-logger)
* [Dependency injection](https://docs.nestjs.com/v10/techniques/logger#dependency-injection)
* [Using the logger for application logging](https://docs.nestjs.com/v10/techniques/logger#using-the-logger-for-application-logging)
* [Logs with timestamps](https://docs.nestjs.com/v10/techniques/logger#logs-with-timestamps)
* [Injecting a custom logger](https://docs.nestjs.com/v10/techniques/logger#injecting-a-custom-logger)
* [Use external logger](https://docs.nestjs.com/v10/techniques/logger#use-external-logger)

```typescript

const app = await NestFactory.create(AppModule, {
  logger: false,
});
await app.listen(process.env.PORT ?? 3000);
```

To enable specific logging levels, set the `logger` property to an array of strings specifying the log levels to display, as follows:

```typescript

const app = await NestFactory.create(AppModule, {
  logger: ['error', 'warn'],
});
await app.listen(process.env.PORT ?? 3000);
```

Values in the array can be any combination of `'log'`, `'fatal'`, `'error'`, `'warn'`, `'debug'`, and `'verbose'`.

> **Hint** To disable color in the default logger's messages, set the `NO_COLOR` environment variable to some non-empty string.

#### Custom implementation[#](/techniques/logger#custom-implementation)

You can provide a custom logger implementation to be used by Nest for system logging by setting the value of the `logger` property to an object that fulfills the `LoggerService` interface. For example, you can tell Nest to use the built-in global JavaScript `console` object (which implements the `LoggerService` interface), as follows:

```typescript

const app = await NestFactory.create(AppModule, {
  logger: console,
});
await app.listen(process.env.PORT ?? 3000);
```

Implementing your own custom logger is straightforward. Simply implement each of the methods of the `LoggerService` interface as shown below.

```typescript

import { LoggerService, Injectable } from '@nestjs/common';

@Injectable()
export class MyLogger implements LoggerService {
  /**
   * Write a 'log' level log.
   */
  log(message: any, ...optionalParams: any[]) {}

  /**
   * Write a 'fatal' level log.
   */
  fatal(message: any, ...optionalParams: any[]) {}

  /**
   * Write an 'error' level log.
   */
  error(message: any, ...optionalParams: any[]) {}

  /**
   * Write a 'warn' level log.
   */
  warn(message: any, ...optionalParams: any[]) {}

  /**
   * Write a 'debug' level log.
   */
  debug?(message: any, ...optionalParams: any[]) {}

  /**
   * Write a 'verbose' level log.
   */
  verbose?(message: any, ...optionalParams: any[]) {}
}
```

You can then supply an instance of `MyLogger` via the `logger` property of the Nest application options object.

```typescript

const app = await NestFactory.create(AppModule, {
  logger: new MyLogger(),
});
await app.listen(process.env.PORT ?? 3000);
```

This technique, while simple, doesn't utilize dependency injection for the `MyLogger` class. This can pose some challenges, particularly for testing, and limit the reusability of `MyLogger`. For a better solution, see the [Dependency Injection](techniques/logger#dependency-injection) section below.

#### Extend built-in logger[#](/techniques/logger#extend-built-in-logger)

Rather than writing a logger from scratch, you may be able to meet your needs by extending the built-in `ConsoleLogger` class and overriding selected behavior of the default implementation.

```typescript

import { ConsoleLogger } from '@nestjs/common';

export class MyLogger extends ConsoleLogger {
  error(message: any, stack?: string, context?: string) {
    // add your tailored logic here
    super.error(...arguments);
  }
}
```

```typescript

import { Module } from '@nestjs/common';
import { MyLogger } from './my-logger.service';

@Module({
  providers: [MyLogger],
  exports: [MyLogger],
})
export class LoggerModule {}
```

With this construct, you are now providing your custom logger for use by any other module. Because your `MyLogger` class is part of a module, it can use dependency injection (for example, to inject a `ConfigService`). There's one more technique needed to provide this custom logger for use by Nest for system logging (e.g., for bootstrapping and error handling).

Because application instantiation (`NestFactory.create()`) happens outside the context of any module, it doesn't participate in the normal Dependency Injection phase of initialization. So we must ensure that at least one application module imports the `LoggerModule` to trigger Nest to instantiate a singleton instance of our `MyLogger` class.

We can then instruct Nest to use the same singleton instance of `MyLogger` with the following construction:

```typescript

const app = await NestFactory.create(AppModule, {
  bufferLogs: true,
});
app.useLogger(app.get(MyLogger));
await app.listen(process.env.PORT ?? 3000);
```

> **Note** In the example above, we set the `bufferLogs` to `true` to make sure all logs will be buffered until a custom logger is attached (`MyLogger` in this case) and the application initialisation process either completes or fails. If the initialisation process fails, Nest will fallback to the original `ConsoleLogger` to print out any reported error messages. Also, you can set the `autoFlushLogs` to `false` (default `true`) to manually flush logs (using the `Logger.flush()` method).

Here we use the `get()` method on the `NestApplication` instance to retrieve the singleton instance of the `MyLogger` object. This technique is essentially a way to "inject" an instance of a logger for use by Nest. The `app.get()` call retrieves the singleton instance of `MyLogger`, and depends on that instance being first injected in another module, as described above.

You can also inject this `MyLogger` provider in your feature classes, thus ensuring consistent logging behavior across both Nest system logging and application logging. See [Using the logger for application logging](techniques/logger#using-the-logger-for-application-logging) and [Injecting a custom logger](techniques/logger#injecting-a-custom-logger) below for more information.

#### Using the logger for application logging[#](/techniques/logger#using-the-logger-for-application-logging)

We can combine several of the techniques above to provide consistent behavior and formatting across both Nest system logging and our own application event/message logging.

A good practice is to instantiate `Logger` class from `@nestjs/common` in each of our services. We can supply our service name as the `context` argument in the `Logger` constructor, like so:

```typescript

import { Logger, Injectable } from '@nestjs/common';

@Injectable()
class MyService {
  private readonly logger = new Logger(MyService.name);

  doSomething() {
    this.logger.log('Doing something...');
  }
}
```

In the default logger implementation, `context` is printed in the square brackets, like `NestFactory` in the example below:

```bash

[Nest] 19096   - 12/08/2019, 7:12:59 AM   [NestFactory] Starting Nest application...
```

If we supply a custom logger via `app.useLogger()`, it will actually be used by Nest internally. That means that our code remains implementation agnostic, while we can easily substitute the default logger for our custom one by calling `app.useLogger()`.

That way if we follow the steps from the previous section and call `app.useLogger(app.get(MyLogger))`, the following calls to `this.logger.log()` from `MyService` would result in calls to method `log` from `MyLogger` instance.

This should be suitable for most cases. But if you need more customization (like adding and calling custom methods), move to the next section.

#### Logs with timestamps[#](/techniques/logger#logs-with-timestamps)

To enable timestamp logging for every logged message, you can use the optional `timestamp: true` setting when creating the logger instance.

```typescript

import { Logger, Injectable } from '@nestjs/common';

@Injectable()
class MyService {
  private readonly logger = new Logger(MyService.name, { timestamp: true });

  doSomething() {
    this.logger.log('Doing something with timestamp here ->');
  }
}
```

This will produce output in the following format:

```bash

[Nest] 19096   - 04/19/2024, 7:12:59 AM   [MyService] Doing something with timestamp here +5ms
```

Note the `+5ms` at the end of the line. For each log statement, the time difference from the previous message is calculated and displayed at the end of the line.

#### Injecting a custom logger[#](/techniques/logger#injecting-a-custom-logger)

To start, extend the built-in logger with code like the following. We supply the `scope` option as configuration metadata for the `ConsoleLogger` class, specifying a [transient](/v10/fundamentals/injection-scopes) scope, to ensure that we'll have a unique instance of the `MyLogger` in each feature module. In this example, we do not extend the individual `ConsoleLogger` methods (like `log()`, `warn()`, etc.), though you may choose to do so.

```typescript

import { Injectable, Scope, ConsoleLogger } from '@nestjs/common';

@Injectable({ scope: Scope.TRANSIENT })
export class MyLogger extends ConsoleLogger {
  customLog() {
    this.log('Please feed the cat!');
  }
}
```

Next, create a `LoggerModule` with a construction like this:

```typescript

import { Module } from '@nestjs/common';
import { MyLogger } from './my-logger.service';

@Module({
  providers: [MyLogger],
  exports: [MyLogger],
})
export class LoggerModule {}
```

Next, import the `LoggerModule` into your feature module. Since we extended default `Logger` we have the convenience of using `setContext` method. So we can start using the context-aware custom logger, like this:

```typescript

import { Injectable } from '@nestjs/common';
import { MyLogger } from './my-logger.service';

@Injectable()
export class CatsService {
  private readonly cats: Cat[] = [];

  constructor(private myLogger: MyLogger) {
    // Due to transient scope, CatsService has its own unique instance of MyLogger,
    // so setting context here will not affect other instances in other services
    this.myLogger.setContext('CatsService');
  }

  findAll(): Cat[] {
    // You can call all the default methods
    this.myLogger.warn('About to return cats!');
    // And your custom methods
    this.myLogger.customLog();
    return this.cats;
  }
}
```

Finally, instruct Nest to use an instance of the custom logger in your `main.ts` file as shown below. Of course in this example, we haven't actually customized the logger behavior (by extending the `Logger` methods like `log()`, `warn()`, etc.), so this step isn't actually needed. But it **would** be needed if you added custom logic to those methods and wanted Nest to use the same implementation.

```typescript

const app = await NestFactory.create(AppModule, {
  bufferLogs: true,
});
app.useLogger(new MyLogger());
await app.listen(process.env.PORT ?? 3000);
```

> **Hint** Alternatively, instead of setting `bufferLogs` to `true`, you could temporarily disable the logger with `logger: false` instruction. Be mindful that if you supply `logger: false` to `NestFactory.create`, nothing will be logged until you call `useLogger`, so you may miss some important initialization errors. If you don't mind that some of your initial messages will be logged with the default logger, you can just omit the `logger: false` option.

#### Use external logger[#](/techniques/logger#use-external-logger)

Production applications often have specific logging requirements, including advanced filtering, formatting and centralized logging. Nest's built-in logger is used for monitoring Nest system behavior, and can also be useful for basic formatted text logging in your feature modules while in development, but production applications often take advantage of dedicated logging modules like [Winston](https://github.com/winstonjs/winston). As with any standard Node.js application, you can take full advantage of such modules in Nest.

----
url: https://docs.nestjs.com/v8/cli/libraries
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Libraries](https://docs.nestjs.com/v8/cli/libraries#libraries)
* [Nest libraries](https://docs.nestjs.com/v8/cli/libraries#nest-libraries)
* [Creating libraries](https://docs.nestjs.com/v8/cli/libraries#creating-libraries)
* [Using libraries](https://docs.nestjs.com/v8/cli/libraries#using-libraries)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/cli/libraries.md "Suggest Edits")

### Libraries

Many applications need to solve the same general problems, or re-use a modular component in several different contexts. Nest has a few ways of addressing this, but each works at a different level to solve the problem in a way that helps meet different architectural and organizational objectives.

Nest [modules](/v8/modules) are useful for providing an execution context that enables sharing components within a single application. Modules can also be packaged with [npm](https://npmjs.com) to create a reusable library that can be installed in different projects. This can be an effective way to distribute configurable, re-usable libraries that can be used by different, loosely connected or unaffiliated organizations (e.g., by distributing/installing 3rd party libraries).

```bash

nest g library my-library
```

When you run the command, the `library` schematic prompts you for a prefix (AKA alias) for the library:

```bash

What prefix would you like to use for the library (default: @app)?
```

```javascript

...
{
    "my-library": {
      "type": "library",
      "root": "libs/my-library",
      "entryFile": "index",
      "sourceRoot": "libs/my-library/src",
      "compilerOptions": {
        "tsConfigPath": "libs/my-library/tsconfig.lib.json"
      }
}
...
```

There are two differences in `nest-cli.json` metadata between libraries and applications:

* the `"type"` property is set to `"library"` instead of `"application"`
* the `"entryFile"` property is set to `"index"` instead of `"main"`

These differences key the build process to handle libraries appropriately. For example, a library exports its functions through the `index.js` file.

As with application-type projects, libraries each have their own `tsconfig.lib.json` file that extends the root (monorepo-wide) `tsconfig.json` file. You can modify this file, if necessary, to provide library-specific compiler options.

You can build the library with the CLI command:

```bash

nest build my-library
```

#### Using libraries[#](/cli/libraries#using-libraries)

With the automatically generated configuration files in place, using libraries is straightforward. How would we import `MyLibraryService` from the `my-library` library into the `my-project` application?

First, note that using library modules is the same as using any other Nest module. What the monorepo does is manage paths in a way that importing libraries and generating builds is now transparent. To use `MyLibraryService`, we need to import its declaring module. We can modify `my-project/src/app.module.ts` as follows to import `MyLibraryModule`.

```typescript

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { MyLibraryModule } from '@app/my-library';

@Module({
  imports: [MyLibraryModule],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}
```

Notice above that we've used a path alias of `@app` in the ES module `import` line, which was the `prefix` we supplied with the `nest g library` command above. Under the covers, Nest handles this through tsconfig path mapping. When adding a library, Nest updates the global (monorepo) `tsconfig.json` file's `"paths"` key like this:

```javascript

"paths": {
    "@app/my-library": [
        "libs/my-library/src"
    ],
    "@app/my-library/*": [
        "libs/my-library/src/*"
    ]
}
```

So, in a nutshell, the combination of the monorepo and library features has made it easy and intuitive to include library modules into applications.

This same mechanism enables building and deploying applications that compose libraries. Once you've imported the `MyLibraryModule`, running `nest build` handles all the module resolution automatically and bundles the app along with any library dependencies, for deployment. The default compiler for a monorepo is **webpack**, so the resulting distribution file is a single file that bundles all of the transpiled JavaScript files into a single file. You can also switch to `tsc` as described [here](https://docs.nestjs.com/cli/monorepo#global-compiler-options).

----
url: https://docs.nestjs.com/v8/recipes/terminus
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Healthchecks (Terminus)](https://docs.nestjs.com/v8/recipes/terminus#healthchecks-terminus)
* [Getting started](https://docs.nestjs.com/v8/recipes/terminus#getting-started)
* [Setting up a Healthcheck](https://docs.nestjs.com/v8/recipes/terminus#setting-up-a-healthcheck)
* [HTTP Healthcheck](https://docs.nestjs.com/v8/recipes/terminus#http-healthcheck)
* [TypeOrm health indicator](https://docs.nestjs.com/v8/recipes/terminus#typeorm-health-indicator)
* [Custom health indicator](https://docs.nestjs.com/v8/recipes/terminus#custom-health-indicator)
* [Examples](https://docs.nestjs.com/v8/recipes/terminus#examples)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/recipes/terminus.md "Suggest Edits")

### Healthchecks (Terminus)

Terminus integration provides you with **readiness/liveness** health checks. Healthchecks are crucial when it comes to complex backend setups. In a nutshell, a health check in the realm of web development usually consists of a special address, for example, `https://my-website.com/health/readiness`. A service or a component of your infrastructure (e.g., Kubernetes) checks this address continuously. Depending on the HTTP status code returned from a `GET` request to this address the service will take action when it receives an "unhealthy" response. Since the definition of "healthy" or "unhealthy" varies with the type of service you provide, the **Terminus** integration supports you with a set of **health indicators**.

As an example, if your web server uses MongoDB to store its data, it would be vital information whether MongoDB is still up and running. In that case, you can make use of the `MongooseHealthIndicator`. If configured correctly - more on that later - your health check address will return a healthy or unhealthy HTTP status code, depending on whether MongoDB is running.

#### Getting started[#](/recipes/terminus#getting-started)

To get started with `@nestjs/terminus` we need to install the required dependency.

```bash

$ npm install --save @nestjs/terminus
```

#### Setting up a Healthcheck[#](/recipes/terminus#setting-up-a-healthcheck)

A health check represents a summary of **health indicators**. A health indicator executes a check of a service, whether it is in a healthy or unhealthy state. A health check is positive if all the assigned health indicators are up and running. Because a lot of applications will need similar health indicators, [`@nestjs/terminus`](https://github.com/nestjs/terminus) provides a set of predefined indicators, such as:

To get started with our first health check, let's create the `HealthModule` and import the `TerminusModule` into it in its imports array.

> **Hint** To create the module using the [Nest CLI](/v8/recipes/terminus/cli/overview), simply execute the `$ nest g module health` command.

health.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { TerminusModule } from '@nestjs/terminus';

@Module({
  imports: [TerminusModule]
})
export class HealthModule {}
```

Our healthcheck(s) can be executed using a [controller](/v8/controllers), which can be easily set up using the [Nest CLI](/v8/recipes/terminus/cli/overview).

```bash

$ nest g controller health
```

> **Info** It is highly recommended to enable shutdown hooks in your application. Terminus integration makes use of this lifecycle event if enabled. Read more about shutdown hooks [here](fundamentals/lifecycle-events#application-shutdown).

#### HTTP Healthcheck[#](/recipes/terminus#http-healthcheck)

Once we have installed `@nestjs/terminus`, imported our `TerminusModule` and created a new controller, we are ready to create a health check.

The `HTTPHealthIndicator` requires the `@nestjs/axios` package so make sure to have it installed:

```bash

$ npm i --save @nestjs/axios
```

Now we can setup our `HealthController`:

health.controller.ts

JS TS

```typescript

import { Controller, Get } from '@nestjs/common';
import { HealthCheckService, HttpHealthIndicator, HealthCheck } from '@nestjs/terminus';

@Controller('health')
export class HealthController {
  constructor(
    private health: HealthCheckService,
    private http: HttpHealthIndicator,
  ) {}

  @Get()
  @HealthCheck()
  check() {
    return this.health.check([
      () => this.http.pingCheck('nestjs-docs', 'https://docs.nestjs.com'),
    ]);
  }
}
```

```typescript

import { Controller, Get } from '@nestjs/common';
import { HealthCheckService, HttpHealthIndicator, HealthCheck } from '@nestjs/terminus';

@Controller('health')
@Dependencies(HealthCheckService, HttpHealthIndicator)
export class HealthController {
  constructor(
    private health,
    private http,
  ) { }

  @Get()
  @HealthCheck()
  healthCheck() {
    return this.health.check([
      async () => this.http.pingCheck('nestjs-docs', 'https://docs.nestjs.com'),
    ])
  }
}
```

health.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { TerminusModule } from '@nestjs/terminus';
import { HttpModule } from '@nestjs/axios';
import { HealthController } from './health.controller';

@Module({
  imports: [TerminusModule, HttpModule],
  controllers: [HealthController],
})
export class HealthModule {}
```

```typescript

import { Module } from '@nestjs/common';
import { TerminusModule } from '@nestjs/terminus';
import { HttpModule } from '@nestjs/axios';
import { HealthController } from './health.controller';

@Module({
  imports: [TerminusModule, HttpModule],
  controllers: [HealthController],
})
export class HealthModule {}
```

Our health check will now send a *GET*-request to the `https://docs.nestjs.com` address. If we get a healthy response from that address, our route at `http://localhost:3000/health` will return the following object with a 200 status code.

```json

{
  "status": "ok",
  "info": {
    "nestjs-docs": {
      "status": "up"
    }
  },
  "error": {},
  "details": {
    "nestjs-docs": {
      "status": "up"
    }
  }
}
```

The interface of this response object can be accessed from the `@nestjs/terminus` package with the `HealthCheckResult` interface.

| `status`  | If any health indicator failed the status will be `'error'`. If the NestJS app is shutting down but still accepting HTTP requests, the health check will have the `'shutting_down'` status. | `'error' \| 'ok' \| 'shutting_down'` |
| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------ |
| `info`    | Object containing information of each health indicator which is of status `'up'`, or in other words "healthy".                                                                              | `object`                             |
| `error`   | Object containing information of each health indicator which is of status `'down'`, or in other words "unhealthy".                                                                          | `object`                             |
| `details` | Object containing all information of each health indicator                                                                                                                                  | `object`                             |

#### TypeOrm health indicator[#](/recipes/terminus#typeorm-health-indicator)

Terminus offers the capability to add database checks to your health check. In order to get started with this health indicator, you should check out the [Database chapter](/v8/techniques/sql) and make sure your database connection within your application is established.

> **Hint** Behind the scenes the `TypeOrmHealthIndicator` simply executes a `SELECT 1`-SQL command which is often used to verify whether the database still alive. In case you are using an Oracle database it uses `SELECT 1 FROM DUAL`.

health.controller.ts

JS TS

```typescript

@Controller('health')
export class HealthController {
  constructor(
    private health: HealthCheckService,
    private db: TypeOrmHealthIndicator,
  ) {}

  @Get()
  @HealthCheck()
  check() {
    return this.health.check([
      () => this.db.pingCheck('database'),
    ]);
  }
}
```

```typescript

@Controller('health')
@Dependencies(HealthCheckService, TypeOrmHealthIndicator)
export class HealthController {
  constructor(
    private health,
    private db,
  ) { }

  @Get()
  @HealthCheck()
  healthCheck() {
    return this.health.check([
      async () => this.db.pingCheck('database'),
    ])
  }
}
```

If your database is reachable, you should now see the following JSON-result when requesting `http://localhost:3000` with a `GET` request:

```json

{
  "status": "ok",
  "info": {
    "database": {
      "status": "up"
    }
  },
  "error": {},
  "details": {
    "database": {
      "status": "up"
    }
  }
}
```

In case your app uses [multiple databases](techniques/database#multiple-databases), you need to inject each connection into your `HealthController`. Then, you can simply pass the connection reference to the `TypeOrmHealthIndicator`.

health.controller.ts

JS TS

```typescript

@Controller('health')
export class HealthController {
  constructor(
    private health: HealthCheckService,
    private db: TypeOrmHealthIndicator,
    @InjectConnection('albumsConnection')
    private albumsConnection: Connection,
    @InjectConnection()
    private defaultConnection: Connection,
  ) {}

  @Get()
  @HealthCheck()
  check() {
    return this.health.check([
      () => this.db.pingCheck('albums-database', { connection: this.albumsConnection }),
      () => this.db.pingCheck('database', { connection: this.defaultConnection }),
    ]);
  }
}
```

#### Custom health indicator[#](/recipes/terminus#custom-health-indicator)

In some cases, the predefined health indicators provided by `@nestjs/terminus` do not cover all of your health check requirements. In that case, you can set up a custom health indicator according to your needs.

Let's get started by creating a service that will represent our custom indicator. To get a basic understanding of how an indicator is structured, we will create an example `DogHealthIndicator`. This service should have the state `'up'` if every `Dog` object has the type `'goodboy'`. If that condition is not satisfied then it should throw an error.

dog.health.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { HealthIndicator, HealthIndicatorResult, HealthCheckError } from '@nestjs/terminus';

export interface Dog {
  name: string;
  type: string;
}

@Injectable()
export class DogHealthIndicator extends HealthIndicator {
  private dogs: Dog[] = [
    { name: 'Fido', type: 'goodboy' },
    { name: 'Rex', type: 'badboy' },
  ];

  async isHealthy(key: string): Promise<HealthIndicatorResult> {
    const badboys = this.dogs.filter(dog => dog.type === 'badboy');
    const isHealthy = badboys.length === 0;
    const result = this.getStatus(key, isHealthy, { badboys: badboys.length });

    if (isHealthy) {
      return result;
    }
    throw new HealthCheckError('Dogcheck failed', result);
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';
import { HealthCheckError } from '@godaddy/terminus';

@Injectable()
export class DogHealthIndicator extends HealthIndicator {
  dogs = [
    { name: 'Fido', type: 'goodboy' },
    { name: 'Rex', type: 'badboy' },
  ];

  async isHealthy(key) {
    const badboys = this.dogs.filter(dog => dog.type === 'badboy');
    const isHealthy = badboys.length === 0;
    const result = this.getStatus(key, isHealthy, { badboys: badboys.length });

    if (isHealthy) {
      return result;
    }
    throw new HealthCheckError('Dogcheck failed', result);
  }
}
```

The next thing we need to do is register the health indicator as a provider.

health.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { TerminusModule } from '@nestjs/terminus';
import { DogHealthIndicator } from './dog.health';

@Module({
  controllers: [HealthController],
  imports: [TerminusModule],
  providers: [DogHealthIndicator]
})
export class HealthModule { }
```

> **Hint** In a real-world application the `DogHealthIndicator` should be provided in a separate module, for example, `DogModule`, which then will be imported by the `HealthModule`.

The last required step is to add the now available health indicator in the required health check endpoint. For that, we go back to our `HealthController` and add it to our `check` function.

health.controller.ts

JS TS

```typescript

import { HealthCheckService } from '@nestjs/terminus';
import { Injectable } from '@nestjs/common';
import { DogHealthIndicator } from './dog.health';

@Injectable()
export class HealthController {
  constructor(
    private health: HealthCheckService,
    private dogHealthIndicator: DogHealthIndicator
  ) {}

  @Get()
  @HealthCheck()
  healthCheck() {
    return this.health.check([
      async () => this.dogHealthIndicator.isHealthy('dog'),
    ])
  }
}
```

```typescript

import { HealthCheckService } from '@nestjs/terminus';
import { Injectable } from '@nestjs/common';
import { DogHealthIndicator } from './dog.health';

@Injectable()
@Dependencies(HealthCheckService, DogHealthIndicator)
export class HealthController {
  constructor(
    private health,
    private dogHealthIndicator
  ) {}

  @Get()
  @HealthCheck()
  healthCheck() {
    return this.health.check([
      async () => this.dogHealthIndicator.isHealthy('dog'),
    ])
  }
}
```

#### Examples[#](/recipes/terminus#examples)

Some working examples are available [here](https://github.com/nestjs/terminus/tree/master/sample).

----
url: https://docs.nestjs.com/v5/microservices/guards
----

### Guards

There is no difference between microservices **guards** and the [regular guards](/v5/guards). The only thing you should be aware of is that instead of throwing `HttpException`, you should use the `RpcException`.

> **Hint** The `RpcException` class is exposed from `@nestjs/microservices` package.

#### Binding guards

Here is an example that makes use of a **method-scoped** guard (class-scoped works either):

TypeScript

```typescript

@UseGuards(AuthGuard)
@MessagePattern({ cmd: 'sum' })
sum(data: number[]): number {
  return (data || []).reduce((a, b) => a + b);
}
```

----
url: https://docs.nestjs.com/v5/controllers
----

### Controllers

Controllers are responsible for handling incoming **requests** and returning **responses** to the client.

A controller's purpose is to receive specific requests for the application. The **routing** mechanism controls which controller receives which requests. Frequently, each controller has more than one route, and different routes can perform different actions.

In order to create a basic controller, we use classes and **decorators**. Decorators associate classes with required metadata and enable Nest to create a routing map (tie requests to the corresponding controllers).

#### Routing

In the following example we'll use the `@Controller()` decorator which is **required** to define a basic controller. We'll specify an optional prefix of `cats`. Using a prefix in a Controller decorator allows us to avoid repeating ourselves when routes could potentially share a common prefix.

cats.controller.ts

JS TS

TypeScript

```typescript

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

@Controller('cats')
export class CatsController {
  @Get()
  findAll() {
    return 'This action returns all cats';
  }
}
```

> **Hint** To create a controller using CLI, simply execute `$ nest g controller cats` command.

The `@Get()` decorator before the `findAll()` method tells Nest to create an endpoint for this particular route path and map every corresponding request to this handler. Since we've declared a prefix for every route ( `cats`), Nest will map every `/cats`**GET** request to this method.

When a GET request is made to this endpoint, Nest will now return a 200 status code and the associated response, which in this case is just a string. Why does that happen? Generally, we distinguish **two different approaches&#x20;**&#x74;o manipulate responses:

|                        |                                                                                                                                                                                                                                                                                                                                                                                                                  |
| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Standard (recommended) | When we return a JavaScript object or array, it'll be **automatically** serialized to JSON. When we return a string however, Nest will send just a string without attempting to serialize it. Furthermore, the response's **status code** is always 200 by default, except for POST requests which use **201**. We can easily change this behaviour by adding the `@HttpCode(...)` decorator at a handler-level. |
| Library-specific       | We can use the library specific [response object](http://expressjs.com/en/api.html#res), which we can inject using the `@Res()` decorator in the function signature (e.g. `findAll(@Res() response)`).                                                                                                                                                                                                           |

> **Warning** It's forbidden to use both approaches at the same time. Nest detects whether the handler is using either `@Res()` or `@Next()`. If both approaches are used in the same time - the Standard approach is automatically disabled for this single route and will no longer work as expected.

#### Request object

A lot of endpoints need access to the client **request** details. In fact, Nest is using a library-specific (express by default) [request object](http://expressjs.com/en/api.html#req). As a result, we can force Nest to inject the request object into the handler using the `@Req()` decorator.

cats.controller.ts

JS TS

TypeScript

```typescript

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

@Controller('cats')
export class CatsController {
  @Get()
  findAll(@Req() request) {
    return 'This action returns all cats';
  }
}
```

TypeScript

```typescript

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

@Controller('cats')
export class CatsController {
  @Get()
  @Bind(Req())
  findAll(request) {
    return 'This action returns all cats';
  }
}
```

The request object represents the HTTP request and has properties for the request query string, parameters, HTTP headers, and body (read more [here](http://expressjs.com/en/api.html#req)). In most cases, it's not necessary to grab these properties manually. We can use **dedicated decorators** instead, such as `@Body()` or `@Query()`, which are available out of the box. Below is a comparison of the provided decorators and the plain express objects they represent.

|                            |                                      |
| -------------------------- | ------------------------------------ |
| `@Request()`               | `req`                                |
| `@Response()`              | `res`                                |
| `@Next()`                  | `next`                               |
| `@Session()`               | `req.session`                        |
| `@Param(param?: string)`   | `req.params` / `req.params[param]`   |
| `@Body(param?: string)`    | `req.body` / `req.body[param]`       |
| `@Query(param?: string)`   | `req.query` / `req.query[param]`     |
| `@Headers(param?: string)` | `req.headers` / `req.headers[param]` |

> **Hint** To learn how to create your own custom decorators, visit [this](/v5/custom-decorators) chapter.

#### Resources

We defined an endpoint to fetch the cats resource (**GET** route). It'll also be great to provide a way of creating new records as well. For this, let's create the **POST** handler:

cats.controller.ts

JS TS

TypeScript

```typescript

import { Controller, Get, Post } from '@nestjs/common';

@Controller('cats')
export class CatsController {
  @Post()
  create() {
    return 'This action adds a new cat';
  }

  @Get()
  findAll() {
    return 'This action returns all cats';
  }
}
```

It's that simple. Nest provides the rest of those endpoint decorators in the same fashion - `@Put()`, `@Delete()`, `@Patch()`, `@Options()`, `@Head()`, and `@All()`. All of them represent respective HTTP request methods.

#### Route wildcards

Pattern based routes are supported as well. For instance, the asterisk is used as a wildcard, and will match any combination of characters.

TypeScript

```typescript

@Get('ab*cd')
findAll() {
  return 'This route uses a wildcard';
}
```

Above route path will match `abcd`, `ab_cd`, `abecd`, and so on. The characters `?`, `+`, `*`, and `()` are subsets of their regular expression counterparts. The hyphen ( `-`) and the dot (`.`) are interpreted literally by string-based paths.

#### Status code

As mentioned, the response **status code** is always **200** by default, except for POST requests which are **201**. We can easily change this behaviour by adding the `@HttpCode(...)` decorator at a handler-level.

TypeScript

```typescript

@Post()
@HttpCode(204)
create() {
  return 'This action adds a new cat';
}
```

Often, your status code isn't static but depends on various factors. In that case, you can use a library-specific **response** (inject using `@Res()`) object (or, in case of an error, throw an exception).

#### Headers

To specify a custom response header, you can either use a `@Header()` decorator or a library-specific response object.

TypeScript

```typescript

@Post()
@Header('Cache-Control', 'none')
create() {
  return 'This action adds a new cat';
}
```

#### Route parameters

Routes with static paths can't help when you need to accept **dynamic data** as part of the URL. In order to define routes with parameters, we can directly particularise the route parameters in the path of the route.

TypeScript

```typescript

@Get(':id')
findOne(@Param() params) {
  console.log(params.id);
  return `This action returns a #${params.id} cat`;
}
```

In order to pick up a particular parameter, simply pass its name in parenthesis.

TypeScript

```typescript

@Get(':id')
findOne(@Param('id') id) {
  return `This action returns a #${id} cat`;
}
```

#### Async/await

We love modern JavaScript and we know that data extraction is mostly **asynchronous**. That's why Nest supports and works well with `async` functions.

> **Hint** Learn more about `async / await` [here](https://kamilmysliwiec.com/typescript-2-1-introduction-async-await)!

Every async function has to return a `Promise`. It means that you can return a deferred value that Nest will be able to resolve by itself. Let's see an example of this below:

cats.controller.ts

JS TS

TypeScript

```typescript

@Get()
async findAll(): Promise<any[]> {
  return [];
}
```

TypeScript

```typescript

@Get()
async findAll() {
  return [];
}
```

The above code is fully valid. Furthermore, Nest route handlers are even more powerful by being able to return Rx [observable streams](http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html). Nest will automatically subscribe to the source underneath and take the last emitted value (once the stream is completed).

cats.controller.ts

JS TS

TypeScript

```typescript

@Get()
findAll(): Observable<any[]> {
  return of([]);
}
```

TypeScript

```typescript

@Get()
findAll() {
  return of([]);
}
```

Either of the above approaches work and you can use whatever fits your requirements.

#### Request payloads

Our previous example of the POST route handler didn't accept any client params. Let's fix this by adding the `@Body()` argument here.

But first (if you use TypeScript), we need to determine the **DTO** (Data Transfer Object) schema. A DTO is an object that defines how the data will be sent over the network. We could determine the DTO schema by using **TypeScript** interfaces, or by simple classes. Surprisingly, we recommend using **classes** here. Why? Classes are part of the JavaScript ES6 standard, and therefore they represent plain functions. On the other hand, since TypeScript interfaces are removed during the transpilation, Nest can't refer to them. This is important because features such as **Pipes** enable additional possibilities when they have access to the metatype of the variable.

Let's create the `CreateCatDto` class:

create-cat.dto.ts

JS TS

TypeScript

```typescript

export class CreateCatDto {
  readonly name: string;
  readonly age: number;
  readonly breed: string;
}
```

It has only three basic properties. All of them are marked as `readonly` because we should always try to make our functions as [pure](https://medium.com/javascript-scene/master-the-javascript-interview-what-is-a-pure-function-d1c076bec976) as possible.

Thereafter we can use the newly created schema inside the `CatsController`:

cats.controller.ts

JS TS

TypeScript

```typescript

@Post()
async create(@Body() createCatDto: CreateCatDto) {
  return 'This action adds a new cat';
}
```

TypeScript

```typescript

@Post()
@Bind(Body())
async create(createCatDto) {
  return 'This action adds a new cat';
}
```

#### Full resource sample

Here is a example that makes use of a few available decorators to create a basic controller. The following controller exposes a couple of methods to access and manipulate internal data.

cats.controller.ts

JS TS

TypeScript

```typescript

import { Controller, Get, Post, Body, Put, Param, Delete } from '@nestjs/common';

@Controller('cats')
export class CatsController {
  @Post()
  create(@Body() createCatDto) {
    return 'This action adds a new cat';
  }

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

  @Get(':id')
  findOne(@Param('id') id) {
    return `This action returns a #${id} cat`;
  }

  @Put(':id')
  update(@Param('id') id, @Body() updateCatDto) {
    return `This action updates a #${id} cat`;
  }

  @Delete(':id')
  remove(@Param('id') id) {
    return `This action removes a #${id} cat`;
  }
}
```

TypeScript

```typescript

import { Controller, Get, Post, Body, Put, Param, Delete } from '@nestjs/common';

@Controller('cats')
export class CatsController {
  @Post()
  create(@Body() createCatDto) {
    return 'This action adds a new cat';
  }

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

  @Get(':id')
  findOne(@Param('id') id) {
    return `This action returns a #${id} cat`;
  }

  @Put(':id')
  update(@Param('id') id, @Body() updateCatDto) {
    return `This action updates a #${id} cat`;
  }

  @Delete(':id')
  remove(@Param('id') id) {
    return `This action removes a #${id} cat`;
  }
}
```

#### Handling errors

There's a separate chapter about handling errors (i.e. working with exceptions) [here](/v5/exception-filters).

#### Getting up and running

With the above controller fully prepared, Nest still doesn't know that `CatsController` exists and as a result won't create an instance of this class.

Controllers always belong to the module, which is why we hold the `controllers` array within the `@Module()` decorator. Since we don't have any other modules except the root `ApplicationModule`, we'll use that to introduce the `CatsController`:

app.module.ts

JS TS

TypeScript

```typescript

import { Module } from '@nestjs/common';
import { CatsController } from './cats/cats.controller';

@Module({
  controllers: [CatsController],
})
export class ApplicationModule {}
```

We attached the metadata to the module class, and Nest can now easily reflect which controllers have to be mounted.

#### Library-specific approach

So far we've discussed the Nest standard way of manipulating responses. The second way of manipulating the response is to use a library-specific [response object](http://expressjs.com/en/api.html#res). In order to inject a particular response object, we need to use the `@Res()` decorator. To show the differences, let's rewrite the `CatsController` to the following:

JS TS

TypeScript

```typescript

import { Controller, Get, Post, Res, HttpStatus } from '@nestjs/common';

@Controller('cats')
export class CatsController {
  @Post()
  create(@Res() res) {
    res.status(HttpStatus.CREATED).send();
  }

  @Get()
  findAll(@Res() res) {
     res.status(HttpStatus.OK).json([]);
  }
}
```

TypeScript

```typescript

import { Controller, Get, Post, Bind, Res, Body, HttpStatus } from '@nestjs/common';

@Controller('cats')
export class CatsController {
  @Post()
  @Bind(Res(), Body())
  create(res, createCatDto) {
    res.status(HttpStatus.CREATED).send();
  }

  @Get()
  @Bind(Res())
  findAll(res) {
     res.status(HttpStatus.OK).json([]);
  }
}
```

Though this approach works, it's much less clear in general. The first approach should always be preferred, but to make Nest **backwards compatible** with previous versions, the above approach is still available. One other thing to note is the **response object** in this approach allows for more flexibility - by allowing us to have full control of the response object (headers manipulation and so on).

* Controllers
* Routing
* Request object
* Resources
* Route wildcards
* Status code
* Headers
* Route parameters
* Async/await
* Request payloads
* Full resource sample
* Handling errors
* Getting up and running
* Library-specific approach

----
url: https://docs.nestjs.com/v11/recipes/hot-reload
----

* [Hot Reload](https://docs.nestjs.com/v11/recipes/hot-reload#hot-reload)
* [With CLI](https://docs.nestjs.com/v11/recipes/hot-reload#with-cli)
* [Installation](https://docs.nestjs.com/v11/recipes/hot-reload#installation)
* [Configuration](https://docs.nestjs.com/v11/recipes/hot-reload#configuration)
* [Hot-Module Replacement](https://docs.nestjs.com/v11/recipes/hot-reload#hot-module-replacement)
* [Without CLI](https://docs.nestjs.com/v11/recipes/hot-reload#without-cli)
* [Installation](https://docs.nestjs.com/v11/recipes/hot-reload#installation-1)
* [Configuration](https://docs.nestjs.com/v11/recipes/hot-reload#configuration-1)
* [Hot-Module Replacement](https://docs.nestjs.com/v11/recipes/hot-reload#hot-module-replacement-1)
* [Example](https://docs.nestjs.com/v11/recipes/hot-reload#example)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/recipes/hot-reload.md "Suggest Edits")

### Hot Reload

The highest impact on your application's bootstrapping process is **TypeScript compilation**. Fortunately, with [webpack](https://github.com/webpack/webpack) HMR (Hot-Module Replacement), we don't need to recompile the entire project each time a change occurs. This significantly decreases the amount of time necessary to instantiate your application, and makes iterative development a lot easier.

> **Warning** Note that `webpack` won't automatically copy your assets (e.g. `graphql` files) to the `dist` folder. Similarly, `webpack` is not compatible with glob static paths (e.g., the `entities` property in `TypeOrmModule`).

### With CLI

If you are using the [Nest CLI](https://docs.nestjs.com/cli/overview), the configuration process is pretty straightforward. The CLI wraps `webpack`, which allows use of the `HotModuleReplacementPlugin`.

#### Installation[#](/recipes/hot-reload#installation)

First install the required packages:

```bash

$ npm i --save-dev webpack-node-externals run-script-webpack-plugin webpack
```

> **Hint** If you use **Yarn Berry** (not classic Yarn), install the `webpack-pnp-externals` package instead of the `webpack-node-externals`.

#### Configuration[#](/recipes/hot-reload#configuration)

Once the installation is complete, create a `webpack-hmr.config.js` file in the root directory of your application.

```typescript

const nodeExternals = require('webpack-node-externals');
const { RunScriptWebpackPlugin } = require('run-script-webpack-plugin');

module.exports = function (options, webpack) {
  return {
    ...options,
    entry: ['webpack/hot/poll?100', options.entry],
    externals: [
      nodeExternals({
        allowlist: ['webpack/hot/poll?100'],
      }),
    ],
    plugins: [
      ...options.plugins,
      new webpack.HotModuleReplacementPlugin(),
      new webpack.WatchIgnorePlugin({
        paths: [/\.js$/, /\.d\.ts$/],
      }),
      new RunScriptWebpackPlugin({ name: options.output.filename, autoRestart: false }),
    ],
  };
};
```

> **Hint** With **Yarn Berry** (not classic Yarn), instead of using the `nodeExternals` in the `externals` configuration property, use the `WebpackPnpExternals` from `webpack-pnp-externals` package: `WebpackPnpExternals({ exclude: ['webpack/hot/poll?100'] })`.

This function takes the original object containing the default webpack configuration as a first argument, and the reference to the underlying `webpack` package used by the Nest CLI as the second one. Also, it returns a modified webpack configuration with the `HotModuleReplacementPlugin`, `WatchIgnorePlugin`, and `RunScriptWebpackPlugin` plugins.

#### Hot-Module Replacement[#](/recipes/hot-reload#hot-module-replacement)

To enable **HMR**, open the application entry file (`main.ts`) and add the following webpack-related instructions:

```typescript

declare const module: any;

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  await app.listen(process.env.PORT ?? 3000);

  if (module.hot) {
    module.hot.accept();
    module.hot.dispose(() => app.close());
  }
}
bootstrap();
```

To simplify the execution process, add a script to your `package.json` file.

```json

"start:dev": "nest build --webpack --webpackPath webpack-hmr.config.js --watch"
```

Now simply open your command line and run the following command:

```bash

$ npm run start:dev
```

### Without CLI

If you are not using the [Nest CLI](https://docs.nestjs.com/cli/overview), the configuration will be slightly more complex (will require more manual steps).

#### Installation[#](/recipes/hot-reload#installation-1)

First install the required packages:

```bash

$ npm i --save-dev webpack webpack-cli webpack-node-externals ts-loader run-script-webpack-plugin
```

> **Hint** If you use **Yarn Berry** (not classic Yarn), install the `webpack-pnp-externals` package instead of the `webpack-node-externals`.

#### Configuration[#](/recipes/hot-reload#configuration-1)

Once the installation is complete, create a `webpack.config.js` file in the root directory of your application.

```typescript

const webpack = require('webpack');
const path = require('path');
const nodeExternals = require('webpack-node-externals');
const { RunScriptWebpackPlugin } = require('run-script-webpack-plugin');

module.exports = {
  entry: ['webpack/hot/poll?100', './src/main.ts'],
  target: 'node',
  externals: [
    nodeExternals({
      allowlist: ['webpack/hot/poll?100'],
    }),
  ],
  module: {
    rules: [
      {
        test: /.tsx?$/,
        use: 'ts-loader',
        exclude: /node_modules/,
      },
    ],
  },
  mode: 'development',
  resolve: {
    extensions: ['.tsx', '.ts', '.js'],
  },
  plugins: [new webpack.HotModuleReplacementPlugin(), new RunScriptWebpackPlugin({ name: 'server.js', autoRestart: false })],
  output: {
    path: path.join(__dirname, 'dist'),
    filename: 'server.js',
  },
};
```

> **Hint** With **Yarn Berry** (not classic Yarn), instead of using the `nodeExternals` in the `externals` configuration property, use the `WebpackPnpExternals` from `webpack-pnp-externals` package: `WebpackPnpExternals({ exclude: ['webpack/hot/poll?100'] })`.

This configuration tells webpack a few essential things about your application: location of the entry file, which directory should be used to hold **compiled** files, and what kind of loader we want to use to compile source files. Generally, you should be able to use this file as-is, even if you don't fully understand all of the options.

#### Hot-Module Replacement[#](/recipes/hot-reload#hot-module-replacement-1)

To enable **HMR**, open the application entry file (`main.ts`) and add the following webpack-related instructions:

```typescript

declare const module: any;

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  await app.listen(process.env.PORT ?? 3000);

  if (module.hot) {
    module.hot.accept();
    module.hot.dispose(() => app.close());
  }
}
bootstrap();
```

To simplify the execution process, add a script to your `package.json` file.

```json

"start:dev": "webpack --config webpack.config.js --watch"
```

Now simply open your command line and run the following command:

```bash

$ npm run start:dev
```

#### Example[#](/recipes/hot-reload#example)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/08-webpack).

----
url: https://docs.nestjs.com/websockets/exception-filters
----

[Skip to content](#content)

On this page

* [Exception filters](https://docs.nestjs.com/websockets/exception-filters#exception-filters)
* [Filters](https://docs.nestjs.com/websockets/exception-filters#filters)
* [Inheritance](https://docs.nestjs.com/websockets/exception-filters#inheritance)

### Exception filters

The WebSockets exceptions layer works like the HTTP [exception filter](/exception-filters) layer, with one difference: instead of throwing `HttpException`, throw `WsException`.

```typescript

throw new WsException('Invalid credentials.');
```

> **Hint** The `WsException` class is imported from the `@nestjs/websockets` package.

When a handler throws the exception above, Nest catches it and emits an `exception` message to the client with the following structure:

```typescript

{
  status: 'error',
  message: 'Invalid credentials.',
  cause: {
    pattern: 'events', // pattern of the message that caused the exception
    data: { name: 'Nest' }, // payload of that message
  },
}
```

The `cause` property lets the client associate the error with the message that triggered it. If you pass an object (rather than a string) to the `WsException` constructor, Nest emits that object as is. Any exception that isn't a `WsException` produces the same structure, with `'Internal server error'` as the message. With the `ws` adapter, which has no named events, the client receives a JSON string of the form `{ "event": "exception", "data": ... }` instead.

#### Filters[#](/websockets/exception-filters#filters)

WebSocket exception filters behave the same way as HTTP exception filters. The following example uses a manually instantiated method-scoped filter. As with HTTP-based applications, you can also use gateway-scoped filters (i.e., decorate the gateway class with `@UseFilters()`).

```typescript

@UseFilters(new WsExceptionFilter())
@SubscribeMessage('events')
onEvent(client, data: any): WsResponse<any> {
  const event = 'events';
  return { event, data };
}
```

> **Warning** Global exception filters (registered with `app.useGlobalFilters()` or the `APP_FILTER` token) don't apply to gateways. Bind WebSocket exception filters at the gateway or method level with `@UseFilters()`.

#### Inheritance[#](/websockets/exception-filters#inheritance)

Typically, you'll create fully customized exception filters tailored to your application requirements. However, sometimes you may want to extend the **core exception filter** and override its behavior based on certain factors.

To delegate exception processing to the base filter, extend `BaseWsExceptionFilter` and call the inherited `catch()` method.

JS TS

```typescript

import { Catch, ArgumentsHost } from '@nestjs/common';
import { BaseWsExceptionFilter } from '@nestjs/websockets';

@Catch()
export class AllExceptionsFilter extends BaseWsExceptionFilter {
  catch(exception: unknown, host: ArgumentsHost) {
    super.catch(exception, host);
  }
}
```

```typescript

import { Catch } from '@nestjs/common';
import { BaseWsExceptionFilter } from '@nestjs/websockets';

@Catch()
export class AllExceptionsFilter extends BaseWsExceptionFilter {
  catch(exception, host) {
    super.catch(exception, host);
  }
}
```

The implementation above is only a shell that demonstrates the approach. A real extended exception filter would add your own **business logic** (e.g., handling various conditions).

The `BaseWsExceptionFilter` constructor accepts an options object. Set `includeCause` to `false` to omit the `cause` property from error messages, or pass a `causeFactory(pattern, data)` function to control its shape.

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/websockets/exception-filters.md)

----
url: https://docs.nestjs.com/v10/migration-guide
----

* [Migration guide](https://docs.nestjs.com/v10/migration-guide#migration-guide)
* [Upgrading packages](https://docs.nestjs.com/v10/migration-guide#upgrading-packages)
* [Cache module](https://docs.nestjs.com/v10/migration-guide#cache-module)
* [Log levels](https://docs.nestjs.com/v10/migration-guide#log-levels)
* [Deprecations](https://docs.nestjs.com/v10/migration-guide#deprecations)
* [CLI Plugins and TypeScript >= 4.8](https://docs.nestjs.com/v10/migration-guide#cli-plugins-and-typescript--48)
* [Dropping support for Node.js v12](https://docs.nestjs.com/v10/migration-guide#dropping-support-for-nodejs-v12)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/migration.md "Suggest Edits")

### Migration guide

This article provides a set of guidelines for migrating from Nest version 9 to version 10. To learn more about the new features we've added in v10, check out this [article](https://trilon.io/blog/nestjs-10-is-now-available). There were some very minor breaking changes that shouldn't affect most users - you can find the full list of them [here](https://github.com/nestjs/nest/releases/tag/v10.0.0).

#### Upgrading packages[#](/migration-guide#upgrading-packages)

While you can upgrade your packages manually, we recommend using [ncu (npm check updates)](https://npmjs.com/package/npm-check-updates).

#### Cache module[#](/migration-guide#cache-module)

The `CacheModule` has been removed from the `@nestjs/common` package and is now available as a standalone package - `@nestjs/cache-manager`. This change was made to avoid unnecessary dependencies in the `@nestjs/common` package. You can learn more about the `@nestjs/cache-manager` package [here](https://docs.nestjs.com/techniques/caching).

#### Log levels[#](/migration-guide#log-levels)

Swapped the values for the `verbose` and `debug` log levels (see [](https://github.com/nestjs/nest/pull/11036/files)[PR](https://github.com/nestjs/nest/pull/11036/files)). The `debug` level is now set to `1`, while `verbose` is set to `0`.

#### Deprecations[#](/migration-guide#deprecations)

All deprecated methods & modules have been removed.

#### CLI Plugins and TypeScript >= 4.8[#](/migration-guide#cli-plugins-and-typescript--48)

NestJS CLI Plugins (available for `@nestjs/swagger` and `@nestjs/graphql` packages) will now require TypeScript >= v4.8 and so older versions of TypeScript will no longer be supported. The reason for this change is that in [TypeScript v4.8 introduced several breaking changes](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-8.html#decorators-are-placed-on-modifiers-on-typescripts-syntax-trees) in its Abstract Syntax Tree (AST) which we use to auto-generate OpenAPI and GraphQL schemas.

#### Dropping support for Node.js v12[#](/migration-guide#dropping-support-for-nodejs-v12)

As of NestJS 10, we no longer support Node.js v12, as [v12 went EOL](https://twitter.com/nodejs/status/1524081123579596800) on April 30, 2022. This means that NestJS 10 requires Node.js v16 or higher. This decision was made to allow us to finally set target to `ES2021` in our TypeScript configuration, instead of shipping polyfills as we did in the past.

From now on, every official NestJS package will be compiled to `ES2021` by default, which should result in a smaller library size and sometimes even (slightly) better performance.

We also strongly recommend using the latest LTS version.

----
url: https://docs.nestjs.com/v9/fundamentals/dynamic-modules
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Dynamic modules](https://docs.nestjs.com/v9/fundamentals/dynamic-modules#dynamic-modules)
* [Introduction](https://docs.nestjs.com/v9/fundamentals/dynamic-modules#introduction)
* [Dynamic module use case](https://docs.nestjs.com/v9/fundamentals/dynamic-modules#dynamic-module-use-case)
* [Config module example](https://docs.nestjs.com/v9/fundamentals/dynamic-modules#config-module-example)
* [Module configuration](https://docs.nestjs.com/v9/fundamentals/dynamic-modules#module-configuration)
* [Example](https://docs.nestjs.com/v9/fundamentals/dynamic-modules#example)
* [Community guidelines](https://docs.nestjs.com/v9/fundamentals/dynamic-modules#community-guidelines)
* [Configurable module builder](https://docs.nestjs.com/v9/fundamentals/dynamic-modules#configurable-module-builder)
* [Custom method key](https://docs.nestjs.com/v9/fundamentals/dynamic-modules#custom-method-key)
* [Custom options factory class](https://docs.nestjs.com/v9/fundamentals/dynamic-modules#custom-options-factory-class)
* [Extra options](https://docs.nestjs.com/v9/fundamentals/dynamic-modules#extra-options)
* [Extending auto-generated methods](https://docs.nestjs.com/v9/fundamentals/dynamic-modules#extending-auto-generated-methods)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/fundamentals/dynamic-modules.md "Suggest Edits")

### Dynamic modules

The [Modules chapter](/v9/modules) covers the basics of Nest modules, and includes a brief introduction to [dynamic modules](https://docs.nestjs.com/modules#dynamic-modules). This chapter expands on the subject of dynamic modules. Upon completion, you should have a good grasp of what they are and how and when to use them.

#### Introduction[#](/fundamentals/dynamic-modules#introduction)

Most application code examples in the **Overview** section of the documentation make use of regular, or static, modules. Modules define groups of components like [providers](/v9/providers) and [controllers](/v9/controllers) that fit together as a modular part of an overall application. They provide an execution context, or scope, for these components. For example, providers defined in a module are visible to other members of the module without the need to export them. When a provider needs to be visible outside of a module, it is first exported from its host module, and then imported into its consuming module.

Let's walk through a familiar example.

First, we'll define a `UsersModule` to provide and export a `UsersService`. `UsersModule` is the **host** module for `UsersService`.

```typescript

import { Module } from '@nestjs/common';
import { UsersService } from './users.service';

@Module({
  providers: [UsersService],
  exports: [UsersService],
})
export class UsersModule {}
```

Next, we'll define an `AuthModule`, which imports `UsersModule`, making `UsersModule`'s exported providers available inside `AuthModule`:

```typescript

import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { UsersModule } from '../users/users.module';

@Module({
  imports: [UsersModule],
  providers: [AuthService],
  exports: [AuthService],
})
export class AuthModule {}
```

These constructs allow us to inject `UsersService` in, for example, the `AuthService` that is hosted in `AuthModule`:

```typescript

import { Injectable } from '@nestjs/common';
import { UsersService } from '../users/users.service';

@Injectable()
export class AuthService {
  constructor(private usersService: UsersService) {}
  /*
    Implementation that makes use of this.usersService
  */
}
```

```typescript

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { ConfigModule } from './config/config.module';

@Module({
  imports: [ConfigModule],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}
```

Let's consider what a *dynamic module* import, where we're passing in a configuration object, might look like. Compare the difference in the `imports` array between these two examples:

```typescript

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { ConfigModule } from './config/config.module';

@Module({
  imports: [ConfigModule.register({ folder: './config' })],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}
```

Let's see what's happening in the dynamic example above. What are the moving parts?

1. `ConfigModule` is a normal class, so we can infer that it must have a **static method** called `register()`. We know it's static because we're calling it on the `ConfigModule` class, not on an **instance** of the class. Note: this method, which we will create soon, can have any arbitrary name, but by convention we should call it either `forRoot()` or `register()`.
2. The `register()` method is defined by us, so we can accept any input arguments we like. In this case, we're going to accept a simple `options` object with suitable properties, which is the typical case.
3. We can infer that the `register()` method must return something like a `module` since its return value appears in the familiar `imports` list, which we've seen so far includes a list of modules.

In fact, what our `register()` method will return is a `DynamicModule`. A dynamic module is nothing more than a module created at run-time, with the same exact properties as a static module, plus one additional property called `module`. Let's quickly review a sample static module declaration, paying close attention to the module options passed in to the decorator:

```typescript

@Module({
  imports: [DogsModule],
  controllers: [CatsController],
  providers: [CatsService],
  exports: [CatsService]
})
```

Dynamic modules must return an object with the exact same interface, plus one additional property called `module`. The `module` property serves as the name of the module, and should be the same as the class name of the module, as shown in the example below.

> **Hint** For a dynamic module, all properties of the module options object are optional **except**`module`.

What about the static `register()` method? We can now see that its job is to return an object that has the `DynamicModule` interface. When we call it, we are effectively providing a module to the `imports` list, similar to the way we would do so in the static case by listing a module class name. In other words, the dynamic module API simply returns a module, but rather than fix the properties in the `@Module` decorator, we specify them programmatically.

There are still a couple of details to cover to help make the picture complete:

1. We can now state that the `@Module()` decorator's `imports` property can take not only a module class name (e.g., `imports: [UsersModule]`), but also a function **returning** a dynamic module (e.g., `imports: [ConfigModule.register(...)]`).
2. A dynamic module can itself import other modules. We won't do so in this example, but if the dynamic module depends on providers from other modules, you would import them using the optional `imports` property. Again, this is exactly analogous to the way you'd declare metadata for a static module using the `@Module()` decorator.

Armed with this understanding, we can now look at what our dynamic `ConfigModule` declaration must look like. Let's take a crack at it.

```typescript

import { DynamicModule, Module } from '@nestjs/common';
import { ConfigService } from './config.service';

@Module({})
export class ConfigModule {
  static register(): DynamicModule {
    return {
      module: ConfigModule,
      providers: [ConfigService],
      exports: [ConfigService],
    };
  }
}
```

It should now be clear how the pieces tie together. Calling `ConfigModule.register(...)` returns a `DynamicModule` object with properties which are essentially the same as those that, until now, we've provided as metadata via the `@Module()` decorator.

> **Hint** Import `DynamicModule` from `@nestjs/common`.

Our dynamic module isn't very interesting yet, however, as we haven't introduced any capability to **configure** it as we said we would like to do. Let's address that next.

#### Module configuration[#](/fundamentals/dynamic-modules#module-configuration)

The obvious solution for customizing the behavior of the `ConfigModule` is to pass it an `options` object in the static `register()` method, as we guessed above. Let's look once again at our consuming module's `imports` property:

```typescript

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { ConfigModule } from './config/config.module';

@Module({
  imports: [ConfigModule.register({ folder: './config' })],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}
```

That nicely handles passing an `options` object to our dynamic module. How do we then use that `options` object in the `ConfigModule`? Let's consider that for a minute. We know that our `ConfigModule` is basically a host for providing and exporting an injectable service - the `ConfigService` - for use by other providers. It's actually our `ConfigService` that needs to read the `options` object to customize its behavior. Let's assume for the moment that we know how to somehow get the `options` from the `register()` method into the `ConfigService`. With that assumption, we can make a few changes to the service to customize its behavior based on the properties from the `options` object. (**Note**: for the time being, since we *haven't* actually determined how to pass it in, we'll just hard-code `options`. We'll fix this in a minute).

```typescript

import { Injectable } from '@nestjs/common';
import * as dotenv from 'dotenv';
import * as fs from 'fs';
import * as path from 'path';
import { EnvConfig } from './interfaces';

@Injectable()
export class ConfigService {
  private readonly envConfig: EnvConfig;

  constructor() {
    const options = { folder: './config' };

    const filePath = `${process.env.NODE_ENV || 'development'}.env`;
    const envFile = path.resolve(__dirname, '../../', options.folder, filePath);
    this.envConfig = dotenv.parse(fs.readFileSync(envFile));
  }

  get(key: string): string {
    return this.envConfig[key];
  }
}
```

Now our `ConfigService` knows how to find the `.env` file in the folder we've specified in `options`.

Our remaining task is to somehow inject the `options` object from the `register()` step into our `ConfigService`. And of course, we'll use *dependency injection* to do it. This is a key point, so make sure you understand it. Our `ConfigModule` is providing `ConfigService`. `ConfigService` in turn depends on the `options` object that is only supplied at run-time. So, at run-time, we'll need to first bind the `options` object to the Nest IoC container, and then have Nest inject it into our `ConfigService`. Remember from the **Custom providers** chapter that providers can [include any value](https://docs.nestjs.com/fundamentals/custom-providers#non-service-based-providers) not just services, so we're fine using dependency injection to handle a simple `options` object.

Let's tackle binding the options object to the IoC container first. We do this in our static `register()` method. Remember that we are dynamically constructing a module, and one of the properties of a module is its list of providers. So what we need to do is define our options object as a provider. This will make it injectable into the `ConfigService`, which we'll take advantage of in the next step. In the code below, pay attention to the `providers` array:

```typescript

import { DynamicModule, Module } from '@nestjs/common';
import { ConfigService } from './config.service';

@Module({})
export class ConfigModule {
  static register(options: Record<string, any>): DynamicModule {
    return {
      module: ConfigModule,
      providers: [
        {
          provide: 'CONFIG_OPTIONS',
          useValue: options,
        },
        ConfigService,
      ],
      exports: [ConfigService],
    };
  }
}
```

Now we can complete the process by injecting the `'CONFIG_OPTIONS'` provider into the `ConfigService`. Recall that when we define a provider using a non-class token we need to use the `@Inject()` decorator [as described here](https://docs.nestjs.com/fundamentals/custom-providers#non-class-based-provider-tokens).

```typescript

import * as dotenv from 'dotenv';
import * as fs from 'fs';
import * as path from 'path';
import { Injectable, Inject } from '@nestjs/common';
import { EnvConfig } from './interfaces';

@Injectable()
export class ConfigService {
  private readonly envConfig: EnvConfig;

  constructor(@Inject('CONFIG_OPTIONS') private options: Record<string, any>) {
    const filePath = `${process.env.NODE_ENV || 'development'}.env`;
    const envFile = path.resolve(__dirname, '../../', options.folder, filePath);
    this.envConfig = dotenv.parse(fs.readFileSync(envFile));
  }

  get(key: string): string {
    return this.envConfig[key];
  }
}
```

One final note: for simplicity we used a string-based injection token (`'CONFIG_OPTIONS'`) above, but best practice is to define it as a constant (or `Symbol`) in a separate file, and import that file. For example:

```typescript

export const CONFIG_OPTIONS = 'CONFIG_OPTIONS';
```

```typescript

export interface ConfigModuleOptions {
  folder: string;
}
```

With this in place, create a new dedicated file (alongside the existing `config.module.ts` file) and name it `config.module-definition.ts`. In this file, let's utilize the `ConfigurableModuleBuilder` to construct `ConfigModule` definition.

config.module-definition.ts

JS TS

```typescript

import { ConfigurableModuleBuilder } from '@nestjs/common';
import { ConfigModuleOptions } from './interfaces/config-module-options.interface';

export const { ConfigurableModuleClass, MODULE_OPTIONS_TOKEN } =
  new ConfigurableModuleBuilder<ConfigModuleOptions>().build();
```

```typescript

import { ConfigurableModuleBuilder } from '@nestjs/common';

export const { ConfigurableModuleClass, MODULE_OPTIONS_TOKEN } =
  new ConfigurableModuleBuilder().build();
```

Now let's open up the `config.module.ts` file and modify its implementation to leverage the auto-generated `ConfigurableModuleClass`:

```typescript

import { Module } from '@nestjs/common';
import { ConfigService } from './config.service';
import { ConfigurableModuleClass } from './config.module-definition';

@Module({
  providers: [ConfigService],
  exports: [ConfigService],
})
export class ConfigModule extends ConfigurableModuleClass {}
```

Extending the `ConfigurableModuleClass` means that `ConfigModule` provides now not only the `register` method (as previously with the custom implementation), but also the `registerAsync` method which allows consumers asynchronously configure that module, for example, by supplying async factories:

```typescript

@Module({
  imports: [
    ConfigModule.register({ folder: './config' }),
    // or alternatively:
    // ConfigModule.registerAsync({
    //   useFactory: () => {
    //     return {
    //       folder: './config',
    //     }
    //   },
    //   inject: [...any extra dependencies...]
    // }),
  ],
})
export class AppModule {}
```

Lastly, let's update the `ConfigService` class to inject the generated module options' provider instead of the `'CONFIG_OPTIONS'` that we used so far.

```typescript

@Injectable()
export class ConfigService {
  constructor(@Inject(MODULE_OPTIONS_TOKEN) private options: ConfigModuleOptions) { ... }
}
```

#### Custom method key[#](/fundamentals/dynamic-modules#custom-method-key)

`ConfigurableModuleClass` by default provides the `register` and its counterpart `registerAsync` methods. To use a different method name, use the `ConfigurableModuleBuilder#setClassMethodName` method, as follows:

config.module-definition.ts

JS TS

```typescript

export const { ConfigurableModuleClass, MODULE_OPTIONS_TOKEN } =
  new ConfigurableModuleBuilder<ConfigModuleOptions>().setClassMethodName('forRoot').build();
```

```typescript

export const { ConfigurableModuleClass, MODULE_OPTIONS_TOKEN } =
  new ConfigurableModuleBuilder().setClassMethodName('forRoot').build();
```

This construction will instruct `ConfigurableModuleBuilder` to generate a class that exposes `forRoot` and `forRootAsync` instead. Example:

```typescript

@Module({
  imports: [
    ConfigModule.forRoot({ folder: './config' }), // <-- note the use of "forRoot" instead of "register"
    // or alternatively:
    // ConfigModule.forRootAsync({
    //   useFactory: () => {
    //     return {
    //       folder: './config',
    //     }
    //   },
    //   inject: [...any extra dependencies...]
    // }),
  ],
})
export class AppModule {}
```

#### Custom options factory class[#](/fundamentals/dynamic-modules#custom-options-factory-class)

Since the `registerAsync` method (or `forRootAsync` or any other name, depending on the configuration) lets consumer pass a provider definition that resolves to the module configuration, a library consumer could potentially supply a class to be used to construct the configuration object.

```typescript

@Module({
  imports: [
    ConfigModule.registerAsync({
      useClass: ConfigModuleOptionsFactory,
    }),
  ],
})
export class AppModule {}
```

This class, by default, must provide the `create()` method that returns a module configuration object. However, if your library follows a different naming convention, you can change that behavior and instruct `ConfigurableModuleBuilder` to expect a different method, for example, `createConfigOptions`, using the `ConfigurableModuleBuilder#setFactoryMethodName` method:

config.module-definition.ts

JS TS

```typescript

export const { ConfigurableModuleClass, MODULE_OPTIONS_TOKEN } =
  new ConfigurableModuleBuilder<ConfigModuleOptions>().setFactoryMethodName('createConfigOptions').build();
```

```typescript

export const { ConfigurableModuleClass, MODULE_OPTIONS_TOKEN } =
  new ConfigurableModuleBuilder().setFactoryMethodName('createConfigOptions').build();
```

Now, `ConfigModuleOptionsFactory` class must expose the `createConfigOptions` method (instead of `create`):

```typescript

@Module({
  imports: [
    ConfigModule.registerAsync({
      useClass: ConfigModuleOptionsFactory, // <-- this class must provide the "createConfigOptions" method
    }),
  ],
})
export class AppModule {}
```

#### Extra options[#](/fundamentals/dynamic-modules#extra-options)

There are edge-cases when your module may need to take extra options that determine how it is supposed to behave (a nice example of such an option is the `isGlobal` flag - or just `global`) that at the same time, shouldn't be included in the `MODULE_OPTIONS_TOKEN` provider (as they are irrelevant to services/providers registered within that module, for example, `ConfigService` does not need to know whether its host module is registered as a global module).

In such cases, the `ConfigurableModuleBuilder#setExtras` method can be used. See the following example:

```typescript

export const { ConfigurableModuleClass, MODULE_OPTIONS_TOKEN } =
  new ConfigurableModuleBuilder<ConfigModuleOptions>()
    .setExtras(
      {
        isGlobal: true,
      },
      (definition, extras) => ({
        ...definition,
        global: extras.isGlobal,
      }),
    )
    .build();
```

In the example above, the first argument passed into the `setExtras` method is an object containing default values for the "extra" properties. The second argument is a function that takes an auto-generated module definitions (with `provider`, `exports`, etc.) and `extras` object which represents extra properties (either specified by the consumer or defaults). The returned value of this function is a modified module definition. In this specific example, we're taking the `extras.isGlobal` property and assigning it to the `global` property of the module definition (which in turn determines whether a module is global or not, read more [here](/modules#dynamic-modules)).

Now when consuming this module, the additional `isGlobal` flag can be passed in, as follows:

```typescript

@Module({
  imports: [
    ConfigModule.register({
      isGlobal: true,
      folder: './config',
    }),
  ],
})
export class AppModule {}
```

However, since `isGlobal` is declared as an "extra" property, it won't be available in the `MODULE_OPTIONS_TOKEN` provider:

```typescript

@Injectable()
export class ConfigService {
  constructor(
    @Inject(MODULE_OPTIONS_TOKEN) private options: ConfigModuleOptions,
  ) {
    // "options" object will not have the "isGlobal" property
    // ...
  }
}
```

#### Extending auto-generated methods[#](/fundamentals/dynamic-modules#extending-auto-generated-methods)

The auto-generated static methods (`register`, `registerAsync`, etc.) can be extended if needed, as follows:

```typescript

import { Module } from '@nestjs/common';
import { ConfigService } from './config.service';
import {
  ConfigurableModuleClass,
  ASYNC_OPTIONS_TYPE,
  OPTIONS_TYPE,
} from './config.module-definition';

@Module({
  providers: [ConfigService],
  exports: [ConfigService],
})
export class ConfigModule extends ConfigurableModuleClass {
  static register(options: typeof OPTIONS_TYPE): DynamicModule {
    return {
      // your custom logic here
      ...super.register(options),
    };
  }

  static registerAsync(options: typeof ASYNC_OPTIONS_TYPE): DynamicModule {
    return {
      // your custom logic here
      ...super.registerAsync(options),
    };
  }
}
```

Note the use of `OPTIONS_TYPE` and `ASYNC_OPTIONS_TYPE` types that must be exported from the module definition file:

```typescript

export const {
  ConfigurableModuleClass,
  MODULE_OPTIONS_TOKEN,
  OPTIONS_TYPE,
  ASYNC_OPTIONS_TYPE,
} = new ConfigurableModuleBuilder<ConfigModuleOptions>().build();
```

----
url: https://docs.nestjs.com/v8/faq/http-adapter
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [HTTP adapter](https://docs.nestjs.com/v8/faq/http-adapter#http-adapter)
* [Outside application context strategy](https://docs.nestjs.com/v8/faq/http-adapter#outside-application-context-strategy)
* [In-context strategy](https://docs.nestjs.com/v8/faq/http-adapter#in-context-strategy)

```typescript

const app = await NestFactory.create(AppModule);
const httpAdapter = app.getHttpAdapter();
```

#### In-context strategy[#](/faq/http-adapter#in-context-strategy)

To get a reference to the `HttpAdapterHost` from within the application context, inject it using the same technique as any other existing provider (e.g., using constructor injection).

JS TS

```typescript

export class CatsService {
  constructor(private adapterHost: HttpAdapterHost) {}
}
```

```typescript

@Dependencies(HttpAdapterHost)
export class CatsService {
  constructor(adapterHost) {
    this.adapterHost = adapterHost;
  }
}
```

> **Hint** The `HttpAdapterHost` is imported from the `@nestjs/core` package.

The `HttpAdapterHost` is **not** an actual `HttpAdapter`. To get the actual `HttpAdapter` instance, simply access the `httpAdapter` property.

```typescript

const adapterHost = app.get(HttpAdapterHost);
const httpAdapter = adapterHost.httpAdapter;
```

The `httpAdapter` is the actual instance of the HTTP adapter used by the underlying framework. It is an instance of either `ExpressAdapter` or `FastifyAdapter` (both classes extend `AbstractHttpAdapter`).

The adapter object exposes several useful methods to interact with the HTTP server. However, if you want to access the library instance (e.g., the Express instance) directly, call the `getInstance()` method.

```typescript

const instance = httpAdapter.getInstance();
```

----
url: https://docs.nestjs.com/v7/recipes/serve-static
----

* [Serve Static](https://docs.nestjs.com/v7/recipes/serve-static#serve-static)
* [Installation](https://docs.nestjs.com/v7/recipes/serve-static#installation)
* [Bootstrap](https://docs.nestjs.com/v7/recipes/serve-static#bootstrap)
* [Configuration](https://docs.nestjs.com/v7/recipes/serve-static#configuration)
* [Example](https://docs.nestjs.com/v7/recipes/serve-static#example)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/recipes/serve-static.md "Suggest Edits")

### Serve Static

In order to serve static content like a Single Page Application (SPA) we can use the `ServeStaticModule` from the [`@nestjs/serve-static`](https://www.npmjs.com/package/@nestjs/serve-static) package.

#### Installation[#](/recipes/serve-static#installation)

First we need to install the required package:

```bash

$ npm install --save @nestjs/serve-static
```

#### Bootstrap[#](/recipes/serve-static#bootstrap)

Once the installation process is done, we can import the `ServeStaticModule` into the root `AppModule` and configure it by passing in a configuration object to the `forRoot()` method.

```typescript

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { ServeStaticModule } from '@nestjs/serve-static';
import { join } from 'path';

@Module({
  imports: [
    ServeStaticModule.forRoot({
      rootPath: join(__dirname, '..', 'client'),
    }),
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}
```

With this in place, build the static website and place its content in the location specified by the `rootPath` property.

#### Configuration[#](/recipes/serve-static#configuration)

[ServeStaticModule](https://github.com/nestjs/serve-static) can be configured with a variety of options to customize its behavior. You can set the path to render your static app, specify excluded paths, enable or disable setting Cache-Control response header, etc. See the full list of options [here](https://github.com/nestjs/serve-static/blob/master/lib/interfaces/serve-static-options.interface.ts).

> **Notice** The default `renderPath` of the Static App is `*` (all paths), and the module will send "index.html" files in response. It lets you create Client-Side routing for your SPA. Paths, specified in your controllers will fallback to the server. You can change this behavior setting `serveRoot`, `renderPath` combining them with other options.

#### Example[#](/recipes/serve-static#example)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/24-serve-static).

----
url: https://docs.nestjs.com/v4/microservices/basics
----

### Basics

The "microservice" isn't the right word here. In fact, the Nest microservice is just an application which is using the different **transport layer** (not HTTP).

Nest supplies support for 2 types of communication - TCP and [Redis](https://redis.io/) pub/sub, but it's easy to bring the new transport strategy by implementing `CustomTransportStrategy` interface. To create a Nest microservice, we're using the `NestFactory` imported from the `@nestjs/core` package.

Let's create a simple microservice which will be listening to messages via TCP protocol. We're gonna start from the `bootstrap()` function.

main.ts

JavaScript TypeScript

TypeScript

```typescript

import { NestFactory } from '@nestjs/core';
import { ApplicationModule } from './app.module';
import { Transport } from '@nestjs/microservices';

async function bootstrap() {
  const app = await NestFactory.createMicroservice(ApplicationModule, {
    transport: Transport.TCP,
  });
  app.listen(() => console.log('Microservice is listening'));
}
bootstrap();
```

> **Notice** `Transport` is a helper enum.

The second argument of the `createMicroservice()` method is an options object. This object may have 3 members:

. .

|             |                                                                                                     |
| ----------- | --------------------------------------------------------------------------------------------------- |
| `transport` | Specifies the transport method (`Transport.TCP` and `Transport.REDIS` are available out-of-the-box) |
| `port`      | Determines the port to make use of                                                                  |
| `url`       | Determines the url to make use of \*only for Redis                                                  |
| `strategy`  | Determines the strategy to make use of \*only for Custom Strategy                                   |

#### Patterns

The Nest microservice recognizes the messages via **patterns**. The pattern is a plain JavaScript value - object, string, or even number. To create a pattern handler, we're using the `@MessagePattern()` decorator imported from the `@nestjs/microservices` package.

math.controller.ts

JavaScript TypeScript

TypeScript

```typescript

import { Controller } from '@nestjs/common';
import { MessagePattern } from '@nestjs/microservices';

@Controller()
export class MathController {
  @MessagePattern({ cmd: 'sum' })
  sum(data: number[]): number {
    return (data || []).reduce((a, b) => a + b);
  }
}
```

TypeScript

```typescript

import { Controller } from '@nestjs/common';
import { MessagePattern } from '@nestjs/microservices';

@Controller()
export class MathController {
  @MessagePattern({ cmd: 'sum' })
  sum(data) {
    return (data || []).reduce((a, b) => a + b);
  }
}
```

> **Notice** We can register the pattern handlers only inside the `@Controller()` class.

The above handler is listening to messages which fulfil the `cmd: 'sum'` pattern. Each pattern handler takes a single argument, the `data` passed from the client. In this case, the data is an array of numbers, which has to be accumulated.

#### Asynchronous responses

Each pattern handler can be `async`, so you're able to return the `Promise`. Moreover, you can return the [RxJS](https://github.com/reactivex/rxjs) `Observable`, so the values would be emitted until the stream is completed.

math.controller.ts

JavaScript TypeScript

TypeScript

```typescript

@MessagePattern({ cmd: 'sum' })
sum(data: number[]): Observable<number> {
  return Observable.from([1, 2, 3]);
}
```

TypeScript

```typescript

@MessagePattern({ cmd: 'sum' })
sum(data) {
  return Observable.from([1, 2, 3]);
}
```

Above message handler will respond **3 times** (with each item from the array).

#### Client

To connect with the Nest microservice, we're using the `ClientProxy` class, which instance is assigned to the property by `@Client()` decorator. This decorator takes single argument - the same object as a Nest microservice options object.

TypeScript

```typescript

@Client({ transport: Transport.TCP, port: 5667 })
client: ClientProxy;
```

> **Notice** Both `@Client()` decorator and `ClientProxy` class are imported from the `@nestjs/microservices` package.

The `ClientProxy` has a `send()` method. This method is intended to call the microservice and returns the `Observable` with its response.

JavaScript TypeScript

TypeScript

```typescript

@Get()
call(): Observable<number> {
  const pattern = { cmd: 'sum' };
  const data = [1, 2, 3, 4, 5];

  return this.client.send<number>(pattern, data);
}
```

TypeScript

```typescript

@Get()
call() {
  const pattern = { cmd: 'sum' };
  const data = [1, 2, 3, 4, 5];

  return this.client.send(pattern, data);
}
```

It takes 2 arguments, the `pattern` and `data`. The `pattern` has to be same as this declared in the `@MessagePattern()` decorator. That's all.

#### Sponsors

[](https://valor-software.com/)

Nest is an MIT-licensed open source project. It can grow thanks to the support by these awesome people. If you'd like to join them, please read more [here](https://opencollective.com/nest). Thanks!

[](https://opencollective.com/nest/backer/0/website)[](https://opencollective.com/nest/backer/1/website)[](https://opencollective.com/nest/backer/2/website)[](https://opencollective.com/nest/backer/3/website)[](https://opencollective.com/nest/backer/4/website)[](https://opencollective.com/nest/backer/5/website)[](https://opencollective.com/nest/backer/6/website)[](https://opencollective.com/nest/backer/7/website)[](https://opencollective.com/nest/backer/8/website)[](https://opencollective.com/nest/backer/9/website)[](https://opencollective.com/nest/backer/10/website)[](https://opencollective.com/nest/backer/11/website)[](https://opencollective.com/nest/backer/12/website)[](https://opencollective.com/nest/backer/13/website)[](https://opencollective.com/nest/backer/14/website)[](https://opencollective.com/nest/backer/15/website)[](https://opencollective.com/nest/backer/16/website)[](https://opencollective.com/nest/backer/17/website)[](https://opencollective.com/nest/backer/18/website)[](https://opencollective.com/nest/backer/19/website)[](https://opencollective.com/nest/backer/20/website)[](https://opencollective.com/nest/backer/21/website)[](https://opencollective.com/nest/backer/22/website)[](https://opencollective.com/nest/backer/23/website)[](https://opencollective.com/nest/backer/24/website)[](https://opencollective.com/nest/backer/25/website)[](https://opencollective.com/nest/backer/26/website)[](https://opencollective.com/nest/backer/27/website)[](https://opencollective.com/nest/backer/28/website)[](https://opencollective.com/nest/backer/29/website)

[Become a sponsor](https://opencollective.com/nest)

----
url: https://docs.nestjs.com/v11/fundamentals/module-ref
----

* [Module reference](https://docs.nestjs.com/v11/fundamentals/module-ref#module-reference)
* [Retrieving instances](https://docs.nestjs.com/v11/fundamentals/module-ref#retrieving-instances)
* [Resolving scoped providers](https://docs.nestjs.com/v11/fundamentals/module-ref#resolving-scoped-providers)
* [Registering REQUEST provider](https://docs.nestjs.com/v11/fundamentals/module-ref#registering-request-provider)
* [Getting current sub-tree](https://docs.nestjs.com/v11/fundamentals/module-ref#getting-current-sub-tree)
* [Instantiating custom classes dynamically](https://docs.nestjs.com/v11/fundamentals/module-ref#instantiating-custom-classes-dynamically)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/fundamentals/module-reference.md "Suggest Edits")

### Module reference

Nest provides the `ModuleRef` class to navigate the internal list of providers and obtain a reference to any provider using its injection token as a lookup key. The `ModuleRef` class also provides a way to dynamically instantiate both static and scoped providers. `ModuleRef` can be injected into a class in the normal way:

cats.service.ts

JS TS

```typescript

@Injectable()
export class CatsService {
  constructor(private moduleRef: ModuleRef) {}
}
```

```typescript

@Injectable()
@Dependencies(ModuleRef)
export class CatsService {
  constructor(moduleRef) {
    this.moduleRef = moduleRef;
  }
}
```

> **Hint** The `ModuleRef` class is imported from the `@nestjs/core` package.

#### Retrieving instances[#](/fundamentals/module-ref#retrieving-instances)

The `ModuleRef` instance (hereafter we'll refer to it as the **module reference**) has a `get()` method. By default, this method returns a provider, controller, or injectable (e.g., guard, interceptor, etc.) that was registered and has been instantiated in the *current module* using its injection token/class name. If the instance is not found, an exception will be raised.

cats.service.ts

JS TS

```typescript

@Injectable()
export class CatsService implements OnModuleInit {
  private service: Service;
  constructor(private moduleRef: ModuleRef) {}

  onModuleInit() {
    this.service = this.moduleRef.get(Service);
  }
}
```

```typescript

@Injectable()
@Dependencies(ModuleRef)
export class CatsService {
  constructor(moduleRef) {
    this.moduleRef = moduleRef;
  }

  onModuleInit() {
    this.service = this.moduleRef.get(Service);
  }
}
```

> **Warning** You can't retrieve scoped providers (transient or request-scoped) with the `get()` method. Instead, use the technique described [below](https://docs.nestjs.com/fundamentals/module-ref#resolving-scoped-providers). Learn how to control scopes [here](/v11/fundamentals/injection-scopes).

To retrieve a provider from the global context (for example, if the provider has been injected in a different module), pass the `{ strict: false }` option as a second argument to `get()`.

```typescript

this.moduleRef.get(Service, { strict: false });
```

#### Resolving scoped providers[#](/fundamentals/module-ref#resolving-scoped-providers)

To dynamically resolve a scoped provider (transient or request-scoped), use the `resolve()` method, passing the provider's injection token as an argument.

cats.service.ts

JS TS

```typescript

@Injectable()
export class CatsService implements OnModuleInit {
  private transientService: TransientService;
  constructor(private moduleRef: ModuleRef) {}

  async onModuleInit() {
    this.transientService = await this.moduleRef.resolve(TransientService);
  }
}
```

```typescript

@Injectable()
@Dependencies(ModuleRef)
export class CatsService {
  constructor(moduleRef) {
    this.moduleRef = moduleRef;
  }

  async onModuleInit() {
    this.transientService = await this.moduleRef.resolve(TransientService);
  }
}
```

The `resolve()` method returns a unique instance of the provider, from its own **DI container sub-tree**. Each sub-tree has a unique **context identifier**. Thus, if you call this method more than once and compare instance references, you will see that they are not equal.

cats.service.ts

JS TS

```typescript

@Injectable()
export class CatsService implements OnModuleInit {
  constructor(private moduleRef: ModuleRef) {}

  async onModuleInit() {
    const transientServices = await Promise.all([
      this.moduleRef.resolve(TransientService),
      this.moduleRef.resolve(TransientService),
    ]);
    console.log(transientServices[0] === transientServices[1]); // false
  }
}
```

```typescript

@Injectable()
@Dependencies(ModuleRef)
export class CatsService {
  constructor(moduleRef) {
    this.moduleRef = moduleRef;
  }

  async onModuleInit() {
    const transientServices = await Promise.all([
      this.moduleRef.resolve(TransientService),
      this.moduleRef.resolve(TransientService),
    ]);
    console.log(transientServices[0] === transientServices[1]); // false
  }
}
```

To generate a single instance across multiple `resolve()` calls, and ensure they share the same generated DI container sub-tree, you can pass a context identifier to the `resolve()` method. Use the `ContextIdFactory` class to generate a context identifier. This class provides a `create()` method that returns an appropriate unique identifier.

cats.service.ts

JS TS

```typescript

@Injectable()
export class CatsService implements OnModuleInit {
  constructor(private moduleRef: ModuleRef) {}

  async onModuleInit() {
    const contextId = ContextIdFactory.create();
    const transientServices = await Promise.all([
      this.moduleRef.resolve(TransientService, contextId),
      this.moduleRef.resolve(TransientService, contextId),
    ]);
    console.log(transientServices[0] === transientServices[1]); // true
  }
}
```

```typescript

@Injectable()
@Dependencies(ModuleRef)
export class CatsService {
  constructor(moduleRef) {
    this.moduleRef = moduleRef;
  }

  async onModuleInit() {
    const contextId = ContextIdFactory.create();
    const transientServices = await Promise.all([
      this.moduleRef.resolve(TransientService, contextId),
      this.moduleRef.resolve(TransientService, contextId),
    ]);
    console.log(transientServices[0] === transientServices[1]); // true
  }
}
```

> **Hint** The `ContextIdFactory` class is imported from the `@nestjs/core` package.

#### Registering `REQUEST` provider[#](/fundamentals/module-ref#registering-request-provider)

Manually generated context identifiers (with `ContextIdFactory.create()`) represent DI sub-trees in which `REQUEST` provider is `undefined` as they are not instantiated and managed by the Nest dependency injection system.

To register a custom `REQUEST` object for a manually created DI sub-tree, use the `ModuleRef#registerRequestByContextId()` method, as follows:

```typescript

const contextId = ContextIdFactory.create();
this.moduleRef.registerRequestByContextId(/* YOUR_REQUEST_OBJECT */, contextId);
```

#### Getting current sub-tree[#](/fundamentals/module-ref#getting-current-sub-tree)

Occasionally, you may want to resolve an instance of a request-scoped provider within a **request context**. Let's say that `CatsService` is request-scoped and you want to resolve the `CatsRepository` instance which is also marked as a request-scoped provider. In order to share the same DI container sub-tree, you must obtain the current context identifier instead of generating a new one (e.g., with the `ContextIdFactory.create()` function, as shown above). To obtain the current context identifier, start by injecting the request object using `@Inject()` decorator.

cats.service.ts

JS TS

```typescript

@Injectable()
export class CatsService {
  constructor(
    @Inject(REQUEST) private request: Record<string, unknown>,
  ) {}
}
```

```typescript

@Injectable()
@Dependencies(REQUEST)
export class CatsService {
  constructor(request) {
    this.request = request;
  }
}
```

> **Hint** Learn more about the request provider [here](https://docs.nestjs.com/fundamentals/injection-scopes#request-provider).

Now, use the `getByRequest()` method of the `ContextIdFactory` class to create a context id based on the request object, and pass this to the `resolve()` call:

```typescript

const contextId = ContextIdFactory.getByRequest(this.request);
const catsRepository = await this.moduleRef.resolve(CatsRepository, contextId);
```

#### Instantiating custom classes dynamically[#](/fundamentals/module-ref#instantiating-custom-classes-dynamically)

To dynamically instantiate a class that **wasn't previously registered** as a **provider**, use the module reference's `create()` method.

cats.service.ts

JS TS

```typescript

@Injectable()
export class CatsService implements OnModuleInit {
  private catsFactory: CatsFactory;
  constructor(private moduleRef: ModuleRef) {}

  async onModuleInit() {
    this.catsFactory = await this.moduleRef.create(CatsFactory);
  }
}
```

```typescript

@Injectable()
@Dependencies(ModuleRef)
export class CatsService {
  constructor(moduleRef) {
    this.moduleRef = moduleRef;
  }

  async onModuleInit() {
    this.catsFactory = await this.moduleRef.create(CatsFactory);
  }
}
```

This technique enables you to conditionally instantiate different classes outside of the framework container.

## Explore your graph with NestJS Devtools

* Graph visualizer
* Routes navigator
* Interactive playground
* CI/CD integration

[Sign up](https://devtools.nestjs.com "Devtools | NestJS - A node.js framework built on top of TypeScript")

----
url: https://docs.nestjs.com/v10/techniques/performance
----

* [Performance (Fastify)](https://docs.nestjs.com/v10/techniques/performance#performance-fastify)
* [Installation](https://docs.nestjs.com/v10/techniques/performance#installation)
* [Adapter](https://docs.nestjs.com/v10/techniques/performance#adapter)
* [Platform specific packages](https://docs.nestjs.com/v10/techniques/performance#platform-specific-packages)
* [Redirect response](https://docs.nestjs.com/v10/techniques/performance#redirect-response)
* [Fastify options](https://docs.nestjs.com/v10/techniques/performance#fastify-options)
* [Middleware](https://docs.nestjs.com/v10/techniques/performance#middleware)
* [Route Config](https://docs.nestjs.com/v10/techniques/performance#route-config)
* [Route Constraints](https://docs.nestjs.com/v10/techniques/performance#route-constraints)
* [Example](https://docs.nestjs.com/v10/techniques/performance#example)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/techniques/performance.md "Suggest Edits")

### Performance (Fastify)

By default, Nest makes use of the [Express](https://expressjs.com/) framework. As mentioned earlier, Nest also provides compatibility with other libraries such as, for example, [Fastify](https://github.com/fastify/fastify). Nest achieves this framework independence by implementing a framework adapter whose primary function is to proxy middleware and handlers to appropriate library-specific implementations.

> **Hint** Note that in order for a framework adapter to be implemented, the target library has to provide similar request/response pipeline processing as found in Express.

[Fastify](https://github.com/fastify/fastify) provides a good alternative framework for Nest because it solves design issues in a similar manner to Express. However, fastify is much **faster** than Express, achieving almost two times better benchmarks results. A fair question is why does Nest use Express as the default HTTP provider? The reason is that Express is widely-used, well-known, and has an enormous set of compatible middleware, which is available to Nest users out-of-the-box.

But since Nest provides framework-independence, you can easily migrate between them. Fastify can be a better choice when you place high value on very fast performance. To utilize Fastify, simply choose the built-in `FastifyAdapter` as shown in this chapter.

#### Installation[#](/techniques/performance#installation)

First, we need to install the required package:

```bash

$ npm i --save @nestjs/platform-fastify
```

#### Adapter[#](/techniques/performance#adapter)

Once the Fastify platform is installed, we can use the `FastifyAdapter`.

main.ts

JS TS

```typescript

import { NestFactory } from '@nestjs/core';
import {
  FastifyAdapter,
  NestFastifyApplication,
} from '@nestjs/platform-fastify';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create<NestFastifyApplication>(
    AppModule,
    new FastifyAdapter()
  );
  await app.listen(process.env.PORT ?? 3000);
}
bootstrap();
```

By default, Fastify listens only on the `localhost 127.0.0.1` interface ([read more](https://www.fastify.io/docs/latest/Guides/Getting-Started/#your-first-server)). If you want to accept connections on other hosts, you should specify `'0.0.0.0'` in the `listen()` call:

```typescript

async function bootstrap() {
  const app = await NestFactory.create<NestFastifyApplication>(
    AppModule,
    new FastifyAdapter(),
  );
  await app.listen(3000, '0.0.0.0');
}
```

#### Platform specific packages[#](/techniques/performance#platform-specific-packages)

Keep in mind that when you use the `FastifyAdapter`, Nest uses Fastify as the **HTTP provider**. This means that each recipe that relies on Express may no longer work. You should, instead, use Fastify equivalent packages.

#### Redirect response[#](/techniques/performance#redirect-response)

Fastify handles redirect responses slightly differently than Express. To do a proper redirect with Fastify, return both the status code and the URL, as follows:

```typescript

@Get()
index(@Res() res) {
  res.status(302).redirect('/login');
}
```

#### Fastify options[#](/techniques/performance#fastify-options)

You can pass options into the Fastify constructor through the `FastifyAdapter` constructor. For example:

```typescript

new FastifyAdapter({ logger: true });
```

#### Middleware[#](/techniques/performance#middleware)

Middleware functions retrieve the raw `req` and `res` objects instead of Fastify's wrappers. This is how the `middie` package works (that's used under the hood) and `fastify` - check out this [page](https://www.fastify.io/docs/latest/Reference/Middleware/) for more information,

logger.middleware.ts

JS TS

```typescript

import { Injectable, NestMiddleware } from '@nestjs/common';
import { FastifyRequest, FastifyReply } from 'fastify';

@Injectable()
export class LoggerMiddleware implements NestMiddleware {
  use(req: FastifyRequest['raw'], res: FastifyReply['raw'], next: () => void) {
    console.log('Request...');
    next();
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';

@Injectable()
export class LoggerMiddleware {
  use(req, res, next) {
    console.log('Request...');
    next();
  }
}
```

#### Route Config[#](/techniques/performance#route-config)

You can use the [route config](https://fastify.dev/docs/latest/Reference/Routes/#config) feature of Fastify with the `@RouteConfig()` decorator.

```typescript

@RouteConfig({ output: 'hello world' })
@Get()
index(@Req() req) {
  return req.routeConfig.output;
}
```

#### Route Constraints[#](/techniques/performance#route-constraints)

As of v10.3.0, `@nestjs/platform-fastify` supports [route constraints](https://fastify.dev/docs/latest/Reference/Routes/#constraints) feature of Fastify with `@RouteConstraints` decorator.

```typescript

@RouteConstraints({ version: '1.2.x' })
newFeature() {
  return 'This works only for version >= 1.2.x';
}
```

> **Hint**`@RouteConfig()` and `@RouteConstraints` are imported from `@nestjs/platform-fastify`.

#### Example[#](/techniques/performance#example)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/10-fastify).

----
url: https://docs.nestjs.com/v10/guards
----

* [Guards](https://docs.nestjs.com/v10/guards#guards)
* [Authorization guard](https://docs.nestjs.com/v10/guards#authorization-guard)
* [Execution context](https://docs.nestjs.com/v10/guards#execution-context)
* [Role-based authentication](https://docs.nestjs.com/v10/guards#role-based-authentication)
* [Binding guards](https://docs.nestjs.com/v10/guards#binding-guards)
* [Setting roles per handler](https://docs.nestjs.com/v10/guards#setting-roles-per-handler)
* [Putting it all together](https://docs.nestjs.com/v10/guards#putting-it-all-together)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/guards.md "Suggest Edits")

### Guards

A guard is a class annotated with the `@Injectable()` decorator, which implements the `CanActivate` interface.

Guards have a **single responsibility**. They determine whether a given request will be handled by the route handler or not, depending on certain conditions (like permissions, roles, ACLs, etc.) present at run-time. This is often referred to as **authorization**. Authorization (and its cousin, **authentication**, with which it usually collaborates) has typically been handled by [middleware](/v10/middleware) in traditional Express applications. Middleware is a fine choice for authentication, since things like token validation and attaching properties to the `request` object are not strongly connected with a particular route context (and its metadata).

But middleware, by its nature, is dumb. It doesn't know which handler will be executed after calling the `next()` function. On the other hand, **Guards** have access to the `ExecutionContext` instance, and thus know exactly what's going to be executed next. They're designed, much like exception filters, pipes, and interceptors, to let you interpose processing logic at exactly the right point in the request/response cycle, and to do so declaratively. This helps keep your code DRY and declarative.

> **Hint** Guards are executed **after** all middleware, but **before** any interceptor or pipe.

#### Authorization guard[#](/guards#authorization-guard)

As mentioned, **authorization** is a great use case for Guards because specific routes should be available only when the caller (usually a specific authenticated user) has sufficient permissions. The `AuthGuard` that we'll build now assumes an authenticated user (and that, therefore, a token is attached to the request headers). It will extract and validate the token, and use the extracted information to determine whether the request can proceed or not.

auth.guard.ts

JS TS

```typescript

import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
import { Observable } from 'rxjs';

@Injectable()
export class AuthGuard implements CanActivate {
  canActivate(
    context: ExecutionContext,
  ): boolean | Promise<boolean> | Observable<boolean> {
    const request = context.switchToHttp().getRequest();
    return validateRequest(request);
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';

@Injectable()
export class AuthGuard {
  async canActivate(context) {
    const request = context.switchToHttp().getRequest();
    return validateRequest(request);
  }
}
```

> **Hint** If you are looking for a real-world example on how to implement an authentication mechanism in your application, visit [this chapter](/v10/security/authentication). Likewise, for more sophisticated authorization example, check [this page](/v10/security/authorization).

By extending `ArgumentsHost`, `ExecutionContext` also adds several new helper methods that provide additional details about the current execution process. These details can be helpful in building more generic guards that can work across a broad set of controllers, methods, and execution contexts. Learn more about `ExecutionContext`[here](/v10/fundamentals/execution-context).

#### Role-based authentication[#](/guards#role-based-authentication)

Let's build a more functional guard that permits access only to users with a specific role. We'll start with a basic guard template, and build on it in the coming sections. For now, it allows all requests to proceed:

roles.guard.ts

JS TS

```typescript

import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
import { Observable } from 'rxjs';

@Injectable()
export class RolesGuard implements CanActivate {
  canActivate(
    context: ExecutionContext,
  ): boolean | Promise<boolean> | Observable<boolean> {
    return true;
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';

@Injectable()
export class RolesGuard {
  canActivate(context) {
    return true;
  }
}
```

#### Binding guards[#](/guards#binding-guards)

Like pipes and exception filters, guards can be **controller-scoped**, method-scoped, or global-scoped. Below, we set up a controller-scoped guard using the `@UseGuards()` decorator. This decorator may take a single argument, or a comma-separated list of arguments. This lets you easily apply the appropriate set of guards with one declaration.

JS TS

```typescript

@Controller('cats')
@UseGuards(RolesGuard)
export class CatsController {}
```

> **Hint** The `@UseGuards()` decorator is imported from the `@nestjs/common` package.

Above, we passed the `RolesGuard` class (instead of an instance), leaving responsibility for instantiation to the framework and enabling dependency injection. As with pipes and exception filters, we can also pass an in-place instance:

JS TS

```typescript

@Controller('cats')
@UseGuards(new RolesGuard())
export class CatsController {}
```

The construction above attaches the guard to every handler declared by this controller. If we wish the guard to apply only to a single method, we apply the `@UseGuards()` decorator at the **method level**.

In order to set up a global guard, use the `useGlobalGuards()` method of the Nest application instance:

JS TS

```typescript

const app = await NestFactory.create(AppModule);
app.useGlobalGuards(new RolesGuard());
```

> **Notice** In the case of hybrid apps the `useGlobalGuards()` method doesn't set up guards for gateways and microservices by default (see [Hybrid application](/v10/faq/hybrid-application) for information on how to change this behavior). For "standard" (non-hybrid) microservice apps, `useGlobalGuards()` does mount the guards globally.

Global guards are used across the whole application, for every controller and every route handler. In terms of dependency injection, global guards registered from outside of any module (with `useGlobalGuards()` as in the example above) cannot inject dependencies since this is done outside the context of any module. In order to solve this issue, you can set up a guard directly from any module using the following construction:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { APP_GUARD } from '@nestjs/core';

@Module({
  providers: [
    {
      provide: APP_GUARD,
      useClass: RolesGuard,
    },
  ],
})
export class AppModule {}
```

> **Hint** When using this approach to perform dependency injection for the guard, note that regardless of the module where this construction is employed, the guard is, in fact, global. Where should this be done? Choose the module where the guard (`RolesGuard` in the example above) is defined. Also, `useClass` is not the only way of dealing with custom provider registration. Learn more [here](/v10/fundamentals/custom-providers).

#### Setting roles per handler[#](/guards#setting-roles-per-handler)

Our `RolesGuard` is working, but it's not very smart yet. We're not yet taking advantage of the most important guard feature - the [execution context](/v10/fundamentals/execution-context). It doesn't yet know about roles, or which roles are allowed for each handler. The `CatsController`, for example, could have different permission schemes for different routes. Some might be available only for an admin user, and others could be open for everyone. How can we match roles to routes in a flexible and reusable way?

This is where **custom metadata** comes into play (learn more [here](https://docs.nestjs.com/fundamentals/execution-context#reflection-and-metadata)). Nest provides the ability to attach custom **metadata** to route handlers through either decorators created via `Reflector#createDecorator` static method, or the built-in `@SetMetadata()` decorator.

For example, let's create a `@Roles()` decorator using the `Reflector#createDecorator` method that will attach the metadata to the handler. `Reflector` is provided out of the box by the framework and exposed from the `@nestjs/core` package.

roles.decorator.ts

JS TS

```ts

import { Reflector } from '@nestjs/core';

export const Roles = Reflector.createDecorator<string[]>();
```

The `Roles` decorator here is a function that takes a single argument of type `string[]`.

Now, to use this decorator, we simply annotate the handler with it:

cats.controller.ts

JS TS

```typescript

@Post()
@Roles(['admin'])
async create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

```typescript

@Post()
@Roles(['admin'])
@Bind(Body())
async create(createCatDto) {
  this.catsService.create(createCatDto);
}
```

Here we've attached the `Roles` decorator metadata to the `create()` method, indicating that only users with the `admin` role should be allowed to access this route.

Alternatively, instead of using the `Reflector#createDecorator` method, we could use the built-in `@SetMetadata()` decorator. Learn more about [here](/fundamentals/execution-context#low-level-approach).

#### Putting it all together[#](/guards#putting-it-all-together)

Let's now go back and tie this together with our `RolesGuard`. Currently, it simply returns `true` in all cases, allowing every request to proceed. We want to make the return value conditional based on comparing the **roles assigned to the current user** to the actual roles required by the current route being processed. In order to access the route's role(s) (custom metadata), we'll use the `Reflector` helper class again, as follows:

roles.guard.ts

JS TS

```typescript

import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
import { Reflector } from '@nestjs/core';
import { Roles } from './roles.decorator';

@Injectable()
export class RolesGuard implements CanActivate {
  constructor(private reflector: Reflector) {}

  canActivate(context: ExecutionContext): boolean {
    const roles = this.reflector.get(Roles, context.getHandler());
    if (!roles) {
      return true;
    }
    const request = context.switchToHttp().getRequest();
    const user = request.user;
    return matchRoles(roles, user.roles);
  }
}
```

```typescript

import { Injectable, Dependencies } from '@nestjs/common';
import { Reflector } from '@nestjs/core';
import { Roles } from './roles.decorator';

@Injectable()
@Dependencies(Reflector)
export class RolesGuard {
  constructor(reflector) {
    this.reflector = reflector;
  }

  canActivate(context) {
    const roles = this.reflector.get(Roles, context.getHandler());
    if (!roles) {
      return true;
    }
    const request = context.switchToHttp().getRequest();
    const user = request.user;
    return matchRoles(roles, user.roles);
  }
}
```

> **Hint** In the node.js world, it's common practice to attach the authorized user to the `request` object. Thus, in our sample code above, we are assuming that `request.user` contains the user instance and allowed roles. In your app, you will probably make that association in your custom **authentication guard** (or middleware). Check [this chapter](/v10/security/authentication) for more information on this topic.

> **Warning** The logic inside the `matchRoles()` function can be as simple or sophisticated as needed. The main point of this example is to show how guards fit into the request/response cycle.

Refer to the [Reflection and metadata](https://docs.nestjs.com/fundamentals/execution-context#reflection-and-metadata) section of the **Execution context** chapter for more details on utilizing `Reflector` in a context-sensitive way.

When a user with insufficient privileges requests an endpoint, Nest automatically returns the following response:

```typescript

{
  "statusCode": 403,
  "message": "Forbidden resource",
  "error": "Forbidden"
}
```

Note that behind the scenes, when a guard returns `false`, the framework throws a `ForbiddenException`. If you want to return a different error response, you should throw your own specific exception. For example:

```typescript

throw new UnauthorizedException();
```

Any exception thrown by a guard will be handled by the [exceptions layer](/v10/exception-filters) (global exceptions filter and any exceptions filters that are applied to the current context).

> **Hint** If you are looking for a real-world example on how to implement authorization, check [this chapter](/v10/security/authorization).

----
url: https://docs.nestjs.com/v10/graphql/scalars
----

* [Scalars](https://docs.nestjs.com/v10/graphql/scalars#scalars)
* [Code first](https://docs.nestjs.com/v10/graphql/scalars#code-first)
* [Override a default scalar](https://docs.nestjs.com/v10/graphql/scalars#override-a-default-scalar)
* [Import a custom scalar](https://docs.nestjs.com/v10/graphql/scalars#import-a-custom-scalar)
* [Create a custom scalar](https://docs.nestjs.com/v10/graphql/scalars#create-a-custom-scalar)
* [Schema first](https://docs.nestjs.com/v10/graphql/scalars#schema-first)

```typescript

GraphQLModule.forRoot({
  buildSchemaOptions: {
    dateScalarMode: 'timestamp',
  }
}),
```

Likewise, the `GraphQLFloat` is used by default to represent the `number` type. To use the `GraphQLInt` instead, set the `numberScalarMode` of the `buildSchemaOptions` object to `'integer'` as follows:

```typescript

GraphQLModule.forRoot({
  buildSchemaOptions: {
    numberScalarMode: 'integer',
  }
}),
```

In addition, you can create custom scalars.

#### Override a default scalar[#](/graphql/scalars#override-a-default-scalar)

To create a custom implementation for the `Date` scalar, simply create a new class.

```typescript

import { Scalar, CustomScalar } from '@nestjs/graphql';
import { Kind, ValueNode } from 'graphql';

@Scalar('Date', () => Date)
export class DateScalar implements CustomScalar<number, Date> {
  description = 'Date custom scalar type';

  parseValue(value: number): Date {
    return new Date(value); // value from the client
  }

  serialize(value: Date): number {
    return value.getTime(); // value sent to the client
  }

  parseLiteral(ast: ValueNode): Date {
    if (ast.kind === Kind.INT) {
      return new Date(ast.value);
    }
    return null;
  }
}
```

With this in place, register `DateScalar` as a provider.

```typescript

@Module({
  providers: [DateScalar],
})
export class CommonModule {}
```

Now we can use the `Date` type in our classes.

```typescript

@Field()
creationDate: Date;
```

#### Import a custom scalar[#](/graphql/scalars#import-a-custom-scalar)

To use a custom scalar, import and register it as a resolver. We’ll use the `graphql-type-json` package for demonstration purposes. This npm package defines a `JSON` GraphQL scalar type.

Start by installing the package:

```bash

$ npm i --save graphql-type-json
```

Once the package is installed, we pass a custom resolver to the `forRoot()` method:

```typescript

import GraphQLJSON from 'graphql-type-json';

@Module({
  imports: [
    GraphQLModule.forRoot({
      resolvers: { JSON: GraphQLJSON },
    }),
  ],
})
export class AppModule {}
```

Now we can use the `JSON` type in our classes.

```typescript

@Field(() => GraphQLJSON)
info: JSON;
```

For a suite of useful scalars, take a look at the [graphql-scalars](https://www.npmjs.com/package/graphql-scalars) package.

#### Create a custom scalar[#](/graphql/scalars#create-a-custom-scalar)

To define a custom scalar, create a new `GraphQLScalarType` instance. We'll create a custom `UUID` scalar.

```typescript

const regex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;

function validate(uuid: unknown): string | never {
  if (typeof uuid !== 'string' || !regex.test(uuid)) {
    throw new Error('invalid uuid');
  }
  return uuid;
}

export const CustomUuidScalar = new GraphQLScalarType({
  name: 'UUID',
  description: 'A simple UUID parser',
  serialize: (value) => validate(value),
  parseValue: (value) => validate(value),
  parseLiteral: (ast) => validate(ast.value),
});
```

We pass a custom resolver to the `forRoot()` method:

```typescript

@Module({
  imports: [
    GraphQLModule.forRoot({
      resolvers: { UUID: CustomUuidScalar },
    }),
  ],
})
export class AppModule {}
```

Now we can use the `UUID` type in our classes.

```typescript

@Field(() => CustomUuidScalar)
uuid: string;
```

#### Schema first[#](/graphql/scalars#schema-first)

To define a custom scalar (read more about scalars [here](https://www.apollographql.com/docs/graphql-tools/scalars.html)), create a type definition and a dedicated resolver. Here (as in the official documentation), we’ll use the `graphql-type-json` package for demonstration purposes. This npm package defines a `JSON` GraphQL scalar type.

Start by installing the package:

```bash

$ npm i --save graphql-type-json
```

Once the package is installed, we pass a custom resolver to the `forRoot()` method:

```typescript

import GraphQLJSON from 'graphql-type-json';

@Module({
  imports: [
    GraphQLModule.forRoot({
      typePaths: ['./**/*.graphql'],
      resolvers: { JSON: GraphQLJSON },
    }),
  ],
})
export class AppModule {}
```

Now we can use the `JSON` scalar in our type definitions:

```graphql

scalar JSON

type Foo {
  field: JSON
}
```

Another method to define a scalar type is to create a simple class. Assume we want to enhance our schema with the `Date` type.

```typescript

import { Scalar, CustomScalar } from '@nestjs/graphql';
import { Kind, ValueNode } from 'graphql';

@Scalar('Date')
export class DateScalar implements CustomScalar<number, Date> {
  description = 'Date custom scalar type';

  parseValue(value: number): Date {
    return new Date(value); // value from the client
  }

  serialize(value: Date): number {
    return value.getTime(); // value sent to the client
  }

  parseLiteral(ast: ValueNode): Date {
    if (ast.kind === Kind.INT) {
      return new Date(ast.value);
    }
    return null;
  }
}
```

With this in place, register `DateScalar` as a provider.

```typescript

@Module({
  providers: [DateScalar],
})
export class CommonModule {}
```

Now we can use the `Date` scalar in type definitions.

```graphql

scalar Date
```

By default, the generated TypeScript definition for all scalars is `any` - which isn't particularly typesafe. But, you can configure how Nest generates typings for your custom scalars when you specify how to generate types:

```typescript

import { GraphQLDefinitionsFactory } from '@nestjs/graphql';
import { join } from 'path';

const definitionsFactory = new GraphQLDefinitionsFactory();

definitionsFactory.generate({
  typePaths: ['./src/**/*.graphql'],
  path: join(process.cwd(), 'src/graphql.ts'),
  outputAs: 'class',
  defaultScalarType: 'unknown',
  customScalarTypeMapping: {
    DateTime: 'Date',
    BigNumber: '_BigNumber',
  },
  additionalHeader: "import _BigNumber from 'bignumber.js'",
});
```

> **Hint** Alternatively, you can use a type reference instead, for example: `DateTime: Date`. In this case, `GraphQLDefinitionsFactory` will extract the name property of the specified type (`Date.name`) to generate TS definitions. Note: adding an import statement for non-built-in types (custom types) is required.

Now, given the following GraphQL custom scalar types:

```graphql

scalar DateTime
scalar BigNumber
scalar Payload
```

We will now see the following generated TypeScript definitions in `src/graphql.ts`:

```typescript

import _BigNumber from 'bignumber.js';

export type DateTime = Date;
export type BigNumber = _BigNumber;
export type Payload = unknown;
```

Here, we've used the `customScalarTypeMapping` property to supply a map of the types we wish to declare for our custom scalars. We've also provided an `additionalHeader` property so that we can add any imports required for these type definitions. Lastly, we've added a `defaultScalarType` of `'unknown'`, so that any custom scalars not specified in `customScalarTypeMapping` will be aliased to `unknown` instead of `any` (which [TypeScript recommends](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-0.html#new-unknown-top-type) using since 3.0 for added type safety).

> **Hint** Note that we've imported `_BigNumber` from `bignumber.js`; this is to avoid [circular type references](https://github.com/Microsoft/TypeScript/issues/12525#issuecomment-263166239).

----
url: https://docs.nestjs.com/v9/techniques/validation
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Validation](https://docs.nestjs.com/v9/techniques/validation#validation)
* [Overview](https://docs.nestjs.com/v9/techniques/validation#overview)
* [Using the built-in ValidationPipe](https://docs.nestjs.com/v9/techniques/validation#using-the-built-in-validationpipe)
* [Auto-validation](https://docs.nestjs.com/v9/techniques/validation#auto-validation)
* [Disable detailed errors](https://docs.nestjs.com/v9/techniques/validation#disable-detailed-errors)
* [Stripping properties](https://docs.nestjs.com/v9/techniques/validation#stripping-properties)
* [Transform payload objects](https://docs.nestjs.com/v9/techniques/validation#transform-payload-objects)
* [Explicit conversion](https://docs.nestjs.com/v9/techniques/validation#explicit-conversion)
* [Mapped types](https://docs.nestjs.com/v9/techniques/validation#mapped-types)
* [Parsing and validating arrays](https://docs.nestjs.com/v9/techniques/validation#parsing-and-validating-arrays)
* [WebSockets and Microservices](https://docs.nestjs.com/v9/techniques/validation#websockets-and-microservices)
* [Learn more](https://docs.nestjs.com/v9/techniques/validation#learn-more)

In the [Pipes](/v9/pipes) chapter, we went through the process of building simple pipes and binding them to controllers, methods or to the global app to demonstrate how the process works. Be sure to review that chapter to best understand the topics of this chapter. Here, we'll focus on various **real world** use cases of the `ValidationPipe`, and show how to use some of its advanced customization features.

#### Using the built-in ValidationPipe[#](/techniques/validation#using-the-built-in-validationpipe)

To begin using it, we first install the required dependency.

```bash

$ npm i --save class-validator class-transformer
```

> **Hint** The `ValidationPipe` is exported from the `@nestjs/common` package.

Because this pipe uses the [`class-validator`](https://github.com/typestack/class-validator) and [`class-transformer`](https://github.com/typestack/class-transformer) libraries, there are many options available. You configure these settings via a configuration object passed to the pipe. Following are the built-in options:

```typescript

export interface ValidationPipeOptions extends ValidatorOptions {
  transform?: boolean;
  disableErrorMessages?: boolean;
  exceptionFactory?: (errors: ValidationError[]) => any;
}
```

In addition to these, all `class-validator` options (inherited from the `ValidatorOptions` interface) are available:

| Option                    | Type       | Description                                                                                                                           |
| ------------------------- | ---------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| `enableDebugMessages`     | `boolean`  | If set to true, validator will print extra warning messages to the console when something is not right.                               |
| `skipUndefinedProperties` | `boolean`  | If set to true then validator will skip validation of all properties that are undefined in the validating object.                     |
| `skipNullProperties`      | `boolean`  | If set to true then validator will skip validation of all properties that are null in the validating object.                          |
| `skipMissingProperties`   | `boolean`  | If set to true then validator will skip validation of all properties that are null or undefined in the validating object.             |
| `whitelist`               | `boolean`  | If set to true, validator will strip validated (returned) object of any properties that do not use any validation decorators.         |
| `forbidNonWhitelisted`    | `boolean`  | If set to true, instead of stripping non-whitelisted properties validator will throw an exception.                                    |
| `forbidUnknownValues`     | `boolean`  | If set to true, attempts to validate unknown objects fail immediately.                                                                |
| `disableErrorMessages`    | `boolean`  | If set to true, validation errors will not be returned to the client.                                                                 |
| `errorHttpStatusCode`     | `number`   | This setting allows you to specify which exception type will be used in case of an error. By default it throws `BadRequestException`. |
| `exceptionFactory`        | `Function` | Takes an array of the validation errors and returns an exception object to be thrown.                                                 |
| `groups`                  | `string[]` | Groups to be used during validation of the object.                                                                                    |
| `always`                  | `boolean`  | Set default for `always` option of decorators. Default can be overridden in decorator options                                         |
| `strictGroups`            | `boolean`  | If `groups` is not given or is empty, ignore decorators with at least one group.                                                      |
| `dismissDefaultMessages`  | `boolean`  | If set to true, the validation will not use default messages. Error message always will be `undefined` if its not explicitly set.     |
| `validationError.target`  | `boolean`  | Indicates if target should be exposed in `ValidationError`.                                                                           |
| `validationError.value`   | `boolean`  | Indicates if validated value should be exposed in `ValidationError`.                                                                  |
| `stopAtFirstError`        | `boolean`  | When set to true, validation of the given property will stop after encountering the first error. Defaults to false.                   |

> **Notice** Find more information about the `class-validator` package in its [repository](https://github.com/typestack/class-validator).

#### Auto-validation[#](/techniques/validation#auto-validation)

We'll start by binding `ValidationPipe` at the application level, thus ensuring all endpoints are protected from receiving incorrect data.

```typescript

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.useGlobalPipes(new ValidationPipe());
  await app.listen(3000);
}
bootstrap();
```

To test our pipe, let's create a basic endpoint.

```typescript

@Post()
create(@Body() createUserDto: CreateUserDto) {
  return 'This action adds a new user';
}
```

> **Hint** Since TypeScript does not store metadata about **generics or interfaces**, when you use them in your DTOs, `ValidationPipe` may not be able to properly validate incoming data. For this reason, consider using concrete classes in your DTOs.

> **Hint** When importing your DTOs, you can't use a type-only import as that would be erased at runtime, i.e. remember to `import { CreateUserDto }` instead of `import type { CreateUserDto }`.

Now we can add a few validation rules in our `CreateUserDto`. We do this using decorators provided by the `class-validator` package, described in detail [here](https://github.com/typestack/class-validator#validation-decorators). In this fashion, any route that uses the `CreateUserDto` will automatically enforce these validation rules.

```typescript

import { IsEmail, IsNotEmpty } from 'class-validator';

export class CreateUserDto {
  @IsEmail()
  email: string;

  @IsNotEmpty()
  password: string;
}
```

With these rules in place, if a request hits our endpoint with an invalid `email` property in the request body, the application will automatically respond with a `400 Bad Request` code, along with the following response body:

```json

{
  "statusCode": 400,
  "error": "Bad Request",
  "message": ["email must be an email"]
}
```

In addition to validating request bodies, the `ValidationPipe` can be used with other request object properties as well. Imagine that we would like to accept `:id` in the endpoint path. To ensure that only numbers are accepted for this request parameter, we can use the following construct:

```typescript

@Get(':id')
findOne(@Param() params: FindOneParams) {
  return 'This action returns a user';
}
```

`FindOneParams`, like a DTO, is simply a class that defines validation rules using `class-validator`. It would look like this:

```typescript

import { IsNumberString } from 'class-validator';

export class FindOneParams {
  @IsNumberString()
  id: number;
}
```

#### Disable detailed errors[#](/techniques/validation#disable-detailed-errors)

Error messages can be helpful to explain what was incorrect in a request. However, some production environments prefer to disable detailed errors. Do this by passing an options object to the `ValidationPipe`:

```typescript

app.useGlobalPipes(
  new ValidationPipe({
    disableErrorMessages: true,
  }),
);
```

As a result, detailed error messages won't be displayed in the response body.

#### Stripping properties[#](/techniques/validation#stripping-properties)

Our `ValidationPipe` can also filter out properties that should not be received by the method handler. In this case, we can **whitelist** the acceptable properties, and any property not included in the whitelist is automatically stripped from the resulting object. For example, if our handler expects `email` and `password` properties, but a request also includes an `age` property, this property can be automatically removed from the resulting DTO. To enable such behavior, set `whitelist` to `true`.

```typescript

app.useGlobalPipes(
  new ValidationPipe({
    whitelist: true,
  }),
);
```

```typescript

@Post()
@UsePipes(new ValidationPipe({ transform: true }))
async create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

To enable this behavior globally, set the option on a global pipe:

```typescript

app.useGlobalPipes(
  new ValidationPipe({
    transform: true,
  }),
);
```

With the auto-transformation option enabled, the `ValidationPipe` will also perform conversion of primitive types. In the following example, the `findOne()` method takes one argument which represents an extracted `id` path parameter:

```typescript

@Get(':id')
findOne(@Param('id') id: number) {
  console.log(typeof id === 'number'); // true
  return 'This action returns a user';
}
```

By default, every path parameter and query parameter comes over the network as a `string`. In the above example, we specified the `id` type as a `number` (in the method signature). Therefore, the `ValidationPipe` will try to automatically convert a string identifier to a number.

#### Explicit conversion[#](/techniques/validation#explicit-conversion)

In the above section, we showed how the `ValidationPipe` can implicitly transform query and path parameters based on the expected type. However, this feature requires having auto-transformation enabled.

Alternatively (with auto-transformation disabled), you can explicitly cast values using the `ParseIntPipe` or `ParseBoolPipe` (note that `ParseStringPipe` is not needed because, as mentioned earlier, every path parameter and query parameter comes over the network as a `string` by default).

```typescript

@Get(':id')
findOne(
  @Param('id', ParseIntPipe) id: number,
  @Query('sort', ParseBoolPipe) sort: boolean,
) {
  console.log(typeof id === 'number'); // true
  console.log(typeof sort === 'boolean'); // true
  return 'This action returns a user';
}
```

> **Hint** The `ParseIntPipe` and `ParseBoolPipe` are exported from the `@nestjs/common` package.

#### Mapped types[#](/techniques/validation#mapped-types)

As you build out features like **CRUD** (Create/Read/Update/Delete) it's often useful to construct variants on a base entity type. Nest provides several utility functions that perform type transformations to make this task more convenient.

> **Warning** If your application uses the `@nestjs/swagger` package, see [this chapter](/v9/openapi/mapped-types) for more information about Mapped Types. Likewise, if you use the `@nestjs/graphql` package see [this chapter](/v9/graphql/mapped-types). Both packages heavily rely on types and so they require a different import to be used. Therefore, if you used `@nestjs/mapped-types` (instead of an appropriate one, either `@nestjs/swagger` or `@nestjs/graphql` depending on the type of your app), you may face various, undocumented side-effects.

When building input validation types (also called DTOs), it's often useful to build **create** and **update** variations on the same type. For example, the **create** variant may require all fields, while the **update** variant may make all fields optional.

Nest provides the `PartialType()` utility function to make this task easier and minimize boilerplate.

The `PartialType()` function returns a type (class) with all the properties of the input type set to optional. For example, suppose we have a **create** type as follows:

```typescript

export class CreateCatDto {
  name: string;
  age: number;
  breed: string;
}
```

By default, all of these fields are required. To create a type with the same fields, but with each one optional, use `PartialType()` passing the class reference (`CreateCatDto`) as an argument:

```typescript

export class UpdateCatDto extends PartialType(CreateCatDto) {}
```

> **Hint** The `PartialType()` function is imported from the `@nestjs/mapped-types` package.

The `PickType()` function constructs a new type (class) by picking a set of properties from an input type. For example, suppose we start with a type like:

```typescript

export class CreateCatDto {
  name: string;
  age: number;
  breed: string;
}
```

We can pick a set of properties from this class using the `PickType()` utility function:

```typescript

export class UpdateCatAgeDto extends PickType(CreateCatDto, ['age'] as const) {}
```

> **Hint** The `PickType()` function is imported from the `@nestjs/mapped-types` package.

The `OmitType()` function constructs a type by picking all properties from an input type and then removing a particular set of keys. For example, suppose we start with a type like:

```typescript

export class CreateCatDto {
  name: string;
  age: number;
  breed: string;
}
```

We can generate a derived type that has every property **except**`name` as shown below. In this construct, the second argument to `OmitType` is an array of property names.

```typescript

export class UpdateCatDto extends OmitType(CreateCatDto, ['name'] as const) {}
```

> **Hint** The `OmitType()` function is imported from the `@nestjs/mapped-types` package.

The `IntersectionType()` function combines two types into one new type (class). For example, suppose we start with two types like:

```typescript

export class CreateCatDto {
  name: string;
  breed: string;
}

export class AdditionalCatInfo {
  color: string;
}
```

We can generate a new type that combines all properties in both types.

```typescript

export class UpdateCatDto extends IntersectionType(
  CreateCatDto,
  AdditionalCatInfo,
) {}
```

> **Hint** The `IntersectionType()` function is imported from the `@nestjs/mapped-types` package.

The type mapping utility functions are composable. For example, the following will produce a type (class) that has all of the properties of the `CreateCatDto` type except for `name`, and those properties will be set to optional:

```typescript

export class UpdateCatDto extends PartialType(
  OmitType(CreateCatDto, ['name'] as const),
) {}
```

#### Parsing and validating arrays[#](/techniques/validation#parsing-and-validating-arrays)

TypeScript does not store metadata about generics or interfaces, so when you use them in your DTOs, `ValidationPipe` may not be able to properly validate incoming data. For instance, in the following code, `createUserDtos` won't be correctly validated:

```typescript

@Post()
createBulk(@Body() createUserDtos: CreateUserDto[]) {
  return 'This action adds new users';
}
```

To validate the array, create a dedicated class which contains a property that wraps the array, or use the `ParseArrayPipe`.

```typescript

@Post()
createBulk(
  @Body(new ParseArrayPipe({ items: CreateUserDto }))
  createUserDtos: CreateUserDto[],
) {
  return 'This action adds new users';
}
```

In addition, the `ParseArrayPipe` may come in handy when parsing query parameters. Let's consider a `findByIds()` method that returns users based on identifiers passed as query parameters.

```typescript

@Get()
findByIds(
  @Query('ids', new ParseArrayPipe({ items: Number, separator: ',' }))
  ids: number[],
) {
  return 'This action returns users by ids';
}
```

This construction validates the incoming query parameters from an HTTP `GET` request like the following:

```bash

GET /?ids=1,2,3
```

#### WebSockets and Microservices[#](/techniques/validation#websockets-and-microservices)

While this chapter shows examples using HTTP style applications (e.g., Express or Fastify), the `ValidationPipe` works the same for WebSockets and microservices, regardless of the transport method that is used.

#### Learn more[#](/techniques/validation#learn-more)

Read more about custom validators, error messages, and available decorators as provided by the `class-validator` package [here](https://github.com/typestack/class-validator).

----
url: https://docs.nestjs.com/v6/recipes/swagger
----

* [OpenAPI (Swagger)](https://docs.nestjs.com/v6/recipes/swagger#openapi-swagger)
* [Installation](https://docs.nestjs.com/v6/recipes/swagger#installation)
* [Bootstrap](https://docs.nestjs.com/v6/recipes/swagger#bootstrap)
* [Route parameters](https://docs.nestjs.com/v6/recipes/swagger#route-parameters)
* [Enums](https://docs.nestjs.com/v6/recipes/swagger#enums)
* [Enums schema](https://docs.nestjs.com/v6/recipes/swagger#enums-schema)
* [Arrays](https://docs.nestjs.com/v6/recipes/swagger#arrays)
* [Circular dependencies](https://docs.nestjs.com/v6/recipes/swagger#circular-dependencies)
* [Generics and interfaces](https://docs.nestjs.com/v6/recipes/swagger#generics-and-interfaces)
* [Raw definitions](https://docs.nestjs.com/v6/recipes/swagger#raw-definitions)
* [Extra models](https://docs.nestjs.com/v6/recipes/swagger#extra-models)
* [oneOf, anyOf, allOf](https://docs.nestjs.com/v6/recipes/swagger#oneof-anyof-allof)
* [Multiple specifications](https://docs.nestjs.com/v6/recipes/swagger#multiple-specifications)
* [Tags](https://docs.nestjs.com/v6/recipes/swagger#tags)
* [Headers](https://docs.nestjs.com/v6/recipes/swagger#headers)
* [Responses](https://docs.nestjs.com/v6/recipes/swagger#responses)
* [Global prefix](https://docs.nestjs.com/v6/recipes/swagger#global-prefix)
* [Security](https://docs.nestjs.com/v6/recipes/swagger#security)
* [Basic authentication](https://docs.nestjs.com/v6/recipes/swagger#basic-authentication)
* [Bearer authentication](https://docs.nestjs.com/v6/recipes/swagger#bearer-authentication)
* [OAuth2 authentication](https://docs.nestjs.com/v6/recipes/swagger#oauth2-authentication)
* [File upload](https://docs.nestjs.com/v6/recipes/swagger#file-upload)
* [Extensions](https://docs.nestjs.com/v6/recipes/swagger#extensions)
* [Decorators](https://docs.nestjs.com/v6/recipes/swagger#decorators)
* [Plugin](https://docs.nestjs.com/v6/recipes/swagger#plugin)
* [Migration to 4.0](https://docs.nestjs.com/v6/recipes/swagger#migration-to-40)
* [Example](https://docs.nestjs.com/v6/recipes/swagger#example)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/recipes/swagger.md "Suggest Edits")

### OpenAPI (Swagger)

The [OpenAPI](https://swagger.io/specification/) specification is a language-agnostic definition format used to describe RESTful APIs. Nest provides a dedicated [module](https://github.com/nestjs/swagger) which allows generating such a specification by leveraging decorators.

#### Installation[#](/recipes/swagger#installation)

To begin using it, we first install the required dependencies.

```bash

$ npm install --save @nestjs/swagger swagger-ui-express
```

If you use fastify, install `fastify-swagger` instead of `swagger-ui-express`:

```bash

$ npm install --save @nestjs/swagger fastify-swagger
```

#### Bootstrap[#](/recipes/swagger#bootstrap)

Once the installation process is complete, open the `main.ts` file and initialize Swagger using the `SwaggerModule` class:

```typescript

import { NestFactory } from '@nestjs/core';
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);

  const options = new DocumentBuilder()
    .setTitle('Cats example')
    .setDescription('The cats API description')
    .setVersion('1.0')
    .addTag('cats')
    .build();
  const document = SwaggerModule.createDocument(app, options);
  SwaggerModule.setup('api', app, document);

  await app.listen(3000);
}
bootstrap();
```

The `DocumentBuilder` helps to structure a base document that conforms to the OpenAPI Specification. It provides several methods that allow setting such properties as title, description, version, etc. In order to create a full document (with all HTTP routes defined) we use the `createDocument()` method of the `SwaggerModule` class. This method takes two arguments, an application instance and a Swagger options object.

Once we create a document, we can call `setup()` method. It accepts:

1. the path to mount the Swagger UI
2. an application instance
3. the document object instantiated above

Now you can run the following command to start the HTTP server:

```bash

$ npm run start
```

While the application is running, open your browser and navigate to `http://localhost:3000/api`. You should see the Swagger UI.

The `SwaggerModule` automatically reflects all of your endpoints. Also, in order to display the Swagger UI, `@nestjs/swagger` makes use of either `swagger-ui-express` or `fastify-swagger` depending on the platform.

> **Hint** To generate and download a Swagger JSON file, navigate to `http://localhost:3000/api-json` in your browser (assuming that your Swagger documentation is available under `http://localhost:3000/api`).

#### Route parameters[#](/recipes/swagger#route-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:

```typescript

@Post()
async create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

> **Hint** To explicitly set the body definition use the `@ApiBody()` decorator (`@nestjs/swagger` package).

Based on the `CreateCatDto`, the module definition will be created:

As you can see, the definition is empty although the class has a few declared properties. In order to make the class properties visible to the `SwaggerModule`, we have to either annotate them with the `@ApiProperty()` decorator or use a CLI plugin (read more in the **Plugin** section) which will do it automatically:

```typescript

import { ApiProperty } from '@nestjs/swagger';

export class CreateCatDto {
  @ApiProperty()
  name: string;

  @ApiProperty()
  age: number;

  @ApiProperty()
  breed: string;
}
```

> **Hint** Consider using the Swagger plugin (see [Plugin](/recipes/swagger#plugin) section) which will automatically do it for you.

Let's open the browser and verify the generated `CreateCatDto` model:

In addition, the `@ApiProperty()` decorator allows setting various [Schema Object](https://swagger.io/specification/#schemaObject) properties:

```typescript

@ApiProperty({
  description: 'The age of a cat',
  min: 1,
  default: 1,
})
age: number;
```

> **Hint** Instead of explicitly typing the `@ApiProperty({ required: false })` you can use `@ApiPropertyOptional()` short-hand decorator.

In order to explicitly set the type of the property, use the `type` key:

```typescript

@ApiProperty({
  type: Number,
})
age: number;
```

#### Enums[#](/recipes/swagger#enums)

To identify an `enum`, we must manually set the `enum` property on the `@ApiProperty` with an array of values.

```typescript

@ApiProperty({ enum: ['Admin', 'Moderator', 'User']})
role: UserRole;
```

Alternatively, define an actual TypeScript enum as follows:

```typescript

export enum UserRole {
  Admin = 'Admin',
  Moderator = 'Moderator',
  User = 'User',
}
```

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

```typescript

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

With `isArray` set to **true**, the `enum` can be selected as a **multi-select**:

#### Enums schema[#](/recipes/swagger#enums-schema)

By default, the `enum` property will add a raw definition of [Enum](https://swagger.io/docs/specification/data-models/enums/) on the `parameter`.

```yaml

CatDetail:
  type: 'object'
  properties:
    ...
    - breed:
        type: 'string'
        enum:
          - Persian
          - Tabby
          - Siamese
```

The above specification works fine for most cases. However, if you are utilizing a tool that takes the specification as **input** and generates **client-side** code, you might run into a problem with the generated code containing duplicated `enums`. Consider the following code snippet:

```typescript

// generated client-side code
export class CatDetail {
   breed: CatDetailEnum;
}

export class CatInformation {
  breed: CatInformationEnum;
}

export enum CatDetailEnum {
  Persian = 'Persian',
  Tabby = 'Tabby',
  Siamese = 'Siamese'
}

export enum CatInformationEnum {
  Persian = 'Persian',
  Tabby = 'Tabby',
  Siamese = 'Siamese'
}
```

> **Hint** The above snippet is generated using a tool called [NSwag](https://github.com/RicoSuter/NSwag).

You can see that now you have two `enums` that are exactly the same. To address this issue, you can pass an `enumName` next to `enum` property in your decorator.

```typescript

export class CatDetail {
   @ApiProperty({ enum: CatBreed, enumName: 'CatBreed' })
   breed: CatBreed;
}
```

`enumName` enables `nestjs/swagger` to turn `CatBreed` into its own `schema` which in turns makes `CatBreed` reusable. The specification will look like the following:

```yaml

CatDetail:
  type: 'object'
  properties:
    ...
    - breed:
        schema:
          $ref: '#/components/schemas/CatBreed'
CatBreed:
  type: string
  enum:
    - Persian
    - Tabby
    - Siamese
```

> **Hint** Any **decorator** that takes `enum` as a property will also take `enumName`.

#### Arrays[#](/recipes/swagger#arrays)

When the property is an array, we must manually indicate the array type as shown below:

```typescript

@ApiProperty({ type: [String] })
names: string[];
```

> **Hint** Consider using the Swagger plugin (see [Plugin](/recipes/swagger#plugin) section) which will automatically detect arrays.

Either include the type as the first element of an array (as shown above) or set the `isArray` property to `true`.

## Official enterprise support

* Providing technical guidance
* Performing in-depth code reviews
* Mentoring team members
* Advising best practices

[Explore more](https://enterprise.nestjs.com "Enterprise | NestJS - A progressive Node.js framework")

#### Circular dependencies[#](/recipes/swagger#circular-dependencies)

When you have circular dependencies between classes, use a lazy function to provide the `SwaggerModule` with type information:

```typescript

@ApiProperty({ type: () => Node })
node: Node;
```

> **Hint** Consider using the Swagger plugin (see [Plugin](/recipes/swagger#plugin) section) which will automatically detect circular dependencies.

#### Generics and interfaces[#](/recipes/swagger#generics-and-interfaces)

Since TypeScript does not store metadata about generics or interfaces, when you use them in your DTOs, `SwaggerModule` may not be able to properly generate model definitions at runtime. For instance, below code won't be correctly inspected by the Swagger module:

```typescript

createBulk(@Body() usersDto: CreateUserDto[])
```

In order to overcome this limitation, you can set the type explicitly:

```typescript

@ApiBody({ type: [CreateUserDto] })
createBulk(@Body() usersDto: CreateUserDto[])
```

#### Raw definitions[#](/recipes/swagger#raw-definitions)

In some specific scenarios (e.g. deeply nested arrays, matrices), you may want to describe your type by hand.

```typescript

@ApiProperty({
  type: 'array',
  items: {
    type: 'array',
    items: {
      type: 'number',
    },
  },
})
coords: number[][];
```

Likewise, in order to define your input/output content manually in controller classes, use the `schema` property:

```typescript

@ApiBody({
  schema: {
    type: 'array',
    items: {
      type: 'array',
      items: {
        type: 'number',
      },
    },
  },
})
async create(@Body() coords: number[][]) {}
```

#### Extra models[#](/recipes/swagger#extra-models)

In order to define additional models that should be inspected by Swagger module, use the `@ApiExtraModels()` decorator:

```typescript

@ApiExtraModels(ExtraModel)
export class CreateCatDto {}
```

Then, you can get the reference (`$ref`) to your model using `getSchemaPath(ExtraModel)`:

```typescript

'application/vnd.api+json': {
   schema: { $ref: getSchemaPath(ExtraModel) },
},
```

#### oneOf, anyOf, allOf[#](/recipes/swagger#oneof-anyof-allof)

In order to combine schemas, you can use `oneOf`, `anyOf` or `allOf` keywords ([read more](https://swagger.io/docs/specification/data-models/oneof-anyof-allof-not/)).

```typescript

@ApiProperty({
  oneOf: [
    { $ref: getSchemaPath(Cat) },
    { $ref: getSchemaPath(Dog) },
  ],
})
pet: Cat | Dog;
```

> **Hint**`getSchemaPath()` function is imported from `@nestjs/swagger`.

Both `Cat` and `Dog` must be defined as extra models using the `@ApiExtraModels()` decorator (at the class-level).

#### Multiple specifications[#](/recipes/swagger#multiple-specifications)

The `SwaggerModule` provides a way to support multiple specifications. In other words, you can serve different documentation, with different UIs, on different endpoints.

To support multiple specifications, your application must be written with a modular approach. The `createDocument()` method takes in a 3rd argument, `extraOptions`, which is an object with a the property `include`. The `include` property has a value which is an array of modules.

You can setup multiple specifications support as shown below:

```typescript

import { NestFactory } from '@nestjs/core';
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);

  /**
   * createDocument(application, configurationOptions, extraOptions);
   *
   * createDocument method takes in an optional 3rd argument "extraOptions"
   * which is an object with "include" property where you can pass an Array
   * of Modules that you want to include in that Swagger Specification
   * E.g: CatsModule and DogsModule will have two separate Swagger Specifications which
   * will be exposed on two different SwaggerUI with two different endpoints.
   */

  const options = new DocumentBuilder()
    .setTitle('Cats example')
    .setDescription('The cats API description')
    .setVersion('1.0')
    .addTag('cats')
    .build();

  const catDocument = SwaggerModule.createDocument(app, options, {
    include: [CatsModule],
  });
  SwaggerModule.setup('api/cats', app, catDocument);

  const secondOptions = new DocumentBuilder()
    .setTitle('Dogs example')
    .setDescription('The dogs API description')
    .setVersion('1.0')
    .addTag('dogs')
    .build();

  const dogDocument = SwaggerModule.createDocument(app, secondOptions, {
    include: [DogsModule],
  });
  SwaggerModule.setup('api/dogs', app, dogDocument);

  await app.listen(3000);
}
bootstrap();
```

Now you can start your server with the following command:

```bash

$ npm run start
```

Navigate to `http://localhost:3000/api/cats` to see the Swagger UI for cats:

In turn, `http://localhost:3000/api/dogs` will expose the Swagger UI for dogs:

#### Tags[#](/recipes/swagger#tags)

To attach a controller to a specific tag, use the `@ApiTags(...tags)` decorator.

```typescript

@ApiTags('cats')
@Controller('cats')
export class CatsController {}
```

#### Headers[#](/recipes/swagger#headers)

To define custom headers that are expected as part of the request, use `@ApiHeader()`.

```typescript

@ApiHeader({
  name: 'X-MyHeader',
  description: 'Custom header',
})
@Controller('cats')
export class CatsController {}
```

#### Responses[#](/recipes/swagger#responses)

To define a custom HTTP response, we use `@ApiResponse()` decorator.

```typescript

@Post()
@ApiResponse({ status: 201, description: 'The record has been successfully created.'})
@ApiResponse({ status: 403, description: 'Forbidden.'})
async create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

Nest provides a set of short-hand **API response** decorators that inherit from the `@ApiResponse` decorator:

* `@ApiDefaultResponse()`

```typescript

@Post()
@ApiCreatedResponse({ description: 'The record has been successfully created.'})
@ApiForbiddenResponse({ description: 'Forbidden.'})
async create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

To specify a return model for a request, we must create a class and annotate all properties with the `@ApiProperty()` decorator.

```typescript

export class Cat {
  @ApiProperty()
  id: number;

  @ApiProperty()
  name: string;

  @ApiProperty()
  age: number;

  @ApiProperty()
  breed: string;
}
```

Then, `Cat` model must be used in combination with the `type` property of the response decorator.

```typescript

@ApiTags('cats')
@Controller('cats')
export class CatsController {
  @Post()
  @ApiCreatedResponse({
    description: 'The record has been successfully created.',
    type: Cat,
  })
  async create(@Body() createCatDto: CreateCatDto): Promise<Cat> {
    return this.catsService.create(createCatDto);
  }
}
```

Let's open the browser and verify the generated `Cat` model:

#### Global prefix[#](/recipes/swagger#global-prefix)

To ignore a global prefix for routes set through `setGlobalPrefix()`, use `ignoreGlobalPrefix`:

```typescript

const document = SwaggerModule.createDocument(app, options, {
  ignoreGlobalPrefix: true,
});
```

#### Security[#](/recipes/swagger#security)

To define which security mechanisms should be used for a specific operation, use the `@ApiSecurity()` decorator.

```typescript

@ApiSecurity('basic')
@Controller('cats')
export class CatsController {}
```

Before you run your application, remember to add the security definition to your base document using `DocumentBuilder`:

```typescript

const options = new DocumentBuilder().addSecurity('basic', {
  type: 'http',
  scheme: 'basic',
});
```

Some of the most popular authentication techniques are predefined (e.g. `basic` and `bearer`) and therefore you don't have to define security mechanisms manually as shown above.

## Learn the right way!

* 60+ chapters
* 4+ hours of videos
* Official certificate
* Deep-dive sessions

[Explore official courses](https://courses.nestjs.com "Courses | NestJS - A node.js framework built on top of TypeScript")

#### Basic authentication[#](/recipes/swagger#basic-authentication)

To enable basic authentication, use `@ApiBasicAuth()`.

```typescript

@ApiBasicAuth()
@Controller('cats')
export class CatsController {}
```

Before you run your application, remember to add the security definition to your base document using `DocumentBuilder`:

```typescript

const options = new DocumentBuilder().addBasicAuth();
```

#### Bearer authentication[#](/recipes/swagger#bearer-authentication)

To enable bearer authentication, use `@ApiBearerAuth()`.

```typescript

@ApiBearerAuth()
@Controller('cats')
export class CatsController {}
```

Before you run your application, remember to add the security definition to your base document using `DocumentBuilder`:

```typescript

const options = new DocumentBuilder().addBearerAuth();
```

#### OAuth2 authentication[#](/recipes/swagger#oauth2-authentication)

To enable OAuth2, use `@ApiOAuth2()`.

```typescript

@ApiOAuth2(['pets:write'])
@Controller('cats')
export class CatsController {}
```

Before you run your application, remember to add the security definition to your base document using `DocumentBuilder`:

```typescript

const options = new DocumentBuilder().addOAuth2();
```

#### File upload[#](/recipes/swagger#file-upload)

You can enable file upload for a specific method with the `@ApiBody` decorator together with `@ApiConsumes()`. Here's a full example using the [File Upload](/v6/techniques/file-upload) technique:

```typescript

@UseInterceptors(FileInterceptor('file'))
@ApiConsumes('multipart/form-data')
@ApiBody({
  description: 'List of cats',
  type: FileUploadDto,
})
uploadFile(@UploadedFile() file) {}
```

Where `FileUploadDto` is defined as follows:

```typescript

class FileUploadDto {
  @ApiProperty({ type: 'string', format: 'binary' })
  file: any;
}
```

#### Extensions[#](/recipes/swagger#extensions)

To add an Extension to a request use the `@ApiExtension()` decorator. The extension name must be prefixed with `x-`.

```typescript

@ApiExtension('x-foo', { hello: 'world' })
```

#### Decorators[#](/recipes/swagger#decorators)

All of the available OpenAPI decorators have an `Api` prefix to distinguish them from the core decorators. Below is a full list of the exported decorators along with a designation of the level at which the decorator may be applied.

| `@ApiOperation()`        | Method              |
| ------------------------ | ------------------- |
| `@ApiResponse()`         | Method / Controller |
| `@ApiProduces()`         | Method / Controller |
| `@ApiConsumes()`         | Method / Controller |
| `@ApiBearerAuth()`       | Method / Controller |
| `@ApiOAuth2()`           | Method / Controller |
| `@ApiBasicAuth()`        | Method / Controller |
| `@ApiSecurity()`         | Method / Controller |
| `@ApiExtraModels()`      | Method / Controller |
| `@ApiBody()`             | Method              |
| `@ApiParam()`            | Method              |
| `@ApiQuery()`            | Method              |
| `@ApiHeader()`           | Method / Controller |
| `@ApiExcludeEndpoint()`  | Method              |
| `@ApiTags()`             | Method / Controller |
| `@ApiProperty()`         | Model               |
| `@ApiPropertyOptional()` | Model               |
| `@ApiHideProperty()`     | Model               |
| `@ApiExtension()`        | Method              |

#### Plugin[#](/recipes/swagger#plugin)

TypeScript's metadata reflection system has several limitations which make it impossible to, for instance, determine what properties a class consists of or recognize whether a given property is optional or required. However, some of these constraints can be addressed at compilation time. Nest provides a plugin that enhances the TypeScript compilation process to reduce the amount of boilerplate code required.

> **Hint** This plugin is **opt-in**. If you prefer, you can declare all decorators manually, or only specific decorators where you need them.

The Swagger plugin will automatically:

* annotate all DTO properties with `@ApiProperty` unless `@ApiHideProperty` is used
* set the `required` property depending on the question mark (e.g. `name?: string` will set `required: false`)
* set the `type` or `enum` property depending on the type (supports arrays as well)
* set the `default` property based on the assigned default value
* set several validation rules based on `class-validator` decorators (if `classValidatorShim` set to `true`)
* add a response decorator to every endpoint with a proper status and `type` (response model)

Previously, if you wanted to provide an interactive experience with the Swagger UI, you had to duplicate a lot of code to let the package knows how your models/components should be declared in the specification. For example, you could define a simple `CreateUserDto` class as follows:

```typescript

export class CreateUserDto {
  @ApiProperty()
  email: string;

  @ApiProperty()
  password: string;

  @ApiProperty({ enum: RoleEnum, default: [], isArray: true })
  roles: RoleEnum[] = [];

  @ApiProperty({ required: false, default: true })
  isEnabled?: boolean = true;
}
```

While it's not a big deal with medium-sized projects, it becomes pretty verbose & clunky once you have a large set of classes.

Now, with the Swagger plugin enabled, the above class definition can be declared simply:

```typescript

export class CreateUserDto {
  email: string;
  password: string;
  roles: RoleEnum[] = [];
  isEnabled?: boolean = true;
}
```

The plugin adds appropriate decorators on the fly based on the **Abstract Syntax Tree**. Hence, you no longer have to struggle with `@ApiProperty` decorators scattered throughout the entire project.

> **Hint** The plugin will automatically generate any missing swagger properties, but if you need to override them, you simply set them explicitly via `@ApiProperty()`.

In order to enable the plugin, simply open `nest-cli.json` (if you use [Nest CLI](/v6/cli/overview)) and add the following `plugins` configuration:

```javascript

{
  "collection": "@nestjs/schematics",
  "sourceRoot": "src",
  "compilerOptions": {
    "plugins": ["@nestjs/swagger/plugin"]
  }
}
```

You can use the `options` property to customize the behavior of the plugin.

```javascript

"plugins": [
  {
    "name": "@nestjs/swagger/plugin",
    "options": {
      "classValidatorShim": false
    }
  }
]
```

The `options` property has to fulfill the following interface:

```typescript

export interface PluginOptions {
  dtoFileNameSuffix?: string[];
  controllerFileNameSuffix?: string[];
  classValidatorShim?: boolean;
}
```

| Option                     | Default                     | Description                                                                                                                             |
| -------------------------- | --------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| `dtoFileNameSuffix`        | `['.dto.ts', '.entity.ts']` | DTO (Data Transfer Object) files suffix                                                                                                 |
| `controllerFileNameSuffix` | `.controller.ts`            | Controller files suffix                                                                                                                 |
| `classValidatorShim`       | `true`                      | If set to true, the module will reuse `class-validator` validation decorators (e.g. `@Max(10)` will add `max: 10` to schema definition) |

If you don't use the CLI but instead have a custom `webpack` configuration, you can use this plugin in combination with `ts-loader`:

```javascript

getCustomTransformers: (program: any) => ({
  before: [require('@nestjs/swagger/plugin').before({}, program)]
}),
```

#### Migration to 4.0[#](/recipes/swagger#migration-to-40)

If you're currently using `@nestjs/swagger@3.*`, note the following breaking/API changes in version 4.0.

* `@ApiOperation({ title: 'test' })` is now`@ApiOperation({ summary: 'test' })`

* `setSchemes` has been removed

The following methods have been added:

* `addServer`
* `addApiKey`
* `addBasicAuth`
* `addSecurity`
* `addSecurityRequirements`

## Hoodies, T-shirts, and accessories!

Support our future development by shopping in the official store!

[See more](https://nestjs.threadless.com/ "Shop | NestJS - A node.js framework built on top of TypeScript")

#### Example[#](/recipes/swagger#example)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/11-swagger).

----
url: https://docs.nestjs.com/v6/graphql/tooling
----

* [Other features](https://docs.nestjs.com/v6/graphql/tooling#other-features)
* [Overview](https://docs.nestjs.com/v6/graphql/tooling#overview)
* [Execution context](https://docs.nestjs.com/v6/graphql/tooling#execution-context)
* [Exception filters](https://docs.nestjs.com/v6/graphql/tooling#exception-filters)
* [Custom decorators](https://docs.nestjs.com/v6/graphql/tooling#custom-decorators)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/guards-interceptors.md "Suggest Edits")

### Other features

In the GraphQL world, there is a lot of debate about handling issues like **authentication**, or **side-effects** of operations. Should we handle things inside the business logic? Should we use a higher-order function to enhance queries and mutations with authorization logic? Or should we use [schema directives](https://www.apollographql.com/docs/apollo-server/schema/directives/)? There is no single one-size-fits-all answer to these questions.

Nest helps address these issues with its cross-platform features like [guards](/v6/guards) and [interceptors](/v6/interceptors). The philosophy is to reduce redundancy and provide tooling that helps create well-structured, readable, and consistent applications.

#### Overview[#](/graphql/tooling#overview)

You can use standard [guards](/v6/guards), [interceptors](/v6/interceptors), [filters](/v6/exception-filters) and [pipes](/v6/pipes) in the same fashion with GraphQL as with any RESTful application. Additionally, you can easily create your own decorators by leveraging the [custom decorators](/v6/custom-decorators) feature. Let's take a look at a sample GraphQL query handler.

```typescript

@Query('author')
@UseGuards(AuthGuard)
async getAuthor(@Args('id', ParseIntPipe) id: number) {
  return this.authorsService.findOneById(id);
}
```

As you can see, GraphQL works with both guards and pipes in the same way as HTTP REST handlers. Because of this, you can move your authentication logic to a guard; you can even reuse the same guard class across both a REST and GraphQL API interface. Similarly, interceptors work across both types of applications in the same way:

```typescript

@Mutation()
@UseInterceptors(EventsInterceptor)
async upvotePost(@Args('postId') postId: number) {
  return this.postsService.upvoteById({ id: postId });
}
```

#### Execution context[#](/graphql/tooling#execution-context)

Since GraphQL receives a different type of data in the incoming request, the [`ExecutionContext`](https://docs.nestjs.com/fundamentals/execution-context) received by both guards and interceptors is somewhat different with GraphQL vs. REST. GraphQL resolvers have a distinct set of arguments: `root`, `args`, `context`, and `info`. Thus guards and interceptors must transform the generic `ExecutionContext` to a `GqlExecutionContext`. This is straightforward:

```typescript

import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common';
import { GqlExecutionContext } from '@nestjs/graphql';

@Injectable()
export class AuthGuard implements CanActivate {
  canActivate(context: ExecutionContext): boolean {
    const ctx = GqlExecutionContext.create(context);
    return true;
  }
}
```

The GraphQL context object returned by `GqlExecutionContext.create()` exposes a **get** method for each GraphQL resolver argument (e.g., `getArgs()`, `getContext()`, etc). Once transformed, we can easily pick out any GraphQL argument for the current request.

#### Exception filters[#](/graphql/tooling#exception-filters)

Nest standard [exception filters](/v6/exception-filters) are compatible with GraphQL applications as well. As with `ExecutionContext`, GraphQL apps should transform the `ArgumentsHost` object to a `GqlArgumentsHost` object.

```typescript

@Catch(HttpException)
export class HttpExceptionFilter implements GqlExceptionFilter {
  catch(exception: HttpException, host: ArgumentsHost) {
    const gqlHost = GqlArgumentsHost.create(host);
    return exception;
  }
}
```

> **Hint** Both `GqlExceptionFilter` and `GqlArgumentsHost` are imported from the `@nestjs/graphql` package.

Note that unlike the REST case, you don't use the native `response` object to generate a response.

#### Custom decorators[#](/graphql/tooling#custom-decorators)

As mentioned, the [custom decorators](/v6/custom-decorators) feature works as expected with GraphQL resolvers. The only difference is that the factory function takes an array of GraphQL request arguments as its second argument, instead of a single `request` object (as with REST applications).

```typescript

export const User = createParamDecorator(
  (data, [root, args, ctx, info]) => ctx.user,
);
```

Use the `@User()` custom decorator as follows:

```typescript

@Mutation()
async upvotePost(
  @User() user: UserEntity,
  @Args('postId') postId: number,
) {}
```

> **Hint** In the above example, we have assumed that the `user` object is assigned to the context of your GraphQL application.

----
url: https://docs.nestjs.com/v11/controllers
----

* [Controllers](https://docs.nestjs.com/v11/controllers#controllers)
* [Routing](https://docs.nestjs.com/v11/controllers#routing)
* [Request object](https://docs.nestjs.com/v11/controllers#request-object)
* [Resources](https://docs.nestjs.com/v11/controllers#resources)
* [Route wildcards](https://docs.nestjs.com/v11/controllers#route-wildcards)
* [Status code](https://docs.nestjs.com/v11/controllers#status-code)
* [Response headers](https://docs.nestjs.com/v11/controllers#response-headers)
* [Redirection](https://docs.nestjs.com/v11/controllers#redirection)
* [Route parameters](https://docs.nestjs.com/v11/controllers#route-parameters)
* [Sub-domain routing](https://docs.nestjs.com/v11/controllers#sub-domain-routing)
* [State sharing](https://docs.nestjs.com/v11/controllers#state-sharing)
* [Asynchronicity](https://docs.nestjs.com/v11/controllers#asynchronicity)
* [Request payloads](https://docs.nestjs.com/v11/controllers#request-payloads)
* [Query parameters](https://docs.nestjs.com/v11/controllers#query-parameters)
* [Handling errors](https://docs.nestjs.com/v11/controllers#handling-errors)
* [Full resource sample](https://docs.nestjs.com/v11/controllers#full-resource-sample)
* [Getting up and running](https://docs.nestjs.com/v11/controllers#getting-up-and-running)
* [Library-specific approach](https://docs.nestjs.com/v11/controllers#library-specific-approach)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/controllers.md "Suggest Edits")

### Controllers

Controllers are responsible for handling incoming **requests** and sending **responses** back to the client.

A controller's purpose is to handle specific requests for the application. The **routing** mechanism determines which controller will handle each request. Often, a controller has multiple routes, and each route can perform a different action.

To create a basic controller, we use classes and **decorators**. Decorators link classes with the necessary metadata, allowing Nest to create a routing map that connects requests to their corresponding controllers.

> **Hint** To quickly create a CRUD controller with built-in [validation](https://docs.nestjs.com/techniques/validation), you can use the CLI's [CRUD generator](https://docs.nestjs.com/recipes/crud-generator#crud-generator): `nest g resource [name]`.

#### Routing[#](/controllers#routing)

In the following example, we’ll use the `@Controller()` decorator, which is **required** to define a basic controller. We'll specify an optional route path prefix of `cats`. Using a path prefix in the `@Controller()` decorator helps us group related routes together and reduces repetitive code. For example, if we want to group routes that manage interactions with a cat entity under the `/cats` path, we can specify the `cats` path prefix in the `@Controller()` decorator. This way, we don't need to repeat that portion of the path for each route in the file.

cats.controller.ts

JS TS

```typescript

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

@Controller('cats')
export class CatsController {
  @Get()
  findAll(): string {
    return 'This action returns all cats';
  }
}
```

```typescript

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

@Controller('cats')
export class CatsController {
  @Get()
  findAll() {
    return 'This action returns all cats';
  }
}
```

> **Hint** To create a controller using the CLI, simply execute the `$ nest g controller [name]` command.

The `@Get()` HTTP request method decorator placed before the `findAll()` method tells Nest to create a handler for a specific endpoint for HTTP requests. This endpoint is defined by the HTTP request method (GET in this case) and the route path. So, what is the route path? The route path for a handler is determined by combining the (optional) prefix declared for the controller with any path specified in the method's decorator. Since we've set a prefix (`cats`) for every route and haven't added any specific path in the method decorator, Nest will map `GET /cats` requests to this handler.

As mentioned, the route path includes both the optional controller path prefix **and** any path string specified in the method's decorator. For example, if the controller prefix is `cats` and the method decorator is `@Get('breed')`, the resulting route will be `GET /cats/breed`.

In our example above, when a GET request is made to this endpoint, Nest routes the request to the user-defined `findAll()` method. Note that the method name we choose here is entirely arbitrary. While we must declare a method to bind the route to, Nest doesn’t attach any specific significance to the method name.

This method will return a 200 status code along with the associated response, which in this case is just a string. Why does this happen? To explain, we first need to introduce the concept that Nest uses two **different** options for manipulating responses:

|                        |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Standard (recommended) | Using this built-in method, when a request handler returns a JavaScript object or array, it will **automatically** be serialized to JSON. When it returns a JavaScript primitive type (e.g., `string`, `number`, `boolean`), however, Nest will send just the value without attempting to serialize it. This makes response handling simple: just return the value, and Nest takes care of the rest. Furthermore, the response's **status code** is always 200 by default, except for POST requests which use 201. We can easily change this behavior by adding the `@HttpCode(...)` decorator at a handler-level (see [Status codes](controllers#status-code)). |
| Library-specific       | We can use the library-specific (e.g., Express) [response object](https://expressjs.com/en/api.html#res), which can be injected using the `@Res()` decorator in the method handler signature (e.g., `findAll(@Res() response)`). With this approach, you have the ability to use the native response handling methods exposed by that object. For example, with Express, you can construct responses using code like `response.status(200).send()`.                                                                                                                                                                                                              |

> **Warning** Nest detects when the handler is using either `@Res()` or `@Next()`, indicating you have chosen the library-specific option. If both approaches are used at the same time, the Standard approach is **automatically disabled** for this single route and will no longer work as expected. To use both approaches at the same time (for example, by injecting the response object to only set cookies/headers but still leave the rest to the framework), you must set the `passthrough` option to `true` in the `@Res({ passthrough: true })` decorator.

## Explore your graph with NestJS Devtools

* Graph visualizer
* Routes navigator
* Interactive playground
* CI/CD integration

[Sign up](https://devtools.nestjs.com "Devtools | NestJS - A node.js framework built on top of TypeScript")

#### Request object[#](/controllers#request-object)

Handlers often need access to the client’s **request** details. Nest provides access to the [request object](https://expressjs.com/en/api.html#req) from the underlying platform (Express by default). You can access the request object by instructing Nest to inject it using the `@Req()` decorator in the handler’s signature.

cats.controller.ts

JS TS

```typescript

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

@Controller('cats')
export class CatsController {
  @Get()
  findAll(@Req() request: Request): string {
    return 'This action returns all cats';
  }
}
```

```typescript

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

@Controller('cats')
export class CatsController {
  @Get()
  @Bind(Req())
  findAll(request) {
    return 'This action returns all cats';
  }
}
```

> **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.

|                           |                                     |
| ------------------------- | ----------------------------------- |
| `@Request(), @Req()`      | `req`                               |
| `@Response(), @Res()`\*   | `res`                               |
| `@Next()`                 | `next`                              |
| `@Session()`              | `req.session`                       |
| `@Param(key?: string)`    | `req.params` / `req.params[key]`    |
| `@Body(key?: string)`     | `req.body` / `req.body[key]`        |
| `@Query(key?: string)`    | `req.query` / `req.query[key]`      |
| `@Headers(name?: string)` | `req.headers` / `req.headers[name]` |
| `@Ip()`                   | `req.ip`                            |
| `@HostParam()`            | `req.hosts`                         |

\* For compatibility with typings across underlying HTTP platforms (e.g., Express and Fastify), Nest provides `@Res()` and `@Response()` decorators. `@Res()` is simply an alias for `@Response()`. Both directly expose the underlying native platform `response` object interface. When using them, you should also import the typings for the underlying library (e.g., `@types/express`) to take full advantage. Note that when you inject either `@Res()` or `@Response()` in a method handler, you put Nest into **Library-specific mode** for that handler, and you become responsible for managing the response. When doing so, you must issue some kind of response by making a call on the `response` object (e.g., `res.json(...)` or `res.send(...)`), or the HTTP server will hang.

> **Hint** To learn how to create your own custom decorators, visit [this](/v11/custom-decorators) chapter.

#### Resources[#](/controllers#resources)

Earlier, we defined an endpoint to fetch the cats resource (**GET** route). We'll typically also want to provide an endpoint that creates new records. For this, let's create the **POST** handler:

cats.controller.ts

JS TS

```typescript

import { Controller, Get, Post } from '@nestjs/common';

@Controller('cats')
export class CatsController {
  @Post()
  create(): string {
    return 'This action adds a new cat';
  }

  @Get()
  findAll(): string {
    return 'This action returns all cats';
  }
}
```

```typescript

import { Controller, Get, Post } from '@nestjs/common';

@Controller('cats')
export class CatsController {
  @Post()
  create() {
    return 'This action adds a new cat';
  }

  @Get()
  findAll() {
    return 'This action returns all cats';
  }
}
```

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.

#### Route wildcards[#](/controllers#route-wildcards)

Pattern-based routes are also supported in NestJS. For example, the asterisk (`*`) can be used as a wildcard to match any combination of characters in a route at the end of a path. In the following example, the `findAll()` method will be executed for any route that starts with `abcd/`, regardless of the number of characters that follow.

```typescript

@Get('abcd/*')
findAll() {
  return 'This route uses a wildcard';
}
```

The `'abcd/*'` route path will match `abcd/`, `abcd/123`, `abcd/abc`, and so on. The hyphen ( `-`) and the dot (`.`) are interpreted literally by string-based paths.

This approach works on both Express and Fastify. However, with the latest release of Express (v5), the routing system has become more strict. In pure Express, you must use a named wildcard to make the route work—for example, `abcd/*splat`, where `splat` is simply the name of the wildcard parameter and has no special meaning. You can name it anything you like. That said, since Nest provides a compatibility layer for Express, you can still use the asterisk (`*`) as a wildcard.

When it comes to asterisks used in the **middle of a route**, Express requires named wildcards (e.g., `ab{*splat}cd`), while Fastify does not support them at all.

#### Status code[#](/controllers#status-code)

As mentioned, the default **status code** for responses is always **200**, except for POST requests, which default to **201**. You can easily change this behavior by using the `@HttpCode(...)` decorator at the handler level.

```typescript

@Post()
@HttpCode(204)
create() {
  return 'This action adds a new cat';
}
```

> **Hint** Import `HttpCode` from the `@nestjs/common` package.

Often, your status code isn't static but depends on various factors. In that case, you can use a library-specific **response** (inject using `@Res()`) object (or, in case of an error, throw an exception).

#### Response headers[#](/controllers#response-headers)

To specify a custom response header, you can either use a `@Header()` decorator or a library-specific response object (and call `res.header()` directly).

```typescript

@Post()
@Header('Cache-Control', 'no-store')
create() {
  return 'This action adds a new cat';
}
```

> **Hint** Import `Header` from the `@nestjs/common` package.

#### Redirection[#](/controllers#redirection)

To redirect a response to a specific URL, you can either use a `@Redirect()` decorator or a library-specific response object (and call `res.redirect()` directly).

`@Redirect()` takes two arguments, `url` and `statusCode`, both are optional. The default value of `statusCode` is `302` (`Found`) if omitted.

```typescript

@Get()
@Redirect('https://nestjs.com', 301)
```

> **Hint** Sometimes you may want to determine the HTTP status code or the redirect URL dynamically. Do this by returning an object following the `HttpRedirectResponse` interface (from `@nestjs/common`).

Returned values will override any arguments passed to the `@Redirect()` decorator. For example:

```typescript

@Get('docs')
@Redirect('https://docs.nestjs.com', 302)
getDocs(@Query('version') version) {
  if (version && version === '5') {
    return { url: 'https://docs.nestjs.com/v5/' };
  }
}
```

#### Route parameters[#](/controllers#route-parameters)

Routes with static paths won’t work when you need to accept **dynamic data** as part of the request (e.g., `GET /cats/1` to get the cat with id `1`). To define routes with parameters, you can add route parameter **tokens** in the route path to capture the dynamic values from the URL. The route parameter token in the `@Get()` decorator example below illustrates this approach. These route parameters can then be accessed using the `@Param()` decorator, which should be added to the method signature.

> **Hint** Routes with parameters should be declared after any static paths. This prevents the parameterized paths from intercepting traffic destined for the static paths.

JS TS

```typescript

@Get(':id')
findOne(@Param() params: any): string {
  console.log(params.id);
  return `This action returns a #${params.id} cat`;
}
```

```typescript

@Get(':id')
@Bind(Param())
findOne(params) {
  console.log(params.id);
  return `This action returns a #${params.id} cat`;
}
```

The `@Param()` decorator is used to decorate a method parameter (in the example above, `params`), making the **route** parameters accessible as properties of that decorated method parameter inside the method. As shown in the code, you can access the `id` parameter by referencing `params.id`. Alternatively, you can pass a specific parameter token to the decorator and directly reference the route parameter by name within the method body.

> **Hint** Import `Param` from the `@nestjs/common` package.

JS TS

```typescript

@Get(':id')
findOne(@Param('id') id: string): string {
  return `This action returns a #${id} cat`;
}
```

```typescript

@Get(':id')
@Bind(Param('id'))
findOne(id) {
  return `This action returns a #${id} cat`;
}
```

#### Sub-domain routing[#](/controllers#sub-domain-routing)

The `@Controller` decorator can take a `host` option to require that the HTTP host of the incoming requests matches some specific value.

```typescript

@Controller({ host: 'admin.example.com' })
export class AdminController {
  @Get()
  index(): string {
    return 'Admin page';
  }
}
```

> **Warning** Since **Fastify** does not support nested routers, if you are using sub-domain routing, it is recommended to use the default Express adapter instead.

Similar to a route `path`, the `host` option can use tokens to capture the dynamic value at that position in the host name. The host parameter token in the `@Controller()` decorator example below demonstrates this usage. Host parameters declared in this way can be accessed using the `@HostParam()` decorator, which should be added to the method signature.

```typescript

@Controller({ host: ':account.example.com' })
export class AccountController {
  @Get()
  getInfo(@HostParam('account') account: string) {
    return account;
  }
}
```

#### State sharing[#](/controllers#state-sharing)

For developers coming from other programming languages, it might be surprising to learn that in Nest, nearly everything is shared across incoming requests. This includes resources like the database connection pool, singleton services with global state, and more. It's important to understand that Node.js doesn't use the request/response Multi-Threaded Stateless Model, where each request is handled by a separate thread. As a result, using singleton instances in Nest is completely **safe** for our applications.

That said, there are specific edge cases where having request-based lifetimes for controllers may be necessary. Examples include per-request caching in GraphQL applications, request tracking, or implementing multi-tenancy. You can learn more about controlling injection scopes [here](/v11/fundamentals/injection-scopes).

#### Asynchronicity[#](/controllers#asynchronicity)

We love modern JavaScript, especially its emphasis on **asynchronous** data handling. That’s why Nest fully supports `async` functions. Every `async` function must return a `Promise`, which allows you to return a deferred value that Nest can resolve automatically. Here's an example:

cats.controller.ts

JS TS

```typescript

@Get()
async findAll(): Promise<any[]> {
  return [];
}
```

```typescript

@Get()
async findAll() {
  return [];
}
```

This code is perfectly valid. But Nest takes it a step further by allowing route handlers to return RxJS [observable streams](https://rxjs-dev.firebaseapp.com/guide/observable) as well. Nest will handle the subscription internally and resolve the final emitted value once the stream completes.

cats.controller.ts

JS TS

```typescript

@Get()
findAll(): Observable<any[]> {
  return of([]);
}
```

```typescript

@Get()
findAll() {
  return of([]);
}
```

Both approaches are valid, and you can choose the one that best suits your needs.

#### Request payloads[#](/controllers#request-payloads)

In our previous example, the POST route handler didn’t accept any client parameters. Let's fix that by adding the `@Body()` decorator.

Before we proceed (if you're using TypeScript), we need to define the **DTO** (Data Transfer Object) schema. A DTO is an object that specifies how data should be sent over the network. We could define the DTO schema using **TypeScript** interfaces or simple classes. However, we recommend using **classes** here. Why? Classes are part of the JavaScript ES6 standard, so they remain intact as real entities in the compiled JavaScript. In contrast, TypeScript interfaces are removed during transpilation, meaning Nest can't reference them at runtime. This is important because features like **Pipes** rely on having access to the metatype of variables at runtime, which is only possible with classes.

Let's create the `CreateCatDto` class:

create-cat.dto.ts

JS TS

```typescript

export class CreateCatDto {
  name: string;
  age: number;
  breed: string;
}
```

It has only three basic properties. Thereafter we can use the newly created DTO inside the `CatsController`:

cats.controller.ts

JS TS

```typescript

@Post()
async create(@Body() createCatDto: CreateCatDto) {
  return 'This action adds a new cat';
}
```

```typescript

@Post()
@Bind(Body())
async create(createCatDto) {
  return 'This action adds a new cat';
}
```

> **Hint** Our `ValidationPipe` can filter out properties that should not be received by the method handler. In this case, we can whitelist the acceptable properties, and any property not included in the whitelist is automatically stripped from the resulting object. In the `CreateCatDto` example, our whitelist is the `name`, `age`, and `breed` properties. Learn more [here](https://docs.nestjs.com/techniques/validation#stripping-properties).

#### Query parameters[#](/controllers#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.

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`:

cats.controller.ts

JS TS

```typescript

@Get()
async findAll(@Query('age') age: number, @Query('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:

```plaintext

GET /cats?age=2&breed=Persian
```

would result in `age` being `2` and `breed` being `Persian`.

If your application requires handling more complex query parameters, such as nested objects or arrays:

```plaintext

?filter[where][name]=John&filter[where][age]=30
?item[]=1&item[]=2
```

you'll need to configure your HTTP adapter (Express or Fastify) to use an appropriate query parser. In Express, you can use the `extended` parser, which allows for rich query objects:

```typescript

const app = await NestFactory.create<NestExpressApplication>(AppModule);
app.set('query parser', 'extended');
```

In Fastify, you can use the `querystringParser` option:

```typescript

const app = await NestFactory.create<NestFastifyApplication>(
  AppModule,
  new FastifyAdapter({
    querystringParser: (str) => qs.parse(str),
  }),
);
```

> **Hint**`qs` is a querystring parser that supports nesting and arrays. You can install it using `npm install qs`.

#### Handling errors[#](/controllers#handling-errors)

There's a separate chapter about handling errors (i.e., working with exceptions) [here](/v11/exception-filters).

#### Full resource sample[#](/controllers#full-resource-sample)

Below is an example that demonstrates the use of several available decorators to create a basic controller. This controller provides a few methods to access and manipulate internal data.

cats.controller.ts

JS TS

```typescript

import { Controller, Get, Query, Post, Body, Put, Param, Delete } from '@nestjs/common';
import { CreateCatDto, UpdateCatDto, ListAllEntities } from './dto';

@Controller('cats')
export class CatsController {
  @Post()
  create(@Body() createCatDto: CreateCatDto) {
    return 'This action adds a new cat';
  }

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

  @Get(':id')
  findOne(@Param('id') id: string) {
    return `This action returns a #${id} cat`;
  }

  @Put(':id')
  update(@Param('id') id: string, @Body() updateCatDto: UpdateCatDto) {
    return `This action updates a #${id} cat`;
  }

  @Delete(':id')
  remove(@Param('id') id: string) {
    return `This action removes a #${id} cat`;
  }
}
```

```typescript

import { Controller, Get, Query, Post, Body, Put, Param, Delete, Bind } from '@nestjs/common';

@Controller('cats')
export class CatsController {
  @Post()
  @Bind(Body())
  create(createCatDto) {
    return 'This action adds a new cat';
  }

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

  @Get(':id')
  @Bind(Param('id'))
  findOne(id) {
    return `This action returns a #${id} cat`;
  }

  @Put(':id')
  @Bind(Param('id'), Body())
  update(id, updateCatDto) {
    return `This action updates a #${id} cat`;
  }

  @Delete(':id')
  @Bind(Param('id'))
  remove(id) {
    return `This action removes a #${id} cat`;
  }
}
```

> **Hint** Nest CLI offers a generator (schematic) that automatically creates **all the boilerplate code**, saving you from doing this manually and improving the overall developer experience. Learn more about this feature [here](/v11/recipes/crud-generator).

#### Getting up and running[#](/controllers#getting-up-and-running)

Even with the `CatsController` fully defined, Nest doesn't yet know about it and won't automatically create an instance of the class.

Controllers must always be part of a module, which is why we include the `controllers` array within the `@Module()` decorator. Since we haven’t defined any other modules apart from the root `AppModule`, we’ll use it to register the `CatsController`:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { CatsController } from './cats/cats.controller';

@Module({
  controllers: [CatsController],
})
export class AppModule {}
```

We attached the metadata to the module class using the `@Module()` decorator, and now Nest can easily determine which controllers need to be mounted.

#### Library-specific approach[#](/controllers#library-specific-approach)

So far, we've covered the standard Nest way of manipulating responses. Another approach is to use a library-specific [response object](https://expressjs.com/en/api.html#res). To inject a specific response object, we can use the `@Res()` decorator. To highlight the differences, let’s rewrite the `CatsController` like this:

JS TS

```typescript

import { Controller, Get, Post, Res, HttpStatus } from '@nestjs/common';
import { Response } from 'express';

@Controller('cats')
export class CatsController {
  @Post()
  create(@Res() res: Response) {
    res.status(HttpStatus.CREATED).send();
  }

  @Get()
  findAll(@Res() res: Response) {
     res.status(HttpStatus.OK).json([]);
  }
}
```

```typescript

import { Controller, Get, Post, Bind, Res, Body, HttpStatus } from '@nestjs/common';

@Controller('cats')
export class CatsController {
  @Post()
  @Bind(Res(), Body())
  create(res, createCatDto) {
    res.status(HttpStatus.CREATED).send();
  }

  @Get()
  @Bind(Res())
  findAll(res) {
     res.status(HttpStatus.OK).json([]);
  }
}
```

While this approach works and offers more flexibility by giving full control over the response object (such as header manipulation and access to library-specific features), it should be used with caution. Generally, this method is less clear and comes with some downsides. The main disadvantage is that your code becomes platform-dependent, as different underlying libraries may have different APIs for the response object. Additionally, it can make testing more challenging, as you'll need to mock the response object, among other things.

Furthermore, by using this approach, you lose compatibility with Nest features that rely on standard response handling, such as Interceptors and the `@HttpCode()` / `@Header()` decorators. To address this, you can enable the `passthrough` option like this:

JS TS

```typescript

@Get()
findAll(@Res({ passthrough: true }) res: Response) {
  res.status(HttpStatus.OK);
  return [];
}
```

```typescript

@Get()
@Bind(Res({ passthrough: true }))
findAll(res) {
  res.status(HttpStatus.OK);
  return [];
}
```

With this approach, you can interact with the native response object (for example, setting cookies or headers based on specific conditions), while still allowing the framework to handle the rest.

----
url: https://docs.nestjs.com/v9/techniques/performance
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Performance (Fastify)](https://docs.nestjs.com/v9/techniques/performance#performance-fastify)
* [Installation](https://docs.nestjs.com/v9/techniques/performance#installation)
* [Adapter](https://docs.nestjs.com/v9/techniques/performance#adapter)
* [Platform specific packages](https://docs.nestjs.com/v9/techniques/performance#platform-specific-packages)
* [Redirect response](https://docs.nestjs.com/v9/techniques/performance#redirect-response)
* [Fastify options](https://docs.nestjs.com/v9/techniques/performance#fastify-options)
* [Middleware](https://docs.nestjs.com/v9/techniques/performance#middleware)
* [Example](https://docs.nestjs.com/v9/techniques/performance#example)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/techniques/performance.md "Suggest Edits")

### Performance (Fastify)

By default, Nest makes use of the [Express](https://expressjs.com/) framework. As mentioned earlier, Nest also provides compatibility with other libraries such as, for example, [Fastify](https://github.com/fastify/fastify). Nest achieves this framework independence by implementing a framework adapter whose primary function is to proxy middleware and handlers to appropriate library-specific implementations.

> **Hint** Note that in order for a framework adapter to be implemented, the target library has to provide similar request/response pipeline processing as found in Express.

[Fastify](https://github.com/fastify/fastify) provides a good alternative framework for Nest because it solves design issues in a similar manner to Express. However, fastify is much **faster** than Express, achieving almost two times better benchmarks results. A fair question is why does Nest use Express as the default HTTP provider? The reason is that Express is widely-used, well-known, and has an enormous set of compatible middleware, which is available to Nest users out-of-the-box.

But since Nest provides framework-independence, you can easily migrate between them. Fastify can be a better choice when you place high value on very fast performance. To utilize Fastify, simply choose the built-in `FastifyAdapter` as shown in this chapter.

#### Installation[#](/techniques/performance#installation)

First, we need to install the required package:

```bash

$ npm i --save @nestjs/platform-fastify
```

#### Adapter[#](/techniques/performance#adapter)

Once the Fastify platform is installed, we can use the `FastifyAdapter`.

main.ts

JS TS

```typescript

import { NestFactory } from '@nestjs/core';
import {
  FastifyAdapter,
  NestFastifyApplication,
} from '@nestjs/platform-fastify';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create<NestFastifyApplication>(
    AppModule,
    new FastifyAdapter()
  );
  await app.listen(3000);
}
bootstrap();
```

By default, Fastify listens only on the `localhost 127.0.0.1` interface ([read more](https://www.fastify.io/docs/latest/Guides/Getting-Started/#your-first-server)). If you want to accept connections on other hosts, you should specify `'0.0.0.0'` in the `listen()` call:

```typescript

async function bootstrap() {
  const app = await NestFactory.create<NestFastifyApplication>(
    AppModule,
    new FastifyAdapter(),
  );
  await app.listen(3000, '0.0.0.0');
}
```

#### Platform specific packages[#](/techniques/performance#platform-specific-packages)

Keep in mind that when you use the `FastifyAdapter`, Nest uses Fastify as the **HTTP provider**. This means that each recipe that relies on Express may no longer work. You should, instead, use Fastify equivalent packages.

#### Redirect response[#](/techniques/performance#redirect-response)

Fastify handles redirect responses slightly differently than Express. To do a proper redirect with Fastify, return both the status code and the URL, as follows:

```typescript

@Get()
index(@Res() res) {
  res.status(302).redirect('/login');
}
```

#### Fastify options[#](/techniques/performance#fastify-options)

You can pass options into the Fastify constructor through the `FastifyAdapter` constructor. For example:

```typescript

new FastifyAdapter({ logger: true });
```

#### Middleware[#](/techniques/performance#middleware)

Middleware functions retrieve the raw `req` and `res` objects instead of Fastify's wrappers. This is how the `middie` package works (that's used under the hood) and `fastify` - check out this [page](https://www.fastify.io/docs/latest/Reference/Middleware/) for more information,

logger.middleware.ts

JS TS

```typescript

import { Injectable, NestMiddleware } from '@nestjs/common';
import { FastifyRequest, FastifyReply } from 'fastify';

@Injectable()
export class LoggerMiddleware implements NestMiddleware {
  use(req: FastifyRequest['raw'], res: FastifyReply['raw'], next: () => void) {
    console.log('Request...');
    next();
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';

@Injectable()
export class LoggerMiddleware {
  use(req, res, next) {
    console.log('Request...');
    next();
  }
}
```

#### Example[#](/techniques/performance#example)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/10-fastify).

----
url: https://docs.nestjs.com/v10/security/authentication
----

* [Authentication](https://docs.nestjs.com/v10/security/authentication#authentication)
* [Creating an authentication module](https://docs.nestjs.com/v10/security/authentication#creating-an-authentication-module)
* [Implementing the "Sign in" endpoint](https://docs.nestjs.com/v10/security/authentication#implementing-the-sign-in-endpoint)
* [JWT token](https://docs.nestjs.com/v10/security/authentication#jwt-token)
* [Implementing the authentication guard](https://docs.nestjs.com/v10/security/authentication#implementing-the-authentication-guard)
* [Enable authentication globally](https://docs.nestjs.com/v10/security/authentication#enable-authentication-globally)
* [Passport integration](https://docs.nestjs.com/v10/security/authentication#passport-integration)
* [Example](https://docs.nestjs.com/v10/security/authentication#example)

```bash

$ nest g module auth
$ nest g controller auth
$ nest g service auth
```

As we implement the `AuthService`, we'll find it useful to encapsulate user operations in a `UsersService`, so let's generate that module and service now:

```bash

$ nest g module users
$ nest g service users
```

Replace the default contents of these generated files as shown below. For our sample app, the `UsersService` simply maintains a hard-coded in-memory list of users, and a find method to retrieve one by username. In a real app, this is where you'd build your user model and persistence layer, using your library of choice (e.g., TypeORM, Sequelize, Mongoose, etc.).

users/users.service.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';

// This should be a real class/interface representing a user entity
export type User = any;

@Injectable()
export class UsersService {
  private readonly users = [
    {
      userId: 1,
      username: 'john',
      password: 'changeme',
    },
    {
      userId: 2,
      username: 'maria',
      password: 'guess',
    },
  ];

  async findOne(username: string): Promise<User | undefined> {
    return this.users.find(user => user.username === username);
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';

@Injectable()
export class UsersService {
  constructor() {
    this.users = [
      {
        userId: 1,
        username: 'john',
        password: 'changeme',
      },
      {
        userId: 2,
        username: 'maria',
        password: 'guess',
      },
    ];
  }

  async findOne(username) {
    return this.users.find(user => user.username === username);
  }
}
```

In the `UsersModule`, the only change needed is to add the `UsersService` to the exports array of the `@Module` decorator so that it is visible outside this module (we'll soon use it in our `AuthService`).

users/users.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { UsersService } from './users.service';

@Module({
  providers: [UsersService],
  exports: [UsersService],
})
export class UsersModule {}
```

```typescript

import { Module } from '@nestjs/common';
import { UsersService } from './users.service';

@Module({
  providers: [UsersService],
  exports: [UsersService],
})
export class UsersModule {}
```

#### Implementing the "Sign in" endpoint[#](/security/authentication#implementing-the-sign-in-endpoint)

Our `AuthService` has the job of retrieving a user and verifying the password. We create a `signIn()` method for this purpose. In the code below, we use a convenient ES6 spread operator to strip the password property from the user object before returning it. This is a common practice when returning user objects, as you don't want to expose sensitive fields like passwords or other security keys.

auth/auth.service.ts

JS TS

```typescript

import { Injectable, UnauthorizedException } from '@nestjs/common';
import { UsersService } from '../users/users.service';

@Injectable()
export class AuthService {
  constructor(private usersService: UsersService) {}

  async signIn(username: string, pass: string): Promise<any> {
    const user = await this.usersService.findOne(username);
    if (user?.password !== pass) {
      throw new UnauthorizedException();
    }
    const { password, ...result } = user;
    // TODO: Generate a JWT and return it here
    // instead of the user object
    return result;
  }
}
```

```typescript

import { Injectable, Dependencies, UnauthorizedException } from '@nestjs/common';
import { UsersService } from '../users/users.service';

@Injectable()
@Dependencies(UsersService)
export class AuthService {
  constructor(usersService) {
    this.usersService = usersService;
  }

  async signIn(username: string, pass: string) {
    const user = await this.usersService.findOne(username);
    if (user?.password !== pass) {
      throw new UnauthorizedException();
    }
    const { password, ...result } = user;
    // TODO: Generate a JWT and return it here
    // instead of the user object
    return result;
  }
}
```

> **Warning** Of course in a real application, you wouldn't store a password in plain text. You'd instead use a library like [bcrypt](https://github.com/kelektiv/node.bcrypt.js#readme), with a salted one-way hash algorithm. With that approach, you'd only store hashed passwords, and then compare the stored password to a hashed version of the **incoming** password, thus never storing or exposing user passwords in plain text. To keep our sample app simple, we violate that absolute mandate and use plain text. **Don't do this in your real app!**

Now, we update our `AuthModule` to import the `UsersModule`.

auth/auth.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { AuthController } from './auth.controller';
import { UsersModule } from '../users/users.module';

@Module({
  imports: [UsersModule],
  providers: [AuthService],
  controllers: [AuthController],
})
export class AuthModule {}
```

```typescript

import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { AuthController } from './auth.controller';
import { UsersModule } from '../users/users.module';

@Module({
  imports: [UsersModule],
  providers: [AuthService],
  controllers: [AuthController],
})
export class AuthModule {}
```

With this in place, let's open up the `AuthController` and add a `signIn()` method to it. This method will be called by the client to authenticate a user. It will receive the username and password in the request body, and will return a JWT token if the user is authenticated.

auth/auth.controller.ts

JS TS

```typescript

import { Body, Controller, Post, HttpCode, HttpStatus } from '@nestjs/common';
import { AuthService } from './auth.service';

@Controller('auth')
export class AuthController {
  constructor(private authService: AuthService) {}

  @HttpCode(HttpStatus.OK)
  @Post('login')
  signIn(@Body() signInDto: Record<string, any>) {
    return this.authService.signIn(signInDto.username, signInDto.password);
  }
}
```

> **Hint** Ideally, instead of using the `Record<string, any>` type, we should use a DTO class to define the shape of the request body. See the [validation](/v10/techniques/validation) chapter for more information.

```bash

$ npm install --save @nestjs/jwt
```

> **Hint** The `@nestjs/jwt` package (see more [here](https://github.com/nestjs/jwt)) is a utility package that helps with JWT manipulation. This includes generating and verifying JWT tokens.

To keep our services cleanly modularized, we'll handle generating the JWT in the `authService`. Open the `auth.service.ts` file in the `auth` folder, inject the `JwtService`, and update the `signIn` method to generate a JWT token as shown below:

auth/auth.service.ts

JS TS

```typescript

import { Injectable, UnauthorizedException } from '@nestjs/common';
import { UsersService } from '../users/users.service';
import { JwtService } from '@nestjs/jwt';

@Injectable()
export class AuthService {
  constructor(
    private usersService: UsersService,
    private jwtService: JwtService
  ) {}

  async signIn(
    username: string,
    pass: string,
  ): Promise<{ access_token: string }> {
    const user = await this.usersService.findOne(username);
    if (user?.password !== pass) {
      throw new UnauthorizedException();
    }
    const payload = { sub: user.userId, username: user.username };
    return {
      access_token: await this.jwtService.signAsync(payload),
    };
  }
}
```

```typescript

import { Injectable, Dependencies, UnauthorizedException } from '@nestjs/common';
import { UsersService } from '../users/users.service';
import { JwtService } from '@nestjs/jwt';

@Dependencies(UsersService, JwtService)
@Injectable()
export class AuthService {
  constructor(usersService, jwtService) {
    this.usersService = usersService;
    this.jwtService = jwtService;
  }

  async signIn(username, pass) {
    const user = await this.usersService.findOne(username);
    if (user?.password !== pass) {
      throw new UnauthorizedException();
    }
    const payload = { username: user.username, sub: user.userId };
    return {
      access_token: await this.jwtService.signAsync(payload),
    };
  }
}
```

We're using the `@nestjs/jwt` library, which supplies a `signAsync()` function to generate our JWT from a subset of the `user` object properties, which we then return as a simple object with a single `access_token` property. Note: we choose a property name of `sub` to hold our `userId` value to be consistent with JWT standards.

We now need to update the `AuthModule` to import the new dependencies and configure the `JwtModule`.

First, create `constants.ts` in the `auth` folder, and add the following code:

auth/constants.ts

JS TS

```typescript

export const jwtConstants = {
  secret: 'DO NOT USE THIS VALUE. INSTEAD, CREATE A COMPLEX SECRET AND KEEP IT SAFE OUTSIDE OF THE SOURCE CODE.',
};
```

```typescript

export const jwtConstants = {
  secret: 'DO NOT USE THIS VALUE. INSTEAD, CREATE A COMPLEX SECRET AND KEEP IT SAFE OUTSIDE OF THE SOURCE CODE.',
};
```

We'll use this to share our key between the JWT signing and verifying steps.

> **Warning****Do not expose this key publicly**. We have done so here to make it clear what the code is doing, but in a production system **you must protect this key** using appropriate measures such as a secrets vault, environment variable, or configuration service.

Now, open `auth.module.ts` in the `auth` folder and update it to look like this:

auth/auth.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { UsersModule } from '../users/users.module';
import { JwtModule } from '@nestjs/jwt';
import { AuthController } from './auth.controller';
import { jwtConstants } from './constants';

@Module({
  imports: [
    UsersModule,
    JwtModule.register({
      global: true,
      secret: jwtConstants.secret,
      signOptions: { expiresIn: '60s' },
    }),
  ],
  providers: [AuthService],
  controllers: [AuthController],
  exports: [AuthService],
})
export class AuthModule {}
```

```typescript

import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { UsersModule } from '../users/users.module';
import { JwtModule } from '@nestjs/jwt';
import { AuthController } from './auth.controller';
import { jwtConstants } from './constants';

@Module({
  imports: [
    UsersModule,
    JwtModule.register({
      global: true,
      secret: jwtConstants.secret,
      signOptions: { expiresIn: '60s' },
    }),
  ],
  providers: [AuthService],
  controllers: [AuthController],
  exports: [AuthService],
})
export class AuthModule {}
```

> **Hint** We're registering the `JwtModule` as global to make things easier for us. This means that we don't need to import the `JwtModule` anywhere else in our application.

We configure the `JwtModule` using `register()`, passing in a configuration object. See [here](https://github.com/nestjs/jwt/blob/master/README.md) for more on the Nest `JwtModule` and [here](https://github.com/auth0/node-jsonwebtoken#usage) for more details on the available configuration options.

Let's go ahead and test our routes using cURL again. You can test with any of the `user` objects hard-coded in the `UsersService`.

```bash

$ # POST to /auth/login
$ curl -X POST http://localhost:3000/auth/login -d '{"username": "john", "password": "changeme"}' -H "Content-Type: application/json"
{"access_token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."}
$ # Note: above JWT truncated
```

#### Implementing the authentication guard[#](/security/authentication#implementing-the-authentication-guard)

We can now address our final requirement: protecting endpoints by requiring a valid JWT be present on the request. We'll do this by creating an `AuthGuard` that we can use to protect our routes.

auth/auth.guard.ts

JS TS

```typescript

import {
  CanActivate,
  ExecutionContext,
  Injectable,
  UnauthorizedException,
} from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
import { jwtConstants } from './constants';
import { Request } from 'express';

@Injectable()
export class AuthGuard implements CanActivate {
  constructor(private jwtService: JwtService) {}

  async canActivate(context: ExecutionContext): Promise<boolean> {
    const request = context.switchToHttp().getRequest();
    const token = this.extractTokenFromHeader(request);
    if (!token) {
      throw new UnauthorizedException();
    }
    try {
      const payload = await this.jwtService.verifyAsync(
        token,
        {
          secret: jwtConstants.secret
        }
      );
      // 💡 We're assigning the payload to the request object here
      // so that we can access it in our route handlers
      request['user'] = payload;
    } catch {
      throw new UnauthorizedException();
    }
    return true;
  }

  private extractTokenFromHeader(request: Request): string | undefined {
    const [type, token] = request.headers.authorization?.split(' ') ?? [];
    return type === 'Bearer' ? token : undefined;
  }
}
```

We can now implement our protected route and register our `AuthGuard` to protect it.

Open the `auth.controller.ts` file and update it as shown below:

auth.controller.ts

JS TS

```typescript

import {
  Body,
  Controller,
  Get,
  HttpCode,
  HttpStatus,
  Post,
  Request,
  UseGuards
} from '@nestjs/common';
import { AuthGuard } from './auth.guard';
import { AuthService } from './auth.service';

@Controller('auth')
export class AuthController {
  constructor(private authService: AuthService) {}

  @HttpCode(HttpStatus.OK)
  @Post('login')
  signIn(@Body() signInDto: Record<string, any>) {
    return this.authService.signIn(signInDto.username, signInDto.password);
  }

  @UseGuards(AuthGuard)
  @Get('profile')
  getProfile(@Request() req) {
    return req.user;
  }
}
```

We're applying the `AuthGuard` that we just created to the `GET /profile` route so that it will be protected.

Ensure the app is running, and test the routes using `cURL`.

```bash

$ # GET /profile
$ curl http://localhost:3000/auth/profile
{"statusCode":401,"message":"Unauthorized"}

$ # POST /auth/login
$ curl -X POST http://localhost:3000/auth/login -d '{"username": "john", "password": "changeme"}' -H "Content-Type: application/json"
{"access_token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2Vybm..."}

$ # GET /profile using access_token returned from previous step as bearer code
$ curl http://localhost:3000/auth/profile -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2Vybm..."
{"sub":1,"username":"john","iat":...,"exp":...}
```

Note that in the `AuthModule`, we configured the JWT to have an expiration of `60 seconds`. This is too short an expiration, and dealing with the details of token expiration and refresh is beyond the scope of this article. However, we chose that to demonstrate an important quality of JWTs. If you wait 60 seconds after authenticating before attempting a `GET /auth/profile` request, you'll receive a `401 Unauthorized` response. This is because `@nestjs/jwt` automatically checks the JWT for its expiration time, saving you the trouble of doing so in your application.

We've now completed our JWT authentication implementation. JavaScript clients (such as Angular/React/Vue), and other JavaScript apps, can now authenticate and communicate securely with our API Server.

#### Enable authentication globally[#](/security/authentication#enable-authentication-globally)

If the vast majority of your endpoints should be protected by default, you can register the authentication guard as a [global guard](/guards#binding-guards) and instead of using `@UseGuards()` decorator on top of each controller, you could simply flag which routes should be public.

First, register the `AuthGuard` as a global guard using the following construction (in any module, for example, in the `AuthModule`):

```typescript

providers: [
  {
    provide: APP_GUARD,
    useClass: AuthGuard,
  },
],
```

With this in place, Nest will automatically bind `AuthGuard` to all endpoints.

Now we must provide a mechanism for declaring routes as public. For this, we can create a custom decorator using the `SetMetadata` decorator factory function.

```typescript

import { SetMetadata } from '@nestjs/common';

export const IS_PUBLIC_KEY = 'isPublic';
export const Public = () => SetMetadata(IS_PUBLIC_KEY, true);
```

In the file above, we exported two constants. One being our metadata key named `IS_PUBLIC_KEY`, and the other being our new decorator itself that we’re going to call `Public` (you can alternatively name it `SkipAuth` or `AllowAnon`, whatever fits your project).

Now that we have a custom `@Public()` decorator, we can use it to decorate any method, as follows:

```typescript

@Public()
@Get()
findAll() {
  return [];
}
```

Lastly, we need the `AuthGuard` to return `true` when the `"isPublic"` metadata is found. For this, we'll use the `Reflector` class (read more [here](/guards#putting-it-all-together)).

```typescript

@Injectable()
export class AuthGuard implements CanActivate {
  constructor(private jwtService: JwtService, private reflector: Reflector) {}

  async canActivate(context: ExecutionContext): Promise<boolean> {
    const isPublic = this.reflector.getAllAndOverride<boolean>(IS_PUBLIC_KEY, [
      context.getHandler(),
      context.getClass(),
    ]);
    if (isPublic) {
      // 💡 See this condition
      return true;
    }

    const request = context.switchToHttp().getRequest();
    const token = this.extractTokenFromHeader(request);
    if (!token) {
      throw new UnauthorizedException();
    }
    try {
      const payload = await this.jwtService.verifyAsync(token, {
        secret: jwtConstants.secret,
      });
      // 💡 We're assigning the payload to the request object here
      // so that we can access it in our route handlers
      request['user'] = payload;
    } catch {
      throw new UnauthorizedException();
    }
    return true;
  }

  private extractTokenFromHeader(request: Request): string | undefined {
    const [type, token] = request.headers.authorization?.split(' ') ?? [];
    return type === 'Bearer' ? token : undefined;
  }
}
```

#### Passport integration[#](/security/authentication#passport-integration)

[Passport](https://github.com/jaredhanson/passport) is the most popular node.js authentication library, well-known by the community and successfully used in many production applications. It's straightforward to integrate this library with a **Nest** application using the `@nestjs/passport` module.

To learn how you can integrate Passport with NestJS, check out this [chapter](/v10/recipes/passport).

#### Example[#](/security/authentication#example)

You can find a complete version of the code in this chapter [here](https://github.com/nestjs/nest/tree/master/sample/19-auth-jwt).

----
url: https://docs.nestjs.com/v9/graphql/scalars
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Scalars](https://docs.nestjs.com/v9/graphql/scalars#scalars)
* [Code first](https://docs.nestjs.com/v9/graphql/scalars#code-first)
* [Override a default scalar](https://docs.nestjs.com/v9/graphql/scalars#override-a-default-scalar)
* [Import a custom scalar](https://docs.nestjs.com/v9/graphql/scalars#import-a-custom-scalar)
* [Create a custom scalar](https://docs.nestjs.com/v9/graphql/scalars#create-a-custom-scalar)
* [Schema first](https://docs.nestjs.com/v9/graphql/scalars#schema-first)

```typescript

GraphQLModule.forRoot({
  buildSchemaOptions: {
    dateScalarMode: 'timestamp',
  }
}),
```

Likewise, the `GraphQLFloat` is used by default to represent the `number` type. To use the `GraphQLInt` instead, set the `numberScalarMode` of the `buildSchemaOptions` object to `'integer'` as follows:

```typescript

GraphQLModule.forRoot({
  buildSchemaOptions: {
    numberScalarMode: 'integer',
  }
}),
```

In addition, you can create custom scalars.

#### Override a default scalar[#](/graphql/scalars#override-a-default-scalar)

To create a custom implementation for the `Date` scalar, simply create a new class.

```typescript

import { Scalar, CustomScalar } from '@nestjs/graphql';
import { Kind, ValueNode } from 'graphql';

@Scalar('Date', (type) => Date)
export class DateScalar implements CustomScalar<number, Date> {
  description = 'Date custom scalar type';

  parseValue(value: number): Date {
    return new Date(value); // value from the client
  }

  serialize(value: Date): number {
    return value.getTime(); // value sent to the client
  }

  parseLiteral(ast: ValueNode): Date {
    if (ast.kind === Kind.INT) {
      return new Date(ast.value);
    }
    return null;
  }
}
```

With this in place, register `DateScalar` as a provider.

```typescript

@Module({
  providers: [DateScalar],
})
export class CommonModule {}
```

Now we can use the `Date` type in our classes.

```typescript

@Field()
creationDate: Date;
```

#### Import a custom scalar[#](/graphql/scalars#import-a-custom-scalar)

To use a custom scalar, import and register it as a resolver. We’ll use the `graphql-type-json` package for demonstration purposes. This npm package defines a `JSON` GraphQL scalar type.

Start by installing the package:

```bash

$ npm i --save graphql-type-json
```

Once the package is installed, we pass a custom resolver to the `forRoot()` method:

```typescript

import GraphQLJSON from 'graphql-type-json';

@Module({
  imports: [
    GraphQLModule.forRoot({
      resolvers: { JSON: GraphQLJSON },
    }),
  ],
})
export class AppModule {}
```

Now we can use the `JSON` type in our classes.

```typescript

@Field((type) => GraphQLJSON)
info: JSON;
```

For a suite of useful scalars, take a look at the [graphql-scalars](https://www.npmjs.com/package/graphql-scalars) package.

#### Create a custom scalar[#](/graphql/scalars#create-a-custom-scalar)

To define a custom scalar, create a new `GraphQLScalarType` instance. We'll create a custom `UUID` scalar.

```typescript

const regex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;

function validate(uuid: unknown): string | never {
  if (typeof uuid !== "string" || !regex.test(uuid)) {
    throw new Error("invalid uuid");
  }
  return uuid;
}

export const CustomUuidScalar = new GraphQLScalarType({
  name: 'UUID',
  description: 'A simple UUID parser',
  serialize: (value) => validate(value),
  parseValue: (value) => validate(value),
  parseLiteral: (ast) => validate(ast.value)
})
```

We pass a custom resolver to the `forRoot()` method:

```typescript

@Module({
  imports: [
    GraphQLModule.forRoot({
      resolvers: { UUID: CustomUuidScalar },
    }),
  ],
})
export class AppModule {}
```

Now we can use the `UUID` type in our classes.

```typescript

@Field((type) => CustomUuidScalar)
uuid: string;
```

#### Schema first[#](/graphql/scalars#schema-first)

To define a custom scalar (read more about scalars [here](https://www.apollographql.com/docs/graphql-tools/scalars.html)), create a type definition and a dedicated resolver. Here (as in the official documentation), we’ll use the `graphql-type-json` package for demonstration purposes. This npm package defines a `JSON` GraphQL scalar type.

Start by installing the package:

```bash

$ npm i --save graphql-type-json
```

Once the package is installed, we pass a custom resolver to the `forRoot()` method:

```typescript

import GraphQLJSON from 'graphql-type-json';

@Module({
  imports: [
    GraphQLModule.forRoot({
      typePaths: ['./**/*.graphql'],
      resolvers: { JSON: GraphQLJSON },
    }),
  ],
})
export class AppModule {}
```

Now we can use the `JSON` scalar in our type definitions:

```graphql

scalar JSON

type Foo {
  field: JSON
}
```

Another method to define a scalar type is to create a simple class. Assume we want to enhance our schema with the `Date` type.

```typescript

import { Scalar, CustomScalar } from '@nestjs/graphql';
import { Kind, ValueNode } from 'graphql';

@Scalar('Date')
export class DateScalar implements CustomScalar<number, Date> {
  description = 'Date custom scalar type';

  parseValue(value: number): Date {
    return new Date(value); // value from the client
  }

  serialize(value: Date): number {
    return value.getTime(); // value sent to the client
  }

  parseLiteral(ast: ValueNode): Date {
    if (ast.kind === Kind.INT) {
      return new Date(ast.value);
    }
    return null;
  }
}
```

With this in place, register `DateScalar` as a provider.

```typescript

@Module({
  providers: [DateScalar],
})
export class CommonModule {}
```

Now we can use the `Date` scalar in type definitions.

```graphql

scalar Date
```

By default, the generated TypeScript definition for all scalars is `any` - which isn't particularly typesafe. But, you can configure how Nest generates typings for your custom scalars when you specify how to generate types:

```typescript

import { GraphQLDefinitionsFactory } from '@nestjs/graphql';
import { join } from 'path';

const definitionsFactory = new GraphQLDefinitionsFactory();

definitionsFactory.generate({
  typePaths: ['./src/**/*.graphql'],
  path: join(process.cwd(), 'src/graphql.ts'),
  outputAs: 'class',
  defaultScalarType: 'unknown',
  customScalarTypeMapping: {
    DateTime: 'Date',
    BigNumber: '_BigNumber',
  },
  additionalHeader: "import _BigNumber from 'bignumber.js'",
});
```

> **Hint** Alternatively, you can use a type reference instead, for example: `DateTime: Date`. In this case, `GraphQLDefinitionsFactory` will extract the name property of the specified type (`Date.name`) to generate TS definitions. Note: adding an import statement for non-built-in types (custom types) is required.

Now, given the following GraphQL custom scalar types:

```graphql

scalar DateTime
scalar BigNumber
scalar Payload
```

We will now see the following generated TypeScript definitions in `src/graphql.ts`:

```typescript

import _BigNumber from 'bignumber.js';

export type DateTime = Date;
export type BigNumber = _BigNumber;
export type Payload = unknown;
```

Here, we've used the `customScalarTypeMapping` property to supply a map of the types we wish to declare for our custom scalars. We've also provided an `additionalHeader` property so that we can add any imports required for these type definitions. Lastly, we've added a `defaultScalarType` of `'unknown'`, so that any custom scalars not specified in `customScalarTypeMapping` will be aliased to `unknown` instead of `any` (which [TypeScript recommends](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-0.html#new-unknown-top-type) using since 3.0 for added type safety).

> **Hint** Note that we've imported `_BigNumber` from `bignumber.js`; this is to avoid [circular type references](https://github.com/Microsoft/TypeScript/issues/12525#issuecomment-263166239).

----
url: https://docs.nestjs.com/v8/fundamentals/dynamic-modules
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Dynamic modules](https://docs.nestjs.com/v8/fundamentals/dynamic-modules#dynamic-modules)
* [Introduction](https://docs.nestjs.com/v8/fundamentals/dynamic-modules#introduction)
* [Dynamic module use case](https://docs.nestjs.com/v8/fundamentals/dynamic-modules#dynamic-module-use-case)
* [Config module example](https://docs.nestjs.com/v8/fundamentals/dynamic-modules#config-module-example)
* [Module configuration](https://docs.nestjs.com/v8/fundamentals/dynamic-modules#module-configuration)
* [Example](https://docs.nestjs.com/v8/fundamentals/dynamic-modules#example)
* [Community guidelines](https://docs.nestjs.com/v8/fundamentals/dynamic-modules#community-guidelines)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/fundamentals/dynamic-modules.md "Suggest Edits")

### Dynamic modules

The [Modules chapter](/v8/modules) covers the basics of Nest modules, and includes a brief introduction to [dynamic modules](https://docs.nestjs.com/modules#dynamic-modules). This chapter expands on the subject of dynamic modules. Upon completion, you should have a good grasp of what they are and how and when to use them.

#### Introduction[#](/fundamentals/dynamic-modules#introduction)

Most application code examples in the **Overview** section of the documentation make use of regular, or static, modules. Modules define groups of components like [providers](/v8/providers) and [controllers](/v8/controllers) that fit together as a modular part of an overall application. They provide an execution context, or scope, for these components. For example, providers defined in a module are visible to other members of the module without the need to export them. When a provider needs to be visible outside of a module, it is first exported from its host module, and then imported into its consuming module.

Let's walk through a familiar example.

First, we'll define a `UsersModule` to provide and export a `UsersService`. `UsersModule` is the **host** module for `UsersService`.

```typescript

import { Module } from '@nestjs/common';
import { UsersService } from './users.service';

@Module({
  providers: [UsersService],
  exports: [UsersService],
})
export class UsersModule {}
```

Next, we'll define an `AuthModule`, which imports `UsersModule`, making `UsersModule`'s exported providers available inside `AuthModule`:

```typescript

import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { UsersModule } from '../users/users.module';

@Module({
  imports: [UsersModule],
  providers: [AuthService],
  exports: [AuthService],
})
export class AuthModule {}
```

These constructs allow us to inject `UsersService` in, for example, the `AuthService` that is hosted in `AuthModule`:

```typescript

import { Injectable } from '@nestjs/common';
import { UsersService } from '../users/users.service';

@Injectable()
export class AuthService {
  constructor(private usersService: UsersService) {}
  /*
    Implementation that makes use of this.usersService
  */
}
```

```typescript

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { ConfigModule } from './config/config.module';

@Module({
  imports: [ConfigModule],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}
```

Let's consider what a *dynamic module* import, where we're passing in a configuration object, might look like. Compare the difference in the `imports` array between these two examples:

```typescript

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { ConfigModule } from './config/config.module';

@Module({
  imports: [ConfigModule.register({ folder: './config' })],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}
```

Let's see what's happening in the dynamic example above. What are the moving parts?

1. `ConfigModule` is a normal class, so we can infer that it must have a **static method** called `register()`. We know it's static because we're calling it on the `ConfigModule` class, not on an **instance** of the class. Note: this method, which we will create soon, can have any arbitrary name, but by convention we should call it either `forRoot()` or `register()`.
2. The `register()` method is defined by us, so we can accept any input arguments we like. In this case, we're going to accept a simple `options` object with suitable properties, which is the typical case.
3. We can infer that the `register()` method must return something like a `module` since its return value appears in the familiar `imports` list, which we've seen so far includes a list of modules.

In fact, what our `register()` method will return is a `DynamicModule`. A dynamic module is nothing more than a module created at run-time, with the same exact properties as a static module, plus one additional property called `module`. Let's quickly review a sample static module declaration, paying close attention to the module options passed in to the decorator:

```typescript

@Module({
  imports: [DogsModule],
  controllers: [CatsController],
  providers: [CatsService],
  exports: [CatsService]
})
```

Dynamic modules must return an object with the exact same interface, plus one additional property called `module`. The `module` property serves as the name of the module, and should be the same as the class name of the module, as shown in the example below.

> **Hint** For a dynamic module, all properties of the module options object are optional **except**`module`.

What about the static `register()` method? We can now see that its job is to return an object that has the `DynamicModule` interface. When we call it, we are effectively providing a module to the `imports` list, similar to the way we would do so in the static case by listing a module class name. In other words, the dynamic module API simply returns a module, but rather than fix the properties in the `@Module` decorator, we specify them programmatically.

There are still a couple of details to cover to help make the picture complete:

1. We can now state that the `@Module()` decorator's `imports` property can take not only a module class name (e.g., `imports: [UsersModule]`), but also a function **returning** a dynamic module (e.g., `imports: [ConfigModule.register(...)]`).
2. A dynamic module can itself import other modules. We won't do so in this example, but if the dynamic module depends on providers from other modules, you would import them using the optional `imports` property. Again, this is exactly analogous to the way you'd declare metadata for a static module using the `@Module()` decorator.

Armed with this understanding, we can now look at what our dynamic `ConfigModule` declaration must look like. Let's take a crack at it.

```typescript

import { DynamicModule, Module } from '@nestjs/common';
import { ConfigService } from './config.service';

@Module({})
export class ConfigModule {
  static register(): DynamicModule {
    return {
      module: ConfigModule,
      providers: [ConfigService],
      exports: [ConfigService],
    };
  }
}
```

It should now be clear how the pieces tie together. Calling `ConfigModule.register(...)` returns a `DynamicModule` object with properties which are essentially the same as those that, until now, we've provided as metadata via the `@Module()` decorator.

> **Hint** Import `DynamicModule` from `@nestjs/common`.

Our dynamic module isn't very interesting yet, however, as we haven't introduced any capability to **configure** it as we said we would like to do. Let's address that next.

#### Module configuration[#](/fundamentals/dynamic-modules#module-configuration)

The obvious solution for customizing the behavior of the `ConfigModule` is to pass it an `options` object in the static `register()` method, as we guessed above. Let's look once again at our consuming module's `imports` property:

```typescript

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { ConfigModule } from './config/config.module';

@Module({
  imports: [ConfigModule.register({ folder: './config' })],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}
```

That nicely handles passing an `options` object to our dynamic module. How do we then use that `options` object in the `ConfigModule`? Let's consider that for a minute. We know that our `ConfigModule` is basically a host for providing and exporting an injectable service - the `ConfigService` - for use by other providers. It's actually our `ConfigService` that needs to read the `options` object to customize its behavior. Let's assume for the moment that we know how to somehow get the `options` from the `register()` method into the `ConfigService`. With that assumption, we can make a few changes to the service to customize its behavior based on the properties from the `options` object. (**Note**: for the time being, since we *haven't* actually determined how to pass it in, we'll just hard-code `options`. We'll fix this in a minute).

```typescript

import { Injectable } from '@nestjs/common';
import * as dotenv from 'dotenv';
import * as fs from 'fs';
import { EnvConfig } from './interfaces';

@Injectable()
export class ConfigService {
  private readonly envConfig: EnvConfig;

  constructor() {
    const options = { folder: './config' };

    const filePath = `${process.env.NODE_ENV || 'development'}.env`;
    const envFile = path.resolve(__dirname, '../../', options.folder, filePath);
    this.envConfig = dotenv.parse(fs.readFileSync(envFile));
  }

  get(key: string): string {
    return this.envConfig[key];
  }
}
```

Now our `ConfigService` knows how to find the `.env` file in the folder we've specified in `options`.

Our remaining task is to somehow inject the `options` object from the `register()` step into our `ConfigService`. And of course, we'll use *dependency injection* to do it. This is a key point, so make sure you understand it. Our `ConfigModule` is providing `ConfigService`. `ConfigService` in turn depends on the `options` object that is only supplied at run-time. So, at run-time, we'll need to first bind the `options` object to the Nest IoC container, and then have Nest inject it into our `ConfigService`. Remember from the **Custom providers** chapter that providers can [include any value](https://docs.nestjs.com/fundamentals/custom-providers#non-service-based-providers) not just services, so we're fine using dependency injection to handle a simple `options` object.

Let's tackle binding the options object to the IoC container first. We do this in our static `register()` method. Remember that we are dynamically constructing a module, and one of the properties of a module is its list of providers. So what we need to do is define our options object as a provider. This will make it injectable into the `ConfigService`, which we'll take advantage of in the next step. In the code below, pay attention to the `providers` array:

```typescript

import { DynamicModule, Module } from '@nestjs/common';
import { ConfigService } from './config.service';

@Module({})
export class ConfigModule {
  static register(options): DynamicModule {
    return {
      module: ConfigModule,
      providers: [
        {
          provide: 'CONFIG_OPTIONS',
          useValue: options,
        },
        ConfigService,
      ],
      exports: [ConfigService],
    };
  }
}
```

Now we can complete the process by injecting the `'CONFIG_OPTIONS'` provider into the `ConfigService`. Recall that when we define a provider using a non-class token we need to use the `@Inject()` decorator [as described here](https://docs.nestjs.com/fundamentals/custom-providers#non-class-based-provider-tokens).

```typescript

import * as dotenv from 'dotenv';
import * as fs from 'fs';
import { Injectable, Inject } from '@nestjs/common';
import { EnvConfig } from './interfaces';

@Injectable()
export class ConfigService {
  private readonly envConfig: EnvConfig;

  constructor(@Inject('CONFIG_OPTIONS') private options) {
    const filePath = `${process.env.NODE_ENV || 'development'}.env`;
    const envFile = path.resolve(__dirname, '../../', options.folder, filePath);
    this.envConfig = dotenv.parse(fs.readFileSync(envFile));
  }

  get(key: string): string {
    return this.envConfig[key];
  }
}
```

One final note: for simplicity we used a string-based injection token (`'CONFIG_OPTIONS'`) above, but best practice is to define it as a constant (or `Symbol`) in a separate file, and import that file. For example:

```typescript

export const CONFIG_OPTIONS = 'CONFIG_OPTIONS';
```

#### Example[#](/fundamentals/dynamic-modules#example)

A full example of the code in this chapter can be found [here](https://github.com/nestjs/nest/tree/master/sample/25-dynamic-modules).

#### Community guidelines[#](/fundamentals/dynamic-modules#community-guidelines)

You may have seen the use for methods like `forRoot`, `register`, and `forFeature` around some of the `@nestjs/` packages and may be wondering what the difference for all of these methods are. There is no hard rule about this, but the `@nestjs/` packages try to follow these guidelines:

When creating a module with:

* `register`, you are expecting to configure a dynamic module with a specific configuration for use only by the calling module. For example, with Nest's `@nestjs/axios`: `HttpModule.register({ baseUrl: 'someUrl' })`. If, in another module you use `HttpModule.register({ baseUrl: 'somewhere else' })`, it will have the different configuration. You can do this for as many modules as you want.

* `forRoot`, you are expecting to configure a dynamic module once and reuse that configuration in multiple places (though possibly unknowingly as it's abstracted away). This is why you have one `GraphQLModule.forRoot()`, one `TypeOrmModule.forRoot()`, etc.

* `forFeature`, you are expecting to use the configuration of a dynamic module's `forRoot` but need to modify some configuration specific to the calling module's needs (i.e. which repository this module should have access to, or the context that a logger should use.)

All of these, usually, have their `async` counterparts as well, `registerAsync`, `forRootAsync`, and `forFeatureAsync`, that mean the same thing, but use Nest's Dependency Injection for the configuration as well.

----
url: https://docs.nestjs.com/v5/migration-guide
----

### Migration guide

This article provides a set of **guidelines** to migrate from 4 to latest 5 version. During the development, we spent a lot of time trying to avoid any breaking changes. Nevertheless, the API had to change in a bunch of places in order to simplify its usage. Also, the previous version has been limited due to decisions that have been made at the very early stage. Now, we are less opinionated and even more powerful than before.

#### Modules

In order to decrease the number of differences between Nest and [Angular](https://angular.io/), few changes have been made regarding `@Module()` decorator.

* `modules` property is now deprecated. Use `imports` instead
* `components` property is now deprecated. Use `providers` instead

#### Decorators

The `@Component()`, `@Middleware()`, `@Interceptor()`, `@Pipe()`, and `@Guard()` are deprecated now. Use `@Injectable()` instead.

#### Middleware interfaces

The `MiddlewaresConsumer` class has been changed to `MiddlewareConsumer`. Also, the `ExpressMiddleware` no longer exists, use `MiddlewareFunction` interface instead.

#### Filters

The exception filters aren't locked in as single-paradigm anymore. Previously, an exception filter had an access to the `response` object. Together with an incoming release, `catch()` method takes `ArgumentsHost` instance instead. This object is well described [here](/v5/exception-filters). Thanks to that, you have an access to each argument, including `response` object.

JS TS

TypeScript

```typescript

// Before
@Catch(HttpException)
export class HttpExceptionFilter implements ExceptionFilter {
  catch(exception: HttpException, response) {}
}

// After
@Catch(HttpException)
export class HttpExceptionFilter implements ExceptionFilter {
  catch(exception: HttpException, host: ArgumentsHost) {
    const response = host.switchToHttp().getResponse();
    // ...
  }
}
```

TypeScript

```typescript

// Before
@Catch(HttpException)
export class HttpExceptionFilter {
  catch(exception, response) {}
}

// After
@Catch(HttpException)
export class HttpExceptionFilter {
  catch(exception, host) {
    const response = host.switchToHttp().getResponse();
    // ...
  }
}
```

#### Guards

The same as filters, guards are far more **flexible** now. An access to the enhanced `ExecutionContext` ([read more](/v5/guards)) gives guards more superpowers and all of that has been built on top of simplified API.

JS TS

TypeScript

```typescript

// Before
@Guard()
export class RolesGuard implements CanActivate {
  canActivate(
    dataOrRequest,
    context: ExecutionContext,
  ): boolean | Promise<boolean> | Observable<boolean> {
    return true;
  }
}

// After
@Injectable()
export class RolesGuard implements CanActivate {
  canActivate(
    context: ExecutionContext,
  ): boolean | Promise<boolean> | Observable<boolean> {
    // const request = context.switchToHttp().getRequest();
    // const data = context.switchToWs().getData();
    return true;
  }
}
```

TypeScript

```typescript

// Before
@Guard()
export class RolesGuard {
  canActivate(dataOrRequest, context) {
    return true;
  }
}

// After
@Injectable()
export class RolesGuard {
  canActivate(context) {
    // const request = context.switchToHttp().getRequest();
    // const data = context.switchToWs().getData();
    return true;
  }
}
```

#### Interceptors

The interceptors API evolved in the exact same way as **equivalent** guards API.

JS TS

TypeScript

```typescript

// Before
@Interceptor()
export class TransformInterceptor implements NestInterceptor {
  intercept(
    dataOrRequest,
    context: ExecutionContext,
    stream$: Observable<any>,
  ): Observable<any> {
    return stream$.map((data) => ({ data }));
  }
}

// After
@Injectable()
export class TransformInterceptor implements NestInterceptor {
  intercept(
    context: ExecutionContext,
    call$: Observable<T>,
  ): Observable<Response<T>> {
    // const request = context.switchToHttp().getRequest();
    // const data = context.switchToWs().getData();
    return call$.pipe(map(data => ({ data })));
  }
}
```

TypeScript

```typescript

// Before
@Interceptor()
export class TransformInterceptor {
  intercept(dataOrRequest, context, stream$) {
    return stream$.map((data) => ({ data }));
  }
}

// After
@Injectable()
export class TransformInterceptor {
  intercept(context, call$) {
    // const request = context.switchToHttp().getRequest();
    // const data = context.switchToWs().getData();
    return call$.pipe(map(data => ({ data })));
  }
}
```

#### Custom decorators

The `createRouteParamDecorator()` function is deprecated. Use `createParamDecorator()` now.

#### Node.js

We follow the Node.js release schedule which recently moved to `8.x` as an active **LTS** version. Therefore, Nest 5 supports >= `8.9.0` as the lowest version now. This shift gaves us sustainable performance boosts thanks to the `es2017` target of the TypeScript compilation.

#### External libraries

Nest 5 doesn't support [rxjs](https://github.com/ReactiveX/rxjs) < 6.0.0. Keep in mind to upgrade this package as well.

* Migration guide
* Modules
* Decorators
* Middleware interfaces
* Filters
* Guards
* Interceptors
* Custom decorators
* Node.js
* External libraries

----
url: https://docs.nestjs.com/v5/support
----

### Support

Nest is an MIT-licensed open source project with its ongoing development made possible thanks to the support by the community. This framework is a result of the long road, full of sleepless nights, working **after hours**, and busy weekends.

Nest doesn't have a large company that sits behind and is continuously paying for hours spent on the development. I fully rely on the **goodness** ❤️ of the people. However, I would love to make this framework even more **powerful**, to be fully focused on delivering you great solutions that make coding process enjoyable: In order to help me, I run few supporting platforms:

* become a backer or sponsor on [OpenCollective](https://opencollective.com/nest)
* use [PayPal](https://paypal.me/kamilmysliwiec) to send a one-time donation
* or reach me directly: <mail@kamilmysliwiec.com>

If you fell in love with Nest, or you run a business which is using Nest, consider sponsoring its development to ensure that the project which your product relies on is **actively maintained** and improved. Also, your support could help me to work more on content that benefits whole Nest community, writing either educational blog posts or recording videos.

* Support

----
url: https://docs.nestjs.com/v11/fundamentals/custom-providers
----

* [Custom providers](https://docs.nestjs.com/v11/fundamentals/custom-providers#custom-providers)
* [DI fundamentals](https://docs.nestjs.com/v11/fundamentals/custom-providers#di-fundamentals)
* [Standard providers](https://docs.nestjs.com/v11/fundamentals/custom-providers#standard-providers)
* [Custom providers](https://docs.nestjs.com/v11/fundamentals/custom-providers#custom-providers-1)
* [Value providers: useValue](https://docs.nestjs.com/v11/fundamentals/custom-providers#value-providers-usevalue)
* [Non-class-based provider tokens](https://docs.nestjs.com/v11/fundamentals/custom-providers#non-class-based-provider-tokens)
* [Interfaces and abstract classes](https://docs.nestjs.com/v11/fundamentals/custom-providers#interfaces-and-abstract-classes)
* [Class providers: useClass](https://docs.nestjs.com/v11/fundamentals/custom-providers#class-providers-useclass)
* [Factory providers: useFactory](https://docs.nestjs.com/v11/fundamentals/custom-providers#factory-providers-usefactory)
* [Alias providers: useExisting](https://docs.nestjs.com/v11/fundamentals/custom-providers#alias-providers-useexisting)
* [Non-service based providers](https://docs.nestjs.com/v11/fundamentals/custom-providers#non-service-based-providers)
* [Export custom provider](https://docs.nestjs.com/v11/fundamentals/custom-providers#export-custom-provider)

```typescript

import { Injectable } from '@nestjs/common';
import { Cat } from './interfaces/cat.interface';

@Injectable()
export class CatsService {
  private readonly cats: Cat[] = [];

  findAll(): Cat[] {
    return this.cats;
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';

@Injectable()
export class CatsService {
  constructor() {
    this.cats = [];
  }

  findAll() {
    return this.cats;
  }
}
```

Then we request that Nest inject the provider into our controller class:

cats.controller.ts

JS TS

```typescript

import { Controller, Get } from '@nestjs/common';
import { CatsService } from './cats.service';
import { Cat } from './interfaces/cat.interface';

@Controller('cats')
export class CatsController {
  constructor(private catsService: CatsService) {}

  @Get()
  async findAll(): Promise<Cat[]> {
    return this.catsService.findAll();
  }
}
```

```typescript

import { Controller, Get, Bind, Dependencies } from '@nestjs/common';
import { CatsService } from './cats.service';

@Controller('cats')
@Dependencies(CatsService)
export class CatsController {
  constructor(catsService) {
    this.catsService = catsService;
  }

  @Get()
  async findAll() {
    return this.catsService.findAll();
  }
}
```

Finally, we register the provider with the Nest IoC container:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { CatsController } from './cats/cats.controller';
import { CatsService } from './cats/cats.service';

@Module({
  controllers: [CatsController],
  providers: [CatsService],
})
export class AppModule {}
```

What exactly is happening under the covers to make this work? There are three key steps in the process:

1. In `cats.service.ts`, the `@Injectable()` decorator declares the `CatsService` class as a class that can be managed by the Nest IoC container.
2. In `cats.controller.ts`, `CatsController` declares a dependency on the `CatsService` token with constructor injection:

```typescript

  constructor(private catsService: CatsService)
```

```typescript

@Module({
  controllers: [CatsController],
  providers: [CatsService],
})
```

The `providers` property takes an array of `providers`. So far, we've supplied those providers via a list of class names. In fact, the syntax `providers: [CatsService]` is short-hand for the more complete syntax:

```typescript

providers: [
  {
    provide: CatsService,
    useClass: CatsService,
  },
];
```

> **Hint** If you are having problems with dependency resolution you can set the `NEST_DEBUG` environment variable and get extra dependency resolution logs during startup.

#### Value providers: `useValue`[#](/fundamentals/custom-providers#value-providers-usevalue)

The `useValue` syntax is useful for injecting a constant value, putting an external library into the Nest container, or replacing a real implementation with a mock object. Let's say you'd like to force Nest to use a mock `CatsService` for testing purposes.

```typescript

import { CatsService } from './cats.service';

const mockCatsService = {
  /* mock implementation
  ...
  */
};

@Module({
  imports: [CatsModule],
  providers: [
    {
      provide: CatsService,
      useValue: mockCatsService,
    },
  ],
})
export class AppModule {}
```

In this example, the `CatsService` token will resolve to the `mockCatsService` mock object. `useValue` requires a value - in this case a literal object that has the same interface as the `CatsService` class it is replacing. Because of TypeScript's [structural typing](https://www.typescriptlang.org/docs/handbook/type-compatibility.html), you can use any object that has a compatible interface, including a literal object or a class instance instantiated with `new`.

#### Non-class-based provider tokens[#](/fundamentals/custom-providers#non-class-based-provider-tokens)

So far, we've used class names as our provider tokens (the value of the `provide` property in a provider listed in the `providers` array). This is matched by the standard pattern used with [constructor based injection](https://docs.nestjs.com/providers#dependency-injection), where the token is also a class name. (Refer back to [DI Fundamentals](/fundamentals/custom-providers#di-fundamentals) for a refresher on tokens if this concept isn't entirely clear). Sometimes, we may want the flexibility to use strings or symbols as the DI token. For example:

```typescript

import { connection } from './connection';

@Module({
  providers: [
    {
      provide: 'CONNECTION',
      useValue: connection,
    },
  ],
})
export class AppModule {}
```

In this example, we are associating a string-valued token (`'CONNECTION'`) with a pre-existing `connection` object we've imported from an external file.

> **Notice** In addition to using strings as token values, you can also use JavaScript [symbols](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol) or TypeScript [enums](https://www.typescriptlang.org/docs/handbook/enums.html).

We've previously seen how to inject a provider using the standard [constructor based injection](https://docs.nestjs.com/providers#dependency-injection) pattern. This pattern **requires** that the dependency be declared with a class name. The `'CONNECTION'` custom provider uses a string-valued token. Let's see how to inject such a provider. To do so, we use the `@Inject()` decorator. This decorator takes a single argument - the token.

JS TS

```typescript

@Injectable()
export class CatsRepository {
  constructor(@Inject('CONNECTION') connection: Connection) {}
}
```

```typescript

@Injectable()
@Dependencies('CONNECTION')
export class CatsRepository {
  constructor(connection) {}
}
```

> **Hint** The `@Inject()` decorator is imported from `@nestjs/common` package.

While we directly use the string `'CONNECTION'` in the above examples for illustration purposes, for clean code organization, it's best practice to define tokens in a separate file, such as `constants.ts`. Treat them much as you would symbols or enums that are defined in their own file and imported where needed.

#### Interfaces and abstract classes[#](/fundamentals/custom-providers#interfaces-and-abstract-classes)

TypeScript types/interfaces are erased during compilation, so Nest can't reference them at runtime. This means an interface can describe the shape of a dependency, but it can't be used as a DI token by itself.

Since Nest resolves providers by runtime tokens, use a string or `Symbol` token when registering a provider for an interface:

```typescript

export interface LoggerService {
  log(message: string): void;
}

export const LOGGER_SERVICE = Symbol('LOGGER_SERVICE');

@Injectable()
export class PinoLoggerService implements LoggerService {
  log(message: string) {
    // implementation details
  }
}

@Module({
  providers: [
    {
      provide: LOGGER_SERVICE,
      useClass: PinoLoggerService,
    },
  ],
})
export class AppModule {}
```

To inject this provider, pass that token to the `@Inject()` decorator:

```typescript

@Injectable()
export class CatsService {
  constructor(
    @Inject(LOGGER_SERVICE)
    private readonly logger: LoggerService,
  ) {}
}
```

Abstract classes, unlike interfaces, exist at runtime. You can use an abstract class as both the TypeScript contract and the DI token:

```typescript

export abstract class LoggerService {
  abstract log(message: string): void;
}

@Injectable()
export class PinoLoggerService implements LoggerService {
  log(message: string) {
    // implementation details
  }
}

@Module({
  providers: [
    {
      provide: LoggerService,
      useClass: PinoLoggerService,
    },
  ],
})
export class AppModule {}
```

With an abstract class token, constructor-based injection can use the abstract class type directly and doesn't require `@Inject()`:

```typescript

@Injectable()
export class CatsService {
  constructor(private readonly logger: LoggerService) {}
}
```

Use string or `Symbol` tokens when the runtime DI token should be decoupled from a class artifact. `Symbol` tokens are especially useful for libraries and larger applications because each symbol has a unique runtime identity, which helps avoid accidental collisions that can occur when unrelated providers use the same string token. When using a symbol token, export it from a shared file and reuse the same symbol instance wherever the provider is registered and injected. Use abstract classes when one artifact should act as both the contract and the runtime token, and you prefer simpler constructor injection. A plain interface is still a good choice when the type is only used for compile-time checking and no DI token is needed.

#### Class providers: `useClass`[#](/fundamentals/custom-providers#class-providers-useclass)

The `useClass` syntax allows you to dynamically determine a class that a token should resolve to. For example, suppose we have an abstract (or default) `ConfigService` class. Depending on the current environment, we want Nest to provide a different implementation of the configuration service. The following code implements such a strategy.

```typescript

const configServiceProvider = {
  provide: ConfigService,
  useClass:
    process.env.NODE_ENV === 'development'
      ? DevelopmentConfigService
      : ProductionConfigService,
};

@Module({
  providers: [configServiceProvider],
})
export class AppModule {}
```

```typescript

const connectionProvider = {
  provide: 'CONNECTION',
  useFactory: (optionsProvider: MyOptionsProvider, optionalProvider?: string) => {
    const options = optionsProvider.get();
    return new DatabaseConnection(options);
  },
  inject: [MyOptionsProvider, { token: 'SomeOptionalProvider', optional: true }],
  //       \______________/             \__________________/
  //        This provider                The provider with this token
  //        is mandatory.                can resolve to `undefined`.
};

@Module({
  providers: [
    connectionProvider,
    MyOptionsProvider, // class-based provider
    // { provide: 'SomeOptionalProvider', useValue: 'anything' },
  ],
})
export class AppModule {}
```

```typescript

const connectionProvider = {
  provide: 'CONNECTION',
  useFactory: (optionsProvider, optionalProvider) => {
    const options = optionsProvider.get();
    return new DatabaseConnection(options);
  },
  inject: [MyOptionsProvider, { token: 'SomeOptionalProvider', optional: true }],
  //       \______________/            \__________________/
  //        This provider               The provider with this token
  //        is mandatory.               can resolve to `undefined`.
};

@Module({
  providers: [
    connectionProvider,
    MyOptionsProvider, // class-based provider
    // { provide: 'SomeOptionalProvider', useValue: 'anything' },
  ],
})
export class AppModule {}
```

#### Alias providers: `useExisting`[#](/fundamentals/custom-providers#alias-providers-useexisting)

The `useExisting` syntax allows you to create aliases for existing providers. This creates two ways to access the same provider. In the example below, the (string-based) token `'AliasedLoggerService'` is an alias for the (class-based) token `LoggerService`. Assume we have two different dependencies, one for `'AliasedLoggerService'` and one for `LoggerService`. If both dependencies are specified with `SINGLETON` scope, they'll both resolve to the same instance.

```typescript

@Injectable()
class LoggerService {
  /* implementation details */
}

const loggerAliasProvider = {
  provide: 'AliasedLoggerService',
  useExisting: LoggerService,
};

@Module({
  providers: [LoggerService, loggerAliasProvider],
})
export class AppModule {}
```

#### Non-service based providers[#](/fundamentals/custom-providers#non-service-based-providers)

While providers often supply services, they are not limited to that usage. A provider can supply **any** value. For example, a provider may supply an array of configuration objects based on the current environment, as shown below:

```typescript

const configFactory = {
  provide: 'CONFIG',
  useFactory: () => {
    return process.env.NODE_ENV === 'development' ? devConfig : prodConfig;
  },
};

@Module({
  providers: [configFactory],
})
export class AppModule {}
```

#### Export custom provider[#](/fundamentals/custom-providers#export-custom-provider)

Like any provider, a custom provider is scoped to its declaring module. To make it visible to other modules, it must be exported. To export a custom provider, we can either use its token or the full provider object.

The following example shows exporting using the token:

JS TS

```typescript

const connectionFactory = {
  provide: 'CONNECTION',
  useFactory: (optionsProvider: OptionsProvider) => {
    const options = optionsProvider.get();
    return new DatabaseConnection(options);
  },
  inject: [OptionsProvider],
};

@Module({
  providers: [connectionFactory],
  exports: ['CONNECTION'],
})
export class AppModule {}
```

```typescript

const connectionFactory = {
  provide: 'CONNECTION',
  useFactory: (optionsProvider) => {
    const options = optionsProvider.get();
    return new DatabaseConnection(options);
  },
  inject: [OptionsProvider],
};

@Module({
  providers: [connectionFactory],
  exports: ['CONNECTION'],
})
export class AppModule {}
```

Alternatively, export with the full provider object:

JS TS

```typescript

const connectionFactory = {
  provide: 'CONNECTION',
  useFactory: (optionsProvider: OptionsProvider) => {
    const options = optionsProvider.get();
    return new DatabaseConnection(options);
  },
  inject: [OptionsProvider],
};

@Module({
  providers: [connectionFactory],
  exports: [connectionFactory],
})
export class AppModule {}
```

```typescript

const connectionFactory = {
  provide: 'CONNECTION',
  useFactory: (optionsProvider) => {
    const options = optionsProvider.get();
    return new DatabaseConnection(options);
  },
  inject: [OptionsProvider],
};

@Module({
  providers: [connectionFactory],
  exports: [connectionFactory],
})
export class AppModule {}
```

----
url: https://docs.nestjs.com/v11/graphql/resolvers
----

* [Resolvers](https://docs.nestjs.com/v11/graphql/resolvers#resolvers)
* [Code first](https://docs.nestjs.com/v11/graphql/resolvers#code-first)
* [Object types](https://docs.nestjs.com/v11/graphql/resolvers#object-types)
* [Code first resolver](https://docs.nestjs.com/v11/graphql/resolvers#code-first-resolver)
* [Query type names](https://docs.nestjs.com/v11/graphql/resolvers#query-type-names)
* [Query decorator options](https://docs.nestjs.com/v11/graphql/resolvers#query-decorator-options)
* [Args decorator options](https://docs.nestjs.com/v11/graphql/resolvers#args-decorator-options)
* [Dedicated arguments class](https://docs.nestjs.com/v11/graphql/resolvers#dedicated-arguments-class)
* [Class inheritance](https://docs.nestjs.com/v11/graphql/resolvers#class-inheritance)
* [Generics](https://docs.nestjs.com/v11/graphql/resolvers#generics)
* [Schema first](https://docs.nestjs.com/v11/graphql/resolvers#schema-first)
* [Schema first resolver](https://docs.nestjs.com/v11/graphql/resolvers#schema-first-resolver)
* [Generating types](https://docs.nestjs.com/v11/graphql/resolvers#generating-types)
* [GraphQL argument decorators](https://docs.nestjs.com/v11/graphql/resolvers#graphql-argument-decorators)
* [Module](https://docs.nestjs.com/v11/graphql/resolvers#module)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/resolvers-map.md "Suggest Edits")

### Resolvers

Resolvers provide the instructions for turning a [GraphQL](https://graphql.org/) operation (a query, mutation, or subscription) into data. They return the same shape of data we specify in our schema -- either synchronously or as a promise that resolves to a result of that shape. Typically, you create a **resolver map** manually. The `@nestjs/graphql` package, on the other hand, generates a resolver map automatically using the metadata provided by the decorators you use to annotate classes. To demonstrate the process of using the package features to create a GraphQL API, we'll create a simple authors API.

#### Code first[#](/graphql/resolvers#code-first)

In the code-first approach, we don't follow the typical process of creating our GraphQL schema by writing GraphQL SDL by hand. Instead, we use TypeScript decorators to generate the SDL from TypeScript class definitions. The `@nestjs/graphql` package reads the metadata defined through the decorators and automatically generates the schema for you.

#### Object types[#](/graphql/resolvers#object-types)

Most of the definitions in a GraphQL schema are **object types**. Each object type you define should represent a domain object that an application client might need to interact with. For example, our sample API needs to be able to fetch a list of authors and their posts, so we should define the `Author` type and `Post` type to support this functionality.

If we were using the schema-first approach, we'd define such a schema with SDL like this:

```graphql

type Author {
  id: Int!
  firstName: String
  lastName: String
  posts: [Post!]!
}
```

In this case, using the code first approach, we define schemas using TypeScript classes and using TypeScript decorators to annotate the fields of those classes. The equivalent of the above SDL in the code first approach is:

authors/models/author.model.ts

JS TS

```typescript

import { Field, Int, ObjectType } from '@nestjs/graphql';
import { Post } from './post';

@ObjectType()
export class Author {
  @Field(type => Int)
  id: number;

  @Field({ nullable: true })
  firstName?: string;

  @Field({ nullable: true })
  lastName?: string;

  @Field(type => [Post])
  posts: Post[];
}
```

> **Hint** TypeScript's metadata reflection system has several limitations which make it impossible, for instance, to determine what properties a class consists of or recognize whether a given property is optional or required. Because of these limitations, we must either explicitly use the `@Field()` decorator in our schema definition classes to provide metadata about each field's GraphQL type and optionality, or use a [CLI plugin](/v11/graphql/cli-plugin) to generate these for us.

The `Author` object type, like any class, is made of a collection of fields, with each field declaring a type. A field's type corresponds to a [GraphQL type](https://graphql.org/learn/schema/). A field's GraphQL type can be either another object type or a scalar type. A GraphQL scalar type is a primitive (like `ID`, `String`, `Boolean`, or `Int`) that resolves to a single value.

> **Hint** In addition to GraphQL's built-in scalar types, you can define custom scalar types (read [more](/v11/graphql/scalars)).

The above `Author` object type definition will cause Nest to **generate** the SDL we showed above:

```graphql

type Author {
  id: Int!
  firstName: String
  lastName: String
  posts: [Post!]!
}
```

```typescript

@Field({ description: `Book title`, deprecationReason: 'Not useful in v2 schema' })
title: string;
```

> **Hint** You can also add a description to, or deprecate, the whole object type: `@ObjectType({ description: 'Author model' })`.

When the field is an array, we must manually indicate the array type in the `Field()` decorator's type function, as shown below:

```typescript

@Field(type => [Post])
posts: Post[];
```

> **Hint** Using array bracket notation (`[ ]`), we can indicate the depth of the array. For example, using `[[Int]]` would represent an integer matrix.

To declare that an array's items (not the array itself) are nullable, set the `nullable` property to `'items'` as shown below:

```typescript

@Field(type => [Post], { nullable: 'items' })
posts: Post[];
```

> **Hint** If both the array and its items are nullable, set `nullable` to `'itemsAndList'` instead.

Now that the `Author` object type is created, let's define the `Post` object type.

posts/models/post.model.ts

JS TS

```typescript

import { Field, Int, ObjectType } from '@nestjs/graphql';

@ObjectType()
export class Post {
  @Field(type => Int)
  id: number;

  @Field()
  title: string;

  @Field(type => Int, { nullable: true })
  votes?: number;
}
```

The `Post` object type will result in generating the following part of the GraphQL schema in SDL:

```graphql

type Post {
  id: Int!
  title: String!
  votes: Int
}
```

#### Code first resolver[#](/graphql/resolvers#code-first-resolver)

At this point, we've defined the objects (type definitions) that can exist in our data graph, but clients don't yet have a way to interact with those objects. To address that, we need to create a resolver class. In the code first method, a resolver class both defines resolver functions **and** generates the **Query type**. This will be clear as we work through the example below:

authors/authors.resolver.ts

JS TS

```typescript

@Resolver(() => Author)
export class AuthorsResolver {
  constructor(
    private authorsService: AuthorsService,
    private postsService: PostsService,
  ) {}

  @Query(() => Author)
  async author(@Args('id', { type: () => Int }) id: number) {
    return this.authorsService.findOneById(id);
  }

  @ResolveField()
  async posts(@Parent() author: Author) {
    const { id } = author;
    return this.postsService.findAll({ authorId: id });
  }
}
```

> **Hint** All decorators (e.g., `@Resolver`, `@ResolveField`, `@Args`, etc.) are exported from the `@nestjs/graphql` package.

You can define multiple resolver classes. Nest will combine these at run time. See the [module](/graphql/resolvers#module) section below for more on code organization.

> **Note** The logic inside the `AuthorsService` and `PostsService` classes can be as simple or sophisticated as needed. The main point of this example is to show how to construct resolvers and how they can interact with other providers.

In the example above, we created the `AuthorsResolver`, which defines one query resolver function and one field resolver function. To create a resolver, we create a class with resolver functions as methods, and annotate the class with the `@Resolver()` decorator.

In this example, we defined a query handler to get the author object based on the `id` sent in the request. To specify that the method is a query handler, use the `@Query()` decorator.

The argument passed to the `@Resolver()` decorator is optional, but comes into play when our graph becomes non-trivial. It's used to supply a parent object used by field resolver functions as they traverse down through an object graph.

In our example, since the class includes a **field resolver** function (for the `posts` property of the `Author` object type), we **must** supply the `@Resolver()` decorator with a value to indicate which class is the parent type (i.e., the corresponding `ObjectType` class name) for all field resolvers defined within this class. As should be clear from the example, when writing a field resolver function, it's necessary to access the parent object (the object the field being resolved is a member of). In this example, we populate an author's posts array with a field resolver that calls a service that takes the author's `id` as an argument. Hence, the need to identify the parent object in the `@Resolver()` decorator. Note the corresponding use of the `@Parent()` method parameter decorator to then extract a reference to that parent object in the field resolver.

We can define multiple `@Query()` resolver functions (both within this class and in any other resolver class), and they will be aggregated into a single **Query type** definition in the generated SDL along with the appropriate entries in the resolver map. This allows you to define queries close to the models and services that they use, and to keep them well organized in modules.

> **Hint** Nest CLI provides a generator (schematic) that automatically generates **all the boilerplate code** to help us avoid doing all of this, and make the developer experience much simpler. Read more about this feature [here](/v11/recipes/crud-generator).

#### Query type names[#](/graphql/resolvers#query-type-names)

In the above examples, the `@Query()` decorator generates a GraphQL schema query type name based on the method name. For example, consider the following construction from the example above:

```typescript

@Query(() => Author)
async author(@Args('id', { type: () => Int }) id: number) {
  return this.authorsService.findOneById(id);
}
```

This generates the following entry for the author query in our schema (the query type uses the same name as the method name):

```graphql

type Query {
  author(id: Int!): Author
}
```

> **Hint** Learn more about GraphQL queries [here](https://graphql.org/learn/queries/).

Conventionally, we prefer to decouple these names; for example, we prefer to use a name like `getAuthor()` for our query handler method, but still use `author` for our query type name. The same applies to our field resolvers. We can easily do this by passing the mapping names as arguments of the `@Query()` and `@ResolveField()` decorators, as shown below:

authors/authors.resolver.ts

JS TS

```typescript

@Resolver(() => Author)
export class AuthorsResolver {
  constructor(
    private authorsService: AuthorsService,
    private postsService: PostsService,
  ) {}

  @Query(() => Author, { name: 'author' })
  async getAuthor(@Args('id', { type: () => Int }) id: number) {
    return this.authorsService.findOneById(id);
  }

  @ResolveField('posts', () => [Post])
  async getPosts(@Parent() author: Author) {
    const { id } = author;
    return this.postsService.findAll({ authorId: id });
  }
}
```

The `getAuthor` handler method above will result in generating the following part of the GraphQL schema in SDL:

```graphql

type Query {
  author(id: Int!): Author
}
```

#### Query decorator options[#](/graphql/resolvers#query-decorator-options)

The `@Query()` decorator's options object (where we pass `{name: 'author'}` above) accepts a number of key/value pairs:

* `name`: name of the query; a `string`
* `description`: a description that will be used to generate GraphQL schema documentation (e.g., in GraphQL playground); a `string`
* `deprecationReason`: sets query metadata to show the query as deprecated (e.g., in GraphQL playground); a `string`
* `nullable`: whether the query can return a null data response; `boolean` or `'items'` or `'itemsAndList'` (see above for details of `'items'` and `'itemsAndList'`)

#### Args decorator options[#](/graphql/resolvers#args-decorator-options)

Use the `@Args()` decorator to extract arguments from a request for use in the method handler. This works in a very similar fashion to [REST route parameter argument extraction](/controllers#route-parameters).

Usually, your `@Args()` decorator will be simple and not require an object argument, as seen with the `getAuthor()` method above. For example, if the type of an identifier is string, the following construction is sufficient, and simply plucks the named field from the inbound GraphQL request for use as a method argument.

```typescript

@Args('id') id: string
```

In the `getAuthor()` case, the `number` type is used, which presents a challenge. The `number` TypeScript type doesn't give us enough information about the expected GraphQL representation (e.g., `Int` vs. `Float`). Thus, we have to **explicitly** pass the type reference. We do that by passing a second argument to the `Args()` decorator, containing argument options, as shown below:

```typescript

@Query(() => Author, { name: 'author' })
async getAuthor(@Args('id', { type: () => Int }) id: number) {
  return this.authorsService.findOneById(id);
}
```

The options object allows us to specify the following optional key-value pairs:

* `type`: a function returning the GraphQL type
* `defaultValue`: a default value; `any`
* `description`: description metadata; `string`
* `deprecationReason`: to deprecate a field and provide metadata describing why; `string`
* `nullable`: whether the field is nullable

Query handler methods can take multiple arguments. Let's imagine that we want to fetch an author based on its `firstName` and `lastName`. In this case, we can call `@Args` twice:

```typescript

getAuthor(
  @Args('firstName', { nullable: true }) firstName?: string,
  @Args('lastName', { defaultValue: '' }) lastName?: string,
) {}
```

> **Hint** In the case of `firstName`, which is a GraphQL nullable field, it isn't necessary to add the non-value types of `null` or `undefined` to the type of this field. Just be aware, you'll need to type guard for these possible non-value types in your resolvers, because a GraphQL nullable field will allow those types to pass through to your resolver.

#### Dedicated arguments class[#](/graphql/resolvers#dedicated-arguments-class)

With inline `@Args()` calls, code like the example above becomes bloated. Instead, you can create a dedicated `GetAuthorArgs` arguments class and access it in the handler method as follows:

```typescript

@Args() args: GetAuthorArgs
```

Create the `GetAuthorArgs` class using `@ArgsType()` as shown below:

authors/dto/get-author.args.ts

JS TS

```typescript

import { MinLength } from 'class-validator';
import { Field, ArgsType } from '@nestjs/graphql';

@ArgsType()
class GetAuthorArgs {
  @Field({ nullable: true })
  firstName?: string;

  @Field({ defaultValue: '' })
  @MinLength(3)
  lastName: string;
}
```

> **Hint** Again, due to TypeScript's metadata reflection system limitations, it's required to either use the `@Field` decorator to manually indicate type and optionality, or use a [CLI plugin](/v11/graphql/cli-plugin). Also, in the case of `firstName`, which is a GraphQL nullable field, it isn't necessary to add the non-value types of `null` or `undefined` to the type of this field. Just be aware, you'll need to type guard for these possible non-value types in your resolvers, because a GraphQL nullable field will allow those types to pass through to your resolver.

This will result in generating the following part of the GraphQL schema in SDL:

```graphql

type Query {
  author(firstName: String, lastName: String = ''): Author
}
```

> **Hint** Note that argument classes like `GetAuthorArgs` play very well with the `ValidationPipe` (read [more](/v11/techniques/validation)).

#### Class inheritance[#](/graphql/resolvers#class-inheritance)

You can use standard TypeScript class inheritance to create base classes with generic utility type features (fields and field properties, validations, etc.) that can be extended. For example, you may have a set of pagination related arguments that always include the standard `offset` and `limit` fields, but also other index fields that are type-specific. You can set up a class hierarchy as shown below.

Base `@ArgsType()` class:

```typescript

@ArgsType()
class PaginationArgs {
  @Field(() => Int)
  offset: number = 0;

  @Field(() => Int)
  limit: number = 10;
}
```

Type specific sub-class of the base `@ArgsType()` class:

```typescript

@ArgsType()
class GetAuthorArgs extends PaginationArgs {
  @Field({ nullable: true })
  firstName?: string;

  @Field({ defaultValue: '' })
  @MinLength(3)
  lastName: string;
}
```

The same approach can be taken with `@ObjectType()` objects. Define generic properties on the base class:

```typescript

@ObjectType()
class Character {
  @Field(() => Int)
  id: number;

  @Field()
  name: string;
}
```

Add type-specific properties on sub-classes:

```typescript

@ObjectType()
class Warrior extends Character {
  @Field()
  level: number;
}
```

You can use inheritance with a resolver as well. You can ensure type safety by combining inheritance and TypeScript generics. For example, to create a base class with a generic `findAll` query, use a construction like this:

```typescript

function BaseResolver<T extends Type<unknown>>(classRef: T): any {
  @Resolver({ isAbstract: true })
  abstract class BaseResolverHost {
    @Query(() => [classRef], { name: `findAll${classRef.name}` })
    async findAll(): Promise<T[]> {
      return [];
    }
  }
  return BaseResolverHost;
}
```

Note the following:

* An explicit return type (`any` above) is required; otherwise, TypeScript complains about the usage of a private class definition. Recommended: define an interface instead of using `any`.
* `Type` is imported from the `@nestjs/common` package
* The `isAbstract: true` property indicates that SDL (Schema Definition Language statements) shouldn't be generated for this class. Note, you can set this property for other types as well to suppress SDL generation.

Here's how you could generate a concrete subclass of the `BaseResolver`:

```typescript

@Resolver(() => Recipe)
export class RecipesResolver extends BaseResolver(Recipe) {
  constructor(private recipesService: RecipesService) {
    super();
  }
}
```

This construct would generate the following SDL:

```graphql

type Query {
  findAllRecipe: [Recipe!]!
}
```

#### Generics[#](/graphql/resolvers#generics)

We saw one use of generics above. This powerful TypeScript feature can be used to create useful abstractions. For example, here's a sample cursor-based pagination implementation based on [this documentation](https://graphql.org/learn/pagination/#pagination-and-edges):

```typescript

import { Field, ObjectType, Int } from '@nestjs/graphql';
import { Type } from '@nestjs/common';

interface IEdgeType<T> {
  cursor: string;
  node: T;
}

export interface IPaginatedType<T> {
  edges: IEdgeType<T>[];
  nodes: T[];
  totalCount: number;
  hasNextPage: boolean;
}

export function Paginated<T>(classRef: Type<T>): Type<IPaginatedType<T>> {
  @ObjectType(`${classRef.name}Edge`)
  abstract class EdgeType {
    @Field(() => String)
    cursor: string;

    @Field(() => classRef)
    node: T;
  }

  @ObjectType({ isAbstract: true })
  abstract class PaginatedType implements IPaginatedType<T> {
    @Field(() => [EdgeType], { nullable: true })
    edges: EdgeType[];

    @Field(() => [classRef], { nullable: true })
    nodes: T[];

    @Field(() => Int)
    totalCount: number;

    @Field()
    hasNextPage: boolean;
  }
  return PaginatedType as Type<IPaginatedType<T>>;
}
```

With the above base class defined, we can now easily create specialized types that inherit this behavior. For example:

```typescript

@ObjectType()
class PaginatedAuthor extends Paginated(Author) {}
```

#### Schema first[#](/graphql/resolvers#schema-first)

As mentioned in the [previous](/v11/graphql/quick-start) chapter, in the schema-first approach, we start by manually defining schema types in SDL (read [more](https://graphql.org/learn/schema/#type-language)). Consider the following SDL type definitions.

> **Hint** For convenience in this chapter, we've aggregated all of the SDL in one location (e.g., one `.graphql` file, as shown below). In practice, you may find it appropriate to organize your code in a modular fashion. For example, it can be helpful to create individual SDL files with type definitions representing each domain entity, along with related services, resolver code, and the Nest module definition class, in a dedicated directory for that entity. Nest will aggregate all the individual schema type definitions at run time.

```graphql

type Author {
  id: Int!
  firstName: String
  lastName: String
  posts: [Post]
}

type Post {
  id: Int!
  title: String!
  votes: Int
}

type Query {
  author(id: Int!): Author
}
```

#### Schema first resolver[#](/graphql/resolvers#schema-first-resolver)

The schema above exposes a single query - `author(id: Int!): Author`.

> **Hint** Learn more about GraphQL queries [here](https://graphql.org/learn/queries/).

Let's now create an `AuthorsResolver` class that resolves author queries:

authors/authors.resolver.ts

JS TS

```typescript

@Resolver('Author')
export class AuthorsResolver {
  constructor(
    private authorsService: AuthorsService,
    private postsService: PostsService,
  ) {}

  @Query()
  async author(@Args('id') id: number) {
    return this.authorsService.findOneById(id);
  }

  @ResolveField()
  async posts(@Parent() author) {
    const { id } = author;
    return this.postsService.findAll({ authorId: id });
  }
}
```

> **Hint** All decorators (e.g., `@Resolver`, `@ResolveField`, `@Args`, etc.) are exported from the `@nestjs/graphql` package.

> **Note** The logic inside the `AuthorsService` and `PostsService` classes can be as simple or sophisticated as needed. The main point of this example is to show how to construct resolvers and how they can interact with other providers.

The `@Resolver()` decorator is required. It takes an optional string argument with the name of a class. This class name is required whenever the class includes `@ResolveField()` decorators to inform Nest that the decorated method is associated with a parent type (the `Author` type in our current example). Alternatively, instead of setting `@Resolver()` at the top of the class, this can be done for each method:

```typescript

@Resolver('Author')
@ResolveField()
async posts(@Parent() author) {
  const { id } = author;
  return this.postsService.findAll({ authorId: id });
}
```

In this case (`@Resolver()` decorator at the method level), if you have multiple `@ResolveField()` decorators inside a class, you must add `@Resolver()` to all of them. This is not considered the best practice (as it creates extra overhead).

> **Hint** Any class name argument passed to `@Resolver()`**does not** affect queries (`@Query()` decorator) or mutations (`@Mutation()` decorator).

> **Warning** Using the `@Resolver` decorator at the method level is not supported with the **code first** approach.

In the above examples, the `@Query()` and `@ResolveField()` decorators are associated with GraphQL schema types based on the method name. For example, consider the following construction from the example above:

```typescript

@Query()
async author(@Args('id') id: number) {
  return this.authorsService.findOneById(id);
}
```

This generates the following entry for the author query in our schema (the query type uses the same name as the method name):

```graphql

type Query {
  author(id: Int!): Author
}
```

Conventionally, we would prefer to decouple these, using names like `getAuthor()` or `getPosts()` for our resolver methods. We can easily do this by passing the mapping name as an argument to the decorator, as shown below:

authors/authors.resolver.ts

JS TS

```typescript

@Resolver('Author')
export class AuthorsResolver {
  constructor(
    private authorsService: AuthorsService,
    private postsService: PostsService,
  ) {}

  @Query('author')
  async getAuthor(@Args('id') id: number) {
    return this.authorsService.findOneById(id);
  }

  @ResolveField('posts')
  async getPosts(@Parent() author) {
    const { id } = author;
    return this.postsService.findAll({ authorId: id });
  }
}
```

> **Hint** Nest CLI provides a generator (schematic) that automatically generates **all the boilerplate code** to help us avoid doing all of this, and make the developer experience much simpler. Read more about this feature [here](/v11/recipes/crud-generator).

#### Generating types[#](/graphql/resolvers#generating-types)

Assuming that we use the schema first approach and have enabled the typings generation feature (with `outputAs: 'class'` as shown in the [previous](/v11/graphql/quick-start) chapter), once you run the application, it will generate the following file (in the location you specified in the `GraphQLModule.forRoot()` method). For example, in `src/graphql.ts`:

graphql.ts

JS TS

```typescript

export class Author {
  id: number;
  firstName?: string;
  lastName?: string;
  posts?: Post[];
}
export class Post {
  id: number;
  title: string;
  votes?: number;
}

export abstract class IQuery {
  abstract author(id: number): Author | Promise<Author>;
}
```

By generating classes (instead of the default technique of generating interfaces), you can use declarative validation **decorators** in combination with the schema first approach, which is an extremely useful technique (read [more](/v11/techniques/validation)). For example, you could add `class-validator` decorators to the generated `CreatePostInput` class as shown below to enforce minimum and maximum string lengths on the `title` field:

```typescript

import { MinLength, MaxLength } from 'class-validator';

export class CreatePostInput {
  @MinLength(3)
  @MaxLength(50)
  title: string;
}
```

> **Notice** To enable auto-validation of your inputs (and parameters), use `ValidationPipe`. Read more about validation [here](/v11/techniques/validation) and more specifically about pipes [here](/v11/pipes).

However, if you add decorators directly to the automatically generated file, they will be **overwritten** each time the file is generated. Instead, create a separate file and simply extend the generated class.

```typescript

import { MinLength, MaxLength } from 'class-validator';
import { Post } from '../../graphql.ts';

export class CreatePostInput extends Post {
  @MinLength(3)
  @MaxLength(50)
  title: string;
}
```

#### GraphQL argument decorators[#](/graphql/resolvers#graphql-argument-decorators)

We can access the standard GraphQL resolver arguments using dedicated decorators. Below is a comparison of the Nest decorators and the plain Apollo parameters they represent.

|                            |                              |
| -------------------------- | ---------------------------- |
| `@Root()` and `@Parent()`  | `root`/`parent`              |
| `@Context(param?: string)` | `context` / `context[param]` |
| `@Info(param?: string)`    | `info` / `info[param]`       |
| `@Args(param?: string)`    | `args` / `args[param]`       |

```typescript

@Module({
  imports: [PostsModule],
  providers: [AuthorsService, AuthorsResolver],
})
export class AuthorsModule {}
```

> **Hint** It is helpful to organize your code by your so-called **domain model** (similar to the way you would organize entry points in a REST API). In this approach, keep your models (`ObjectType` classes), resolvers and services together within a Nest module representing the domain model. Keep all of these components in a single folder per module. When you do this, and use the [Nest CLI](/v11/cli/overview) to generate each element, Nest will wire all of these parts together (locating files in appropriate folders, generating entries in `provider` and `imports` arrays, etc.) automatically for you.

----
url: https://docs.nestjs.com/v10/cli/usages
----

* [CLI command reference](https://docs.nestjs.com/v10/cli/usages#cli-command-reference)
* [nest new](https://docs.nestjs.com/v10/cli/usages#nest-new)
* [nest generate](https://docs.nestjs.com/v10/cli/usages#nest-generate)
* [nest build](https://docs.nestjs.com/v10/cli/usages#nest-build)
* [nest start](https://docs.nestjs.com/v10/cli/usages#nest-start)
* [nest add](https://docs.nestjs.com/v10/cli/usages#nest-add)
* [nest info](https://docs.nestjs.com/v10/cli/usages#nest-info)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/cli/usages.md "Suggest Edits")

### CLI command reference

#### nest new[#](/cli/usages#nest-new)

Creates a new (standard mode) Nest project.

```bash

$ nest new <name> [options]
$ nest n <name> [options]
```

| Argument | Description                 |
| -------- | --------------------------- |
| `<name>` | The name of the new project |

##### Options

| Option                                | Description                                                                                                                                                                                          |
| ------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--dry-run`                           | Reports changes that would be made, but does not change the filesystem. Alias: `-d`                                                                                                                  |
| `--skip-git`                          | Skip git repository initialization. Alias: `-g`                                                                                                                                                      |
| `--skip-install`                      | Skip package installation. Alias: `-s`                                                                                                                                                               |
| `--package-manager [package-manager]` | Specify package manager. Use `npm`, `yarn`, or `pnpm`. Package manager must be installed globally. Alias: `-p`                                                                                       |
| `--language [language]`               | Specify programming language (`TS` or `JS`). Alias: `-l`                                                                                                                                             |
| `--collection [collectionName]`       | Specify schematics collection. Use package name of installed npm package containing schematic. Alias: `-c`                                                                                           |
| `--strict`                            | Start the project with the following TypeScript compiler flags enabled: `strictNullChecks`, `noImplicitAny`, `strictBindCallApply`, `forceConsistentCasingInFileNames`, `noFallthroughCasesInSwitch` |

#### nest generate[#](/cli/usages#nest-generate)

Generates and/or modifies files based on a schematic

```bash

$ nest generate <schematic> <name> [options]
$ nest g <schematic> <name> [options]
```

##### Arguments

| Argument      | Description                                                                                              |
| ------------- | -------------------------------------------------------------------------------------------------------- |
| `<schematic>` | The `schematic` or `collection:schematic` to generate. See the table below for the available schematics. |
| `<name>`      | The name of the generated component.                                                                     |

##### Schematics

| Name          | Alias | Description                                                                                                                |
| ------------- | ----- | -------------------------------------------------------------------------------------------------------------------------- |
| `app`         |       | Generate a new application within a monorepo (converting to monorepo if it's a standard structure).                        |
| `library`     | `lib` | Generate a new library within a monorepo (converting to monorepo if it's a standard structure).                            |
| `class`       | `cl`  | Generate a new class.                                                                                                      |
| `controller`  | `co`  | Generate a controller declaration.                                                                                         |
| `decorator`   | `d`   | Generate a custom decorator.                                                                                               |
| `filter`      | `f`   | Generate a filter declaration.                                                                                             |
| `gateway`     | `ga`  | Generate a gateway declaration.                                                                                            |
| `guard`       | `gu`  | Generate a guard declaration.                                                                                              |
| `interface`   | `itf` | Generate an interface.                                                                                                     |
| `interceptor` | `itc` | Generate an interceptor declaration.                                                                                       |
| `middleware`  | `mi`  | Generate a middleware declaration.                                                                                         |
| `module`      | `mo`  | Generate a module declaration.                                                                                             |
| `pipe`        | `pi`  | Generate a pipe declaration.                                                                                               |
| `provider`    | `pr`  | Generate a provider declaration.                                                                                           |
| `resolver`    | `r`   | Generate a resolver declaration.                                                                                           |
| `resource`    | `res` | Generate a new CRUD resource. See the [CRUD (resource) generator](/v10/recipes/crud-generator) for more details. (TS only) |
| `service`     | `s`   | Generate a service declaration.                                                                                            |

##### Options

| Option                          | Description                                                                                                |
| ------------------------------- | ---------------------------------------------------------------------------------------------------------- |
| `--dry-run`                     | Reports changes that would be made, but does not change the filesystem. Alias: `-d`                        |
| `--project [project]`           | Project that element should be added to. Alias: `-p`                                                       |
| `--flat`                        | Do not generate a folder for the element.                                                                  |
| `--collection [collectionName]` | Specify schematics collection. Use package name of installed npm package containing schematic. Alias: `-c` |
| `--spec`                        | Enforce spec files generation (default)                                                                    |
| `--no-spec`                     | Disable spec files generation                                                                              |

#### nest build[#](/cli/usages#nest-build)

Compiles an application or workspace into an output folder.

Also, the `build` command is responsible for:

* mapping paths (if using path aliases) via `tsconfig-paths`
* annotating DTOs with OpenAPI decorators (if `@nestjs/swagger` CLI plugin is enabled)
* annotating DTOs with GraphQL decorators (if `@nestjs/graphql` CLI plugin is enabled)

```bash

$ nest build <name> [options]
```

##### Arguments

| Argument | Description                       |
| -------- | --------------------------------- |
| `<name>` | The name of the project to build. |

##### Options

| Option             | Description                                                                                                                                                                     |
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--path [path]`    | Path to `tsconfig` file. Alias `-p`                                                                                                                                             |
| `--config [path]`  | Path to `nest-cli` configuration file. Alias `-c`                                                                                                                               |
| `--watch`          | Run in watch mode (live-reload). If you're using `tsc` for compilation, you can type `rs` to restart the application (when `manualRestart` option is set to `true`). Alias `-w` |
| `--builder [name]` | Specify the builder to use for compilation (`tsc`, `swc`, or `webpack`). Alias `-b`                                                                                             |
| `--webpack`        | Use webpack for compilation (deprecated: use `--builder webpack` instead).                                                                                                      |
| `--webpackPath`    | Path to webpack configuration.                                                                                                                                                  |
| `--tsc`            | Force use `tsc` for compilation.                                                                                                                                                |

#### nest start[#](/cli/usages#nest-start)

Compiles and runs an application (or default project in a workspace).

```bash

$ nest start <name> [options]
```

##### Arguments

| Argument | Description                     |
| -------- | ------------------------------- |
| `<name>` | The name of the project to run. |

##### Options

| Option                  | Description                                                                                                          |
| ----------------------- | -------------------------------------------------------------------------------------------------------------------- |
| `--path [path]`         | Path to `tsconfig` file. Alias `-p`                                                                                  |
| `--config [path]`       | Path to `nest-cli` configuration file. Alias `-c`                                                                    |
| `--watch`               | Run in watch mode (live-reload) Alias `-w`                                                                           |
| `--builder [name]`      | Specify the builder to use for compilation (`tsc`, `swc`, or `webpack`). Alias `-b`                                  |
| `--preserveWatchOutput` | Keep outdated console output in watch mode instead of clearing the screen. (`tsc` watch mode only)                   |
| `--watchAssets`         | Run in watch mode (live-reload), watching non-TS files (assets). See [Assets](cli/monorepo#assets) for more details. |
| `--debug [hostport]`    | Run in debug mode (with --inspect flag) Alias `-d`                                                                   |
| `--webpack`             | Use webpack for compilation. (deprecated: use `--builder webpack` instead)                                           |
| `--webpackPath`         | Path to webpack configuration.                                                                                       |
| `--tsc`                 | Force use `tsc` for compilation.                                                                                     |
| `--exec [binary]`       | Binary to run (default: `node`). Alias `-e`                                                                          |
| `-- [key=value]`        | Command-line arguments that can be referenced with `process.argv`.                                                   |

#### nest add[#](/cli/usages#nest-add)

Imports a library that has been packaged as a **nest library**, running its install schematic.

```bash

$ nest add <name> [options]
```

##### Arguments

| Argument | Description                        |
| -------- | ---------------------------------- |
| `<name>` | The name of the library to import. |

#### nest info[#](/cli/usages#nest-info)

Displays information about installed nest packages and other helpful system info. For example:

```bash

$ nest info
```

```bash

 _   _             _      ___  _____  _____  _     _____
| \ | |           | |    |_  |/  ___|/  __ \| |   |_   _|
|  \| |  ___  ___ | |_     | |\ `--. | /  \/| |     | |
| . ` | / _ \/ __|| __|    | | `--. \| |    | |     | |
| |\  ||  __/\__ \| |_ /\__/ //\__/ /| \__/\| |_____| |_
\_| \_/ \___||___/ \__|\____/ \____/  \____/\_____/\___/

[System Information]
OS Version : macOS High Sierra
NodeJS Version : v16.18.0
[Nest Information]
microservices version : 10.0.0
websockets version : 10.0.0
testing version : 10.0.0
common version : 10.0.0
core version : 10.0.0
```

----
url: https://docs.nestjs.com/v8/graphql/resolvers
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Resolvers](https://docs.nestjs.com/v8/graphql/resolvers#resolvers)
* [Code first](https://docs.nestjs.com/v8/graphql/resolvers#code-first)
* [Object types](https://docs.nestjs.com/v8/graphql/resolvers#object-types)
* [Code first resolver](https://docs.nestjs.com/v8/graphql/resolvers#code-first-resolver)
* [Query type names](https://docs.nestjs.com/v8/graphql/resolvers#query-type-names)
* [Query decorator options](https://docs.nestjs.com/v8/graphql/resolvers#query-decorator-options)
* [Args decorator options](https://docs.nestjs.com/v8/graphql/resolvers#args-decorator-options)
* [Dedicated arguments class](https://docs.nestjs.com/v8/graphql/resolvers#dedicated-arguments-class)
* [Class inheritance](https://docs.nestjs.com/v8/graphql/resolvers#class-inheritance)
* [Generics](https://docs.nestjs.com/v8/graphql/resolvers#generics)
* [Schema first](https://docs.nestjs.com/v8/graphql/resolvers#schema-first)
* [Schema first resolver](https://docs.nestjs.com/v8/graphql/resolvers#schema-first-resolver)
* [Generating types](https://docs.nestjs.com/v8/graphql/resolvers#generating-types)
* [GraphQL argument decorators](https://docs.nestjs.com/v8/graphql/resolvers#graphql-argument-decorators)
* [Module](https://docs.nestjs.com/v8/graphql/resolvers#module)

```graphql

type Author {
  id: Int!
  firstName: String
  lastName: String
  posts: [Post!]!
}
```

In this case, using the code first approach, we define schemas using TypeScript classes and using TypeScript decorators to annotate the fields of those classes. The equivalent of the above SDL in the code first approach is:

authors/models/author.model.ts

JS TS

```typescript

import { Field, Int, ObjectType } from '@nestjs/graphql';
import { Post } from './post';

@ObjectType()
export class Author {
  @Field(type => Int)
  id: number;

  @Field({ nullable: true })
  firstName?: string;

  @Field({ nullable: true })
  lastName?: string;

  @Field(type => [Post])
  posts: Post[];
}
```

> **Hint** TypeScript's metadata reflection system has several limitations which make it impossible, for instance, to determine what properties a class consists of or recognize whether a given property is optional or required. Because of these limitations, we must either explicitly use the `@Field()` decorator in our schema definition classes to provide metadata about each field's GraphQL type and optionality, or use a [CLI plugin](/v8/graphql/cli-plugin) to generate these for us.

The `Author` object type, like any class, is made of a collection of fields, with each field declaring a type. A field's type corresponds to a [GraphQL type](https://graphql.org/learn/schema/). A field's GraphQL type can be either another object type or a scalar type. A GraphQL scalar type is a primitive (like `ID`, `String`, `Boolean`, or `Int`) that resolves to a single value.

> **Hint** In addition to GraphQL's built-in scalar types, you can define custom scalar types (read [more](/v8/graphql/scalars)).

The above `Author` object type definition will cause Nest to **generate** the SDL we showed above:

```graphql

type Author {
  id: Int!
  firstName: String
  lastName: String
  posts: [Post!]!
}
```

```typescript

@Field({ description: `Book title`, deprecationReason: 'Not useful in v2 schema' })
title: string;
```

> **Hint** You can also add a description to, or deprecate, the whole object type: `@ObjectType({ description: 'Author model' })`.

When the field is an array, we must manually indicate the array type in the `Field()` decorator's type function, as shown below:

```typescript

@Field(type => [Post])
posts: Post[];
```

> **Hint** Using array bracket notation (`[ ]`), we can indicate the depth of the array. For example, using `[[Int]]` would represent an integer matrix.

To declare that an array's items (not the array itself) are nullable, set the `nullable` property to `'items'` as shown below:

```typescript

@Field(type => [Post], { nullable: 'items' })
posts: Post[];
```

> **Hint** If both the array and its items are nullable, set `nullable` to `'itemsAndList'` instead.

Now that the `Author` object type is created, let's define the `Post` object type.

posts/models/post.model.ts

JS TS

```typescript

import { Field, Int, ObjectType } from '@nestjs/graphql';

@ObjectType()
export class Post {
  @Field(type => Int)
  id: number;

  @Field()
  title: string;

  @Field(type => Int, { nullable: true })
  votes?: number;
}
```

The `Post` object type will result in generating the following part of the GraphQL schema in SDL:

```graphql

type Post {
  id: Int!
  title: String!
  votes: Int
}
```

#### Code first resolver[#](/graphql/resolvers#code-first-resolver)

At this point, we've defined the objects (type definitions) that can exist in our data graph, but clients don't yet have a way to interact with those objects. To address that, we need to create a resolver class. In the code first method, a resolver class both defines resolver functions **and** generates the **Query type**. This will be clear as we work through the example below:

authors/authors.resolver.ts

JS TS

```typescript

@Resolver(of => Author)
export class AuthorsResolver {
  constructor(
    private authorsService: AuthorsService,
    private postsService: PostsService,
  ) {}

  @Query(returns => Author)
  async author(@Args('id', { type: () => Int }) id: number) {
    return this.authorsService.findOneById(id);
  }

  @ResolveField()
  async posts(@Parent() author: Author) {
    const { id } = author;
    return this.postsService.findAll({ authorId: id });
  }
}
```

> **Hint** All decorators (e.g., `@Resolver`, `@ResolveField`, `@Args`, etc.) are exported from the `@nestjs/graphql` package.

You can define multiple resolver classes. Nest will combine these at run time. See the [module](/graphql/resolvers#module) section below for more on code organization.

> **Note** The logic inside the `AuthorsService` and `PostsService` classes can be as simple or sophisticated as needed. The main point of this example is to show how to construct resolvers and how they can interact with other providers.

In the example above, we created the `AuthorsResolver` which defines one query resolver function and one field resolver function. To create a resolver, we create a class with resolver functions as methods, and annotate the class with the `@Resolver()` decorator.

In this example, we defined a query handler to get the author object based on the `id` sent in the request. To specify that the method is a query handler, use the `@Query()` decorator.

The argument passed to the `@Resolver()` decorator is optional, but comes into play when our graph becomes non-trivial. It's used to supply a parent object used by field resolver functions as they traverse down through an object graph.

In our example, since the class includes a **field resolver** function (for the `posts` property of the `Author` object type), we **must** supply the `@Resolver()` decorator with a value to indicate which class is the parent type (i.e., the corresponding `ObjectType` class name) for all field resolvers defined within this class. As should be clear from the example, when writing a field resolver function, it's necessary to access the parent object (the object the field being resolved is a member of). In this example, we populate an author's posts array with a field resolver that calls a service which takes the author's `id` as an argument. Hence the need to identify the parent object in the `@Resolver()` decorator. Note the corresponding use of the `@Parent()` method parameter decorator to then extract a reference to that parent object in the field resolver.

We can define multiple `@Query()` resolver functions (both within this class, and in any other resolver class), and they will be aggregated into a single **Query type** definition in the generated SDL along with the appropriate entries in the resolver map. This allows you to define queries close to the models and services that they use, and to keep them well organized in modules.

> **Hint** Nest CLI provides a generator (schematic) that automatically generates **all the boilerplate code** to help us avoid doing all of this, and make the developer experience much simpler. Read more about this feature [here](/v8/recipes/crud-generator).

#### Query type names[#](/graphql/resolvers#query-type-names)

In the above examples, the `@Query()` decorator generates a GraphQL schema query type name based on the method name. For example, consider the following construction from the example above:

```typescript

@Query(returns => Author)
async author(@Args('id', { type: () => Int }) id: number) {
  return this.authorsService.findOneById(id);
}
```

This generates the following entry for the author query in our schema (the query type uses the same name as the method name):

```graphql

type Query {
  author(id: Int!): Author
}
```

> **Hint** Learn more about GraphQL queries [here](https://graphql.org/learn/queries/).

Conventionally, we prefer to decouple these names; for example, we prefer to use a name like `getAuthor()` for our query handler method, but still use `author` for our query type name. The same applies to our field resolvers. We can easily do this by passing the mapping names as arguments of the `@Query()` and `@ResolveField()` decorators, as shown below:

authors/authors.resolver.ts

JS TS

```typescript

@Resolver(of => Author)
export class AuthorsResolver {
  constructor(
    private authorsService: AuthorsService,
    private postsService: PostsService,
  ) {}

  @Query(returns => Author, { name: 'author' })
  async getAuthor(@Args('id', { type: () => Int }) id: number) {
    return this.authorsService.findOneById(id);
  }

  @ResolveField('posts', returns => [Post])
  async getPosts(@Parent() author: Author) {
    const { id } = author;
    return this.postsService.findAll({ authorId: id });
  }
}
```

The `getAuthor` handler method above will result in generating the following part of the GraphQL schema in SDL:

```graphql

type Query {
  author(id: Int!): Author
}
```

```typescript

@Args('id') id: string
```

In the `getAuthor()` case, the `number` type is used, which presents a challenge. The `number` TypeScript type doesn't give us enough information about the expected GraphQL representation (e.g., `Int` vs. `Float`). Thus we have to **explicitly** pass the type reference. We do that by passing a second argument to the `Args()` decorator, containing argument options, as shown below:

```typescript

@Query(returns => Author, { name: 'author' })
async getAuthor(@Args('id', { type: () => Int }) id: number) {
  return this.authorsService.findOneById(id);
}
```

```typescript

getAuthor(
  @Args('firstName', { nullable: true }) firstName?: string,
  @Args('lastName', { defaultValue: '' }) lastName?: string,
) {}
```

#### Dedicated arguments class[#](/graphql/resolvers#dedicated-arguments-class)

With inline `@Args()` calls, code like the example above becomes bloated. Instead, you can create a dedicated `GetAuthorArgs` arguments class and access it in the handler method as follows:

```typescript

@Args() args: GetAuthorArgs
```

Create the `GetAuthorArgs` class using `@ArgsType()` as shown below:

authors/dto/get-author.args.ts

JS TS

```typescript

import { MinLength } from 'class-validator';
import { Field, ArgsType } from '@nestjs/graphql';

@ArgsType()
class GetAuthorArgs {
  @Field({ nullable: true })
  firstName?: string;

  @Field({ defaultValue: '' })
  @MinLength(3)
  lastName: string;
}
```

> **Hint** Again, due to TypeScript's metadata reflection system limitations, it's required to either use the `@Field` decorator to manually indicate type and optionality, or use a [CLI plugin](/v8/graphql/cli-plugin).

This will result in generating the following part of the GraphQL schema in SDL:

```graphql

type Query {
  author(firstName: String, lastName: String = ''): Author
}
```

> **Hint** Note that arguments classes like `GetAuthorArgs` play very well with the `ValidationPipe` (read [more](/v8/techniques/validation)).

#### Class inheritance[#](/graphql/resolvers#class-inheritance)

You can use standard TypeScript class inheritance to create base classes with generic utility type features (fields and field properties, validations, etc.) that can be extended. For example, you may have a set of pagination related arguments that always include the standard `offset` and `limit` fields, but also other index fields that are type-specific. You can set up a class hierarchy as shown below.

Base `@ArgsType()` class:

```typescript

@ArgsType()
class PaginationArgs {
  @Field((type) => Int)
  offset: number = 0;

  @Field((type) => Int)
  limit: number = 10;
}
```

Type specific sub-class of the base `@ArgsType()` class:

```typescript

@ArgsType()
class GetAuthorArgs extends PaginationArgs {
  @Field({ nullable: true })
  firstName?: string;

  @Field({ defaultValue: '' })
  @MinLength(3)
  lastName: string;
}
```

The same approach can be taken with `@ObjectType()` objects. Define generic properties on the base class:

```typescript

@ObjectType()
class Character {
  @Field((type) => Int)
  id: number;

  @Field()
  name: string;
}
```

Add type-specific properties on sub-classes:

```typescript

@ObjectType()
class Warrior extends Character {
  @Field()
  level: number;
}
```

You can use inheritance with a resolver as well. You can ensure type safety by combining inheritance and TypeScript generics. For example, to create a base class with a generic `findAll` query, use a construction like this:

```typescript

function BaseResolver<T extends Type<unknown>>(classRef: T): any {
  @Resolver({ isAbstract: true })
  abstract class BaseResolverHost {
    @Query((type) => [classRef], { name: `findAll${classRef.name}` })
    async findAll(): Promise<T[]> {
      return [];
    }
  }
  return BaseResolverHost;
}
```

Note the following:

* an explicit return type (`any` above) is required: otherwise TypeScript complains about the usage of a private class definition. Recommended: define an interface instead of using `any`.
* `Type` is imported from the `@nestjs/common` package
* The `isAbstract: true` property indicates that SDL (Schema Definition Language statements) shouldn't be generated for this class. Note, you can set this property for other types as well to suppress SDL generation.

Here's how you could generate a concrete sub-class of the `BaseResolver`:

```typescript

@Resolver((of) => Recipe)
export class RecipesResolver extends BaseResolver(Recipe) {
  constructor(private recipesService: RecipesService) {
    super();
  }
}
```

This construct would generated the following SDL:

```graphql

type Query {
  findAllRecipe: [Recipe!]!
}
```

#### Generics[#](/graphql/resolvers#generics)

We saw one use of generics above. This powerful TypeScript feature can be used to create useful abstractions. For example, here's a sample cursor-based pagination implementation based on [this documentation](https://graphql.org/learn/pagination/#pagination-and-edges):

```typescript

import { Field, ObjectType, Int } from '@nestjs/graphql';
import { Type } from '@nestjs/common';

interface IEdgeType<T> {
  cursor: string;
  node: T;
}

export interface IPaginatedType<T> {
  edges: IEdgeType<T>[];
  nodes: T[];
  totalCount: number;
  hasNextPage: boolean;
}

export function Paginated<T>(classRef: Type<T>): Type<IPaginatedType<T>> {
  @ObjectType(`${classRef.name}Edge`)
  abstract class EdgeType {
    @Field((type) => String)
    cursor: string;

    @Field((type) => classRef)
    node: T;
  }

  @ObjectType({ isAbstract: true })
  abstract class PaginatedType implements IPaginatedType<T> {
    @Field((type) => [EdgeType], { nullable: true })
    edges: EdgeType[];

    @Field((type) => [classRef], { nullable: true })
    nodes: T[];

    @Field((type) => Int)
    totalCount: number;

    @Field()
    hasNextPage: boolean;
  }
  return PaginatedType as Type<IPaginatedType<T>>;
}
```

With the above base class defined, we can now easily create specialized types that inherit this behavior. For example:

```typescript

@ObjectType()
class PaginatedAuthor extends Paginated(Author) {}
```

#### Schema first[#](/graphql/resolvers#schema-first)

As mentioned in the [previous](/v8/graphql/quick-start) chapter, in the schema first approach we start by manually defining schema types in SDL (read [more](https://graphql.org/learn/schema/#type-language)). Consider the following SDL type definitions.

> **Hint** For convenience in this chapter, we've aggregated all of the SDL in one location (e.g., one `.graphql` file, as shown below). In practice, you may find it appropriate to organize your code in a modular fashion. For example, it can be helpful to create individual SDL files with type definitions representing each domain entity, along with related services, resolver code, and the Nest module definition class, in a dedicated directory for that entity. Nest will aggregate all the individual schema type definitions at run time.

```graphql

type Author {
  id: Int!
  firstName: String
  lastName: String
  posts: [Post]
}

type Post {
  id: Int!
  title: String!
  votes: Int
}

type Query {
  author(id: Int!): Author
}
```

#### Schema first resolver[#](/graphql/resolvers#schema-first-resolver)

The schema above exposes a single query - `author(id: Int!): Author`.

> **Hint** Learn more about GraphQL queries [here](https://graphql.org/learn/queries/).

Let's now create an `AuthorsResolver` class that resolves author queries:

authors/authors.resolver.ts

JS TS

```typescript

@Resolver('Author')
export class AuthorsResolver {
  constructor(
    private authorsService: AuthorsService,
    private postsService: PostsService,
  ) {}

  @Query()
  async author(@Args('id') id: number) {
    return this.authorsService.findOneById(id);
  }

  @ResolveField()
  async posts(@Parent() author) {
    const { id } = author;
    return this.postsService.findAll({ authorId: id });
  }
}
```

> **Hint** All decorators (e.g., `@Resolver`, `@ResolveField`, `@Args`, etc.) are exported from the `@nestjs/graphql` package.

> **Note** The logic inside the `AuthorsService` and `PostsService` classes can be as simple or sophisticated as needed. The main point of this example is to show how to construct resolvers and how they can interact with other providers.

The `@Resolver()` decorator is required. It takes an optional string argument with the name of a class. This class name is required whenever the class includes `@ResolveField()` decorators to inform Nest that the decorated method is associated with a parent type (the `Author` type in our current example). Alternatively, instead of setting `@Resolver()` at the top of the class, this can be done for each method:

```typescript

@Resolver('Author')
@ResolveField()
async posts(@Parent() author) {
  const { id } = author;
  return this.postsService.findAll({ authorId: id });
}
```

In this case (`@Resolver()` decorator at the method level), if you have multiple `@ResolveField()` decorators inside a class, you must add `@Resolver()` to all of them. This is not considered the best practice (as it creates extra overhead).

> **Hint** Any class name argument passed to `@Resolver()`**does not** affect queries (`@Query()` decorator) or mutations (`@Mutation()` decorator).

> **Warning** Using the `@Resolver` decorator at the method level is not supported with the **code first** approach.

In the above examples, the `@Query()` and `@ResolveField()` decorators are associated with GraphQL schema types based on the method name. For example, consider the following construction from the example above:

```typescript

@Query()
async author(@Args('id') id: number) {
  return this.authorsService.findOneById(id);
}
```

This generates the following entry for the author query in our schema (the query type uses the same name as the method name):

```graphql

type Query {
  author(id: Int!): Author
}
```

Conventionally, we would prefer to decouple these, using names like `getAuthor()` or `getPosts()` for our resolver methods. We can easily do this by passing the mapping name as an argument to the decorator, as shown below:

authors/authors.resolver.ts

JS TS

```typescript

@Resolver('Author')
export class AuthorsResolver {
  constructor(
    private authorsService: AuthorsService,
    private postsService: PostsService,
  ) {}

  @Query('author')
  async getAuthor(@Args('id') id: number) {
    return this.authorsService.findOneById(id);
  }

  @ResolveField('posts')
  async getPosts(@Parent() author) {
    const { id } = author;
    return this.postsService.findAll({ authorId: id });
  }
}
```

> **Hint** Nest CLI provides a generator (schematic) that automatically generates **all the boilerplate code** to help us avoid doing all of this, and make the developer experience much simpler. Read more about this feature [here](/v8/recipes/crud-generator).

#### Generating types[#](/graphql/resolvers#generating-types)

Assuming that we use the schema first approach and have enabled the typings generation feature (with `outputAs: 'class'` as shown in the [previous](/v8/graphql/quick-start) chapter), once you run the application it will generate the following file (in the location you specified in the `GraphQLModule.forRoot()` method). For example, in `src/graphql.ts`:

graphql.ts

JS TS

```typescript

export class Author {
  id: number;
  firstName?: string;
  lastName?: string;
  posts?: Post[];
}

export class Post {
  id: number;
  title: string;
  votes?: number;
}

export abstract class IQuery {
  abstract author(id: number): Author | Promise<Author>;
}
```

By generating classes (instead of the default technique of generating interfaces), you can use declarative validation **decorators** in combination with the schema first approach, which is an extremely useful technique (read [more](/v8/techniques/validation)). For example, you could add `class-validator` decorators to the generated `CreatePostInput` class as shown below to enforce minimum and maximum string lengths on the `title` field:

```typescript

import { MinLength, MaxLength } from 'class-validator';

export class CreatePostInput {
  @MinLength(3)
  @MaxLength(50)
  title: string;
}
```

> **Notice** To enable auto-validation of your inputs (and parameters), use `ValidationPipe`. Read more about validation [here](/v8/techniques/validation) and more specifically about pipes [here](/v8/pipes).

However, if you add decorators directly to the automatically generated file, they will be **overwritten** each time the file is generated. Instead, create a separate file and simply extend the generated class.

```typescript

import { MinLength, MaxLength } from 'class-validator';
import { Post } from '../../graphql.ts';

export class CreatePostInput extends Post {
  @MinLength(3)
  @MaxLength(50)
  title: string;
}
```

#### GraphQL argument decorators[#](/graphql/resolvers#graphql-argument-decorators)

We can access the standard GraphQL resolver arguments using dedicated decorators. Below is a comparison of the Nest decorators and the plain Apollo parameters they represent.

|                            |                              |
| -------------------------- | ---------------------------- |
| `@Root()` and `@Parent()`  | `root`/`parent`              |
| `@Context(param?: string)` | `context` / `context[param]` |
| `@Info(param?: string)`    | `info` / `info[param]`       |
| `@Args(param?: string)`    | `args` / `args[param]`       |

```typescript

@Module({
  imports: [PostsModule],
  providers: [AuthorsService, AuthorsResolver],
})
export class AuthorsModule {}
```

> **Hint** It is helpful to organize your code by your so-called **domain model** (similar to the way you would organize entry points in a REST API). In this approach, keep your models (`ObjectType` classes), resolvers and services together within a Nest module representing the domain model. Keep all of these components in a single folder per module. When you do this, and use the [Nest CLI](/v8/cli/overview) to generate each element, Nest will wire all of these parts together (locating files in appropriate folders, generating entries in `provider` and `imports` arrays, etc.) automatically for you.

----
url: https://docs.nestjs.com/v6/microservices/interceptors
----

* [Interceptors](https://docs.nestjs.com/v6/microservices/interceptors#interceptors)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/microservices/interceptors.md "Suggest Edits")

### Interceptors

There is no difference between [regular interceptors](/v6/interceptors) and microservices interceptors. The following example uses a manually instantiated method-scoped interceptor. Just as with HTTP based applications, you can also use controller-scoped interceptors (i.e., prefix the controller class with a `@UseInterceptors()` decorator).

JS TS

```typescript

@UseInterceptors(new TransformInterceptor())
@MessagePattern({ cmd: 'sum' })
accumulate(data: number[]): number {
  return (data || []).reduce((a, b) => a + b);
}
```

```typescript

@UseInterceptors(new TransformInterceptor())
@MessagePattern({ cmd: 'sum' })
accumulate(data) {
  return (data || []).reduce((a, b) => a + b);
}
```

----
url: https://docs.nestjs.com/first-steps
----

[Skip to content](#content)

On this page

* [First steps](https://docs.nestjs.com/first-steps#first-steps)
* [Language](https://docs.nestjs.com/first-steps#language)
* [Prerequisites](https://docs.nestjs.com/first-steps#prerequisites)
* [Setup](https://docs.nestjs.com/first-steps#setup)
* [Platform](https://docs.nestjs.com/first-steps#platform)
* [Running the application](https://docs.nestjs.com/first-steps#running-the-application)
* [Linting and formatting](https://docs.nestjs.com/first-steps#linting-and-formatting)

### First steps

This set of articles covers the **core fundamentals** of Nest. To introduce the essential building blocks of a Nest application, we'll build a basic CRUD application whose features cover a lot of ground at an introductory level.

#### Language[#](/first-steps#language)

Nest is written in [TypeScript](https://www.typescriptlang.org/) and runs on [Node.js](https://nodejs.org/en/), and it supports both TypeScript and plain JavaScript. Because Nest relies on the latest language features, using it with plain JavaScript requires [Babel](https://babeljs.io/).

Most examples in this documentation use TypeScript, but you can **switch any code snippet** to plain JavaScript syntax with the language toggle in the upper-right corner of the snippet.

#### Prerequisites[#](/first-steps#prerequisites)

Make sure that [Node.js](https://nodejs.org) is installed on your operating system. Running a Nest application requires **v20.19 or later** (or **v22.12+** on the 22.x line). The Nest CLI's generators (such as `nest new` and `nest generate`) require **v22.22.3+, v24.15+, or v26+**. We recommend the latest active LTS release, which satisfies both requirements.

#### Setup[#](/first-steps#setup)

The quickest way to set up a new project is with the [Nest CLI](/cli/overview). With [npm](https://www.npmjs.com/) installed, run the following commands in your terminal:

```bash

$ npm i -g @nestjs/cli
$ nest new project-name
```

The CLI asks which module system to use: ESM (the default), which uses Vitest as the test runner, or CommonJS, which uses Jest.

It also asks whether to set up [NestJS Observe](https://www.observe.nestjs.com/ "NestJS Observe"), the official observability platform for Nest. If you answer yes, the generated project includes the `@nestjs/observe` SDK, already wired into `AppModule` and `NestFactory.create()`. In an interactive terminal, the prompt defaults to yes; in non-interactive environments, such as CI, it is skipped and Observe is not added. Pass `--observe` or `--no-observe` to skip the prompt either way. See the [Observability](/observability/overview) chapter for what Observe covers.

If you set up Observe, the CLI then offers to link the new project to it, once the dependencies are installed. Accepting prints a code to approve at [observe.nestjs.com/link](https://www.observe.nestjs.com/link "Link a project to NestJS Observe") (signing up first if you don't have an account; the free plan needs no payment details), and the CLI then writes the app key and secret into `.env` and makes every `nest start` script (`start`, `start:dev`, and `start:debug`) load it. Requests, background jobs, errors, and distributed traces start reporting the next time you start the application. To link later, or when the CLI doesn't offer it (without a terminal, or with `--skip-install`), run `npx @nestjs/observe link` in the project directory - see [Linking from the terminal](/observability/sdk#linking-from-the-terminal).

> **Hint** New projects are generated with TypeScript's [strict](https://www.typescriptlang.org/tsconfig#strict) mode enabled. To opt out, set `"strict": false` in the generated `tsconfig.json`.

The CLI creates a `project-name` directory, installs the dependencies, generates a few boilerplate files, and populates a `src/` directory with several core files.

src

app.controller.spec.ts

app.controller.ts

app.module.ts

app.service.ts

main.ts

The following table describes these core files:

| `app.controller.ts`      | A basic controller with a single route.                                                         |
| ------------------------ | ----------------------------------------------------------------------------------------------- |
| `app.controller.spec.ts` | The unit tests for the controller.                                                              |
| `app.module.ts`          | The root module of the application.                                                             |
| `app.service.ts`         | A basic service with a single method.                                                           |
| `main.ts`                | The entry file of the application. It uses `NestFactory` to create a Nest application instance. |

The `main.ts` file contains an async function that **bootstraps** the application:

main.ts

JS TS

```typescript

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module.js';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  await app.listen(process.env.PORT ?? 3000);
}
await bootstrap();
```

```typescript

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module.js';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  await app.listen(process.env.PORT ?? 3000);
}
await bootstrap();
```

To create a Nest application instance, use `NestFactory` from `@nestjs/core`, which exposes a few methods for this purpose. The `create()` method returns an application object that implements the `INestApplication` interface. The methods of this object are described in the following chapters. In the `main.ts` example above, the application starts an HTTP listener and waits for inbound HTTP requests.

The project structure generated by the Nest CLI encourages the convention of keeping each module in its own dedicated directory.

> **Hint** By default, if an error occurs while the application is being created, the process exits with code `1`. To have the error thrown instead, disable the `abortOnError` option (e.g., `NestFactory.create(AppModule, { abortOnError: false })`).

## Learn the right way!

* **80+ chapters
* **5+ hours of videos
* **Official certificate
* **Deep-dive sessions

[Explore official courses](https://courses.nestjs.com "Courses | NestJS - A node.js framework built on top of TypeScript")

#### Platform[#](/first-steps#platform)

Nest is designed to be platform-agnostic. Platform independence lets you create reusable logical parts that can be used across several different types of applications. Nest can work with any Node.js HTTP framework once an adapter is created for it. Two HTTP platforms are supported out of the box: [Express](https://expressjs.com/) and [Fastify](https://www.fastify.io). Choose the one that best suits your needs.

| `platform-express` | [Express](https://expressjs.com/) is a well-known, minimalist web framework for Node.js. It is a battle-tested, production-ready library with extensive community resources. Nest uses the `@nestjs/platform-express` package by default, so no setup is required. |
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `platform-fastify` | [Fastify](https://www.fastify.io/) is a high-performance, low-overhead framework focused on efficiency and speed. To learn how to use it, see [Performance (Fastify)](/http/performance).                                                                          |

Each platform exposes its own application interface: `NestExpressApplication` and `NestFastifyApplication`, respectively.

When you pass a type to the `NestFactory.create()` method, as in the example below, the `app` object exposes methods that are available only on that platform. You don't **need** to specify a type **unless** you want to access the underlying platform API.

```typescript

const app = await NestFactory.create<NestExpressApplication>(AppModule);
```

#### Running the application[#](/first-steps#running-the-application)

Once the installation is complete, run the following command to start the application and listen for inbound HTTP requests:

```bash

$ npm run start
```

> **Hint** To speed up development builds, use the [SWC builder](/recipes/swc) by passing the `-b swc` flag to the `start` script: `npm run start -- -b swc`.

This command starts the HTTP server on the port defined in the `src/main.ts` file (`3000`, unless the `PORT` environment variable is set). Once the application is running, open your browser and navigate to `http://localhost:3000/`. You should see the `Hello World!` message.

To watch your files for changes, start the application with the following command instead:

```bash

$ npm run start:dev
```

This command watches your files and, whenever they change, recompiles and restarts the server.

#### Linting and formatting[#](/first-steps#linting-and-formatting)

The [Nest CLI](/cli/overview) aims to scaffold a reliable development workflow that scales. For a fast default workflow, generated TypeScript projects come with a code **linter** and a **formatter** preinstalled: [oxlint](https://oxc.rs/docs/guide/usage/linter.html) and [Prettier](https://prettier.io/), respectively.

> **Hint** Not sure how formatters and linters differ? See Prettier's [comparison](https://prettier.io/docs/en/comparison.html).

For headless environments where an IDE is not involved (continuous integration, Git hooks, etc.), the project includes ready-to-use `npm` scripts that run [`oxlint`](https://www.npmjs.com/package/oxlint) and [`prettier`](https://www.npmjs.com/package/prettier):

```bash

# Lint with oxlint
$ npm run lint

# Format with prettier
$ npm run format
```

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/first-steps.md)

----
url: https://docs.nestjs.com/v11/graphql/plugins
----

* [Plugins with Apollo](https://docs.nestjs.com/v11/graphql/plugins#plugins-with-apollo)
* [Custom plugins](https://docs.nestjs.com/v11/graphql/plugins#custom-plugins)
* [Using external plugins](https://docs.nestjs.com/v11/graphql/plugins#using-external-plugins)
* [Plugins with Mercurius](https://docs.nestjs.com/v11/graphql/plugins#plugins-with-mercurius)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/plugins.md "Suggest Edits")

### Plugins with Apollo

Plugins enable you to extend Apollo Server's core functionality by performing custom operations in response to certain events. Currently, these events correspond to individual phases of the GraphQL request lifecycle, and to the startup of Apollo Server itself (read more [here](https://www.apollographql.com/docs/apollo-server/integrations/plugins/)). For example, a basic logging plugin might log the GraphQL query string associated with each request that's sent to Apollo Server.

#### Custom plugins[#](/graphql/plugins#custom-plugins)

To create a plugin, declare a class annotated with the `@Plugin` decorator exported from the `@nestjs/apollo` package. Also, for better code autocompletion, implement the `ApolloServerPlugin` interface from the `@apollo/server` package.

```typescript

import { ApolloServerPlugin, GraphQLRequestListener } from '@apollo/server';
import { Plugin } from '@nestjs/apollo';

@Plugin()
export class LoggingPlugin implements ApolloServerPlugin {
  async requestDidStart(): Promise<GraphQLRequestListener<any>> {
    console.log('Request started');
    return {
      async willSendResponse() {
        console.log('Will send response');
      },
    };
  }
}
```

With this in place, we can register the `LoggingPlugin` as a provider.

```typescript

@Module({
  providers: [LoggingPlugin],
})
export class CommonModule {}
```

Nest will automatically instantiate a plugin and apply it to the Apollo Server.

#### Using external plugins[#](/graphql/plugins#using-external-plugins)

There are several plugins provided out-of-the-box. To use an existing plugin, simply import it and add it to the `plugins` array:

```typescript

GraphQLModule.forRoot({
  // ...
  plugins: [ApolloServerOperationRegistry({ /* options */})]
}),
```

> **Hint** The `ApolloServerOperationRegistry` plugin is exported from the `@apollo/server-plugin-operation-registry` package.

#### Plugins with Mercurius[#](/graphql/plugins#plugins-with-mercurius)

Some of the existing mercurius-specific Fastify plugins must be loaded after the mercurius plugin (read more [here](https://mercurius.dev/#/docs/plugins)) on the plugin tree.

> **Warning**[mercurius-upload](https://github.com/mercurius-js/mercurius-upload) is an exception and should be registered in the main file.

For this, `MercuriusDriver` exposes an optional `plugins` configuration option. It represents an array of objects that consist of two attributes: `plugin` and its `options`. Therefore, registering the [cache plugin](https://github.com/mercurius-js/cache) would look like this:

```typescript

GraphQLModule.forRoot({
  driver: MercuriusDriver,
  // ...
  plugins: [
    {
      plugin: cache,
      options: {
        ttl: 10,
        policy: {
          Query: {
            add: true
          }
        }
      },
    }
  ]
}),
```

----
url: https://docs.nestjs.com/v8/fundamentals/lifecycle-events
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Lifecycle Events](https://docs.nestjs.com/v8/fundamentals/lifecycle-events#lifecycle-events)
* [Lifecycle sequence](https://docs.nestjs.com/v8/fundamentals/lifecycle-events#lifecycle-sequence)
* [Lifecycle events](https://docs.nestjs.com/v8/fundamentals/lifecycle-events#lifecycle-events-1)
* [Usage](https://docs.nestjs.com/v8/fundamentals/lifecycle-events#usage)
* [Asynchronous initialization](https://docs.nestjs.com/v8/fundamentals/lifecycle-events#asynchronous-initialization)
* [Application shutdown](https://docs.nestjs.com/v8/fundamentals/lifecycle-events#application-shutdown)

| Lifecycle hook method           | Lifecycle event triggering the hook method call                                                                                                                                                              |
| ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `onModuleInit()`                | Called once the host module's dependencies have been resolved.                                                                                                                                               |
| `onApplicationBootstrap()`      | Called once all modules have been initialized, but before listening for connections.                                                                                                                         |
| `onModuleDestroy()`\*           | Called after a termination signal (e.g., `SIGTERM`) has been received.                                                                                                                                       |
| `beforeApplicationShutdown()`\* | Called after all `onModuleDestroy()` handlers have completed (Promises resolved or rejected); once complete (Promises resolved or rejected), all existing connections will be closed (`app.close()` called). |
| `onApplicationShutdown()`\*     | Called after connections close (`app.close()` resolves).                                                                                                                                                     |

\* For these events, if you're not calling `app.close()` explicitly, you must opt-in to make them work with system signals such as `SIGTERM`. See [Application shutdown](fundamentals/lifecycle-events#application-shutdown) below.

> **Warning** The lifecycle hooks listed above are not triggered for **request-scoped** classes. Request-scoped classes are not tied to the application lifecycle and their lifespan is unpredictable. They are exclusively created for each request and automatically garbage-collected after the response is sent.

#### Usage[#](/fundamentals/lifecycle-events#usage)

Each lifecycle hook is represented by an interface. Interfaces are technically optional because they do not exist after TypeScript compilation. Nonetheless, it's good practice to use them in order to benefit from strong typing and editor tooling. To register a lifecycle hook, implement the appropriate interface. For example, to register a method to be called during module initialization on a particular class (e.g., Controller, Provider or Module), implement the `OnModuleInit` interface by supplying an `onModuleInit()` method, as shown below:

JS TS

```typescript

import { Injectable, OnModuleInit } from '@nestjs/common';

@Injectable()
export class UsersService implements OnModuleInit {
  onModuleInit() {
    console.log(`The module has been initialized.`);
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';

@Injectable()
export class UsersService {
  onModuleInit() {
    console.log(`The module has been initialized.`);
  }
}
```

#### Asynchronous initialization[#](/fundamentals/lifecycle-events#asynchronous-initialization)

Both the `OnModuleInit` and `OnApplicationBootstrap` hooks allow you to defer the application initialization process (return a `Promise` or mark the method as `async` and `await` an asynchronous method completion in the method body).

JS TS

```typescript

async onModuleInit(): Promise<void> {
  await this.fetch();
}
```

```typescript

async onModuleInit() {
  await this.fetch();
}
```

#### Application shutdown[#](/fundamentals/lifecycle-events#application-shutdown)

The `onModuleDestroy()`, `beforeApplicationShutdown()` and `onApplicationShutdown()` hooks are called in the terminating phase (in response to an explicit call to `app.close()` or upon receipt of system signals such as SIGTERM if opted-in). This feature is often used with [Kubernetes](https://kubernetes.io/) to manage containers' lifecycles, by [Heroku](https://www.heroku.com/) for dynos or similar services.

Shutdown hook listeners consume system resources, so they are disabled by default. To use shutdown hooks, you **must enable listeners** by calling `enableShutdownHooks()`:

```typescript

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);

  // Starts listening for shutdown hooks
  app.enableShutdownHooks();

  await app.listen(3000);
}
bootstrap();
```

> **warning** Due to inherent platform limitations, NestJS has limited support for application shutdown hooks on Windows. You can expect `SIGINT` to work, as well as `SIGBREAK` and to some extent `SIGHUP` - [read more](https://nodejs.org/api/process.html#process_signal_events). However `SIGTERM` will never work on Windows because killing a process in the task manager is unconditional, "i.e., there's no way for an application to detect or prevent it". Here's some [relevant documentation](https://docs.libuv.org/en/v1.x/signal.html) from libuv to learn more about how `SIGINT`, `SIGBREAK` and others are handled on Windows. Also, see Node.js documentation of [Process Signal Events](https://nodejs.org/api/process.html#process_signal_events)

> **Info**`enableShutdownHooks` consumes memory by starting listeners. In cases where you are running multiple Nest apps in a single Node process (e.g., when running parallel tests with Jest), Node may complain about excessive listener processes. For this reason, `enableShutdownHooks` is not enabled by default. Be aware of this condition when you are running multiple instances in a single Node process.

When the application receives a termination signal it will call any registered `onModuleDestroy()`, `beforeApplicationShutdown()`, then `onApplicationShutdown()` methods (in the sequence described above) with the corresponding signal as the first parameter. If a registered function awaits an asynchronous call (returns a promise), Nest will not continue in the sequence until the promise is resolved or rejected.

JS TS

```typescript

@Injectable()
class UsersService implements OnApplicationShutdown {
  onApplicationShutdown(signal: string) {
    console.log(signal); // e.g. "SIGINT"
  }
}
```

```typescript

@Injectable()
class UsersService implements OnApplicationShutdown {
  onApplicationShutdown(signal) {
    console.log(signal); // e.g. "SIGINT"
  }
}
```

> **Info** Calling `app.close()` doesn't terminate the Node process but only triggers the `onModuleDestroy()` and `onApplicationShutdown()` hooks, so if there are some intervals, long-running background tasks, etc. the process won't be automatically terminated.

----
url: https://docs.nestjs.com/v9/graphql/other-features
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Other features](https://docs.nestjs.com/v9/graphql/other-features#other-features)
* [Overview](https://docs.nestjs.com/v9/graphql/other-features#overview)
* [Execution context](https://docs.nestjs.com/v9/graphql/other-features#execution-context)
* [Exception filters](https://docs.nestjs.com/v9/graphql/other-features#exception-filters)
* [Custom decorators](https://docs.nestjs.com/v9/graphql/other-features#custom-decorators)
* [Execute enhancers at the field resolver level](https://docs.nestjs.com/v9/graphql/other-features#execute-enhancers-at-the-field-resolver-level)
* [Creating a custom driver](https://docs.nestjs.com/v9/graphql/other-features#creating-a-custom-driver)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/guards-interceptors.md "Suggest Edits")

### Other features

In the GraphQL world, there is a lot of debate about handling issues like **authentication**, or **side-effects** of operations. Should we handle things inside the business logic? Should we use a higher-order function to enhance queries and mutations with authorization logic? Or should we use [schema directives](https://www.apollographql.com/docs/apollo-server/schema/directives/)? There is no single one-size-fits-all answer to these questions.

Nest helps address these issues with its cross-platform features like [guards](/v9/guards) and [interceptors](/v9/interceptors). The philosophy is to reduce redundancy and provide tooling that helps create well-structured, readable, and consistent applications.

#### Overview[#](/graphql/other-features#overview)

You can use standard [guards](/v9/guards), [interceptors](/v9/interceptors), [filters](/v9/exception-filters) and [pipes](/v9/pipes) in the same fashion with GraphQL as with any RESTful application. Additionally, you can easily create your own decorators by leveraging the [custom decorators](/v9/custom-decorators) feature. Let's take a look at a sample GraphQL query handler.

```typescript

@Query('author')
@UseGuards(AuthGuard)
async getAuthor(@Args('id', ParseIntPipe) id: number) {
  return this.authorsService.findOneById(id);
}
```

As you can see, GraphQL works with both guards and pipes in the same way as HTTP REST handlers. Because of this, you can move your authentication logic to a guard; you can even reuse the same guard class across both a REST and GraphQL API interface. Similarly, interceptors work across both types of applications in the same way:

```typescript

@Mutation()
@UseInterceptors(EventsInterceptor)
async upvotePost(@Args('postId') postId: number) {
  return this.postsService.upvoteById({ id: postId });
}
```

#### Execution context[#](/graphql/other-features#execution-context)

Since GraphQL receives a different type of data in the incoming request, the [execution context](https://docs.nestjs.com/fundamentals/execution-context) received by both guards and interceptors is somewhat different with GraphQL vs. REST. GraphQL resolvers have a distinct set of arguments: `root`, `args`, `context`, and `info`. Thus guards and interceptors must transform the generic `ExecutionContext` to a `GqlExecutionContext`. This is straightforward:

```typescript

import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common';
import { GqlExecutionContext } from '@nestjs/graphql';

@Injectable()
export class AuthGuard implements CanActivate {
  canActivate(context: ExecutionContext): boolean {
    const ctx = GqlExecutionContext.create(context);
    return true;
  }
}
```

The GraphQL context object returned by `GqlExecutionContext.create()` exposes a **get** method for each GraphQL resolver argument (e.g., `getArgs()`, `getContext()`, etc). Once transformed, we can easily pick out any GraphQL argument for the current request.

#### Exception filters[#](/graphql/other-features#exception-filters)

Nest standard [exception filters](/v9/exception-filters) are compatible with GraphQL applications as well. As with `ExecutionContext`, GraphQL apps should transform the `ArgumentsHost` object to a `GqlArgumentsHost` object.

```typescript

@Catch(HttpException)
export class HttpExceptionFilter implements GqlExceptionFilter {
  catch(exception: HttpException, host: ArgumentsHost) {
    const gqlHost = GqlArgumentsHost.create(host);
    return exception;
  }
}
```

> **Hint** Both `GqlExceptionFilter` and `GqlArgumentsHost` are imported from the `@nestjs/graphql` package.

Note that unlike the REST case, you don't use the native `response` object to generate a response.

#### Custom decorators[#](/graphql/other-features#custom-decorators)

As mentioned, the [custom decorators](/v9/custom-decorators) feature works as expected with GraphQL resolvers.

```typescript

export const User = createParamDecorator(
  (data: unknown, ctx: ExecutionContext) =>
    GqlExecutionContext.create(ctx).getContext().user,
);
```

Use the `@User()` custom decorator as follows:

```typescript

@Mutation()
async upvotePost(
  @User() user: UserEntity,
  @Args('postId') postId: number,
) {}
```

> **Hint** In the above example, we have assumed that the `user` object is assigned to the context of your GraphQL application.

#### Execute enhancers at the field resolver level[#](/graphql/other-features#execute-enhancers-at-the-field-resolver-level)

In the GraphQL context, Nest does not run **enhancers** (the generic name for interceptors, guards and filters) at the field level [see this issue](https://github.com/nestjs/graphql/issues/320#issuecomment-511193229): they only run for the top level `@Query()`/`@Mutation()` method. You can tell Nest to execute interceptors, guards or filters for methods annotated with `@ResolveField()` by setting the `fieldResolverEnhancers` option in `GqlModuleOptions`. Pass it a list of `'interceptors'`, `'guards'`, and/or `'filters'` as appropriate:

```typescript

GraphQLModule.forRoot({
  fieldResolverEnhancers: ['interceptors']
}),
```

> **Warning** Enabling enhancers for field resolvers can cause performance issues when you are returning lots of records and your field resolver is executed thousands of times. For this reason, when you enable `fieldResolverEnhancers`, we advise you to skip execution of enhancers that are not strictly necessary for your field resolvers. You can do this using the following helper function:

```typescript

export function isResolvingGraphQLField(context: ExecutionContext): boolean {
  if (context.getType<GqlContextType>() === 'graphql') {
    const gqlContext = GqlExecutionContext.create(context);
    const info = gqlContext.getInfo();
    const parentType = info.parentType.name;
    return parentType !== 'Query' && parentType !== 'Mutation';
  }
  return false;
}
```

#### Creating a custom driver[#](/graphql/other-features#creating-a-custom-driver)

Nest provides two official drivers out-of-the-box: `@nestjs/apollo` and `@nestjs/mercurius`, as well as an API allowing developers to build new **custom drivers**. With a custom driver, you can integrate any GraphQL library or extend the existing integration, adding extra features on top.

For example, to integrate the `express-graphql` package, you could create the following driver class:

```typescript

import { AbstractGraphQLDriver, GqlModuleOptions } from '@nestjs/graphql';
import { graphqlHTTP } from 'express-graphql';

class ExpressGraphQLDriver extends AbstractGraphQLDriver {
  async start(options: GqlModuleOptions<any>): Promise<void> {
    options = await this.graphQlFactory.mergeWithSchema(options);

    const { httpAdapter } = this.httpAdapterHost;
    httpAdapter.use(
      '/graphql',
      graphqlHTTP({
        schema: options.schema,
        graphiql: true,
      }),
    );
  }

  async stop() {}
}
```

And then use it as follows:

```typescript

GraphQLModule.forRoot({
  driver: ExpressGraphQLDriver,
});
```

----
url: https://docs.nestjs.com/v11/graphql/mapped-types
----

* [Mapped types](https://docs.nestjs.com/v11/graphql/mapped-types#mapped-types)
* [Partial](https://docs.nestjs.com/v11/graphql/mapped-types#partial)
* [Pick](https://docs.nestjs.com/v11/graphql/mapped-types#pick)
* [Omit](https://docs.nestjs.com/v11/graphql/mapped-types#omit)
* [Intersection](https://docs.nestjs.com/v11/graphql/mapped-types#intersection)
* [Composition](https://docs.nestjs.com/v11/graphql/mapped-types#composition)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/mapped-types.md "Suggest Edits")

### Mapped types

> **Warning** This chapter applies only to the code first approach.

As you build out features like CRUD (Create/Read/Update/Delete) it's often useful to construct variants on a base entity type. Nest provides several utility functions that perform type transformations to make this task more convenient.

#### Partial[#](/graphql/mapped-types#partial)

When building input validation types (also called Data Transfer Objects or DTOs), it's often useful to build **create** and **update** variations on the same type. For example, the **create** variant may require all fields, while the **update** variant may make all fields optional.

Nest provides the `PartialType()` utility function to make this task easier and minimize boilerplate.

The `PartialType()` function returns a type (class) with all the properties of the input type set to optional. For example, suppose we have a **create** type as follows:

```typescript

@InputType()
class CreateUserInput {
  @Field()
  email: string;

  @Field()
  password: string;

  @Field()
  firstName: string;
}
```

By default, all of these fields are required. To create a type with the same fields, but with each one optional, use `PartialType()` passing the class reference (`CreateUserInput`) as an argument:

```typescript

@InputType()
export class UpdateUserInput extends PartialType(CreateUserInput) {}
```

> **Hint** The `PartialType()` function is imported from the `@nestjs/graphql` package.

The `PartialType()` function takes an optional second argument that is a reference to a decorator factory. This argument can be used to change the decorator function applied to the resulting (child) class. If not specified, the child class effectively uses the same decorator as the **parent** class (the class referenced in the first argument). In the example above, we are extending `CreateUserInput` which is annotated with the `@InputType()` decorator. Since we want `UpdateUserInput` to also be treated as if it were decorated with `@InputType()`, we didn't need to pass `InputType` as the second argument. If the parent and child types are different, (e.g., the parent is decorated with `@ObjectType`), we would pass `InputType` as the second argument. For example:

```typescript

@InputType()
export class UpdateUserInput extends PartialType(User, InputType) {}
```

#### Pick[#](/graphql/mapped-types#pick)

The `PickType()` function constructs a new type (class) by picking a set of properties from an input type. For example, suppose we start with a type like:

```typescript

@InputType()
class CreateUserInput {
  @Field()
  email: string;

  @Field()
  password: string;

  @Field()
  firstName: string;
}
```

We can pick a set of properties from this class using the `PickType()` utility function:

```typescript

@InputType()
export class UpdateEmailInput extends PickType(CreateUserInput, [
  'email',
] as const) {}
```

> **Hint** The `PickType()` function is imported from the `@nestjs/graphql` package.

#### Omit[#](/graphql/mapped-types#omit)

The `OmitType()` function constructs a type by picking all properties from an input type and then removing a particular set of keys. For example, suppose we start with a type like:

```typescript

@InputType()
class CreateUserInput {
  @Field()
  email: string;

  @Field()
  password: string;

  @Field()
  firstName: string;
}
```

We can generate a derived type that has every property **except**`email` as shown below. In this construct, the second argument to `OmitType` is an array of property names.

```typescript

@InputType()
export class UpdateUserInput extends OmitType(CreateUserInput, [
  'email',
] as const) {}
```

> **Hint** The `OmitType()` function is imported from the `@nestjs/graphql` package.

#### Intersection[#](/graphql/mapped-types#intersection)

The `IntersectionType()` function combines two types into one new type (class). For example, suppose we start with two types like:

```typescript

@InputType()
class CreateUserInput {
  @Field()
  email: string;

  @Field()
  password: string;
}

@ObjectType()
export class AdditionalUserInfo {
  @Field()
  firstName: string;

  @Field()
  lastName: string;
}
```

We can generate a new type that combines all properties in both types.

```typescript

@InputType()
export class UpdateUserInput extends IntersectionType(
  CreateUserInput,
  AdditionalUserInfo,
) {}
```

> **Hint** The `IntersectionType()` function is imported from the `@nestjs/graphql` package.

#### Composition[#](/graphql/mapped-types#composition)

The type mapping utility functions are composable. For example, the following will produce a type (class) that has all of the properties of the `CreateUserInput` type except for `email`, and those properties will be set to optional:

```typescript

@InputType()
export class UpdateUserInput extends PartialType(
  OmitType(CreateUserInput, ['email'] as const),
) {}
```

----
url: https://docs.nestjs.com/v10/faq/hybrid-application
----

* [Hybrid application](https://docs.nestjs.com/v10/faq/hybrid-application#hybrid-application)
* [Sharing configuration](https://docs.nestjs.com/v10/faq/hybrid-application#sharing-configuration)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/faq/hybrid-application.md "Suggest Edits")

### Hybrid application

A hybrid application is one that listens for requests from two or more different sources. This can combine an HTTP server with a microservice listener or even just multiple different microservice listeners. The default `createMicroservice` method does not allow for multiple servers so in this case each microservice must be created and started manually. In order to do this, the `INestApplication` instance can be connected with `INestMicroservice` instances through the `connectMicroservice()` method.

```typescript

const app = await NestFactory.create(AppModule);
const microservice = app.connectMicroservice<MicroserviceOptions>({
  transport: Transport.TCP,
});

await app.startAllMicroservices();
await app.listen(3001);
```

> **Hint** the `app.listen(port)` method starts an HTTP server on the specified address. If your application does not handle HTTP requests then you should use the `app.init()` method instead.

To connect multiple microservice instances, issue the call to `connectMicroservice()` for each microservice:

```typescript

const app = await NestFactory.create(AppModule);
// microservice #1
const microserviceTcp = app.connectMicroservice<MicroserviceOptions>({
  transport: Transport.TCP,
  options: {
    port: 3001,
  },
});
// microservice #2
const microserviceRedis = app.connectMicroservice<MicroserviceOptions>({
  transport: Transport.REDIS,
  options: {
    host: 'localhost',
    port: 6379,
  },
});

await app.startAllMicroservices();
await app.listen(3001);
```

To bind `@MessagePattern()` to only one transport strategy (for example, MQTT) in a hybrid application with multiple microservices, we can pass the second argument of type `Transport` which is an enum with all the built-in transport strategies defined.

JS TS

```typescript

@MessagePattern('time.us.*', Transport.NATS)
getDate(@Payload() data: number[], @Ctx() context: NatsContext) {
  console.log(`Subject: ${context.getSubject()}`); // e.g. "time.us.east"
  return new Date().toLocaleTimeString(...);
}
@MessagePattern({ cmd: 'time.us' }, Transport.TCP)
getTCPDate(@Payload() data: number[]) {
  return new Date().toLocaleTimeString(...);
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('time.us.*', Transport.NATS)
getDate(data, context) {
  console.log(`Subject: ${context.getSubject()}`); // e.g. "time.us.east"
  return new Date().toLocaleTimeString(...);
}
@Bind(Payload(), Ctx())
@MessagePattern({ cmd: 'time.us' }, Transport.TCP)
getTCPDate(data, context) {
  return new Date().toLocaleTimeString(...);
}
```

> **Hint**`@Payload()`, `@Ctx()`, `Transport` and `NatsContext` are imported from `@nestjs/microservices`.

#### Sharing configuration[#](/faq/hybrid-application#sharing-configuration)

By default a hybrid application will not inherit global pipes, interceptors, guards and filters configured for the main (HTTP-based) application. To inherit these configuration properties from the main application, set the `inheritAppConfig` property in the second argument (an optional options object) of the `connectMicroservice()` call, as follow:

```typescript

const microservice = app.connectMicroservice<MicroserviceOptions>(
  {
    transport: Transport.TCP,
  },
  { inheritAppConfig: true },
);
```

----
url: https://docs.nestjs.com/v7/cli/overview
----

* [Overview](https://docs.nestjs.com/v7/cli/overview#overview)
* [Installation](https://docs.nestjs.com/v7/cli/overview#installation)
* [Basic workflow](https://docs.nestjs.com/v7/cli/overview#basic-workflow)
* [Project structure](https://docs.nestjs.com/v7/cli/overview#project-structure)
* [CLI command syntax](https://docs.nestjs.com/v7/cli/overview#cli-command-syntax)
* [Command overview](https://docs.nestjs.com/v7/cli/overview#command-overview)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/cli/overview.md "Suggest Edits")

### Overview

The [Nest CLI](https://github.com/nestjs/nest-cli) is a command-line interface tool that helps you to initialize, develop, and maintain your Nest applications. It assists in multiple ways, including scaffolding the project, serving it in development mode, and building and bundling the application for production distribution. It embodies best-practice architectural patterns to encourage well-structured apps.

#### Installation[#](/cli/overview#installation)

**Note**: In this guide we describe using [npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm) to install packages, including the Nest CLI. Other package managers may be used at your discretion. With npm, you have several options available for managing how your OS command line resolves the location of the `nest` CLI binary file. Here, we describe installing the `nest` binary globally using the `-g` option. This provides a measure of convenience, and is the approach we assume throughout the documentation. Note that installing **any**`npm` package globally leaves the responsibility of ensuring they're running the correct version up to the user. It also means that if you have different projects, each will run the **same** version of the CLI. A reasonable alternative is to use the [npx](https://github.com/npm/npx) program (or similar features with other package managers) to ensure that you run a **managed version** of the Nest CLI. We recommend you consult the [npx documentation](https://github.com/npm/npx) and/or your DevOps support staff for more information.

Install the CLI globally using the `npm install -g` command (see the **Note** above for details about global installs).

```bash

$ npm install -g @nestjs/cli
```

#### Basic workflow[#](/cli/overview#basic-workflow)

Once installed, you can invoke CLI commands directly from your OS command line through the `nest` executable. See the available `nest` commands by entering the following:

```bash

$ nest --help
```

Get help on an individual command using the following construct. Substitute any command, like `new`, `add`, etc., where you see `generate` in the example below to get detailed help on that command:

```bash

$ nest generate --help
```

To create, build and run a new basic Nest project in development mode, go to the folder that should be the parent of your new project, and run the following commands:

```bash

$ nest new my-nest-project
$ cd my-nest-project
$ npm run start:dev
```

In your browser, open <http://localhost:3000> to see the new application running. The app will automatically recompile and reload when you change any of the source files.

#### Project structure[#](/cli/overview#project-structure)

When you run `nest new`, Nest generates a boilerplate application structure by creating a new folder and populating an initial set of files. You can continue working in this default structure, adding new components, as described throughout this documentation. We refer to the project structure generated by `nest new` as **standard mode**. Nest also supports an alternate structure for managing multiple projects and libraries called **monorepo mode**.

Aside from a few specific considerations around how the **build** process works (essentially, monorepo mode simplifies build complexities that can sometimes arise from monorepo-style project structures), and built-in [library](/v7/cli/libraries) support, the rest of the Nest features, and this documentation, apply equally to both standard and monorepo mode project structures. In fact, you can easily switch from standard mode to monorepo mode at any time in the future, so you can safely defer this decision while you're still learning about Nest.

You can use either mode to manage multiple projects. Here's a quick summary of the differences:

| Feature                                              | Standard Mode                                                      | Monorepo Mode                                              |
| ---------------------------------------------------- | ------------------------------------------------------------------ | ---------------------------------------------------------- |
| Multiple projects                                    | Separate file system structure                                     | Single file system structure                               |
| `node_modules` & `package.json`                      | Separate instances                                                 | Shared across monorepo                                     |
| Default compiler                                     | `tsc`                                                              | webpack                                                    |
| Compiler settings                                    | Specified separately                                               | Monorepo defaults that can be overridden per project       |
| Config files like `tslint.json`, `.prettierrc`, etc. | Specified separately                                               | Shared across monorepo                                     |
| `nest build` and `nest start` commands               | Target defaults automatically to the (only) project in the context | Target defaults to the **default project** in the monorepo |
| Libraries                                            | Managed manually, usually via npm packaging                        | Built-in support, including path management and bundling   |

Read the sections on [Workspaces](/v7/cli/monorepo) and [Libraries](/v7/cli/libraries) for more detailed information to help you decide which mode is most suitable for you.

```bash

nest commandOrAlias requiredArg [optionalArg] [options]
```

For example:

```bash

$ nest new my-nest-project --dry-run
```

Here, `new` is the *commandOrAlias*. The `new` command has an alias of `n`. `my-nest-project` is the *requiredArg*. If a *requiredArg* is not supplied on the command line, `nest` will prompt for it. Also, `--dry-run` has an equivalent short-hand form `-d`. With this in mind, the following command is the equivalent of the above:

```bash

$ nest n my-nest-project -d
```

Most commands, and some options, have aliases. Try running `nest new --help` to see these options and aliases, and to confirm your understanding of the above constructs.

#### Command overview[#](/cli/overview#command-overview)

Run `nest <command> --help` for any of the following commands to see command-specific options.

See [usage](/v7/cli/usages) for detailed descriptions for each command.

| Command    | Alias | Description                                                                                          |
| ---------- | ----- | ---------------------------------------------------------------------------------------------------- |
| `new`      | `n`   | Scaffolds a new *standard mode* application with all boilerplate files needed to run.                |
| `generate` | `g`   | Generates and/or modifies files based on a schematic.                                                |
| `build`    |       | Compiles an application or workspace into an output folder.                                          |
| `start`    |       | Compiles and runs an application (or default project in a workspace).                                |
| `add`      |       | Imports a library that has been packaged as a **nest library**, running its install schematic.       |
| `update`   | `u`   | Update `@nestjs` dependencies in the `package.json``"dependencies"` list to their `@latest` version. |
| `info`     | `i`   | Displays information about installed nest packages and other helpful system info.                    |

----
url: https://docs.nestjs.com/v7/graphql/mapped-types
----

* [Mapped types](https://docs.nestjs.com/v7/graphql/mapped-types#mapped-types)
* [Partial](https://docs.nestjs.com/v7/graphql/mapped-types#partial)
* [Pick](https://docs.nestjs.com/v7/graphql/mapped-types#pick)
* [Omit](https://docs.nestjs.com/v7/graphql/mapped-types#omit)
* [Intersection](https://docs.nestjs.com/v7/graphql/mapped-types#intersection)
* [Composition](https://docs.nestjs.com/v7/graphql/mapped-types#composition)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/mapped-types.md "Suggest Edits")

### Mapped types

> **Warning** This chapter applies only to the code first approach.

As you build out features like CRUD (Create/Read/Update/Delete) it's often useful to construct variants on a base entity type. Nest provides several utility functions that perform type transformations to make this task more convenient.

#### Partial[#](/graphql/mapped-types#partial)

When building input validation types (also called DTOs), it's often useful to build **create** and **update** variations on the same type. For example, the **create** variant may require all fields, while the **update** variant may make all fields optional.

Nest provides the `PartialType()` utility function to make this task easier and minimize boilerplate.

The `PartialType()` function returns a type (class) with all the properties of the input type set to optional. For example, suppose we have a **create** type as follows:

```typescript

@InputType()
class CreateUserInput {
  @Field()
  email: string;

  @Field()
  password: string;

  @Field()
  firstName: string;
}
```

By default, all of these fields are required. To create a type with the same fields, but with each one optional, use `PartialType()` passing the class reference (`CreateUserInput`) as an argument:

```typescript

@InputType()
export class UpdateUserInput extends PartialType(CreateUserInput) {}
```

> **Hint** The `PartialType()` function is imported from the `@nestjs/graphql` package.

The `PartialType()` function takes an optional second argument that is a reference to a decorator factory. This argument can be used to change the decorator function applied to the resulting (child) class. If not specified, the child class effectively uses the same decorator as the **parent** class (the class referenced in the first argument). In the example above, we are extending `CreateUserInput` which is annotated with the `@InputType()` decorator. Since we want `UpdateUserInput` to also be treated as if it were decorated with `@InputType()`, we didn't need to pass `InputType` as the second argument. If the parent and child types are different, (e.g., the parent is decorated with `@ObjectType`), we would pass `InputType` as the second argument. For example:

```typescript

@InputType()
export class UpdateUserInput extends PartialType(User, InputType) {}
```

#### Pick[#](/graphql/mapped-types#pick)

The `PickType()` function constructs a new type (class) by picking a set of properties from an input type. For example, suppose we start with a type like:

```typescript

@InputType()
class CreateUserInput {
  @Field()
  email: string;

  @Field()
  password: string;

  @Field()
  firstName: string;
}
```

We can pick a set of properties from this class using the `PickType()` utility function:

```typescript

@InputType()
export class UpdateEmailInput extends PickType(CreateUserInput, ['email'] as const) {}
```

> **Hint** The `PickType()` function is imported from the `@nestjs/graphql` package.

#### Omit[#](/graphql/mapped-types#omit)

The `OmitType()` function constructs a type by picking all properties from an input type and then removing a particular set of keys. For example, suppose we start with a type like:

```typescript

@InputType()
class CreateUserInput {
  @Field()
  email: string;

  @Field()
  password: string;

  @Field()
  firstName: string;
}
```

We can generate a derived type that has every property **except**`email` as shown below. In this construct, the second argument to `OmitType` is an array of property names.

```typescript

@InputType()
export class UpdateUserInput extends OmitType(CreateUserInput, ['email'] as const) {}
```

> **Hint** The `OmitType()` function is imported from the `@nestjs/graphql` package.

#### Intersection[#](/graphql/mapped-types#intersection)

The `IntersectionType()` function combines two types into one new type (class). For example, suppose we start with two types like:

```typescript

@InputType()
class CreateUserInput {
  @Field()
  email: string;

  @Field()
  password: string;
}

@ObjectType()
export class AdditionalUserInfo {
  @Field()
  firstName: string;
  
  @Field()
  lastName: string;
}
```

We can generate a new type that combines all properties in both types.

```typescript

@InputType()
export class UpdateUserInput extends IntersectionType(CreateUserInput, AdditionalUserInfo) {}
```

> **Hint** The `IntersectionType()` function is imported from the `@nestjs/graphql` package.

#### Composition[#](/graphql/mapped-types#composition)

The type mapping utility functions are composable. For example, the following will produce a type (class) that has all of the properties of the `CreateUserInput` type except for `email`, and those properties will be set to optional:

```typescript

@InputType()
export class UpdateUserInput extends PartialType(
  OmitType(CreateUserInput, ['email'] as const),
) {}
```

----
url: https://docs.nestjs.com/v6/fundamentals/custom-providers
----

* [Custom providers](https://docs.nestjs.com/v6/fundamentals/custom-providers#custom-providers)
* [DI fundamentals](https://docs.nestjs.com/v6/fundamentals/custom-providers#di-fundamentals)
* [Standard providers](https://docs.nestjs.com/v6/fundamentals/custom-providers#standard-providers)
* [Custom providers](https://docs.nestjs.com/v6/fundamentals/custom-providers#custom-providers-1)
* [Value providers: useValue](https://docs.nestjs.com/v6/fundamentals/custom-providers#value-providers-usevalue)
* [Non-class-based provider tokens](https://docs.nestjs.com/v6/fundamentals/custom-providers#non-class-based-provider-tokens)
* [Class providers: useClass](https://docs.nestjs.com/v6/fundamentals/custom-providers#class-providers-useclass)
* [Factory providers: useFactory](https://docs.nestjs.com/v6/fundamentals/custom-providers#factory-providers-usefactory)
* [Alias providers: useExisting](https://docs.nestjs.com/v6/fundamentals/custom-providers#alias-providers-useexisting)
* [Non-service based providers](https://docs.nestjs.com/v6/fundamentals/custom-providers#non-service-based-providers)
* [Export custom provider](https://docs.nestjs.com/v6/fundamentals/custom-providers#export-custom-provider)

```typescript

import { Injectable } from '@nestjs/common';
import { Cat } from './interfaces/cat.interface';

@Injectable()
export class CatsService {
  private readonly cats: Cat[] = [];

  findAll(): Cat[] {
    return this.cats;
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';

@Injectable()
export class CatsService {
  constructor() {
    this.cats = [];
  }

  findAll() {
    return this.cats;
  }
}
```

Then we request that Nest inject the provider into our controller class:

cats.controller.ts

JS TS

```typescript

import { Controller, Get } from '@nestjs/common';
import { CatsService } from './cats.service';
import { Cat } from './interfaces/cat.interface';

@Controller('cats')
export class CatsController {
  constructor(private readonly catsService: CatsService) {}

  @Get()
  async findAll(): Promise<Cat[]> {
    return this.catsService.findAll();
  }
}
```

```typescript

import { Controller, Get, Bind, Dependencies } from '@nestjs/common';
import { CatsService } from './cats.service';

@Controller('cats')
@Dependencies(CatsService)
export class CatsController {
  constructor(catsService) {
    this.catsService = catsService;
  }

  @Get()
  async findAll() {
    return this.catsService.findAll();
  }
}
```

Finally, we register the provider with the Nest IoC container:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { CatsController } from './cats/cats.controller';
import { CatsService } from './cats/cats.service';

@Module({
  controllers: [CatsController],
  providers: [CatsService],
})
export class AppModule {}
```

What exactly is happening under the covers to make this work? There are three key steps in the process:

1. In `cats.service.ts`, the `@Injectable()` decorator declares the `CatsService` class as a class that can be managed by the Nest IoC container.

2. In `cats.controller.ts`, `CatsController` declares a dependency on the `CatsService` token with constructor injection:

```typescript

  constructor(private readonly catsService: CatsService)
```

3. In `app.module.ts`, we associate the token `CatsService` with the class `CatsService` from the `cats.service.ts` file. We'll [see below](/fundamentals/custom-providers#standard-providers) exactly how this association (also called *registration*) occurs.

When the Nest IoC container instantiates a `CatsController`, it first looks for any dependencies\*. When it finds the `CatsService` dependency, it performs a lookup on the `CatsService` token, which returns the `CatsService` class, per the registration step (#3 above). Assuming `SINGLETON` scope (the default behavior), Nest will then either create an instance of `CatsService`, cache it, and return it, or if one is already cached, return the existing instance.

\*This explanation is a bit simplified to illustrate the point. One important area we glossed over is that the process of analyzing the code for dependencies is very sophisticated, and happens during application bootstrapping. One key feature is that dependency analysis (or "creating the dependency graph"), is **transitive**. In the above example, if the `CatsService` itself had dependencies, those too would be resolved. The dependency graph ensures that dependencies are resolved in the correct order - essentially "bottom up". This mechanism relieves the developer from having to manage such complex dependency graphs.

## Learn the right way!

* **60+ chapters
* **4+ hours of videos
* **Official certificate
* **Deep-dive sessions

[Explore official courses](https://courses.nestjs.com "Courses | NestJS - A node.js framework built on top of TypeScript")

#### Standard providers[#](/fundamentals/custom-providers#standard-providers)

Let's take a closer look at the `@Module()` decorator. In `app.module`, we declare:

```typescript

@Module({
  controllers: [CatsController],
  providers: [CatsService],
})
```

The `providers` property takes an array of `providers`. So far, we've supplied those providers via a list of class names. In fact, the syntax `providers: [CatsService]` is short-hand for the more complete syntax:

```typescript

providers: [
  {
    provide: CatsService,
    useClass: CatsService,
  },
];
```

```typescript

import { CatsService } from './cats.service';

const mockCatsService = {
  /* mock implementation
  ...
  */
};

@Module({
  imports: [CatsModule],
  providers: [
    {
      provide: CatsService,
      useValue: mockCatsService,
    },
  ],
})
export class AppModule {}
```

In this example, the `CatsService` token will resolve to the `mockCatsService` mock object. `useValue` requires a value - in this case a literal object that has the same interface as the `CatsService` class it is replacing. Because of TypeScript's [structural typing](https://www.typescriptlang.org/docs/handbook/type-compatibility.html), you can use any object that has a compatible interface, including a literal object or a class instance instantiated with `new`.

#### Non-class-based provider tokens[#](/fundamentals/custom-providers#non-class-based-provider-tokens)

So far, we've used class names as our provider tokens (the value of the `provide` property in a provider listed in the `providers` array). This is matched by the standard pattern used with [constructor based injection](https://docs.nestjs.com/providers#dependency-injection), where the token is also a class name. (Refer back to [DI Fundamentals](/fundamentals/custom-providers#di-fundamentals) for a refresher on tokens if this concept isn't entirely clear). Sometimes, we may want the flexibility to use strings or symbols as the DI token. For example:

```typescript

import { connection } from './connection';

@Module({
  providers: [
    {
      provide: 'CONNECTION',
      useValue: connection,
    },
  ],
})
export class AppModule {}
```

In this example, we are associating a string-valued token (`'CONNECTION'`) with a pre-existing `connection` object we've imported from an external file.

> **Notice** In addition to using strings as token values, you can also use JavaScript [symbols](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol).

We've previously seen how to inject a provider using the standard [constructor based injection](https://docs.nestjs.com/providers#dependency-injection) pattern. This pattern **requires** that the dependency be declared with a class name. The `'CONNECTION'` custom provider uses a string-valued token. Let's see how to inject such a provider. To do so, we use the `@Inject()` decorator. This decorator takes a single argument - the token.

JS TS

```typescript

@Injectable()
export class CatsRepository {
  constructor(@Inject('CONNECTION') connection: Connection) {}
}
```

```typescript

@Injectable()
@Dependencies('CONNECTION')
export class CatsRepository {
  constructor(connection) {}
}
```

> **Hint** The `@Inject()` decorator is imported from `@nestjs/common` package.

While we directly use the string `'CONNECTION'` in the above examples for illustration purposes, for clean code organization, it's best practice to define tokens in a separate file, such as `constants.ts`. Treat them much as you would symbols or enums that are defined in their own file and imported where needed.

#### Class providers: `useClass`[#](/fundamentals/custom-providers#class-providers-useclass)

The `useClass` syntax allows you to dynamically determine a class that a token should resolve to. For example, suppose we have an abstract (or default) `ConfigService` class. Depending on the current environment, we want Nest to provide a different implementation of the configuration service. The following code implements such a strategy.

```typescript

const configServiceProvider = {
  provide: ConfigService,
  useClass:
    process.env.NODE_ENV === 'development'
      ? DevelopmentConfigService
      : ProductionConfigService,
};

@Module({
  providers: [configServiceProvider],
})
export class AppModule {}
```

```typescript

const connectionFactory = {
  provide: 'CONNECTION',
  useFactory: (optionsProvider: OptionsProvider) => {
    const options = optionsProvider.get();
    return new DatabaseConnection(options);
  },
  inject: [OptionsProvider],
};

@Module({
  providers: [connectionFactory],
})
export class AppModule {}
```

```typescript

const connectionFactory = {
  provide: 'CONNECTION',
  useFactory: (optionsProvider) => {
    const options = optionsProvider.get();
    return new DatabaseConnection(options);
  },
  inject: [OptionsProvider],
};

@Module({
  providers: [connectionFactory],
})
export class AppModule {}
```

#### Alias providers: `useExisting`[#](/fundamentals/custom-providers#alias-providers-useexisting)

The `useExisting` syntax allows you to create aliases for existing providers. This creates two ways to access the same provider. In the example below, the (string-based) token `'AliasedLoggerService'` is an alias for the (class-based) token `LoggerService`. Assume we have two different dependencies, one for `'AlilasedLoggerService'` and one for `LoggerService`. If both dependencies are specified with `SINGLETON` scope, they'll both resolve to the same instance.

```typescript

@Injectable()
class LoggerService {
  /* implementation details */
}

const loggerAliasProvider = {
  provide: 'AliasedLoggerService',
  useExisting: LoggerService,
};

@Module({
  providers: [LoggerService, loggerAliasProvider],
})
export class AppModule {}
```

#### Non-service based providers[#](/fundamentals/custom-providers#non-service-based-providers)

While providers often supply services, they are not limited to that usage. A provider can supply **any** value. For example, a provider may supply an array of configuration objects based on the current environment, as shown below:

```typescript

const configFactory = {
  provide: 'CONFIG',
  useFactory: () => {
    return process.env.NODE_ENV === 'development' ? devConfig : prodConfig;
  },
};

@Module({
  providers: [configFactory],
})
export class AppModule {}
```

#### Export custom provider[#](/fundamentals/custom-providers#export-custom-provider)

Like any provider, a custom provider is scoped to its declaring module. To make it visible to other modules, it must be exported. To export a custom provider, we can either use its token or the full provider object.

The following example shows exporting using the token:

JS TS

```typescript

const connectionFactory = {
  provide: 'CONNECTION',
  useFactory: (optionsProvider: OptionsProvider) => {
    const options = optionsProvider.get();
    return new DatabaseConnection(options);
  },
  inject: [OptionsProvider],
};

@Module({
  providers: [connectionFactory],
  exports: ['CONNECTION'],
})
export class AppModule {}
```

```typescript

const connectionFactory = {
  provide: 'CONNECTION',
  useFactory: (optionsProvider) => {
    const options = optionsProvider.get();
    return new DatabaseConnection(options);
  },
  inject: [OptionsProvider],
};

@Module({
  providers: [connectionFactory],
  exports: ['CONNECTION'],
})
export class AppModule {}
```

Alternatively, export with the full provider object:

JS TS

```typescript

const connectionFactory = {
  provide: 'CONNECTION',
  useFactory: (optionsProvider: OptionsProvider) => {
    const options = optionsProvider.get();
    return new DatabaseConnection(options);
  },
  inject: [OptionsProvider],
};

@Module({
  providers: [connectionFactory],
  exports: [connectionFactory],
})
export class AppModule {}
```

```typescript

const connectionFactory = {
  provide: 'CONNECTION',
  useFactory: (optionsProvider) => {
    const options = optionsProvider.get();
    return new DatabaseConnection(options);
  },
  inject: [OptionsProvider],
};

@Module({
  providers: [connectionFactory],
  exports: [connectionFactory],
})
export class AppModule {}
```

----
url: https://docs.nestjs.com/v11/cli/overview
----

* [Overview](https://docs.nestjs.com/v11/cli/overview#overview)
* [Installation](https://docs.nestjs.com/v11/cli/overview#installation)
* [Basic workflow](https://docs.nestjs.com/v11/cli/overview#basic-workflow)
* [Project structure](https://docs.nestjs.com/v11/cli/overview#project-structure)
* [CLI command syntax](https://docs.nestjs.com/v11/cli/overview#cli-command-syntax)
* [Command overview](https://docs.nestjs.com/v11/cli/overview#command-overview)
* [Requirements](https://docs.nestjs.com/v11/cli/overview#requirements)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/cli/overview.md "Suggest Edits")

### Overview

The [Nest CLI](https://github.com/nestjs/nest-cli) is a command-line interface tool that helps you to initialize, develop, and maintain your Nest applications. It assists in multiple ways, including scaffolding the project, serving it in development mode, and building and bundling the application for production distribution. It embodies best-practice architectural patterns to encourage well-structured apps.

#### Installation[#](/cli/overview#installation)

**Note**: In this guide we describe using [npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm) to install packages, including the Nest CLI. Other package managers may be used at your discretion. With npm, you have several options available for managing how your OS command line resolves the location of the `nest` CLI binary file. Here, we describe installing the `nest` binary globally using the `-g` option. This provides a measure of convenience, and is the approach we assume throughout the documentation. Note that installing **any**`npm` package globally leaves the responsibility of ensuring they're running the correct version up to the user. It also means that if you have different projects, each will run the **same** version of the CLI. A reasonable alternative is to use the [npx](https://github.com/npm/cli/blob/latest/docs/lib/content/commands/npx.md) program, built into the `npm` cli (or similar features with other package managers) to ensure that you run a **managed version** of the Nest CLI. We recommend you consult the [npx documentation](https://github.com/npm/cli/blob/latest/docs/lib/content/commands/npx.md) and/or your DevOps support staff for more information.

Install the CLI globally using the `npm install -g` command (see the **Note** above for details about global installs).

```bash

$ npm install -g @nestjs/cli
```

> **Hint** Alternatively, you can use this command `npx @nestjs/cli@latest` without installing the cli globally.

#### Basic workflow[#](/cli/overview#basic-workflow)

Once installed, you can invoke CLI commands directly from your OS command line through the `nest` executable. See the available `nest` commands by entering the following:

```bash

$ nest --help
```

Get help on an individual command using the following construct. Substitute any command, like `new`, `add`, etc., where you see `generate` in the example below to get detailed help on that command:

```bash

$ nest generate --help
```

To create, build and run a new basic Nest project in development mode, go to the folder that should be the parent of your new project, and run the following commands:

```bash

$ nest new my-nest-project
$ cd my-nest-project
$ npm run start:dev
```

In your browser, open <http://localhost:3000> to see the new application running. The app will automatically recompile and reload when you change any of the source files.

> **Hint** We recommend using the [SWC builder](/v11/recipes/swc) for faster builds (10x more performant than the default TypeScript compiler).

#### Project structure[#](/cli/overview#project-structure)

When you run `nest new`, Nest generates a boilerplate application structure by creating a new folder and populating an initial set of files. You can continue working in this default structure, adding new components, as described throughout this documentation. We refer to the project structure generated by `nest new` as **standard mode**. Nest also supports an alternate structure for managing multiple projects and libraries called **monorepo mode**.

Aside from a few specific considerations around how the **build** process works (essentially, monorepo mode simplifies build complexities that can sometimes arise from monorepo-style project structures), and built-in [library](/v11/cli/libraries) support, the rest of the Nest features, and this documentation, apply equally to both standard and monorepo mode project structures. In fact, you can easily switch from standard mode to monorepo mode at any time in the future, so you can safely defer this decision while you're still learning about Nest.

You can use either mode to manage multiple projects. Here's a quick summary of the differences:

| Feature                                                    | Standard Mode                                                      | Monorepo Mode                                              |
| ---------------------------------------------------------- | ------------------------------------------------------------------ | ---------------------------------------------------------- |
| Multiple projects                                          | Separate file system structure                                     | Single file system structure                               |
| `node_modules` & `package.json`                            | Separate instances                                                 | Shared across monorepo                                     |
| Default compiler                                           | `tsc`                                                              | webpack                                                    |
| Compiler settings                                          | Specified separately                                               | Monorepo defaults that can be overridden per project       |
| Config files like `eslint.config.mjs`, `.prettierrc`, etc. | Specified separately                                               | Shared across monorepo                                     |
| `nest build` and `nest start` commands                     | Target defaults automatically to the (only) project in the context | Target defaults to the **default project** in the monorepo |
| Libraries                                                  | Managed manually, usually via npm packaging                        | Built-in support, including path management and bundling   |

Read the sections on [Workspaces](/v11/cli/monorepo) and [Libraries](/v11/cli/libraries) for more detailed information to help you decide which mode is most suitable for you.

```bash

nest commandOrAlias requiredArg [optionalArg] [options]
```

For example:

```bash

$ nest new my-nest-project --dry-run
```

Here, `new` is the *commandOrAlias*. The `new` command has an alias of `n`. `my-nest-project` is the *requiredArg*. If a *requiredArg* is not supplied on the command line, `nest` will prompt for it. Also, `--dry-run` has an equivalent short-hand form `-d`. With this in mind, the following command is the equivalent of the above:

```bash

$ nest n my-nest-project -d
```

Most commands, and some options, have aliases. Try running `nest new --help` to see these options and aliases, and to confirm your understanding of the above constructs.

#### Command overview[#](/cli/overview#command-overview)

Run `nest <command> --help` for any of the following commands to see command-specific options.

See [usage](/v11/cli/usages) for detailed descriptions for each command.

| Command    | Alias | Description                                                                                    |
| ---------- | ----- | ---------------------------------------------------------------------------------------------- |
| `new`      | `n`   | Scaffolds a new *standard mode* application with all boilerplate files needed to run.          |
| `generate` | `g`   | Generates and/or modifies files based on a schematic.                                          |
| `build`    |       | Compiles an application or workspace into an output folder.                                    |
| `start`    |       | Compiles and runs an application (or default project in a workspace).                          |
| `add`      |       | Imports a library that has been packaged as a **nest library**, running its install schematic. |
| `info`     | `i`   | Displays information about installed nest packages and other helpful system info.              |

#### Requirements[#](/cli/overview#requirements)

Nest CLI requires a Node.js binary built with [internationalization support](https://nodejs.org/api/intl.html) (ICU), such as the official binaries from the [Node.js project page](https://nodejs.org/en/download). If you encounter errors related to ICU, check that your binary meets this requirement.

```bash

node -p process.versions.icu
```

If the command prints `undefined`, your Node.js binary has no internationalization support.

----
url: https://docs.nestjs.com/v10/recipes/documentation
----

* [Documentation](https://docs.nestjs.com/v10/recipes/documentation#documentation)
* [Setup](https://docs.nestjs.com/v10/recipes/documentation#setup)
* [Generation](https://docs.nestjs.com/v10/recipes/documentation#generation)
* [Contribute](https://docs.nestjs.com/v10/recipes/documentation#contribute)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/recipes/documentation.md "Suggest Edits")

### Documentation

**Compodoc** is a documentation tool for Angular applications. Since Nest and Angular share similar project and code structures, **Compodoc** works with Nest applications as well.

#### Setup[#](/recipes/documentation#setup)

Setting up Compodoc inside an existing Nest project is very simple. Start by adding the dev-dependency with the following command in your OS terminal:

```bash

$ npm i -D @compodoc/compodoc
```

#### Generation[#](/recipes/documentation#generation)

Generate project documentation using the following command (npm 6 is required for `npx` support). See [the official documentation](https://compodoc.app/guides/usage.html) for more options.

```bash

$ npx @compodoc/compodoc -p tsconfig.json -s
```

Open your browser and navigate to <http://localhost:8080>. You should see an initial Nest CLI project:

#### Contribute[#](/recipes/documentation#contribute)

You can participate and contribute to the Compodoc project [here](https://github.com/compodoc/compodoc).

----
url: https://docs.nestjs.com/v7/graphql/directives
----

* [Directives](https://docs.nestjs.com/v7/graphql/directives#directives)
* [Custom directives](https://docs.nestjs.com/v7/graphql/directives#custom-directives)
* [Code first](https://docs.nestjs.com/v7/graphql/directives#code-first)
* [Schema first](https://docs.nestjs.com/v7/graphql/directives#schema-first)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/directives.md "Suggest Edits")

To create a custom schema directive, declare a class which extends the `SchemaDirectiveVisitor` class exported from the `apollo-server` package.

```typescript

import { SchemaDirectiveVisitor } from 'apollo-server';
import { defaultFieldResolver, GraphQLField } from 'graphql';

export class UpperCaseDirective extends SchemaDirectiveVisitor {
  visitFieldDefinition(field: GraphQLField<any, any>) {
    const { resolve = defaultFieldResolver } = field;
    field.resolve = async function(...args) {
      const result = await resolve.apply(this, args);
      if (typeof result === 'string') {
        return result.toUpperCase();
      }
      return result;
    };
  }
}
```

> **Hint** Note that directives cannot be decorated with the `@Injectable()` decorator. Thus, they are not able to inject dependencies.

Now, register the `UpperCaseDirective` in the `GraphQLModule.forRoot()` method:

```typescript

GraphQLModule.forRoot({
  // ...
  schemaDirectives: {
    upper: UpperCaseDirective,
  },
});
```

Once registered, the `@upper` directive can be used in our schema. However, the way you apply the directive will vary depending on the approach you use (code first or schema first).

#### Code first[#](/graphql/directives#code-first)

In the code first approach, use the `@Directive()` decorator to apply the directive.

```typescript

@Directive('@upper')
@Field()
title: string;
```

> **Hint** The `@Directive()` decorator is exported from the `@nestjs/graphql` package.

Directives can be applied on fields, field resolvers, input and object types, as well as queries, mutations, and subscriptions. Here's an example of the directive applied on the query handler level:

```typescript

@Directive('@deprecated(reason: "This query will be removed in the next version")')
@Query(returns => Author, { name: 'author' })
async getAuthor(@Args({ name: 'id', type: () => Int }) id: number) {
  return this.authorsService.findOneById(id);
}
```

Directives applied through the `@Directive()` decorator will not be reflected in the generated schema definition file.

#### Schema first[#](/graphql/directives#schema-first)

In the schema first approach, apply directives directly in SDL.

```graphql

directive @upper on FIELD_DEFINITION

type Post {
  id: Int!
  title: String! @upper
  votes: Int
}
```

----
url: https://docs.nestjs.com/v5/middleware
----

### Middleware

The middleware is a function which is called **before** the route handler. Middleware functions have access to the [request](http://expressjs.com/en/4x/api.html#req) and [response](http://expressjs.com/en/4x/api.html#res) objects, and the `next` middleware function in the application’s request-response cycle. The **next** middleware function is commonly denoted by a variable named `next`.

The Nest middleware, by default, are equal to [express](http://expressjs.com/en/guide/using-middleware.html) middleware. Here's a great list of the middleware capabilities copied from the official express documentation:

> Middleware functions can perform the following tasks:
>
> * execute any code.
> * make changes to the request and the response objects.
> * end the request-response cycle.
> * call the next middleware function in the stack.
> * if the current middleware function does not end the request-response cycle, it must call `next()` to pass control to the next middleware function. Otherwise, the request will be left hanging.

The Nest middleware is either a function, or a class with an `@Injectable()` decorator. The class should implement the `NestMiddleware` interface, while function does not have any special requirements. Let's start from the `LoggerMiddleware` example.

logger.middleware.ts

JS TS

TypeScript

```typescript

import { Injectable, NestMiddleware, MiddlewareFunction } from '@nestjs/common';

@Injectable()
export class LoggerMiddleware implements NestMiddleware {
  resolve(...args: any[]): MiddlewareFunction {
    return (req, res, next) => {
      console.log('Request...');
      next();
    };
  }
}
```

TypeScript

```typescript

import { Injectable } from '@nestjs/common';

@Injectable()
export class LoggerMiddleware {
  resolve(...args) {
    return (req, res, next) => {
      console.log('Request...');
      next();
    };
  }
}
```

The `resolve()` method has to return a regular library-specific middleware `(req, res, next) => any`.

#### Dependency injection

There is no exception when it comes to the middleware. Same as providers and controllers, they are able to **inject dependencies&#x20;**&#x74;hat belongs to the same module (through the `constructor`).

#### Applying middleware

There is no place for middleware in the `@Module()` decorator. We have to set them up using the `configure()` method of the module class. Modules that include middleware have to implement the `NestModule` interface. Let's set up the `LoggerMiddleware` at the `ApplicationModule` level.

app.module.ts

JS TS

TypeScript

```typescript

import { Module, NestModule, MiddlewareConsumer } from '@nestjs/common';
import { LoggerMiddleware } from './common/middlewares/logger.middleware';
import { CatsModule } from './cats/cats.module';

@Module({
  imports: [CatsModule],
})
export class ApplicationModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer
      .apply(LoggerMiddleware)
      .forRoutes('cats');
  }
}
```

TypeScript

```typescript

import { Module } from '@nestjs/common';
import { LoggerMiddleware } from './common/middlewares/logger.middleware';
import { CatsModule } from './cats/cats.module';

@Module({
  imports: [CatsModule],
})
export class ApplicationModule {
  configure(consumer) {
    consumer
      .apply(LoggerMiddleware)
      .forRoutes('cats');
  }
}
```

In the above example we have set up the `LoggerMiddleware` for `/cats` route handlers that we have previously defined inside the `CatsController`. Besides, we may restrict a middleware to the particular request method.

app.module.ts

JS TS

TypeScript

```typescript

import { Module, NestModule, RequestMethod, MiddlewareConsumer } from '@nestjs/common';
import { LoggerMiddleware } from './common/middlewares/logger.middleware';
import { CatsModule } from './cats/cats.module';

@Module({
  imports: [CatsModule],
})
export class ApplicationModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer
      .apply(LoggerMiddleware)
      .forRoutes({ path: 'cats', method: RequestMethod.GET });
  }
}
```

TypeScript

```typescript

import { Module, RequestMethod } from '@nestjs/common';
import { LoggerMiddleware } from './common/middlewares/logger.middleware';
import { CatsModule } from './cats/cats.module';

@Module({
  imports: [CatsModule],
})
export class ApplicationModule {
  configure(consumer) {
    consumer
      .apply(LoggerMiddleware)
      .forRoutes({ path: 'cats', method: RequestMethod.GET });
  }
}
```

#### Route wildcards

Pattern based routes are supported as well. For instance, the asterisk is used as a **wildcard**, and will match any combination of characters.

TypeScript

```typescript

forRoutes({ path: 'ab*cd', method: RequestMethod.ALL })
```

Above route path will match `abcd`, `ab_cd`, `abecd`, and so on. The characters `?`, `+`, `*`, and `()` are subsets of their regular expression counterparts. The hyphen ( `-`) and the dot (`.`) are interpreted literally by string-based paths.

#### Middleware consumer

The `MiddlewareConsumer` is a helper class. It provides several built-in methods to manage middleware. All of them can be simply **chained**. The `forRoutes()` can take a single string, multiple strings, `RouteInfo` object, a controller class and even multiple controller classes. In most cases you'll probably just pass the **controllers** and separate them by a comma. Below is an example with a single controller:

app.module.ts

JS TS

TypeScript

```typescript

import { Module, NestModule, MiddlewareConsumer } from '@nestjs/common';
import { LoggerMiddleware } from './common/middlewares/logger.middleware';
import { CatsModule } from './cats/cats.module';

@Module({
  imports: [CatsModule],
})
export class ApplicationModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer
      .apply(LoggerMiddleware)
      .forRoutes(CatsController);
  }
}
```

TypeScript

```typescript

import { Module } from '@nestjs/common';
import { LoggerMiddleware } from './common/middlewares/logger.middleware';
import { CatsModule } from './cats/cats.module';

@Module({
  imports: [CatsModule],
})
export class ApplicationModule {
  configure(consumer) {
    consumer
      .apply(LoggerMiddleware)
      .forRoutes(CatsController);
  }
}
```

> **Hint** The `apply()` method may either take a single middleware, or an **array of middleware**.

Whilst class is used, quite often we might want to **exclude** certain routes. That is very intuitive due to the `exclude()` method.

app.module.ts

JS TS

TypeScript

```typescript

import { Module, NestModule, RequestMethod, MiddlewareConsumer } from '@nestjs/common';
import { LoggerMiddleware } from './common/middlewares/logger.middleware';
import { CatsModule } from './cats/cats.module';

@Module({
  imports: [CatsModule],
})
export class ApplicationModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer
      .apply(LoggerMiddleware)
      .exclude(
        { path: 'cats', method: RequestMethod.GET },
        { path: 'cats', method: RequestMethod.POST },
      )
      .forRoutes(CatsController);
  }
}
```

TypeScript

```typescript

import { Module, RequestMethod } from '@nestjs/common';
import { LoggerMiddleware } from './common/middlewares/logger.middleware';
import { CatsModule } from './cats/cats.module';

@Module({
  imports: [CatsModule],
})
export class ApplicationModule {
  configure(consumer) {
    consumer
      .apply(LoggerMiddleware)
      .exclude(
        { path: 'cats', method: RequestMethod.GET },
        { path: 'cats', method: RequestMethod.POST },
      )
      .forRoutes(CatsController);
  }
}
```

Consequently, `LoggerMiddleware` will be bounded to all routes defined inside `CatsController` except these two passed to the `exclude()` function. Please note that `exclude()` method **won't work&#x20;**&#x77;ith your functional middleware. In addition, this function doesn't exclude paths from more generic routes (e.g. wildcards). In such case, you should rather put your paths-restriction logic directly to the middleware and, for example, compare a request's URL.

#### Configurable middleware

Sometimes the behaviour of the middleware depends on the custom values e.g. an array of user roles, options object, and so on. We may apply additional arguments to the `resolve()` using the `with()` method. See an example below:

app.module.ts

JS TS

TypeScript

```typescript

import { Module, NestModule, MiddlewareConsumer } from '@nestjs/common';
import { LoggerMiddleware } from './common/middlewares/logger.middleware';
import { CatsModule } from './cats/cats.module';
import { CatsController } from './cats/cats.controller';

@Module({
  imports: [CatsModule],
})
export class ApplicationModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer
      .apply(LoggerMiddleware)
      .with('ApplicationModule')
      .forRoutes(CatsController);
  }
}
```

TypeScript

```typescript

import { Module } from '@nestjs/common';
import { LoggerMiddleware } from './common/middlewares/logger.middleware';
import { CatsModule } from './cats/cats.module';
import { CatsController } from './cats/cats.controller';

@Module({
  imports: [CatsModule],
})
export class ApplicationModule {
  configure(consumer) {
    consumer
      .apply(LoggerMiddleware)
      .with('ApplicationModule')
      .forRoutes(CatsController);
  }
}
```

We have passed a plain string - `ApplicationModule` to the `with()` method. Thereafter, we have to adjust the `resolve()` method of the `LoggerMiddleware`.

logger.middleware.ts

JS TS

TypeScript

```typescript

import { Injectable, NestMiddleware, MiddlewareFunction } from '@nestjs/common';

@Injectable()
export class LoggerMiddleware implements NestMiddleware {
  resolve(name: string): MiddlewareFunction {
    return (req, res, next) => {
      console.log(`[${name}] Request...`); // [ApplicationModule] Request...
      next();
    };
 }
}
```

TypeScript

```typescript

import { Injectable } from '@nestjs/common';

@Injectable()
export class LoggerMiddleware {
  resolve(name) {
    return (req, res, next) => {
      console.log(`[${name}] Request...`); // [ApplicationModule] Request...
      next();
    };
 }
}
```

In this case, the value of the `name` property will be `'ApplicationModule'`.

#### Asynchronous middleware

There are no contraindications that would prevent us from returning the `async` function within the `resolve()` method. Also, it's possible to make the `resolve()` method `async` as well. This common pattern is called **deffered middleware**.

logger.middleware.ts

JS TS

TypeScript

```typescript

import { Injectable, NestMiddleware, MiddlewareFunction } from '@nestjs/common';

@Injectable()
export class LoggerMiddleware implements NestMiddleware {
  async resolve(name: string): Promise<MiddlewareFunction> {
    await someAsyncJob();

    return async (req, res, next) => {
      await someAsyncJob();
      console.log(`[${name}] Request...`); // [ApplicationModule] Request...
      next();
    };
 }
}
```

TypeScript

```typescript

import { Injectable } from '@nestjs/common';

@Injectable()
export class LoggerMiddleware {
  async resolve(name) {
    await someAsyncJob();

    return async (req, res, next) => {
      await someAsyncJob();
      console.log(`[${name}] Request...`); // [ApplicationModule] Request...
      next();
    };
  }
}
```

#### Functional middleware

The `LoggerMiddleware` is quite short. It has no members, no additional methods, no dependencies. Why can't we just use a simple function? It's a good question, cause in fact - we can. This type of the middleware is called **functional middleware&#x20;**. Let's transform the logger into a function.

logger.middleware.ts

JS TS

TypeScript

```typescript

export function logger(req, res, next) {
  console.log(`Request...`);
  next();
};
```

And use it within the `ApplicationModule`:

app.module.ts

JS TS

TypeScript

```typescript

import { Module, NestModule, MiddlewareConsumer } from '@nestjs/common';
import { logger } from './common/middlewares/logger.middleware';
import { CatsModule } from './cats/cats.module';
import { CatsController } from './cats/cats.controller';

@Module({
  imports: [CatsModule],
})
export class ApplicationModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer
      .apply(logger)
      .forRoutes(CatsController);
  }
}
```

TypeScript

```typescript

import { Module } from '@nestjs/common';
import { logger } from './common/middlewares/logger.middleware';
import { CatsModule } from './cats/cats.module';
import { CatsController } from './cats/cats.controller';

@Module({
  imports: [CatsModule],
})
export class ApplicationModule {
  configure(consumer) {
    consumer
      .apply(logger)
      .forRoutes(CatsController);
  }
}
```

> **Hint** Let's consider using **functional middleware** every time when your middleware doesn't need any dependencies.

#### Multiple middleware

As mentioned before, in order to bind multiple middleware that are executed sequentially, we can separate them by a comma inside the `apply()` method.

JS TS

TypeScript

```typescript

export class ApplicationModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer
      .apply(cors(), helmet(), logger)
      .forRoutes(CatsController);
  }
}
```

TypeScript

```typescript

@Module({
  imports: [CatsModule],
})
export class ApplicationModule {
  configure(consumer) {
      consumer
        .apply(cors(), helmet(), logger)
        .forRoutes(CatsController);
    }
  }
```

#### Global middleware

In order to tie a middleware to each registered route at once, we can take advantage of `use()` method that is supplied by the `INestApplication` instance:

TypeScript

```typescript

const app = await NestFactory.create(ApplicationModule);
app.use(logger);
await app.listen(3000);
```

* Middleware
* Dependency injection
* Applying middleware
* Route wildcards
* Middleware consumer
* Configurable middleware
* Asynchronous middleware
* Functional middleware
* Multiple middleware
* Global middleware

----
url: https://docs.nestjs.com/v6/techniques/authentication
----

* [Authentication](https://docs.nestjs.com/v6/techniques/authentication#authentication)
* [Authentication requirements](https://docs.nestjs.com/v6/techniques/authentication#authentication-requirements)
* [Implementing Passport strategies](https://docs.nestjs.com/v6/techniques/authentication#implementing-passport-strategies)
* [Implementing Passport local](https://docs.nestjs.com/v6/techniques/authentication#implementing-passport-local)
* [Built-in Passport Guards](https://docs.nestjs.com/v6/techniques/authentication#built-in-passport-guards)
* [Login route](https://docs.nestjs.com/v6/techniques/authentication#login-route)
* [JWT functionality](https://docs.nestjs.com/v6/techniques/authentication#jwt-functionality)
* [Implementing Passport JWT](https://docs.nestjs.com/v6/techniques/authentication#implementing-passport-jwt)
* [Implement protected route and JWT strategy guards](https://docs.nestjs.com/v6/techniques/authentication#implement-protected-route-and-jwt-strategy-guards)
* [Default strategy](https://docs.nestjs.com/v6/techniques/authentication#default-strategy)
* [Request-scoped strategies](https://docs.nestjs.com/v6/techniques/authentication#request-scoped-strategies)
* [Extending guards](https://docs.nestjs.com/v6/techniques/authentication#extending-guards)
* [Customize Passport](https://docs.nestjs.com/v6/techniques/authentication#customize-passport)
* [Named strategies](https://docs.nestjs.com/v6/techniques/authentication#named-strategies)
* [GraphQL](https://docs.nestjs.com/v6/techniques/authentication#graphql)

[](https://srv.carbonads.net/ads/click/x/GTND4277CVSIC2JEFTBLYKQUF67D62Q7CTSDCZ3JCAAI623WCTADK5QKC67IP277CY7I4K7ICY7I4K3YCEBDK27YHEYI55QLCAYD653ECTNCYBZ52K)[Kubernetes, Proxmox of databases op AMD EPYC 4005-servers, klaar in enkele minuten. Configureer uw server. ](https://srv.carbonads.net/ads/click/x/GTND4277CVSIC2JEFTBLYKQUF67D62Q7CTSDCZ3JCAAI623WCTADK5QKC67IP277CY7I4K7ICY7I4K3YCEBDK27YHEYI55QLCAYD653ECTNCYBZ52K)[ads via Carbon](http://carbonads.net/?utm_source=nestjscom\&utm_medium=ad_via_link\&utm_campaign=in_unit\&utm_term=carbon)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/techniques/authentication.md "Suggest Edits")

### Authentication

Authentication is an **essential** part of most applications. There are many different approaches and strategies to handle authentication. The approach taken for any project depends on its particular application requirements. This chapter presents several approaches to authentication that can be adapted to a variety of different requirements.

[Passport](https://github.com/jaredhanson/passport) is the most popular node.js authentication library, well-known by the community and successfully used in many production applications. It's straightforward to integrate this library with a **Nest** application using the `@nestjs/passport` module. At a high level, Passport executes a series of steps to:

* Authenticate a user by verifying their "credentials" (such as username/password, JSON Web Token ([JWT](https://jwt.io/)), or identity token from an Identity Provider)
* Manage authenticated state (by issuing a portable token, such as a JWT, or creating an [Express session](https://github.com/expressjs/session))
* Attach information about the authenticated user to the `Request` object for further use in route handlers

Passport has a rich ecosystem of [strategies](http://www.passportjs.org/packages/) that implement various authentication mechanisms. While simple in concept, the set of Passport strategies you can choose from is large and presents a lot of variety. Passport abstracts these varied steps into a standard pattern, and the `@nestjs/passport` module wraps and standardizes this pattern into familiar Nest constructs.

In this chapter, we'll implement a complete end-to-end authentication solution for a RESTful API server using these powerful and flexible modules. You can use the concepts described here to implement any Passport strategy to customize your authentication scheme. You can follow the steps in this chapter to build this complete example. You can find a repository with a completed sample app [here](https://github.com/nestjs/nest/tree/master/sample/19-auth-jwt).

#### Authentication requirements[#](/techniques/authentication#authentication-requirements)

Let's flesh out our requirements. For this use case, clients will start by authenticating with a username and password. Once authenticated, the server will issue a JWT that can be sent as a [bearer token in an authorization header](https://tools.ietf.org/html/rfc6750) on subsequent requests to prove authentication. We'll also create a protected route that is accessible only to requests that contain a valid JWT.

We'll start with the first requirement: authenticating a user. We'll then extend that by issuing a JWT. Finally, we'll create a protected route that checks for a valid JWT on the request.

First we need to install the required packages. Passport provides a strategy called [passport-local](https://github.com/jaredhanson/passport-local) that implements a username/password authentication mechanism, which suits our needs for this portion of our use case.

```bash

$ npm install --save @nestjs/passport passport passport-local
$ npm install --save-dev @types/passport-local
```

> **Notice** For **any** Passport strategy you choose, you'll always need the `@nestjs/passport` and `passport` packages. Then, you'll need to install the strategy-specific package (e.g., `passport-jwt` or `passport-local`) that implements the particular authentication strategy you are building. In addition, you can also install the type definitions for any Passport strategy, as show above with `@types/passport-local`, which provides assistance while writing TypeScript code.

#### Implementing Passport strategies[#](/techniques/authentication#implementing-passport-strategies)

We're now ready to implement the authentication feature. We'll start with an overview of the process used for **any** Passport strategy. It's helpful to think of Passport as a mini framework in itself. The elegance of the framework is that it abstracts the authentication process into a few basic steps that you customize based on the strategy you're implementing. It's like a framework because you configure it by supplying customization parameters (as plain JSON objects) and custom code in the form of callback functions, which Passport calls at the appropriate time. The `@nestjs/passport` module wraps this framework in a Nest style package, making it easy to integrate into a Nest application. We'll use `@nestjs/passport` below, but first let's consider how **vanilla Passport** works.

In vanilla Passport, you configure a strategy by providing two things:

1. A set of options that are specific to that strategy. For example, in a JWT strategy, you might provide a secret to sign tokens.
2. A "verify callback", which is where you tell Passport how to interact with your user store (where you manage user accounts). Here, you verify whether a user exists (and/or create a new user), and whether their credentials are valid. The Passport library expects this callback to return a full user if the validation succeeds, or a null if it fails (failure is defined as either the user is not found, or, in the case of passport-local, the password does not match).

With `@nestjs/passport`, you configure a Passport strategy by extending the `PassportStrategy` class. You pass the strategy options (item 1 above) by calling the `super()` method in your subclass, optionally passing in an options object. You provide the verify callback (item 2 above) by implementing a `validate()` method in your subclass.

We'll start by generating an `AuthModule` and in it, an `AuthService`:

```bash

$ nest g module auth
$ nest g service auth
```

As we implement the `AuthService`, we'll find it useful to encapsulate user operations in a `UsersService`, so let's generate that module and service now:

```bash

$ nest g module users
$ nest g service users
```

Replace the default contents of these generated files as shown below. For our sample app, the `UsersService` simply maintains a hard-coded in-memory list of users, and a find method to retrieve one by username. In a real app, this is where you'd build your user model and persistence layer, using your library of choice (e.g., TypeORM, Sequelize, Mongoose, etc.).

users/users.service.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';

export type User = any;

@Injectable()
export class UsersService {
  private readonly users: User[];

  constructor() {
    this.users = [
      {
        userId: 1,
        username: 'john',
        password: 'changeme',
      },
      {
        userId: 2,
        username: 'chris',
        password: 'secret',
      },
      {
        userId: 3,
        username: 'maria',
        password: 'guess',
      },
    ];
  }

  async findOne(username: string): Promise<User | undefined> {
    return this.users.find(user => user.username === username);
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';

@Injectable()
export class UsersService {
  constructor() {
    this.users = [
      {
        userId: 1,
        username: 'john',
        password: 'changeme',
      },
      {
        userId: 2,
        username: 'chris',
        password: 'secret',
      },
      {
        userId: 3,
        username: 'maria',
        password: 'guess',
      },
    ];
  }

  async findOne(username) {
    return this.users.find(user => user.username === username);
  }
}
```

In the `UsersModule`, the only change needed is to add the `UsersService` to the exports array of the `@Module` decorator so that it is visible outside this module (we'll soon use it in our `AuthService`).

users/users.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { UsersService } from './users.service';

@Module({
  providers: [UsersService],
  exports: [UsersService],
})
export class UsersModule {}
```

```typescript

import { Module } from '@nestjs/common';
import { UsersService } from './users.service';

@Module({
  providers: [UsersService],
  exports: [UsersService],
})
export class UsersModule {}
```

Our `AuthService` has the job of retrieving a user and verifying the password. We create a `validateUser()` method for this purpose. In the code below, we use a convenient ES6 spread operator to strip the password property from the user object before returning it. We'll be calling into the `validateUser()` method from our Passport local strategy in a moment.

auth/auth.service.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { UsersService } from '../users/users.service';

@Injectable()
export class AuthService {
  constructor(private readonly usersService: UsersService) {}

  async validateUser(username: string, pass: string): Promise<any> {
    const user = await this.usersService.findOne(username);
    if (user && user.password === pass) {
      const { password, ...result } = user;
      return result;
    }
    return null;
  }
}
```

```typescript

import { Injectable, Dependencies } from '@nestjs/common';
import { UsersService } from '../users/users.service';

@Injectable()
@Dependencies(UsersService)
export class AuthService {
  constructor(usersService) {
    this.usersService = usersService;
  }

  async validateUser(username, pass) {
    const user = await this.usersService.findOne(username);
    if (user && user.password === pass) {
      const { password, ...result } = user;
      return result;
    }
    return null;
  }
}
```

> **Warning** Of course in a real application, you wouldn't store a password in plain text. You'd instead use a library like [bcrypt](https://github.com/kelektiv/node.bcrypt.js#readme), with a salted one-way hash algorithm. With that approach, you'd only store hashed passwords, and then compare the stored password to a hashed version of the **incoming** password, thus never storing or exposing user passwords in plain text. To keep our sample app simple, we violate that absolute mandate and use plain text. **Don't do this in your real app!**

Now, we update our `AuthModule` to import the `UsersModule`.

auth/auth.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { UsersModule } from '../users/users.module';

@Module({
  imports: [UsersModule],
  providers: [AuthService],
})
export class AuthModule {}
```

```typescript

import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { UsersModule } from '../users/users.module';

@Module({
  imports: [UsersModule],
  providers: [AuthService],
})
export class AuthModule {}
```

#### Implementing Passport local[#](/techniques/authentication#implementing-passport-local)

Now we can implement our Passport **local authentication strategy**. Create a file called `local.strategy.ts` in the `auth` folder, and add the following code:

auth/local.strategy.ts

JS TS

```typescript

import { Strategy } from 'passport-local';
import { PassportStrategy } from '@nestjs/passport';
import { Injectable, UnauthorizedException } from '@nestjs/common';
import { AuthService } from './auth.service';

@Injectable()
export class LocalStrategy extends PassportStrategy(Strategy) {
  constructor(private readonly authService: AuthService) {
    super();
  }

  async validate(username: string, password: string): Promise<any> {
    const user = await this.authService.validateUser(username, password);
    if (!user) {
      throw new UnauthorizedException();
    }
    return user;
  }
}
```

```typescript

import { Strategy } from 'passport-local';
import { PassportStrategy } from '@nestjs/passport';
import { Injectable, UnauthorizedException, Dependencies } from '@nestjs/common';
import { AuthService } from './auth.service';

@Injectable()
@Dependencies(AuthService)
export class LocalStrategy extends PassportStrategy(Strategy) {
  constructor(authService) {
    this.authService = authService
    super();
  }

  async validate(username, password) {
    const user = await this.authService.validateUser(username, password);
    if (!user) {
      throw new UnauthorizedException();
    }
    return user;
  }
}
```

We've followed the recipe described earlier for all Passport strategies. In our use case with passport-local, there are no configuration options, so our constructor simply calls `super()`, without an options object.

We've also implemented the `validate()` method. For each strategy, Passport will call the verify function (implemented with the `validate()` method in `@nestjs/passport`) using an appropriate strategy-specific set of parameters. For the local-strategy, Passport expects a `validate()` method with the following signature: `validate(username: string, password:string): any`.

Most of the validation work is done in our `AuthService` (with the help of our `UserService`), so this method is quite straightforward. The `validate()` method for **any** Passport strategy will follow a similar pattern, varying only in the details of how credentials are represented. If a user is found and the credentials are valid, the user is returned so Passport can complete its tasks (e.g., creating the `user` property on the `Request` object), and the request handling pipeline can continue. If it's not found, we throw an exception and let our [exceptions layer](exception-filters) handle it.

Typically, the only significant difference in the `validate()` method for each strategy is **how** you determine if a user exists and is valid. For example, in a JWT strategy, depending on requirements, we may evaluate whether the `userId` carried in the decoded token matches a record in our user database, or matches a list of revoked tokens. Hence, this pattern of sub-classing and implementing strategy-specific validation is consistent, elegant and extensible.

We need to configure our `AuthModule` to use the Passport features we just defined. Update `auth.module.ts` to look like this:

auth/auth.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { UsersModule } from '../users/users.module';
import { PassportModule } from '@nestjs/passport';
import { LocalStrategy } from './local.strategy';

@Module({
  imports: [UsersModule, PassportModule],
  providers: [AuthService, LocalStrategy],
})
export class AuthModule {}
```

```typescript

import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { UsersModule } from '../users/users.module';
import { PassportModule } from '@nestjs/passport';
import { LocalStrategy } from './local.strategy';

@Module({
  imports: [UsersModule, PassportModule],
  providers: [AuthService, LocalStrategy],
})
export class AuthModule {}
```

#### Built-in Passport Guards[#](/techniques/authentication#built-in-passport-guards)

* 60+ chapters
* 4+ hours of videos
* Official certificate
* Deep-dive sessions

[Explore official courses](https://courses.nestjs.com "Courses | NestJS - A node.js framework built on top of TypeScript")

#### Login route[#](/techniques/authentication#login-route)

With the strategy in place, we can now implement a bare-bones `/auth/login` route, and apply the built-in Guard to initiate the passport-local flow.

Open the `app.controller.ts` file and replace its contents with the following:

app.controller.ts

JS TS

```typescript

import { Controller, Request, Post, UseGuards } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';

@Controller()
export class AppController {
  @UseGuards(AuthGuard('local'))
  @Post('auth/login')
  async login(@Request() req) {
    return req.user;
  }
}
```

```typescript

import { Controller, Bind, Request, Post, UseGuards } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';

@Controller()
export class AppController {
  @UseGuards(AuthGuard('local'))
  @Post('auth/login')
  @Bind(Req())
  async login(req) {
    return req.user;
  }
}
```

With `@UseGuards(AuthGuard('local'))` we are using an `AuthGuard` that `@nestjs/passport`**automatically provisioned** for us when we extended the passport-local strategy. Let's break that down. Our Passport local strategy has a default name of `'local'`. We reference that name in the `@UseGuards()` decorator to associate it with code supplied by the `passport-local` package. This is used to disambiguate which strategy to invoke in case we have multiple Passport strategies in our app (each of which may provision a strategy-specific `AuthGuard`). While we only have one such strategy so far, we'll shortly add a second, so this is needed for disambiguation.

In order to test our route we'll have our `/auth/login` route simply return the user for now. This also lets us demonstrate another Passport feature: Passport automatically creates a `user` object, based on the value we return from the `validate()` method, and assigns it to the `Request` object as `req.user`. Later, we'll replace this with code to create and return a JWT instead.

Since these are API routes, we'll test them using the commonly available [cURL](https://curl.haxx.se/) library. You can test with any of the `user` objects hard-coded in the `UsersService`.

```bash

$ # POST to /auth/login
$ curl -X POST http://localhost:3000/auth/login -d '{"username": "john", "password": "changeme"}' -H "Content-Type: application/json"
$ # result -> {"userId":1,"username":"john"}
```

While this works, passing the strategy name directly to the `AuthGuard()` introduces magic strings in the codebase. Instead, we recommend creating your own class, as shown below:

auth/local-auth.guard.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';

@Injectable()
export class LocalAuthGuard extends AuthGuard('local') {}
```

Now, we can update the `/auth/login` route handler and use the `LocalAuthGuard` instead:

```typescript

@UseGuards(LocalAuthGuard)
@Post('auth/login')
async login(@Request() req) {
  return req.user;
}
```

#### JWT functionality[#](/techniques/authentication#jwt-functionality)

We're ready to move on to the JWT portion of our auth system. Let's review and refine our requirements:

* Allow users to authenticate with username/password, returning a JWT for use in subsequent calls to protected API endpoints. We're well on our way to meeting this requirement. To complete it, we'll need to write the code that issues a JWT.
* Create API routes which are protected based on the presence of a valid JWT as a bearer token

We'll need to install a couple more packages to support our JWT requirements:

```bash

$ npm install @nestjs/jwt passport-jwt
$ npm install @types/passport-jwt --save-dev
```

```typescript

import { Injectable } from '@nestjs/common';
import { UsersService } from '../users/users.service';
import { JwtService } from '@nestjs/jwt';

@Injectable()
export class AuthService {
  constructor(
    private readonly usersService: UsersService,
    private readonly jwtService: JwtService
  ) {}

  async validateUser(username: string, pass: string): Promise<any> {
    const user = await this.usersService.findOne(username);
    if (user && user.password === pass) {
      const { password, ...result } = user;
      return result;
    }
    return null;
  }

  async login(user: any) {
    const payload = { username: user.username, sub: user.userId };
    return {
      access_token: this.jwtService.sign(payload),
    };
  }
}
```

```typescript

import { Injectable, Dependencies } from '@nestjs/common';
import { UsersService } from '../users/users.service';
import { JwtService } from '@nestjs/jwt';

@Dependencies(UsersService, JwtService)
@Injectable()
export class AuthService {
  constructor(usersService, jwtService)
  ) {
    this.usersService = usersService;
    this.jwtService = jwtService;
  }

  async validateUser(username, pass) {
    const user = await this.usersService.findOne(username);
    if (user && user.password === pass) {
      const { password, ...result } = user;
      return result;
    }
    return null;
  }

  async login(user) {
    const payload = { username: user.username, sub: user.userId };
    return {
      access_token: this.jwtService.sign(payload),
    };
  }
}
```

We're using the `@nestjs/jwt` library, which supplies a `sign()` function to generate our JWT from a subset of the `user` object properties, which we then return as a simple object with a single `access_token` property. Note: we choose a property name of `sub` to hold our `userId` value to be consistent with JWT standards. Don't forget to inject the JwtService provider into the `AuthService`.

We now need to update the `AuthModule` to import the new dependencies and configure the `JwtModule`.

First, create `constants.ts` in the `auth` folder, and add the following code:

auth/constants.ts

JS TS

```typescript

export const jwtConstants = {
  secret: 'secretKey',
};
```

```typescript

export const jwtConstants = {
  secret: 'secretKey',
};
```

We'll use this to share our key between the JWT signing and verifying steps.

> **Warning****Do not expose this key publicly**. We have done so here to make it clear what the code is doing, but in a production system **you must protect this key** using appropriate measures such as a secrets vault, environment variable, or configuration service.

Now, open `auth.module.ts` in the `auth` folder and update it to look like this:

auth/auth.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { LocalStrategy } from './local.strategy';
import { UsersModule } from '../users/users.module';
import { PassportModule } from '@nestjs/passport';
import { JwtModule } from '@nestjs/jwt';
import { jwtConstants } from './constants';

@Module({
  imports: [
    UsersModule,
    PassportModule,
    JwtModule.register({
      secret: jwtConstants.secret,
      signOptions: { expiresIn: '60s' },
    }),
  ],
  providers: [AuthService, LocalStrategy],
  exports: [AuthService],
})
export class AuthModule {}
```

```typescript

import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { LocalStrategy } from './local.strategy';
import { UsersModule } from '../users/users.module';
import { PassportModule } from '@nestjs/passport';
import { JwtModule } from '@nestjs/jwt';
import { jwtConstants } from './constants';

@Module({
  imports: [
    UsersModule,
    PassportModule,
    JwtModule.register({
      secret: jwtConstants.secret,
      signOptions: { expiresIn: '60s' },
    }),
  ],
  providers: [AuthService, LocalStrategy],
  exports: [AuthService],
})
export class AuthModule {}
```

We configure the `JwtModule` using `register()`, passing in a configuration object. See [here](https://github.com/nestjs/jwt/blob/master/README.md) for more on the Nest `JwtModule` and [here](https://github.com/auth0/node-jsonwebtoken#usage) for more details on the available configuration options.

Now we can update the `/auth/login` route to return a JWT.

app.controller.ts

JS TS

```typescript

import { Controller, Request, Post, UseGuards } from '@nestjs/common';
import { LocalAuthGuard } from './auth/local-auth.guard';
import { AuthService } from './auth/auth.service';

@Controller()
export class AppController {
  constructor(private readonly authService: AuthService) {}

  @UseGuards(LocalAuthGuard)
  @Post('auth/login')
  async login(@Request() req) {
    return this.authService.login(req.user);
  }
}
```

```typescript

import { Controller, Bind, Request, Post, UseGuards } from '@nestjs/common';
import { LocalAuthGuard } from './auth/local-auth.guard';
import { AuthService } from './auth/auth.service';

@Controller()
export class AppController {
  constructor(private readonly authService: AuthService) {}

  @UseGuards(LocalAuthGuard)
  @Post('auth/login')
  @Bind(Req())
  async login(req) {
    return this.authService.login(req.user);
  }
}
```

Let's go ahead and test our routes using cURL again. You can test with any of the `user` objects hard-coded in the `UsersService`.

```bash

$ # POST to /auth/login
$ curl -X POST http://localhost:3000/auth/login -d '{"username": "john", "password": "changeme"}' -H "Content-Type: application/json"
$ # result -> {"access_token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."}
$ # Note: above JWT truncated
```

#### Implementing Passport JWT[#](/techniques/authentication#implementing-passport-jwt)

We can now address our final requirement: protecting endpoints by requiring a valid JWT be present on the request. Passport can help us here too. It provides the [passport-jwt](https://github.com/mikenicholson/passport-jwt) strategy for securing RESTful endpoints with JSON Web Tokens. Start by creating a file called `jwt.strategy.ts` in the `auth` folder, and add the following code:

auth/jwt.strategy.ts

JS TS

```typescript

import { ExtractJwt, Strategy } from 'passport-jwt';
import { PassportStrategy } from '@nestjs/passport';
import { Injectable } from '@nestjs/common';
import { jwtConstants } from './constants';

@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
  constructor() {
    super({
      jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
      ignoreExpiration: false,
      secretOrKey: jwtConstants.secret,
    });
  }

  async validate(payload: any) {
    return { userId: payload.sub, username: payload.username };
  }
}
```

```typescript

import { ExtractJwt, Strategy } from 'passport-jwt';
import { PassportStrategy } from '@nestjs/passport';
import { Injectable } from '@nestjs/common';
import { jwtConstants } from './constants';

@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
  constructor() {
    super({
      jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
      ignoreExpiration: false,
      secretOrKey: jwtConstants.secret,
    });
  }

  async validate(payload) {
    return { userId: payload.sub, username: payload.username };
  }
}
```

```typescript

import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { LocalStrategy } from './local.strategy';
import { JwtStrategy } from './jwt.strategy';
import { UsersModule } from '../users/users.module';
import { PassportModule } from '@nestjs/passport';
import { JwtModule } from '@nestjs/jwt';
import { jwtConstants } from './constants';

@Module({
  imports: [
    UsersModule,
    PassportModule,
    JwtModule.register({
      secret: jwtConstants.secret,
      signOptions: { expiresIn: '60s' },
    }),
  ],
  providers: [AuthService, LocalStrategy, JwtStrategy],
  exports: [AuthService],
})
export class AuthModule {}
```

```typescript

import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { LocalStrategy } from './local.strategy';
import { JwtStrategy } from './jwt.strategy';
import { UsersModule } from '../users/users.module';
import { PassportModule } from '@nestjs/passport';
import { JwtModule } from '@nestjs/jwt';
import { jwtConstants } from './constants';

@Module({
  imports: [
    UsersModule,
    PassportModule,
    JwtModule.register({
      secret: jwtConstants.secret,
      signOptions: { expiresIn: '60s' },
    }),
  ],
  providers: [AuthService, LocalStrategy, JwtStrategy],
  exports: [AuthService],
})
export class AuthModule {}
```

By importing the same secret used when we signed the JWT, we ensure that the **verify** phase performed by Passport, and the **sign** phase performed in our AuthService, use a common secret.

Finally, we define the `JwtAuthGuard` class which extends the built-in `AuthGuard`:

auth/jwt-auth.guard.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';

@Injectable()
export class JwtAuthGuard extends AuthGuard('jwt') {}
```

#### Implement protected route and JWT strategy guards[#](/techniques/authentication#implement-protected-route-and-jwt-strategy-guards)

We can now implement our protected route and its associated Guard.

Open the `app.controller.ts` file and update it as shown below:

app.controller.ts

JS TS

```typescript

import { Controller, Get, Request, Post, UseGuards } from '@nestjs/common';
import { JwtAuthGuard } from './auth/jwt-auth.guard';
import { LocalAuthGuard } from './auth/local-auth.guard';
import { AuthService } from './auth/auth.service';

@Controller()
export class AppController {
  constructor(private readonly authService: AuthService) {}

  @UseGuards(LocalAuthGuard)
  @Post('auth/login')
  async login(@Request() req) {
    return this.authService.login(req.user);
  }

  @UseGuards(JwtAuthGuard)
  @Get('profile')
  getProfile(@Request() req) {
    return req.user;
  }
}
```

```typescript

import { Controller, Bind, Get, Request, Post, UseGuards } from '@nestjs/common';
import { JwtAuthGuard } from './auth/jwt-auth.guard';
import { LocalAuthGuard } from './auth/local-auth.guard';
import { AuthService } from './auth/auth.service';

@Controller()
export class AppController {
  constructor(private readonly authService: AuthService) {}

  @UseGuards(LocalAuthGuard)
  @Post('auth/login')
  @Bind(Req())
  async login(req) {
    return this.authService.login(req.user);
  }

  @UseGuards(JwtAuthGuard)
  @Get('profile')
  @Bind(Req())
  getProfile(req) {
    return req.user;
  }
}
```

Once again, we're applying the `AuthGuard` that the `@nestjs/passport` module has automatically provisioned for us when we configured the passport-jwt module. This Guard is referenced by its default name, `jwt`. When our `GET /profile` route is hit, the Guard will automatically invoke our passport-jwt custom configured logic, validating the JWT, and assigning the `user` property to the `Request` object.

Ensure the app is running, and test the routes using `cURL`.

```bash

$ # GET /profile
$ curl http://localhost:3000/profile
$ # result -> {"statusCode":401,"error":"Unauthorized"}

$ # POST /auth/login
$ curl -X POST http://localhost:3000/auth/login -d '{"username": "john", "password": "changeme"}' -H "Content-Type: application/json"
$ # result -> {"access_token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2Vybm... }

$ # GET /profile using access_token returned from previous step as bearer code
$ curl http://localhost:3000/profile -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2Vybm..."
$ # result -> {"userId":1,"username":"john"}
```

Note that in the `AuthModule`, we configured the JWT to have an expiration of `60 seconds`. This is probably too short an expiration, and dealing with the details of token expiration and refresh is beyond the scope of this article. However, we chose that to demonstrate an important quality of JWTs and the passport-jwt strategy. If you wait 60 seconds after authenticating before attempting a `GET /profile` request, you'll receive a `401 Unauthorized` response. This is because Passport automatically checks the JWT for its expiration time, saving you the trouble of doing so in your application.

We've now completed our JWT authentication implementation. JavaScript clients (such as Angular/React/Vue), and other JavaScript apps, can now authenticate and communicate securely with our API Server. You can find a complete version of the code in this chapter [here](/v6/).

## Official enterprise support

* Providing technical guidance
* Performing in-depth code reviews
* Mentoring team members
* Advising best practices

[Explore more](https://enterprise.nestjs.com "Enterprise | NestJS - A progressive Node.js framework")

#### Default strategy[#](/techniques/authentication#default-strategy)

In our `AppController`, we pass the name of the strategy in the `@AuthGuard()` decorator. We need to do this because we've introduced **two** Passport strategies (passport-local and passport-jwt), both of which supply implementations of various Passport components. Passing the name disambiguates which implementation we're linking to. When multiple strategies are included in an application, we can declare a default strategy so that we no longer have to pass the name in the `@AuthGuard` decorator if using that default strategy. Here's how to register a default strategy when importing the `PassportModule`. This code would go in the `AuthModule`:

```typescript

import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { LocalStrategy } from './local.strategy';
import { UsersModule } from '../users/users.module';
import { PassportModule } from '@nestjs/passport';
import { JwtModule } from '@nestjs/jwt';
import { jwtConstants } from './constants';
import { JwtStrategy } from './jwt.strategy';

@Module({
  imports: [
    PassportModule.register({ defaultStrategy: 'jwt' }),
    JwtModule.register({
      secret: jwtConstants.secret,
      signOptions: { expiresIn: '60s' },
    }),
    UsersModule,
  ],
  providers: [AuthService, LocalStrategy, JwtStrategy],
  exports: [AuthService],
})
export class AuthModule {}
```

#### Request-scoped strategies[#](/techniques/authentication#request-scoped-strategies)

The passport API is based on registering strategies to the global instance of the library. Therefore strategies are not designed to have request-dependent options or to be dynamically instantiated per request (read more about the [request-scoped](/v6/fundamentals/injection-scopes) providers). When you configure your strategy to be request-scoped, Nest will never instantiate it since it's not tied to any specific route. There is no physical way to determine which "request-scoped" strategies should be executed per request.

However, there are ways to dynamically resolve request-scoped providers within the strategy. For this, we leverage the [module reference](/v6/fundamentals/module-ref) feature.

First, open the `local.strategy.ts` file and inject the `ModuleRef` in the normal way:

```typescript

constructor(private readonly moduleRef: ModuleRef) {
  super({
    passReqToCallback: true,
  });
}
```

> **Hint** The `ModuleRef` class is imported from the `@nestjs/core` package.

Be sure to set the `passReqToCallback` configuration property to `true`, as shown above.

In the next step, the request instance will be used to obtain the current context identifier, instead of generating a new one (read more about request context [here](/fundamentals/module-ref#getting-current-sub-tree)).

Now, inside the `validate()` method of the `LocalStrategy` class, use the `getByRequest()` method of the `ContextIdFactory` class to create a context id based on the request object, and pass this to the `resolve()` call:

```typescript

async validate(
  request: Request,
  username: string,
  password: string,
) {
  const contextId = ContextIdFactory.getByRequest(request);
  // "AuthService" is a request-scoped provider
  const authService = await this.moduleRef.resolve(AuthService, contextId);
  ...
}
```

In the example above, the `resolve()` method will asynchronously return the request-scoped instance of the `AuthService` provider (we assumed that `AuthService` is marked as a request-scoped provider).

#### Extending guards[#](/techniques/authentication#extending-guards)

In most cases, using a provided `AuthGuard` class is sufficient. However, there might be use-cases when you would like to simply extend the default error handling or authentication logic. For this, you can extend the built-in class and override methods within a sub-class.

```typescript

import {
  ExecutionContext,
  Injectable,
  UnauthorizedException,
} from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';

@Injectable()
export class JwtAuthGuard extends AuthGuard('jwt') {
  canActivate(context: ExecutionContext) {
    // Add your custom authentication logic here
    // for example, call super.logIn(request) to establish a session.
    return super.canActivate(context);
  }

  handleRequest(err, user, info) {
    // You can throw an exception based on either "info" or "err" arguments
    if (err || !user) {
      throw err || new UnauthorizedException();
    }
    return user;
  }
}
```

#### Customize Passport[#](/techniques/authentication#customize-passport)

Any standard Passport customization options can be passed the same way, using the `register()` method. The available options depend on the strategy being implemented. For example:

```typescript

PassportModule.register({ session: true });
```

You can also pass strategies an options object in their constructors to configure them. For the local strategy you can pass e.g.:

```typescript

constructor(private readonly authService: AuthService) {
  super({
    usernameField: 'email',
    passwordField: 'password',
  });
}
```

Take a look at the official [Passport Website](http://www.passportjs.org/docs/oauth/) for property names.

#### Named strategies[#](/techniques/authentication#named-strategies)

When implementing a strategy, you can provide a name for it by passing a second argument to the `PassportStrategy` function. If you don't do this, each strategy will have a default name (e.g., 'jwt' for jwt-strategy):

```typescript

export class JwtStrategy extends PassportStrategy(Strategy, 'myjwt')
```

Then, you refer to this via a decorator like `@AuthGuard('myjwt')`.

#### GraphQL[#](/techniques/authentication#graphql)

In order to use an AuthGuard with [GraphQL](https://docs.nestjs.com/graphql/quick-start), extend the built-in AuthGuard class and override the getRequest() method.

```typescript

@Injectable()
export class GqlAuthGuard extends AuthGuard('jwt') {
  getRequest(context: ExecutionContext) {
    const ctx = GqlExecutionContext.create(context);
    return ctx.getContext().req;
  }
}
```

To use the above construct, be sure to pass the request (`req`) object as part of the context value in the GraphQL Module settings:

```typescript

GraphQLModule.forRoot({
  context: ({ req }) => ({ req }),
});
```

To get the current authenticated user in your graphql resolver, you can define a User decorator:

```typescript

import { createParamDecorator } from '@nestjs/common';

export const CurrentUser = createParamDecorator(
  (data, [root, args, ctx, info]) => ctx.req.user,
);
```

To use above decorator in your resolver, be sure to include it as a parameter of your query or mutation:

```typescript

@Query(returns => User)
@UseGuards(GqlAuthGuard)
whoAmI(@CurrentUser() user: User) {
  return this.userService.findById(user.id);
}
```

----
url: https://docs.nestjs.com/fundamentals/custom-providers
----

[Skip to content](#content)

On this page

* [Custom providers](https://docs.nestjs.com/fundamentals/custom-providers#custom-providers)
* [DI fundamentals](https://docs.nestjs.com/fundamentals/custom-providers#di-fundamentals)
* [Standard providers](https://docs.nestjs.com/fundamentals/custom-providers#standard-providers)
* [Custom providers](https://docs.nestjs.com/fundamentals/custom-providers#custom-providers-1)
* [Value providers: useValue](https://docs.nestjs.com/fundamentals/custom-providers#value-providers-usevalue)
* [Non-class-based provider tokens](https://docs.nestjs.com/fundamentals/custom-providers#non-class-based-provider-tokens)
* [Interfaces and abstract classes](https://docs.nestjs.com/fundamentals/custom-providers#interfaces-and-abstract-classes)
* [Class providers: useClass](https://docs.nestjs.com/fundamentals/custom-providers#class-providers-useclass)
* [Factory providers: useFactory](https://docs.nestjs.com/fundamentals/custom-providers#factory-providers-usefactory)
* [Alias providers: useExisting](https://docs.nestjs.com/fundamentals/custom-providers#alias-providers-useexisting)
* [Non-service based providers](https://docs.nestjs.com/fundamentals/custom-providers#non-service-based-providers)
* [Export custom provider](https://docs.nestjs.com/fundamentals/custom-providers#export-custom-provider)

[](https://srv.carbonads.net/ads/click/x/GTND4277CVSD5KJUCAYLYKQUF67D62Q7CW7DTZ3JCAAI623WCTBDPK7KF6ADT53YCTSI62JJFTBDE5QWCWYD5KJKC6SILKJUCT7DEK3EHJNCLSIZ)[100% agent accuracy with steering hooks. Learn how. ](https://srv.carbonads.net/ads/click/x/GTND4277CVSD5KJUCAYLYKQUF67D62Q7CW7DTZ3JCAAI623WCTBDPK7KF6ADT53YCTSI62JJFTBDE5QWCWYD5KJKC6SILKJUCT7DEK3EHJNCLSIZ)[ads via Carbon](http://carbonads.net/?utm_source=nestjscom\&utm_medium=ad_via_link\&utm_campaign=in_unit\&utm_term=carbon)

### Custom providers

Earlier chapters touched on various aspects of **dependency injection (DI)** and how Nest uses it. One example is [constructor-based](/providers#dependency-injection) dependency injection, which injects instances (often service providers) into classes. Dependency injection is built into the Nest core at a fundamental level. So far, we've explored only one main pattern. As your application grows more complex, you may need the full feature set of the DI system, so this chapter explores it in more detail.

#### DI fundamentals[#](/fundamentals/custom-providers#di-fundamentals)

Dependency injection is an [inversion of control (IoC)](https://en.wikipedia.org/wiki/Inversion_of_control) technique in which you delegate the instantiation of dependencies to the IoC container (in our case, the NestJS runtime system) instead of instantiating them imperatively in your own code. Let's examine what happens in this example from the [Providers](/providers) chapter.

First, we define a provider. The `@Injectable()` decorator marks the `CatsService` class as a provider.

cats.service.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import type { Cat } from './interfaces/cat.interface.js';

@Injectable()
export class CatsService {
  private readonly cats: Cat[] = [];

  findAll(): Cat[] {
    return this.cats;
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';

@Injectable()
export class CatsService {
  constructor() {
    this.cats = [];
  }

  findAll() {
    return this.cats;
  }
}
```

Then we request that Nest inject the provider into our controller class:

cats.controller.ts

JS TS

```typescript

import { Controller, Get } from '@nestjs/common';
import { CatsService } from './cats.service.js';
import type { Cat } from './interfaces/cat.interface.js';

@Controller('cats')
export class CatsController {
  constructor(private catsService: CatsService) {}

  @Get()
  async findAll(): Promise<Cat[]> {
    return this.catsService.findAll();
  }
}
```

```typescript

import { Controller, Get, Dependencies } from '@nestjs/common';
import { CatsService } from './cats.service.js';

@Controller('cats')
@Dependencies(CatsService)
export class CatsController {
  constructor(catsService) {
    this.catsService = catsService;
  }

  @Get()
  async findAll() {
    return this.catsService.findAll();
  }
}
```

Finally, we register the provider with the Nest IoC container:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { CatsController } from './cats/cats.controller.js';
import { CatsService } from './cats/cats.service.js';

@Module({
  controllers: [CatsController],
  providers: [CatsService],
})
export class AppModule {}
```

Three key steps make this work:

1. In `cats.service.ts`, the `@Injectable()` decorator declares `CatsService` as a class that the Nest IoC container can manage.
2. In `cats.controller.ts`, `CatsController` declares a dependency on the `CatsService` token with constructor injection:

```typescript

  constructor(private catsService: CatsService)
```

3. In `app.module.ts`, we associate the token `CatsService` with the class `CatsService` from the `cats.service.ts` file. The [Standard providers](/fundamentals/custom-providers#standard-providers) section below shows exactly how this association (also called *registration*) occurs.

When the Nest IoC container instantiates a `CatsController`, it first looks for any dependencies\*. When it finds the `CatsService` dependency, it looks up the `CatsService` token, which returns the `CatsService` class, per the registration step (#3 above). Assuming `SINGLETON` scope (the default), Nest then either creates an instance of `CatsService`, caches it, and returns it, or, if an instance is already cached, returns the existing one.

\*This explanation is simplified to illustrate the point. In reality, analyzing the code for dependencies is a sophisticated process that happens during application bootstrapping. One key property is that dependency analysis (or "creating the dependency graph") is **transitive**: in the example above, if `CatsService` itself had dependencies, those would be resolved too. The dependency graph ensures that dependencies are resolved in the correct order, essentially "bottom up". This mechanism relieves you from having to manage complex dependency graphs yourself.

## Learn the right way!

* 80+ chapters
* 5+ hours of videos
* Official certificate
* Deep-dive sessions

[Explore official courses](https://courses.nestjs.com "Courses | NestJS - A node.js framework built on top of TypeScript")

#### Standard providers[#](/fundamentals/custom-providers#standard-providers)

Let's take a closer look at the `@Module()` decorator. In `app.module`, we declare:

```typescript

@Module({
  controllers: [CatsController],
  providers: [CatsService],
})
```

The `providers` property takes an array of providers. So far, we've supplied those providers as a list of class names. In fact, the syntax `providers: [CatsService]` is shorthand for the more complete syntax:

```typescript

providers: [
  {
    provide: CatsService,
    useClass: CatsService,
  },
];
```

This explicit construction shows the registration process: it associates the token `CatsService` with the class `CatsService`. The shorthand notation is a convenience for the most common use case, where the token is used to request an instance of the class with the same name.

#### Custom providers[#](/fundamentals/custom-providers#custom-providers-1)

Sometimes your requirements go beyond what *standard providers* offer. For example:

* You want to create a custom instance instead of having Nest instantiate (or return a cached instance of) a class.
* You want to reuse an existing class in a second dependency.
* You want to override a class with a mock version for testing.

Nest lets you define custom providers to handle these cases, and offers several ways to define them. The following sections walk through each one.

> **Hint** If you run into problems with dependency resolution, set the `NEST_DEBUG` environment variable to get extra dependency resolution logs during startup.

#### Value providers: `useValue`[#](/fundamentals/custom-providers#value-providers-usevalue)

The `useValue` syntax is useful for injecting a constant value, putting an external library into the Nest container, or replacing a real implementation with a mock object. For example, suppose you want Nest to use a mock `CatsService` for testing purposes:

```typescript

import { CatsService } from './cats.service.js';

const mockCatsService = {
  /* mock implementation
  ...
  */
};

@Module({
  imports: [CatsModule],
  providers: [
    {
      provide: CatsService,
      useValue: mockCatsService,
    },
  ],
})
export class AppModule {}
```

In this example, the `CatsService` token resolves to the `mockCatsService` mock object. `useValue` requires a value, in this case a literal object that has the same interface as the `CatsService` class it replaces. Because of TypeScript's [structural typing](https://www.typescriptlang.org/docs/handbook/type-compatibility.html), you can use any object with a compatible interface, including a literal object or a class instance created with `new`.

#### Non-class-based provider tokens[#](/fundamentals/custom-providers#non-class-based-provider-tokens)

So far, we've used class names as our provider tokens (the value of the `provide` property in a provider listed in the `providers` array). This matches the standard pattern used with [constructor-based injection](/providers#dependency-injection), where the token is also a class name. (See [DI fundamentals](/fundamentals/custom-providers#di-fundamentals) for a refresher on tokens.) Sometimes you need the flexibility to use strings or symbols as DI tokens. For example:

```typescript

import { connection } from './connection.js';

@Module({
  providers: [
    {
      provide: 'CONNECTION',
      useValue: connection,
    },
  ],
})
export class AppModule {}
```

In this example, we associate a string-valued token (`'CONNECTION'`) with a pre-existing `connection` object imported from an external file.

> **Notice** Besides strings, you can also use JavaScript [symbols](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol) or TypeScript [enums](https://www.typescriptlang.org/docs/handbook/enums.html) as token values.

The standard [constructor-based injection](/providers#dependency-injection) pattern **requires** the dependency to be declared with a class name. The `'CONNECTION'` custom provider, however, uses a string-valued token. To inject such a provider, use the `@Inject()` decorator, which takes a single argument: the token.

JS TS

```typescript

@Injectable()
export class CatsRepository {
  constructor(@Inject('CONNECTION') connection: Connection) {}
}
```

```typescript

@Injectable()
@Dependencies('CONNECTION')
export class CatsRepository {
  constructor(connection) {}
}
```

> **Hint** The `@Inject()` decorator is imported from the `@nestjs/common` package.

The examples above use the string `'CONNECTION'` directly for illustration. For clean code organization, define tokens in a separate file, such as `constants.ts`, and import them where needed, as you would with symbols or enums.

#### Interfaces and abstract classes[#](/fundamentals/custom-providers#interfaces-and-abstract-classes)

TypeScript types and interfaces are erased during compilation, so Nest can't reference them at runtime. An interface can describe the shape of a dependency, but it can't serve as a DI token by itself.

Because Nest resolves providers by runtime tokens, use a string or `Symbol` token when registering a provider for an interface:

```typescript

export interface LoggerService {
  log(message: string): void;
}

export const LOGGER_SERVICE = Symbol('LOGGER_SERVICE');

@Injectable()
export class PinoLoggerService implements LoggerService {
  log(message: string) {
    // implementation details
  }
}

@Module({
  providers: [
    {
      provide: LOGGER_SERVICE,
      useClass: PinoLoggerService,
    },
  ],
})
export class AppModule {}
```

To inject this provider, pass that token to the `@Inject()` decorator:

```typescript

@Injectable()
export class CatsService {
  constructor(
    @Inject(LOGGER_SERVICE)
    private readonly logger: LoggerService,
  ) {}
}
```

Abstract classes, unlike interfaces, exist at runtime. You can use an abstract class as both the TypeScript contract and the DI token:

```typescript

export abstract class LoggerService {
  abstract log(message: string): void;
}

@Injectable()
export class PinoLoggerService implements LoggerService {
  log(message: string) {
    // implementation details
  }
}

@Module({
  providers: [
    {
      provide: LoggerService,
      useClass: PinoLoggerService,
    },
  ],
})
export class AppModule {}
```

With an abstract class token, constructor-based injection uses the abstract class type directly and doesn't require `@Inject()`:

```typescript

@Injectable()
export class CatsService {
  constructor(private readonly logger: LoggerService) {}
}
```

Use string or `Symbol` tokens when the runtime DI token should be decoupled from a class. `Symbol` tokens are especially useful for libraries and larger applications: each symbol has a unique runtime identity, which avoids the accidental collisions that can occur when unrelated providers use the same string token. When using a symbol token, export it from a shared file and reuse the same symbol instance wherever the provider is registered and injected. Use an abstract class when one artifact should act as both the contract and the runtime token, and you prefer simpler constructor injection. A plain interface remains a good choice when the type is used only for compile-time checking and no DI token is needed.

#### Class providers: `useClass`[#](/fundamentals/custom-providers#class-providers-useclass)

The `useClass` syntax lets you dynamically determine the class that a token resolves to. For example, suppose we have an abstract (or default) `ConfigService` class, and we want Nest to provide a different implementation of the configuration service depending on the current environment. The following code implements this strategy:

```typescript

const configServiceProvider = {
  provide: ConfigService,
  useClass:
    process.env.NODE_ENV === 'development'
      ? DevelopmentConfigService
      : ProductionConfigService,
};

@Module({
  providers: [configServiceProvider],
})
export class AppModule {}
```

Two details in this sample are worth noting. First, we define `configServiceProvider` as a literal object, then pass it in the module decorator's `providers` property. This is only code organization; it is functionally equivalent to the examples used so far in this chapter.

Second, we use the `ConfigService` class name as the token. For any class that depends on `ConfigService`, Nest injects an instance of the provided class (`DevelopmentConfigService` or `ProductionConfigService`), overriding any default implementation that may have been declared elsewhere (e.g., a `ConfigService` declared with an `@Injectable()` decorator).

#### Factory providers: `useFactory`[#](/fundamentals/custom-providers#factory-providers-usefactory)

The `useFactory` syntax lets you create providers **dynamically**. The provider's value is whatever the factory function returns. The factory function can be as simple or as complex as needed. A simple factory may not depend on any other providers. A more complex factory can inject the providers it needs to compute its result. For the latter case, the factory provider syntax has a pair of related mechanisms:

1. The factory function can accept (optional) arguments.
2. The (optional) `inject` property accepts an array of providers that Nest resolves and passes as arguments to the factory function during instantiation. These providers can also be marked as optional. The two lists are correlated: Nest passes the instances from the `inject` list to the factory function as arguments, in the same order. The example below demonstrates this.

JS TS

```typescript

const connectionProvider = {
  provide: 'CONNECTION',
  useFactory: (optionsProvider: MyOptionsProvider, optionalProvider?: string) => {
    const options = optionsProvider.get();
    return new DatabaseConnection(options);
  },
  inject: [MyOptionsProvider, { token: 'SomeOptionalProvider', optional: true }],
  //       \______________/             \__________________/
  //        This provider                The provider with this token
  //        is mandatory.                can resolve to `undefined`.
};

@Module({
  providers: [
    connectionProvider,
    MyOptionsProvider, // class-based provider
    // { provide: 'SomeOptionalProvider', useValue: 'anything' },
  ],
})
export class AppModule {}
```

```typescript

const connectionProvider = {
  provide: 'CONNECTION',
  useFactory: (optionsProvider, optionalProvider) => {
    const options = optionsProvider.get();
    return new DatabaseConnection(options);
  },
  inject: [MyOptionsProvider, { token: 'SomeOptionalProvider', optional: true }],
  //       \______________/            \__________________/
  //        This provider               The provider with this token
  //        is mandatory.               can resolve to `undefined`.
};

@Module({
  providers: [
    connectionProvider,
    MyOptionsProvider, // class-based provider
    // { provide: 'SomeOptionalProvider', useValue: 'anything' },
  ],
})
export class AppModule {}
```

#### Alias providers: `useExisting`[#](/fundamentals/custom-providers#alias-providers-useexisting)

The `useExisting` syntax lets you create aliases for existing providers, which gives you two ways to access the same provider. In the example below, the (string-based) token `'AliasedLoggerService'` is an alias for the (class-based) token `LoggerService`. Assume we have two different dependencies, one on `'AliasedLoggerService'` and one on `LoggerService`. If both dependencies are specified with `SINGLETON` scope, they both resolve to the same instance.

```typescript

@Injectable()
class LoggerService {
  /* implementation details */
}

const loggerAliasProvider = {
  provide: 'AliasedLoggerService',
  useExisting: LoggerService,
};

@Module({
  providers: [LoggerService, loggerAliasProvider],
})
export class AppModule {}
```

#### Non-service based providers[#](/fundamentals/custom-providers#non-service-based-providers)

Providers often supply services, but they aren't limited to that. A provider can supply **any** value. For example, a provider can supply a configuration object based on the current environment:

```typescript

const configFactory = {
  provide: 'CONFIG',
  useFactory: () => {
    return process.env.NODE_ENV === 'development' ? devConfig : prodConfig;
  },
};

@Module({
  providers: [configFactory],
})
export class AppModule {}
```

#### Export custom provider[#](/fundamentals/custom-providers#export-custom-provider)

Like any provider, a custom provider is scoped to its declaring module. To make it visible to other modules, you must export it, using either its token or the full provider object.

The following example exports the provider by its token:

JS TS

```typescript

const connectionFactory = {
  provide: 'CONNECTION',
  useFactory: (optionsProvider: OptionsProvider) => {
    const options = optionsProvider.get();
    return new DatabaseConnection(options);
  },
  inject: [OptionsProvider],
};

@Module({
  providers: [connectionFactory],
  exports: ['CONNECTION'],
})
export class AppModule {}
```

```typescript

const connectionFactory = {
  provide: 'CONNECTION',
  useFactory: (optionsProvider) => {
    const options = optionsProvider.get();
    return new DatabaseConnection(options);
  },
  inject: [OptionsProvider],
};

@Module({
  providers: [connectionFactory],
  exports: ['CONNECTION'],
})
export class AppModule {}
```

Alternatively, export the full provider object:

JS TS

```typescript

const connectionFactory = {
  provide: 'CONNECTION',
  useFactory: (optionsProvider: OptionsProvider) => {
    const options = optionsProvider.get();
    return new DatabaseConnection(options);
  },
  inject: [OptionsProvider],
};

@Module({
  providers: [connectionFactory],
  exports: [connectionFactory],
})
export class AppModule {}
```

```typescript

const connectionFactory = {
  provide: 'CONNECTION',
  useFactory: (optionsProvider) => {
    const options = optionsProvider.get();
    return new DatabaseConnection(options);
  },
  inject: [OptionsProvider],
};

@Module({
  providers: [connectionFactory],
  exports: [connectionFactory],
})
export class AppModule {}
```

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/fundamentals/dependency-injection.md)

----
url: https://docs.nestjs.com/application/http-client
----

[Skip to content](#content)

On this page

* [HTTP client](https://docs.nestjs.com/application/http-client#http-client)
* [Installation](https://docs.nestjs.com/application/http-client#installation)
* [Getting started](https://docs.nestjs.com/application/http-client#getting-started)
* [Named clients](https://docs.nestjs.com/application/http-client#named-clients)
* [Application-wide defaults](https://docs.nestjs.com/application/http-client#application-wide-defaults)
* [Async configuration](https://docs.nestjs.com/application/http-client#async-configuration)
* [Making requests](https://docs.nestjs.com/application/http-client#making-requests)
* [Timeouts and cancellation](https://docs.nestjs.com/application/http-client#timeouts-and-cancellation)
* [Retries](https://docs.nestjs.com/application/http-client#retries)
* [Handling errors](https://docs.nestjs.com/application/http-client#handling-errors)
* [Interceptors](https://docs.nestjs.com/application/http-client#interceptors)
* [Streaming responses](https://docs.nestjs.com/application/http-client#streaming-responses)
* [Proxies, TLS, and redirects](https://docs.nestjs.com/application/http-client#proxies-tls-and-redirects)
* [Security](https://docs.nestjs.com/application/http-client#security)
* [Testing](https://docs.nestjs.com/application/http-client#testing)
* [Working with RxJS](https://docs.nestjs.com/application/http-client#working-with-rxjs)
* [Migrating from @nestjs/axios](https://docs.nestjs.com/application/http-client#migrating-from-nestjsaxios)

### HTTP client

Most applications call other services over HTTP. The `@nestjs/http-client` package provides a client for this, built on the `fetch` API that ships with Node.js. It adds what `fetch` leaves out: base URLs, default headers, JSON bodies, path and query parameters, typed responses, timeouts, retries, interceptors, and named clients. You configure it as a Nest module and inject it like any other provider.

The package has no dependencies besides `@nestjs/common` and `@nestjs/core`. Every method returns a Promise, so you `await` requests and handle failures with `try`/`catch`. If you prefer Observables, see [Working with RxJS](/application/http-client#working-with-rxjs).

> **Hint** This package replaces the Axios-based `HttpModule` from `@nestjs/axios`, which this chapter used to describe. `@nestjs/axios` remains available. See [Migrating from @nestjs/axios](/application/http-client#migrating-from-nestjsaxios) to switch.

#### Installation[#](/application/http-client#installation)

To get started, install the package:

```bash

$ npm i --save @nestjs/http-client
```

#### Getting started[#](/application/http-client#getting-started)

Import `HttpClientModule` into the module that makes the requests, and register a client with the `register()` method:

cats.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { HttpClientModule } from '@nestjs/http-client';
import { CatsService } from './cats.service.js';

@Module({
  imports: [
    HttpClientModule.register({
      baseUrl: 'https://api.example.com/v1',
      timeout: '5s',
    }),
  ],
  providers: [CatsService],
})
export class CatsModule {}
```

Then inject the `HttpClient` class:

cats.service.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { HttpClient } from '@nestjs/http-client';
import type { Cat } from './interfaces/cat.interface.js';

@Injectable()
export class CatsService {
  constructor(private readonly http: HttpClient) {}

  async findAll(): Promise<Cat[]> {
    const { data } = await this.http.get<Cat[]>('/cats');
    return data;
  }
}
```

The request goes to `https://api.example.com/v1/cats`. A relative URL is appended to `baseUrl` with exactly one `/` between them, so the `/v1` prefix is kept (unlike `new URL('/cats', base)`, which would drop it). A client without a `baseUrl` requires absolute URLs.

Like other `register()` methods, each call creates a client for the module that imports it. To make a client injectable in every module, set `isGlobal: true`.

#### Named clients[#](/application/http-client#named-clients)

An application usually talks to several upstream services, each with its own base URL, credentials, and timeouts. Give each client a `name`:

repos.module.ts

JS TS

```typescript

@Module({
  imports: [
    HttpClientModule.register({
      name: 'github',
      baseUrl: 'https://api.github.com',
      headers: { accept: 'application/vnd.github+json' },
    }),
  ],
  providers: [ReposService],
})
export class ReposModule {}
```

and inject it with the `@InjectHttpClient()` decorator:

repos.service.ts

JS TS

```typescript

@Injectable()
export class ReposService {
  constructor(@InjectHttpClient('github') private readonly github: HttpClient) {}
}
```

A client registered without a name is the default client, injected as `HttpClient`. The `getHttpClientToken(name)` function returns the injection token of a client, which is useful in tests and custom providers.

#### Application-wide defaults[#](/application/http-client#application-wide-defaults)

Settings that every client shares, such as a `user-agent` header, a timeout, a retry policy, or a logging interceptor, go into `HttpClientModule.forRoot()`. Import it once, in the root module. It is always global:

app.module.ts

JS TS

```typescript

@Module({
  imports: [
    HttpClientModule.forRoot({
      headers: { 'user-agent': 'cats-service/1.0' },
      timeout: '10s',
    }),
    CatsModule,
    ReposModule,
  ],
})
export class AppModule {}
```

`forRoot()` doesn't register a client itself, and it doesn't take a `baseUrl`. Each client's own settings win over its defaults, with three exceptions: headers are merged (set a header to `null` in a client to remove a default), retry settings are merged field by field, and the `forRoot()` interceptors run before the client's own.

#### Async configuration[#](/application/http-client#async-configuration)

To build a client's options from other providers, such as the `ConfigService` from the [configuration](/application/configuration#getting-started) chapter, use `registerAsync()`:

repos.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { HttpClientModule, type Duration } from '@nestjs/http-client';
import { ReposService } from './repos.service.js';

@Module({
  imports: [
    HttpClientModule.registerAsync({
      name: 'github',
      imports: [ConfigModule],
      inject: [ConfigService],
      useFactory: (config: ConfigService) => ({
        baseUrl: config.getOrThrow<string>('GITHUB_API_URL'),
        headers: { authorization: `Bearer ${config.getOrThrow<string>('GITHUB_TOKEN')}` },
        timeout: config.get<Duration>('GITHUB_TIMEOUT', '5s'),
      }),
    }),
  ],
  providers: [ReposService],
})
export class ReposModule {}
```

The factory can be `async`. It returns the same options as `register()`, typed `HttpClientFactoryOptions`, except for `name`, `isGlobal`, `imports`, and interceptor classes: Nest needs those to build the module, before the factory runs, so they go next to `useFactory`. A factory that returns one of them stops the application at startup.

Instead of a factory, you can pass a class that implements the `HttpClientOptionsFactory` interface. Nest instantiates it inside the client's module and calls its `createHttpClientOptions()` method:

github-client.config.ts

JS TS

```typescript

@Injectable()
export class GithubClientConfig implements HttpClientOptionsFactory {
  constructor(private readonly config: ConfigService) {}

  createHttpClientOptions(): HttpClientFactoryOptions {
    return { baseUrl: this.config.getOrThrow<string>('GITHUB_API_URL') };
  }
}
```

```typescript

HttpClientModule.registerAsync({
  name: 'github',
  imports: [ConfigModule],
  useClass: GithubClientConfig,
});
```

To reuse a provider that already exists instead of creating a private copy, pass `useExisting: GithubClientConfig`, with the module that exports it in `imports`. `forRootAsync()` works the same way. Its `useClass` or `useExisting` class implements `HttpClientModuleOptionsFactory`, with a `createHttpClientModuleOptions()` method.

#### Making requests[#](/application/http-client#making-requests)

A client has a method for each HTTP verb: `get()`, `post()`, `put()`, `patch()`, `delete()`, `head()`, and `options()`. Each one takes a URL and an optional options object, and resolves to an `HttpResponse`. The `request()` method takes the verb as the `method` option.

repos.service.ts

JS TS

```typescript

@Injectable()
export class ReposService {
  constructor(@InjectHttpClient('github') private readonly github: HttpClient) {}

  async findAll(org: string): Promise<Repo[]> {
    const { data } = await this.github.get<Repo[]>('/orgs/:org/repos', {
      params: { org },
      query: { type: 'public', sort: 'updated', topic: ['nest', 'typescript'] },
    });
    return data;
  }

  async createIssue(owner: string, repo: string, issue: CreateIssueDto): Promise<Issue> {
    const { data } = await this.github.post<Issue>('/repos/:owner/:repo/issues', {
      params: { owner, repo },
      json: issue,
    });
    return data;
  }
}
```

The options mirror what a Nest controller reads from a request:

* `params` fills the `:name` segments of the path, URI-encoded. A segment without a value throws, even when `params` is omitted, and so does a key that matches no segment, or a value that would move the request to another endpoint (an empty string, `.`, or `..`).
* `query` is an object or a `URLSearchParams` instance, appended to any query already in the URL. Arrays repeat the key (`topic=nest&topic=typescript`), `Date` values become ISO strings, and `null` and `undefined` values are skipped. The first request above goes to `https://api.github.com/orgs/nestjs/repos?type=public&sort=updated&topic=nest&topic=typescript`.
* `json` is serialized with `JSON.stringify()`, and sets the `content-type: application/json` header unless you set one.
* `body` is passed to `fetch` as is: a string, `Buffer`, `FormData`, `URLSearchParams`, `Blob`, a web or Node.js stream, or an async iterable. Pass either `json` or `body`, not both. A `GET` or `HEAD` request with a body throws before anything is sent.
* `headers` is merged over the client's headers. A `null` value removes a header.
* `timeout`, `retry`, `signal`, `throwOnHttpError`, `redirect`, and `dispatcher` override the client's settings for one request, and are covered below.
* `context` is a free-form object that [interceptors](/application/http-client#interceptors) can read.

The type argument, such as `Repo[]`, describes `data`. Nothing checks it at runtime, so validate responses from APIs you don't control. The `responseType` option controls how the body is read:

| `responseType`     | `data`                                                                                                                                                                                                                                                                                                  |
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `'auto'` (default) | Parsed JSON when the `content-type` is JSON (including `+json` types), otherwise a string. `undefined` when the body is empty, for `204` and `205` responses, and for `HEAD` requests. A `304` response throws by default, like any non-2xx; with `throwOnHttpError: false`, its `data` is `undefined`. |
| `'json'`           | Parsed JSON, whatever the content type.                                                                                                                                                                                                                                                                 |
| `'text'`           | A string.                                                                                                                                                                                                                                                                                               |
| `'arrayBuffer'`    | An `ArrayBuffer`.                                                                                                                                                                                                                                                                                       |
| `'stream'`         | A Node.js `Readable`. See [Streaming responses](/application/http-client#streaming-responses).                                                                                                                                                                                                          |
| `'response'`       | The web `Response`, with its body unread.                                                                                                                                                                                                                                                               |

The type of `data` follows `responseType`, so `responseType: 'text'` resolves to `HttpResponse<string>`. A successful response whose body isn't valid JSON, although it was expected to be, rejects with an `HttpParseError`. The response object has the following shape:

```typescript

interface HttpResponse<T> {
  status: number;
  statusText: string;
  ok: boolean;
  headers: Headers; // a web Headers object: headers.get('etag')
  data: T;
  url: string; // the final URL, after redirects
  request: HttpRequest; // the request that was sent, after interceptors ran
}
```

#### Timeouts and cancellation[#](/application/http-client#timeouts-and-cancellation)

`fetch` has no timeout of its own, apart from the 5-minute limits of undici, the HTTP client inside Node.js. Set a `timeout` on each client, either in milliseconds or as a duration string such as `'500ms'`, `'5s'`, or `'2m'`. An invalid value fails at startup, with an error that names the option. `0` means no timeout, which is the default.

The timeout applies to **each attempt**, not to the whole call. It covers the attempt's interceptors and reading the response body. For `responseType: 'stream'` and `'response'`, it stops once the headers arrive, so a long download isn't cut off. When it elapses, the attempt fails with an `HttpTimeoutError`, and the request is retried like after any other [transient failure](/application/http-client#retries).

To cancel a request, pass an `AbortSignal` as the `signal` option. It is combined with the timeout. A cancelled request rejects with the signal's `reason`, as `fetch` does, and is never retried, even while it waits between two attempts.

Because of retries, a call can take up to `attempts × timeout`, plus the waits between attempts. To put a limit on the whole call, pass a deadline as the signal:

```typescript

const { data } = await this.github.get<Repo>('/repos/:owner/:repo', {
  params: { owner, repo },
  signal: AbortSignal.timeout(10_000),
});
```

The deadline rejects with a `DOMException` named `TimeoutError`, which `toHttpException()` maps to `504 Gateway Timeout`, like an `HttpTimeoutError`. To combine it with another signal, use `AbortSignal.any([signal, AbortSignal.timeout(10_000)])`.

#### Retries[#](/application/http-client#retries)

Retries are **on by default**. Without any configuration, a client makes up to 3 attempts for `GET`, `HEAD`, `OPTIONS`, `PUT`, and `DELETE`, the methods that HTTP defines as idempotent. It retries after:

* connection errors, such as a refused or reset connection (including a reset while the body is read),
* per-attempt timeouts,
* `408`, `429`, `500`, `502`, `503`, and `504` responses.

Between attempts, the client waits with exponential backoff and full jitter: a random delay of up to 200 ms after the first attempt, up to 400 ms after the second, and so on, capped at 30 seconds. A `Retry-After` response header, in seconds or as an HTTP date, replaces the backoff. When it asks for more than the cap, the client doesn't wait at all, and returns (or throws) the `429` or `503` response right away. A request whose body is a stream is never retried, because the first attempt consumed it.

The `retry` option takes a number of attempts, `false` for a single attempt, or an object:

```typescript

HttpClientModule.register({
  name: 'github',
  baseUrl: 'https://api.github.com',
  retry: {
    attempts: 4, // in total, including the first request
    backoff: { delay: '500ms', factor: 2, maxDelay: '5s', jitter: 'full' },
    retryIf: (error, attempt) => !(error instanceof HttpNetworkError),
    methods: ['GET', 'HEAD', 'OPTIONS', 'PUT', 'DELETE'],
    statusCodes: [408, 429, 500, 502, 503, 504],
  },
}),
```

Every field you omit keeps its default. `backoff` can also be a function that receives the number of the attempt that failed and its error, and returns a duration. `jitter` can be `'full'`, `'equal'` (at least half of the computed delay), or `'none'`. `retryIf` is only asked about failures the client would retry anyway, so it can narrow the defaults but not widen them; use `methods` and `statusCodes` for that. It receives the `HttpResponseError` (with its `body`), `HttpTimeoutError`, or `HttpNetworkError` of the attempt that failed.

Retry settings are layered: `forRoot()`, then the client, then the request. Each layer overrides only the fields it sets, and a later layer can turn retries back on after an earlier `false`. `methods` and `statusCodes`, however, **replace** the default lists instead of adding to them.

`POST` and `PATCH` aren't retried, because repeating them could, for example, charge a customer twice. When the upstream API supports idempotency keys, send one and opt in for that request:

```typescript

const { data } = await this.payments.post<Charge>('/charges', {
  json: charge,
  headers: { 'idempotency-key': `charge-${order.id}` },
  retry: { methods: ['POST'] },
});
```

The key identifies the operation, so every attempt sends the same one, and the upstream returns the original result instead of creating a second charge. Setting `methods: ['POST']` on the client instead would also stop `GET` retries, since the list replaces the default one.

> **Warning** Retries multiply along a chain of services. If service A calls B, B calls C, and every hop makes 3 attempts, one failing request to C turns into 9 calls to C, which arrive exactly when C is already struggling. Retry at one layer only, usually the service that calls the external dependency, and set `retry: false` on clients that call your own services.

#### Handling errors[#](/application/http-client#handling-errors)

A request rejects with one of the following errors, all of which extend the `HttpClientError` class:

| Error               | When                                                                                                                                               | Fields                                                                                   |
| ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- |
| `HttpResponseError` | The upstream answered with a non-2xx status.                                                                                                       | `status`, `statusText`, `headers`, `body` (parsed JSON, otherwise text), `method`, `url` |
| `HttpTimeoutError`  | The `timeout` elapsed on the last attempt.                                                                                                         | `timeoutMs`, `method`, `url`                                                             |
| `HttpNetworkError`  | The connection failed: DNS, a refused or reset connection, TLS, or a redirect the client refused (to another origin, or with `redirect: 'error'`). | `cause` (for example, with `cause.code` set to `ECONNREFUSED`), `method`, `url`          |
| `HttpParseError`    | A successful response isn't valid JSON, although it was expected to be.                                                                            | `status`, `statusText`, `headers`, `body` (the raw text), `method`, `url`                |

A cancelled request rejects with the signal's reason, and errors thrown by interceptors propagate unchanged. A request the client refuses to send, such as one with an invalid `params` value, rejects with a `TypeError`. To receive non-2xx responses as values instead, set `throwOnHttpError: false` on the client or on a request, and check `ok` or `status` yourself.

If one of these errors escapes a route handler, Nest answers `500 Internal Server Error`. For your API's callers, though, a failing upstream is usually a `502 Bad Gateway`, and one that doesn't answer in time is a `504 Gateway Timeout`. The `toHttpException()` function maps the errors accordingly:

| Error                                                                            | Becomes                                                                                   |
| -------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- |
| `HttpResponseError`                                                              | `502 Bad Gateway`, or the upstream status and body when the status is listed in `forward` |
| `HttpTimeoutError`, or the `TimeoutError` of an `AbortSignal.timeout()` deadline | `504 Gateway Timeout`                                                                     |
| `HttpNetworkError`, `HttpParseError`                                             | `502 Bad Gateway`                                                                         |
| Anything else, including an `HttpException`                                      | Returned unchanged, so Nest handles it as usual                                           |

repos.service.ts

JS TS

```typescript

async findOne(owner: string, repo: string): Promise<Repo> {
  try {
    const { data } = await this.github.get<Repo>('/repos/:owner/:repo', {
      params: { owner, repo },
    });
    return data;
  } catch (error) {
    if (error instanceof HttpResponseError && error.status === 404) {
      throw new NotFoundException(`Repository ${owner}/${repo} not found`);
    }
    throw toHttpException(error);
  }
}
```

By default, the upstream body isn't passed on to the caller, since it may describe the upstream's internals. To pass selected statuses through with their body, such as a `422` whose body tells the caller what to fix, use `toHttpException(error, options)` with `forward` set to `[422]`, or to `true` for every status. The original error is kept as the exception's `cause`.

Nest's built-in exception filter [doesn't log](/exception-filters#exceptions-logging) an `HttpException`, so a `502` or `504` would leave no trace. `toHttpException()` therefore logs every failure that it turns into a `5xx`, with the `HttpClient` context:

```text

ERROR [HttpClient] GET https://api.github.com/repos/nestjs/nest failed with 503 Service Unavailable; answering 502 Bad Gateway
```

Set the `log` option to `false` when something else, such as your own exception filter, already logs upstream failures.

Instead of mapping errors in every service, you can let them leave the handler unchanged and map them in an [exception filter](/exception-filters#binding-filters). This keeps call sites free of `try`/`catch`, and interceptors further out still see the original error:

http-client-error.filter.ts

JS TS

```typescript

import { ArgumentsHost, Catch } from '@nestjs/common';
import { BaseExceptionFilter } from '@nestjs/core';
import { HttpClientError, toHttpException } from '@nestjs/http-client';

@Catch(HttpClientError)
export class HttpClientErrorFilter extends BaseExceptionFilter {
  catch(error: HttpClientError, host: ArgumentsHost) {
    super.catch(toHttpException(error), host);
  }
}
```

An `AbortSignal.timeout()` deadline isn't an `HttpClientError`, so add `DOMException` to `@Catch()` if you use deadlines. `toHttpException()` returns an `HttpException`, so in a microservice or WebSocket handler, convert the errors to an `RpcException` or `WsException` yourself.

> **Hint** Error messages and objects end up in logs, so the client keeps secrets out of them. A message never includes the response body, and the URL in it has its query values masked, as in `GET https://api.example.com/users?email=***`. The `url`, `headers`, and `body` fields are non-enumerable: your code can read them, but loggers and `JSON.stringify()` leave them out.

#### Interceptors[#](/application/http-client#interceptors)

An interceptor wraps every request a client sends. It receives the request and a `next` function that sends it, and returns the resulting web `Response`. The simplest form is a function:

api-key.interceptor.ts

JS TS

```typescript

import type { HttpClientInterceptorFn } from '@nestjs/http-client';

export function apiKeyInterceptor(apiKey: string): HttpClientInterceptorFn {
  return (request, next) => {
    request.headers.set('x-api-key', apiKey);
    return next(request);
  };
}
```

The `HttpRequest` object holds the `method`, the `url` (a `URL` instance), the `headers` (a `Headers` instance), the `body`, the `signal`, the `attempt` number, and the request's `context`. You can change it in place, or pass a modified copy to `next()`. Interceptors see the response **before** the status check, so a `4xx` or `5xx` response reaches them too. An interceptor must return what `next()` resolves to, or a `Response` of its own.

When an interceptor needs other providers, write it as a class that implements the `HttpClientInterceptor` interface:

github-auth.interceptor.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import type { HttpClientInterceptor, HttpHandler, HttpRequest } from '@nestjs/http-client';
import { GithubTokenService } from './github-token.service.js';

@Injectable()
export class GithubAuthInterceptor implements HttpClientInterceptor {
  constructor(private readonly tokens: GithubTokenService) {}

  async intercept(request: HttpRequest, next: HttpHandler): Promise<Response> {
    request.headers.set('authorization', `Bearer ${await this.tokens.getToken()}`);
    return next(request);
  }
}
```

Pass interceptors in the `interceptors` array of `register()` or `forRoot()`, or next to `useFactory` in the async variants:

repos.module.ts

JS TS

```typescript

@Module({
  imports: [
    HttpClientModule.register({
      name: 'github',
      baseUrl: 'https://api.github.com',
      interceptors: [GithubAuthInterceptor],
    }),
  ],
  providers: [GithubTokenService, GithubAuthInterceptor, ReposService],
})
export class ReposModule {}
```

Nest resolves interceptor classes when the application initializes, so an interceptor may even depend on a service that injects the same client. If the class is a provider anywhere in the application, as `GithubAuthInterceptor` is above, that instance is used. Otherwise, Nest creates it inside the client's own module, which sees global providers and the modules you pass in the `imports` option of `register()`. An async factory may also return interceptors in its options, but only functions and instances, such as `apiKeyInterceptor(config.getOrThrow('API_KEY'))`.

Interceptors run in the order they are listed, the first one outermost, and the `forRoot()` interceptors run before the client's own. They run **once per attempt**, so a retry gets a fresh token, and `request.attempt` tells them which attempt it is. When an attempt fails, `next()` rejects with an `HttpNetworkError` or `HttpTimeoutError`, or with the abort reason. This makes an interceptor a good place to log upstream traffic:

http-logging.interceptor.ts

JS TS

```typescript

import { Injectable, Logger } from '@nestjs/common';
import type { HttpClientInterceptor, HttpHandler, HttpRequest } from '@nestjs/http-client';

@Injectable()
export class HttpLoggingInterceptor implements HttpClientInterceptor {
  private readonly logger = new Logger('HttpClient');

  async intercept(request: HttpRequest, next: HttpHandler): Promise<Response> {
    const target = `${request.method} ${request.url.origin}${request.url.pathname}`;
    const start = performance.now();
    try {
      const response = await next(request);
      const ms = Math.round(performance.now() - start);
      this.logger.log(`${target} ${response.status} ${ms}ms (attempt ${request.attempt})`);
      return response;
    } catch (error) {
      this.logger.warn(`${target} failed: ${(error as Error).name} (attempt ${request.attempt})`);
      throw error;
    }
  }
}
```

Registered with `HttpClientModule.forRoot()` and `interceptors: [HttpLoggingInterceptor]`, it logs the requests of every client. It logs the path without the query string, which often carries personal data or keys.

> **Hint** For tracing, you don't need an interceptor. [NestJS Observe](/observability/distributed-tracing#http-to-http) records every outbound `fetch` call as a span, and propagates the trace id to other Nest services.

#### Streaming responses[#](/application/http-client#streaming-responses)

To pass a large response through without buffering it in memory, set `responseType: 'stream'`. The `data` is a Node.js `Readable`, which you can return from a route handler in a [`StreamableFile`](/http/file-upload#streaming-files):

invoices.controller.ts

JS TS

```typescript

@Get(':id/pdf')
async download(@Param('id') id: string): Promise<StreamableFile> {
  const { data, headers } = await this.billing.get('/invoices/:id/pdf', {
    params: { id },
    responseType: 'stream',
  });
  return new StreamableFile(data, {
    type: headers.get('content-type') ?? 'application/pdf',
  });
}
```

The timeout stops once the headers arrive, while cancelling the `signal` still stops the download. A non-2xx response is read and thrown as an `HttpResponseError`, as usual. Don't pass the upstream's `content-length` header on as the `length` option: `fetch` decompresses gzip and brotli bodies, so the stream can be longer than the header says. For the web `ReadableStream`, use `responseType: 'response'` and read `data.body`.

#### Proxies, TLS, and redirects[#](/application/http-client#proxies-tls-and-redirects)

Node.js's `fetch` runs on undici, whose default dispatcher keeps a pool of keep-alive connections, so the common case needs no configuration. To change the pool size, route through a proxy, or use custom TLS settings (a private CA, or client certificates), pass an undici dispatcher as the `dispatcher` option:

partner.module.ts

JS TS

```typescript

import { readFileSync } from 'node:fs';
import { Agent } from 'undici';

@Module({
  imports: [
    HttpClientModule.register({
      name: 'partner',
      baseUrl: 'https://partner.example.com',
      dispatcher: new Agent({
        connections: 20,
        connect: {
          ca: readFileSync('certs/partner-ca.pem'),
          cert: readFileSync('certs/client.pem'),
          key: readFileSync('certs/client-key.pem'),
        },
      }),
    }),
  ],
})
export class PartnerModule {}
```

For a proxy, pass `new ProxyAgent('http://proxy.internal:3128')`. Node.js doesn't expose these classes from a built-in module, so install the `undici` package yourself (`@nestjs/http-client` doesn't depend on it), preferably with the major version that your Node.js release bundles. A Node.js `http.Agent`, which Axios accepts as `httpsAgent`, doesn't work with `fetch`, and fails to compile. To route every client through the proxy from the `HTTP_PROXY`, `HTTPS_PROXY`, and `NO_PROXY` environment variables instead, start Node.js with `--use-env-proxy` (or set `NODE_USE_ENV_PROXY=1`) on a release that supports it.

The `redirect` option controls how `3xx` responses are handled. A client with a `baseUrl` follows redirects on its own origin only, and fails one to another host with an `HttpNetworkError`, since its headers carry that upstream's credentials (see [Security](/application/http-client#security)). A client without a `baseUrl` lets `fetch` follow redirects anywhere, dropping the `authorization` and `cookie` headers when the origin changes, but not others.

Set `redirect` to `'follow'` to follow redirects anywhere with a `baseUrl` too, for an API that intentionally redirects to another host, to `'error'` to fail on every redirect, or to `'manual'` to receive `3xx` responses as they are. A `3xx` response isn't a success, so combine `'manual'` with `throwOnHttpError: false` to read its `location` header.

#### Security[#](/application/http-client#security)

The client guards against a few common mistakes:

* **A client with a `baseUrl` only sends requests to its origin.** An absolute URL on the same origin, such as a pagination link, works, but one on another host throws before anything is sent. A redirect to another host fails too, before the request is repeated there. The client's headers and interceptors carry that upstream's credentials, and a URL taken from user input or from an upstream response must not receive them. Use a client without a `baseUrl` to call arbitrary hosts, or `redirect: 'follow'` for an API that redirects to another host on purpose.
* **Path parameters are encoded.** Put request values in `params` and `query` instead of building the path with string interpolation. They are URI-encoded, and a `params` value such as `..` throws instead of moving the request to another endpoint.
* **Credentials in URLs are refused.** A `baseUrl` or request URL such as `https://user:pass@example.com` throws. Send credentials in the `authorization` header instead. A header value with a line break throws, without quoting the value in the message.
* **Errors are safe to log**, as described in [Handling errors](/application/http-client#handling-errors).

#### Testing[#](/application/http-client#testing)

A stub `fetch` is the easiest way to test code that calls an external API. Pass it to `HttpClientModule.forRoot()`, and every client uses it, while keeping its base URL, headers, retry policy, and interceptors. The stub only has to return a standard `Response`:

repos.service.spec.ts

JS TS

```typescript

import { Test } from '@nestjs/testing';
import { HttpClientModule } from '@nestjs/http-client';
import { vi } from 'vitest';
import { ReposModule } from './repos.module.js';
import { ReposService } from './repos.service.js';

describe('ReposService', () => {
  const fetch = vi.fn<typeof globalThis.fetch>();
  let repos: ReposService;

  beforeEach(async () => {
    fetch.mockReset();
    const moduleRef = await Test.createTestingModule({
      imports: [HttpClientModule.forRoot({ fetch }), ReposModule],
    }).compile();
    await moduleRef.init();
    repos = moduleRef.get(ReposService);
  });

  it('lists the public repositories of an organization', async () => {
    fetch.mockResolvedValueOnce(Response.json([{ name: 'nest' }]));

    await expect(repos.findAll('nestjs')).resolves.toEqual([{ name: 'nest' }]);
    const [url] = fetch.mock.calls[0];
    expect(String(url)).toBe(
      'https://api.github.com/orgs/nestjs/repos?type=public&sort=updated&topic=nest&topic=typescript',
    );
  });

  it('retries a 503', async () => {
    fetch
      .mockResolvedValueOnce(new Response(null, { status: 503 }))
      .mockResolvedValueOnce(Response.json([]));

    await expect(repos.findAll('nestjs')).resolves.toEqual([]);
    expect(fetch).toHaveBeenCalledTimes(2);
  });
});
```

Give every call its own `Response`, as `mockResolvedValueOnce()` does above: a response body can be read only once, so `mockResolvedValue()` would hand an already-read response to a retry. A client that sets its own `fetch` option keeps it, since a client's settings win over the `forRoot()` defaults. A client without one calls `globalThis.fetch` on every request, so `vi.stubGlobal('fetch', stub)` works too.

For an end-to-end test of an application that already calls `forRoot()`, override its options instead. This replaces every `forRoot()` option, except the interceptors passed directly to `forRoot()` or next to `useFactory`, which keep running:

```typescript

const moduleRef = await Test.createTestingModule({ imports: [AppModule] })
  .overrideProvider(HTTP_CLIENT_MODULE_OPTIONS)
  .useValue({ fetch })
  .compile();
```

To keep HTTP out of a test entirely, replace the client itself with `overrideProvider(getHttpClientToken('github'))`. Outside of Nest, for example in a script, create a client with `new HttpClient(options)`.

#### Working with RxJS[#](/application/http-client#working-with-rxjs)

To compose a request with RxJS operators, wrap it in an Observable. `defer()` starts the request when the Observable is subscribed to, while `from()` starts it immediately:

```typescript

import { defer } from 'rxjs';

const cats$ = defer(() => this.http.get<Cat[]>('/cats'));
```

Neither one cancels the request on unsubscribe. When you need that, for example with `switchMap()`, connect unsubscription to an `AbortController`:

```typescript

import { Observable } from 'rxjs';

function fromRequest<T>(send: (signal: AbortSignal) => Promise<T>): Observable<T> {
  return new Observable<T>((subscriber) => {
    const controller = new AbortController();
    send(controller.signal).then(
      (value) => {
        subscriber.next(value);
        subscriber.complete();
      },
      (error) => subscriber.error(error),
    );
    return () => controller.abort();
  });
}

const cats$ = fromRequest((signal) => this.http.get<Cat[]>('/cats', { signal }));
```

#### Migrating from `@nestjs/axios`[#](/application/http-client#migrating-from-nestjsaxios)

The `@nestjs/axios` package remains available, and both packages can be installed side by side while you migrate. The following table maps its features to `@nestjs/http-client`:

| `@nestjs/axios`                                            | `@nestjs/http-client`                                                                                                                                                |
| ---------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `HttpModule.register()` with `baseURL`                     | `HttpClientModule.register()` with `baseUrl`                                                                                                                         |
| `HttpModule.registerAsync()`                               | `HttpClientModule.registerAsync()`, which also takes a `name`                                                                                                        |
| `HttpModuleOptionsFactory` with `createHttpOptions()`      | `HttpClientOptionsFactory` with `createHttpClientOptions()`                                                                                                          |
| `extraProviders` in `registerAsync()`                      | A module that exports the providers, passed in `imports`                                                                                                             |
| One `HttpService` per importing module                     | Named clients, injected with `@InjectHttpClient(name)`                                                                                                               |
| `HttpService` methods, which return Observables            | `HttpClient` methods, which return Promises                                                                                                                          |
| `firstValueFrom(this.httpService.get(url))`                | `await this.http.get(url)`                                                                                                                                           |
| `post(url, data)`                                          | `post(url, options)`, with the data in `json` (or `body`)                                                                                                            |
| `params` in the request config                             | `query`. Arrays repeat the key, where Axios writes `key[]=`. In `@nestjs/http-client`, `params` fills `:name` path segments, and throws for a key that matches none. |
| `response.headers['etag']`                                 | `response.headers.get('etag')`                                                                                                                                       |
| `AxiosError` with `error.response?.status`                 | `HttpResponseError` with `error.status` and `error.body`                                                                                                             |
| `error.code === 'ECONNABORTED'`                            | `HttpTimeoutError`                                                                                                                                                   |
| `validateStatus: () => true`                               | `throwOnHttpError: false`                                                                                                                                            |
| `axiosRef` (the Axios instance)                            | No underlying instance. Use the client's options, or pass a custom function as `fetch`.                                                                              |
| `axiosRef.interceptors.request.use()` and `response.use()` | `interceptors`, with one function for both the request and the response                                                                                              |
| `httpsAgent` or `proxy`                                    | `dispatcher`, an undici `Agent` or `ProxyAgent`                                                                                                                      |
| `maxRedirects: 0`                                          | `redirect: 'manual'`                                                                                                                                                 |
| No retries, unless you add `axios-retry`                   | Retries on by default for idempotent methods. `retry: false` restores the Axios behavior.                                                                            |
| `timeout` for the whole request                            | `timeout` per attempt, also as a string such as `'5s'`                                                                                                               |
| `onUploadProgress`, `onDownloadProgress`                   | No equivalent. Count the bytes of a stream instead.                                                                                                                  |

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/application/http-client.md)

----
url: https://docs.nestjs.com/v10/graphql/generating-sdl
----

* [Generating SDL](https://docs.nestjs.com/v10/graphql/generating-sdl#generating-sdl)
* [Usage](https://docs.nestjs.com/v10/graphql/generating-sdl#usage)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/schema-generator.md "Suggest Edits")

### Generating SDL

> **Warning** This chapter applies only to the code first approach.

To manually generate a GraphQL SDL schema (i.e., without running an application, connecting to the database, hooking up resolvers, etc.), use the `GraphQLSchemaBuilderModule`.

```typescript

async function generateSchema() {
  const app = await NestFactory.create(GraphQLSchemaBuilderModule);
  await app.init();

  const gqlSchemaFactory = app.get(GraphQLSchemaFactory);
  const schema = await gqlSchemaFactory.create([RecipesResolver]);
  console.log(printSchema(schema));
}
```

> **Hint** The `GraphQLSchemaBuilderModule` and `GraphQLSchemaFactory` are imported from the `@nestjs/graphql` package. The `printSchema` function is imported from the `graphql` package.

#### Usage[#](/graphql/generating-sdl#usage)

The `gqlSchemaFactory.create()` method takes an array of resolver class references. For example:

```typescript

const schema = await gqlSchemaFactory.create([
  RecipesResolver,
  AuthorsResolver,
  PostsResolvers,
]);
```

It also takes a second optional argument with an array of scalar classes:

```typescript

const schema = await gqlSchemaFactory.create(
  [RecipesResolver, AuthorsResolver, PostsResolvers],
  [DurationScalar, DateScalar],
);
```

Lastly, you can pass an options object:

```typescript

const schema = await gqlSchemaFactory.create([RecipesResolver], {
  skipCheck: true,
  orphanedTypes: [],
});
```

* `skipCheck`: ignore schema validation; boolean, defaults to `false`
* `orphanedTypes`: list of classes that are not explicitly referenced (not part of the object graph) to be generated. Normally, if a class is declared but isn't otherwise referenced in the graph, it's omitted. The property value is an array of class references.

----
url: https://docs.nestjs.com/v9/recipes/router-module
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Router module](https://docs.nestjs.com/v9/recipes/router-module#router-module)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/recipes/router-module.md "Suggest Edits")

### Router module

> **Hint** This chapter is only relevant to HTTP-based applications.

In an HTTP application (for example, REST API), the route path for a handler is determined by concatenating the (optional) prefix declared for the controller (inside the `@Controller` decorator), and any path specified in the method's decorator (e.g, `@Get('users')`). You can learn more about that in [this section](/controllers#routing). Additionally, you can define a [global prefix](/v9/faq/global-prefix) for all routes registered in your application, or enable [versioning](/v9/techniques/versioning).

Also, there are edge-cases when defining a prefix at a module-level (and so for all controllers registered inside that module) may come in handy. For example, imagine a REST application that exposes several different endpoints being used by a specific portion of your application called "Dashboard". In such a case, instead of repeating the `/dashboard` prefix within each controller, you could use a utility `RouterModule` module, as follows:

```typescript

@Module({
  imports: [
    DashboardModule,
    RouterModule.register([
      {
        path: 'dashboard',
        module: DashboardModule,
      },
    ]),
  ],
})
export class AppModule {}
```

> **Hint** The `RouterModule` class is exported from the `@nestjs/core` package.

In addition, you can define hierarchical structures. This means each module can have `children` modules. The children modules will inherit their parent's prefix. In the following example, we'll register the `AdminModule` as a parent module of `DashboardModule` and `MetricsModule`.

```typescript

@Module({
  imports: [
    AdminModule,
    DashboardModule,
    MetricsModule,
    RouterModule.register([
      {
        path: 'admin',
        module: AdminModule,
        children: [
          {
            path: 'dashboard',
            module: DashboardModule,
          },
          {
            path: 'metrics',
            module: MetricsModule,
          },
        ],
      },
    ])
  ],
});
```

> **Hint** This feature should be used very carefully, as overusing it can make code difficult to maintain over time.

In the example above, any controller registered inside the `DashboardModule` will have an extra `/admin/dashboard` prefix (as the module concatenates paths from top to bottom - recursively - parent to children). Likewise, each controller defined inside the `MetricsModule` will have an additional module-level prefix `/admin/metrics`.

----
url: https://docs.nestjs.com/v8/security/authentication
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Authentication](https://docs.nestjs.com/v8/security/authentication#authentication)
* [Authentication requirements](https://docs.nestjs.com/v8/security/authentication#authentication-requirements)
* [Implementing Passport strategies](https://docs.nestjs.com/v8/security/authentication#implementing-passport-strategies)
* [Implementing Passport local](https://docs.nestjs.com/v8/security/authentication#implementing-passport-local)
* [Built-in Passport Guards](https://docs.nestjs.com/v8/security/authentication#built-in-passport-guards)
* [Login route](https://docs.nestjs.com/v8/security/authentication#login-route)
* [JWT functionality](https://docs.nestjs.com/v8/security/authentication#jwt-functionality)
* [Implementing Passport JWT](https://docs.nestjs.com/v8/security/authentication#implementing-passport-jwt)
* [Implement protected route and JWT strategy guards](https://docs.nestjs.com/v8/security/authentication#implement-protected-route-and-jwt-strategy-guards)
* [Example](https://docs.nestjs.com/v8/security/authentication#example)
* [Extending guards](https://docs.nestjs.com/v8/security/authentication#extending-guards)
* [Enable authentication globally](https://docs.nestjs.com/v8/security/authentication#enable-authentication-globally)
* [Request-scoped strategies](https://docs.nestjs.com/v8/security/authentication#request-scoped-strategies)
* [Customize Passport](https://docs.nestjs.com/v8/security/authentication#customize-passport)
* [Named strategies](https://docs.nestjs.com/v8/security/authentication#named-strategies)
* [GraphQL](https://docs.nestjs.com/v8/security/authentication#graphql)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/security/authentication.md "Suggest Edits")

```bash

$ npm install --save @nestjs/passport passport passport-local
$ npm install --save-dev @types/passport-local
```

> **Notice** For **any** Passport strategy you choose, you'll always need the `@nestjs/passport` and `passport` packages. Then, you'll need to install the strategy-specific package (e.g., `passport-jwt` or `passport-local`) that implements the particular authentication strategy you are building. In addition, you can also install the type definitions for any Passport strategy, as shown above with `@types/passport-local`, which provides assistance while writing TypeScript code.

```bash

$ nest g module auth
$ nest g service auth
```

As we implement the `AuthService`, we'll find it useful to encapsulate user operations in a `UsersService`, so let's generate that module and service now:

```bash

$ nest g module users
$ nest g service users
```

Replace the default contents of these generated files as shown below. For our sample app, the `UsersService` simply maintains a hard-coded in-memory list of users, and a find method to retrieve one by username. In a real app, this is where you'd build your user model and persistence layer, using your library of choice (e.g., TypeORM, Sequelize, Mongoose, etc.).

users/users.service.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';

// This should be a real class/interface representing a user entity
export type User = any;

@Injectable()
export class UsersService {
  private readonly users = [
    {
      userId: 1,
      username: 'john',
      password: 'changeme',
    },
    {
      userId: 2,
      username: 'maria',
      password: 'guess',
    },
  ];

  async findOne(username: string): Promise<User | undefined> {
    return this.users.find(user => user.username === username);
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';

@Injectable()
export class UsersService {
  constructor() {
    this.users = [
      {
        userId: 1,
        username: 'john',
        password: 'changeme',
      },
      {
        userId: 2,
        username: 'maria',
        password: 'guess',
      },
    ];
  }

  async findOne(username) {
    return this.users.find(user => user.username === username);
  }
}
```

In the `UsersModule`, the only change needed is to add the `UsersService` to the exports array of the `@Module` decorator so that it is visible outside this module (we'll soon use it in our `AuthService`).

users/users.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { UsersService } from './users.service';

@Module({
  providers: [UsersService],
  exports: [UsersService],
})
export class UsersModule {}
```

```typescript

import { Module } from '@nestjs/common';
import { UsersService } from './users.service';

@Module({
  providers: [UsersService],
  exports: [UsersService],
})
export class UsersModule {}
```

Our `AuthService` has the job of retrieving a user and verifying the password. We create a `validateUser()` method for this purpose. In the code below, we use a convenient ES6 spread operator to strip the password property from the user object before returning it. We'll be calling into the `validateUser()` method from our Passport local strategy in a moment.

auth/auth.service.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { UsersService } from '../users/users.service';

@Injectable()
export class AuthService {
  constructor(private usersService: UsersService) {}

  async validateUser(username: string, pass: string): Promise<any> {
    const user = await this.usersService.findOne(username);
    if (user && user.password === pass) {
      const { password, ...result } = user;
      return result;
    }
    return null;
  }
}
```

```typescript

import { Injectable, Dependencies } from '@nestjs/common';
import { UsersService } from '../users/users.service';

@Injectable()
@Dependencies(UsersService)
export class AuthService {
  constructor(usersService) {
    this.usersService = usersService;
  }

  async validateUser(username, pass) {
    const user = await this.usersService.findOne(username);
    if (user && user.password === pass) {
      const { password, ...result } = user;
      return result;
    }
    return null;
  }
}
```

> **Warning** Of course in a real application, you wouldn't store a password in plain text. You'd instead use a library like [bcrypt](https://github.com/kelektiv/node.bcrypt.js#readme), with a salted one-way hash algorithm. With that approach, you'd only store hashed passwords, and then compare the stored password to a hashed version of the **incoming** password, thus never storing or exposing user passwords in plain text. To keep our sample app simple, we violate that absolute mandate and use plain text. **Don't do this in your real app!**

Now, we update our `AuthModule` to import the `UsersModule`.

auth/auth.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { UsersModule } from '../users/users.module';

@Module({
  imports: [UsersModule],
  providers: [AuthService],
})
export class AuthModule {}
```

```typescript

import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { UsersModule } from '../users/users.module';

@Module({
  imports: [UsersModule],
  providers: [AuthService],
})
export class AuthModule {}
```

#### Implementing Passport local[#](/security/authentication#implementing-passport-local)

Now we can implement our Passport **local authentication strategy**. Create a file called `local.strategy.ts` in the `auth` folder, and add the following code:

auth/local.strategy.ts

JS TS

```typescript

import { Strategy } from 'passport-local';
import { PassportStrategy } from '@nestjs/passport';
import { Injectable, UnauthorizedException } from '@nestjs/common';
import { AuthService } from './auth.service';

@Injectable()
export class LocalStrategy extends PassportStrategy(Strategy) {
  constructor(private authService: AuthService) {
    super();
  }

  async validate(username: string, password: string): Promise<any> {
    const user = await this.authService.validateUser(username, password);
    if (!user) {
      throw new UnauthorizedException();
    }
    return user;
  }
}
```

```typescript

import { Strategy } from 'passport-local';
import { PassportStrategy } from '@nestjs/passport';
import { Injectable, UnauthorizedException, Dependencies } from '@nestjs/common';
import { AuthService } from './auth.service';

@Injectable()
@Dependencies(AuthService)
export class LocalStrategy extends PassportStrategy(Strategy) {
  constructor(authService) {
    super();
    this.authService = authService;
  }

  async validate(username, password) {
    const user = await this.authService.validateUser(username, password);
    if (!user) {
      throw new UnauthorizedException();
    }
    return user;
  }
}
```

We've followed the recipe described earlier for all Passport strategies. In our use case with passport-local, there are no configuration options, so our constructor simply calls `super()`, without an options object.

> **Hint** We can pass an options object in the call to `super()` to customize the behavior of the passport strategy. In this example, the passport-local strategy by default expects properties called `username` and `password` in the request body. Pass an options object to specify different property names, for example: `super({ usernameField: 'email' })`. See the [Passport documentation](http://www.passportjs.org/docs/configure/) for more information.

We've also implemented the `validate()` method. For each strategy, Passport will call the verify function (implemented with the `validate()` method in `@nestjs/passport`) using an appropriate strategy-specific set of parameters. For the local-strategy, Passport expects a `validate()` method with the following signature: `validate(username: string, password:string): any`.

Most of the validation work is done in our `AuthService` (with the help of our `UsersService`), so this method is quite straightforward. The `validate()` method for **any** Passport strategy will follow a similar pattern, varying only in the details of how credentials are represented. If a user is found and the credentials are valid, the user is returned so Passport can complete its tasks (e.g., creating the `user` property on the `Request` object), and the request handling pipeline can continue. If it's not found, we throw an exception and let our [exceptions layer](exception-filters) handle it.

Typically, the only significant difference in the `validate()` method for each strategy is **how** you determine if a user exists and is valid. For example, in a JWT strategy, depending on requirements, we may evaluate whether the `userId` carried in the decoded token matches a record in our user database, or matches a list of revoked tokens. Hence, this pattern of sub-classing and implementing strategy-specific validation is consistent, elegant and extensible.

We need to configure our `AuthModule` to use the Passport features we just defined. Update `auth.module.ts` to look like this:

auth/auth.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { UsersModule } from '../users/users.module';
import { PassportModule } from '@nestjs/passport';
import { LocalStrategy } from './local.strategy';

@Module({
  imports: [UsersModule, PassportModule],
  providers: [AuthService, LocalStrategy],
})
export class AuthModule {}
```

```typescript

import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { UsersModule } from '../users/users.module';
import { PassportModule } from '@nestjs/passport';
import { LocalStrategy } from './local.strategy';

@Module({
  imports: [UsersModule, PassportModule],
  providers: [AuthService, LocalStrategy],
})
export class AuthModule {}
```

* 80+ chapters
* 5+ hours of videos
* Official certificate
* Deep-dive sessions

[Explore official courses](https://courses.nestjs.com "Courses | NestJS - A node.js framework built on top of TypeScript")

#### Login route[#](/security/authentication#login-route)

With the strategy in place, we can now implement a bare-bones `/auth/login` route, and apply the built-in Guard to initiate the passport-local flow.

Open the `app.controller.ts` file and replace its contents with the following:

app.controller.ts

JS TS

```typescript

import { Controller, Request, Post, UseGuards } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';

@Controller()
export class AppController {
  @UseGuards(AuthGuard('local'))
  @Post('auth/login')
  async login(@Request() req) {
    return req.user;
  }
}
```

```typescript

import { Controller, Bind, Request, Post, UseGuards } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';

@Controller()
export class AppController {
  @UseGuards(AuthGuard('local'))
  @Post('auth/login')
  @Bind(Request())
  async login(req) {
    return req.user;
  }
}
```

With `@UseGuards(AuthGuard('local'))` we are using an `AuthGuard` that `@nestjs/passport`**automatically provisioned** for us when we extended the passport-local strategy. Let's break that down. Our Passport local strategy has a default name of `'local'`. We reference that name in the `@UseGuards()` decorator to associate it with code supplied by the `passport-local` package. This is used to disambiguate which strategy to invoke in case we have multiple Passport strategies in our app (each of which may provision a strategy-specific `AuthGuard`). While we only have one such strategy so far, we'll shortly add a second, so this is needed for disambiguation.

In order to test our route we'll have our `/auth/login` route simply return the user for now. This also lets us demonstrate another Passport feature: Passport automatically creates a `user` object, based on the value we return from the `validate()` method, and assigns it to the `Request` object as `req.user`. Later, we'll replace this with code to create and return a JWT instead.

Since these are API routes, we'll test them using the commonly available [cURL](https://curl.haxx.se/) library. You can test with any of the `user` objects hard-coded in the `UsersService`.

```bash

$ # POST to /auth/login
$ curl -X POST http://localhost:3000/auth/login -d '{"username": "john", "password": "changeme"}' -H "Content-Type: application/json"
$ # result -> {"userId":1,"username":"john"}
```

While this works, passing the strategy name directly to the `AuthGuard()` introduces magic strings in the codebase. Instead, we recommend creating your own class, as shown below:

auth/local-auth.guard.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';

@Injectable()
export class LocalAuthGuard extends AuthGuard('local') {}
```

Now, we can update the `/auth/login` route handler and use the `LocalAuthGuard` instead:

```typescript

@UseGuards(LocalAuthGuard)
@Post('auth/login')
async login(@Request() req) {
  return req.user;
}
```

#### JWT functionality[#](/security/authentication#jwt-functionality)

We're ready to move on to the JWT portion of our auth system. Let's review and refine our requirements:

* Allow users to authenticate with username/password, returning a JWT for use in subsequent calls to protected API endpoints. We're well on our way to meeting this requirement. To complete it, we'll need to write the code that issues a JWT.
* Create API routes which are protected based on the presence of a valid JWT as a bearer token

We'll need to install a couple more packages to support our JWT requirements:

```bash

$ npm install --save @nestjs/jwt passport-jwt
$ npm install --save-dev @types/passport-jwt
```

```typescript

import { Injectable } from '@nestjs/common';
import { UsersService } from '../users/users.service';
import { JwtService } from '@nestjs/jwt';

@Injectable()
export class AuthService {
  constructor(
    private usersService: UsersService,
    private jwtService: JwtService
  ) {}

  async validateUser(username: string, pass: string): Promise<any> {
    const user = await this.usersService.findOne(username);
    if (user && user.password === pass) {
      const { password, ...result } = user;
      return result;
    }
    return null;
  }

  async login(user: any) {
    const payload = { username: user.username, sub: user.userId };
    return {
      access_token: this.jwtService.sign(payload),
    };
  }
}
```

```typescript

import { Injectable, Dependencies } from '@nestjs/common';
import { UsersService } from '../users/users.service';
import { JwtService } from '@nestjs/jwt';

@Dependencies(UsersService, JwtService)
@Injectable()
export class AuthService {
  constructor(usersService, jwtService) {
    this.usersService = usersService;
    this.jwtService = jwtService;
  }

  async validateUser(username, pass) {
    const user = await this.usersService.findOne(username);
    if (user && user.password === pass) {
      const { password, ...result } = user;
      return result;
    }
    return null;
  }

  async login(user) {
    const payload = { username: user.username, sub: user.userId };
    return {
      access_token: this.jwtService.sign(payload),
    };
  }
}
```

We're using the `@nestjs/jwt` library, which supplies a `sign()` function to generate our JWT from a subset of the `user` object properties, which we then return as a simple object with a single `access_token` property. Note: we choose a property name of `sub` to hold our `userId` value to be consistent with JWT standards. Don't forget to inject the JwtService provider into the `AuthService`.

We now need to update the `AuthModule` to import the new dependencies and configure the `JwtModule`.

First, create `constants.ts` in the `auth` folder, and add the following code:

auth/constants.ts

JS TS

```typescript

export const jwtConstants = {
  secret: 'secretKey',
};
```

```typescript

export const jwtConstants = {
  secret: 'secretKey',
};
```

We'll use this to share our key between the JWT signing and verifying steps.

> **Warning****Do not expose this key publicly**. We have done so here to make it clear what the code is doing, but in a production system **you must protect this key** using appropriate measures such as a secrets vault, environment variable, or configuration service.

Now, open `auth.module.ts` in the `auth` folder and update it to look like this:

auth/auth.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { LocalStrategy } from './local.strategy';
import { UsersModule } from '../users/users.module';
import { PassportModule } from '@nestjs/passport';
import { JwtModule } from '@nestjs/jwt';
import { jwtConstants } from './constants';

@Module({
  imports: [
    UsersModule,
    PassportModule,
    JwtModule.register({
      secret: jwtConstants.secret,
      signOptions: { expiresIn: '60s' },
    }),
  ],
  providers: [AuthService, LocalStrategy],
  exports: [AuthService],
})
export class AuthModule {}
```

```typescript

import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { LocalStrategy } from './local.strategy';
import { UsersModule } from '../users/users.module';
import { PassportModule } from '@nestjs/passport';
import { JwtModule } from '@nestjs/jwt';
import { jwtConstants } from './constants';

@Module({
  imports: [
    UsersModule,
    PassportModule,
    JwtModule.register({
      secret: jwtConstants.secret,
      signOptions: { expiresIn: '60s' },
    }),
  ],
  providers: [AuthService, LocalStrategy],
  exports: [AuthService],
})
export class AuthModule {}
```

We configure the `JwtModule` using `register()`, passing in a configuration object. See [here](https://github.com/nestjs/jwt/blob/master/README.md) for more on the Nest `JwtModule` and [here](https://github.com/auth0/node-jsonwebtoken#usage) for more details on the available configuration options.

Now we can update the `/auth/login` route to return a JWT.

app.controller.ts

JS TS

```typescript

import { Controller, Request, Post, UseGuards } from '@nestjs/common';
import { LocalAuthGuard } from './auth/local-auth.guard';
import { AuthService } from './auth/auth.service';

@Controller()
export class AppController {
  constructor(private authService: AuthService) {}

  @UseGuards(LocalAuthGuard)
  @Post('auth/login')
  async login(@Request() req) {
    return this.authService.login(req.user);
  }
}
```

```typescript

import { Controller, Bind, Request, Post, UseGuards } from '@nestjs/common';
import { LocalAuthGuard } from './auth/local-auth.guard';
import { AuthService } from './auth/auth.service';

@Controller()
export class AppController {
  constructor(private authService: AuthService) {}

  @UseGuards(LocalAuthGuard)
  @Post('auth/login')
  @Bind(Request())
  async login(req) {
    return this.authService.login(req.user);
  }
}
```

Let's go ahead and test our routes using cURL again. You can test with any of the `user` objects hard-coded in the `UsersService`.

```bash

$ # POST to /auth/login
$ curl -X POST http://localhost:3000/auth/login -d '{"username": "john", "password": "changeme"}' -H "Content-Type: application/json"
$ # result -> {"access_token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."}
$ # Note: above JWT truncated
```

#### Implementing Passport JWT[#](/security/authentication#implementing-passport-jwt)

We can now address our final requirement: protecting endpoints by requiring a valid JWT be present on the request. Passport can help us here too. It provides the [passport-jwt](https://github.com/mikenicholson/passport-jwt) strategy for securing RESTful endpoints with JSON Web Tokens. Start by creating a file called `jwt.strategy.ts` in the `auth` folder, and add the following code:

auth/jwt.strategy.ts

JS TS

```typescript

import { ExtractJwt, Strategy } from 'passport-jwt';
import { PassportStrategy } from '@nestjs/passport';
import { Injectable } from '@nestjs/common';
import { jwtConstants } from './constants';

@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
  constructor() {
    super({
      jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
      ignoreExpiration: false,
      secretOrKey: jwtConstants.secret,
    });
  }

  async validate(payload: any) {
    return { userId: payload.sub, username: payload.username };
  }
}
```

```typescript

import { ExtractJwt, Strategy } from 'passport-jwt';
import { PassportStrategy } from '@nestjs/passport';
import { Injectable } from '@nestjs/common';
import { jwtConstants } from './constants';

@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
  constructor() {
    super({
      jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
      ignoreExpiration: false,
      secretOrKey: jwtConstants.secret,
    });
  }

  async validate(payload) {
    return { userId: payload.sub, username: payload.username };
  }
}
```

```typescript

import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { LocalStrategy } from './local.strategy';
import { JwtStrategy } from './jwt.strategy';
import { UsersModule } from '../users/users.module';
import { PassportModule } from '@nestjs/passport';
import { JwtModule } from '@nestjs/jwt';
import { jwtConstants } from './constants';

@Module({
  imports: [
    UsersModule,
    PassportModule,
    JwtModule.register({
      secret: jwtConstants.secret,
      signOptions: { expiresIn: '60s' },
    }),
  ],
  providers: [AuthService, LocalStrategy, JwtStrategy],
  exports: [AuthService],
})
export class AuthModule {}
```

```typescript

import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { LocalStrategy } from './local.strategy';
import { JwtStrategy } from './jwt.strategy';
import { UsersModule } from '../users/users.module';
import { PassportModule } from '@nestjs/passport';
import { JwtModule } from '@nestjs/jwt';
import { jwtConstants } from './constants';

@Module({
  imports: [
    UsersModule,
    PassportModule,
    JwtModule.register({
      secret: jwtConstants.secret,
      signOptions: { expiresIn: '60s' },
    }),
  ],
  providers: [AuthService, LocalStrategy, JwtStrategy],
  exports: [AuthService],
})
export class AuthModule {}
```

By importing the same secret used when we signed the JWT, we ensure that the **verify** phase performed by Passport, and the **sign** phase performed in our AuthService, use a common secret.

Finally, we define the `JwtAuthGuard` class which extends the built-in `AuthGuard`:

auth/jwt-auth.guard.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';

@Injectable()
export class JwtAuthGuard extends AuthGuard('jwt') {}
```

#### Implement protected route and JWT strategy guards[#](/security/authentication#implement-protected-route-and-jwt-strategy-guards)

We can now implement our protected route and its associated Guard.

Open the `app.controller.ts` file and update it as shown below:

app.controller.ts

JS TS

```typescript

import { Controller, Get, Request, Post, UseGuards } from '@nestjs/common';
import { JwtAuthGuard } from './auth/jwt-auth.guard';
import { LocalAuthGuard } from './auth/local-auth.guard';
import { AuthService } from './auth/auth.service';

@Controller()
export class AppController {
  constructor(private authService: AuthService) {}

  @UseGuards(LocalAuthGuard)
  @Post('auth/login')
  async login(@Request() req) {
    return this.authService.login(req.user);
  }

  @UseGuards(JwtAuthGuard)
  @Get('profile')
  getProfile(@Request() req) {
    return req.user;
  }
}
```

```typescript

import { Controller, Dependencies, Bind, Get, Request, Post, UseGuards } from '@nestjs/common';
import { JwtAuthGuard } from './auth/jwt-auth.guard';
import { LocalAuthGuard } from './auth/local-auth.guard';
import { AuthService } from './auth/auth.service';

@Dependencies(AuthService)
@Controller()
export class AppController {
  constructor(authService) {
    this.authService = authService;
  }

  @UseGuards(LocalAuthGuard)
  @Post('auth/login')
  @Bind(Request())
  async login(req) {
    return this.authService.login(req.user);
  }

  @UseGuards(JwtAuthGuard)
  @Get('profile')
  @Bind(Request())
  getProfile(req) {
    return req.user;
  }
}
```

Once again, we're applying the `AuthGuard` that the `@nestjs/passport` module has automatically provisioned for us when we configured the passport-jwt module. This Guard is referenced by its default name, `jwt`. When our `GET /profile` route is hit, the Guard will automatically invoke our passport-jwt custom configured logic, validating the JWT, and assigning the `user` property to the `Request` object.

Ensure the app is running, and test the routes using `cURL`.

```bash

$ # GET /profile
$ curl http://localhost:3000/profile
$ # result -> {"statusCode":401,"message":"Unauthorized"}

$ # POST /auth/login
$ curl -X POST http://localhost:3000/auth/login -d '{"username": "john", "password": "changeme"}' -H "Content-Type: application/json"
$ # result -> {"access_token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2Vybm... }

$ # GET /profile using access_token returned from previous step as bearer code
$ curl http://localhost:3000/profile -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2Vybm..."
$ # result -> {"userId":1,"username":"john"}
```

Note that in the `AuthModule`, we configured the JWT to have an expiration of `60 seconds`. This is probably too short an expiration, and dealing with the details of token expiration and refresh is beyond the scope of this article. However, we chose that to demonstrate an important quality of JWTs and the passport-jwt strategy. If you wait 60 seconds after authenticating before attempting a `GET /profile` request, you'll receive a `401 Unauthorized` response. This is because Passport automatically checks the JWT for its expiration time, saving you the trouble of doing so in your application.

We've now completed our JWT authentication implementation. JavaScript clients (such as Angular/React/Vue), and other JavaScript apps, can now authenticate and communicate securely with our API Server.

#### Example[#](/security/authentication#example)

You can find a complete version of the code in this chapter [here](https://github.com/nestjs/nest/tree/master/sample/19-auth-jwt).

#### Extending guards[#](/security/authentication#extending-guards)

In most cases, using a provided `AuthGuard` class is sufficient. However, there might be use-cases when you would like to simply extend the default error handling or authentication logic. For this, you can extend the built-in class and override methods within a sub-class.

```typescript

import {
  ExecutionContext,
  Injectable,
  UnauthorizedException,
} from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';

@Injectable()
export class JwtAuthGuard extends AuthGuard('jwt') {
  canActivate(context: ExecutionContext) {
    // Add your custom authentication logic here
    // for example, call super.logIn(request) to establish a session.
    return super.canActivate(context);
  }

  handleRequest(err, user, info) {
    // You can throw an exception based on either "info" or "err" arguments
    if (err || !user) {
      throw err || new UnauthorizedException();
    }
    return user;
  }
}
```

In addition to extending the default error handling and authentication logic, we can allow authentication to go through a chain of strategies. The first strategy to succeed, redirect, or error will halt the chain. Authentication failures will proceed through each strategy in series, ultimately failing if all strategies fail.

```typescript

export class JwtAuthGuard extends AuthGuard(['strategy_jwt_1', 'strategy_jwt_2', '...']) { ... }
```

#### Enable authentication globally[#](/security/authentication#enable-authentication-globally)

If the vast majority of your endpoints should be protected by default, you can register the authentication guard as a [global guard](/guards#binding-guards) and instead of using `@UseGuards()` decorator on top of each controller, you could simply flag which routes should be public.

First, register the `JwtAuthGuard` as a global guard using the following construction (in any module):

```typescript

providers: [
  {
    provide: APP_GUARD,
    useClass: JwtAuthGuard,
  },
],
```

With this in place, Nest will automatically bind `JwtAuthGuard` to all endpoints.

Now we must provide a mechanism for declaring routes as public. For this, we can create a custom decorator using the `SetMetadata` decorator factory function.

```typescript

import { SetMetadata } from '@nestjs/common';

export const IS_PUBLIC_KEY = 'isPublic';
export const Public = () => SetMetadata(IS_PUBLIC_KEY, true);
```

In the file above, we exported two constants. One being our metadata key named `IS_PUBLIC_KEY`, and the other being our new decorator itself that we’re going to call `Public` (you can alternatively name it `SkipAuth` or `AllowAnon`, whatever fits your project).

Now that we have a custom `@Public()` decorator, we can use it to decorate any method, as follows:

```typescript

@Public()
@Get()
findAll() {
  return [];
}
```

Lastly, we need the `JwtAuthGuard` to return `true` when the `"isPublic"` metadata is found. For this, we'll use the `Reflector` class (read more [here](/guards#putting-it-all-together)).

```typescript

@Injectable()
export class JwtAuthGuard extends AuthGuard('jwt') {
  constructor(private reflector: Reflector) {
    super();
  }

  canActivate(context: ExecutionContext) {
    const isPublic = this.reflector.getAllAndOverride<boolean>(IS_PUBLIC_KEY, [
      context.getHandler(),
      context.getClass(),
    ]);
    if (isPublic) {
      return true;
    }
    return super.canActivate(context);
  }
}
```

#### Request-scoped strategies[#](/security/authentication#request-scoped-strategies)

The passport API is based on registering strategies to the global instance of the library. Therefore strategies are not designed to have request-dependent options or to be dynamically instantiated per request (read more about the [request-scoped](/v8/fundamentals/injection-scopes) providers). When you configure your strategy to be request-scoped, Nest will never instantiate it since it's not tied to any specific route. There is no physical way to determine which "request-scoped" strategies should be executed per request.

However, there are ways to dynamically resolve request-scoped providers within the strategy. For this, we leverage the [module reference](/v8/fundamentals/module-ref) feature.

First, open the `local.strategy.ts` file and inject the `ModuleRef` in the normal way:

```typescript

constructor(private moduleRef: ModuleRef) {
  super({
    passReqToCallback: true,
  });
}
```

> **Hint** The `ModuleRef` class is imported from the `@nestjs/core` package.

Be sure to set the `passReqToCallback` configuration property to `true`, as shown above.

In the next step, the request instance will be used to obtain the current context identifier, instead of generating a new one (read more about request context [here](/fundamentals/module-ref#getting-current-sub-tree)).

Now, inside the `validate()` method of the `LocalStrategy` class, use the `getByRequest()` method of the `ContextIdFactory` class to create a context id based on the request object, and pass this to the `resolve()` call:

```typescript

async validate(
  request: Request,
  username: string,
  password: string,
) {
  const contextId = ContextIdFactory.getByRequest(request);
  // "AuthService" is a request-scoped provider
  const authService = await this.moduleRef.resolve(AuthService, contextId);
  ...
}
```

In the example above, the `resolve()` method will asynchronously return the request-scoped instance of the `AuthService` provider (we assumed that `AuthService` is marked as a request-scoped provider).

#### Customize Passport[#](/security/authentication#customize-passport)

Any standard Passport customization options can be passed the same way, using the `register()` method. The available options depend on the strategy being implemented. For example:

```typescript

PassportModule.register({ session: true });
```

You can also pass strategies an options object in their constructors to configure them. For the local strategy you can pass e.g.:

```typescript

constructor(private authService: AuthService) {
  super({
    usernameField: 'email',
    passwordField: 'password',
  });
}
```

Take a look at the official [Passport Website](http://www.passportjs.org/docs/oauth/) for property names.

#### Named strategies[#](/security/authentication#named-strategies)

When implementing a strategy, you can provide a name for it by passing a second argument to the `PassportStrategy` function. If you don't do this, each strategy will have a default name (e.g., 'jwt' for jwt-strategy):

```typescript

export class JwtStrategy extends PassportStrategy(Strategy, 'myjwt')
```

Then, you refer to this via a decorator like `@UseGuards(AuthGuard('myjwt'))`.

#### GraphQL[#](/security/authentication#graphql)

In order to use an AuthGuard with [GraphQL](https://docs.nestjs.com/graphql/quick-start), extend the built-in AuthGuard class and override the getRequest() method.

```typescript

@Injectable()
export class GqlAuthGuard extends AuthGuard('jwt') {
  getRequest(context: ExecutionContext) {
    const ctx = GqlExecutionContext.create(context);
    return ctx.getContext().req;
  }
}
```

To get the current authenticated user in your graphql resolver, you can define a `@CurrentUser()` decorator:

```typescript

import { createParamDecorator, ExecutionContext } from '@nestjs/common';
import { GqlExecutionContext } from '@nestjs/graphql';

export const CurrentUser = createParamDecorator(
  (data: unknown, context: ExecutionContext) => {
    const ctx = GqlExecutionContext.create(context);
    return ctx.getContext().req.user;
  },
);
```

To use above decorator in your resolver, be sure to include it as a parameter of your query or mutation:

```typescript

@Query(returns => User)
@UseGuards(GqlAuthGuard)
whoAmI(@CurrentUser() user: User) {
  return this.usersService.findById(user.id);
}
```

----
url: https://docs.nestjs.com/v11/techniques/validation
----

* [Validation](https://docs.nestjs.com/v11/techniques/validation#validation)
* [Overview](https://docs.nestjs.com/v11/techniques/validation#overview)
* [Using the built-in ValidationPipe](https://docs.nestjs.com/v11/techniques/validation#using-the-built-in-validationpipe)
* [Auto-validation](https://docs.nestjs.com/v11/techniques/validation#auto-validation)
* [Disable detailed errors](https://docs.nestjs.com/v11/techniques/validation#disable-detailed-errors)
* [Stripping properties](https://docs.nestjs.com/v11/techniques/validation#stripping-properties)
* [Transform payload objects](https://docs.nestjs.com/v11/techniques/validation#transform-payload-objects)
* [Explicit conversion](https://docs.nestjs.com/v11/techniques/validation#explicit-conversion)
* [Mapped types](https://docs.nestjs.com/v11/techniques/validation#mapped-types)
* [Parsing and validating arrays](https://docs.nestjs.com/v11/techniques/validation#parsing-and-validating-arrays)
* [WebSockets and Microservices](https://docs.nestjs.com/v11/techniques/validation#websockets-and-microservices)
* [Learn more](https://docs.nestjs.com/v11/techniques/validation#learn-more)

In the [Pipes](/v11/pipes) chapter, we went through the process of building simple pipes and binding them to controllers, methods or to the global app to demonstrate how the process works. Be sure to review that chapter to best understand the topics of this chapter. Here, we'll focus on various **real world** use cases of the `ValidationPipe`, and show how to use some of its advanced customization features.

#### Using the built-in ValidationPipe[#](/techniques/validation#using-the-built-in-validationpipe)

To begin using it, we first install the required dependency.

```bash

$ npm i --save class-validator class-transformer
```

> **Hint** The `ValidationPipe` is exported from the `@nestjs/common` package.

Because this pipe uses the [`class-validator`](https://github.com/typestack/class-validator) and [`class-transformer`](https://github.com/typestack/class-transformer) libraries, there are many options available. You configure these settings via a configuration object passed to the pipe. Following are the built-in options:

```typescript

export interface ValidationPipeOptions extends ValidatorOptions {
  transform?: boolean;
  disableErrorMessages?: boolean;
  exceptionFactory?: (errors: ValidationError[]) => any;
  errorFormat?: 'list' | 'grouped';
}
```

In addition to these, all `class-validator` options (inherited from the `ValidatorOptions` interface) are available:

| Option                    | Type                  | Description                                                                                                                                                                                                                                                                                                  |
| ------------------------- | --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `enableDebugMessages`     | `boolean`             | If set to true, validator will print extra warning messages to the console when something is not right.                                                                                                                                                                                                      |
| `skipUndefinedProperties` | `boolean`             | If set to true then validator will skip validation of all properties that are undefined in the validating object.                                                                                                                                                                                            |
| `skipNullProperties`      | `boolean`             | If set to true then validator will skip validation of all properties that are null in the validating object.                                                                                                                                                                                                 |
| `skipMissingProperties`   | `boolean`             | If set to true then validator will skip validation of all properties that are null or undefined in the validating object.                                                                                                                                                                                    |
| `whitelist`               | `boolean`             | If set to true, validator will strip validated (returned) object of any properties that do not use any validation decorators.                                                                                                                                                                                |
| `forbidNonWhitelisted`    | `boolean`             | If set to true, instead of stripping non-whitelisted properties validator will throw an exception.                                                                                                                                                                                                           |
| `forbidUnknownValues`     | `boolean`             | If set to true, attempts to validate unknown objects fail immediately.                                                                                                                                                                                                                                       |
| `disableErrorMessages`    | `boolean`             | If set to true, validation errors will not be returned to the client.                                                                                                                                                                                                                                        |
| `errorHttpStatusCode`     | `number`              | This setting allows you to specify which exception type will be used in case of an error. By default it throws `BadRequestException`.                                                                                                                                                                        |
| `exceptionFactory`        | `Function`            | Takes an array of the validation errors and returns an exception object to be thrown.                                                                                                                                                                                                                        |
| `groups`                  | `string[]`            | Groups to be used during validation of the object.                                                                                                                                                                                                                                                           |
| `always`                  | `boolean`             | Set default for `always` option of decorators. Default can be overridden in decorator options.                                                                                                                                                                                                               |
| `strictGroups`            | `boolean`             | If `groups` is not given or is empty, ignore decorators with at least one group.                                                                                                                                                                                                                             |
| `dismissDefaultMessages`  | `boolean`             | If set to true, the validation will not use default messages. Error message always will be `undefined` if its not explicitly set.                                                                                                                                                                            |
| `validationError.target`  | `boolean`             | Indicates if target should be exposed in `ValidationError`.                                                                                                                                                                                                                                                  |
| `validationError.value`   | `boolean`             | Indicates if validated value should be exposed in `ValidationError`.                                                                                                                                                                                                                                         |
| `stopAtFirstError`        | `boolean`             | When set to true, validation of the given property will stop after encountering the first error. Defaults to false.                                                                                                                                                                                          |
| `errorFormat`             | `'list' \| 'grouped'` | Specifies the format of validation error messages. `'list'` (default) returns an array of error message strings. `'grouped'` returns an object with property paths as keys and arrays of unmodified error messages as values, preserving custom validation messages without prepending parent path prefixes. |

> **Notice** Find more information about the `class-validator` package in its [repository](https://github.com/typestack/class-validator).

#### Auto-validation[#](/techniques/validation#auto-validation)

We'll start by binding `ValidationPipe` at the application level, thus ensuring all endpoints are protected from receiving incorrect data.

```typescript

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.useGlobalPipes(new ValidationPipe());
  await app.listen(process.env.PORT ?? 3000);
}
bootstrap();
```

To test our pipe, let's create a basic endpoint.

```typescript

@Post()
create(@Body() createUserDto: CreateUserDto) {
  return 'This action adds a new user';
}
```

> **Hint** Since TypeScript does not store metadata about **generics or interfaces**, when you use them in your DTOs, `ValidationPipe` may not be able to properly validate incoming data. For this reason, consider using concrete classes in your DTOs.

> **Hint** When importing your DTOs, you can't use a type-only import as that would be erased at runtime, i.e. remember to `import { CreateUserDto }` instead of `import type { CreateUserDto }`.

Now we can add a few validation rules in our `CreateUserDto`. We do this using decorators provided by the `class-validator` package, described in detail [here](https://github.com/typestack/class-validator#validation-decorators). In this fashion, any route that uses the `CreateUserDto` will automatically enforce these validation rules.

```typescript

import { IsEmail, IsNotEmpty } from 'class-validator';

export class CreateUserDto {
  @IsEmail()
  email: string;

  @IsNotEmpty()
  password: string;
}
```

With these rules in place, if a request hits our endpoint with an invalid `email` property in the request body, the application will automatically respond with a `400 Bad Request` code, along with the following response body:

```json

{
  "statusCode": 400,
  "error": "Bad Request",
  "message": ["email must be an email"]
}
```

In addition to validating request bodies, the `ValidationPipe` can be used with other request object properties as well. Imagine that we would like to accept `:id` in the endpoint path. To ensure that only numbers are accepted for this request parameter, we can use the following construct:

```typescript

@Get(':id')
findOne(@Param() params: FindOneParams) {
  return 'This action returns a user';
}
```

`FindOneParams`, like a DTO, is simply a class that defines validation rules using `class-validator`. It would look like this:

```typescript

import { IsNumberString } from 'class-validator';

export class FindOneParams {
  @IsNumberString()
  id: string;
}
```

#### Disable detailed errors[#](/techniques/validation#disable-detailed-errors)

Error messages can be helpful to explain what was incorrect in a request. However, some production environments prefer to disable detailed errors. Do this by passing an options object to the `ValidationPipe`:

```typescript

app.useGlobalPipes(
  new ValidationPipe({
    disableErrorMessages: true,
  }),
);
```

As a result, detailed error messages won't be displayed in the response body.

#### Stripping properties[#](/techniques/validation#stripping-properties)

Our `ValidationPipe` can also filter out properties that should not be received by the method handler. In this case, we can **whitelist** the acceptable properties, and any property not included in the whitelist is automatically stripped from the resulting object. For example, if our handler expects `email` and `password` properties, but a request also includes an `age` property, this property can be automatically removed from the resulting DTO. To enable such behavior, set `whitelist` to `true`.

```typescript

app.useGlobalPipes(
  new ValidationPipe({
    whitelist: true,
  }),
);
```

```typescript

@Post()
@UsePipes(new ValidationPipe({ transform: true }))
async create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

To enable this behavior globally, set the option on a global pipe:

```typescript

app.useGlobalPipes(
  new ValidationPipe({
    transform: true,
  }),
);
```

With the auto-transformation option enabled, the `ValidationPipe` will also perform conversion of primitive types. In the following example, the `findOne()` method takes one argument which represents an extracted `id` path parameter:

```typescript

@Get(':id')
findOne(@Param('id') id: number) {
  console.log(typeof id === 'number'); // true
  return 'This action returns a user';
}
```

By default, every path parameter and query parameter comes over the network as a `string`. In the above example, we specified the `id` type as a `number` (in the method signature). Therefore, the `ValidationPipe` will try to automatically convert a string identifier to a number.

#### Explicit conversion[#](/techniques/validation#explicit-conversion)

In the above section, we showed how the `ValidationPipe` can implicitly transform query and path parameters based on the expected type. However, this feature requires having auto-transformation enabled.

Alternatively (with auto-transformation disabled), you can explicitly cast values using the `ParseIntPipe` or `ParseBoolPipe` (note that `ParseStringPipe` is not needed because, as mentioned earlier, every path parameter and query parameter comes over the network as a `string` by default).

```typescript

@Get(':id')
findOne(
  @Param('id', ParseIntPipe) id: number,
  @Query('sort', ParseBoolPipe) sort: boolean,
) {
  console.log(typeof id === 'number'); // true
  console.log(typeof sort === 'boolean'); // true
  return 'This action returns a user';
}
```

> **Hint** The `ParseIntPipe` and `ParseBoolPipe` are exported from the `@nestjs/common` package.

#### Mapped types[#](/techniques/validation#mapped-types)

As you build out features like **CRUD** (Create/Read/Update/Delete) it's often useful to construct variants on a base entity type. Nest provides several utility functions that perform type transformations to make this task more convenient.

> **Warning** If your application uses the `@nestjs/swagger` package, see [this chapter](/v11/openapi/mapped-types) for more information about Mapped Types. Likewise, if you use the `@nestjs/graphql` package see [this chapter](/v11/graphql/mapped-types). Both packages heavily rely on types and so they require a different import to be used. Therefore, if you used `@nestjs/mapped-types` (instead of an appropriate one, either `@nestjs/swagger` or `@nestjs/graphql` depending on the type of your app), you may face various, undocumented side-effects.

When building input validation types (also called DTOs), it's often useful to build **create** and **update** variations on the same type. For example, the **create** variant may require all fields, while the **update** variant may make all fields optional.

Nest provides the `PartialType()` utility function to make this task easier and minimize boilerplate.

The `PartialType()` function returns a type (class) with all the properties of the input type set to optional. For example, suppose we have a **create** type as follows:

```typescript

export class CreateCatDto {
  name: string;
  age: number;
  breed: string;
}
```

By default, all of these fields are required. To create a type with the same fields, but with each one optional, use `PartialType()` passing the class reference (`CreateCatDto`) as an argument:

```typescript

export class UpdateCatDto extends PartialType(CreateCatDto) {}
```

> **Hint** The `PartialType()` function is imported from the `@nestjs/mapped-types` package.

The `PickType()` function constructs a new type (class) by picking a set of properties from an input type. For example, suppose we start with a type like:

```typescript

export class CreateCatDto {
  name: string;
  age: number;
  breed: string;
}
```

We can pick a set of properties from this class using the `PickType()` utility function:

```typescript

export class UpdateCatAgeDto extends PickType(CreateCatDto, ['age'] as const) {}
```

> **Hint** The `PickType()` function is imported from the `@nestjs/mapped-types` package.

The `OmitType()` function constructs a type by picking all properties from an input type and then removing a particular set of keys. For example, suppose we start with a type like:

```typescript

export class CreateCatDto {
  name: string;
  age: number;
  breed: string;
}
```

We can generate a derived type that has every property **except**`name` as shown below. In this construct, the second argument to `OmitType` is an array of property names.

```typescript

export class UpdateCatDto extends OmitType(CreateCatDto, ['name'] as const) {}
```

> **Hint** The `OmitType()` function is imported from the `@nestjs/mapped-types` package.

The `IntersectionType()` function combines two types into one new type (class). For example, suppose we start with two types like:

```typescript

export class CreateCatDto {
  name: string;
  breed: string;
}

export class AdditionalCatInfo {
  color: string;
}
```

We can generate a new type that combines all properties in both types.

```typescript

export class UpdateCatDto extends IntersectionType(
  CreateCatDto,
  AdditionalCatInfo,
) {}
```

> **Hint** The `IntersectionType()` function is imported from the `@nestjs/mapped-types` package.

The type mapping utility functions are composable. For example, the following will produce a type (class) that has all of the properties of the `CreateCatDto` type except for `name`, and those properties will be set to optional:

```typescript

export class UpdateCatDto extends PartialType(
  OmitType(CreateCatDto, ['name'] as const),
) {}
```

#### Parsing and validating arrays[#](/techniques/validation#parsing-and-validating-arrays)

TypeScript does not store metadata about generics or interfaces, so when you use them in your DTOs, `ValidationPipe` may not be able to properly validate incoming data. For instance, in the following code, `createUserDtos` won't be correctly validated:

```typescript

@Post()
createBulk(@Body() createUserDtos: CreateUserDto[]) {
  return 'This action adds new users';
}
```

To validate the array, create a dedicated class which contains a property that wraps the array, or use the `ParseArrayPipe`.

```typescript

@Post()
createBulk(
  @Body(new ParseArrayPipe({ items: CreateUserDto }))
  createUserDtos: CreateUserDto[],
) {
  return 'This action adds new users';
}
```

In addition, the `ParseArrayPipe` may come in handy when parsing query parameters. Let's consider a `findByIds()` method that returns users based on identifiers passed as query parameters.

```typescript

@Get()
findByIds(
  @Query('ids', new ParseArrayPipe({ items: Number, separator: ',' }))
  ids: number[],
) {
  return 'This action returns users by ids';
}
```

This construction validates the incoming query parameters from an HTTP `GET` request like the following:

```bash

GET /?ids=1,2,3
```

#### WebSockets and Microservices[#](/techniques/validation#websockets-and-microservices)

While this chapter shows examples using HTTP style applications (e.g., Express or Fastify), the `ValidationPipe` works the same for WebSockets and microservices, regardless of the transport method that is used.

#### Learn more[#](/techniques/validation#learn-more)

Read more about custom validators, error messages, and available decorators as provided by the `class-validator` package [here](https://github.com/typestack/class-validator).

----
url: https://docs.nestjs.com/v11/techniques/mongodb
----

* [Mongo](https://docs.nestjs.com/v11/techniques/mongodb#mongo)
* [Model injection](https://docs.nestjs.com/v11/techniques/mongodb#model-injection)
* [Connection](https://docs.nestjs.com/v11/techniques/mongodb#connection)
* [Sessions](https://docs.nestjs.com/v11/techniques/mongodb#sessions)
* [Multiple databases](https://docs.nestjs.com/v11/techniques/mongodb#multiple-databases)
* [Hooks (middleware)](https://docs.nestjs.com/v11/techniques/mongodb#hooks-middleware)
* [Plugins](https://docs.nestjs.com/v11/techniques/mongodb#plugins)
* [Discriminators](https://docs.nestjs.com/v11/techniques/mongodb#discriminators)
* [Testing](https://docs.nestjs.com/v11/techniques/mongodb#testing)
* [Async configuration](https://docs.nestjs.com/v11/techniques/mongodb#async-configuration)
* [Connection events](https://docs.nestjs.com/v11/techniques/mongodb#connection-events)
* [Subdocuments](https://docs.nestjs.com/v11/techniques/mongodb#subdocuments)
* [Virtuals](https://docs.nestjs.com/v11/techniques/mongodb#virtuals)
* [Example](https://docs.nestjs.com/v11/techniques/mongodb#example)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/techniques/mongo.md "Suggest Edits")

### Mongo

Nest supports two methods for integrating with the [MongoDB](https://www.mongodb.com/) database. You can either use the built-in [TypeORM](https://github.com/typeorm/typeorm) module described [here](/v11/techniques/database), which has a connector for MongoDB, or use [Mongoose](https://mongoosejs.com), the most popular MongoDB object modeling tool. In this chapter we'll describe the latter, using the dedicated `@nestjs/mongoose` package.

Start by installing the [required dependencies](https://github.com/Automattic/mongoose):

```bash

$ npm i @nestjs/mongoose mongoose
```

Once the installation process is complete, we can import the `MongooseModule` into the root `AppModule`.

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';

@Module({
  imports: [MongooseModule.forRoot('mongodb://localhost/nest')],
})
export class AppModule {}
```

```typescript

import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
import { HydratedDocument } from 'mongoose';

export type CatDocument = HydratedDocument<Cat>;

@Schema()
export class Cat {
  @Prop()
  name: string;

  @Prop()
  age: number;

  @Prop()
  breed: string;
}

export const CatSchema = SchemaFactory.createForClass(Cat);
```

> **Hint** Note you can also generate a raw schema definition using the `DefinitionsFactory` class (from the `nestjs/mongoose`). This allows you to manually modify the schema definition generated based on the metadata you provided. This is useful for certain edge-cases where it may be hard to represent everything with decorators.

The `@Schema()` decorator marks a class as a schema definition. It maps our `Cat` class to a MongoDB collection of the same name, but with an additional “s” at the end - so the final mongo collection name will be `cats`. This decorator accepts a single optional argument which is a schema options object. Think of it as the object you would normally pass as a second argument of the `mongoose.Schema` class' constructor (e.g., `new mongoose.Schema(_, options)`)). To learn more about available schema options, see [this](https://mongoosejs.com/docs/guide.html#options) chapter.

The `@Prop()` decorator defines a property in the document. For example, in the schema definition above, we defined three properties: `name`, `age`, and `breed`. The [schema types](https://mongoosejs.com/docs/schematypes.html) for these properties are automatically inferred thanks to TypeScript metadata (and reflection) capabilities. However, in more complex scenarios in which types cannot be implicitly reflected (for example, arrays or nested object structures), types must be indicated explicitly, as follows:

```typescript

@Prop([String])
tags: string[];
```

Alternatively, the `@Prop()` decorator accepts an options object argument ([read more](https://mongoosejs.com/docs/schematypes.html#schematype-options) about the available options). With this, you can indicate whether a property is required or not, specify a default value, or mark it as immutable. For example:

```typescript

@Prop({ required: true })
name: string;
```

In case you want to specify relation to another model, later for populating, you can use `@Prop()` decorator as well. For example, if `Cat` has `Owner` which is stored in a different collection called `owners`, the property should have type and ref. For example:

```typescript

import * as mongoose from 'mongoose';
import { Owner } from '../owners/schemas/owner.schema';

// inside the class definition
@Prop({ type: mongoose.Schema.Types.ObjectId, ref: 'Owner' })
owner: Owner;
```

In case there are multiple owners, your property configuration should look as follows:

```typescript

@Prop({ type: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Owner' }] })
owners: Owner[];
```

If you don’t intend to always populate a reference to another collection, consider using `mongoose.Types.ObjectId` as the type instead:

```typescript

@Prop({ type: mongoose.Schema.Types.ObjectId, ref: 'Owner' })
// This ensures the field is not confused with a populated reference
owner: mongoose.Types.ObjectId;
```

Then, when you need to selectively populate it later, you can use a repository function that specifies the correct type:

```typescript

import { Owner } from './schemas/owner.schema';

// e.g. inside a service or repository
async findAllPopulated() {
  return this.catModel.find().populate<{ owner: Owner }>("owner");
}
```

> **Hint** If there is no foreign document to populate, the type could be `Owner | null`, depending on your [Mongoose configuration](https://mongoosejs.com/docs/populate.html#doc-not-found). Alternatively, it might throw an error, in which case the type will be `Owner`.

Finally, the **raw** schema definition can also be passed to the decorator. This is useful when, for example, a property represents a nested object which is not defined as a class. For this, use the `raw()` function from the `@nestjs/mongoose` package, as follows:

```typescript

@Prop(raw({
  firstName: { type: String },
  lastName: { type: String }
}))
details: Record<string, any>;
```

Alternatively, if you prefer **not using decorators**, you can define a schema manually. For example:

```typescript

export const CatSchema = new mongoose.Schema({
  name: String,
  age: Number,
  breed: String,
});
```

The `cat.schema` file resides in a folder in the `cats` directory, where we also define the `CatsModule`. While you can store schema files wherever you prefer, we recommend storing them near their related **domain** objects, in the appropriate module directory.

Let's look at the `CatsModule`:

cats.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';
import { Cat, CatSchema } from './schemas/cat.schema';

@Module({
  imports: [MongooseModule.forFeature([{ name: Cat.name, schema: CatSchema }])],
  controllers: [CatsController],
  providers: [CatsService],
})
export class CatsModule {}
```

The `MongooseModule` provides the `forFeature()` method to configure the module, including defining which models should be registered in the current scope. If you also want to use the models in another module, add MongooseModule to the `exports` section of `CatsModule` and import `CatsModule` in the other module.

Once you've registered the schema, you can inject a `Cat` model into the `CatsService` using the `@InjectModel()` decorator:

cats.service.ts

JS TS

```typescript

import { Model } from 'mongoose';
import { Injectable } from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import { Cat } from './schemas/cat.schema';
import { CreateCatDto } from './dto/create-cat.dto';

@Injectable()
export class CatsService {
  constructor(@InjectModel(Cat.name) private catModel: Model<Cat>) {}

  async create(createCatDto: CreateCatDto): Promise<Cat> {
    const createdCat = new this.catModel(createCatDto);
    return createdCat.save();
  }

  async findAll(): Promise<Cat[]> {
    return this.catModel.find().exec();
  }
}
```

```typescript

import { Model } from 'mongoose';
import { Injectable, Dependencies } from '@nestjs/common';
import { getModelToken } from '@nestjs/mongoose';
import { Cat } from './schemas/cat.schema';

@Injectable()
@Dependencies(getModelToken(Cat.name))
export class CatsService {
  constructor(catModel) {
    this.catModel = catModel;
  }

  async create(createCatDto) {
    const createdCat = new this.catModel(createCatDto);
    return createdCat.save();
  }

  async findAll() {
    return this.catModel.find().exec();
  }
}
```

#### Connection[#](/techniques/mongodb#connection)

At times you may need to access the native [Mongoose Connection](https://mongoosejs.com/docs/api.html#Connection) object. For example, you may want to make native API calls on the connection object. You can inject the Mongoose Connection by using the `@InjectConnection()` decorator as follows:

```typescript

import { Injectable } from '@nestjs/common';
import { InjectConnection } from '@nestjs/mongoose';
import { Connection } from 'mongoose';

@Injectable()
export class CatsService {
  constructor(@InjectConnection() private connection: Connection) {}
}
```

#### Sessions[#](/techniques/mongodb#sessions)

To start a session with Mongoose, it's recommended to inject the database connection using `@InjectConnection` rather than calling `mongoose.startSession()` directly. This approach allows better integration with the NestJS dependency injection system, ensuring proper connection management.

Here's an example of how to start a session:

```typescript

import { InjectConnection } from '@nestjs/mongoose';
import { Connection } from 'mongoose';

@Injectable()
export class CatsService {
  constructor(@InjectConnection() private readonly connection: Connection) {}

  async startTransaction() {
    const session = await this.connection.startSession();
    session.startTransaction();
    // Your transaction logic here
  }
}
```

In this example, `@InjectConnection()` is used to inject the Mongoose connection into the service. Once the connection is injected, you can use `connection.startSession()` to begin a new session. This session can be used to manage database transactions, ensuring atomic operations across multiple queries. After starting the session, remember to commit or abort the transaction based on your logic.

#### Multiple databases[#](/techniques/mongodb#multiple-databases)

Some projects require multiple database connections. This can also be achieved with this module. To work with multiple connections, first create the connections. In this case, connection naming becomes **mandatory**.

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';

@Module({
  imports: [
    MongooseModule.forRoot('mongodb://localhost/test', {
      connectionName: 'cats',
    }),
    MongooseModule.forRoot('mongodb://localhost/users', {
      connectionName: 'users',
    }),
  ],
})
export class AppModule {}
```

> **Notice** Please note that you shouldn't have multiple connections without a name, or with the same name, otherwise they will get overridden.

With this setup, you have to tell the `MongooseModule.forFeature()` function which connection should be used.

```typescript

@Module({
  imports: [
    MongooseModule.forFeature([{ name: Cat.name, schema: CatSchema }], 'cats'),
  ],
})
export class CatsModule {}
```

You can also inject the `Connection` for a given connection:

```typescript

import { Injectable } from '@nestjs/common';
import { InjectConnection } from '@nestjs/mongoose';
import { Connection } from 'mongoose';

@Injectable()
export class CatsService {
  constructor(@InjectConnection('cats') private connection: Connection) {}
}
```

To inject a given `Connection` to a custom provider (for example, factory provider), use the `getConnectionToken()` function passing the name of the connection as an argument.

```typescript

{
  provide: CatsService,
  useFactory: (catsConnection: Connection) => {
    return new CatsService(catsConnection);
  },
  inject: [getConnectionToken('cats')],
}
```

If you are just looking to inject the model from a named database, you can use the connection name as a second parameter to the `@InjectModel()` decorator.

cats.service.ts

JS TS

```typescript

@Injectable()
export class CatsService {
  constructor(@InjectModel(Cat.name, 'cats') private catModel: Model<Cat>) {}
}
```

```typescript

@Injectable()
@Dependencies(getModelToken(Cat.name, 'cats'))
export class CatsService {
  constructor(catModel) {
    this.catModel = catModel;
  }
}
```

#### Hooks (middleware)[#](/techniques/mongodb#hooks-middleware)

Middleware (also called pre and post hooks) are functions which are passed control during execution of asynchronous functions. Middleware is specified on the schema level and is useful for writing plugins ([source](https://mongoosejs.com/docs/middleware.html)). Calling `pre()` or `post()` after compiling a model does not work in Mongoose. To register a hook **before** model registration, use the `forFeatureAsync()` method of the `MongooseModule` along with a factory provider (i.e., `useFactory`). With this technique, you can access a schema object, then use the `pre()` or `post()` method to register a hook on that schema. See example below:

```typescript

@Module({
  imports: [
    MongooseModule.forFeatureAsync([
      {
        name: Cat.name,
        useFactory: () => {
          const schema = CatSchema;
          schema.pre('save', function () {
            console.log('Hello from pre save');
          });
          return schema;
        },
      },
    ]),
  ],
})
export class AppModule {}
```

Like other [factory providers](https://docs.nestjs.com/fundamentals/custom-providers#factory-providers-usefactory), our factory function can be `async` and can inject dependencies through `inject`.

```typescript

@Module({
  imports: [
    MongooseModule.forFeatureAsync([
      {
        name: Cat.name,
        imports: [ConfigModule],
        useFactory: (configService: ConfigService) => {
          const schema = CatSchema;
          schema.pre('save', function() {
            console.log(
              `${configService.get('APP_NAME')}: Hello from pre save`,
            );
          });
          return schema;
        },
        inject: [ConfigService],
      },
    ]),
  ],
})
export class AppModule {}
```

#### Plugins[#](/techniques/mongodb#plugins)

To register a [plugin](https://mongoosejs.com/docs/plugins.html) for a given schema, use the `forFeatureAsync()` method.

```typescript

@Module({
  imports: [
    MongooseModule.forFeatureAsync([
      {
        name: Cat.name,
        useFactory: () => {
          const schema = CatSchema;
          schema.plugin(require('mongoose-autopopulate'));
          return schema;
        },
      },
    ]),
  ],
})
export class AppModule {}
```

To register a plugin for all schemas at once, call the `.plugin()` method of the `Connection` object. You should access the connection before models are created; to do this, use the `connectionFactory`:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';

@Module({
  imports: [
    MongooseModule.forRoot('mongodb://localhost/test', {
      connectionFactory: (connection) => {
        connection.plugin(require('mongoose-autopopulate'));
        return connection;
      }
    }),
  ],
})
export class AppModule {}
```

#### Discriminators[#](/techniques/mongodb#discriminators)

[Discriminators](https://mongoosejs.com/docs/discriminators.html) are a schema inheritance mechanism. They enable you to have multiple models with overlapping schemas on top of the same underlying MongoDB collection.

Suppose you wanted to track different types of events in a single collection. Every event will have a timestamp.

event.schema.ts

JS TS

```typescript

@Schema({ discriminatorKey: 'kind' })
export class Event {
  @Prop({
    type: String,
    required: true,
    enum: [ClickedLinkEvent.name, SignUpEvent.name],
  })
  kind: string;

  @Prop({ type: Date, required: true })
  time: Date;
}

export const EventSchema = SchemaFactory.createForClass(Event);
```

> **Hint** The way mongoose tells the difference between the different discriminator models is by the "discriminator key", which is `__t` by default. Mongoose adds a String path called `__t` to your schemas that it uses to track which discriminator this document is an instance of. You may also use the `discriminatorKey` option to define the path for discrimination.

`SignUpEvent` and `ClickedLinkEvent` instances will be stored in the same collection as generic events.

Now, let's define the `ClickedLinkEvent` class, as follows:

click-link-event.schema.ts

JS TS

```typescript

@Schema()
export class ClickedLinkEvent {
  kind: string;
  time: Date;

  @Prop({ type: String, required: true })
  url: string;
}

export const ClickedLinkEventSchema = SchemaFactory.createForClass(ClickedLinkEvent);
```

And `SignUpEvent` class:

sign-up-event.schema.ts

JS TS

```typescript

@Schema()
export class SignUpEvent {
  kind: string;
  time: Date;

  @Prop({ type: String, required: true })
  user: string;
}

export const SignUpEventSchema = SchemaFactory.createForClass(SignUpEvent);
```

With this in place, use the `discriminators` option to register a discriminator for a given schema. It works on both `MongooseModule.forFeature` and `MongooseModule.forFeatureAsync`:

event.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';

@Module({
  imports: [
    MongooseModule.forFeature([
      {
        name: Event.name,
        schema: EventSchema,
        discriminators: [
          { name: ClickedLinkEvent.name, schema: ClickedLinkEventSchema },
          { name: SignUpEvent.name, schema: SignUpEventSchema },
        ],
      },
    ]),
  ]
})
export class EventsModule {}
```

#### Testing[#](/techniques/mongodb#testing)

When unit testing an application, we usually want to avoid any database connection, making our test suites simpler to set up and faster to execute. But our classes might depend on models that are pulled from the connection instance. How do we resolve these classes? The solution is to create mock models.

To make this easier, the `@nestjs/mongoose` package exposes a `getModelToken()` function that returns a prepared [injection token](https://docs.nestjs.com/fundamentals/custom-providers#di-fundamentals) based on a token name. Using this token, you can easily provide a mock implementation using any of the standard [custom provider](/v11/fundamentals/custom-providers) techniques, including `useClass`, `useValue`, and `useFactory`. For example:

```typescript

@Module({
  providers: [
    CatsService,
    {
      provide: getModelToken(Cat.name),
      useValue: catModel,
    },
  ],
})
export class CatsModule {}
```

```typescript

MongooseModule.forRootAsync({
  useFactory: () => ({
    uri: 'mongodb://localhost/nest',
  }),
});
```

Like other [factory providers](https://docs.nestjs.com/fundamentals/custom-providers#factory-providers-usefactory), our factory function can be `async` and can inject dependencies through `inject`.

```typescript

MongooseModule.forRootAsync({
  imports: [ConfigModule],
  useFactory: async (configService: ConfigService) => ({
    uri: configService.get<string>('MONGODB_URI'),
  }),
  inject: [ConfigService],
});
```

Alternatively, you can configure the `MongooseModule` using a class instead of a factory, as shown below:

```typescript

MongooseModule.forRootAsync({
  useClass: MongooseConfigService,
});
```

The construction above instantiates `MongooseConfigService` inside `MongooseModule`, using it to create the required options object. Note that in this example, the `MongooseConfigService` has to implement the `MongooseOptionsFactory` interface, as shown below. The `MongooseModule` will call the `createMongooseOptions()` method on the instantiated object of the supplied class.

```typescript

@Injectable()
export class MongooseConfigService implements MongooseOptionsFactory {
  createMongooseOptions(): MongooseModuleOptions {
    return {
      uri: 'mongodb://localhost/nest',
    };
  }
}
```

If you want to reuse an existing options provider instead of creating a private copy inside the `MongooseModule`, use the `useExisting` syntax.

```typescript

MongooseModule.forRootAsync({
  imports: [ConfigModule],
  useExisting: ConfigService,
});
```

#### Connection events[#](/techniques/mongodb#connection-events)

You can listen to Mongoose [connection events](https://mongoosejs.com/docs/connections.html#connection-events) by using the `onConnectionCreate` configuration option. This allows you to implement custom logic whenever a connection is established. For instance, you can register event listeners for the `connected`, `open`, `disconnected`, `reconnected`, and `disconnecting` events, as demonstrated below:

```typescript

MongooseModule.forRoot('mongodb://localhost/test', {
  onConnectionCreate: (connection: Connection) => {
    connection.on('connected', () => console.log('connected'));
    connection.on('open', () => console.log('open'));
    connection.on('disconnected', () => console.log('disconnected'));
    connection.on('reconnected', () => console.log('reconnected'));
    connection.on('disconnecting', () => console.log('disconnecting'));

    return connection;
  },
}),
```

```typescript

MongooseModule.forRootAsync({
  useFactory: () => ({
    uri: 'mongodb://localhost/test',
    onConnectionCreate: (connection: Connection) => {
      // Register event listeners here
      return connection;
    },
  }),
}),
```

This provides a flexible way to manage connection events, enabling you to handle changes in connection status effectively.

#### Subdocuments[#](/techniques/mongodb#subdocuments)

To nest subdocuments within a parent document, you can define your schemas as follows:

name.schema.ts

JS TS

```typescript

@Schema()
export class Name {
  @Prop()
  firstName: string;

  @Prop()
  lastName: string;
}

export const NameSchema = SchemaFactory.createForClass(Name);
```

And then reference the subdocument in the parent schema:

person.schema.ts

JS TS

```typescript

@Schema()
export class Person {
  @Prop(NameSchema)
  name: Name;
}

export const PersonSchema = SchemaFactory.createForClass(Person);

export type PersonDocumentOverride = {
  name: Types.Subdocument<Types.ObjectId> & Name;
};

export type PersonDocument = HydratedDocument<Person, PersonDocumentOverride>;
```

If you want to include multiple subdocuments, you can use an array of subdocuments. It's important to override the type of the property accordingly:

name.schema.ts

JS TS

```typescript

@Schema()
export class Person {
  @Prop([NameSchema])
  name: Name[];
}

export const PersonSchema = SchemaFactory.createForClass(Person);

export type PersonDocumentOverride = {
  name: Types.DocumentArray<Name>;
};

export type PersonDocument = HydratedDocument<Person, PersonDocumentOverride>;
```

#### Virtuals[#](/techniques/mongodb#virtuals)

In Mongoose, a **virtual** is a property that exists on a document but is not persisted to MongoDB. It is not stored in the database but is computed dynamically whenever it's accessed. Virtuals are typically used for derived or computed values, like combining fields (e.g., creating a `fullName` property by concatenating `firstName` and `lastName`), or for creating properties that rely on existing data in the document.

```ts

class Person {
  @Prop()
  firstName: string;

  @Prop()
  lastName: string;

  @Virtual({
    get: function (this: Person) {
      return `${this.firstName} ${this.lastName}`;
    },
  })
  fullName: string;
}
```

> **Hint** The `@Virtual()` decorator is imported from the `@nestjs/mongoose` package.

In this example, the `fullName` virtual is derived from `firstName` and `lastName`. Even though it behaves like a normal property when accessed, it’s never saved to the MongoDB document.:

#### Example[#](/techniques/mongodb#example)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/06-mongoose).

----
url: https://docs.nestjs.com/application/queues
----

[Skip to content](#content)

On this page

* [Queues](https://docs.nestjs.com/application/queues#queues)
* [BullMQ installation](https://docs.nestjs.com/application/queues#bullmq-installation)
* [Named configurations](https://docs.nestjs.com/application/queues#named-configurations)
* [Producers](https://docs.nestjs.com/application/queues#producers)
* [Job options](https://docs.nestjs.com/application/queues#job-options)
* [Consumers](https://docs.nestjs.com/application/queues#consumers)
* [Request-scoped consumers](https://docs.nestjs.com/application/queues#request-scoped-consumers)
* [Event listeners](https://docs.nestjs.com/application/queues#event-listeners)
* [Queue management](https://docs.nestjs.com/application/queues#queue-management)
* [Observing queues in production](https://docs.nestjs.com/application/queues#observing-queues-in-production)
* [Separate processes](https://docs.nestjs.com/application/queues#separate-processes)
* [Async configuration](https://docs.nestjs.com/application/queues#async-configuration)
* [Manual registration](https://docs.nestjs.com/application/queues#manual-registration)
* [Bull installation](https://docs.nestjs.com/application/queues#bull-installation)
* [Named configurations](https://docs.nestjs.com/application/queues#named-configurations-1)
* [Producers](https://docs.nestjs.com/application/queues#producers-1)
* [Named jobs](https://docs.nestjs.com/application/queues#named-jobs)
* [Job options](https://docs.nestjs.com/application/queues#job-options-1)
* [Consumers](https://docs.nestjs.com/application/queues#consumers-1)
* [Request-scoped consumers](https://docs.nestjs.com/application/queues#request-scoped-consumers-1)
* [Event listeners](https://docs.nestjs.com/application/queues#event-listeners-1)
* [Queue management](https://docs.nestjs.com/application/queues#queue-management-1)
* [Separate processes](https://docs.nestjs.com/application/queues#separate-processes-1)
* [Async configuration](https://docs.nestjs.com/application/queues#async-configuration-1)
* [Example](https://docs.nestjs.com/application/queues#example)

### Queues

Queues are a design pattern that helps you deal with common application scaling and performance challenges. Some examples of problems that queues can help you solve are:

* Smooth out processing peaks. For example, if users can initiate resource-intensive tasks at arbitrary times, you can add these tasks to a queue instead of performing them synchronously. Worker processes then pull tasks from the queue in a controlled manner. As the application grows, you can add queue consumers to scale up back-end task handling.
* Break up monolithic tasks that may otherwise block the Node.js event loop. For example, if a user request requires CPU-intensive work like audio transcoding, you can delegate this task to other processes, so user-facing processes remain responsive.
* Provide a reliable communication channel across services. For example, you can queue tasks (jobs) in one process or service and consume them in another. By listening for status events, any process or service can be notified of completion, errors, or other state changes in the job lifecycle. When queue producers or consumers fail, their state is preserved, and task handling can resume automatically when nodes restart.

Nest provides the `@nestjs/bullmq` package for BullMQ integration and the `@nestjs/bull` package for Bull integration. Both packages wrap their respective libraries, which are developed by the same team. Bull is in maintenance mode (the team only fixes bugs), while BullMQ is actively developed and offers a modern TypeScript implementation with a different set of features. If Bull meets your requirements, it remains a reliable, battle-tested choice.

Both BullMQ and Bull use [Redis](https://redis.io/) to persist job data, so you need a running Redis instance. Because they are Redis-backed, your queue architecture can be fully distributed and platform-independent. For example, you can run some queue [producers](application/queues#producers), [consumers](application/queues#consumers), and [listeners](application/queues#event-listeners) in Nest on one or more nodes, and other producers, consumers, and listeners on other Node.js platforms on other network nodes.

This chapter covers the `@nestjs/bullmq` and `@nestjs/bull` packages. For more background and implementation details, see the [BullMQ documentation](https://docs.bullmq.io/) and the [Bull reference](https://github.com/OptimalBits/bull/blob/master/REFERENCE.md).

#### BullMQ installation[#](/application/queues#bullmq-installation)

To begin using BullMQ, install the required dependencies.

```bash

$ npm install --save @nestjs/bullmq bullmq
```

Once the installation process is complete, import the `BullModule` into the root `AppModule`.

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { BullModule } from '@nestjs/bullmq';

@Module({
  imports: [
    BullModule.forRoot({
      connection: {
        host: 'localhost',
        port: 6379,
      },
    }),
  ],
})
export class AppModule {}
```

The `forRoot()` method registers a `bullmq` configuration object that all queues registered in the application use (unless specified otherwise). The following are a few of the configuration properties:

* `connection: ConnectionOptions` - Options to configure the Redis connection. See [Connections](https://docs.bullmq.io/guide/connections) for more information.
* `prefix: string` - Prefix for all queue keys (defaults to `bull`).
* `defaultJobOptions: DefaultJobOptions` - Default settings for new jobs. See [DefaultJobOptions](https://docs.bullmq.io/api/interfaces/v6.DefaultJobOptions.html) for more information. These don't take effect for jobs added through a `FlowProducer`; see [bullmq#1034](https://github.com/taskforcesh/bullmq/issues/1034) for an explanation.
* `settings: AdvancedRepeatOptions` - Advanced settings for repeatable jobs. These should usually not be changed. See [AdvancedRepeatOptions](https://docs.bullmq.io/api/interfaces/v6.AdvancedRepeatOptions.html) for more information.
* `extraOptions` - Extra options for module initialization. See [Manual registration](/application/queues#manual-registration).

All options are optional. Apart from `extraOptions`, they are passed directly to the BullMQ `Queue` constructor. See the [QueueOptions API reference](https://docs.bullmq.io/api/interfaces/v6.QueueOptions.html) for the complete list.

To register a queue, import the `BullModule.registerQueue()` dynamic module, as follows:

```typescript

BullModule.registerQueue({
  name: 'audio',
});
```

> **Hint** Create multiple queues by passing multiple configuration objects (as separate arguments) to the `registerQueue()` method.

The `registerQueue()` method instantiates and/or registers queues. Queues are shared across modules and processes that connect to the same underlying Redis database with the same credentials. Each queue is identified by its `name` property. The queue name serves both as an injection token (for injecting the queue into controllers and providers) and as an argument to decorators that associate consumer classes and listeners with queues.

You can also override some of the preconfigured options for a specific queue, as follows:

```typescript

BullModule.registerQueue({
  name: 'audio',
  connection: {
    port: 6380,
  },
});
```

BullMQ also supports parent-child relationships between jobs. This enables flows, where jobs are the nodes of trees of arbitrary depth. See [Flows](https://docs.bullmq.io/guide/flows) in the BullMQ documentation to learn more.

To register a flow producer, use the `registerFlowProducer()` method:

```typescript

BullModule.registerFlowProducer({
  name: 'flowProducerName',
});
```

Because jobs are persisted in Redis, each time a named queue is instantiated (e.g., when an app starts or restarts), it attempts to process any old jobs left over from a previous unfinished session.

Each queue can have one or many producers, consumers, and listeners. Consumers retrieve jobs from the queue in a specific order: FIFO (the default), LIFO, or according to priorities. The [job options](application/queues#job-options) section explains how to control the processing order.

## Official enterprise support

* Providing technical guidance
* Performing in-depth code reviews
* Mentoring team members
* Advising best practices

[Explore more](https://enterprise.nestjs.com "Enterprise | NestJS - A progressive Node.js framework")

#### Named configurations[#](/application/queues#named-configurations)

If your queues connect to multiple Redis instances, you can use a technique called **named configurations**. This feature lets you register several configurations under specified keys, which you can then refer to in the queue options.

For example, assuming you have an additional Redis instance (apart from the default one) used by a few queues in your application, you can register its configuration as follows:

```typescript

BullModule.forRoot('alternative-config', {
  connection: {
    port: 6381,
  },
});
```

In the example above, `'alternative-config'` is a configuration key (it can be any string).

You can now point to this configuration in the `registerQueue()` options object:

```typescript

BullModule.registerQueue({
  configKey: 'alternative-config',
  name: 'video',
});
```

#### Producers[#](/application/queues#producers)

Job producers add jobs to queues. Producers are typically application services (Nest [providers](/providers)). To add jobs to a queue, first inject the queue into the service:

```typescript

import { Injectable } from '@nestjs/common';
import { Queue } from 'bullmq';
import { InjectQueue } from '@nestjs/bullmq';

@Injectable()
export class AudioService {
  constructor(@InjectQueue('audio') private audioQueue: Queue) {}
}
```

> **Hint** The `@InjectQueue()` decorator identifies the queue by its name, as provided in the `registerQueue()` method call (e.g., `'audio'`).

Now, add a job by calling the queue's `add()` method, passing a job name and a user-defined data object. Job data must be serializable, because jobs are stored in Redis. The shape of the data is arbitrary; use it to represent the semantics of your job. The name lets a [consumer](application/queues#consumers) tell different kinds of jobs apart.

```typescript

const job = await this.audioQueue.add('transcode', {
  foo: 'bar',
});
```

#### Job options[#](/application/queues#job-options)

Jobs can have additional options associated with them. Pass an options object as the third argument of the `Queue.add()` method, after the job data. Some of the job options are:

* `priority`: `number` - Priority value, from 0 to 2,097,151. `0` (the default) means no explicit priority; jobs without a priority are processed before prioritized jobs, and among prioritized jobs, lower numbers are processed first. Using priorities has a slight impact on performance, so use them only when required.
* `delay`: `number` - Time (in milliseconds) to wait until this job can be processed. For accurate delays, workers and producers should have their clocks synchronized.
* `attempts`: `number` - The total number of attempts to try the job until it completes (defaults to 1).
* `backoff`: `number | BackoffOptions` - Backoff setting for automatic retries if the job fails. See [BackoffOptions](https://docs.bullmq.io/api/interfaces/v6.BackoffOptions.html).
* `lifo`: `boolean` - If `true`, adds the job to the right end of the queue instead of the left (default `false`).
* `jobId`: `string` - Overrides the job ID. By default, the job ID is a unique integer. If you use this option, it's up to you to ensure the ID is unique. A job with an ID that already exists is not added.
* `removeOnComplete`: `boolean | number | KeepJobs` - If `true`, removes the job when it successfully completes. A number specifies how many jobs to keep, and a `KeepJobs` object specifies a maximum age and/or count. By default, the job is kept in the completed set.
* `removeOnFail`: `boolean | number | KeepJobs` - If `true`, removes the job when it fails after all attempts. A number or `KeepJobs` object works as for `removeOnComplete`. By default, the job is kept in the failed set.
* `stackTraceLimit`: `number` - Limits the number of stack trace lines recorded for a failed job.

> **Hint** BullMQ no longer accepts a `repeat` option in `Queue.add()`. To run a job repeatedly (e.g., on a cron pattern), create a job scheduler with the `Queue#upsertJobScheduler()` method. See [Job Schedulers](https://docs.bullmq.io/guide/job-schedulers) in the BullMQ documentation.

Here are a few examples of customizing jobs with job options.

To delay the start of a job, use the `delay` property.

```typescript

const job = await this.audioQueue.add(
  'transcode',
  {
    foo: 'bar',
  },
  { delay: 3000 }, // 3 seconds delayed
);
```

To add a job to the right end of the queue (i.e., process it as **LIFO**, Last In First Out), set the `lifo` property to `true`.

```typescript

const job = await this.audioQueue.add(
  'transcode',
  {
    foo: 'bar',
  },
  { lifo: true },
);
```

To prioritize a job, use the `priority` property.

```typescript

const job = await this.audioQueue.add(
  'transcode',
  {
    foo: 'bar',
  },
  { priority: 2 },
);
```

For the full list of options, see the [JobsOptions](https://docs.bullmq.io/api/types/v6.JobsOptions.html) and [BaseJobOptions](https://docs.bullmq.io/api/interfaces/v6.BaseJobOptions.html) API references.

#### Consumers[#](/application/queues#consumers)

A consumer is a **class** defining methods that process jobs added to the queue, listen for events on the queue, or both. Declare a consumer class using the `@Processor()` decorator as follows:

```typescript

import { Processor } from '@nestjs/bullmq';

@Processor('audio')
export class AudioConsumer {}
```

> **Hint** Consumers must be registered as `providers` so the `@nestjs/bullmq` package can pick them up.

The decorator's string argument (e.g., `'audio'`) is the name of the queue to associate with the class. The consumer class must extend `WorkerHost` and implement its `process()` method:

```typescript

import { Processor, WorkerHost } from '@nestjs/bullmq';
import { Job } from 'bullmq';

@Processor('audio')
export class AudioConsumer extends WorkerHost {
  async process(job: Job<any, any, string>): Promise<any> {
    let progress = 0;
    for (let i = 0; i < 100; i++) {
      await doSomething(job.data);
      progress += 1;
      await job.updateProgress(progress);
    }
    return {};
  }
}
```

The `process()` method is called whenever the worker is idle and there are jobs to process in the queue. It receives the `job` object as its only argument. The value it returns is stored in the job object and can be accessed later, for example, in a listener for the `completed` event.

`Job` objects have multiple methods that allow you to interact with their state. For example, the code above uses the `updateProgress()` method to update the job's progress. See the [Job API reference](https://docs.bullmq.io/api/classes/v6.Job.html) for the complete list.

In Bull, you could designate that a job handler method handles **only** jobs of a certain type (jobs with a specific `name`) by passing that `name` to the `@Process()` decorator, as shown below.

> **Warning** This doesn't work with BullMQ. Read on for the BullMQ approach.

```typescript

@Process('transcode')
async transcode(job: Job<unknown>) { ... }
```

BullMQ doesn't support this behavior, because it caused confusion. Instead, use a `switch` statement on the job name to call different services or logic for each kind of job:

```typescript

import { Processor, WorkerHost } from '@nestjs/bullmq';
import { Job } from 'bullmq';

@Processor('audio')
export class AudioConsumer extends WorkerHost {
  async process(job: Job<any, any, string>): Promise<any> {
    switch (job.name) {
      case 'transcode': {
        let progress = 0;
        for (let i = 0; i < 100; i++) {
          await doSomething(job.data);
          progress += 1;
          await job.updateProgress(progress);
        }
        return {};
      }
      case 'concatenate': {
        await doSomeLogic2();
        break;
      }
    }
  }
}
```

This is covered in the [named processor](https://docs.bullmq.io/patterns/named-processor) section of the BullMQ documentation.

#### Request-scoped consumers[#](/application/queues#request-scoped-consumers)

When a consumer is flagged as request-scoped (see [injection scopes](/fundamentals/injection-scopes#provider-scope)), a new instance of the class is created exclusively for each job. The instance is garbage-collected after the job completes.

```typescript

@Processor({
  name: 'audio',
  scope: Scope.REQUEST,
})
```

Because request-scoped consumer classes are instantiated dynamically and scoped to a single job, you can inject the current job through the constructor using the `JOB_REF` token.

```typescript

constructor(@Inject(JOB_REF) jobRef: Job) {
  console.log(jobRef);
}
```

> **Hint** The `JOB_REF` token is imported from the `@nestjs/bullmq` package.

#### Event listeners[#](/application/queues#event-listeners)

BullMQ emits a set of events when queue and/or job state changes occur. You can subscribe to these events at the worker level using the `@OnWorkerEvent(event)` decorator, or at the queue level with a dedicated listener class and the `@OnQueueEvent(event)` decorator.

Worker events must be declared within a [consumer](application/queues#consumers) class (i.e., within a class decorated with the `@Processor()` decorator). To listen for an event, use the `@OnWorkerEvent(event)` decorator with the event you want to handle. For example, to listen to the event emitted when a job enters the active state in the `audio` queue, use the following construct:

```typescript

import { Processor, WorkerHost, OnWorkerEvent } from '@nestjs/bullmq';
import { Job } from 'bullmq';

@Processor('audio')
export class AudioConsumer extends WorkerHost {
  @OnWorkerEvent('active')
  onActive(job: Job) {
    console.log(
      `Processing job ${job.id} of type ${job.name} with data ${job.data}...`,
    );
  }

  // ...
}
```

The complete list of worker events and their arguments is available as the properties of the [WorkerListener](https://docs.bullmq.io/api/interfaces/v6.WorkerListener.html) interface.

Queue event listeners must use the `@QueueEventsListener(queue)` decorator and extend the `QueueEventsHost` class provided by `@nestjs/bullmq`. To listen for an event, use the `@OnQueueEvent(event)` decorator with the event you want to handle. For example, to listen to the event emitted when a job enters the active state in the `audio` queue, use the following construct:

```typescript

import {
  QueueEventsHost,
  QueueEventsListener,
  OnQueueEvent,
} from '@nestjs/bullmq';

@QueueEventsListener('audio')
export class AudioEventsListener extends QueueEventsHost {
  @OnQueueEvent('active')
  onActive(job: { jobId: string; prev?: string }) {
    console.log(`Processing job ${job.jobId}...`);
  }

  // ...
}
```

> **Hint** Queue event listeners must be registered as `providers` so the `@nestjs/bullmq` package can pick them up.

The complete list of queue events and their arguments is available as the properties of the [QueueEventsListener](https://docs.bullmq.io/api/interfaces/v6.QueueEventsListener.html) interface.

#### Queue management[#](/application/queues#queue-management)

Queues have an API for management functions such as pausing and resuming, and retrieving the count of jobs in various states. See the [Queue API reference](https://docs.bullmq.io/api/classes/v6.Queue.html) for the full API. Invoke these methods directly on the `Queue` object, as shown in the pause and resume examples below.

Pause a queue with the `pause()` method. A paused queue doesn't process new jobs until it's resumed, but jobs already being processed continue until they finish.

```typescript

await audioQueue.pause();
```

To resume a paused queue, use the `resume()` method, as follows:

```typescript

await audioQueue.resume();
```

#### Observing queues in production[#](/application/queues#observing-queues-in-production)

Queues fail in ways that HTTP endpoints don't. A job doesn't return a status code to an impatient user. It retries quietly, three times, with backoff, and the only symptom is that something downstream never happened. The two questions that matter are therefore *"is this queue keeping up?"* and *"did that job run at all?"*, and the consumer's own logs can't answer either of them.

[NestJS Observe](https://www.observe.nestjs.com/ "NestJS Observe") instruments queue consumers automatically, the same way it instruments controllers: `@Processor()` classes and their handlers are recognized as jobs, so no manual span wiring is needed:

* **Queue wait time is measured separately from execution time.** A job that takes 200 ms to run but sat in the queue for four minutes is a capacity problem, not a slow handler. The two numbers are reported side by side, so you can tell which one you have.
* **Attempts and failure reasons are recorded per run.** You see that a job succeeded on attempt 3 rather than seeing only the success, which is usually the difference between "fine" and "quietly degrading".
* **Silence is alertable.** A *job silence* rule fires when a named job hasn't reported for longer than a tolerance you choose. That's how you find out that the nightly billing consumer stopped running on the night it stops, rather than at the end of the month.

Failed jobs carry the same error card as failed requests: the resolved stack trace with source lines, the logs written during the run, and the waterfall of what the job did before it threw. See the [Observability](/observability/overview) chapter for setup.

#### Separate processes[#](/application/queues#separate-processes)

Job handlers can also run in a separate (forked) process (see [Sandboxed processors](https://docs.bullmq.io/guide/workers/sandboxed-processors) in the BullMQ documentation). This has several advantages:

* The process is sandboxed, so if it crashes, the worker isn't affected.
* You can run blocking code without affecting the queue (jobs don't stall).
* Better utilization of multi-core CPUs.
* Fewer connections to Redis.

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { BullModule } from '@nestjs/bullmq';
import { join } from 'node:path';

@Module({
  imports: [
    BullModule.registerQueue({
      name: 'audio',
      processors: [join(import.meta.dirname, 'processor.js')],
    }),
  ],
})
export class AppModule {}
```

> **Warning** Because your function runs in a forked process, dependency injection (and the IoC container) isn't available. Your processor function must contain (or create) all instances of the external dependencies it needs.

#### Async configuration[#](/application/queues#async-configuration)

You may want to pass `bullmq` options asynchronously instead of statically. In this case, use the `forRootAsync()` method, which provides several ways to handle async configuration. Likewise, to pass queue options asynchronously, use the `registerQueueAsync()` method.

One approach is to use a factory function:

```typescript

BullModule.forRootAsync({
  useFactory: () => ({
    connection: {
      host: 'localhost',
      port: 6379,
    },
  }),
});
```

The factory behaves like any other [asynchronous provider](/fundamentals/async-providers) (e.g., it can be `async` and can inject dependencies through `inject`).

```typescript

BullModule.forRootAsync({
  imports: [ConfigModule],
  useFactory: async (configService: ConfigService) => ({
    connection: {
      host: configService.get('QUEUE_HOST'),
      port: configService.get('QUEUE_PORT'),
    },
  }),
  inject: [ConfigService],
});
```

Alternatively, you can use the `useClass` syntax:

```typescript

BullModule.forRootAsync({
  useClass: BullConfigService,
});
```

The construction above instantiates `BullConfigService` inside `BullModule` and uses it to provide an options object by calling `createSharedConfiguration()`. This means `BullConfigService` has to implement the `SharedBullConfigurationFactory` interface, as shown below:

```typescript

@Injectable()
class BullConfigService implements SharedBullConfigurationFactory {
  createSharedConfiguration(): BullRootModuleOptions {
    return {
      connection: {
        host: 'localhost',
        port: 6379,
      },
    };
  }
}
```

To reuse a provider imported from a different module instead of creating `BullConfigService` inside `BullModule`, use the `useExisting` syntax.

```typescript

BullModule.forRootAsync({
  imports: [ConfigModule],
  useExisting: ConfigService,
});
```

This construction works the same as `useClass` with one critical difference: `BullModule` looks up imported modules to reuse an existing `ConfigService` instead of instantiating a new one.

Likewise, to pass queue options asynchronously, use the `registerQueueAsync()` method. Specify the `name` attribute outside the factory function.

```typescript

BullModule.registerQueueAsync({
  name: 'audio',
  useFactory: () => ({
    connection: {
      host: 'localhost',
      port: 6379,
    },
  }),
});
```

#### Manual registration[#](/application/queues#manual-registration)

By default, `BullModule` automatically registers BullMQ components (queues, processors, and event listener services) in the `onModuleInit` lifecycle hook. In some cases, this behavior isn't what you want. To prevent automatic registration, enable `manualRegistration` in `BullModule`:

```typescript

BullModule.forRoot({
  extraOptions: {
    manualRegistration: true,
  },
});
```

To register these components manually, inject `BullRegistrar` and call its `register()` method, ideally within the `onModuleInit()` or `onApplicationBootstrap()` lifecycle hook.

```typescript

import { Injectable, OnModuleInit } from '@nestjs/common';
import { BullRegistrar } from '@nestjs/bullmq';

@Injectable()
export class AudioService implements OnModuleInit {
  constructor(private bullRegistrar: BullRegistrar) {}

  onModuleInit() {
    if (yourConditionHere) {
      this.bullRegistrar.register();
    }
  }
}
```

Until you call `BullRegistrar#register()`, no BullMQ components work, which means no jobs are processed.

#### Bull installation[#](/application/queues#bull-installation)

> **Note** If you use BullMQ, skip this section and the ones that follow.

To begin using Bull, install the required dependencies.

```bash

$ npm install --save @nestjs/bull bull
```

Once the installation process is complete, import the `BullModule` into the root `AppModule`.

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { BullModule } from '@nestjs/bull';

@Module({
  imports: [
    BullModule.forRoot({
      redis: {
        host: 'localhost',
        port: 6379,
      },
    }),
  ],
})
export class AppModule {}
```

The `forRoot()` method registers a `bull` configuration object that all queues registered in the application use (unless specified otherwise). A configuration object consists of the following properties (all optional):

* `limiter: RateLimiter` - Options to control the rate at which the queue's jobs are processed. See [RateLimiter](https://github.com/OptimalBits/bull/blob/master/REFERENCE.md#queue) for more information.
* `redis: RedisOpts` - Options to configure the Redis connection. See [RedisOpts](https://github.com/OptimalBits/bull/blob/master/REFERENCE.md#queue) for more information.
* `prefix: string` - Prefix for all queue keys.
* `defaultJobOptions: JobOpts` - Options to control the default settings for new jobs. See [JobOpts](https://github.com/OptimalBits/bull/blob/master/REFERENCE.md#queueadd) for more information.
* `settings: AdvancedSettings` - Advanced queue configuration settings. These should usually not be changed. See [AdvancedSettings](https://github.com/OptimalBits/bull/blob/master/REFERENCE.md#queue) for more information.

These options are passed directly to the Bull `Queue` constructor. See the [Queue section of the Bull reference](https://github.com/OptimalBits/bull/blob/master/REFERENCE.md#queue) for details.

To register a queue, import the `BullModule.registerQueue()` dynamic module, as follows:

```typescript

BullModule.registerQueue({
  name: 'audio',
});
```

> **Hint** Create multiple queues by passing multiple configuration objects (as separate arguments) to the `registerQueue()` method.

The `registerQueue()` method instantiates and/or registers queues. Queues are shared across modules and processes that connect to the same underlying Redis database with the same credentials. Each queue is identified by its `name` property. The queue name serves both as an injection token (for injecting the queue into controllers and providers) and as an argument to decorators that associate consumer classes and listeners with queues.

You can also override some of the preconfigured options for a specific queue, as follows:

```typescript

BullModule.registerQueue({
  name: 'audio',
  redis: {
    port: 6380,
  },
});
```

Because jobs are persisted in Redis, each time a named queue is instantiated (e.g., when an app starts or restarts), it attempts to process any old jobs left over from a previous unfinished session.

Each queue can have one or many producers, consumers, and listeners. Consumers retrieve jobs from the queue in a specific order: FIFO (the default), LIFO, or according to priorities. The [job options](application/queues#job-options) section explains how to control the processing order.

## Official enterprise support

* Providing technical guidance
* Performing in-depth code reviews
* Mentoring team members
* Advising best practices

[Explore more](https://enterprise.nestjs.com "Enterprise | NestJS - A progressive Node.js framework")

#### Named configurations[#](/application/queues#named-configurations-1)

If your queues connect to multiple Redis instances, you can use a technique called **named configurations**. This feature lets you register several configurations under specified keys, which you can then refer to in the queue options.

For example, assuming you have an additional Redis instance (apart from the default one) used by a few queues in your application, you can register its configuration as follows:

```typescript

BullModule.forRoot('alternative-config', {
  redis: {
    port: 6381,
  },
});
```

In the example above, `'alternative-config'` is a configuration key (it can be any string).

You can now point to this configuration in the `registerQueue()` options object:

```typescript

BullModule.registerQueue({
  configKey: 'alternative-config',
  name: 'video',
});
```

#### Producers[#](/application/queues#producers-1)

Job producers add jobs to queues. Producers are typically application services (Nest [providers](/providers)). To add jobs to a queue, first inject the queue into the service:

```typescript

import { Injectable } from '@nestjs/common';
import { Queue } from 'bull';
import { InjectQueue } from '@nestjs/bull';

@Injectable()
export class AudioService {
  constructor(@InjectQueue('audio') private audioQueue: Queue) {}
}
```

> **Hint** The `@InjectQueue()` decorator identifies the queue by its name, as provided in the `registerQueue()` method call (e.g., `'audio'`).

Now, add a job by calling the queue's `add()` method, passing a user-defined data object. Job data must be serializable, because jobs are stored in Redis. The shape of the data is arbitrary; use it to represent the semantics of your job.

```typescript

const job = await this.audioQueue.add({
  foo: 'bar',
});
```

#### Named jobs[#](/application/queues#named-jobs)

Jobs can have names. This lets you create specialized [consumers](application/queues#consumers) that only process jobs with a given name.

```typescript

const job = await this.audioQueue.add('transcode', {
  foo: 'bar',
});
```

> **Warning** When using named jobs, you must create a processor for each unique name added to a queue, or the queue reports that a processor for the given job is missing. See [consumers](application/queues#consumers) for more information on consuming named jobs.

#### Job options[#](/application/queues#job-options-1)

Jobs can have additional options associated with them. Pass an options object after the job data in the `Queue.add()` method. The job options are:

* `priority`: `number` - Optional priority value. Ranges from 1 (highest priority) to MAX\_INT (lowest priority). Using priorities has a slight impact on performance, so use them with caution.
* `delay`: `number` - Time (in milliseconds) to wait until this job can be processed. For accurate delays, both server and clients should have their clocks synchronized.
* `attempts`: `number` - The total number of attempts to try the job until it completes.
* `repeat`: `RepeatOpts` - Repeats the job according to a cron specification. See [RepeatOpts](https://github.com/OptimalBits/bull/blob/master/REFERENCE.md#queueadd).
* `backoff`: `number | BackoffOpts` - Backoff setting for automatic retries if the job fails. See [BackoffOpts](https://github.com/OptimalBits/bull/blob/master/REFERENCE.md#queueadd).
* `lifo`: `boolean` - If `true`, adds the job to the right end of the queue instead of the left (default `false`).
* `timeout`: `number` - The number of milliseconds after which the job fails with a timeout error.
* `jobId`: `number | string` - Overrides the job ID. By default, the job ID is a unique integer. If you use this option, it's up to you to ensure the ID is unique. A job with an ID that already exists is not added.
* `removeOnComplete`: `boolean | number` - If `true`, removes the job when it successfully completes. A number specifies how many jobs to keep. By default, the job is kept in the completed set.
* `removeOnFail`: `boolean | number` - If `true`, removes the job when it fails after all attempts. A number specifies how many jobs to keep. By default, the job is kept in the failed set.
* `stackTraceLimit`: `number` - Limits the number of stack trace lines recorded for a failed job.

Here are a few examples of customizing jobs with job options.

To delay the start of a job, use the `delay` property.

```typescript

const job = await this.audioQueue.add(
  {
    foo: 'bar',
  },
  { delay: 3000 }, // 3 seconds delayed
);
```

To add a job to the right end of the queue (i.e., process it as **LIFO**, Last In First Out), set the `lifo` property to `true`.

```typescript

const job = await this.audioQueue.add(
  {
    foo: 'bar',
  },
  { lifo: true },
);
```

To prioritize a job, use the `priority` property.

```typescript

const job = await this.audioQueue.add(
  {
    foo: 'bar',
  },
  { priority: 2 },
);
```

#### Consumers[#](/application/queues#consumers-1)

A consumer is a **class** defining methods that process jobs added to the queue, listen for events on the queue, or both. Declare a consumer class using the `@Processor()` decorator as follows:

```typescript

import { Processor } from '@nestjs/bull';

@Processor('audio')
export class AudioConsumer {}
```

> **Hint** Consumers must be registered as `providers` so the `@nestjs/bull` package can pick them up.

The decorator's string argument (e.g., `'audio'`) is the name of the queue to associate with the class methods.

Within a consumer class, declare job handlers by decorating handler methods with the `@Process()` decorator.

```typescript

import { Processor, Process } from '@nestjs/bull';
import { Job } from 'bull';

@Processor('audio')
export class AudioConsumer {
  @Process()
  async transcode(job: Job<unknown>) {
    let progress = 0;
    for (let i = 0; i < 100; i++) {
      await doSomething(job.data);
      progress += 1;
      await job.progress(progress);
    }
    return {};
  }
}
```

The decorated method (e.g., `transcode()`) is called whenever the worker is idle and there are jobs to process in the queue. It receives the `job` object as its only argument. The value it returns is stored in the job object and can be accessed later, for example, in a listener for the `completed` event.

`Job` objects have multiple methods that allow you to interact with their state. For example, the code above uses the `progress()` method to update the job's progress. See the [Job section of the Bull reference](https://github.com/OptimalBits/bull/blob/master/REFERENCE.md#job) for the complete `Job` API.

You can designate that a job handler method handles **only** jobs of a certain type (jobs with a specific `name`) by passing that `name` to the `@Process()` decorator, as shown below. A consumer class can have multiple `@Process()` handlers, one for each job type (`name`). When you use named jobs, make sure there is a handler for each name.

```typescript

@Process('transcode')
async transcode(job: Job<unknown>) { ... }
```

> **Warning** When you define multiple consumers for the same queue, the `concurrency` option in `@Process({ concurrency: 1 })` doesn't take effect. The minimum `concurrency` matches the number of consumers defined. This applies even if the `@Process()` handlers use different names to handle named jobs.

#### Request-scoped consumers[#](/application/queues#request-scoped-consumers-1)

When a consumer is flagged as request-scoped (see [injection scopes](/fundamentals/injection-scopes#provider-scope)), a new instance of the class is created exclusively for each job. The instance is garbage-collected after the job completes.

```typescript

@Processor({
  name: 'audio',
  scope: Scope.REQUEST,
})
```

Because request-scoped consumer classes are instantiated dynamically and scoped to a single job, you can inject the current job through the constructor using the `JOB_REF` token.

```typescript

constructor(@Inject(JOB_REF) jobRef: Job) {
  console.log(jobRef);
}
```

> **Hint** The `JOB_REF` token is imported from the `@nestjs/bull` package.

#### Event listeners[#](/application/queues#event-listeners-1)

Bull emits a set of events when queue and/or job state changes occur. The `@nestjs/bull` package exports a set of decorators that let you subscribe to a core set of standard events.

Event listeners must be declared within a [consumer](application/queues#consumers) class (i.e., within a class decorated with the `@Processor()` decorator). To listen for an event, use one of the decorators in the table below to declare a handler for the event. For example, to listen to the event emitted when a job enters the active state in the `audio` queue, use the following construct:

```typescript

import { Processor, Process, OnQueueActive } from '@nestjs/bull';
import { Job } from 'bull';

@Processor('audio')
export class AudioConsumer {

  @OnQueueActive()
  onActive(job: Job) {
    console.log(
      `Processing job ${job.id} of type ${job.name} with data ${job.data}...`,
    );
  }
  ...
```

Because Bull operates in a distributed (multi-node) environment, it defines the concept of event locality. Events may be triggered either entirely within a single process, or on shared queues from different processes. A **local** event is produced when an action or state change is triggered on a queue in the local process. In other words, when your event producers and consumers are local to a single process, all events happening on queues are local.

When a queue is shared across multiple processes, **global** events come into play. For a listener in one process to receive an event notification triggered by another process, it must register for a global event.

Event handlers are invoked whenever their corresponding event is emitted. Each handler is called with the signature shown in the table below, which provides access to information relevant to the event. One key difference between local and global event handler signatures is discussed below the table.

| Local event listeners | Global event listeners      | Handler method signature / When fired                                                                                                                              |
| --------------------- | --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `@OnQueueError()`     | `@OnGlobalQueueError()`     | `handler(error: Error)` - An error occurred. `error` contains the triggering error.                                                                                |
| `@OnQueueWaiting()`   | `@OnGlobalQueueWaiting()`   | `handler(jobId: number \| string)` - A job is waiting to be processed as soon as a worker is idle. `jobId` contains the ID of the job that has entered this state. |
| `@OnQueueActive()`    | `@OnGlobalQueueActive()`    | `handler(job: Job)` - Job `job` has started.                                                                                                                       |
| `@OnQueueStalled()`   | `@OnGlobalQueueStalled()`   | `handler(job: Job)` - Job `job` has been marked as stalled. This is useful for debugging job workers that crash or pause the event loop.                           |
| `@OnQueueProgress()`  | `@OnGlobalQueueProgress()`  | `handler(job: Job, progress: number)` - Job `job`'s progress was updated to value `progress`.                                                                      |
| `@OnQueueCompleted()` | `@OnGlobalQueueCompleted()` | `handler(job: Job, result: any)` - Job `job` successfully completed with a result `result`.                                                                        |
| `@OnQueueFailed()`    | `@OnGlobalQueueFailed()`    | `handler(job: Job, err: Error)` - Job `job` failed with reason `err`.                                                                                              |
| `@OnQueuePaused()`    | `@OnGlobalQueuePaused()`    | `handler()` - The queue has been paused.                                                                                                                           |
| `@OnQueueResumed()`   | `@OnGlobalQueueResumed()`   | `handler()` - The queue has been resumed.                                                                                                                          |
| `@OnQueueCleaned()`   | `@OnGlobalQueueCleaned()`   | `handler(jobs: Job[], type: string)` - Old jobs have been cleaned from the queue. `jobs` is an array of cleaned jobs, and `type` is the type of jobs cleaned.      |
| `@OnQueueDrained()`   | `@OnGlobalQueueDrained()`   | `handler()` - Emitted whenever the queue has processed all the waiting jobs (even if some delayed jobs are not yet processed).                                     |
| `@OnQueueRemoved()`   | `@OnGlobalQueueRemoved()`   | `handler(job: Job)` - Job `job` was successfully removed.                                                                                                          |

When listening for global events, the method signatures can differ slightly from their local counterparts. Specifically, any handler that receives a `job` object in the local version receives a `jobId` (`number | string`) in the global version instead. To get a reference to the actual `job` object in such a case, use the `Queue#getJob()` method. This call returns a promise, so declare the handler `async` and await it. For example:

```typescript

@OnGlobalQueueCompleted()
async onGlobalCompleted(jobId: number, result: any) {
  const job = await this.immediateQueue.getJob(jobId);
  console.log('(Global) on completed: job ', job.id, ' -> result: ', result);
}
```

> **Hint** To access the `Queue` object (to make a `getJob()` call), you must inject it. The queue must also be registered in the module where you inject it.

In addition to the specific event listener decorators, you can use the generic `@OnQueueEvent()` decorator in combination with either the `BullQueueEvents` or `BullQueueGlobalEvents` enum. See the [Events section of the Bull reference](https://github.com/OptimalBits/bull/blob/master/REFERENCE.md#events) to learn more about events.

#### Queue management[#](/application/queues#queue-management-1)

Queues have an API for management functions such as pausing and resuming, and retrieving the count of jobs in various states. See the [Queue section of the Bull reference](https://github.com/OptimalBits/bull/blob/master/REFERENCE.md#queue) for the full API. Invoke these methods directly on the `Queue` object, as shown in the pause and resume examples below.

Pause a queue with the `pause()` method. A paused queue doesn't process new jobs until it's resumed, but jobs already being processed continue until they finish.

```typescript

await audioQueue.pause();
```

To resume a paused queue, use the `resume()` method, as follows:

```typescript

await audioQueue.resume();
```

#### Separate processes[#](/application/queues#separate-processes-1)

Job handlers can also run in a separate (forked) process (see [Separate processes](https://github.com/OptimalBits/bull#separate-processes) in the Bull documentation). This has several advantages:

* The process is sandboxed, so if it crashes, the worker isn't affected.
* You can run blocking code without affecting the queue (jobs don't stall).
* Better utilization of multi-core CPUs.
* Fewer connections to Redis.

app.module.ts

JS TS

```ts

import { Module } from '@nestjs/common';
import { BullModule } from '@nestjs/bull';
import { join } from 'node:path';

@Module({
  imports: [
    BullModule.registerQueue({
      name: 'audio',
      processors: [join(import.meta.dirname, 'processor.js')],
    }),
  ],
})
export class AppModule {}
```

Because your function runs in a forked process, dependency injection (and the IoC container) isn't available. Your processor function must contain (or create) all instances of the external dependencies it needs.

processor.ts

JS TS

```ts

import { Job, DoneCallback } from 'bull';

export default function (job: Job, cb: DoneCallback) {
  console.log(`[${process.pid}] ${JSON.stringify(job.data)}`);
  cb(null, 'It works');
}
```

#### Async configuration[#](/application/queues#async-configuration-1)

You may want to pass `bull` options asynchronously instead of statically. In this case, use the `forRootAsync()` method, which provides several ways to handle async configuration.

One approach is to use a factory function:

```typescript

BullModule.forRootAsync({
  useFactory: () => ({
    redis: {
      host: 'localhost',
      port: 6379,
    },
  }),
});
```

The factory behaves like any other [asynchronous provider](/fundamentals/async-providers) (e.g., it can be `async` and can inject dependencies through `inject`).

```typescript

BullModule.forRootAsync({
  imports: [ConfigModule],
  useFactory: async (configService: ConfigService) => ({
    redis: {
      host: configService.get('QUEUE_HOST'),
      port: configService.get('QUEUE_PORT'),
    },
  }),
  inject: [ConfigService],
});
```

Alternatively, you can use the `useClass` syntax:

```typescript

BullModule.forRootAsync({
  useClass: BullConfigService,
});
```

The construction above instantiates `BullConfigService` inside `BullModule` and uses it to provide an options object by calling `createSharedConfiguration()`. This means `BullConfigService` has to implement the `SharedBullConfigurationFactory` interface, as shown below:

```typescript

@Injectable()
class BullConfigService implements SharedBullConfigurationFactory {
  createSharedConfiguration(): BullRootModuleOptions {
    return {
      redis: {
        host: 'localhost',
        port: 6379,
      },
    };
  }
}
```

To reuse a provider imported from a different module instead of creating `BullConfigService` inside `BullModule`, use the `useExisting` syntax.

```typescript

BullModule.forRootAsync({
  imports: [ConfigModule],
  useExisting: ConfigService,
});
```

This construction works the same as `useClass` with one critical difference: `BullModule` looks up imported modules to reuse an existing `ConfigService` instead of instantiating a new one.

Likewise, to pass queue options asynchronously, use the `registerQueueAsync()` method. Specify the `name` attribute outside the factory function.

```typescript

BullModule.registerQueueAsync({
  name: 'audio',
  useFactory: () => ({
    redis: {
      host: 'localhost',
      port: 6379,
    },
  }),
});
```

#### Example[#](/application/queues#example)

A working example is available in the [26-queues sample](https://github.com/nestjs/nest/tree/master/sample/26-queues).

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/application/queues.md)

----
url: https://docs.nestjs.com/v11/faq/hybrid-application
----

* [Hybrid application](https://docs.nestjs.com/v11/faq/hybrid-application#hybrid-application)
* [Sharing configuration](https://docs.nestjs.com/v11/faq/hybrid-application#sharing-configuration)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/faq/hybrid-application.md "Suggest Edits")

### Hybrid application

A hybrid application is one that listens for requests from two or more different sources. This can combine an HTTP server with a microservice listener or even just multiple different microservice listeners. The default `createMicroservice` method does not allow for multiple servers so in this case each microservice must be created and started manually. In order to do this, the `INestApplication` instance can be connected with `INestMicroservice` instances through the `connectMicroservice()` method.

```typescript

const app = await NestFactory.create(AppModule);
const microservice = app.connectMicroservice<MicroserviceOptions>({
  transport: Transport.TCP,
});

await app.startAllMicroservices();
await app.listen(3001);
```

> **Hint** the `app.listen(port)` method starts an HTTP server on the specified address. If your application does not handle HTTP requests then you should use the `app.init()` method instead.

To connect multiple microservice instances, issue the call to `connectMicroservice()` for each microservice:

```typescript

const app = await NestFactory.create(AppModule);
// microservice #1
const microserviceTcp = app.connectMicroservice<MicroserviceOptions>({
  transport: Transport.TCP,
  options: {
    port: 3001,
  },
});
// microservice #2
const microserviceRedis = app.connectMicroservice<MicroserviceOptions>({
  transport: Transport.REDIS,
  options: {
    host: 'localhost',
    port: 6379,
  },
});

await app.startAllMicroservices();
await app.listen(3001);
```

To bind `@MessagePattern()` to only one transport strategy (for example, MQTT) in a hybrid application with multiple microservices, we can pass the second argument of type `Transport` which is an enum with all the built-in transport strategies defined.

JS TS

```typescript

@MessagePattern('time.us.*', Transport.NATS)
getDate(@Payload() data: number[], @Ctx() context: NatsContext) {
  console.log(`Subject: ${context.getSubject()}`); // e.g. "time.us.east"
  return new Date().toLocaleTimeString(...);
}
@MessagePattern({ cmd: 'time.us' }, Transport.TCP)
getTCPDate(@Payload() data: number[]) {
  return new Date().toLocaleTimeString(...);
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('time.us.*', Transport.NATS)
getDate(data, context) {
  console.log(`Subject: ${context.getSubject()}`); // e.g. "time.us.east"
  return new Date().toLocaleTimeString(...);
}
@Bind(Payload(), Ctx())
@MessagePattern({ cmd: 'time.us' }, Transport.TCP)
getTCPDate(data, context) {
  return new Date().toLocaleTimeString(...);
}
```

> **Hint**`@Payload()`, `@Ctx()`, `Transport` and `NatsContext` are imported from `@nestjs/microservices`.

#### Sharing configuration[#](/faq/hybrid-application#sharing-configuration)

By default a hybrid application will not inherit global pipes, interceptors, guards and filters configured for the main (HTTP-based) application. To inherit these configuration properties from the main application, set the `inheritAppConfig` property in the second argument (an optional options object) of the `connectMicroservice()` call, as follow:

```typescript

const microservice = app.connectMicroservice<MicroserviceOptions>(
  {
    transport: Transport.TCP,
  },
  { inheritAppConfig: true },
);
```

----
url: https://docs.nestjs.com/v11/standalone-applications
----

* [Standalone applications](https://docs.nestjs.com/v11/standalone-applications#standalone-applications)
* [Getting started](https://docs.nestjs.com/v11/standalone-applications#getting-started)
* [Retrieving providers from static modules](https://docs.nestjs.com/v11/standalone-applications#retrieving-providers-from-static-modules)
* [Retrieving providers from dynamic modules](https://docs.nestjs.com/v11/standalone-applications#retrieving-providers-from-dynamic-modules)
* [Terminating phase](https://docs.nestjs.com/v11/standalone-applications#terminating-phase)
* [Example](https://docs.nestjs.com/v11/standalone-applications#example)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/application-context.md "Suggest Edits")

### Standalone applications

There are several ways of mounting a Nest application. You can create a web app, a microservice or just a bare Nest **standalone application** (without any network listeners). The Nest standalone application is a wrapper around the Nest **IoC container**, which holds all instantiated classes. We can obtain a reference to any existing instance from within any imported module directly using the standalone application object. Thus, you can take advantage of the Nest framework anywhere, including, for example, scripted **CRON** jobs. You can even build a **CLI** on top of it.

#### Getting started[#](/standalone-applications#getting-started)

To create a Nest standalone application, use the following construction:

JS TS

```typescript

async function bootstrap() {
  const app = await NestFactory.createApplicationContext(AppModule);
  // your application logic here ...
}
bootstrap();
```

#### Retrieving providers from static modules[#](/standalone-applications#retrieving-providers-from-static-modules)

The standalone application object allows you to obtain a reference to any instance registered within the Nest application. Let's imagine that we have a `TasksService` provider in the `TasksModule` module that was imported by our `AppModule` module. This class provides a set of methods that we want to call from within a CRON job.

JS TS

```typescript

const tasksService = app.get(TasksService);
```

To access the `TasksService` instance we use the `get()` method. The `get()` method acts like a **query** that searches for an instance in each registered module. You can pass any provider's token to it. Alternatively, for strict context checking, pass an options object with the `strict: true` property. With this option in effect, you have to navigate through specific modules to obtain a particular instance from the selected context.

JS TS

```typescript

const tasksService = app.select(TasksModule).get(TasksService, { strict: true });
```

Following is a summary of the methods available for retrieving instance references from the standalone application object.

|            |                                                                                                                                                  |
| ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| `get()`    | Retrieves an instance of a controller or provider (including guards, filters, and so on) available in the application context.                   |
| `select()` | Navigates through the module's graph to pull out a specific instance of the selected module (used together with strict mode as described above). |

> **Hint** In non-strict mode, the root module is selected by default. To select any other module, you need to navigate the modules graph manually, step by step.

Keep in mind that a standalone application does not have any network listeners, so any Nest features related to HTTP (e.g., middleware, interceptors, pipes, guards, etc.) are not available in this context.

For example, even if you register a global interceptor in your application and then retrieve a controller's instance using the `app.get()` method, the interceptor will not be executed.

#### Retrieving providers from dynamic modules[#](/standalone-applications#retrieving-providers-from-dynamic-modules)

When dealing with [dynamic modules](/v11/fundamentals/dynamic-modules), we should supply the same object that represents the registered dynamic module in the application to `app.select`. For example:

JS TS

```typescript

export const dynamicConfigModule = ConfigModule.register({ folder: './config' });

@Module({
  imports: [dynamicConfigModule],
})
export class AppModule {}
```

Then you can select that module later on:

JS TS

```typescript

const configService = app.select(dynamicConfigModule).get(ConfigService, { strict: true });
```

#### Terminating phase[#](/standalone-applications#terminating-phase)

If you want the Node application to close after the script finishes (e.g., for a script running CRON jobs), you must call the `app.close()` method in the end of your `bootstrap` function like this:

JS TS

```typescript

async function bootstrap() {
  const app = await NestFactory.createApplicationContext(AppModule);
  // application logic...
  await app.close();
}
bootstrap();
```

And as mentioned in the [Lifecycle events](/v11/fundamentals/lifecycle-events) chapter, that will trigger lifecycle hooks.

#### Example[#](/standalone-applications#example)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/18-context).

----
url: https://docs.nestjs.com/v9/techniques/queues
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Queues](https://docs.nestjs.com/v9/techniques/queues#queues)
* [Installation](https://docs.nestjs.com/v9/techniques/queues#installation)
* [Named configurations](https://docs.nestjs.com/v9/techniques/queues#named-configurations)
* [Producers](https://docs.nestjs.com/v9/techniques/queues#producers)
* [Named jobs](https://docs.nestjs.com/v9/techniques/queues#named-jobs)
* [Job options](https://docs.nestjs.com/v9/techniques/queues#job-options)
* [Consumers](https://docs.nestjs.com/v9/techniques/queues#consumers)
* [Request-scoped consumers](https://docs.nestjs.com/v9/techniques/queues#request-scoped-consumers)
* [Event listeners](https://docs.nestjs.com/v9/techniques/queues#event-listeners)
* [Queue management](https://docs.nestjs.com/v9/techniques/queues#queue-management)
* [Separate processes](https://docs.nestjs.com/v9/techniques/queues#separate-processes)
* [Async configuration](https://docs.nestjs.com/v9/techniques/queues#async-configuration)
* [Example](https://docs.nestjs.com/v9/techniques/queues#example)

```bash

$ npm install --save @nestjs/bull bull
```

Once the installation process is complete, we can import the `BullModule` into the root `AppModule`.

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { BullModule } from '@nestjs/bull';

@Module({
  imports: [
    BullModule.forRoot({
      redis: {
        host: 'localhost',
        port: 6379,
      },
    }),
  ],
})
export class AppModule {}
```

```typescript

BullModule.registerQueue({
  name: 'audio',
});
```

> **Hint** Create multiple queues by passing multiple comma-separated configuration objects to the `registerQueue()` method.

The `registerQueue()` method is used to instantiate and/or register queues. Queues are shared across modules and processes that connect to the same underlying Redis database with the same credentials. Each queue is unique by its name property. A queue name is used as both an injection token (for injecting the queue into controllers/providers), and as an argument to decorators to associate consumer classes and listeners with queues.

You can also override some of the pre-configured options for a specific queue, as follows:

```typescript

BullModule.registerQueue({
  name: 'audio',
  redis: {
    port: 6380,
  },
});
```

```typescript

BullModule.forRoot('alternative-config', {
  redis: {
    port: 6381,
  },
});
```

In the example above, `'alternative-config'` is just a configuration key (it can be any arbitrary string).

With this in place, you can now point to this configuration in the `registerQueue()` options object:

```typescript

BullModule.registerQueue({
  configKey: 'alternative-config',
  name: 'video'
});
```

#### Producers[#](/techniques/queues#producers)

Job producers add jobs to queues. Producers are typically application services (Nest [providers](/v9/providers)). To add jobs to a queue, first inject the queue into the service as follows:

```typescript

import { Injectable } from '@nestjs/common';
import { Queue } from 'bull';
import { InjectQueue } from '@nestjs/bull';

@Injectable()
export class AudioService {
  constructor(@InjectQueue('audio') private audioQueue: Queue) {}
}
```

> **Hint** The `@InjectQueue()` decorator identifies the queue by its name, as provided in the `registerQueue()` method call (e.g., `'audio'`).

Now, add a job by calling the queue's `add()` method, passing a user-defined job object. Jobs are represented as serializable JavaScript objects (since that is how they are stored in the Redis database). The shape of the job you pass is arbitrary; use it to represent the semantics of your job object.

```typescript

const job = await this.audioQueue.add({
  foo: 'bar',
});
```

#### Named jobs[#](/techniques/queues#named-jobs)

Jobs may have unique names. This allows you to create specialized [consumers](techniques/queues#consumers) that will only process jobs with a given name.

```typescript

const job = await this.audioQueue.add('transcode', {
  foo: 'bar',
});
```

> **Warning** When using named jobs, you must create processors for each unique name added to a queue, or the queue will complain that you are missing a processor for the given job. See [here](techniques/queues#consumers) for more information on consuming named jobs.

```typescript

const job = await this.audioQueue.add(
  {
    foo: 'bar',
  },
  { delay: 3000 }, // 3 seconds delayed
);
```

To add a job to the right end of the queue (process the job as **LIFO** (Last In First Out)), set the `lifo` property of the configuration object to `true`.

```typescript

const job = await this.audioQueue.add(
  {
    foo: 'bar',
  },
  { lifo: true },
);
```

To prioritize a job, use the `priority` property.

```typescript

const job = await this.audioQueue.add(
  {
    foo: 'bar',
  },
  { priority: 2 },
);
```

#### Consumers[#](/techniques/queues#consumers)

A consumer is a **class** defining methods that either process jobs added into the queue, or listen for events on the queue, or both. Declare a consumer class using the `@Processor()` decorator as follows:

```typescript

import { Processor } from '@nestjs/bull';

@Processor('audio')
export class AudioConsumer {}
```

> **Hint** Consumers must be registered as `providers` so the `@nestjs/bull` package can pick them up.

Where the decorator's string argument (e.g., `'audio'`) is the name of the queue to be associated with the class methods.

Within a consumer class, declare job handlers by decorating handler methods with the `@Process()` decorator.

```typescript

import { Processor, Process } from '@nestjs/bull';
import { Job } from 'bull';

@Processor('audio')
export class AudioConsumer {
  @Process()
  async transcode(job: Job<unknown>) {
    let progress = 0;
    for (i = 0; i < 100; i++) {
      await doSomething(job.data);
      progress += 1;
      await job.progress(progress);
    }
    return {};
  }
}
```

The decorated method (e.g., `transcode()`) is called whenever the worker is idle and there are jobs to process in the queue. This handler method receives the `job` object as its only argument. The value returned by the handler method is stored in the job object and can be accessed later on, for example in a listener for the completed event.

`Job` objects have multiple methods that allow you to interact with their state. For example, the above code uses the `progress()` method to update the job's progress. See [here](https://github.com/OptimalBits/bull/blob/master/REFERENCE.md#job) for the complete `Job` object API reference.

You can designate that a job handler method will handle **only** jobs of a certain type (jobs with a specific `name`) by passing that `name` to the `@Process()` decorator as shown below. You can have multiple `@Process()` handlers in a given consumer class, corresponding to each job type (`name`). When you use named jobs, be sure to have a handler corresponding to each name.

```typescript

@Process('transcode')
async transcode(job: Job<unknown>) { ... }
```

> **Warning** When defining multiple consumers for the same queue, the `concurrency` option in `@Process({ concurrency: 1 })` won't take effect. The minimum `concurrency` will match the number of consumers defined. This also applies even if `@Process()` handlers use a different `name` to handle named jobs.

#### Request-scoped consumers[#](/techniques/queues#request-scoped-consumers)

When a consumer is flagged as request-scoped (learn more about the injection scopes [here](/fundamentals/injection-scopes#provider-scope)), a new instance of the class will be created exclusively for each job. The instance will be garbage-collected after the job has completed.

```typescript

@Processor({
  name: 'audio',
  scope: Scope.REQUEST,
})
```

Since request-scoped consumer classes are instantiated dynamically and scoped to a single job, you can inject a `JOB_REF` through the constructor using a standard approach.

```typescript

constructor(@Inject(JOB_REF) jobRef: Job) {
  console.log(jobRef);
}
```

> **Hint** The `JOB_REF` token is imported from the `@nestjs/bull` package.

#### Event listeners[#](/techniques/queues#event-listeners)

Bull generates a set of useful events when queue and/or job state changes occur. Nest provides a set of decorators that allow subscribing to a core set of standard events. These are exported from the `@nestjs/bull` package.

Event listeners must be declared within a [consumer](techniques/queues#consumers) class (i.e., within a class decorated with the `@Processor()` decorator). To listen for an event, use one of the decorators in the table below to declare a handler for the event. For example, to listen to the event emitted when a job enters the active state in the `audio` queue, use the following construct:

```typescript

import { Processor, Process, OnQueueActive } from '@nestjs/bull';
import { Job } from 'bull';

@Processor('audio')
export class AudioConsumer {

  @OnQueueActive()
  onActive(job: Job) {
    console.log(
      `Processing job ${job.id} of type ${job.name} with data ${job.data}...`,
    );
  }
  ...
```

Since Bull operates in a distributed (multi-node) environment, it defines the concept of event locality. This concept recognizes that events may be triggered either entirely within a single process, or on shared queues from different processes. A **local** event is one that is produced when an action or state change is triggered on a queue in the local process. In other words, when your event producers and consumers are local to a single process, all events happening on queues are local.

When a queue is shared across multiple processes, we encounter the possibility of **global** events. For a listener in one process to receive an event notification triggered by another process, it must register for a global event.

Event handlers are invoked whenever their corresponding event is emitted. The handler is called with the signature shown in the table below, providing access to information relevant to the event. We discuss one key difference between local and global event handler signatures below.

| Local event listeners | Global event listeners      | Handler method signature / When fired                                                                                                                                 |
| --------------------- | --------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `@OnQueueError()`     | `@OnGlobalQueueError()`     | `handler(error: Error)` - An error occurred. `error` contains the triggering error.                                                                                   |
| `@OnQueueWaiting()`   | `@OnGlobalQueueWaiting()`   | `handler(jobId: number \| string)` - A Job is waiting to be processed as soon as a worker is idling. `jobId` contains the id for the job that has entered this state. |
| `@OnQueueActive()`    | `@OnGlobalQueueActive()`    | `handler(job: Job)` - Job `job`has started.                                                                                                                           |
| `@OnQueueStalled()`   | `@OnGlobalQueueStalled()`   | `handler(job: Job)` - Job `job` has been marked as stalled. This is useful for debugging job workers that crash or pause the event loop.                              |
| `@OnQueueProgress()`  | `@OnGlobalQueueProgress()`  | `handler(job: Job, progress: number)` - Job `job`'s progress was updated to value `progress`.                                                                         |
| `@OnQueueCompleted()` | `@OnGlobalQueueCompleted()` | `handler(job: Job, result: any)` Job `job` successfully completed with a result `result`.                                                                             |
| `@OnQueueFailed()`    | `@OnGlobalQueueFailed()`    | `handler(job: Job, err: Error)` Job `job` failed with reason `err`.                                                                                                   |
| `@OnQueuePaused()`    | `@OnGlobalQueuePaused()`    | `handler()` The queue has been paused.                                                                                                                                |
| `@OnQueueResumed()`   | `@OnGlobalQueueResumed()`   | `handler(job: Job)` The queue has been resumed.                                                                                                                       |
| `@OnQueueCleaned()`   | `@OnGlobalQueueCleaned()`   | `handler(jobs: Job[], type: string)` Old jobs have been cleaned from the queue. `jobs` is an array of cleaned jobs, and `type` is the type of jobs cleaned.           |
| `@OnQueueDrained()`   | `@OnGlobalQueueDrained()`   | `handler()` Emitted whenever the queue has processed all the waiting jobs (even if there can be some delayed jobs not yet processed).                                 |
| `@OnQueueRemoved()`   | `@OnGlobalQueueRemoved()`   | `handler(job: Job)` Job `job` was successfully removed.                                                                                                               |

When listening for global events, the method signatures can be slightly different from their local counterpart. Specifically, any method signature that receives `job` objects in the local version, instead receives a `jobId` (`number`) in the global version. To get a reference to the actual `job` object in such a case, use the `Queue#getJob` method. This call should be awaited, and therefore the handler should be declared `async`. For example:

```typescript

@OnGlobalQueueCompleted()
async onGlobalCompleted(jobId: number, result: any) {
  const job = await this.immediateQueue.getJob(jobId);
  console.log('(Global) on completed: job ', job.id, ' -> result: ', result);
}
```

> **Hint** To access the `Queue` object (to make a `getJob()` call), you must of course inject it. Also, the Queue must be registered in the module where you are injecting it.

In addition to the specific event listener decorators, you can also use the generic `@OnQueueEvent()` decorator in combination with either `BullQueueEvents` or `BullQueueGlobalEvents` enums. Read more about events [here](https://github.com/OptimalBits/bull/blob/master/REFERENCE.md#events).

#### Queue management[#](/techniques/queues#queue-management)

Queue's have an API that allows you to perform management functions like pausing and resuming, retrieving the count of jobs in various states, and several more. You can find the full queue API [here](https://github.com/OptimalBits/bull/blob/master/REFERENCE.md#queue). Invoke any of these methods directly on the `Queue` object, as shown below with the pause/resume examples.

Pause a queue with the `pause()` method call. A paused queue will not process new jobs until resumed, but current jobs being processed will continue until they are finalized.

```typescript

await audioQueue.pause();
```

To resume a paused queue, use the `resume()` method, as follows:

```typescript

await audioQueue.resume();
```

```ts

import { Module } from '@nestjs/common';
import { BullModule } from '@nestjs/bull';
import { join } from 'path';

@Module({
  imports: [
    BullModule.registerQueue({
      name: 'audio',
      processors: [join(__dirname, 'processor.js')],
    }),
  ],
})
export class AppModule {}
```

Please note that because your function is being executed in a forked process, Dependency Injection (and IoC container) won't be available. That means that your processor function will need to contain (or create) all instances of external dependencies it needs.

processor.ts

JS TS

```ts

import { Job, DoneCallback } from 'bull';

export default function (job: Job, cb: DoneCallback) {
  console.log(`[${process.pid}] ${JSON.stringify(job.data)}`);
  cb(null, 'It works');
}
```

#### Async configuration[#](/techniques/queues#async-configuration)

You may want to pass `bull` options asynchronously instead of statically. In this case, use the `forRootAsync()` method which provides several ways to deal with async configuration. Likewise, if you want to pass queue options asynchronously, use the `registerQueueAsync()` method.

One approach is to use a factory function:

```typescript

BullModule.forRootAsync({
  useFactory: () => ({
    redis: {
      host: 'localhost',
      port: 6379,
    },
  }),
});
```

Our factory behaves like any other [asynchronous provider](https://docs.nestjs.com/fundamentals/async-providers) (e.g., it can be `async` and it's able to inject dependencies through `inject`).

```typescript

BullModule.forRootAsync({
  imports: [ConfigModule],
  useFactory: async (configService: ConfigService) => ({
    redis: {
      host: configService.get('QUEUE_HOST'),
      port: configService.get('QUEUE_PORT'),
    },
  }),
  inject: [ConfigService],
});
```

Alternatively, you can use the `useClass` syntax:

```typescript

BullModule.forRootAsync({
  useClass: BullConfigService,
});
```

The construction above will instantiate `BullConfigService` inside `BullModule` and use it to provide an options object by calling `createSharedConfiguration()`. Note that this means that the `BullConfigService` has to implement the `SharedBullConfigurationFactory` interface, as shown below:

```typescript

@Injectable()
class BullConfigService implements SharedBullConfigurationFactory {
  createSharedConfiguration(): BullModuleOptions {
    return {
      redis: {
        host: 'localhost',
        port: 6379,
      },
    };
  }
}
```

In order to prevent the creation of `BullConfigService` inside `BullModule` and use a provider imported from a different module, you can use the `useExisting` syntax.

```typescript

BullModule.forRootAsync({
  imports: [ConfigModule],
  useExisting: ConfigService,
});
```

This construction works the same as `useClass` with one critical difference - `BullModule` will lookup imported modules to reuse an existing `ConfigService` instead of instantiating a new one.

#### Example[#](/techniques/queues#example)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/26-queues).

----
url: https://docs.nestjs.com/v9/security/encryption-and-hashing
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Encryption and Hashing](https://docs.nestjs.com/v9/security/encryption-and-hashing#encryption-and-hashing)
* [Encryption](https://docs.nestjs.com/v9/security/encryption-and-hashing#encryption)
* [Hashing](https://docs.nestjs.com/v9/security/encryption-and-hashing#hashing)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/security/encryption-hashing.md "Suggest Edits")

### Encryption and Hashing

**Encryption** is the process of encoding information. This process converts the original representation of the information, known as plaintext, into an alternative form known as ciphertext. Ideally, only authorized parties can decipher a ciphertext back to plaintext and access the original information. Encryption does not itself prevent interference but denies the intelligible content to a would-be interceptor. Encryption is a two-way function; what is encrypted can be decrypted with the proper key.

**Hashing** is the process of converting a given key into another value. A hash function is used to generate the new value according to a mathematical algorithm. Once hashing has been done, it should be impossible to go from the output to the input.

#### Encryption[#](/security/encryption-and-hashing#encryption)

Node.js provides a built-in [crypto module](https://nodejs.org/api/crypto.html) that you can use to encrypt and decrypt strings, numbers, buffers, streams, and more. Nest itself does not provide any additional package on top of this module to avoid introducing unnecessary abstractions.

As an example, let's use AES (Advanced Encryption System) `'aes-256-ctr'` algorithm CTR encryption mode.

```typescript

import { createCipheriv, randomBytes, scrypt } from 'crypto';
import { promisify } from 'util';

const iv = randomBytes(16);
const password = 'Password used to generate key';

// The key length is dependent on the algorithm.
// In this case for aes256, it is 32 bytes.
const key = (await promisify(scrypt)(password, 'salt', 32)) as Buffer;
const cipher = createCipheriv('aes-256-ctr', key, iv);

const textToEncrypt = 'Nest';
const encryptedText = Buffer.concat([
  cipher.update(textToEncrypt),
  cipher.final(),
]);
```

Now to decrypt `encryptedText` value:

```typescript

import { createDecipheriv } from 'crypto';

const decipher = createDecipheriv('aes-256-ctr', key, iv);
const decryptedText = Buffer.concat([
  decipher.update(encryptedText),
  decipher.final(),
]);
```

#### Hashing[#](/security/encryption-and-hashing#hashing)

For hashing, we recommend using either the [bcrypt](https://www.npmjs.com/package/bcrypt) or [argon2](https://www.npmjs.com/package/argon2) packages. Nest itself does not provide any additional wrappers on top of these modules to avoid introducing unnecessary abstractions (making the learning curve short).

As an example, let's use `bcrypt` to hash a random password.

First install required packages:

```shell

$ npm i bcrypt
$ npm i -D @types/bcrypt
```

Once the installation is complete, you can use the `hash` function, as follows:

```typescript

import * as bcrypt from 'bcrypt';

const saltOrRounds = 10;
const password = 'random_password';
const hash = await bcrypt.hash(password, saltOrRounds);
```

To generate a salt, use the `genSalt` function:

```typescript

const salt = await bcrypt.genSalt();
```

To compare/check a password, use the `compare` function:

```typescript

const isMatch = await bcrypt.compare(password, hash);
```

You can read more about available functions [here](https://www.npmjs.com/package/bcrypt).

----
url: https://docs.nestjs.com/v9/openapi/introduction
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Introduction](https://docs.nestjs.com/v9/openapi/introduction#introduction)
* [Installation](https://docs.nestjs.com/v9/openapi/introduction#installation)
* [Bootstrap](https://docs.nestjs.com/v9/openapi/introduction#bootstrap)
* [Document options](https://docs.nestjs.com/v9/openapi/introduction#document-options)
* [Setup options](https://docs.nestjs.com/v9/openapi/introduction#setup-options)
* [Example](https://docs.nestjs.com/v9/openapi/introduction#example)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/openapi/introduction.md "Suggest Edits")

### Introduction

The [OpenAPI](https://swagger.io/specification/) specification is a language-agnostic definition format used to describe RESTful APIs. Nest provides a dedicated [module](https://github.com/nestjs/swagger) which allows generating such a specification by leveraging decorators.

#### Installation[#](/openapi/introduction#installation)

To begin using it, we first install the required dependency.

```bash

$ npm install --save @nestjs/swagger
```

#### Bootstrap[#](/openapi/introduction#bootstrap)

Once the installation process is complete, open the `main.ts` file and initialize Swagger using the `SwaggerModule` class:

main.ts

JS TS

```typescript

import { NestFactory } from '@nestjs/core';
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);

  const config = new DocumentBuilder()
    .setTitle('Cats example')
    .setDescription('The cats API description')
    .setVersion('1.0')
    .addTag('cats')
    .build();
  const document = SwaggerModule.createDocument(app, config);
  SwaggerModule.setup('api', app, document);

  await app.listen(3000);
}
bootstrap();
```

> **Hint**`document` (returned by the `SwaggerModule#createDocument()` method) is a serializable object conforming to [OpenAPI Document](https://swagger.io/specification/#openapi-document). Instead of hosting it via HTTP, you could also save it as a JSON/YAML file, and consume it in different ways.

```bash

$ npm run start
```

While the application is running, open your browser and navigate to `http://localhost:3000/api`. You should see the Swagger UI.

As you can see, the `SwaggerModule` automatically reflects all of your endpoints.

> **Hint** To generate and download a Swagger JSON file, navigate to `http://localhost:3000/api-json` (assuming that your Swagger documentation is available under `http://localhost:3000/api`).

> **Warning** When using `fastify` and `helmet`, there may be a problem with [CSP](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP), to solve this collision, configure the CSP as shown below:
>
> ```typescript
>
> app.register(helmet, {
>   contentSecurityPolicy: {
>     directives: {
>       defaultSrc: [`'self'`],
>       styleSrc: [`'self'`, `'unsafe-inline'`],
>       imgSrc: [`'self'`, 'data:', 'validator.swagger.io'],
>       scriptSrc: [`'self'`, `https: 'unsafe-inline'`],
>     },
>   },
> });
>
> // If you are not going to use CSP at all, you can use this:
> app.register(helmet, {
>   contentSecurityPolicy: false,
> });
> ```

#### Document options[#](/openapi/introduction#document-options)

When creating a document, it is possible to provide some extra options to fine tune the library's behavior. These options should be of type `SwaggerDocumentOptions`, which can be the following:

```typescript

export interface SwaggerDocumentOptions {
  /**
   * List of modules to include in the specification
   */
  include?: Function[];

  /**
   * Additional, extra models that should be inspected and included in the specification
   */
  extraModels?: Function[];

  /**
   * If `true`, swagger will ignore the global prefix set through `setGlobalPrefix()` method
   */
  ignoreGlobalPrefix?: boolean;

  /**
   * If `true`, swagger will also load routes from the modules imported by `include` modules
   */
  deepScanRoutes?: boolean;

  /**
   * Custom operationIdFactory that will be used to generate the `operationId`
   * based on the `controllerKey` and `methodKey`
   * @default () => controllerKey_methodKey
   */
  operationIdFactory?: (controllerKey: string, methodKey: string) => string;
}
```

For example, if you want to make sure that the library generates operation names like `createUser` instead of `UserController_createUser`, you can set the following:

```typescript

const options: SwaggerDocumentOptions =  {
  operationIdFactory: (
    controllerKey: string,
    methodKey: string
  ) => methodKey
};
const document = SwaggerModule.createDocument(app, config, options);
```

#### Setup options[#](/openapi/introduction#setup-options)

You can configure Swagger UI by passing the options object which fulfills the `ExpressSwaggerCustomOptions` (if you use express) interface as a fourth argument of the `SwaggerModule#setup` method.

```typescript

export interface ExpressSwaggerCustomOptions {
  explorer?: boolean;
  swaggerOptions?: Record<string, any>;
  customCss?: string;
  customCssUrl?: string;
  customJs?: string;
  customfavIcon?: string;
  swaggerUrl?: string;
  customSiteTitle?: string;
  validatorUrl?: string;
  url?: string;
  urls?: Record<'url' | 'name', string>[];
}
```

#### Example[#](/openapi/introduction#example)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/11-swagger).

----
url: https://docs.nestjs.com/v7/techniques/task-scheduling
----

* [Task Scheduling](https://docs.nestjs.com/v7/techniques/task-scheduling#task-scheduling)
* [Installation](https://docs.nestjs.com/v7/techniques/task-scheduling#installation)
* [Declarative cron jobs](https://docs.nestjs.com/v7/techniques/task-scheduling#declarative-cron-jobs)
* [Declarative intervals](https://docs.nestjs.com/v7/techniques/task-scheduling#declarative-intervals)
* [Declarative timeouts](https://docs.nestjs.com/v7/techniques/task-scheduling#declarative-timeouts)
* [Dynamic schedule module API](https://docs.nestjs.com/v7/techniques/task-scheduling#dynamic-schedule-module-api)
* [Dynamic cron jobs](https://docs.nestjs.com/v7/techniques/task-scheduling#dynamic-cron-jobs)
* [Dynamic intervals](https://docs.nestjs.com/v7/techniques/task-scheduling#dynamic-intervals)
* [Dynamic timeouts](https://docs.nestjs.com/v7/techniques/task-scheduling#dynamic-timeouts)
* [Example](https://docs.nestjs.com/v7/techniques/task-scheduling#example)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/techniques/task-scheduling.md "Suggest Edits")

### Task Scheduling

Task scheduling allows you to schedule arbitrary code (methods/functions) to execute at a fixed date/time, at recurring intervals, or once after a specified interval. In the Linux world, this is often handled by packages like [cron](https://en.wikipedia.org/wiki/Cron) at the OS level. For Node.js apps, there are several packages that emulate cron-like functionality. Nest provides the `@nestjs/schedule` package, which integrates with the popular Node.js [node-cron](https://github.com/kelektiv/node-cron) package. We'll cover this package in the current chapter.

#### Installation[#](/techniques/task-scheduling#installation)

To begin using it, we first install the required dependencies.

```bash

$ npm install --save @nestjs/schedule
$ npm install --save-dev @types/cron
```

To activate job scheduling, import the `ScheduleModule` into the root `AppModule` and run the `forRoot()` static method as shown below:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { ScheduleModule } from '@nestjs/schedule';

@Module({
  imports: [
    ScheduleModule.forRoot()
  ],
})
export class AppModule {}
```

The `.forRoot()` call initializes the scheduler and registers any declarative [cron jobs](techniques/task-scheduling#declarative-cron-jobs), [timeouts](techniques/task-scheduling#declarative-timeouts) and [intervals](techniques/task-scheduling#declarative-intervals) that exist within your app. Registration occurs when the `onApplicationBootstrap` lifecycle hook occurs, ensuring that all modules have loaded and declared any scheduled jobs.

#### Declarative cron jobs[#](/techniques/task-scheduling#declarative-cron-jobs)

A cron job schedules an arbitrary function (method call) to run automatically. Cron jobs can run:

* Once, at a specified date/time.
* On a recurring basis; recurring jobs can run at a specified instant within a specified interval (for example, once per hour, once per week, once every 5 minutes)

Declare a cron job with the `@Cron()` decorator preceding the method definition containing the code to be executed, as follows:

```typescript

import { Injectable, Logger } from '@nestjs/common';
import { Cron } from '@nestjs/schedule';

@Injectable()
export class TasksService {
  private readonly logger = new Logger(TasksService.name);

  @Cron('45 * * * * *')
  handleCron() {
    this.logger.debug('Called when the current second is 45');
  }
}
```

In this example, the `handleCron()` method will be called each time the current second is `45`. In other words, the method will be run once per minute, at the 45 second mark.

The `@Cron()` decorator supports all standard [cron patterns](http://crontab.org/):

* Asterisk (e.g. `*`)
* Ranges (e.g. `1-3,5`)
* Steps (e.g. `*/2`)

In the example above, we passed `45 * * * * *` to the decorator. The following key shows how each position in the cron pattern string is interpreted:

```javascript

* * * * * *
| | | | | |
| | | | | day of week
| | | | month
| | | day of month
| | hour
| minute
second (optional)
```

Some sample cron patterns are:

|                     |                                             |
| ------------------- | ------------------------------------------- |
| `* * * * * *`       | every second                                |
| `45 * * * * *`      | every minute, on the 45th second            |
| `* 10 * * * *`      | every hour, at the start of the 10th minute |
| `0 */30 9-17 * * *` | every 30 minutes between 9am and 5pm        |
| `0 30 11 * * 1-5`   | Monday to Friday at 11:30am                 |

The `@nestjs/schedule` package provides a convenience enum with commonly used cron patterns. You can use this enum as follows:

```typescript

import { Injectable, Logger } from '@nestjs/common';
import { Cron, CronExpression } from '@nestjs/schedule';

@Injectable()
export class TasksService {
  private readonly logger = new Logger(TasksService.name);

  @Cron(CronExpression.EVERY_45_SECONDS)
  handleCron() {
    this.logger.debug('Called every 45 seconds');
  }
}
```

In this example, the `handleCron()` method will be called every `45` seconds.

Alternatively, you can supply a JavaScript `Date` object to the `@Cron()` decorator. Doing so causes the job to execute exactly once, at the specified date.

> **Hint** Use JavaScript date arithmetic to schedule jobs relative to the current date. For example, `@Cron(new Date(Date.now() + 10 * 1000))` to schedule a job to run 10 seconds after the app starts.

Also, you can supply additional options as the second parameter to the `@Cron()` decorator.

|             |                                                                                                                                                                                                                                                        |
| ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `name`      | Useful to access and control a cron job after it's been declared.                                                                                                                                                                                      |
| `timeZone`  | Specify the timezone for the execution. This will modify the actual time relative to your timezone. If the timezone is invalid, an error is thrown. You can check all timezones available at [Moment Timezone](http://momentjs.com/timezone/) website. |
| `utcOffset` | This allows you to specify the offset of your timezone rather than using the `timeZone` param.                                                                                                                                                         |

```typescript

import { Injectable } from '@nestjs/common';
import { Cron, CronExpression } from '@nestjs/schedule';

@Injectable()
export class NotificationService {
  @Cron('* * 0 * * *', {
    name: 'notifications',
    timeZone: 'Europe/Paris',
  })
  triggerNotifications() {}
}
```

You can access and control a cron job after it's been declared, or dynamically create a cron job (where its cron pattern is defined at runtime) with the [Dynamic API](/techniques/task-scheduling#dynamic-schedule-module-api). To access a declarative cron job via the API, you must associate the job with a name by passing the `name` property in an optional options object as the second argument of the decorator.

#### Declarative intervals[#](/techniques/task-scheduling#declarative-intervals)

To declare that a method should run at a (recurring) specified interval, prefix the method definition with the `@Interval()` decorator. Pass the interval value, as a number in milliseconds, to the decorator as shown below:

```typescript

@Interval(10000)
handleInterval() {
  this.logger.debug('Called every 10 seconds');
}
```

> **Hint** This mechanism uses the JavaScript `setInterval()` function under the hood. You can also utilize a cron job to schedule recurring jobs.

If you want to control your declarative interval from outside the declaring class via the [Dynamic API](/techniques/task-scheduling#dynamic-schedule-module-api), associate the interval with a name using the following construction:

```typescript

@Interval('notifications', 2500)
handleInterval() {}
```

```typescript

@Timeout(5000)
handleTimeout() {
  this.logger.debug('Called once after 5 seconds');
}
```

> **Hint** This mechanism uses the JavaScript `setTimeout()` function under the hood.

If you want to control your declarative timeout from outside the declaring class via the [Dynamic API](/techniques/task-scheduling#dynamic-schedule-module-api), associate the timeout with a name using the following construction:

```typescript

@Timeout('notifications', 2500)
handleTimeout() {}
```

The [Dynamic API](techniques/task-scheduling#dynamic-timeouts) also enables **creating** dynamic timeouts, where the timeout's properties are defined at runtime, and **listing and deleting** them.

#### Dynamic schedule module API[#](/techniques/task-scheduling#dynamic-schedule-module-api)

The `@nestjs/schedule` module provides a dynamic API that enables managing declarative [cron jobs](techniques/task-scheduling#declarative-cron-jobs), [timeouts](techniques/task-scheduling#declarative-timeouts) and [intervals](techniques/task-scheduling#declarative-intervals). The API also enables creating and managing **dynamic** cron jobs, timeouts and intervals, where the properties are defined at runtime.

#### Dynamic cron jobs[#](/techniques/task-scheduling#dynamic-cron-jobs)

Obtain a reference to a `CronJob` instance by name from anywhere in your code using the `SchedulerRegistry` API. First, inject `SchedulerRegistry` using standard constructor injection:

```typescript

constructor(private schedulerRegistry: SchedulerRegistry) {}
```

> **Hint** Import the `SchedulerRegistry` from the `@nestjs/schedule` package.

Then use it in a class as follows. Assume a cron job was created with the following declaration:

```typescript

@Cron('* * 8 * * *', {
  name: 'notifications',
})
triggerNotifications() {}
```

Access this job using the following:

```typescript

const job = this.schedulerRegistry.getCronJob('notifications');

job.stop();
console.log(job.lastDate());
```

The `getCronJob()` method returns the named cron job. The returned `CronJob` object has the following methods:

* `stop()` - stops a job that is scheduled to run.
* `start()` - restarts a job that has been stopped.
* `setTime(time: CronTime)` - stops a job, sets a new time for it, and then starts it
* `lastDate()` - returns a string representation of the last date a job executed
* `nextDates(count: number)` - returns an array (size `count`) of `moment` objects representing upcoming job execution dates.

> **Hint** Use `toDate()` on `moment` objects to render them in human readable form.

**Create** a new cron job dynamically using the `SchedulerRegistry.addCronJob()` method, as follows:

```typescript

addCronJob(name: string, seconds: string) {
  const job = new CronJob(`${seconds} * * * * *`, () => {
    this.logger.warn(`time (${seconds}) for job ${name} to run!`);
  });

  this.scheduler.addCronJob(name, job);
  job.start();

  this.logger.warn(
    `job ${name} added for each minute at ${seconds} seconds!`,
  );
}
```

In this code, we use the `CronJob` object from the `cron` package to create the cron job. The `CronJob` constructor takes a cron pattern (just like the `@Cron()`[decorator](techniques/task-scheduling#declarative-cron-jobs)) as its first argument, and a callback to be executed when the cron timer fires as its second argument. The `SchedulerRegistry.addCronJob()` method takes two arguments: a name for the `CronJob`, and the `CronJob` object itself.

> **Warning** Remember to inject the `SchedulerRegistry` before accessing it. Import `CronJob` from the `cron` package.

**Delete** a named cron job using the `SchedulerRegistry.deleteCronJob()` method, as follows:

```typescript

deleteCron(name: string) {
  this.scheduler.deleteCronJob(name);
  this.logger.warn(`job ${name} deleted!`);
}
```

**List** all cron jobs using the `SchedulerRegistry.getCronJobs()` method as follows:

```typescript

getCrons() {
  const jobs = this.scheduler.getCronJobs();
  jobs.forEach((value, key, map) => {
    let next;
    try {
      next = value.nextDates().toDate();
    } catch (e) {
      next = 'error: next fire date is in the past!';
    }
    this.logger.log(`job: ${key} -> next: ${next}`);
  });
}
```

The `getCronJobs()` method returns a `map`. In this code, we iterate over the map and attempt to access the `nextDates()` method of each `CronJob`. In the `CronJob` API, if a job has already fired and has no future firing dates, it throws an exception.

#### Dynamic intervals[#](/techniques/task-scheduling#dynamic-intervals)

Obtain a reference to an interval with the `SchedulerRegistry.getInterval()` method. As above, inject `SchedulerRegistry` using standard constructor injection:

```typescript

constructor(private schedulerRegistry: SchedulerRegistry) {}
```

And use it as follows:

```typescript

const interval = this.schedulerRegistry.getInterval('notifications');
clearInterval(interval);
```

**Create** a new interval dynamically using the `SchedulerRegistry.addInterval()` method, as follows:

```typescript

addInterval(name: string, milliseconds: number) {
  const callback = () => {
    this.logger.warn(`Interval ${name} executing at time (${milliseconds})!`);
  };

  const interval = setInterval(callback, milliseconds);
  this.scheduler.addInterval(name, interval);
}
```

In this code, we create a standard JavaScript interval, then pass it to the `ScheduleRegistry.addInterval()` method. That method takes two arguments: a name for the interval, and the interval itself.

**Delete** a named interval using the `SchedulerRegistry.deleteInterval()` method, as follows:

```typescript

deleteInterval(name: string) {
  this.scheduler.deleteInterval(name);
  this.logger.warn(`Interval ${name} deleted!`);
}
```

**List** all intervals using the `SchedulerRegistry.getIntervals()` method as follows:

```typescript

getIntervals() {
  const intervals = this.scheduler.getIntervals();
  intervals.forEach(key => this.logger.log(`Interval: ${key}`));
}
```

#### Dynamic timeouts[#](/techniques/task-scheduling#dynamic-timeouts)

Obtain a reference to a timeout with the `SchedulerRegistry.getTimeout()` method. As above, inject `SchedulerRegistry` using standard constructor injection:

```typescript

constructor(private schedulerRegistry: SchedulerRegistry) {}
```

And use it as follows:

```typescript

const timeout = this.schedulerRegistry.getTimeout('notifications');
clearTimeout(timeout);
```

**Create** a new timeout dynamically using the `SchedulerRegistry.addTimeout()` method, as follows:

```typescript

addTimeout(name: string, milliseconds: number) {
  const callback = () => {
    this.logger.warn(`Timeout ${name} executing after (${milliseconds})!`);
  };

  const timeout = setTimeout(callback, milliseconds);
  this.scheduler.addTimeout(name, timeout);
}
```

In this code, we create a standard JavaScript timeout, then pass it to the `ScheduleRegistry.addTimeout()` method. That method takes two arguments: a name for the timeout, and the timeout itself.

**Delete** a named timeout using the `SchedulerRegistry.deleteTimeout()` method, as follows:

```typescript

deleteTimeout(name: string) {
  this.scheduler.deleteTimeout(name);
  this.logger.warn(`Timeout ${name} deleted!`);
}
```

**List** all timeouts using the `SchedulerRegistry.getTimeouts()` method as follows:

```typescript

getTimeouts() {
  const timeouts = this.scheduler.getTimeouts();
  timeouts.forEach(key => this.logger.log(`Timeout: ${key}`));
}
```

#### Example[#](/techniques/task-scheduling#example)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/27-scheduling).

----
url: https://docs.nestjs.com/v8/websockets/guards
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Guards](https://docs.nestjs.com/v8/websockets/guards#guards)
* [Binding guards](https://docs.nestjs.com/v8/websockets/guards#binding-guards)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/websockets/guards.md "Suggest Edits")

### Guards

There is no fundamental difference between web sockets guards and [regular HTTP application guards](/v8/guards). The only difference is that instead of throwing `HttpException`, you should use `WsException`.

> **Hint** The `WsException` class is exposed from `@nestjs/websockets` package.

#### Binding guards[#](/websockets/guards#binding-guards)

The following example uses a method-scoped guard. Just as with HTTP based applications, you can also use gateway-scoped guards (i.e., prefix the gateway class with a `@UseGuards()` decorator).

JS TS

```typescript

@UseGuards(AuthGuard)
@SubscribeMessage('events')
handleEvent(client: Client, data: unknown): WsResponse<unknown> {
  const event = 'events';
  return { event, data };
}
```

```typescript

@UseGuards(AuthGuard)
@SubscribeMessage('events')
handleEvent(client, data) {
  const event = 'events';
  return { event, data };
}
```

----
url: https://docs.nestjs.com/v8/middleware
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Middleware](https://docs.nestjs.com/v8/middleware#middleware)
* [Dependency injection](https://docs.nestjs.com/v8/middleware#dependency-injection)
* [Applying middleware](https://docs.nestjs.com/v8/middleware#applying-middleware)
* [Route wildcards](https://docs.nestjs.com/v8/middleware#route-wildcards)
* [Middleware consumer](https://docs.nestjs.com/v8/middleware#middleware-consumer)
* [Excluding routes](https://docs.nestjs.com/v8/middleware#excluding-routes)
* [Functional middleware](https://docs.nestjs.com/v8/middleware#functional-middleware)
* [Multiple middleware](https://docs.nestjs.com/v8/middleware#multiple-middleware)
* [Global middleware](https://docs.nestjs.com/v8/middleware#global-middleware)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/middlewares.md "Suggest Edits")

### Middleware

Middleware is a function which is called **before** the route handler. Middleware functions have access to the [request](https://expressjs.com/en/4x/api.html#req) and [response](https://expressjs.com/en/4x/api.html#res) objects, and the `next()` middleware function in the application’s request-response cycle. The **next** middleware function is commonly denoted by a variable named `next`.

Nest middleware are, by default, equivalent to [express](https://expressjs.com/en/guide/using-middleware.html) middleware. The following description from the official express documentation describes the capabilities of middleware:

> Middleware functions can perform the following tasks:
>
> * execute any code.
> * make changes to the request and the response objects.
> * end the request-response cycle.
> * call the next middleware function in the stack.
> * if the current middleware function does not end the request-response cycle, it must call `next()` to pass control to the next middleware function. Otherwise, the request will be left hanging.

You implement custom Nest middleware in either a function, or in a class with an `@Injectable()` decorator. The class should implement the `NestMiddleware` interface, while the function does not have any special requirements. Let's start by implementing a simple middleware feature using the class method.

logger.middleware.ts

JS TS

```typescript

import { Injectable, NestMiddleware } from '@nestjs/common';
import { Request, Response, NextFunction } from 'express';

@Injectable()
export class LoggerMiddleware implements NestMiddleware {
  use(req: Request, res: Response, next: NextFunction) {
    console.log('Request...');
    next();
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';

@Injectable()
export class LoggerMiddleware {
  use(req, res, next) {
    console.log('Request...');
    next();
  }
}
```

#### Dependency injection[#](/middleware#dependency-injection)

Nest middleware fully supports Dependency Injection. Just as with providers and controllers, they are able to **inject dependencies** that are available within the same module. As usual, this is done through the `constructor`.

#### Applying middleware[#](/middleware#applying-middleware)

There is no place for middleware in the `@Module()` decorator. Instead, we set them up using the `configure()` method of the module class. Modules that include middleware have to implement the `NestModule` interface. Let's set up the `LoggerMiddleware` at the `AppModule` level.

app.module.ts

JS TS

```typescript

import { Module, NestModule, MiddlewareConsumer } from '@nestjs/common';
import { LoggerMiddleware } from './common/middleware/logger.middleware';
import { CatsModule } from './cats/cats.module';

@Module({
  imports: [CatsModule],
})
export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer
      .apply(LoggerMiddleware)
      .forRoutes('cats');
  }
}
```

```typescript

import { Module } from '@nestjs/common';
import { LoggerMiddleware } from './common/middleware/logger.middleware';
import { CatsModule } from './cats/cats.module';

@Module({
  imports: [CatsModule],
})
export class AppModule {
  configure(consumer) {
    consumer
      .apply(LoggerMiddleware)
      .forRoutes('cats');
  }
}
```

In the above example we have set up the `LoggerMiddleware` for the `/cats` route handlers that were previously defined inside the `CatsController`. We may also further restrict a middleware to a particular request method by passing an object containing the route `path` and request `method` to the `forRoutes()` method when configuring the middleware. In the example below, notice that we import the `RequestMethod` enum to reference the desired request method type.

app.module.ts

JS TS

```typescript

import { Module, NestModule, RequestMethod, MiddlewareConsumer } from '@nestjs/common';
import { LoggerMiddleware } from './common/middleware/logger.middleware';
import { CatsModule } from './cats/cats.module';

@Module({
  imports: [CatsModule],
})
export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer
      .apply(LoggerMiddleware)
      .forRoutes({ path: 'cats', method: RequestMethod.GET });
  }
}
```

```typescript

import { Module, RequestMethod } from '@nestjs/common';
import { LoggerMiddleware } from './common/middleware/logger.middleware';
import { CatsModule } from './cats/cats.module';

@Module({
  imports: [CatsModule],
})
export class AppModule {
  configure(consumer) {
    consumer
      .apply(LoggerMiddleware)
      .forRoutes({ path: 'cats', method: RequestMethod.GET });
  }
}
```

> **Hint** The `configure()` method can be made asynchronous using `async/await` (e.g., you can `await` completion of an asynchronous operation inside the `configure()` method body).

#### Route wildcards[#](/middleware#route-wildcards)

Pattern based routes are supported as well. For instance, the asterisk is used as a **wildcard**, and will match any combination of characters:

```typescript

forRoutes({ path: 'ab*cd', method: RequestMethod.ALL });
```

The `'ab*cd'` route path will match `abcd`, `ab_cd`, `abecd`, and so on. The characters `?`, `+`, `*`, and `()` may be used in a route path, and are subsets of their regular expression counterparts. The hyphen ( `-`) and the dot (`.`) are interpreted literally by string-based paths.

> **Warning** The `fastify` package uses the latest version of the `path-to-regexp` package, which no longer supports wildcard asterisks `*`. Instead, you must use parameters (e.g., `(.*)`, `:splat*`).

#### Middleware consumer[#](/middleware#middleware-consumer)

The `MiddlewareConsumer` is a helper class. It provides several built-in methods to manage middleware. All of them can be simply **chained** in the [fluent style](https://en.wikipedia.org/wiki/Fluent_interface). The `forRoutes()` method can take a single string, multiple strings, a `RouteInfo` object, a controller class and even multiple controller classes. In most cases you'll probably just pass a list of **controllers** separated by commas. Below is an example with a single controller:

app.module.ts

JS TS

```typescript

import { Module, NestModule, MiddlewareConsumer } from '@nestjs/common';
import { LoggerMiddleware } from './common/middleware/logger.middleware';
import { CatsModule } from './cats/cats.module';
import { CatsController } from './cats/cats.controller';

@Module({
  imports: [CatsModule],
})
export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer
      .apply(LoggerMiddleware)
      .forRoutes(CatsController);
  }
}
```

```typescript

import { Module } from '@nestjs/common';
import { LoggerMiddleware } from './common/middleware/logger.middleware';
import { CatsModule } from './cats/cats.module';
import { CatsController } from './cats/cats.controller';

@Module({
  imports: [CatsModule],
})
export class AppModule {
  configure(consumer) {
    consumer
      .apply(LoggerMiddleware)
      .forRoutes(CatsController);
  }
}
```

> **Hint** The `apply()` method may either take a single middleware, or multiple arguments to specify [multiple middlewares](/middleware#multiple-middleware).

#### Excluding routes[#](/middleware#excluding-routes)

At times we want to **exclude** certain routes from having the middleware applied. We can easily exclude certain routes with the `exclude()` method. This method can take a single string, multiple strings, or a `RouteInfo` object identifying routes to be excluded, as shown below:

```typescript

consumer
  .apply(LoggerMiddleware)
  .exclude(
    { path: 'cats', method: RequestMethod.GET },
    { path: 'cats', method: RequestMethod.POST },
    'cats/(.*)',
  )
  .forRoutes(CatsController);
```

> **Hint** The `exclude()` method supports wildcard parameters using the [path-to-regexp](https://github.com/pillarjs/path-to-regexp#parameters) package.

With the example above, `LoggerMiddleware` will be bound to all routes defined inside `CatsController`**except** the three passed to the `exclude()` method.

#### Functional middleware[#](/middleware#functional-middleware)

The `LoggerMiddleware` class we've been using is quite simple. It has no members, no additional methods, and no dependencies. Why can't we just define it in a simple function instead of a class? In fact, we can. This type of middleware is called **functional middleware**. Let's transform the logger middleware from class-based into functional middleware to illustrate the difference:

logger.middleware.ts

JS TS

```typescript

import { Request, Response, NextFunction } from 'express';

export function logger(req: Request, res: Response, next: NextFunction) {
  console.log(`Request...`);
  next();
};
```

```typescript

export function logger(req, res, next) {
  console.log(`Request...`);
  next();
};
```

And use it within the `AppModule`:

app.module.ts

JS TS

```typescript

consumer
  .apply(logger)
  .forRoutes(CatsController);
```

> **Hint** Consider using the simpler **functional middleware** alternative any time your middleware doesn't need any dependencies.

#### Multiple middleware[#](/middleware#multiple-middleware)

As mentioned above, in order to bind multiple middleware that are executed sequentially, simply provide a comma separated list inside the `apply()` method:

```typescript

consumer.apply(cors(), helmet(), logger).forRoutes(CatsController);
```

#### Global middleware[#](/middleware#global-middleware)

If we want to bind middleware to every registered route at once, we can use the `use()` method that is supplied by the `INestApplication` instance:

main.ts

JS TS

```typescript

const app = await NestFactory.create(AppModule);
app.use(logger);
await app.listen(3000);
```

> **Hint** Accessing the DI container in a global middleware is not possible. You can use a [functional middleware](middleware#functional-middleware) instead when using `app.use()`. Alternatively, you can use a class middleware and consume it with `.forRoutes('*')` within the `AppModule` (or any other module).

----
url: https://docs.nestjs.com/v8/microservices/rabbitmq
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [RabbitMQ](https://docs.nestjs.com/v8/microservices/rabbitmq#rabbitmq)
* [Installation](https://docs.nestjs.com/v8/microservices/rabbitmq#installation)
* [Overview](https://docs.nestjs.com/v8/microservices/rabbitmq#overview)
* [Options](https://docs.nestjs.com/v8/microservices/rabbitmq#options)
* [Client](https://docs.nestjs.com/v8/microservices/rabbitmq#client)
* [Context](https://docs.nestjs.com/v8/microservices/rabbitmq#context)
* [Message acknowledgement](https://docs.nestjs.com/v8/microservices/rabbitmq#message-acknowledgement)
* [Record builders](https://docs.nestjs.com/v8/microservices/rabbitmq#record-builders)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/microservices/rabbitmq.md "Suggest Edits")

### RabbitMQ

[RabbitMQ](https://www.rabbitmq.com/) is an open-source and lightweight message broker which supports multiple messaging protocols. It can be deployed in distributed and federated configurations to meet high-scale, high-availability requirements. In addition, it's the most widely deployed message broker, used worldwide at small startups and large enterprises.

#### Installation[#](/microservices/rabbitmq#installation)

To start building RabbitMQ-based microservices, first install the required packages:

```bash

$ npm i --save amqplib amqp-connection-manager
```

#### Overview[#](/microservices/rabbitmq#overview)

To use the RabbitMQ transporter, pass the following options object to the `createMicroservice()` method:

main.ts

JS TS

```typescript

const app = await NestFactory.createMicroservice<MicroserviceOptions>(AppModule, {
  transport: Transport.RMQ,
  options: {
    urls: ['amqp://localhost:5672'],
    queue: 'cats_queue',
    queueOptions: {
      durable: false
    },
  },
});
```

```typescript

const app = await NestFactory.createMicroservice(AppModule, {
  transport: Transport.RMQ,
  options: {
    urls: ['amqp://localhost:5672'],
    queue: 'cats_queue',
    queueOptions: {
      durable: false
    },
  },
});
```

> **Hint** The `Transport` enum is imported from the `@nestjs/microservices` package.

#### Options[#](/microservices/rabbitmq#options)

The `options` property is specific to the chosen transporter. The **RabbitMQ** transporter exposes the properties described below.

|                         |                                                                                                                          |
| ----------------------- | ------------------------------------------------------------------------------------------------------------------------ |
| `urls`                  | Connection urls                                                                                                          |
| `queue`                 | Queue name which your server will listen to                                                                              |
| `prefetchCount`         | Sets the prefetch count for the channel                                                                                  |
| `isGlobalPrefetchCount` | Enables per channel prefetching                                                                                          |
| `noAck`                 | If `false`, manual acknowledgment mode enabled                                                                           |
| `queueOptions`          | Additional queue options (read more [here](https://www.squaremobius.net/amqp.node/channel_api.html#channel_assertQueue)) |
| `socketOptions`         | Additional socket options (read more [here](https://www.squaremobius.net/amqp.node/channel_api.html#socket-options))     |
| `headers`               | Headers to be sent along with every message                                                                              |

#### Client[#](/microservices/rabbitmq#client)

Like other microservice transporters, you have [several options](https://docs.nestjs.com/microservices/basics#client) for creating a RabbitMQ `ClientProxy` instance.

One method for creating an instance is to use the `ClientsModule`. To create a client instance with the `ClientsModule`, import it and use the `register()` method to pass an options object with the same properties shown above in the `createMicroservice()` method, as well as a `name` property to be used as the injection token. Read more about `ClientsModule`[here](https://docs.nestjs.com/microservices/basics#client).

```typescript

@Module({
  imports: [
    ClientsModule.register([
      {
        name: 'MATH_SERVICE',
        transport: Transport.RMQ,
        options: {
          urls: ['amqp://localhost:5672'],
          queue: 'cats_queue',
          queueOptions: {
            durable: false
          },
        },
      },
    ]),
  ]
  ...
})
```

Other options to create a client (either `ClientProxyFactory` or `@Client()`) can be used as well. You can read about them [here](https://docs.nestjs.com/microservices/basics#client).

#### Context[#](/microservices/rabbitmq#context)

In more sophisticated scenarios, you may want to access more information about the incoming request. When using the RabbitMQ transporter, you can access the `RmqContext` object.

JS TS

```typescript

@MessagePattern('notifications')
getNotifications(@Payload() data: number[], @Ctx() context: RmqContext) {
  console.log(`Pattern: ${context.getPattern()}`);
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('notifications')
getNotifications(data, context) {
  console.log(`Pattern: ${context.getPattern()}`);
}
```

> **Hint**`@Payload()`, `@Ctx()` and `RmqContext` are imported from the `@nestjs/microservices` package.

To access the original RabbitMQ message (with the `properties`, `fields`, and `content`), use the `getMessage()` method of the `RmqContext` object, as follows:

JS TS

```typescript

@MessagePattern('notifications')
getNotifications(@Payload() data: number[], @Ctx() context: RmqContext) {
  console.log(context.getMessage());
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('notifications')
getNotifications(data, context) {
  console.log(context.getMessage());
}
```

To retrieve a reference to the RabbitMQ [channel](https://www.rabbitmq.com/channels.html), use the `getChannelRef` method of the `RmqContext` object, as follows:

JS TS

```typescript

@MessagePattern('notifications')
getNotifications(@Payload() data: number[], @Ctx() context: RmqContext) {
  console.log(context.getChannelRef());
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('notifications')
getNotifications(data, context) {
  console.log(context.getChannelRef());
}
```

#### Message acknowledgement[#](/microservices/rabbitmq#message-acknowledgement)

To make sure a message is never lost, RabbitMQ supports [message acknowledgements](https://www.rabbitmq.com/confirms.html). An acknowledgement is sent back by the consumer to tell RabbitMQ that a particular message has been received, processed and that RabbitMQ is free to delete it. If a consumer dies (its channel is closed, connection is closed, or TCP connection is lost) without sending an ack, RabbitMQ will understand that a message wasn't processed fully and will re-queue it.

To enable manual acknowledgment mode, set the `noAck` property to `false`:

```typescript

options: {
  urls: ['amqp://localhost:5672'],
  queue: 'cats_queue',
  noAck: false,
  queueOptions: {
    durable: false
  },
},
```

When manual consumer acknowledgements are turned on, we must send a proper acknowledgement from the worker to signal that we are done with a task.

JS TS

```typescript

@MessagePattern('notifications')
getNotifications(@Payload() data: number[], @Ctx() context: RmqContext) {
  const channel = context.getChannelRef();
  const originalMsg = context.getMessage();

  channel.ack(originalMsg);
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('notifications')
getNotifications(data, context) {
  const channel = context.getChannelRef();
  const originalMsg = context.getMessage();

  channel.ack(originalMsg);
}
```

#### Record builders[#](/microservices/rabbitmq#record-builders)

To configure message options, you can use the `RmqRecordBuilder` class (note: this is doable for event-based flows as well). For example, to set `headers` and `priority` properties, use the `setOptions` method, as follows:

```typescript

const message = ':cat:';
const record = new RmqRecordBuilder(message)
  .setOptions({
    headers: {
      ['x-version']: '1.0.0',
    },
    priority: 3,
  })
  .build();

this.client.send('replace-emoji', record).subscribe(...);
```

> **Hint**`RmqRecordBuilder` class is exported from the `@nestjs/microservices` package.

And you can read these values on the server-side as well, by accessing the `RmqContext`, as follows:

JS TS

```typescript

@MessagePattern('replace-emoji')
replaceEmoji(@Payload() data: string, @Ctx() context: RmqContext): string {
  const { properties: { headers } } = context.getMessage();
  return headers['x-version'] === '1.0.0' ? '🐱' : '🐈';
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('replace-emoji')
replaceEmoji(data, context) {
  const { properties: { headers } } = context.getMessage();
  return headers['x-version'] === '1.0.0' ? '🐱' : '🐈';
}
```

----
url: https://docs.nestjs.com/v6/fundamentals/async-providers
----

* [Asynchronous providers](https://docs.nestjs.com/v6/fundamentals/async-providers#asynchronous-providers)
* [Injection](https://docs.nestjs.com/v6/fundamentals/async-providers#injection)
* [Example](https://docs.nestjs.com/v6/fundamentals/async-providers#example)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/fundamentals/async-components.md "Suggest Edits")

### Asynchronous providers

At times, the application start should be delayed until one or more **asynchronous tasks** are completed. For example, you may not want to start accepting requests until the connection with the database has been established. You can achieve this using *asynchronous providers*.

The syntax for this is to use `async/await` with the `useFactory` syntax. The factory returns a `Promise`, and the factory function can `await` asynchronous tasks. Nest will await resolution of the promise before instantiating any class that depends on (injects) such a provider.

```typescript

{
  provide: 'ASYNC_CONNECTION',
  useFactory: async () => {
    const connection = await createConnection(options);
    return connection;
  },
}
```

> **Hint** Learn more about custom provider syntax [here](/v6/fundamentals/custom-providers).

#### Injection[#](/fundamentals/async-providers#injection)

Asynchronous providers are injected to other components by their tokens, like any other provider. In the example above, you would use the construct `@Inject('ASYNC_CONNECTION')`.

## Official enterprise support

* **Providing technical guidance
* **Performing in-depth code reviews
* **Mentoring team members
* **Advising best practices

[Explore more](https://enterprise.nestjs.com "Enterprise | NestJS - A progressive Node.js framework")

#### Example[#](/fundamentals/async-providers#example)

[The TypeORM recipe](/v6/recipes/sql-typeorm) has a more substantial example of an asynchronous provider.

----
url: https://docs.nestjs.com/v7
----

* [Introduction](https://docs.nestjs.com/v7/#introduction)
* [Philosophy](https://docs.nestjs.com/v7/#philosophy)
* [Installation](https://docs.nestjs.com/v7/#installation)
* [Alternatives](https://docs.nestjs.com/v7/#alternatives)

To get started, you can either scaffold the project with the [Nest CLI](/v7/cli/overview), or clone a starter project (both will produce the same outcome).

To scaffold the project with the Nest CLI, run the following commands. This will create a new project directory, and populate the directory with the initial core Nest files and supporting modules, creating a conventional base structure for your project. Creating a new project with the **Nest CLI** is recommended for first-time users. We'll continue with this approach in [First Steps](/v7/first-steps).

```bash

$ npm i -g @nestjs/cli
$ nest new project-name
```

#### Alternatives[#](/#alternatives)

Alternatively, to install the TypeScript starter project with **Git**:

```bash

$ git clone https://github.com/nestjs/typescript-starter.git project
$ cd project
$ npm install
$ npm run start
```

Open your browser and navigate to [`http://localhost:3000/`](http://localhost:3000/).

To install the JavaScript flavor of the starter project, use `javascript-starter.git` in the command sequence above.

You can also manually create a new project from scratch by installing the core and supporting files with **npm** (or **yarn**). In this case, of course, you'll be responsible for creating the project boilerplate files yourself.

```bash

$ npm i --save @nestjs/core @nestjs/common rxjs reflect-metadata
```

----
url: https://docs.nestjs.com/v7/openapi/operations
----

* [Operations](https://docs.nestjs.com/v7/openapi/operations#operations)
* [Tags](https://docs.nestjs.com/v7/openapi/operations#tags)
* [Headers](https://docs.nestjs.com/v7/openapi/operations#headers)
* [Responses](https://docs.nestjs.com/v7/openapi/operations#responses)
* [File upload](https://docs.nestjs.com/v7/openapi/operations#file-upload)
* [Extensions](https://docs.nestjs.com/v7/openapi/operations#extensions)
* [Advanced: Generic ApiResponse](https://docs.nestjs.com/v7/openapi/operations#advanced-generic-apiresponse)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/openapi/operations.md "Suggest Edits")

### Operations

In OpenAPI terms, paths are endpoints (resources), such as `/users` or `/reports/summary`, that your API exposes, and operations are the HTTP methods used to manipulate these paths, such as `GET`, `POST` or `DELETE`.

#### Tags[#](/openapi/operations#tags)

To attach a controller to a specific tag, use the `@ApiTags(...tags)` decorator.

```typescript

@ApiTags('cats')
@Controller('cats')
export class CatsController {}
```

#### Headers[#](/openapi/operations#headers)

To define custom headers that are expected as part of the request, use `@ApiHeader()`.

```typescript

@ApiHeader({
  name: 'X-MyHeader',
  description: 'Custom header',
})
@Controller('cats')
export class CatsController {}
```

#### Responses[#](/openapi/operations#responses)

To define a custom HTTP response, use the `@ApiResponse()` decorator.

```typescript

@Post()
@ApiResponse({ status: 201, description: 'The record has been successfully created.'})
@ApiResponse({ status: 403, description: 'Forbidden.'})
async create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

Nest provides a set of short-hand **API response** decorators that inherit from the `@ApiResponse` decorator:

* `@ApiOkResponse()`
* `@ApiCreatedResponse()`
* `@ApiAcceptedResponse()`
* `@ApiNoContentResponse()`
* `@ApiMovedPermanentlyResponse()`

```typescript

@Post()
@ApiCreatedResponse({ description: 'The record has been successfully created.'})
@ApiForbiddenResponse({ description: 'Forbidden.'})
async create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

To specify a return model for a request, we must create a class and annotate all properties with the `@ApiProperty()` decorator.

```typescript

export class Cat {
  @ApiProperty()
  id: number;

  @ApiProperty()
  name: string;

  @ApiProperty()
  age: number;

  @ApiProperty()
  breed: string;
}
```

Then the `Cat` model can be used in combination with the `type` property of the response decorator.

```typescript

@ApiTags('cats')
@Controller('cats')
export class CatsController {
  @Post()
  @ApiCreatedResponse({
    description: 'The record has been successfully created.',
    type: Cat,
  })
  async create(@Body() createCatDto: CreateCatDto): Promise<Cat> {
    return this.catsService.create(createCatDto);
  }
}
```

Let's open the browser and verify the generated `Cat` model:

#### File upload[#](/openapi/operations#file-upload)

You can enable file upload for a specific method with the `@ApiBody` decorator together with `@ApiConsumes()`. Here's a full example using the [File Upload](/v7/techniques/file-upload) technique:

```typescript

@UseInterceptors(FileInterceptor('file'))
@ApiConsumes('multipart/form-data')
@ApiBody({
  description: 'List of cats',
  type: FileUploadDto,
})
uploadFile(@UploadedFile() file) {}
```

Where `FileUploadDto` is defined as follows:

```typescript

class FileUploadDto {
  @ApiProperty({ type: 'string', format: 'binary' })
  file: any;
}
```

To handle multiple files uploading, you can define `FilesUploadDto` as follows:

```typescript

class FilesUploadDto {
  @ApiProperty({ type: 'array', items: { type: 'string', format: 'binary' } })
  files: any[];
}
```

#### Extensions[#](/openapi/operations#extensions)

To add an Extension to a request use the `@ApiExtension()` decorator. The extension name must be prefixed with `x-`.

```typescript

@ApiExtension('x-foo', { hello: 'world' })
```

#### Advanced: Generic `ApiResponse`[#](/openapi/operations#advanced-generic-apiresponse)

With the ability to provide [Raw Definitions](/openapi/types-and-parameters#raw-definitions), we can define Generic schema for Swagger UI. Assume we have the following DTO:

```ts

export class PaginatedDto<TData> {
  @ApiProperty()
  total: number;

  @ApiProperty()
  limit: number;

  @ApiProperty()
  offset: number;

  results: TData[];
}
```

We skip decorating `results` as we will be providing a raw definition for it later. Now, let's define another DTO and name it, for example, `CatDto`, as follows:

```ts

export class CatDto {
  @ApiProperty()
  name: string;

  @ApiProperty()
  age: number;

  @ApiProperty()
  breed: string;
}
```

With this in place, we can define a `PaginatedDto<CatDto>` response, as follows:

```ts

@ApiOkResponse({
  schema: {
    allOf: [
      { $ref: getSchemaPath(PaginatedDto) },
      {
        properties: {
          results: {
            type: 'array',
            items: { $ref: getSchemaPath(CatDto) },
          },
        },
      },
    ],
  },
})
async findAll(): Promise<PaginatedDto<CatDto>> {}
```

In this example, we specify that the response will have allOf `PaginatedDto` and the `results` property will be of type `Array<CatDto>`.

* `getSchemaPath()` function that returns the OpenAPI Schema path from within the OpenAPI Spec File for a given model.
* `allOf` is a concept that OAS 3 provides to cover various Inheritance related use-cases.

Lastly, since `PaginatedDto` is not directly referenced by any controller, the `SwaggerModule` will not be able to generate a corresponding model definition just yet. In this case, we must add it as an [Extra Model](/openapi/types-and-parameters#extra-models). For example, we can use the `@ApiExtraModels()` decorator on the controller level, as follows:

```ts

@Controller('cats')
@ApiExtraModels(PaginatedDto)
export class CatsController {}
```

If you run Swagger now, the generated `swagger.json` for this specific endpoint should have the following response defined:

```json

"responses": {
  "200": {
    "description": "",
    "content": {
      "application/json": {
        "schema": {
          "allOf": [
            {
              "$ref": "#/components/schemas/PaginatedDto"
            },
            {
              "properties": {
                "results": {
                  "$ref": "#/components/schemas/CatDto"
                }
              }
            }
          ]
        }
      }
    }
  }
}
```

To make it reusable, we can create a custom decorator for `PaginatedDto`, as follows:

```ts

export const ApiPaginatedResponse = <TModel extends Type<any>>(
  model: TModel,
) => {
  return applyDecorators(
    ApiOkResponse({
      schema: {
        allOf: [
          { $ref: getSchemaPath(PaginatedDto) },
          {
            properties: {
              results: {
                type: 'array',
                items: { $ref: getSchemaPath(model) },
              },
            },
          },
        ],
      },
    }),
  );
};
```

> **Hint**`Type<any>` interface and `applyDecorators` function are imported from the `@nestjs/common` package.

With this in place, we can use the custom `@ApiPaginatedResponse()` decorator on our endpoint:

```ts

@ApiPaginatedResponse(CatDto)
async findAll(): Promise<PaginatedDto<CatDto>> {}
```

For client generation tools, this approach poses an ambiguity in how the `PaginatedResponse<TModel>` is being generated for the client. The following snippet is an example of a client generator result for the above `GET /` endpoint.

```typescript

// Angular
findAll(): Observable<{ total: number, limit: number, offset: number, results: CatDto[] }>
```

As you can see, the **Return Type** here is ambiguous. To workaround this issue, you can add a `title` property to the `schema` for `ApiPaginatedResponse`:

```typescript

export const ApiPaginatedResponse = <TModel extends Type<any>>(model: TModel) => {
  return applyDecorators(
    ApiOkResponse({
      schema: {
        title: `PaginatedResponseOf${model.name}`
        allOf: [
          // ...
        ],
      },
    }),
  );
};
```

Now the result of the client generator tool will become:

```ts

// Angular
findAll(): Observable<PaginatedResponseOfCatDto>
```

----
url: https://docs.nestjs.com/v6/techniques/mvc
----

* [Model-View-Controller](https://docs.nestjs.com/v6/techniques/mvc#model-view-controller)
* [Template rendering](https://docs.nestjs.com/v6/techniques/mvc#template-rendering)
* [Dynamic template rendering](https://docs.nestjs.com/v6/techniques/mvc#dynamic-template-rendering)
* [Example](https://docs.nestjs.com/v6/techniques/mvc#example)
* [Fastify](https://docs.nestjs.com/v6/techniques/mvc#fastify)
* [Example](https://docs.nestjs.com/v6/techniques/mvc#example-1)

[](https://srv.carbonads.net/ads/click/x/GTND4277CVSIC2JEFTBLYKQUF67D62JIFTSIVZ3JCAAI6KQJFT7ITKJKC6SDV277CYSIC2QMCEBI52QIFTSD42QLHEYI55QLCAYD653ECTNCYBZ52K)[One SDK. Any model. Ship agents. Get started. ](https://srv.carbonads.net/ads/click/x/GTND4277CVSIC2JEFTBLYKQUF67D62JIFTSIVZ3JCAAI6KQJFT7ITKJKC6SDV277CYSIC2QMCEBI52QIFTSD42QLHEYI55QLCAYD653ECTNCYBZ52K)[ads via Carbon](http://carbonads.net/?utm_source=nestjscom\&utm_medium=ad_via_link\&utm_campaign=in_unit\&utm_term=carbon)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/techniques/mvc.md "Suggest Edits")

### Model-View-Controller

Nest, by default, makes use of the [Express](https://github.com/expressjs/express) library under the hood. Hence, every technique for using the MVC (Model-View-Controller) pattern in Express applies to Nest as well.

First, let's scaffold a simple Nest application using the [CLI](https://github.com/nestjs/nest-cli) tool:

```bash

$ npm i -g @nestjs/cli
$ nest new project
```

In order to create an MVC app, we also need a [template engine](http://expressjs.com/en/guide/using-template-engines.html) to render our HTML views:

```bash

$ npm install --save hbs
```

We've used the `hbs` ([Handlebars](https://github.com/pillarjs/hbs#readme)) engine, though you can use whatever fits your requirements. Once the installation process is complete, we need to configure the express instance using the following code:

main.ts

JS TS

```typescript

import { NestFactory } from '@nestjs/core';
import { NestExpressApplication } from '@nestjs/platform-express';
import { join } from 'path';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create<NestExpressApplication>(
    AppModule,
  );

  app.useStaticAssets(join(__dirname, '..', 'public'));
  app.setBaseViewsDir(join(__dirname, '..', 'views'));
  app.setViewEngine('hbs');

  await app.listen(3000);
}
bootstrap();
```

```typescript

import { NestFactory } from '@nestjs/core';
import { join } from 'path';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(
    AppModule,
  );

  app.useStaticAssets(join(__dirname, '..', 'public'));
  app.setBaseViewsDir(join(__dirname, '..', 'views'));
  app.setViewEngine('hbs');

  await app.listen(3000);
}
bootstrap();
```

We told [Express](https://github.com/expressjs/express) that the `public` directory will be used for storing static assets, `views` will contain templates, and the `hbs` template engine should be used to render HTML output.

#### Template rendering[#](/techniques/mvc#template-rendering)

Now, let's create a `views` directory and `index.hbs` template inside it. In the template, we'll print a `message` passed from the controller:

```html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>App</title>
  </head>
  <body>
    {{ message }}
  </body>
</html>
```

Next, open the `app.controller` file and replace the `root()` method with the following code:

app.controller.ts

JS TS

```typescript

import { Get, Controller, Render } from '@nestjs/common';

@Controller()
export class AppController {
  @Get()
  @Render('index')
  root() {
    return { message: 'Hello world!' };
  }
}
```

In this code, we are specifying the template to use in the `@Render()` decorator, and the return value of the route handler method is passed to the template for rendering. Notice that the return value is an object with a property `message`, matching the `message` placeholder we created in the template.

While the application is running, open your browser and navigate to `http://localhost:3000`. You should see the `Hello world!` message.

#### Dynamic template rendering[#](/techniques/mvc#dynamic-template-rendering)

If the application logic must dynamically decide which template to render, then we should use the `@Res()` decorator, and supply the view name in our route handler, rather than in the `@Render()` decorator:

> **Hint** When Nest detects the `@Res()` decorator, it injects the library-specific `response` object. We can use this object to dynamically render the template. Learn more about the `response` object API [here](http://expressjs.com/en/api.html).

app.controller.ts

JS TS

```typescript

import { Get, Controller, Render } from '@nestjs/common';
import { Response } from 'express';
import { AppService } from './app.service';

@Controller()
export class AppController {
  constructor(private readonly appService: AppService) {}

  @Get()
  root(@Res() res: Response) {
    return res.render(
      this.appService.getViewName(),
      { message: 'Hello world!' },
    );
  }
}
```

#### Example[#](/techniques/mvc#example)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/15-mvc).

#### Fastify[#](/techniques/mvc#fastify)

As mentioned in this [chapter](/v6/techniques/performance), we are able to use any compatible HTTP provider together with Nest. One such library is [Fastify](https://github.com/fastify/fastify). In order to create an MVC application with Fastify, we have to install the following packages:

```bash

$ npm i --save fastify point-of-view handlebars
```

The next steps cover almost the same process used with Express, with minor differences specific to the platform. Once the installation process is complete, open the `main.ts` file and update its contents:

main.ts

JS TS

```typescript

import { NestFactory } from '@nestjs/core';
import { NestFastifyApplication, FastifyAdapter } from '@nestjs/platform-fastify';
import { AppModule } from './app.module';
import { join } from 'path';

async function bootstrap() {
  const app = await NestFactory.create<NestFastifyApplication>(
    AppModule,
    new FastifyAdapter(),
  );
  app.useStaticAssets({
    root: join(__dirname, '..', 'public'),
    prefix: '/public/',
  });
  app.setViewEngine({
    engine: {
      handlebars: require('handlebars'),
    },
    templates: join(__dirname, '..', 'views'),
  });
  await app.listen(3000);
}
bootstrap();
```

```typescript

import { NestFactory } from '@nestjs/core';
import { FastifyAdapter } from '@nestjs/platform-fastify';
import { AppModule } from './app.module';
import { join } from 'path';

async function bootstrap() {
  const app = await NestFactory.create(AppModule, new FastifyAdapter());
  app.useStaticAssets({
    root: join(__dirname, '..', 'public'),
    prefix: '/public/',
  });
  app.setViewEngine({
    engine: {
      handlebars: require('handlebars'),
    },
    templates: join(__dirname, '..', 'views'),
  });
  await app.listen(3000);
}
bootstrap();
```

The Fastify API is slightly different but the end result of those methods calls remains the same. One difference to notice with Fastify is that the template name passed into the `@Render()` decorator must include a file extension.

app.controller.ts

JS TS

```typescript

import { Get, Controller, Render } from '@nestjs/common';

@Controller()
export class AppController {
  @Get()
  @Render('index.hbs')
  root() {
    return { message: 'Hello world!' };
  }
}
```

While the application is running, open your browser and navigate to `http://localhost:3000`. You should see the `Hello world!` message.

#### Example[#](/techniques/mvc#example-1)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/17-mvc-fastify).

----
url: https://docs.nestjs.com/http/server-sent-events
----

[Skip to content](#content)

On this page

* [Server-Sent Events](https://docs.nestjs.com/http/server-sent-events#server-sent-events)
* [Usage](https://docs.nestjs.com/http/server-sent-events#usage)
* [Status code and headers](https://docs.nestjs.com/http/server-sent-events#status-code-and-headers)
* [Client disconnection](https://docs.nestjs.com/http/server-sent-events#client-disconnection)
* [Signal lifetime](https://docs.nestjs.com/http/server-sent-events#signal-lifetime)
* [Example](https://docs.nestjs.com/http/server-sent-events#example)

### Server-Sent Events

Server-Sent Events (SSE) is a server push technology that enables a client to receive automatic updates from a server over an HTTP connection. Each notification is sent as a block of text terminated by a pair of newlines (see [Server-sent events on MDN](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events) to learn more).

#### Usage[#](/http/server-sent-events#usage)

To enable Server-Sent Events on a route (a route registered within a **controller class**), annotate the route handler with the `@Sse()` decorator.

```typescript

@Sse('sse')
sse(): Observable<MessageEvent> {
  return interval(1000).pipe(map((_) => ({ data: { hello: 'world' } })));
}
```

> **Hint** The `@Sse()` decorator and the `MessageEvent` interface are imported from the `@nestjs/common` package, while `Observable`, `interval`, and `map` are imported from the `rxjs` package.

> **Warning** Server-Sent Events routes must return an `Observable` stream (or a `Promise` that resolves to one, as shown [below](/http/server-sent-events#client-disconnection)).

In the example above, we defined a route named `sse` that propagates real-time updates. Clients can listen to these events using the [EventSource API](https://developer.mozilla.org/en-US/docs/Web/API/EventSource).

The `sse()` method returns an `Observable` that emits multiple `MessageEvent` objects (in this example, a new `MessageEvent` every second). Each `MessageEvent` object should respect the following interface to match the specification:

```typescript

export interface MessageEvent {
  data?: string | object;
  id?: string;
  type?: string;
  retry?: number;
  comment?: string;
}
```

Object `data` is serialized to JSON. The `type` property is sent as the SSE `event` field, and `comment` is sent as a comment line, which `EventSource` clients ignore (useful, for example, as a keep-alive). If you don't set `id`, Nest assigns an incrementing ID to each event.

With this in place, you can create an instance of the `EventSource` class in your client-side application, passing the `/sse` route (which matches the path passed to the `@Sse()` decorator above) as a constructor argument.

An `EventSource` instance opens a persistent connection to an HTTP server, which sends events in `text/event-stream` format. The connection remains open until it's closed by calling `EventSource.close()`.

Once the connection is open, incoming messages from the server are delivered to your code in the form of events. If the incoming message has an `event` field, the triggered event has the same name as the field value. If no `event` field is present, a generic `message` event is fired (see the [EventSource documentation on MDN](https://developer.mozilla.org/en-US/docs/Web/API/EventSource)).

```javascript

const eventSource = new EventSource('/sse');
eventSource.onmessage = ({ data }) => {
  console.log('New message', JSON.parse(data));
};
```

#### Status code and headers[#](/http/server-sent-events#status-code-and-headers)

An `@Sse()` route sends the headers set with the `@Header()` decorator. Starting with NestJS v12.1.3, it also sends the status code that its handler or an interceptor sets on the response before the stream starts, and, on Fastify, the headers they set (Express already sent those). To set them in the handler, inject the response with the `@Res()` decorator and its `passthrough` option enabled:

```typescript

@Sse('sse')
sse(@Res({ passthrough: true }) res: Response): Observable<MessageEvent> {
  res.status(202);
  res.header('x-version', '1.0.0');
  return interval(1000).pipe(map((_) => ({ data: { hello: 'world' } })));
}
```

> **Hint**`Res` is imported from the `@nestjs/common` package, and the `Response` type from the `express` package. On Fastify, use the `FastifyReply` type from the `fastify` package.

#### Client disconnection[#](/http/server-sent-events#client-disconnection)

When a client closes the SSE connection (e.g., with `eventSource.close()`), Nest automatically unsubscribes from the returned `Observable`. This stops the event stream and cleans up any associated resources, including the interval timer in the example above.

To run custom teardown logic when a client disconnects, use the `finalize` operator:

```typescript

@Sse('sse')
sse(): Observable<MessageEvent> {
  return interval(1000).pipe(
    map((_) => ({ data: { hello: 'world' } })),
    finalize(() => console.log('Client disconnected')),
  );
}
```

> **Hint** The `finalize` operator (imported from `rxjs`) executes its callback whenever the `Observable` terminates: by completion, error, or unsubscription (which includes client disconnection). This makes it the right place to release external resources, such as database cursors or file handles, tied to the stream.

An `@Sse()` handler can be asynchronous, returning a `Promise<Observable>` rather than an `Observable` directly. This is common when the stream needs expensive setup before the first event can be produced, such as opening a database cursor, acquiring a model session, or authorizing against a downstream service.

```typescript

@Sse('stream')
async stream(): Promise<Observable<MessageEvent>> {
  const session = await createSession();

  return new Observable(subscriber => {
    // ...produce events from `session`
  });
}
```

This leaves a gap. If the client disconnects **while the promise is still resolving**, Nest never subscribes to the returned `Observable`, because it doesn't start a producer whose consumer has already gone away. That's the right behavior for the stream, but it means the `Observable`'s teardown logic never runs, and anything allocated during setup (the `session` above) leaks.

To close that gap, inject the request's `AbortSignal` with the `@SseSignal()` decorator:

```typescript

import { MessageEvent, Sse, SseSignal } from '@nestjs/common';
import { EMPTY, Observable } from 'rxjs';

@Sse('stream')
async stream(@SseSignal() signal: AbortSignal): Promise<Observable<MessageEvent>> {
  const session = await createSession();

  if (signal.aborted) {
    // The client disconnected during setup. The Observable below will never be
    // subscribed, so release the resource here.
    await session.close();
    return EMPTY;
  }

  return new Observable(subscriber => {
    const stream = session.start();
    stream.on('data', data => subscriber.next({ data }));

    return () => {
      stream.stop();
      session.close();
    };
  });
}
```

#### Signal lifetime[#](/http/server-sent-events#signal-lifetime)

The signal represents the lifetime of the **SSE response**, not only the connection. It's aborted once the stream terminates for any reason:

* the client disconnected;
* the `Observable` completed;
* the `Observable` errored.

This makes the signal a single cleanup hook for the whole request. Instead of duplicating teardown across an `abort` listener and the `Observable`'s own teardown function, you can wire resources to the signal once and have them released on every exit path:

```typescript

@Sse('stream')
async stream(@SseSignal() signal: AbortSignal): Promise<Observable<MessageEvent>> {
  // The signal aborts when the response ends, so the fetch is canceled whether
  // the client disconnected or the stream simply finished.
  const upstream = await fetch(UPSTREAM_URL, { signal });

  return new Observable(subscriber => {
    // ...
  });
}
```

Because the signal also aborts on normal completion, `signal.aborted` is only meaningful as a "did the client go away?" check **during setup**, before the `Observable` is returned. At that point, the stream can't have completed yet, so an aborted signal unambiguously means the client disconnected.

> **Notice** Cleanup wired to the `abort` event may run alongside the `Observable`'s teardown function, so make it idempotent.

Inside a producer, you can also use the signal to end the stream when the client leaves:

```typescript

return new Observable<MessageEvent>(subscriber => {
  const timer = setInterval(() => subscriber.next({ data: 'tick' }), 1000);
  const onAbort = () => subscriber.complete();

  signal.addEventListener('abort', onAbort, { once: true });

  return () => {
    clearInterval(timer);
    signal.removeEventListener('abort', onAbort);
  };
});
```

> **Hint**`@SseSignal()` is only populated on `@Sse()` routes; on any other route handler, it resolves to `undefined`. It works the same way on the Express and Fastify platforms.

#### Example[#](/http/server-sent-events#example)

A working example is available in the [28-sse sample](https://github.com/nestjs/nest/tree/master/sample/28-sse).

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/http/server-sent-events.md)

----
url: https://docs.nestjs.com/cli/libraries
----

[Skip to content](#content)

On this page

* [Libraries](https://docs.nestjs.com/cli/libraries#libraries)
* [Nest libraries](https://docs.nestjs.com/cli/libraries#nest-libraries)
* [Creating libraries](https://docs.nestjs.com/cli/libraries#creating-libraries)
* [Using libraries](https://docs.nestjs.com/cli/libraries#using-libraries)

### Libraries

Many applications need to solve the same general problems, or reuse a modular component in several contexts. Nest offers a few ways to address this. Each works at a different level and helps meet different architectural and organizational objectives.

Nest [modules](/modules) provide an execution context that lets components be shared within a single application. You can also package modules with [npm](https://npmjs.com) to create a reusable library that different projects can install. This is an effective way to distribute configurable, reusable libraries to loosely connected or unaffiliated organizations (e.g., by distributing and installing third-party libraries).

For sharing code within closely organized groups (e.g., within company or project boundaries), a more lightweight approach can be useful. Monorepos emerged to enable that, and within a monorepo, a **library** provides a lightweight way to share code. In a Nest monorepo, libraries make it straightforward to assemble applications that share components. This also encourages you to decompose monolithic applications, and to focus development on building and composing modular components.

#### Nest libraries[#](/cli/libraries#nest-libraries)

A Nest library is a Nest project that, unlike an application, cannot run on its own. A library must be imported into a containing application for its code to execute. The built-in support for libraries described in this section is only available for **monorepos** (standard mode projects can achieve similar functionality using npm packages).

For example, an organization may develop an `AuthModule` that manages authentication by implementing the company policies that govern all internal applications. Rather than building that module separately for each application, or packaging the code with npm and requiring each project to install it, a monorepo can define the module as a library. Organized this way, all consumers of the library module see an up-to-date version of `AuthModule` as soon as it is committed. This can significantly help coordinate component development and assembly, and it simplifies end-to-end testing.

#### Creating libraries[#](/cli/libraries#creating-libraries)

Any functionality that is suitable for reuse is a candidate for a library. Deciding what should be a library, and what should be part of an application, is an architectural design decision. Creating a library involves more than copying code from an existing application into it: library code must be decoupled from the application. This may take **more** time up front and force design decisions that you wouldn't face with more tightly coupled code. The effort pays off when the library lets you assemble multiple applications more quickly.

To create a library, run the following command:

```bash

$ nest g library my-library
```

When you run the command, the `library` schematic prompts you for a prefix (also known as an alias) for the library:

```bash

What prefix would you like to use for the library (default: @app or 'defaultLibraryPrefix' setting value)?
```

The default prefix is `@app`, unless your `nest-cli.json` file sets a `defaultLibraryPrefix` property.

The command creates a new project called `my-library` in your workspace. Like an application-type project, a library-type project is generated into a named folder by a schematic. Libraries live in the `libs` folder of the monorepo root. Nest creates the `libs` folder when you create the first library.

The files generated for a library differ slightly from those generated for an application. Here are the contents of the `libs` folder after running the command above:

libs

my-library

src

index.ts

my-library.module.ts

my-library.service.ts

tsconfig.lib.json

The `nest-cli.json` file now has a new entry for the library under the `"projects"` key:

```javascript

...
{
    "my-library": {
      "type": "library",
      "root": "libs/my-library",
      "entryFile": "index",
      "sourceRoot": "libs/my-library/src",
      "compilerOptions": {
        "tsConfigPath": "libs/my-library/tsconfig.lib.json"
      }
}
...
```

There are two differences in `nest-cli.json` metadata between libraries and applications:

* the `"type"` property is set to `"library"` instead of `"application"`
* the `"entryFile"` property is set to `"index"` instead of `"main"`

These differences tell the build process to handle libraries appropriately. For example, a library exports its functionality through the `index.js` file.

Like application-type projects, each library has its own `tsconfig.lib.json` file that extends the root (monorepo-wide) `tsconfig.json` file. You can modify this file to provide library-specific compiler options.

To build the library, run:

```bash

$ nest build my-library
```

#### Using libraries[#](/cli/libraries#using-libraries)

With the generated configuration files in place, using libraries is straightforward. Suppose you want to use `MyLibraryService` from the `my-library` library in the `my-project` application.

Using library modules is the same as using any other Nest module. The monorepo manages paths so that importing libraries and generating builds is transparent. To use `MyLibraryService`, import its declaring module. Modify `my-project/src/app.module.ts` as follows to import `MyLibraryModule`:

```typescript

import { Module } from '@nestjs/common';
import { AppController } from './app.controller.js';
import { AppService } from './app.service.js';
import { MyLibraryModule } from '@app/my-library';

@Module({
  imports: [MyLibraryModule],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}
```

The `import` statement above uses the `@app` path alias, which is the `prefix` we supplied to the `nest g library` command. Nest implements this through tsconfig path mapping. When you add a library, Nest updates the `"paths"` key of the global (monorepo) `tsconfig.json` file like this:

```javascript

"paths": {
    "@app/my-library": [
        "./libs/my-library/src"
    ],
    "@app/my-library/*": [
        "./libs/my-library/src/*"
    ]
}
```

In an ESM project, the first entry points at the library's entry file instead (`./libs/my-library/src/index.ts`).

> **Warning** The `paths` mapping is understood only by the TypeScript compiler. Test runners resolve modules on their own. If you run an application's end-to-end tests with Jest, mirror each alias in that application's e2e Jest config `moduleNameMapper` option, for example: `"moduleNameMapper": { "^@app/my-library(|/.*)$": "<rootDir>/../../libs/my-library/src/$1" }`. Otherwise, imports through the alias fail at test runtime even though the project compiles.

Together, the monorepo and library features make it straightforward to include library modules in applications.

The same mechanism lets you build and deploy applications that compose libraries. Once you've imported `MyLibraryModule`, `nest build` handles module resolution automatically and bundles the application, along with any library dependencies, for deployment. The default compiler for a monorepo is **Rspack**, so the output is a single file that bundles all the transpiled JavaScript. You can switch to `tsc` as described in [Global compiler options](/cli/monorepo#global-compiler-options).

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/cli/libraries.md)

----
url: https://docs.nestjs.com/openapi/operations
----

[Skip to content](#content)

On this page

* [Operations](https://docs.nestjs.com/openapi/operations#operations)
* [Tags](https://docs.nestjs.com/openapi/operations#tags)
* [Headers](https://docs.nestjs.com/openapi/operations#headers)
* [Responses](https://docs.nestjs.com/openapi/operations#responses)
* [File upload](https://docs.nestjs.com/openapi/operations#file-upload)
* [Extensions](https://docs.nestjs.com/openapi/operations#extensions)
* [Advanced: Generic ApiResponse](https://docs.nestjs.com/openapi/operations#advanced-generic-apiresponse)

### Operations

In OpenAPI terms, paths are the endpoints (resources) that your API exposes, such as `/users` or `/reports/summary`. Operations are the HTTP methods used to manipulate these paths, such as `GET`, `POST`, or `DELETE`.

#### Tags[#](/openapi/operations#tags)

To attach a controller to a specific tag, use the `@ApiTags(...tags)` decorator:

```typescript

@ApiTags('cats')
@Controller('cats')
export class CatsController {}
```

OpenAPI 3.2 extends the Tag Object so that tags can be organized into a hierarchy and annotated with a hint about how they should be presented. To declare these relationships, define the tags up front with `DocumentBuilder` and pass the `parent` and `kind` options to `addTag()`:

```typescript

const config = new DocumentBuilder()
  .setOpenAPIVersion('3.2.0')
  .addTag('Animals', 'Everything about animals', undefined, { kind: 'nav' })
  .addTag('Cats', 'Cat operations', undefined, { parent: 'Animals' })
  .addTag('Dogs', 'Dog operations', undefined, { parent: 'Animals' })
  .build();
```

The `parent` option references another tag by name. The `kind` option is a free-form, machine-readable string that hints at how the tag should be used, commonly `nav`, `badge`, or `audience`. The same options object also accepts a `summary`, another OpenAPI 3.2 Tag Object field.

> **Warning** The `parent` and `kind` fields belong to the OpenAPI 3.2 Tag Object. You must call `setOpenAPIVersion('3.2.0')`. Otherwise, the generated document still declares `openapi: 3.0.0`, and strict validators reject these fields. Hierarchy fields can only be defined through `DocumentBuilder.addTag()`. The `@ApiTags()` decorator ignores them and logs a warning.

#### Headers[#](/openapi/operations#headers)

To define custom headers that are expected as part of the request, use `@ApiHeader()`:

```typescript

@ApiHeader({
  name: 'X-MyHeader',
  description: 'Custom header',
})
@Controller('cats')
export class CatsController {}
```

#### Responses[#](/openapi/operations#responses)

To define a custom HTTP response, use the `@ApiResponse()` decorator:

```typescript

@Post()
@ApiResponse({ status: 201, description: 'The record has been successfully created.'})
@ApiResponse({ status: 403, description: 'Forbidden.'})
async create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

Nest provides a set of shorthand **API response** decorators built on top of `@ApiResponse()`, one for each common status code. They include:

* `@ApiOkResponse()`
* `@ApiCreatedResponse()`
* `@ApiAcceptedResponse()`
* `@ApiNoContentResponse()`
* `@ApiMovedPermanentlyResponse()`
* `@ApiFoundResponse()`
* `@ApiPreconditionFailedResponse()`

```typescript

@Post()
@ApiCreatedResponse({ description: 'The record has been successfully created.'})
@ApiForbiddenResponse({ description: 'Forbidden.'})
async create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

To specify a return model for a request, create a class and annotate all of its properties with the `@ApiProperty()` decorator:

```typescript

export class Cat {
  @ApiProperty()
  id: number;

  @ApiProperty()
  name: string;

  @ApiProperty()
  age: number;

  @ApiProperty()
  breed: string;
}
```

You can then use the `Cat` model with the `type` property of the response decorator:

```typescript

@ApiTags('cats')
@Controller('cats')
export class CatsController {
  @Post()
  @ApiCreatedResponse({
    description: 'The record has been successfully created.',
    type: Cat,
  })
  async create(@Body() createCatDto: CreateCatDto): Promise<Cat> {
    return this.catsService.create(createCatDto);
  }
}
```

Open the browser and verify the generated `Cat` model:

Instead of defining responses for each endpoint or controller individually, you can define a global response for all endpoints using the `DocumentBuilder` class. This is useful for responses that every endpoint in your application can return (e.g., errors like `401 Unauthorized` or `500 Internal Server Error`).

```typescript

const config = new DocumentBuilder()
  .addGlobalResponse({
    status: 500,
    description: 'Internal server error',
  })
  // other configurations
  .build();
```

#### File upload[#](/openapi/operations#file-upload)

To document file upload for a specific method, use the `@ApiBody()` decorator together with `@ApiConsumes()`. Here's a full example using the [file upload](/http/file-upload) technique:

```typescript

@UseInterceptors(FileInterceptor('file'))
@ApiConsumes('multipart/form-data')
@ApiBody({
  description: 'List of cats',
  type: FileUploadDto,
})
uploadFile(@UploadedFile() file: Express.Multer.File) {}
```

Where `FileUploadDto` is defined as follows:

```typescript

class FileUploadDto {
  @ApiProperty({ type: 'string', format: 'binary' })
  file: any;
}
```

To handle multiple file uploads, define `FilesUploadDto` as follows:

```typescript

class FilesUploadDto {
  @ApiProperty({ type: 'array', items: { type: 'string', format: 'binary' } })
  files: any[];
}
```

#### Extensions[#](/openapi/operations#extensions)

To add an extension to an operation, use the `@ApiExtension()` decorator. The extension name must be prefixed with `x-` (otherwise, the decorator throws an error).

```typescript

@ApiExtension('x-foo', { hello: 'world' })
```

#### Advanced: Generic `ApiResponse`[#](/openapi/operations#advanced-generic-apiresponse)

With [raw definitions](/openapi/types-and-parameters#raw-definitions), you can define a generic schema for Swagger UI. Assume you have the following DTO:

```ts

export class PaginatedDto<TData> {
  @ApiProperty()
  total: number;

  @ApiProperty()
  limit: number;

  @ApiProperty()
  offset: number;

  results: TData[];
}
```

We skip decorating `results`, because we'll provide a raw definition for it later. Now, define another DTO, for example `CatDto`, as follows:

```ts

export class CatDto {
  @ApiProperty()
  name: string;

  @ApiProperty()
  age: number;

  @ApiProperty()
  breed: string;
}
```

With this in place, you can define a `PaginatedDto<CatDto>` response:

```ts

@ApiOkResponse({
  schema: {
    allOf: [
      { $ref: getSchemaPath(PaginatedDto) },
      {
        properties: {
          results: {
            type: 'array',
            items: { $ref: getSchemaPath(CatDto) },
          },
        },
      },
    ],
  },
})
async findAll(): Promise<PaginatedDto<CatDto>> {}
```

In this example, the response combines `PaginatedDto` (through `allOf`) with a `results` property of type `Array<CatDto>`.

* `getSchemaPath()` returns the OpenAPI schema path of a given model within the OpenAPI document.
* `allOf` is an OAS 3 keyword that covers various inheritance-related use cases.

Lastly, because no controller references `PaginatedDto` directly, the `SwaggerModule` can't generate a corresponding model definition yet. In this case, you must add it as an [extra model](/openapi/types-and-parameters#extra-models). For example, use the `@ApiExtraModels()` decorator at the controller level:

```ts

@Controller('cats')
@ApiExtraModels(PaginatedDto)
export class CatsController {}
```

If you run Swagger now, the generated `swagger.json` for this endpoint defines the following response:

```json

"responses": {
  "200": {
    "description": "",
    "content": {
      "application/json": {
        "schema": {
          "allOf": [
            {
              "$ref": "#/components/schemas/PaginatedDto"
            },
            {
              "properties": {
                "results": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/CatDto"
                  }
                }
              }
            }
          ]
        }
      }
    }
  }
}
```

To make it reusable, create a custom decorator for `PaginatedDto`:

```ts

export const ApiPaginatedResponse = <TModel extends Type<any>>(
  model: TModel,
) => {
  return applyDecorators(
    ApiExtraModels(PaginatedDto, model),
    ApiOkResponse({
      schema: {
        allOf: [
          { $ref: getSchemaPath(PaginatedDto) },
          {
            properties: {
              results: {
                type: 'array',
                items: { $ref: getSchemaPath(model) },
              },
            },
          },
        ],
      },
    }),
  );
};
```

> **Hint** The `Type<any>` interface and the `applyDecorators()` function are imported from the `@nestjs/common` package.

To ensure that the `SwaggerModule` generates a definition for the model, the decorator registers it as an extra model with `ApiExtraModels()`, just as we did earlier for `PaginatedDto` in the controller.

With this in place, you can use the custom `@ApiPaginatedResponse()` decorator on your endpoint:

```ts

@ApiPaginatedResponse(CatDto)
async findAll(): Promise<PaginatedDto<CatDto>> {}
```

For client generation tools, this approach makes it ambiguous how `PaginatedDto<TModel>` should be generated for the client. The following snippet is an example of a client generator result for the `GET /` endpoint above:

```typescript

// Angular
findAll(): Observable<{ total: number, limit: number, offset: number, results: CatDto[] }>
```

The **return type** here is ambiguous. To work around this issue, add a `title` property to the `schema` in `ApiPaginatedResponse`:

```typescript

export const ApiPaginatedResponse = <TModel extends Type<any>>(
  model: TModel,
) => {
  return applyDecorators(
    ApiOkResponse({
      schema: {
        title: `PaginatedResponseOf${model.name}`,
        allOf: [
          // ...
        ],
      },
    }),
  );
};
```

The client generator's result now becomes:

```ts

// Angular
findAll(): Observable<PaginatedResponseOfCatDto>
```

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/openapi/operations.md)

----
url: https://docs.nestjs.com/v10/techniques/streaming-files
----

* [Streaming files](https://docs.nestjs.com/v10/techniques/streaming-files#streaming-files)
* [Streamable File class](https://docs.nestjs.com/v10/techniques/streaming-files#streamable-file-class)
* [Cross-platform support](https://docs.nestjs.com/v10/techniques/streaming-files#cross-platform-support)
* [Example](https://docs.nestjs.com/v10/techniques/streaming-files#example)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/techniques/streaming-files.md "Suggest Edits")

### Streaming files

> **Note** This chapter shows how you can stream files from your **HTTP application**. The examples presented below do not apply to GraphQL or Microservice applications.

There may be times where you would like to send back a file from your REST API to the client. To do this with Nest, normally you'd do the following:

```ts

@Controller('file')
export class FileController {
  @Get()
  getFile(@Res() res: Response) {
    const file = createReadStream(join(process.cwd(), 'package.json'));
    file.pipe(res);
  }
}
```

But in doing so you end up losing access to your post-controller interceptor logic. To handle this, you can return a `StreamableFile` instance and under the hood, the framework will take care of piping the response.

#### Streamable File class[#](/techniques/streaming-files#streamable-file-class)

A `StreamableFile` is a class that holds onto the stream that is to be returned. To create a new `StreamableFile`, you can pass either a `Buffer` or a `Stream` to the `StreamableFile` constructor.

> **hint** The `StreamableFile` class can be imported from `@nestjs/common`.

#### Cross-platform support[#](/techniques/streaming-files#cross-platform-support)

Fastify, by default, can support sending files without needing to call `stream.pipe(res)`, so you don't need to use the `StreamableFile` class at all. However, Nest supports the use of `StreamableFile` in both platform types, so if you end up switching between Express and Fastify there's no need to worry about compatibility between the two engines.

#### Example[#](/techniques/streaming-files#example)

You can find a simple example of returning the `package.json` as a file instead of a JSON below, but the idea extends out naturally to images, documents, and any other file type.

```ts

import { Controller, Get, StreamableFile } from '@nestjs/common';
import { createReadStream } from 'fs';
import { join } from 'path';

@Controller('file')
export class FileController {
  @Get()
  getFile(): StreamableFile {
    const file = createReadStream(join(process.cwd(), 'package.json'));
    return new StreamableFile(file);
  }
}
```

The default content type (the value for `Content-Type` HTTP response header) is `application/octet-stream`. If you need to customize this value you can use the `type` option from `StreamableFile`, or use the `res.set` method or the [`@Header()`](/controllers#headers) decorator, like this:

```ts

import { Controller, Get, StreamableFile, Res } from '@nestjs/common';
import { createReadStream } from 'fs';
import { join } from 'path';
import type { Response } from 'express'; // Assuming that we are using the ExpressJS HTTP Adapter

@Controller('file')
export class FileController {
  @Get()
  getFile(): StreamableFile {
    const file = createReadStream(join(process.cwd(), 'package.json'));
    return new StreamableFile(file, {
      type: 'application/json',
      disposition: 'attachment; filename="package.json"',
      // If you want to define the Content-Length value to another value instead of file's length:
      // length: 123,
    });
  }

  // Or even:
  @Get()
  getFileChangingResponseObjDirectly(@Res({ passthrough: true }) res: Response): StreamableFile {
    const file = createReadStream(join(process.cwd(), 'package.json'));
    res.set({
      'Content-Type': 'application/json',
      'Content-Disposition': 'attachment; filename="package.json"',
    });
    return new StreamableFile(file);
  }

  // Or even:
  @Get()
  @Header('Content-Type', 'application/json')
  @Header('Content-Disposition', 'attachment; filename="package.json"')
  getFileUsingStaticValues(): StreamableFile {
    const file = createReadStream(join(process.cwd(), 'package.json'));
    return new StreamableFile(file);
  }  
}
```

----
url: https://docs.nestjs.com/v4/
----

### Introduction

Nest is a framework for building efficient, scalable [Node.js](http://nodejs.org) server-side applications. It uses modern JavaScript, is built with [TypeScript](http://www.typescriptlang.org) (preserves compatibility with pure JavaScript) and combines elements of OOP (Object Oriented Programming), FP (Functional Programming), and FRP (Functional Reactive Programming).

Under the hood, Nest makes use of [Express](https://expressjs.com/), allowing for easy use of the myriad third-party plugins which are available.

### Philosophy

In recent years, thanks to Node.js, JavaScript has become the “lingua franca” of the web for both front and backend applications, giving rise to awesome projects like [Angular](https://angular.io/), [React](https://github.com/facebook/react) and [Vue](https://github.com/vuejs/vue) which improve developer productivity and enable the construction of fast, testable, extensible frontend applications. However, on the server-side, while there are a lot of superb libraries, helpers and tools for Node, none of them effectively solve the main problem - the architecture.

Nest aims to provide an application architecture out of the box which allows for effortless creation of highly testable, scalable, loosely coupled and easily maintainable applications.

### Installation

Install the starter project with **Git**:

JavaScript TypeScript

```bash

$ git clone https://github.com/nestjs/typescript-starter.git project
$ cd project
$ npm install
$ npm run start
```

```bash

$ git clone https://github.com/nestjs/javascript-starter.git project
$ cd project
$ npm install
$ npm run start
```

Start a New Project from Scratch with **NPM**:

```bash

$ npm i --save @nestjs/core @nestjs/common @nestjs/microservices @nestjs/websockets @nestjs/testing reflect-metadata rxjs
```

### People

* Author - [Kamil Myśliwiec](https://kamilmysliwiec.com "Kamil Mysliwiec Blog | Full-Stack Software Engineer")
* Website - [https://nestjs.com](https://nestjs.com "Nest - A node.js framework built on top of TypeScript")

#### Sponsors

[](https://valor-software.com/)

Nest is an MIT-licensed open source project. It can grow thanks to the support by these awesome people. If you'd like to join them, please read more [here](https://opencollective.com/nest). Thanks!

[](https://opencollective.com/nest/backer/0/website)[](https://opencollective.com/nest/backer/1/website)[](https://opencollective.com/nest/backer/2/website)[](https://opencollective.com/nest/backer/3/website)[](https://opencollective.com/nest/backer/4/website)[](https://opencollective.com/nest/backer/5/website)[](https://opencollective.com/nest/backer/6/website)[](https://opencollective.com/nest/backer/7/website)[](https://opencollective.com/nest/backer/8/website)[](https://opencollective.com/nest/backer/9/website)[](https://opencollective.com/nest/backer/10/website)[](https://opencollective.com/nest/backer/11/website)[](https://opencollective.com/nest/backer/12/website)[](https://opencollective.com/nest/backer/13/website)[](https://opencollective.com/nest/backer/14/website)[](https://opencollective.com/nest/backer/15/website)[](https://opencollective.com/nest/backer/16/website)[](https://opencollective.com/nest/backer/17/website)[](https://opencollective.com/nest/backer/18/website)[](https://opencollective.com/nest/backer/19/website)[](https://opencollective.com/nest/backer/20/website)[](https://opencollective.com/nest/backer/21/website)[](https://opencollective.com/nest/backer/22/website)[](https://opencollective.com/nest/backer/23/website)[](https://opencollective.com/nest/backer/24/website)[](https://opencollective.com/nest/backer/25/website)[](https://opencollective.com/nest/backer/26/website)[](https://opencollective.com/nest/backer/27/website)[](https://opencollective.com/nest/backer/28/website)[](https://opencollective.com/nest/backer/29/website)

[Become a sponsor](https://opencollective.com/nest)

----
url: https://docs.nestjs.com/v11/techniques/database
----

* [Database](https://docs.nestjs.com/v11/techniques/database#database)
* [TypeORM Integration](https://docs.nestjs.com/v11/techniques/database#typeorm-integration)
* [Repository pattern](https://docs.nestjs.com/v11/techniques/database#repository-pattern)
* [Relations](https://docs.nestjs.com/v11/techniques/database#relations)
* [Auto-load entities](https://docs.nestjs.com/v11/techniques/database#auto-load-entities)
* [Separating entity definition](https://docs.nestjs.com/v11/techniques/database#separating-entity-definition)
* [TypeORM Transactions](https://docs.nestjs.com/v11/techniques/database#typeorm-transactions)
* [Subscribers](https://docs.nestjs.com/v11/techniques/database#subscribers)
* [Migrations](https://docs.nestjs.com/v11/techniques/database#migrations)
* [Multiple databases](https://docs.nestjs.com/v11/techniques/database#multiple-databases)
* [Testing](https://docs.nestjs.com/v11/techniques/database#testing)
* [Async configuration](https://docs.nestjs.com/v11/techniques/database#async-configuration)
* [Custom DataSource Factory](https://docs.nestjs.com/v11/techniques/database#custom-datasource-factory)
* [Example](https://docs.nestjs.com/v11/techniques/database#example)
* [Sequelize Integration](https://docs.nestjs.com/v11/techniques/database#sequelize-integration)
* [Models](https://docs.nestjs.com/v11/techniques/database#models)
* [Relations](https://docs.nestjs.com/v11/techniques/database#relations-1)
* [Auto-load models](https://docs.nestjs.com/v11/techniques/database#auto-load-models)
* [Sequelize Transactions](https://docs.nestjs.com/v11/techniques/database#sequelize-transactions)
* [Migrations](https://docs.nestjs.com/v11/techniques/database#migrations-1)
* [Multiple databases](https://docs.nestjs.com/v11/techniques/database#multiple-databases-1)
* [Testing](https://docs.nestjs.com/v11/techniques/database#testing-1)
* [Async configuration](https://docs.nestjs.com/v11/techniques/database#async-configuration-1)
* [Example](https://docs.nestjs.com/v11/techniques/database#example-1)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/techniques/sql.md "Suggest Edits")

### Database

Nest is database agnostic, allowing you to easily integrate with any SQL or NoSQL database. You have a number of options available to you, depending on your preferences. At the most general level, connecting Nest to a database is simply a matter of loading an appropriate Node.js driver for the database, just as you would with [Express](https://expressjs.com/en/guide/database-integration.html) or Fastify.

You can also directly use any general purpose Node.js database integration **library** or ORM, such as [MikroORM](https://mikro-orm.io/) (see [MikroORM recipe](/v11/recipes/mikroorm)), [Sequelize](https://sequelize.org/) (see [Sequelize integration](/techniques/database#sequelize-integration)), [Knex.js](https://knexjs.org/) (see [Knex.js tutorial](https://dev.to/nestjs/build-a-nestjs-module-for-knex-js-or-other-resource-based-libraries-in-5-minutes-12an)), [TypeORM](https://github.com/typeorm/typeorm), and [Prisma](https://www.github.com/prisma/prisma) (see [Prisma recipe](/v11/recipes/prisma)), to operate at a higher level of abstraction.

For convenience, Nest provides tight integration with TypeORM and Sequelize out-of-the-box with the `@nestjs/typeorm` and `@nestjs/sequelize` packages respectively, which we'll cover in the current chapter, and Mongoose with `@nestjs/mongoose`, which is covered in [this chapter](/v11/techniques/mongodb). These integrations provide additional NestJS-specific features, such as model/repository injection, testability, and asynchronous configuration to make accessing your chosen database even easier.

### TypeORM Integration

For integrating with SQL and NoSQL databases, Nest provides the `@nestjs/typeorm` package. [TypeORM](https://github.com/typeorm/typeorm) is the most mature Object Relational Mapper (ORM) available for TypeScript. Since it's written in TypeScript, it integrates well with the Nest framework.

To begin using it, we first install the required dependencies. In this chapter, we'll demonstrate using the popular [MySQL](https://www.mysql.com/) Relational DBMS, but TypeORM provides support for many relational databases, such as PostgreSQL, Oracle, Microsoft SQL Server, SQLite, and even NoSQL databases like MongoDB. The procedure we walk through in this chapter will be the same for any database supported by TypeORM. You'll simply need to install the associated client API libraries for your selected database.

```bash

$ npm install --save @nestjs/typeorm typeorm mysql2
```

Once the installation process is complete, we can import the `TypeOrmModule` into the root `AppModule`.

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';

@Module({
  imports: [
    TypeOrmModule.forRoot({
      type: 'mysql',
      host: 'localhost',
      port: 3306,
      username: 'root',
      password: 'root',
      database: 'test',
      entities: [],
      synchronize: true,
    }),
  ],
})
export class AppModule {}
```

> **Warning** Setting `synchronize: true` shouldn't be used in production - otherwise you can lose production data.

The `forRoot()` method supports all the configuration properties exposed by the `DataSource` constructor from the [TypeORM](https://typeorm.io/data-source-options#common-data-source-options) package. In addition, there are several extra configuration properties described below.

|                    |                                                                     |
| ------------------ | ------------------------------------------------------------------- |
| `retryAttempts`    | Number of attempts to connect to the database (default: `10`)       |
| `retryDelay`       | Delay between connection retry attempts (ms) (default: `3000`)      |
| `autoLoadEntities` | If `true`, entities will be loaded automatically (default: `false`) |

> **Hint** Learn more about the data source options [here](https://typeorm.io/data-source-options).

Once this is done, the TypeORM `DataSource` and `EntityManager` objects will be available to inject across the entire project (without needing to import any modules), for example:

app.module.ts

JS TS

```typescript

import { DataSource } from 'typeorm';

@Module({
  imports: [TypeOrmModule.forRoot(), UsersModule],
})
export class AppModule {
  constructor(private dataSource: DataSource) {}
}
```

```typescript

import { DataSource } from 'typeorm';

@Dependencies(DataSource)
@Module({
  imports: [TypeOrmModule.forRoot(), UsersModule],
})
export class AppModule {
  constructor(dataSource) {
    this.dataSource = dataSource;
  }
}
```

#### Repository pattern[#](/techniques/database#repository-pattern)

[TypeORM](https://github.com/typeorm/typeorm) supports the **repository design pattern**, so each entity has its own repository. These repositories can be obtained from the database data source.

To continue the example, we need at least one entity. Let's define the `User` entity.

user.entity.ts

JS TS

```typescript

import { Entity, Column, PrimaryGeneratedColumn } from 'typeorm';

@Entity()
export class User {
  @PrimaryGeneratedColumn()
  id: number;

  @Column()
  firstName: string;

  @Column()
  lastName: string;

  @Column({ default: true })
  isActive: boolean;
}
```

> **Hint** Learn more about entities in the [TypeORM documentation](https://typeorm.io/docs/entity/entities/).

The `User` entity file sits in the `users` directory. This directory contains all files related to the `UsersModule`. You can decide where to keep your model files, however, we recommend creating them near their **domain**, in the corresponding module directory.

To begin using the `User` entity, we need to let TypeORM know about it by inserting it into the `entities` array in the module `forRoot()` method options (unless you use a static glob path):

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { User } from './users/user.entity';

@Module({
  imports: [
    TypeOrmModule.forRoot({
      type: 'mysql',
      host: 'localhost',
      port: 3306,
      username: 'root',
      password: 'root',
      database: 'test',
      entities: [User],
      synchronize: true,
    }),
  ],
})
export class AppModule {}
```

Next, let's look at the `UsersModule`:

users.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { UsersService } from './users.service';
import { UsersController } from './users.controller';
import { User } from './user.entity';

@Module({
  imports: [TypeOrmModule.forFeature([User])],
  providers: [UsersService],
  controllers: [UsersController],
})
export class UsersModule {}
```

This module uses the `forFeature()` method to define which repositories are registered in the current scope. With that in place, we can inject the `UsersRepository` into the `UsersService` using the `@InjectRepository()` decorator:

users.service.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { User } from './user.entity';

@Injectable()
export class UsersService {
  constructor(
    @InjectRepository(User)
    private usersRepository: Repository<User>,
  ) {}

  findAll(): Promise<User[]> {
    return this.usersRepository.find();
  }

  findOne(id: number): Promise<User | null> {
    return this.usersRepository.findOneBy({ id });
  }

  async remove(id: number): Promise<void> {
    await this.usersRepository.delete(id);
  }
}
```

```typescript

import { Injectable, Dependencies } from '@nestjs/common';
import { getRepositoryToken } from '@nestjs/typeorm';
import { User } from './user.entity';

@Injectable()
@Dependencies(getRepositoryToken(User))
export class UsersService {
  constructor(usersRepository) {
    this.usersRepository = usersRepository;
  }

  findAll() {
    return this.usersRepository.find();
  }

  findOne(id) {
    return this.usersRepository.findOneBy({ id });
  }

  async remove(id) {
    await this.usersRepository.delete(id);
  }
}
```

> **Notice** Don't forget to import the `UsersModule` into the root `AppModule`.

If you want to use the repository outside of the module which imports `TypeOrmModule.forFeature`, you'll need to re-export the providers generated by it. You can do this by exporting the whole module, like this:

users.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { User } from './user.entity';

@Module({
  imports: [TypeOrmModule.forFeature([User])],
  exports: [TypeOrmModule]
})
export class UsersModule {}
```

Now if we import `UsersModule` in `UserHttpModule`, we can use `@InjectRepository(User)` in the providers of the latter module.

users-http.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { UsersModule } from './users.module';
import { UsersService } from './users.service';
import { UsersController } from './users.controller';

@Module({
  imports: [UsersModule],
  providers: [UsersService],
  controllers: [UsersController]
})
export class UserHttpModule {}
```

#### Relations[#](/techniques/database#relations)

Relations are associations established between two or more tables. Relations are based on common fields from each table, often involving primary and foreign keys.

There are three types of relations:

|                             |                                                                                                                                                                                                                                 |
| --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `One-to-one`                | Every row in the primary table has one and only one associated row in the foreign table. Use the `@OneToOne()` decorator to define this type of relation.                                                                       |
| `One-to-many / Many-to-one` | Every row in the primary table has one or more related rows in the foreign table. Use the `@OneToMany()` and `@ManyToOne()` decorators to define this type of relation.                                                         |
| `Many-to-many`              | Every row in the primary table has many related rows in the foreign table, and every record in the foreign table has many related rows in the primary table. Use the `@ManyToMany()` decorator to define this type of relation. |

To define relations in entities, use the corresponding **decorators**. For example, to define that each `User` can have multiple photos, use the `@OneToMany()` decorator.

user.entity.ts

JS TS

```typescript

import { Entity, Column, PrimaryGeneratedColumn, OneToMany } from 'typeorm';
import { Photo } from '../photos/photo.entity';

@Entity()
export class User {
  @PrimaryGeneratedColumn()
  id: number;

  @Column()
  firstName: string;

  @Column()
  lastName: string;

  @Column({ default: true })
  isActive: boolean;

  @OneToMany(type => Photo, photo => photo.user)
  photos: Photo[];
}
```

> **Hint** To learn more about relations in TypeORM, visit the [TypeORM documentation](https://typeorm.io/docs/relations/relations).

#### Auto-load entities[#](/techniques/database#auto-load-entities)

Manually adding entities to the `entities` array of the data source options can be tedious. In addition, referencing entities from the root module breaks application domain boundaries and causes leaking implementation details to other parts of the application. To address this issue, an alternative solution is provided. To automatically load entities, set the `autoLoadEntities` property of the configuration object (passed into the `forRoot()` method) to `true`, as shown below:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';

@Module({
  imports: [
    TypeOrmModule.forRoot({
      ...
      autoLoadEntities: true,
    }),
  ],
})
export class AppModule {}
```

With that option specified, every entity registered through the `forFeature()` method will be automatically added to the `entities` array of the configuration object.

> **Warning** Note that entities that aren't registered through the `forFeature()` method, but are only referenced from the entity (via a relationship), won't be included by way of the `autoLoadEntities` setting.

#### Separating entity definition[#](/techniques/database#separating-entity-definition)

You can define an entity and its columns right in the model, using decorators. But some people prefer to define entities and their columns inside separate files using the ["entity schemas"](https://typeorm.io/docs/entity/separating-entity-definition).

```typescript

import { EntitySchema } from 'typeorm';
import { User } from './user.entity';

export const UserSchema = new EntitySchema<User>({
  name: 'User',
  target: User,
  columns: {
    id: {
      type: Number,
      primary: true,
      generated: true,
    },
    firstName: {
      type: String,
    },
    lastName: {
      type: String,
    },
    isActive: {
      type: Boolean,
      default: true,
    },
  },
  relations: {
    photos: {
      type: 'one-to-many',
      target: 'Photo', // the name of the PhotoSchema
    },
  },
});
```

> **Warning** If you provide the `target` option, the `name` option value has to be the same as the name of the target class. If you do not provide the `target` you can use any name.

Nest allows you to use an `EntitySchema` instance wherever an `Entity` is expected, for example:

```typescript

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { UserSchema } from './user.schema';
import { UsersController } from './users.controller';
import { UsersService } from './users.service';

@Module({
  imports: [TypeOrmModule.forFeature([UserSchema])],
  providers: [UsersService],
  controllers: [UsersController],
})
export class UsersModule {}
```

#### TypeORM Transactions[#](/techniques/database#typeorm-transactions)

A database transaction symbolizes a unit of work performed within a database management system against a database, and treated in a coherent and reliable way independent of other transactions. A transaction generally represents any change in a database ([learn more](https://en.wikipedia.org/wiki/Database_transaction)).

There are many different strategies to handle [TypeORM transactions](https://typeorm.io/docs/advanced-topics/transactions/). We recommend using the `QueryRunner` class because it gives full control over the transaction.

First, we need to inject the `DataSource` object into a class in the normal way:

```typescript

@Injectable()
export class UsersService {
  constructor(private dataSource: DataSource) {}
}
```

> **Hint** The `DataSource` class is imported from the `typeorm` package.

Now, we can use this object to create a transaction.

```typescript

async createMany(users: User[]) {
  const queryRunner = this.dataSource.createQueryRunner();

  await queryRunner.connect();
  await queryRunner.startTransaction();
  try {
    await queryRunner.manager.save(users[0]);
    await queryRunner.manager.save(users[1]);

    await queryRunner.commitTransaction();
  } catch (err) {
    // since we have errors lets rollback the changes we made
    await queryRunner.rollbackTransaction();
  } finally {
    // you need to release a queryRunner which was manually instantiated
    await queryRunner.release();
  }
}
```

> **Hint** Note that the `dataSource` is used only to create the `QueryRunner`. However, to test this class would require mocking the entire `DataSource` object (which exposes several methods). Thus, we recommend using a helper factory class (e.g., `QueryRunnerFactory`) and defining an interface with a limited set of methods required to maintain transactions. This technique makes mocking these methods pretty straightforward.

## Explore your graph with NestJS Devtools

* Graph visualizer
* Routes navigator
* Interactive playground
* CI/CD integration

[Sign up](https://devtools.nestjs.com "Devtools | NestJS - A node.js framework built on top of TypeScript")

Alternatively, you can use the callback-style approach with the `transaction` method of the `DataSource` object ([read more](https://typeorm.io/docs/advanced-topics/transactions/#creating-and-using-transactions)).

```typescript

async createMany(users: User[]) {
  await this.dataSource.transaction(async manager => {
    await manager.save(users[0]);
    await manager.save(users[1]);
  });
}
```

#### Subscribers[#](/techniques/database#subscribers)

With TypeORM [subscribers](https://typeorm.io/docs/advanced-topics/listeners-and-subscribers#what-is-a-subscriber), you can listen to specific entity events.

```typescript

import {
  DataSource,
  EntitySubscriberInterface,
  EventSubscriber,
  InsertEvent,
} from 'typeorm';
import { User } from './user.entity';

@EventSubscriber()
export class UserSubscriber implements EntitySubscriberInterface<User> {
  constructor(dataSource: DataSource) {
    dataSource.subscribers.push(this);
  }

  listenTo() {
    return User;
  }

  beforeInsert(event: InsertEvent<User>) {
    console.log(`BEFORE USER INSERTED: `, event.entity);
  }
}
```

> **Warning** Event subscribers can not be [request-scoped](/v11/fundamentals/injection-scopes).

Now, add the `UserSubscriber` class to the `providers` array:

```typescript

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { User } from './user.entity';
import { UsersController } from './users.controller';
import { UsersService } from './users.service';
import { UserSubscriber } from './user.subscriber';

@Module({
  imports: [TypeOrmModule.forFeature([User])],
  providers: [UsersService, UserSubscriber],
  controllers: [UsersController],
})
export class UsersModule {}
```

#### Migrations[#](/techniques/database#migrations)

[Migrations](https://typeorm.io/docs/advanced-topics/migrations/) provide a way to incrementally update the database schema to keep it in sync with the application's data model while preserving existing data in the database. To generate, run, and revert migrations, TypeORM provides a dedicated [CLI](https://typeorm.io/docs/advanced-topics/migrations/#creating-a-new-migration).

Migration classes are separate from the Nest application source code. Their lifecycle is maintained by the TypeORM CLI. Therefore, you are not able to leverage dependency injection and other Nest specific features with migrations. To learn more about migrations, follow the guide in the [TypeORM documentation](https://typeorm.io/docs/advanced-topics/migrations/).

#### Multiple databases[#](/techniques/database#multiple-databases)

Some projects require multiple database connections. This can also be achieved with this module. To work with multiple connections, first create the connections. In this case, data source naming becomes **mandatory**.

Suppose you have an `Album` entity stored in its own database.

```typescript

const defaultOptions = {
  type: 'postgres',
  port: 5432,
  username: 'user',
  password: 'password',
  database: 'db',
  synchronize: true,
};

@Module({
  imports: [
    TypeOrmModule.forRoot({
      ...defaultOptions,
      host: 'user_db_host',
      entities: [User],
    }),
    TypeOrmModule.forRoot({
      ...defaultOptions,
      name: 'albumsConnection',
      host: 'album_db_host',
      entities: [Album],
    }),
  ],
})
export class AppModule {}
```

> **Notice** If you don't set the `name` for a data source, its name is set to `default`. Please note that you shouldn't have multiple connections without a name, or with the same name, otherwise they will get overridden.

> **Notice** If you are using `TypeOrmModule.forRootAsync`, you have to **also** set the data source name outside `useFactory`. For example:
>
> ```typescript
>
> TypeOrmModule.forRootAsync({
>   name: 'albumsConnection',
>   useFactory: ...,
>   inject: ...,
> }),
> ```
>
> See [this issue](https://github.com/nestjs/typeorm/issues/86) for more details.

At this point, you have `User` and `Album` entities registered with their own data source. With this setup, you have to tell the `TypeOrmModule.forFeature()` method and the `@InjectRepository()` decorator which data source should be used. If you do not pass any data source name, the `default` data source is used.

```typescript

@Module({
  imports: [
    TypeOrmModule.forFeature([User]),
    TypeOrmModule.forFeature([Album], 'albumsConnection'),
  ],
})
export class AppModule {}
```

You can also inject the `DataSource` or `EntityManager` for a given data source:

```typescript

@Injectable()
export class AlbumsService {
  constructor(
    @InjectDataSource('albumsConnection')
    private dataSource: DataSource,
    @InjectEntityManager('albumsConnection')
    private entityManager: EntityManager,
  ) {}
}
```

It's also possible to inject any `DataSource` to the providers:

```typescript

@Module({
  providers: [
    {
      provide: AlbumsService,
      useFactory: (albumsConnection: DataSource) => {
        return new AlbumsService(albumsConnection);
      },
      inject: [getDataSourceToken('albumsConnection')],
    },
  ],
})
export class AlbumsModule {}
```

#### Testing[#](/techniques/database#testing)

When it comes to unit testing an application, we usually want to avoid making a database connection, keeping our test suites independent and their execution process as fast as possible. But our classes might depend on repositories that are pulled from the data source (connection) instance. How do we handle that? The solution is to create mock repositories. In order to achieve that, we set up [custom providers](/v11/fundamentals/custom-providers). Each registered repository is automatically represented by an `<EntityName>Repository` token, where `EntityName` is the name of your entity class.

The `@nestjs/typeorm` package exposes the `getRepositoryToken()` function which returns a prepared token based on a given entity.

```typescript

@Module({
  providers: [
    UsersService,
    {
      provide: getRepositoryToken(User),
      useValue: mockRepository,
    },
  ],
})
export class UsersModule {}
```

Now a substitute `mockRepository` will be used as the `UsersRepository`. Whenever any class asks for `UsersRepository` using an `@InjectRepository()` decorator, Nest will use the registered `mockRepository` object.

#### Async configuration[#](/techniques/database#async-configuration)

You may want to pass your repository module options asynchronously instead of statically. In this case, use the `forRootAsync()` method, which provides several ways to deal with async configuration.

One approach is to use a factory function:

```typescript

TypeOrmModule.forRootAsync({
  useFactory: () => ({
    type: 'mysql',
    host: 'localhost',
    port: 3306,
    username: 'root',
    password: 'root',
    database: 'test',
    entities: [],
    synchronize: true,
  }),
});
```

Our factory behaves like any other [asynchronous provider](https://docs.nestjs.com/fundamentals/async-providers) (e.g., it can be `async` and it's able to inject dependencies through `inject`).

```typescript

TypeOrmModule.forRootAsync({
  imports: [ConfigModule],
  useFactory: (configService: ConfigService) => ({
    type: 'mysql',
    host: configService.get('HOST'),
    port: +configService.get('PORT'),
    username: configService.get('USERNAME'),
    password: configService.get('PASSWORD'),
    database: configService.get('DATABASE'),
    entities: [],
    synchronize: true,
  }),
  inject: [ConfigService],
});
```

Alternatively, you can use the `useClass` syntax:

```typescript

TypeOrmModule.forRootAsync({
  useClass: TypeOrmConfigService,
});
```

The construction above will instantiate `TypeOrmConfigService` inside `TypeOrmModule` and use it to provide an options object by calling `createTypeOrmOptions()`. Note that this means that the `TypeOrmConfigService` has to implement the `TypeOrmOptionsFactory` interface, as shown below:

```typescript

@Injectable()
export class TypeOrmConfigService implements TypeOrmOptionsFactory {
  createTypeOrmOptions(): TypeOrmModuleOptions {
    return {
      type: 'mysql',
      host: 'localhost',
      port: 3306,
      username: 'root',
      password: 'root',
      database: 'test',
      entities: [],
      synchronize: true,
    };
  }
}
```

In order to prevent the creation of `TypeOrmConfigService` inside `TypeOrmModule` and use a provider imported from a different module, you can use the `useExisting` syntax.

```typescript

TypeOrmModule.forRootAsync({
  imports: [ConfigModule],
  useExisting: ConfigService,
});
```

This construction works the same as `useClass` with one critical difference - `TypeOrmModule` will lookup imported modules to reuse an existing `ConfigService` instead of instantiating a new one.

> **Hint** Make sure that the `name` property is defined at the same level as the `useFactory`, `useClass`, or `useValue` property. This will allow Nest to properly register the data source under the appropriate injection token.

#### Custom DataSource Factory[#](/techniques/database#custom-datasource-factory)

In conjunction with async configuration using `useFactory`, `useClass`, or `useExisting`, you can optionally specify a `dataSourceFactory` function which will allow you to provide your own TypeORM data source rather than allowing `TypeOrmModule` to create the data source.

`dataSourceFactory` receives the TypeORM `DataSourceOptions` configured during async configuration using `useFactory`, `useClass`, or `useExisting` and returns a `Promise` that resolves a TypeORM `DataSource`.

```typescript

TypeOrmModule.forRootAsync({
  imports: [ConfigModule],
  inject: [ConfigService],
  // Use useFactory, useClass, or useExisting
  // to configure the DataSourceOptions.
  useFactory: (configService: ConfigService) => ({
    type: 'mysql',
    host: configService.get('HOST'),
    port: +configService.get('PORT'),
    username: configService.get('USERNAME'),
    password: configService.get('PASSWORD'),
    database: configService.get('DATABASE'),
    entities: [],
    synchronize: true,
  }),
  // dataSource receives the configured DataSourceOptions
  // and returns a Promise<DataSource>.
  dataSourceFactory: async (options) => {
    const dataSource = await new DataSource(options).initialize();
    return dataSource;
  },
});
```

> **Hint** The `DataSource` class is imported from the `typeorm` package.

```bash

$ npm install --save @nestjs/sequelize sequelize sequelize-typescript mysql2
$ npm install --save-dev @types/sequelize
```

Once the installation process is complete, we can import the `SequelizeModule` into the root `AppModule`.

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { SequelizeModule } from '@nestjs/sequelize';

@Module({
  imports: [
    SequelizeModule.forRoot({
      dialect: 'mysql',
      host: 'localhost',
      port: 3306,
      username: 'root',
      password: 'root',
      database: 'test',
      models: [],
    }),
  ],
})
export class AppModule {}
```

The `forRoot()` method supports all the configuration properties exposed by the Sequelize constructor ([read more](https://sequelize.org/docs/v6/getting-started/#connecting-to-a-database)). In addition, there are several extra configuration properties described below.

|                       |                                                                                         |
| --------------------- | --------------------------------------------------------------------------------------- |
| `retryAttempts`       | Number of attempts to connect to the database (default: `10`)                           |
| `retryDelay`          | Delay between connection retry attempts (ms) (default: `3000`)                          |
| `autoLoadModels`      | If `true`, models will be loaded automatically (default: `false`)                       |
| `keepConnectionAlive` | If `true`, connection will not be closed on the application shutdown (default: `false`) |
| `synchronize`         | If `true`, automatically loaded models will be synchronized (default: `true`)           |

Once this is done, the `Sequelize` object will be available to inject across the entire project (without needing to import any modules), for example:

app.service.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { Sequelize } from 'sequelize-typescript';

@Injectable()
export class AppService {
  constructor(private sequelize: Sequelize) {}
}
```

```typescript

import { Injectable } from '@nestjs/common';
import { Sequelize } from 'sequelize-typescript';

@Dependencies(Sequelize)
@Injectable()
export class AppService {
  constructor(sequelize) {
    this.sequelize = sequelize;
  }
}
```

#### Models[#](/techniques/database#models)

Sequelize implements the Active Record pattern. With this pattern, you use model classes directly to interact with the database. To continue the example, we need at least one model. Let's define the `User` model.

user.model.ts

JS TS

```typescript

import { Column, Model, Table } from 'sequelize-typescript';

@Table
export class User extends Model {
  @Column
  firstName: string;

  @Column
  lastName: string;

  @Column({ defaultValue: true })
  isActive: boolean;
}
```

> **Hint** Learn more about the available decorators [here](https://github.com/RobinBuschmann/sequelize-typescript#column).

The `User` model file sits in the `users` directory. This directory contains all files related to the `UsersModule`. You can decide where to keep your model files, however, we recommend creating them near their **domain**, in the corresponding module directory.

To begin using the `User` model, we need to let Sequelize know about it by inserting it into the `models` array in the module `forRoot()` method options:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { SequelizeModule } from '@nestjs/sequelize';
import { User } from './users/user.model';

@Module({
  imports: [
    SequelizeModule.forRoot({
      dialect: 'mysql',
      host: 'localhost',
      port: 3306,
      username: 'root',
      password: 'root',
      database: 'test',
      models: [User],
    }),
  ],
})
export class AppModule {}
```

Next, let's look at the `UsersModule`:

users.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { SequelizeModule } from '@nestjs/sequelize';
import { User } from './user.model';
import { UsersController } from './users.controller';
import { UsersService } from './users.service';

@Module({
  imports: [SequelizeModule.forFeature([User])],
  providers: [UsersService],
  controllers: [UsersController],
})
export class UsersModule {}
```

This module uses the `forFeature()` method to define which models are registered in the current scope. With that in place, we can inject the `UserModel` into the `UsersService` using the `@InjectModel()` decorator:

users.service.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { InjectModel } from '@nestjs/sequelize';
import { User } from './user.model';

@Injectable()
export class UsersService {
  constructor(
    @InjectModel(User)
    private userModel: typeof User,
  ) {}

  async findAll(): Promise<User[]> {
    return this.userModel.findAll();
  }

  findOne(id: string): Promise<User> {
    return this.userModel.findOne({
      where: {
        id,
      },
    });
  }

  async remove(id: string): Promise<void> {
    const user = await this.findOne(id);
    await user.destroy();
  }
}
```

```typescript

import { Injectable, Dependencies } from '@nestjs/common';
import { getModelToken } from '@nestjs/sequelize';
import { User } from './user.model';

@Injectable()
@Dependencies(getModelToken(User))
export class UsersService {
  constructor(usersRepository) {
    this.usersRepository = usersRepository;
  }

  async findAll() {
    return this.userModel.findAll();
  }

  findOne(id) {
    return this.userModel.findOne({
      where: {
        id,
      },
    });
  }

  async remove(id) {
    const user = await this.findOne(id);
    await user.destroy();
  }
}
```

> **Notice** Don't forget to import the `UsersModule` into the root `AppModule`.

If you want to use the model outside of the module which imports `SequelizeModule.forFeature`, you'll need to re-export the providers generated by it. You can do this by exporting the whole module, like this:

users.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { SequelizeModule } from '@nestjs/sequelize';
import { User } from './user.entity';

@Module({
  imports: [SequelizeModule.forFeature([User])],
  exports: [SequelizeModule]
})
export class UsersModule {}
```

Now if we import `UsersModule` in `UserHttpModule`, we can use `@InjectModel(User)` in the providers of the latter module.

users-http.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { UsersModule } from './users.module';
import { UsersService } from './users.service';
import { UsersController } from './users.controller';

@Module({
  imports: [UsersModule],
  providers: [UsersService],
  controllers: [UsersController]
})
export class UserHttpModule {}
```

#### Relations[#](/techniques/database#relations-1)

Relations are associations established between two or more tables. Relations are based on common fields from each table, often involving primary and foreign keys.

There are three types of relations:

|                             |                                                                                                                                                             |
| --------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `One-to-one`                | Every row in the primary table has one and only one associated row in the foreign table                                                                     |
| `One-to-many / Many-to-one` | Every row in the primary table has one or more related rows in the foreign table                                                                            |
| `Many-to-many`              | Every row in the primary table has many related rows in the foreign table, and every record in the foreign table has many related rows in the primary table |

To define relations in models, use the corresponding **decorators**. For example, to define that each `User` can have multiple photos, use the `@HasMany()` decorator.

user.model.ts

JS TS

```typescript

import { Column, Model, Table, HasMany } from 'sequelize-typescript';
import { Photo } from '../photos/photo.model';

@Table
export class User extends Model {
  @Column
  firstName: string;

  @Column
  lastName: string;

  @Column({ defaultValue: true })
  isActive: boolean;

  @HasMany(() => Photo)
  photos: Photo[];
}
```

> **Hint** To learn more about associations in Sequelize, read [this](https://github.com/RobinBuschmann/sequelize-typescript#model-association) chapter.

#### Auto-load models[#](/techniques/database#auto-load-models)

Manually adding models to the `models` array of the connection options can be tedious. In addition, referencing models from the root module breaks application domain boundaries and causes leaking implementation details to other parts of the application. To solve this issue, automatically load models by setting both `autoLoadModels` and `synchronize` properties of the configuration object (passed into the `forRoot()` method) to `true`, as shown below:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { SequelizeModule } from '@nestjs/sequelize';

@Module({
  imports: [
    SequelizeModule.forRoot({
      ...
      autoLoadModels: true,
      synchronize: true,
    }),
  ],
})
export class AppModule {}
```

With that option specified, every model registered through the `forFeature()` method will be automatically added to the `models` array of the configuration object.

> **Warning** Note that models that aren't registered through the `forFeature()` method, but are only referenced from the model (via an association), won't be included.

#### Sequelize Transactions[#](/techniques/database#sequelize-transactions)

A database transaction symbolizes a unit of work performed within a database management system against a database, and treated in a coherent and reliable way independent of other transactions. A transaction generally represents any change in a database ([learn more](https://en.wikipedia.org/wiki/Database_transaction)).

There are many different strategies to handle [Sequelize transactions](https://sequelize.org/docs/v6/other-topics/transactions/). Below is a sample implementation of a managed transaction (auto-callback).

First, we need to inject the `Sequelize` object into a class in the normal way:

```typescript

@Injectable()
export class UsersService {
  constructor(private sequelize: Sequelize) {}
}
```

> **Hint** The `Sequelize` class is imported from the `sequelize-typescript` package.

Now, we can use this object to create a transaction.

```typescript

async createMany() {
  try {
    await this.sequelize.transaction(async t => {
      const transactionHost = { transaction: t };

      await this.userModel.create(
          { firstName: 'Abraham', lastName: 'Lincoln' },
          transactionHost,
      );
      await this.userModel.create(
          { firstName: 'John', lastName: 'Boothe' },
          transactionHost,
      );
    });
  } catch (err) {
    // Transaction has been rolled back
    // err is whatever rejected the promise chain returned to the transaction callback
  }
}
```

> **Hint** Note that the `Sequelize` instance is used only to start the transaction. However, to test this class would require mocking the entire `Sequelize` object (which exposes several methods). Thus, we recommend using a helper factory class (e.g., `TransactionRunner`) and defining an interface with a limited set of methods required to maintain transactions. This technique makes mocking these methods pretty straightforward.

```typescript

const defaultOptions = {
  dialect: 'postgres',
  port: 5432,
  username: 'user',
  password: 'password',
  database: 'db',
  synchronize: true,
};

@Module({
  imports: [
    SequelizeModule.forRoot({
      ...defaultOptions,
      host: 'user_db_host',
      models: [User],
    }),
    SequelizeModule.forRoot({
      ...defaultOptions,
      name: 'albumsConnection',
      host: 'album_db_host',
      models: [Album],
    }),
  ],
})
export class AppModule {}
```

> **Notice** If you don't set the `name` for a connection, its name is set to `default`. Please note that you shouldn't have multiple connections without a name, or with the same name, otherwise they will get overridden.

At this point, you have `User` and `Album` models registered with their own connection. With this setup, you have to tell the `SequelizeModule.forFeature()` method and the `@InjectModel()` decorator which connection should be used. If you do not pass any connection name, the `default` connection is used.

```typescript

@Module({
  imports: [
    SequelizeModule.forFeature([User]),
    SequelizeModule.forFeature([Album], 'albumsConnection'),
  ],
})
export class AppModule {}
```

You can also inject the `Sequelize` instance for a given connection:

```typescript

@Injectable()
export class AlbumsService {
  constructor(
    @InjectConnection('albumsConnection')
    private sequelize: Sequelize,
  ) {}
}
```

It's also possible to inject any `Sequelize` instance to the providers:

```typescript

@Module({
  providers: [
    {
      provide: AlbumsService,
      useFactory: (albumsSequelize: Sequelize) => {
        return new AlbumsService(albumsSequelize);
      },
      inject: [getDataSourceToken('albumsConnection')],
    },
  ],
})
export class AlbumsModule {}
```

#### Testing[#](/techniques/database#testing-1)

When it comes to unit testing an application, we usually want to avoid making a database connection, keeping our test suites independent and their execution process as fast as possible. But our classes might depend on models that are pulled from the connection instance. How do we handle that? The solution is to create mock models. In order to achieve that, we set up [custom providers](/v11/fundamentals/custom-providers). Each registered model is automatically represented by a `<ModelName>Model` token, where `ModelName` is the name of your model class.

The `@nestjs/sequelize` package exposes the `getModelToken()` function which returns a prepared token based on a given model.

```typescript

@Module({
  providers: [
    UsersService,
    {
      provide: getModelToken(User),
      useValue: mockModel,
    },
  ],
})
export class UsersModule {}
```

Now a substitute `mockModel` will be used as the `UserModel`. Whenever any class asks for `UserModel` using an `@InjectModel()` decorator, Nest will use the registered `mockModel` object.

#### Async configuration[#](/techniques/database#async-configuration-1)

You may want to pass your `SequelizeModule` options asynchronously instead of statically. In this case, use the `forRootAsync()` method, which provides several ways to deal with async configuration.

One approach is to use a factory function:

```typescript

SequelizeModule.forRootAsync({
  useFactory: () => ({
    dialect: 'mysql',
    host: 'localhost',
    port: 3306,
    username: 'root',
    password: 'root',
    database: 'test',
    models: [],
  }),
});
```

Our factory behaves like any other [asynchronous provider](https://docs.nestjs.com/fundamentals/async-providers) (e.g., it can be `async` and it's able to inject dependencies through `inject`).

```typescript

SequelizeModule.forRootAsync({
  imports: [ConfigModule],
  useFactory: (configService: ConfigService) => ({
    dialect: 'mysql',
    host: configService.get('HOST'),
    port: +configService.get('PORT'),
    username: configService.get('USERNAME'),
    password: configService.get('PASSWORD'),
    database: configService.get('DATABASE'),
    models: [],
  }),
  inject: [ConfigService],
});
```

Alternatively, you can use the `useClass` syntax:

```typescript

SequelizeModule.forRootAsync({
  useClass: SequelizeConfigService,
});
```

The construction above will instantiate `SequelizeConfigService` inside `SequelizeModule` and use it to provide an options object by calling `createSequelizeOptions()`. Note that this means that the `SequelizeConfigService` has to implement the `SequelizeOptionsFactory` interface, as shown below:

```typescript

@Injectable()
class SequelizeConfigService implements SequelizeOptionsFactory {
  createSequelizeOptions(): SequelizeModuleOptions {
    return {
      dialect: 'mysql',
      host: 'localhost',
      port: 3306,
      username: 'root',
      password: 'root',
      database: 'test',
      models: [],
    };
  }
}
```

In order to prevent the creation of `SequelizeConfigService` inside `SequelizeModule` and use a provider imported from a different module, you can use the `useExisting` syntax.

```typescript

SequelizeModule.forRootAsync({
  imports: [ConfigModule],
  useExisting: ConfigService,
});
```

This construction works the same as `useClass` with one critical difference - `SequelizeModule` will lookup imported modules to reuse an existing `ConfigService` instead of instantiating a new one.

#### Example[#](/techniques/database#example-1)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/07-sequelize).

----
url: https://docs.nestjs.com/v11/fundamentals/execution-context
----

* [Execution context](https://docs.nestjs.com/v11/fundamentals/execution-context#execution-context)
* [ArgumentsHost class](https://docs.nestjs.com/v11/fundamentals/execution-context#argumentshost-class)
* [Current application context](https://docs.nestjs.com/v11/fundamentals/execution-context#current-application-context)
* [Host handler arguments](https://docs.nestjs.com/v11/fundamentals/execution-context#host-handler-arguments)
* [ExecutionContext class](https://docs.nestjs.com/v11/fundamentals/execution-context#executioncontext-class)
* [Reflection and metadata](https://docs.nestjs.com/v11/fundamentals/execution-context#reflection-and-metadata)
* [Low-level approach](https://docs.nestjs.com/v11/fundamentals/execution-context#low-level-approach)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/fundamentals/execution-context.md "Suggest Edits")

### Execution context

Nest provides several utility classes that help make it easy to write applications that function across multiple application contexts (e.g., Nest HTTP server-based, microservices and WebSockets application contexts). These utilities provide information about the current execution context which can be used to build generic [guards](/v11/guards), [filters](/v11/exception-filters), and [interceptors](/v11/interceptors) that can work across a broad set of controllers, methods, and execution contexts.

We cover two such classes in this chapter: `ArgumentsHost` and `ExecutionContext`.

#### ArgumentsHost class[#](/fundamentals/execution-context#argumentshost-class)

The `ArgumentsHost` class provides methods for retrieving the arguments being passed to a handler. It allows choosing the appropriate context (e.g., HTTP, RPC (microservice), or WebSockets) to retrieve the arguments from. The framework provides an instance of `ArgumentsHost`, typically referenced as a `host` parameter, in places where you may want to access it. For example, the `catch()` method of an [exception filter](https://docs.nestjs.com/exception-filters#arguments-host) is called with an `ArgumentsHost`instance.

`ArgumentsHost` simply acts as an abstraction over a handler's arguments. For example, for HTTP server applications (when `@nestjs/platform-express` is being used), the `host` object encapsulates Express's `[request, response, next]` array, where `request` is the request object, `response` is the response object, and `next` is a function that controls the application's request-response cycle. On the other hand, for [GraphQL](/v11/graphql/quick-start) applications, the `host` object contains the `[root, args, context, info]` array.

#### Current application context[#](/fundamentals/execution-context#current-application-context)

When building generic [guards](/v11/guards), [filters](/v11/exception-filters), and [interceptors](/v11/interceptors) which are meant to run across multiple application contexts, we need a way to determine the type of application that our method is currently running in. Do this with the `getType()` method of `ArgumentsHost`:

```typescript

if (host.getType() === 'http') {
  // do something that is only important in the context of regular HTTP requests (REST)
} else if (host.getType() === 'rpc') {
  // do something that is only important in the context of Microservice requests
} else if (host.getType<GqlContextType>() === 'graphql') {
  // do something that is only important in the context of GraphQL requests
}
```

> **Hint** The `GqlContextType` is imported from the `@nestjs/graphql` package.

With the application type available, we can write more generic components, as shown below.

#### Host handler arguments[#](/fundamentals/execution-context#host-handler-arguments)

To retrieve the array of arguments being passed to the handler, one approach is to use the host object's `getArgs()` method.

```typescript

const [req, res, next] = host.getArgs();
```

You can pluck a particular argument by index using the `getArgByIndex()` method:

```typescript

const request = host.getArgByIndex(0);
const response = host.getArgByIndex(1);
```

In these examples we retrieved the request and response objects by index, which is not typically recommended as it couples the application to a particular execution context. Instead, you can make your code more robust and reusable by using one of the `host` object's utility methods to switch to the appropriate application context for your application. The context switch utility methods are shown below.

```typescript

/**
 * Switch context to RPC.
 */
switchToRpc(): RpcArgumentsHost;
/**
 * Switch context to HTTP.
 */
switchToHttp(): HttpArgumentsHost;
/**
 * Switch context to WebSockets.
 */
switchToWs(): WsArgumentsHost;
```

Let's rewrite the previous example using the `switchToHttp()` method. The `host.switchToHttp()` helper call returns an `HttpArgumentsHost` object that is appropriate for the HTTP application context. The `HttpArgumentsHost` object has two useful methods we can use to extract the desired objects. We also use the Express type assertions in this case to return native Express typed objects:

```typescript

const ctx = host.switchToHttp();
const request = ctx.getRequest<Request>();
const response = ctx.getResponse<Response>();
```

Similarly `WsArgumentsHost` and `RpcArgumentsHost` have methods to return appropriate objects in the microservices and WebSockets contexts. Here are the methods for `WsArgumentsHost`:

```typescript

export interface WsArgumentsHost {
  /**
   * Returns the data object.
   */
  getData<T>(): T;
  /**
   * Returns the client object.
   */
  getClient<T>(): T;
}
```

Following are the methods for `RpcArgumentsHost`:

```typescript

export interface RpcArgumentsHost {
  /**
   * Returns the data object.
   */
  getData<T>(): T;

  /**
   * Returns the context object.
   */
  getContext<T>(): T;
}
```

#### ExecutionContext class[#](/fundamentals/execution-context#executioncontext-class)

`ExecutionContext` extends `ArgumentsHost`, providing additional details about the current execution process. Like `ArgumentsHost`, Nest provides an instance of `ExecutionContext` in places you may need it, such as in the `canActivate()` method of a [guard](https://docs.nestjs.com/guards#execution-context) and the `intercept()` method of an [interceptor](https://docs.nestjs.com/interceptors#execution-context). It provides the following methods:

```typescript

export interface ExecutionContext extends ArgumentsHost {
  /**
   * Returns the type of the controller class which the current handler belongs to.
   */
  getClass<T>(): Type<T>;
  /**
   * Returns a reference to the handler (method) that will be invoked next in the
   * request pipeline.
   */
  getHandler(): Function;
}
```

The `getHandler()` method returns a reference to the handler about to be invoked. The `getClass()` method returns the type of the `Controller` class which this particular handler belongs to. For example, in an HTTP context, if the currently processed request is a `POST` request, bound to the `create()` method on the `CatsController`, `getHandler()` returns a reference to the `create()` method and `getClass()` returns the `CatsController`**class** (not instance).

```typescript

const methodKey = ctx.getHandler().name; // "create"
const className = ctx.getClass().name; // "CatsController"
```

The ability to access references to both the current class and handler method provides great flexibility. Most importantly, it gives us the opportunity to access the metadata set through either decorators created via `Reflector#createDecorator` or the built-in `@SetMetadata()` decorator from within guards or interceptors. We cover this use case below.

Nest provides the ability to attach **custom metadata** to route handlers through decorators created via `Reflector#createDecorator` method, and the built-in `@SetMetadata()` decorator. In this section, let's compare the two approaches and see how to access the metadata from within a guard or interceptor.

To create strongly-typed decorators using `Reflector#createDecorator`, we need to specify the type argument. For example, let's create a `Roles` decorator that takes an array of strings as an argument.

roles.decorator.ts

JS TS

```ts

import { Reflector } from '@nestjs/core';

export const Roles = Reflector.createDecorator<string[]>();
```

The `Roles` decorator here is a function that takes a single argument of type `string[]`.

Now, to use this decorator, we simply annotate the handler with it:

cats.controller.ts

JS TS

```typescript

@Post()
@Roles(['admin'])
async create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

```typescript

@Post()
@Roles(['admin'])
@Bind(Body())
async create(createCatDto) {
  this.catsService.create(createCatDto);
}
```

Here we've attached the `Roles` decorator metadata to the `create()` method, indicating that only users with the `admin` role should be allowed to access this route.

To access the route's role(s) (custom metadata), we'll use the `Reflector` helper class again. `Reflector` can be injected into a class in the normal way:

roles.guard.ts

JS TS

```typescript

@Injectable()
export class RolesGuard {
  constructor(private reflector: Reflector) {}
}
```

```typescript

@Injectable()
@Dependencies(Reflector)
export class CatsService {
  constructor(reflector) {
    this.reflector = reflector;
  }
}
```

> **Hint** The `Reflector` class is imported from the `@nestjs/core` package.

Now, to read the handler metadata, use the `get()` method:

```typescript

const roles = this.reflector.get(Roles, context.getHandler());
```

The `Reflector#get` method allows us to easily access the metadata by passing in two arguments: a decorator reference and a **context** (decorator target) to retrieve the metadata from. In this example, the specified **decorator** is `Roles` (refer back to the `roles.decorator.ts` file above). The context is provided by the call to `context.getHandler()`, which results in extracting the metadata for the currently processed route handler. Remember, `getHandler()` gives us a **reference** to the route handler function.

Alternatively, we may organize our controller by applying metadata at the controller level, applying to all routes in the controller class.

cats.controller.ts

JS TS

```typescript

@Roles(['admin'])
@Controller('cats')
export class CatsController {}
```

```typescript

@Roles(['admin'])
@Controller('cats')
export class CatsController {}
```

In this case, to extract controller metadata, we pass `context.getClass()` as the second argument (to provide the controller class as the context for metadata extraction) instead of `context.getHandler()`:

roles.guard.ts

JS TS

```typescript

const roles = this.reflector.get(Roles, context.getClass());
```

Given the ability to provide metadata at multiple levels, you may need to extract and merge metadata from several contexts. The `Reflector` class provides two utility methods used to help with this. These methods extract **both** controller and method metadata at once, and combine them in different ways.

Consider the following scenario, where you've supplied `Roles` metadata at both levels.

cats.controller.ts

JS TS

```typescript

@Roles(['user'])
@Controller('cats')
export class CatsController {
  @Post()
  @Roles(['admin'])
  async create(@Body() createCatDto: CreateCatDto) {
    this.catsService.create(createCatDto);
  }
}
```

```typescript

@Roles(['user'])
@Controller('cats')
export class CatsController {}
  @Post()
  @Roles(['admin'])
  @Bind(Body())
  async create(createCatDto) {
    this.catsService.create(createCatDto);
  }
}
```

If your intent is to specify `'user'` as the default role, and override it selectively for certain methods, you would probably use the `getAllAndOverride()` method.

```typescript

const roles = this.reflector.getAllAndOverride(Roles, [context.getHandler(), context.getClass()]);
```

A guard with this code, running in the context of the `create()` method, with the above metadata, would result in `roles` containing `['admin']`.

To get metadata for both and merge it (this method merges both arrays and objects), use the `getAllAndMerge()` method:

```typescript

const roles = this.reflector.getAllAndMerge(Roles, [context.getHandler(), context.getClass()]);
```

This would result in `roles` containing `['user', 'admin']`.

For both of these merge methods, you pass the metadata key as the first argument, and an array of metadata target contexts (i.e., calls to the `getHandler()` and/or `getClass()` methods) as the second argument.

#### Low-level approach[#](/fundamentals/execution-context#low-level-approach)

As mentioned earlier, instead of using `Reflector#createDecorator`, you can also use the built-in `@SetMetadata()` decorator to attach metadata to a handler.

cats.controller.ts

JS TS

```typescript

@Post()
@SetMetadata('roles', ['admin'])
async create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

```typescript

@Post()
@SetMetadata('roles', ['admin'])
@Bind(Body())
async create(createCatDto) {
  this.catsService.create(createCatDto);
}
```

> **Hint** The `@SetMetadata()` decorator is imported from the `@nestjs/common` package.

With the construction above, we attached the `roles` metadata (`roles` is a metadata key and `['admin']` is the associated value) to the `create()` method. While this works, it's not good practice to use `@SetMetadata()` directly in your routes. Instead, you can create your own decorators, as shown below:

roles.decorator.ts

JS TS

```typescript

import { SetMetadata } from '@nestjs/common';

export const Roles = (...roles: string[]) => SetMetadata('roles', roles);
```

```typescript

import { SetMetadata } from '@nestjs/common';

export const Roles = (...roles) => SetMetadata('roles', roles);
```

This approach is much cleaner and more readable, and somewhat resembles the `Reflector#createDecorator` approach. The difference is that with `@SetMetadata` you have more control over the metadata key and value, and also can create decorators that take more than one argument.

Now that we have a custom `@Roles()` decorator, we can use it to decorate the `create()` method.

cats.controller.ts

JS TS

```typescript

@Post()
@Roles('admin')
async create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

```typescript

@Post()
@Roles('admin')
@Bind(Body())
async create(createCatDto) {
  this.catsService.create(createCatDto);
}
```

To access the route's role(s) (custom metadata), we'll use the `Reflector` helper class again:

roles.guard.ts

JS TS

```typescript

@Injectable()
export class RolesGuard {
  constructor(private reflector: Reflector) {}
}
```

```typescript

@Injectable()
@Dependencies(Reflector)
export class CatsService {
  constructor(reflector) {
    this.reflector = reflector;
  }
}
```

> **Hint** The `Reflector` class is imported from the `@nestjs/core` package.

Now, to read the handler metadata, use the `get()` method.

```typescript

const roles = this.reflector.get<string[]>('roles', context.getHandler());
```

Here instead of passing a decorator reference, we pass the metadata **key** as the first argument (which in our case is `'roles'`). Everything else remains the same as in the `Reflector#createDecorator` example.

----
url: https://docs.nestjs.com/v11/graphql/mutations
----

* [Mutations](https://docs.nestjs.com/v11/graphql/mutations#mutations)
* [Code first](https://docs.nestjs.com/v11/graphql/mutations#code-first)
* [Schema first](https://docs.nestjs.com/v11/graphql/mutations#schema-first)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/mutations.md "Suggest Edits")

### Mutations

Most discussions of GraphQL focus on data fetching, but any complete data platform needs a way to modify server-side data as well. In REST, any request could end up causing side-effects on the server, but best practice suggests we should not modify data in GET requests. GraphQL is similar - technically any query could be implemented to cause a data write. However, like REST, it's recommended to observe the convention that any operations that cause writes should be sent explicitly via a mutation (read more [here](https://graphql.org/learn/queries/#mutations)).

The official [Apollo](https://www.apollographql.com/docs/graphql-tools/generate-schema.html) documentation uses an `upvotePost()` mutation example. This mutation implements a method to increase a post's `votes` property value. To create an equivalent mutation in Nest, we'll make use of the `@Mutation()` decorator.

#### Code first[#](/graphql/mutations#code-first)

Let's add another method to the `AuthorResolver` used in the previous section (see [resolvers](/v11/graphql/resolvers)).

```typescript

@Mutation(() => Post)
async upvotePost(@Args({ name: 'postId', type: () => Int }) postId: number) {
  return this.postsService.upvoteById({ id: postId });
}
```

> **Hint** All decorators (e.g., `@Resolver`, `@ResolveField`, `@Args`, etc.) are exported from the `@nestjs/graphql` package.

This will result in generating the following part of the GraphQL schema in SDL:

```graphql

type Mutation {
  upvotePost(postId: Int!): Post
}
```

The `upvotePost()` method takes `postId` (`Int`) as an argument and returns an updated `Post` entity. For the reasons explained in the [resolvers](/v11/graphql/resolvers) section, we have to explicitly set the expected type.

If the mutation needs to take an object as an argument, we can create an **input type**. The input type is a special kind of object type that can be passed in as an argument (read more [here](https://graphql.org/learn/schema/#input-types)). To declare an input type, use the `@InputType()` decorator.

```typescript

import { InputType, Field } from '@nestjs/graphql';

@InputType()
export class UpvotePostInput {
  @Field()
  postId: number;
}
```

> **Hint** The `@InputType()` decorator takes an options object as an argument, so you can, for example, specify the input type's description. Note that, due to TypeScript's metadata reflection system limitations, you must either use the `@Field` decorator to manually indicate a type, or use a [CLI plugin](/v11/graphql/cli-plugin).

We can then use this type in the resolver class:

```typescript

@Mutation(() => Post)
async upvotePost(
  @Args('upvotePostData') upvotePostData: UpvotePostInput,
) {}
```

#### Schema first[#](/graphql/mutations#schema-first)

Let's extend our `AuthorResolver` used in the previous section (see [resolvers](/v11/graphql/resolvers)).

```typescript

@Mutation()
async upvotePost(@Args('postId') postId: number) {
  return this.postsService.upvoteById({ id: postId });
}
```

Note that we assumed above that the business logic has been moved to the `PostsService` (querying the post and incrementing its `votes` property). The logic inside the `PostsService` class can be as simple or sophisticated as needed. The main point of this example is to show how resolvers can interact with other providers.

The last step is to add our mutation to the existing types definition.

```graphql

type Author {
  id: Int!
  firstName: String
  lastName: String
  posts: [Post]
}

type Post {
  id: Int!
  title: String
  votes: Int
}

type Query {
  author(id: Int!): Author
}

type Mutation {
  upvotePost(postId: Int!): Post
}
```

The `upvotePost(postId: Int!): Post` mutation is now available to be called as part of our application's GraphQL API.

----
url: https://docs.nestjs.com/v9/security/authentication
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Authentication](https://docs.nestjs.com/v9/security/authentication#authentication)
* [Creating an authentication module](https://docs.nestjs.com/v9/security/authentication#creating-an-authentication-module)
* [Implementing the "Sign in" endpoint](https://docs.nestjs.com/v9/security/authentication#implementing-the-sign-in-endpoint)
* [JWT token](https://docs.nestjs.com/v9/security/authentication#jwt-token)
* [Implementing the authentication guard](https://docs.nestjs.com/v9/security/authentication#implementing-the-authentication-guard)
* [Enable authentication globally](https://docs.nestjs.com/v9/security/authentication#enable-authentication-globally)
* [Passport integration](https://docs.nestjs.com/v9/security/authentication#passport-integration)
* [Example](https://docs.nestjs.com/v9/security/authentication#example)

```bash

$ nest g module auth
$ nest g controller auth
$ nest g service auth
```

As we implement the `AuthService`, we'll find it useful to encapsulate user operations in a `UsersService`, so let's generate that module and service now:

```bash

$ nest g module users
$ nest g service users
```

Replace the default contents of these generated files as shown below. For our sample app, the `UsersService` simply maintains a hard-coded in-memory list of users, and a find method to retrieve one by username. In a real app, this is where you'd build your user model and persistence layer, using your library of choice (e.g., TypeORM, Sequelize, Mongoose, etc.).

users/users.service.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';

// This should be a real class/interface representing a user entity
export type User = any;

@Injectable()
export class UsersService {
  private readonly users = [
    {
      userId: 1,
      username: 'john',
      password: 'changeme',
    },
    {
      userId: 2,
      username: 'maria',
      password: 'guess',
    },
  ];

  async findOne(username: string): Promise<User | undefined> {
    return this.users.find(user => user.username === username);
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';

@Injectable()
export class UsersService {
  constructor() {
    this.users = [
      {
        userId: 1,
        username: 'john',
        password: 'changeme',
      },
      {
        userId: 2,
        username: 'maria',
        password: 'guess',
      },
    ];
  }

  async findOne(username) {
    return this.users.find(user => user.username === username);
  }
}
```

In the `UsersModule`, the only change needed is to add the `UsersService` to the exports array of the `@Module` decorator so that it is visible outside this module (we'll soon use it in our `AuthService`).

users/users.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { UsersService } from './users.service';

@Module({
  providers: [UsersService],
  exports: [UsersService],
})
export class UsersModule {}
```

```typescript

import { Module } from '@nestjs/common';
import { UsersService } from './users.service';

@Module({
  providers: [UsersService],
  exports: [UsersService],
})
export class UsersModule {}
```

#### Implementing the "Sign in" endpoint[#](/security/authentication#implementing-the-sign-in-endpoint)

Our `AuthService` has the job of retrieving a user and verifying the password. We create a `signIn()` method for this purpose. In the code below, we use a convenient ES6 spread operator to strip the password property from the user object before returning it. This is a common practice when returning user objects, as you don't want to expose sensitive fields like passwords or other security keys.

auth/auth.service.ts

JS TS

```typescript

import { Injectable, UnauthorizedException } from '@nestjs/common';
import { UsersService } from '../users/users.service';

@Injectable()
export class AuthService {
  constructor(private usersService: UsersService) {}

  async signIn(username: string, pass: string): Promise<any> {
    const user = await this.usersService.findOne(username);
    if (user?.password !== pass) {
      throw new UnauthorizedException();
    }
    const { password, ...result } = user;
    // TODO: Generate a JWT and return it here
    // instead of the user object
    return result;
  }
}
```

```typescript

import { Injectable, Dependencies, UnauthorizedException } from '@nestjs/common';
import { UsersService } from '../users/users.service';

@Injectable()
@Dependencies(UsersService)
export class AuthService {
  constructor(usersService) {
    this.usersService = usersService;
  }

  async signIn(username: string, pass: string) {
    const user = await this.usersService.findOne(username);
    if (user?.password !== pass) {
      throw new UnauthorizedException();
    }
    const { password, ...result } = user;
    // TODO: Generate a JWT and return it here
    // instead of the user object
    return result;
  }
}
```

> **Warning** Of course in a real application, you wouldn't store a password in plain text. You'd instead use a library like [bcrypt](https://github.com/kelektiv/node.bcrypt.js#readme), with a salted one-way hash algorithm. With that approach, you'd only store hashed passwords, and then compare the stored password to a hashed version of the **incoming** password, thus never storing or exposing user passwords in plain text. To keep our sample app simple, we violate that absolute mandate and use plain text. **Don't do this in your real app!**

Now, we update our `AuthModule` to import the `UsersModule`.

auth/auth.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { AuthController } from './auth.controller';
import { UsersModule } from '../users/users.module';

@Module({
  imports: [UsersModule],
  providers: [AuthService],
  controllers: [AuthController],
})
export class AuthModule {}
```

```typescript

import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { AuthController } from './auth.controller';
import { UsersModule } from '../users/users.module';

@Module({
  imports: [UsersModule],
  providers: [AuthService],
  controllers: [AuthController],
})
export class AuthModule {}
```

With this in place, let's open up the `AuthController` and add a `signIn()` method to it. This method will be called by the client to authenticate a user. It will receive the username and password in the request body, and will return a JWT token if the user is authenticated.

auth/auth.controller.ts

JS TS

```typescript

import { Body, Controller, Post, HttpCode, HttpStatus } from '@nestjs/common';
import { AuthService } from './auth.service';

@Controller('auth')
export class AuthController {
  constructor(private authService: AuthService) {}

  @HttpCode(HttpStatus.OK)
  @Post('login')
  signIn(@Body() signInDto: Record<string, any>) {
    return this.authService.signIn(signInDto.username, signInDto.password);
  }
}
```

> **Hint** Ideally, instead of using the `Record<string, any>` type, we should use a DTO class to define the shape of the request body. See the [validation](/v9/techniques/validation) chapter for more information.

```bash

$ npm install --save @nestjs/jwt
```

> **Hint** The `@nestjs/jwt` package (see more [here](https://github.com/nestjs/jwt)) is a utility package that helps with JWT manipulation. This includes generating and verifying JWT tokens.

To keep our services cleanly modularized, we'll handle generating the JWT in the `authService`. Open the `auth.service.ts` file in the `auth` folder, inject the `JwtService`, and update the `signIn` method to generate a JWT token as shown below:

auth/auth.service.ts

JS TS

```typescript

import { Injectable, UnauthorizedException } from '@nestjs/common';
import { UsersService } from '../users/users.service';
import { JwtService } from '@nestjs/jwt';

@Injectable()
export class AuthService {
  constructor(
    private usersService: UsersService,
    private jwtService: JwtService
  ) {}

  async signIn(username, pass) {
    const user = await this.usersService.findOne(username);
    if (user?.password !== pass) {
      throw new UnauthorizedException();
    }
    const payload = { sub: user.userId, username: user.username };
    return {
      access_token: await this.jwtService.signAsync(payload),
    };
  }
}
```

```typescript

import { Injectable, Dependencies, UnauthorizedException } from '@nestjs/common';
import { UsersService } from '../users/users.service';
import { JwtService } from '@nestjs/jwt';

@Dependencies(UsersService, JwtService)
@Injectable()
export class AuthService {
  constructor(usersService, jwtService) {
    this.usersService = usersService;
    this.jwtService = jwtService;
  }

  async signIn(username, pass) {
    const user = await this.usersService.findOne(username);
    if (user?.password !== pass) {
      throw new UnauthorizedException();
    }
    const payload = { username: user.username, sub: user.userId };
    return {
      access_token: await this.jwtService.signAsync(payload),
    };
  }
}
```

We're using the `@nestjs/jwt` library, which supplies a `signAsync()` function to generate our JWT from a subset of the `user` object properties, which we then return as a simple object with a single `access_token` property. Note: we choose a property name of `sub` to hold our `userId` value to be consistent with JWT standards. Don't forget to inject the JwtService provider into the `AuthService`.

We now need to update the `AuthModule` to import the new dependencies and configure the `JwtModule`.

First, create `constants.ts` in the `auth` folder, and add the following code:

auth/constants.ts

JS TS

```typescript

export const jwtConstants = {
  secret: 'DO NOT USE THIS VALUE. INSTEAD, CREATE A COMPLEX SECRET AND KEEP IT SAFE OUTSIDE OF THE SOURCE CODE.',
};
```

```typescript

export const jwtConstants = {
  secret: 'DO NOT USE THIS VALUE. INSTEAD, CREATE A COMPLEX SECRET AND KEEP IT SAFE OUTSIDE OF THE SOURCE CODE.',
};
```

We'll use this to share our key between the JWT signing and verifying steps.

> **Warning****Do not expose this key publicly**. We have done so here to make it clear what the code is doing, but in a production system **you must protect this key** using appropriate measures such as a secrets vault, environment variable, or configuration service.

Now, open `auth.module.ts` in the `auth` folder and update it to look like this:

auth/auth.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { UsersModule } from '../users/users.module';
import { JwtModule } from '@nestjs/jwt';
import { AuthController } from './auth.controller';
import { jwtConstants } from './constants';

@Module({
  imports: [
    UsersModule,
    JwtModule.register({
      global: true,
      secret: jwtConstants.secret,
      signOptions: { expiresIn: '60s' },
    }),
  ],
  providers: [AuthService],
  controllers: [AuthController],
  exports: [AuthService],
})
export class AuthModule {}
```

```typescript

import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { UsersModule } from '../users/users.module';
import { JwtModule } from '@nestjs/jwt';
import { AuthController } from './auth.controller';
import { jwtConstants } from './constants';

@Module({
  imports: [
    UsersModule,
    JwtModule.register({
      global: true,
      secret: jwtConstants.secret,
      signOptions: { expiresIn: '60s' },
    }),
  ],
  providers: [AuthService],
  controllers: [AuthController],
  exports: [AuthService],
})
export class AuthModule {}
```

> **Hint** We're registering the `JwtModule` as global to make things easier for us. This means that we don't need to import the `JwtModule` anywhere else in our application.

We configure the `JwtModule` using `register()`, passing in a configuration object. See [here](https://github.com/nestjs/jwt/blob/master/README.md) for more on the Nest `JwtModule` and [here](https://github.com/auth0/node-jsonwebtoken#usage) for more details on the available configuration options.

Let's go ahead and test our routes using cURL again. You can test with any of the `user` objects hard-coded in the `UsersService`.

```bash

$ # POST to /auth/login
$ curl -X POST http://localhost:3000/auth/login -d '{"username": "john", "password": "changeme"}' -H "Content-Type: application/json"
{"access_token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."}
$ # Note: above JWT truncated
```

#### Implementing the authentication guard[#](/security/authentication#implementing-the-authentication-guard)

We can now address our final requirement: protecting endpoints by requiring a valid JWT be present on the request. We'll do this by creating an `AuthGuard` that we can use to protect our routes.

auth/auth.guard.ts

JS TS

```typescript

import {
  CanActivate,
  ExecutionContext,
  Injectable,
  UnauthorizedException,
} from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
import { jwtConstants } from './constants';
import { Request } from 'express';

@Injectable()
export class AuthGuard implements CanActivate {
  constructor(private jwtService: JwtService) {}

  async canActivate(context: ExecutionContext): Promise<boolean> {
    const request = context.switchToHttp().getRequest();
    const token = this.extractTokenFromHeader(request);
    if (!token) {
      throw new UnauthorizedException();
    }
    try {
      const payload = await this.jwtService.verifyAsync(
        token,
        {
          secret: jwtConstants.secret
        }
      );
      // 💡 We're assigning the payload to the request object here
      // so that we can access it in our route handlers
      request['user'] = payload;
    } catch {
      throw new UnauthorizedException();
    }
    return true;
  }

  private extractTokenFromHeader(request: Request): string | undefined {
    const [type, token] = request.headers.authorization?.split(' ') ?? [];
    return type === 'Bearer' ? token : undefined;
  }
}
```

We can now implement our protected route and register our `AuthGuard` to protect it.

Open the `auth.controller.ts` file and update it as shown below:

auth.controller.ts

JS TS

```typescript

import {
  Body,
  Controller,
  Get,
  HttpCode,
  HttpStatus,
  Post,
  Request,
  UseGuards
} from '@nestjs/common';
import { AuthGuard } from './auth.guard';
import { AuthService } from './auth.service';

@Controller('auth')
export class AuthController {
  constructor(private authService: AuthService) {}

  @HttpCode(HttpStatus.OK)
  @Post('login')
  signIn(@Body() signInDto: Record<string, any>) {
    return this.authService.signIn(signInDto.username, signInDto.password);
  }

  @UseGuards(AuthGuard)
  @Get('profile')
  getProfile(@Request() req) {
    return req.user;
  }
}
```

We're applying the `AuthGuard` that we just created to the `GET /profile` route so that it will be protected.

Ensure the app is running, and test the routes using `cURL`.

```bash

$ # GET /profile
$ curl http://localhost:3000/auth/profile
{"statusCode":401,"message":"Unauthorized"}

$ # POST /auth/login
$ curl -X POST http://localhost:3000/auth/login -d '{"username": "john", "password": "changeme"}' -H "Content-Type: application/json"
{"access_token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2Vybm..."}

$ # GET /profile using access_token returned from previous step as bearer code
$ curl http://localhost:3000/auth/profile -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2Vybm..."
{"sub":1,"username":"john","iat":...,"exp":...}
```

Note that in the `AuthModule`, we configured the JWT to have an expiration of `60 seconds`. This is too short an expiration, and dealing with the details of token expiration and refresh is beyond the scope of this article. However, we chose that to demonstrate an important quality of JWTs. If you wait 60 seconds after authenticating before attempting a `GET /auth/profile` request, you'll receive a `401 Unauthorized` response. This is because `@nestjs/jwt` automatically checks the JWT for its expiration time, saving you the trouble of doing so in your application.

We've now completed our JWT authentication implementation. JavaScript clients (such as Angular/React/Vue), and other JavaScript apps, can now authenticate and communicate securely with our API Server.

#### Enable authentication globally[#](/security/authentication#enable-authentication-globally)

If the vast majority of your endpoints should be protected by default, you can register the authentication guard as a [global guard](/guards#binding-guards) and instead of using `@UseGuards()` decorator on top of each controller, you could simply flag which routes should be public.

First, register the `AuthGuard` as a global guard using the following construction (in any module, for example, in the `AuthModule`):

```typescript

providers: [
  {
    provide: APP_GUARD,
    useClass: AuthGuard,
  },
],
```

With this in place, Nest will automatically bind `AuthGuard` to all endpoints.

Now we must provide a mechanism for declaring routes as public. For this, we can create a custom decorator using the `SetMetadata` decorator factory function.

```typescript

import { SetMetadata } from '@nestjs/common';

export const IS_PUBLIC_KEY = 'isPublic';
export const Public = () => SetMetadata(IS_PUBLIC_KEY, true);
```

In the file above, we exported two constants. One being our metadata key named `IS_PUBLIC_KEY`, and the other being our new decorator itself that we’re going to call `Public` (you can alternatively name it `SkipAuth` or `AllowAnon`, whatever fits your project).

Now that we have a custom `@Public()` decorator, we can use it to decorate any method, as follows:

```typescript

@Public()
@Get()
findAll() {
  return [];
}
```

Lastly, we need the `AuthGuard` to return `true` when the `"isPublic"` metadata is found. For this, we'll use the `Reflector` class (read more [here](/guards#putting-it-all-together)).

```typescript

@Injectable()
export class AuthGuard implements CanActivate {
  constructor(private jwtService: JwtService, private reflector: Reflector) {}

  async canActivate(context: ExecutionContext): Promise<boolean> {
    const isPublic = this.reflector.getAllAndOverride<boolean>(IS_PUBLIC_KEY, [
      context.getHandler(),
      context.getClass(),
    ]);
    if (isPublic) {
      // 💡 See this condition
      return true;
    }

    const request = context.switchToHttp().getRequest();
    const token = this.extractTokenFromHeader(request);
    if (!token) {
      throw new UnauthorizedException();
    }
    try {
      const payload = await this.jwtService.verifyAsync(token, {
        secret: jwtConstants.secret,
      });
      // 💡 We're assigning the payload to the request object here
      // so that we can access it in our route handlers
      request['user'] = payload;
    } catch {
      throw new UnauthorizedException();
    }
    return true;
  }

  private extractTokenFromHeader(request: Request): string | undefined {
    const [type, token] = request.headers.authorization?.split(' ') ?? [];
    return type === 'Bearer' ? token : undefined;
  }
}
```

#### Passport integration[#](/security/authentication#passport-integration)

[Passport](https://github.com/jaredhanson/passport) is the most popular node.js authentication library, well-known by the community and successfully used in many production applications. It's straightforward to integrate this library with a **Nest** application using the `@nestjs/passport` module.

To learn how you can integrate Passport with NestJS, check out this [chapter](/v9/recipes/passport).

#### Example[#](/security/authentication#example)

You can find a complete version of the code in this chapter [here](https://github.com/nestjs/nest/tree/master/sample/19-auth-jwt).

----
url: https://docs.nestjs.com/v9/fundamentals/custom-providers
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Custom providers](https://docs.nestjs.com/v9/fundamentals/custom-providers#custom-providers)
* [DI fundamentals](https://docs.nestjs.com/v9/fundamentals/custom-providers#di-fundamentals)
* [Standard providers](https://docs.nestjs.com/v9/fundamentals/custom-providers#standard-providers)
* [Custom providers](https://docs.nestjs.com/v9/fundamentals/custom-providers#custom-providers-1)
* [Value providers: useValue](https://docs.nestjs.com/v9/fundamentals/custom-providers#value-providers-usevalue)
* [Non-class-based provider tokens](https://docs.nestjs.com/v9/fundamentals/custom-providers#non-class-based-provider-tokens)
* [Class providers: useClass](https://docs.nestjs.com/v9/fundamentals/custom-providers#class-providers-useclass)
* [Factory providers: useFactory](https://docs.nestjs.com/v9/fundamentals/custom-providers#factory-providers-usefactory)
* [Alias providers: useExisting](https://docs.nestjs.com/v9/fundamentals/custom-providers#alias-providers-useexisting)
* [Non-service based providers](https://docs.nestjs.com/v9/fundamentals/custom-providers#non-service-based-providers)
* [Export custom provider](https://docs.nestjs.com/v9/fundamentals/custom-providers#export-custom-provider)

```typescript

import { Injectable } from '@nestjs/common';
import { Cat } from './interfaces/cat.interface';

@Injectable()
export class CatsService {
  private readonly cats: Cat[] = [];

  findAll(): Cat[] {
    return this.cats;
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';

@Injectable()
export class CatsService {
  constructor() {
    this.cats = [];
  }

  findAll() {
    return this.cats;
  }
}
```

Then we request that Nest inject the provider into our controller class:

cats.controller.ts

JS TS

```typescript

import { Controller, Get } from '@nestjs/common';
import { CatsService } from './cats.service';
import { Cat } from './interfaces/cat.interface';

@Controller('cats')
export class CatsController {
  constructor(private catsService: CatsService) {}

  @Get()
  async findAll(): Promise<Cat[]> {
    return this.catsService.findAll();
  }
}
```

```typescript

import { Controller, Get, Bind, Dependencies } from '@nestjs/common';
import { CatsService } from './cats.service';

@Controller('cats')
@Dependencies(CatsService)
export class CatsController {
  constructor(catsService) {
    this.catsService = catsService;
  }

  @Get()
  async findAll() {
    return this.catsService.findAll();
  }
}
```

Finally, we register the provider with the Nest IoC container:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { CatsController } from './cats/cats.controller';
import { CatsService } from './cats/cats.service';

@Module({
  controllers: [CatsController],
  providers: [CatsService],
})
export class AppModule {}
```

What exactly is happening under the covers to make this work? There are three key steps in the process:

1. In `cats.service.ts`, the `@Injectable()` decorator declares the `CatsService` class as a class that can be managed by the Nest IoC container.
2. In `cats.controller.ts`, `CatsController` declares a dependency on the `CatsService` token with constructor injection:

```typescript

  constructor(private catsService: CatsService)
```

```typescript

@Module({
  controllers: [CatsController],
  providers: [CatsService],
})
```

The `providers` property takes an array of `providers`. So far, we've supplied those providers via a list of class names. In fact, the syntax `providers: [CatsService]` is short-hand for the more complete syntax:

```typescript

providers: [
  {
    provide: CatsService,
    useClass: CatsService,
  },
];
```

> **Hint** If you are having problems with dependency resolution you can set the `NEST_DEBUG` environment variable and get extra dependency resolution logs during startup.

#### Value providers: `useValue`[#](/fundamentals/custom-providers#value-providers-usevalue)

The `useValue` syntax is useful for injecting a constant value, putting an external library into the Nest container, or replacing a real implementation with a mock object. Let's say you'd like to force Nest to use a mock `CatsService` for testing purposes.

```typescript

import { CatsService } from './cats.service';

const mockCatsService = {
  /* mock implementation
  ...
  */
};

@Module({
  imports: [CatsModule],
  providers: [
    {
      provide: CatsService,
      useValue: mockCatsService,
    },
  ],
})
export class AppModule {}
```

In this example, the `CatsService` token will resolve to the `mockCatsService` mock object. `useValue` requires a value - in this case a literal object that has the same interface as the `CatsService` class it is replacing. Because of TypeScript's [structural typing](https://www.typescriptlang.org/docs/handbook/type-compatibility.html), you can use any object that has a compatible interface, including a literal object or a class instance instantiated with `new`.

#### Non-class-based provider tokens[#](/fundamentals/custom-providers#non-class-based-provider-tokens)

So far, we've used class names as our provider tokens (the value of the `provide` property in a provider listed in the `providers` array). This is matched by the standard pattern used with [constructor based injection](https://docs.nestjs.com/providers#dependency-injection), where the token is also a class name. (Refer back to [DI Fundamentals](/fundamentals/custom-providers#di-fundamentals) for a refresher on tokens if this concept isn't entirely clear). Sometimes, we may want the flexibility to use strings or symbols as the DI token. For example:

```typescript

import { connection } from './connection';

@Module({
  providers: [
    {
      provide: 'CONNECTION',
      useValue: connection,
    },
  ],
})
export class AppModule {}
```

In this example, we are associating a string-valued token (`'CONNECTION'`) with a pre-existing `connection` object we've imported from an external file.

> **Notice** In addition to using strings as token values, you can also use JavaScript [symbols](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol) or TypeScript [enums](https://www.typescriptlang.org/docs/handbook/enums.html).

We've previously seen how to inject a provider using the standard [constructor based injection](https://docs.nestjs.com/providers#dependency-injection) pattern. This pattern **requires** that the dependency be declared with a class name. The `'CONNECTION'` custom provider uses a string-valued token. Let's see how to inject such a provider. To do so, we use the `@Inject()` decorator. This decorator takes a single argument - the token.

JS TS

```typescript

@Injectable()
export class CatsRepository {
  constructor(@Inject('CONNECTION') connection: Connection) {}
}
```

```typescript

@Injectable()
@Dependencies('CONNECTION')
export class CatsRepository {
  constructor(connection) {}
}
```

> **Hint** The `@Inject()` decorator is imported from `@nestjs/common` package.

While we directly use the string `'CONNECTION'` in the above examples for illustration purposes, for clean code organization, it's best practice to define tokens in a separate file, such as `constants.ts`. Treat them much as you would symbols or enums that are defined in their own file and imported where needed.

#### Class providers: `useClass`[#](/fundamentals/custom-providers#class-providers-useclass)

The `useClass` syntax allows you to dynamically determine a class that a token should resolve to. For example, suppose we have an abstract (or default) `ConfigService` class. Depending on the current environment, we want Nest to provide a different implementation of the configuration service. The following code implements such a strategy.

```typescript

const configServiceProvider = {
  provide: ConfigService,
  useClass:
    process.env.NODE_ENV === 'development'
      ? DevelopmentConfigService
      : ProductionConfigService,
};

@Module({
  providers: [configServiceProvider],
})
export class AppModule {}
```

```typescript

const connectionProvider = {
  provide: 'CONNECTION',
  useFactory: (optionsProvider: OptionsProvider, optionalProvider?: string) => {
    const options = optionsProvider.get();
    return new DatabaseConnection(options);
  },
  inject: [OptionsProvider, { token: 'SomeOptionalProvider', optional: true }],
  //       \_____________/            \__________________/
  //        This provider              The provider with this
  //        is mandatory.              token can resolve to `undefined`.
};

@Module({
  providers: [
    connectionProvider,
    OptionsProvider,
    // { provide: 'SomeOptionalProvider', useValue: 'anything' },
  ],
})
export class AppModule {}
```

```typescript

const connectionProvider = {
  provide: 'CONNECTION',
  useFactory: (optionsProvider, optionalProvider) => {
    const options = optionsProvider.get();
    return new DatabaseConnection(options);
  },
  inject: [OptionsProvider, { token: 'SomeOptionalProvider', optional: true }],
  //       \_____________/            \__________________/
  //        This provider              The provider with this
  //        is mandatory.              token can resolve to `undefined`.
};

@Module({
  providers: [
    connectionProvider,
    OptionsProvider,
    // { provide: 'SomeOptionalProvider', useValue: 'anything' },
  ],
})
export class AppModule {}
```

#### Alias providers: `useExisting`[#](/fundamentals/custom-providers#alias-providers-useexisting)

The `useExisting` syntax allows you to create aliases for existing providers. This creates two ways to access the same provider. In the example below, the (string-based) token `'AliasedLoggerService'` is an alias for the (class-based) token `LoggerService`. Assume we have two different dependencies, one for `'AliasedLoggerService'` and one for `LoggerService`. If both dependencies are specified with `SINGLETON` scope, they'll both resolve to the same instance.

```typescript

@Injectable()
class LoggerService {
  /* implementation details */
}

const loggerAliasProvider = {
  provide: 'AliasedLoggerService',
  useExisting: LoggerService,
};

@Module({
  providers: [LoggerService, loggerAliasProvider],
})
export class AppModule {}
```

#### Non-service based providers[#](/fundamentals/custom-providers#non-service-based-providers)

While providers often supply services, they are not limited to that usage. A provider can supply **any** value. For example, a provider may supply an array of configuration objects based on the current environment, as shown below:

```typescript

const configFactory = {
  provide: 'CONFIG',
  useFactory: () => {
    return process.env.NODE_ENV === 'development' ? devConfig : prodConfig;
  },
};

@Module({
  providers: [configFactory],
})
export class AppModule {}
```

#### Export custom provider[#](/fundamentals/custom-providers#export-custom-provider)

Like any provider, a custom provider is scoped to its declaring module. To make it visible to other modules, it must be exported. To export a custom provider, we can either use its token or the full provider object.

The following example shows exporting using the token:

JS TS

```typescript

const connectionFactory = {
  provide: 'CONNECTION',
  useFactory: (optionsProvider: OptionsProvider) => {
    const options = optionsProvider.get();
    return new DatabaseConnection(options);
  },
  inject: [OptionsProvider],
};

@Module({
  providers: [connectionFactory],
  exports: ['CONNECTION'],
})
export class AppModule {}
```

```typescript

const connectionFactory = {
  provide: 'CONNECTION',
  useFactory: (optionsProvider) => {
    const options = optionsProvider.get();
    return new DatabaseConnection(options);
  },
  inject: [OptionsProvider],
};

@Module({
  providers: [connectionFactory],
  exports: ['CONNECTION'],
})
export class AppModule {}
```

Alternatively, export with the full provider object:

JS TS

```typescript

const connectionFactory = {
  provide: 'CONNECTION',
  useFactory: (optionsProvider: OptionsProvider) => {
    const options = optionsProvider.get();
    return new DatabaseConnection(options);
  },
  inject: [OptionsProvider],
};

@Module({
  providers: [connectionFactory],
  exports: [connectionFactory],
})
export class AppModule {}
```

```typescript

const connectionFactory = {
  provide: 'CONNECTION',
  useFactory: (optionsProvider) => {
    const options = optionsProvider.get();
    return new DatabaseConnection(options);
  },
  inject: [OptionsProvider],
};

@Module({
  providers: [connectionFactory],
  exports: [connectionFactory],
})
export class AppModule {}
```

----
url: https://docs.nestjs.com/v9/fundamentals/execution-context
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Execution context](https://docs.nestjs.com/v9/fundamentals/execution-context#execution-context)
* [ArgumentsHost class](https://docs.nestjs.com/v9/fundamentals/execution-context#argumentshost-class)
* [Current application context](https://docs.nestjs.com/v9/fundamentals/execution-context#current-application-context)
* [Host handler arguments](https://docs.nestjs.com/v9/fundamentals/execution-context#host-handler-arguments)
* [ExecutionContext class](https://docs.nestjs.com/v9/fundamentals/execution-context#executioncontext-class)
* [Reflection and metadata](https://docs.nestjs.com/v9/fundamentals/execution-context#reflection-and-metadata)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/fundamentals/execution-context.md "Suggest Edits")

### Execution context

Nest provides several utility classes that help make it easy to write applications that function across multiple application contexts (e.g., Nest HTTP server-based, microservices and WebSockets application contexts). These utilities provide information about the current execution context which can be used to build generic [guards](/v9/guards), [filters](/v9/exception-filters), and [interceptors](/v9/interceptors) that can work across a broad set of controllers, methods, and execution contexts.

We cover two such classes in this chapter: `ArgumentsHost` and `ExecutionContext`.

#### ArgumentsHost class[#](/fundamentals/execution-context#argumentshost-class)

The `ArgumentsHost` class provides methods for retrieving the arguments being passed to a handler. It allows choosing the appropriate context (e.g., HTTP, RPC (microservice), or WebSockets) to retrieve the arguments from. The framework provides an instance of `ArgumentsHost`, typically referenced as a `host` parameter, in places where you may want to access it. For example, the `catch()` method of an [exception filter](https://docs.nestjs.com/exception-filters#arguments-host) is called with an `ArgumentsHost`instance.

`ArgumentsHost` simply acts as an abstraction over a handler's arguments. For example, for HTTP server applications (when `@nestjs/platform-express` is being used), the `host` object encapsulates Express's `[request, response, next]` array, where `request` is the request object, `response` is the response object, and `next` is a function that controls the application's request-response cycle. On the other hand, for [GraphQL](/v9/graphql/quick-start) applications, the `host` object contains the `[root, args, context, info]` array.

#### Current application context[#](/fundamentals/execution-context#current-application-context)

When building generic [guards](/v9/guards), [filters](/v9/exception-filters), and [interceptors](/v9/interceptors) which are meant to run across multiple application contexts, we need a way to determine the type of application that our method is currently running in. Do this with the `getType()` method of `ArgumentsHost`:

```typescript

if (host.getType() === 'http') {
  // do something that is only important in the context of regular HTTP requests (REST)
} else if (host.getType() === 'rpc') {
  // do something that is only important in the context of Microservice requests
} else if (host.getType<GqlContextType>() === 'graphql') {
  // do something that is only important in the context of GraphQL requests
}
```

> **Hint** The `GqlContextType` is imported from the `@nestjs/graphql` package.

With the application type available, we can write more generic components, as shown below.

#### Host handler arguments[#](/fundamentals/execution-context#host-handler-arguments)

To retrieve the array of arguments being passed to the handler, one approach is to use the host object's `getArgs()` method.

```typescript

const [req, res, next] = host.getArgs();
```

You can pluck a particular argument by index using the `getArgByIndex()` method:

```typescript

const request = host.getArgByIndex(0);
const response = host.getArgByIndex(1);
```

In these examples we retrieved the request and response objects by index, which is not typically recommended as it couples the application to a particular execution context. Instead, you can make your code more robust and reusable by using one of the `host` object's utility methods to switch to the appropriate application context for your application. The context switch utility methods are shown below.

```typescript

/**
 * Switch context to RPC.
 */
switchToRpc(): RpcArgumentsHost;
/**
 * Switch context to HTTP.
 */
switchToHttp(): HttpArgumentsHost;
/**
 * Switch context to WebSockets.
 */
switchToWs(): WsArgumentsHost;
```

Let's rewrite the previous example using the `switchToHttp()` method. The `host.switchToHttp()` helper call returns an `HttpArgumentsHost` object that is appropriate for the HTTP application context. The `HttpArgumentsHost` object has two useful methods we can use to extract the desired objects. We also use the Express type assertions in this case to return native Express typed objects:

```typescript

const ctx = host.switchToHttp();
const request = ctx.getRequest<Request>();
const response = ctx.getResponse<Response>();
```

Similarly `WsArgumentsHost` and `RpcArgumentsHost` have methods to return appropriate objects in the microservices and WebSockets contexts. Here are the methods for `WsArgumentsHost`:

```typescript

export interface WsArgumentsHost {
  /**
   * Returns the data object.
   */
  getData<T>(): T;
  /**
   * Returns the client object.
   */
  getClient<T>(): T;
}
```

Following are the methods for `RpcArgumentsHost`:

```typescript

export interface RpcArgumentsHost {
  /**
   * Returns the data object.
   */
  getData<T>(): T;

  /**
   * Returns the context object.
   */
  getContext<T>(): T;
}
```

#### ExecutionContext class[#](/fundamentals/execution-context#executioncontext-class)

`ExecutionContext` extends `ArgumentsHost`, providing additional details about the current execution process. Like `ArgumentsHost`, Nest provides an instance of `ExecutionContext` in places you may need it, such as in the `canActivate()` method of a [guard](https://docs.nestjs.com/guards#execution-context) and the `intercept()` method of an [interceptor](https://docs.nestjs.com/interceptors#execution-context). It provides the following methods:

```typescript

export interface ExecutionContext extends ArgumentsHost {
  /**
   * Returns the type of the controller class which the current handler belongs to.
   */
  getClass<T>(): Type<T>;
  /**
   * Returns a reference to the handler (method) that will be invoked next in the
   * request pipeline.
   */
  getHandler(): Function;
}
```

The `getHandler()` method returns a reference to the handler about to be invoked. The `getClass()` method returns the type of the `Controller` class which this particular handler belongs to. For example, in an HTTP context, if the currently processed request is a `POST` request, bound to the `create()` method on the `CatsController`, `getHandler()` returns a reference to the `create()` method and `getClass()` returns the `CatsController`**type** (not instance).

```typescript

const methodKey = ctx.getHandler().name; // "create"
const className = ctx.getClass().name; // "CatsController"
```

```typescript

@Post()
@SetMetadata('roles', ['admin'])
async create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

```typescript

@Post()
@SetMetadata('roles', ['admin'])
@Bind(Body())
async create(createCatDto) {
  this.catsService.create(createCatDto);
}
```

> **Hint** The `@SetMetadata()` decorator is imported from the `@nestjs/common` package.

With the construction above, we attached the `roles` metadata (`roles` is a metadata key and `['admin']` is the associated value) to the `create()` method. While this works, it's not good practice to use `@SetMetadata()` directly in your routes. Instead, create your own decorators, as shown below:

roles.decorator.ts

JS TS

```typescript

import { SetMetadata } from '@nestjs/common';

export const Roles = (...roles: string[]) => SetMetadata('roles', roles);
```

```typescript

import { SetMetadata } from '@nestjs/common';

export const Roles = (...roles) => SetMetadata('roles', roles);
```

This approach is much cleaner and more readable, and is strongly typed. Now that we have a custom `@Roles()` decorator, we can use it to decorate the `create()` method.

cats.controller.ts

JS TS

```typescript

@Post()
@Roles('admin')
async create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

```typescript

@Post()
@Roles('admin')
@Bind(Body())
async create(createCatDto) {
  this.catsService.create(createCatDto);
}
```

To access the route's role(s) (custom metadata), we'll use the `Reflector` helper class, which is provided out of the box by the framework and exposed from the `@nestjs/core` package. `Reflector` can be injected into a class in the normal way:

roles.guard.ts

JS TS

```typescript

@Injectable()
export class RolesGuard {
  constructor(private reflector: Reflector) {}
}
```

```typescript

@Injectable()
@Dependencies(Reflector)
export class CatsService {
  constructor(reflector) {
    this.reflector = reflector;
  }
}
```

> **Hint** The `Reflector` class is imported from the `@nestjs/core` package.

Now, to read the handler metadata, use the `get()` method.

```typescript

const roles = this.reflector.get<string[]>('roles', context.getHandler());
```

The `Reflector#get` method allows us to easily access the metadata by passing in two arguments: a metadata **key** and a **context** (decorator target) to retrieve the metadata from. In this example, the specified **key** is `'roles'` (refer back to the `roles.decorator.ts` file above and the `SetMetadata()` call made there). The context is provided by the call to `context.getHandler()`, which results in extracting the metadata for the currently processed route handler. Remember, `getHandler()` gives us a **reference** to the route handler function.

Alternatively, we may organize our controller by applying metadata at the controller level, applying to all routes in the controller class.

cats.controller.ts

JS TS

```typescript

@Roles('admin')
@Controller('cats')
export class CatsController {}
```

```typescript

@Roles('admin')
@Controller('cats')
export class CatsController {}
```

In this case, to extract controller metadata, we pass `context.getClass()` as the second argument (to provide the controller class as the context for metadata extraction) instead of `context.getHandler()`:

roles.guard.ts

JS TS

```typescript

const roles = this.reflector.get<string[]>('roles', context.getClass());
```

```typescript

const roles = this.reflector.get('roles', context.getClass());
```

Given the ability to provide metadata at multiple levels, you may need to extract and merge metadata from several contexts. The `Reflector` class provides two utility methods used to help with this. These methods extract **both** controller and method metadata at once, and combine them in different ways.

Consider the following scenario, where you've supplied `'roles'` metadata at both levels.

cats.controller.ts

JS TS

```typescript

@Roles('user')
@Controller('cats')
export class CatsController {
  @Post()
  @Roles('admin')
  async create(@Body() createCatDto: CreateCatDto) {
    this.catsService.create(createCatDto);
  }
}
```

```typescript

@Roles('user')
@Controller('cats')
export class CatsController {}
  @Post()
  @Roles('admin')
  @Bind(Body())
  async create(createCatDto) {
    this.catsService.create(createCatDto);
  }
}
```

If your intent is to specify `'user'` as the default role, and override it selectively for certain methods, you would probably use the `getAllAndOverride()` method.

```typescript

const roles = this.reflector.getAllAndOverride<string[]>('roles', [
  context.getHandler(),
  context.getClass(),
]);
```

A guard with this code, running in the context of the `create()` method, with the above metadata, would result in `roles` containing `['admin']`.

To get metadata for both and merge it (this method merges both arrays and objects), use the `getAllAndMerge()` method:

```typescript

const roles = this.reflector.getAllAndMerge<string[]>('roles', [
  context.getHandler(),
  context.getClass(),
]);
```

This would result in `roles` containing `['user', 'admin']`.

For both of these merge methods, you pass the metadata key as the first argument, and an array of metadata target contexts (i.e., calls to the `getHandler()` and/or `getClass())` methods) as the second argument.

----
url: https://docs.nestjs.com/v4/websockets/adapter
----

### Adapter

The Nest websockets module is based on [socket.io](https://github.com/socketio/socket.io), but you can bring your own library, by making use of `WebSocketAdapter` interface. This interface forces to implement few methods described in the following table:

|                       |                                                                |
| --------------------- | -------------------------------------------------------------- |
| `create`              | Attaches the socket instance to the specified port             |
| `bindClientConnect`   | Binds the client connection                                    |
| `bindMessageHandlers` | Binds the incoming message to the appropriate message handlers |

Also, there're 2 optional methods:

|                        |                                                                                                   |
| ---------------------- | ------------------------------------------------------------------------------------------------- |
| `createWithNamespace`  | Attaches the socket instance to the specified port and namespace (if your library supports rooms) |
| `bindClientDisconnect` | Binds the client disconnection event                                                              |

For demonstration purposes, we're going to integrate [ws](https://github.com/websockets/ws) library with the Nest application.

ws-adapter.ts

JavaScript TypeScript

TypeScript

```typescript

import * as WebSocket from 'ws';
import { WebSocketAdapter } from '@nestjs/common';
import { MessageMappingProperties } from '@nestjs/websockets';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/fromEvent';
import 'rxjs/add/observable/empty';
import 'rxjs/add/operator/switchMap';
import 'rxjs/add/operator/filter';

export class WsAdapter implements WebSocketAdapter {
  create(port: number) {
    return new WebSocket.Server({ port });
  }

  bindClientConnect(server, callback: (...args: any[]) => void) {
    server.on('connection', callback);
  }

  bindMessageHandlers(client: WebSocket, handlers: MessageMappingProperties[], process: (data) => Observable<any>) {
    Observable.fromEvent(client, 'message')
      .switchMap((buffer) => this.bindMessageHandler(buffer, handlers, process))
      .filter((result) => !!result)
      .subscribe((response) => client.send(JSON.stringify(response)));
  }

  bindMessageHandler(buffer, handlers: MessageMappingProperties[], process: (data) => Observable<any>): Observable<any> {
    const data = JSON.parse(buffer.data);
    const messageHandler = handlers.find((handler) => handler.message === data.type);
    if (!messageHandler) {
      return Observable.empty();
    }
    const { callback } = messageHandler;
    return process(callback(data));
  }
}
```

TypeScript

```typescript

import * as WebSocket from 'ws';
import { MessageMappingProperties } from '@nestjs/websockets';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/fromEvent';
import 'rxjs/add/observable/empty';
import 'rxjs/add/operator/switchMap';
import 'rxjs/add/operator/filter';

export class WsAdapter {
  create(port) {
    return new WebSocket.Server({ port });
  }

  bindClientConnect(server, callback) {
    server.on('connection', callback);
  }

  bindMessageHandlers(client, handlers, process) {
    Observable.fromEvent(client, 'message')
      .switchMap((buffer) => this.bindMessageHandler(buffer, handlers, process))
      .filter((result) => !!result)
      .subscribe((response) => client.send(JSON.stringify(response)));
  }

  bindMessageHandler(buffer, handlers, process) {
    const data = JSON.parse(buffer.data);
    const messageHandler = handlers.find((handler) => handler.message === data.type);
    if (!messageHandler) {
      return Observable.empty();
    }
    const { callback } = messageHandler;
    return process(callback(data));
  }
}
```

Since `WsAdapter` class is ready to use, we can setup the adapter using `useWebSocketAdapter()` method:

main.ts

JavaScript TypeScript

TypeScript

```typescript

const app = await NestFactory.create(ApplicationModule);
app.useWebSocketAdapter(new WsAdapter());
```

Now Nest will make use of our `WsAdapter` instead of the default one.

#### Sponsors

[](https://valor-software.com/)

Nest is an MIT-licensed open source project. It can grow thanks to the support by these awesome people. If you'd like to join them, please read more [here](https://opencollective.com/nest). Thanks!

[](https://opencollective.com/nest/backer/0/website)[](https://opencollective.com/nest/backer/1/website)[](https://opencollective.com/nest/backer/2/website)[](https://opencollective.com/nest/backer/3/website)[](https://opencollective.com/nest/backer/4/website)[](https://opencollective.com/nest/backer/5/website)[](https://opencollective.com/nest/backer/6/website)[](https://opencollective.com/nest/backer/7/website)[](https://opencollective.com/nest/backer/8/website)[](https://opencollective.com/nest/backer/9/website)[](https://opencollective.com/nest/backer/10/website)[](https://opencollective.com/nest/backer/11/website)[](https://opencollective.com/nest/backer/12/website)[](https://opencollective.com/nest/backer/13/website)[](https://opencollective.com/nest/backer/14/website)[](https://opencollective.com/nest/backer/15/website)[](https://opencollective.com/nest/backer/16/website)[](https://opencollective.com/nest/backer/17/website)[](https://opencollective.com/nest/backer/18/website)[](https://opencollective.com/nest/backer/19/website)[](https://opencollective.com/nest/backer/20/website)[](https://opencollective.com/nest/backer/21/website)[](https://opencollective.com/nest/backer/22/website)[](https://opencollective.com/nest/backer/23/website)[](https://opencollective.com/nest/backer/24/website)[](https://opencollective.com/nest/backer/25/website)[](https://opencollective.com/nest/backer/26/website)[](https://opencollective.com/nest/backer/27/website)[](https://opencollective.com/nest/backer/28/website)[](https://opencollective.com/nest/backer/29/website)

[Become a sponsor](https://opencollective.com/nest)

----
url: https://docs.nestjs.com/v9/support
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Support](https://docs.nestjs.com/v9/support#support)
* [How can you help?](https://docs.nestjs.com/v9/support#how-can-you-help)

----
url: https://docs.nestjs.com/v9/faq/request-lifecycle
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Request lifecycle](https://docs.nestjs.com/v9/faq/request-lifecycle#request-lifecycle)
* [Middleware](https://docs.nestjs.com/v9/faq/request-lifecycle#middleware)
* [Guards](https://docs.nestjs.com/v9/faq/request-lifecycle#guards)
* [Interceptors](https://docs.nestjs.com/v9/faq/request-lifecycle#interceptors)
* [Pipes](https://docs.nestjs.com/v9/faq/request-lifecycle#pipes)
* [Filters](https://docs.nestjs.com/v9/faq/request-lifecycle#filters)
* [Summary](https://docs.nestjs.com/v9/faq/request-lifecycle#summary)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/faq/request-lifecycle.md "Suggest Edits")

### Request lifecycle

Nest applications handle requests and produce responses in a sequence we refer to as the **request lifecycle**. With the use of middleware, pipes, guards, and interceptors, it can be challenging to track down where a particular piece of code executes during the request lifecycle, especially as global, controller level, and route level components come into play. In general, a request flows through middleware to guards, then to interceptors, then to pipes and finally back to interceptors on the return path (as the response is generated).

#### Middleware[#](/faq/request-lifecycle#middleware)

Middleware is executed in a particular sequence. First, Nest runs globally bound middleware (such as middleware bound with `app.use`) and then it runs [module bound middleware](/v9/middleware), which are determined on paths. Middleware are run sequentially in the order they are bound, similar to the way middleware in Express works. In the case of middleware bound across different modules, the middleware bound to the root module will run first, and then middleware will run in the order that the modules are added to the imports array.

#### Guards[#](/faq/request-lifecycle#guards)

Guard execution starts with global guards, then proceeds to controller guards, and finally to route guards. As with middleware, guards run in the order in which they are bound. For example:

```typescript

@UseGuards(Guard1, Guard2)
@Controller('cats')
export class CatsController {
  constructor(private catsService: CatsService) {}

  @UseGuards(Guard3)
  @Get()
  getCats(): Cats[] {
    return this.catsService.getCats();
  }
}
```

`Guard1` will execute before `Guard2` and both will execute before `Guard3`.

> **Hint** When speaking about globally bound vs controller or locally bound, the difference is where the guard (or other component is bound). If you are using `app.useGlobalGuard()` or providing the component via a module, it is globally bound. Otherwise, it is bound to a controller if the decorator precedes a controller class, or to a route if the decorator proceeds a route declaration.

#### Interceptors[#](/faq/request-lifecycle#interceptors)

Interceptors, for the most part, follow the same pattern as guards, with one catch: as interceptors return [RxJS Observables](https://github.com/ReactiveX/rxjs), the observables will be resolved in a first in last out manner. So inbound requests will go through the standard global, controller, route level resolution, but the response side of the request (i.e., after returning from the controller method handler) will be resolved from route to controller to global. Also, any errors thrown by pipes, controllers, or services can be read in the `catchError` operator of an interceptor.

#### Pipes[#](/faq/request-lifecycle#pipes)

Pipes follow the standard global to controller to route bound sequence, with the same first in first out in regards to the `@UsePipes()` parameters. However, at a route parameter level, if you have multiple pipes running, they will run in the order of the last parameter with a pipe to the first. This also applies to the route level and controller level pipes. For example, if we have the following controller:

```typescript

@UsePipes(GeneralValidationPipe)
@Controller('cats')
export class CatsController {
  constructor(private catsService: CatsService) {}

  @UsePipes(RouteSpecificPipe)
  @Patch(':id')
  updateCat(
    @Body() body: UpdateCatDTO,
    @Param() params: UpdateCatParams,
    @Query() query: UpdateCatQuery,
  ) {
    return this.catsService.updateCat(body, params, query);
  }
}
```

then the `GeneralValidationPipe` will run for the `query`, then the `params`, and then the `body` objects before moving on to the `RouteSpecificPipe`, which follows the same order. If any parameter-specific pipes were in place, they would run (again, from the last to first parameter) after the controller and route level pipes.

#### Filters[#](/faq/request-lifecycle#filters)

Filters are the only component that do not resolve global first. Instead, filters resolve from the lowest level possible, meaning execution starts with any route bound filters and proceeding next to controller level, and finally to global filters. Note that exceptions cannot be passed from filter to filter; if a route level filter catches the exception, a controller or global level filter cannot catch the same exception. The only way to achieve an effect like this is to use inheritance between the filters.

> **Hint** Filters are only executed if any uncaught exception occurs during the request process. Caught exceptions, such as those caught with a `try/catch` will not trigger Exception Filters to fire. As soon as an uncaught exception is encountered, the rest of the lifecycle is ignored and the request skips straight to the filter.

Nest is an MIT-licensed open source project. It can grow thanks to the support by these awesome people. If you'd like to join them, please read more [here](/v9/support).

#### Principal Sponsors

[](https://trilon.io/)[](https://www.redhat.com/)[](https://valor-software.com/)[](https://github.com/Sanofi-IADC)[](https://nx.dev/)[](https://amplication.com/)

#### Sponsors / Partners

[Become a sponsor](https://opencollective.com/nest)

**

### Join our Newsletter

Subscribe to stay up to date with the latest Nest updates, features, and videos!

----
url: https://docs.nestjs.com/v8/faq/global-prefix
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Global prefix](https://docs.nestjs.com/v8/faq/global-prefix#global-prefix)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/faq/global-prefix.md "Suggest Edits")

### Global prefix

To set a prefix for **every route** registered in an HTTP application, use the `setGlobalPrefix()` method of the `INestApplication` instance.

```typescript

const app = await NestFactory.create(AppModule);
app.setGlobalPrefix('v1');
```

You can exclude routes from the global prefix using the following construction:

```typescript

app.setGlobalPrefix('v1', {
  exclude: [{ path: 'health', method: RequestMethod.GET }],
});
```

Alternatively, you can specify route as a string (it will apply to every request method):

```typescript

app.setGlobalPrefix('v1', { exclude: ['cats'] });
```

----
url: https://docs.nestjs.com/v7/microservices/interceptors
----

* [Interceptors](https://docs.nestjs.com/v7/microservices/interceptors#interceptors)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/microservices/interceptors.md "Suggest Edits")

### Interceptors

There is no difference between [regular interceptors](/v7/interceptors) and microservices interceptors. The following example uses a manually instantiated method-scoped interceptor. Just as with HTTP based applications, you can also use controller-scoped interceptors (i.e., prefix the controller class with a `@UseInterceptors()` decorator).

JS TS

```typescript

@UseInterceptors(new TransformInterceptor())
@MessagePattern({ cmd: 'sum' })
accumulate(data: number[]): number {
  return (data || []).reduce((a, b) => a + b);
}
```

```typescript

@UseInterceptors(new TransformInterceptor())
@MessagePattern({ cmd: 'sum' })
accumulate(data) {
  return (data || []).reduce((a, b) => a + b);
}
```

----
url: https://docs.nestjs.com/v9/fundamentals/lazy-loading-modules
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Lazy-loading modules](https://docs.nestjs.com/v9/fundamentals/lazy-loading-modules#lazy-loading-modules)
* [Getting started](https://docs.nestjs.com/v9/fundamentals/lazy-loading-modules#getting-started)
* [Lazy-loading controllers, gateways, and resolvers](https://docs.nestjs.com/v9/fundamentals/lazy-loading-modules#lazy-loading-controllers-gateways-and-resolvers)
* [Common use-cases](https://docs.nestjs.com/v9/fundamentals/lazy-loading-modules#common-use-cases)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/fundamentals/lazy-loading-modules.md "Suggest Edits")

### Lazy-loading modules

By default, modules are eagerly loaded, which means that as soon as the application loads, so do all the modules, whether or not they are immediately necessary. While this is fine for most applications, it may become a bottleneck for apps/workers running in the **serverless environment**, where the startup latency ("cold start") is crucial.

Lazy loading can help decrease bootstrap time by loading only modules required by the specific serverless function invocation. In addition, you could also load other modules asynchronously once the serverless function is "warm" to speed-up the bootstrap time for subsequent calls even further (deferred modules registration).

> **Hint** If you're familiar with the **Angular** framework, you might have seen the "lazy-loading modules" term before. Be aware that this technique is **functionally different** in Nest and so think about this as an entirely different feature that shares similar naming conventions.

> **Warning** Do note that [lifecycle hooks methods](https://docs.nestjs.com/fundamentals/lifecycle-events) are not invoked in lazy loaded modules and services.

#### Getting started[#](/fundamentals/lazy-loading-modules#getting-started)

To load modules on-demand, Nest provides the `LazyModuleLoader` class that can be injected into a class in the normal way:

cats.service.ts

JS TS

```typescript

@Injectable()
export class CatsService {
  constructor(private lazyModuleLoader: LazyModuleLoader) {}
}
```

```typescript

@Injectable()
@Dependencies(LazyModuleLoader)
export class CatsService {
  constructor(lazyModuleLoader) {
    this.lazyModuleLoader = lazyModuleLoader;
  }
}
```

> **Hint** The `LazyModuleLoader` class is imported from the `@nestjs/core` package.

Alternatively, you can obtain a reference to the `LazyModuleLoader` provider from within your application bootstrap file (`main.ts`), as follows:

```typescript

// "app" represents a Nest application instance
const lazyModuleLoader = app.get(LazyModuleLoader);
```

With this in place, you can now load any module using the following construction:

```typescript

const { LazyModule } = await import('./lazy.module');
const moduleRef = await this.lazyModuleLoader.load(() => LazyModule);
```

> **Hint** "Lazy-loaded" modules are **cached** upon the first `LazyModuleLoader#load` method invocation. That means, each consecutive attempt to load `LazyModule` will be **very fast** and will return a cached instance, instead of loading the module again.
>
> ```bash
>
> Load "LazyModule" attempt: 1
> time: 2.379ms
> Load "LazyModule" attempt: 2
> time: 0.294ms
> Load "LazyModule" attempt: 3
> time: 0.303ms
> ```
>
> Also, "lazy-loaded" modules share the same modules graph as those eagerly loaded on the application bootstrap as well as any other lazy modules registered later in your app.

Where `lazy.module.ts` is a TypeScript file that exports a **regular Nest module** (no extra changes are required).

The `LazyModuleLoader#load` method returns the [module reference](/v9/fundamentals/module-ref) (of `LazyModule`) that lets you navigate the internal list of providers and obtain a reference to any provider using its injection token as a lookup key.

For example, let's say we have a `LazyModule` with the following definition:

```typescript

@Module({
  providers: [LazyService],
  exports: [LazyService],
})
export class LazyModule {}
```

> **Hint** Lazy-loaded modules cannot be registered as **global modules** as it simply makes no sense (since they are registered lazily, on-demand when all the statically registered modules have been already instantiated). Likewise, registered **global enhancers** (guards/interceptors/etc.) **will not work** properly either.

With this, we could obtain a reference to the `LazyService` provider, as follows:

```typescript

const { LazyModule } = await import('./lazy.module');
const moduleRef = await this.lazyModuleLoader.load(() => LazyModule);

const { LazyService } = await import('./lazy.service');
const lazyService = moduleRef.get(LazyService);
```

> **Warning** If you use **Webpack**, make sure to update your `tsconfig.json` file - setting `compilerOptions.module` to `"esnext"` and adding `compilerOptions.moduleResolution` property with `"node"` as a value:
>
> ```json
>
> {
>   "compilerOptions": {
>     "module": "esnext",
>     "moduleResolution": "node",
>     ...
>   }
> }
> ```
>
> With these options set up, you'll be able to leverage the [code splitting](https://webpack.js.org/guides/code-splitting/) feature.

#### Lazy-loading controllers, gateways, and resolvers[#](/fundamentals/lazy-loading-modules#lazy-loading-controllers-gateways-and-resolvers)

Since controllers (or resolvers in GraphQL applications) in Nest represent sets of routes/paths/topics (or queries/mutations), you **cannot lazy load them** using the `LazyModuleLoader` class.

> **Warning** Controllers, [resolvers](/v9/graphql/resolvers), and [gateways](/v9/websockets/gateways) registered inside lazy-loaded modules will not behave as expected. Similarly, you cannot register middleware functions (by implementing the `MiddlewareConsumer` interface) on-demand.

For example, let's say you're building a REST API (HTTP application) with a Fastify driver under the hood (using the `@nestjs/platform-fastify` package). Fastify does not let you register routes after the application is ready/successfully listening to messages. That means even if we analyzed route mappings registered in the module's controllers, all lazy-loaded routes wouldn't be accessible since there is no way to register them at runtime.

Likewise, some transport strategies we provide as part of the `@nestjs/microservices` package (including Kafka, gRPC, or RabbitMQ) require to subscribe/listen to specific topics/channels before the connection is established. Once your application starts listening to messages, the framework would not be able to subscribe/listen to new topics.

Lastly, the `@nestjs/graphql` package with the code first approach enabled automatically generates the GraphQL schema on-the-fly based on the metadata. That means, it requires all classes to be loaded beforehand. Otherwise, it would not be doable to create the appropriate, valid schema.

#### Common use-cases[#](/fundamentals/lazy-loading-modules#common-use-cases)

Most commonly, you will see lazy loaded modules in situations when your worker/cron job/lambda & serverless function/webhook must trigger different services (different logic) based on the input arguments (route path/date/query parameters, etc.). On the other hand, lazy-loading modules may not make too much sense for monolithic applications, where the startup time is rather irrelevant.

----
url: https://docs.nestjs.com/v7/graphql/other-features
----

* [Other features](https://docs.nestjs.com/v7/graphql/other-features#other-features)
* [Overview](https://docs.nestjs.com/v7/graphql/other-features#overview)
* [Execution context](https://docs.nestjs.com/v7/graphql/other-features#execution-context)
* [Exception filters](https://docs.nestjs.com/v7/graphql/other-features#exception-filters)
* [Custom decorators](https://docs.nestjs.com/v7/graphql/other-features#custom-decorators)
* [Execute enhancers at the field resolver level](https://docs.nestjs.com/v7/graphql/other-features#execute-enhancers-at-the-field-resolver-level)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/guards-interceptors.md "Suggest Edits")

### Other features

In the GraphQL world, there is a lot of debate about handling issues like **authentication**, or **side-effects** of operations. Should we handle things inside the business logic? Should we use a higher-order function to enhance queries and mutations with authorization logic? Or should we use [schema directives](https://www.apollographql.com/docs/apollo-server/schema/directives/)? There is no single one-size-fits-all answer to these questions.

Nest helps address these issues with its cross-platform features like [guards](/v7/guards) and [interceptors](/v7/interceptors). The philosophy is to reduce redundancy and provide tooling that helps create well-structured, readable, and consistent applications.

#### Overview[#](/graphql/other-features#overview)

You can use standard [guards](/v7/guards), [interceptors](/v7/interceptors), [filters](/v7/exception-filters) and [pipes](/v7/pipes) in the same fashion with GraphQL as with any RESTful application. Additionally, you can easily create your own decorators by leveraging the [custom decorators](/v7/custom-decorators) feature. Let's take a look at a sample GraphQL query handler.

```typescript

@Query('author')
@UseGuards(AuthGuard)
async getAuthor(@Args('id', ParseIntPipe) id: number) {
  return this.authorsService.findOneById(id);
}
```

As you can see, GraphQL works with both guards and pipes in the same way as HTTP REST handlers. Because of this, you can move your authentication logic to a guard; you can even reuse the same guard class across both a REST and GraphQL API interface. Similarly, interceptors work across both types of applications in the same way:

```typescript

@Mutation()
@UseInterceptors(EventsInterceptor)
async upvotePost(@Args('postId') postId: number) {
  return this.postsService.upvoteById({ id: postId });
}
```

#### Execution context[#](/graphql/other-features#execution-context)

Since GraphQL receives a different type of data in the incoming request, the [execution context](https://docs.nestjs.com/fundamentals/execution-context) received by both guards and interceptors is somewhat different with GraphQL vs. REST. GraphQL resolvers have a distinct set of arguments: `root`, `args`, `context`, and `info`. Thus guards and interceptors must transform the generic `ExecutionContext` to a `GqlExecutionContext`. This is straightforward:

```typescript

import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common';
import { GqlExecutionContext } from '@nestjs/graphql';

@Injectable()
export class AuthGuard implements CanActivate {
  canActivate(context: ExecutionContext): boolean {
    const ctx = GqlExecutionContext.create(context);
    return true;
  }
}
```

The GraphQL context object returned by `GqlExecutionContext.create()` exposes a **get** method for each GraphQL resolver argument (e.g., `getArgs()`, `getContext()`, etc). Once transformed, we can easily pick out any GraphQL argument for the current request.

#### Exception filters[#](/graphql/other-features#exception-filters)

Nest standard [exception filters](/v7/exception-filters) are compatible with GraphQL applications as well. As with `ExecutionContext`, GraphQL apps should transform the `ArgumentsHost` object to a `GqlArgumentsHost` object.

```typescript

@Catch(HttpException)
export class HttpExceptionFilter implements GqlExceptionFilter {
  catch(exception: HttpException, host: ArgumentsHost) {
    const gqlHost = GqlArgumentsHost.create(host);
    return exception;
  }
}
```

> **Hint** Both `GqlExceptionFilter` and `GqlArgumentsHost` are imported from the `@nestjs/graphql` package.

Note that unlike the REST case, you don't use the native `response` object to generate a response.

#### Custom decorators[#](/graphql/other-features#custom-decorators)

As mentioned, the [custom decorators](/v7/custom-decorators) feature works as expected with GraphQL resolvers.

```typescript

export const User = createParamDecorator(
  (data: unknown, ctx: ExecutionContext) =>
    GqlExecutionContext.create(ctx).getContext().user,
);
```

Use the `@User()` custom decorator as follows:

```typescript

@Mutation()
async upvotePost(
  @User() user: UserEntity,
  @Args('postId') postId: number,
) {}
```

> **Hint** In the above example, we have assumed that the `user` object is assigned to the context of your GraphQL application.

#### Execute enhancers at the field resolver level[#](/graphql/other-features#execute-enhancers-at-the-field-resolver-level)

In the GraphQL context, Nest does not run **enhancers** (the generic name for interceptors, guards and filters) at the field level [see this issue](https://github.com/nestjs/graphql/issues/320#issuecomment-511193229): they only run for the top level `@Query()`/`@Mutation()` method. You can tell Nest to execute interceptors, guards or filters for methods annotated with `@ResolveField()` by setting the `fieldResolverEnhancers` option in `GqlModuleOptions`. Pass it a list of `'interceptors'`, `'guards'`, and/or `'filters'` as appropriate:

```typescript

GraphQLModule.forRoot({
  fieldResolverEnhancers: ['interceptors']
}),
```

> **Warning** Enabling enhancers for field resolvers can cause performance issues when you are returning lots of records and your field resolver is executed thousands of times. For this reason, when you enable `fieldResolverEnhancers`, we advise you to skip execution of enhancers that are not strictly necessary for your field resolvers. You can do this using the following helper function:

```typescript

export function isResolvingGraphQLField(context: ExecutionContext): boolean {
  if (context.getType<GqlContextType>() === 'graphql') {
    const gqlContext = GqlExecutionContext.create(context);
    const info = gqlContext.getInfo();
    const parentType = info.parentType.name;
    return parentType !== 'Query' && parentType !== 'Mutation';
  }
  return false;
}
```

----
url: https://docs.nestjs.com/v11/websockets/guards
----

* [Guards](https://docs.nestjs.com/v11/websockets/guards#guards)
* [Binding guards](https://docs.nestjs.com/v11/websockets/guards#binding-guards)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/websockets/guards.md "Suggest Edits")

### Guards

There is no fundamental difference between web sockets guards and [regular HTTP application guards](/v11/guards). The only difference is that instead of throwing `HttpException`, you should use `WsException`.

> **Hint** The `WsException` class is exposed from `@nestjs/websockets` package.

#### Binding guards[#](/websockets/guards#binding-guards)

The following example uses a method-scoped guard. Just as with HTTP based applications, you can also use gateway-scoped guards (i.e., prefix the gateway class with a `@UseGuards()` decorator).

JS TS

```typescript

@UseGuards(AuthGuard)
@SubscribeMessage('events')
handleEvent(client: Client, data: unknown): WsResponse<unknown> {
  const event = 'events';
  return { event, data };
}
```

```typescript

@UseGuards(AuthGuard)
@SubscribeMessage('events')
handleEvent(client, data) {
  const event = 'events';
  return { event, data };
}
```

----
url: https://docs.nestjs.com/v11/websockets/exception-filters
----

* [Exception filters](https://docs.nestjs.com/v11/websockets/exception-filters#exception-filters)
* [Filters](https://docs.nestjs.com/v11/websockets/exception-filters#filters)
* [Inheritance](https://docs.nestjs.com/v11/websockets/exception-filters#inheritance)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/websockets/exception-filters.md "Suggest Edits")

### Exception filters

The only difference between the HTTP [exception filter](/v11/exception-filters) layer and the corresponding web sockets layer is that instead of throwing `HttpException`, you should use `WsException`.

```typescript

throw new WsException('Invalid credentials.');
```

> **Hint** The `WsException` class is imported from the `@nestjs/websockets` package.

With the sample above, Nest will handle the thrown exception and emit the `exception` message with the following structure:

```typescript

{
  status: 'error',
  message: 'Invalid credentials.'
}
```

#### Filters[#](/websockets/exception-filters#filters)

Web sockets exception filters behave equivalently to HTTP exception filters. The following example uses a manually instantiated method-scoped filter. Just as with HTTP based applications, you can also use gateway-scoped filters (i.e., prefix the gateway class with a `@UseFilters()` decorator).

```typescript

@UseFilters(new WsExceptionFilter())
@SubscribeMessage('events')
onEvent(client, data: any): WsResponse<any> {
  const event = 'events';
  return { event, data };
}
```

#### Inheritance[#](/websockets/exception-filters#inheritance)

Typically, you'll create fully customized exception filters crafted to fulfill your application requirements. However, there might be use-cases when you would like to simply extend the **core exception filter**, and override the behavior based on certain factors.

In order to delegate exception processing to the base filter, you need to extend `BaseWsExceptionFilter` and call the inherited `catch()` method.

JS TS

```typescript

import { Catch, ArgumentsHost } from '@nestjs/common';
import { BaseWsExceptionFilter } from '@nestjs/websockets';

@Catch()
export class AllExceptionsFilter extends BaseWsExceptionFilter {
  catch(exception: unknown, host: ArgumentsHost) {
    super.catch(exception, host);
  }
}
```

```typescript

import { Catch } from '@nestjs/common';
import { BaseWsExceptionFilter } from '@nestjs/websockets';

@Catch()
export class AllExceptionsFilter extends BaseWsExceptionFilter {
  catch(exception, host) {
    super.catch(exception, host);
  }
}
```

----
url: https://docs.nestjs.com/v10/graphql/mutations
----

* [Mutations](https://docs.nestjs.com/v10/graphql/mutations#mutations)
* [Code first](https://docs.nestjs.com/v10/graphql/mutations#code-first)
* [Schema first](https://docs.nestjs.com/v10/graphql/mutations#schema-first)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/mutations.md "Suggest Edits")

### Mutations

Most discussions of GraphQL focus on data fetching, but any complete data platform needs a way to modify server-side data as well. In REST, any request could end up causing side-effects on the server, but best practice suggests we should not modify data in GET requests. GraphQL is similar - technically any query could be implemented to cause a data write. However, like REST, it's recommended to observe the convention that any operations that cause writes should be sent explicitly via a mutation (read more [here](https://graphql.org/learn/queries/#mutations)).

The official [Apollo](https://www.apollographql.com/docs/graphql-tools/generate-schema.html) documentation uses an `upvotePost()` mutation example. This mutation implements a method to increase a post's `votes` property value. To create an equivalent mutation in Nest, we'll make use of the `@Mutation()` decorator.

#### Code first[#](/graphql/mutations#code-first)

Let's add another method to the `AuthorResolver` used in the previous section (see [resolvers](/v10/graphql/resolvers)).

```typescript

@Mutation(() => Post)
async upvotePost(@Args({ name: 'postId', type: () => Int }) postId: number) {
  return this.postsService.upvoteById({ id: postId });
}
```

> **Hint** All decorators (e.g., `@Resolver`, `@ResolveField`, `@Args`, etc.) are exported from the `@nestjs/graphql` package.

This will result in generating the following part of the GraphQL schema in SDL:

```graphql

type Mutation {
  upvotePost(postId: Int!): Post
}
```

The `upvotePost()` method takes `postId` (`Int`) as an argument and returns an updated `Post` entity. For the reasons explained in the [resolvers](/v10/graphql/resolvers) section, we have to explicitly set the expected type.

If the mutation needs to take an object as an argument, we can create an **input type**. The input type is a special kind of object type that can be passed in as an argument (read more [here](https://graphql.org/learn/schema/#input-types)). To declare an input type, use the `@InputType()` decorator.

```typescript

import { InputType, Field } from '@nestjs/graphql';

@InputType()
export class UpvotePostInput {
  @Field()
  postId: number;
}
```

> **Hint** The `@InputType()` decorator takes an options object as an argument, so you can, for example, specify the input type's description. Note that, due to TypeScript's metadata reflection system limitations, you must either use the `@Field` decorator to manually indicate a type, or use a [CLI plugin](/v10/graphql/cli-plugin).

We can then use this type in the resolver class:

```typescript

@Mutation(() => Post)
async upvotePost(
  @Args('upvotePostData') upvotePostData: UpvotePostInput,
) {}
```

#### Schema first[#](/graphql/mutations#schema-first)

Let's extend our `AuthorResolver` used in the previous section (see [resolvers](/v10/graphql/resolvers)).

```typescript

@Mutation()
async upvotePost(@Args('postId') postId: number) {
  return this.postsService.upvoteById({ id: postId });
}
```

Note that we assumed above that the business logic has been moved to the `PostsService` (querying the post and incrementing its `votes` property). The logic inside the `PostsService` class can be as simple or sophisticated as needed. The main point of this example is to show how resolvers can interact with other providers.

The last step is to add our mutation to the existing types definition.

```graphql

type Author {
  id: Int!
  firstName: String
  lastName: String
  posts: [Post]
}

type Post {
  id: Int!
  title: String
  votes: Int
}

type Query {
  author(id: Int!): Author
}

type Mutation {
  upvotePost(postId: Int!): Post
}
```

The `upvotePost(postId: Int!): Post` mutation is now available to be called as part of our application's GraphQL API.

----
url: https://docs.nestjs.com/v5/techniques/validation
----

### Validation

The validation is an essential functionality of any existing web application. To automatically validate incoming requests, we leverage [class-validator](https://github.com/typestack/class-validator) package which built-in `ValidationPipe` makes use of underneath. The `ValidationPipe` provides a convenient method to validate incoming client payloads with a variety of powerful validation rules.

#### Overview

In [Pipes](/v5/pipes) chapter, we went through the process of building a simplified validation pipe. To better understand what we're doing under the hood, we heavily recommend to read this article. Here, we'll mainly focus on the real use-cases instead.

#### Auto-validation

For the sake of this tutorial, we'll bind `ValidationPipe` to the whole application, thus, all endpoints will be automatically protected from the incorrect data.

TypeScript

```typescript

async function bootstrap() {
  const app = await NestFactory.create(ApplicationModule);
  app.useGlobalPipes(new ValidationPipe());
  await app.listen(3000);
}
bootstrap();
```

To test our pipe, let's create a basic endpoint.

TypeScript

```typescript

@Post()
create(@Body() createUserDto: CreateUserDto) {
  return 'This action adds a new user';
}
```

Then, add a few validation rules in our `CreateCatDto`.

TypeScript

```typescript

import { IsEmail, IsNotEmpty } from 'class-validator';

export class CreateUserDto {
  @IsEmail()
  email: string;

  @IsNotEmpty()
  password: string;
}
```

Now, when someone requests our endpoint with an invalid `email`, the application would respond with a `400 Bad Request` code and the following response body.

TypeScript

```typescript

{
  "statusCode": 400,
  "error": "Bad Request",
  "message": [
      {
          "target": {},
          "property": "email",
          "children": [],
          "constraints": {
              "isEmail": "email must be an email"
          }
      }
  ]
}
```

Obviously, the response body is not a sole use-case for the`ValidationPipe`. Imagine, that we would like to accept `:id` in the endpoint path. Only numbers shall be valid though. This is pretty simple as well.

TypeScript

```typescript

@Get(':id')
findOne(@Param() params: FindOneParams) {
  return 'This action returns a user';
}
```

And `FindOneParams` looks like below.

TypeScript

```typescript

import { IsNumberString } from 'class-validator';

export class FindOneParams {
  @IsNumberString()
  id: number;
}
```

#### Disable detailed errors

Error messages help a lot in order to comprehend what was wrong with the data sent through the network. However, in some production environments, you might want to disable detailed errors.

TypeScript

```typescript

app.useGlobalPipes(new ValidationPipe({
  disableErrorMessages: true,
}));
```

Now, error messages won't be populated to the end user.

#### Stripping properties

Quite frequently, we would like only predefined (whitelisted) properties to be passed on. For instance, if we expect `email` and `password` properties, when someone sends `age`, this property should be stripped and not available in the DTO. To enable such behavior, set `whitelist` to `true`.

TypeScript

```typescript

app.useGlobalPipes(new ValidationPipe({
  whitelist: true,
}));
```

This setting will enable auto-stripping of non-whitelisted (without any decorator on top of them) properties. However, if you want to stop the request processing entirely, and return an error response to the user, use `forbidNonWhitelisted` instead.

#### Auto payload transforming

The `ValidationPipe` doesn't automatically transform your payloads to the corresponding DTO classes. If you take a look at either `createCatDto` or `findOneParams` in your controller methods, you will notice that they're not actual instances of these classes. To enable auto-transformation, set `transform` to `true`.

TypeScript

```typescript

app.useGlobalPipes(new ValidationPipe({
  transform: true,
}));
```

#### Websockets & Microservices

All these guidelines cornern both WebSockets as well as microservices, regardless of transport method that is being used.

#### Learn more

In order to read more about custom validators, error messages, and available decorators, visit this [page](https://github.com/typestack/class-validator).

* Validation
* Overview
* Auto-validation
* Disable detailed errors
* Stripping properties
* Auto payload transforming

----
url: https://docs.nestjs.com/v4/custom-decorators
----

### Custom Route Param Decorators

Nest is built around a language feature called **decorators**. It's a well-known concept in a lot of commonly used programming languages, but in the JavaScript world, it's still relatively new. To better understand how the decorators work, you should take a look at [this](https://medium.com/google-developers/exploring-es7-decorators-76ecb65fb841) article. Here's a simple definition:

> An ES2016 decorator is an expression which returns a function and can take a target, name and property descriptor as arguments. You apply it by prefixing the decorator with an `@` character and placing this at the very top of what you are trying to decorate. Decorators can be defined for either a class or a property.

Nest provides a set of useful **param decorators**, which you can use together with the HTTP route handlers. Below is a comparison of the decorators with the plain express objects.

|                            |                                      |
| -------------------------- | ------------------------------------ |
| `@Request()`               | `req`                                |
| `@Response()`              | `res`                                |
| `@Next()`                  | `next`                               |
| `@Session()`               | `req.session`                        |
| `@Param(param?: string)`   | `req.params` / `req.params[param]`   |
| `@Body(param?: string)`    | `req.body` / `req.body[param]`       |
| `@Query(param?: string)`   | `req.query` / `req.query[param]`     |
| `@Headers(param?: string)` | `req.headers` / `req.headers[param]` |

Additionally, you can create your own, **custom decorator**. Why it's useful?

In the node.js world, it's a common practice to attach properties to the **request** object. Then you have to grab them manually every time in the route handlers, for example, using following construction:

TypeScript

```typescript

const user = req.user;
```

In order to do this more readable and transparent, we can create the `@User()` decorator and reuse it across all of the controllers.

user.decorator.ts

JavaScript TypeScript

TypeScript

```typescript

import { createRouteParamDecorator } from '@nestjs/common';

export const User = createRouteParamDecorator((data, req) => {
  return req.user;
});
```

Now you can simply use it wherever you want to.

JavaScript TypeScript

TypeScript

```typescript

@Get()
async findOne(@User() user: UserEntity) {
  console.log(user);
}
```

TypeScript

```typescript

@Get()
@Bind(User())
async findOne(user) {
  console.log(user);
}
```

#### Passing data

When the behaviour of your decorator depends on some conditions, you may use the `data` param to pass an argument to the decorator factory function. For example, the construction below:

JavaScript TypeScript

TypeScript

```typescript

@Get()
async findOne(@User('test') user: UserEntity) {
  console.log(user);
}
```

TypeScript

```typescript

@Get()
@Bind(User('test'))
async findOne(user) {
  console.log(user);
}
```

Will making it possible to access the `test` string via the `data` param:

user.decorator.ts

JavaScript TypeScript

TypeScript

```typescript

import { createRouteParamDecorator } from '@nestjs/common';

export const User = createRouteParamDecorator((data, req) => {
  console.log(data); // test
  return req.user;
});
```

#### Pipes

Nest treats a custom route param decorator the same way as the built-in ones (`@Body()`, `@Param()` and `@Query()`). It means that pipes are executed also for the custom annotated parameters (in this case, for the `user` argument). Moreover, you can apply the pipe directly to the custom decorator:

JavaScript TypeScript

TypeScript

```typescript

@Get()
async findOne(@User(new ValidationPipe()) user: UserEntity) {
  console.log(user);
}
```

TypeScript

```typescript

@Get()
@Bind(User(new ValidationPipe()))
async findOne(user) {
  console.log(user);
}
```

#### Sponsors

[](https://valor-software.com/)

Nest is an MIT-licensed open source project. It can grow thanks to the support by these awesome people. If you'd like to join them, please read more [here](https://opencollective.com/nest). Thanks!

[](https://opencollective.com/nest/backer/0/website)[](https://opencollective.com/nest/backer/1/website)[](https://opencollective.com/nest/backer/2/website)[](https://opencollective.com/nest/backer/3/website)[](https://opencollective.com/nest/backer/4/website)[](https://opencollective.com/nest/backer/5/website)[](https://opencollective.com/nest/backer/6/website)[](https://opencollective.com/nest/backer/7/website)[](https://opencollective.com/nest/backer/8/website)[](https://opencollective.com/nest/backer/9/website)[](https://opencollective.com/nest/backer/10/website)[](https://opencollective.com/nest/backer/11/website)[](https://opencollective.com/nest/backer/12/website)[](https://opencollective.com/nest/backer/13/website)[](https://opencollective.com/nest/backer/14/website)[](https://opencollective.com/nest/backer/15/website)[](https://opencollective.com/nest/backer/16/website)[](https://opencollective.com/nest/backer/17/website)[](https://opencollective.com/nest/backer/18/website)[](https://opencollective.com/nest/backer/19/website)[](https://opencollective.com/nest/backer/20/website)[](https://opencollective.com/nest/backer/21/website)[](https://opencollective.com/nest/backer/22/website)[](https://opencollective.com/nest/backer/23/website)[](https://opencollective.com/nest/backer/24/website)[](https://opencollective.com/nest/backer/25/website)[](https://opencollective.com/nest/backer/26/website)[](https://opencollective.com/nest/backer/27/website)[](https://opencollective.com/nest/backer/28/website)[](https://opencollective.com/nest/backer/29/website)

[Become a sponsor](https://opencollective.com/nest)

----
url: https://docs.nestjs.com/v6/fundamentals/lifecycle-events
----

* [Lifecycle Events](https://docs.nestjs.com/v6/fundamentals/lifecycle-events#lifecycle-events)
* [Lifecycle sequence](https://docs.nestjs.com/v6/fundamentals/lifecycle-events#lifecycle-sequence)
* [Lifecycle events](https://docs.nestjs.com/v6/fundamentals/lifecycle-events#lifecycle-events-1)
* [Usage](https://docs.nestjs.com/v6/fundamentals/lifecycle-events#usage)
* [Asynchronous initialization](https://docs.nestjs.com/v6/fundamentals/lifecycle-events#asynchronous-initialization)
* [Application shutdown](https://docs.nestjs.com/v6/fundamentals/lifecycle-events#application-shutdown)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/fundamentals/lifecycle-events.md "Suggest Edits")

### Lifecycle Events

A Nest application, as well as every application element, has a lifecycle managed by Nest. Nest provides **lifecycle hooks** that give visibility into key lifecycle events, and the ability to act (run registered code on your `module`, `injectable` or `controller`) when they occur.

#### Lifecycle sequence[#](/fundamentals/lifecycle-events#lifecycle-sequence)

The following diagram depicts the sequence of key application lifecycle events, from the time the application is bootstrapped until the node process exits. We can divide the overall lifecycle into three phases: **initializing**, **running** and **terminating**. Using this lifecycle, you can plan for appropriate initialization of modules and services, manage active connections, and gracefully shutdown your application when it receives a termination signal.

#### Lifecycle events[#](/fundamentals/lifecycle-events#lifecycle-events-1)

Lifecycle events happen during application bootstrapping and shutdown. Nest calls registered lifecycle hook methods on `modules`, `injectables` and `controllers` at each of the following lifecycle events (**shutdown hooks** need to be enabled first, as described [below](https://docs.nestjs.com/fundamentals/lifecycle-events#application-shutdown)). As shown in the diagram above, Nest also calls the appropriate underlying methods to begin listening for connections, and to stop listening for connections.

| Lifecycle hook method         | Lifecycle event triggering the hook method call                                                                                                                                                              |
| ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `onModuleInit()`              | Called once the host module's dependencies have been resolved.                                                                                                                                               |
| `onApplicationBootstrap()`    | Called once all modules have been initialized, but before listening for connections.                                                                                                                         |
| `onModuleDestroy()`           | Called after a termination signal (e.g., `SIGTERM`) has been received.                                                                                                                                       |
| `beforeApplicationShutdown()` | Called after all `onModuleDestroy()` handlers have completed (Promises resolved or rejected); once complete (Promises resolved or rejected), all existing connections will be closed (`app.close()` called). |
| `onApplicationShutdown()`     | Called after connections close (`app.close()` resolves).                                                                                                                                                     |

#### Usage[#](/fundamentals/lifecycle-events#usage)

Each lifecycle hook is represented by an interface. Interfaces are technically optional because they do not exist after TypeScript compilation. Nonetheless, it's good practice to use them in order to benefit from strong typing and editor tooling. To register a lifecycle hook, implement the appropriate interface. For example, to register a method to be called during module initialization on a particular class (e.g., Controller, Provider or Module), implement the `OnModuleInit` interface by supplying an `onModuleInit()` method, as shown below:

JS TS

```typescript

import { Injectable, OnModuleInit } from '@nestjs/common';

@Injectable()
export class UsersService implements OnModuleInit {
  onModuleInit() {
    console.log(`The module has been initialized.`);
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';

@Injectable()
export class UsersService {
  onModuleInit() {
    console.log(`The module has been initialized.`);
  }
}
```

#### Asynchronous initialization[#](/fundamentals/lifecycle-events#asynchronous-initialization)

Both the `OnModuleInit` and `OnApplicationBootstrap` hooks allow you to defer the application initialization process (return a `Promise` or mark the method as `async` and `await` an asynchronous method completion in the method body).

JS TS

```typescript

async onModuleInit(): Promise<void> {
  await this.fetch();
}
```

```typescript

async onModuleInit() {
  await this.fetch();
}
```

#### Application shutdown[#](/fundamentals/lifecycle-events#application-shutdown)

The `beforeApplicationShutdown()` and `onApplicationShutdown()` hooks are called in the **terminating** phase (in response to system signals such as `SIGTERM`). This feature is often used with [Kubernetes](https://kubernetes.io/), [Heroku](https://www.heroku.com/) or similar services.

To use these hooks you must activate a listener which listens to shutdown signals.

```typescript

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  // Starts listening for shutdown hooks
  app.enableShutdownHooks();
  await app.listen(3000);
}
bootstrap();
```

When the application receives a termination signal it will call any registered `beforeApplicationShutdown()`, then `onApplicationShutdown()` methods (in the sequence described above) with the corresponding signal as the first parameter. If a registered function awaits an asynchronous call (returns a promise), Nest will not continue in the sequence until the promise is resolved or rejected.

JS TS

```typescript

@Injectable()
class UsersService implements OnApplicationShutdown {
  onApplicationShutdown(signal: string) {
    console.log(signal); // e.g. "SIGINT"
  }
}
```

```typescript

@Injectable()
class UsersService implements OnApplicationShutdown {
  onApplicationShutdown(signal) {
    console.log(signal); // e.g. "SIGINT"
  }
}
```

----
url: https://docs.nestjs.com/v6/microservices/guards
----

* [Guards](https://docs.nestjs.com/v6/microservices/guards#guards)
* [Binding guards](https://docs.nestjs.com/v6/microservices/guards#binding-guards)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/microservices/guards.md "Suggest Edits")

### Guards

There is no fundamental difference between microservices guards and [regular HTTP application guards](/v6/guards). The only difference is that instead of throwing `HttpException`, you should use `RpcException`.

> **Hint** The `RpcException` class is exposed from `@nestjs/microservices` package.

#### Binding guards[#](/microservices/guards#binding-guards)

The following example uses a method-scoped guard. Just as with HTTP based applications, you can also use controller-scoped guards (i.e., prefix the controller class with a `@UseGuards()` decorator).

JS TS

```typescript

@UseGuards(AuthGuard)
@MessagePattern({ cmd: 'sum' })
accumulate(data: number[]): number {
  return (data || []).reduce((a, b) => a + b);
}
```

```typescript

@UseGuards(AuthGuard)
@MessagePattern({ cmd: 'sum' })
accumulate(data) {
  return (data || []).reduce((a, b) => a + b);
}
```

----
url: https://docs.nestjs.com/v10/recipes/suites
----

* [Suites (formerly Automock)](https://docs.nestjs.com/v10/recipes/suites#suites-formerly-automock)
* [Introduction](https://docs.nestjs.com/v10/recipes/suites#introduction)
* [Installation](https://docs.nestjs.com/v10/recipes/suites#installation)
* [Example and module setup](https://docs.nestjs.com/v10/recipes/suites#example-and-module-setup)
* [Testing CatsApiService with TestingModule](https://docs.nestjs.com/v10/recipes/suites#testing-catsapiservice-with-testingmodule)
* [Sociable Testing Example](https://docs.nestjs.com/v10/recipes/suites#sociable-testing-example)
* [Integration Testing and Database](https://docs.nestjs.com/v10/recipes/suites#integration-testing-and-database)
* [Sociable Unit Tests, Integration Tests, and Mocking](https://docs.nestjs.com/v10/recipes/suites#sociable-unit-tests-integration-tests-and-mocking)
* [Testing IoC Container Registration](https://docs.nestjs.com/v10/recipes/suites#testing-ioc-container-registration)
* [Comparison Between Solitary, Sociable, Integration, and E2E Testing](https://docs.nestjs.com/v10/recipes/suites#comparison-between-solitary-sociable-integration-and-e2e-testing)
* [Solitary Unit Tests](https://docs.nestjs.com/v10/recipes/suites#solitary-unit-tests)
* [Sociable Unit Tests](https://docs.nestjs.com/v10/recipes/suites#sociable-unit-tests)
* [Integration Tests](https://docs.nestjs.com/v10/recipes/suites#integration-tests)
* [E2E Tests](https://docs.nestjs.com/v10/recipes/suites#e2e-tests)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/recipes/suites.md "Suggest Edits")

### Suites (formerly Automock)

Suites is an opinionated and flexible testing meta-framework designed to enhance the software testing experience for backend systems. By bringing together a variety of testing tools into a unified framework, Suites streamlines the creation of reliable tests, helping to ensure the development of high-quality software.

> **Hint**`Suites` is a third-party package and is not maintained by the NestJS core team. Please report any issues with the library to the [appropriate repository](https://github.com/suites-dev/suites).

#### Introduction[#](/recipes/suites#introduction)

Inversion of Control (IoC) is a fundamental principle in the NestJS framework, enabling a modular, testable architecture. While NestJS offers built-in tools for creating testing modules, Suites provides an alternative approach that emphasizes testing isolated units or small groups of units together. Suites uses a virtual container for dependencies, where mocks are automatically generated, eliminating the need to manually replace each provider with a mock in the IoC (or DI) container. This approach can be used either in place of or alongside NestJS’s `Test.createTestingModule` method, offering more flexibility for unit testing based on your needs.

#### Installation[#](/recipes/suites#installation)

To use Suites with NestJS, install the necessary packages:

```bash

$ npm i -D @suites/unit @suites/di.nestjs @suites/doubles.jest
```

> **Hint**`Suites` supports Vitest and Sinon as test doubles as well, `@suites/doubles.vitest` and `@suites/doubles.sinon` respectively.

#### Example and module setup[#](/recipes/suites#example-and-module-setup)

Consider a module setup for `CatsService` that includes `CatsApiService`, `CatsDAL`, `HttpClient`, and `Logger`. This will be our base for the examples in this recipe:

cats.module.ts

JS TS

```typescript

import { HttpModule } from '@nestjs/axios';
import { PrismaModule } from '../prisma.module';

@Module({
  imports: [HttpModule.register({ baseUrl: 'https://api.cats.com/' }), PrismaModule],
  providers: [CatsService, CatsApiService, CatsDAL, Logger],
  exports: [CatsService],
})
export class CatsModule {}
```

Both the `HttpModule` and `PrismaModule` are exporting providers to the host module.

Let's start by testing the `CatsHttpService` in isolation. This service is responsible for fetching cat data from an API and logging the operation.

cats-http.service.ts

JS TS

```typescript

@Injectable()
export class CatsHttpService {
  constructor(private httpClient: HttpClient, private logger: Logger) {}

  async fetchCats(): Promise<Cat[]> {
    this.logger.log('Fetching cats from the API');
    const response = await this.httpClient.get('/cats');
    return response.data;
  }
}
```

We want to isolate `CatsHttpService` and mock its dependencies, `HttpClient` and `Logger`. Suites allows us to do this easily using the `.solitary()` method from `TestBed`.

cats-http.service.spec.ts

JS TS

```typescript

import { TestBed, Mocked } from '@suites/unit';

describe('Cats Http Service Unit Test', () => {
  let catsHttpService: CatsHttpService;
  let httpClient: Mocked<HttpClient>;
  let logger: Mocked<Logger>;

  beforeAll(async () => {
    // Isolate CatsHttpService and mock HttpClient and Logger
    const { unit, unitRef } = await TestBed.solitary(CatsHttpService).compile();

    catsHttpService = unit;
    httpClient = unitRef.get(HttpClient);
    logger = unitRef.get(Logger);
  });

  it('should fetch cats from the API and log the operation', async () => {
    const catsFixtures: Cat[] = [{ id: 1, name: 'Catty' }, { id: 2, name: 'Mitzy' }];
    httpClient.get.mockResolvedValue({ data: catsFixtures });

    const cats = await catsHttpService.fetchCats();

    expect(logger.log).toHaveBeenCalledWith('Fetching cats from the API');
    expect(httpClient.get).toHaveBeenCalledWith('/cats');
    expect(cats).toEqual<Cat[]>(catsFixtures);
  });
});
```

In the example above, Suites automatically mocks the dependencies of `CatsHttpService` using `TestBed.solitary()`. This makes the setup easier since you don’t have to manually mock each dependency.

* Auto-Mocking of Dependencies: Suites generates mocks for all dependencies of the unit being tested.

* Empty Behavior of Mocks: Initially, these mocks don’t have any predefined behavior. You’ll need to specify their behavior as needed for your tests.

* `unit` and `unitRef` properties:

  * `unit` refers to the actual instance of the class being tested, complete with its mocked dependencies.
  * `unitRef` is a reference that allows you to access the mocked dependencies.

#### Testing `CatsApiService` with `TestingModule`[#](/recipes/suites#testing-catsapiservice-with-testingmodule)

For `CatsApiService`, we want to ensure that the `HttpModule` is properly imported and configured in the `CatsModule` host module. This includes verifying that the base URL (and other configurations) for `Axios` is set correctly.

In this case, we won’t use Suites; instead, we’ll use Nest’s `TestingModule` to test the actual configuration of `HttpModule`. We’ll utilize `nock` to mock HTTP requests without mocking the `HttpClient` in this scenario.

cats-api.service.ts

JS TS

```typescript

import { HttpClient } from '@nestjs/axios';

@Injectable()
export class CatsApiService {
  constructor(private httpClient: HttpClient) {}

  async getCatById(id: number): Promise<Cat> {
    const response = await this.httpClient.get(`/cats/${id}`);
    return response.data;
  }
}
```

We need to test `CatsApiService` with a real, unmocked `HttpClient` to ensure the DI and configuration of `Axios` (http) are correct. This involves importing the `CatsModule` and using `nock` for HTTP request mocking.

cats-api.service.integration.test.ts

JS TS

```typescript

import { Test } from '@nestjs/testing';
import * as nock from 'nock';

describe('Cats Api Service Integration Test', () => {
  let catsApiService: CatsApiService;

  beforeAll(async () => {
    const moduleRef = await Test.createTestingModule({
      imports: [CatsModule],
    }).compile();

    catsApiService = moduleRef.get(CatsApiService);
  });

  afterEach(() => {
    nock.cleanAll();
  });

  it('should fetch cat by id using real HttpClient', async () => {
    const catFixture: Cat = { id: 1, name: 'Catty' };

    nock('https://api.cats.com') // Making this URL identical to the one in HttpModule registration
      .get('/cats/1')
      .reply(200, catFixture);

    const cat = await catsApiService.getCatById(1);
    expect(cat).toEqual<Cat>(catFixture);
  });
});
```

#### Sociable Testing Example[#](/recipes/suites#sociable-testing-example)

Next, let's test `CatsService`, which depends on `CatsApiService` and `CatsDAL`. We'll mock `CatsApiService` and expose `CatsDAL`.

cats.dal.ts

JS TS

```typescript

import { PrismaClient } from '@prisma/client';

@Injectable()
export class CatsDAL {
  constructor(private prisma: PrismaClient) {}

  async saveCat(cat: Cat): Promise<Cat> {
    return this.prisma.cat.create({data: cat});
  }
}
```

Next up, we have the `CatsService`, which depends on `CatsApiService` and `CatsDAL`:

cats.service.ts

JS TS

```typescript

@Injectable()
export class CatsService {
  constructor(
    private catsApiService: CatsApiService,
    private catsDAL: CatsDAL
  ) {}

  async getAndSaveCat(id: number): Promise<Cat> {
    const cat = await this.catsApiService.getCatById(id);
    return this.catsDAL.saveCat(cat);
  }
}
```

And now, let's test `CatsService` using sociable testing with Suites:

cats.service.spec.ts

JS TS

```typescript

import { TestBed, Mocked } from '@suites/unit';
import { PrismaClient } from '@prisma/client';

describe('Cats Service Sociable Unit Test', () => {
  let catsService: CatsService;
  let prisma: Mocked<PrismaClient>;
  let catsApiService: Mocked<CatsApiService>;

  beforeAll(async () => {
    // Sociable test setup, exposing CatsDAL and mocking CatsApiService
    const { unit, unitRef } = await TestBed.sociable(CatsService)
      .expose(CatsDAL)
      .mock(CatsApiService)
      .final({ getCatById: async () => ({ id: 1, name: 'Catty' })})
      .compile();

    catsService = unit;
    prisma = unitRef.get(PrismaClient);
  });

  it('should get cat by id and save it', async () => {
    const catFixture: Cat = { id: 1, name: 'Catty' };
    prisma.cat.create.mockResolvedValue(catFixture);

    const savedCat = await catsService.getAndSaveCat(1);

    expect(prisma.cat.create).toHaveBeenCalledWith({ data: catFixture });
    expect(savedCat).toEqual(catFixture);
  });
});
```

In this example, we use the `.sociable()` method to set up the test environment. We utilize the `.expose()` method to allow real interactions with `CatsDAL`, while mocking `CatsApiService` with the `.mock()` method. The `.final()` method establishes fixed behavior for `CatsApiService`, ensuring consistent outcomes across tests.

This approach emphasizes testing `CatsService` with genuine interactions with `CatsDAL`, which involves handling `Prisma`. Suites will use `CatsDAL` as is, and only its dependencies, like `Prisma`, will be mocked in this case.

It's important to note that this approach is **solely for verifying behavior** and differs from loading the entire testing module. Sociable tests are valuable for confirming the behavior of units in isolation from their direct dependencies, especially when you want to focus on the behavior and interactions of units.

#### Integration Testing and Database[#](/recipes/suites#integration-testing-and-database)

For `CatsDAL`, it's possible to test against a real database such as SQLite or PostgreSQL (for instance, using Docker Compose). However, for this example, we will mock `Prisma` and focus on sociable testing. The reason for mocking `Prisma` is to avoid I/O operations and concentrate on the behavior of `CatsService` in isolation. That said, you can also conduct tests with real I/O operations and a live database.

#### Sociable Unit Tests, Integration Tests, and Mocking[#](/recipes/suites#sociable-unit-tests-integration-tests-and-mocking)

* Sociable Unit Tests: These focus on testing the interactions and behaviors between units while mocking their deeper dependencies. In this example, we mock `Prisma` and expose `CatsDAL`.

* Integration Tests: These involve real I/O operations and a fully configured dependency injection (DI) setup. Testing `CatsApiService` with `HttpModule` and `nock` is considered an integration test, as it verifies the real configuration and interactions of `HttpClient`. In this scenario, we will use Nest's `TestingModule` to load the actual module configuration.

**Exercise caution when using mocks.** Be sure to test I/O operations and DI configurations (especially when HTTP or database interactions are involved). After validating these components with integration tests, you can confidently mock them for sociable unit tests to focus on behavior and interactions. Suites sociable tests are geared towards verifying the behavior of units in isolation from their direct dependencies, while integration tests ensure that the overall system configuration and I/O operations function correctly.

#### Testing IoC Container Registration[#](/recipes/suites#testing-ioc-container-registration)

It's essential to verify that your DI container is properly configured to prevent runtime errors. This includes ensuring that all providers, services, and modules are registered and injected correctly. Testing the DI container configuration helps catch misconfigurations early, preventing issues that might only arise at runtime.

To confirm that the IoC container is set up correctly, let's create an integration test that loads the actual module configuration and verifies that all providers are registered and injected properly.

```typescript

import { Test, TestingModule } from '@nestjs/testing';
import { CatsModule } from './cats.module';
import { CatsService } from './cats.service';

describe('Cats Module Integration Test', () => {
  let moduleRef: TestingModule;

  beforeAll(async () => {
    moduleRef = await Test.createTestingModule({
      imports: [CatsModule],
    }).compile();
  });

  it('should resolve exported providers from the ioc container', () => {
    const catsService = moduleRef.get(CatsService);
    expect(catsService).toBeDefined();
  });
});
```

#### Comparison Between Solitary, Sociable, Integration, and E2E Testing[#](/recipes/suites#comparison-between-solitary-sociable-integration-and-e2e-testing)

#### Solitary Unit Tests[#](/recipes/suites#solitary-unit-tests)

* **Focus**: Test single unit (class) in full isolation.
* **Use Case**: Testing `CatsHttpService`.
* **Tools**: Suites' `TestBed.solitary()` method.
* **Example**: Mocking `HttpClient` and testing `CatsHttpService`.

#### Sociable Unit Tests[#](/recipes/suites#sociable-unit-tests)

* **Focus**: Verify interactions between units while mocking deeper dependencies.
* **Use Case**: Testing `CatsService` with a mocked `CatsApiService` and exposing `CatsDAL`.
* **Tools**: Suites' `TestBed.sociable()` method.
* **Example**: Mocking `Prisma` and testing `CatsService`.

#### Integration Tests[#](/recipes/suites#integration-tests)

* **Focus**: Involve real I/O operations and fully configured modules (IoC container).
* **Use Case**: Testing `CatsApiService` with `HttpModule` and `nock`.
* **Tools**: Nest's `TestingModule`.
* **Example**: Testing the real configuration and interaction of `HttpClient`.

#### E2E Tests[#](/recipes/suites#e2e-tests)

* **Focus**: Cover the interaction of classes and modules at a more aggregate level.
* **Use Case**: Testing the full behavior of the system from the perspective of the end-user.
* **Tools**: Nest's `TestingModule`, `supertest`.
* **Example**: Testing the `CatsModule` using `supertest` to simulate HTTP requests.

Refer to the [NestJS official testing guide](https://docs.nestjs.com/fundamentals/testing#end-to-end-testing) for more details on setting up and running E2E tests.

----
url: https://docs.nestjs.com/v9/graphql/migration-guide
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Migrating to v11 from v10](https://docs.nestjs.com/v9/graphql/migration-guide#migrating-to-v11-from-v10)
* [Apollo packages](https://docs.nestjs.com/v9/graphql/migration-guide#apollo-packages)
* [Mercurius packages](https://docs.nestjs.com/v9/graphql/migration-guide#mercurius-packages)
* [Migrating to v10 from v9](https://docs.nestjs.com/v9/graphql/migration-guide#migrating-to-v10-from-v9)
* [Introducing "driver" packages](https://docs.nestjs.com/v9/graphql/migration-guide#introducing-driver-packages)
* [Plugins](https://docs.nestjs.com/v9/graphql/migration-guide#plugins)
* [Directives](https://docs.nestjs.com/v9/graphql/migration-guide#directives)
* [Federation](https://docs.nestjs.com/v9/graphql/migration-guide#federation)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/migration.md "Suggest Edits")

### Migrating to v11 from v10

This chapter provides a set of guidelines for migrating from `@nestjs/graphql` version 10 to version 11. As part of this major release, we updated the Apollo driver to be compatible with Apollo Server v4 (instead of v3). Note: there are several breaking changes in Apollo Server v4 (especially around plugins and ecosystem packages), so you'll have to update your codebase accordingly. For more information, see the [Apollo Server v4 migration guide](https://www.apollographql.com/docs/apollo-server/migration/).

#### Apollo packages[#](/graphql/migration-guide#apollo-packages)

Instead of installing the `apollo-server-express` package, you'll have to install `@apollo/server`:

```bash

$ npm uninstall apollo-server-express
$ npm install @apollo/server
```

If you use the Fastify adapter, you'll have to install the `@as-integrations/fastify` package instead:

```bash

$ npm uninstall apollo-server-fastify
$ npm install @apollo/server @as-integrations/fastify
```

#### Mercurius packages[#](/graphql/migration-guide#mercurius-packages)

Mercurius gateway is no longer a part of the `mercurius` package. Instead, you'll have to install the `@mercuriusjs/gateway` package separately:

```bash

$ npm install @mercuriusjs/gateway
```

Similarly, for creating federated schemas, you'll have to install the `@mercuriusjs/federation` package:

```bash

$ npm install @mercuriusjs/federation
```

### Migrating to v10 from v9

This chapter provides a set of guidelines for migrating from `@nestjs/graphql` version 9 to version 10. The focus of this major-version release is to provide a lighter, platform-agnostic core library.

#### Introducing "driver" packages[#](/graphql/migration-guide#introducing-driver-packages)

In the latest version, we made a decision to break the `@nestjs/graphql` package up into a few separate libraries, letting you choose whether to use Apollo (`@nestjs/apollo`), Mercurius (`@nestjs/mercurius`), or another GraphQL library in your project.

This implies that now you have to explicitly specify what driver your application will use.

```typescript

// Before
import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';

@Module({
  imports: [
    GraphQLModule.forRoot({
      autoSchemaFile: 'schema.gql',
    }),
  ],
})
export class AppModule {}

// After
import { ApolloDriver, ApolloDriverConfig } from '@nestjs/apollo';
import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';

@Module({
  imports: [
    GraphQLModule.forRoot<ApolloDriverConfig>({
      driver: ApolloDriver,
      autoSchemaFile: 'schema.gql',
    }),
  ],
})
export class AppModule {}
```

#### Plugins[#](/graphql/migration-guide#plugins)

Apollo Server plugins let you perform custom operations in response to certain events. Since this is an exclusive Apollo feature, we moved it from the `@nestjs/graphql` to the newly created `@nestjs/apollo` package so you'll have to update imports in your application.

```typescript

// Before
import { Plugin } from '@nestjs/graphql';

// After
import { Plugin } from '@nestjs/apollo';
```

#### Directives[#](/graphql/migration-guide#directives)

`schemaDirectives` feature has been replaced with the new [Schema directives API](https://www.graphql-tools.com/docs/schema-directives) in v8 of `@graphql-tools/schema` package.

```typescript

// Before
import { SchemaDirectiveVisitor } from '@graphql-tools/utils';
import { defaultFieldResolver, GraphQLField } from 'graphql';

export class UpperCaseDirective extends SchemaDirectiveVisitor {
  visitFieldDefinition(field: GraphQLField<any, any>) {
    const { resolve = defaultFieldResolver } = field;
    field.resolve = async function (...args) {
      const result = await resolve.apply(this, args);
      if (typeof result === 'string') {
        return result.toUpperCase();
      }
      return result;
    };
  }
}

// After
import { getDirective, MapperKind, mapSchema } from '@graphql-tools/utils';
import { defaultFieldResolver, GraphQLSchema } from 'graphql';

export function upperDirectiveTransformer(
  schema: GraphQLSchema,
  directiveName: string,
) {
  return mapSchema(schema, {
    [MapperKind.OBJECT_FIELD]: (fieldConfig) => {
      const upperDirective = getDirective(
        schema,
        fieldConfig,
        directiveName,
      )?.[0];

      if (upperDirective) {
        const { resolve = defaultFieldResolver } = fieldConfig;

        // Replace the original resolver with a function that *first* calls
        // the original resolver, then converts its result to upper case
        fieldConfig.resolve = async function (source, args, context, info) {
          const result = await resolve(source, args, context, info);
          if (typeof result === 'string') {
            return result.toUpperCase();
          }
          return result;
        };
        return fieldConfig;
      }
    },
  });
}
```

To apply this directive implementation to a schema that contains `@upper` directives, use the `transformSchema` function:

```typescript

GraphQLModule.forRoot<ApolloDriverConfig>({
  ...
  transformSchema: schema => upperDirectiveTransformer(schema, 'upper'),
})
```

#### Federation[#](/graphql/migration-guide#federation)

`GraphQLFederationModule` has been removed and replaced with the corresponding driver class:

```typescript

// Before
GraphQLFederationModule.forRoot({
  autoSchemaFile: true,
});

// After
GraphQLModule.forRoot<ApolloFederationDriverConfig>({
  driver: ApolloFederationDriver,
  autoSchemaFile: true,
});
```

> **Hint** Both `ApolloFederationDriver` class and `ApolloFederationDriverConfig` are exported from the `@nestjs/apollo` package.

Likewise, instead of using a dedicated `GraphQLGatewayModule`, simply pass the appropriate `driver` class to your `GraphQLModule` settings:

```typescript

// Before
GraphQLGatewayModule.forRoot({
  gateway: {
    supergraphSdl: new IntrospectAndCompose({
      subgraphs: [
        { name: 'users', url: 'http://localhost:3000/graphql' },
        { name: 'posts', url: 'http://localhost:3001/graphql' },
      ],
    }),
  },
});

// After
GraphQLModule.forRoot<ApolloGatewayDriverConfig>({
  driver: ApolloGatewayDriver,
  gateway: {
    supergraphSdl: new IntrospectAndCompose({
      subgraphs: [
        { name: 'users', url: 'http://localhost:3000/graphql' },
        { name: 'posts', url: 'http://localhost:3001/graphql' },
      ],
    }),
  },
});
```

> **Hint** Both `ApolloGatewayDriver` class and `ApolloGatewayDriverConfig` are exported from the `@nestjs/apollo` package.

----
url: https://docs.nestjs.com/v7/fundamentals/module-ref
----

* [Module reference](https://docs.nestjs.com/v7/fundamentals/module-ref#module-reference)
* [Retrieving instances](https://docs.nestjs.com/v7/fundamentals/module-ref#retrieving-instances)
* [Resolving scoped providers](https://docs.nestjs.com/v7/fundamentals/module-ref#resolving-scoped-providers)
* [Registering REQUEST provider](https://docs.nestjs.com/v7/fundamentals/module-ref#registering-request-provider)
* [Getting current sub-tree](https://docs.nestjs.com/v7/fundamentals/module-ref#getting-current-sub-tree)
* [Instantiating custom classes dynamically](https://docs.nestjs.com/v7/fundamentals/module-ref#instantiating-custom-classes-dynamically)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/fundamentals/module-reference.md "Suggest Edits")

### Module reference

Nest provides the `ModuleRef` class to navigate the internal list of providers and obtain a reference to any provider using its injection token as a lookup key. The `ModuleRef` class also provides a way to dynamically instantiate both static and scoped providers. `ModuleRef` can be injected into a class in the normal way:

cats.service.ts

JS TS

```typescript

@Injectable()
export class CatsService {
  constructor(private moduleRef: ModuleRef) {}
}
```

```typescript

@Injectable()
@Dependencies(ModuleRef)
export class CatsService {
  constructor(moduleRef) {
    this.moduleRef = moduleRef;
  }
}
```

> **Hint** The `ModuleRef` class is imported from the `@nestjs/core` package.

#### Retrieving instances[#](/fundamentals/module-ref#retrieving-instances)

The `ModuleRef` instance (hereafter we'll refer to it as the **module reference**) has a `get()` method. This method retrieves a provider, controller, or injectable (e.g., guard, interceptor, etc.) that exists (has been instantiated) in the **current** module using its injection token/class name.

cats.service.ts

JS TS

```typescript

@Injectable()
export class CatsService implements OnModuleInit {
  private service: Service;
  constructor(private moduleRef: ModuleRef) {}

  onModuleInit() {
    this.service = this.moduleRef.get(Service);
  }
}
```

```typescript

@Injectable()
@Dependencies(ModuleRef)
export class CatsService {
  constructor(moduleRef) {
    this.moduleRef = moduleRef;
  }

  onModuleInit() {
    this.service = this.moduleRef.get(Service);
  }
}
```

> **Warning** You can't retrieve scoped providers (transient or request-scoped) with the `get()` method. Instead, use the technique described [below](https://docs.nestjs.com/fundamentals/module-ref#resolving-scoped-providers). Learn how to control scopes [here](/v7/fundamentals/injection-scopes).

To retrieve a provider from the global context (for example, if the provider has been injected in a different module), pass the `{ strict: false }` option as a second argument to `get()`.

```typescript

this.moduleRef.get(Service, { strict: false });
```

#### Resolving scoped providers[#](/fundamentals/module-ref#resolving-scoped-providers)

To dynamically resolve a scoped provider (transient or request-scoped), use the `resolve()` method, passing the provider's injection token as an argument.

cats.service.ts

JS TS

```typescript

@Injectable()
export class CatsService implements OnModuleInit {
  private transientService: TransientService;
  constructor(private moduleRef: ModuleRef) {}

  async onModuleInit() {
    this.transientService = await this.moduleRef.resolve(TransientService);
  }
}
```

```typescript

@Injectable()
@Dependencies(ModuleRef)
export class CatsService {
  constructor(moduleRef) {
    this.moduleRef = moduleRef;
  }

  async onModuleInit() {
    this.transientService = await this.moduleRef.resolve(TransientService);
  }
}
```

The `resolve()` method returns a unique instance of the provider, from its own **DI container sub-tree**. Each sub-tree has a unique **context identifier**. Thus, if you call this method more than once and compare instance references, you will see that they are not equal.

cats.service.ts

JS TS

```typescript

@Injectable()
export class CatsService implements OnModuleInit {
  constructor(private moduleRef: ModuleRef) {}

  async onModuleInit() {
    const transientServices = await Promise.all([
      this.moduleRef.resolve(TransientService),
      this.moduleRef.resolve(TransientService),
    ]);
    console.log(transientServices[0] === transientServices[1]); // false
  }
}
```

```typescript

@Injectable()
@Dependencies(ModuleRef)
export class CatsService {
  constructor(moduleRef) {
    this.moduleRef = moduleRef;
  }

  async onModuleInit() {
    const transientServices = await Promise.all([
      this.moduleRef.resolve(TransientService),
      this.moduleRef.resolve(TransientService),
    ]);
    console.log(transientServices[0] === transientServices[1]); // false
  }
}
```

To generate a single instance across multiple `resolve()` calls, and ensure they share the same generated DI container sub-tree, you can pass a context identifier to the `resolve()` method. Use the `ContextIdFactory` class to generate a context identifier. This class provides a `create()` method that returns an appropriate unique identifier.

cats.service.ts

JS TS

```typescript

@Injectable()
export class CatsService implements OnModuleInit {
  constructor(private moduleRef: ModuleRef) {}

  async onModuleInit() {
    const contextId = ContextIdFactory.create();
    const transientServices = await Promise.all([
      this.moduleRef.resolve(TransientService, contextId),
      this.moduleRef.resolve(TransientService, contextId),
    ]);
    console.log(transientServices[0] === transientServices[1]); // true
  }
}
```

```typescript

@Injectable()
@Dependencies(ModuleRef)
export class CatsService {
  constructor(moduleRef) {
    this.moduleRef = moduleRef;
  }

  async onModuleInit() {
    const contextId = ContextIdFactory.create();
    const transientServices = await Promise.all([
      this.moduleRef.resolve(TransientService, contextId),
      this.moduleRef.resolve(TransientService, contextId),
    ]);
    console.log(transientServices[0] === transientServices[1]); // true
  }
}
```

> **Hint** The `ContextIdFactory` class is imported from the `@nestjs/core` package.

#### Registering `REQUEST` provider[#](/fundamentals/module-ref#registering-request-provider)

Manually generated context identifiers (with `ContextIdFactory.create()`) represent DI sub-trees in which `REQUEST` provider is `undefined` as they are not instantiated and managed by the Nest dependency injection system.

To register a custom `REQUEST` object for a manually created DI sub-tree, use the `ModuleRef#registerRequestByContextId()` method, as follows:

```typescript

const contextId = ContextIdFactory.create();
this.moduleRef.registerRequestByContextId(/* YOUR_REQUEST_OBJECT */, contextId);
```

#### Getting current sub-tree[#](/fundamentals/module-ref#getting-current-sub-tree)

Occasionally, you may want to resolve an instance of a request-scoped provider within a **request context**. Let's say that `CatsService` is request-scoped and you want to resolve the `CatsRepository` instance which is also marked as a request-scoped provider. In order to share the same DI container sub-tree, you must obtain the current context identifier instead of generating a new one (e.g., with the `ContextIdFactory.create()` function, as shown above). To obtain the current context identifier, start by injecting the request object using `@Inject()` decorator.

cats.service.ts

JS TS

```typescript

@Injectable()
export class CatsService {
  constructor(
    @Inject(REQUEST) private request: Record<string, unknown>,
  ) {}
}
```

```typescript

@Injectable()
@Dependencies(REQUEST)
export class CatsService {
  constructor(request) {
    this.request = request;
  }
}
```

> **Hint** Learn more about the request provider [here](https://docs.nestjs.com/fundamentals/injection-scopes#request-provider).

Now, use the `getByRequest()` method of the `ContextIdFactory` class to create a context id based on the request object, and pass this to the `resolve()` call:

```typescript

const contextId = ContextIdFactory.getByRequest(this.request);
const catsRepository = await this.moduleRef.resolve(CatsRepository, contextId);
```

#### Instantiating custom classes dynamically[#](/fundamentals/module-ref#instantiating-custom-classes-dynamically)

To dynamically instantiate a class that **wasn't previously registered** as a **provider**, use the module reference's `create()` method.

cats.service.ts

JS TS

```typescript

@Injectable()
export class CatsService implements OnModuleInit {
  private catsFactory: CatsFactory;
  constructor(private moduleRef: ModuleRef) {}

  async onModuleInit() {
    this.catsFactory = await this.moduleRef.create(CatsFactory);
  }
}
```

```typescript

@Injectable()
@Dependencies(ModuleRef)
export class CatsService {
  constructor(moduleRef) {
    this.moduleRef = moduleRef;
  }

  async onModuleInit() {
    this.catsFactory = await this.moduleRef.create(CatsFactory);
  }
}
```

This technique enables you to conditionally instantiate different classes outside of the framework container.

## Hoodies, T-shirts, and accessories!

Support our future development by shopping in the official store!

[See more](https://nestjs.threadless.com/ "Shop | NestJS - A node.js framework built on top of TypeScript")

----
url: https://docs.nestjs.com/v6/migration-guide
----

* [Migration guide](https://docs.nestjs.com/v6/migration-guide#migration-guide)
* [Middleware](https://docs.nestjs.com/v6/migration-guide#middleware)
* [Interceptors](https://docs.nestjs.com/v6/migration-guide#interceptors)
* [Platforms](https://docs.nestjs.com/v6/migration-guide#platforms)
* [Metadata reflection](https://docs.nestjs.com/v6/migration-guide#metadata-reflection)
* [GraphQL](https://docs.nestjs.com/v6/migration-guide#graphql)
* [Express instance](https://docs.nestjs.com/v6/migration-guide#express-instance)
* [Deprecations](https://docs.nestjs.com/v6/migration-guide#deprecations)
* [TypeScript](https://docs.nestjs.com/v6/migration-guide#typescript)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/migration.md "Suggest Edits")

### Migration guide

This article provides a set of **guidelines** for migrating from 5 to the latest 6 version. Even though we tried to reduce a number of breaking changes, the API had to be modified in a few places in order to simplify its usage.

#### Middleware[#](/migration-guide#middleware)

Based on [this](https://github.com/nestjs/nest/issues/1378) topic, the middleware API has been changed in order to make it more straightforward for people who come from different Node libraries and also to reduce the number of confusions that arose from the previous API.

JS TS

```typescript

// Before
@Injectable()
export class LoggerMiddleware implements NestMiddleware {
 resolve(...args: any[]): MiddlewareFunction {
   return (req: Request, res: Response, next: Function) => {
     console.log('Request...');
     next();
   };
 }
}

// After
@Injectable()
export class LoggerMiddleware implements NestMiddleware {
  use(req: Request, res: Response, next: Function) {
    console.log('Request...');
    next();
  }
}
```

```typescript

@Injectable()
export class LoggerMiddleware {
 resolve(...args) {
   return (req, res, next) => {
     console.log('Request...');
     next();
   };
 }
}

// After
@Injectable()
export class LoggerMiddleware {
  use(req, res, next) {
    console.log('Request...');
    next();
  }
}
```

Consequently, the `with()` method of the `MiddlewareConsumer` won't work anymore (is fully useless). If you want to pass options to the middleware class, use a [custom provider](/v6/fundamentals/custom-providers) or check more examples [here](https://github.com/nestjs/nest/issues/1378).

#### Interceptors[#](/migration-guide#interceptors)

The interceptors API has also been simplified. In addition, the change was required due to this [issue](https://github.com/nestjs/nest/issues/1016) which was reported by the community.

JS TS

```typescript

// Before
@Injectable()
export class TransformInterceptor implements NestInterceptor {
  intercept(
    context: ExecutionContext,
    call$: Observable<T>,
  ): Observable<Response<T>> {
    return call$.pipe(map(data => ({ data })));
  }
}

// After
@Injectable()
export class TransformInterceptor implements NestInterceptor {
  intercept(
    context: ExecutionContext,
    next: CallHandler,
  ): Observable<Response<T>> {
    return next
      .handle()
      .pipe(map(data => ({ data })));
  }
}
```

```typescript

// Before
@Injectable()
export class TransformInterceptor {
  intercept(context, next) {
    return call$.pipe(map(data => ({ data })));
  }
}

// After
@Injectable()
export class TransformInterceptor {
  intercept(context, next) {
    return next
      .handle()
      .pipe(map(data => ({ data })));
  }
}
```

> **Hint** The `CallHandler` interface is exported from the `@nestjs/common` package.

Please note that your interceptors will now run in the correct order - they will follow a simple request processing pipeline, being executed from global to concrete once the request wants to hit an end-handler, and then (in response pipeline), they will be executed from specific to global ones (if you attach some asynchronous/mapping logic inside them).

#### Platforms[#](/migration-guide#platforms)

So far, even if you were not using an HTTP server, you had to install the `express` library internally (as a dependency of the `@nestjs/core` package). Since a new major release, Nest will no longer ship these packages upfront. Each platform has been extracted into an individual package, respectively `@nestjs/platform-express`, `@nestjs/platform-fastify`, `@nestjs/platform-ws`, and `@nestjs/platform-socket.io`. Assuming that your application was using both `express` and `socket.io`, you only have to install the corresponding platforms:

```bash

$ npm i @nestjs/platform-express @nestjs/platform-socket.io
```

Every existing adapter (for example, `FastifyAdapter`) is now being served from the dedicated platform package.

* `FastifyAdapter` - `@nestjs/platform-fastify`
* `ExpressAdapter` - `@nestjs/platform-express`
* `WsAdapter` - `@nestjs/platform-ws`
* `IoAdapter` - `@nestjs/platform-socket.io`

Also, `FileInterceptor` (and other `multer` related interceptors) are now exported from `@nestjs/platform-express` (because `multer` library is not compatible with `fastify`).

#### Metadata reflection[#](/migration-guide#metadata-reflection)

The `@ReflectMetadata()` decorator has been deprecated and will be removed in the next major release (for now it will only display a warning). Use the `@SetMetadata()` decorator instead.

#### GraphQL[#](/migration-guide#graphql)

The subscriptions mechanism has been changed. Check [this](/v6/graphql/subscriptions) chapter for more details. Additionally, `@nestjs/graphql` package was heavily relying on `@ReflectMetadata()` (which has been deprecated) so it's required to update the package itself as well.

#### Express instance[#](/migration-guide#express-instance)

We no longer support passing `express` instance as a second argument of the `NestFactory.create()` method. In order to pluck underlying HTTP adapter, use techniques described [here](/faq/http-adapter). Also, you can pass `ExpressAdapter` instead (simply pass your `express` instance as a constructor parameter `new ExpressAdapter(express)`).

```typescript

// Before (no longer supported)
const server = express();
const app = await NestFactory.create(ApplicationModule, server);

// After (potential solution)
const server = express();
const app = await NestFactory.create(
  ApplicationModule,
  new ExpressAdapter(server),
);
```

#### Deprecations[#](/migration-guide#deprecations)

All deprecations (from 4 to 5 version) have been finally removed.

#### TypeScript[#](/migration-guide#typescript)

Nest 6 supports the latest major release of [TypeScript](https://www.typescriptlang.org/) (3.0.0).

----
url: https://docs.nestjs.com/v6/faq/global-prefix
----

* [Global prefix](https://docs.nestjs.com/v6/faq/global-prefix#global-prefix)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/faq/global-prefix.md "Suggest Edits")

### Global prefix

To set a prefix for **every route** registered in an HTTP application, use the `setGlobalPrefix()` method of the `INestApplication` instance.

```typescript

const app = await NestFactory.create(AppModule);
app.setGlobalPrefix('v1');
```

----
url: https://docs.nestjs.com/v5/microservices/interceptors
----

### Interceptors

There is no difference between [regular interceptors](/v5/interceptors) and the microservices interceptors. Here is an example that makes use of a manually instantiated **method-scoped** guard (class-scoped works either):

TypeScript

```typescript

@UseInterceptors(new TransformInterceptor())
@MessagePattern({ cmd: 'sum' })
sum(data: number[]): number {
  return (data || []).reduce((a, b) => a + b);
}
```

----
url: https://docs.nestjs.com/v4/graphql/subscriptions
----

### Subscriptions

Subscription is just another GraphQL operation type like Query and Mutation. It allows creating real-time subscriptions over a bidirectional transport layer, mainly over websockets. Read more about the subscriptions [here](https://www.apollographql.com/docs/graphql-subscriptions).

Below is a `commentAdded` subscription example, copied & pasted directly from the official [Apollo](https://www.apollographql.com/docs/graphql-subscriptions/subscriptions-to-schema.html) documentation:

JavaScript TypeScript

TypeScript

```typescript

Subscription: {
  commentAdded: {
    subscribe: () => pubsub.asyncIterator('commentAdded')
  }
}
```

> **Notice** The `pubsub` is an instance of `PubSub` class. Read more about it [here](https://www.apollographql.com/docs/graphql-subscriptions/setup.html).

In order to create an equivalent subscription in Nest-way, we'll make use of the `@Subscription()` decorator. Let's extend our `AuthorResolver` used in the [resolvers map](/v4/graphql/resolvers-map) section.

JavaScript TypeScript

TypeScript

```typescript

import { Query, Resolver, Subscription, ResolveProperty } from '@nestjs/graphql';
import { find, filter } from 'lodash';
import { PubSub } from 'graphql-subscriptions';

// example data
const authors = [
  { id: 1, firstName: 'Tom', lastName: 'Coleman' },
  { id: 2, firstName: 'Sashko', lastName: 'Stubailo' },
  { id: 3, firstName: 'Mikhail', lastName: 'Novikov' },
];
const posts = [
  { id: 1, authorId: 1, title: 'Introduction to GraphQL', votes: 2 },
  { id: 2, authorId: 2, title: 'Welcome to Meteor', votes: 3 },
  { id: 3, authorId: 2, title: 'Advanced GraphQL', votes: 1 },
  { id: 4, authorId: 3, title: 'Launchpad is Cool', votes: 7 },
];

// example pubsub
const pubsub = new PubSub();

@Resolver('Author')
export class AuthorResolver {
  @Query('author')
  getAuthor(obj, args, context, info) {
    return find(authors, { id: args.id });
  }

  @Subscription()
  commentAdded() {
    return {
      subscribe: () => pubsub.asyncIterator('commentAdded'),
    };
  }

  @ResolveProperty('posts')
  getPosts(author) {
    return filter(posts, { authorId: author.id });
  }
}
```

#### Refactor

We have used a local `PubSub` instance here. Instead, we should define `PubSub` as a **component**, inject it through the constructor (using `@Inject()` decorator), and reuse it across the entire application. You can read more about Nest custom components [here](/v4/fundamentals/dependency-injection).

#### Type definitions

The last step is to update type definitions ([read more](http://graphql.org/learn/schema/#type-language)) file.

author-types.graphql

Java

```java

type Author {
  id: Int!
  firstName: String
  lastName: String
  posts: [Post]
}

type Post {
  id: Int!
  title: String
  votes: Int
}

type Query {
  author(id: Int!): Author
}

type Comment {
  id: String
  content: String
}

type Subscription {
  commentAdded(repoFullName: String!): Comment
}
```

That's all. We created a single `commentAdded(repoFullName: String!): Comment` subscription.

#### Sponsors

[](https://valor-software.com/)

Nest is an MIT-licensed open source project. It can grow thanks to the support by these awesome people. If you'd like to join them, please read more [here](https://opencollective.com/nest). Thanks!

[](https://opencollective.com/nest/backer/0/website)[](https://opencollective.com/nest/backer/1/website)[](https://opencollective.com/nest/backer/2/website)[](https://opencollective.com/nest/backer/3/website)[](https://opencollective.com/nest/backer/4/website)[](https://opencollective.com/nest/backer/5/website)[](https://opencollective.com/nest/backer/6/website)[](https://opencollective.com/nest/backer/7/website)[](https://opencollective.com/nest/backer/8/website)[](https://opencollective.com/nest/backer/9/website)[](https://opencollective.com/nest/backer/10/website)[](https://opencollective.com/nest/backer/11/website)[](https://opencollective.com/nest/backer/12/website)[](https://opencollective.com/nest/backer/13/website)[](https://opencollective.com/nest/backer/14/website)[](https://opencollective.com/nest/backer/15/website)[](https://opencollective.com/nest/backer/16/website)[](https://opencollective.com/nest/backer/17/website)[](https://opencollective.com/nest/backer/18/website)[](https://opencollective.com/nest/backer/19/website)[](https://opencollective.com/nest/backer/20/website)[](https://opencollective.com/nest/backer/21/website)[](https://opencollective.com/nest/backer/22/website)[](https://opencollective.com/nest/backer/23/website)[](https://opencollective.com/nest/backer/24/website)[](https://opencollective.com/nest/backer/25/website)[](https://opencollective.com/nest/backer/26/website)[](https://opencollective.com/nest/backer/27/website)[](https://opencollective.com/nest/backer/28/website)[](https://opencollective.com/nest/backer/29/website)

[Become a sponsor](https://opencollective.com/nest)

----
url: https://docs.nestjs.com/v9/fundamentals/lifecycle-events
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Lifecycle Events](https://docs.nestjs.com/v9/fundamentals/lifecycle-events#lifecycle-events)
* [Lifecycle sequence](https://docs.nestjs.com/v9/fundamentals/lifecycle-events#lifecycle-sequence)
* [Lifecycle events](https://docs.nestjs.com/v9/fundamentals/lifecycle-events#lifecycle-events-1)
* [Usage](https://docs.nestjs.com/v9/fundamentals/lifecycle-events#usage)
* [Asynchronous initialization](https://docs.nestjs.com/v9/fundamentals/lifecycle-events#asynchronous-initialization)
* [Application shutdown](https://docs.nestjs.com/v9/fundamentals/lifecycle-events#application-shutdown)

| Lifecycle hook method           | Lifecycle event triggering the hook method call                                                                                                                                                              |
| ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `onModuleInit()`                | Called once the host module's dependencies have been resolved.                                                                                                                                               |
| `onApplicationBootstrap()`      | Called once all modules have been initialized, but before listening for connections.                                                                                                                         |
| `onModuleDestroy()`\*           | Called after a termination signal (e.g., `SIGTERM`) has been received.                                                                                                                                       |
| `beforeApplicationShutdown()`\* | Called after all `onModuleDestroy()` handlers have completed (Promises resolved or rejected); once complete (Promises resolved or rejected), all existing connections will be closed (`app.close()` called). |
| `onApplicationShutdown()`\*     | Called after connections close (`app.close()` resolves).                                                                                                                                                     |

\* For these events, if you're not calling `app.close()` explicitly, you must opt-in to make them work with system signals such as `SIGTERM`. See [Application shutdown](fundamentals/lifecycle-events#application-shutdown) below.

> **Warning** The lifecycle hooks listed above are not triggered for **request-scoped** classes. Request-scoped classes are not tied to the application lifecycle and their lifespan is unpredictable. They are exclusively created for each request and automatically garbage-collected after the response is sent.

> **Hint** Execution order of `onModuleInit()` and `onApplicationBootstrap()` directly depends on the order of module imports, awaiting the previous hook.

#### Usage[#](/fundamentals/lifecycle-events#usage)

Each lifecycle hook is represented by an interface. Interfaces are technically optional because they do not exist after TypeScript compilation. Nonetheless, it's good practice to use them in order to benefit from strong typing and editor tooling. To register a lifecycle hook, implement the appropriate interface. For example, to register a method to be called during module initialization on a particular class (e.g., Controller, Provider or Module), implement the `OnModuleInit` interface by supplying an `onModuleInit()` method, as shown below:

JS TS

```typescript

import { Injectable, OnModuleInit } from '@nestjs/common';

@Injectable()
export class UsersService implements OnModuleInit {
  onModuleInit() {
    console.log(`The module has been initialized.`);
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';

@Injectable()
export class UsersService {
  onModuleInit() {
    console.log(`The module has been initialized.`);
  }
}
```

#### Asynchronous initialization[#](/fundamentals/lifecycle-events#asynchronous-initialization)

Both the `OnModuleInit` and `OnApplicationBootstrap` hooks allow you to defer the application initialization process (return a `Promise` or mark the method as `async` and `await` an asynchronous method completion in the method body).

JS TS

```typescript

async onModuleInit(): Promise<void> {
  await this.fetch();
}
```

```typescript

async onModuleInit() {
  await this.fetch();
}
```

#### Application shutdown[#](/fundamentals/lifecycle-events#application-shutdown)

The `onModuleDestroy()`, `beforeApplicationShutdown()` and `onApplicationShutdown()` hooks are called in the terminating phase (in response to an explicit call to `app.close()` or upon receipt of system signals such as SIGTERM if opted-in). This feature is often used with [Kubernetes](https://kubernetes.io/) to manage containers' lifecycles, by [Heroku](https://www.heroku.com/) for dynos or similar services.

Shutdown hook listeners consume system resources, so they are disabled by default. To use shutdown hooks, you **must enable listeners** by calling `enableShutdownHooks()`:

```typescript

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);

  // Starts listening for shutdown hooks
  app.enableShutdownHooks();

  await app.listen(3000);
}
bootstrap();
```

> **warning** Due to inherent platform limitations, NestJS has limited support for application shutdown hooks on Windows. You can expect `SIGINT` to work, as well as `SIGBREAK` and to some extent `SIGHUP` - [read more](https://nodejs.org/api/process.html#process_signal_events). However `SIGTERM` will never work on Windows because killing a process in the task manager is unconditional, "i.e., there's no way for an application to detect or prevent it". Here's some [relevant documentation](https://docs.libuv.org/en/v1.x/signal.html) from libuv to learn more about how `SIGINT`, `SIGBREAK` and others are handled on Windows. Also, see Node.js documentation of [Process Signal Events](https://nodejs.org/api/process.html#process_signal_events)

> **Info**`enableShutdownHooks` consumes memory by starting listeners. In cases where you are running multiple Nest apps in a single Node process (e.g., when running parallel tests with Jest), Node may complain about excessive listener processes. For this reason, `enableShutdownHooks` is not enabled by default. Be aware of this condition when you are running multiple instances in a single Node process.

When the application receives a termination signal it will call any registered `onModuleDestroy()`, `beforeApplicationShutdown()`, then `onApplicationShutdown()` methods (in the sequence described above) with the corresponding signal as the first parameter. If a registered function awaits an asynchronous call (returns a promise), Nest will not continue in the sequence until the promise is resolved or rejected.

JS TS

```typescript

@Injectable()
class UsersService implements OnApplicationShutdown {
  onApplicationShutdown(signal: string) {
    console.log(signal); // e.g. "SIGINT"
  }
}
```

```typescript

@Injectable()
class UsersService implements OnApplicationShutdown {
  onApplicationShutdown(signal) {
    console.log(signal); // e.g. "SIGINT"
  }
}
```

> **Info** Calling `app.close()` doesn't terminate the Node process but only triggers the `onModuleDestroy()` and `onApplicationShutdown()` hooks, so if there are some intervals, long-running background tasks, etc. the process won't be automatically terminated.

----
url: https://docs.nestjs.com/v8/faq/common-errors
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Common errors](https://docs.nestjs.com/v8/faq/common-errors#common-errors)
* ["Cannot resolve dependency" error](https://docs.nestjs.com/v8/faq/common-errors#cannot-resolve-dependency-error)
* ["Circular dependency" error](https://docs.nestjs.com/v8/faq/common-errors#circular-dependency-error)
* [Debugging dependency errors](https://docs.nestjs.com/v8/faq/common-errors#debugging-dependency-errors)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/faq/errors.md "Suggest Edits")

### Common errors

During your development with NestJS, you may encounter various errors as you learn the framework.

#### "Cannot resolve dependency" error[#](/faq/common-errors#cannot-resolve-dependency-error)

Probably the most common error message is about Nest not being able to resolve dependencies of a provider. The error message usually looks something like this:

```bash

Nest can't resolve dependencies of the <provider> (?). Please make sure that the argument <unknown_token> at index [<index>] is available in the <module> context.

Potential solutions:
- If <unknown_token> is a provider, is it part of the current <module>?
- If <unknown_token> is exported from a separate @Module, is that module imported within <module>?
  @Module({
    imports: [ /* the Module containing <unknown_token> */ ]
  })
```

The most common culprit of the error, is not having the `<provider>` in the module's `providers` array. Please make sure that the provider is indeed in the `providers` array and following [standard NestJS provider practices](/fundamentals/custom-providers#di-fundamentals).

There are a few gotchas, that are common. One is putting a provider in an `imports` array. If this is the case, the error will have the provider's name where `<module>` should be.

If you run across this error while developing, take a look at the module mentioned in the error message and look at its `providers`. For each provider in the `providers` array, make sure the module has access to all of the dependencies. Often times, `providers` are duplicated in a "Feature Module" and a "Root Module" which means Nest will try to instantiate the provider twice. More than likely, the module containing the `<provider>` being duplicated should be added in the "Root Module"'s `imports` array instead.

If the `<unknown_token>` above is the string `dependency`, you might have a circular file import. This is different from the [circular dependency](/faq/common-errors#circular-dependency-error) below because instead of having providers depend on each other in their constructors, it just means that two files end up importing each other. A common case would be a module file declaring a token and importing a provider, and the provider import the token constant from the module file. If you are using barrel files, ensure that your barrel imports do not end up creating these circular imports as well.

If the `<unknown_token>` above is the string `Object`, it means that you're injecting using an type/interface without a proper provider's token. To fix that, make sure you're importing the class reference or use a custom token with `@Inject()` decorator. Read the [custom providers page](/v8/fundamentals/custom-providers).

Also, make sure you didn't end up injecting the provider on itself because self-injections are not allowed on NetJS. When this happens, `<unknown_token>` will likely be equal to `<provider>`.

If you are in a **monorepo setup**, you may face the same error as above but for core provider called `ModuleRef` as a `<unknown_token>`:

```bash

Nest can't resolve dependencies of the <provider> (?).
Please make sure that the argument ModuleRef at index [<index>] is available in the <module> context.
...
```

This likely happens when your project end up loading two Node modules of the package `@nestjs/core`, like this:

```text

.
├── package.json
├── apps
│   └── api
│       └── node_modules
│           └── @nestjs/bull
│               └── node_modules
│                   └── @nestjs/core
└── node_modules
    ├── (other packages)
    └── @nestjs/core
```

Solutions:

* For **Yarn** Workspaces, use the [nohoist feature](https://classic.yarnpkg.com/blog/2018/02/15/nohoist) to prevent hoisting the package `@nestjs/core`.

#### "Circular dependency" error[#](/faq/common-errors#circular-dependency-error)

Occasionally you'll find it difficult to avoid [circular dependencies](https://docs.nestjs.com/fundamentals/circular-dependency) in your application. You'll need to take some steps to help Nest resolve these. Errors that arise from circular dependencies look like this:

```bash

Nest cannot create the <module> instance.
The module at index [<index>] of the <module> "imports" array is undefined.

Potential causes:
- A circular dependency between modules. Use forwardRef() to avoid it. Read more: https://docs.nestjs.com/fundamentals/circular-dependency
- The module at index [<index>] is of type "undefined". Check your import statements and the type of the module.

Scope [<module_import_chain>]
# example chain AppModule -> FooModule
```

Circular dependencies can arise from both providers depending on each other, or typescript files depending on each other for constants, such as exporting constants from a module file and importing them in a service file. In the latter case, it is advised to create a separate file for your constants. In the former case, please follow the guide on circular dependencies and make sure that both the modules **and** the providers are marked with `forwardRef`.

#### Debugging dependency errors[#](/faq/common-errors#debugging-dependency-errors)

Along with just manually verifying your dependencies are correct, as of Nest 8.1.0 you can set the `NEST_DEBUG` environment variable to a string that resolves as truthy, and get extra logging information while Nest is resolving all of the dependencies for the application.

In the above image, the string in yellow is the host class of the dependency being injected, the string in blue is the name of the injected dependency, or its injection token, and the string in purple is the module in which the dependency is being searched for. Using this, you can usually trace back the dependency resolution for what's happening and why you're getting dependency injection problems.

----
url: https://docs.nestjs.com/v9/cli/libraries
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Libraries](https://docs.nestjs.com/v9/cli/libraries#libraries)
* [Nest libraries](https://docs.nestjs.com/v9/cli/libraries#nest-libraries)
* [Creating libraries](https://docs.nestjs.com/v9/cli/libraries#creating-libraries)
* [Using libraries](https://docs.nestjs.com/v9/cli/libraries#using-libraries)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/cli/libraries.md "Suggest Edits")

### Libraries

Many applications need to solve the same general problems, or re-use a modular component in several different contexts. Nest has a few ways of addressing this, but each works at a different level to solve the problem in a way that helps meet different architectural and organizational objectives.

Nest [modules](/v9/modules) are useful for providing an execution context that enables sharing components within a single application. Modules can also be packaged with [npm](https://npmjs.com) to create a reusable library that can be installed in different projects. This can be an effective way to distribute configurable, re-usable libraries that can be used by different, loosely connected or unaffiliated organizations (e.g., by distributing/installing 3rd party libraries).

```bash

$ nest g library my-library
```

When you run the command, the `library` schematic prompts you for a prefix (AKA alias) for the library:

```bash

What prefix would you like to use for the library (default: @app)?
```

```javascript

...
{
    "my-library": {
      "type": "library",
      "root": "libs/my-library",
      "entryFile": "index",
      "sourceRoot": "libs/my-library/src",
      "compilerOptions": {
        "tsConfigPath": "libs/my-library/tsconfig.lib.json"
      }
}
...
```

There are two differences in `nest-cli.json` metadata between libraries and applications:

* the `"type"` property is set to `"library"` instead of `"application"`
* the `"entryFile"` property is set to `"index"` instead of `"main"`

These differences key the build process to handle libraries appropriately. For example, a library exports its functions through the `index.js` file.

As with application-type projects, libraries each have their own `tsconfig.lib.json` file that extends the root (monorepo-wide) `tsconfig.json` file. You can modify this file, if necessary, to provide library-specific compiler options.

You can build the library with the CLI command:

```bash

$ nest build my-library
```

#### Using libraries[#](/cli/libraries#using-libraries)

With the automatically generated configuration files in place, using libraries is straightforward. How would we import `MyLibraryService` from the `my-library` library into the `my-project` application?

First, note that using library modules is the same as using any other Nest module. What the monorepo does is manage paths in a way that importing libraries and generating builds is now transparent. To use `MyLibraryService`, we need to import its declaring module. We can modify `my-project/src/app.module.ts` as follows to import `MyLibraryModule`.

```typescript

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { MyLibraryModule } from '@app/my-library';

@Module({
  imports: [MyLibraryModule],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}
```

Notice above that we've used a path alias of `@app` in the ES module `import` line, which was the `prefix` we supplied with the `nest g library` command above. Under the covers, Nest handles this through tsconfig path mapping. When adding a library, Nest updates the global (monorepo) `tsconfig.json` file's `"paths"` key like this:

```javascript

"paths": {
    "@app/my-library": [
        "libs/my-library/src"
    ],
    "@app/my-library/*": [
        "libs/my-library/src/*"
    ]
}
```

So, in a nutshell, the combination of the monorepo and library features has made it easy and intuitive to include library modules into applications.

This same mechanism enables building and deploying applications that compose libraries. Once you've imported the `MyLibraryModule`, running `nest build` handles all the module resolution automatically and bundles the app along with any library dependencies, for deployment. The default compiler for a monorepo is **webpack**, so the resulting distribution file is a single file that bundles all of the transpiled JavaScript files into a single file. You can also switch to `tsc` as described [here](https://docs.nestjs.com/cli/monorepo#global-compiler-options).

----
url: https://docs.nestjs.com/v8/techniques/logger
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Logger](https://docs.nestjs.com/v8/techniques/logger#logger)
* [Basic customization](https://docs.nestjs.com/v8/techniques/logger#basic-customization)
* [Custom implementation](https://docs.nestjs.com/v8/techniques/logger#custom-implementation)
* [Extend built-in logger](https://docs.nestjs.com/v8/techniques/logger#extend-built-in-logger)
* [Dependency injection](https://docs.nestjs.com/v8/techniques/logger#dependency-injection)
* [Using the logger for application logging](https://docs.nestjs.com/v8/techniques/logger#using-the-logger-for-application-logging)
* [Injecting a custom logger](https://docs.nestjs.com/v8/techniques/logger#injecting-a-custom-logger)
* [Use external logger](https://docs.nestjs.com/v8/techniques/logger#use-external-logger)

```typescript

const app = await NestFactory.create(AppModule, {
  logger: false,
});
await app.listen(3000);
```

To enable specific logging levels, set the `logger` property to an array of strings specifying the log levels to display, as follows:

```typescript

const app = await NestFactory.create(AppModule, {
  logger: ['error', 'warn'],
});
await app.listen(3000);
```

Values in the array can be any combination of `'log'`, `'error'`, `'warn'`, `'debug'`, and `'verbose'`.

> **Hint** To disable color in the default logger's messages, set the `NO_COLOR` environment variable to some non-empty string.

#### Custom implementation[#](/techniques/logger#custom-implementation)

You can provide a custom logger implementation to be used by Nest for system logging by setting the value of the `logger` property to an object that fulfills the `LoggerService` interface. For example, you can tell Nest to use the built-in global JavaScript `console` object (which implements the `LoggerService` interface), as follows:

```typescript

const app = await NestFactory.create(AppModule, {
  logger: console,
});
await app.listen(3000);
```

Implementing your own custom logger is straightforward. Simply implement each of the methods of the `LoggerService` interface as shown below.

```typescript

import { LoggerService } from '@nestjs/common';

export class MyLogger implements LoggerService {
  /**
   * Write a 'log' level log.
   */
  log(message: any, ...optionalParams: any[]) {}

  /**
   * Write an 'error' level log.
   */
  error(message: any, ...optionalParams: any[]) {}

  /**
   * Write a 'warn' level log.
   */
  warn(message: any, ...optionalParams: any[]) {}

  /**
   * Write a 'debug' level log.
   */
  debug?(message: any, ...optionalParams: any[]) {}

  /**
   * Write a 'verbose' level log.
   */
  verbose?(message: any, ...optionalParams: any[]) {}
}
```

You can then supply an instance of `MyLogger` via the `logger` property of the Nest application options object.

```typescript

const app = await NestFactory.create(AppModule, {
  logger: new MyLogger(),
});
await app.listen(3000);
```

This technique, while simple, doesn't utilize dependency injection for the `MyLogger` class. This can pose some challenges, particularly for testing, and limit the reusability of `MyLogger`. For a better solution, see the [Dependency Injection](techniques/logger#dependency-injection) section below.

#### Extend built-in logger[#](/techniques/logger#extend-built-in-logger)

Rather than writing a logger from scratch, you may be able to meet your needs by extending the built-in `ConsoleLogger` class and overriding selected behavior of the default implementation.

```typescript

import { ConsoleLogger } from '@nestjs/common';

export class MyLogger extends ConsoleLogger {
  error(message: any, stack?: string, context?: string) {
    // add your tailored logic here
    super.error(...arguments);
  }
}
```

```typescript

import { Module } from '@nestjs/common';
import { MyLogger } from './my-logger.service';

@Module({
  providers: [MyLogger],
  exports: [MyLogger],
})
export class LoggerModule {}
```

With this construct, you are now providing your custom logger for use by any other module. Because your `MyLogger` class is part of a module, it can use dependency injection (for example, to inject a `ConfigService`). There's one more technique needed to provide this custom logger for use by Nest for system logging (e.g., for bootstrapping and error handling).

Because application instantiation (`NestFactory.create()`) happens outside the context of any module, it doesn't participate in the normal Dependency Injection phase of initialization. So we must ensure that at least one application module imports the `LoggerModule` to trigger Nest to instantiate a singleton instance of our `MyLogger` class.

We can then instruct Nest to use the same singleton instance of `MyLogger` with the following construction:

```typescript

const app = await NestFactory.create(ApplicationModule, {
  bufferLogs: true,
});
app.useLogger(app.get(MyLogger));
await app.listen(3000);
```

> **Note** In the example above, we set the `bufferLogs` to `true` to make sure all logs will be buffered until a custom logger is attached (`MyLogger` in this case) and the application initialisation process either completes or fails. If the initialisation process fails, Nest will fallback to the original `ConsoleLogger` to print out any reported error messages. Also, you can set the `autoFlushLogs` to `false` (default `true`) to manually flush logs (using the `Logger#flush()` method).

Here we use the `get()` method on the `NestApplication` instance to retrieve the singleton instance of the `MyLogger` object. This technique is essentially a way to "inject" an instance of a logger for use by Nest. The `app.get()` call retrieves the singleton instance of `MyLogger`, and depends on that instance being first injected in another module, as described above.

You can also inject this `MyLogger` provider in your feature classes, thus ensuring consistent logging behavior across both Nest system logging and application logging. See [Using the logger for application logging](techniques/logger#using-the-logger-for-application-logging) and [Injecting a custom logger](techniques/logger#injecting-a-custom-logger) below for more information.

#### Using the logger for application logging[#](/techniques/logger#using-the-logger-for-application-logging)

We can combine several of the techniques above to provide consistent behavior and formatting across both Nest system logging and our own application event/message logging.

A good practice is to instantiate `Logger` class from `@nestjs/common` in each of our services. We can supply our service name as the `context` argument in the `Logger` constructor, like so:

```typescript

import { Logger, Injectable } from '@nestjs/common';

@Injectable()
class MyService {
  private readonly logger = new Logger(MyService.name);

  doSomething() {
    this.logger.log('Doing something...');
  }
}
```

In the default logger implementation, `context` is printed in the square brackets, like `NestFactory` in the example below:

```bash

[Nest] 19096   - 12/08/2019, 7:12:59 AM   [NestFactory] Starting Nest application...
```

If we supply a custom logger via `app.useLogger()`, it will actually be used by Nest internally. That means that our code remains implementation agnostic, while we can easily substitute the default logger for our custom one by calling `app.useLogger()`.

That way if we follow the steps from the previous section and call `app.useLogger(app.get(MyLogger))`, the following calls to `this.logger.log()` from `MyService` would result in calls to method `log` from `MyLogger` instance.

This should be suitable for most cases. But if you need more customization (like adding and calling custom methods), move to the next section.

#### Injecting a custom logger[#](/techniques/logger#injecting-a-custom-logger)

To start, extend the built-in logger with code like the following. We supply the `scope` option as configuration metadata for the `ConsoleLogger` class, specifying a [transient](/v8/fundamentals/injection-scopes) scope, to ensure that we'll have a unique instance of the `MyLogger` in each feature module. In this example, we do not extend the individual `ConsoleLogger` methods (like `log()`, `warn()`, etc.), though you may choose to do so.

```typescript

import { Injectable, Scope, ConsoleLogger } from '@nestjs/common';

@Injectable({ scope: Scope.TRANSIENT })
export class MyLogger extends ConsoleLogger {
  customLog() {
    this.log('Please feed the cat!');
  }
}
```

Next, create a `LoggerModule` with a construction like this:

```typescript

import { Module } from '@nestjs/common';
import { MyLogger } from './my-logger.service';

@Module({
  providers: [MyLogger],
  exports: [MyLogger],
})
export class LoggerModule {}
```

Next, import the `LoggerModule` into your feature module. Since we extended default `Logger` we have the convenience of using `setContext` method. So we can start using the context-aware custom logger, like this:

```typescript

import { Injectable } from '@nestjs/common';
import { MyLogger } from './my-logger.service';

@Injectable()
export class CatsService {
  private readonly cats: Cat[] = [];

  constructor(private myLogger: MyLogger) {
    // Due to transient scope, CatsService has its own unique instance of MyLogger,
    // so setting context here will not affect other instances in other services
    this.myLogger.setContext('CatsService');
  }

  findAll(): Cat[] {
    // You can call all the default methods
    this.myLogger.warn('About to return cats!');
    // And your custom methods
    this.myLogger.customLog();
    return this.cats;
  }
}
```

Finally, instruct Nest to use an instance of the custom logger in your `main.ts` file as shown below. Of course in this example, we haven't actually customized the logger behavior (by extending the `Logger` methods like `log()`, `warn()`, etc.), so this step isn't actually needed. But it **would** be needed if you added custom logic to those methods and wanted Nest to use the same implementation.

```typescript

const app = await NestFactory.create(ApplicationModule, {
  bufferLogs: true,
});
app.useLogger(new MyLogger());
await app.listen(3000);
```

> **Hint** Alternatively, instead of setting `bufferLogs` to `true`, you could temporarily disable the logger with `logger: false` instruction. Be mindful that if you supply `logger: false` to `NestFactory.create`, nothing will be logged until you call `useLogger`, so you may miss some important initialization errors. If you don't mind that some of your initial messages will be logged with the default logger, you can just omit the `logger: false` option.

#### Use external logger[#](/techniques/logger#use-external-logger)

Production applications often have specific logging requirements, including advanced filtering, formatting and centralized logging. Nest's built-in logger is used for monitoring Nest system behavior, and can also be useful for basic formatted text logging in your feature modules while in development, but production applications often take advantage of dedicated logging modules like [Winston](https://github.com/winstonjs/winston). As with any standard Node.js application, you can take full advantage of such modules in Nest.

----
url: https://docs.nestjs.com/v7/controllers
----

* [Controllers](https://docs.nestjs.com/v7/controllers#controllers)
* [Routing](https://docs.nestjs.com/v7/controllers#routing)
* [Request object](https://docs.nestjs.com/v7/controllers#request-object)
* [Resources](https://docs.nestjs.com/v7/controllers#resources)
* [Route wildcards](https://docs.nestjs.com/v7/controllers#route-wildcards)
* [Status code](https://docs.nestjs.com/v7/controllers#status-code)
* [Headers](https://docs.nestjs.com/v7/controllers#headers)
* [Redirection](https://docs.nestjs.com/v7/controllers#redirection)
* [Route parameters](https://docs.nestjs.com/v7/controllers#route-parameters)
* [Sub-Domain Routing](https://docs.nestjs.com/v7/controllers#sub-domain-routing)
* [Scopes](https://docs.nestjs.com/v7/controllers#scopes)
* [Asynchronicity](https://docs.nestjs.com/v7/controllers#asynchronicity)
* [Request payloads](https://docs.nestjs.com/v7/controllers#request-payloads)
* [Handling errors](https://docs.nestjs.com/v7/controllers#handling-errors)
* [Full resource sample](https://docs.nestjs.com/v7/controllers#full-resource-sample)
* [Getting up and running](https://docs.nestjs.com/v7/controllers#getting-up-and-running)
* [Library-specific approach](https://docs.nestjs.com/v7/controllers#library-specific-approach)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/controllers.md "Suggest Edits")

### Controllers

Controllers are responsible for handling incoming **requests** and returning **responses** to the client.

A controller's purpose is to receive specific requests for the application. The **routing** mechanism controls which controller receives which requests. Frequently, each controller has more than one route, and different routes can perform different actions.

In order to create a basic controller, we use classes and **decorators**. Decorators associate classes with required metadata and enable Nest to create a routing map (tie requests to the corresponding controllers).

> **Hint** For quickly creating a CRUD controller with the [validation](https://docs.nestjs.com/techniques/validation) built-in, you may use the CLI's [CRUD generator](https://docs.nestjs.com/recipes/crud-generator#crud-generator): `nest g resource [name]`.

#### Routing[#](/controllers#routing)

In the following example we'll use the `@Controller()` decorator, which is **required** to define a basic controller. We'll specify an optional route path prefix of `cats`. Using a path prefix in a `@Controller()` decorator allows us to easily group a set of related routes, and minimize repetitive code. For example, we may choose to group a set of routes that manage interactions with a customer entity under the route `/customers`. In that case, we could specify the path prefix `customers` in the `@Controller()` decorator so that we don't have to repeat that portion of the path for each route in the file.

cats.controller.ts

JS TS

```typescript

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

@Controller('cats')
export class CatsController {
  @Get()
  findAll(): string {
    return 'This action returns all cats';
  }
}
```

```typescript

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

@Controller('cats')
export class CatsController {
  @Get()
  findAll() {
    return 'This action returns all cats';
  }
}
```

> **Hint** To create a controller using the CLI, simply execute the `$ nest g controller cats` command.

The `@Get()` HTTP request method decorator before the `findAll()` method tells Nest to create a handler for a specific endpoint for HTTP requests. The endpoint corresponds to the HTTP request method (GET in this case) and the route path. What is the route path? The route path for a handler is determined by concatenating the (optional) prefix declared for the controller, and any path specified in the request decorator. Since we've declared a prefix for every route ( `cats`), and haven't added any path information in the decorator, Nest will map `GET /cats` requests to this handler. As mentioned, the path includes both the optional controller path prefix **and** any path string declared in the request method decorator. For example, a path prefix of `customers` combined with the decorator `@Get('profile')` would produce a route mapping for requests like `GET /customers/profile`.

In our example above, when a GET request is made to this endpoint, Nest routes the request to our user-defined `findAll()` method. Note that the method name we choose here is completely arbitrary. We obviously must declare a method to bind the route to, but Nest doesn't attach any significance to the method name chosen.

This method will return a 200 status code and the associated response, which in this case is just a string. Why does that happen? To explain, we'll first introduce the concept that Nest employs two **different** options for manipulating responses:

|                        |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Standard (recommended) | Using this built-in method, when a request handler returns a JavaScript object or array, it will **automatically** be serialized to JSON. When it returns a JavaScript primitive type (e.g., `string`, `number`, `boolean`), however, Nest will send just the value without attempting to serialize it. This makes response handling simple: just return the value, and Nest takes care of the rest. Furthermore, the response's **status code** is always 200 by default, except for POST requests which use 201. We can easily change this behavior by adding the `@HttpCode(...)` decorator at a handler-level (see [Status codes](controllers#status-code)). |
| Library-specific       | We can use the library-specific (e.g., Express) [response object](https://expressjs.com/en/api.html#res), which can be injected using the `@Res()` decorator in the method handler signature (e.g., `findAll(@Res() response)`). With this approach, you have the ability to use the native response handling methods exposed by that object. For example, with Express, you can construct responses using code like `response.status(200).send()`.                                                                                                                                                                                                              |

> **Warning** Nest detects when the handler is using either `@Res()` or `@Next()`, indicating you have chosen the library-specific option. If both approaches are used at the same time, the Standard approach is **automatically disabled** for this single route and will no longer work as expected. To use both approaches at the same time (for example, by injecting the response object to only set cookies/headers but still leave the rest to the framework), you must set the `passthrough` option to `true` in the `@Res({ passthrough: true })` decorator.

## Official enterprise support

* **Providing technical guidance
* **Performing in-depth code reviews
* **Mentoring team members
* **Advising best practices

[Explore more](https://enterprise.nestjs.com "Enterprise | NestJS - A progressive Node.js framework")

#### Request object[#](/controllers#request-object)

Handlers often need access to the client **request** details. Nest provides access to the [request object](https://expressjs.com/en/api.html#req) of the underlying platform (Express by default). We can access the request object by instructing Nest to inject it by adding the `@Req()` decorator to the handler's signature.

cats.controller.ts

JS TS

```typescript

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

@Controller('cats')
export class CatsController {
  @Get()
  findAll(@Req() request: Request): string {
    return 'This action returns all cats';
  }
}
```

```typescript

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

@Controller('cats')
export class CatsController {
  @Get()
  @Bind(Req())
  findAll(request) {
    return 'This action returns all cats';
  }
}
```

> **Hint** In order to take advantage of `express` typings (as in the `request: Request` parameter example above), install `@types/express` package.

The request object represents the HTTP request and has properties for the request query string, parameters, HTTP headers, and body (read more [here](https://expressjs.com/en/api.html#req)). In most cases, it's not necessary to grab these properties manually. We can use dedicated decorators instead, such as `@Body()` or `@Query()`, which are available out of the box. Below is a list of the provided decorators and the plain platform-specific objects they represent.

|                           |                                     |
| ------------------------- | ----------------------------------- |
| `@Request(), @Req()`      | `req`                               |
| `@Response(), @Res()`\*   | `res`                               |
| `@Next()`                 | `next`                              |
| `@Session()`              | `req.session`                       |
| `@Param(key?: string)`    | `req.params` / `req.params[key]`    |
| `@Body(key?: string)`     | `req.body` / `req.body[key]`        |
| `@Query(key?: string)`    | `req.query` / `req.query[key]`      |
| `@Headers(name?: string)` | `req.headers` / `req.headers[name]` |
| `@Ip()`                   | `req.ip`                            |
| `@HostParam()`            | `req.hosts`                         |

\* For compatibility with typings across underlying HTTP platforms (e.g., Express and Fastify), Nest provides `@Res()` and `@Response()` decorators. `@Res()` is simply an alias for `@Response()`. Both directly expose the underlying native platform `response` object interface. When using them, you should also import the typings for the underlying library (e.g., `@types/express`) to take full advantage. Note that when you inject either `@Res()` or `@Response()` in a method handler, you put Nest into **Library-specific mode** for that handler, and you become responsible for managing the response. When doing so, you must issue some kind of response by making a call on the `response` object (e.g., `res.json(...)` or `res.send(...)`), or the HTTP server will hang.

> **Hint** To learn how to create your own custom decorators, visit [this](/v7/custom-decorators) chapter.

#### Resources[#](/controllers#resources)

Earlier, we defined an endpoint to fetch the cats resource (**GET** route). We'll typically also want to provide an endpoint that creates new records. For this, let's create the **POST** handler:

cats.controller.ts

JS TS

```typescript

import { Controller, Get, Post } from '@nestjs/common';

@Controller('cats')
export class CatsController {
  @Post()
  create(): string {
    return 'This action adds a new cat';
  }

  @Get()
  findAll(): string {
    return 'This action returns all cats';
  }
}
```

```typescript

import { Controller, Get, Post } from '@nestjs/common';

@Controller('cats')
export class CatsController {
  @Post()
  create() {
    return 'This action adds a new cat';
  }

  @Get()
  findAll() {
    return 'This action returns all cats';
  }
}
```

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.

#### Route wildcards[#](/controllers#route-wildcards)

Pattern based routes are supported as well. For instance, the asterisk is used as a wildcard, and will match any combination of characters.

```typescript

@Get('ab*cd')
findAll() {
  return 'This route uses a wildcard';
}
```

The `'ab*cd'` route path will match `abcd`, `ab_cd`, `abecd`, and so on. The characters `?`, `+`, `*`, and `()` may be used in a route path, and are subsets of their regular expression counterparts. The hyphen ( `-`) and the dot (`.`) are interpreted literally by string-based paths.

#### Status code[#](/controllers#status-code)

As mentioned, the response **status code** is always **200** by default, except for POST requests which are **201**. We can easily change this behavior by adding the `@HttpCode(...)` decorator at a handler level.

```typescript

@Post()
@HttpCode(204)
create() {
  return 'This action adds a new cat';
}
```

> **Hint** Import `HttpCode` from the `@nestjs/common` package.

Often, your status code isn't static but depends on various factors. In that case, you can use a library-specific **response** (inject using `@Res()`) object (or, in case of an error, throw an exception).

#### Headers[#](/controllers#headers)

To specify a custom response header, you can either use a `@Header()` decorator or a library-specific response object (and call `res.header()` directly).

```typescript

@Post()
@Header('Cache-Control', 'none')
create() {
  return 'This action adds a new cat';
}
```

> **Hint** Import `Header` from the `@nestjs/common` package.

#### Redirection[#](/controllers#redirection)

To redirect a response to a specific URL, you can either use a `@Redirect()` decorator or a library-specific response object (and call `res.redirect()` directly).

`@Redirect()` takes a required `url` argument, and an optional `statusCode` argument. The `statusCode` defaults to `302` (`Found`) if omitted.

```typescript

@Get()
@Redirect('https://nestjs.com', 301)
```

Sometimes you may want to determine the HTTP status code or the redirect URL dynamically. Do this by returning an object from the route handler method with the shape:

```json

{
  "url": string,
  "statusCode": number
}
```

Returned values will override any arguments passed to the `@Redirect()` decorator. For example:

```typescript

@Get('docs')
@Redirect('https://docs.nestjs.com', 302)
getDocs(@Query('version') version) {
  if (version && version === '5') {
    return { url: 'https://docs.nestjs.com/v5/' };
  }
}
```

#### Route parameters[#](/controllers#route-parameters)

Routes with static paths won't work when you need to accept **dynamic data** as part of the request (e.g., `GET /cats/1` to get cat with id `1`). In order to define routes with parameters, we can add route parameter **tokens** in the path of the route to capture the dynamic value at that position in the request URL. The route parameter token in the `@Get()` decorator example below demonstrates this usage. Route parameters declared in this way can be accessed using the `@Param()` decorator, which should be added to the method signature.

JS TS

```typescript

@Get(':id')
findOne(@Param() params): string {
  console.log(params.id);
  return `This action returns a #${params.id} cat`;
}
```

```typescript

@Get(':id')
@Bind(Param())
findOne(params) {
  console.log(params.id);
  return `This action returns a #${params.id} cat`;
}
```

`@Param()` is used to decorate a method parameter (`params` in the example above), and makes the **route** parameters available as properties of that decorated method parameter inside the body of the method. As seen in the code above, we can access the `id` parameter by referencing `params.id`. You can also pass in a particular parameter token to the decorator, and then reference the route parameter directly by name in the method body.

> **Hint** Import `Param` from the `@nestjs/common` package.

JS TS

```typescript

@Get(':id')
findOne(@Param('id') id: string): string {
  return `This action returns a #${id} cat`;
}
```

```typescript

@Get(':id')
@Bind(Param('id'))
findOne(id) {
  return `This action returns a #${id} cat`;
}
```

#### Sub-Domain Routing[#](/controllers#sub-domain-routing)

The `@Controller` decorator can take a `host` option to require that the HTTP host of the incoming requests matches some specific value.

```typescript

@Controller({ host: 'admin.example.com' })
export class AdminController {
  @Get()
  index(): string {
    return 'Admin page';
  }
}
```

> **Warning** Since **Fastify** lacks support for nested routers, when using sub-domain routing, the (default) Express adapter should be used instead.

Similar to a route `path`, the `hosts` option can use tokens to capture the dynamic value at that position in the host name. The host parameter token in the `@Controller()` decorator example below demonstrates this usage. Host parameters declared in this way can be accessed using the `@HostParam()` decorator, which should be added to the method signature.

```typescript

@Controller({ host: ':account.example.com' })
export class AccountController {
  @Get()
  getInfo(@HostParam('account') account: string) {
    return account;
  }
}
```

#### Scopes[#](/controllers#scopes)

For people coming from different programming language backgrounds, it might be unexpected to learn that in Nest, almost everything is shared across incoming requests. We have a connection pool to the database, singleton services with global state, etc. Remember that Node.js doesn't follow the request/response Multi-Threaded Stateless Model in which every request is processed by a separate thread. Hence, using singleton instances is fully **safe** for our applications.

However, there are edge-cases when request-based lifetime of the controller may be the desired behavior, for instance per-request caching in GraphQL applications, request tracking or multi-tenancy. Learn how to control scopes [here](/v7/fundamentals/injection-scopes).

#### Asynchronicity[#](/controllers#asynchronicity)

We love modern JavaScript and we know that data extraction is mostly **asynchronous**. That's why Nest supports and works well with `async` functions.

> **Hint** Learn more about `async / await` feature [here](https://kamilmysliwiec.com/typescript-2-1-introduction-async-await)

Every async function has to return a `Promise`. This means that you can return a deferred value that Nest will be able to resolve by itself. Let's see an example of this:

cats.controller.ts

JS TS

```typescript

@Get()
async findAll(): Promise<any[]> {
  return [];
}
```

```typescript

@Get()
async findAll() {
  return [];
}
```

The above code is fully valid. Furthermore, Nest route handlers are even more powerful by being able to return RxJS [observable streams](http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html). Nest will automatically subscribe to the source underneath and take the last emitted value (once the stream is completed).

cats.controller.ts

JS TS

```typescript

@Get()
findAll(): Observable<any[]> {
  return of([]);
}
```

```typescript

@Get()
findAll() {
  return of([]);
}
```

```typescript

export class CreateCatDto {
  name: string;
  age: number;
  breed: string;
}
```

It has only three basic properties. Thereafter we can use the newly created DTO inside the `CatsController`:

cats.controller.ts

JS TS

```typescript

@Post()
async create(@Body() createCatDto: CreateCatDto) {
  return 'This action adds a new cat';
}
```

```typescript

@Post()
@Bind(Body())
async create(createCatDto) {
  return 'This action adds a new cat';
}
```

#### Handling errors[#](/controllers#handling-errors)

There's a separate chapter about handling errors (i.e., working with exceptions) [here](/v7/exception-filters).

#### Full resource sample[#](/controllers#full-resource-sample)

Below is an example that makes use of several of the available decorators to create a basic controller. This controller exposes a couple of methods to access and manipulate internal data.

cats.controller.ts

JS TS

```typescript

import { Controller, Get, Query, Post, Body, Put, Param, Delete } from '@nestjs/common';
import { CreateCatDto, UpdateCatDto, ListAllEntities } from './dto';

@Controller('cats')
export class CatsController {
  @Post()
  create(@Body() createCatDto: CreateCatDto) {
    return 'This action adds a new cat';
  }

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

  @Get(':id')
  findOne(@Param('id') id: string) {
    return `This action returns a #${id} cat`;
  }

  @Put(':id')
  update(@Param('id') id: string, @Body() updateCatDto: UpdateCatDto) {
    return `This action updates a #${id} cat`;
  }

  @Delete(':id')
  remove(@Param('id') id: string) {
    return `This action removes a #${id} cat`;
  }
}
```

```typescript

import { Controller, Get, Query, Post, Body, Put, Param, Delete, Bind } from '@nestjs/common';

@Controller('cats')
export class CatsController {
  @Post()
  @Bind(Body())
  create(createCatDto) {
    return 'This action adds a new cat';
  }

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

  @Get(':id')
  @Bind(Param('id'))
  findOne(id) {
    return `This action returns a #${id} cat`;
  }

  @Put(':id')
  @Bind(Param('id'), Body())
  update(id, updateCatDto) {
    return `This action updates a #${id} cat`;
  }

  @Delete(':id')
  @Bind(Param('id'))
  remove(id) {
    return `This action removes a #${id} cat`;
  }
}
```

> **Hint** Nest CLI provides a generator (schematic) that automatically generates **all the boilerplate code** to help us avoid doing all of this, and make the developer experience much simpler. Read more about this feature [here](/v7/recipes/crud-generator).

#### Getting up and running[#](/controllers#getting-up-and-running)

With the above controller fully defined, Nest still doesn't know that `CatsController` exists and as a result won't create an instance of this class.

Controllers always belong to a module, which is why we include the `controllers` array within the `@Module()` decorator. Since we haven't yet defined any other modules except the root `AppModule`, we'll use that to introduce the `CatsController`:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { CatsController } from './cats/cats.controller';

@Module({
  controllers: [CatsController],
})
export class AppModule {}
```

```typescript

import { Controller, Get, Post, Res, HttpStatus } from '@nestjs/common';
import { Response } from 'express';

@Controller('cats')
export class CatsController {
  @Post()
  create(@Res() res: Response) {
    res.status(HttpStatus.CREATED).send();
  }

  @Get()
  findAll(@Res() res: Response) {
     res.status(HttpStatus.OK).json([]);
  }
}
```

```typescript

import { Controller, Get, Post, Bind, Res, Body, HttpStatus } from '@nestjs/common';

@Controller('cats')
export class CatsController {
  @Post()
  @Bind(Res(), Body())
  create(res, createCatDto) {
    res.status(HttpStatus.CREATED).send();
  }

  @Get()
  @Bind(Res())
  findAll(res) {
     res.status(HttpStatus.OK).json([]);
  }
}
```

Though this approach works, and does in fact allow for more flexibility in some ways by providing full control of the response object (headers manipulation, library-specific features, and so on), it should be used with care. In general, the approach is much less clear and does have some disadvantages. The main disadvantage is that your code become platform-dependent (as underlying libraries may have different APIs on the response object), and harder to test (you'll have to mock the response object, etc.).

Also, in the example above, you lose compatibility with Nest features that depend on Nest standard response handling, such as Interceptors and `@HttpCode()` / `@Header()` decorators. To fix this, you can set the `passthrough` option to `true`, as follows:

JS TS

```typescript

@Get()
findAll(@Res({ passthrough: true }) res: Response) {
  res.status(HttpStatus.OK);
  return [];
}
```

```typescript

@Get()
@Bind(Res({ passthrough: true }))
findAll(res) {
  res.status(HttpStatus.OK);
  return [];
}
```

Now you can interact with the native response object (for example, set cookies or headers depending on certain conditions), but leave the rest to the framework.

----
url: https://docs.nestjs.com/v5/techniques/caching
----

### Caching

Cache is a great and simple **technique** that helps in improving your app's performance. It acts as a temporary data store, which accessing is really performant.

#### Installation

We need to install the required package at first:

```bash
$ npm install --save cache-manager
```

#### In-memory cache

Nest provides a unified API for various cache storages. The built-in one is an in-memory data store. However, you can easily switch to a more comprehensive solution, like Redis. In order to enable caching, firstly import `CacheModule` and call its `register()` method.

TypeScript

```typescript

import { CacheModule, Module } from '@nestjs/common';
import { AppController } from './app.controller';

@Module({
  imports: [CacheModule.register()],
  controllers: [AppController],
})
export class ApplicationModule {}
```

Then just tie `CacheInterceptor` somewhere.

TypeScript

```typescript

@Controller()
@UseInterceptors(CacheInterceptor)
export class AppController {
  @Get()
  findAll(): string[] {
    return [];
  }
}
```

> **Warning** Only `GET` endpoints are cached.

#### Global cache

To reduce an amount of the required boilerplate, you can bind `CacheInterceptor` to each existing endpoint at once.

TypeScript

```typescript

import { CacheModule, Module, CacheInterceptor } from '@nestjs/common';
import { AppController } from './app.controller';
import { APP_INTERCEPTOR } from '@nestjs/core';

@Module({
  imports: [CacheModule.register()],
  controllers: [AppController],
  providers: [
    {
      provide: APP_INTERCEPTOR,
      useClass: CacheInterceptor,
    },
  ],
})
export class ApplicationModule {}
```

#### WebSockets & Microservices

Obviously, you can effortlessly apply `CacheInterceptor` to WebSocket subscribers as well as Microservice's patterns (regardless of transport method that is being used).

TypeScript

```typescript

@CacheKey('events')
@UseInterceptors(CacheInterceptor)
@SubscribeMessage('events')
onEvent(client, data): Observable<string[]> {
  return [];
}
```

> **Hint** The `@CacheKey()` decorator is imported from `@nestjs/common` package.

However, the additional `@CacheKey()` decorator is required in order to specify a key used to subsequently store and retrieve cached data. Besides, please note that you **shouldn't cache everything**. Actions which responsibility is to perform some business operations rather than simply querying the data should never be cached.

#### Customize caching

All cached data have its own expiration time (TTL). To customize default values, pass options object to the `register()` method.

TypeScript

```typescript

CacheModule.register({
  ttl: 5, // seconds
  max: 10, // maximum number of items in cache
})
```

#### Different stores

We take advantage of [cache-manager](https://github.com/BryanDonovan/node-cache-manager) under the hood. This package supports a wide-range of useful stores, for example, [Redis](https://github.com/dabroek/node-cache-manager-redis-store) store (full list [here](https://github.com/BryanDonovan/node-cache-manager#store-engines)). To set up the Redis store, simple pass the package together with correspoding options to the `register()` method.

TypeScript

```typescript

import * as redisStore from 'cache-manager-redis-store';
import { CacheModule, Module } from '@nestjs/common';
import { AppController } from './app.controller';

@Module({
  imports: [CacheModule.register({
    store: redisStore,
    host: 'localhost',
    port: 6379,
  })],
  controllers: [AppController],
})
export class ApplicationModule {}
```

#### Adjust tracking

By default, Nest uses request URL (in HTTP app) or cache key (in websockets and microservices) set through `@CacheKey()` decorator to associate cache records with your endpoints. Nevertheless, sometimes you might want to set up tracking based on different factors, for example, using HTTP headers (e.g. `Authorization` to properly identify `profile` endpoints).

In order to achieve that, create a subclass of `CacheInterceptor` and override `trackBy()` method.

TypeScript

```typescript

@Injectable()
class HttpCacheInterceptor extends CacheInterceptor {
  trackBy(context: ExecutionContext): string | undefined {
    return 'key';
  }
}
```

#### Async configuration

Quite often you might want to asynchronously pass your module options instead of passing them beforehand. In such case, use `registerAsync()` method, that provides a couple of various ways to deal with async data.

First possible approach is to use a factory function:

TypeScript

```typescript

CacheModule.forRootAsync({
  useFactory: () => ({
    ttl: 5,
  }),
})
```

Obviously, our factory behaves like every other one (might be `async` and is able to inject dependencies through `inject`).

TypeScript

```typescript

CacheModule.forRootAsync({
  imports: [ConfigModule],
  useFactory: async (configService: ConfigService) => ({
    ttl: configService.getString('CACHE_TTL'),
  }),
  inject: [ConfigService],
})
```

Alternatively, you are able to use class instead of a factory.

TypeScript

```typescript

CacheModule.forRootAsync({
  useClass: CacheConfigService,
})
```

Above construction will instantiate `CacheConfigService` inside `CacheModule` and will leverage it to create options object. The `CacheConfigService` has to implement `CacheOptionsFactory` interface.

TypeScript

```typescript

@Injectable()
class CacheConfigService implements CacheOptionsFactory {
  createCacheOptions(): CacheModuleOptions {
    return {
      ttl: 5,
    };
  }
}
```

In order to prevent the creation of `CacheConfigService` inside `CacheModule` and use a provider imported from a different module, you can use the `useExisting` syntax.

TypeScript

```typescript

CacheModule.forRootAsync({
  imports: [ConfigModule],
  useExisting: ConfigService,
})
```

It works the same as `useClass` with one critical difference - `CacheModule` will lookup imported modules to reuse already created `ConfigService`, instead of instantiating it on its own.

* Caching
* Installation
* In-memory cache
* Global cache
* WebSockets & Microservices
* Customize caching
* Different stores
* Adjust tracking

----
url: https://docs.nestjs.com/reliability/terminus
----

[Skip to content](#content)

On this page

* [Health checks](https://docs.nestjs.com/reliability/terminus#health-checks)
* [Getting started](https://docs.nestjs.com/reliability/terminus#getting-started)
* [Setting up a Healthcheck](https://docs.nestjs.com/reliability/terminus#setting-up-a-healthcheck)
* [HTTP Healthcheck](https://docs.nestjs.com/reliability/terminus#http-healthcheck)
* [TypeOrm health indicator](https://docs.nestjs.com/reliability/terminus#typeorm-health-indicator)
* [Disk health indicator](https://docs.nestjs.com/reliability/terminus#disk-health-indicator)
* [Memory health indicator](https://docs.nestjs.com/reliability/terminus#memory-health-indicator)
* [Custom health indicator](https://docs.nestjs.com/reliability/terminus#custom-health-indicator)
* [Timeouts and caching](https://docs.nestjs.com/reliability/terminus#timeouts-and-caching)
* [Logging](https://docs.nestjs.com/reliability/terminus#logging)
* [Graceful shutdown timeout](https://docs.nestjs.com/reliability/terminus#graceful-shutdown-timeout)
* [More examples](https://docs.nestjs.com/reliability/terminus#more-examples)

### Health checks

The Terminus integration provides **readiness/liveness** health checks. Health checks are crucial in complex backend setups. In web development, a health check usually consists of a dedicated address, for example, `https://my-website.com/health/readiness`. A service or component of your infrastructure (e.g., [Kubernetes](https://kubernetes.io/)) checks this address continuously. Depending on the HTTP status code returned from a `GET` request to this address, the service takes action when it receives an "unhealthy" response. Because the definition of "healthy" or "unhealthy" varies with the type of service you provide, the **Terminus** integration offers a set of **health indicators**.

For example, if your web server uses MongoDB to store its data, whether MongoDB is still up and running is vital information. In that case, you can use the `MongooseHealthIndicator`. Once configured (as described below), your health check address returns a healthy or unhealthy HTTP status code, depending on whether MongoDB is running.

#### Getting started[#](/reliability/terminus#getting-started)

To get started with `@nestjs/terminus`, install the required dependency:

```bash

$ npm install --save @nestjs/terminus
```

#### Setting up a Healthcheck[#](/reliability/terminus#setting-up-a-healthcheck)

A health check represents a summary of **health indicators**. A health indicator checks whether a service is in a healthy or unhealthy state. A health check is positive if all the assigned health indicators are up and running. Because many applications need similar health indicators, [`@nestjs/terminus`](https://github.com/nestjs/terminus) provides a set of predefined indicators:

* `HttpHealthIndicator`
* `TypeOrmHealthIndicator`
* `MongooseHealthIndicator`
* `SequelizeHealthIndicator`
* `MikroOrmHealthIndicator`
* `PrismaHealthIndicator`
* `MicroserviceHealthIndicator`
* `GRPCHealthIndicator`
* `MemoryHealthIndicator`
* `DiskHealthIndicator`

To get started with our first health check, let's create the `HealthModule` and add the `TerminusModule` to its `imports` array.

> **Hint** To create the module using the [Nest CLI](/cli/overview), run the `$ nest g module health` command.

health.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { TerminusModule } from '@nestjs/terminus';

@Module({
  imports: [TerminusModule]
})
export class HealthModule {}
```

Health checks are executed by a [controller](/controllers), which you can generate with the [Nest CLI](/cli/overview).

```bash

$ nest g controller health
```

> **Hint** We highly recommend enabling shutdown hooks in your application. When they are enabled, the Terminus integration uses this lifecycle event to report the `'shutting_down'` status and to apply the [graceful shutdown timeout](/reliability/terminus#graceful-shutdown-timeout). Learn more in the [application shutdown](/fundamentals/lifecycle-events#application-shutdown) section.

#### HTTP Healthcheck[#](/reliability/terminus#http-healthcheck)

Once you have installed `@nestjs/terminus`, imported the `TerminusModule`, and created a new controller, you are ready to create a health check.

The `HttpHealthIndicator` requires the `@nestjs/axios` package, so make sure it is installed:

```bash

$ npm i --save @nestjs/axios axios
```

Now set up the `HealthController`:

health.controller.ts

JS TS

```typescript

import { Controller, Get } from '@nestjs/common';
import { HealthCheckService, HttpHealthIndicator, HealthCheck } from '@nestjs/terminus';

@Controller('health')
export class HealthController {
  constructor(
    private health: HealthCheckService,
    private http: HttpHealthIndicator,
  ) {}

  @Get()
  @HealthCheck()
  check() {
    return this.health.check([
      () => this.http.pingCheck('nestjs-docs', 'https://docs.nestjs.com'),
    ]);
  }
}
```

```typescript

import { Controller, Dependencies, Get } from '@nestjs/common';
import { HealthCheckService, HttpHealthIndicator, HealthCheck } from '@nestjs/terminus';

@Controller('health')
@Dependencies(HealthCheckService, HttpHealthIndicator)
export class HealthController {
  constructor(health, http) {
    this.health = health;
    this.http = http;
  }

  @Get()
  @HealthCheck()
  healthCheck() {
    return this.health.check([
      () => this.http.pingCheck('nestjs-docs', 'https://docs.nestjs.com'),
    ])
  }
}
```

health.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { TerminusModule } from '@nestjs/terminus';
import { HttpModule } from '@nestjs/axios';
import { HealthController } from './health.controller.js';

@Module({
  imports: [TerminusModule, HttpModule],
  controllers: [HealthController],
})
export class HealthModule {}
```

```typescript

import { Module } from '@nestjs/common';
import { TerminusModule } from '@nestjs/terminus';
import { HttpModule } from '@nestjs/axios';
import { HealthController } from './health.controller.js';

@Module({
  imports: [TerminusModule, HttpModule],
  controllers: [HealthController],
})
export class HealthModule {}
```

The health check now sends a `GET` request to the `https://docs.nestjs.com` address. If that address returns a healthy response, the route at `http://localhost:3000/health` returns the following object with a `200` status code:

```json

{
  "status": "ok",
  "info": {
    "nestjs-docs": {
      "status": "up"
    }
  },
  "error": {},
  "details": {
    "nestjs-docs": {
      "status": "up"
    }
  }
}
```

The `@nestjs/terminus` package exports the type of this response object as `HealthCheckResult`.

| `status`  | If any health indicator failed, the status is `'error'`. If no indicator failed but at least one is `'degraded'`, the status is `'degraded'`. If the Nest application is shutting down but still accepting HTTP requests, the status is `'shutting_down'`. | `'error' \| 'ok' \| 'degraded' \| 'shutting_down'` |
| --------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------- |
| `info`    | Object containing information about each health indicator whose status is `'up'` or `'degraded'`, in other words, "still serving".                                                                                                                         | `object`                                           |
| `error`   | Object containing information about each health indicator whose status is `'down'`, in other words, "unhealthy".                                                                                                                                           | `object`                                           |
| `details` | Object containing information about every health indicator.                                                                                                                                                                                                | `object`                                           |

##### Check for specific HTTP response codes[#](/reliability/terminus#check-for-specific-http-response-codes)

In certain cases, you might want to check for specific criteria and validate the response. For example, assume `https://my-external-service.com` returns a `204` response code. With `HttpHealthIndicator.responseCheck()`, you can check for that response code specifically and treat all other codes as unhealthy.

In the following example, any response code other than `204` is unhealthy. The third parameter is a function (sync or async) that returns a boolean indicating whether the response is considered healthy (`true`) or unhealthy (`false`).

health.controller.ts

JS TS

```typescript

// Within the `HealthController`-class

@Get()
@HealthCheck()
check() {
  return this.health.check([
    () =>
      this.http.responseCheck(
        'my-external-service',
        'https://my-external-service.com',
        (res) => res.status === 204,
      ),
  ]);
}
```

#### TypeOrm health indicator[#](/reliability/terminus#typeorm-health-indicator)

Terminus lets you add database checks to your health check. Before using this health indicator, read the [database](/data/typeorm) chapter and make sure your application's database connection is established.

> **Hint** Behind the scenes, the `TypeOrmHealthIndicator` executes a `SELECT 1` SQL command, which is commonly used to verify whether the database is still alive. For Oracle databases, it uses `SELECT 1 FROM DUAL`, and for SAP HANA, `SELECT now() FROM dummy`.

health.controller.ts

JS TS

```typescript

@Controller('health')
export class HealthController {
  constructor(
    private health: HealthCheckService,
    private db: TypeOrmHealthIndicator,
  ) {}

  @Get()
  @HealthCheck()
  check() {
    return this.health.check([
      () => this.db.pingCheck('database').withTimeout(1000),
    ]);
  }
}
```

```typescript

@Controller('health')
@Dependencies(HealthCheckService, TypeOrmHealthIndicator)
export class HealthController {
  constructor(health, db) {
    this.health = health;
    this.db = db;
  }

  @Get()
  @HealthCheck()
  healthCheck() {
    return this.health.check([
      () => this.db.pingCheck('database').withTimeout(1000),
    ])
  }
}
```

If your database is reachable, a `GET` request to `http://localhost:3000/health` returns the following JSON result:

```json

{
  "status": "ok",
  "info": {
    "database": {
      "status": "up",
      "responseTime": 12
    }
  },
  "error": {},
  "details": {
    "database": {
      "status": "up",
      "responseTime": 12
    }
  }
}
```

If your application uses [multiple databases](/data/typeorm#multiple-databases), inject each data source into your `HealthController`. Then, pass the data source reference to the `TypeOrmHealthIndicator` using the `connection` option.

health.controller.ts

JS TS

```typescript

@Controller('health')
export class HealthController {
  constructor(
    private health: HealthCheckService,
    private db: TypeOrmHealthIndicator,
    @InjectDataSource('albumsConnection')
    private albumsConnection: DataSource,
    @InjectDataSource()
    private defaultConnection: DataSource,
  ) {}

  @Get()
  @HealthCheck()
  check() {
    return this.health.check([
      () => this.db.pingCheck('albums-database', { connection: this.albumsConnection }).withTimeout(1000),
      () => this.db.pingCheck('database', { connection: this.defaultConnection }).withTimeout(1000),
    ]);
  }
}
```

#### Disk health indicator[#](/reliability/terminus#disk-health-indicator)

The `DiskHealthIndicator` checks how much storage is in use. To get started, inject the `DiskHealthIndicator` into your `HealthController`. The following example checks the storage used by the path `/` (on Windows, use `C:\\`). If more than 50% of the total storage space is used, the health check reports an unhealthy state.

health.controller.ts

JS TS

```typescript

@Controller('health')
export class HealthController {
  constructor(
    private readonly health: HealthCheckService,
    private readonly disk: DiskHealthIndicator,
  ) {}

  @Get()
  @HealthCheck()
  check() {
    return this.health.check([
      () => this.disk.checkStorage('storage', { path: '/', thresholdPercent: 0.5 }),
    ]);
  }
}
```

```typescript

@Controller('health')
@Dependencies(HealthCheckService, DiskHealthIndicator)
export class HealthController {
  constructor(health, disk) {
    this.health = health;
    this.disk = disk;
  }

  @Get()
  @HealthCheck()
  healthCheck() {
    return this.health.check([
      () => this.disk.checkStorage('storage', { path: '/', thresholdPercent: 0.5 }),
    ])
  }
}
```

The `DiskHealthIndicator.checkStorage()` method can also check against a fixed amount of space. The following example is unhealthy if the storage used by the path `/` exceeds 250GB.

health.controller.ts

JS TS

```typescript

// Within the `HealthController`-class

@Get()
@HealthCheck()
check() {
  return this.health.check([
    () => this.disk.checkStorage('storage', {  path: '/', threshold: 250 * 1024 * 1024 * 1024, })
  ]);
}
```

#### Memory health indicator[#](/reliability/terminus#memory-health-indicator)

Use the `MemoryHealthIndicator` to make sure your process doesn't exceed a certain memory limit. The following example checks the heap of your process.

> **Hint** The heap is the portion of memory where dynamically allocated memory resides. `checkHeap()` compares the `heapUsed` value reported by `process.memoryUsage()` (the V8 heap memory currently in use) against the given threshold in bytes.

health.controller.ts

JS TS

```typescript

@Controller('health')
export class HealthController {
  constructor(
    private health: HealthCheckService,
    private memory: MemoryHealthIndicator,
  ) {}

  @Get()
  @HealthCheck()
  check() {
    return this.health.check([
      () => this.memory.checkHeap('memory_heap', 150 * 1024 * 1024),
    ]);
  }
}
```

```typescript

@Controller('health')
@Dependencies(HealthCheckService, MemoryHealthIndicator)
export class HealthController {
  constructor(health, memory) {
    this.health = health;
    this.memory = memory;
  }

  @Get()
  @HealthCheck()
  healthCheck() {
    return this.health.check([
      () => this.memory.checkHeap('memory_heap', 150 * 1024 * 1024),
    ])
  }
}
```

You can also verify the RSS of your process with `MemoryHealthIndicator.checkRSS()`. The following example returns an unhealthy response code if your process has more than 150MB allocated.

> **Hint** RSS (Resident Set Size) shows how much memory is allocated to the process and held in RAM. It doesn't include memory that is swapped out. It does include memory from shared libraries, as long as the pages from those libraries are actually in memory, as well as all stack and heap memory.

health.controller.ts

JS TS

```typescript

// Within the `HealthController`-class

@Get()
@HealthCheck()
check() {
  return this.health.check([
    () => this.memory.checkRSS('memory_rss', 150 * 1024 * 1024),
  ]);
}
```

#### Custom health indicator[#](/reliability/terminus#custom-health-indicator)

In some cases, the predefined health indicators provided by `@nestjs/terminus` don't cover all of your health check requirements. In that case, you can create a custom health indicator.

Most health indicators follow the same pattern: run an operation, then mark the indicator as `'up'` if it succeeds and as `'down'` if it fails. The `HealthIndicatorService` implements this pattern with `attempt()`. To show how an indicator is structured, we will create an example `DogHealthIndicator`. This service should have the state `'up'` as long as an external dog API responds within one second.

dog.health.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { HealthIndicatorService } from '@nestjs/terminus';

@Injectable()
export class DogHealthIndicator {
  constructor(
    private readonly healthIndicatorService: HealthIndicatorService
  ) {}

  isHealthy(key: string) {
    return this.healthIndicatorService
      .check(key)
      .attempt(async ({ signal }) => {
        const response = await fetch('https://dog.ceo/api/breeds/list', { signal });
        const { message: breeds } = await response.json();

        return { breeds: breeds.length };
      })
      .withTimeout(1000);
  }
}
```

```typescript

import { Injectable, Dependencies } from '@nestjs/common';
import { HealthIndicatorService } from '@nestjs/terminus';

@Injectable()
@Dependencies(HealthIndicatorService)
export class DogHealthIndicator {
  constructor(healthIndicatorService) {
    this.healthIndicatorService = healthIndicatorService;
  }

  isHealthy(key) {
    return this.healthIndicatorService
      .check(key)
      .attempt(async ({ signal }) => {
        const response = await fetch('https://dog.ceo/api/breeds/list', { signal });
        const { message: breeds } = await response.json();

        return { breeds: breeds.length };
      })
      .withTimeout(1000);
  }
}
```

`attempt()` accepts a sync or async function and marks the indicator as `'up'` once it resolves. Any data the function returns is appended to the result. If the function throws, the indicator is marked as `'down'` and the error message is added to the result. In both cases, the time the function took is reported as `responseTime`. `withTimeout()` limits the attempt to the given number of milliseconds (see [Timeouts and caching](/reliability/terminus#timeouts-and-caching)).

Next, register the health indicator as a provider:

health.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { TerminusModule } from '@nestjs/terminus';
import { DogHealthIndicator } from './dog.health.js';
import { HealthController } from './health.controller.js';

@Module({
  controllers: [HealthController],
  imports: [TerminusModule],
  providers: [DogHealthIndicator]
})
export class HealthModule { }
```

> **Hint** In a real-world application, the `DogHealthIndicator` should be provided in a separate module, for example, `DogModule`, which is then imported by the `HealthModule`.

The last step is to add the new health indicator to the health check endpoint. Go back to the `HealthController` and add it to the `healthCheck()` method:

health.controller.ts

JS TS

```typescript

import { HealthCheckService, HealthCheck } from '@nestjs/terminus';
import { Controller, Get } from '@nestjs/common';
import { DogHealthIndicator } from './dog.health.js';

@Controller('health')
export class HealthController {
  constructor(
    private health: HealthCheckService,
    private dogHealthIndicator: DogHealthIndicator
  ) {}

  @Get()
  @HealthCheck()
  healthCheck() {
    return this.health.check([
      () => this.dogHealthIndicator.isHealthy('dog'),
    ])
  }
}
```

```typescript

import { HealthCheckService, HealthCheck } from '@nestjs/terminus';
import { Controller, Dependencies, Get } from '@nestjs/common';
import { DogHealthIndicator } from './dog.health.js';

@Controller('health')
@Dependencies(HealthCheckService, DogHealthIndicator)
export class HealthController {
  constructor(
    health,
    dogHealthIndicator
  ) {
    this.health = health;
    this.dogHealthIndicator = dogHealthIndicator;
  }

  @Get()
  @HealthCheck()
  healthCheck() {
    return this.health.check([
      () => this.dogHealthIndicator.isHealthy('dog'),
    ])
  }
}
```

If the API responds in time, the health check returns the following result:

```json

{
  "status": "ok",
  "info": {
    "dog": {
      "status": "up",
      "breeds": 98,
      "responseTime": 143
    }
  },
  "error": {},
  "details": {
    "dog": {
      "status": "up",
      "breeds": 98,
      "responseTime": 143
    }
  }
}
```

> **Hint** Terminus executes attempts itself, so you can pass an attempt to `health.check([...])` either directly (`this.dogHealthIndicator.isHealthy('dog')`) or wrapped in a function, as in the example above.

##### Explicit control with up() and down()[#](/reliability/terminus#explicit-control-with-up-and-down)

Sometimes "healthy" means more than "the operation didn't throw". To decide the state yourself, return `up()` or `down()` directly instead of using `attempt()`. Assume the dogs are now stored locally, and the indicator should only be healthy if every `Dog` has the type `'goodboy'`.

dog.health.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { HealthIndicatorService } from '@nestjs/terminus';

export interface Dog {
  name: string;
  type: string;
}

@Injectable()
export class DogHealthIndicator {
  constructor(
    private readonly healthIndicatorService: HealthIndicatorService
  ) {}

  private dogs: Dog[] = [
    { name: 'Fido', type: 'goodboy' },
    { name: 'Rex', type: 'badboy' },
  ];

  async isHealthy(key: string) {
    const indicator = this.healthIndicatorService.check(key);
    const badboys = this.dogs.filter(dog => dog.type === 'badboy');

    if (badboys.length > 0) {
      return indicator.down({ badboys: badboys.length });
    }

    return indicator.up();
  }
}
```

```typescript

import { Injectable, Dependencies } from '@nestjs/common';
import { HealthIndicatorService } from '@nestjs/terminus';

@Injectable()
@Dependencies(HealthIndicatorService)
export class DogHealthIndicator {
  constructor(healthIndicatorService) {
    this.healthIndicatorService = healthIndicatorService;
  }

  dogs = [
    { name: 'Fido', type: 'goodboy' },
    { name: 'Rex', type: 'badboy' },
  ];

  async isHealthy(key) {
    const indicator = this.healthIndicatorService.check(key);
    const badboys = this.dogs.filter(dog => dog.type === 'badboy');

    if (badboys.length > 0) {
      return indicator.down({ badboys: badboys.length });
    }

    return indicator.up();
  }
}
```

Both `up()` and `down()` accept either an object with additional data, which is appended to the result, or a string, which is added as the `message` property.

##### Degraded state[#](/reliability/terminus#degraded-state)

Not every problem justifies taking the application out of rotation. An unreachable cache, for example, slows the application down but doesn't break it. For such cases, an indicator can return `degraded()`. A degraded indicator doesn't fail the health check: it is listed under `info`, the overall status becomes `'degraded'`, and the HTTP status code stays `200`. Orchestrators keep routing traffic, while the state remains visible in monitoring.

cache.health.ts

JS TS

```typescript

@Injectable()
export class CacheHealthIndicator {
  constructor(
    private readonly healthIndicatorService: HealthIndicatorService,
    private readonly cache: CacheService,
  ) {}

  async isHealthy(key: string) {
    const indicator = this.healthIndicatorService.check(key);
    const hasCache = await this.cache.isConnected();

    if (!hasCache) {
      return indicator.degraded('cache unreachable, serving without cache');
    }

    return indicator.up();
  }
}
```

```json

{
  "status": "degraded",
  "info": {
    "cache": {
      "status": "degraded",
      "message": "cache unreachable, serving without cache"
    }
  },
  "error": {},
  "details": {
    "cache": {
      "status": "degraded",
      "message": "cache unreachable, serving without cache"
    }
  }
}
```

Like `up()` and `down()`, `degraded()` accepts either an object with additional data or a message string. As soon as any indicator is `'down'`, the overall status is `'error'` regardless of degraded indicators.

> **Warning** A health indicator built with `up()`, `down()`, and `degraded()` reports its state by returning one of them. An error thrown by such an indicator is treated as a bug, not an unhealthy state: it aborts the whole health check and results in a `500` response instead of a `503`. If your indicator wraps an operation that may throw, use `attempt()`, which translates a thrown error into a `'down'` state.

#### Timeouts and caching[#](/reliability/terminus#timeouts-and-caching)

Every check built with `attempt()` returns a `HealthCheckAttempt`. This includes your custom indicators as well as the built-in database, microservice, and gRPC indicators. Before the attempt is executed, you can configure it by chaining `withTimeout()` and `cacheFor()`.

##### Timeouts[#](/reliability/terminus#timeouts)

`withTimeout()` limits the attempt to the given number of milliseconds. Once the time is up, the indicator is marked as `'down'` and the `AbortSignal` passed to your function is aborted. Pass that `signal` to the underlying operation so that it is canceled as well, rather than lingering in the background.

health.controller.ts

JS TS

```typescript

// Within the `HealthController`-class
@Get()
@HealthCheck()
check() {
  return this.health.check([
    () => this.db.pingCheck('database').withTimeout(1500),
    () => this.dogHealthIndicator.isHealthy('dog'),
  ]);
}
```

If the dog API from the custom indicator doesn't respond within one second, the health check responds with the following result:

```json

{
  "status": "error",
  "info": {
    "database": {
      "status": "up",
      "responseTime": 12
    }
  },
  "error": {
    "dog": {
      "status": "down",
      "message": "timeout of 1000ms exceeded",
      "responseTime": 1001
    }
  },
  "details": {
    "database": {
      "status": "up",
      "responseTime": 12
    },
    "dog": {
      "status": "down",
      "message": "timeout of 1000ms exceeded",
      "responseTime": 1001
    }
  }
}
```

> **Warning** The `timeout` option of the built-in indicators (e.g., `this.db.pingCheck('database', { timeout: 1500 })`) is deprecated. Chain `.withTimeout()` on the returned attempt instead.

##### Caching[#](/reliability/terminus#caching)

Orchestrators typically poll health checks every few seconds, and some checks are too expensive to run on every request. `cacheFor()` caches the result of an attempt for the given number of milliseconds. While a fresh result exists, the function isn't executed again, and concurrent health checks share a single in-flight execution. The cache is shared across requests and keyed by the indicator key.

health.controller.ts

JS TS

```typescript

// Within the `HealthController`-class
@Get()
@HealthCheck()
check() {
  return this.health.check([
    () => this.db.pingCheck('database').withTimeout(1500).cacheFor(5000),
  ]);
}
```

Results served from the cache are marked with `cachedResponse: true`:

```json

{
  "status": "ok",
  "info": {
    "database": {
      "status": "up",
      "responseTime": 12,
      "cachedResponse": true
    }
  },
  "error": {},
  "details": {
    "database": {
      "status": "up",
      "responseTime": 12,
      "cachedResponse": true
    }
  }
}
```

#### Logging[#](/reliability/terminus#logging)

By default, Terminus logs an error when a health check fails. When a graceful shutdown timeout is configured, it also logs the progress of the shutdown. The `TerminusModule.forRoot()` method gives you more control over how errors are logged, and lets you take over logging entirely.

This section walks you through creating a custom logger, `TerminusLogger`. This logger extends the built-in `ConsoleLogger`, so you can choose which parts of the logger to override.

> **Hint** To learn more about custom loggers in Nest, see [injecting a custom logger](/application/logger#injecting-a-custom-logger).

terminus-logger.service.ts

JS TS

```typescript

import { Injectable, Scope, ConsoleLogger } from '@nestjs/common';

@Injectable({ scope: Scope.TRANSIENT })
export class TerminusLogger extends ConsoleLogger {
  error(message: any, stack?: string, context?: string): void;
  error(message: any, ...optionalParams: any[]): void;
  error(
    message: unknown,
    stack?: unknown,
    context?: unknown,
    ...rest: unknown[]
  ): void {
    // Override how error messages are logged here
  }
}
```

Once you have created your custom logger, pass it to `TerminusModule.forRoot()`:

health.module.ts

JS TS

```typescript

@Module({
imports: [
  TerminusModule.forRoot({
    logger: TerminusLogger,
  }),
],
})
export class HealthModule {}
```

To suppress all log messages from Terminus, including error messages, set the `logger` option to `false`:

health.module.ts

JS TS

```typescript

@Module({
imports: [
  TerminusModule.forRoot({
    logger: false,
  }),
],
})
export class HealthModule {}
```

You can also configure how health check errors are displayed in your logs.

| Error Log Style  | Description                                                                                                                   | Example |
| :--------------- | :---------------------------------------------------------------------------------------------------------------------------- | :------ |
| `json` (default) | Prints a summary of the health check result as a JSON object when a check fails                                               |         |
| `pretty`         | Prints a summary of the health check result in formatted boxes when a check fails, highlighting successful and failed results |         |

To change the log style, use the `errorLogStyle` configuration option:

health.module.ts

JS TS

```typescript

@Module({
  imports: [
    TerminusModule.forRoot({
      errorLogStyle: 'pretty',
    }),
  ]
})
export class HealthModule {}
```

#### Graceful shutdown timeout[#](/reliability/terminus#graceful-shutdown-timeout)

If your application needs to postpone its shutdown, Terminus can handle it for you with the `gracefulShutdownTimeoutMs` option (in milliseconds, `0` by default). This setting is particularly useful with an orchestrator such as Kubernetes. By setting a delay slightly longer than the readiness check interval, you can achieve zero downtime when shutting down containers: as soon as a termination signal is received, the health check reports `'shutting_down'` with a `503` status code, so the orchestrator stops routing new traffic while the application finishes in-flight requests during the delay.

health.module.ts

JS TS

```typescript

@Module({
  imports: [
    TerminusModule.forRoot({
      gracefulShutdownTimeoutMs: 1000,
    }),
  ]
})
export class HealthModule {}
```

> **Warning** The delay is only applied on `SIGTERM`, which is the signal orchestrators such as Kubernetes send when stopping a container. Other signals (e.g. `SIGINT` from `Ctrl+C`) still switch the health check to `'shutting_down'` but shut the application down immediately. Make sure [shutdown hooks](/fundamentals/lifecycle-events#application-shutdown) are enabled; otherwise, Terminus never receives the signal.

#### More examples[#](/reliability/terminus#more-examples)

More working examples are available in the [Terminus samples directory](https://github.com/nestjs/terminus/tree/master/sample).

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/reliability/terminus.md)

----
url: https://docs.nestjs.com/v11/websockets/adapter
----

* [Adapters](https://docs.nestjs.com/v11/websockets/adapter#adapters)
* [Extend socket.io](https://docs.nestjs.com/v11/websockets/adapter#extend-socketio)
* [Ws library](https://docs.nestjs.com/v11/websockets/adapter#ws-library)
* [Advanced (custom adapter)](https://docs.nestjs.com/v11/websockets/adapter#advanced-custom-adapter)
* [Example](https://docs.nestjs.com/v11/websockets/adapter#example)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/websockets/adapter.md "Suggest Edits")

### Adapters

The WebSockets module is platform-agnostic, hence, you can bring your own library (or even a native implementation) by making use of `WebSocketAdapter` interface. This interface forces to implement few methods described in the following table:

|                        |                                                                 |
| ---------------------- | --------------------------------------------------------------- |
| `create`               | Creates a socket instance based on passed arguments             |
| `bindClientConnect`    | Binds the client connection event                               |
| `bindClientDisconnect` | Binds the client disconnection event (optional\*)               |
| `bindMessageHandlers`  | Binds the incoming message to the corresponding message handler |
| `close`                | Terminates a server instance                                    |

#### Extend socket.io[#](/websockets/adapter#extend-socketio)

The [socket.io](https://github.com/socketio/socket.io) package is wrapped in an `IoAdapter` class. What if you would like to enhance the basic functionality of the adapter? For instance, your technical requirements require a capability to broadcast events across multiple load-balanced instances of your web service. For this, you can extend `IoAdapter` and override a single method which responsibility is to instantiate new socket.io servers. But first of all, let's install the required package.

> **Warning** To use socket.io with multiple load-balanced instances you either have to disable polling by setting `transports: ['websocket']` in your clients socket.io configuration or you have to enable cookie based routing in your load balancer. Redis alone is not enough. See [here](https://socket.io/docs/v4/using-multiple-nodes/#enabling-sticky-session) for more information.

```bash

$ npm i --save redis socket.io @socket.io/redis-adapter
```

Once the package is installed, we can create a `RedisIoAdapter` class.

```typescript

import { IoAdapter } from '@nestjs/platform-socket.io';
import { ServerOptions } from 'socket.io';
import { createAdapter } from '@socket.io/redis-adapter';
import { createClient } from 'redis';

export class RedisIoAdapter extends IoAdapter {
  private adapterConstructor: ReturnType<typeof createAdapter>;

  async connectToRedis(): Promise<void> {
    const pubClient = createClient({ url: `redis://localhost:6379` });
    const subClient = pubClient.duplicate();

    await Promise.all([pubClient.connect(), subClient.connect()]);

    this.adapterConstructor = createAdapter(pubClient, subClient);
  }

  createIOServer(port: number, options?: ServerOptions): any {
    const server = super.createIOServer(port, options);
    server.adapter(this.adapterConstructor);
    return server;
  }
}
```

Afterward, simply switch to your newly created Redis adapter.

```typescript

const app = await NestFactory.create(AppModule);
const redisIoAdapter = new RedisIoAdapter(app);
await redisIoAdapter.connectToRedis();

app.useWebSocketAdapter(redisIoAdapter);
```

#### Ws library[#](/websockets/adapter#ws-library)

Another available adapter is a `WsAdapter` which in turn acts like a proxy between the framework and integrate blazing fast and thoroughly tested [ws](https://github.com/websockets/ws) library. This adapter is fully compatible with native browser WebSockets and is far faster than socket.io package. Unluckily, it has significantly fewer functionalities available out-of-the-box. In some cases, you don't necessarily need them though.

> **Hint**`ws` library does not support namespaces (communication channels popularised by `socket.io`). However, to somehow mimic this feature, you can mount multiple `ws` servers on different paths (example: `@WebSocketGateway({ path: '/users' })`).

In order to use `ws`, we firstly have to install the required package:

```bash

$ npm i --save @nestjs/platform-ws
```

Once the package is installed, we can switch an adapter:

```typescript

const app = await NestFactory.create(AppModule);
app.useWebSocketAdapter(new WsAdapter(app));
```

> **Hint** The `WsAdapter` is imported from `@nestjs/platform-ws`.

The `wsAdapter` is designed to handle messages in the `{ event: string, data: any }` format. If you need to receive and process messages in a different format, you'll need to configure a message parser to convert them into this required format.

```typescript

const wsAdapter = new WsAdapter(app, {
  // To handle messages in the [event, data] format
  messageParser: (data) => {
    const [event, payload] = JSON.parse(data.toString());
    return { event, data: payload };
  },
});
```

Alternatively, you can configure the message parser after the adapter is created by using the `setMessageParser` method.

#### Advanced (custom adapter)[#](/websockets/adapter#advanced-custom-adapter)

For demonstration purposes, we are going to integrate the [ws](https://github.com/websockets/ws) library manually. As mentioned, the adapter for this library is already created and is exposed from the `@nestjs/platform-ws` package as a `WsAdapter` class. Here is how the simplified implementation could potentially look like:

ws-adapter.ts

JS TS

```typescript

import * as WebSocket from 'ws';
import { WebSocketAdapter, INestApplicationContext } from '@nestjs/common';
import { MessageMappingProperties } from '@nestjs/websockets';
import { Observable, fromEvent, EMPTY } from 'rxjs';
import { mergeMap, filter } from 'rxjs/operators';

export class WsAdapter implements WebSocketAdapter {
  constructor(private app: INestApplicationContext) {}

  create(port: number, options: any = {}): any {
    return new WebSocket.Server({ port, ...options });
  }

  bindClientConnect(server, callback: Function) {
    server.on('connection', callback);
  }

  bindMessageHandlers(
    client: WebSocket,
    handlers: MessageMappingProperties[],
    process: (data: any) => Observable<any>,
  ) {
    fromEvent(client, 'message')
      .pipe(
        mergeMap(data => this.bindMessageHandler(data, handlers, process)),
        filter(result => result),
      )
      .subscribe(response => client.send(JSON.stringify(response)));
  }

  bindMessageHandler(
    buffer,
    handlers: MessageMappingProperties[],
    process: (data: any) => Observable<any>,
  ): Observable<any> {
    const message = JSON.parse(buffer.data);
    const messageHandler = handlers.find(
      handler => handler.message === message.event,
    );
    if (!messageHandler) {
      return EMPTY;
    }
    return process(messageHandler.callback(message.data));
  }

  close(server) {
    server.close();
  }
}
```

> **Hint** When you want to take advantage of [ws](https://github.com/websockets/ws) library, use built-in `WsAdapter` instead of creating your own one.

Then, we can set up a custom adapter using `useWebSocketAdapter()` method:

main.ts

JS TS

```typescript

const app = await NestFactory.create(AppModule);
app.useWebSocketAdapter(new WsAdapter(app));
```

#### Example[#](/websockets/adapter#example)

A working example that uses `WsAdapter` is available [here](https://github.com/nestjs/nest/tree/master/sample/16-gateways-ws).

----
url: https://docs.nestjs.com/v8/controllers
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Controllers](https://docs.nestjs.com/v8/controllers#controllers)
* [Routing](https://docs.nestjs.com/v8/controllers#routing)
* [Request object](https://docs.nestjs.com/v8/controllers#request-object)
* [Resources](https://docs.nestjs.com/v8/controllers#resources)
* [Route wildcards](https://docs.nestjs.com/v8/controllers#route-wildcards)
* [Status code](https://docs.nestjs.com/v8/controllers#status-code)
* [Headers](https://docs.nestjs.com/v8/controllers#headers)
* [Redirection](https://docs.nestjs.com/v8/controllers#redirection)
* [Route parameters](https://docs.nestjs.com/v8/controllers#route-parameters)
* [Sub-Domain Routing](https://docs.nestjs.com/v8/controllers#sub-domain-routing)
* [Scopes](https://docs.nestjs.com/v8/controllers#scopes)
* [Asynchronicity](https://docs.nestjs.com/v8/controllers#asynchronicity)
* [Request payloads](https://docs.nestjs.com/v8/controllers#request-payloads)
* [Handling errors](https://docs.nestjs.com/v8/controllers#handling-errors)
* [Full resource sample](https://docs.nestjs.com/v8/controllers#full-resource-sample)
* [Getting up and running](https://docs.nestjs.com/v8/controllers#getting-up-and-running)
* [Library-specific approach](https://docs.nestjs.com/v8/controllers#library-specific-approach)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/controllers.md "Suggest Edits")

### Controllers

Controllers are responsible for handling incoming **requests** and returning **responses** to the client.

A controller's purpose is to receive specific requests for the application. The **routing** mechanism controls which controller receives which requests. Frequently, each controller has more than one route, and different routes can perform different actions.

In order to create a basic controller, we use classes and **decorators**. Decorators associate classes with required metadata and enable Nest to create a routing map (tie requests to the corresponding controllers).

> **Hint** For quickly creating a CRUD controller with the [validation](https://docs.nestjs.com/techniques/validation) built-in, you may use the CLI's [CRUD generator](https://docs.nestjs.com/recipes/crud-generator#crud-generator): `nest g resource [name]`.

#### Routing[#](/controllers#routing)

In the following example we'll use the `@Controller()` decorator, which is **required** to define a basic controller. We'll specify an optional route path prefix of `cats`. Using a path prefix in a `@Controller()` decorator allows us to easily group a set of related routes, and minimize repetitive code. For example, we may choose to group a set of routes that manage interactions with a customer entity under the route `/customers`. In that case, we could specify the path prefix `customers` in the `@Controller()` decorator so that we don't have to repeat that portion of the path for each route in the file.

cats.controller.ts

JS TS

```typescript

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

@Controller('cats')
export class CatsController {
  @Get()
  findAll(): string {
    return 'This action returns all cats';
  }
}
```

```typescript

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

@Controller('cats')
export class CatsController {
  @Get()
  findAll() {
    return 'This action returns all cats';
  }
}
```

> **Hint** To create a controller using the CLI, simply execute the `$ nest g controller cats` command.

The `@Get()` HTTP request method decorator before the `findAll()` method tells Nest to create a handler for a specific endpoint for HTTP requests. The endpoint corresponds to the HTTP request method (GET in this case) and the route path. What is the route path? The route path for a handler is determined by concatenating the (optional) prefix declared for the controller, and any path specified in the method's decorator. Since we've declared a prefix for every route ( `cats`), and haven't added any path information in the decorator, Nest will map `GET /cats` requests to this handler. As mentioned, the path includes both the optional controller path prefix **and** any path string declared in the request method decorator. For example, a path prefix of `customers` combined with the decorator `@Get('profile')` would produce a route mapping for requests like `GET /customers/profile`.

In our example above, when a GET request is made to this endpoint, Nest routes the request to our user-defined `findAll()` method. Note that the method name we choose here is completely arbitrary. We obviously must declare a method to bind the route to, but Nest doesn't attach any significance to the method name chosen.

This method will return a 200 status code and the associated response, which in this case is just a string. Why does that happen? To explain, we'll first introduce the concept that Nest employs two **different** options for manipulating responses:

|                        |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Standard (recommended) | Using this built-in method, when a request handler returns a JavaScript object or array, it will **automatically** be serialized to JSON. When it returns a JavaScript primitive type (e.g., `string`, `number`, `boolean`), however, Nest will send just the value without attempting to serialize it. This makes response handling simple: just return the value, and Nest takes care of the rest. Furthermore, the response's **status code** is always 200 by default, except for POST requests which use 201. We can easily change this behavior by adding the `@HttpCode(...)` decorator at a handler-level (see [Status codes](controllers#status-code)). |
| Library-specific       | We can use the library-specific (e.g., Express) [response object](https://expressjs.com/en/api.html#res), which can be injected using the `@Res()` decorator in the method handler signature (e.g., `findAll(@Res() response)`). With this approach, you have the ability to use the native response handling methods exposed by that object. For example, with Express, you can construct responses using code like `response.status(200).send()`.                                                                                                                                                                                                              |

> **Warning** Nest detects when the handler is using either `@Res()` or `@Next()`, indicating you have chosen the library-specific option. If both approaches are used at the same time, the Standard approach is **automatically disabled** for this single route and will no longer work as expected. To use both approaches at the same time (for example, by injecting the response object to only set cookies/headers but still leave the rest to the framework), you must set the `passthrough` option to `true` in the `@Res({ passthrough: true })` decorator.

Handlers often need access to the client **request** details. Nest provides access to the [request object](https://expressjs.com/en/api.html#req) of the underlying platform (Express by default). We can access the request object by instructing Nest to inject it by adding the `@Req()` decorator to the handler's signature.

cats.controller.ts

JS TS

```typescript

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

@Controller('cats')
export class CatsController {
  @Get()
  findAll(@Req() request: Request): string {
    return 'This action returns all cats';
  }
}
```

```typescript

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

@Controller('cats')
export class CatsController {
  @Get()
  @Bind(Req())
  findAll(request) {
    return 'This action returns all cats';
  }
}
```

> **Hint** In order to take advantage of `express` typings (as in the `request: Request` parameter example above), install `@types/express` package.

The request object represents the HTTP request and has properties for the request query string, parameters, HTTP headers, and body (read more [here](https://expressjs.com/en/api.html#req)). In most cases, it's not necessary to grab these properties manually. We can use dedicated decorators instead, such as `@Body()` or `@Query()`, which are available out of the box. Below is a list of the provided decorators and the plain platform-specific objects they represent.

|                           |                                     |
| ------------------------- | ----------------------------------- |
| `@Request(), @Req()`      | `req`                               |
| `@Response(), @Res()`\*   | `res`                               |
| `@Next()`                 | `next`                              |
| `@Session()`              | `req.session`                       |
| `@Param(key?: string)`    | `req.params` / `req.params[key]`    |
| `@Body(key?: string)`     | `req.body` / `req.body[key]`        |
| `@Query(key?: string)`    | `req.query` / `req.query[key]`      |
| `@Headers(name?: string)` | `req.headers` / `req.headers[name]` |
| `@Ip()`                   | `req.ip`                            |
| `@HostParam()`            | `req.hosts`                         |

\* For compatibility with typings across underlying HTTP platforms (e.g., Express and Fastify), Nest provides `@Res()` and `@Response()` decorators. `@Res()` is simply an alias for `@Response()`. Both directly expose the underlying native platform `response` object interface. When using them, you should also import the typings for the underlying library (e.g., `@types/express`) to take full advantage. Note that when you inject either `@Res()` or `@Response()` in a method handler, you put Nest into **Library-specific mode** for that handler, and you become responsible for managing the response. When doing so, you must issue some kind of response by making a call on the `response` object (e.g., `res.json(...)` or `res.send(...)`), or the HTTP server will hang.

> **Hint** To learn how to create your own custom decorators, visit [this](/v8/custom-decorators) chapter.

#### Resources[#](/controllers#resources)

Earlier, we defined an endpoint to fetch the cats resource (**GET** route). We'll typically also want to provide an endpoint that creates new records. For this, let's create the **POST** handler:

cats.controller.ts

JS TS

```typescript

import { Controller, Get, Post } from '@nestjs/common';

@Controller('cats')
export class CatsController {
  @Post()
  create(): string {
    return 'This action adds a new cat';
  }

  @Get()
  findAll(): string {
    return 'This action returns all cats';
  }
}
```

```typescript

import { Controller, Get, Post } from '@nestjs/common';

@Controller('cats')
export class CatsController {
  @Post()
  create() {
    return 'This action adds a new cat';
  }

  @Get()
  findAll() {
    return 'This action returns all cats';
  }
}
```

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.

#### Route wildcards[#](/controllers#route-wildcards)

Pattern based routes are supported as well. For instance, the asterisk is used as a wildcard, and will match any combination of characters.

```typescript

@Get('ab*cd')
findAll() {
  return 'This route uses a wildcard';
}
```

The `'ab*cd'` route path will match `abcd`, `ab_cd`, `abecd`, and so on. The characters `?`, `+`, `*`, and `()` may be used in a route path, and are subsets of their regular expression counterparts. The hyphen ( `-`) and the dot (`.`) are interpreted literally by string-based paths.

#### Status code[#](/controllers#status-code)

As mentioned, the response **status code** is always **200** by default, except for POST requests which are **201**. We can easily change this behavior by adding the `@HttpCode(...)` decorator at a handler level.

```typescript

@Post()
@HttpCode(204)
create() {
  return 'This action adds a new cat';
}
```

> **Hint** Import `HttpCode` from the `@nestjs/common` package.

Often, your status code isn't static but depends on various factors. In that case, you can use a library-specific **response** (inject using `@Res()`) object (or, in case of an error, throw an exception).

#### Headers[#](/controllers#headers)

To specify a custom response header, you can either use a `@Header()` decorator or a library-specific response object (and call `res.header()` directly).

```typescript

@Post()
@Header('Cache-Control', 'none')
create() {
  return 'This action adds a new cat';
}
```

> **Hint** Import `Header` from the `@nestjs/common` package.

#### Redirection[#](/controllers#redirection)

To redirect a response to a specific URL, you can either use a `@Redirect()` decorator or a library-specific response object (and call `res.redirect()` directly).

`@Redirect()` takes two arguments, `url` and `statusCode`, both are optional. The default value of `statusCode` is `302` (`Found`) if omitted.

```typescript

@Get()
@Redirect('https://nestjs.com', 301)
```

Sometimes you may want to determine the HTTP status code or the redirect URL dynamically. Do this by returning an object from the route handler method with the shape:

```json

{
  "url": string,
  "statusCode": number
}
```

Returned values will override any arguments passed to the `@Redirect()` decorator. For example:

```typescript

@Get('docs')
@Redirect('https://docs.nestjs.com', 302)
getDocs(@Query('version') version) {
  if (version && version === '5') {
    return { url: 'https://docs.nestjs.com/v5/' };
  }
}
```

#### Route parameters[#](/controllers#route-parameters)

Routes with static paths won't work when you need to accept **dynamic data** as part of the request (e.g., `GET /cats/1` to get cat with id `1`). In order to define routes with parameters, we can add route parameter **tokens** in the path of the route to capture the dynamic value at that position in the request URL. The route parameter token in the `@Get()` decorator example below demonstrates this usage. Route parameters declared in this way can be accessed using the `@Param()` decorator, which should be added to the method signature.

JS TS

```typescript

@Get(':id')
findOne(@Param() params): string {
  console.log(params.id);
  return `This action returns a #${params.id} cat`;
}
```

```typescript

@Get(':id')
@Bind(Param())
findOne(params) {
  console.log(params.id);
  return `This action returns a #${params.id} cat`;
}
```

`@Param()` is used to decorate a method parameter (`params` in the example above), and makes the **route** parameters available as properties of that decorated method parameter inside the body of the method. As seen in the code above, we can access the `id` parameter by referencing `params.id`. You can also pass in a particular parameter token to the decorator, and then reference the route parameter directly by name in the method body.

> **Hint** Import `Param` from the `@nestjs/common` package.

JS TS

```typescript

@Get(':id')
findOne(@Param('id') id: string): string {
  return `This action returns a #${id} cat`;
}
```

```typescript

@Get(':id')
@Bind(Param('id'))
findOne(id) {
  return `This action returns a #${id} cat`;
}
```

#### Sub-Domain Routing[#](/controllers#sub-domain-routing)

The `@Controller` decorator can take a `host` option to require that the HTTP host of the incoming requests matches some specific value.

```typescript

@Controller({ host: 'admin.example.com' })
export class AdminController {
  @Get()
  index(): string {
    return 'Admin page';
  }
}
```

> **Warning** Since **Fastify** lacks support for nested routers, when using sub-domain routing, the (default) Express adapter should be used instead.

Similar to a route `path`, the `hosts` option can use tokens to capture the dynamic value at that position in the host name. The host parameter token in the `@Controller()` decorator example below demonstrates this usage. Host parameters declared in this way can be accessed using the `@HostParam()` decorator, which should be added to the method signature.

```typescript

@Controller({ host: ':account.example.com' })
export class AccountController {
  @Get()
  getInfo(@HostParam('account') account: string) {
    return account;
  }
}
```

#### Scopes[#](/controllers#scopes)

For people coming from different programming language backgrounds, it might be unexpected to learn that in Nest, almost everything is shared across incoming requests. We have a connection pool to the database, singleton services with global state, etc. Remember that Node.js doesn't follow the request/response Multi-Threaded Stateless Model in which every request is processed by a separate thread. Hence, using singleton instances is fully **safe** for our applications.

However, there are edge-cases when request-based lifetime of the controller may be the desired behavior, for instance per-request caching in GraphQL applications, request tracking or multi-tenancy. Learn how to control scopes [here](/v8/fundamentals/injection-scopes).

#### Asynchronicity[#](/controllers#asynchronicity)

We love modern JavaScript and we know that data extraction is mostly **asynchronous**. That's why Nest supports and works well with `async` functions.

> **Hint** Learn more about `async / await` feature [here](https://kamilmysliwiec.com/typescript-2-1-introduction-async-await)

Every async function has to return a `Promise`. This means that you can return a deferred value that Nest will be able to resolve by itself. Let's see an example of this:

cats.controller.ts

JS TS

```typescript

@Get()
async findAll(): Promise<any[]> {
  return [];
}
```

```typescript

@Get()
async findAll() {
  return [];
}
```

The above code is fully valid. Furthermore, Nest route handlers are even more powerful by being able to return RxJS [observable streams](http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html). Nest will automatically subscribe to the source underneath and take the last emitted value (once the stream is completed).

cats.controller.ts

JS TS

```typescript

@Get()
findAll(): Observable<any[]> {
  return of([]);
}
```

```typescript

@Get()
findAll() {
  return of([]);
}
```

```typescript

export class CreateCatDto {
  name: string;
  age: number;
  breed: string;
}
```

It has only three basic properties. Thereafter we can use the newly created DTO inside the `CatsController`:

cats.controller.ts

JS TS

```typescript

@Post()
async create(@Body() createCatDto: CreateCatDto) {
  return 'This action adds a new cat';
}
```

```typescript

@Post()
@Bind(Body())
async create(createCatDto) {
  return 'This action adds a new cat';
}
```

> **Hint** Our `ValidationPipe` can filter out properties that should not be received by the method handler. In this case, we can whitelist the acceptable properties, and any property not included in the whitelist is automatically stripped from the resulting object. In the `CreateCatDto` example, our whitelist is the `name`, `age`, and `breed` properties. Learn more [here](https://docs.nestjs.com/techniques/validation#stripping-properties).

#### Handling errors[#](/controllers#handling-errors)

There's a separate chapter about handling errors (i.e., working with exceptions) [here](/v8/exception-filters).

#### Full resource sample[#](/controllers#full-resource-sample)

Below is an example that makes use of several of the available decorators to create a basic controller. This controller exposes a couple of methods to access and manipulate internal data.

cats.controller.ts

JS TS

```typescript

import { Controller, Get, Query, Post, Body, Put, Param, Delete } from '@nestjs/common';
import { CreateCatDto, UpdateCatDto, ListAllEntities } from './dto';

@Controller('cats')
export class CatsController {
  @Post()
  create(@Body() createCatDto: CreateCatDto) {
    return 'This action adds a new cat';
  }

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

  @Get(':id')
  findOne(@Param('id') id: string) {
    return `This action returns a #${id} cat`;
  }

  @Put(':id')
  update(@Param('id') id: string, @Body() updateCatDto: UpdateCatDto) {
    return `This action updates a #${id} cat`;
  }

  @Delete(':id')
  remove(@Param('id') id: string) {
    return `This action removes a #${id} cat`;
  }
}
```

```typescript

import { Controller, Get, Query, Post, Body, Put, Param, Delete, Bind } from '@nestjs/common';

@Controller('cats')
export class CatsController {
  @Post()
  @Bind(Body())
  create(createCatDto) {
    return 'This action adds a new cat';
  }

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

  @Get(':id')
  @Bind(Param('id'))
  findOne(id) {
    return `This action returns a #${id} cat`;
  }

  @Put(':id')
  @Bind(Param('id'), Body())
  update(id, updateCatDto) {
    return `This action updates a #${id} cat`;
  }

  @Delete(':id')
  @Bind(Param('id'))
  remove(id) {
    return `This action removes a #${id} cat`;
  }
}
```

> **Hint** Nest CLI provides a generator (schematic) that automatically generates **all the boilerplate code** to help us avoid doing all of this, and make the developer experience much simpler. Read more about this feature [here](/v8/recipes/crud-generator).

#### Getting up and running[#](/controllers#getting-up-and-running)

With the above controller fully defined, Nest still doesn't know that `CatsController` exists and as a result won't create an instance of this class.

Controllers always belong to a module, which is why we include the `controllers` array within the `@Module()` decorator. Since we haven't yet defined any other modules except the root `AppModule`, we'll use that to introduce the `CatsController`:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { CatsController } from './cats/cats.controller';

@Module({
  controllers: [CatsController],
})
export class AppModule {}
```

```typescript

import { Controller, Get, Post, Res, HttpStatus } from '@nestjs/common';
import { Response } from 'express';

@Controller('cats')
export class CatsController {
  @Post()
  create(@Res() res: Response) {
    res.status(HttpStatus.CREATED).send();
  }

  @Get()
  findAll(@Res() res: Response) {
     res.status(HttpStatus.OK).json([]);
  }
}
```

```typescript

import { Controller, Get, Post, Bind, Res, Body, HttpStatus } from '@nestjs/common';

@Controller('cats')
export class CatsController {
  @Post()
  @Bind(Res(), Body())
  create(res, createCatDto) {
    res.status(HttpStatus.CREATED).send();
  }

  @Get()
  @Bind(Res())
  findAll(res) {
     res.status(HttpStatus.OK).json([]);
  }
}
```

Though this approach works, and does in fact allow for more flexibility in some ways by providing full control of the response object (headers manipulation, library-specific features, and so on), it should be used with care. In general, the approach is much less clear and does have some disadvantages. The main disadvantage is that your code becomes platform-dependent (as underlying libraries may have different APIs on the response object), and harder to test (you'll have to mock the response object, etc.).

Also, in the example above, you lose compatibility with Nest features that depend on Nest standard response handling, such as Interceptors and `@HttpCode()` / `@Header()` decorators. To fix this, you can set the `passthrough` option to `true`, as follows:

JS TS

```typescript

@Get()
findAll(@Res({ passthrough: true }) res: Response) {
  res.status(HttpStatus.OK);
  return [];
}
```

```typescript

@Get()
@Bind(Res({ passthrough: true }))
findAll(res) {
  res.status(HttpStatus.OK);
  return [];
}
```

Now you can interact with the native response object (for example, set cookies or headers depending on certain conditions), but leave the rest to the framework.

----
url: https://docs.nestjs.com/v9/graphql/directives
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Directives](https://docs.nestjs.com/v9/graphql/directives#directives)
* [Custom directives](https://docs.nestjs.com/v9/graphql/directives#custom-directives)
* [Code first](https://docs.nestjs.com/v9/graphql/directives#code-first)
* [Schema first](https://docs.nestjs.com/v9/graphql/directives#schema-first)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/directives.md "Suggest Edits")

To instruct what should happen when Apollo/Mercurius encounters your directive, you can create a transformer function. This function uses the `mapSchema` function to iterate through locations in your schema (field definitions, type definitions, etc.) and perform corresponding transformations.

```typescript

import { getDirective, MapperKind, mapSchema } from '@graphql-tools/utils';
import { defaultFieldResolver, GraphQLSchema } from 'graphql';

export function upperDirectiveTransformer(
  schema: GraphQLSchema,
  directiveName: string,
) {
  return mapSchema(schema, {
    [MapperKind.OBJECT_FIELD]: (fieldConfig) => {
      const upperDirective = getDirective(
        schema,
        fieldConfig,
        directiveName,
      )?.[0];

      if (upperDirective) {
        const { resolve = defaultFieldResolver } = fieldConfig;

        // Replace the original resolver with a function that *first* calls
        // the original resolver, then converts its result to upper case
        fieldConfig.resolve = async function (source, args, context, info) {
          const result = await resolve(source, args, context, info);
          if (typeof result === 'string') {
            return result.toUpperCase();
          }
          return result;
        };
        return fieldConfig;
      }
    },
  });
}
```

Now, apply the `upperDirectiveTransformer` transformation function in the `GraphQLModule#forRoot` method using the `transformSchema` function:

```typescript

GraphQLModule.forRoot({
  // ...
  transformSchema: (schema) => upperDirectiveTransformer(schema, 'upper'),
});
```

Once registered, the `@upper` directive can be used in our schema. However, the way you apply the directive will vary depending on the approach you use (code first or schema first).

#### Code first[#](/graphql/directives#code-first)

In the code first approach, use the `@Directive()` decorator to apply the directive.

```typescript

@Directive('@upper')
@Field()
title: string;
```

> **Hint** The `@Directive()` decorator is exported from the `@nestjs/graphql` package.

Directives can be applied on fields, field resolvers, input and object types, as well as queries, mutations, and subscriptions. Here's an example of the directive applied on the query handler level:

```typescript

@Directive('@deprecated(reason: "This query will be removed in the next version")')
@Query(returns => Author, { name: 'author' })
async getAuthor(@Args({ name: 'id', type: () => Int }) id: number) {
  return this.authorsService.findOneById(id);
}
```

> **Warning** Directives applied through the `@Directive()` decorator will not be reflected in the generated schema definition file.

Lastly, make sure to declare directives in the `GraphQLModule`, as follows:

```typescript

GraphQLModule.forRoot({
  // ...,
  transformSchema: schema => upperDirectiveTransformer(schema, 'upper'),
  buildSchemaOptions: {
    directives: [
      new GraphQLDirective({
        name: 'upper',
        locations: [DirectiveLocation.FIELD_DEFINITION],
      }),
    ],
  },
}),
```

> **Hint** Both `GraphQLDirective` and `DirectiveLocation` are exported from the `graphql` package.

#### Schema first[#](/graphql/directives#schema-first)

In the schema first approach, apply directives directly in SDL.

```graphql

directive @upper on FIELD_DEFINITION

type Post {
  id: Int!
  title: String! @upper
  votes: Int
}
```

----
url: https://docs.nestjs.com/application/logger
----

[Skip to content](#content)

On this page

* [Logger](https://docs.nestjs.com/application/logger#logger)
* [Basic customization](https://docs.nestjs.com/application/logger#basic-customization)
* [JSON logging](https://docs.nestjs.com/application/logger#json-logging)
* [Structured logging params](https://docs.nestjs.com/application/logger#structured-logging-params)
* [Logging in production](https://docs.nestjs.com/application/logger#logging-in-production)
* [Using the logger for application logging](https://docs.nestjs.com/application/logger#using-the-logger-for-application-logging)
* [Logs with timestamps](https://docs.nestjs.com/application/logger#logs-with-timestamps)
* [Custom implementation](https://docs.nestjs.com/application/logger#custom-implementation)
* [Extend built-in logger](https://docs.nestjs.com/application/logger#extend-built-in-logger)
* [Dependency injection](https://docs.nestjs.com/application/logger#dependency-injection)
* [Injecting a custom logger](https://docs.nestjs.com/application/logger#injecting-a-custom-logger)
* [Correlating logs with requests](https://docs.nestjs.com/application/logger#correlating-logs-with-requests)
* [Use external logger](https://docs.nestjs.com/application/logger#use-external-logger)

### Logger

Nest comes with a built-in logger that is used during application bootstrapping and in several other circumstances, such as displaying caught exceptions (i.e., system logging). This functionality is provided by the `Logger` class in the `@nestjs/common` package. You can fully control the behavior of the logging system, including any of the following:

* disable logging entirely
* specify the level of detail (e.g., display errors, warnings, debug information, etc.)
* configure the formatting of log messages (raw, JSON, colorized, etc.)
* override the timestamp in the default logger (e.g., use the ISO 8601 standard as the date format)
* completely override the default logger
* customize the default logger by extending it
* use dependency injection to simplify composing and testing your application

You can also use the built-in logger, or create your own custom implementation, to log your own application-level events and messages.

The built-in logger is not only a development convenience. Combined with [JSON output](/application/logger#json-logging), [structured logging params](/application/logger#structured-logging-params), and the trace id that [NestJS Observe](/application/logger#correlating-logs-with-requests) attaches to every line written during a request, it covers what most production applications need from a logger: one machine-readable record per line on stdout, queryable fields, log levels, and a way to tie each line back to the request that wrote it. Container platforms and log aggregators (CloudWatch, Cloud Logging, Datadog, Loki, Elasticsearch, and so on) ingest that output as-is, with no extra dependency in your application. The [Logging in production](/application/logger#logging-in-production) section below shows the full setup.

Reach for a dedicated library such as [Pino](https://github.com/pinojs/pino) or [Winston](https://github.com/winstonjs/winston) when you need something the built-in logger deliberately leaves out: writing to files or other transports from inside the process, field redaction, or the last bit of throughput on very log-heavy services. See [Use external logger](/application/logger#use-external-logger).

#### Basic customization[#](/application/logger#basic-customization)

To disable logging, set the `logger` property to `false` in the (optional) Nest application options object, passed as the second argument to the `NestFactory.create()` method.

```typescript

const app = await NestFactory.create(AppModule, {
  logger: false,
});
await app.listen(process.env.PORT ?? 3000);
```

To enable specific log levels, set the `logger` property to an array of strings specifying the log levels to display, as follows:

```typescript

const app = await NestFactory.create(AppModule, {
  logger: ['error', 'warn'],
});
await app.listen(process.env.PORT ?? 3000);
```

Values in the array can be any combination of `'log'`, `'fatal'`, `'error'`, `'warn'`, `'debug'`, and `'verbose'`.

> **Hint** Log levels cascade from the most severe level in the array: every level at least as severe as that one is enabled too. `['log']` therefore also enables `'warn'`, `'error'`, and `'fatal'`. Less severe levels are enabled only if they are listed, so `['debug', 'error']` enables `'debug'`, `'error'`, and `'fatal'`, but not `'log'` or `'warn'`.

To enable a level and everything more severe than it, build the array with `filterLogLevels()` instead of listing the levels by hand. It takes a string, which makes it a good fit for an environment variable:

```typescript

import { filterLogLevels } from '@nestjs/common';

const app = await NestFactory.create(AppModule, {
  logger: filterLogLevels(process.env.LOG_LEVEL ?? '>=warn'), // ['warn', 'error', 'fatal']
});
```

Besides `'>=warn'`, it accepts `'>warn'` (more severe than `warn` only), a comma-separated list such as `'log,error'`, or a single level. An empty or unrecognized string returns all levels, and an unknown level after `>` or `>=` throws.

To change the levels after the application has been created (for example, once your configuration has loaded), pass an array of levels to `app.useLogger()`. Nest hands it to the current logger's `setLogLevels()` method:

```typescript

app.useLogger(['error', 'warn']);
```

To disable colorized output, pass a `ConsoleLogger` instance with the `colors` property set to `false` as the value of the `logger` property:

```typescript

const app = await NestFactory.create(AppModule, {
  logger: new ConsoleLogger({
    colors: false,
  }),
});
```

Colors are also off by default when the `NO_COLOR` environment variable is set to any non-empty value.

To configure a prefix for each log message, pass a `ConsoleLogger` instance with the `prefix` property set:

```typescript

const app = await NestFactory.create(AppModule, {
  logger: new ConsoleLogger({
    prefix: 'MyApp', // Default is "Nest"
  }),
});
```

The following table lists all available options:

| Option            | Description                                                                                                                                                                                                                                                                                                                              | Default                                                                                                             |
| ----------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| `logLevels`       | Enabled log levels.                                                                                                                                                                                                                                                                                                                      | `['log', 'fatal', 'error', 'warn', 'debug', 'verbose']`                                                             |
| `timestamp`       | If enabled, will print timestamp (time difference) between current and previous log message. Note: This option is not used when `json` is enabled.                                                                                                                                                                                       | `false`                                                                                                             |
| `prefix`          | A prefix to be used for each log message. Note: This option is not used when `json` is enabled.                                                                                                                                                                                                                                          | `Nest`                                                                                                              |
| `json`            | If enabled, will print the log message in JSON format.                                                                                                                                                                                                                                                                                   | `false`                                                                                                             |
| `colors`          | If enabled, will print the log message in color.                                                                                                                                                                                                                                                                                         | `true` (`false` if `json` is enabled or `NO_COLOR` is set)                                                          |
| `context`         | The context of the logger.                                                                                                                                                                                                                                                                                                               | `undefined`                                                                                                         |
| `forceConsole`    | If enabled, will use `console.log`/`console.error` instead of `process.stdout.write`/`process.stderr.write`. Useful in test environments, such as Jest, that buffer console calls.                                                                                                                                                       | `false`                                                                                                             |
| `compact`         | If enabled, will print the log message in a single line, even if it is an object with multiple properties. If set to a number, the most n inner elements are united on a single line as long as all properties fit into breakLength. Short array elements are also grouped together.                                                     | `false` (`true` if `json` is enabled)                                                                               |
| `maxArrayLength`  | Specifies the maximum number of Array, TypedArray, Map, Set, WeakMap, and WeakSet elements to include when formatting. Set to null or Infinity to show all elements. Set to 0 or negative to show no elements. Ignored when `json` is enabled, colors are disabled, and `compact` is set to true as it produces a parseable JSON output. | `100`                                                                                                               |
| `maxStringLength` | Specifies the maximum number of characters to include when formatting. Set to null or Infinity to show all elements. Set to 0 or negative to show no characters. Ignored when `json` is enabled, colors are disabled, and `compact` is set to true as it produces a parseable JSON output.                                               | `10000`                                                                                                             |
| `sorted`          | If enabled, will sort keys while formatting objects. Can also be a custom sorting function. Ignored when `json` is enabled, colors are disabled, and `compact` is set to true as it produces a parseable JSON output.                                                                                                                    | `false`                                                                                                             |
| `depth`           | Specifies the number of times to recurse while formatting object. This is useful for inspecting large objects. To recurse up to the maximum call stack size pass Infinity or null. Ignored when `json` is enabled, colors are disabled, and `compact` is set to true as it produces a parseable JSON output.                             | `5`                                                                                                                 |
| `showHidden`      | If true, object's non-enumerable symbols and properties are included in the formatted result. WeakMap and WeakSet entries are also included as well as user defined prototype properties                                                                                                                                                 | `false`                                                                                                             |
| `breakLength`     | The length at which input values are split across multiple lines. Set to Infinity to format the input as a single line (in combination with "compact" set to true). Ignored when `json` is enabled, colors are disabled, and `compact` is set to true as it produces a parseable JSON output.                                            | `Infinity` when `compact` is enabled, or when colors are off and `compact` isn't explicitly `false`; `80` otherwise |

#### JSON logging[#](/application/logger#json-logging)

JSON logging is essential for application observability and for integration with log management systems. To enable it, create a `ConsoleLogger` instance with its `json` property set to `true`, and pass it as the value of the `logger` property when creating the application instance:

```typescript

const app = await NestFactory.create(AppModule, {
  logger: new ConsoleLogger({
    json: true,
  }),
});
```

This configuration outputs logs in a structured JSON format, which makes it easier to integrate with external systems such as log aggregators and cloud platforms. For example, platforms like **AWS ECS** (Elastic Container Service) natively support JSON logs, enabling features like:

* **Log filtering**: narrow down logs based on fields like log level, timestamp, or custom metadata.
* **Search and analysis**: use query tools to analyze and track trends in your application's behavior.

If you're using [NestJS Mau](https://mau.nestjs.com), JSON logging also lets you view logs in a well-organized, structured format, which is especially useful for debugging and performance monitoring.

> **Note** When `json` is set to `true`, the `ConsoleLogger` defaults `colors` to `false` and `compact` to `true`. With those two values, each entry is serialized with `JSON.stringify()`, so the output is valid JSON, free of formatting artifacts. For development, you can explicitly set `colors` to `true` (or `compact` to `false`). Entries are then rendered with Node's `util.inspect()`, which is easier to read during local debugging but is no longer strict JSON.

When JSON logging is enabled, the log output looks like this (on a single line):

```json

{
  "level": "log",
  "pid": 19096,
  "timestamp": 1607370779834,
  "message": "Starting Nest application...",
  "context": "NestFactory"
}
```

Each entry has the following fields:

* `level`: the log level.
* `pid`: the process id.
* `timestamp`: when the entry was written, in milliseconds since the Unix epoch. The `timestamp` and `prefix` options, and a [custom timestamp format](/application/logger#extend-built-in-logger), apply to text output only.
* `message`: the message, as passed to the logger.
* `context`: the logger context, when there is one.
* `stack`: the stack trace passed to `error()`, when there is one.
* `params`: the [structured logging params](/application/logger#structured-logging-params), when any were passed.

As in text mode, `error` entries are written to stderr and all other levels to stdout.

#### Structured logging params[#](/application/logger#structured-logging-params)

Log messages often need to carry metadata: a user id, a request duration, a correlation id. Starting with NestJS v12, plain objects passed **after** the first message argument are treated as structured params and attached to the same log entry instead of being emitted as separate log records.

```typescript

const logger = new Logger('UserService');
logger.log('User created', { userId: 1, email: 'foo@bar.com' });
```

In text mode, the params are appended inline to the same formatted line:

```plaintext

[Nest] 3785  - 02/26/2026, 10:04:41 AM     LOG [UserService] User created { userId: 1, email: 'foo@bar.com' }
```

When several plain objects are passed, they are merged into a single set of params:

```typescript

logger.log('Request handled', { method: 'GET' }, { path: '/api', duration: 42 });
```

```plaintext

[Nest] 3785  - 02/26/2026, 10:04:41 AM     LOG [UserService] Request handled { method: 'GET', path: '/api', duration: 42 }
```

In JSON mode, params are nested under a `params` key by default:

```json

{
  "level": "log",
  "pid": 3785,
  "timestamp": 1772089691769,
  "message": "User created",
  "context": "UserService",
  "params": { "userId": 1, "email": "foo@bar.com" }
}
```

To spread them into the root of the JSON object instead (which some log aggregators prefer), enable `flattenParams`:

```typescript

new ConsoleLogger({ json: true, flattenParams: true });
```

```json

{
  "level": "log",
  "pid": 3785,
  "timestamp": 1772089691769,
  "message": "User created",
  "context": "UserService",
  "userId": 1,
  "email": "foo@bar.com"
}
```

The relevant `ConsoleLogger` options are:

| Option             | Description                                                                                                                                                                                                                        | Default |
| ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- |
| `structuredParams` | If enabled, plain objects logged after the message are attached to the same entry as params.                                                                                                                                       | `true`  |
| `flattenParams`    | If enabled, params are spread into the root of the JSON record instead of nested under `params`. A param whose key the record already uses (such as `message` or `level`) is dropped. JSON mode only; requires `structuredParams`. | `false` |

> **Hint** Only **plain objects** are treated as params. Arrays, strings, numbers, class instances, and `null` are still logged as separate messages (a string passed as the *last* argument is still treated as the context), and a plain object passed as the *first* argument is still treated as the message itself. Set `structuredParams: false` to restore the pre-v12 behavior.

#### Logging in production[#](/application/logger#logging-in-production)

Put together, JSON output and structured params give you production-grade logs from the built-in logger alone:

```typescript

// main.ts
const app = await NestFactory.create(AppModule, {
  logger: new ConsoleLogger({
    json: true,
    logLevels: ['log', 'warn', 'error', 'fatal'],
  }),
});
```

```typescript

// orders.service.ts
@Injectable()
export class OrdersService {
  private readonly logger = new Logger(OrdersService.name);

  async capture(order: Order) {
    // ...
    this.logger.log('Payment captured', { orderId: order.id, amount: order.total });
  }
}
```

With [NestJS Observe](/application/logger#correlating-logs-with-requests) installed, each line written during a request also carries that request's trace id, without changing a single log call:

```json

{"level":"log","pid":66803,"timestamp":1789978166281,"message":"Payment captured","context":"OrdersService","params":{"orderId":"ord_8f2a","amount":4200},"traceId":"0199a3f2-7c1e-7b40-9d2a-5e8f1c3b7a64"}
```

That single line is filterable by level and context, queryable by `orderId`, and joinable to every other line from the same request, which is the job most teams install a third-party logger to do. Write logs to stdout like this and let the platform (Docker, Kubernetes, ECS, Cloud Run, and so on) collect and ship them. That keeps rotation, buffering, and delivery out of your application process.

> **Hint** Set `flattenParams: true` if your aggregator indexes top-level fields only, so `orderId` becomes a root-level field instead of `params.orderId`.

#### Using the logger for application logging[#](/application/logger#using-the-logger-for-application-logging)

You can combine several of the techniques above to provide consistent behavior and formatting across both Nest system logging and your own application event/message logging.

A good practice is to instantiate the `Logger` class from `@nestjs/common` in each of your services, supplying the service name as the `context` argument of the `Logger` constructor:

```typescript

import { Logger, Injectable } from '@nestjs/common';

@Injectable()
class MyService {
  private readonly logger = new Logger(MyService.name);

  doSomething() {
    this.logger.log('Doing something...');
  }
}
```

In the default logger implementation, `context` is printed in square brackets, like `NestFactory` in the example below:

```bash

[Nest] 19096  - 12/08/2019, 7:12:59 AM     LOG [NestFactory] Starting Nest application...
```

If a message is expensive to build, pass a function that returns it instead. In the default text format, the built-in `ConsoleLogger` calls the function only when the level is enabled, so a disabled `debug` line costs nothing:

```typescript

this.logger.debug(() => `Cache state: ${JSON.stringify(this.cache.dump())}`);
```

If you supply a custom logger via `app.useLogger()`, Nest uses it internally, and calls made through `Logger` instances are delegated to it. Your code remains implementation agnostic, and you can substitute the default logger with your own by calling `app.useLogger()`.

For example, if you follow the steps in the [Dependency injection](application/logger#dependency-injection) section below and call `app.useLogger(app.get(MyLogger))`, subsequent calls to `this.logger.log()` from `MyService` result in calls to the `log()` method of the `MyLogger` instance.

This is suitable for most cases. If you need more customization (like adding and calling custom methods), see the [Injecting a custom logger](application/logger#injecting-a-custom-logger) section.

#### Logs with timestamps[#](/application/logger#logs-with-timestamps)

To print a timestamp difference for every logged message, pass the optional `timestamp: true` setting when creating the logger instance:

```typescript

import { Logger, Injectable } from '@nestjs/common';

@Injectable()
class MyService {
  private readonly logger = new Logger(MyService.name, { timestamp: true });

  doSomething() {
    this.logger.log('Doing something with timestamp here ->');
  }
}
```

This will produce output in the following format:

```bash

[Nest] 19096  - 04/19/2024, 7:12:59 AM     LOG [MyService] Doing something with timestamp here -> +5ms
```

Note the `+5ms` at the end of the line. It is the time elapsed since the previous line written by any `ConsoleLogger` in the process, not only by this logger.

#### Custom implementation[#](/application/logger#custom-implementation)

You can provide a custom logger implementation for Nest to use for system logging by setting the `logger` property to an object that fulfills the `LoggerService` interface. For example, you can tell Nest to use the global JavaScript `console` object (which implements the `LoggerService` interface), as follows:

```typescript

const app = await NestFactory.create(AppModule, {
  logger: console,
});
await app.listen(process.env.PORT ?? 3000);
```

To implement your own custom logger, implement each of the methods of the `LoggerService` interface, as shown below:

```typescript

import { LoggerService, LogLevel, Injectable } from '@nestjs/common';

@Injectable()
export class MyLogger implements LoggerService {
  /**
   * Write a 'log' level log.
   */
  log(message: any, ...optionalParams: any[]) {}

  /**
   * Write a 'fatal' level log.
   */
  fatal(message: any, ...optionalParams: any[]) {}

  /**
   * Write an 'error' level log.
   */
  error(message: any, ...optionalParams: any[]) {}

  /**
   * Write a 'warn' level log.
   */
  warn(message: any, ...optionalParams: any[]) {}

  /**
   * Write a 'debug' level log.
   */
  debug?(message: any, ...optionalParams: any[]) {}

  /**
   * Write a 'verbose' level log.
   */
  verbose?(message: any, ...optionalParams: any[]) {}

  /**
   * Set the enabled log levels. Called by `app.useLogger()`
   * when it's given an array of levels.
   */
  setLogLevels?(levels: LogLevel[]) {}
}
```

You can then supply an instance of `MyLogger` via the `logger` property of the Nest application options object:

```typescript

const app = await NestFactory.create(AppModule, {
  logger: new MyLogger(),
});
await app.listen(process.env.PORT ?? 3000);
```

This technique, while simple, doesn't use dependency injection for the `MyLogger` class. This can pose challenges, particularly for testing, and limits the reusability of `MyLogger`. For a better solution, see the [Dependency injection](application/logger#dependency-injection) section below.

#### Extend built-in logger[#](/application/logger#extend-built-in-logger)

Rather than writing a logger from scratch, you may be able to meet your needs by extending the built-in `ConsoleLogger` class and overriding selected behavior of the default implementation:

```typescript

import { ConsoleLogger } from '@nestjs/common';

export class MyLogger extends ConsoleLogger {
  error(message: any, stack?: string, context?: string) {
    // add your tailored logic here
    super.error(...arguments);
  }
}
```

The same approach changes the timestamp format. For example, to print ISO 8601 timestamps instead of the locale-formatted date, override the protected `getTimestamp()` method:

```typescript

import { ConsoleLogger } from '@nestjs/common';

export class IsoTimestampLogger extends ConsoleLogger {
  protected getTimestamp() {
    return new Date().toISOString();
  }
}
```

```bash

[Nest] 19096  - 2026-09-28T06:46:17.869Z     LOG [NestFactory] Starting Nest application...
```

This applies to text output only. With [JSON logging](/application/logger#json-logging), the `timestamp` field is always milliseconds since the Unix epoch.

You can use such an extended logger in your feature modules as described in the [Using the logger for application logging](application/logger#using-the-logger-for-application-logging) section above.

You can tell Nest to use your extended logger for system logging by passing an instance of it via the `logger` property of the application options object (as shown in the [Custom implementation](application/logger#custom-implementation) section above), or by using the technique shown in the [Dependency injection](application/logger#dependency-injection) section below. If you do so, call `super`, as shown in the sample code above, to delegate the log method call to the parent (built-in) class so that Nest can rely on the built-in features it expects.

## Learn the right way!

* 80+ chapters
* 5+ hours of videos
* Official certificate
* Deep-dive sessions

[Explore official courses](https://courses.nestjs.com "Courses | NestJS - A node.js framework built on top of TypeScript")

#### Dependency injection[#](/application/logger#dependency-injection)

For more advanced logging functionality, take advantage of dependency injection. For example, you may want to inject a `ConfigService` into your logger to customize it, and in turn inject your custom logger into other controllers and/or providers. To enable dependency injection for your custom logger, create a class that implements `LoggerService` and register that class as a provider in a module. For example, you can:

1. Define a `MyLogger` class that either extends the built-in `ConsoleLogger` or completely overrides it, as shown in the previous sections. Be sure to implement the `LoggerService` interface.
2. Create a `LoggerModule` as shown below, and provide `MyLogger` from that module.

```typescript

import { Module } from '@nestjs/common';
import { MyLogger } from './my-logger.service.js';

@Module({
  providers: [MyLogger],
  exports: [MyLogger],
})
export class LoggerModule {}
```

With this construct, your custom logger is available to any other module. Because your `MyLogger` class is part of a module, it can use dependency injection (for example, to inject a `ConfigService`). One more step is needed for Nest to use this custom logger for system logging (e.g., for bootstrapping and error handling).

Because application instantiation (`NestFactory.create()`) happens outside the context of any module, it doesn't participate in the normal dependency injection phase of initialization. So you must ensure that at least one application module imports the `LoggerModule`, which triggers Nest to instantiate a singleton instance of the `MyLogger` class.

You can then instruct Nest to use the same singleton instance of `MyLogger` with the following construction:

```typescript

const app = await NestFactory.create(AppModule, {
  bufferLogs: true,
});
app.useLogger(app.get(MyLogger));
await app.listen(process.env.PORT ?? 3000);
```

> **Note** In the example above, `bufferLogs` is set to `true` so that all logs are held in a buffer until a custom logger (`MyLogger` in this case) is attached. With `autoFlushLogs` enabled (the default), Nest flushes the buffer on its own: an HTTP application (or microservice) flushes it when it starts listening in `app.listen()`, and a standalone [application context](/standalone-applications) flushes it when you call `app.useLogger()`. If initialization fails, Nest flushes it right away. When Nest can't create a provider (for example, because its factory throws), it falls back to the original `ConsoleLogger` to print the buffer and the error. When a lifecycle hook such as `onModuleInit()` rejects, Nest prints the buffer through the logger you attached (or through the original one, if none is attached yet) but doesn't log the error: the call that started initialization, such as `app.listen()`, rejects with it. Set `autoFlushLogs` to `false` to flush the buffer yourself with `app.flushLogs()` (or the static `Logger.flush()`).

Here, the `get()` method of the `NestApplication` instance retrieves the singleton instance of `MyLogger`. This technique is essentially a way to "inject" a logger instance for use by Nest. The `app.get()` call depends on that instance first being instantiated through a module import, as described above.

You can also inject this `MyLogger` provider into your feature classes, ensuring consistent logging behavior across both Nest system logging and application logging. See [Using the logger for application logging](application/logger#using-the-logger-for-application-logging) and [Injecting a custom logger](application/logger#injecting-a-custom-logger) below for more information.

> **Warning** If a provider factory or a lifecycle hook calls `process.exit()` itself (for example, after a failed connection check), or a startup step never settles (such as a connection that keeps retrying), nothing in the buffer is printed, not even when you stop the process with `Ctrl+C`. Throw an error instead, so that initialization fails and Nest flushes the buffer.

When startup logs must always be visible, even if the process exits or stalls, don't buffer them: pass a logger instance as the `logger` option of `NestFactory.create()`, as shown in [Custom implementation](/application/logger#custom-implementation), so that Nest hands each line to it as soon as it is logged. That instance is created outside the dependency injection system, so it can't inject providers such as `ConfigService`.

#### Injecting a custom logger[#](/application/logger#injecting-a-custom-logger)

To start, extend the built-in logger with code like the following. The `scope` option, supplied as configuration metadata for the `ConsoleLogger` subclass, specifies a [transient](/fundamentals/injection-scopes) scope so that each consumer gets its own logger instance. This is important because each module sets a unique context on its logger via `setContext()` — with a singleton, that call would overwrite the context across the entire app. In this example, we do not extend the individual `ConsoleLogger` methods (like `log()`, `warn()`, etc.), though you may choose to do so.

```typescript

import { Injectable, Scope, ConsoleLogger } from '@nestjs/common';

@Injectable({ scope: Scope.TRANSIENT })
export class MyLogger extends ConsoleLogger {
  customLog() {
    this.log('Please feed the cat!');
  }
}
```

Next, create a `LoggerModule` with a construction like this:

```typescript

import { Module } from '@nestjs/common';
import { MyLogger } from './my-logger.service.js';

@Module({
  providers: [MyLogger],
  exports: [MyLogger],
})
export class LoggerModule {}
```

Next, import the `LoggerModule` into your feature module. Because `MyLogger` extends `ConsoleLogger`, you can use its `setContext()` method and start using the context-aware custom logger, like this:

```typescript

import { Injectable } from '@nestjs/common';
import { MyLogger } from './my-logger.service.js';

@Injectable()
export class CatsService {
  private readonly cats: Cat[] = [];

  constructor(private myLogger: MyLogger) {
    // Due to transient scope, CatsService has its own unique instance of MyLogger,
    // so setting context here will not affect other instances in other services
    this.myLogger.setContext('CatsService');
  }

  findAll(): Cat[] {
    // You can call all the default methods
    this.myLogger.warn('About to return cats!');
    // And your custom methods
    this.myLogger.customLog();
    return this.cats;
  }
}
```

`MyLogger` inherits the rest of the `ConsoleLogger` API too: `resetContext()` restores the context passed to the constructor, and `isLevelEnabled('debug')` tells you whether a level is currently enabled, so you can skip preparing data for a line that would be discarded.

Finally, instruct Nest to use an instance of the custom logger in your `main.ts` file, as shown below. This example doesn't customize the logger behavior (by overriding `ConsoleLogger` methods like `log()`, `warn()`, etc.), so this step isn't strictly needed here. It **is** needed if you add custom logic to those methods and want Nest to use the same implementation.

```typescript

const app = await NestFactory.create(AppModule, {
  bufferLogs: true,
});
app.useLogger(new MyLogger());
await app.listen(process.env.PORT ?? 3000);
```

> **Hint** Alternatively, instead of setting `bufferLogs` to `true`, you could temporarily disable the logger with the `logger: false` option. Be aware that if you pass `logger: false` to `NestFactory.create()`, nothing is logged until you call `useLogger()`, so you may miss important initialization errors. If you don't mind some initial messages being logged with the default logger, omit the `logger: false` option.

#### Correlating logs with requests[#](/application/logger#correlating-logs-with-requests)

Centralizing logs solves storage, not investigation. Once every instance ships to the same place, the hard part becomes reconstructing a *single* request out of thousands of interleaved lines. That is why so much production debugging is really the work of inventing a correlation id, threading it through every log call, and hoping nothing on the path forgot to pass it along.

[NestJS Observe](https://www.observe.nestjs.com/ "NestJS Observe") removes that bookkeeping. Turn on `forwardLogs` and every line written through Nest's `Logger` is captured with the trace it was written in already attached:

```typescript

ObserveModule.forRoot({
  serviceId: 'orders-api',
  forwardLogs: true,
});
```

You keep calling `this.logger.log()` with an `orderId` param exactly as before: no correlation id to generate, no context object to thread through your service layer. On an execution page, the logs for that one request are then placed on the trace's own clock, each line sitting next to the span that was in flight when it was written, so "the retry warning fired *before* the timeout, not after" is something you can see instead of infer from timestamps across three log streams.

Structured logging params carry through as well, so `orderId` stays a queryable field rather than being flattened into the message text. Log lines are also alertable in their own right, for example: "tell me when `payment declined` appears more than 10 times in 15 minutes".

If you would rather keep log content in your own aggregator, you do not have to forward anything. Even with `forwardLogs` off, the SDK augments `ConsoleLogger` so every line written during a request carries that request's trace id: at the end of the line in the default format (` Trace ID: <id>`, after the message), and as a `traceId` field with [JSON logging](/application/logger#json-logging) enabled:

```json

{"level":"log","pid":66803,"timestamp":1789978166281,"message":"Payment captured","context":"OrdersService","traceId":"0199a3f2-7c1e-7b40-9d2a-5e8f1c3b7a64"}
```

That id is enough to jump from a line in your existing stack to the full trace in the dashboard. It is on by default and controlled by the `attachTraceIdToLogs` option (see [Trace correlation](/observability/sdk#trace-correlation)). Lines written outside a request (during bootstrap, for example) are left as they are. The augmentation applies to Nest's built-in `ConsoleLogger` only, so if you replace it with an [external logger](/application/logger#use-external-logger), read the id yourself with `TracerService.currentTraceId()`. See the [SDK reference](/observability/sdk#logs) for forwarding and its redaction settings.

The trace id is not the only thing that lives for the length of a request. The SDK keeps an `AsyncLocalStorage` store for every request, job, and message it instruments, and `TracerService` exposes it through `setAttribute()` and `getAttribute()`. That is the natural place for the user or tenant a request is acting for, readable from anywhere downstream without threading it through every call. See [Request-scoped attributes](/observability/manual-instrumentation#request-scoped-attributes), and the [Async local storage](/recipes/async-local-storage) recipe for how it compares to a store you set up yourself.

#### Use external logger[#](/application/logger#use-external-logger)

As [Logging in production](/application/logger#logging-in-production) shows, the built-in logger already covers structured, centralized logging for most applications. Some requirements still call for a dedicated library such as [Pino](https://github.com/pinojs/pino) or [Winston](https://github.com/winstonjs/winston): multiple in-process transports (files, syslog, HTTP), redaction of sensitive fields, custom serializers, or the lowest possible overhead on services that log at very high volume. As with any standard Node.js application, you can take full advantage of such modules in Nest: implement the `LoggerService` interface as described in [Custom implementation](/application/logger#custom-implementation), or use a community integration.

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/application/logger.md)

----
url: https://docs.nestjs.com/v11/graphql/field-middleware
----

* [Field middleware](https://docs.nestjs.com/v11/graphql/field-middleware#field-middleware)
* [Getting started](https://docs.nestjs.com/v11/graphql/field-middleware#getting-started)
* [Global field middleware](https://docs.nestjs.com/v11/graphql/field-middleware#global-field-middleware)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/field-middleware.md "Suggest Edits")

### Field middleware

> **Warning** This chapter applies only to the code first approach.

Field Middleware lets you run arbitrary code **before or after** a field is resolved. A field middleware can be used to convert the result of a field, validate the arguments of a field, or even check field-level roles (for example, required to access a target field for which a middleware function is executed).

You can connect multiple middleware functions to a field. In this case, they will be called sequentially along the chain where the previous middleware decides to call the next one. The order of the middleware functions in the `middleware` array is important. The first resolver is the "most-outer" layer, so it gets executed first and last (similarly to the `graphql-middleware` package). The second resolver is the "second-outer" layer, so it gets executed second and second to last.

#### Getting started[#](/graphql/field-middleware#getting-started)

Let's start off by creating a simple middleware that will log a field value before it's sent back to the client:

```typescript

import { FieldMiddleware, MiddlewareContext, NextFn } from '@nestjs/graphql';

const loggerMiddleware: FieldMiddleware = async (
  ctx: MiddlewareContext,
  next: NextFn,
) => {
  const value = await next();
  console.log(value);
  return value;
};
```

> **Hint** The `MiddlewareContext` is an object that consist of the same arguments that are normally received by the GraphQL resolver function (`{ source, args, context, info }`), while `NextFn` is a function that let you execute the next middleware in the stack (bound to this field) or the actual field resolver.

> **Warning** Field middleware functions cannot inject dependencies nor access Nest's DI container as they are designed to be very lightweight and shouldn't perform any potentially time-consuming operations (like retrieving data from the database). If you need to call external services/query data from the data source, you should do it in a guard/interceptor bounded to a root query/mutation handler and assign it to `context` object which you can access from within the field middleware (specifically, from the `MiddlewareContext` object).

Note that field middleware must match the `FieldMiddleware` interface. In the example above, we first run the `next()` function (which executes the actual field resolver and returns a field value) and then, we log this value to our terminal. Also, the value returned from the middleware function completely overrides the previous value and since we don't want to perform any changes, we simply return the original value.

With this in place, we can register our middleware directly in the `@Field()` decorator, as follows:

```typescript

@ObjectType()
export class Recipe {
  @Field({ middleware: [loggerMiddleware] })
  title: string;
}
```

Now whenever we request the `title` field of `Recipe` object type, the original field's value will be logged to the console.

> **Hint** To learn how you can implement a field-level permissions system with the use of [extensions](/v11/graphql/extensions) feature, check out this [section](/graphql/extensions#using-custom-metadata).

> **Warning** Field middleware can be applied only to `ObjectType` classes. For more details, check out this [issue](https://github.com/nestjs/graphql/issues/2446).

Also, as mentioned above, we can control the field's value from within the middleware function. For demonstration purposes, let's capitalise a recipe's title (if present):

```typescript

const value = await next();
return value?.toUpperCase();
```

In this case, every title will be automatically uppercased, when requested.

Likewise, you can bind a field middleware to a custom field resolver (a method annotated with the `@ResolveField()` decorator), as follows:

```typescript

@ResolveField(() => String, { middleware: [loggerMiddleware] })
title() {
  return 'Placeholder';
}
```

> **Warning** In case enhancers are enabled at the field resolver level ([read more](/graphql/other-features#execute-enhancers-at-the-field-resolver-level)), field middleware functions will run before any interceptors, guards, etc., **bounded to the method** (but after the root-level enhancers registered for query or mutation handlers).

#### Global field middleware[#](/graphql/field-middleware#global-field-middleware)

In addition to binding a middleware directly to a specific field, you can also register one or multiple middleware functions globally. In this case, they will be automatically connected to all fields of your object types.

```typescript

GraphQLModule.forRoot({
  autoSchemaFile: 'schema.gql',
  buildSchemaOptions: {
    fieldMiddleware: [loggerMiddleware],
  },
}),
```

> **Hint** Globally registered field middleware functions will be executed **before** locally registered ones (those bound directly to specific fields).

----
url: https://docs.nestjs.com/v9/fundamentals/injection-scopes
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Injection scopes](https://docs.nestjs.com/v9/fundamentals/injection-scopes#injection-scopes)
* [Provider scope](https://docs.nestjs.com/v9/fundamentals/injection-scopes#provider-scope)
* [Usage](https://docs.nestjs.com/v9/fundamentals/injection-scopes#usage)
* [Controller scope](https://docs.nestjs.com/v9/fundamentals/injection-scopes#controller-scope)
* [Scope hierarchy](https://docs.nestjs.com/v9/fundamentals/injection-scopes#scope-hierarchy)
* [Request provider](https://docs.nestjs.com/v9/fundamentals/injection-scopes#request-provider)
* [Inquirer provider](https://docs.nestjs.com/v9/fundamentals/injection-scopes#inquirer-provider)
* [Performance](https://docs.nestjs.com/v9/fundamentals/injection-scopes#performance)
* [Durable providers](https://docs.nestjs.com/v9/fundamentals/injection-scopes#durable-providers)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/fundamentals/provider-scopes.md "Suggest Edits")

### Injection scopes

For people coming from different programming language backgrounds, it might be unexpected to learn that in Nest, almost everything is shared across incoming requests. We have a connection pool to the database, singleton services with global state, etc. Remember that Node.js doesn't follow the request/response Multi-Threaded Stateless Model in which every request is processed by a separate thread. Hence, using singleton instances is fully **safe** for our applications.

However, there are edge-cases when request-based lifetime may be the desired behavior, for instance per-request caching in GraphQL applications, request tracking, and multi-tenancy. Injection scopes provide a mechanism to obtain the desired provider lifetime behavior.

#### Provider scope[#](/fundamentals/injection-scopes#provider-scope)

A provider can have any of the following scopes:

|             |                                                                                                                                                                                                                                                                            |
| ----------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `DEFAULT`   | A single instance of the provider is shared across the entire application. The instance lifetime is tied directly to the application lifecycle. Once the application has bootstrapped, all singleton providers have been instantiated. Singleton scope is used by default. |
| `REQUEST`   | A new instance of the provider is created exclusively for each incoming **request**. The instance is garbage-collected after the request has completed processing.                                                                                                         |
| `TRANSIENT` | Transient providers are not shared across consumers. Each consumer that injects a transient provider will receive a new, dedicated instance.                                                                                                                               |

> **Hint** Using singleton scope is **recommended** for most use cases. Sharing providers across consumers and across requests means that an instance can be cached and its initialization occurs only once, during application startup.

#### Usage[#](/fundamentals/injection-scopes#usage)

Specify injection scope by passing the `scope` property to the `@Injectable()` decorator options object:

```typescript

import { Injectable, Scope } from '@nestjs/common';

@Injectable({ scope: Scope.REQUEST })
export class CatsService {}
```

Similarly, for [custom providers](/v9/fundamentals/custom-providers), set the `scope` property in the long-hand form for a provider registration:

```typescript

{
  provide: 'CACHE_MANAGER',
  useClass: CacheManager,
  scope: Scope.TRANSIENT,
}
```

> **Hint** Import the `Scope` enum from `@nestjs/common`

Singleton scope is used by default, and need not be declared. If you do want to declare a provider as singleton scoped, use the `Scope.DEFAULT` value for the `scope` property.

> **Notice** Websocket Gateways should not use request-scoped providers because they must act as singletons. Each gateway encapsulates a real socket and cannot be instantiated multiple times. The limitation also applies to some other providers, like [*Passport strategies*](../security/authentication#request-scoped-strategies) or *Cron controllers*.

#### Controller scope[#](/fundamentals/injection-scopes#controller-scope)

Controllers can also have scope, which applies to all request method handlers declared in that controller. Like provider scope, the scope of a controller declares its lifetime. For a request-scoped controller, a new instance is created for each inbound request, and garbage-collected when the request has completed processing.

Declare controller scope with the `scope` property of the `ControllerOptions` object:

```typescript

@Controller({
  path: 'cats',
  scope: Scope.REQUEST,
})
export class CatsController {}
```

```typescript

import { Injectable, Scope, Inject } from '@nestjs/common';
import { REQUEST } from '@nestjs/core';
import { Request } from 'express';

@Injectable({ scope: Scope.REQUEST })
export class CatsService {
  constructor(@Inject(REQUEST) private request: Request) {}
}
```

Because of underlying platform/protocol differences, you access the inbound request slightly differently for Microservice or GraphQL applications. In [GraphQL](/v9/graphql/quick-start) applications, you inject `CONTEXT` instead of `REQUEST`:

```typescript

import { Injectable, Scope, Inject } from '@nestjs/common';
import { CONTEXT } from '@nestjs/graphql';

@Injectable({ scope: Scope.REQUEST })
export class CatsService {
  constructor(@Inject(CONTEXT) private context) {}
}
```

You then configure your `context` value (in the `GraphQLModule`) to contain `request` as its property.

#### Inquirer provider[#](/fundamentals/injection-scopes#inquirer-provider)

If you want to get the class where a provider was constructed, for instance in logging or metrics providers, you can inject the `INQUIRER` token.

```typescript

import { Inject, Injectable, Scope } from '@nestjs/common';
import { INQUIRER } from '@nestjs/core';

@Injectable({ scope: Scope.TRANSIENT })
export class HelloService {
  constructor(@Inject(INQUIRER) private parentClass: object) {}

  sayHello(message: string) {
    console.log(`${this.parentClass?.constructor?.name}: ${message}`);
  }
}
```

And then use it as follows:

```typescript

import { Injectable } from '@nestjs/common';
import { HelloService } from './hello.service';

@Injectable()
export class AppService {
  constructor(private helloService: HelloService) {}

  getRoot(): string {
    this.helloService.sayHello('My name is getRoot');

    return 'Hello world!';
  }
}
```

In the example above when `AppService#getRoot` is called, `"AppService: My name is getRoot"` will be logged to the console.

#### Performance[#](/fundamentals/injection-scopes#performance)

Using request-scoped providers will have an impact on application performance. While Nest tries to cache as much metadata as possible, it will still have to create an instance of your class on each request. Hence, it will slow down your average response time and overall benchmarking result. Unless a provider must be request-scoped, it is strongly recommended that you use the default singleton scope.

> **Hint** Although it all sounds quite intimidating, a properly designed application that leverages request-scoped providers should not slow down by more than \~5% latency-wise.

#### Durable providers[#](/fundamentals/injection-scopes#durable-providers)

Request-scoped providers, as mentioned in the section above, may lead to increased latency since having at least 1 request-scoped provider (injected into the controller instance, or deeper - injected into one of its providers) makes the controller request-scoped as well. That means, it must be recreated (instantiated) per each individual request (and garbage collected afterwards). Now, that also means, that for let's say 30k requests in parallel, there will be 30k ephemeral instances of the controller (and its request-scoped providers).

Having a common provider that most providers depend on (think of a database connection, or a logger service), automatically converts all those providers to request-scoped providers as well. This can pose a challenge in **multi-tenant applications**, especially for those that have a central request-scoped "data source" provider that grabs headers/token from the request object and based on its values, retrieves the corresponding database connection/schema (specific to that tenant).

For instance, let's say you have an application alternately used by 10 different customers. Each customer has its **own dedicated data source**, and you want to make sure customer A will never be able to reach customer's B database. One way to achieve this could be to declare a request-scoped "data source" provider that - based on the request object - determines what's the "current customer" and retrieves its corresponding database. With this approach, you can turn your application into a multi-tenant application in just a few minutes. But, a major downside to this approach is that since most likely a large chunk of your application' components rely on the "data source" provider, they will implicitly become "request-scoped", and therefore you will undoubtedly see an impact in your apps performance.

But what if we had a better solution? Since we only have 10 customers, couldn't we have 10 individual [DI sub-trees](/fundamentals/module-ref#resolving-scoped-providers) per customer (instead of recreating each tree per request)? If your providers don't rely on any property that's truly unique for each consecutive request (e.g., request UUID) but instead there're some specific attributes that let us aggregate (classify) them, there's no reason to *recreate DI sub-tree* on every incoming request.

And that's exactly when the **durable providers** come in handy.

Before we start flagging providers as durable, we must first register a **strategy** that instructs Nest what are those "common request attributes", provide logic that groups requests - associates them with their corresponding DI sub-trees.

```typescript

import {
  HostComponentInfo,
  ContextId,
  ContextIdFactory,
  ContextIdStrategy,
} from '@nestjs/core';
import { Request } from 'express';

const tenants = new Map<string, ContextId>();

export class AggregateByTenantContextIdStrategy implements ContextIdStrategy {
  attach(contextId: ContextId, request: Request) {
    const tenantId = request.headers['x-tenant-id'] as string;
    let tenantSubTreeId: ContextId;

    if (tenants.has(tenantId)) {
      tenantSubTreeId = tenants.get(tenantId);
    } else {
      tenantSubTreeId = ContextIdFactory.create();
      tenants.set(tenantId, tenantSubTreeId);
    }

    // If tree is not durable, return the original "contextId" object
    return (info: HostComponentInfo) =>
      info.isTreeDurable ? tenantSubTreeId : contextId;
  }
}
```

> **Hint** Similar to the request scope, durability bubbles up the injection chain. That means if A depends on B which is flagged as `durable`, A implicitly becomes durable too (unless `durable` is explicitly set to `false` for A provider).

> **Warning** Note this strategy is not ideal for applications operating with a large number of tenants.

The value returned from the `attach` method instructs Nest what context identifier should be used for a given host. In this case, we specified that the `tenantSubTreeId` should be used instead of the original, auto-generated `contextId` object, when the host component (e.g., request-scoped controller) is flagged as durable (you can learn how to mark providers as durable below). Also, in the above example, **no payload** would be registered (where payload = `REQUEST`/`CONTEXT` provider that represents the "root" - parent of the sub-tree).

If you want to register the payload for a durable tree, use the following construction instead:

```typescript

// The return of `AggregateByTenantContextIdStrategy#attach` method:
return {
  resolve: (info: HostComponentInfo) =>
    info.isTreeDurable ? tenantSubTreeId : contextId,
  payload: { tenantId },
  }
```

Now whenever you inject the `REQUEST` provider (or `CONTEXT` for GraphQL applications) using the `@Inject(REQUEST)`/`@Inject(CONTEXT)`, the `payload` object would be injected (consisting of a single property - `tenantId` in this case).

Alright so with this strategy in place, you can register it somewhere in your code (as it applies globally anyway), so for example, you could place it in the `main.ts` file:

```typescript

ContextIdFactory.apply(new AggregateByTenantContextIdStrategy());
```

> **Hint** The `ContextIdFactory` class is imported from the `@nestjs/core` package.

As long as the registration occurs before any request hits your application, everything will work as intended.

Lastly, to turn a regular provider into a durable provider, simply set the `durable` flag to `true` and change its scope to `Scope.REQUEST` (not needed if the REQUEST scope is in the injection chain already):

```typescript

import { Injectable, Scope } from '@nestjs/common';

@Injectable({ scope: Scope.REQUEST, durable: true })
export class CatsService {}
```

Similarly, for [custom providers](/v9/fundamentals/custom-providers), set the `durable` property in the long-hand form for a provider registration:

```typescript

{
  provide: 'foobar',
  useFactory: () => { ... },
  scope: Scope.REQUEST,
  durable: true,
}
```

----
url: https://docs.nestjs.com/openapi/other-features
----

[Skip to content](#content)

On this page

* [Other features](https://docs.nestjs.com/openapi/other-features#other-features)
* [Global prefix](https://docs.nestjs.com/openapi/other-features#global-prefix)
* [Global parameters](https://docs.nestjs.com/openapi/other-features#global-parameters)
* [Global responses](https://docs.nestjs.com/openapi/other-features#global-responses)
* [Multiple specifications](https://docs.nestjs.com/openapi/other-features#multiple-specifications)
* [Dropdown in the explorer bar](https://docs.nestjs.com/openapi/other-features#dropdown-in-the-explorer-bar)

[](https://srv.carbonads.net/ads/click/x/GTND4277CVSD5KJUCAYLYKQUF67D62Q7CW7DTZ3JCAAI6KQJCASIV2QKFT7IP2QYFT7I4KJUCTYIC53NCVYD553KC6SILKJUCT7DEK3EHJNCLSIZ)[Your side project deserves Lambda, not localhost. Start building ](https://srv.carbonads.net/ads/click/x/GTND4277CVSD5KJUCAYLYKQUF67D62Q7CW7DTZ3JCAAI6KQJCASIV2QKFT7IP2QYFT7I4KJUCTYIC53NCVYD553KC6SILKJUCT7DEK3EHJNCLSIZ)[ads via Carbon](http://carbonads.net/?utm_source=nestjscom\&utm_medium=ad_via_link\&utm_campaign=in_unit\&utm_term=carbon)

### Other features

This page covers other features of the Swagger module that you may find useful.

#### Global prefix[#](/openapi/other-features#global-prefix)

To ignore the global prefix set through `setGlobalPrefix()`, use the `ignoreGlobalPrefix` option:

```typescript

const document = SwaggerModule.createDocument(app, options, {
  ignoreGlobalPrefix: true,
});
```

#### Global parameters[#](/openapi/other-features#global-parameters)

To define parameters for all routes, use `DocumentBuilder`:

```typescript

const config = new DocumentBuilder()
  .addGlobalParameters({
    name: 'tenantId',
    in: 'header',
  })
  // other configurations
  .build();
```

#### Global responses[#](/openapi/other-features#global-responses)

To define global responses for all routes, use `DocumentBuilder`. This is useful for setting up consistent responses across all endpoints in your application, such as error codes like `401 Unauthorized` or `500 Internal Server Error`.

```typescript

const config = new DocumentBuilder()
  .addGlobalResponse({
    status: 500,
    description: 'Internal server error',
  })
  // other configurations
  .build();
```

#### Multiple specifications[#](/openapi/other-features#multiple-specifications)

The `SwaggerModule` supports multiple specifications. In other words, you can serve different documentation, with different UIs, on different endpoints.

To support multiple specifications, your application must be written with a modular approach. The `createDocument()` method takes a third argument, `extraOptions`, which is an object with an `include` property. The `include` property takes an array of modules.

Set up support for multiple specifications as shown below:

```typescript

import { NestFactory } from '@nestjs/core';
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
import { AppModule } from './app.module.js';
import { CatsModule } from './cats/cats.module.js';
import { DogsModule } from './dogs/dogs.module.js';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);

  /**
   * createDocument(application, configurationOptions, extraOptions);
   *
   * createDocument method takes an optional 3rd argument "extraOptions"
   * which is an object with "include" property where you can pass an Array
   * of Modules that you want to include in that Swagger Specification
   * E.g: CatsModule and DogsModule will have two separate Swagger Specifications which
   * will be exposed on two different SwaggerUI with two different endpoints.
   */

  const options = new DocumentBuilder()
    .setTitle('Cats example')
    .setDescription('The cats API description')
    .setVersion('1.0')
    .addTag('cats')
    .build();

  const catDocumentFactory = () =>
    SwaggerModule.createDocument(app, options, {
      include: [CatsModule],
    });
  SwaggerModule.setup('api/cats', app, catDocumentFactory);

  const secondOptions = new DocumentBuilder()
    .setTitle('Dogs example')
    .setDescription('The dogs API description')
    .setVersion('1.0')
    .addTag('dogs')
    .build();

  const dogDocumentFactory = () =>
    SwaggerModule.createDocument(app, secondOptions, {
      include: [DogsModule],
    });
  SwaggerModule.setup('api/dogs', app, dogDocumentFactory);

  await app.listen(process.env.PORT ?? 3000);
}
await bootstrap();
```

Now start your server with the following command:

```bash

$ npm run start
```

Navigate to `http://localhost:3000/api/cats` to see the Swagger UI for cats:

In turn, `http://localhost:3000/api/dogs` will expose the Swagger UI for dogs:

#### Dropdown in the explorer bar[#](/openapi/other-features#dropdown-in-the-explorer-bar)

To list multiple specifications in the dropdown menu of the explorer bar, set `explorer: true` and configure `swaggerOptions.urls` in your `SwaggerCustomOptions`.

> **Hint** Make sure that `swaggerOptions.urls` points to the JSON format of your Swagger documents. To specify the JSON document's path, use the `jsonDocumentUrl` option of `SwaggerCustomOptions`. For more options, see [setup options](/openapi/introduction#setup-options).

Here's how to select multiple specifications from a dropdown in the explorer bar:

```typescript

import { NestFactory } from '@nestjs/core';
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
import { AppModule } from './app.module.js';
import { CatsModule } from './cats/cats.module.js';
import { DogsModule } from './dogs/dogs.module.js';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);

  // Main API options
  const options = new DocumentBuilder()
    .setTitle('Multiple Specifications Example')
    .setDescription('Description for multiple specifications')
    .setVersion('1.0')
    .build();

  // Create main API document
  const document = SwaggerModule.createDocument(app, options);

  // Setup main API Swagger UI with dropdown support
  SwaggerModule.setup('api', app, document, {
    explorer: true,
    swaggerOptions: {
      urls: [
        {
          name: '1. API',
          url: 'api/swagger.json',
        },
        {
          name: '2. Cats API',
          url: 'api/cats/swagger.json',
        },
        {
          name: '3. Dogs API',
          url: 'api/dogs/swagger.json',
        },
      ],
    },
    jsonDocumentUrl: '/api/swagger.json',
  });

  // Cats API options
  const catOptions = new DocumentBuilder()
    .setTitle('Cats Example')
    .setDescription('Description for the Cats API')
    .setVersion('1.0')
    .addTag('cats')
    .build();

  // Create Cats API document
  const catDocument = SwaggerModule.createDocument(app, catOptions, {
    include: [CatsModule],
  });

  // Setup Cats API Swagger UI
  SwaggerModule.setup('api/cats', app, catDocument, {
    jsonDocumentUrl: '/api/cats/swagger.json',
  });

  // Dogs API options
  const dogOptions = new DocumentBuilder()
    .setTitle('Dogs Example')
    .setDescription('Description for the Dogs API')
    .setVersion('1.0')
    .addTag('dogs')
    .build();

  // Create Dogs API document
  const dogDocument = SwaggerModule.createDocument(app, dogOptions, {
    include: [DogsModule],
  });

  // Setup Dogs API Swagger UI
  SwaggerModule.setup('api/dogs', app, dogDocument, {
    jsonDocumentUrl: '/api/dogs/swagger.json',
  });

  await app.listen(process.env.PORT ?? 3000);
}

await bootstrap();
```

This example sets up a main API along with separate specifications for cats and dogs, each accessible from the dropdown in the explorer bar.

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/openapi/other-features.md)

----
url: https://docs.nestjs.com/v11/techniques/configuration
----

* [Configuration](https://docs.nestjs.com/v11/techniques/configuration#configuration)
* [Installation](https://docs.nestjs.com/v11/techniques/configuration#installation)
* [Getting started](https://docs.nestjs.com/v11/techniques/configuration#getting-started)
* [Custom env file path](https://docs.nestjs.com/v11/techniques/configuration#custom-env-file-path)
* [Disable env variables loading](https://docs.nestjs.com/v11/techniques/configuration#disable-env-variables-loading)
* [Use module globally](https://docs.nestjs.com/v11/techniques/configuration#use-module-globally)
* [Custom configuration files](https://docs.nestjs.com/v11/techniques/configuration#custom-configuration-files)
* [Using the ConfigService](https://docs.nestjs.com/v11/techniques/configuration#using-the-configservice)
* [Configuration namespaces](https://docs.nestjs.com/v11/techniques/configuration#configuration-namespaces)
* [Namespaced configurations in modules](https://docs.nestjs.com/v11/techniques/configuration#namespaced-configurations-in-modules)
* [Cache environment variables](https://docs.nestjs.com/v11/techniques/configuration#cache-environment-variables)
* [Partial registration](https://docs.nestjs.com/v11/techniques/configuration#partial-registration)
* [Schema validation](https://docs.nestjs.com/v11/techniques/configuration#schema-validation)
* [Custom validate function](https://docs.nestjs.com/v11/techniques/configuration#custom-validate-function)
* [Custom getter functions](https://docs.nestjs.com/v11/techniques/configuration#custom-getter-functions)
* [Environment variables loaded hook](https://docs.nestjs.com/v11/techniques/configuration#environment-variables-loaded-hook)
* [Conditional module configuration](https://docs.nestjs.com/v11/techniques/configuration#conditional-module-configuration)
* [Expandable variables](https://docs.nestjs.com/v11/techniques/configuration#expandable-variables)
* [Using in the main.ts](https://docs.nestjs.com/v11/techniques/configuration#using-in-the-maints)

```bash

$ npm i --save @nestjs/config
```

> **Hint** The `@nestjs/config` package internally uses [dotenv](https://github.com/motdotla/dotenv).

> **Note**`@nestjs/config` requires TypeScript 4.1 or later.

#### Getting started[#](/techniques/configuration#getting-started)

Once the installation process is complete, we can import the `ConfigModule`. Typically, we'll import it into the root `AppModule` and control its behavior using the `.forRoot()` static method. During this step, environment variable key/value pairs are parsed and resolved. Later, we'll see several options for accessing the `ConfigService` class of the `ConfigModule` in our other feature modules.

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';

@Module({
  imports: [ConfigModule.forRoot()],
})
export class AppModule {}
```

The above code will load and parse a `.env` file from the default location (the project root directory), merge key/value pairs from the `.env` file with environment variables assigned to `process.env`, and store the result in a private structure that you can access through the `ConfigService`. The `forRoot()` method registers the `ConfigService` provider, which provides a `get()` method for reading these parsed/merged configuration variables. Since `@nestjs/config` relies on [dotenv](https://github.com/motdotla/dotenv), it uses that package's rules for resolving conflicts in environment variable names. When a key exists both in the runtime environment as an environment variable (e.g., via OS shell exports like `export DATABASE_USER=test`) and in a `.env` file, the runtime environment variable takes precedence.

A sample `.env` file looks something like this:

```json

DATABASE_USER=test
DATABASE_PASSWORD=test
```

If you need some env variables to be available even before the `ConfigModule` is loaded and Nest application is bootstrapped (for example, to pass the microservice configuration to the `NestFactory#createMicroservice` method), you can use the `--env-file` option of the Nest CLI. This option allows you to specify the path to the `.env` file that should be loaded before the application starts. `--env-file` flag support was introduced in Node v20, see [the documentation](https://nodejs.org/dist/v20.18.1/docs/api/cli.html#--env-fileconfig) for more details.

```bash

$ nest start --env-file .env
```

#### Custom env file path[#](/techniques/configuration#custom-env-file-path)

By default, the package looks for a `.env` file in the root directory of the application. To specify another path for the `.env` file, set the `envFilePath` property of an (optional) options object you pass to `forRoot()`, as follows:

```typescript

ConfigModule.forRoot({
  envFilePath: '.development.env',
});
```

You can also specify multiple paths for `.env` files like this:

```typescript

ConfigModule.forRoot({
  envFilePath: ['.env.development.local', '.env.development'],
});
```

If a variable is found in multiple files, the first one takes precedence.

#### Disable env variables loading[#](/techniques/configuration#disable-env-variables-loading)

If you don't want to load the `.env` file, but instead would like to simply access environment variables from the runtime environment (as with OS shell exports like `export DATABASE_USER=test`), set the options object's `ignoreEnvFile` property to `true`, as follows:

```typescript

ConfigModule.forRoot({
  ignoreEnvFile: true,
});
```

#### Use module globally[#](/techniques/configuration#use-module-globally)

When you want to use `ConfigModule` in other modules, you'll need to import it (as is standard with any Nest module). Alternatively, declare it as a [global module](https://docs.nestjs.com/modules#global-modules) by setting the options object's `isGlobal` property to `true`, as shown below. In that case, you will not need to import `ConfigModule` in other modules once it's been loaded in the root module (e.g., `AppModule`).

```typescript

ConfigModule.forRoot({
  isGlobal: true,
});
```

#### Custom configuration files[#](/techniques/configuration#custom-configuration-files)

For more complex projects, you may utilize custom configuration files to return nested configuration objects. This allows you to group related configuration settings by function (e.g., database-related settings), and to store related settings in individual files to help manage them independently.

A custom configuration file exports a factory function that returns a configuration object. The configuration object can be any arbitrarily nested plain JavaScript object. The `process.env` object will contain the fully resolved environment variable key/value pairs (with `.env` file and externally defined variables resolved and merged as described [above](techniques/configuration#getting-started)). Since you control the returned configuration object, you can add any required logic to cast values to an appropriate type, set default values, etc. For example:

config/configuration.ts

JS TS

```typescript

export default () => ({
  port: parseInt(process.env.PORT, 10) || 3000,
  database: {
    host: process.env.DATABASE_HOST,
    port: parseInt(process.env.DATABASE_PORT, 10) || 5432
  }
});
```

We load this file using the `load` property of the options object we pass to the `ConfigModule.forRoot()` method:

```typescript

import configuration from './config/configuration';

@Module({
  imports: [
    ConfigModule.forRoot({
      load: [configuration],
    }),
  ],
})
export class AppModule {}
```

> **Notice** The value assigned to the `load` property is an array, allowing you to load multiple configuration files (e.g. `load: [databaseConfig, authConfig]`)

With custom configuration files, we can also manage custom files such as YAML files. Here is an example of a configuration using YAML format:

```yaml

http:
  host: 'localhost'
  port: 8080

db:
  postgres:
    url: 'localhost'
    port: 5432
    database: 'yaml-db'

  sqlite:
    database: 'sqlite.db'
```

To read and parse YAML files, we can leverage the `js-yaml` package.

```bash

$ npm i js-yaml
$ npm i -D @types/js-yaml
```

Once the package is installed, we use the `yaml#load` function to load the YAML file we just created above.

config/configuration.ts

JS TS

```typescript

import { readFileSync } from 'node:fs';
import { join } from 'node:path';
import * as yaml from 'js-yaml';

const YAML_CONFIG_FILENAME = 'config.yaml';

export default () => {
  return yaml.load(
    readFileSync(join(__dirname, YAML_CONFIG_FILENAME), 'utf8'),
  ) as Record<string, any>;
};
```

> **Note** Nest CLI does not automatically move your "assets" (non-TS files) to the `dist` folder during the build process. To make sure that your YAML files are copied, you have to specify this in the `compilerOptions#assets` object in the `nest-cli.json` file. As an example, if the `config` folder is at the same level as the `src` folder, add `compilerOptions#assets` with the value `"assets": [{"include": "../config/*.yaml", "outDir": "./dist/config"}]`. Read more [here](/cli/monorepo#assets).

Just a quick note - configuration files aren't automatically validated, even if you're using the `validationSchema` option in NestJS's `ConfigModule`. If you need validation or want to apply any transformations, you'll have to handle that within the factory function where you have complete control over the configuration object. This allows you to implement any custom validation logic as needed.

For example, if you want to ensure that port is within a certain range, you can add a validation step to the factory function:

config/configuration.ts

JS TS

```typescript

export default () => {
  const config = yaml.load(
    readFileSync(join(__dirname, YAML_CONFIG_FILENAME), 'utf8'),
  ) as Record<string, any>;

  if (config.http.port < 1024 || config.http.port > 49151) {
    throw new Error('HTTP port must be between 1024 and 49151');
  }

  return config;
};
```

```typescript

@Module({
  imports: [ConfigModule],
  // ...
})
```

Then we can inject it using standard constructor injection:

```typescript

constructor(private configService: ConfigService) {}
```

> **Hint** The `ConfigService` is imported from the `@nestjs/config` package.

And use it in our class:

```typescript

// get an environment variable
const dbUser = this.configService.get<string>('DATABASE_USER');

// get a custom configuration value
const dbHost = this.configService.get<string>('database.host');
```

As shown above, use the `configService.get()` method to get a simple environment variable by passing the variable name. You can do TypeScript type hinting by passing the type, as shown above (e.g., `get<string>(...)`). The `get()` method can also traverse a nested custom configuration object (created via a [Custom configuration file](techniques/configuration#custom-configuration-files)), as shown in the second example above.

You can also get the whole nested custom configuration object using an interface as the type hint:

```typescript

interface DatabaseConfig {
  host: string;
  port: number;
}

const dbConfig = this.configService.get<DatabaseConfig>('database');

// you can now use `dbConfig.port` and `dbConfig.host`
const port = dbConfig.port;
```

The `get()` method also takes an optional second argument defining a default value, which will be returned when the key doesn't exist, as shown below:

```typescript

// use "localhost" when "database.host" is not defined
const dbHost = this.configService.get<string>('database.host', 'localhost');
```

`ConfigService` has two optional generics (type arguments). The first one is to help prevent accessing a config property that does not exist. Use it as shown below:

```typescript

interface EnvironmentVariables {
  PORT: number;
  TIMEOUT: string;
}

// somewhere in the code
constructor(private configService: ConfigService<EnvironmentVariables>) {
  const port = this.configService.get('PORT', { infer: true });

  // TypeScript Error: this is invalid as the URL property is not defined in EnvironmentVariables
  const url = this.configService.get('URL', { infer: true });
}
```

With the `infer` property set to `true`, the `ConfigService#get` method will automatically infer the property type based on the interface, so for example, `typeof port === "number"` (if you're not using `strictNullChecks` flag from TypeScript) since `PORT` has a `number` type in the `EnvironmentVariables` interface.

Also, with the `infer` feature, you can infer the type of a nested custom configuration object's property, even when using dot notation, as follows:

```typescript

constructor(private configService: ConfigService<{ database: { host: string } }>) {
  const dbHost = this.configService.get('database.host', { infer: true })!;
  // typeof dbHost === "string"                                          |
  //                                                                     +--> non-null assertion operator
}
```

The second generic relies on the first one, acting as a type assertion to get rid of all `undefined` types that `ConfigService`'s methods can return when `strictNullChecks` is on. For instance:

```typescript

// ...
constructor(private configService: ConfigService<{ PORT: number }, true>) {
  //                                                               ^^^^
  const port = this.configService.get('PORT', { infer: true });
  //    ^^^ The type of port will be 'number' thus you don't need TS type assertions anymore
}
```

> **Hint** To make sure the `ConfigService#get` method retrieves values exclusively from custom configuration files and ignores `process.env` variables, set the `skipProcessEnv` option to `true` in the options object of the `ConfigModule`'s `forRoot()` method.

#### Configuration namespaces[#](/techniques/configuration#configuration-namespaces)

The `ConfigModule` allows you to define and load multiple custom configuration files, as shown in [Custom configuration files](techniques/configuration#custom-configuration-files) above. You can manage complex configuration object hierarchies with nested configuration objects as shown in that section. Alternatively, you can return a "namespaced" configuration object with the `registerAs()` function as follows:

config/database.config.ts

JS TS

```typescript

export default registerAs('database', () => ({
  host: process.env.DATABASE_HOST,
  port: process.env.DATABASE_PORT || 5432
}));
```

As with custom configuration files, inside your `registerAs()` factory function, the `process.env` object will contain the fully resolved environment variable key/value pairs (with `.env` file and externally defined variables resolved and merged as described [above](techniques/configuration#getting-started)).

> **Hint** The `registerAs` function is exported from the `@nestjs/config` package.

Load a namespaced configuration with the `load` property of the `forRoot()` method's options object, in the same way you load a custom configuration file:

```typescript

import databaseConfig from './config/database.config';

@Module({
  imports: [
    ConfigModule.forRoot({
      load: [databaseConfig],
    }),
  ],
})
export class AppModule {}
```

Now, to get the `host` value from the `database` namespace, use dot notation. Use `'database'` as the prefix to the property name, corresponding to the name of the namespace (passed as the first argument to the `registerAs()` function):

```typescript

const dbHost = this.configService.get<string>('database.host');
```

A reasonable alternative is to inject the `database` namespace directly. This allows us to benefit from strong typing:

```typescript

constructor(
  @Inject(databaseConfig.KEY)
  private dbConfig: ConfigType<typeof databaseConfig>,
) {}
```

> **Hint** The `ConfigType` is exported from the `@nestjs/config` package.

#### Namespaced configurations in modules[#](/techniques/configuration#namespaced-configurations-in-modules)

To use a namespaced configuration as a configuration object for another module in your application, you can utilize the `.asProvider()` method of the configuration object. This method converts your namespaced configuration into a provider, which can then be passed to the `forRootAsync()` (or any equivalent method) of the module you want to use.

Here's an example:

```typescript

import databaseConfig from './config/database.config';

@Module({
  imports: [
    TypeOrmModule.forRootAsync(databaseConfig.asProvider()),
  ],
})
```

To understand how the `.asProvider()` method functions, let's examine the return value:

```typescript

// Return value of the .asProvider() method
{
  imports: [ConfigModule.forFeature(databaseConfig)],
  useFactory: (configuration: ConfigType<typeof databaseConfig>) => configuration,
  inject: [databaseConfig.KEY]
}
```

This structure allows you to seamlessly integrate namespaced configurations into your modules, ensuring that your application remains organized and modular, without writing boilerplate, repetitive code.

#### Cache environment variables[#](/techniques/configuration#cache-environment-variables)

As accessing `process.env` can be slow, you can set the `cache` property of the options object passed to `ConfigModule.forRoot()` to increase the performance of `ConfigService#get` method when it comes to variables stored in `process.env`.

```typescript

ConfigModule.forRoot({
  cache: true,
});
```

#### Partial registration[#](/techniques/configuration#partial-registration)

Thus far, we've processed configuration files in our root module (e.g., `AppModule`), with the `forRoot()` method. Perhaps you have a more complex project structure, with feature-specific configuration files located in multiple different directories. Rather than load all these files in the root module, the `@nestjs/config` package provides a feature called **partial registration**, which references only the configuration files associated with each feature module. Use the `forFeature()` static method within a feature module to perform this partial registration, as follows:

```typescript

import databaseConfig from './config/database.config';

@Module({
  imports: [ConfigModule.forFeature(databaseConfig)],
})
export class DatabaseModule {}
```

> **Warning** In some circumstances, you may need to access properties loaded via partial registration using the `onModuleInit()` hook, rather than in a constructor. This is because the `forFeature()` method is run during module initialization, and the order of module initialization is indeterminate. If you access values loaded this way by another module, in a constructor, the module that the configuration depends upon may not yet have initialized. The `onModuleInit()` method runs only after all modules it depends upon have been initialized, so this technique is safe.

#### Schema validation[#](/techniques/configuration#schema-validation)

It is standard practice to throw an exception during application startup if required environment variables haven't been provided or if they don't meet certain validation rules. The `@nestjs/config` package enables two different ways to do this:

* [Joi](https://github.com/sideway/joi) built-in validator. With Joi, you define an object schema and validate JavaScript objects against it.
* A custom `validate()` function which takes environment variables as an input.

To use Joi, we must install Joi package:

```bash

$ npm install --save joi
```

Now we can define a Joi validation schema and pass it via the `validationSchema` property of the `forRoot()` method's options object, as shown below:

app.module.ts

JS TS

```typescript

import * as Joi from 'joi';

@Module({
  imports: [
    ConfigModule.forRoot({
      validationSchema: Joi.object({
        NODE_ENV: Joi.string()
          .valid('development', 'production', 'test', 'provision')
          .default('development'),
        PORT: Joi.number().port().default(3000),
      }),
    }),
  ],
})
export class AppModule {}
```

By default, all schema keys are considered optional. Here, we set default values for `NODE_ENV` and `PORT` which will be used if we don't provide these variables in the environment (`.env` file or process environment). Alternatively, we can use the `required()` validation method to require that a value must be defined in the environment (`.env` file or process environment). In this case, the validation step will throw an exception if we don't provide the variable in the environment. See [Joi validation methods](https://joi.dev/api/?v=17.3.0#example) for more on how to construct validation schemas.

By default, unknown environment variables (environment variables whose keys are not present in the schema) are allowed and do not trigger a validation exception. By default, all validation errors are reported. You can alter these behaviors by passing an options object via the `validationOptions` key of the `forRoot()` options object. This options object can contain any of the standard validation options properties provided by [Joi validation options](https://joi.dev/api/?v=17.3.0#anyvalidatevalue-options). For example, to reverse the two settings above, pass options like this:

app.module.ts

JS TS

```typescript

import * as Joi from 'joi';

@Module({
  imports: [
    ConfigModule.forRoot({
      validationSchema: Joi.object({
        NODE_ENV: Joi.string()
          .valid('development', 'production', 'test', 'provision')
          .default('development'),
        PORT: Joi.number().port().default(3000),
      }),
      validationOptions: {
        allowUnknown: false,
        abortEarly: true,
      },
    }),
  ],
})
export class AppModule {}
```

The `@nestjs/config` package uses default settings of:

* `allowUnknown`: controls whether or not to allow unknown keys in the environment variables. Default is `true`
* `abortEarly`: if true, stops validation on the first error; if false, returns all errors. Defaults to `false`.

Note that once you decide to pass a `validationOptions` object, any settings you do not explicitly pass will default to `Joi` standard defaults (not the `@nestjs/config` defaults). For example, if you leave `allowUnknowns` unspecified in your custom `validationOptions` object, it will have the `Joi` default value of `false`. Hence, it is probably safest to specify **both** of these settings in your custom object.

> **Hint** To disable validation of predefined environment variables, set the `validatePredefined` attribute to `false` in the `forRoot()` method's options object. Predefined environment variables are process variables (`process.env` variables) that were set before the module was imported. For example, if you start your application with `PORT=3000 node main.js`, then `PORT` is a predefined environment variable.

#### Custom validate function[#](/techniques/configuration#custom-validate-function)

Alternatively, you can specify a **synchronous**`validate` function that takes an object containing the environment variables (from env file and process) and returns an object containing validated environment variables so that you can convert/mutate them if needed. If the function throws an error, it will prevent the application from bootstrapping.

In this example, we'll proceed with the `class-transformer` and `class-validator` packages. First, we have to define:

* a class with validation constraints,
* a validate function that makes use of the `plainToInstance` and `validateSync` functions.

env.validation.ts

JS TS

```typescript

import { plainToInstance } from 'class-transformer';
import { IsEnum, IsNumber, Max, Min, validateSync } from 'class-validator';

enum Environment {
  Development = "development",
  Production = "production",
  Test = "test",
  Provision = "provision",
}

class EnvironmentVariables {
  @IsEnum(Environment)
  NODE_ENV: Environment;

  @IsNumber()
  @Min(0)
  @Max(65535)
  PORT: number;
}

export function validate(config: Record<string, unknown>) {
  const validatedConfig = plainToInstance(
    EnvironmentVariables,
    config,
    { enableImplicitConversion: true },
  );
  const errors = validateSync(validatedConfig, { skipMissingProperties: false });

  if (errors.length > 0) {
    throw new Error(errors.toString());
  }
  return validatedConfig;
}
```

With this in place, use the `validate` function as a configuration option of the `ConfigModule`, as follows:

app.module.ts

JS TS

```typescript

import { validate } from './env.validation';

@Module({
  imports: [
    ConfigModule.forRoot({
      validate,
    }),
  ],
})
export class AppModule {}
```

#### Custom getter functions[#](/techniques/configuration#custom-getter-functions)

`ConfigService` defines a generic `get()` method to retrieve a configuration value by key. We may also add `getter` functions to enable a little more natural coding style:

JS TS

```typescript

@Injectable()
export class ApiConfigService {
  constructor(private configService: ConfigService) {}

  get isAuthEnabled(): boolean {
    return this.configService.get('AUTH_ENABLED') === 'true';
  }
}
```

```typescript

@Dependencies(ConfigService)
@Injectable()
export class ApiConfigService {
  constructor(configService) {
    this.configService = configService;
  }

  get isAuthEnabled() {
    return this.configService.get('AUTH_ENABLED') === 'true';
  }
}
```

Now we can use the getter function as follows:

app.service.ts

JS TS

```typescript

@Injectable()
export class AppService {
  constructor(apiConfigService: ApiConfigService) {
    if (apiConfigService.isAuthEnabled) {
      // Authentication is enabled
    }
  }
}
```

```typescript

@Dependencies(ApiConfigService)
@Injectable()
export class AppService {
  constructor(apiConfigService) {
    if (apiConfigService.isAuthEnabled) {
      // Authentication is enabled
    }
  }
}
```

#### Environment variables loaded hook[#](/techniques/configuration#environment-variables-loaded-hook)

If a module configuration depends on the environment variables, and these variables are loaded from the `.env` file, you can use the `ConfigModule.envVariablesLoaded` hook to ensure that the file was loaded before interacting with the `process.env` object, see the following example:

```typescript

export async function getStorageModule() {
  await ConfigModule.envVariablesLoaded;
  return process.env.STORAGE === 'S3' ? S3StorageModule : DefaultStorageModule;
}
```

This construction guarantees that after the `ConfigModule.envVariablesLoaded` Promise resolves, all configuration variables are loaded up.

#### Conditional module configuration[#](/techniques/configuration#conditional-module-configuration)

There may be times where you want to conditionally load in a module and specify the condition in an env variable. Fortunately, `@nestjs/config` provides a `ConditionalModule` that allows you to do just that.

```typescript

@Module({
  imports: [
    ConfigModule.forRoot(),
    ConditionalModule.registerWhen(FooModule, 'USE_FOO'),
  ],
})
export class AppModule {}
```

The above module would only load in the `FooModule` if in the `.env` file there is not a `false` value for the env variable `USE_FOO`. You can also pass a custom condition yourself, a function receiving the `process.env` reference that should return a boolean for the `ConditionalModule` to handle:

```typescript

@Module({
  imports: [
    ConfigModule.forRoot(),
    ConditionalModule.registerWhen(
      FooBarModule,
      (env: NodeJS.ProcessEnv) => !!env['foo'] && !!env['bar'],
    ),
  ],
})
export class AppModule {}
```

It is important to be sure that when using the `ConditionalModule` you also have the `ConfigModule` loaded in the application, so that the `ConfigModule.envVariablesLoaded` hook can be properly referenced and utilized. If the hook is not flipped to true within 5 seconds, or a timeout in milliseconds, set by the user in the third options parameter of the `registerWhen` method, then the `ConditionalModule` will throw an error and Nest will abort starting the application.

#### Expandable variables[#](/techniques/configuration#expandable-variables)

The `@nestjs/config` package supports environment variable expansion. With this technique, you can create nested environment variables, where one variable is referred to within the definition of another. For example:

```json

APP_URL=mywebsite.com
SUPPORT_EMAIL=support@${APP_URL}
```

With this construction, the variable `SUPPORT_EMAIL` resolves to `'support@mywebsite.com'`. Note the use of the `${...}` syntax to trigger resolving the value of the variable `APP_URL` inside the definition of `SUPPORT_EMAIL`.

> **Hint** For this feature, `@nestjs/config` package internally uses [dotenv-expand](https://github.com/motdotla/dotenv-expand).

Enable environment variable expansion using the `expandVariables` property in the options object passed to the `forRoot()` method of the `ConfigModule`, as shown below:

app.module.ts

JS TS

```typescript

@Module({
  imports: [
    ConfigModule.forRoot({
      // ...
      expandVariables: true,
    }),
  ],
})
export class AppModule {}
```

#### Using in the `main.ts`[#](/techniques/configuration#using-in-the-maints)

While our config is stored in a service, it can still be used in the `main.ts` file. This way, you can use it to store variables such as the application port or the CORS host.

To access it, you must use the `app.get()` method, followed by the service reference:

```typescript

const configService = app.get(ConfigService);
```

You can then use it as usual, by calling the `get` method with the configuration key:

```typescript

const port = configService.get('PORT');
```

----
url: https://docs.nestjs.com/v10/security/csrf
----

* [CSRF Protection](https://docs.nestjs.com/v10/security/csrf#csrf-protection)
* [Use with Express (default)](https://docs.nestjs.com/v10/security/csrf#use-with-express-default)
* [Use with Fastify](https://docs.nestjs.com/v10/security/csrf#use-with-fastify)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/security/csrf.md "Suggest Edits")

### CSRF Protection

Cross-site request forgery (CSRF or XSRF) is a type of attack where **unauthorized** commands are sent from a trusted user to a web application. To help prevent this, you can use the [csrf-csrf](https://github.com/Psifi-Solutions/csrf-csrf) package.

#### Use with Express (default)[#](/security/csrf#use-with-express-default)

Start by installing the required package:

```bash

$ npm i csrf-csrf
```

> **Warning** As noted in the [csrf-csrf documentation](https://github.com/Psifi-Solutions/csrf-csrf?tab=readme-ov-file#getting-started), this middleware requires session middleware or `cookie-parser` to be initialized beforehand. Please refer to the documentation for further details.

Once the installation is complete, register the `csrf-csrf` middleware as global middleware.

```typescript

import { doubleCsrf } from 'csrf-csrf';
// ...
// somewhere in your initialization file
const {
  invalidCsrfTokenError, // This is provided purely for convenience if you plan on creating your own middleware.
  generateToken, // Use this in your routes to generate and provide a CSRF hash, along with a token cookie and token.
  validateRequest, // Also a convenience if you plan on making your own middleware.
  doubleCsrfProtection, // This is the default CSRF protection middleware.
} = doubleCsrf(doubleCsrfOptions);
app.use(doubleCsrfProtection);
```

#### Use with Fastify[#](/security/csrf#use-with-fastify)

Start by installing the required package:

```bash

$ npm i --save @fastify/csrf-protection
```

Once the installation is complete, register the `@fastify/csrf-protection` plugin, as follows:

```typescript

import fastifyCsrf from '@fastify/csrf-protection';
// ...
// somewhere in your initialization file after registering some storage plugin
await app.register(fastifyCsrf);
```

> **Warning** As explained in the `@fastify/csrf-protection` docs [here](https://github.com/fastify/csrf-protection#usage), this plugin requires a storage plugin to be initialized first. Please, see that documentation for further instructions.

----
url: https://docs.nestjs.com/v9/devtools/overview
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Overview](https://docs.nestjs.com/v9/devtools/overview#overview)
* [Investigating the "Cannot resolve dependency" error](https://docs.nestjs.com/v9/devtools/overview#investigating-the-cannot-resolve-dependency-error)
* [Routes explorer](https://docs.nestjs.com/v9/devtools/overview#routes-explorer)
* [Sandbox](https://docs.nestjs.com/v9/devtools/overview#sandbox)
* [Bootstrap performance analyzer](https://docs.nestjs.com/v9/devtools/overview#bootstrap-performance-analyzer)
* [Audit](https://docs.nestjs.com/v9/devtools/overview#audit)
* [Preview static files](https://docs.nestjs.com/v9/devtools/overview#preview-static-files)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/devtools/overview.md "Suggest Edits")

### Overview

> **Hint** This chapter covers the Nest Devtools integration with the Nest framework. If you are looking for the Devtools application, please visit the [Devtools](https://devtools.nestjs.com) website.

To start debugging your local application, open up the `main.ts` file and make sure to set the `snapshot` attribute to `true` in the application options object, as follows:

```typescript

async function bootstrap() {
  const app = await NestFactory.create(AppModule, {
    snapshot: true,
  });
  await app.listen(3000);
}
```

This will instruct the framework to collect necessary metadata that will let Nest Devtools visualize your application's graph.

Next up, let's install the required dependency:

```bash

$ npm i @nestjs/devtools-integration
```

> **Warning** If you're using `@nestjs/graphql` package in your application, make sure to install the latest version (`npm i @nestjs/graphql@11`).

With this dependency in place, let's open up the `app.module.ts` file and import the `DevtoolsModule` that we just installed:

```typescript

@Module({
  imports: [
    DevtoolsModule.register({
      http: process.env.NODE_ENV !== 'production',
    }),
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}
```

> **Warning** The reason we are checking the `NODE_ENV` environment variable here is that you should never use this module in production!

Once the `DevtoolsModule` is imported and your application is up and running (`npm run start:dev`), you should be able to navigate to [Devtools](https://devtools.nestjs.com) URL and see the instrospected graph.

> **Hint** As you can see on the screenshot above, every module connects to the `InternalCoreModule`. `InternalCoreModule` is a global module that is always imported into the root module. Since it's registered as a global node, Nest automatically creates edges between all of the modules and the `InternalCoreModule` node. Now, if you want to hide global modules from the graph, you can use the "**Hide global modules**" checkbox (in the sidebar).

So as we can see, `DevtoolsModule` makes your application expose an additional HTTP server (on port 8000) that the Devtools application will use to introspect your app.

Just to double-check that everything works as expected, change the graph view to "Classes". You should see the following screen:

To focus on a specific node, click on the rectangle and the graph will show a popup window with the **"Focus"** button. You can also use the search bar (located in the sidebar) to find a specific node.

> **Hint** If you click on the **Inspect** button, application will take you to the `/debug` page with that specific node selected.

> **Hint** To export a graph as an image, click on the **Export as PNG** button in the right corner of the graph.

Using the form controls located in the sidebar (on the left), you can control edges proximity to, for example, visualize a specific application sub-tree:

This can be particularly useful when you have **new developers** on your team and you want to show them how your application is structured. You can also use this feature to visualize a specific module (e.g. `TasksModule`) and all of its dependencies, which can come in handy when you're breaking down a large application into smaller modules (for example, individual micro-services).

You can watch this video to see the **Graph Explorer** feature in action:

#### Investigating the "Cannot resolve dependency" error[#](/devtools/overview#investigating-the-cannot-resolve-dependency-error)

> **Note** This feature is supported for `@nestjs/core` >= `v9.3.10`.

Probably the most common error message you might have seen is about Nest not being able to resolve dependencies of a provider. Using Nest Devtools, you can effortlessly identify the issue and learn how to resolve it.

First, open up the `main.ts` file and update the `bootstrap()` call, as follows:

```typescript

bootstrap().catch((err) => {
  fs.writeFileSync('graph.json', PartialGraphHost.toString() ?? '');
  process.exit(1);
});
```

Also, make sure to set the `abortOnError` to `false`:

```typescript

const app = await NestFactory.create(AppModule, {
  snapshot: true,
  abortOnError: false, // <--- THIS
});
```

Now every time your application fails to bootstrap due to the **"Cannot resolve dependency"** error, you'll find the `graph.json` (that represents a partial graph) file in the root directory. You can then drag & drop this file into Devtools (make sure to switch the current mode from "Interactive" to "Preview"):

Upon successful upload, you should see the following graph & dialog window:

As you can see, the highlighted `TasksModule` is the one we should look into. Also, in the dialog window you can already see some instructions on how to use fix this issue.

If we switch to the "Classes" view instead, that's what we'll see:

This graph illustrates that the `DiagnosticsService` which we want to inject into the `TasksService` was not found in the context of the `TasksModule` module, and we should likely just import the `DiagnosticsModule` into the `TasksModule` module to fix this up!

#### Routes explorer[#](/devtools/overview#routes-explorer)

When you navigate to the **Routes explorer** page, you should see all of the registered entrypoints:

> **Hint** This page shows not only HTTP routes, but also all of the other entrypoints (e.g. WebSockets, gRPC, GraphQL resolvers etc.).

> **Hint** To pretty display an array of objects, use the `console.table()` (or just `table()`) function.

You can watch this video to see the **Interactive Playground** feature in action:

#### Bootstrap performance analyzer[#](/devtools/overview#bootstrap-performance-analyzer)

To see a list of all class nodes (controllers, providers, enhancers, etc.) and their corresponding instantiation times, navigate to the **Bootstrap performance** page:

This page is particularly useful when you want to identify the slowest parts of your application's bootstrap process (e.g. when you want to optimize the application's startup time which is crucial for, for example, serverless environments).

#### Audit[#](/devtools/overview#audit)

To see the auto-generated audit - errors/warnings/hints that the application came up with while analyzing your serialized graph, navigate to the **Audit** page:

> **Hint** The screenshot above doesn't show all of the available audit rules.

This page comes in handy when you want to identify potential issues in your application.

#### Preview static files[#](/devtools/overview#preview-static-files)

To save a serialized graph to a file, use the following code:

```typescript

await app.listen(3000); // OR await app.init()
fs.writeFileSync('./graph.json', app.get(SerializedGraph).toString());
```

> **Hint**`SerializedGraph` is exported from the `@nestjs/core` package.

Then you can drag and drop this/upload this file:

This is helpful when you want to share your graph with someone else (e.g., co-worker), or when you want to analyze it offline.

----
url: https://docs.nestjs.com/v8/graphql/federation
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Federation](https://docs.nestjs.com/v8/graphql/federation#federation)
* [Federation with Apollo](https://docs.nestjs.com/v8/graphql/federation#federation-with-apollo)
* [Schema first](https://docs.nestjs.com/v8/graphql/federation#schema-first)
* [Code first](https://docs.nestjs.com/v8/graphql/federation#code-first)
* [Federated example: Posts](https://docs.nestjs.com/v8/graphql/federation#federated-example-posts)
* [Schema first](https://docs.nestjs.com/v8/graphql/federation#schema-first-1)
* [Code first](https://docs.nestjs.com/v8/graphql/federation#code-first-1)
* [Federated example: Gateway](https://docs.nestjs.com/v8/graphql/federation#federated-example-gateway)
* [Federation with Mercurius](https://docs.nestjs.com/v8/graphql/federation#federation-with-mercurius)
* [Schema first](https://docs.nestjs.com/v8/graphql/federation#schema-first-2)
* [Code first](https://docs.nestjs.com/v8/graphql/federation#code-first-2)
* [Federated example: Posts](https://docs.nestjs.com/v8/graphql/federation#federated-example-posts-1)
* [Schema first](https://docs.nestjs.com/v8/graphql/federation#schema-first-3)
* [Code first](https://docs.nestjs.com/v8/graphql/federation#code-first-3)
* [Federated example: Gateway](https://docs.nestjs.com/v8/graphql/federation#federated-example-gateway-1)

> **Warning** Federation currently does not support subscriptions.

In the following sections, we'll set up a demo application that consits of a gateway and two federated endpoints: Users service and Posts service.

#### Federation with Apollo[#](/graphql/federation#federation-with-apollo)

Start by installing the required dependencies:

```bash

$ npm install --save @apollo/federation @apollo/subgraph
```

#### Schema first[#](/graphql/federation#schema-first)

The "User service" provides a simple schema. Note the `@key` directive: it instructs the Apollo query planner that a particular instance of `User` can be fetched if you specify its `id`. Also, note that we `extend` the `Query` type.

```graphql

type User @key(fields: "id") {
  id: ID!
  name: String!
}

extend type Query {
  getUser(id: ID!): User
}
```

Resolver provides one additional method named `resolveReference()`. This method is triggered by the Apollo Gateway whenever a related resource requires a User instance. We'll see an example of this in the Posts service later. Please note that the method must be annotated with the `@ResolveReference()` decorator.

```typescript

import { Args, Query, Resolver, ResolveReference } from '@nestjs/graphql';
import { UsersService } from './users.service';

@Resolver('User')
export class UsersResolver {
  constructor(private usersService: UsersService) {}

  @Query()
  getUser(@Args('id') id: string) {
    return this.usersService.findById(id);
  }

  @ResolveReference()
  resolveReference(reference: { __typename: string; id: string }) {
    return this.usersService.findById(reference.id);
  }
}
```

Finally, we hook everything up by registering the `GraphQLModule` passing the `ApolloFederationDriver` driver in the configuration object:

```typescript

import {
  ApolloFederationDriver,
  ApolloFederationDriverConfig,
} from '@nestjs/apollo';
import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';
import { UsersResolver } from './users.resolver';

@Module({
  imports: [
    GraphQLModule.forRoot<ApolloFederationDriverConfig>({
      driver: ApolloFederationDriver,
      typePaths: ['**/*.graphql'],
    }),
  ],
  providers: [UsersResolver],
})
export class AppModule {}
```

#### Code first[#](/graphql/federation#code-first)

Start by adding some extra decorators to the `User` entity.

```ts

import { Directive, Field, ID, ObjectType } from '@nestjs/graphql';

@ObjectType()
@Directive('@key(fields: "id")')
export class User {
  @Field((type) => ID)
  id: number;

  @Field()
  name: string;
}
```

Resolver provides one additional method named `resolveReference()`. This method is triggered by the Apollo Gateway whenever a related resource requires a User instance. We'll see an example of this in the Posts service later. Please note that the method must be annotated with the `@ResolveReference()` decorator.

```ts

import { Args, Query, Resolver, ResolveReference } from '@nestjs/graphql';
import { User } from './user.entity';
import { UsersService } from './users.service';

@Resolver((of) => User)
export class UsersResolver {
  constructor(private usersService: UsersService) {}

  @Query((returns) => User)
  getUser(@Args('id') id: number): User {
    return this.usersService.findById(id);
  }

  @ResolveReference()
  resolveReference(reference: { __typename: string; id: number }): User {
    return this.usersService.findById(reference.id);
  }
}
```

Finally, we hook everything up by registering the `GraphQLModule` passing the `ApolloFederationDriver` driver in the configuration object:

```typescript

import {
  ApolloFederationDriver,
  ApolloFederationDriverConfig,
} from '@nestjs/apollo';
import { Module } from '@nestjs/common';
import { UsersResolver } from './users.resolver';
import { UsersService } from './users.service'; // Not included in this example

@Module({
  imports: [
    GraphQLModule.forRoot<ApolloFederationDriverConfig>({
      driver: ApolloFederationDriver,
      autoSchemaFile: true,
    }),
  ],
  providers: [UsersResolver, UsersService],
})
export class AppModule {}
```

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/31-graphql-federation-code-first/users-application) in code first mode and [here](https://github.com/nestjs/nest/tree/master/sample/32-graphql-federation-schema-first/users-application) in schema first mode.

#### Federated example: Posts[#](/graphql/federation#federated-example-posts)

Post service is supposed to serve aggregated posts through the `getPosts` query, but also extend our `User` type with the `user.posts` field.

#### Schema first[#](/graphql/federation#schema-first-1)

"Posts service" references the `User` type in its schema by marking it with the `extend` keyword. It also declares one additional property on the `User` type (`posts`). Note the `@key` directive used for matching instances of User, and the `@external` directive indicating that the `id` field is managed elsewhere.

```graphql

type Post @key(fields: "id") {
  id: ID!
  title: String!
  body: String!
  user: User
}

extend type User @key(fields: "id") {
  id: ID! @external
  posts: [Post]
}

extend type Query {
  getPosts: [Post]
}
```

In the following example, the `PostsResolver` provides the `getUser()` method that returns a reference containing `__typename` and some additional properties your application may need to resolve the reference, in this case `id`. `__typename` is used by the GraphQL Gateway to pinpoint the microservice responsible for the User type and retrieve the corresponding instance. The "Users service" described above will be requested upon execution of the `resolveReference()` method.

```typescript

import { Query, Resolver, Parent, ResolveField } from '@nestjs/graphql';
import { PostsService } from './posts.service';
import { Post } from './posts.interfaces';

@Resolver('Post')
export class PostsResolver {
  constructor(private postsService: PostsService) {}

  @Query('getPosts')
  getPosts() {
    return this.postsService.findAll();
  }

  @ResolveField('user')
  getUser(@Parent() post: Post) {
    return { __typename: 'User', id: post.userId };
  }
}
```

Lastly, we must register the `GraphQLModule`, similarly to what we did in the "Users service" section.

```typescript

import {
  ApolloFederationDriver,
  ApolloFederationDriverConfig,
} from '@nestjs/apollo';
import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';
import { PostsResolver } from './posts.resolver';

@Module({
  imports: [
    GraphQLModule.forRoot<ApolloFederationDriverConfig>({
      driver: ApolloFederationDriver,
      typePaths: ['**/*.graphql'],
    }),
  ],
  providers: [PostsResolvers],
})
export class AppModule {}
```

#### Code first[#](/graphql/federation#code-first-1)

First, we will have to declare a class representing the `User` entity. Although the entity itself lives in another service, we will be using it (extending its definition) here. Note the `@extends` and `@external` directives.

```ts

import { Directive, ObjectType, Field, ID } from '@nestjs/graphql';
import { Post } from './post.entity';

@ObjectType()
@Directive('@extends')
@Directive('@key(fields: "id")')
export class User {
  @Field((type) => ID)
  @Directive('@external')
  id: number;

  @Field((type) => [Post])
  posts?: Post[];
}
```

Now let's create the corresponding resolver for our extension on the `User` entity, as follows:

```ts

import { Parent, ResolveField, Resolver } from '@nestjs/graphql';
import { PostsService } from './posts.service';
import { Post } from './post.entity';
import { User } from './user.entity';

@Resolver((of) => User)
export class UsersResolver {
  constructor(private readonly postsService: PostsService) {}

  @ResolveField((of) => [Post])
  public posts(@Parent() user: User): Post[] {
    return this.postsService.forAuthor(user.id);
  }
}
```

We also have to define the `Post` entity class:

```ts

import { Directive, Field, ID, Int, ObjectType } from '@nestjs/graphql';
import { User } from './user.entity';

@ObjectType()
@Directive('@key(fields: "id")')
export class Post {
  @Field((type) => ID)
  id: number;

  @Field()
  title: string;

  @Field((type) => Int)
  authorId: number;

  @Field((type) => User)
  user?: User;
}
```

And its resolver:

```ts

import { Query, Args, ResolveField, Resolver, Parent } from '@nestjs/graphql';
import { PostsService } from './posts.service';
import { Post } from './post.entity';
import { User } from './user.entity';

@Resolver((of) => Post)
export class PostsResolver {
  constructor(private readonly postsService: PostsService) {}

  @Query((returns) => Post)
  findPost(@Args('id') id: number): Post {
    return this.postsService.findOne(id);
  }

  @Query((returns) => [Post])
  getPosts(): Post[] {
    return this.postsService.all();
  }

  @ResolveField((of) => User)
  user(@Parent() post: Post): any {
    return { __typename: 'User', id: post.authorId };
  }
}
```

And finally, tie it together in a module. Note the schema build options, where we specify that `User` is an orphaned (external) type.

```ts

import {
  ApolloFederationDriver,
  ApolloFederationDriverConfig,
} from '@nestjs/apollo';
import { Module } from '@nestjs/common';
import { User } from './user.entity';
import { PostsResolvers } from './posts.resolvers';
import { UsersResolvers } from './users.resolvers';
import { PostsService } from './posts.service'; // Not included in example

@Module({
  imports: [
    GraphQLModule.forRoot<ApolloFederationDriverConfig>({
      driver: ApolloFederationDriver,
      autoSchemaFile: true,
      buildSchemaOptions: {
        orphanedTypes: [User],
      },
    }),
  ],
  providers: [PostsResolver, UsersResolver, PostsService],
})
export class AppModule {}
```

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/31-graphql-federation-code-first/posts-application) for the code first mode and [here](https://github.com/nestjs/nest/tree/master/sample/32-graphql-federation-schema-first/posts-application) for the schema first mode.

#### Federated example: Gateway[#](/graphql/federation#federated-example-gateway)

Start by installing the required dependency:

```bash

$ npm install --save @apollo/gateway
```

The gateway requires a list of endpoints to be specified and it will auto-discover the corresponding schemas. Therefore the implementation of the gateway servce will remain the same for both code and schema first approaches.

```typescript

import { IntrospectAndCompose } from '@apollo/gateway';
import { ApolloGatewayDriver, ApolloGatewayDriverConfig } from '@nestjs/apollo';
import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';

@Module({
  imports: [
    GraphQLModule.forRoot<ApolloGatewayDriverConfig>({
      driver: ApolloGatewayDriver,
      server: {
        // ... Apollo server options
        cors: true,
      },
      gateway: {
        supergraphSdl: new IntrospectAndCompose({
          subgraphs: [
            { name: 'users', url: 'http://user-service/graphql' },
            { name: 'posts', url: 'http://post-service/graphql' },
          ],
        }),
      },
    }),
  ],
})
export class AppModule {}
```

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/31-graphql-federation-code-first/gateway) for the code first mode and [here](https://github.com/nestjs/nest/tree/master/sample/32-graphql-federation-schema-first/gateway) for the schema first mode.

#### Federation with Mercurius[#](/graphql/federation#federation-with-mercurius)

Start by installing the required dependencies:

```bash

$ npm install --save @apollo/subgraph @nestjs/mercurius
```

> **Note** The `@apollo/subgraph` package is required to build a subgraph schema (`buildSubgraphSchema`, `printSubgraphSchema` functions).

#### Schema first[#](/graphql/federation#schema-first-2)

The "User service" provides a simple schema. Note the `@key` directive: it instructs the Mercurius query planner that a particular instance of `User` can be fetched if you specify its `id`. Also, note that we `extend` the `Query` type.

```graphql

type User @key(fields: "id") {
  id: ID!
  name: String!
}

extend type Query {
  getUser(id: ID!): User
}
```

Resolver provides one additional method named `resolveReference()`. This method is triggered by the Mercurius Gateway whenever a related resource requires a User instance. We'll see an example of this in the Posts service later. Please note that the method must be annotated with the `@ResolveReference()` decorator.

```typescript

import { Args, Query, Resolver, ResolveReference } from '@nestjs/graphql';
import { UsersService } from './users.service';

@Resolver('User')
export class UsersResolver {
  constructor(private usersService: UsersService) {}

  @Query()
  getUser(@Args('id') id: string) {
    return this.usersService.findById(id);
  }

  @ResolveReference()
  resolveReference(reference: { __typename: string; id: string }) {
    return this.usersService.findById(reference.id);
  }
}
```

Finally, we hook everything up by registering the `GraphQLModule` passing the `MercuriusFederationDriver` driver in the configuration object:

```typescript

import {
  MercuriusFederationDriver,
  MercuriusFederationDriverConfig,
} from '@nestjs/mercurius';
import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';
import { UsersResolver } from './users.resolver';

@Module({
  imports: [
    GraphQLModule.forRoot<MercuriusFederationDriverConfig>({
      driver: MercuriusFederationDriver,
      typePaths: ['**/*.graphql'],
      federationMetadata: true,
    }),
  ],
  providers: [UsersResolver],
})
export class AppModule {}
```

#### Code first[#](/graphql/federation#code-first-2)

Start by adding some extra decorators to the `User` entity.

```ts

import { Directive, Field, ID, ObjectType } from '@nestjs/graphql';

@ObjectType()
@Directive('@key(fields: "id")')
export class User {
  @Field((type) => ID)
  id: number;

  @Field()
  name: string;
}
```

Resolver provides one additional method named `resolveReference()`. This method is triggered by the Mercurius Gateway whenever a related resource requires a User instance. We'll see an example of this in the Posts service later. Please note that the method must be annotated with the `@ResolveReference()` decorator.

```ts

import { Args, Query, Resolver, ResolveReference } from '@nestjs/graphql';
import { User } from './user.entity';
import { UsersService } from './users.service';

@Resolver((of) => User)
export class UsersResolver {
  constructor(private usersService: UsersService) {}

  @Query((returns) => User)
  getUser(@Args('id') id: number): User {
    return this.usersService.findById(id);
  }

  @ResolveReference()
  resolveReference(reference: { __typename: string; id: number }): User {
    return this.usersService.findById(reference.id);
  }
}
```

Finally, we hook everything up by registering the `GraphQLModule` passing the `MercuriusFederationDriver` driver in the configuration object:

```typescript

import {
  MercuriusFederationDriver,
  MercuriusFederationDriverConfig,
} from '@nestjs/mercurius';
import { Module } from '@nestjs/common';
import { UsersResolver } from './users.resolver';
import { UsersService } from './users.service'; // Not included in this example

@Module({
  imports: [
    GraphQLModule.forRoot<MercuriusFederationDriverConfig>({
      driver: MercuriusFederationDriver,
      autoSchemaFile: true,
      federationMetadata: true,
    }),
  ],
  providers: [UsersResolver, UsersService],
})
export class AppModule {}
```

#### Federated example: Posts[#](/graphql/federation#federated-example-posts-1)

Post service is supposed to serve aggregated posts through the `getPosts` query, but also extend our `User` type with the `user.posts` field.

#### Schema first[#](/graphql/federation#schema-first-3)

"Posts service" references the `User` type in its schema by marking it with the `extend` keyword. It also declares one additional property on the `User` type (`posts`). Note the `@key` directive used for matching instances of User, and the `@external` directive indicating that the `id` field is managed elsewhere.

```graphql

type Post @key(fields: "id") {
  id: ID!
  title: String!
  body: String!
  user: User
}

extend type User @key(fields: "id") {
  id: ID! @external
  posts: [Post]
}

extend type Query {
  getPosts: [Post]
}
```

In the following example, the `PostsResolver` provides the `getUser()` method that returns a reference containing `__typename` and some additional properties your application may need to resolve the reference, in this case `id`. `__typename` is used by the GraphQL Gateway to pinpoint the microservice responsible for the User type and retrieve the corresponding instance. The "Users service" described above will be requested upon execution of the `resolveReference()` method.

```typescript

import { Query, Resolver, Parent, ResolveField } from '@nestjs/graphql';
import { PostsService } from './posts.service';
import { Post } from './posts.interfaces';

@Resolver('Post')
export class PostsResolver {
  constructor(private postsService: PostsService) {}

  @Query('getPosts')
  getPosts() {
    return this.postsService.findAll();
  }

  @ResolveField('user')
  getUser(@Parent() post: Post) {
    return { __typename: 'User', id: post.userId };
  }
}
```

Lastly, we must register the `GraphQLModule`, similarly to what we did in the "Users service" section.

```typescript

import {
  MercuriusFederationDriver,
  MercuriusFederationDriverConfig,
} from '@nestjs/mercurius';
import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';
import { PostsResolver } from './posts.resolver';

@Module({
  imports: [
    GraphQLModule.forRoot<MercuriusFederationDriverConfig>({
      driver: MercuriusFederationDriver,
      federationMetadata: true,
      typePaths: ['**/*.graphql'],
    }),
  ],
  providers: [PostsResolvers],
})
export class AppModule {}
```

#### Code first[#](/graphql/federation#code-first-3)

First, we will have to declare a class representing the `User` entity. Although the entity itself lives in another service, we will be using it (extending its definition) here. Note the `@extends` and `@external` directives.

```ts

import { Directive, ObjectType, Field, ID } from '@nestjs/graphql';
import { Post } from './post.entity';

@ObjectType()
@Directive('@extends')
@Directive('@key(fields: "id")')
export class User {
  @Field((type) => ID)
  @Directive('@external')
  id: number;

  @Field((type) => [Post])
  posts?: Post[];
}
```

Now let's create the corresponding resolver for our extension on the `User` entity, as follows:

```ts

import { Parent, ResolveField, Resolver } from '@nestjs/graphql';
import { PostsService } from './posts.service';
import { Post } from './post.entity';
import { User } from './user.entity';

@Resolver((of) => User)
export class UsersResolver {
  constructor(private readonly postsService: PostsService) {}

  @ResolveField((of) => [Post])
  public posts(@Parent() user: User): Post[] {
    return this.postsService.forAuthor(user.id);
  }
}
```

We also have to define the `Post` entity class:

```ts

import { Directive, Field, ID, Int, ObjectType } from '@nestjs/graphql';
import { User } from './user.entity';

@ObjectType()
@Directive('@key(fields: "id")')
export class Post {
  @Field((type) => ID)
  id: number;

  @Field()
  title: string;

  @Field((type) => Int)
  authorId: number;

  @Field((type) => User)
  user?: User;
}
```

And its resolver:

```ts

import { Query, Args, ResolveField, Resolver, Parent } from '@nestjs/graphql';
import { PostsService } from './posts.service';
import { Post } from './post.entity';
import { User } from './user.entity';

@Resolver((of) => Post)
export class PostsResolver {
  constructor(private readonly postsService: PostsService) {}

  @Query((returns) => Post)
  findPost(@Args('id') id: number): Post {
    return this.postsService.findOne(id);
  }

  @Query((returns) => [Post])
  getPosts(): Post[] {
    return this.postsService.all();
  }

  @ResolveField((of) => User)
  user(@Parent() post: Post): any {
    return { __typename: 'User', id: post.authorId };
  }
}
```

And finally, tie it together in a module. Note the schema build options, where we specify that `User` is an orphaned (external) type.

```ts

import {
  MercuriusFederationDriver,
  MercuriusFederationDriverConfig,
} from '@nestjs/mercurius';
import { Module } from '@nestjs/common';
import { User } from './user.entity';
import { PostsResolvers } from './posts.resolvers';
import { UsersResolvers } from './users.resolvers';
import { PostsService } from './posts.service'; // Not included in example

@Module({
  imports: [
    GraphQLModule.forRoot<MercuriusFederationDriverConfig>({
      driver: MercuriusFederationDriver,
      autoSchemaFile: true,
      federationMetadata: true,
      buildSchemaOptions: {
        orphanedTypes: [User],
      },
    }),
  ],
  providers: [PostsResolver, UsersResolver, PostsService],
})
export class AppModule {}
```

#### Federated example: Gateway[#](/graphql/federation#federated-example-gateway-1)

The gateway requires a list of endpoints to be specified and it will auto-discover the corresponding schemas. Therefore the implementation of the gateway servce will remain the same for both code and schema first approaches.

```typescript

import {
  MercuriusGatewayDriver,
  MercuriusGatewayDriverConfig,
} from '@nestjs/mercurius';
import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';

@Module({
  imports: [
    GraphQLModule.forRoot<MercuriusGatewayDriverConfig>({
      driver: MercuriusGatewayDriver,
      gateway: {
        services: [
          { name: 'users', url: 'http://user-service/graphql' },
          { name: 'posts', url: 'http://post-service/graphql' },
        ],
      },
    }),
  ],
})
export class AppModule {}
```

----
url: https://docs.nestjs.com/v7/microservices/grpc
----

* [gRPC](https://docs.nestjs.com/v7/microservices/grpc#grpc)
* [Installation](https://docs.nestjs.com/v7/microservices/grpc#installation)
* [Overview](https://docs.nestjs.com/v7/microservices/grpc#overview)
* [Options](https://docs.nestjs.com/v7/microservices/grpc#options)
* [Sample gRPC service](https://docs.nestjs.com/v7/microservices/grpc#sample-grpc-service)
* [Client](https://docs.nestjs.com/v7/microservices/grpc#client)
* [Example](https://docs.nestjs.com/v7/microservices/grpc#example)
* [gRPC Streaming](https://docs.nestjs.com/v7/microservices/grpc#grpc-streaming)
* [Streaming sample](https://docs.nestjs.com/v7/microservices/grpc#streaming-sample)
* [Subject strategy](https://docs.nestjs.com/v7/microservices/grpc#subject-strategy)
* [Call stream handler](https://docs.nestjs.com/v7/microservices/grpc#call-stream-handler)
* [gRPC Metadata](https://docs.nestjs.com/v7/microservices/grpc#grpc-metadata)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/microservices/grpc.md "Suggest Edits")

### gRPC

[gRPC](https://github.com/grpc/grpc-node) is a modern, open source, high performance RPC framework that can run in any environment. It can efficiently connect services in and across data centers with pluggable support for load balancing, tracing, health checking and authentication.

Like many RPC systems, gRPC is based on the concept of defining a service in terms of functions (methods) that can be called remotely. For each method, you define the parameters and return types. Services, parameters, and return types are defined in `.proto` files using Google's open source language-neutral [protocol buffers](https://developers.google.com/protocol-buffers) mechanism.

With the gRPC transporter, Nest uses `.proto` files to dynamically bind clients and servers to make it easy to implement remote procedure calls, automatically serializing and deserializing structured data.

#### Installation[#](/microservices/grpc#installation)

To start building gRPC-based microservices, first install the required packages:

```bash

$ npm i --save grpc @grpc/proto-loader
```

#### Overview[#](/microservices/grpc#overview)

Like other Nest microservices transport layer implementations, you select the gRPC transporter mechanism using the `transport` property of the options object passed to the `createMicroservice()` method. In the following example, we'll set up a hero service. The `options` property provides metadata about that service; its properties are described [below](microservices/grpc#options).

main.ts

JS TS

```typescript

const app = await NestFactory.createMicroservice<MicroserviceOptions>(AppModule, {
  transport: Transport.GRPC,
  options: {
    package: 'hero',
    protoPath: join(__dirname, 'hero/hero.proto'),
  },
});
```

```typescript

const app = await NestFactory.createMicroservice(AppModule, {
  transport: Transport.GRPC,
  options: {
    package: 'hero',
    protoPath: join(__dirname, 'hero/hero.proto'),
  },
});
```

> **Hint** The `join()` function is imported from the `path` package; the `Transport` enum is imported from the `@nestjs/microservices` package.

In the `nest-cli.json` file, we add the `assets` property that allows us to distribute non-TypeScript files, and `watchAssets` - to turn on watching all non-TypeScript assets. In our case, we want `.proto` files to be automatically copied to the `dist` folder.

```json

{
  "compilerOptions": {
    "assets": ["**/*.proto"],
    "watchAssets": true
  }
}
```

#### Options[#](/microservices/grpc#options)

The **gRPC** transporter options object exposes the properties described below.

|               |                                                                                                                                                                                                                          |
| ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `package`     | Protobuf package name (matches `package` setting from `.proto` file). Required                                                                                                                                           |
| `protoPath`   | Absolute (or relative to the root dir) path to the `.proto` file. Required                                                                                                                                               |
| `url`         | Connection url. String in the format `ip address/dns name:port` (for example, `'localhost:50051'`) defining the address/port on which the transporter establishes a connection. Optional. Defaults to `'localhost:5000'` |
| `protoLoader` | NPM package name for the utility to load `.proto` files. Optional. Defaults to `'@grpc/proto-loader'`                                                                                                                    |
| `loader`      | `@grpc/proto-loader` options. These provide detailed control over the behavior of `.proto` files. Optional. See [here](https://github.com/grpc/grpc-node/blob/master/packages/proto-loader/README.md) for more details   |
| `credentials` | Server credentials. Optional. [Read more here](https://grpc.io/grpc/node/grpc.ServerCredentials.html)                                                                                                                    |

#### Sample gRPC service[#](/microservices/grpc#sample-grpc-service)

Let's define our sample gRPC service called `HeroesService`. In the above `options` object, the`protoPath` property sets a path to the `.proto` definitions file `hero.proto`. The `hero.proto` file is structured using [protocol buffers](https://developers.google.com/protocol-buffers). Here's what it looks like:

```typescript

// hero/hero.proto
syntax = "proto3";

package hero;

service HeroesService {
  rpc FindOne (HeroById) returns (Hero) {}
}

message HeroById {
  int32 id = 1;
}

message Hero {
  int32 id = 1;
  string name = 2;
}
```

Our `HeroesService` exposes a `FindOne()` method. This method expects an input argument of type `HeroById` and returns a `Hero` message (protocol buffers use `message` elements to define both parameter types and return types).

Next, we need to implement the service. To define a handler that fulfills this definition, we use the `@GrpcMethod()` decorator in a controller, as shown below. This decorator provides the metadata needed to declare a method as a gRPC service method.

> **Hint** The `@MessagePattern()` decorator ([read more](microservices/basics#request-response)) introduced in previous microservices chapters is not used with gRPC-based microservices. The `@GrpcMethod()` decorator effectively takes its place for gRPC-based microservices.

heroes.controller.ts

JS TS

```typescript

@Controller()
export class HeroesController {
  @GrpcMethod('HeroesService', 'FindOne')
  findOne(data: HeroById, metadata: Metadata, call: ServerUnaryCall<any>): Hero {
    const items = [
      { id: 1, name: 'John' },
      { id: 2, name: 'Doe' },
    ];
    return items.find(({ id }) => id === data.id);
  }
}
```

```typescript

@Controller()
export class HeroesController {
  @GrpcMethod('HeroesService', 'FindOne')
  findOne(data, metadata, call) {
    const items = [
      { id: 1, name: 'John' },
      { id: 2, name: 'Doe' },
    ];
    return items.find(({ id }) => id === data.id);
  }
}
```

> **Hint** The `@GrpcMethod()` decorator is imported from the `@nestjs/microservices` package, while `Metadata` and `ServerUnaryCall` from the `grpc` package.

The decorator shown above takes two arguments. The first is the service name (e.g., `'HeroesService'`), corresponding to the `HeroesService` service definition in `hero.proto`. The second (the string `'FindOne'`) corresponds to the `FindOne()` rpc method defined within `HeroesService` in the `hero.proto` file.

The `findOne()` handler method takes three arguments, the `data` passed from the caller, `metadata` that stores gRPC request metadata and `call` to obtain the `GrpcCall` object properties such as `sendMetadata` for send metadata to client.

Both `@GrpcMethod()` decorator arguments are optional. If called without the second argument (e.g., `'FindOne'`), Nest will automatically associate the `.proto` file rpc method with the handler based on converting the handler name to upper camel case (e.g., the `findOne` handler is associated with the `FindOne` rpc call definition). This is shown below.

heroes.controller.ts

JS TS

```typescript

@Controller()
export class HeroesController {
  @GrpcMethod('HeroesService')
  findOne(data: HeroById, metadata: Metadata, call: ServerUnaryCall<any>): Hero {
    const items = [
      { id: 1, name: 'John' },
      { id: 2, name: 'Doe' },
    ];
    return items.find(({ id }) => id === data.id);
  }
}
```

```typescript

@Controller()
export class HeroesController {
  @GrpcMethod('HeroesService')
  findOne(data, metadata, call) {
    const items = [
      { id: 1, name: 'John' },
      { id: 2, name: 'Doe' },
    ];
    return items.find(({ id }) => id === data.id);
  }
}
```

You can also omit the first `@GrpcMethod()` argument. In this case, Nest automatically associates the handler with the service definition from the proto definitions file based on the **class** name where the handler is defined. For example, in the following code, class `HeroesService` associates its handler methods with the `HeroesService` service definition in the `hero.proto` file based on the matching of the name `'HeroesService'`.

heroes.controller.ts

JS TS

```typescript

@Controller()
export class HeroesService {
  @GrpcMethod()
  findOne(data: HeroById, metadata: Metadata, call: ServerUnaryCall<any>): Hero {
    const items = [
      { id: 1, name: 'John' },
      { id: 2, name: 'Doe' },
    ];
    return items.find(({ id }) => id === data.id);
  }
}
```

```typescript

@Controller()
export class HeroesService {
  @GrpcMethod()
  findOne(data, metadata, call) {
    const items = [
      { id: 1, name: 'John' },
      { id: 2, name: 'Doe' },
    ];
    return items.find(({ id }) => id === data.id);
  }
}
```

#### Client[#](/microservices/grpc#client)

Nest applications can act as gRPC clients, consuming services defined in `.proto` files. You access remote services through a `ClientGrpc` object. You can obtain a `ClientGrpc` object in several ways.

The preferred technique is to import the `ClientsModule`. Use the `register()` method to bind a package of services defined in a `.proto` file to an injection token, and to configure the service. The `name` property is the injection token. For gRPC services, use `transport: Transport.GRPC`. The `options` property is an object with the same properties described [above](microservices/grpc#options).

```typescript

imports: [
  ClientsModule.register([
    {
      name: 'HERO_PACKAGE',
      transport: Transport.GRPC,
      options: {
        package: 'hero',
        protoPath: join(__dirname, 'hero/hero.proto'),
      },
    },
  ]),
];
```

> **Hint** The `register()` method takes an array of objects. Register multiple packages by providing a comma separated list of registration objects.

Once registered, we can inject the configured `ClientGrpc` object with `@Inject()`. Then we use the `ClientGrpc` object's `getService()` method to retrieve the service instance, as shown below.

```typescript

@Injectable()
export class AppService implements OnModuleInit {
  private heroesService: HeroesService;

  constructor(@Inject('HERO_PACKAGE') private client: ClientGrpc) {}

  onModuleInit() {
    this.heroesService = this.client.getService<HeroesService>('HeroesService');
  }

  getHero(): Observable<string> {
    return this.heroesService.findOne({ id: 1 });
  }
}
```

> **Warning** gRPC Client will not send fields that contain underscore `_` in their names unless the `keepCase` options is set to `true` in the proto loader configuration (`options.loader.keepcase` in the microservice transporter configuration).

Notice that there is a small difference compared to the technique used in other microservice transport methods. Instead of the `ClientProxy` class, we use the `ClientGrpc` class, which provides the `getService()` method. The `getService()` generic method takes a service name as an argument and returns its instance (if available).

Alternatively, you can use the `@Client()` decorator to instantiate a `ClientGrpc` object, as follows:

```typescript

@Injectable()
export class AppService implements OnModuleInit {
  @Client({
    transport: Transport.GRPC,
    options: {
      package: 'hero',
      protoPath: join(__dirname, 'hero/hero.proto'),
    },
  })
  client: ClientGrpc;

  private heroesService: HeroesService;

  onModuleInit() {
    this.heroesService = this.client.getService<HeroesService>('HeroesService');
  }

  getHero(): Observable<string> {
    return this.heroesService.findOne({ id: 1 });
  }
}
```

Finally, for more complex scenarios, we can inject a dynamically configured client using the `ClientProxyFactory` class as described [here](/microservices/basics#client).

In either case, we end up with a reference to our `HeroesService` proxy object, which exposes the same set of methods that are defined inside the `.proto` file. Now, when we access this proxy object (i.e., `heroesService`), the gRPC system automatically serializes requests, forwards them to the remote system, returns a response, and deserializes the response. Because gRPC shields us from these network communication details, `heroesService` looks and acts like a local provider.

Note, all service methods are **lower camel cased** (in order to follow the natural convention of the language). So, for example, while our `.proto` file `HeroesService` definition contains the `FindOne()` function, the `heroesService` instance will provide the `findOne()` method.

```typescript

interface HeroesService {
  findOne(data: { id: number }): Observable<any>;
}
```

A message handler is also able to return an `Observable`, in which case the result values will be emitted until the stream is completed.

heroes.controller.ts

JS TS

```typescript

@Get()
call(): Observable<any> {
  return this.heroesService.findOne({ id: 1 });
}
```

```typescript

@Get()
call() {
  return this.heroesService.findOne({ id: 1 });
}
```

To send gRPC metadata (along with the request), you can pass a second argument, as follows:

```typescript

call(): Observable<any> {
  const metadata = new Metadata();
  metadata.add('Set-Cookie', 'yummy_cookie=choco');

  return this.heroesService.findOne({ id: 1 }, metadata);
}
```

> **Hint** The `Metadata` class is imported from the `grpc` package.

```typescript

// hello/hello.proto
syntax = "proto3";

package hello;

service HelloService {
  rpc BidiHello(stream HelloRequest) returns (stream HelloResponse);
  rpc LotsOfGreetings(stream HelloRequest) returns (HelloResponse);
}

message HelloRequest {
  string greeting = 1;
}

message HelloResponse {
  string reply = 1;
}
```

> **Hint** The `LotsOfGreetings` method can be simply implemented with the `@GrpcMethod` decorator (as in the examples above) since the returned stream can emit multiple values.

Based on this `.proto` file, let's define the `HelloService` interface:

```typescript

interface HelloService {
  bidiHello(upstream: Observable<HelloRequest>): Observable<HelloResponse>;
  lotsOfGreetings(
    upstream: Observable<HelloRequest>,
  ): Observable<HelloResponse>;
}

interface HelloRequest {
  greeting: string;
}

interface HelloResponse {
  reply: string;
}
```

#### Subject strategy[#](/microservices/grpc#subject-strategy)

The `@GrpcStreamMethod()` decorator provides the function parameter as an RxJS `Observable`. Thus, we can receive and process multiple messages.

```typescript

@GrpcStreamMethod()
bidiHello(messages: Observable<any>, metadata: Metadata, call: ServerDuplexStream<any, any>): Observable<any> {
  const subject = new Subject();

  const onNext = message => {
    console.log(message);
    subject.next({
      reply: 'Hello, world!'
    });
  };
  const onComplete = () => subject.complete();
  messages.subscribe(onNext, null, onComplete);

  return subject.asObservable();
}
```

> **Warning** For supporting full-duplex interaction with the `@GrpcStreamMethod()` decorator, the controller method must return an RxJS `Observable`.

> **Hint** The `Metadata` and `ServerUnaryCall` classes/interfaces are imported from the `grpc` package.

According to the service definition (in the `.proto` file), the `BidiHello` method should stream requests to the service. To send multiple asynchronous messages to the stream from a client, we leverage an RxJS `ReplySubject` class.

```typescript

const helloService = this.client.getService<HelloService>('HelloService');
const helloRequest$ = new ReplaySubject<HelloRequest>();

helloRequest$.next({ greeting: 'Hello (1)!' });
helloRequest$.next({ greeting: 'Hello (2)!' });
helloRequest$.complete();

return helloService.bidiHello(helloRequest$);
```

In the example above, we wrote two messages to the stream (`next()` calls) and notified the service that we've completed sending the data (`complete()` call).

#### Call stream handler[#](/microservices/grpc#call-stream-handler)

When the method return value is defined as `stream`, the `@GrpcStreamCall()` decorator provides the function parameter as `grpc.ServerDuplexStream`, which supports standard methods like `.on('data', callback)`, `.write(message)` or `.cancel()`. Full documentation on available methods can be found [here](https://grpc.github.io/grpc/node/grpc-ClientDuplexStream.html).

Alternatively, when the method return value is not a `stream`, the `@GrpcStreamCall()` decorator provides two function parameters, respectively `grpc.ServerReadableStream` (read more [here](https://grpc.github.io/grpc/node/grpc-ServerReadableStream.html)) and `callback`.

Let's start with implementing the `BidiHello` which should support a full-duplex interaction.

```typescript

@GrpcStreamCall()
bidiHello(requestStream: any) {
  requestStream.on('data', message => {
    console.log(message);
    requestStream.write({
      reply: 'Hello, world!'
    });
  });
}
```

> **Hint** This decorator does not require any specific return parameter to be provided. It is expected that the stream will be handled similar to any other standard stream type.

In the example above, we used the `write()` method to write objects to the response stream. The callback passed into the `.on()` method as a second parameter will be called every time our service receives a new chunk of data.

Let's implement the `LotsOfGreetings` method.

```typescript

@GrpcStreamCall()
lotsOfGreetings(requestStream: any, callback: (err: unknown, value: HelloResponse) => void) {
  requestStream.on('data', message => {
    console.log(message);
  });
  requestStream.on('end', () => callback(null, { reply: 'Hello, world!' }));
}
```

```typescript

@Controller()
export class HeroesService {
  @GrpcMethod()
  findOne(data: HeroById, metadata: Metadata, call: ServerUnaryCall<any>): Hero {
    const serverMetadata = new Metadata();
    const items = [
      { id: 1, name: 'John' },
      { id: 2, name: 'Doe' },
    ];

    serverMetadata.add('Set-Cookie', 'yummy_cookie=choco');
    call.sendMetadata(serverMetadata);

    return items.find(({ id }) => id === data.id);
  }
}
```

```typescript

@Controller()
export class HeroesService {
  @GrpcMethod()
  findOne(data, metadata, call) {
    const serverMetadata = new Metadata();
    const items = [
      { id: 1, name: 'John' },
      { id: 2, name: 'Doe' },
    ];

    serverMetadata.add('Set-Cookie', 'yummy_cookie=choco');
    call.sendMetadata(serverMetadata);

    return items.find(({ id }) => id === data.id);
  }
}
```

Likewise, to read the metadata in handlers annotated with the `@GrpcStreamMethod()` handler ([subject strategy](microservices/grpc#subject-strategy)), use the second argument (metadata), which is of type `Metadata` (imported from the `grpc` package).

To send back metadata from the handler, use the `ServerDuplexStream#sendMetadata()` method (third handler argument).

To read metadata from within the [call stream handlers](microservices/grpc#call-stream-handler) (handlers annotated with `@GrpcStreamCall()` decorator), listen to the `metadata` event on the `requestStream` reference, as follows:

```typescript

requestStream.on('metadata', (metadata: Metadata) => {
  const meta = metadata.get('X-Meta');
});
```

----
url: https://docs.nestjs.com/microservices/pre-request-hooks
----

[Skip to content](#content)

On this page

* [Pre-request hooks](https://docs.nestjs.com/microservices/pre-request-hooks#pre-request-hooks)
* [Binding hooks](https://docs.nestjs.com/microservices/pre-request-hooks#binding-hooks)
* [AsyncLocalStorage propagation](https://docs.nestjs.com/microservices/pre-request-hooks#asynclocalstorage-propagation)
* [Logging and metrics](https://docs.nestjs.com/microservices/pre-request-hooks#logging-and-metrics)

### Pre-request hooks

Pre-request hooks are functions that run before all enhancers (guards, interceptors, and pipes) on every invocation of a pattern handler. They are the microservices equivalent of HTTP middleware: a place to establish per-request context that must be visible to guards and the rest of the pipeline.

> **Hint** The `PreRequestHook` interface is exported from the `@nestjs/common` package.

Hooks run at the start of the following sequence:

```

Incoming message
  └─ Pre-request hooks  (registration order)
       └─ Guards
            └─ Interceptors
                 └─ Pipes
                      └─ Handler
```

Exceptions thrown inside a hook are caught by the same wrapper that covers the rest of the pipeline, so your existing [exception filters](/microservices/exception-filters) handle them without extra configuration.

#### Binding hooks[#](/microservices/pre-request-hooks#binding-hooks)

Register hooks on the microservice instance with the `registerPreRequestHook()` method, before the microservice is initialized (i.e., before calling `app.listen()` or `app.init()`). Hooks registered after initialization are ignored, and Nest logs a warning. Multiple calls accumulate hooks in registration order.

Each hook receives an `ExecutionContext` and a `next` function. Calling `next()` advances to the next hook or, when no hooks remain, to the guard → interceptor → pipe → handler pipeline. The hook must return an `Observable`: either the one produced by `next()`, or one that wraps it.

> **Warning** If a hook doesn't call `next()`, the handler never runs. This is the same contract as HTTP middleware.

> **Note** In a [hybrid application](/faq/hybrid-application), `connectMicroservice()` initializes the connected microservice immediately (unless you pass `deferInitialization: true` in its second argument), so hooks registered on the returned instance afterward are not applied.

main.ts

JS TS

```typescript

import { NestFactory } from '@nestjs/core';
import { Transport, MicroserviceOptions } from '@nestjs/microservices';
import { AppModule } from './app.module.js';

async function bootstrap() {
  const app = await NestFactory.createMicroservice<MicroserviceOptions>(
    AppModule,
    { transport: Transport.TCP },
  );

  app.registerPreRequestHook((ctx, next) => {
    return next();
  });

  await app.listen();
}
await bootstrap();
```

```typescript

import { NestFactory } from '@nestjs/core';
import { Transport } from '@nestjs/microservices';
import { AppModule } from './app.module.js';

async function bootstrap() {
  const app = await NestFactory.createMicroservice(AppModule, {
    transport: Transport.TCP,
  });

  app.registerPreRequestHook((ctx, next) => {
    return next();
  });

  await app.listen();
}
await bootstrap();
```

#### AsyncLocalStorage propagation[#](/microservices/pre-request-hooks#asynclocalstorage-propagation)

A common use case is initializing `AsyncLocalStorage` before guards run, which makes the store available throughout the entire pipeline:

main.ts

JS TS

```typescript

import { NestFactory } from '@nestjs/core';
import { Transport, MicroserviceOptions } from '@nestjs/microservices';
import { Observable } from 'rxjs';
import { AsyncLocalStorage } from 'async_hooks';
import { randomUUID } from 'crypto';
import { AppModule } from './app.module.js';

export const als = new AsyncLocalStorage<{ correlationId: string }>();

async function bootstrap() {
  const app = await NestFactory.createMicroservice<MicroserviceOptions>(
    AppModule,
    { transport: Transport.TCP },
  );

  app.registerPreRequestHook((ctx, next) => {
    return new Observable(subscriber => {
      als.run({ correlationId: randomUUID() }, () => {
        next().subscribe(subscriber);
      });
    });
  });

  await app.listen();
}
await bootstrap();
```

```typescript

import { NestFactory } from '@nestjs/core';
import { Transport } from '@nestjs/microservices';
import { Observable } from 'rxjs';
import { AsyncLocalStorage } from 'async_hooks';
import { randomUUID } from 'crypto';
import { AppModule } from './app.module.js';

export const als = new AsyncLocalStorage();

async function bootstrap() {
  const app = await NestFactory.createMicroservice(AppModule, {
    transport: Transport.TCP,
  });

  app.registerPreRequestHook((ctx, next) => {
    return new Observable(subscriber => {
      als.run({ correlationId: randomUUID() }, () => {
        next().subscribe(subscriber);
      });
    });
  });

  await app.listen();
}
await bootstrap();
```

Because the hook runs before the guards, `als.getStore()` returns the initialized store in any guard, interceptor, or handler:

correlation.guard.ts

JS TS

```typescript

import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
import { als } from './main.js';

@Injectable()
export class CorrelationGuard implements CanActivate {
  canActivate(context: ExecutionContext): boolean {
    const { correlationId } = als.getStore()!;
    return true;
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';
import { als } from './main.js';

@Injectable()
export class CorrelationGuard {
  canActivate(context) {
    const { correlationId } = als.getStore();
    return true;
  }
}
```

#### Logging and metrics[#](/microservices/pre-request-hooks#logging-and-metrics)

You can apply RxJS operators to the `Observable` returned by `next()` to observe the full handler lifecycle:

main.ts

JS TS

```typescript

import { tap, catchError } from 'rxjs/operators';
import { throwError } from 'rxjs';

app.registerPreRequestHook((ctx, next) => {
  const handler = ctx.getHandler().name;
  const start = Date.now();

  return next().pipe(
    tap(() => console.log(`[${handler}] completed in ${Date.now() - start}ms`)),
    catchError(err => {
      console.error(`[${handler}] failed:`, err.message);
      return throwError(() => err);
    }),
  );
});
```

```typescript

import { tap, catchError } from 'rxjs/operators';
import { throwError } from 'rxjs';

app.registerPreRequestHook((ctx, next) => {
  const handler = ctx.getHandler().name;
  const start = Date.now();

  return next().pipe(
    tap(() => console.log(`[${handler}] completed in ${Date.now() - start}ms`)),
    catchError(err => {
      console.error(`[${handler}] failed:`, err.message);
      return throwError(() => err);
    }),
  );
});
```

> **Hint** Pre-request hooks are global: you can't register them for individual patterns. When no hooks are registered, Nest skips the hook chain entirely, so the feature adds no overhead. Pre-request hooks don't apply to WebSocket gateways.

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/microservices/pre-request-hooks.md)

----
url: https://docs.nestjs.com/v10/openapi/operations
----

* [Operations](https://docs.nestjs.com/v10/openapi/operations#operations)
* [Tags](https://docs.nestjs.com/v10/openapi/operations#tags)
* [Headers](https://docs.nestjs.com/v10/openapi/operations#headers)
* [Responses](https://docs.nestjs.com/v10/openapi/operations#responses)
* [File upload](https://docs.nestjs.com/v10/openapi/operations#file-upload)
* [Extensions](https://docs.nestjs.com/v10/openapi/operations#extensions)
* [Advanced: Generic ApiResponse](https://docs.nestjs.com/v10/openapi/operations#advanced-generic-apiresponse)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/openapi/operations.md "Suggest Edits")

### Operations

In OpenAPI terms, paths are endpoints (resources), such as `/users` or `/reports/summary`, that your API exposes, and operations are the HTTP methods used to manipulate these paths, such as `GET`, `POST` or `DELETE`.

#### Tags[#](/openapi/operations#tags)

To attach a controller to a specific tag, use the `@ApiTags(...tags)` decorator.

```typescript

@ApiTags('cats')
@Controller('cats')
export class CatsController {}
```

#### Headers[#](/openapi/operations#headers)

To define custom headers that are expected as part of the request, use `@ApiHeader()`.

```typescript

@ApiHeader({
  name: 'X-MyHeader',
  description: 'Custom header',
})
@Controller('cats')
export class CatsController {}
```

#### Responses[#](/openapi/operations#responses)

To define a custom HTTP response, use the `@ApiResponse()` decorator.

```typescript

@Post()
@ApiResponse({ status: 201, description: 'The record has been successfully created.'})
@ApiResponse({ status: 403, description: 'Forbidden.'})
async create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

```typescript

@Post()
@ApiCreatedResponse({ description: 'The record has been successfully created.'})
@ApiForbiddenResponse({ description: 'Forbidden.'})
async create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

To specify a return model for a request, we must create a class and annotate all properties with the `@ApiProperty()` decorator.

```typescript

export class Cat {
  @ApiProperty()
  id: number;

  @ApiProperty()
  name: string;

  @ApiProperty()
  age: number;

  @ApiProperty()
  breed: string;
}
```

Then the `Cat` model can be used in combination with the `type` property of the response decorator.

```typescript

@ApiTags('cats')
@Controller('cats')
export class CatsController {
  @Post()
  @ApiCreatedResponse({
    description: 'The record has been successfully created.',
    type: Cat,
  })
  async create(@Body() createCatDto: CreateCatDto): Promise<Cat> {
    return this.catsService.create(createCatDto);
  }
}
```

Let's open the browser and verify the generated `Cat` model:

#### File upload[#](/openapi/operations#file-upload)

You can enable file upload for a specific method with the `@ApiBody` decorator together with `@ApiConsumes()`. Here's a full example using the [File Upload](/v10/techniques/file-upload) technique:

```typescript

@UseInterceptors(FileInterceptor('file'))
@ApiConsumes('multipart/form-data')
@ApiBody({
  description: 'List of cats',
  type: FileUploadDto,
})
uploadFile(@UploadedFile() file) {}
```

Where `FileUploadDto` is defined as follows:

```typescript

class FileUploadDto {
  @ApiProperty({ type: 'string', format: 'binary' })
  file: any;
}
```

To handle multiple files uploading, you can define `FilesUploadDto` as follows:

```typescript

class FilesUploadDto {
  @ApiProperty({ type: 'array', items: { type: 'string', format: 'binary' } })
  files: any[];
}
```

#### Extensions[#](/openapi/operations#extensions)

To add an Extension to a request use the `@ApiExtension()` decorator. The extension name must be prefixed with `x-`.

```typescript

@ApiExtension('x-foo', { hello: 'world' })
```

#### Advanced: Generic `ApiResponse`[#](/openapi/operations#advanced-generic-apiresponse)

With the ability to provide [Raw Definitions](/openapi/types-and-parameters#raw-definitions), we can define Generic schema for Swagger UI. Assume we have the following DTO:

```ts

export class PaginatedDto<TData> {
  @ApiProperty()
  total: number;

  @ApiProperty()
  limit: number;

  @ApiProperty()
  offset: number;

  results: TData[];
}
```

We skip decorating `results` as we will be providing a raw definition for it later. Now, let's define another DTO and name it, for example, `CatDto`, as follows:

```ts

export class CatDto {
  @ApiProperty()
  name: string;

  @ApiProperty()
  age: number;

  @ApiProperty()
  breed: string;
}
```

With this in place, we can define a `PaginatedDto<CatDto>` response, as follows:

```ts

@ApiOkResponse({
  schema: {
    allOf: [
      { $ref: getSchemaPath(PaginatedDto) },
      {
        properties: {
          results: {
            type: 'array',
            items: { $ref: getSchemaPath(CatDto) },
          },
        },
      },
    ],
  },
})
async findAll(): Promise<PaginatedDto<CatDto>> {}
```

In this example, we specify that the response will have allOf `PaginatedDto` and the `results` property will be of type `Array<CatDto>`.

* `getSchemaPath()` function that returns the OpenAPI Schema path from within the OpenAPI Spec File for a given model.
* `allOf` is a concept that OAS 3 provides to cover various Inheritance related use-cases.

Lastly, since `PaginatedDto` is not directly referenced by any controller, the `SwaggerModule` will not be able to generate a corresponding model definition just yet. In this case, we must add it as an [Extra Model](/openapi/types-and-parameters#extra-models). For example, we can use the `@ApiExtraModels()` decorator on the controller level, as follows:

```ts

@Controller('cats')
@ApiExtraModels(PaginatedDto)
export class CatsController {}
```

If you run Swagger now, the generated `swagger.json` for this specific endpoint should have the following response defined:

```json

"responses": {
  "200": {
    "description": "",
    "content": {
      "application/json": {
        "schema": {
          "allOf": [
            {
              "$ref": "#/components/schemas/PaginatedDto"
            },
            {
              "properties": {
                "results": {
                  "$ref": "#/components/schemas/CatDto"
                }
              }
            }
          ]
        }
      }
    }
  }
}
```

To make it reusable, we can create a custom decorator for `PaginatedDto`, as follows:

```ts

export const ApiPaginatedResponse = <TModel extends Type<any>>(
  model: TModel,
) => {
  return applyDecorators(
    ApiExtraModels(PaginatedDto, model),
    ApiOkResponse({
      schema: {
        allOf: [
          { $ref: getSchemaPath(PaginatedDto) },
          {
            properties: {
              results: {
                type: 'array',
                items: { $ref: getSchemaPath(model) },
              },
            },
          },
        ],
      },
    }),
  );
};
```

> **Hint**`Type<any>` interface and `applyDecorators` function are imported from the `@nestjs/common` package.

To ensure that `SwaggerModule` will generate a definition for our model, we must add it as an extra model, like we did earlier with the `PaginatedDto` in the controller.

With this in place, we can use the custom `@ApiPaginatedResponse()` decorator on our endpoint:

```ts

@ApiPaginatedResponse(CatDto)
async findAll(): Promise<PaginatedDto<CatDto>> {}
```

For client generation tools, this approach poses an ambiguity in how the `PaginatedResponse<TModel>` is being generated for the client. The following snippet is an example of a client generator result for the above `GET /` endpoint.

```typescript

// Angular
findAll(): Observable<{ total: number, limit: number, offset: number, results: CatDto[] }>
```

As you can see, the **Return Type** here is ambiguous. To workaround this issue, you can add a `title` property to the `schema` for `ApiPaginatedResponse`:

```typescript

export const ApiPaginatedResponse = <TModel extends Type<any>>(model: TModel) => {
  return applyDecorators(
    ApiOkResponse({
      schema: {
        title: `PaginatedResponseOf${model.name}`,
        allOf: [
          // ...
        ],
      },
    }),
  );
};
```

Now the result of the client generator tool will become:

```ts

// Angular
findAll(): Observable<PaginatedResponseOfCatDto>
```

----
url: https://docs.nestjs.com/v8/recipes/sql-sequelize
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [SQL (Sequelize)](https://docs.nestjs.com/v8/recipes/sql-sequelize#sql-sequelize)
* [Getting started](https://docs.nestjs.com/v8/recipes/sql-sequelize#getting-started)
* [Model injection](https://docs.nestjs.com/v8/recipes/sql-sequelize#model-injection)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/recipes/sql-sequelize.md "Suggest Edits")

### SQL (Sequelize)

##### This chapter applies only to TypeScript

> **Warning** In this article, you'll learn how to create a `DatabaseModule` based on the **Sequelize** package from scratch using custom components. As a consequence, this technique contains a lot of overhead that you can avoid by using the dedicated, out-of-the-box `@nestjs/sequelize` package. To learn more, see [here](/techniques/database#sequelize-integration).

[Sequelize](https://github.com/sequelize/sequelize) is a popular Object Relational Mapper (ORM) written in a vanilla JavaScript, but there is a [sequelize-typescript](https://github.com/RobinBuschmann/sequelize-typescript) TypeScript wrapper which provides a set of decorators and other extras for the base sequelize.

#### Getting started[#](/recipes/sql-sequelize#getting-started)

To start the adventure with this library we have to install the following dependencies:

```bash

$ npm install --save sequelize sequelize-typescript mysql2
$ npm install --save-dev @types/sequelize
```

The first step we need to do is create a **Sequelize** instance with an options object passed into the constructor. Also, we need to add all models (the alternative is to use `modelPaths` property) and `sync()` our database tables.

database.providers.ts

JS TS

```typescript

import { Sequelize } from 'sequelize-typescript';
import { Cat } from '../cats/cat.entity';

export const databaseProviders = [
  {
    provide: 'SEQUELIZE',
    useFactory: async () => {
      const sequelize = new Sequelize({
        dialect: 'mysql',
        host: 'localhost',
        port: 3306,
        username: 'root',
        password: 'password',
        database: 'nest',
      });
      sequelize.addModels([Cat]);
      await sequelize.sync();
      return sequelize;
    },
  },
];
```

> **Hint** Following best practices, we declared the custom provider in the separated file which has a `*.providers.ts` suffix.

Then, we need to export these providers to make them **accessible** for the rest part of the application.

```typescript

import { Module } from '@nestjs/common';
import { databaseProviders } from './database.providers';

@Module({
  providers: [...databaseProviders],
  exports: [...databaseProviders],
})
export class DatabaseModule {}
```

Now we can inject the `Sequelize` object using `@Inject()` decorator. Each class that would depend on the `Sequelize` async provider will wait until a `Promise` is resolved.

#### Model injection[#](/recipes/sql-sequelize#model-injection)

In [Sequelize](https://github.com/sequelize/sequelize) the **Model** defines a table in the database. Instances of this class represent a database row. Firstly, we need at least one entity:

cat.entity.ts

JS TS

```typescript

import { Table, Column, Model } from 'sequelize-typescript';

@Table
export class Cat extends Model {
  @Column
  name: string;

  @Column
  age: number;

  @Column
  breed: string;
}
```

The `Cat` entity belongs to the `cats` directory. This directory represents the `CatsModule`. Now it's time to create a **Repository** provider:

cats.providers.ts

JS TS

```typescript

import { Cat } from './cat.entity';

export const catsProviders = [
  {
    provide: 'CATS_REPOSITORY',
    useValue: Cat,
  },
];
```

> **Warning** In the real-world applications you should avoid **magic strings**. Both `CATS_REPOSITORY` and `SEQUELIZE` should be kept in the separated `constants.ts` file.

In Sequelize, we use static methods to manipulate the data, and thus we created an **alias** here.

Now we can inject the `CATS_REPOSITORY` to the `CatsService` using the `@Inject()` decorator:

cats.service.ts

JS TS

```typescript

import { Injectable, Inject } from '@nestjs/common';
import { CreateCatDto } from './dto/create-cat.dto';
import { Cat } from './cat.entity';

@Injectable()
export class CatsService {
  constructor(
    @Inject('CATS_REPOSITORY')
    private catsRepository: typeof Cat
  ) {}

  async findAll(): Promise<Cat[]> {
    return this.catsRepository.findAll<Cat>();
  }
}
```

The database connection is **asynchronous**, but Nest makes this process completely invisible for the end-user. The `CATS_REPOSITORY` provider is waiting for the db connection, and the `CatsService` is delayed until repository is ready to use. The entire application can start when each class is instantiated.

Here is a final `CatsModule`:

cats.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';
import { catsProviders } from './cats.providers';
import { DatabaseModule } from '../database/database.module';

@Module({
  imports: [DatabaseModule],
  controllers: [CatsController],
  providers: [
    CatsService,
    ...catsProviders,
  ],
})
export class CatsModule {}
```

> **Hint** Do not forget to import the `CatsModule` into the root `AppModule`.

----
url: https://docs.nestjs.com/v7/websockets/guards
----

* [Guards](https://docs.nestjs.com/v7/websockets/guards#guards)
* [Binding guards](https://docs.nestjs.com/v7/websockets/guards#binding-guards)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/websockets/guards.md "Suggest Edits")

### Guards

There is no fundamental difference between web sockets guards and [regular HTTP application guards](/v7/guards). The only difference is that instead of throwing `HttpException`, you should use `WsException`.

> **Hint** The `WsException` class is exposed from `@nestjs/websockets` package.

#### Binding guards[#](/websockets/guards#binding-guards)

The following example uses a method-scoped guard. Just as with HTTP based applications, you can also use gateway-scoped guards (i.e., prefix the gateway class with a `@UseGuards()` decorator).

JS TS

```typescript

@UseGuards(AuthGuard)
@SubscribeMessage('events')
handleEvent(client: Client, data: unknown): WsResponse<unknown> {
  const event = 'events';
  return { event, data };
}
```

```typescript

@UseGuards(AuthGuard)
@SubscribeMessage('events')
handleEvent(client, data) {
  const event = 'events';
  return { event, data };
}
```

----
url: https://docs.nestjs.com/graphql/generating-sdl
----

[Skip to content](#content)

On this page

* [Generating SDL](https://docs.nestjs.com/graphql/generating-sdl#generating-sdl)
* [Usage](https://docs.nestjs.com/graphql/generating-sdl#usage)

### Generating SDL

> **Warning** This chapter applies only to the code first approach.

To generate a GraphQL SDL schema manually (i.e., without running an application, connecting to the database, hooking up resolvers, etc.), use the `GraphQLSchemaBuilderModule`:

```typescript

async function generateSchema() {
  const app = await NestFactory.create(GraphQLSchemaBuilderModule);
  await app.init();

  const gqlSchemaFactory = app.get(GraphQLSchemaFactory);
  const schema = await gqlSchemaFactory.create([RecipesResolver]);
  console.log(printSchema(schema));
}
```

> **Hint** The `GraphQLSchemaBuilderModule` and `GraphQLSchemaFactory` are imported from the `@nestjs/graphql` package. The `printSchema` function is imported from the `graphql` package.

#### Usage[#](/graphql/generating-sdl#usage)

The `gqlSchemaFactory.create()` method takes an array of resolver class references. For example:

```typescript

const schema = await gqlSchemaFactory.create([
  RecipesResolver,
  AuthorsResolver,
  PostsResolver,
]);
```

It also takes an optional second argument with an array of scalar classes:

```typescript

const schema = await gqlSchemaFactory.create(
  [RecipesResolver, AuthorsResolver, PostsResolver],
  [DurationScalar, DateScalar],
);
```

Lastly, you can pass an options object (the same `BuildSchemaOptions` accepted by the `buildSchemaOptions` property of the `GraphQLModule` configuration):

```typescript

const schema = await gqlSchemaFactory.create([RecipesResolver], {
  skipCheck: true,
  orphanedTypes: [],
});
```

* `skipCheck`: skip schema validation; boolean, defaults to `false`
* `orphanedTypes`: an array of classes to generate even though they aren't explicitly referenced (i.e., aren't part of the object graph). Normally, a class that is declared but not referenced anywhere in the graph is omitted.

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/schema-generator.md)

----
url: https://docs.nestjs.com/v10/recipes/sql-sequelize
----

* [SQL (Sequelize)](https://docs.nestjs.com/v10/recipes/sql-sequelize#sql-sequelize)
* [Getting started](https://docs.nestjs.com/v10/recipes/sql-sequelize#getting-started)
* [Model injection](https://docs.nestjs.com/v10/recipes/sql-sequelize#model-injection)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/recipes/sql-sequelize.md "Suggest Edits")

### SQL (Sequelize)

##### This chapter applies only to TypeScript

> **Warning** In this article, you'll learn how to create a `DatabaseModule` based on the **Sequelize** package from scratch using custom components. As a consequence, this technique contains a lot of overhead that you can avoid by using the dedicated, out-of-the-box `@nestjs/sequelize` package. To learn more, see [here](/techniques/database#sequelize-integration).

[Sequelize](https://github.com/sequelize/sequelize) is a popular Object Relational Mapper (ORM) written in a vanilla JavaScript, but there is a [sequelize-typescript](https://github.com/RobinBuschmann/sequelize-typescript) TypeScript wrapper which provides a set of decorators and other extras for the base sequelize.

#### Getting started[#](/recipes/sql-sequelize#getting-started)

To start the adventure with this library we have to install the following dependencies:

```bash

$ npm install --save sequelize sequelize-typescript mysql2
$ npm install --save-dev @types/sequelize
```

The first step we need to do is create a **Sequelize** instance with an options object passed into the constructor. Also, we need to add all models (the alternative is to use `modelPaths` property) and `sync()` our database tables.

database.providers.ts

JS TS

```typescript

import { Sequelize } from 'sequelize-typescript';
import { Cat } from '../cats/cat.entity';

export const databaseProviders = [
  {
    provide: 'SEQUELIZE',
    useFactory: async () => {
      const sequelize = new Sequelize({
        dialect: 'mysql',
        host: 'localhost',
        port: 3306,
        username: 'root',
        password: 'password',
        database: 'nest',
      });
      sequelize.addModels([Cat]);
      await sequelize.sync();
      return sequelize;
    },
  },
];
```

> **Hint** Following best practices, we declared the custom provider in the separated file which has a `*.providers.ts` suffix.

Then, we need to export these providers to make them **accessible** for the rest part of the application.

```typescript

import { Module } from '@nestjs/common';
import { databaseProviders } from './database.providers';

@Module({
  providers: [...databaseProviders],
  exports: [...databaseProviders],
})
export class DatabaseModule {}
```

Now we can inject the `Sequelize` object using `@Inject()` decorator. Each class that would depend on the `Sequelize` async provider will wait until a `Promise` is resolved.

#### Model injection[#](/recipes/sql-sequelize#model-injection)

In [Sequelize](https://github.com/sequelize/sequelize) the **Model** defines a table in the database. Instances of this class represent a database row. Firstly, we need at least one entity:

cat.entity.ts

JS TS

```typescript

import { Table, Column, Model } from 'sequelize-typescript';

@Table
export class Cat extends Model {
  @Column
  name: string;

  @Column
  age: number;

  @Column
  breed: string;
}
```

The `Cat` entity belongs to the `cats` directory. This directory represents the `CatsModule`. Now it's time to create a **Repository** provider:

cats.providers.ts

JS TS

```typescript

import { Cat } from './cat.entity';

export const catsProviders = [
  {
    provide: 'CATS_REPOSITORY',
    useValue: Cat,
  },
];
```

> **Warning** In the real-world applications you should avoid **magic strings**. Both `CATS_REPOSITORY` and `SEQUELIZE` should be kept in the separated `constants.ts` file.

In Sequelize, we use static methods to manipulate the data, and thus we created an **alias** here.

Now we can inject the `CATS_REPOSITORY` to the `CatsService` using the `@Inject()` decorator:

cats.service.ts

JS TS

```typescript

import { Injectable, Inject } from '@nestjs/common';
import { CreateCatDto } from './dto/create-cat.dto';
import { Cat } from './cat.entity';

@Injectable()
export class CatsService {
  constructor(
    @Inject('CATS_REPOSITORY')
    private catsRepository: typeof Cat
  ) {}

  async findAll(): Promise<Cat[]> {
    return this.catsRepository.findAll<Cat>();
  }
}
```

The database connection is **asynchronous**, but Nest makes this process completely invisible for the end-user. The `CATS_REPOSITORY` provider is waiting for the db connection, and the `CatsService` is delayed until repository is ready to use. The entire application can start when each class is instantiated.

Here is a final `CatsModule`:

cats.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';
import { catsProviders } from './cats.providers';
import { DatabaseModule } from '../database/database.module';

@Module({
  imports: [DatabaseModule],
  controllers: [CatsController],
  providers: [
    CatsService,
    ...catsProviders,
  ],
})
export class CatsModule {}
```

> **Hint** Do not forget to import the `CatsModule` into the root `AppModule`.

----
url: https://docs.nestjs.com/v7/fundamentals/testing
----

* [Testing](https://docs.nestjs.com/v7/fundamentals/testing#testing)
* [Installation](https://docs.nestjs.com/v7/fundamentals/testing#installation)
* [Unit testing](https://docs.nestjs.com/v7/fundamentals/testing#unit-testing)
* [Testing utilities](https://docs.nestjs.com/v7/fundamentals/testing#testing-utilities)
* [End-to-end testing](https://docs.nestjs.com/v7/fundamentals/testing#end-to-end-testing)
* [Overriding globally registered enhancers](https://docs.nestjs.com/v7/fundamentals/testing#overriding-globally-registered-enhancers)
* [Testing request-scoped instances](https://docs.nestjs.com/v7/fundamentals/testing#testing-request-scoped-instances)

```bash

$ npm i --save-dev @nestjs/testing
```

#### Unit testing[#](/fundamentals/testing#unit-testing)

In the following example, we test two classes: `CatsController` and `CatsService`. As mentioned, [Jest](https://github.com/facebook/jest) is provided as the default testing framework. It serves as a test-runner and also provides assert functions and test-double utilities that help with mocking, spying, etc. In the following basic test, we manually instantiate these classes, and ensure that the controller and service fulfill their API contract.

cats.controller.spec.ts

JS TS

```typescript

import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

describe('CatsController', () => {
  let catsController: CatsController;
  let catsService: CatsService;

  beforeEach(() => {
    catsService = new CatsService();
    catsController = new CatsController(catsService);
  });

  describe('findAll', () => {
    it('should return an array of cats', async () => {
      const result = ['test'];
      jest.spyOn(catsService, 'findAll').mockImplementation(() => result);

      expect(await catsController.findAll()).toBe(result);
    });
  });
});
```

```typescript

import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

describe('CatsController', () => {
  let catsController;
  let catsService;

  beforeEach(() => {
    catsService = new CatsService();
    catsController = new CatsController(catsService);
  });

  describe('findAll', () => {
    it('should return an array of cats', async () => {
      const result = ['test'];
      jest.spyOn(catsService, 'findAll').mockImplementation(() => result);

      expect(await catsController.findAll()).toBe(result);
    });
  });
});
```

> **Hint** Keep your test files located near the classes they test. Testing files should have a `.spec` or `.test` suffix.

Because the above sample is trivial, we aren't really testing anything Nest-specific. Indeed, we aren't even using dependency injection (notice that we pass an instance of `CatsService` to our `catsController`). This form of testing - where we manually instantiate the classes being tested - is often called **isolated testing** as it is independent from the framework. Let's introduce some more advanced capabilities that help you test applications that make more extensive use of Nest features.

#### Testing utilities[#](/fundamentals/testing#testing-utilities)

The `@nestjs/testing` package provides a set of utilities that enable a more robust testing process. Let's rewrite the previous example using the built-in `Test` class:

cats.controller.spec.ts

JS TS

```typescript

import { Test } from '@nestjs/testing';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

describe('CatsController', () => {
  let catsController: CatsController;
  let catsService: CatsService;

  beforeEach(async () => {
    const moduleRef = await Test.createTestingModule({
        controllers: [CatsController],
        providers: [CatsService],
      }).compile();

    catsService = moduleRef.get<CatsService>(CatsService);
    catsController = moduleRef.get<CatsController>(CatsController);
  });

  describe('findAll', () => {
    it('should return an array of cats', async () => {
      const result = ['test'];
      jest.spyOn(catsService, 'findAll').mockImplementation(() => result);

      expect(await catsController.findAll()).toBe(result);
    });
  });
});
```

```typescript

import { Test } from '@nestjs/testing';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

describe('CatsController', () => {
  let catsController;
  let catsService;

  beforeEach(async () => {
    const moduleRef = await Test.createTestingModule({
        controllers: [CatsController],
        providers: [CatsService],
      }).compile();

    catsService = moduleRef.get(CatsService);
    catsController = moduleRef.get(CatsController);
  });

  describe('findAll', () => {
    it('should return an array of cats', async () => {
      const result = ['test'];
      jest.spyOn(catsService, 'findAll').mockImplementation(() => result);

      expect(await catsController.findAll()).toBe(result);
    });
  });
});
```

The `Test` class is useful for providing an application execution context that essentially mocks the full Nest runtime, but gives you hooks that make it easy to manage class instances, including mocking and overriding. The `Test` class has a `createTestingModule()` method that takes a module metadata object as its argument (the same object you pass to the `@Module()` decorator). This method returns a `TestingModule` instance which in turn provides a few methods. For unit tests, the important one is the `compile()` method. This method bootstraps a module with its dependencies (similar to the way an application is bootstrapped in the conventional `main.ts` file using `NestFactory.create()`), and returns a module that is ready for testing.

> **Hint** The `compile()` method is **asynchronous** and therefore has to be awaited. Once the module is compiled you can retrieve any **static** instance it declares (controllers and providers) using the `get()` method.

`TestingModule` inherits from the [module reference](/v7/fundamentals/module-ref) class, and therefore its ability to dynamically resolve scoped providers (transient or request-scoped). Do this with the `resolve()` method (the `get()` method can only retrieve static instances).

```typescript

const moduleRef = await Test.createTestingModule({
  controllers: [CatsController],
  providers: [CatsService],
}).compile();

catsService = await moduleRef.resolve(CatsService);
```

> **Warning** The `resolve()` method returns a unique instance of the provider, from its own **DI container sub-tree**. Each sub-tree has a unique context identifier. Thus, if you call this method more than once and compare instance references, you will see that they are not equal.

> **Hint** Learn more about the module reference features [here](/v7/fundamentals/module-ref).

Instead of using the production version of any provider, you can override it with a [custom provider](/v7/fundamentals/custom-providers) for testing purposes. For example, you can mock a database service instead of connecting to a live database. We'll cover overrides in the next section, but they're available for unit tests as well.

## Learn the right way!

* 80+ chapters
* 5+ hours of videos

```typescript

import * as request from 'supertest';
import { Test } from '@nestjs/testing';
import { CatsModule } from '../../src/cats/cats.module';
import { CatsService } from '../../src/cats/cats.service';
import { INestApplication } from '@nestjs/common';

describe('Cats', () => {
  let app: INestApplication;
  let catsService = { findAll: () => ['test'] };

  beforeAll(async () => {
    const moduleRef = await Test.createTestingModule({
      imports: [CatsModule],
    })
      .overrideProvider(CatsService)
      .useValue(catsService)
      .compile();

    app = moduleRef.createNestApplication();
    await app.init();
  });

  it(`/GET cats`, () => {
    return request(app.getHttpServer())
      .get('/cats')
      .expect(200)
      .expect({
        data: catsService.findAll(),
      });
  });

  afterAll(async () => {
    await app.close();
  });
});
```

```typescript

import * as request from 'supertest';
import { Test } from '@nestjs/testing';
import { CatsModule } from '../../src/cats/cats.module';
import { CatsService } from '../../src/cats/cats.service';
import { INestApplication } from '@nestjs/common';

describe('Cats', () => {
  let app: INestApplication;
  let catsService = { findAll: () => ['test'] };

  beforeAll(async () => {
    const moduleRef = await Test.createTestingModule({
      imports: [CatsModule],
    })
      .overrideProvider(CatsService)
      .useValue(catsService)
      .compile();

    app = moduleRef.createNestApplication();
    await app.init();
  });

  it(`/GET cats`, () => {
    return request(app.getHttpServer())
      .get('/cats')
      .expect(200)
      .expect({
        data: catsService.findAll(),
      });
  });

  afterAll(async () => {
    await app.close();
  });
});
```

> **Hint** If you're using [Fastify](/v7/techniques/performance) as your HTTP adapter, it requires a slightly different configuration, and has built-in testing capabilities:
>
> ```ts
>
> let app: NestFastifyApplication;
>
> beforeAll(async () => {
>   app = moduleRef.createNestApplication<NestFastifyApplication>(
>     new FastifyAdapter(),
>   );
>
>   await app.init();
>   await app.getHttpAdapter().getInstance().ready();
> })
>
> it(`/GET cats`, () => {
>   return app
>     .inject({
>       method: 'GET',
>       url: '/cats'
>     }).then(result => {
>       expect(result.statusCode).toEqual(200)
>       expect(result.payload).toEqual(/* expectedPayload */)
>     });
> })
> ```

|                            |                                                                                                                                                                                                                                                   |
| -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `createNestApplication()`  | Creates and returns a Nest application (`INestApplication` instance) based on the given module. Note that you must manually initialize the application using the `init()` method.                                                                 |
| `createNestMicroservice()` | Creates and returns a Nest microservice (`INestMicroservice` instance) based on the given module.                                                                                                                                                 |
| `get()`                    | Retrieves a static instance of a controller or provider (including guards, filters, etc.) available in the application context. Inherited from the [module reference](/fundamentals/module-ref) class.                                            |
| `resolve()`                | Retrieves a dynamically created scoped instance (request or transient) of a controller or provider (including guards, filters, etc.) available in the application context. Inherited from the [module reference](/fundamentals/module-ref) class. |
| `select()`                 | Navigates through the module's dependency graph; can be used to retrieve a specific instance from the selected module (used along with strict mode (`strict: true`) in `get()` method).                                                           |

> **Hint** Keep your e2e test files inside the `test` directory. The testing files should have a `.e2e-spec` suffix.

#### Overriding globally registered enhancers[#](/fundamentals/testing#overriding-globally-registered-enhancers)

If you have a globally registered guard (or pipe, interceptor, or filter), you need to take a few more steps to override that enhancer. To recap the original registration looks like this:

```typescript

providers: [
  {
    provide: APP_GUARD,
    useClass: JwtAuthGuard,
  },
],
```

This is registering the guard as a "multi"-provider through the `APP_*` token. To be able to replace the `JwtAuthGuard` here, the registration needs to use an existing provider in this slot:

```typescript

providers: [
  {
    provide: APP_GUARD,
    useExisting: JwtAuthGuard,
  },
  JwtAuthGuard,
],
```

> **Hint** Change the `useClass` to `useExisting` to reference a registered provider instead of having Nest instantiate it behind the token.

Now the `JwtAuthGuard` is visible to Nest as a regular provider that can be overridden when creating the `TestingModule`:

```typescript

const moduleRef = await Test.createTestingModule({
  imports: [AppModule],
})
  .overrideProvider(JwtAuthGuard)
  .useClass(MockAuthGuard)
  .compile();
```

Now all your tests will use the `MockAuthGuard` on every request.

#### Testing request-scoped instances[#](/fundamentals/testing#testing-request-scoped-instances)

[Request-scoped](/v7/fundamentals/injection-scopes) providers are created uniquely for each incoming **request**. The instance is garbage-collected after the request has completed processing. This poses a problem, because we can't access a dependency injection sub-tree generated specifically for a tested request.

We know (based on the sections above) that the `resolve()` method can be used to retrieve a dynamically instantiated class. Also, as described [here](https://docs.nestjs.com/fundamentals/module-ref#resolving-scoped-providers), we know we can pass a unique context identifier to control the lifecycle of a DI container sub-tree. How do we leverage this in a testing context?

The strategy is to generate a context identifier beforehand and force Nest to use this particular ID to create a sub-tree for all incoming requests. In this way we'll be able to retrieve instances created for a tested request.

To accomplish this, use `jest.spyOn()` on the `ContextIdFactory`:

```typescript

const contextId = ContextIdFactory.create();
jest
  .spyOn(ContextIdFactory, 'getByRequest')
  .mockImplementation(() => contextId);
```

Now we can use the `contextId` to access a single generated DI container sub-tree for any subsequent request.

```typescript

catsService = await moduleRef.resolve(CatsService, contextId);
```

----
url: https://docs.nestjs.com/v11/modules
----

* [Modules](https://docs.nestjs.com/v11/modules#modules)
* [Feature modules](https://docs.nestjs.com/v11/modules#feature-modules)
* [Shared modules](https://docs.nestjs.com/v11/modules#shared-modules)
* [Module re-exporting](https://docs.nestjs.com/v11/modules#module-re-exporting)
* [Dependency injection](https://docs.nestjs.com/v11/modules#dependency-injection)
* [Global modules](https://docs.nestjs.com/v11/modules#global-modules)
* [Dynamic modules](https://docs.nestjs.com/v11/modules#dynamic-modules)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/modules.md "Suggest Edits")

### Modules

A module is a class that is annotated with the `@Module()` decorator. This decorator provides metadata that **Nest** uses to organize and manage the application structure efficiently.

Every Nest application has at least one module, the **root module**, which serves as the starting point for Nest to build the **application graph**. This graph is an internal structure that Nest uses to resolve relationships and dependencies between modules and providers. While small applications might only have a root module, this is generally not the case. Modules are **highly recommended** as an effective way to organize your components. For most applications, you'll likely have multiple modules, each encapsulating a closely related set of **capabilities**.

The `@Module()` decorator takes a single object with properties that describe the module:

| `providers`   | the providers that will be instantiated by the Nest injector and that may be shared at least across this module                                                                                          |
| ------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `controllers` | the set of controllers defined in this module which have to be instantiated                                                                                                                              |
| `imports`     | the list of imported modules that export the providers which are required in this module                                                                                                                 |
| `exports`     | the subset of `providers` that are provided by this module and should be available in other modules which import this module. You can use either the provider itself or just its token (`provide` value) |

The module **encapsulates** providers by default, meaning you can only inject providers that are either part of the current module or explicitly exported from other imported modules. The exported providers from a module essentially serve as the module's public interface or API.

#### Feature modules[#](/modules#feature-modules)

In our example, the `CatsController` and `CatsService` are closely related and serve the same application domain. It makes sense to group them into a feature module. A feature module organizes code that is relevant to a specific feature, helping to maintain clear boundaries and better organization. This is particularly important as the application or team grows, and it aligns with the [SOLID](https://en.wikipedia.org/wiki/SOLID) principles.

Next, we'll create the `CatsModule` to demonstrate how to group the controller and service.

cats/cats.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

@Module({
  controllers: [CatsController],
  providers: [CatsService],
})
export class CatsModule {}
```

> **Hint** To create a module using the CLI, simply execute the `$ nest g module cats` command.

Above, we defined the `CatsModule` in the `cats.module.ts` file, and moved everything related to this module into the `cats` directory. The last thing we need to do is import this module into the root module (the `AppModule`, defined in the `app.module.ts` file).

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { CatsModule } from './cats/cats.module';

@Module({
  imports: [CatsModule],
})
export class AppModule {}
```

```typescript

import { Module } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

@Module({
  controllers: [CatsController],
  providers: [CatsService],
  exports: [CatsService]
})
export class CatsModule {}
```

Now any module that imports the `CatsModule` has access to the `CatsService` and will share the same instance with all other modules that import it as well.

If we were to directly register the `CatsService` in every module that requires it, it would indeed work, but it would result in each module getting its own separate instance of the `CatsService`. This can lead to increased memory usage since multiple instances of the same service are created, and it could also cause unexpected behavior, such as state inconsistency if the service maintains any internal state.

By encapsulating the `CatsService` inside a module, such as the `CatsModule`, and exporting it, we ensure that the same instance of `CatsService` is reused across all modules that import `CatsModule`. This not only reduces memory consumption but also leads to more predictable behavior, as all modules share the same instance, making it easier to manage shared states or resources. This is one of the key benefits of modularity and dependency injection in frameworks like NestJS—allowing services to be efficiently shared throughout the application.

## Explore your graph with NestJS Devtools

* **Graph visualizer
* **Routes navigator
* **Interactive playground
* **CI/CD integration

[Sign up](https://devtools.nestjs.com "Devtools | NestJS - A node.js framework built on top of TypeScript")

#### Module re-exporting[#](/modules#module-re-exporting)

As seen above, Modules can export their internal providers. In addition, they can re-export modules that they import. In the example below, the `CommonModule` is both imported into **and** exported from the `CoreModule`, making it available for other modules which import this one.

```typescript

@Module({
  imports: [CommonModule],
  exports: [CommonModule],
})
export class CoreModule {}
```

#### Dependency injection[#](/modules#dependency-injection)

A module class can **inject** providers as well (e.g., for configuration purposes):

cats.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

@Module({
  controllers: [CatsController],
  providers: [CatsService],
})
export class CatsModule {
  constructor(private catsService: CatsService) {}
}
```

```typescript

import { Module, Dependencies } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

@Module({
  controllers: [CatsController],
  providers: [CatsService],
})
@Dependencies(CatsService)
export class CatsModule {
  constructor(catsService) {
    this.catsService = catsService;
  }
}
```

However, module classes themselves cannot be injected as providers due to [circular dependency](/v11/fundamentals/circular-dependency) .

#### Global modules[#](/modules#global-modules)

If you have to import the same set of modules everywhere, it can get tedious. Unlike in Nest, [Angular](https://angular.dev)`providers` are registered in the global scope. Once defined, they're available everywhere. Nest, however, encapsulates providers inside the module scope. You aren't able to use a module's providers elsewhere without first importing the encapsulating module.

When you want to provide a set of providers which should be available everywhere out-of-the-box (e.g., helpers, database connections, etc.), make the module **global** with the `@Global()` decorator.

```typescript

import { Module, Global } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

@Global()
@Module({
  controllers: [CatsController],
  providers: [CatsService],
  exports: [CatsService],
})
export class CatsModule {}
```

The `@Global()` decorator makes the module global-scoped. Global modules should be registered **only once**, generally by the root or core module. In the above example, the `CatsService` provider will be ubiquitous, and modules that wish to inject the service will not need to import the `CatsModule` in their imports array.

> **Hint** Making everything global is not recommended as a design practice. While global modules can help reduce boilerplate, it's generally better to use the `imports` array to make a module's API available to other modules in a controlled and clear way. This approach provides better structure and maintainability, ensuring that only the necessary parts of the module are shared with others while avoiding unnecessary coupling between unrelated parts of the application.

#### Dynamic modules[#](/modules#dynamic-modules)

Dynamic modules in Nest allow you to create modules that can be configured at runtime. This is especially useful when you need to provide flexible, customizable modules where the providers can be created based on certain options or configurations. Here's a brief overview of how **dynamic modules** work.

JS TS

```typescript

import { Module, DynamicModule } from '@nestjs/common';
import { createDatabaseProviders } from './database.providers';
import { Connection } from './connection.provider';

@Module({
  providers: [Connection],
  exports: [Connection],
})
export class DatabaseModule {
  static forRoot(entities = [], options?): DynamicModule {
    const providers = createDatabaseProviders(options, entities);
    return {
      module: DatabaseModule,
      providers: providers,
      exports: providers,
    };
  }
}
```

```typescript

import { Module } from '@nestjs/common';
import { createDatabaseProviders } from './database.providers';
import { Connection } from './connection.provider';

@Module({
  providers: [Connection],
  exports: [Connection],
})
export class DatabaseModule {
  static forRoot(entities = [], options) {
    const providers = createDatabaseProviders(options, entities);
    return {
      module: DatabaseModule,
      providers: providers,
      exports: providers,
    };
  }
}
```

> **Hint** The `forRoot()` method may return a dynamic module either synchronously or asynchronously (i.e., via a `Promise`).

This module defines the `Connection` provider by default (in the `@Module()` decorator metadata), but additionally - depending on the `entities` and `options` objects passed into the `forRoot()` method - exposes a collection of providers, for example, repositories. Note that the properties returned by the dynamic module **extend** (rather than override) the base module metadata defined in the `@Module()` decorator. That's how both the statically declared `Connection` provider **and** the dynamically generated repository providers are exported from the module.

If you want to register a dynamic module in the global scope, set the `global` property to `true`.

```typescript

{
  global: true,
  module: DatabaseModule,
  providers: providers,
  exports: providers,
}
```

> **Warning** As mentioned above, making everything global **is not a good design decision**.

The `DatabaseModule` can be imported and configured in the following manner:

```typescript

import { Module } from '@nestjs/common';
import { DatabaseModule } from './database/database.module';
import { User } from './users/entities/user.entity';

@Module({
  imports: [DatabaseModule.forRoot([User])],
})
export class AppModule {}
```

If you want to in turn re-export a dynamic module, you can omit the `forRoot()` method call in the exports array:

```typescript

import { Module } from '@nestjs/common';
import { DatabaseModule } from './database/database.module';
import { User } from './users/entities/user.entity';

@Module({
  imports: [DatabaseModule.forRoot([User])],
  exports: [DatabaseModule],
})
export class AppModule {}
```

The [Dynamic modules](/v11/fundamentals/dynamic-modules) chapter covers this topic in greater detail, and includes a [working example](https://github.com/nestjs/nest/tree/master/sample/25-dynamic-modules).

> **Hint** Learn how to build highly customizable dynamic modules with the use of `ConfigurableModuleBuilder` here in [this chapter](/fundamentals/dynamic-modules#configurable-module-builder).

----
url: https://docs.nestjs.com/v9/recipes/mongodb
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [MongoDB (Mongoose)](https://docs.nestjs.com/v9/recipes/mongodb#mongodb-mongoose)
* [Getting started](https://docs.nestjs.com/v9/recipes/mongodb#getting-started)
* [Model injection](https://docs.nestjs.com/v9/recipes/mongodb#model-injection)
* [Example](https://docs.nestjs.com/v9/recipes/mongodb#example)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/recipes/mongodb.md "Suggest Edits")

### MongoDB (Mongoose)

> **Warning** In this article, you'll learn how to create a `DatabaseModule` based on the **Mongoose** package from scratch using custom components. As a consequence, this solution contains a lot of overhead that you can omit using ready to use and available out-of-the-box dedicated `@nestjs/mongoose` package. To learn more, see [here](/v9/techniques/mongodb).

[Mongoose](https://mongoosejs.com) is the most popular [MongoDB](https://www.mongodb.org/) object modeling tool.

#### Getting started[#](/recipes/mongodb#getting-started)

To start the adventure with this library we have to install all required dependencies:

```typescript

$ npm install --save mongoose
```

The first step we need to do is to establish the connection with our database using `connect()` function. The `connect()` function returns a `Promise`, and therefore we have to create an [async provider](/v9/fundamentals/async-components).

database.providers.ts

JS TS

```typescript

import * as mongoose from 'mongoose';

export const databaseProviders = [
  {
    provide: 'DATABASE_CONNECTION',
    useFactory: (): Promise<typeof mongoose> =>
      mongoose.connect('mongodb://localhost/nest'),
  },
];
```

```typescript

import * as mongoose from 'mongoose';

export const databaseProviders = [
  {
    provide: 'DATABASE_CONNECTION',
    useFactory: () => mongoose.connect('mongodb://localhost/nest'),
  },
];
```

> **Hint** Following best practices, we declared the custom provider in the separated file which has a `*.providers.ts` suffix.

Then, we need to export these providers to make them **accessible** for the rest part of the application.

database.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { databaseProviders } from './database.providers';

@Module({
  providers: [...databaseProviders],
  exports: [...databaseProviders],
})
export class DatabaseModule {}
```

Now we can inject the `Connection` object using `@Inject()` decorator. Each class that would depend on the `Connection` async provider will wait until a `Promise` is resolved.

#### Model injection[#](/recipes/mongodb#model-injection)

With Mongoose, everything is derived from a [Schema](https://mongoosejs.com/docs/guide.html). Let's define the `CatSchema`:

schemas/cat.schema.ts

JS TS

```typescript

import * as mongoose from 'mongoose';

export const CatSchema = new mongoose.Schema({
  name: String,
  age: Number,
  breed: String,
});
```

The `CatsSchema` belongs to the `cats` directory. This directory represents the `CatsModule`.

Now it's time to create a **Model** provider:

cats.providers.ts

JS TS

```typescript

import { Connection } from 'mongoose';
import { CatSchema } from './schemas/cat.schema';

export const catsProviders = [
  {
    provide: 'CAT_MODEL',
    useFactory: (connection: Connection) => connection.model('Cat', CatSchema),
    inject: ['DATABASE_CONNECTION'],
  },
];
```

```typescript

import { CatSchema } from './schemas/cat.schema';

export const catsProviders = [
  {
    provide: 'CAT_MODEL',
    useFactory: (connection) => connection.model('Cat', CatSchema),
    inject: ['DATABASE_CONNECTION'],
  },
];
```

> **Warning** In the real-world applications you should avoid **magic strings**. Both `CAT_MODEL` and `DATABASE_CONNECTION` should be kept in the separated `constants.ts` file.

Now we can inject the `CAT_MODEL` to the `CatsService` using the `@Inject()` decorator:

cats.service.ts

JS TS

```typescript

import { Model } from 'mongoose';
import { Injectable, Inject } from '@nestjs/common';
import { Cat } from './interfaces/cat.interface';
import { CreateCatDto } from './dto/create-cat.dto';

@Injectable()
export class CatsService {
  constructor(
    @Inject('CAT_MODEL')
    private catModel: Model<Cat>,
  ) {}

  async create(createCatDto: CreateCatDto): Promise<Cat> {
    const createdCat = new this.catModel(createCatDto);
    return createdCat.save();
  }

  async findAll(): Promise<Cat[]> {
    return this.catModel.find().exec();
  }
}
```

```typescript

import { Injectable, Dependencies } from '@nestjs/common';

@Injectable()
@Dependencies('CAT_MODEL')
export class CatsService {
  constructor(catModel) {
    this.catModel = catModel;
  }

  async create(createCatDto) {
    const createdCat = new this.catModel(createCatDto);
    return createdCat.save();
  }

  async findAll() {
    return this.catModel.find().exec();
  }
}
```

In the above example we have used the `Cat` interface. This interface extends the `Document` from the mongoose package:

```typescript

import { Document } from 'mongoose';

export interface Cat extends Document {
  readonly name: string;
  readonly age: number;
  readonly breed: string;
}
```

The database connection is **asynchronous**, but Nest makes this process completely invisible for the end-user. The `CatModel` class is waiting for the db connection, and the `CatsService` is delayed until model is ready to use. The entire application can start when each class is instantiated.

Here is a final `CatsModule`:

cats.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';
import { catsProviders } from './cats.providers';
import { DatabaseModule } from '../database/database.module';

@Module({
  imports: [DatabaseModule],
  controllers: [CatsController],
  providers: [
    CatsService,
    ...catsProviders,
  ],
})
export class CatsModule {}
```

> **Hint** Do not forget to import the `CatsModule` into the root `AppModule`.

#### Example[#](/recipes/mongodb#example)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/14-mongoose-base).

----
url: https://docs.nestjs.com/v9/migration-guide
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Migration guide](https://docs.nestjs.com/v9/migration-guide#migration-guide)
* [Redis strategy (microservices)](https://docs.nestjs.com/v9/migration-guide#redis-strategy-microservices)
* [gRPC client interceptors](https://docs.nestjs.com/v9/migration-guide#grpc-client-interceptors)
* [Testing module](https://docs.nestjs.com/v9/migration-guide#testing-module)
* [Kafka message/event handlers](https://docs.nestjs.com/v9/migration-guide#kafka-messageevent-handlers)
* [Kafka retriable errors](https://docs.nestjs.com/v9/migration-guide#kafka-retriable-errors)
* [Fastify](https://docs.nestjs.com/v9/migration-guide#fastify)
* [@nestjs/swagger package](https://docs.nestjs.com/v9/migration-guide#nestjsswagger-package)
* [Deprecations](https://docs.nestjs.com/v9/migration-guide#deprecations)
* [Node.js](https://docs.nestjs.com/v9/migration-guide#nodejs)
* [CLI](https://docs.nestjs.com/v9/migration-guide#cli)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/migration.md "Suggest Edits")

### Migration guide

This article provides a set of guidelines for migrating from Nest version 8 to version 9. To learn more about the new features we've added in v9, check out this [link](https://github.com/nestjs/nest/pull/9588).

#### Redis strategy (microservices)[#](/migration-guide#redis-strategy-microservices)

[Redis](/v9/microservices/redis) strategy uses the [ioredis](https://github.com/luin/ioredis) driver instead of `redis` now.

```typescript

// Before
const app = await NestFactory.createMicroservice<MicroserviceOptions>(
  AppModule,
  {
    transport: Transport.REDIS,
    options: {
      url: 'redis://localhost:6379',
    },
  },
);

// Now
const app = await NestFactory.createMicroservice<MicroserviceOptions>(
  AppModule,
  {
    transport: Transport.REDIS,
    options: {
      host: 'localhost',
      port: 6379,
    },
  },
);
```

Also, make sure to install the `ioredis` package:

```bash

$ npm i ioredis
```

#### gRPC client interceptors[#](/migration-guide#grpc-client-interceptors)

In the previous version, the `interceptors` configuration property was exposed in the wrong location. In v9, make sure to pass `interceptors` as part of the `channelOptions` object, see example [here](https://github.com/nestjs/nest/issues/9079#issuecomment-1078744758).

#### Testing module[#](/migration-guide#testing-module)

Previously, if you wanted to supply the configuration object to the `TestingModule#createNestApplication` method, and if you were using the default HTTP driver (express), you had to do this as follows:

```typescript

app = moduleFixture.createNestApplication<NestExpressApplication>(undefined, {
  rawBody: true,
});
```

In v9, you can skip the first argument (`undefined`):

```typescript

app = moduleFixture.createNestApplication<NestExpressApplication>({
  rawBody: true,
});
```

#### Kafka message/event handlers[#](/migration-guide#kafka-messageevent-handlers)

Previously, Kafka message and event handlers were receiving payloads as wrapped Kafka messages with `key`, `value`, `headers`, and a few other properties. In v9, those payloads are automatically unwrapped and your handlers will only receive the `value` attribute's value. To retrieve the original Kafka message, you can use the `KafkaContext` object (read more [here](/microservices/kafka#context)).

```typescript

// Before
@MessagePattern('hero.kill.dragon')
killDragon(@Payload() message: KillDragonMessage, @Ctx() context: KafkaContext) {
  console.log(`Dragon ID: ${message.value.dragonId}`);
}

// Now
@MessagePattern('hero.kill.dragon')
killDragon(@Payload() message: KillDragonMessage, @Ctx() context: KafkaContext) {
  console.log(`Dragon ID: ${message.dragonId}`);
  // Original message: "context.getMessage()"
}
```

#### Kafka retriable errors[#](/migration-guide#kafka-retriable-errors)

In v9, we introduced the **[Retriable exceptions](/microservices/kafka#retriable-exceptions)** feature. Note: for event handlers (**event-based communication**) all unhandled exceptions become "retriable exceptions" by default, and so they will be auto-delivered.

#### Fastify[#](/migration-guide#fastify)

Fastify has been upgraded to v4. Also, all of the core Fastify plugins that were prefixed with `fastify-` are now renamed and published under the `@fastify` scope (for example, `fastify-cookie` becomes `@fastify/cookie`, `fastify-helmet` becomes `@fastify/helmet`, etc.). Read more [here](https://github.com/fastify/fastify/issues/3856).

#### `@nestjs/swagger` package[#](/migration-guide#nestjsswagger-package)

There are a few minor breaking changes in the `@nestjs/swagger` package (`swagger-ui-express` and `fastify-swagger` packages are no longer required). See this [PR](https://github.com/nestjs/swagger/pull/1886) for more details.

#### Deprecations[#](/migration-guide#deprecations)

All deprecated methods & modules have been removed (e.g., the deprecated `listenAsync()` method).

#### Node.js[#](/migration-guide#nodejs)

This release drops support for Node v10. We strongly recommend using the latest LTS version.

#### CLI[#](/migration-guide#cli)

Due to stability issues, the command `update` was removed in the v9 of `@nestjs/cli`.\
You can use dedicated tools like [`ncu`](https://www.npmjs.com/package/npm-check-updates), `npm update`, [`yarn upgrade-interactive`](https://classic.yarnpkg.com/en/docs/cli/upgrade-interactive), etc., if you want to upgrade your dependencies.

----
url: https://docs.nestjs.com/v7/recipes/prisma
----

* [Prisma](https://docs.nestjs.com/v7/recipes/prisma#prisma)
* [Getting started](https://docs.nestjs.com/v7/recipes/prisma#getting-started)
* [Create your NestJS project](https://docs.nestjs.com/v7/recipes/prisma#create-your-nestjs-project)
* [Set up Prisma](https://docs.nestjs.com/v7/recipes/prisma#set-up-prisma)
* [Set the database connection](https://docs.nestjs.com/v7/recipes/prisma#set-the-database-connection)
* [Create two database tables with Prisma Migrate](https://docs.nestjs.com/v7/recipes/prisma#create-two-database-tables-with-prisma-migrate)
* [Install and generate Prisma Client](https://docs.nestjs.com/v7/recipes/prisma#install-and-generate-prisma-client)
* [Use Prisma Client in your NestJS services](https://docs.nestjs.com/v7/recipes/prisma#use-prisma-client-in-your-nestjs-services)
* [Summary](https://docs.nestjs.com/v7/recipes/prisma#summary)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/recipes/prisma.md "Suggest Edits")

### Prisma

[Prisma](https://www.prisma.io) is an [open-source](https://github.com/prisma/prisma) ORM for Node.js and TypeScript. It is used as an **alternative** to writing plain SQL, or using another database access tool such as SQL query builders (like [knex.js](https://knexjs.org/)) or ORMs (like [TypeORM](https://typeorm.io/) and [Sequelize](https://sequelize.org/)). Prisma currently supports PostgreSQL, MySQL, SQL Server and SQLite.

While Prisma can be used with plain JavaScript, it embraces TypeScript and provides a level to type-safety that goes beyond the guarantees other ORMs in the TypeScript ecosystem. You can find an in-depth comparison of the type-safety guarantees of Prisma and TypeORM [here](https://www.prisma.io/docs/concepts/more/comparisons/prisma-and-typeorm#type-safety).

> **Note** If you want to get a quick overview of how Prisma works, you can follow the [Quickstart](https://www.prisma.io/docs/getting-started/quickstart) or read the [Introduction](https://www.prisma.io/docs/understand-prisma/introduction) in the [documentation](https://www.prisma.io/docs/). There also are ready-to-run examples for [REST](https://github.com/prisma/prisma-examples/tree/latest/typescript/rest-nestjs) and [GraphQL](https://github.com/prisma/prisma-examples/tree/latest/typescript/graphql-nestjs) in the [`prisma-examples`](https://github.com/prisma/prisma-examples/) repo.

#### Getting started[#](/recipes/prisma#getting-started)

In this recipe, you'll learn how to get started with NestJS and Prisma from scratch. You are going to build a sample NestJS application with a REST API that can read and write data in a database.

For the purpose of this guide, you'll use a [SQLite](https://sqlite.org/) database to save the overhead of setting up a database server. Note that you can still follow this guide, even if you're using PostgreSQL or MySQL – you'll get extra instructions for using these databases at the right places.

> **Note** If you already have an existing project and consider migrating to Prisma, you can follow the guide for [adding Prisma to an existing project](https://www.prisma.io/docs/getting-started/setup-prisma/add-to-existing-project-typescript-postgres). If you are migrating from TypeORM, you can read the guide [Migrating from TypeORM to Prisma](https://www.prisma.io/docs/guides/migrate-to-prisma/migrate-from-typeorm).

#### Create your NestJS project[#](/recipes/prisma#create-your-nestjs-project)

To get started, install the NestJS CLI and create your app skeleton with the following commands:

```bash

$ npm install -g @nestjs/cli
$ nest new hello-prisma
```

See the [First steps](https://docs.nestjs.com/first-steps) page to learn more about the project files created by this command. Note also that you can now run `npm start` to start your application. The REST API running at `http://localhost:3000/` currently serves a single route that's implemented in `src/app.controller.ts`. Over the course of this guide, you'll implement additional routes to store and retrieve data about *users* and *posts*.

#### Set up Prisma[#](/recipes/prisma#set-up-prisma)

Start by installing the Prisma CLI as a development dependency in your project:

```bash

$ cd hello-prisma
$ npm install prisma --save-dev
```

In the following steps, we'll be utilizing the [Prisma CLI](https://www.prisma.io/docs/reference/tools-and-interfaces/prisma-cli). As a best practice, it's recommended to invoke the CLI locally by prefixing it with `npx`:

```bash

$ npx prisma
```

Expand if you're using Yarn

If you're using Yarn, then you can install the Prisma CLI as follows:

```bash

$ yarn add prisma --dev
```

Once installed, you can invoke it by prefixing it with `yarn`:

```bash

$ yarn prisma
```

Now create your initial Prisma setup using the `init` command of the Prisma CLI:

```bash

$ npx prisma init
```

This command creates a new `prisma` directory with the following contents:

* `schema.prisma`: Specifies your database connection and contains the database schema
* `.env`: A [dotenv](https://github.com/motdotla/dotenv) file, typically used to store your database credentials in a group of environment variables

#### Set the database connection[#](/recipes/prisma#set-the-database-connection)

Your database connection is configured in the `datasource` block in your `schema.prisma` file. By default it's set to `postgresql`, but since you're using a SQLite database in this guide you need to adjust the `provider` field of the `datasource` block to `sqlite`:

```groovy

datasource db {
  provider = "sqlite"
  url      = env("DATABASE_URL")
}

generator client {
  provider = "prisma-client-js"
}
```

Now, open up `.env` and adjust the `DATABASE_URL` environment variable to look as follows:

```bash

DATABASE_URL="file:./dev.db"
```

SQLite databases are simple files; no server is required to use a SQLite database. So instead of configuring a connection URL with a *host* and *port*, you can just point it to a local file which in this case is called `dev.db`. This file will be created in the next step.

Expand if you're using PostgreSQL or MySQL

With PostgreSQL and MySQL, you need to configure the connection URL to point to the *database server*. You can learn more about the required connection URL format [here](https://www.prisma.io/docs/reference/database-reference/connection-urls).

**PostgreSQL**

If you're using PostgreSQL, you have to adjust the `schema.prisma` and `.env` files as follows:

**`schema.prisma`**

```groovy

datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}

generator client {
  provider = "prisma-client-js"
}
```

**`.env`**

```bash

DATABASE_URL="postgresql://USER:PASSWORD@HOST:PORT/DATABASE?schema=SCHEMA"
```

Replace the placeholders spelled in all uppercase letters with your database credentials. Note that if you're unsure what to provide for the `SCHEMA` placeholder, it's most likely the default value `public`:

```bash

DATABASE_URL="postgresql://USER:PASSWORD@HOST:PORT/DATABASE?schema=public"
```

If you want to learn how to set up a PostgreSQL database, you can follow this guide on [setting up a free PostgreSQL database on Heroku](https://dev.to/prisma/how-to-setup-a-free-postgresql-database-on-heroku-1dc1).

**MySQL**

If you're using MySQL, you have to adjust the `schema.prisma` and `.env` files as follows:

**`schema.prisma`**

```groovy

datasource db {
  provider = "mysql"
  url      = env("DATABASE_URL")
}

generator client {
  provider = "prisma-client-js"
}
```

**`.env`**

```bash

DATABASE_URL="mysql://USER:PASSWORD@HOST:PORT/DATABASE"
```

Replace the placeholders spelled in all uppercase letters with your database credentials.

#### Create two database tables with Prisma Migrate[#](/recipes/prisma#create-two-database-tables-with-prisma-migrate)

In this section, you'll create two new tables in your database using [Prisma Migrate](https://www.prisma.io/docs/concepts/components/prisma-migrate). Prisma Migrate generates SQL migration files for your declarative data model definition in the Prisma schema. These migration files are fully customizable so that you can configure any additional features of the underlying database or include additional commands, e.g. for seeding.

Add the following two models to your `schema.prisma` file:

```groovy

model User {
  id    Int     @default(autoincrement()) @id
  email String  @unique
  name  String?
  posts Post[]
}

model Post {
  id        Int      @default(autoincrement()) @id
  title     String
  content   String?
  published Boolean? @default(false)
  author    User?    @relation(fields: [authorId], references: [id])
  authorId  Int?
}
```

With your Prisma models in place, you can generate your SQL migration files and run them against the database. Run the following commands in your terminal:

```bash

$ npx prisma migrate dev --name init --preview-feature
```

> **Note** The `prisma migrate` commands currently requires the `--preview-feature` option as it's in [Preview](https://www.prisma.io/docs/about/releases#preview).

This `prisma migrate dev` command generates SQL files and directly runs them against the database. In this case, the following migration files was created in the existing `prisma` directory:

```bash

$ tree prisma
prisma
├── dev.db
├── migrations
│   └── 20201207100915_init
│       └── migration.sql
└── schema.prisma
```

Expand to view the generated SQL statements

The following tables were created in your SQLite database:

```sql

-- CreateTable
CREATE TABLE "User" (
    "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
    "email" TEXT NOT NULL,
    "name" TEXT
);

-- CreateTable
CREATE TABLE "Post" (
    "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
    "title" TEXT NOT NULL,
    "content" TEXT,
    "published" BOOLEAN DEFAULT false,
    "authorId" INTEGER,

    FOREIGN KEY ("authorId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE
);

-- CreateIndex
CREATE UNIQUE INDEX "User.email_unique" ON "User"("email");
```

#### Install and generate Prisma Client[#](/recipes/prisma#install-and-generate-prisma-client)

Prisma Client is a type-safe database client that's *generated* from your Prisma model definition. Because of this approach, Prisma Client can expose [CRUD](https://www.prisma.io/docs/concepts/components/prisma-client/crud) operations that are *tailored* specifically to your models.

To install Prisma Client in your project, run the following command in your terminal:

```bash

$ npm install @prisma/client
```

Note that during installation, Prisma automatically invokes the `prisma generate` command for you. In the future, you need to run this command after *every* change to your Prisma models to update your generated Prisma Client.

> **Note** The `prisma generate` command reads your Prisma schema and updates the generated Prisma Client library inside `node_modules/@prisma/client`.

#### Use Prisma Client in your NestJS services[#](/recipes/prisma#use-prisma-client-in-your-nestjs-services)

You're now able to send database queries with Prisma Client. If you want to learn more about building queries with Prisma Client, check out the [API documentation](https://www.prisma.io/docs/reference/tools-and-interfaces/prisma-client/crud).

When setting up your NestJS application, you'll want to abstract away the Prisma Client API for database queries within a service. To get started, you can create a new `PrismaService` that takes care of instantiating `PrismaClient` and connecting to your database.

Inside the `src` directory, create a new file called `prisma.service.ts` and add the following code to it:

```typescript

import { Injectable, OnModuleInit, OnModuleDestroy } from '@nestjs/common';
import { PrismaClient } from '@prisma/client';

@Injectable()
export class PrismaService extends PrismaClient
  implements OnModuleInit, OnModuleDestroy {
  async onModuleInit() {
    await this.$connect();
  }

  async onModuleDestroy() {
    await this.$disconnect();
  }
}
```

Next, you can write services that you can use to make database calls for the `User` and `Post` models from your Prisma schema.

Still inside the `src` directory, create a new file called `user.service.ts` and add the following code to it:

```typescript

import { Injectable } from '@nestjs/common';
import { PrismaService } from './prisma.service';
import {
  User,
  Prisma
} from '@prisma/client';

@Injectable()
export class UserService {
  constructor(private prisma: PrismaService) {}

  async user(userWhereUniqueInput: Prisma.UserWhereUniqueInput): Promise<User | null> {
    return this.prisma.user.findUnique({
      where: userWhereUniqueInput,
    });
  }

  async users(params: {
    skip?: number;
    take?: number;
    cursor?: Prisma.UserWhereUniqueInput;
    where?: Prisma.UserWhereInput;
    orderBy?: Prisma.UserOrderByInput;
  }): Promise<User[]> {
    const { skip, take, cursor, where, orderBy } = params;
    return this.prisma.user.findMany({
      skip,
      take,
      cursor,
      where,
      orderBy,
    });
  }

  async createUser(data: Prisma.UserCreateInput): Promise<User> {
    return this.prisma.user.create({
      data,
    });
  }

  async updateUser(params: {
    where: Prisma.UserWhereUniqueInput;
    data: Prisma.UserUpdateInput;
  }): Promise<User> {
    const { where, data } = params;
    return this.prisma.user.update({
      data,
      where,
    });
  }

  async deleteUser(where: Prisma.UserWhereUniqueInput): Promise<User> {
    return this.prisma.user.delete({
      where,
    });
  }
}
```

Notice how you're using Prisma Client's generated types to ensure that the methods that are exposed by your service are properly typed. You therefore save the boilerplate of typing your models and creating additional interface or DTO files.

Now do the same for the `Post` model.

Still inside the `src` directory, create a new file called `post.service.ts` and add the following code to it:

```typescript

import { Injectable } from '@nestjs/common';
import { PrismaService } from './prisma.service';
import {
  Post,
  Prisma,
} from '@prisma/client';

@Injectable()
export class PostService {
  constructor(private prisma: PrismaService) {}

  async post(postWhereUniqueInput: Prisma.PostWhereUniqueInput): Promise<Post | null> {
    return this.prisma.post.findUnique({
      where: postWhereUniqueInput,
    });
  }

  async posts(params: {
    skip?: number;
    take?: number;
    cursor?: Prisma.PostWhereUniqueInput;
    where?: Prisma.PostWhereInput;
    orderBy?: Prisma.PostOrderByInput;
  }): Promise<Post[]> {
    const { skip, take, cursor, where, orderBy } = params;
    return this.prisma.post.findMany({
      skip,
      take,
      cursor,
      where,
      orderBy,
    });
  }

  async createPost(data: Prisma.PostCreateInput): Promise<Post> {
    return this.prisma.post.create({
      data,
    });
  }

  async updatePost(params: {
    where: Prisma.PostWhereUniqueInput;
    data: Prisma.PostUpdateInput;
  }): Promise<Post> {
    const { data, where } = params;
    return this.prisma.post.update({
      data,
      where,
    });
  }

  async deletePost(where: Prisma.PostWhereUniqueInput): Promise<Post> {
    return this.prisma.post.delete({
      where,
    });
  }
}
```

Your `UserService` and `PostService` currently wrap the CRUD queries that are available in Prisma Client. In a real world application, the service would also be the place to add business logic to your application. For example, you could have a method called `updatePassword` inside the `UserService` that would be responsible for updating the password of a user.

##### Implement your REST API routes in the main app controller

Finally, you'll use the services you created in the previous sections to implement the different routes of your app. For the purpose of this guide, you'll put all your routes into the already existing `AppController` class.

Replace the contents of the `app.controller.ts` file with the following code:

```typescript

import {
  Controller,
  Get,
  Param,
  Post,
  Body,
  Put,
  Delete,
} from '@nestjs/common';
import { UserService } from './user.service';
import { PostService } from './post.service';
import { User as UserModel, Post as PostModel } from '@prisma/client';

@Controller()
export class AppController {
  constructor(
    private readonly userService: UserService,
    private readonly postService: PostService,
  ) {}

  @Get('post/:id')
  async getPostById(@Param('id') id: string): Promise<PostModel> {
    return this.postService.post({ id: Number(id) });
  }

  @Get('feed')
  async getPublishedPosts(): Promise<PostModel[]> {
    return this.postService.posts({
      where: { published: true },
    });
  }

  @Get('filtered-posts/:searchString')
  async getFilteredPosts(
    @Param('searchString') searchString: string,
  ): Promise<PostModel[]> {
    return this.postService.posts({
      where: {
        OR: [
          {
            title: { contains: searchString },
          },
          {
            content: { contains: searchString },
          },
        ],
      },
    });
  }

  @Post('post')
  async createDraft(
    @Body() postData: { title: string; content?: string; authorEmail: string },
  ): Promise<PostModel> {
    const { title, content, authorEmail } = postData;
    return this.postService.createPost({
      title,
      content,
      author: {
        connect: { email: authorEmail },
      },
    });
  }

  @Post('user')
  async signupUser(
    @Body() userData: { name?: string; email: string },
  ): Promise<UserModel> {
    return this.userService.createUser(userData);
  }

  @Put('publish/:id')
  async publishPost(@Param('id') id: string): Promise<PostModel> {
    return this.postService.updatePost({
      where: { id: Number(id) },
      data: { published: true },
    });
  }

  @Delete('post/:id')
  async deletePost(@Param('id') id: string): Promise<PostModel> {
    return this.postService.deletePost({ id: Number(id) });
  }
}
```

    * `title: String` (required): The title of the post
    * `content: String` (optional): The content of the post
    * `authorEmail: String` (required): The email of the user that creates the post

* `/user`: Create a new user

  * Body:

    * `email: String` (required): The email address of the user
    * `name: String` (optional): The name of the user

###### `PUT`

* `/publish/:id`: Publish a post by its `id`

###### `DELETE`

* `/post/:id`: Delete a post by its `id`

#### Summary[#](/recipes/prisma#summary)

In this recipe, you learned how to use Prisma along with NestJS to implement a REST API. The controller that implements the routes of the API is calling a `PrismaService` which in turn uses Prisma Client to send queries to a database to fulfill the data needs of incoming requests.

If you want to learn more about using NestJS with Prisma, be sure to check out the following resources:

* [NestJS & Prisma](https://www.prisma.io/nestjs)
* [Ready-to-run example projects for REST & GraphQL](https://github.com/prisma/prisma-examples/)
* [Production-ready starter kit](https://github.com/fivethree-team/nestjs-prisma-starter#instructions)
* [Video: Accessing Databases using NestJS with Prisma (5min)](https://www.youtube.com/watch?v=UlVJ340UEuk\&ab_channel=Prisma) by [Marc Stammerjohann](https://github.com/marcjulian)

----
url: https://docs.nestjs.com/v9/discover/companies
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Who is using Nest?](https://docs.nestjs.com/v9/discover/companies#who-is-using-nest)
* [Companies](https://docs.nestjs.com/v9/discover/companies#companies)

### Who is using Nest?

We are proudly helping various companies building their products at scale. If you are using Nest and would you like to be listed here, see this [thread](https://github.com/nestjs/nest/issues/1006). We are willing to put your logo here!

#### Companies[#](/discover/companies#companies)

According to our knowledge, all the following companies have built awesome projects on top of our framework:

[](https://roche.com)[](https://adidas.com)[](https://capgemini.com)[](https://www.societegenerale.fr/)[](https://rewe-digital.com/)[](https://www.decathlon.com/)[](https://www.autodesk.com/)[](https://www.neo4j.com/)[](https://www.shipt.com/)[](https://github.com/Sanofi-IADC)[](https://valor-software.com/)[](https://sitepen.com)[](https://gojob.com/)[](https://neoteric.eu/)[](https://trellis.org/)[](https://scal.io)[](https://swingdev.io/)[](https://culturacolectiva.com)[](https://trilon.io)[](http://architectnow.net)[](https://www.iflix.com)[](https://genuinebee.com/)[](https://runplayersleague.com)[](http://www.yanrongyun.com)[](https://sclable.com)[](https://www.dozto.com)[](https://www.qingtui.cn/)[](https://crowdlinker.com/)[](https://nothing.ch/)[](https://swissdevjobs.ch/jobs/Dev-Ops/All)[](https://zeo.org/tr/)[](https://valueadd.pl/)[](https://bedu.org)[](https://shopback.com)[](https://www.facile.it)[](https://interfacewerk.de)[](https://www.ottonova.de)[](https://radity.com)[](https://globalctoforum.org/)[](https://rivvy.app)[](https://www.vuestorefront.io/)[](https://fuseautotech.com)[](https://amplication.com)[](https://hingehealth.com)

|                                     |
| ----------------------------------- |
| <https://gorrion.io/>               |
| <http://balticdatascience.com/>     |
| <https://prohabits.com/>            |
| <https://komed-health.com/>         |
| <https://kerberus.com.co/>          |
| <http://xtremis.com/>               |
| <https://notadd.com/>               |
| <http://jsdaddy.io/>                |
| <https://yumpingo.com/>             |
| <https://analytics-importer.cz/>    |
| <https://dayzim.com/>               |
| <https://wizkids.co.uk/>            |
| <https://pilvia.com/>               |
| <https://wi-q.com/>                 |
| <http://agrofel.com.br>             |
| <https://societegenerale.com/>      |
| <https://trashpanda.hulan.nl/>      |
| <https://bytedance.com/>            |
| <https://votercircle.com>           |
| <https://erento.com>                |
| <https://ideas.manticore-labs.com/> |
| <https://smartexlab.com/>           |
| <https://automama.ru/>              |
| <https://iflix.com/>                |
| <https://frontendwatch.com/>        |
| <https://mobilejazz.com/>           |
| <https://cgiandi.com/>              |
| <https://www.titlex.com.au/>        |
| <https://codengage.com/>            |
| <https://budacode.com/>             |
| <https://blueanchor.io/>            |
| <https://www.easymetrics.com/>      |
| <https://getapollo.io/>             |
| <https://big-bench.com/>            |
| <https://www.qingtui.cn/>           |
| <https://www.rosebayconsult.com/>   |
| <https://www.patrocinium.com/>      |
| <https://creatorsdaily.com>         |
| <https://autoscar.com.br>           |
| <https://www.mediktiv.com>          |
| <https://harmonize.health>          |
| <https://accerlery.be>              |
| <https://www.facile.it>             |
| <https://shopback.com>              |
| <https://www.ottonova.de>           |
| <https://www.radity.com>            |
| <https://globalctoforum.org>        |
| <https://halojasa.com>              |
| <https://hexito.com>                |
| <https://rivvy.app>                 |
| <https://padfever.com/>             |
| <https://datenlotse.org>            |
| <https://bemum.co>                  |
| <https://weoptimeye.ai>             |
| <https://nemovote.com>              |
| <https://selleo.com>                |
| <https://pchas.ir>                  |
| <https://tayeh.ir>                  |
| <https://forwardigital.co.uk>       |
| <https://rozetka.com.ua>            |
| <https://www.itrio.net>             |
| <https://alexishr.com>              |
| <https://dyrector.io>               |
| <https://stijlbreuk.nl>             |
| <https://polygon-software.ch>       |
| <https://bewith.io>                 |
| <https://swetrix.com>               |
| <https://swyftlogistics.com>        |
| <https://evershop.io>               |
| <https://e-design.ca>               |
| <https://growthmill.com>            |
| <https://tarken.com.br>             |
| <https://remato.com>                |
| <https://remberg.de/en>             |

and a lot more but we don't have enough time to update above list. Feel free to create a [pull request](https://github.com/nestjs/docs.nestjs.com/pulls) though!

----
url: https://docs.nestjs.com/v6/providers
----

* [Providers](https://docs.nestjs.com/v6/providers#providers)
* [Services](https://docs.nestjs.com/v6/providers#services)
* [Dependency injection](https://docs.nestjs.com/v6/providers#dependency-injection)
* [Scopes](https://docs.nestjs.com/v6/providers#scopes)
* [Custom providers](https://docs.nestjs.com/v6/providers#custom-providers)
* [Optional providers](https://docs.nestjs.com/v6/providers#optional-providers)
* [Property-based injection](https://docs.nestjs.com/v6/providers#property-based-injection)
* [Provider registration](https://docs.nestjs.com/v6/providers#provider-registration)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/components.md "Suggest Edits")

### Providers

Providers are a fundamental concept in Nest. Many of the basic Nest classes may be treated as a provider – services, repositories, factories, helpers, and so on. The main idea of a provider is that it can **inject** dependencies; this means objects can create various relationships with each other, and the function of "wiring up" instances of objects can largely be delegated to the Nest runtime system. A provider is simply a class annotated with an `@Injectable()` decorator.

In the previous chapter, we built a simple `CatsController`. Controllers should handle HTTP requests and delegate more complex tasks to **providers**. Providers are plain JavaScript classes with an `@Injectable()` decorator preceding their class declaration.

> **Hint** Since Nest enables the possibility to design and organize dependencies in a more OO-way, we strongly recommend following the [SOLID](https://en.wikipedia.org/wiki/SOLID) principles.

#### Services[#](/providers#services)

Let's start by creating a simple `CatsService`. This service will be responsible for data storage and retrieval, and is designed to be used by the `CatsController`, so it's a good candidate to be defined as a provider. Thus, we decorate the class with `@Injectable()`.

cats.service.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { Cat } from './interfaces/cat.interface';

@Injectable()
export class CatsService {
  private readonly cats: Cat[] = [];

  create(cat: Cat) {
    this.cats.push(cat);
  }

  findAll(): Cat[] {
    return this.cats;
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';

@Injectable()
export class CatsService {
  constructor() {
    this.cats = [];
  }

  create(cat) {
    this.cats.push(cat);
  }

  findAll() {
    return this.cats;
  }
}
```

> **Hint** To create a service using the CLI, simply execute the `$ nest g service cats` command.

Our `CatsService` is a basic class with one property and two methods. The only new feature is that it uses the `@Injectable()` decorator. The `@Injectable()` decorator attaches metadata, which tells Nest that this class is a Nest provider. By the way, this example also uses a `Cat` interface, which probably looks something like this:

```typescript

export interface Cat {
  name: string;
  age: number;
  breed: string;
}
```

Now that we have a service class to retrieve cats, let's use it inside the `CatsController`:

cats.controller.ts

JS TS

```typescript

import { Controller, Get, Post, Body } from '@nestjs/common';
import { CreateCatDto } from './dto/create-cat.dto';
import { CatsService } from './cats.service';
import { Cat } from './interfaces/cat.interface';

@Controller('cats')
export class CatsController {
  constructor(private readonly catsService: CatsService) {}

  @Post()
  async create(@Body() createCatDto: CreateCatDto) {
    this.catsService.create(createCatDto);
  }

  @Get()
  async findAll(): Promise<Cat[]> {
    return this.catsService.findAll();
  }
}
```

```typescript

import { Controller, Get, Post, Body, Bind, Dependencies } from '@nestjs/common';
import { CatsService } from './cats.service';

@Controller('cats')
@Dependencies(CatsService)
export class CatsController {
  constructor(catsService) {
    this.catsService = catsService;
  }

  @Post()
  @Bind(Body())
  async create(createCatDto) {
    this.catsService.create(createCatDto);
  }

  @Get()
  async findAll() {
    return this.catsService.findAll();
  }
}
```

The `CatsService` is **injected** through the class constructor. Notice the use of the `private readonly` syntax. This shorthand allows us to both declare and initialize the `catsService` member immediately in the same location.

#### Dependency injection[#](/providers#dependency-injection)

Nest is built around the strong design pattern commonly known as **Dependency injection**. We recommend reading a great article about this concept in the official [Angular](https://angular.io/guide/dependency-injection) documentation.

In Nest, thanks to TypeScript capabilities, it's extremely easy to manage dependencies because they are resolved just by type. In the example below, Nest will resolve the `catsService` by creating and returning an instance of `CatsService` (or, in the normal case of a singleton, returning the existing instance if it has already been requested elsewhere). This dependency is resolved and passed to your controller's constructor (or assigned to the indicated property):

```typescript

constructor(private readonly catsService: CatsService) {}
```

#### Scopes[#](/providers#scopes)

Providers normally have a lifetime ("scope") synchronized with the application lifecycle. When the application is bootstrapped, every dependency must be resolved, and therefore every provider has to be instantiated. Similarly, when the application shuts down, each provider will be destroyed. However, there are ways to make your provider lifetime **request-scoped** as well. You can read more about these techniques [here](/v6/fundamentals/injection-scopes).

## Learn the right way!

* 60+ chapters
* 4+ hours of videos
* Official certificate
* Deep-dive sessions

[Explore official courses](https://courses.nestjs.com "Courses | NestJS - A node.js framework built on top of TypeScript")

#### Custom providers[#](/providers#custom-providers)

Nest has a built-in inversion of control ("IoC") container that resolves relationships between providers. This feature underlies the dependency injection feature described above, but is in fact far more powerful than what we've described so far. The `@Injectable()` decorator is only the tip of the iceberg, and is not the only way to define providers. In fact, you can use plain values, classes, and either asynchronous or synchronous factories. More examples are provided [here](/v6/fundamentals/dependency-injection).

#### Optional providers[#](/providers#optional-providers)

Occasionally, you might have dependencies which do not necessarily have to be resolved. For instance, your class may depend on a **configuration object**, but if none is passed, the default values should be used. In such a case, the dependency becomes optional, because lack of the configuration provider wouldn't lead to errors.

To indicate a provider is optional, use the `@Optional()` decorator in the constructor's signature.

```typescript

import { Injectable, Optional, Inject } from '@nestjs/common';

@Injectable()
export class HttpService<T> {
  constructor(
    @Optional() @Inject('HTTP_OPTIONS') private readonly httpClient: T,
  ) {}
}
```

Note that in the example above we are using a custom provider, which is the reason we include the `HTTP_OPTIONS` custom **token**. Previous examples showed constructor-based injection indicating a dependency through a class in the constructor. Read more about custom providers and their associated tokens [here](/v6/fundamentals/custom-providers).

#### Property-based injection[#](/providers#property-based-injection)

The technique we've used so far is called constructor-based injection, as providers are injected via the constructor method. In some very specific cases, **property-based injection** might be useful. For instance, if your top-level class depends on either one or multiple providers, passing them all the way up by calling `super()` in sub-classes from the constructor can be very tedious. In order to avoid this, you can use the `@Inject()` decorator at the property level.

```typescript

import { Injectable, Inject } from '@nestjs/common';

@Injectable()
export class HttpService<T> {
  @Inject('HTTP_OPTIONS')
  private readonly httpClient: T;
}
```

> **Warning** If your class doesn't extend another provider, you should always prefer using **constructor-based** injection.

#### Provider registration[#](/providers#provider-registration)

Now that we have defined a provider (`CatsService`), and we have a consumer of that service (`CatsController`), we need to register the service with Nest so that it can perform the injection. We do this by editing our module file (`app.module.ts`) and adding the service to the `providers` array of the `@Module()` decorator.

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { CatsController } from './cats/cats.controller';
import { CatsService } from './cats/cats.service';

@Module({
  controllers: [CatsController],
  providers: [CatsService],
})
export class AppModule {}
```

### Support us


----
url: https://docs.nestjs.com/v4/techniques/sql
----

### SQL

To reduce a boilerplate necessary to start the adventure with the databases, Nest comes with the ready to use `@nestjs/typeorm` package. We have selected [TypeORM](https://github.com/typeorm/typeorm) because it is definitely the most mature Object Relational Mapper (ORM) available in the node.js world. Since it's written in TypeScript, it works pretty well with the Nest framework.

Firstly, we need to install all of the required dependencies:

```bash

$ npm install --save @nestjs/typeorm typeorm mysql
```

> **Notice** In this chapter we'll use a MySQL database, but **TypeORM** provides a support for a lot of different ones such as PostgreSQL, SQLite, and even MongoDB (NoSQL).

Once the installation process is completed, we can import the `TypeOrmModule` into the root `ApplicationModule`.

app.module.ts

JavaScript TypeScript

TypeScript

```typescript

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';

@Module({
  imports: [
    TypeOrmModule.forRoot({
      type: 'mysql',
      host: 'localhost',
      port: 3306,
      username: 'root',
      password: 'root',
      database: 'test',
      entities: [__dirname + '/../**/*.entity{.ts,.js}'],
      synchronize: true,
    }),
  ],
})
export class ApplicationModule {}
```

The `forRoot()` method accepts the same configuration object as `createConnection()` from the [TypeORM](https://github.com/typeorm/typeorm) package. Futhermore, instead of passing anything to the `forRoot()`, we can create an `ormconfig.json` file in the project root directory.

ormconfig.json

JSON

```json

{
  "type": "mysql",
  "host": "localhost",
  "port": 3306,
  "username": "root",
  "password": "root",
  "database": "test",
  "entities": ["src/**/**.entity{.ts,.js}"],
  "synchronize": true
}
```

Now we can simply leave the parenthesis empty:

app.module.ts

JavaScript TypeScript

TypeScript

```typescript

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';

@Module({
  imports: [TypeOrmModule.forRoot()],
})
export class ApplicationModule {}
```

Afterwards, the `Connection` and `EntityManager` will be available to inject across entire project (without importing any module elsewhere), for example in this way:

app.module.ts

JavaScript TypeScript

TypeScript

```typescript

import { Connection } from 'typeorm';

@Module({
  imports: [TypeOrmModule.forRoot(), PhotoModule],
})
export class ApplicationModule {
  constructor(private readonly connection: Connection) {}
}
```

TypeScript

```typescript

import { Connection } from 'typeorm';

@Dependencies(Connection)
@Module({
  imports: [TypeOrmModule.forRoot(), PhotoModule],
})
export class ApplicationModule {
  constructor(connection) {
    this.connection = connection;
  }
}
```

#### Repository pattern

The [TypeORM](https://github.com/typeorm/typeorm) supports the repository design pattern, so each entity has its own Repository. These repositories can be obtained from the database connection.

Firstly, we need at least one entity. We're gonna reuse the `Photo` entity from the offical documentation.

photo/photo.entity.ts

JavaScript TypeScript

TypeScript

```typescript

import { Entity, Column, PrimaryGeneratedColumn } from 'typeorm';

@Entity()
export class Photo {
  @PrimaryGeneratedColumn()
  id: number;

  @Column({ length: 500 })
  name: string;

  @Column('text')
  description: string;

  @Column()
  filename: string;

  @Column('int')
  views: number;

  @Column()
  isPublished: boolean;
}
```

The `Photo` entity belongs to the `photo` directory. This directory represents the `PhotoModule`. It's your decision where you gonna keep your model files. From my point of view, the best way's to hold them nearly their **domain**, in the appropriate module directory.

Let's have a look at the `PhotoModule`:

photo/photo.module.ts

JavaScript TypeScript

TypeScript

```typescript

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { PhotoService } from './photo.service';
import { PhotoController } from './photo.controller';
import { Photo } from './photo.entity';

@Module({
  imports: [TypeOrmModule.forFeature([Photo])],
  components: [PhotoService],
  controllers: [PhotoController],
})
export class PhotoModule {}
```

This module uses `forFeature()` method to define which repositories shall be registered in the current scope.

Now we can inject the `PhotoRepository` to the `PhotoService` using the `@InjectRepository()` decorator:

photo/photo.service.ts

JavaScript TypeScript

TypeScript

```typescript

import { Component, Inject } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Photo } from './photo.entity';

@Component()
export class PhotoService {
  constructor(
    @InjectRepository(Photo)
    private readonly photoRepository: Repository<Photo>,
  ) {}

  async findAll(): Promise<Photo[]> {
    return await this.photoRepository.find();
  }
}
```

TypeScript

```typescript

import { Component, Dependencies } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Photo } from './photo.entity';

@Component()
@Dependencies(InjectRepository(Photo))
export class PhotoService {
  constructor(photoRepository) {
    this.photoRepository = photoRepository;
  }

  async findAll() {
    return await this.photoRepository.find();
  }
}
```

That's all. The full source code's available [here](https://github.com/nestjs/nest/tree/master/examples/05-sql-typeorm).

> **Hint** Don't forget to import the `PhotoModule` into the root `ApplicationModule`.

#### Sponsors

[](https://valor-software.com/)

Nest is an MIT-licensed open source project. It can grow thanks to the support by these awesome people. If you'd like to join them, please read more [here](https://opencollective.com/nest). Thanks!

[](https://opencollective.com/nest/backer/0/website)[](https://opencollective.com/nest/backer/1/website)[](https://opencollective.com/nest/backer/2/website)[](https://opencollective.com/nest/backer/3/website)[](https://opencollective.com/nest/backer/4/website)[](https://opencollective.com/nest/backer/5/website)[](https://opencollective.com/nest/backer/6/website)[](https://opencollective.com/nest/backer/7/website)[](https://opencollective.com/nest/backer/8/website)[](https://opencollective.com/nest/backer/9/website)[](https://opencollective.com/nest/backer/10/website)[](https://opencollective.com/nest/backer/11/website)[](https://opencollective.com/nest/backer/12/website)[](https://opencollective.com/nest/backer/13/website)[](https://opencollective.com/nest/backer/14/website)[](https://opencollective.com/nest/backer/15/website)[](https://opencollective.com/nest/backer/16/website)[](https://opencollective.com/nest/backer/17/website)[](https://opencollective.com/nest/backer/18/website)[](https://opencollective.com/nest/backer/19/website)[](https://opencollective.com/nest/backer/20/website)[](https://opencollective.com/nest/backer/21/website)[](https://opencollective.com/nest/backer/22/website)[](https://opencollective.com/nest/backer/23/website)[](https://opencollective.com/nest/backer/24/website)[](https://opencollective.com/nest/backer/25/website)[](https://opencollective.com/nest/backer/26/website)[](https://opencollective.com/nest/backer/27/website)[](https://opencollective.com/nest/backer/28/website)[](https://opencollective.com/nest/backer/29/website)

[Become a sponsor](https://opencollective.com/nest)

----
url: https://docs.nestjs.com/v4/microservices/guards
----

### Guards

There's one difference between [regular guards](/v4/guards) and the microservices **guards**. The microservices guards takes the `data` passed from the client instead of expressjs request object as an argument of the `canActivate()` function. Also, when the guard returns `false`, it throws `RpcException` (not `HttpException`).

> **Hint** The `RpcException` class is available within the `@nestjs/microservices` package.

#### Sponsors

[](https://valor-software.com/)

Nest is an MIT-licensed open source project. It can grow thanks to the support by these awesome people. If you'd like to join them, please read more [here](https://opencollective.com/nest). Thanks!

[](https://opencollective.com/nest/backer/0/website)[](https://opencollective.com/nest/backer/1/website)[](https://opencollective.com/nest/backer/2/website)[](https://opencollective.com/nest/backer/3/website)[](https://opencollective.com/nest/backer/4/website)[](https://opencollective.com/nest/backer/5/website)[](https://opencollective.com/nest/backer/6/website)[](https://opencollective.com/nest/backer/7/website)[](https://opencollective.com/nest/backer/8/website)[](https://opencollective.com/nest/backer/9/website)[](https://opencollective.com/nest/backer/10/website)[](https://opencollective.com/nest/backer/11/website)[](https://opencollective.com/nest/backer/12/website)[](https://opencollective.com/nest/backer/13/website)[](https://opencollective.com/nest/backer/14/website)[](https://opencollective.com/nest/backer/15/website)[](https://opencollective.com/nest/backer/16/website)[](https://opencollective.com/nest/backer/17/website)[](https://opencollective.com/nest/backer/18/website)[](https://opencollective.com/nest/backer/19/website)[](https://opencollective.com/nest/backer/20/website)[](https://opencollective.com/nest/backer/21/website)[](https://opencollective.com/nest/backer/22/website)[](https://opencollective.com/nest/backer/23/website)[](https://opencollective.com/nest/backer/24/website)[](https://opencollective.com/nest/backer/25/website)[](https://opencollective.com/nest/backer/26/website)[](https://opencollective.com/nest/backer/27/website)[](https://opencollective.com/nest/backer/28/website)[](https://opencollective.com/nest/backer/29/website)

[Become a sponsor](https://opencollective.com/nest)

----
url: https://docs.nestjs.com/v11/first-steps
----

* [First steps](https://docs.nestjs.com/v11/first-steps#first-steps)
* [Language](https://docs.nestjs.com/v11/first-steps#language)
* [Prerequisites](https://docs.nestjs.com/v11/first-steps#prerequisites)
* [Setup](https://docs.nestjs.com/v11/first-steps#setup)
* [Platform](https://docs.nestjs.com/v11/first-steps#platform)
* [Running the application](https://docs.nestjs.com/v11/first-steps#running-the-application)
* [Linting and formatting](https://docs.nestjs.com/v11/first-steps#linting-and-formatting)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/first-steps.md "Suggest Edits")

### First steps

In this set of articles, you'll learn the **core fundamentals** of Nest. To get familiar with the essential building blocks of Nest applications, we'll build a basic CRUD application with features that cover a lot of ground at an introductory level.

#### Language[#](/first-steps#language)

We're in love with [TypeScript](https://www.typescriptlang.org/), but above all - we love [Node.js](https://nodejs.org/en/). That's why Nest is compatible with both TypeScript and pure JavaScript. Nest takes advantage of the latest language features, so to use it with vanilla JavaScript we need a [Babel](https://babeljs.io/) compiler.

We'll mostly use TypeScript in the examples we provide, but you can always **switch the code snippets** to vanilla JavaScript syntax (simply click to toggle the language button in the upper right hand corner of each snippet).

#### Prerequisites[#](/first-steps#prerequisites)

Please make sure that [Node.js](https://nodejs.org) (version >= 20) is installed on your operating system.

#### Setup[#](/first-steps#setup)

Setting up a new project is quite simple with the [Nest CLI](/v11/cli/overview). With [npm](https://www.npmjs.com/) installed, you can create a new Nest project with the following commands in your OS terminal:

```bash

$ npm i -g @nestjs/cli
$ nest new project-name
```

> **Hint** To create a new project with TypeScript's [stricter](https://www.typescriptlang.org/tsconfig#strict) feature set, pass the `--strict` flag to the `nest new` command.

| `app.controller.ts`      | A basic controller with a single route.                                                                             |
| ------------------------ | ------------------------------------------------------------------------------------------------------------------- |
| `app.controller.spec.ts` | The unit tests for the controller.                                                                                  |
| `app.module.ts`          | The root module of the application.                                                                                 |
| `app.service.ts`         | A basic service with a single method.                                                                               |
| `main.ts`                | The entry file of the application which uses the core function `NestFactory` to create a Nest application instance. |

The `main.ts` includes an async function, which will **bootstrap** our application:

main.ts

JS TS

```typescript

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  await app.listen(process.env.PORT ?? 3000);
}
bootstrap();
```

```typescript

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  await app.listen(process.env.PORT ?? 3000);
}
bootstrap();
```

To create a Nest application instance, we use the core `NestFactory` class. `NestFactory` exposes a few static methods that allow creating an application instance. The `create()` method returns an application object, which fulfills the `INestApplication` interface. This object provides a set of methods which are described in the coming chapters. In the `main.ts` example above, we simply start up our HTTP listener, which lets the application await inbound HTTP requests.

Note that a project scaffolded with the Nest CLI creates an initial project structure that encourages developers to follow the convention of keeping each module in its own dedicated directory.

> **Hint** By default, if any error happens while creating the application your app will exit with the code `1`. If you want to make it throw an error instead disable the option `abortOnError` (e.g., `NestFactory.create(AppModule, { abortOnError: false })`).

| `platform-express` | [Express](https://expressjs.com/) is a well-known minimalist web framework for node. It's a battle tested, production-ready library with lots of resources implemented by the community. The `@nestjs/platform-express` package is used by default. Many users are well served with Express, and need take no action to enable it. |
| ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `platform-fastify` | [Fastify](https://www.fastify.io/) is a high performance and low overhead framework highly focused on providing maximum efficiency and speed. Read how to use it [here](/v11/techniques/performance).                                                                                                                              |

Whichever platform is used, it exposes its own application interface. These are seen respectively as `NestExpressApplication` and `NestFastifyApplication`.

When you pass a type to the `NestFactory.create()` method, as in the example below, the `app` object will have methods available exclusively for that specific platform. Note, however, you don't **need** to specify a type **unless** you actually want to access the underlying platform API.

```typescript

const app = await NestFactory.create<NestExpressApplication>(AppModule);
```

#### Running the application[#](/first-steps#running-the-application)

Once the installation process is complete, you can run the following command at your OS command prompt to start the application listening for inbound HTTP requests:

```bash

$ npm run start
```

> **Hint** To speed up the development process (x20 times faster builds), you can use the [SWC builder](/v11/recipes/swc) by passing the `-b swc` flag to the `start` script, as follows `npm run start -- -b swc`.

This command starts the app with the HTTP server listening on the port defined in the `src/main.ts` file. Once the application is running, open your browser and navigate to `http://localhost:3000/`. You should see the `Hello World!` message.

To watch for changes in your files, you can run the following command to start the application:

```bash

$ npm run start:dev
```

This command will watch your files, automatically recompiling and reloading the server.

#### Linting and formatting[#](/first-steps#linting-and-formatting)

[CLI](/v11/cli/overview) provides best effort to scaffold a reliable development workflow at scale. Thus, a generated Nest project comes with both a code **linter** and **formatter** preinstalled (respectively [eslint](https://eslint.org/) and [prettier](https://prettier.io/)).

> **Hint** Not sure about the role of formatters vs linters? Learn the difference [here](https://prettier.io/docs/en/comparison.html).

To ensure maximum stability and extensibility, we use the base [`eslint`](https://www.npmjs.com/package/eslint) and [`prettier`](https://www.npmjs.com/package/prettier) cli packages. This setup allows neat IDE integration with official extensions by design.

For headless environments where an IDE is not relevant (Continuous Integration, Git hooks, etc.) a Nest project comes with ready-to-use `npm` scripts.

```bash

# Lint and autofix with eslint
$ npm run lint

# Format with prettier
$ npm run format
```

----
url: https://docs.nestjs.com/v9/microservices/rabbitmq
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [RabbitMQ](https://docs.nestjs.com/v9/microservices/rabbitmq#rabbitmq)
* [Installation](https://docs.nestjs.com/v9/microservices/rabbitmq#installation)
* [Overview](https://docs.nestjs.com/v9/microservices/rabbitmq#overview)
* [Options](https://docs.nestjs.com/v9/microservices/rabbitmq#options)
* [Client](https://docs.nestjs.com/v9/microservices/rabbitmq#client)
* [Context](https://docs.nestjs.com/v9/microservices/rabbitmq#context)
* [Message acknowledgement](https://docs.nestjs.com/v9/microservices/rabbitmq#message-acknowledgement)
* [Record builders](https://docs.nestjs.com/v9/microservices/rabbitmq#record-builders)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/microservices/rabbitmq.md "Suggest Edits")

### RabbitMQ

[RabbitMQ](https://www.rabbitmq.com/) is an open-source and lightweight message broker which supports multiple messaging protocols. It can be deployed in distributed and federated configurations to meet high-scale, high-availability requirements. In addition, it's the most widely deployed message broker, used worldwide at small startups and large enterprises.

#### Installation[#](/microservices/rabbitmq#installation)

To start building RabbitMQ-based microservices, first install the required packages:

```bash

$ npm i --save amqplib amqp-connection-manager
```

#### Overview[#](/microservices/rabbitmq#overview)

To use the RabbitMQ transporter, pass the following options object to the `createMicroservice()` method:

main.ts

JS TS

```typescript

const app = await NestFactory.createMicroservice<MicroserviceOptions>(AppModule, {
  transport: Transport.RMQ,
  options: {
    urls: ['amqp://localhost:5672'],
    queue: 'cats_queue',
    queueOptions: {
      durable: false
    },
  },
});
```

```typescript

const app = await NestFactory.createMicroservice(AppModule, {
  transport: Transport.RMQ,
  options: {
    urls: ['amqp://localhost:5672'],
    queue: 'cats_queue',
    queueOptions: {
      durable: false
    },
  },
});
```

> **Hint** The `Transport` enum is imported from the `@nestjs/microservices` package.

#### Options[#](/microservices/rabbitmq#options)

The `options` property is specific to the chosen transporter. The **RabbitMQ** transporter exposes the properties described below.

|                         |                                                                                                                          |
| ----------------------- | ------------------------------------------------------------------------------------------------------------------------ |
| `urls`                  | Connection urls                                                                                                          |
| `queue`                 | Queue name which your server will listen to                                                                              |
| `prefetchCount`         | Sets the prefetch count for the channel                                                                                  |
| `isGlobalPrefetchCount` | Enables per channel prefetching                                                                                          |
| `noAck`                 | If `false`, manual acknowledgment mode enabled                                                                           |
| `queueOptions`          | Additional queue options (read more [here](https://www.squaremobius.net/amqp.node/channel_api.html#channel_assertQueue)) |
| `socketOptions`         | Additional socket options (read more [here](https://www.squaremobius.net/amqp.node/channel_api.html#socket-options))     |
| `headers`               | Headers to be sent along with every message                                                                              |

#### Client[#](/microservices/rabbitmq#client)

Like other microservice transporters, you have [several options](https://docs.nestjs.com/microservices/basics#client) for creating a RabbitMQ `ClientProxy` instance.

One method for creating an instance is to use the `ClientsModule`. To create a client instance with the `ClientsModule`, import it and use the `register()` method to pass an options object with the same properties shown above in the `createMicroservice()` method, as well as a `name` property to be used as the injection token. Read more about `ClientsModule`[here](https://docs.nestjs.com/microservices/basics#client).

```typescript

@Module({
  imports: [
    ClientsModule.register([
      {
        name: 'MATH_SERVICE',
        transport: Transport.RMQ,
        options: {
          urls: ['amqp://localhost:5672'],
          queue: 'cats_queue',
          queueOptions: {
            durable: false
          },
        },
      },
    ]),
  ]
  ...
})
```

Other options to create a client (either `ClientProxyFactory` or `@Client()`) can be used as well. You can read about them [here](https://docs.nestjs.com/microservices/basics#client).

#### Context[#](/microservices/rabbitmq#context)

In more sophisticated scenarios, you may want to access more information about the incoming request. When using the RabbitMQ transporter, you can access the `RmqContext` object.

JS TS

```typescript

@MessagePattern('notifications')
getNotifications(@Payload() data: number[], @Ctx() context: RmqContext) {
  console.log(`Pattern: ${context.getPattern()}`);
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('notifications')
getNotifications(data, context) {
  console.log(`Pattern: ${context.getPattern()}`);
}
```

> **Hint**`@Payload()`, `@Ctx()` and `RmqContext` are imported from the `@nestjs/microservices` package.

To access the original RabbitMQ message (with the `properties`, `fields`, and `content`), use the `getMessage()` method of the `RmqContext` object, as follows:

JS TS

```typescript

@MessagePattern('notifications')
getNotifications(@Payload() data: number[], @Ctx() context: RmqContext) {
  console.log(context.getMessage());
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('notifications')
getNotifications(data, context) {
  console.log(context.getMessage());
}
```

To retrieve a reference to the RabbitMQ [channel](https://www.rabbitmq.com/channels.html), use the `getChannelRef` method of the `RmqContext` object, as follows:

JS TS

```typescript

@MessagePattern('notifications')
getNotifications(@Payload() data: number[], @Ctx() context: RmqContext) {
  console.log(context.getChannelRef());
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('notifications')
getNotifications(data, context) {
  console.log(context.getChannelRef());
}
```

#### Message acknowledgement[#](/microservices/rabbitmq#message-acknowledgement)

To make sure a message is never lost, RabbitMQ supports [message acknowledgements](https://www.rabbitmq.com/confirms.html). An acknowledgement is sent back by the consumer to tell RabbitMQ that a particular message has been received, processed and that RabbitMQ is free to delete it. If a consumer dies (its channel is closed, connection is closed, or TCP connection is lost) without sending an ack, RabbitMQ will understand that a message wasn't processed fully and will re-queue it.

To enable manual acknowledgment mode, set the `noAck` property to `false`:

```typescript

options: {
  urls: ['amqp://localhost:5672'],
  queue: 'cats_queue',
  noAck: false,
  queueOptions: {
    durable: false
  },
},
```

When manual consumer acknowledgements are turned on, we must send a proper acknowledgement from the worker to signal that we are done with a task.

JS TS

```typescript

@MessagePattern('notifications')
getNotifications(@Payload() data: number[], @Ctx() context: RmqContext) {
  const channel = context.getChannelRef();
  const originalMsg = context.getMessage();

  channel.ack(originalMsg);
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('notifications')
getNotifications(data, context) {
  const channel = context.getChannelRef();
  const originalMsg = context.getMessage();

  channel.ack(originalMsg);
}
```

#### Record builders[#](/microservices/rabbitmq#record-builders)

To configure message options, you can use the `RmqRecordBuilder` class (note: this is doable for event-based flows as well). For example, to set `headers` and `priority` properties, use the `setOptions` method, as follows:

```typescript

const message = ':cat:';
const record = new RmqRecordBuilder(message)
  .setOptions({
    headers: {
      ['x-version']: '1.0.0',
    },
    priority: 3,
  })
  .build();

this.client.send('replace-emoji', record).subscribe(...);
```

> **Hint**`RmqRecordBuilder` class is exported from the `@nestjs/microservices` package.

And you can read these values on the server-side as well, by accessing the `RmqContext`, as follows:

JS TS

```typescript

@MessagePattern('replace-emoji')
replaceEmoji(@Payload() data: string, @Ctx() context: RmqContext): string {
  const { properties: { headers } } = context.getMessage();
  return headers['x-version'] === '1.0.0' ? '🐱' : '🐈';
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('replace-emoji')
replaceEmoji(data, context) {
  const { properties: { headers } } = context.getMessage();
  return headers['x-version'] === '1.0.0' ? '🐱' : '🐈';
}
```

----
url: https://docs.nestjs.com/v9/openapi/decorators
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Decorators](https://docs.nestjs.com/v9/openapi/decorators#decorators)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/openapi/decorators.md "Suggest Edits")

### Decorators

All of the available OpenAPI decorators have an `Api` prefix to distinguish them from the core decorators. Below is a full list of the exported decorators along with a designation of the level at which the decorator may be applied.

| `@ApiBasicAuth()`         | Method / Controller |
| ------------------------- | ------------------- |
| `@ApiBearerAuth()`        | Method / Controller |
| `@ApiBody()`              | Method              |
| `@ApiConsumes()`          | Method / Controller |
| `@ApiCookieAuth()`        | Method / Controller |
| `@ApiExcludeController()` | Controller          |
| `@ApiExcludeEndpoint()`   | Method              |
| `@ApiExtension()`         | Method              |
| `@ApiExtraModels()`       | Method / Controller |
| `@ApiHeader()`            | Method / Controller |
| `@ApiHideProperty()`      | Model               |
| `@ApiOAuth2()`            | Method / Controller |
| `@ApiOperation()`         | Method              |
| `@ApiParam()`             | Method              |
| `@ApiProduces()`          | Method / Controller |
| `@ApiProperty()`          | Model               |
| `@ApiPropertyOptional()`  | Model               |
| `@ApiQuery()`             | Method              |
| `@ApiResponse()`          | Method / Controller |
| `@ApiSecurity()`          | Method / Controller |
| `@ApiTags()`              | Method / Controller |

----
url: https://docs.nestjs.com/v5/faq/lifecycle-events
----

### Lifecycle Events

There are two application lifecycle events, `OnModuleInit` and `OnModuleDestroy` hooks. It's a good practice to use them for all the initialization stuff and avoid putting anything directly in the constructor. The constructor should be used only to initialize the class members and for injecting the required dependencies.

JS TS

TypeScript

```typescript

import { Injectable, OnModuleInit, OnModuleDestroy } from '@nestjs/common';

@Injectable()
export class UsersService implements OnModuleInit, OnModuleDestroy {
  onModuleInit() {
    console.log(`Initialization...`);
  }
  
  onModuleDestroy() {
    console.log(`Cleanup...`);
  }
}
```

TypeScript

```typescript

import { Injectable } from '@nestjs/common';

@Injectable()
export class UsersService {
  onModuleInit() {
    console.log(`Initialization...`);
  }

  onModuleDestroy() {
    console.log(`Cleanup...`);
  }
}
```

In order to defer initialization of the application, you can either use `await` keyword or return a `Promise`.

JS TS

TypeScript

```typescript

async onModuleInit(): Promise<any> {
  await this.fetch();
}
```

TypeScript

```typescript

async onModuleInit() {
  await this.fetch();
}
```

* Lifecycle Events

----
url: https://docs.nestjs.com/v4/components
----

### Components

Almost everything is a component – Service, Repository, Factory, Helper \[...] and they can be **injected** into controllers or into other components through `constructor`.

In the previous chapter, we have built a simple `CatsController`.

The controllers should only handle HTTP requests and delegate more complex tasks to the **components**. The components are plain TypeScript classes with a `@Component()` decorator.

> **Hint** Since Nest enables the possibility to design and organize the dependencies in a more OO-way, we strongly recommend following the **SOLID** principles.

Let's create a `CatsService` component:

cats.service.ts

JavaScript TypeScript

TypeScript

```typescript

import { Component } from '@nestjs/common';
import { Cat } from './interfaces/cat.interface';

@Component()
export class CatsService {
  private readonly cats: Cat[] = [];

  create(cat: Cat) {
    this.cats.push(cat);
  }

  findAll(): Cat[] {
    return this.cats;
  }
}
```

TypeScript

```typescript

import { Component } from '@nestjs/common';

@Component()
export class CatsService {
  constructor() {
    this.cats = [];
  }

  create(cat) {
    this.cats.push(cat);
  }

  findAll() {
    return this.cats;
  }
}
```

There's nothing special about components. Here's a `CatsService`, a basic class with one property and two methods. The only difference is that it has the `@Component()` decorator. The `@Component()` attaches the metadata, thereby Nest knows that this class is a Nest component.

> **Notice** There's a `Cat` interface here. I didn't mention it because the schema is exactly same as in the `CreateCatDto` class which we have created in the previous chapter.

Since we have the service class already done, let's use it inside the `CatsController`:

cats.controller.ts

JavaScript TypeScript

TypeScript

```typescript

import { Controller, Get, Post, Body } from '@nestjs/common';
import { CreateCatDto } from './dto/create-cat.dto';
import { CatsService } from './cats.service';
import { Cat } from './interfaces/cat.interface';

@Controller('cats')
export class CatsController {
  constructor(private readonly catsService: CatsService) {}

  @Post()
  async create(@Body() createCatDto: CreateCatDto) {
    this.catsService.create(createCatDto);
  }

  @Get()
  async findAll(): Promise<Cat[]> {
    return this.catsService.findAll();
  }
}
```

TypeScript

```typescript

import { Controller, Get, Post, Body, Bind, Dependencies } from '@nestjs/common';
import { CatsService } from './cats.service';

@Controller('cats')
@Dependencies(CatsService)
export class CatsController {
  constructor(catsService) {
    this.catsService = catsService;
  }

  @Post()
  @Bind(Body())
  async create(createCatDto) {
    this.catsService.create(createCatDto);
  }

  @Get()
  async findAll() {
    return this.catsService.findAll();
  }
}
```

The `CatsService` is injected through the class constructor. Don't be afraid of the `private readonly` shortened syntax. It means that we've created and initialized the `catsService` member in the same location.

#### Dependency Injection

Nest is built around the strong design pattern commonly known as **Dependency Injection**. There's a great article about this concept in the [official Angular documentation](https://angular.io/guide/dependency-injection).

> **Hint** Learn more about the **Dependency Injection** in Nest [here](http://docs.nestjs.com/fundamentals/dependency-injection).

It's extremely easy to manage dependencies with **TypeScript** because Nest will resolve your dependencies just by **injecting** them in your controller's constructor:

TypeScript

```typescript

constructor(private readonly catsService: CatsService) {}
```

#### Last step

The last thing is to tell the module that something called `CatsService` truly exists. We do this by editing our module file - `app.module.ts`, and put the service into the `components` array of the `@Module()` decorator.

app.module.ts

JavaScript TypeScript

TypeScript

```typescript

import { Module } from '@nestjs/common';
import { CatsController } from './cats/cats.controller';
import { CatsService } from './cats/cats.service';

@Module({
    controllers: [CatsController],
    components: [CatsService],
})
export class ApplicationModule {}
```

Now Nest will be able to resolve the dependencies of the `CatsController` class. This is how our directory structure looks right now:

#### Sponsors

[](https://valor-software.com/)

Nest is an MIT-licensed open source project. It can grow thanks to the support by these awesome people. If you'd like to join them, please read more [here](https://opencollective.com/nest). Thanks!

[](https://opencollective.com/nest/backer/0/website)[](https://opencollective.com/nest/backer/1/website)[](https://opencollective.com/nest/backer/2/website)[](https://opencollective.com/nest/backer/3/website)[](https://opencollective.com/nest/backer/4/website)[](https://opencollective.com/nest/backer/5/website)[](https://opencollective.com/nest/backer/6/website)[](https://opencollective.com/nest/backer/7/website)[](https://opencollective.com/nest/backer/8/website)[](https://opencollective.com/nest/backer/9/website)[](https://opencollective.com/nest/backer/10/website)[](https://opencollective.com/nest/backer/11/website)[](https://opencollective.com/nest/backer/12/website)[](https://opencollective.com/nest/backer/13/website)[](https://opencollective.com/nest/backer/14/website)[](https://opencollective.com/nest/backer/15/website)[](https://opencollective.com/nest/backer/16/website)[](https://opencollective.com/nest/backer/17/website)[](https://opencollective.com/nest/backer/18/website)[](https://opencollective.com/nest/backer/19/website)[](https://opencollective.com/nest/backer/20/website)[](https://opencollective.com/nest/backer/21/website)[](https://opencollective.com/nest/backer/22/website)[](https://opencollective.com/nest/backer/23/website)[](https://opencollective.com/nest/backer/24/website)[](https://opencollective.com/nest/backer/25/website)[](https://opencollective.com/nest/backer/26/website)[](https://opencollective.com/nest/backer/27/website)[](https://opencollective.com/nest/backer/28/website)[](https://opencollective.com/nest/backer/29/website)

[Become a sponsor](https://opencollective.com/nest)

----
url: https://docs.nestjs.com/standalone-applications
----

[Skip to content](#content)

On this page

* [Standalone applications](https://docs.nestjs.com/standalone-applications#standalone-applications)
* [Getting started](https://docs.nestjs.com/standalone-applications#getting-started)
* [Retrieving providers from static modules](https://docs.nestjs.com/standalone-applications#retrieving-providers-from-static-modules)
* [Retrieving providers from dynamic modules](https://docs.nestjs.com/standalone-applications#retrieving-providers-from-dynamic-modules)
* [Terminating phase](https://docs.nestjs.com/standalone-applications#terminating-phase)
* [Example](https://docs.nestjs.com/standalone-applications#example)

### Standalone applications

There are several ways to mount a Nest application. You can create a web app, a microservice, or a bare Nest **standalone application** (without any network listeners). A standalone application is a wrapper around the Nest **IoC container**, which holds all instantiated classes. Through the standalone application object, you can obtain a reference to any existing instance from any imported module. This lets you take advantage of the Nest framework anywhere, including scripted **CRON** jobs. You can even build a **CLI** on top of it.

#### Getting started[#](/standalone-applications#getting-started)

To create a Nest standalone application, use the following construction:

JS TS

```typescript

async function bootstrap() {
  const app = await NestFactory.createApplicationContext(AppModule);
  // your application logic here ...
}
await bootstrap();
```

#### Retrieving providers from static modules[#](/standalone-applications#retrieving-providers-from-static-modules)

The standalone application object lets you obtain a reference to any instance registered within the Nest application. Imagine that a `TasksService` provider lives in a `TasksModule`, which is imported by `AppModule`. The class provides a set of methods that you want to call from within a CRON job.

JS TS

```typescript

const tasksService = app.get(TasksService);
```

To access the `TasksService` instance, use the `get()` method. It acts like a **query** that searches for an instance in each registered module, and accepts any provider's token. For strict context checking, pass an options object with the `strict: true` property. With this option in effect, you have to navigate to a specific module to obtain an instance from that selected context.

JS TS

```typescript

const tasksService = app.select(TasksModule).get(TasksService, { strict: true });
```

The following table summarizes the methods available for retrieving instance references from the standalone application object.

|            |                                                                                                                                                 |
| ---------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| `get()`    | Retrieves an instance of a controller or provider (including guards, filters, and so on) available in the application context.                  |
| `select()` | Navigates through the module graph to pull out a specific instance of the selected module (used together with strict mode, as described above). |

> **Hint** In non-strict mode, the root module is selected by default. To select any other module, navigate the module graph manually, step by step.

A standalone application does not have any network listeners, so Nest features tied to request handling (e.g., middleware, interceptors, pipes, and guards) are not available in this context.

For example, even if you register a global interceptor in your application and then retrieve a controller instance with the `app.get()` method, the interceptor is not executed when you call the controller's methods.

#### Retrieving providers from dynamic modules[#](/standalone-applications#retrieving-providers-from-dynamic-modules)

When working with [dynamic modules](/fundamentals/dynamic-modules), pass `app.select()` the same object that represents the registered dynamic module in the application. For example:

JS TS

```typescript

export const dynamicConfigModule = ConfigModule.register({ folder: './config' });

@Module({
  imports: [dynamicConfigModule],
})
export class AppModule {}
```

You can then select that module later on:

JS TS

```typescript

const configService = app.select(dynamicConfigModule).get(ConfigService, { strict: true });
```

#### Terminating phase[#](/standalone-applications#terminating-phase)

If you want the Node.js process to exit after the script finishes (e.g., for a script running CRON jobs), call the `app.close()` method at the end of your `bootstrap()` function:

JS TS

```typescript

async function bootstrap() {
  const app = await NestFactory.createApplicationContext(AppModule);
  // application logic...
  await app.close();
}
await bootstrap();
```

As described in the [lifecycle events](/fundamentals/lifecycle-events) chapter, calling `app.close()` triggers the shutdown lifecycle hooks.

#### Example[#](/standalone-applications#example)

A working example is available in the [standalone application sample](https://github.com/nestjs/nest/tree/master/sample/18-context) on GitHub.

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/application-context.md)

----
url: https://docs.nestjs.com/v8/faq/request-lifecycle
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Request lifecycle](https://docs.nestjs.com/v8/faq/request-lifecycle#request-lifecycle)
* [Middleware](https://docs.nestjs.com/v8/faq/request-lifecycle#middleware)
* [Guards](https://docs.nestjs.com/v8/faq/request-lifecycle#guards)
* [Interceptors](https://docs.nestjs.com/v8/faq/request-lifecycle#interceptors)
* [Pipes](https://docs.nestjs.com/v8/faq/request-lifecycle#pipes)
* [Filters](https://docs.nestjs.com/v8/faq/request-lifecycle#filters)
* [Summary](https://docs.nestjs.com/v8/faq/request-lifecycle#summary)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/faq/request-lifecycle.md "Suggest Edits")

### Request lifecycle

Nest applications handle requests and produce responses in a sequence we refer to as the **request lifecycle**. With the use of middleware, pipes, guards, and interceptors, it can be challenging to track down where a particular piece of code executes during the request lifecycle, especially as global, controller level, and route level components come into play. In general, a request flows through middleware to guards, then to interceptors, then to pipes and finally back to interceptors on the return path (as the response is generated).

#### Middleware[#](/faq/request-lifecycle#middleware)

Middleware is executed in a particular sequence. First, Nest runs globally bound middleware (such as middleware bound with `app.use`) and then it runs [module bound middleware](/v8/middleware), which are determined on paths. Middleware are run sequentially in the order they are bound, similar to the way middleware in Express works. In the case of middleware bound across different modules, the middleware bound to the root module will run first, and then middleware will run in the order that the modules are added to the imports array.

#### Guards[#](/faq/request-lifecycle#guards)

Guard execution starts with global guards, then proceeds to controller guards, and finally to route guards. As with middleware, guards run in the order in which they are bound. For example:

```typescript

@UseGuards(Guard1, Guard2)
@Controller('cats')
export class CatsController {
  constructor(private catsService: CatsService) {}

  @UseGuards(Guard3)
  @Get()
  getCats(): Cats[] {
    return this.catsService.getCats();
  }
}
```

`Guard1` will execute before `Guard2` and both will execute before `Guard3`.

> **Hint** When speaking about globally bound vs controller or locally bound, the difference is where the guard (or other component is bound). If you are using `app.useGlobalGuard()` or providing the component via a module, it is globally bound. Otherwise, it is bound to a controller if the decorator precedes a controller class, or to a route if the decorator proceeds a route declaration.

#### Interceptors[#](/faq/request-lifecycle#interceptors)

Interceptors, for the most part, follow the same pattern as guards, with one catch: as interceptors return [RxJS Observables](https://github.com/ReactiveX/rxjs), the observables will be resolved in a first in last out manner. So inbound requests will go through the standard global, controller, route level resolution, but the response side of the request (i.e., after returning from the controller method handler) will be resolved from route to controller to global. Also, any errors thrown by pipes, controllers, or services can be read in the `catchError` operator of an interceptor.

#### Pipes[#](/faq/request-lifecycle#pipes)

Pipes follow the standard global to controller to route bound sequence, with the same first in first out in regards to the `@usePipes()` parameters. However, at a route parameter level, if you have multiple pipes running, they will run in the order of the last parameter with a pipe to the first. This also applies to the route level and controller level pipes. For example, if we have the following controller:

```typescript

@UsePipes(GeneralValidationPipe)
@Controller('cats')
export class CatsController {
  constructor(private catsService: CatsService) {}

  @UsePipes(RouteSpecificPipe)
  @Patch(':id')
  updateCat(
    @Body() body: UpdateCatDTO,
    @Param() params: UpdateCatParams,
    @Query() query: UpdateCatQuery,
  ) {
    return this.catsService.updateCat(body, params, query);
  }
}
```

then the `GeneralValidationPipe` will run for the `query`, then the `params`, and then the `body` objects before moving on to the `RouteSpecificPipe`, which follows the same order. If any parameter-specific pipes were in place, they would run (again, from the last to first parameter) after the controller and route level pipes.

#### Filters[#](/faq/request-lifecycle#filters)

Filters are the only component that do not resolve global first. Instead, filters resolve from the lowest level possible, meaning execution starts with any route bound filters and proceeding next to controller level, and finally to global filters. Note that exceptions cannot be passed from filter to filter; if a route level filter catches the exception, a controller or global level filter cannot catch the same exception. The only way to achieve an effect like this is to use inheritance between the filters.

> **Hint** Filters are only executed if any uncaught exception occurs during the request process. Caught exceptions, such as those caught with a `try/catch` will not trigger Exception Filters to fire. As soon as an uncaught exception is encountered, the rest of the lifecycle is ignored and the request skips straight to the filter.

----
url: https://docs.nestjs.com/v6/guards
----

* [Guards](https://docs.nestjs.com/v6/guards#guards)
* [Authorization guard](https://docs.nestjs.com/v6/guards#authorization-guard)
* [Execution context](https://docs.nestjs.com/v6/guards#execution-context)
* [Role-based authentication](https://docs.nestjs.com/v6/guards#role-based-authentication)
* [Binding guards](https://docs.nestjs.com/v6/guards#binding-guards)
* [Setting roles per handler](https://docs.nestjs.com/v6/guards#setting-roles-per-handler)
* [Putting it all together](https://docs.nestjs.com/v6/guards#putting-it-all-together)

[](https://srv.carbonads.net/ads/click/x/GTND4277CVSD5KJUCAYLYKQUF67D42JMCABIVZ3JCAAI6K3MFTBDT27KC6YD653YC6ADVKJECKSIC5QUCV7DVKQJHEYI55QLCAYD653ECTNCYBZ52K)[Check out the latest remote job listings from Authentic Jobs. ](https://srv.carbonads.net/ads/click/x/GTND4277CVSD5KJUCAYLYKQUF67D42JMCABIVZ3JCAAI6K3MFTBDT27KC6YD653YC6ADVKJECKSIC5QUCV7DVKQJHEYI55QLCAYD653ECTNCYBZ52K)[ads via Carbon](http://carbonads.net/?utm_source=nestjscom\&utm_medium=ad_via_link\&utm_campaign=in_unit\&utm_term=carbon)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/guards.md "Suggest Edits")

### Guards

A guard is a class annotated with the `@Injectable()` decorator. Guards should implement the `CanActivate` interface.

Guards have a **single responsibility**. They determine whether a given request will be handled by the route handler or not, depending on certain conditions (like permissions, roles, ACLs, etc.) present at run-time. This is often referred to as **authorization**. Authorization (and its cousin, **authentication**, with which it usually collaborates) has typically been handled by [middleware](/v6/middleware) in traditional Express applications. Middleware is a fine choice for authentication, since things like token validation and attaching properties to the `request` object are not strongly connected with a particular route context (and its metadata).

But middleware, by its nature, is dumb. It doesn't know which handler will be executed after calling the `next()` function. On the other hand, **Guards** have access to the `ExecutionContext` instance, and thus know exactly what's going to be executed next. They're designed, much like exception filters, pipes, and interceptors, to let you interpose processing logic at exactly the right point in the request/response cycle, and to do so declaratively. This helps keep your code DRY and declarative.

> **Hint** Guards are executed **after** each middleware, but **before** any interceptor or pipe.

#### Authorization guard[#](/guards#authorization-guard)

As mentioned, **authorization** is a great use case for Guards because specific routes should be available only when the caller (usually a specific authenticated user) has sufficient permissions. The `AuthGuard` that we'll build now assumes an authenticated user (and that, therefore, a token is attached to the request headers). It will extract and validate the token, and use the extracted information to determine whether the request can proceed or not.

auth.guard.ts

JS TS

```typescript

import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
import { Observable } from 'rxjs';

@Injectable()
export class AuthGuard implements CanActivate {
  canActivate(
    context: ExecutionContext,
  ): boolean | Promise<boolean> | Observable<boolean> {
    const request = context.switchToHttp().getRequest();
    return validateRequest(request);
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';

@Injectable()
export class AuthGuard {
  async canActivate(context) {
    const request = context.switchToHttp().getRequest();
    return validateRequest(request);
  }
}
```

By extending `ArgumentsHost`, `ExecutionContext` also adds several new helper methods that provide additional details about the current execution process. These details can be helpful in building more generic guards that can work across a broad set of controllers, methods, and execution contexts. Learn more about `ExecutionContext`[here](/v6/fundamentals/execution-context).

#### Role-based authentication[#](/guards#role-based-authentication)

Let's build a more functional guard that permits access only to users with a specific role. We'll start with a basic guard template, and build on it in the coming sections. For now, it allows all requests to proceed:

roles.guard.ts

JS TS

```typescript

import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
import { Observable } from 'rxjs';

@Injectable()
export class RolesGuard implements CanActivate {
  canActivate(
    context: ExecutionContext,
  ): boolean | Promise<boolean> | Observable<boolean> {
    return true;
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';

@Injectable()
export class RolesGuard {
  canActivate(context) {
    return true;
  }
}
```

#### Binding guards[#](/guards#binding-guards)

Like pipes and exception filters, guards can be **controller-scoped**, method-scoped, or global-scoped. Below, we set up a controller-scoped guard using the `@UseGuards()` decorator. This decorator may take a single argument, or a comma-separated list of arguments. This lets you easily apply the appropriate set of guards with one declaration.

JS TS

```typescript

@Controller('cats')
@UseGuards(RolesGuard)
export class CatsController {}
```

> **Hint** The `@UseGuards()` decorator is imported from the `@nestjs/common` package.

Above, we passed the `RolesGuard` type (instead of an instance), leaving responsibility for instantiation to the framework and enabling dependency injection. As with pipes and exception filters, we can also pass an in-place instance:

JS TS

```typescript

@Controller('cats')
@UseGuards(new RolesGuard())
export class CatsController {}
```

The construction above attaches the guard to every handler declared by this controller. If we wish the guard to apply only to a single method, we apply the `@UseGuards()` decorator at the **method level**.

In order to set up a global guard, use the `useGlobalGuards()` method of the Nest application instance:

JS TS

```typescript

const app = await NestFactory.create(AppModule);
app.useGlobalGuards(new RolesGuard());
```

> **Notice** In the case of hybrid apps the `useGlobalGuards()` method doesn't set up guards for gateways and micro services. For "standard" (non-hybrid) microservice apps, `useGlobalGuards()` does mount the guards globally.

Global guards are used across the whole application, for every controller and every route handler. In terms of dependency injection, global guards registered from outside of any module (with `useGlobalGuards()` as in the example above) cannot inject dependencies since this is done outside the context of any module. In order to solve this issue, you can set up a guard directly from any module using the following construction:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { APP_GUARD } from '@nestjs/core';

@Module({
  providers: [
    {
      provide: APP_GUARD,
      useClass: RolesGuard,
    },
  ],
})
export class AppModule {}
```

> **Hint** When using this approach to perform dependency injection for the guard, note that regardless of the module where this construction is employed, the guard is, in fact, global. Where should this be done? Choose the module where the guard (`RolesGuard` in the example above) is defined. Also, `useClass` is not the only way of dealing with custom provider registration. Learn more [here](/v6/fundamentals/custom-providers).

#### Setting roles per handler[#](/guards#setting-roles-per-handler)

Our `RolesGuard` is working, but it's not very smart yet. We're not yet taking advantage of the most important guard feature - the [execution context](/v6/fundamentals/execution-context). It doesn't yet know about roles, or which roles are allowed for each handler. The `CatsController`, for example, could have different permission schemes for different routes. Some might be available only for an admin user, and others could be open for everyone. How can we match roles to routes in a flexible and reusable way?

This is where **custom metadata** comes into play (learn more [here](https://docs.nestjs.com/fundamentals/execution-context#reflection-and-metadata)). Nest provides the ability to attach custom **metadata** to route handlers through the `@SetMetadata()` decorator. This metadata supplies our missing `role` data, which a smart guard needs to make decisions. Let's take a look at using `@SetMetadata()`:

cats.controller.ts

JS TS

```typescript

@Post()
@SetMetadata('roles', ['admin'])
async create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

```typescript

@Post()
@SetMetadata('roles', ['admin'])
@Bind(Body())
async create(createCatDto) {
  this.catsService.create(createCatDto);
}
```

> **Hint** The `@SetMetadata()` decorator is imported from the `@nestjs/common` package.

With the construction above, we attached the `roles` metadata (`roles` is a key, while `['admin']` is a particular value) to the `create()` method. While this works, it's not good practice to use `@SetMetadata()` directly in your routes. Instead, create your own decorators, as shown below:

roles.decorator.ts

JS TS

```typescript

import { SetMetadata } from '@nestjs/common';

export const Roles = (...roles: string[]) => SetMetadata('roles', roles);
```

```typescript

import { SetMetadata } from '@nestjs/common';

export const Roles = (...roles) => SetMetadata('roles', roles);
```

This approach is much cleaner and more readable, and is strongly typed. Now that we have a custom `@Roles()` decorator, we can use it to decorate the `create()` method.

cats.controller.ts

JS TS

```typescript

@Post()
@Roles('admin')
async create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

```typescript

@Post()
@Roles('admin')
@Bind(Body())
async create(createCatDto) {
  this.catsService.create(createCatDto);
}
```

#### Putting it all together[#](/guards#putting-it-all-together)

Let's now go back and tie this together with our `RolesGuard`. Currently, it simply returns `true` in all cases, allowing every request to proceed. We want to make the return value conditional based on the comparing the **roles assigned to the current user** to the actual roles required by the current route being processed. In order to access the route's role(s) (custom metadata), we'll use the `Reflector` helper class, which is provided out of the box by the framework and exposed from the `@nestjs/core` package.

roles.guard.ts

JS TS

```typescript

import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
import { Reflector } from '@nestjs/core';

@Injectable()
export class RolesGuard implements CanActivate {
  constructor(private readonly reflector: Reflector) {}

  canActivate(context: ExecutionContext): boolean {
    const roles = this.reflector.get<string[]>('roles', context.getHandler());
    if (!roles) {
      return true;
    }
    const request = context.switchToHttp().getRequest();
    const user = request.user;
    return matchRoles(roles, user.roles);
  }
}
```

```typescript

import { Injectable, Dependencies } from '@nestjs/common';
import { Reflector } from '@nestjs/core';

@Injectable()
@Dependencies(Reflector)
export class RolesGuard {
  constructor(reflector) {
    this.reflector = reflector;
  }

  canActivate(context) {
    const roles = this.reflector.get('roles', context.getHandler());
    if (!roles) {
      return true;
    }
    const request = context.switchToHttp().getRequest();
    const user = request.user;
    return matchRoles(roles, user.roles);
  }
}
```

> **Hint** In the node.js world, it's common practice to attach the authorized user to the `request` object. Thus, in our sample code above, we are assuming that `request.user` contains the user instance and allowed roles. In your app, you will probably make that association in your custom **authentication guard** (or middleware).

> **Warning** The logic inside the `matchRoles()` function can be as simple or sophisticated as needed. The main point of this example is to show how guards fit into the request/response cycle.

Refer to the [Reflection and metadata](https://docs.nestjs.com/fundamentals/execution-context#reflection-and-metadata) section of the **Execution context** chapter for more details on utilizing `Reflector` in a context-sensitive way.

When a user with insufficient privileges requests an endpoint, Nest automatically returns the following response:

```typescript

{
  "statusCode": 403,
  "message": "Forbidden resource"
}
```

Note that behind the scenes, when a guard returns `false`, the framework throws a `ForbiddenException`. If you want to return a different error response, you should throw your own specific exception. For example:

```typescript

throw new UnauthorizedException();
```

Any exception thrown by a guard will be handled by the [exceptions layer](/v6/exception-filters) (global exceptions filter and any exceptions filters that are applied to the current context).

----
url: https://docs.nestjs.com/v11/security/encryption-and-hashing
----

* [Encryption and Hashing](https://docs.nestjs.com/v11/security/encryption-and-hashing#encryption-and-hashing)
* [Encryption](https://docs.nestjs.com/v11/security/encryption-and-hashing#encryption)
* [Hashing](https://docs.nestjs.com/v11/security/encryption-and-hashing#hashing)

```typescript

import { createCipheriv, randomBytes, scrypt } from 'node:crypto';
import { promisify } from 'node:util';

const iv = randomBytes(16);
const password = 'Password used to generate key';

// The key length is dependent on the algorithm.
// In this case for aes256, it is 32 bytes.
const key = (await promisify(scrypt)(password, 'salt', 32)) as Buffer;
const cipher = createCipheriv('aes-256-ctr', key, iv);

const textToEncrypt = 'Nest';
const encryptedText = Buffer.concat([
  cipher.update(textToEncrypt),
  cipher.final(),
]);
```

Now to decrypt `encryptedText` value:

```typescript

import { createDecipheriv } from 'node:crypto';

const decipher = createDecipheriv('aes-256-ctr', key, iv);
const decryptedText = Buffer.concat([
  decipher.update(encryptedText),
  decipher.final(),
]);
```

#### Hashing[#](/security/encryption-and-hashing#hashing)

For hashing, we recommend using either the [bcrypt](https://www.npmjs.com/package/bcrypt) or [argon2](https://www.npmjs.com/package/argon2) packages. Nest itself does not provide any additional wrappers on top of these modules to avoid introducing unnecessary abstractions (making the learning curve short).

As an example, let's use `bcrypt` to hash a random password.

First install required packages:

```shell

$ npm i bcrypt
$ npm i -D @types/bcrypt
```

Once the installation is complete, you can use the `hash` function, as follows:

```typescript

import * as bcrypt from 'bcrypt';

const saltOrRounds = 10;
const password = 'random_password';
const hash = await bcrypt.hash(password, saltOrRounds);
```

To generate a salt, use the `genSalt` function:

```typescript

const salt = await bcrypt.genSalt();
```

To compare/check a password, use the `compare` function:

```typescript

const isMatch = await bcrypt.compare(password, hash);
```

You can read more about available functions [here](https://www.npmjs.com/package/bcrypt).

----
url: https://docs.nestjs.com/v9/techniques/mvc
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Model-View-Controller](https://docs.nestjs.com/v9/techniques/mvc#model-view-controller)
* [Template rendering](https://docs.nestjs.com/v9/techniques/mvc#template-rendering)
* [Dynamic template rendering](https://docs.nestjs.com/v9/techniques/mvc#dynamic-template-rendering)
* [Example](https://docs.nestjs.com/v9/techniques/mvc#example)
* [Fastify](https://docs.nestjs.com/v9/techniques/mvc#fastify)
* [Example](https://docs.nestjs.com/v9/techniques/mvc#example-1)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/techniques/mvc.md "Suggest Edits")

### Model-View-Controller

Nest, by default, makes use of the [Express](https://github.com/expressjs/express) library under the hood. Hence, every technique for using the MVC (Model-View-Controller) pattern in Express applies to Nest as well.

First, let's scaffold a simple Nest application using the [CLI](https://github.com/nestjs/nest-cli) tool:

```bash

$ npm i -g @nestjs/cli
$ nest new project
```

In order to create an MVC app, we also need a [template engine](https://expressjs.com/en/guide/using-template-engines.html) to render our HTML views:

```bash

$ npm install --save hbs
```

We've used the `hbs` ([Handlebars](https://github.com/pillarjs/hbs#readme)) engine, though you can use whatever fits your requirements. Once the installation process is complete, we need to configure the express instance using the following code:

main.ts

JS TS

```typescript

import { NestFactory } from '@nestjs/core';
import { NestExpressApplication } from '@nestjs/platform-express';
import { join } from 'path';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create<NestExpressApplication>(
    AppModule,
  );

  app.useStaticAssets(join(__dirname, '..', 'public'));
  app.setBaseViewsDir(join(__dirname, '..', 'views'));
  app.setViewEngine('hbs');

  await app.listen(3000);
}
bootstrap();
```

```typescript

import { NestFactory } from '@nestjs/core';
import { join } from 'path';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(
    AppModule,
  );

  app.useStaticAssets(join(__dirname, '..', 'public'));
  app.setBaseViewsDir(join(__dirname, '..', 'views'));
  app.setViewEngine('hbs');

  await app.listen(3000);
}
bootstrap();
```

We told [Express](https://github.com/expressjs/express) that the `public` directory will be used for storing static assets, `views` will contain templates, and the `hbs` template engine should be used to render HTML output.

#### Template rendering[#](/techniques/mvc#template-rendering)

Now, let's create a `views` directory and `index.hbs` template inside it. In the template, we'll print a `message` passed from the controller:

```html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>App</title>
  </head>
  <body>
    {{ message }}
  </body>
</html>
```

Next, open the `app.controller` file and replace the `root()` method with the following code:

app.controller.ts

JS TS

```typescript

import { Get, Controller, Render } from '@nestjs/common';

@Controller()
export class AppController {
  @Get()
  @Render('index')
  root() {
    return { message: 'Hello world!' };
  }
}
```

In this code, we are specifying the template to use in the `@Render()` decorator, and the return value of the route handler method is passed to the template for rendering. Notice that the return value is an object with a property `message`, matching the `message` placeholder we created in the template.

While the application is running, open your browser and navigate to `http://localhost:3000`. You should see the `Hello world!` message.

#### Dynamic template rendering[#](/techniques/mvc#dynamic-template-rendering)

If the application logic must dynamically decide which template to render, then we should use the `@Res()` decorator, and supply the view name in our route handler, rather than in the `@Render()` decorator:

> **Hint** When Nest detects the `@Res()` decorator, it injects the library-specific `response` object. We can use this object to dynamically render the template. Learn more about the `response` object API [here](https://expressjs.com/en/api.html).

app.controller.ts

JS TS

```typescript

import { Get, Controller, Res, Render } from '@nestjs/common';
import { Response } from 'express';
import { AppService } from './app.service';

@Controller()
export class AppController {
  constructor(private appService: AppService) {}

  @Get()
  root(@Res() res: Response) {
    return res.render(
      this.appService.getViewName(),
      { message: 'Hello world!' },
    );
  }
}
```

#### Example[#](/techniques/mvc#example)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/15-mvc).

#### Fastify[#](/techniques/mvc#fastify)

As mentioned in this [chapter](/v9/techniques/performance), we are able to use any compatible HTTP provider together with Nest. One such library is [Fastify](https://github.com/fastify/fastify). In order to create an MVC application with Fastify, we have to install the following packages:

```bash

$ npm i --save @fastify/static @fastify/view handlebars
```

The next steps cover almost the same process used with Express, with minor differences specific to the platform. Once the installation process is complete, open the `main.ts` file and update its contents:

main.ts

JS TS

```typescript

import { NestFactory } from '@nestjs/core';
import { NestFastifyApplication, FastifyAdapter } from '@nestjs/platform-fastify';
import { AppModule } from './app.module';
import { join } from 'path';

async function bootstrap() {
  const app = await NestFactory.create<NestFastifyApplication>(
    AppModule,
    new FastifyAdapter(),
  );
  app.useStaticAssets({
    root: join(__dirname, '..', 'public'),
    prefix: '/public/',
  });
  app.setViewEngine({
    engine: {
      handlebars: require('handlebars'),
    },
    templates: join(__dirname, '..', 'views'),
  });
  await app.listen(3000);
}
bootstrap();
```

```typescript

import { NestFactory } from '@nestjs/core';
import { FastifyAdapter } from '@nestjs/platform-fastify';
import { AppModule } from './app.module';
import { join } from 'path';

async function bootstrap() {
  const app = await NestFactory.create(AppModule, new FastifyAdapter());
  app.useStaticAssets({
    root: join(__dirname, '..', 'public'),
    prefix: '/public/',
  });
  app.setViewEngine({
    engine: {
      handlebars: require('handlebars'),
    },
    templates: join(__dirname, '..', 'views'),
  });
  await app.listen(3000);
}
bootstrap();
```

The Fastify API is slightly different but the end result of those methods calls remains the same. One difference to notice with Fastify is that the template name passed into the `@Render()` decorator must include a file extension.

app.controller.ts

JS TS

```typescript

import { Get, Controller, Render } from '@nestjs/common';

@Controller()
export class AppController {
  @Get()
  @Render('index.hbs')
  root() {
    return { message: 'Hello world!' };
  }
}
```

While the application is running, open your browser and navigate to `http://localhost:3000`. You should see the `Hello world!` message.

#### Example[#](/techniques/mvc#example-1)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/17-mvc-fastify).

----
url: https://docs.nestjs.com/v8/graphql/field-middleware
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Field middleware](https://docs.nestjs.com/v8/graphql/field-middleware#field-middleware)
* [Getting started](https://docs.nestjs.com/v8/graphql/field-middleware#getting-started)
* [Global field middleware](https://docs.nestjs.com/v8/graphql/field-middleware#global-field-middleware)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/field-middleware.md "Suggest Edits")

### Field middleware

> **Warning** This chapter applies only to the code first approach.

Field Middleware lets you run arbitrary code **before or after** a field is resolved. A field middleware can be used to convert the result of a field, validate the arguments of a field, or even check field-level roles (for example, required to access a target field for which a middleware function is executed).

You can connect multiple middleware functions to a field. In this case, they will be called sequentially along the chain where the previous middleware decides to call the next one. The order of the middleware functions in the `middleware` array is important. The first resolver is the "most-outer" layer, so it gets executed first and last (similarly to the `graphql-middleware` package). The second resolver is the "second-outer" layer, so it gets executed second and second to last.

#### Getting started[#](/graphql/field-middleware#getting-started)

Let's start off by creating a simple middleware that will log a field value before it's sent back to the client:

```typescript

import { FieldMiddleware, MiddlewareContext, NextFn } from '@nestjs/graphql';

const loggerMiddleware: FieldMiddleware = async (
  ctx: MiddlewareContext,
  next: NextFn,
) => {
  const value = await next();
  console.log(value);
  return value;
};
```

> **Hint** The `MiddlewareContext` is an object that consist of the same arguments that are normally received by the GraphQL resolver function (`{ source, args, context, info }`), while `NextFn` is a function that let you execute the next middleware in the stack (bound to this field) or the actual field resolver.

> **Warning** Field middleware functions cannot inject dependencies nor access Nest's DI container as they are designed to be very lightweight and shouldn't perform any potentially time-consuming operations (like retrieving data from the database). If you need to call external services/query data from the data source, you should do it in a guard/interceptor bounded to a root query/mutation handler and assign it to `context` object which you can access from within the field middleware (specifically, from the `MiddlewareContext` object).

Note that field middleware must match the `FieldMiddleware` interface. In the example above, we first run the `next()` function (which executes the actual field resolver and returns a field value) and then, we log this value to our terminal. Also, the value returned from the middleware function completely overrides the previous value and since we don't want to perform any changes, we simply return the original value.

With this in place, we can register our middleware directly in the `@Field()` decorator, as follows:

```typescript

@ObjectType()
export class Recipe {
  @Field({ middleware: [loggerMiddleware] })
  title: string;
}
```

Now whenever we request the `title` field of `Recipe` object type, the original field's value will be logged to the console.

> **Hint** To learn how you can implement a field-level permissions system with the use of [extensions](/v8/graphql/extensions) feature, check out this [section](/graphql/extensions#using-custom-metadata).

Also, as mentioned above, we can control the field's value from within the middleware function. For demonstration purposes, let's capitalise a recipe's title (if present):

```typescript

const value = await next();
return value?.toUpperCase();
```

In this case, every title will be automatically uppercased, when requested.

Likewise, you can bind a field middleware to a custom field resolver (a method annotated with the `@ResolveField()` decorator), as follows:

```typescript

@ResolveField(() => String, { middleware: [loggerMiddleware] })
title() {
  return 'Placeholder';
}
```

> **Warning** In case enhancers are enabled at the field resolver level ([read more](/graphql/other-features#execute-enhancers-at-the-field-resolver-level)), field middleware functions will run before any interceptors, guards, etc., **bounded to the method** (but after the root-level enhancers registered for query or mutation handlers).

#### Global field middleware[#](/graphql/field-middleware#global-field-middleware)

In addition to binding a middleware directly to a specific field, you can also register one or multiple middleware functions globally. In this case, they will be automatically connected to all fields of your object types.

```typescript

GraphQLModule.forRoot({
  autoSchemaFile: 'schema.gql',
  buildSchemaOptions: {
    fieldMiddleware: [loggerMiddleware],
  },
}),
```

> **Hint** Globally registered field middleware functions will be executed **before** locally registered ones (those bound directly to specific fields).

----
url: https://docs.nestjs.com/v11/recipes/necord
----

* [Necord](https://docs.nestjs.com/v11/recipes/necord#necord)
* [Installation](https://docs.nestjs.com/v11/recipes/necord#installation)
* [Usage](https://docs.nestjs.com/v11/recipes/necord#usage)
* [Text commands](https://docs.nestjs.com/v11/recipes/necord#text-commands)
* [Application commands](https://docs.nestjs.com/v11/recipes/necord#application-commands)
* [Slash commands](https://docs.nestjs.com/v11/recipes/necord#slash-commands)
* [User context menu](https://docs.nestjs.com/v11/recipes/necord#user-context-menu)
* [Message context menu](https://docs.nestjs.com/v11/recipes/necord#message-context-menu)
* [Buttons](https://docs.nestjs.com/v11/recipes/necord#buttons)
* [Select menus](https://docs.nestjs.com/v11/recipes/necord#select-menus)
* [Modals](https://docs.nestjs.com/v11/recipes/necord#modals)
* [More information](https://docs.nestjs.com/v11/recipes/necord#more-information)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/recipes/necord.md "Suggest Edits")

### Necord

Necord is a powerful module that simplifies the creation of [Discord](https://discord.com) bots, allowing for seamless integration with your NestJS application.

> **Note** Necord is a third-party package and is not officially maintained by the NestJS core team. If you encounter any issues, please report them in the [official repository](https://github.com/necordjs/necord).

#### Installation[#](/recipes/necord#installation)

To get started, you need to install Necord alongside its dependency, [`Discord.js`](https://discord.js.org).

```bash

$ npm install necord discord.js
```

#### Usage[#](/recipes/necord#usage)

To utilize Necord in your project, import the `NecordModule` and configure it with the necessary options.

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { NecordModule } from 'necord';
import { IntentsBitField } from 'discord.js';
import { AppService } from './app.service';

@Module({
  imports: [
    NecordModule.forRoot({
      token: process.env.DISCORD_TOKEN,
      intents: [IntentsBitField.Flags.Guilds],
      development: [process.env.DISCORD_DEVELOPMENT_GUILD_ID],
    }),
  ],
  providers: [AppService],
})
export class AppModule {}
```

> **Hint** You can find a comprehensive list of available intents [here](https://discord.com/developers/docs/topics/gateway#gateway-intents).

With this setup, you can inject the `AppService` into your providers to easily register commands, events, and more.

app.service.ts

JS TS

```typescript

import { Injectable, Logger } from '@nestjs/common';
import { Context, On, Once, ContextOf } from 'necord';
import { Client } from 'discord.js';

@Injectable()
export class AppService {
  private readonly logger = new Logger(AppService.name);

  @Once('ready')
  public onReady(@Context() [client]: ContextOf<'ready'>) {
    this.logger.log(`Bot logged in as ${client.user.username}`);
  }

  @On('warn')
  public onWarn(@Context() [message]: ContextOf<'warn'>) {
    this.logger.warn(message);
  }
}
```

##### Understanding context

You may have noticed the `@Context` decorator in the examples above. This decorator injects the event context into your method, allowing you to access various event-specific data. Since there are multiple types of events, the context type is inferred using the `ContextOf<type: string>` type. You can easily access context variables by using the `@Context()` decorator, which fills the variable with an array of arguments relevant to the event.

#### Text commands[#](/recipes/necord#text-commands)

> **Caution** Text commands rely on message content, which is set to be deprecated for verified bots and applications with over 100 servers. This means that if your bot is unable to access message content, text commands will not function. Read more about this change [here](https://support-dev.discord.com/hc/en-us/articles/4404772028055-Message-Content-Access-Deprecation-for-Verified-Bots).

Here's how to create a simple command handler for messages using the `@TextCommand` decorator.

app.commands.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { Context, TextCommand, TextCommandContext, Arguments } from 'necord';

@Injectable()
export class AppCommands {
  @TextCommand({
    name: 'ping',
    description: 'Responds with pong!',
  })
  public onPing(
    @Context() [message]: TextCommandContext,
    @Arguments() args: string[],
  ) {
    return message.reply('pong!');
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';
import { Context, SlashCommand, SlashCommandContext } from 'necord';

@Injectable()
export class AppCommands {
  @SlashCommand({
    name: 'ping',
    description: 'Responds with pong!',
  })
  public async onPing(@Context() [interaction]: SlashCommandContext) {
    return interaction.reply({ content: 'Pong!' });
  }
}
```

> **Hint** When your bot client logs in, it will automatically register all defined commands. Note that global commands are cached for up to an hour. To avoid issues with the global cache, utilize the `development` argument in the Necord module, which restricts command visibility to a single guild.

##### Options

You can define parameters for your slash commands using option decorators. Let's create a `TextDto` class for this purpose:

text.dto.ts

JS TS

```typescript

import { StringOption } from 'necord';

export class TextDto {
  @StringOption({
    name: 'text',
    description: 'Input your text here',
    required: true,
  })
  text: string;
}
```

You can then use this DTO in the `AppCommands` class:

app.commands.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { Context, SlashCommand, Options, SlashCommandContext } from 'necord';
import { TextDto } from './length.dto';

@Injectable()
export class AppCommands {
  @SlashCommand({
    name: 'length',
    description: 'Calculate the length of your text',
  })
  public async onLength(
    @Context() [interaction]: SlashCommandContext,
    @Options() { text }: TextDto,
  ) {
    return interaction.reply({
      content: `The length of your text is: ${text.length}`,
    });
  }
}
```

For a complete list of built-in option decorators, check out [this documentation](https://necord.org/interactions/slash-commands#options).

##### Autocomplete

To implement autocomplete functionality for your slash commands, you'll need to create an interceptor. This interceptor will handle requests as users type in the autocomplete field.

cats-autocomplete.interceptor.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { AutocompleteInteraction } from 'discord.js';
import { AutocompleteInterceptor } from 'necord';

@Injectable()
class CatsAutocompleteInterceptor extends AutocompleteInterceptor {
  public transformOptions(interaction: AutocompleteInteraction) {
    const focused = interaction.options.getFocused(true);
    let choices: string[];

    if (focused.name === 'cat') {
      choices = ['Siamese', 'Persian', 'Maine Coon'];
    }

    return interaction.respond(
      choices
        .filter((choice) => choice.startsWith(focused.value.toString()))
        .map((choice) => ({ name: choice, value: choice })),
    );
  }
}
```

You will also need to mark your options class with `autocomplete: true`:

cat.dto.ts

JS TS

```typescript

import { StringOption } from 'necord';

export class CatDto {
  @StringOption({
    name: 'cat',
    description: 'Choose a cat breed',
    autocomplete: true,
    required: true,
  })
  cat: string;
}
```

Finally, apply the interceptor to your slash command:

cats.commands.ts

JS TS

```typescript

import { Injectable, UseInterceptors } from '@nestjs/common';
import { Context, SlashCommand, Options, SlashCommandContext } from 'necord';
import { CatDto } from '/cat.dto';
import { CatsAutocompleteInterceptor } from './cats-autocomplete.interceptor';

@Injectable()
export class CatsCommands {
  @UseInterceptors(CatsAutocompleteInterceptor)
  @SlashCommand({
    name: 'cat',
    description: 'Retrieve information about a specific cat breed',
  })
  public async onSearch(
    @Context() [interaction]: SlashCommandContext,
    @Options() { cat }: CatDto,
  ) {
    return interaction.reply({
      content: `I found information on the breed of ${cat} cat!`,
    });
  }
}
```

#### User context menu[#](/recipes/necord#user-context-menu)

User commands appear on the context menu that appears when right-clicking (or tapping) on users. These commands provide quick actions that target users directly.

app.commands.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { Context, UserCommand, UserCommandContext, TargetUser } from 'necord';
import { User } from 'discord.js';

@Injectable()
export class AppCommands {
  @UserCommand({ name: 'Get avatar' })
  public async getUserAvatar(
    @Context() [interaction]: UserCommandContext,
    @TargetUser() user: User,
  ) {
    return interaction.reply({
      embeds: [
        new MessageEmbed()
          .setTitle(`Avatar of ${user.username}`)
          .setImage(user.displayAvatarURL({ size: 4096, dynamic: true })),
      ],
    });
  }
}
```

#### Message context menu[#](/recipes/necord#message-context-menu)

Message commands show up in the context menu when right-clicking on messages, allowing for quick actions relevant to those messages.

app.commands.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { Context, MessageCommand, MessageCommandContext, TargetMessage } from 'necord';
import { Message } from 'discord.js';

@Injectable()
export class AppCommands {
  @MessageCommand({ name: 'Copy Message' })
  public async copyMessage(
    @Context() [interaction]: MessageCommandContext,
    @TargetMessage() message: Message,
  ) {
    return interaction.reply({ content: message.content });
  }
}
```

#### Buttons[#](/recipes/necord#buttons)

[Buttons](https://discord.com/developers/docs/interactions/message-components#buttons) are interactive elements that can be included in messages. When clicked, they send an [interaction](https://discord.com/developers/docs/interactions/receiving-and-responding#interaction-object) to your application.

app.components.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { Context, Button, ButtonContext } from 'necord';

@Injectable()
export class AppComponents {
  @Button('BUTTON')
  public onButtonClick(@Context() [interaction]: ButtonContext) {
    return interaction.reply({ content: 'Button clicked!' });
  }
}
```

#### Select menus[#](/recipes/necord#select-menus)

[Select menus](https://discord.com/developers/docs/interactions/message-components#select-menus) are another type of interactive component that appears on messages. They provide a dropdown-like UI for users to select options.

app.components.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { Context, StringSelect, StringSelectContext, SelectedStrings } from 'necord';

@Injectable()
export class AppComponents {
  @StringSelect('SELECT_MENU')
  public onSelectMenu(
    @Context() [interaction]: StringSelectContext,
    @SelectedStrings() values: string[],
  ) {
    return interaction.reply({ content: `You selected: ${values.join(', ')}` });
  }
}
```

For a full list of built-in select menu components, visit [this link](https://necord.org/interactions/message-components#select-menu).

#### Modals[#](/recipes/necord#modals)

Modals are pop-up forms that allow users to submit formatted input. Here's how to create and handle modals using Necord:

app.modals.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { Context, Modal, ModalContext } from 'necord';

@Injectable()
export class AppModals {
  @Modal('pizza')
  public onModal(@Context() [interaction]: ModalContext) {
    return interaction.reply({
      content: `Your fav pizza : ${interaction.fields.getTextInputValue('pizza')}`
    });
  }
}
```

#### More information[#](/recipes/necord#more-information)

Visit the [Necord](https://necord.org) website for more information.

----
url: https://docs.nestjs.com/v7/recipes/sql-typeorm
----

* [SQL (TypeORM)](https://docs.nestjs.com/v7/recipes/sql-typeorm#sql-typeorm)
* [Getting started](https://docs.nestjs.com/v7/recipes/sql-typeorm#getting-started)
* [Repository pattern](https://docs.nestjs.com/v7/recipes/sql-typeorm#repository-pattern)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/recipes/sql-typeorm.md "Suggest Edits")

### SQL (TypeORM)

##### This chapter applies only to TypeScript

> **Warning** In this article, you'll learn how to create a `DatabaseModule` based on the **TypeORM** package from scratch using custom providers mechanism. As a consequence, this solution contains a lot of overhead that you can omit using ready to use and available out-of-the-box dedicated `@nestjs/typeorm` package. To learn more, see [here](/v7/techniques/sql).

[TypeORM](https://github.com/typeorm/typeorm) is definitely the most mature Object Relational Mapper (ORM) available in the node.js world. Since it's written in TypeScript, it works pretty well with the Nest framework.

#### Getting started[#](/recipes/sql-typeorm#getting-started)

To start the adventure with this library we have to install all required dependencies:

```bash

$ npm install --save typeorm mysql
```

The first step we need to do is to establish the connection with our database using `createConnection()` function imported from the `typeorm` package. The `createConnection()` function returns a `Promise`, and therefore we have to create an [async provider](/v7/fundamentals/async-components).

database.providers.ts

JS TS

```typescript

import { createConnection } from 'typeorm';

export const databaseProviders = [
  {
    provide: 'DATABASE_CONNECTION',
    useFactory: async () => await createConnection({
      type: 'mysql',
      host: 'localhost',
      port: 3306,
      username: 'root',
      password: 'root',
      database: 'test',
      entities: [
          __dirname + '/../**/*.entity{.ts,.js}',
      ],
      synchronize: true,
    }),
  },
];
```

> **Warning** Setting `synchronize: true` shouldn't be used in production - otherwise you can lose production data.

> **Hint** Following best practices, we declared the custom provider in the separated file which has a `*.providers.ts` suffix.

Then, we need to export these providers to make them **accessible** for the rest of the application.

database.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { databaseProviders } from './database.providers';

@Module({
  providers: [...databaseProviders],
  exports: [...databaseProviders],
})
export class DatabaseModule {}
```

Now we can inject the `Connection` object using `@Inject()` decorator. Each class that would depend on the `Connection` async provider will wait until a `Promise` is resolved.

#### Repository pattern[#](/recipes/sql-typeorm#repository-pattern)

The [TypeORM](https://github.com/typeorm/typeorm) supports the repository design pattern, thus each entity has its own Repository. These repositories can be obtained from the database connection.

But firstly, we need at least one entity. We are going to reuse the `Photo` entity from the official documentation.

photo.entity.ts

JS TS

```typescript

import { Entity, Column, PrimaryGeneratedColumn } from 'typeorm';

@Entity()
export class Photo {
  @PrimaryGeneratedColumn()
  id: number;

  @Column({ length: 500 })
  name: string;

  @Column('text')
  description: string;

  @Column()
  filename: string;

  @Column('int')
  views: number;

  @Column()
  isPublished: boolean;
}
```

The `Photo` entity belongs to the `photo` directory. This directory represents the `PhotoModule`. Now, let's create a **Repository** provider:

photo.providers.ts

JS TS

```typescript

import { Connection, Repository } from 'typeorm';
import { Photo } from './photo.entity';

export const photoProviders = [
  {
    provide: 'PHOTO_REPOSITORY',
    useFactory: (connection: Connection) => connection.getRepository(Photo),
    inject: ['DATABASE_CONNECTION'],
  },
];
```

> **Warning** In the real-world applications you should avoid **magic strings**. Both `PHOTO_REPOSITORY` and `DATABASE_CONNECTION` should be kept in the separated `constants.ts` file.

Now we can inject the `Repository<Photo>` to the `PhotoService` using the `@Inject()` decorator:

photo.service.ts

JS TS

```typescript

import { Injectable, Inject } from '@nestjs/common';
import { Repository } from 'typeorm';
import { Photo } from './photo.entity';

@Injectable()
export class PhotoService {
  constructor(
    @Inject('PHOTO_REPOSITORY')
    private photoRepository: Repository<Photo>,
  ) {}

  async findAll(): Promise<Photo[]> {
    return this.photoRepository.find();
  }
}
```

The database connection is **asynchronous**, but Nest makes this process completely invisible for the end-user. The `PhotoRepository` is waiting for the db connection, and the `PhotoService` is delayed until repository is ready to use. The entire application can start when each class is instantiated.

Here is a final `PhotoModule`:

photo.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { DatabaseModule } from '../database/database.module';
import { photoProviders } from './photo.providers';
import { PhotoService } from './photo.service';

@Module({
  imports: [DatabaseModule],
  providers: [
    ...photoProviders,
    PhotoService,
  ],
})
export class PhotoModule {}
```

> **Hint** Do not forget to import the `PhotoModule` into the root `ApplicationModule`.

----
url: https://docs.nestjs.com/v7/openapi/introduction
----

* [Introduction](https://docs.nestjs.com/v7/openapi/introduction#introduction)
* [Installation](https://docs.nestjs.com/v7/openapi/introduction#installation)
* [Bootstrap](https://docs.nestjs.com/v7/openapi/introduction#bootstrap)
* [Document options](https://docs.nestjs.com/v7/openapi/introduction#document-options)
* [Setup options](https://docs.nestjs.com/v7/openapi/introduction#setup-options)
* [Example](https://docs.nestjs.com/v7/openapi/introduction#example)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/openapi/introduction.md "Suggest Edits")

### Introduction

The [OpenAPI](https://swagger.io/specification/) specification is a language-agnostic definition format used to describe RESTful APIs. Nest provides a dedicated [module](https://github.com/nestjs/swagger) which allows generating such a specification by leveraging decorators.

#### Installation[#](/openapi/introduction#installation)

To begin using it, we first install the required dependencies.

```bash

$ npm install --save @nestjs/swagger swagger-ui-express
```

If you use fastify, install `fastify-swagger` instead of `swagger-ui-express`:

```bash

$ npm install --save @nestjs/swagger fastify-swagger
```

#### Bootstrap[#](/openapi/introduction#bootstrap)

Once the installation process is complete, open the `main.ts` file and initialize Swagger using the `SwaggerModule` class:

```typescript

import { NestFactory } from '@nestjs/core';
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);

  const config = new DocumentBuilder()
    .setTitle('Cats example')
    .setDescription('The cats API description')
    .setVersion('1.0')
    .addTag('cats')
    .build();
  const document = SwaggerModule.createDocument(app, config);
  SwaggerModule.setup('api', app, document);

  await app.listen(3000);
}
bootstrap();
```

> **Hint**`document` (returned by the `SwaggerModule#createDocument()` method) is a serializable object conforming to [OpenAPI Document](https://swagger.io/specification/#openapi-document). Instead of hosting it via HTTP, you could also save it as a JSON/YAML file, and consume it in different ways.

```bash

$ npm run start
```

While the application is running, open your browser and navigate to `http://localhost:3000/api`. You should see the Swagger UI.

The `SwaggerModule` automatically reflects all of your endpoints. Note that the Swagger UI is created using either `swagger-ui-express` or `fastify-swagger`, depending on the platform.

> **Hint** To generate and download a Swagger JSON file, navigate to `http://localhost:3000/api-json` (`swagger-ui-express`) or `http://localhost:3000/api/json` (`fastify-swagger`) in your browser (assuming that your Swagger documentation is available under `http://localhost:3000/api`).

> **Warning** When using `fastify-swagger` and `helmet`, there may be a problem with [CSP](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP), to solve this collision, configure the CSP as shown below:
>
> ```typescript
>
> app.register(helmet, {
>   contentSecurityPolicy: {
>     directives: {
>       defaultSrc: [`'self'`],
>       styleSrc: [`'self'`, `'unsafe-inline'`],
>       imgSrc: [`'self'`, 'data:', 'validator.swagger.io'],
>       scriptSrc: [`'self'`, `https: 'unsafe-inline'`],
>     },
>   },
> });
>
> // If you are not going to use CSP at all, you can use this:
> app.register(helmet, {
>   contentSecurityPolicy: false,
> });
> ```

#### Document options[#](/openapi/introduction#document-options)

When creating a document, it is possible to provide some extra options to fine tune the library's behavior. These options should be of type `SwaggerDocumentOptions`, which can be the following:

```typescript

export interface SwaggerDocumentOptions {
  /**
   * List of modules to include in the specification
   */
  include?: Function[];

  /**
   * Additional, extra models that should be inspected and included in the specification
   */
  extraModels?: Function[];

  /**
   * If `true`, swagger will ignore the global prefix set through `setGlobalPrefix()` method
   */
  ignoreGlobalPrefix?: boolean;

  /**
   * If `true`, swagger will also load routes from the modules imported by `include` modules
   */
  deepScanRoutes?: boolean;

  /**
   * Custom operationIdFactory that will be used to generate the `operationId`
   * based on the `controllerKey` and `methodKey`
   * @default () => controllerKey_methodKey
   */
  operationIdFactory?: (controllerKey: string, methodKey: string) => string;
}
```

For example, if you want to make sure that the library generates operation names like `createUser` instead of `UserController_createUser`, you can set the following:

```typescript

const options: SwaggerDocumentOptions =  {
  operationIdFactory: (
    controllerKey: string,
    methodKey: string
  ) => methodKey
};
const document = SwaggerModule.createDocument(app, config, options);
```

#### Setup options[#](/openapi/introduction#setup-options)

You can configure Swagger UI by passing the options object which fulfills the `SwaggerCustomOptions` interface as a fourth argument of the `SwaggerModule#setup` method.

```typescript

export interface SwaggerCustomOptions {
  explorer?: boolean;
  swaggerOptions?: Record<string, any>;
  customCss?: string;
  customCssUrl?: string;
  customJs?: string;
  customfavIcon?: string;
  swaggerUrl?: string;
  customSiteTitle?: string;
  validatorUrl?: string;
  url?: string;
  urls?: Record<'url' | 'name', string>[];
}
```

For example, if you want to make sure that the authentication token persists after refreshing the page, or change the page title (that shows up in the browser), you can use the following settings:

```typescript

const customOptions: SwaggerCustomOptions = {
  swaggerOptions: {
    persistAuthorization: true,
  },
  customSiteTitle: 'My API Docs',
};
SwaggerModule.setup('docs', app, document, customOptions);
```

#### Example[#](/openapi/introduction#example)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/11-swagger).

----
url: https://docs.nestjs.com/v6/faq/hybrid-application
----

* [Hybrid application](https://docs.nestjs.com/v6/faq/hybrid-application#hybrid-application)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/faq/hybrid-application.md "Suggest Edits")

### Hybrid application

A hybrid application is one that both listens for HTTP requests, as well as makes use of connected microservices. The `INestApplication` instance can be connected with `INestMicroservice` instances through the `connectMicroservice()` method. To connect multiple microservice instances, simply pass additional microservice configuration objects as arguments in a comma-separated list.

```typescript

const app = await NestFactory.create(AppModule);
const microservice = app.connectMicroservice({
  transport: Transport.TCP,
});

await app.startAllMicroservicesAsync();
await app.listen(3001);
```

----
url: https://docs.nestjs.com/v6/fundamentals/injection-scopes
----

* [Injection scopes](https://docs.nestjs.com/v6/fundamentals/injection-scopes#injection-scopes)
* [Provider scope](https://docs.nestjs.com/v6/fundamentals/injection-scopes#provider-scope)
* [Usage](https://docs.nestjs.com/v6/fundamentals/injection-scopes#usage)
* [Controller scope](https://docs.nestjs.com/v6/fundamentals/injection-scopes#controller-scope)
* [Scope hierarchy](https://docs.nestjs.com/v6/fundamentals/injection-scopes#scope-hierarchy)
* [Request provider](https://docs.nestjs.com/v6/fundamentals/injection-scopes#request-provider)
* [Performance](https://docs.nestjs.com/v6/fundamentals/injection-scopes#performance)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/fundamentals/provider-scopes.md "Suggest Edits")

### Injection scopes

For people coming from different programming language backgrounds, it might be unexpected to learn that in Nest, almost everything is shared across incoming requests. We have a connection pool to the database, singleton services with global state, etc. Remember that Node.js doesn't follow the request/response Multi-Threaded Stateless Model in which every request is processed by a separate thread. Hence, using singleton instances is fully **safe** for our applications.

However, there are edge-cases when request-based lifetime may be the desired behavior, for instance per-request caching in GraphQL applications, request tracking, and multi-tenancy. Injection scopes provide a mechanism to obtain the desired provider lifetime behavior.

#### Provider scope[#](/fundamentals/injection-scopes#provider-scope)

A provider can have any of the following scopes:

|             |                                                                                                                                                                                                                                                                            |
| ----------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `SINGLETON` | A single instance of the provider is shared across the entire application. The instance lifetime is tied directly to the application lifecycle. Once the application has bootstrapped, all singleton providers have been instantiated. Singleton scope is used by default. |
| `REQUEST`   | A new instance of the provider is created exclusively for each incoming **request**. The instance is garbage-collected after the request has completed processing.                                                                                                         |
| `TRANSIENT` | Transient providers are not shared across consumers. Each consumer that injects a transient provider will receive a new, dedicated instance.                                                                                                                               |

> **Hint** Using singleton scope is **recommended** for most use cases. Sharing providers across consumers and across requests means that an instance can be cached and its initialization occurs only once, during application startup.

#### Usage[#](/fundamentals/injection-scopes#usage)

Specify injection scope by passing the `scope` property to the `@Injectable()` decorator options object:

```typescript

import { Injectable, Scope } from '@nestjs/common';

@Injectable({ scope: Scope.REQUEST })
export class CatsService {}
```

Similarly, for [custom providers](/v6/fundamentals/custom-providers), set the `scope` property in the long-hand form for a provider registration:

```typescript

{
  provide: 'CACHE_MANAGER',
  useClass: CacheManager,
  scope: Scope.TRANSIENT,
}
```

> **Hint** Import the `Scope` enum from `@nestjs/common`

> **Notice** Gateways should not use request-scoped providers because they must act as singletons. Each gateway encapsulates a real socket and cannot be instantiated multiple times.

Singleton scope is used by default, and need not be declared. If you do want to declare a provider as singleton scoped, use the `Scope.DEFAULT` value for the `scope` property.

#### Controller scope[#](/fundamentals/injection-scopes#controller-scope)

Controllers can also have scope, which applies to all request method handlers declared in that controller. Like provider scope, the scope of a controller declares its lifetime. For a request-scoped controller, a new instance is created for each inbound request, and garbage-collected when the request has completed processing.

Declare controller scope with the `scope` property of the `ControllerOptions` object:

```typescript

@Controller({
  path: 'cats',
  scope: Scope.REQUEST,
})
export class CatsController {}
```

#### Scope hierarchy[#](/fundamentals/injection-scopes#scope-hierarchy)

Scope bubbles up the injection chain. A controller that depends on a request-scoped provider will, itself, be request-scoped.

Imagine the following dependency graph: `CatsController <- CatsService <- CatsRepository`. If `CatsService` is request-scoped (and the others are default singletons), the `CatsController` will become request-scoped as it is dependent on the injected service. The `CatsRepository`, which is not dependent, would remain singleton-scoped.

## Learn the right way!

* 60+ chapters
* 4+ hours of videos
* Official certificate
* Deep-dive sessions

[Explore official courses](https://courses.nestjs.com "Courses | NestJS - A node.js framework built on top of TypeScript")

#### Request provider[#](/fundamentals/injection-scopes#request-provider)

In an HTTP server-based application (e.g., using `@nestjs/platform-express` or `@nestjs/platform-fastify`), you may want to access a reference to the original request object when using request-scoped providers. You can do this by injecting the `REQUEST` object.

```typescript

import { Injectable, Scope, Inject } from '@nestjs/common';
import { REQUEST } from '@nestjs/core';
import { Request } from 'express';

@Injectable({ scope: Scope.REQUEST })
export class CatsService {
  constructor(@Inject(REQUEST) private readonly request: Request) {}
}
```

Because of underlying platform/protocol differences, you access the inbound request slightly differently for Microservice or GraphQL applications. In [GraphQL](/v6/graphql/quick-start) applications, you inject `CONTEXT` instead of `REQUEST`:

```typescript

import { Injectable, Scope, Inject } from '@nestjs/common';
import { CONTEXT } from '@nestjs/graphql';

@Injectable({ scope: Scope.REQUEST })
export class CatsService {
  constructor(@Inject(CONTEXT) private readonly context) {}
}
```

You then configure your `context` value (in the `GraphQLModule`) to contain `request` as its property.

#### Performance[#](/fundamentals/injection-scopes#performance)

Using request-scoped providers will have an impact on application performance. While Nest tries to cache as much metadata as possible, it will still have to create an instance of your class on each request. Hence, it will slow down your average response time and overall benchmarking result. Unless a provider must be request-scoped, it is strongly recommended that you use the default singleton scope.

----
url: https://docs.nestjs.com/v5/fundamentals/async-providers
----

### Asynchronous providers

When the application start has to be delayed until some **asynchronous tasks** will be finished, for example, until the connection with the database will be established, you should consider using asynchronous providers. In order to create an `async` provider, we use the `useFactory`. The factory has to return a `Promise` (thus `async` functions fit as well).

TypeScript

```typescript

{
  provide: 'AsyncDbConnection',
  useFactory: async () => {
    const connection = await createConnection(options);
    return connection;
  },
},
```

> **Hint** Learn more about the custom providers syntax [here](/v5/fundamentals/custom-providers).

#### Injection

The asynchronous providers can be simply injected to other components by their tokens (in the above case, by the `AsyncDbConnection` token). Each class that depends on the asynchronous provider will be instantiated once the async provider is **already resolved**.

The above example is for demonstration purposes. If you're looking for more detailed one, [see here](/v5/recipes/sql-typeorm).

* Asynchronous providers
* Injection

----
url: https://docs.nestjs.com/controllers
----

[Skip to content](#content)

On this page

* [Controllers](https://docs.nestjs.com/controllers#controllers)
* [Routing](https://docs.nestjs.com/controllers#routing)
* [Request object](https://docs.nestjs.com/controllers#request-object)
* [Resources](https://docs.nestjs.com/controllers#resources)
* [Route wildcards](https://docs.nestjs.com/controllers#route-wildcards)
* [Route conflicts and resolution order](https://docs.nestjs.com/controllers#route-conflicts-and-resolution-order)
* [Status code](https://docs.nestjs.com/controllers#status-code)
* [Response headers](https://docs.nestjs.com/controllers#response-headers)
* [Redirection](https://docs.nestjs.com/controllers#redirection)
* [Route parameters](https://docs.nestjs.com/controllers#route-parameters)
* [Sub-domain routing](https://docs.nestjs.com/controllers#sub-domain-routing)
* [State sharing](https://docs.nestjs.com/controllers#state-sharing)
* [Asynchronicity](https://docs.nestjs.com/controllers#asynchronicity)
* [Request payloads](https://docs.nestjs.com/controllers#request-payloads)
* [Query parameters](https://docs.nestjs.com/controllers#query-parameters)
* [Handling errors](https://docs.nestjs.com/controllers#handling-errors)
* [Observing routes in production](https://docs.nestjs.com/controllers#observing-routes-in-production)
* [Full resource sample](https://docs.nestjs.com/controllers#full-resource-sample)
* [Getting up and running](https://docs.nestjs.com/controllers#getting-up-and-running)
* [Library-specific approach](https://docs.nestjs.com/controllers#library-specific-approach)

### Controllers

Controllers are responsible for handling incoming **requests** and sending **responses** back to the client.

A controller's purpose is to handle specific requests for the application. The **routing** mechanism determines which controller handles each request. A controller often has multiple routes, and each route can perform a different action.

To create a basic controller, you use classes and **decorators**. Decorators associate classes with the required metadata, which Nest uses to build a routing map that connects requests to their corresponding controllers.

> **Hint** To create a CRUD controller with built-in [validation](https://docs.nestjs.com/application/validation), use the CLI's [CRUD generator](https://docs.nestjs.com/recipes/crud-generator#crud-generator): `nest g resource [name]`.

#### Routing[#](/controllers#routing)

The following example uses the `@Controller()` decorator, which is **required** to define a basic controller, with an optional route path prefix of `cats`. A path prefix in the `@Controller()` decorator groups related routes and reduces repetitive code. For example, to group the routes that manage cat entities under the `/cats` path, specify the `cats` prefix in the `@Controller()` decorator. You then don't need to repeat that portion of the path for each route in the file.

cats.controller.ts

JS TS

```typescript

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

@Controller('cats')
export class CatsController {
  @Get()
  findAll(): string {
    return 'This action returns all cats';
  }
}
```

```typescript

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

@Controller('cats')
export class CatsController {
  @Get()
  findAll() {
    return 'This action returns all cats';
  }
}
```

> **Hint** To create a controller using the CLI, run the `$ nest g controller [name]` command.

The `@Get()` HTTP request method decorator placed before the `findAll()` method tells Nest to create a handler for a specific endpoint. An endpoint is defined by the HTTP request method (GET in this case) and the route path. The route path of a handler combines the (optional) prefix declared for the controller **and** any path specified in the method's decorator. Since the example sets a prefix (`cats`) and no path in the method decorator, Nest maps `GET /cats` requests to this handler.

If the method decorator also specified a path, such as `@Get('breed')`, the resulting route would be `GET /cats/breed`.

When a `GET /cats` request arrives, Nest routes it to the user-defined `findAll()` method. The method name is arbitrary: you must declare a method to bind the route to, but Nest attaches no significance to its name.

This method returns a 200 status code along with the associated response, which in this case is a string. To explain why, we need to introduce the two **different** options Nest provides for manipulating responses:

|                        |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Standard (recommended) | With this built-in method, when a route handler returns a JavaScript object or array, it is **automatically** serialized to JSON. When it returns a JavaScript primitive type (e.g., `string`, `number`, `boolean`), Nest sends the value without attempting to serialize it. Response handling is therefore straightforward: return the value, and Nest takes care of the rest. The response's **status code** is 200 by default, except for POST requests, which use 201. You can change this behavior by adding the `@HttpCode(...)` decorator at the handler level (see [Status code](controllers#status-code)). |
| Library-specific       | You can use the library-specific (e.g., Express) [response object](https://expressjs.com/en/api.html#res), injected with the `@Res()` decorator in the route handler signature (e.g., `findAll(@Res() response)`). This approach lets you use the native response handling methods exposed by that object. For example, with Express, you can construct responses with code like `response.status(200).send()`.                                                                                                                                                                                                      |

> **Warning** Nest detects when a handler uses either `@Res()` or `@Next()`, which indicates that you have chosen the library-specific option. If both approaches are used at the same time, the standard approach is **automatically disabled** for that route and no longer works as expected. To combine them (for example, to inject the response object only to set cookies or headers while leaving the rest to the framework), set the `passthrough` option to `true` in the `@Res({ passthrough: true })` decorator.

## Debug production with NestJS Observe

* Every request traced
* Errors with source code
* Logs in context
* Zero config, free plan

[Start for free](https://observe.nestjs.com "Observe | NestJS - A progressive Node.js framework")

#### Request object[#](/controllers#request-object)

Handlers often need access to the client's **request** details. Nest provides access to the [request object](https://expressjs.com/en/api.html#req) of the underlying platform (Express by default). To access it, add the `@Req()` decorator to the handler's signature, which instructs Nest to inject it.

cats.controller.ts

JS TS

```typescript

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

@Controller('cats')
export class CatsController {
  @Get()
  findAll(@Req() request: Request): string {
    return 'This action returns all cats';
  }
}
```

```typescript

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

@Controller('cats')
export class CatsController {
  @Get()
  @Bind(Req())
  findAll(request) {
    return 'This action returns all cats';
  }
}
```

> **Hint** To take advantage of `express` typings (as in the `request: Request` parameter above), install the `@types/express` package.

The request object represents the HTTP request and has properties for the query string, route parameters, HTTP headers, and body (see the [Express documentation](https://expressjs.com/en/api.html#req)). In most cases, you don't need to access these properties manually. Instead, use dedicated decorators such as `@Body()` or `@Query()`, which are available out of the box. The following table lists the provided decorators and the platform-specific objects they represent.

|                                 |                                                                                |
| ------------------------------- | ------------------------------------------------------------------------------ |
| `@Request(), @Req()`            | `req`                                                                          |
| `@Response(), @Res()`\*         | `res`                                                                          |
| `@Next()`                       | `next`                                                                         |
| `@Session()`                    | `req.session`                                                                  |
| `@Param(key?: string)`          | `req.params` / `req.params[key]`                                               |
| `@Body(key?: string)`           | `req.body` / `req.body[key]`                                                   |
| `@Query(key?: string)`          | `req.query` / `req.query[key]`                                                 |
| `@Headers(name?: string)`       | `req.headers` / `req.headers[name]`                                            |
| `@Cookies(name?: string)`       | request cookies / the cookie named `name` (see [Cookies](/techniques/cookies)) |
| `@SignedCookies(name?: string)` | verified signed cookies / the signed cookie named `name`                       |
| `@Ip()`                         | `req.ip`                                                                       |
| `@HostParam()`                  | `req.hosts`                                                                    |

\* For compatibility with typings across underlying HTTP platforms (e.g., Express and Fastify), Nest provides the `@Res()` and `@Response()` decorators. `@Res()` is an alias for `@Response()`. Both directly expose the native `response` object of the underlying platform. When using them, also install the typings for the underlying library (e.g., `@types/express`) to take full advantage of them. When you inject either `@Res()` or `@Response()` in a route handler, you put Nest into **library-specific mode** for that handler, and you become responsible for managing the response. You must then send a response by calling a method on the `response` object (e.g., `res.json(...)` or `res.send(...)`); otherwise, the request will hang.

`@Body()`, `@Query()`, `@Param()`, and `@RawBody()` also accept an options object with `schema` and `pipes` properties. This lets you attach [Standard Schema](https://standardschema.dev/) compatible schemas, such as those created with Zod, Valibot, or ArkType, directly to route parameters.

```typescript

@Post()
create(@Body({ schema: createCatSchema }) createCatDto: CreateCatDto) {
  return this.catsService.create(createCatDto);
}

@Get(':id')
findOne(@Param('id', { schema: z.coerce.number().int().positive() }) id: number) {
  return this.catsService.findOne(id);
}
```

On their own, these decorators only attach the schema as metadata. To validate against it, register the built-in `StandardSchemaValidationPipe` or a custom pipe that reads `metadata.schema`.

> **Hint** To learn how to create your own decorators, see the [Custom route decorators](/custom-decorators) chapter.

#### Resources[#](/controllers#resources)

Earlier, we defined an endpoint to fetch the cats resource (**GET** route). Typically, we also want an endpoint that creates new records. Let's add a **POST** handler:

cats.controller.ts

JS TS

```typescript

import { Controller, Get, Post } from '@nestjs/common';

@Controller('cats')
export class CatsController {
  @Post()
  create(): string {
    return 'This action adds a new cat';
  }

  @Get()
  findAll(): string {
    return 'This action returns all cats';
  }
}
```

```typescript

import { Controller, Get, Post } from '@nestjs/common';

@Controller('cats')
export class CatsController {
  @Post()
  create() {
    return 'This action adds a new cat';
  }

  @Get()
  findAll() {
    return 'This action returns all cats';
  }
}
```

Nest provides decorators for all standard HTTP methods: `@Get()`, `@Post()`, `@Put()`, `@Delete()`, `@Patch()`, `@Options()`, `@Head()`, and `@QueryMethod()`. The last one maps to the `QUERY` method; it is named `QueryMethod` to avoid a clash with the `@Query()` parameter decorator. In addition, `@All()` defines an endpoint that handles all of them.

#### Route wildcards[#](/controllers#route-wildcards)

Nest also supports pattern-based routes. For example, an asterisk (`*`) at the end of a path acts as a wildcard that matches any combination of characters. In the following example, the `findAll()` method is executed for any route that starts with `abcd/`, regardless of the number of characters that follow.

```typescript

@Get('abcd/*')
findAll() {
  return 'This route uses a wildcard';
}
```

The `'abcd/*'` route path matches `abcd/`, `abcd/123`, `abcd/abc`, and so on. In string-based paths, the hyphen (`-`) and the dot (`.`) are interpreted literally.

This approach works with both Express and Fastify. Express v5, however, made its routing stricter: in plain Express, a wildcard must be named for the route to work (e.g., `abcd/{*splat}`, where `splat` is an arbitrary name for the wildcard parameter with no special meaning). Because Nest provides a compatibility layer for Express, you can still use an unnamed asterisk (`*`) as a wildcard.

For asterisks in the **middle of a route**, Express requires named wildcards (e.g., `ab{*splat}cd`), while Fastify does not support them at all.

#### Route conflicts and resolution order[#](/controllers#route-conflicts-and-resolution-order)

Nest registers routes in declaration order. On order-sensitive adapters, such as the default Express adapter, a parametric route can therefore silently shadow a more specific one:

```typescript

@Controller('users')
export class UsersController {
  @Get(':id')
  findOne() {}

  @Get('me') // never reached: `:id` matches "me" first
  findMe() {}
}
```

This is easy to miss: the application boots without a warning, and the problem only surfaces at runtime, when a request is dispatched to the wrong handler. Pipes such as `ParseIntPipe` do not help here, because routing selects the handler *before* any pipe runs.

NestJS v12 adds two opt-in `NestApplicationOptions` properties that guard against this. Both default to the previous behavior, so existing applications are unaffected unless you set them.

**`routeConflictPolicy`** enables bootstrap-time diagnostics. For each kind of conflict, it takes a severity of `'off'` (the default), `'warn'`, or `'error'`:

```typescript

const app = await NestFactory.create(AppModule, {
  routeConflictPolicy: { duplicate: 'error', shadow: 'warn' },
});
```

|             |                                                                                     |
| ----------- | ----------------------------------------------------------------------------------- |
| `duplicate` | Two routes share an identical method, path, host, and version.                      |
| `shadow`    | Two route patterns can match the same request (e.g., `/users/me` and `/users/:id`). |

With `'error'`, all offending pairs are aggregated into a single `RouteConflictException`, thrown when the application initializes (in `app.init()`, or in `app.listen()` if you don't call `init()` explicitly). This way, you see every conflict at once rather than one per restart.

**`routeResolutionStrategy`** controls registration order. Setting it to `'specificity'` registers the most specific routes first (literal segments take precedence over parametric segments, which take precedence over wildcards), so the example above works regardless of declaration order:

```typescript

const app = await NestFactory.create(AppModule, {
  routeResolutionStrategy: 'specificity',
});
```

The default is `'declaration'`, which preserves the previous behavior.

> **Hint** Apart from the `duplicate` policy, these options only matter on adapters where registration order affects matching. `ExpressAdapter` is order-sensitive; `FastifyAdapter` is not, because its router (`find-my-way`) already ranks routes by specificity. On Fastify, the `shadow` policy is a no-op and `'specificity'` sorting has no effect, while the `duplicate` policy is honored on both adapters. The `RouteConflictPolicy`, `RouteConflictPolicyLevel`, and `RouteResolutionStrategy` types are exported from `@nestjs/common`.

#### Status code[#](/controllers#status-code)

As mentioned, the default response **status code** is **200**, except for POST requests, which default to **201**. You can change this behavior with the `@HttpCode(...)` decorator at the handler level.

```typescript

@Post()
@HttpCode(204)
create() {
  return 'This action adds a new cat';
}
```

> **Hint** Import `HttpCode` from the `@nestjs/common` package.

Often, the status code isn't static but depends on various factors. In that case, use a library-specific **response** object (injected with `@Res()`) or, in case of an error, throw an exception.

#### Response headers[#](/controllers#response-headers)

To set a custom response header, use either the `@Header()` decorator or a library-specific response object (and call `res.header()` directly).

```typescript

@Post()
@Header('Cache-Control', 'no-store')
create() {
  return 'This action adds a new cat';
}
```

> **Hint** Import `Header` from the `@nestjs/common` package.

#### Redirection[#](/controllers#redirection)

To redirect a response to a specific URL, use either the `@Redirect()` decorator or a library-specific response object (and call `res.redirect()` directly).

`@Redirect()` takes two optional arguments, `url` and `statusCode`. If omitted, `statusCode` defaults to `302` (`Found`).

```typescript

@Get()
@Redirect('https://nestjs.com', 301)
```

> **Hint** To determine the HTTP status code or the redirect URL dynamically, return an object that follows the `HttpRedirectResponse` interface (exported from `@nestjs/common`).

Returned values override any arguments passed to the `@Redirect()` decorator. For example:

JS TS

```typescript

@Get('docs')
@Redirect('https://docs.nestjs.com', 302)
getDocs(@Query('version') version) {
  if (version && version === '5') {
    return { url: 'https://docs.nestjs.com/v5/' };
  }
}
```

```typescript

@Get('docs')
@Redirect('https://docs.nestjs.com', 302)
@Bind(Query('version'))
getDocs(version) {
  if (version && version === '5') {
    return { url: 'https://docs.nestjs.com/v5/' };
  }
}
```

#### Route parameters[#](/controllers#route-parameters)

Routes with static paths don't work when you need to accept **dynamic data** as part of the request (e.g., `GET /cats/1` to get the cat with id `1`). To define a route with parameters, add route parameter **tokens** to the route path to capture the dynamic values from the URL, as the `@Get()` decorator in the example below shows. You can then access these route parameters with the `@Param()` decorator, added to the method signature.

> **Hint** Declare routes with parameters after any static paths, so that the parameterized path doesn't intercept traffic destined for the static one. See [Route conflicts and resolution order](/controllers#route-conflicts-and-resolution-order) for the options that detect this at bootstrap or resolve it for you.

JS TS

```typescript

@Get(':id')
findOne(@Param() params: any): string {
  console.log(params.id);
  return `This action returns a #${params.id} cat`;
}
```

```typescript

@Get(':id')
@Bind(Param())
findOne(params) {
  console.log(params.id);
  return `This action returns a #${params.id} cat`;
}
```

The `@Param()` decorator decorates a method parameter (`params` in the example above), making the **route** parameters available as properties of that parameter inside the method. As the code shows, you access the `id` parameter as `params.id`. Alternatively, pass a specific parameter token to the decorator and reference the route parameter directly by name in the method body.

> **Hint** Import `Param` from the `@nestjs/common` package.

JS TS

```typescript

@Get(':id')
findOne(@Param('id') id: string): string {
  return `This action returns a #${id} cat`;
}
```

```typescript

@Get(':id')
@Bind(Param('id'))
findOne(id) {
  return `This action returns a #${id} cat`;
}
```

#### Sub-domain routing[#](/controllers#sub-domain-routing)

The `@Controller()` decorator can take a `host` option to require that the HTTP host of incoming requests matches a specific value.

admin.controller.ts

JS TS

```typescript

@Controller({ host: 'admin.example.com' })
export class AdminController {
  @Get()
  index(): string {
    return 'Admin page';
  }
}
```

```typescript

@Controller({ host: 'admin.example.com' })
export class AdminController {
  @Get()
  index() {
    return 'Admin page';
  }
}
```

> **Warning** Since **Fastify** does not support nested routers, use the default Express adapter if you rely on sub-domain routing.

Like a route `path`, the `host` option can use tokens to capture the dynamic value at that position in the host name, as the host parameter token in the `@Controller()` decorator below shows. You can access host parameters declared this way with the `@HostParam()` decorator, added to the method signature.

account.controller.ts

JS TS

```typescript

@Controller({ host: ':account.example.com' })
export class AccountController {
  @Get()
  getInfo(@HostParam('account') account: string) {
    return account;
  }
}
```

```typescript

@Controller({ host: ':account.example.com' })
export class AccountController {
  @Get()
  @Bind(HostParam('account'))
  getInfo(account) {
    return account;
  }
}
```

#### State sharing[#](/controllers#state-sharing)

Developers coming from other programming languages may be surprised to learn that in Nest, nearly everything is shared across incoming requests. This includes resources such as the database connection pool, singleton services with global state, and more. Node.js doesn't follow the request/response multi-threaded stateless model, in which each request is handled by a separate thread. As a result, using singleton instances in Nest is fully **safe**.

That said, some edge cases may require request-based lifetimes for controllers, such as per-request caching in GraphQL applications, request tracking, or multi-tenancy. To learn how to control this, see [Injection scopes](/fundamentals/injection-scopes).

#### Asynchronicity[#](/controllers#asynchronicity)

Modern JavaScript relies heavily on **asynchronous** data handling, and Nest fully supports `async` functions. An `async` function always returns a `Promise`, so a route handler can return a deferred value that Nest resolves automatically:

cats.controller.ts

JS TS

```typescript

@Get()
async findAll(): Promise<any[]> {
  return [];
}
```

```typescript

@Get()
async findAll() {
  return [];
}
```

Route handlers can also return RxJS [observable streams](https://rxjs.dev/guide/observable). Nest subscribes to the stream internally and resolves the last emitted value once the stream completes.

cats.controller.ts

JS TS

```typescript

@Get()
findAll(): Observable<any[]> {
  return of([]);
}
```

```typescript

@Get()
findAll() {
  return of([]);
}
```

Both approaches are valid; choose the one that best suits your needs.

#### Request payloads[#](/controllers#request-payloads)

The POST route handler in the previous example didn't accept any client parameters. Let's fix that by adding the `@Body()` decorator.

Before we proceed (if you're using TypeScript), we need to define the **DTO** (Data Transfer Object) schema. A DTO is an object that defines the shape of data sent over the network. You could define the DTO schema using **TypeScript** interfaces or plain classes, but **classes** are the recommended choice. Classes are part of the JavaScript ES6 standard, so they are preserved as real entities in the compiled JavaScript. TypeScript interfaces, by contrast, are removed during transpilation, so Nest can't reference them at runtime. This matters because features such as **pipes** rely on access to the metatype of variables at runtime, which is only possible with classes.

Create the `CreateCatDto` class:

create-cat.dto.ts

JS TS

```typescript

export class CreateCatDto {
  name: string;
  age: number;
  breed: string;
}
```

It has three basic properties. We can now use the new DTO inside the `CatsController`:

cats.controller.ts

JS TS

```typescript

@Post()
async create(@Body() createCatDto: CreateCatDto) {
  return 'This action adds a new cat';
}
```

```typescript

@Post()
@Bind(Body())
async create(createCatDto) {
  return 'This action adds a new cat';
}
```

> **Hint** The `ValidationPipe` can filter out properties that the route handler should not receive. You whitelist the acceptable properties, and any property not in the whitelist is automatically stripped from the resulting object. In the `CreateCatDto` example, the whitelist consists of the `name`, `age`, and `breed` properties. Learn more in [Stripping properties](https://docs.nestjs.com/application/validation#stripping-properties).

#### Query parameters[#](/controllers#query-parameters)

To extract query parameters from incoming requests, use the `@Query()` decorator.

Consider a route that filters a list of cats by query parameters such as `age` and `breed`. First, define the query parameters in the `CatsController`:

cats.controller.ts

JS TS

```typescript

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

```typescript

@Get()
@Bind(Query('age'), Query('breed'))
async findAll(age, breed) {
  return `This action returns all cats filtered by age: ${age} and breed: ${breed}`;
}
```

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

```plaintext

GET /cats?age=2&breed=Persian
```

results in `age` being `'2'` and `breed` being `'Persian'`. Query parameter values arrive as strings, and the `number` type annotation alone doesn't convert them. To receive a number, apply a pipe such as `ParseIntPipe` (see [Pipes](/pipes)).

If your application needs to handle more complex query parameters, such as nested objects or arrays:

```plaintext

?filter[where][name]=John&filter[where][age]=30
?item[]=1&item[]=2
```

configure your HTTP adapter (Express or Fastify) to use an appropriate query parser. In Express, use the `extended` parser, which supports rich query objects:

main.ts

JS TS

```typescript

const app = await NestFactory.create<NestExpressApplication>(AppModule);
app.set('query parser', 'extended');
```

```typescript

const app = await NestFactory.create(AppModule);
app.set('query parser', 'extended');
```

In Fastify, use the `querystringParser` option:

main.ts

JS TS

```typescript

const app = await NestFactory.create<NestFastifyApplication>(
  AppModule,
  new FastifyAdapter({
    querystringParser: (str) => qs.parse(str),
  }),
);
```

```typescript

const app = await NestFactory.create(
  AppModule,
  new FastifyAdapter({
    querystringParser: (str) => qs.parse(str),
  }),
);
```

> **Hint**`qs` is a query string parser that supports nesting and arrays. Install it with `npm install qs`.

#### Handling errors[#](/controllers#handling-errors)

Handling errors (i.e., working with exceptions) is covered in the [Exception filters](/exception-filters) chapter.

#### Observing routes in production[#](/controllers#observing-routes-in-production)

A controller that behaves perfectly on your machine can behave very differently under real traffic. In production, the question is never "does this route work?" but "why did `GET /cats/:id` go from 40 ms to 900 ms after Tuesday's deploy, and is it every request or one unlucky tenant?"

Route handlers are the natural unit for answering that question, and [NestJS Observe](https://www.observe.nestjs.com/ "NestJS Observe") reports on exactly that unit. Because the `@nestjs/observe` SDK hooks into Nest's own request lifecycle rather than wrapping the HTTP server, every measurement is labeled with the route pattern you declared (`GET /cats/:id`, not 10,000 distinct URLs). Each route is therefore a single line you can sort, chart, and alert on:

```typescript

const app = await NestFactory.create(AppModule, {
  instrument: ObserveInstrument,
});
```

Together with importing `ObserveModule.forRoot()` into your root module, that is the whole integration. From there, a slow route is three clicks away: sort the route list by p95; open the operation to see whether the regression is constant or spiky and whether it started with a release; then open one slow execution and read its waterfall to see which controller, service method, or query held the time. Time is attributed per **class and method**, with awaited time subtracted, so `CatsService.findOne()` spending 800 ms in its own code is immediately distinguishable from `CatsService.findOne()` waiting 800 ms on the database.

See the [Observability](/observability/overview) chapter to get set up, and [Dashboard](/observability/dashboard) for the full walk from an alert down to a single request.

#### Full resource sample[#](/controllers#full-resource-sample)

The following example uses several of the available decorators to create a basic controller. The controller exposes a few methods to access and manipulate internal data.

cats.controller.ts

JS TS

```typescript

import { Controller, Get, Query, Post, Body, Put, Param, Delete } from '@nestjs/common';
import { CreateCatDto, UpdateCatDto, ListAllEntities } from './dto.js';

@Controller('cats')
export class CatsController {
  @Post()
  create(@Body() createCatDto: CreateCatDto) {
    return 'This action adds a new cat';
  }

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

  @Get(':id')
  findOne(@Param('id') id: string) {
    return `This action returns a #${id} cat`;
  }

  @Put(':id')
  update(@Param('id') id: string, @Body() updateCatDto: UpdateCatDto) {
    return `This action updates a #${id} cat`;
  }

  @Delete(':id')
  remove(@Param('id') id: string) {
    return `This action removes a #${id} cat`;
  }
}
```

```typescript

import { Controller, Get, Query, Post, Body, Put, Param, Delete, Bind } from '@nestjs/common';

@Controller('cats')
export class CatsController {
  @Post()
  @Bind(Body())
  create(createCatDto) {
    return 'This action adds a new cat';
  }

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

  @Get(':id')
  @Bind(Param('id'))
  findOne(id) {
    return `This action returns a #${id} cat`;
  }

  @Put(':id')
  @Bind(Param('id'), Body())
  update(id, updateCatDto) {
    return `This action updates a #${id} cat`;
  }

  @Delete(':id')
  @Bind(Param('id'))
  remove(id) {
    return `This action removes a #${id} cat`;
  }
}
```

> **Hint** The Nest CLI provides a generator (schematic) that automatically creates **all the boilerplate code**, so you don't have to write it manually. Learn more in the [CRUD generator](/recipes/crud-generator) recipe.

#### Getting up and running[#](/controllers#getting-up-and-running)

Even with `CatsController` fully defined, Nest doesn't know about it yet and won't create an instance of the class.

Controllers must always belong to a module, which is why we include the `controllers` array in the `@Module()` decorator. Since we haven't defined any modules other than the root `AppModule`, we'll use it to register `CatsController`:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { CatsController } from './cats/cats.controller.js';

@Module({
  controllers: [CatsController],
})
export class AppModule {}
```

With this metadata attached to the module class through the `@Module()` decorator, Nest can determine which controllers to mount.

#### Library-specific approach[#](/controllers#library-specific-approach)

So far, we've covered the standard Nest way of manipulating responses. The alternative is to use a library-specific [response object](https://expressjs.com/en/api.html#res), injected with the `@Res()` decorator. To highlight the differences, let's rewrite `CatsController` as follows:

JS TS

```typescript

import { Controller, Get, Post, Res, HttpStatus } from '@nestjs/common';
import type { Response } from 'express';

@Controller('cats')
export class CatsController {
  @Post()
  create(@Res() res: Response) {
    res.status(HttpStatus.CREATED).send();
  }

  @Get()
  findAll(@Res() res: Response) {
    res.status(HttpStatus.OK).json([]);
  }
}
```

```typescript

import { Controller, Get, Post, Bind, Res, HttpStatus } from '@nestjs/common';

@Controller('cats')
export class CatsController {
  @Post()
  @Bind(Res())
  create(res) {
    res.status(HttpStatus.CREATED).send();
  }

  @Get()
  @Bind(Res())
  findAll(res) {
    res.status(HttpStatus.OK).json([]);
  }
}
```

This approach offers more flexibility by giving full control over the response object (e.g., header manipulation and access to library-specific features), but it should be used with caution. It is generally less clear and has some downsides. The main disadvantage is that your code becomes platform-dependent, since different underlying libraries may expose different APIs on the response object. It also makes testing harder, as you need to mock the response object, among other things.

In addition, this approach loses compatibility with Nest features that rely on standard response handling, such as interceptors and the `@HttpCode()` / `@Header()` decorators. To address this, enable the `passthrough` option:

JS TS

```typescript

@Get()
findAll(@Res({ passthrough: true }) res: Response) {
  res.status(HttpStatus.OK);
  return [];
}
```

```typescript

@Get()
@Bind(Res({ passthrough: true }))
findAll(res) {
  res.status(HttpStatus.OK);
  return [];
}
```

This way, you can interact with the native response object (for example, to set cookies or headers based on specific conditions) while leaving the rest to the framework.

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/controllers.md)

----
url: https://docs.nestjs.com/v6/graphql/resolvers-map
----

* [Resolvers](https://docs.nestjs.com/v6/graphql/resolvers-map#resolvers)
* [Schema first](https://docs.nestjs.com/v6/graphql/resolvers-map#schema-first)
* [Typings](https://docs.nestjs.com/v6/graphql/resolvers-map#typings)
* [Code first](https://docs.nestjs.com/v6/graphql/resolvers-map#code-first)
* [Decorators](https://docs.nestjs.com/v6/graphql/resolvers-map#decorators)
* [Module](https://docs.nestjs.com/v6/graphql/resolvers-map#module)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/resolvers-map.md "Suggest Edits")

### Resolvers

Typically, you create a resolvers map manually. The `@nestjs/graphql` package, on the other hand, generates a resolvers map automatically using the metadata provided by the decorators. To demonstrate the library basics, we'll create a simple authors API.

#### Schema first[#](/graphql/resolvers-map#schema-first)

As mentioned in the [previous](/v6/graphql/quick-start) chapter, in the schema first approach we manually define our types in SDL (read [more](http://graphql.org/learn/schema/#type-language)).

```graphql

type Author {
  id: Int!
  firstName: String
  lastName: String
  posts: [Post]
}

type Post {
  id: Int!
  title: String!
  votes: Int
}

type Query {
  author(id: Int!): Author
}
```

Our GraphQL schema contains a single exposed query - `author(id: Int!): Author`. Now, let's create an `AuthorResolver`.

```typescript

@Resolver('Author')
export class AuthorResolver {
  constructor(
    private readonly authorsService: AuthorsService,
    private readonly postsService: PostsService,
  ) {}

  @Query()
  async author(@Args('id') id: number) {
    return this.authorsService.findOneById(id);
  }

  @ResolveProperty()
  async posts(@Parent() author) {
    const { id } = author;
    return this.postsService.findAll({ authorId: id });
  }
}
```

> **Hint** If you use the `@Resolver()` decorator, you don't have to mark a class as an `@Injectable()`.

The `@Resolver()` decorator does not affect queries and mutations (neither `@Query()` nor `@Mutation()` decorators). It only informs Nest that each `@ResolveProperty()` inside this particular class has a parent, which is an `Author` type in this case (`Author.posts` relation). Basically, instead of setting `@Resolver()` at the top of the class, this can be done close to the method:

```typescript

@Resolver('Author')
@ResolveProperty()
async posts(@Parent() author) {
  const { id } = author;
  return this.postsService.findAll({ authorId: id });
}
```

However, if you have multiple `@ResolveProperty()` decorators inside one class, you must add `@Resolver()` to all of them, which is not necessarily a good practice (as it creates extra overhead).

Conventionally, we would use something like `getAuthor()` or `getPosts()` as method names. We can easily do this by passing the real names as arguments of the decorator.

```typescript

@Resolver('Author')
export class AuthorResolver {
  constructor(
    private readonly authorsService: AuthorsService,
    private readonly postsService: PostsService,
  ) {}

  @Query('author')
  async getAuthor(@Args('id') id: number) {
    return this.authorsService.findOneById(id);
  }

  @ResolveProperty('posts')
  async getPosts(@Parent() author) {
    const { id } = author;
    return this.postsService.findAll({ authorId: id });
  }
}
```

> **Hint** The `@Resolver()` decorator can be used at the method-level as well.

#### Typings[#](/graphql/resolvers-map#typings)

Assuming that we have enabled the typings generation feature (with `outputAs: 'class'` as shown in the [previous](/v6/graphql/quick-start) chapter), once you run the application it should generate the following file:

```typescript

export class Author {
  id: number;
  firstName?: string;
  lastName?: string;
  posts?: Post[];
}

export class Post {
  id: number;
  title: string;
  votes?: number;
}

export abstract class IQuery {
  abstract author(id: number): Author | Promise<Author>;
}
```

Generating classes (instead of interfaces) allows you to use **decorators**, which makes them extremely useful for validation purposes (read [more](/v6/techniques/validation)). For example:

```typescript

import { MinLength, MaxLength } from 'class-validator';

export class CreatePostInput {
  @MinLength(3)
  @MaxLength(50)
  title: string;
}
```

> **Notice** To enable auto-validation of your inputs (and parameters), use `ValidationPipe`. Read more about validation [here](/v6/techniques/validation) or more specifically about pipes [here](/v6/pipes).

However, if you add decorators directly to the automatically generated file, they will be **overwritten** each time the file is generated. Instead, create a separate file and simply extend the generated class.

```typescript

import { MinLength, MaxLength } from 'class-validator';
import { Post } from '../../graphql.ts';

export class CreatePostInput extends Post {
  @MinLength(3)
  @MaxLength(50)
  title: string;
}
```

#### Code first[#](/graphql/resolvers-map#code-first)

In the code first approach, we don't write SDL by hand. Instead we use decorators.

```typescript

import { Field, Int, ObjectType } from 'type-graphql';
import { Post } from './post';

@ObjectType()
export class Author {
  @Field(type => Int)
  id: number;

  @Field({ nullable: true })
  firstName?: string;

  @Field({ nullable: true })
  lastName?: string;

  @Field(type => [Post])
  posts: Post[];
}
```

`Author` model has been created. Now, let's create the missing `Post` class.

```typescript

import { Field, Int, ObjectType } from 'type-graphql';

@ObjectType()
export class Post {
  @Field(type => Int)
  id: number;

  @Field()
  title: string;

  @Field(type => Int, { nullable: true })
  votes?: number;
}
```

With our models in place, we can move to the resolver class.

```typescript

@Resolver(of => Author)
export class AuthorResolver {
  constructor(
    private readonly authorsService: AuthorsService,
    private readonly postsService: PostsService,
  ) {}

  @Query(returns => Author)
  async author(@Args({ name: 'id', type: () => Int }) id: number) {
    return this.authorsService.findOneById(id);
  }

  @ResolveProperty()
  async posts(@Parent() author) {
    const { id } = author;
    return this.postsService.findAll({ authorId: id });
  }
}
```

Conventionally, we would use something like `getAuthor()` or `getPosts()` as method names. We can easily do this by passing the real names as arguments of the decorator.

```typescript

@Resolver(of => Author)
export class AuthorResolver {
  constructor(
    private readonly authorsService: AuthorsService,
    private readonly postsService: PostsService,
  ) {}

  @Query(returns => Author, { name: 'author' })
  async getAuthor(@Args({ name: 'id', type: () => Int }) id: number) {
    return this.authorsService.findOneById(id);
  }

  @ResolveProperty('posts', returns => [Post])
  async getPosts(@Parent() author) {
    const { id } = author;
    return this.postsService.findAll({ authorId: id });
  }
}
```

Usually, you won't have to pass such an object into the `@Args()` decorator. For example, if your identifier's type is string, the following construction would be sufficient:

```typescript

@Args('id') id: string
```

However, the `number` type doesn't give `type-graphql` enough information about the expected GraphQL representation (`Int` vs. `Float`). Thus we have to **explicitly** pass the type reference.

Moreover, you can create a dedicated `AuthorArgs` class:

```typescript

@Args() args: AuthorArgs
```

With the following body:

```typescript

@ArgsType()
class AuthorArgs {
  @Field(type => Int)
  @Min(1)
  id: number;
}
```

> **Hint**`Int` and both decorators `@Field()` and `@ArgsType()` are imported from the `type-graphql` package, while `@Min()` comes from the `class-validator`.

You may also notice that such classes play very well with the `ValidationPipe` (read [more](/v6/techniques/validation)).

## Hoodies, T-shirts, and accessories!

Support our future development by shopping in the official store!

[See more](https://nestjs.threadless.com/ "Shop | NestJS - A node.js framework built on top of TypeScript")

#### Decorators[#](/graphql/resolvers-map#decorators)

You may note that we refer to the following arguments using dedicated decorators. Below is a comparison of the provided decorators and the plain Apollo parameters they represent.

|                            |                              |
| -------------------------- | ---------------------------- |
| `@Root()` and `@Parent()`  | `root`/`parent`              |
| `@Context(param?: string)` | `context` / `context[param]` |
| `@Info(param?: string)`    | `info` / `info[param]`       |
| `@Args(param?: string)`    | `args` / `args[param]`       |

#### Module[#](/graphql/resolvers-map#module)

Once we're done here, we have to provide the `AuthorResolver` somewhere. For example, we can do this in the newly created `AuthorsModule`.

```typescript

@Module({
  imports: [PostsModule],
  providers: [AuthorsService, AuthorResolver],
})
export class AuthorsModule {}
```

The `GraphQLModule` will take care of reflecting the metadata and transforming classes into the correct resolvers map automatically. The only thing you need to be aware of is that you need to import this module somewhere, so Nest will be able to utilize `AuthorsModule`.

> **Hint** Learn more about GraphQL queries [here](http://graphql.org/learn/queries/).

----
url: https://docs.nestjs.com/fundamentals/injection-scopes
----

[Skip to content](#content)

On this page

* [Injection scopes](https://docs.nestjs.com/fundamentals/injection-scopes#injection-scopes)
* [Provider scope](https://docs.nestjs.com/fundamentals/injection-scopes#provider-scope)
* [Usage](https://docs.nestjs.com/fundamentals/injection-scopes#usage)
* [Controller scope](https://docs.nestjs.com/fundamentals/injection-scopes#controller-scope)
* [Scope hierarchy](https://docs.nestjs.com/fundamentals/injection-scopes#scope-hierarchy)
* [Request provider](https://docs.nestjs.com/fundamentals/injection-scopes#request-provider)
* [Inquirer provider](https://docs.nestjs.com/fundamentals/injection-scopes#inquirer-provider)
* [Performance](https://docs.nestjs.com/fundamentals/injection-scopes#performance)
* [Durable providers](https://docs.nestjs.com/fundamentals/injection-scopes#durable-providers)

### Injection scopes

If you come from a different programming language background, you might be surprised to learn that in Nest, almost everything is shared across incoming requests: a connection pool to the database, singleton services with global state, and so on. Node.js doesn't follow the multi-threaded stateless request/response model, in which every request is processed by a separate thread. Using singleton instances is therefore fully **safe** in Nest applications.

However, there are edge cases where a request-based lifetime is the desired behavior, e.g., per-request caching in GraphQL applications, request tracking, and multi-tenancy. Injection scopes let you obtain the provider lifetime you need.

#### Provider scope[#](/fundamentals/injection-scopes#provider-scope)

A provider can have any of the following scopes:

|             |                                                                                                                                                                                                                                                                        |
| ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `DEFAULT`   | A single instance of the provider is shared across the entire application. The instance lifetime is tied directly to the application lifecycle. Once the application has bootstrapped, all singleton providers have been instantiated. Singleton scope is the default. |
| `REQUEST`   | A new instance of the provider is created exclusively for each incoming **request**. The instance is garbage-collected after the request has been processed.                                                                                                           |
| `TRANSIENT` | Transient providers are not shared across consumers. Each consumer that injects a transient provider receives a new, dedicated instance.                                                                                                                               |

> **Hint** Singleton scope is **recommended** for most use cases. Sharing providers across consumers and across requests means that an instance can be cached, and its initialization occurs only once, during application startup.

#### Usage[#](/fundamentals/injection-scopes#usage)

Specify injection scope by passing the `scope` property to the `@Injectable()` decorator options object:

```typescript

import { Injectable, Scope } from '@nestjs/common';

@Injectable({ scope: Scope.REQUEST })
export class CatsService {}
```

Similarly, for [custom providers](/fundamentals/custom-providers), set the `scope` property in the long-hand form of the provider registration:

```typescript

{
  provide: 'CACHE_MANAGER',
  useClass: CacheManager,
  scope: Scope.TRANSIENT,
}
```

> **Hint** Import the `Scope` enum from `@nestjs/common`.

Singleton scope is the default and doesn't need to be declared. If you want to declare a provider as singleton-scoped explicitly, use the `Scope.DEFAULT` value for the `scope` property.

> **Hint** Starting with NestJS v12, WebSocket gateways support request-scoped providers. The scope is tied to the socket connection, not to a single message. See [Request-scoped gateways](/websockets/gateways#request-scoped-gateways).

> **Notice** Some providers must act as singletons and should not use request-scoped providers, like [*Passport strategies*](/recipes/passport#request-scoped-strategies) or *Cron controllers*.

#### Controller scope[#](/fundamentals/injection-scopes#controller-scope)

Controllers can also have a scope, which applies to all route handlers declared in that controller. Like provider scope, the scope of a controller declares its lifetime. For a request-scoped controller, a new instance is created for each inbound request and garbage-collected once the request has been processed.

Declare controller scope with the `scope` property of the `ControllerOptions` object:

```typescript

@Controller({
  path: 'cats',
  scope: Scope.REQUEST,
})
export class CatsController {}
```

#### Scope hierarchy[#](/fundamentals/injection-scopes#scope-hierarchy)

The `REQUEST` scope bubbles up the injection chain. A controller that depends on a request-scoped provider is itself request-scoped.

Consider the following dependency graph: `CatsController <- CatsService <- CatsRepository`. If `CatsService` is request-scoped (and the others are default singletons), `CatsController` becomes request-scoped, because it depends on the injected service. `CatsRepository`, which doesn't depend on `CatsService`, remains singleton-scoped.

Transient-scoped dependencies don't follow that pattern. If a singleton-scoped `DogsService` injects a transient `LoggerService` provider, it receives a fresh instance of it. However, `DogsService` stays singleton-scoped, so injecting it anywhere does *not* resolve to a new instance of `DogsService`. If you want that behavior, explicitly mark `DogsService` as `TRANSIENT` as well.

In an HTTP server-based application (e.g., using `@nestjs/platform-express` or `@nestjs/platform-fastify`), you may want to access a reference to the original request object when using request-scoped providers. To do so, inject the `REQUEST` object.

The `REQUEST` provider is inherently request-scoped, so you don't need to specify the `REQUEST` scope explicitly when using it (if you do, it is disregarded). Any provider that relies on a request-scoped provider automatically adopts request scope, and this behavior cannot be changed.

```typescript

import { Injectable, Scope, Inject } from '@nestjs/common';
import { REQUEST } from '@nestjs/core';
import { Request } from 'express';

@Injectable({ scope: Scope.REQUEST })
export class CatsService {
  constructor(@Inject(REQUEST) private request: Request) {}
}
```

Because of underlying platform and protocol differences, you access the inbound request slightly differently in microservice or GraphQL applications. In [GraphQL](/graphql/quick-start) applications, inject `CONTEXT` instead of `REQUEST`:

```typescript

import { Injectable, Scope, Inject } from '@nestjs/common';
import { CONTEXT } from '@nestjs/graphql';

@Injectable({ scope: Scope.REQUEST })
export class CatsService {
  constructor(@Inject(CONTEXT) private context) {}
}
```

Then configure your `context` value (in the `GraphQLModule`) to contain `request` as a property.

#### Inquirer provider[#](/fundamentals/injection-scopes#inquirer-provider)

To get the class in which a provider was constructed, e.g., in logging or metrics providers, inject the `INQUIRER` token:

```typescript

import { Inject, Injectable, Scope } from '@nestjs/common';
import { INQUIRER } from '@nestjs/core';

@Injectable({ scope: Scope.TRANSIENT })
export class HelloService {
  constructor(@Inject(INQUIRER) private parentClass: object) {}

  sayHello(message: string) {
    console.log(`${this.parentClass?.constructor?.name}: ${message}`);
  }
}
```

Then use it as follows:

```typescript

import { Injectable } from '@nestjs/common';
import { HelloService } from './hello.service.js';

@Injectable()
export class AppService {
  constructor(private helloService: HelloService) {}

  getRoot(): string {
    this.helloService.sayHello('My name is getRoot');

    return 'Hello world!';
  }
}
```

In the example above, when `AppService#getRoot` is called, `"AppService: My name is getRoot"` is logged to the console.

#### Performance[#](/fundamentals/injection-scopes#performance)

Request-scoped providers affect application performance. Although Nest caches as much metadata as possible, it still has to create an instance of your class on each request, which slows down your average response time and overall benchmark results. Unless a provider must be request-scoped, we strongly recommend using the default singleton scope.

> **Hint** A properly designed application that uses request-scoped providers should not see latency increase by more than \~5%.

Many providers are request-scoped only to read a value that belongs to the current request: the authenticated user, the tenant, or a locale. For that, a per-request store based on `AsyncLocalStorage` keeps every provider a singleton and works the same way in HTTP handlers, microservice message handlers, and queue jobs. If your application uses [NestJS Observe](/observability/overview), it already keeps such a store for every request, message, and job it instruments: write to it with `TracerService.setAttribute()` and read from anywhere downstream with `getAttribute()`, with no scope changes and no store of your own to maintain. See [Async local storage](/recipes/async-local-storage#nestjs-observe) for details and the alternatives.

#### Durable providers[#](/fundamentals/injection-scopes#durable-providers)

As mentioned in the previous section, request-scoped providers may increase latency, because having at least one request-scoped provider (injected into the controller instance, or deeper, into one of its providers) makes the controller request-scoped as well. The controller must then be recreated (instantiated) for each individual request and garbage-collected afterward. For, say, 30k requests in parallel, there are 30k ephemeral instances of the controller (and its request-scoped providers).

If a common provider that most providers depend on (think of a database connection or a logger service) is request-scoped, all of those providers automatically become request-scoped as well. This can pose a challenge in **multi-tenant applications**, especially those with a central request-scoped "data source" provider that reads headers or a token from the request object and, based on their values, retrieves the corresponding database connection or schema for that tenant.

For instance, suppose your application is used by 10 different customers. Each customer has its **own dedicated data source**, and you want to make sure customer A can never reach customer B's database. One way to achieve this is to declare a request-scoped "data source" provider that determines the "current customer" from the request object and retrieves the corresponding database. This approach turns your application into a multi-tenant application in a few minutes. Its major downside is that a large part of your application's components likely rely on the "data source" provider, so they implicitly become request-scoped, which degrades your application's performance.

With only 10 customers, you could instead have 10 individual [DI sub-trees](/fundamentals/module-ref#resolving-scoped-providers), one per customer, rather than recreating each tree per request. If your providers don't rely on any property that's truly unique to each request (e.g., a request UUID), but on specific attributes that let you aggregate (classify) requests, there's no reason to *recreate the DI sub-tree* on every incoming request.

This is where **durable providers** come in.

Before flagging providers as durable, you must register a **strategy** that tells Nest what those "common request attributes" are, and provides the logic that groups requests, i.e., associates them with their corresponding DI sub-trees.

```typescript

import {
  HostComponentInfo,
  ContextId,
  ContextIdFactory,
  ContextIdStrategy,
} from '@nestjs/core';
import { Request } from 'express';

const tenants = new Map<string, ContextId>();

export class AggregateByTenantContextIdStrategy implements ContextIdStrategy {
  attach(contextId: ContextId, request: Request) {
    const tenantId = request.headers['x-tenant-id'] as string;
    let tenantSubTreeId: ContextId;

    if (tenants.has(tenantId)) {
      tenantSubTreeId = tenants.get(tenantId);
    } else {
      tenantSubTreeId = ContextIdFactory.create();
      tenants.set(tenantId, tenantSubTreeId);
    }

    // If tree is not durable, return the original "contextId" object
    return (info: HostComponentInfo) =>
      info.isTreeDurable ? tenantSubTreeId : contextId;
  }
}
```

> **Hint** Like request scope, durability bubbles up the injection chain. If A depends on B, which is flagged as `durable`, A implicitly becomes durable too, provided that all of A's other request-scoped dependencies are durable as well (and unless A is explicitly declared with `Scope.REQUEST` and `durable: false`).

> **Warning** This strategy is not ideal for applications with a large number of tenants.

The value returned from the `attach` method tells Nest which context identifier to use for a given host. In this case, we specify that `tenantSubTreeId` should be used instead of the original, auto-generated `contextId` object when the host component (e.g., a request-scoped controller) is flagged as durable (you'll learn how to mark providers as durable below). Also, in the example above, **no payload** is registered (the payload being the `REQUEST`/`CONTEXT` provider that represents the "root", i.e., the parent of the sub-tree).

To register the payload for a durable tree, use the following construction instead:

```typescript

// The return of `AggregateByTenantContextIdStrategy#attach` method:
return {
  resolve: (info: HostComponentInfo) =>
    info.isTreeDurable ? tenantSubTreeId : contextId,
  payload: { tenantId },
};
```

Now, whenever you inject the `REQUEST` provider (or `CONTEXT` for GraphQL applications) with `@Inject(REQUEST)`/`@Inject(CONTEXT)`, the `payload` object is injected (consisting of a single property, `tenantId`, in this case).

With this strategy in place, register it anywhere in your code (it applies globally), e.g., in the `main.ts` file:

```typescript

ContextIdFactory.apply(new AggregateByTenantContextIdStrategy());
```

> **Hint** The `ContextIdFactory` class is imported from the `@nestjs/core` package.

As long as the registration occurs before any request hits your application, everything works as intended.

Finally, to turn a regular provider into a durable provider, set the `durable` flag to `true` and change its scope to `Scope.REQUEST`. Nest reads the `durable` flag only on providers explicitly declared with `Scope.REQUEST`; a provider that is request-scoped only implicitly (through its dependencies) derives its durability from those dependencies, as described in the hint above.

```typescript

import { Injectable, Scope } from '@nestjs/common';

@Injectable({ scope: Scope.REQUEST, durable: true })
export class CatsService {}
```

Similarly, for [custom providers](/fundamentals/custom-providers), set the `durable` property in the long-hand form of the provider registration:

```typescript

{
  provide: 'foobar',
  useFactory: () => { ... },
  scope: Scope.REQUEST,
  durable: true,
}
```

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/fundamentals/provider-scopes.md)

----
url: https://docs.nestjs.com/v10/techniques/session
----

* [Session](https://docs.nestjs.com/v10/techniques/session#session)
* [Use with Express (default)](https://docs.nestjs.com/v10/techniques/session#use-with-express-default)
* [Use with Fastify](https://docs.nestjs.com/v10/techniques/session#use-with-fastify)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/techniques/sessions.md "Suggest Edits")

### Session

**HTTP sessions** provide a way to store information about the user across multiple requests, which is particularly useful for [MVC](/v10/techniques/mvc) applications.

#### Use with Express (default)[#](/techniques/session#use-with-express-default)

First install the [required package](https://github.com/expressjs/session) (and its types for TypeScript users):

```shell

$ npm i express-session
$ npm i -D @types/express-session
```

Once the installation is complete, apply the `express-session` middleware as global middleware (for example, in your `main.ts` file).

```typescript

import * as session from 'express-session';
// somewhere in your initialization file
app.use(
  session({
    secret: 'my-secret',
    resave: false,
    saveUninitialized: false,
  }),
);
```

> **Notice** The default server-side session storage is purposely not designed for a production environment. It will leak memory under most conditions, does not scale past a single process, and is meant for debugging and developing. Read more in the [official repository](https://github.com/expressjs/session).

The `secret` is used to sign the session ID cookie. This can be either a string for a single secret, or an array of multiple secrets. If an array of secrets is provided, only the first element will be used to sign the session ID cookie, while all the elements will be considered when verifying the signature in requests. The secret itself should be not easily parsed by a human and would best be a random set of characters.

Enabling the `resave` option forces the session to be saved back to the session store, even if the session was never modified during the request. The default value is `true`, but using the default has been deprecated, as the default will change in the future.

Likewise, enabling the `saveUninitialized` option Forces a session that is "uninitialized" to be saved to the store. A session is uninitialized when it is new but not modified. Choosing `false` is useful for implementing login sessions, reducing server storage usage, or complying with laws that require permission before setting a cookie. Choosing `false` will also help with race conditions where a client makes multiple parallel requests without a session ([source](https://github.com/expressjs/session#saveuninitialized)).

You can pass several other options to the `session` middleware, read more about them in the [API documentation](https://github.com/expressjs/session#options).

> **Hint** Please note that `secure: true` is a recommended option. However, it requires an https-enabled website, i.e., HTTPS is necessary for secure cookies. If secure is set, and you access your site over HTTP, the cookie will not be set. If you have your node.js behind a proxy and are using `secure: true`, you need to set `"trust proxy"` in express.

With this in place, you can now set and read session values from within the route handlers, as follows:

```typescript

@Get()
findAll(@Req() request: Request) {
  request.session.visits = request.session.visits ? request.session.visits + 1 : 1;
}
```

> **Hint** The `@Req()` decorator is imported from the `@nestjs/common`, while `Request` from the `express` package.

Alternatively, you can use the `@Session()` decorator to extract a session object from the request, as follows:

```typescript

@Get()
findAll(@Session() session: Record<string, any>) {
  session.visits = session.visits ? session.visits + 1 : 1;
}
```

> **Hint** The `@Session()` decorator is imported from the `@nestjs/common` package.

#### Use with Fastify[#](/techniques/session#use-with-fastify)

First install the required package:

```shell

$ npm i @fastify/secure-session
```

Once the installation is complete, register the `fastify-secure-session` plugin:

```typescript

import secureSession from '@fastify/secure-session';

// somewhere in your initialization file
const app = await NestFactory.create<NestFastifyApplication>(
  AppModule,
  new FastifyAdapter(),
);
await app.register(secureSession, {
  secret: 'averylogphrasebiggerthanthirtytwochars',
  salt: 'mq9hDxBVDbspDR6n',
});
```

> **Hint** You can also pregenerate a key ([see instructions](https://github.com/fastify/fastify-secure-session)) or use [keys rotation](https://github.com/fastify/fastify-secure-session#using-keys-with-key-rotation).

Read more about the available options in the [official repository](https://github.com/fastify/fastify-secure-session).

With this in place, you can now set and read session values from within the route handlers, as follows:

```typescript

@Get()
findAll(@Req() request: FastifyRequest) {
  const visits = request.session.get('visits');
  request.session.set('visits', visits ? visits + 1 : 1);
}
```

Alternatively, you can use the `@Session()` decorator to extract a session object from the request, as follows:

```typescript

@Get()
findAll(@Session() session: secureSession.Session) {
  const visits = session.get('visits');
  session.set('visits', visits ? visits + 1 : 1);
}
```

> **Hint** The `@Session()` decorator is imported from the `@nestjs/common`, while `secureSession.Session` from the `@fastify/secure-session` package (import statement: `import * as secureSession from '@fastify/secure-session'`).

----
url: https://docs.nestjs.com/v5/microservices/pipes
----

### Pipes

There is no difference between microservices **pipes** and the [regular pipes](/v5/pipes). The only thing you should be aware of is that instead of throwing `HttpException`, you should use the `RpcException`.

> **Hint** The `RpcException` class is exposed from `@nestjs/microservices` package.

#### Binding pipes

Here is an example that makes use of a manually instantiated **method-scoped** pipe (class-scoped works either):

TypeScript

```typescript

@UsePipes(new ValidationPipe())
@MessagePattern({ cmd: 'sum' })
sum(data: number[]): number {
  return (data || []).reduce((a, b) => a + b);
}
```

----
url: https://docs.nestjs.com/v9/techniques/session
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Session](https://docs.nestjs.com/v9/techniques/session#session)
* [Use with Express (default)](https://docs.nestjs.com/v9/techniques/session#use-with-express-default)
* [Use with Fastify](https://docs.nestjs.com/v9/techniques/session#use-with-fastify)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/techniques/sessions.md "Suggest Edits")

### Session

**HTTP sessions** provide a way to store information about the user across multiple requests, which is particularly useful for [MVC](/v9/techniques/mvc) applications.

#### Use with Express (default)[#](/techniques/session#use-with-express-default)

First install the [required package](https://github.com/expressjs/session) (and its types for TypeScript users):

```shell

$ npm i express-session
$ npm i -D @types/express-session
```

Once the installation is complete, apply the `express-session` middleware as global middleware (for example, in your `main.ts` file).

```typescript

import * as session from 'express-session';
// somewhere in your initialization file
app.use(
  session({
    secret: 'my-secret',
    resave: false,
    saveUninitialized: false,
  }),
);
```

> **Notice** The default server-side session storage is purposely not designed for a production environment. It will leak memory under most conditions, does not scale past a single process, and is meant for debugging and developing. Read more in the [official repository](https://github.com/expressjs/session).

The `secret` is used to sign the session ID cookie. This can be either a string for a single secret, or an array of multiple secrets. If an array of secrets is provided, only the first element will be used to sign the session ID cookie, while all the elements will be considered when verifying the signature in requests. The secret itself should be not easily parsed by a human and would best be a random set of characters.

Enabling the `resave` option forces the session to be saved back to the session store, even if the session was never modified during the request. The default value is `true`, but using the default has been deprecated, as the default will change in the future.

Likewise, enabling the `saveUninitialized` option Forces a session that is "uninitialized" to be saved to the store. A session is uninitialized when it is new but not modified. Choosing `false` is useful for implementing login sessions, reducing server storage usage, or complying with laws that require permission before setting a cookie. Choosing `false` will also help with race conditions where a client makes multiple parallel requests without a session ([source](https://github.com/expressjs/session#saveuninitialized)).

You can pass several other options to the `session` middleware, read more about them in the [API documentation](https://github.com/expressjs/session#options).

> **Hint** Please note that `secure: true` is a recommended option. However, it requires an https-enabled website, i.e., HTTPS is necessary for secure cookies. If secure is set, and you access your site over HTTP, the cookie will not be set. If you have your node.js behind a proxy and are using `secure: true`, you need to set `"trust proxy"` in express.

With this in place, you can now set and read session values from within the route handlers, as follows:

```typescript

@Get()
findAll(@Req() request: Request) {
  request.session.visits = request.session.visits ? request.session.visits + 1 : 1;
}
```

> **Hint** The `@Req()` decorator is imported from the `@nestjs/common`, while `Request` from the `express` package.

Alternatively, you can use the `@Session()` decorator to extract a session object from the request, as follows:

```typescript

@Get()
findAll(@Session() session: Record<string, any>) {
  session.visits = session.visits ? session.visits + 1 : 1;
}
```

> **Hint** The `@Session()` decorator is imported from the `@nestjs/common` package.

#### Use with Fastify[#](/techniques/session#use-with-fastify)

First install the required package:

```shell

$ npm i @fastify/secure-session
```

Once the installation is complete, register the `fastify-secure-session` plugin:

```typescript

import secureSession from '@fastify/secure-session';

// somewhere in your initialization file
const app = await NestFactory.create<NestFastifyApplication>(
  AppModule,
  new FastifyAdapter(),
);
await app.register(secureSession, {
  secret: 'averylogphrasebiggerthanthirtytwochars',
  salt: 'mq9hDxBVDbspDR6n',
});
```

> **Hint** You can also pregenerate a key ([see instructions](https://github.com/fastify/fastify-secure-session)) or use [keys rotation](https://github.com/fastify/fastify-secure-session#using-keys-with-key-rotation).

Read more about the available options in the [official repository](https://github.com/fastify/fastify-secure-session).

With this in place, you can now set and read session values from within the route handlers, as follows:

```typescript

@Get()
findAll(@Req() request: FastifyRequest) {
  const visits = request.session.get('visits');
  request.session.set('visits', visits ? visits + 1 : 1);
}
```

Alternatively, you can use the `@Session()` decorator to extract a session object from the request, as follows:

```typescript

@Get()
findAll(@Session() session: secureSession.Session) {
  const visits = session.get('visits');
  session.set('visits', visits ? visits + 1 : 1);
}
```

> **Hint** The `@Session()` decorator is imported from the `@nestjs/common`, while `secureSession.Session` from the `@fastify/secure-session` package (import statement: `import * as secureSession from '@fastify/secure-session'`).

----
url: https://docs.nestjs.com/v9/recipes/prisma
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Prisma](https://docs.nestjs.com/v9/recipes/prisma#prisma)
* [Getting started](https://docs.nestjs.com/v9/recipes/prisma#getting-started)
* [Create your NestJS project](https://docs.nestjs.com/v9/recipes/prisma#create-your-nestjs-project)
* [Set up Prisma](https://docs.nestjs.com/v9/recipes/prisma#set-up-prisma)
* [Set the database connection](https://docs.nestjs.com/v9/recipes/prisma#set-the-database-connection)
* [Create two database tables with Prisma Migrate](https://docs.nestjs.com/v9/recipes/prisma#create-two-database-tables-with-prisma-migrate)
* [Install and generate Prisma Client](https://docs.nestjs.com/v9/recipes/prisma#install-and-generate-prisma-client)
* [Use Prisma Client in your NestJS services](https://docs.nestjs.com/v9/recipes/prisma#use-prisma-client-in-your-nestjs-services)
* [Issues with enableShutdownHooks](https://docs.nestjs.com/v9/recipes/prisma#issues-with-enableshutdownhooks)
* [Summary](https://docs.nestjs.com/v9/recipes/prisma#summary)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/recipes/prisma.md "Suggest Edits")

### Prisma

[Prisma](https://www.prisma.io) is an [open-source](https://github.com/prisma/prisma) ORM for Node.js and TypeScript. It is used as an **alternative** to writing plain SQL, or using another database access tool such as SQL query builders (like [knex.js](https://knexjs.org/)) or ORMs (like [TypeORM](https://typeorm.io/) and [Sequelize](https://sequelize.org/)). Prisma currently supports PostgreSQL, MySQL, SQL Server, SQLite, MongoDB and CockroachDB ([Preview](https://www.prisma.io/docs/reference/database-reference/supported-databases)).

While Prisma can be used with plain JavaScript, it embraces TypeScript and provides a level to type-safety that goes beyond the guarantees other ORMs in the TypeScript ecosystem. You can find an in-depth comparison of the type-safety guarantees of Prisma and TypeORM [here](https://www.prisma.io/docs/concepts/more/comparisons/prisma-and-typeorm#type-safety).

> **Note** If you want to get a quick overview of how Prisma works, you can follow the [Quickstart](https://www.prisma.io/docs/getting-started/quickstart) or read the [Introduction](https://www.prisma.io/docs/understand-prisma/introduction) in the [documentation](https://www.prisma.io/docs/). There also are ready-to-run examples for [REST](https://github.com/prisma/prisma-examples/tree/latest/typescript/rest-nestjs) and [GraphQL](https://github.com/prisma/prisma-examples/tree/latest/typescript/graphql-nestjs) in the [`prisma-examples`](https://github.com/prisma/prisma-examples/) repo.

#### Getting started[#](/recipes/prisma#getting-started)

In this recipe, you'll learn how to get started with NestJS and Prisma from scratch. You are going to build a sample NestJS application with a REST API that can read and write data in a database.

For the purpose of this guide, you'll use a [SQLite](https://sqlite.org/) database to save the overhead of setting up a database server. Note that you can still follow this guide, even if you're using PostgreSQL or MySQL – you'll get extra instructions for using these databases at the right places.

> **Note** If you already have an existing project and consider migrating to Prisma, you can follow the guide for [adding Prisma to an existing project](https://www.prisma.io/docs/getting-started/setup-prisma/add-to-existing-project-typescript-postgres). If you are migrating from TypeORM, you can read the guide [Migrating from TypeORM to Prisma](https://www.prisma.io/docs/guides/migrate-to-prisma/migrate-from-typeorm).

#### Create your NestJS project[#](/recipes/prisma#create-your-nestjs-project)

To get started, install the NestJS CLI and create your app skeleton with the following commands:

```bash

$ npm install -g @nestjs/cli
$ nest new hello-prisma
```

See the [First steps](https://docs.nestjs.com/first-steps) page to learn more about the project files created by this command. Note also that you can now run `npm start` to start your application. The REST API running at `http://localhost:3000/` currently serves a single route that's implemented in `src/app.controller.ts`. Over the course of this guide, you'll implement additional routes to store and retrieve data about *users* and *posts*.

#### Set up Prisma[#](/recipes/prisma#set-up-prisma)

Start by installing the Prisma CLI as a development dependency in your project:

```bash

$ cd hello-prisma
$ npm install prisma --save-dev
```

In the following steps, we'll be utilizing the [Prisma CLI](https://www.prisma.io/docs/reference/tools-and-interfaces/prisma-cli). As a best practice, it's recommended to invoke the CLI locally by prefixing it with `npx`:

```bash

$ npx prisma
```

Expand if you're using Yarn

If you're using Yarn, then you can install the Prisma CLI as follows:

```bash

$ yarn add prisma --dev
```

Once installed, you can invoke it by prefixing it with `yarn`:

```bash

$ yarn prisma
```

Now create your initial Prisma setup using the `init` command of the Prisma CLI:

```bash

$ npx prisma init
```

This command creates a new `prisma` directory with the following contents:

* `schema.prisma`: Specifies your database connection and contains the database schema
* `.env`: A [dotenv](https://github.com/motdotla/dotenv) file, typically used to store your database credentials in a group of environment variables

#### Set the database connection[#](/recipes/prisma#set-the-database-connection)

Your database connection is configured in the `datasource` block in your `schema.prisma` file. By default it's set to `postgresql`, but since you're using a SQLite database in this guide you need to adjust the `provider` field of the `datasource` block to `sqlite`:

```groovy

datasource db {
  provider = "sqlite"
  url      = env("DATABASE_URL")
}

generator client {
  provider = "prisma-client-js"
}
```

Now, open up `.env` and adjust the `DATABASE_URL` environment variable to look as follows:

```bash

DATABASE_URL="file:./dev.db"
```

SQLite databases are simple files; no server is required to use a SQLite database. So instead of configuring a connection URL with a *host* and *port*, you can just point it to a local file which in this case is called `dev.db`. This file will be created in the next step.

Expand if you're using PostgreSQL or MySQL

With PostgreSQL and MySQL, you need to configure the connection URL to point to the *database server*. You can learn more about the required connection URL format [here](https://www.prisma.io/docs/reference/database-reference/connection-urls).

**PostgreSQL**

If you're using PostgreSQL, you have to adjust the `schema.prisma` and `.env` files as follows:

**`schema.prisma`**

```groovy

datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}

generator client {
  provider = "prisma-client-js"
}
```

**`.env`**

```bash

DATABASE_URL="postgresql://USER:PASSWORD@HOST:PORT/DATABASE?schema=SCHEMA"
```

Replace the placeholders spelled in all uppercase letters with your database credentials. Note that if you're unsure what to provide for the `SCHEMA` placeholder, it's most likely the default value `public`:

```bash

DATABASE_URL="postgresql://USER:PASSWORD@HOST:PORT/DATABASE?schema=public"
```

If you want to learn how to set up a PostgreSQL database, you can follow this guide on [setting up a free PostgreSQL database on Heroku](https://dev.to/prisma/how-to-setup-a-free-postgresql-database-on-heroku-1dc1).

**MySQL**

If you're using MySQL, you have to adjust the `schema.prisma` and `.env` files as follows:

**`schema.prisma`**

```groovy

datasource db {
  provider = "mysql"
  url      = env("DATABASE_URL")
}

generator client {
  provider = "prisma-client-js"
}
```

**`.env`**

```bash

DATABASE_URL="mysql://USER:PASSWORD@HOST:PORT/DATABASE"
```

Replace the placeholders spelled in all uppercase letters with your database credentials.

#### Create two database tables with Prisma Migrate[#](/recipes/prisma#create-two-database-tables-with-prisma-migrate)

In this section, you'll create two new tables in your database using [Prisma Migrate](https://www.prisma.io/docs/concepts/components/prisma-migrate). Prisma Migrate generates SQL migration files for your declarative data model definition in the Prisma schema. These migration files are fully customizable so that you can configure any additional features of the underlying database or include additional commands, e.g. for seeding.

Add the following two models to your `schema.prisma` file:

```groovy

model User {
  id    Int     @default(autoincrement()) @id
  email String  @unique
  name  String?
  posts Post[]
}

model Post {
  id        Int      @default(autoincrement()) @id
  title     String
  content   String?
  published Boolean? @default(false)
  author    User?    @relation(fields: [authorId], references: [id])
  authorId  Int?
}
```

With your Prisma models in place, you can generate your SQL migration files and run them against the database. Run the following commands in your terminal:

```bash

$ npx prisma migrate dev --name init
```

This `prisma migrate dev` command generates SQL files and directly runs them against the database. In this case, the following migration files was created in the existing `prisma` directory:

```bash

$ tree prisma
prisma
├── dev.db
├── migrations
│   └── 20201207100915_init
│       └── migration.sql
└── schema.prisma
```

Expand to view the generated SQL statements

The following tables were created in your SQLite database:

```sql

-- CreateTable
CREATE TABLE "User" (
    "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
    "email" TEXT NOT NULL,
    "name" TEXT
);

-- CreateTable
CREATE TABLE "Post" (
    "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
    "title" TEXT NOT NULL,
    "content" TEXT,
    "published" BOOLEAN DEFAULT false,
    "authorId" INTEGER,

    FOREIGN KEY ("authorId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE
);

-- CreateIndex
CREATE UNIQUE INDEX "User.email_unique" ON "User"("email");
```

#### Install and generate Prisma Client[#](/recipes/prisma#install-and-generate-prisma-client)

Prisma Client is a type-safe database client that's *generated* from your Prisma model definition. Because of this approach, Prisma Client can expose [CRUD](https://www.prisma.io/docs/concepts/components/prisma-client/crud) operations that are *tailored* specifically to your models.

To install Prisma Client in your project, run the following command in your terminal:

```bash

$ npm install @prisma/client
```

Note that during installation, Prisma automatically invokes the `prisma generate` command for you. In the future, you need to run this command after *every* change to your Prisma models to update your generated Prisma Client.

> **Note** The `prisma generate` command reads your Prisma schema and updates the generated Prisma Client library inside `node_modules/@prisma/client`.

#### Use Prisma Client in your NestJS services[#](/recipes/prisma#use-prisma-client-in-your-nestjs-services)

You're now able to send database queries with Prisma Client. If you want to learn more about building queries with Prisma Client, check out the [API documentation](https://www.prisma.io/docs/reference/tools-and-interfaces/prisma-client/crud).

When setting up your NestJS application, you'll want to abstract away the Prisma Client API for database queries within a service. To get started, you can create a new `PrismaService` that takes care of instantiating `PrismaClient` and connecting to your database.

Inside the `src` directory, create a new file called `prisma.service.ts` and add the following code to it:

```typescript

import { INestApplication, Injectable, OnModuleInit } from '@nestjs/common';
import { PrismaClient } from '@prisma/client';

@Injectable()
export class PrismaService extends PrismaClient implements OnModuleInit {
  async onModuleInit() {
    await this.$connect();
  }

  async enableShutdownHooks(app: INestApplication) {
    this.$on('beforeExit', async () => {
      await app.close();
    });
  }
}
```

> **Note** The `onModuleInit` is optional — if you leave it out, Prisma will connect lazily on its first call to the database. We don't bother with `onModuleDestroy`, since Prisma has its own shutdown hooks where it will destroy the connection. For more info on `enableShutdownHooks`, please see [Issues with `enableShutdownHooks`](recipes/prisma#issues-with-enableshutdownhooks)

Next, you can write services that you can use to make database calls for the `User` and `Post` models from your Prisma schema.

Still inside the `src` directory, create a new file called `user.service.ts` and add the following code to it:

```typescript

import { Injectable } from '@nestjs/common';
import { PrismaService } from './prisma.service';
import { User, Prisma } from '@prisma/client';

@Injectable()
export class UserService {
  constructor(private prisma: PrismaService) {}

  async user(
    userWhereUniqueInput: Prisma.UserWhereUniqueInput,
  ): Promise<User | null> {
    return this.prisma.user.findUnique({
      where: userWhereUniqueInput,
    });
  }

  async users(params: {
    skip?: number;
    take?: number;
    cursor?: Prisma.UserWhereUniqueInput;
    where?: Prisma.UserWhereInput;
    orderBy?: Prisma.UserOrderByWithRelationInput;
  }): Promise<User[]> {
    const { skip, take, cursor, where, orderBy } = params;
    return this.prisma.user.findMany({
      skip,
      take,
      cursor,
      where,
      orderBy,
    });
  }

  async createUser(data: Prisma.UserCreateInput): Promise<User> {
    return this.prisma.user.create({
      data,
    });
  }

  async updateUser(params: {
    where: Prisma.UserWhereUniqueInput;
    data: Prisma.UserUpdateInput;
  }): Promise<User> {
    const { where, data } = params;
    return this.prisma.user.update({
      data,
      where,
    });
  }

  async deleteUser(where: Prisma.UserWhereUniqueInput): Promise<User> {
    return this.prisma.user.delete({
      where,
    });
  }
}
```

Notice how you're using Prisma Client's generated types to ensure that the methods that are exposed by your service are properly typed. You therefore save the boilerplate of typing your models and creating additional interface or DTO files.

Now do the same for the `Post` model.

Still inside the `src` directory, create a new file called `post.service.ts` and add the following code to it:

```typescript

import { Injectable } from '@nestjs/common';
import { PrismaService } from './prisma.service';
import { Post, Prisma } from '@prisma/client';

@Injectable()
export class PostService {
  constructor(private prisma: PrismaService) {}

  async post(
    postWhereUniqueInput: Prisma.PostWhereUniqueInput,
  ): Promise<Post | null> {
    return this.prisma.post.findUnique({
      where: postWhereUniqueInput,
    });
  }

  async posts(params: {
    skip?: number;
    take?: number;
    cursor?: Prisma.PostWhereUniqueInput;
    where?: Prisma.PostWhereInput;
    orderBy?: Prisma.PostOrderByWithRelationInput;
  }): Promise<Post[]> {
    const { skip, take, cursor, where, orderBy } = params;
    return this.prisma.post.findMany({
      skip,
      take,
      cursor,
      where,
      orderBy,
    });
  }

  async createPost(data: Prisma.PostCreateInput): Promise<Post> {
    return this.prisma.post.create({
      data,
    });
  }

  async updatePost(params: {
    where: Prisma.PostWhereUniqueInput;
    data: Prisma.PostUpdateInput;
  }): Promise<Post> {
    const { data, where } = params;
    return this.prisma.post.update({
      data,
      where,
    });
  }

  async deletePost(where: Prisma.PostWhereUniqueInput): Promise<Post> {
    return this.prisma.post.delete({
      where,
    });
  }
}
```

Your `UserService` and `PostService` currently wrap the CRUD queries that are available in Prisma Client. In a real world application, the service would also be the place to add business logic to your application. For example, you could have a method called `updatePassword` inside the `UserService` that would be responsible for updating the password of a user.

##### Implement your REST API routes in the main app controller

Finally, you'll use the services you created in the previous sections to implement the different routes of your app. For the purpose of this guide, you'll put all your routes into the already existing `AppController` class.

Replace the contents of the `app.controller.ts` file with the following code:

```typescript

import {
  Controller,
  Get,
  Param,
  Post,
  Body,
  Put,
  Delete,
} from '@nestjs/common';
import { UserService } from './user.service';
import { PostService } from './post.service';
import { User as UserModel, Post as PostModel } from '@prisma/client';

@Controller()
export class AppController {
  constructor(
    private readonly userService: UserService,
    private readonly postService: PostService,
  ) {}

  @Get('post/:id')
  async getPostById(@Param('id') id: string): Promise<PostModel> {
    return this.postService.post({ id: Number(id) });
  }

  @Get('feed')
  async getPublishedPosts(): Promise<PostModel[]> {
    return this.postService.posts({
      where: { published: true },
    });
  }

  @Get('filtered-posts/:searchString')
  async getFilteredPosts(
    @Param('searchString') searchString: string,
  ): Promise<PostModel[]> {
    return this.postService.posts({
      where: {
        OR: [
          {
            title: { contains: searchString },
          },
          {
            content: { contains: searchString },
          },
        ],
      },
    });
  }

  @Post('post')
  async createDraft(
    @Body() postData: { title: string; content?: string; authorEmail: string },
  ): Promise<PostModel> {
    const { title, content, authorEmail } = postData;
    return this.postService.createPost({
      title,
      content,
      author: {
        connect: { email: authorEmail },
      },
    });
  }

  @Post('user')
  async signupUser(
    @Body() userData: { name?: string; email: string },
  ): Promise<UserModel> {
    return this.userService.createUser(userData);
  }

  @Put('publish/:id')
  async publishPost(@Param('id') id: string): Promise<PostModel> {
    return this.postService.updatePost({
      where: { id: Number(id) },
      data: { published: true },
    });
  }

  @Delete('post/:id')
  async deletePost(@Param('id') id: string): Promise<PostModel> {
    return this.postService.deletePost({ id: Number(id) });
  }
}
```

    * `title: String` (required): The title of the post
    * `content: String` (optional): The content of the post
    * `authorEmail: String` (required): The email of the user that creates the post

* `/user`: Create a new user

  * Body:

    * `email: String` (required): The email address of the user
    * `name: String` (optional): The name of the user

###### `PUT`

* `/publish/:id`: Publish a post by its `id`

###### `DELETE`

* `/post/:id`: Delete a post by its `id`

#### Issues with `enableShutdownHooks`[#](/recipes/prisma#issues-with-enableshutdownhooks)

Prisma interferes with NestJS `enableShutdownHooks`. Prisma listens for shutdown signals and will call `process.exit()` before your application shutdown hooks fire. To deal with this, you would need to add a listener for Prisma `beforeExit` event.

```typescript

// main.ts
...
import { PrismaService } from './services/prisma/prisma.service';
...
async function bootstrap() {
  ...
  const prismaService = app.get(PrismaService);
  await prismaService.enableShutdownHooks(app)
  ...
}
bootstrap()
```

----
url: https://docs.nestjs.com/v8/microservices/guards
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Guards](https://docs.nestjs.com/v8/microservices/guards#guards)
* [Binding guards](https://docs.nestjs.com/v8/microservices/guards#binding-guards)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/microservices/guards.md "Suggest Edits")

### Guards

There is no fundamental difference between microservices guards and [regular HTTP application guards](/v8/guards). The only difference is that instead of throwing `HttpException`, you should use `RpcException`.

> **Hint** The `RpcException` class is exposed from `@nestjs/microservices` package.

#### Binding guards[#](/microservices/guards#binding-guards)

The following example uses a method-scoped guard. Just as with HTTP based applications, you can also use controller-scoped guards (i.e., prefix the controller class with a `@UseGuards()` decorator).

JS TS

```typescript

@UseGuards(AuthGuard)
@MessagePattern({ cmd: 'sum' })
accumulate(data: number[]): number {
  return (data || []).reduce((a, b) => a + b);
}
```

```typescript

@UseGuards(AuthGuard)
@MessagePattern({ cmd: 'sum' })
accumulate(data) {
  return (data || []).reduce((a, b) => a + b);
}
```

----
url: https://docs.nestjs.com/v7/recipes/mongodb
----

* [MongoDB (Mongoose)](https://docs.nestjs.com/v7/recipes/mongodb#mongodb-mongoose)
* [Getting started](https://docs.nestjs.com/v7/recipes/mongodb#getting-started)
* [Model injection](https://docs.nestjs.com/v7/recipes/mongodb#model-injection)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/recipes/mongodb.md "Suggest Edits")

### MongoDB (Mongoose)

> **Warning** In this article, you'll learn how to create a `DatabaseModule` based on the **Mongoose** package from scratch using custom components. As a consequence, this solution contains a lot of overhead that you can omit using ready to use and available out-of-the-box dedicated `@nestjs/mongoose` package. To learn more, see [here](/v7/techniques/mongodb).

[Mongoose](https://mongoosejs.com) is the most popular [MongoDB](https://www.mongodb.org/) object modeling tool.

#### Getting started[#](/recipes/mongodb#getting-started)

To start the adventure with this library we have to install all required dependencies:

```typescript

$ npm install --save mongoose
```

The first step we need to do is to establish the connection with our database using `connect()` function. The `connect()` function returns a `Promise`, and therefore we have to create an [async provider](/v7/fundamentals/async-components).

database.providers.ts

JS TS

```typescript

import * as mongoose from 'mongoose';

export const databaseProviders = [
  {
    provide: 'DATABASE_CONNECTION',
    useFactory: (): Promise<typeof mongoose> =>
      mongoose.connect('mongodb://localhost/nest'),
  },
];
```

```typescript

import * as mongoose from 'mongoose';

export const databaseProviders = [
  {
    provide: 'DATABASE_CONNECTION',
    useFactory: () => mongoose.connect('mongodb://localhost/nest'),
  },
];
```

> **Hint** Following best practices, we declared the custom provider in the separated file which has a `*.providers.ts` suffix.

Then, we need to export these providers to make them **accessible** for the rest part of the application.

database.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { databaseProviders } from './database.providers';

@Module({
  providers: [...databaseProviders],
  exports: [...databaseProviders],
})
export class DatabaseModule {}
```

Now we can inject the `Connection` object using `@Inject()` decorator. Each class that would depend on the `Connection` async provider will wait until a `Promise` is resolved.

#### Model injection[#](/recipes/mongodb#model-injection)

With Mongoose, everything is derived from a [Schema](https://mongoosejs.com/docs/guide.html). Let's define the `CatSchema`:

schemas/cat.schema.ts

JS TS

```typescript

import * as mongoose from 'mongoose';

export const CatSchema = new mongoose.Schema({
  name: String,
  age: Number,
  breed: String,
});
```

The `CatsSchema` belongs to the `cats` directory. This directory represents the `CatsModule`.

Now it's time to create a **Model** provider:

cats.providers.ts

JS TS

```typescript

import { Connection } from 'mongoose';
import { CatSchema } from './schemas/cat.schema';

export const catsProviders = [
  {
    provide: 'CAT_MODEL',
    useFactory: (connection: Connection) => connection.model('Cat', CatSchema),
    inject: ['DATABASE_CONNECTION'],
  },
];
```

```typescript

import { CatSchema } from './schemas/cat.schema';

export const catsProviders = [
  {
    provide: 'CAT_MODEL',
    useFactory: (connection) => connection.model('Cat', CatSchema),
    inject: ['DATABASE_CONNECTION'],
  },
];
```

> **Warning** In the real-world applications you should avoid **magic strings**. Both `CAT_MODEL` and `DATABASE_CONNECTION` should be kept in the separated `constants.ts` file.

Now we can inject the `CAT_MODEL` to the `CatsService` using the `@Inject()` decorator:

cats.service.ts

JS TS

```typescript

import { Model } from 'mongoose';
import { Injectable, Inject } from '@nestjs/common';
import { Cat } from './interfaces/cat.interface';
import { CreateCatDto } from './dto/create-cat.dto';

@Injectable()
export class CatsService {
  constructor(
    @Inject('CAT_MODEL')
    private catModel: Model<Cat>,
  ) {}

  async create(createCatDto: CreateCatDto): Promise<Cat> {
    const createdCat = new this.catModel(createCatDto);
    return createdCat.save();
  }

  async findAll(): Promise<Cat[]> {
    return this.catModel.find().exec();
  }
}
```

```typescript

import { Injectable, Dependencies } from '@nestjs/common';

@Injectable()
@Dependencies('CAT_MODEL')
export class CatsService {
  constructor(catModel) {
    this.catModel = catModel;
  }

  async create(createCatDto) {
    const createdCat = new this.catModel(createCatDto);
    return createdCat.save();
  }

  async findAll() {
    return this.catModel.find().exec();
  }
}
```

In the above example we have used the `Cat` interface. This interface extends the `Document` from the mongoose package:

```typescript

import { Document } from 'mongoose';

export interface Cat extends Document {
  readonly name: string;
  readonly age: number;
  readonly breed: string;
}
```

The database connection is **asynchronous**, but Nest makes this process completely invisible for the end-user. The `CatModel` class is waiting for the db connection, and the `CatsService` is delayed until model is ready to use. The entire application can start when each class is instantiated.

Here is a final `CatsModule`:

cats.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';
import { catsProviders } from './cats.providers';
import { DatabaseModule } from '../database/database.module';

@Module({
  imports: [DatabaseModule],
  controllers: [CatsController],
  providers: [
    CatsService,
    ...catsProviders,
  ],
})
export class CatsModule {}
```

> **Hint** Do not forget to import the `CatsModule` into the root `ApplicationModule`.

----
url: https://docs.nestjs.com/v10/fundamentals/lazy-loading-modules
----

* [Lazy loading modules](https://docs.nestjs.com/v10/fundamentals/lazy-loading-modules#lazy-loading-modules)
* [Getting started](https://docs.nestjs.com/v10/fundamentals/lazy-loading-modules#getting-started)
* [Lazy loading controllers, gateways, and resolvers](https://docs.nestjs.com/v10/fundamentals/lazy-loading-modules#lazy-loading-controllers-gateways-and-resolvers)
* [Common use-cases](https://docs.nestjs.com/v10/fundamentals/lazy-loading-modules#common-use-cases)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/fundamentals/lazy-loading-modules.md "Suggest Edits")

### Lazy loading modules

By default, modules are eagerly loaded, which means that as soon as the application loads, so do all the modules, whether or not they are immediately necessary. While this is fine for most applications, it may become a bottleneck for apps/workers running in the **serverless environment**, where the startup latency ("cold start") is crucial.

Lazy loading can help decrease bootstrap time by loading only modules required by the specific serverless function invocation. In addition, you could also load other modules asynchronously once the serverless function is "warm" to speed-up the bootstrap time for subsequent calls even further (deferred modules registration).

> **Hint** If you're familiar with the **[Angular](https://angular.dev/)** framework, you might have seen the "[lazy-loading modules](https://angular.dev/guide/ngmodules/lazy-loading#lazy-loading-basics)" term before. Be aware that this technique is **functionally different** in Nest and so think about this as an entirely different feature that shares similar naming conventions.

> **Warning** Do note that [lifecycle hooks methods](https://docs.nestjs.com/fundamentals/lifecycle-events) are not invoked in lazy loaded modules and services.

#### Getting started[#](/fundamentals/lazy-loading-modules#getting-started)

To load modules on-demand, Nest provides the `LazyModuleLoader` class that can be injected into a class in the normal way:

cats.service.ts

JS TS

```typescript

@Injectable()
export class CatsService {
  constructor(private lazyModuleLoader: LazyModuleLoader) {}
}
```

```typescript

@Injectable()
@Dependencies(LazyModuleLoader)
export class CatsService {
  constructor(lazyModuleLoader) {
    this.lazyModuleLoader = lazyModuleLoader;
  }
}
```

> **Hint** The `LazyModuleLoader` class is imported from the `@nestjs/core` package.

Alternatively, you can obtain a reference to the `LazyModuleLoader` provider from within your application bootstrap file (`main.ts`), as follows:

```typescript

// "app" represents a Nest application instance
const lazyModuleLoader = app.get(LazyModuleLoader);
```

With this in place, you can now load any module using the following construction:

```typescript

const { LazyModule } = await import('./lazy.module');
const moduleRef = await this.lazyModuleLoader.load(() => LazyModule);
```

> **Hint** "Lazy loaded" modules are **cached** upon the first `LazyModuleLoader#load` method invocation. That means, each consecutive attempt to load `LazyModule` will be **very fast** and will return a cached instance, instead of loading the module again.
>
> ```bash
>
> Load "LazyModule" attempt: 1
> time: 2.379ms
> Load "LazyModule" attempt: 2
> time: 0.294ms
> Load "LazyModule" attempt: 3
> time: 0.303ms
> ```
>
> Also, "lazy loaded" modules share the same modules graph as those eagerly loaded on the application bootstrap as well as any other lazy modules registered later in your app.

Where `lazy.module.ts` is a TypeScript file that exports a **regular Nest module** (no extra changes are required).

The `LazyModuleLoader#load` method returns the [module reference](/v10/fundamentals/module-ref) (of `LazyModule`) that lets you navigate the internal list of providers and obtain a reference to any provider using its injection token as a lookup key.

For example, let's say we have a `LazyModule` with the following definition:

```typescript

@Module({
  providers: [LazyService],
  exports: [LazyService],
})
export class LazyModule {}
```

> **Hint** Lazy loaded modules cannot be registered as **global modules** as it simply makes no sense (since they are registered lazily, on-demand when all the statically registered modules have been already instantiated). Likewise, registered **global enhancers** (guards/interceptors/etc.) **will not work** properly either.

With this, we could obtain a reference to the `LazyService` provider, as follows:

```typescript

const { LazyModule } = await import('./lazy.module');
const moduleRef = await this.lazyModuleLoader.load(() => LazyModule);

const { LazyService } = await import('./lazy.service');
const lazyService = moduleRef.get(LazyService);
```

> **Warning** If you use **Webpack**, make sure to update your `tsconfig.json` file - setting `compilerOptions.module` to `"esnext"` and adding `compilerOptions.moduleResolution` property with `"node"` as a value:
>
> ```json
>
> {
>   "compilerOptions": {
>     "module": "esnext",
>     "moduleResolution": "node",
>     ...
>   }
> }
> ```
>
> With these options set up, you'll be able to leverage the [code splitting](https://webpack.js.org/guides/code-splitting/) feature.

#### Lazy loading controllers, gateways, and resolvers[#](/fundamentals/lazy-loading-modules#lazy-loading-controllers-gateways-and-resolvers)

Since controllers (or resolvers in GraphQL applications) in Nest represent sets of routes/paths/topics (or queries/mutations), you **cannot lazy load them** using the `LazyModuleLoader` class.

> **Warning** Controllers, [resolvers](/v10/graphql/resolvers), and [gateways](/v10/websockets/gateways) registered inside lazy loaded modules will not behave as expected. Similarly, you cannot register middleware functions (by implementing the `MiddlewareConsumer` interface) on-demand.

For example, let's say you're building a REST API (HTTP application) with a Fastify driver under the hood (using the `@nestjs/platform-fastify` package). Fastify does not let you register routes after the application is ready/successfully listening to messages. That means even if we analyzed route mappings registered in the module's controllers, all lazy loaded routes wouldn't be accessible since there is no way to register them at runtime.

Likewise, some transport strategies we provide as part of the `@nestjs/microservices` package (including Kafka, gRPC, or RabbitMQ) require to subscribe/listen to specific topics/channels before the connection is established. Once your application starts listening to messages, the framework would not be able to subscribe/listen to new topics.

Lastly, the `@nestjs/graphql` package with the code first approach enabled automatically generates the GraphQL schema on-the-fly based on the metadata. That means, it requires all classes to be loaded beforehand. Otherwise, it would not be doable to create the appropriate, valid schema.

#### Common use-cases[#](/fundamentals/lazy-loading-modules#common-use-cases)

Most commonly, you will see lazy loaded modules in situations when your worker/cron job/lambda & serverless function/webhook must trigger different services (different logic) based on the input arguments (route path/date/query parameters, etc.). On the other hand, lazy loading modules may not make too much sense for monolithic applications, where the startup time is rather irrelevant.

----
url: https://docs.nestjs.com/v8/openapi/operations
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Operations](https://docs.nestjs.com/v8/openapi/operations#operations)
* [Tags](https://docs.nestjs.com/v8/openapi/operations#tags)
* [Headers](https://docs.nestjs.com/v8/openapi/operations#headers)
* [Responses](https://docs.nestjs.com/v8/openapi/operations#responses)
* [File upload](https://docs.nestjs.com/v8/openapi/operations#file-upload)
* [Extensions](https://docs.nestjs.com/v8/openapi/operations#extensions)
* [Advanced: Generic ApiResponse](https://docs.nestjs.com/v8/openapi/operations#advanced-generic-apiresponse)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/openapi/operations.md "Suggest Edits")

### Operations

In OpenAPI terms, paths are endpoints (resources), such as `/users` or `/reports/summary`, that your API exposes, and operations are the HTTP methods used to manipulate these paths, such as `GET`, `POST` or `DELETE`.

#### Tags[#](/openapi/operations#tags)

To attach a controller to a specific tag, use the `@ApiTags(...tags)` decorator.

```typescript

@ApiTags('cats')
@Controller('cats')
export class CatsController {}
```

#### Headers[#](/openapi/operations#headers)

To define custom headers that are expected as part of the request, use `@ApiHeader()`.

```typescript

@ApiHeader({
  name: 'X-MyHeader',
  description: 'Custom header',
})
@Controller('cats')
export class CatsController {}
```

#### Responses[#](/openapi/operations#responses)

To define a custom HTTP response, use the `@ApiResponse()` decorator.

```typescript

@Post()
@ApiResponse({ status: 201, description: 'The record has been successfully created.'})
@ApiResponse({ status: 403, description: 'Forbidden.'})
async create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

```typescript

@Post()
@ApiCreatedResponse({ description: 'The record has been successfully created.'})
@ApiForbiddenResponse({ description: 'Forbidden.'})
async create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

To specify a return model for a request, we must create a class and annotate all properties with the `@ApiProperty()` decorator.

```typescript

export class Cat {
  @ApiProperty()
  id: number;

  @ApiProperty()
  name: string;

  @ApiProperty()
  age: number;

  @ApiProperty()
  breed: string;
}
```

Then the `Cat` model can be used in combination with the `type` property of the response decorator.

```typescript

@ApiTags('cats')
@Controller('cats')
export class CatsController {
  @Post()
  @ApiCreatedResponse({
    description: 'The record has been successfully created.',
    type: Cat,
  })
  async create(@Body() createCatDto: CreateCatDto): Promise<Cat> {
    return this.catsService.create(createCatDto);
  }
}
```

Let's open the browser and verify the generated `Cat` model:

#### File upload[#](/openapi/operations#file-upload)

You can enable file upload for a specific method with the `@ApiBody` decorator together with `@ApiConsumes()`. Here's a full example using the [File Upload](/v8/techniques/file-upload) technique:

```typescript

@UseInterceptors(FileInterceptor('file'))
@ApiConsumes('multipart/form-data')
@ApiBody({
  description: 'List of cats',
  type: FileUploadDto,
})
uploadFile(@UploadedFile() file) {}
```

Where `FileUploadDto` is defined as follows:

```typescript

class FileUploadDto {
  @ApiProperty({ type: 'string', format: 'binary' })
  file: any;
}
```

To handle multiple files uploading, you can define `FilesUploadDto` as follows:

```typescript

class FilesUploadDto {
  @ApiProperty({ type: 'array', items: { type: 'string', format: 'binary' } })
  files: any[];
}
```

#### Extensions[#](/openapi/operations#extensions)

To add an Extension to a request use the `@ApiExtension()` decorator. The extension name must be prefixed with `x-`.

```typescript

@ApiExtension('x-foo', { hello: 'world' })
```

#### Advanced: Generic `ApiResponse`[#](/openapi/operations#advanced-generic-apiresponse)

With the ability to provide [Raw Definitions](/openapi/types-and-parameters#raw-definitions), we can define Generic schema for Swagger UI. Assume we have the following DTO:

```ts

export class PaginatedDto<TData> {
  @ApiProperty()
  total: number;

  @ApiProperty()
  limit: number;

  @ApiProperty()
  offset: number;

  results: TData[];
}
```

We skip decorating `results` as we will be providing a raw definition for it later. Now, let's define another DTO and name it, for example, `CatDto`, as follows:

```ts

export class CatDto {
  @ApiProperty()
  name: string;

  @ApiProperty()
  age: number;

  @ApiProperty()
  breed: string;
}
```

With this in place, we can define a `PaginatedDto<CatDto>` response, as follows:

```ts

@ApiOkResponse({
  schema: {
    allOf: [
      { $ref: getSchemaPath(PaginatedDto) },
      {
        properties: {
          results: {
            type: 'array',
            items: { $ref: getSchemaPath(CatDto) },
          },
        },
      },
    ],
  },
})
async findAll(): Promise<PaginatedDto<CatDto>> {}
```

In this example, we specify that the response will have allOf `PaginatedDto` and the `results` property will be of type `Array<CatDto>`.

* `getSchemaPath()` function that returns the OpenAPI Schema path from within the OpenAPI Spec File for a given model.
* `allOf` is a concept that OAS 3 provides to cover various Inheritance related use-cases.

Lastly, since `PaginatedDto` is not directly referenced by any controller, the `SwaggerModule` will not be able to generate a corresponding model definition just yet. In this case, we must add it as an [Extra Model](/openapi/types-and-parameters#extra-models). For example, we can use the `@ApiExtraModels()` decorator on the controller level, as follows:

```ts

@Controller('cats')
@ApiExtraModels(PaginatedDto)
export class CatsController {}
```

If you run Swagger now, the generated `swagger.json` for this specific endpoint should have the following response defined:

```json

"responses": {
  "200": {
    "description": "",
    "content": {
      "application/json": {
        "schema": {
          "allOf": [
            {
              "$ref": "#/components/schemas/PaginatedDto"
            },
            {
              "properties": {
                "results": {
                  "$ref": "#/components/schemas/CatDto"
                }
              }
            }
          ]
        }
      }
    }
  }
}
```

To make it reusable, we can create a custom decorator for `PaginatedDto`, as follows:

```ts

export const ApiPaginatedResponse = <TModel extends Type<any>>(
  model: TModel,
) => {
  return applyDecorators(
    ApiOkResponse({
      schema: {
        allOf: [
          { $ref: getSchemaPath(PaginatedDto) },
          {
            properties: {
              results: {
                type: 'array',
                items: { $ref: getSchemaPath(model) },
              },
            },
          },
        ],
      },
    }),
  );
};
```

> **Hint**`Type<any>` interface and `applyDecorators` function are imported from the `@nestjs/common` package.

With this in place, we can use the custom `@ApiPaginatedResponse()` decorator on our endpoint:

```ts

@ApiPaginatedResponse(CatDto)
async findAll(): Promise<PaginatedDto<CatDto>> {}
```

For client generation tools, this approach poses an ambiguity in how the `PaginatedResponse<TModel>` is being generated for the client. The following snippet is an example of a client generator result for the above `GET /` endpoint.

```typescript

// Angular
findAll(): Observable<{ total: number, limit: number, offset: number, results: CatDto[] }>
```

As you can see, the **Return Type** here is ambiguous. To workaround this issue, you can add a `title` property to the `schema` for `ApiPaginatedResponse`:

```typescript

export const ApiPaginatedResponse = <TModel extends Type<any>>(model: TModel) => {
  return applyDecorators(
    ApiOkResponse({
      schema: {
        title: `PaginatedResponseOf${model.name}`
        allOf: [
          // ...
        ],
      },
    }),
  );
};
```

Now the result of the client generator tool will become:

```ts

// Angular
findAll(): Observable<PaginatedResponseOfCatDto>
```

----
url: https://docs.nestjs.com/v4/microservices/custom-transport
----

### Custom Transport

The Nest has a built-in transport via TCP and Redis, but other communication schemes can be implemented with `CustomTransportStrategy` interface. For demonstration purposes, we're going to port the [RabbitMQ](https://www.rabbitmq.com/) transport strategy using [ampqlib](https://github.com/squaremo/amqp.node) library.

#### Server

Let's start from the `RabbitMQServer` which will match incoming messages to the right message handlers.

rabbitmq-server.ts

JavaScript TypeScript

TypeScript

```typescript

import * as amqp from 'amqplib';
import { Server, CustomTransportStrategy } from '@nestjs/microservices';
import { Observable } from 'rxjs/Observable';

export class RabbitMQServer extends Server implements CustomTransportStrategy {
    private server: amqp.Connection = null;
    private channel: amqp.Channel = null;

    constructor(
      private readonly host: string,
      private readonly queue: string) {
        super();
      }

  public async listen(callback: () => void) {
    await this.init();
    this.channel.consume(`${this.queue}_sub`, this.handleMessage.bind(this), {
      noAck: true,
    });
  }

  public close() {
    this.channel && this.channel.close();
    this.server && this.server.close();
  }

  private async handleMessage(message) {
    const { content } = message;
    const messageObj = JSON.parse(content.toString());

    const handlers = this.getHandlers();
    const pattern = JSON.stringify(messageObj.pattern);
    if (!this.messageHandlers[pattern]) {
        return;
    }

    const handler = this.messageHandlers[pattern];
    const response$ = this.transformToObservable(await handler(messageObj.data)) as Observable<any>;
    response$ && this.send(response$, (data) => this.sendMessage(data));
  }

  private sendMessage(message) {
    const buffer = Buffer.from(JSON.stringify(message));
    this.channel.sendToQueue(`${this.queue}_pub`, buffer);
  }

  private async init() {
    this.server = await amqp.connect(this.host);
    this.channel = await this.server.createChannel();
    this.channel.assertQueue(`${this.queue}_sub`, { durable: false });
    this.channel.assertQueue(`${this.queue}_pub`, { durable: false });
  }
}
```

TypeScript

```typescript

import * as amqp from 'amqplib';
import { Server } from '@nestjs/microservices';
import { Observable } from 'rxjs/Observable';

export class RabbitMQServer extends Server {
    constructor(host, queue) {
      super();

      this.host = host;
      this.queue = queue;
      this.server = null;
      this.channel = null;
    }

  async listen(callback) {
    await this.init();
    this.channel.consume(`${this.queue}_sub`, this.handleMessage.bind(this), {
      noAck: true,
    });
  }

  close() {
    this.channel && this.channel.close();
    this.server && this.server.close();
  }

  async handleMessage(message) {
    const { content } = message;
    const messageObj = JSON.parse(content.toString());

    const handlers = this.getHandlers();
    const pattern = JSON.stringify(messageObj.pattern);
    if (!this.messageHandlers[pattern]) {
        return;
    }

    const handler = this.messageHandlers[pattern];
    const response$ = this.transformToObservable(await handler(messageObj.data));
    response$ && this.send(response$, (data) => this.sendMessage(data));
  }

  sendMessage(message) {
    const buffer = Buffer.from(JSON.stringify(message));
    this.channel.sendToQueue(`${this.queue}_pub`, buffer);
  }

  async init() {
    this.server = await amqp.connect(this.host);
    this.channel = await this.server.createChannel();
    this.channel.assertQueue(`${this.queue}_sub`, { durable: false });
    this.channel.assertQueue(`${this.queue}_pub`, { durable: false });
  }
}
```

The `CustomTransportStrategy` forces to implement two fundamental methods - `listen()` and `close()`. Moreover, the `RabbitMQServer` shall extends the abstract `Server` class. This class supplies the core `getHandlers()` and `send()` methods, and helper `transformToObservable()` method.

The last step is to set up the `RabbitMQServer`:

main.ts

JavaScript TypeScript

TypeScript

```typescript

const app = await NestFactory.createMicroservice(ApplicationModule, {
    strategy: new RabbitMQServer('amqp://localhost', 'channel'),
});
```

#### Client

The [RabbitMQ](https://www.rabbitmq.com/) server's listening to messages. Now it's time to create a client class, which shall extends the abstract `ClientProxy` class. To make it work, we only have to override `sendSingleMessage()` method.

rabbitmq-client.ts

JavaScript TypeScript

TypeScript

```typescript

import * as amqp from 'amqplib';
import { ClientProxy } from '@nestjs/microservices';

export class RabbitMQClient extends ClientProxy {
  constructor(
    private readonly host: string,
    private readonly queue: string) {
      super();
    }

  protected async sendSingleMessage(messageObj, callback: (err, result, disposed?: boolean) => void) {
    const server = await amqp.connect(this.host);
    const channel = await server.createChannel();

    const { sub, pub } = this.getQueues();
    channel.assertQueue(sub, { durable: false });
    channel.assertQueue(pub, { durable: false });

    channel.consume(pub, (message) => this.handleMessage(message, server, callback), { noAck: true });
    channel.sendToQueue(sub, Buffer.from(JSON.stringify(messageObj)));
  }

  private handleMessage(message, server, callback: (err, result, disposed?: boolean) => void) {
    const { content } = message;
    const { err, response, disposed } = JSON.parse(content.toString());
    if (disposed) {
        server.close();
    }
    callback(err, response, disposed);
  }

  private getQueues() {
    return { pub: `${this.queue}_pub`, sub: `${this.queue}_sub` };
  }
}
```

TypeScript

```typescript

import * as amqp from 'amqplib';
import { ClientProxy } from '@nestjs/microservices';

export class RabbitMQClient extends ClientProxy {
  constructor(host, queue) {
      super();

      this.host = host;
      this.queue = queue;
    }

  async sendSingleMessage(messageObj, callback) {
    const server = await amqp.connect(this.host);
    const channel = await server.createChannel();

    const { sub, pub } = this.getQueues();
    channel.assertQueue(sub, { durable: false });
    channel.assertQueue(pub, { durable: false });

    channel.consume(pub, (message) => this.handleMessage(message, server, callback), { noAck: true });
    channel.sendToQueue(sub, Buffer.from(JSON.stringify(messageObj)));
  }

  handleMessage(message, server, callback) {
    const { content } = message;
    const { err, response, disposed } = JSON.parse(content.toString());
    if (disposed) {
        server.close();
    }
    callback(err, response, disposed);
  }

  getQueues() {
    return { pub: `${this.queue}_pub`, sub: `${this.queue}_sub` };
  }
}
```

Earlier, the Nest was responsible for creating the instance of the client class. We've been using the `@Client()` decorator. Now, when we've created our own solution, we can just create the `RabbitMQClient` instance directly, using `new` operator.

TypeScript

```typescript

this.client = new RabbitMQClient('amqp://localhost', 'example');
```

> **Hint** To make unit testing easy, you can provide a [custom component](/v4/fundamentals/dependency-injection) instead of creating the instance directly in the class body.

#### Sponsors

[](https://valor-software.com/)

Nest is an MIT-licensed open source project. It can grow thanks to the support by these awesome people. If you'd like to join them, please read more [here](https://opencollective.com/nest). Thanks!

[](https://opencollective.com/nest/backer/0/website)[](https://opencollective.com/nest/backer/1/website)[](https://opencollective.com/nest/backer/2/website)[](https://opencollective.com/nest/backer/3/website)[](https://opencollective.com/nest/backer/4/website)[](https://opencollective.com/nest/backer/5/website)[](https://opencollective.com/nest/backer/6/website)[](https://opencollective.com/nest/backer/7/website)[](https://opencollective.com/nest/backer/8/website)[](https://opencollective.com/nest/backer/9/website)[](https://opencollective.com/nest/backer/10/website)[](https://opencollective.com/nest/backer/11/website)[](https://opencollective.com/nest/backer/12/website)[](https://opencollective.com/nest/backer/13/website)[](https://opencollective.com/nest/backer/14/website)[](https://opencollective.com/nest/backer/15/website)[](https://opencollective.com/nest/backer/16/website)[](https://opencollective.com/nest/backer/17/website)[](https://opencollective.com/nest/backer/18/website)[](https://opencollective.com/nest/backer/19/website)[](https://opencollective.com/nest/backer/20/website)[](https://opencollective.com/nest/backer/21/website)[](https://opencollective.com/nest/backer/22/website)[](https://opencollective.com/nest/backer/23/website)[](https://opencollective.com/nest/backer/24/website)[](https://opencollective.com/nest/backer/25/website)[](https://opencollective.com/nest/backer/26/website)[](https://opencollective.com/nest/backer/27/website)[](https://opencollective.com/nest/backer/28/website)[](https://opencollective.com/nest/backer/29/website)

[Become a sponsor](https://opencollective.com/nest)

----
url: https://docs.nestjs.com/graphql/subscriptions
----

[Skip to content](#content)

On this page

* [Subscriptions](https://docs.nestjs.com/graphql/subscriptions#subscriptions)
* [Enable subscriptions with Apollo driver](https://docs.nestjs.com/graphql/subscriptions#enable-subscriptions-with-apollo-driver)
* [Code first](https://docs.nestjs.com/graphql/subscriptions#code-first)
* [Publishing](https://docs.nestjs.com/graphql/subscriptions#publishing)
* [Filtering subscriptions](https://docs.nestjs.com/graphql/subscriptions#filtering-subscriptions)
* [Mutating subscription payloads](https://docs.nestjs.com/graphql/subscriptions#mutating-subscription-payloads)
* [Schema first](https://docs.nestjs.com/graphql/subscriptions#schema-first)
* [PubSub](https://docs.nestjs.com/graphql/subscriptions#pubsub)
* [Customize subscriptions server](https://docs.nestjs.com/graphql/subscriptions#customize-subscriptions-server)
* [Authentication over WebSockets](https://docs.nestjs.com/graphql/subscriptions#authentication-over-websockets)
* [Enable subscriptions with Mercurius driver](https://docs.nestjs.com/graphql/subscriptions#enable-subscriptions-with-mercurius-driver)
* [Code first](https://docs.nestjs.com/graphql/subscriptions#code-first-1)
* [Publishing](https://docs.nestjs.com/graphql/subscriptions#publishing-1)
* [Filtering subscriptions](https://docs.nestjs.com/graphql/subscriptions#filtering-subscriptions-1)
* [Schema first](https://docs.nestjs.com/graphql/subscriptions#schema-first-1)
* [PubSub](https://docs.nestjs.com/graphql/subscriptions#pubsub-1)
* [Authentication over WebSockets](https://docs.nestjs.com/graphql/subscriptions#authentication-over-websockets-1)

[](https://srv.carbonads.net/ads/click/x/GTND4277CVSD5KJUCAYLYKQUF67D62Q7CW7DTZ3JCAAI6KQJCASIV2QKC6YIC2QECV7D52Q7CVYDV27MCVBIK2QWHEYI55QLCAYD653ECTNCYBZ52K)[Your side project deserves Lambda, not localhost. Start building ](https://srv.carbonads.net/ads/click/x/GTND4277CVSD5KJUCAYLYKQUF67D62Q7CW7DTZ3JCAAI6KQJCASIV2QKC6YIC2QECV7D52Q7CVYDV27MCVBIK2QWHEYI55QLCAYD653ECTNCYBZ52K)[ads via Carbon](http://carbonads.net/?utm_source=nestjscom\&utm_medium=ad_via_link\&utm_campaign=in_unit\&utm_term=carbon)

### Subscriptions

In addition to fetching data with queries and modifying data with mutations, the GraphQL spec supports a third operation type, called `subscription`. GraphQL subscriptions push data from the server to clients that choose to listen to real-time messages. Like queries, subscriptions specify a set of fields to be delivered to the client. Instead of immediately returning a single result, however, they open a channel, and the server sends a result to the client every time a particular event occurs.

A common use case for subscriptions is notifying the client about particular events, such as the creation of a new object or updated fields (see [Subscriptions](https://www.apollographql.com/docs/react/data/subscriptions) in the Apollo documentation).

#### Enable subscriptions with Apollo driver[#](/graphql/subscriptions#enable-subscriptions-with-apollo-driver)

Subscriptions are transported over WebSockets by the [graphql-ws](https://github.com/enisdenjo/graphql-ws) package. `@nestjs/graphql` already depends on it, but install it in your project as well if you import from it directly (e.g., the `Context` type used in [Authentication over WebSockets](/graphql/subscriptions#authentication-over-websockets)):

```bash

$ npm i --save graphql-ws
```

Then enable the transport:

```typescript

GraphQLModule.forRoot<ApolloDriverConfig>({
  driver: ApolloDriver,
  subscriptions: {
    'graphql-ws': true,
  },
}),
```

> **Warning** Support for `subscriptions-transport-ws` was **removed** in `@nestjs/graphql` v14. The package is no longer a dependency, and the `'subscriptions-transport-ws'` key is no longer accepted in the `subscriptions` options object. If you are upgrading, replace that key with `'graphql-ws'` and update your clients to the newer protocol. The two protocols are wire-incompatible, so clients still using `subscriptions-transport-ws` fail to connect. The `onConnect` callback signature differs as well: with `graphql-ws`, it receives the connection context, and extra context values belong in its `extra` field (see [Authentication over WebSockets](/graphql/subscriptions#authentication-over-websockets) below).

#### Code first[#](/graphql/subscriptions#code-first)

To create a subscription with the code first approach, use the `@Subscription()` decorator (exported from the `@nestjs/graphql` package) and the `PubSub` class from the `graphql-subscriptions` package, which provides a simple **publish/subscribe API**.

The following subscription handler **subscribes** to an event by calling `PubSub#asyncIterableIterator`. This method takes a single argument, the `triggerName`, which corresponds to an event topic name.

```typescript

const pubSub = new PubSub();

@Resolver(() => Author)
export class AuthorResolver {
  // ...
  @Subscription(() => Comment)
  commentAdded() {
    return pubSub.asyncIterableIterator('commentAdded');
  }
}
```

> **Hint** All decorators are exported from the `@nestjs/graphql` package, while the `PubSub` class is exported from the `graphql-subscriptions` package (`npm i graphql-subscriptions`).

> **Note**`PubSub` is a class that exposes a simple `publish` and `subscribe` API. Learn more in the [graphql-subscriptions setup guide](https://www.apollographql.com/docs/graphql-subscriptions/setup.html). The Apollo docs warn that the [default implementation](https://github.com/apollographql/graphql-subscriptions#getting-started-with-your-first-subscription) is not suitable for production. Production apps should use a `PubSub` implementation backed by an external store (see the list of [PubSub implementations](https://github.com/apollographql/graphql-subscriptions#pubsub-implementations)).

This generates the following part of the GraphQL schema in SDL:

```graphql

type Subscription {
  commentAdded: Comment!
}
```

Subscriptions, by definition, return an object with a single top-level property whose key is the name of the subscription. This name is either inherited from the name of the subscription handler method (i.e., `commentAdded` above), or provided explicitly through the `name` option in the second argument to the `@Subscription()` decorator, as shown below.

```typescript

@Subscription(() => Comment, {
  name: 'commentAdded',
})
subscribeToCommentAdded() {
  return pubSub.asyncIterableIterator('commentAdded');
}
```

This construct produces the same SDL as the previous code sample, but decouples the method name from the subscription name.

#### Publishing[#](/graphql/subscriptions#publishing)

To publish the event, use the `PubSub#publish` method. It is often called within a mutation to trigger a client-side update when a part of the object graph has changed. For example:

posts/posts.resolver.ts

JS TS

```typescript

@Mutation(() => Comment)
async addComment(
  @Args('postId', { type: () => Int }) postId: number,
  @Args('comment', { type: () => CommentInput }) comment: CommentInput,
) {
  const newComment = this.commentsService.addComment({ id: postId, comment });
  pubSub.publish('commentAdded', { commentAdded: newComment });
  return newComment;
}
```

The `PubSub#publish` method takes a `triggerName` (again, think of it as an event topic name) as the first parameter, and an event payload as the second. As mentioned, a subscription, by definition, returns a value, and that value has a shape. Look again at the generated SDL for the `commentAdded` subscription:

```graphql

type Subscription {
  commentAdded: Comment!
}
```

This tells us that the subscription must return an object with a top-level property named `commentAdded` whose value is a `Comment` object. The shape of the event payload emitted by the `PubSub#publish` method must match the shape of the value the subscription is expected to return. In the example above, the `pubSub.publish('commentAdded', { commentAdded: newComment })` statement publishes a `commentAdded` event with the appropriately shaped payload. If the shapes don't match, the subscription fails when the event is resolved.

#### Filtering subscriptions[#](/graphql/subscriptions#filtering-subscriptions)

To filter out specific events, set the `filter` property to a filter function. This function works like the callback passed to an array's `filter()` method. It takes two arguments: `payload`, containing the event payload (as sent by the event publisher), and `variables`, containing any arguments passed in with the subscription request. It returns a boolean that determines whether the event should be published to client listeners.

```typescript

@Subscription(() => Comment, {
  filter: (payload, variables) =>
    payload.commentAdded.title === variables.title,
})
commentAdded(@Args('title') title: string) {
  return pubSub.asyncIterableIterator('commentAdded');
}
```

#### Mutating subscription payloads[#](/graphql/subscriptions#mutating-subscription-payloads)

To transform the published event payload, set the `resolve` property to a function. The function receives the event payload (as sent by the event publisher) and returns the appropriate value.

```typescript

@Subscription(() => Comment, {
  resolve: value => value,
})
commentAdded() {
  return pubSub.asyncIterableIterator('commentAdded');
}
```

> **Note** If you use the `resolve` option, return the unwrapped payload (in our example, return the `newComment` object directly, not a `{ commentAdded: newComment }` object).

To access injected providers (e.g., to validate the data with an external service), use the following construction.

```typescript

@Subscription(() => Comment, {
  resolve(this: AuthorResolver, value) {
    // "this" refers to an instance of "AuthorResolver"
    return value;
  }
})
commentAdded() {
  return pubSub.asyncIterableIterator('commentAdded');
}
```

The same construction works with filters:

```typescript

@Subscription(() => Comment, {
  filter(this: AuthorResolver, payload, variables) {
    // "this" refers to an instance of "AuthorResolver"
    return payload.commentAdded.title === variables.title;
  }
})
commentAdded() {
  return pubSub.asyncIterableIterator('commentAdded');
}
```

#### Schema first[#](/graphql/subscriptions#schema-first)

To create an equivalent subscription in Nest, use the `@Subscription()` decorator.

```typescript

const pubSub = new PubSub();

@Resolver('Author')
export class AuthorResolver {
  // ...
  @Subscription()
  commentAdded() {
    return pubSub.asyncIterableIterator('commentAdded');
  }
}
```

To filter out specific events based on context and arguments, set the `filter` property.

```typescript

@Subscription('commentAdded', {
  filter: (payload, variables) =>
    payload.commentAdded.title === variables.title,
})
commentAdded() {
  return pubSub.asyncIterableIterator('commentAdded');
}
```

To transform the published payload, use a `resolve` function.

```typescript

@Subscription('commentAdded', {
  resolve: value => value,
})
commentAdded() {
  return pubSub.asyncIterableIterator('commentAdded');
}
```

To access injected providers (e.g., to validate the data with an external service), use the following construction:

```typescript

@Subscription('commentAdded', {
  resolve(this: AuthorResolver, value) {
    // "this" refers to an instance of "AuthorResolver"
    return value;
  }
})
commentAdded() {
  return pubSub.asyncIterableIterator('commentAdded');
}
```

The same construction works with filters:

```typescript

@Subscription('commentAdded', {
  filter(this: AuthorResolver, payload, variables) {
    // "this" refers to an instance of "AuthorResolver"
    return payload.commentAdded.title === variables.title;
  }
})
commentAdded() {
  return pubSub.asyncIterableIterator('commentAdded');
}
```

The last step is to update the type definitions file.

```graphql

type Author {
  id: Int!
  firstName: String
  lastName: String
  posts: [Post]
}

type Post {
  id: Int!
  title: String
  votes: Int
}

type Query {
  author(id: Int!): Author
}

type Comment {
  id: String
  content: String
}

type Subscription {
  commentAdded(title: String!): Comment
}
```

With this, we've created a single `commentAdded(title: String!): Comment` subscription. A full [schema first sample](https://github.com/nestjs/nest/blob/master/sample/12-graphql-schema-first) is available in the NestJS repository.

#### PubSub[#](/graphql/subscriptions#pubsub)

The examples above instantiate a local `PubSub` instance. The preferred approach is to define `PubSub` as a [provider](/fundamentals/custom-providers) and inject it through the constructor (using the `@Inject()` decorator), so that the same instance is reused across the whole application. For example, define a provider as follows, then inject `'PUB_SUB'` where needed.

```typescript

{
  provide: 'PUB_SUB',
  useValue: new PubSub(),
}
```

#### Customize subscriptions server[#](/graphql/subscriptions#customize-subscriptions-server)

To customize the subscriptions server (e.g., to change its path, which defaults to the GraphQL endpoint path), pass an options object for `graphql-ws` in the `subscriptions` property:

```typescript

GraphQLModule.forRoot<ApolloDriverConfig>({
  driver: ApolloDriver,
  subscriptions: {
    'graphql-ws': {
      path: '/graphql',
    },
  },
});
```

#### Authentication over WebSockets[#](/graphql/subscriptions#authentication-over-websockets)

To check whether the user is authenticated, use the `onConnect` callback function, which you can specify in the `subscriptions` options.

With `graphql-ws`, the `onConnect` callback receives the connection context, including `connectionParams`.

```typescript

GraphQLModule.forRoot<ApolloDriverConfig>({
  driver: ApolloDriver,
  subscriptions: {
    'graphql-ws': {
      onConnect: (context: Context<any>) => {
        const { connectionParams, extra } = context;
        const authToken = connectionParams.authToken;
        if (!isValid(authToken)) {
          throw new Error('Token is not valid');
        }
        // when using graphql-ws, additional context values should be stored in the extra field
        extra.user = { user: {} };
      },
    },
  },
  context: ({ extra }) => {
    // you can now access your additional context value through the extra field
  },
});
```

#### Enable subscriptions with Mercurius driver[#](/graphql/subscriptions#enable-subscriptions-with-mercurius-driver)

To enable subscriptions, set the `subscription` property to `true`.

```typescript

GraphQLModule.forRoot<MercuriusDriverConfig>({
  driver: MercuriusDriver,
  subscription: true,
}),
```

> **Hint** You can also pass an options object to set up a custom emitter, validate incoming connections, etc. See the `subscription` option in the [Mercurius plugin options](https://github.com/mercurius-js/mercurius/blob/master/docs/api/options.md#plugin-options).

#### Code first[#](/graphql/subscriptions#code-first-1)

To create a subscription with the code first approach, use the `@Subscription()` decorator (exported from the `@nestjs/graphql` package) and the `PubSub` class from the `mercurius` package, which provides a simple **publish/subscribe API**.

The following subscription handler **subscribes** to an event by calling `PubSub#subscribe`. This method takes the topic name as its argument.

```typescript

@Resolver(() => Author)
export class AuthorResolver {
  // ...
  @Subscription(() => Comment)
  commentAdded(@Context('pubsub') pubSub: PubSub) {
    return pubSub.subscribe('commentAdded');
  }
}
```

> **Hint** All decorators used in the example above are exported from the `@nestjs/graphql` package, while the `PubSub` class is exported from the `mercurius` package.

> **Note**`PubSub` is a class that exposes a simple `publish` and `subscribe` API. To register a custom `PubSub` class, see [Subscriptions with custom PubSub](https://github.com/mercurius-js/mercurius/blob/master/docs/subscriptions.md#subscriptions-with-custom-pubsub) in the Mercurius documentation.

This generates the following part of the GraphQL schema in SDL:

```graphql

type Subscription {
  commentAdded: Comment!
}
```

Subscriptions, by definition, return an object with a single top-level property whose key is the name of the subscription. This name is either inherited from the name of the subscription handler method (i.e., `commentAdded` above), or provided explicitly through the `name` option in the second argument to the `@Subscription()` decorator, as shown below.

```typescript

@Subscription(() => Comment, {
  name: 'commentAdded',
})
subscribeToCommentAdded(@Context('pubsub') pubSub: PubSub) {
  return pubSub.subscribe('commentAdded');
}
```

This construct produces the same SDL as the previous code sample, but decouples the method name from the subscription name.

#### Publishing[#](/graphql/subscriptions#publishing-1)

To publish the event, use the `PubSub#publish` method. It is often called within a mutation to trigger a client-side update when a part of the object graph has changed. For example:

posts/posts.resolver.ts

JS TS

```typescript

@Mutation(() => Comment)
async addComment(
  @Args('postId', { type: () => Int }) postId: number,
  @Args('comment', { type: () => CommentInput }) comment: CommentInput,
  @Context('pubsub') pubSub: PubSub,
) {
  const newComment = this.commentsService.addComment({ id: postId, comment });
  await pubSub.publish({
    topic: 'commentAdded',
    payload: {
      commentAdded: newComment
    }
  });
  return newComment;
}
```

As mentioned, a subscription, by definition, returns a value, and that value has a shape. Look again at the generated SDL for the `commentAdded` subscription:

```graphql

type Subscription {
  commentAdded: Comment!
}
```

This tells us that the subscription must return an object with a top-level property named `commentAdded` whose value is a `Comment` object. The shape of the event payload emitted by the `PubSub#publish` method must match the shape of the value the subscription is expected to return. In the example above, the `pubSub.publish({ topic: 'commentAdded', payload: { commentAdded: newComment } })` statement publishes a `commentAdded` event with the appropriately shaped payload. If the shapes don't match, the subscription fails when the event is resolved.

#### Filtering subscriptions[#](/graphql/subscriptions#filtering-subscriptions-1)

To filter out specific events, set the `filter` property to a filter function. This function works like the callback passed to an array's `filter()` method. It takes two arguments: `payload`, containing the event payload (as sent by the event publisher), and `variables`, containing any arguments passed in with the subscription request. It returns a boolean that determines whether the event should be published to client listeners.

```typescript

@Subscription(() => Comment, {
  filter: (payload, variables) =>
    payload.commentAdded.title === variables.title,
})
commentAdded(@Args('title') title: string, @Context('pubsub') pubSub: PubSub) {
  return pubSub.subscribe('commentAdded');
}
```

To access injected providers (e.g., to validate the data with an external service), use the following construction.

```typescript

@Subscription(() => Comment, {
  filter(this: AuthorResolver, payload, variables) {
    // "this" refers to an instance of "AuthorResolver"
    return payload.commentAdded.title === variables.title;
  }
})
commentAdded(@Args('title') title: string, @Context('pubsub') pubSub: PubSub) {
  return pubSub.subscribe('commentAdded');
}
```

#### Schema first[#](/graphql/subscriptions#schema-first-1)

To create an equivalent subscription in Nest, use the `@Subscription()` decorator.

```typescript

@Resolver('Author')
export class AuthorResolver {
  // ...
  @Subscription()
  commentAdded(@Context('pubsub') pubSub: PubSub) {
    return pubSub.subscribe('commentAdded');
  }
}
```

To filter out specific events based on context and arguments, set the `filter` property.

```typescript

@Subscription('commentAdded', {
  filter: (payload, variables) =>
    payload.commentAdded.title === variables.title,
})
commentAdded(@Context('pubsub') pubSub: PubSub) {
  return pubSub.subscribe('commentAdded');
}
```

To access injected providers (e.g., to validate the data with an external service), use the following construction:

```typescript

@Subscription('commentAdded', {
  filter(this: AuthorResolver, payload, variables) {
    // "this" refers to an instance of "AuthorResolver"
    return payload.commentAdded.title === variables.title;
  }
})
commentAdded(@Context('pubsub') pubSub: PubSub) {
  return pubSub.subscribe('commentAdded');
}
```

The last step is to update the type definitions file.

```graphql

type Author {
  id: Int!
  firstName: String
  lastName: String
  posts: [Post]
}

type Post {
  id: Int!
  title: String
  votes: Int
}

type Query {
  author(id: Int!): Author
}

type Comment {
  id: String
  content: String
}

type Subscription {
  commentAdded(title: String!): Comment
}
```

With this, we've created a single `commentAdded(title: String!): Comment` subscription.

#### PubSub[#](/graphql/subscriptions#pubsub-1)

The examples above use the default `PubSub` emitter ([mqemitter](https://github.com/mcollina/mqemitter)). For production, the preferred approach is to use `mqemitter-redis`. Alternatively, you can provide a custom `PubSub` implementation (see [Subscriptions](https://github.com/mercurius-js/mercurius/blob/master/docs/subscriptions.md) in the Mercurius documentation).

```typescript

import mqemitterRedis from 'mqemitter-redis';

GraphQLModule.forRoot<MercuriusDriverConfig>({
  driver: MercuriusDriver,
  subscription: {
    emitter: mqemitterRedis({
      port: 6579,
      host: '127.0.0.1',
    }),
  },
});
```

#### Authentication over WebSockets[#](/graphql/subscriptions#authentication-over-websockets-1)

To check whether the user is authenticated, use the `verifyClient` callback function, which you can specify in the `subscription` options.

The `verifyClient` callback receives the `info` object as its first argument, which you can use to read the request's headers.

```typescript

GraphQLModule.forRoot<MercuriusDriverConfig>({
  driver: MercuriusDriver,
  subscription: {
    verifyClient: (info, next) => {
      const authorization = info.req.headers?.authorization as string;
      if (!authorization?.startsWith('Bearer ')) {
        return next(false);
      }
      next(true);
    },
  }
}),
```

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/subscriptions.md)

----
url: https://docs.nestjs.com/v11/recipes/sql-typeorm
----

* [SQL (TypeORM)](https://docs.nestjs.com/v11/recipes/sql-typeorm#sql-typeorm)
* [Getting started](https://docs.nestjs.com/v11/recipes/sql-typeorm#getting-started)
* [Repository pattern](https://docs.nestjs.com/v11/recipes/sql-typeorm#repository-pattern)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/recipes/sql-typeorm.md "Suggest Edits")

### SQL (TypeORM)

##### This chapter applies only to TypeScript

> **Warning** In this article, you'll learn how to create a `DatabaseModule` based on the **TypeORM** package from scratch using custom providers mechanism. As a consequence, this solution contains a lot of overhead that you can omit using ready to use and available out-of-the-box dedicated `@nestjs/typeorm` package. To learn more, see [here](/v11/techniques/sql).

[TypeORM](https://github.com/typeorm/typeorm) is definitely the most mature Object Relational Mapper (ORM) available in the node.js world. Since it's written in TypeScript, it works pretty well with the Nest framework.

#### Getting started[#](/recipes/sql-typeorm#getting-started)

To start the adventure with this library we have to install all required dependencies:

```bash

$ npm install --save typeorm mysql2
```

The first step we need to do is to establish the connection with our database using `new DataSource().initialize()` class imported from the `typeorm` package. The `initialize()` function returns a `Promise`, and therefore we have to create an [async provider](/v11/fundamentals/async-components).

database.providers.ts

JS TS

```typescript

import { DataSource } from 'typeorm';

export const databaseProviders = [
  {
    provide: 'DATA_SOURCE',
    useFactory: async () => {
      const dataSource = new DataSource({
        type: 'mysql',
        host: 'localhost',
        port: 3306,
        username: 'root',
        password: 'root',
        database: 'test',
        entities: [
            __dirname + '/../**/*.entity{.ts,.js}',
        ],
        synchronize: true,
      });

      return dataSource.initialize();
    },
  },
];
```

> **Warning** Setting `synchronize: true` shouldn't be used in production - otherwise you can lose production data.

> **Hint** Following best practices, we declared the custom provider in the separated file which has a `*.providers.ts` suffix.

Then, we need to export these providers to make them **accessible** for the rest of the application.

database.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { databaseProviders } from './database.providers';

@Module({
  providers: [...databaseProviders],
  exports: [...databaseProviders],
})
export class DatabaseModule {}
```

Now we can inject the `DATA_SOURCE` object using `@Inject()` decorator. Each class that would depend on the `DATA_SOURCE` async provider will wait until a `Promise` is resolved.

#### Repository pattern[#](/recipes/sql-typeorm#repository-pattern)

The [TypeORM](https://github.com/typeorm/typeorm) supports the repository design pattern, thus each entity has its own Repository. These repositories can be obtained from the database connection.

But firstly, we need at least one entity. We are going to reuse the `Photo` entity from the official documentation.

photo.entity.ts

JS TS

```typescript

import { Entity, Column, PrimaryGeneratedColumn } from 'typeorm';

@Entity()
export class Photo {
  @PrimaryGeneratedColumn()
  id: number;

  @Column({ length: 500 })
  name: string;

  @Column('text')
  description: string;

  @Column()
  filename: string;

  @Column('int')
  views: number;

  @Column()
  isPublished: boolean;
}
```

The `Photo` entity belongs to the `photo` directory. This directory represents the `PhotoModule`. Now, let's create a **Repository** provider:

photo.providers.ts

JS TS

```typescript

import { DataSource } from 'typeorm';
import { Photo } from './photo.entity';

export const photoProviders = [
  {
    provide: 'PHOTO_REPOSITORY',
    useFactory: (dataSource: DataSource) => dataSource.getRepository(Photo),
    inject: ['DATA_SOURCE'],
  },
];
```

> **Warning** In the real-world applications you should avoid **magic strings**. Both `PHOTO_REPOSITORY` and `DATA_SOURCE` should be kept in the separated `constants.ts` file.

Now we can inject the `Repository<Photo>` to the `PhotoService` using the `@Inject()` decorator:

photo.service.ts

JS TS

```typescript

import { Injectable, Inject } from '@nestjs/common';
import { Repository } from 'typeorm';
import { Photo } from './photo.entity';

@Injectable()
export class PhotoService {
  constructor(
    @Inject('PHOTO_REPOSITORY')
    private photoRepository: Repository<Photo>,
  ) {}

  async findAll(): Promise<Photo[]> {
    return this.photoRepository.find();
  }
}
```

The database connection is **asynchronous**, but Nest makes this process completely invisible for the end-user. The `PhotoRepository` is waiting for the db connection, and the `PhotoService` is delayed until repository is ready to use. The entire application can start when each class is instantiated.

Here is a final `PhotoModule`:

photo.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { DatabaseModule } from '../database/database.module';
import { photoProviders } from './photo.providers';
import { PhotoService } from './photo.service';

@Module({
  imports: [DatabaseModule],
  providers: [
    ...photoProviders,
    PhotoService,
  ],
})
export class PhotoModule {}
```

> **Hint** Do not forget to import the `PhotoModule` into the root `AppModule`.

----
url: https://docs.nestjs.com/graphql/mutations
----

[Skip to content](#content)

On this page

* [Mutations](https://docs.nestjs.com/graphql/mutations#mutations)
* [Code first](https://docs.nestjs.com/graphql/mutations#code-first)
* [Schema first](https://docs.nestjs.com/graphql/mutations#schema-first)

### Mutations

Most discussions of GraphQL focus on data fetching, but any complete data platform needs a way to modify server-side data as well. In REST, any request could cause side effects on the server, but best practice is not to modify data in `GET` requests. GraphQL is similar: technically, any query could be implemented to write data. However, as with REST, the convention is to send any operation that causes writes explicitly as a mutation (see [Mutations](https://graphql.org/learn/queries/#mutations) in the GraphQL documentation).

The official [Apollo documentation](https://www.apollographql.com/docs/graphql-tools/generate-schema.html) uses an `upvotePost()` mutation example, which increments a post's `votes` property. To create an equivalent mutation in Nest, use the `@Mutation()` decorator.

#### Code first[#](/graphql/mutations#code-first)

Add another method to the `AuthorsResolver` from the [Resolvers](/graphql/resolvers) chapter.

```typescript

@Mutation(() => Post)
async upvotePost(@Args({ name: 'postId', type: () => Int }) postId: number) {
  return this.postsService.upvoteById({ id: postId });
}
```

> **Hint** All decorators (e.g., `@Resolver`, `@ResolveField`, `@Args`, etc.) are exported from the `@nestjs/graphql` package.

This generates the following part of the GraphQL schema in SDL:

```graphql

type Mutation {
  upvotePost(postId: Int!): Post!
}
```

The `upvotePost()` method takes `postId` (`Int`) as an argument and returns the updated `Post` entity. For the reasons explained in the [Resolvers](/graphql/resolvers) chapter, you have to set the expected type explicitly.

If the mutation needs to take an object as an argument, create an **input type**. An input type is a special kind of object type that can be passed in as an argument (see [Input types](https://graphql.org/learn/schema/#input-types) in the GraphQL documentation). To declare an input type, use the `@InputType()` decorator.

```typescript

import { InputType, Field } from '@nestjs/graphql';

@InputType()
export class UpvotePostInput {
  @Field()
  postId: number;
}
```

> **Hint** The `@InputType()` decorator takes an options object as an argument, so you can, for example, specify the input type's description. Due to the limitations of TypeScript's metadata reflection system, you must either use the `@Field()` decorator to indicate a type, or use the [CLI plugin](/graphql/cli-plugin).

You can then use this type in the resolver class:

```typescript

@Mutation(() => Post)
async upvotePost(
  @Args('upvotePostData') upvotePostData: UpvotePostInput,
) {}
```

#### Schema first[#](/graphql/mutations#schema-first)

Extend the `AuthorsResolver` from the [Resolvers](/graphql/resolvers) chapter.

```typescript

@Mutation()
async upvotePost(@Args('postId') postId: number) {
  return this.postsService.upvoteById({ id: postId });
}
```

This example assumes that the business logic (querying the post and incrementing its `votes` property) lives in the `PostsService`. That logic can be as simple or sophisticated as needed. The point of this example is to show how resolvers interact with other providers.

The last step is to add the mutation to the existing type definitions.

```graphql

type Author {
  id: Int!
  firstName: String
  lastName: String
  posts: [Post]
}

type Post {
  id: Int!
  title: String
  votes: Int
}

type Query {
  author(id: Int!): Author
}

type Mutation {
  upvotePost(postId: Int!): Post
}
```

The `upvotePost(postId: Int!): Post` mutation is now part of the application's GraphQL API.

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/mutations.md)

----
url: https://docs.nestjs.com/v10/graphql/sharing-models
----

* [Sharing models](https://docs.nestjs.com/v10/graphql/sharing-models#sharing-models)
* [Using the model shim](https://docs.nestjs.com/v10/graphql/sharing-models#using-the-model-shim)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/sharing-models.md "Suggest Edits")

### Sharing models

> **Warning** This chapter applies only to the code first approach.

One of the biggest advantages of using Typescript for the backend of your project is the ability to reuse the same models in a Typescript-based frontend application, by using a common Typescript package.

But there's a problem: the models created using the code first approach are heavily decorated with GraphQL related decorators. Those decorators are irrelevant in the frontend, negatively impacting performance.

#### Using the model shim[#](/graphql/sharing-models#using-the-model-shim)

To solve this issue, NestJS provides a "shim" which allows you to replace the original decorators with inert code by using a `webpack` (or similar) configuration. To use this shim, configure an alias between the `@nestjs/graphql` package and the shim.

For example, for webpack this is resolved this way:

```typescript

resolve: { // see: https://webpack.js.org/configuration/resolve/
  alias: {
      "@nestjs/graphql": path.resolve(__dirname, "../node_modules/@nestjs/graphql/dist/extra/graphql-model-shim")
  }
}
```

> **Hint** The [TypeORM](/v10/techniques/database) package has a similar shim that can be found [here](https://github.com/typeorm/typeorm/blob/master/extra/typeorm-model-shim.js).

----
url: https://docs.nestjs.com/v11/techniques/caching
----

* [Caching](https://docs.nestjs.com/v11/techniques/caching#caching)
* [Installation](https://docs.nestjs.com/v11/techniques/caching#installation)
* [In-memory cache](https://docs.nestjs.com/v11/techniques/caching#in-memory-cache)
* [Interacting with the Cache store](https://docs.nestjs.com/v11/techniques/caching#interacting-with-the-cache-store)
* [Auto-caching responses](https://docs.nestjs.com/v11/techniques/caching#auto-caching-responses)
* [Time-to-live (TTL)](https://docs.nestjs.com/v11/techniques/caching#time-to-live-ttl)
* [Use module globally](https://docs.nestjs.com/v11/techniques/caching#use-module-globally)
* [Global cache overrides](https://docs.nestjs.com/v11/techniques/caching#global-cache-overrides)
* [WebSockets and Microservices](https://docs.nestjs.com/v11/techniques/caching#websockets-and-microservices)
* [Adjust tracking](https://docs.nestjs.com/v11/techniques/caching#adjust-tracking)
* [Using alternative Cache stores](https://docs.nestjs.com/v11/techniques/caching#using-alternative-cache-stores)
* [Async configuration](https://docs.nestjs.com/v11/techniques/caching#async-configuration)
* [Example](https://docs.nestjs.com/v11/techniques/caching#example)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/techniques/caching.md "Suggest Edits")

### Caching

Caching is a powerful and straightforward **technique** for enhancing your application's performance. By acting as a temporary storage layer, it allows for quicker access to frequently used data, reducing the need to repeatedly fetch or compute the same information. This results in faster response times and improved overall efficiency.

#### Installation[#](/techniques/caching#installation)

To get started with caching in Nest, you need to install the `@nestjs/cache-manager` package along with the `cache-manager` package.

```bash

$ npm install @nestjs/cache-manager cache-manager
```

By default, everything is stored in memory; Since `cache-manager` uses [Keyv](https://keyv.org/docs/) under the hood, you can easily switch to a more advanced storage solution, such as Redis, by installing the appropriate package. We'll cover this in more detail later.

#### In-memory cache[#](/techniques/caching#in-memory-cache)

To enable caching in your application, import the `CacheModule` and configure it using the `register()` method:

```typescript

import { Module } from '@nestjs/common';
import { CacheModule } from '@nestjs/cache-manager';
import { AppController } from './app.controller';

@Module({
  imports: [CacheModule.register()],
  controllers: [AppController],
})
export class AppModule {}
```

This setup initializes in-memory caching with default settings, allowing you to start caching data immediately.

#### Interacting with the Cache store[#](/techniques/caching#interacting-with-the-cache-store)

To interact with the cache manager instance, inject it to your class using the `CACHE_MANAGER` token, as follows:

```typescript

constructor(@Inject(CACHE_MANAGER) private cacheManager: Cache) {}
```

> **Hint** The `Cache` class and the `CACHE_MANAGER` token are both imported from the `@nestjs/cache-manager` package.

The `get` method on the `Cache` instance (from the `cache-manager` package) is used to retrieve items from the cache. If the item does not exist in the cache, `undefined` will be returned (in `cache-manager` v6 and earlier, `null` was returned instead). Treat both as falsy when migrating.

```typescript

const value = await this.cacheManager.get('key');
```

To add an item to the cache, use the `set` method:

```typescript

await this.cacheManager.set('key', 'value');
```

> **Note** The in-memory cache storage can only store values of types that are supported by [the structured clone algorithm](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm#javascript_types).

You can manually specify a TTL (expiration time in milliseconds) for this specific key, as follows:

```typescript

await this.cacheManager.set('key', 'value', 1000);
```

Where `1000` is the TTL in milliseconds - in this case, the cache item will expire after one second.

To disable expiration of the cache, set the `ttl` configuration property to `0`:

```typescript

await this.cacheManager.set('key', 'value', 0);
```

To remove an item from the cache, use the `del` method:

```typescript

await this.cacheManager.del('key');
```

To clear the entire cache, use the `clear` method:

```typescript

await this.cacheManager.clear();
```

#### Auto-caching responses[#](/techniques/caching#auto-caching-responses)

> **Warning** In [GraphQL](/v11/graphql/quick-start) applications, interceptors are executed separately for each field resolver. Thus, `CacheModule` (which uses interceptors to cache responses) will not work properly.

To enable auto-caching responses, just tie the `CacheInterceptor` where you want to cache data.

```typescript

@Controller()
@UseInterceptors(CacheInterceptor)
export class AppController {
  @Get()
  findAll(): string[] {
    return [];
  }
}
```

> **Warning** Only `GET` endpoints are cached. Also, HTTP server routes that inject the native response object (`@Res()`) cannot use the Cache Interceptor. See [response mapping](https://docs.nestjs.com/interceptors#response-mapping) for more details.

To reduce the amount of required boilerplate, you can bind `CacheInterceptor` to all endpoints globally:

```typescript

import { Module } from '@nestjs/common';
import { CacheModule, CacheInterceptor } from '@nestjs/cache-manager';
import { AppController } from './app.controller';
import { APP_INTERCEPTOR } from '@nestjs/core';

@Module({
  imports: [CacheModule.register()],
  controllers: [AppController],
  providers: [
    {
      provide: APP_INTERCEPTOR,
      useClass: CacheInterceptor,
    },
  ],
})
export class AppModule {}
```

#### Time-to-live (TTL)[#](/techniques/caching#time-to-live-ttl)

The default value for `ttl` is `0`, meaning the cache will never expire. To specify a custom [TTL](https://en.wikipedia.org/wiki/Time_to_live), you can provide the `ttl` option in the `register()` method, as demonstrated below:

```typescript

CacheModule.register({
  ttl: 5000, // milliseconds
});
```

#### Use module globally[#](/techniques/caching#use-module-globally)

When you want to use `CacheModule` in other modules, you'll need to import it (as is standard with any Nest module). Alternatively, declare it as a [global module](https://docs.nestjs.com/modules#global-modules) by setting the options object's `isGlobal` property to `true`, as shown below. In that case, you will not need to import `CacheModule` in other modules once it's been loaded in the root module (e.g., `AppModule`).

```typescript

CacheModule.register({
  isGlobal: true,
});
```

#### Global cache overrides[#](/techniques/caching#global-cache-overrides)

While global cache is enabled, cache entries are stored under a `CacheKey` that is auto-generated based on the route path. You may override certain cache settings (`@CacheKey()` and `@CacheTTL()`) on a per-method basis, allowing customized caching strategies for individual controller methods. This may be most relevant while using [different cache stores.](https://docs.nestjs.com/techniques/caching#different-stores)

You can apply the `@CacheTTL()` decorator on a per-controller basis to set a caching TTL for the entire controller. In situations where both controller-level and method-level cache TTL settings are defined, the cache TTL settings specified at the method level will take priority over the ones set at the controller level.

```typescript

@Controller()
@CacheTTL(50)
export class AppController {
  @CacheKey('custom_key')
  @CacheTTL(20)
  findAll(): string[] {
    return [];
  }
}
```

> **Hint** The `@CacheKey()` and `@CacheTTL()` decorators are imported from the `@nestjs/cache-manager` package.

The `@CacheKey()` decorator may be used with or without a corresponding `@CacheTTL()` decorator and vice versa. One may choose to override only the `@CacheKey()` or only the `@CacheTTL()`. Settings that are not overridden with a decorator will use the default values as registered globally (see [Customize caching](https://docs.nestjs.com/techniques/caching#customize-caching)).

#### WebSockets and Microservices[#](/techniques/caching#websockets-and-microservices)

You can also apply the `CacheInterceptor` to WebSocket subscribers as well as Microservice's patterns (regardless of the transport method that is being used).

JS TS

```typescript

@CacheKey('events')
@UseInterceptors(CacheInterceptor)
@SubscribeMessage('events')
handleEvent(client: Client, data: string[]): Observable<string[]> {
  return [];
}
```

```typescript

@CacheKey('events')
@UseInterceptors(CacheInterceptor)
@SubscribeMessage('events')
handleEvent(client, data) {
  return [];
}
```

However, the additional `@CacheKey()` decorator is required in order to specify a key used to subsequently store and retrieve cached data. Also, please note that you **shouldn't cache everything**. Actions which perform some business operations rather than simply querying the data should never be cached.

Additionally, you may specify a cache expiration time (TTL) by using the `@CacheTTL()` decorator, which will override the global default TTL value.

JS TS

```typescript

@CacheTTL(10)
@UseInterceptors(CacheInterceptor)
@SubscribeMessage('events')
handleEvent(client: Client, data: string[]): Observable<string[]> {
  return [];
}
```

```typescript

@CacheTTL(10)
@UseInterceptors(CacheInterceptor)
@SubscribeMessage('events')
handleEvent(client, data) {
  return [];
}
```

> **Hint** The `@CacheTTL()` decorator may be used with or without a corresponding `@CacheKey()` decorator.

#### Adjust tracking[#](/techniques/caching#adjust-tracking)

By default, Nest uses the request URL (in an HTTP app) or cache key (in websockets and microservices apps, set through the `@CacheKey()` decorator) to associate cache records with your endpoints. Nevertheless, sometimes you might want to set up tracking based on different factors, for example, using HTTP headers (e.g. `Authorization` to properly identify `profile` endpoints).

In order to accomplish that, create a subclass of `CacheInterceptor` and override the `trackBy()` method.

```typescript

@Injectable()
class HttpCacheInterceptor extends CacheInterceptor {
  trackBy(context: ExecutionContext): string | undefined {
    return 'key';
  }
}
```

#### Using alternative Cache stores[#](/techniques/caching#using-alternative-cache-stores)

Switching to a different cache store is straightforward. First, install the appropriate package. For example, to use Redis, install the `@keyv/redis` package:

```bash

$ npm install @keyv/redis
```

With this in place, you can register the `CacheModule` with multiple stores as shown below:

```typescript

import { Module } from '@nestjs/common';
import { CacheModule } from '@nestjs/cache-manager';
import { AppController } from './app.controller';
import KeyvRedis from '@keyv/redis';
import { Keyv } from 'keyv';
import { KeyvCacheableMemory } from 'cacheable';

@Module({
  imports: [
    CacheModule.registerAsync({
      useFactory: async () => {
        return {
          stores: [
            new Keyv({
              store: new KeyvCacheableMemory({ ttl: 60000, lruSize: 5000 }),
            }),
            new KeyvRedis('redis://localhost:6379'),
          ],
        };
      },
    }),
  ],
  controllers: [AppController],
})
export class AppModule {}
```

In this example, we've registered two stores: `CacheableMemory` and `KeyvRedis`. The `CacheableMemory` store is a simple in-memory store, which is created via the `KeyvCacheableMemory` storage adapter, while `KeyvRedis` is a Redis store. The `stores` array is used to specify the stores you want to use. The first store in the array is the default store, and the rest are fallback stores.

Check out the [Keyv documentation](https://keyv.org/docs/) for more information on available stores.

#### Async configuration[#](/techniques/caching#async-configuration)

You may want to asynchronously pass in module options instead of passing them statically at compile time. In this case, use the `registerAsync()` method, which provides several ways to deal with async configuration.

One approach is to use a factory function:

```typescript

CacheModule.registerAsync({
  useFactory: () => ({
    ttl: 5,
  }),
});
```

Our factory behaves like all other asynchronous module factories (it can be `async` and is able to inject dependencies through `inject`).

```typescript

CacheModule.registerAsync({
  imports: [ConfigModule],
  useFactory: async (configService: ConfigService) => ({
    ttl: configService.get('CACHE_TTL'),
  }),
  inject: [ConfigService],
});
```

Alternatively, you can use the `useClass` method:

```typescript

CacheModule.registerAsync({
  useClass: CacheConfigService,
});
```

The above construction will instantiate `CacheConfigService` inside `CacheModule` and will use it to get the options object. The `CacheConfigService` has to implement the `CacheOptionsFactory` interface in order to provide the configuration options:

```typescript

@Injectable()
class CacheConfigService implements CacheOptionsFactory {
  createCacheOptions(): CacheModuleOptions {
    return {
      ttl: 5,
    };
  }
}
```

If you wish to use an existing configuration provider imported from a different module, use the `useExisting` syntax:

```typescript

CacheModule.registerAsync({
  imports: [ConfigModule],
  useExisting: ConfigService,
});
```

This works the same as `useClass` with one critical difference - `CacheModule` will lookup imported modules to reuse any already-created `ConfigService`, instead of instantiating its own.

> **Hint**`CacheModule#register`, `CacheModule#registerAsync` and `CacheOptionsFactory` have an optional generic (type argument) to narrow down store-specific configuration options, making it type safe.

You can also pass so-called `extraProviders` to the `registerAsync()` method. These providers will be merged with the module providers.

```typescript

CacheModule.registerAsync({
  imports: [ConfigModule],
  useClass: ConfigService,
  extraProviders: [MyAdditionalProvider],
});
```

This is useful when you want to provide additional dependencies to the factory function or the class constructor.

#### Example[#](/techniques/caching#example)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/20-cache).

----
url: https://docs.nestjs.com/v11/faq/common-errors
----

* [Common errors](https://docs.nestjs.com/v11/faq/common-errors#common-errors)
* ["Cannot resolve dependency" error](https://docs.nestjs.com/v11/faq/common-errors#cannot-resolve-dependency-error)
* ["Circular dependency" error](https://docs.nestjs.com/v11/faq/common-errors#circular-dependency-error)
* [Debugging dependency errors](https://docs.nestjs.com/v11/faq/common-errors#debugging-dependency-errors)
* ["File change detected" loops endlessly](https://docs.nestjs.com/v11/faq/common-errors#file-change-detected-loops-endlessly)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/faq/errors.md "Suggest Edits")

### Common errors

During your development with NestJS, you may encounter various errors as you learn the framework.

#### "Cannot resolve dependency" error[#](/faq/common-errors#cannot-resolve-dependency-error)

> **Hint** Check out the [NestJS Devtools](/devtools/overview#investigating-the-cannot-resolve-dependency-error) which can help you resolve the "Cannot resolve dependency" error effortlessly.

Probably the most common error message is about Nest not being able to resolve dependencies of a provider. The error message usually looks something like this:

```bash

Nest can't resolve dependencies of the <provider> (?). Please make sure that the argument <unknown_token> at index [<index>] is available in the <module> context.

Potential solutions:
- Is <module> a valid NestJS module?
- If <unknown_token> is a provider, is it part of the current <module>?
- If <unknown_token> is exported from a separate @Module, is that module imported within <module>?
  @Module({
    imports: [ /* the Module containing <unknown_token> */ ]
  })
```

The most common culprit of the error, is not having the `<provider>` in the module's `providers` array. Please make sure that the provider is indeed in the `providers` array and following [standard NestJS provider practices](/fundamentals/custom-providers#di-fundamentals).

There are a few gotchas, that are common. One is putting a provider in an `imports` array. If this is the case, the error will have the provider's name where `<module>` should be.

If you run across this error while developing, take a look at the module mentioned in the error message and look at its `providers`. For each provider in the `providers` array, make sure the module has access to all of the dependencies. Often times, `providers` are duplicated in a "Feature Module" and a "Root Module" which means Nest will try to instantiate the provider twice. More than likely, the module containing the `<provider>` being duplicated should be added in the "Root Module"'s `imports` array instead.

If the `<unknown_token>` above is `dependency`, you might have a circular file import. This is different from the [circular dependency](/faq/common-errors#circular-dependency-error) below because instead of having providers depend on each other in their constructors, it just means that two files end up importing each other. A common case would be a module file declaring a token and importing a provider, and the provider import the token constant from the module file. If you are using barrel files, ensure that your barrel imports do not end up creating these circular imports as well.

If the `<unknown_token>` above is `Object`, it means that you're injecting using an type/interface without a proper provider's token. To fix that, make sure that:

1. you're importing the class reference or use a custom token with `@Inject()` decorator. Read the [custom providers page](/v11/fundamentals/custom-providers), and

```bash

Nest can't resolve dependencies of the <provider> (?).
Please make sure that the argument ModuleRef at index [<index>] is available in the <module> context.
...
```

This likely happens when your project end up loading two Node modules of the package `@nestjs/core`, like this:

```text

.
├── package.json
├── apps
│   └── api
│       └── node_modules
│           └── @nestjs/bull
│               └── node_modules
│                   └── @nestjs/core
└── node_modules
    ├── (other packages)
    └── @nestjs/core
```

Solutions:

* For **Yarn** Workspaces, use the [nohoist feature](https://classic.yarnpkg.com/blog/2018/02/15/nohoist) to prevent hoisting the package `@nestjs/core`.
* For **pnpm** Workspaces, set `@nestjs/core` as a peerDependencies in your other module and `"dependenciesMeta": {"other-module-name": {"injected": true }}` in the app package.json where the module is imported. see: [dependenciesmetainjected](https://pnpm.io/package_json#dependenciesmetainjected)

#### "Circular dependency" error[#](/faq/common-errors#circular-dependency-error)

Occasionally you'll find it difficult to avoid [circular dependencies](https://docs.nestjs.com/fundamentals/circular-dependency) in your application. You'll need to take some steps to help Nest resolve these. Errors that arise from circular dependencies look like this:

```bash

Nest cannot create the <module> instance.
The module at index [<index>] of the <module> "imports" array is undefined.

Potential causes:
- A circular dependency between modules. Use forwardRef() to avoid it. Read more: https://docs.nestjs.com/fundamentals/circular-dependency
- The module at index [<index>] is of type "undefined". Check your import statements and the type of the module.

Scope [<module_import_chain>]
# example chain AppModule -> FooModule
```

Circular dependencies can arise from both providers depending on each other, or typescript files depending on each other for constants, such as exporting constants from a module file and importing them in a service file. In the latter case, it is advised to create a separate file for your constants. In the former case, please follow the guide on circular dependencies and make sure that both the modules **and** the providers are marked with `forwardRef`.

#### Debugging dependency errors[#](/faq/common-errors#debugging-dependency-errors)

Along with just manually verifying your dependencies are correct, as of Nest 8.1.0 you can set the `NEST_DEBUG` environment variable to a string that resolves as truthy, and get extra logging information while Nest is resolving all of the dependencies for the application.

In the above image, the string in yellow is the host class of the dependency being injected, the string in blue is the name of the injected dependency, or its injection token, and the string in purple is the module in which the dependency is being searched for. Using this, you can usually trace back the dependency resolution for what's happening and why you're getting dependency injection problems.

#### "File change detected" loops endlessly[#](/faq/common-errors#file-change-detected-loops-endlessly)

Windows users who are using TypeScript version 4.9 and up may encounter this problem. This happens when you're trying to run your application in watch mode, e.g `npm run start:dev` and see an endless loop of the log messages:

```bash

XX:XX:XX AM - File change detected. Starting incremental compilation...
XX:XX:XX AM - Found 0 errors. Watching for file changes.
```

When you're using the NestJS CLI to start your application in watch mode it is done by calling `tsc --watch`, and as of version 4.9 of TypeScript, a [new strategy](https://devblogs.microsoft.com/typescript/announcing-typescript-4-9/#file-watching-now-uses-file-system-events) for detecting file changes is used which is likely to be the cause of this problem. In order to fix this problem, you need to add a setting to your tsconfig.json file after the `"compilerOptions"` option as follows:

```bash

  "watchOptions": {
    "watchFile": "fixedPollingInterval"
  }
```

This tells TypeScript to use the polling method for checking for file changes instead of file system events (the new default method), which can cause issues on some machines. You can read more about the `"watchFile"` option in [TypeScript documentation](https://www.typescriptlang.org/tsconfig#watch-watchDirectory).

----
url: https://docs.nestjs.com/v9/middleware
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Middleware](https://docs.nestjs.com/v9/middleware#middleware)
* [Dependency injection](https://docs.nestjs.com/v9/middleware#dependency-injection)
* [Applying middleware](https://docs.nestjs.com/v9/middleware#applying-middleware)
* [Route wildcards](https://docs.nestjs.com/v9/middleware#route-wildcards)
* [Middleware consumer](https://docs.nestjs.com/v9/middleware#middleware-consumer)
* [Excluding routes](https://docs.nestjs.com/v9/middleware#excluding-routes)
* [Functional middleware](https://docs.nestjs.com/v9/middleware#functional-middleware)
* [Multiple middleware](https://docs.nestjs.com/v9/middleware#multiple-middleware)
* [Global middleware](https://docs.nestjs.com/v9/middleware#global-middleware)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/middlewares.md "Suggest Edits")

### Middleware

Middleware is a function which is called **before** the route handler. Middleware functions have access to the [request](https://expressjs.com/en/4x/api.html#req) and [response](https://expressjs.com/en/4x/api.html#res) objects, and the `next()` middleware function in the application’s request-response cycle. The **next** middleware function is commonly denoted by a variable named `next`.

Nest middleware are, by default, equivalent to [express](https://expressjs.com/en/guide/using-middleware.html) middleware. The following description from the official express documentation describes the capabilities of middleware:

> Middleware functions can perform the following tasks:
>
> * execute any code.
> * make changes to the request and the response objects.
> * end the request-response cycle.
> * call the next middleware function in the stack.
> * if the current middleware function does not end the request-response cycle, it must call `next()` to pass control to the next middleware function. Otherwise, the request will be left hanging.

You implement custom Nest middleware in either a function, or in a class with an `@Injectable()` decorator. The class should implement the `NestMiddleware` interface, while the function does not have any special requirements. Let's start by implementing a simple middleware feature using the class method.

> **Warning**`Express` and `fastify` handle middleware differently and provide different method signatures, read more [here](/techniques/performance#middleware).

logger.middleware.ts

JS TS

```typescript

import { Injectable, NestMiddleware } from '@nestjs/common';
import { Request, Response, NextFunction } from 'express';

@Injectable()
export class LoggerMiddleware implements NestMiddleware {
  use(req: Request, res: Response, next: NextFunction) {
    console.log('Request...');
    next();
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';

@Injectable()
export class LoggerMiddleware {
  use(req, res, next) {
    console.log('Request...');
    next();
  }
}
```

#### Dependency injection[#](/middleware#dependency-injection)

Nest middleware fully supports Dependency Injection. Just as with providers and controllers, they are able to **inject dependencies** that are available within the same module. As usual, this is done through the `constructor`.

#### Applying middleware[#](/middleware#applying-middleware)

There is no place for middleware in the `@Module()` decorator. Instead, we set them up using the `configure()` method of the module class. Modules that include middleware have to implement the `NestModule` interface. Let's set up the `LoggerMiddleware` at the `AppModule` level.

app.module.ts

JS TS

```typescript

import { Module, NestModule, MiddlewareConsumer } from '@nestjs/common';
import { LoggerMiddleware } from './common/middleware/logger.middleware';
import { CatsModule } from './cats/cats.module';

@Module({
  imports: [CatsModule],
})
export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer
      .apply(LoggerMiddleware)
      .forRoutes('cats');
  }
}
```

```typescript

import { Module } from '@nestjs/common';
import { LoggerMiddleware } from './common/middleware/logger.middleware';
import { CatsModule } from './cats/cats.module';

@Module({
  imports: [CatsModule],
})
export class AppModule {
  configure(consumer) {
    consumer
      .apply(LoggerMiddleware)
      .forRoutes('cats');
  }
}
```

In the above example we have set up the `LoggerMiddleware` for the `/cats` route handlers that were previously defined inside the `CatsController`. We may also further restrict a middleware to a particular request method by passing an object containing the route `path` and request `method` to the `forRoutes()` method when configuring the middleware. In the example below, notice that we import the `RequestMethod` enum to reference the desired request method type.

app.module.ts

JS TS

```typescript

import { Module, NestModule, RequestMethod, MiddlewareConsumer } from '@nestjs/common';
import { LoggerMiddleware } from './common/middleware/logger.middleware';
import { CatsModule } from './cats/cats.module';

@Module({
  imports: [CatsModule],
})
export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer
      .apply(LoggerMiddleware)
      .forRoutes({ path: 'cats', method: RequestMethod.GET });
  }
}
```

```typescript

import { Module, RequestMethod } from '@nestjs/common';
import { LoggerMiddleware } from './common/middleware/logger.middleware';
import { CatsModule } from './cats/cats.module';

@Module({
  imports: [CatsModule],
})
export class AppModule {
  configure(consumer) {
    consumer
      .apply(LoggerMiddleware)
      .forRoutes({ path: 'cats', method: RequestMethod.GET });
  }
}
```

> **Hint** The `configure()` method can be made asynchronous using `async/await` (e.g., you can `await` completion of an asynchronous operation inside the `configure()` method body).

> **Warning** When using the `express` adapter, the NestJS app will register `json` and `urlencoded` from the package `body-parser` by default. This means if you want to customize that middleware via the `MiddlewareConsumer`, you need to turn off the global middleware by setting the `bodyParser` flag to `false` when creating the application with `NestFactory.create()`.

#### Route wildcards[#](/middleware#route-wildcards)

Pattern based routes are supported as well. For instance, the asterisk is used as a **wildcard**, and will match any combination of characters:

```typescript

forRoutes({ path: 'ab*cd', method: RequestMethod.ALL });
```

The `'ab*cd'` route path will match `abcd`, `ab_cd`, `abecd`, and so on. The characters `?`, `+`, `*`, and `()` may be used in a route path, and are subsets of their regular expression counterparts. The hyphen ( `-`) and the dot (`.`) are interpreted literally by string-based paths.

> **Warning** The `fastify` package uses the latest version of the `path-to-regexp` package, which no longer supports wildcard asterisks `*`. Instead, you must use parameters (e.g., `(.*)`, `:splat*`).

#### Middleware consumer[#](/middleware#middleware-consumer)

The `MiddlewareConsumer` is a helper class. It provides several built-in methods to manage middleware. All of them can be simply **chained** in the [fluent style](https://en.wikipedia.org/wiki/Fluent_interface). The `forRoutes()` method can take a single string, multiple strings, a `RouteInfo` object, a controller class and even multiple controller classes. In most cases you'll probably just pass a list of **controllers** separated by commas. Below is an example with a single controller:

app.module.ts

JS TS

```typescript

import { Module, NestModule, MiddlewareConsumer } from '@nestjs/common';
import { LoggerMiddleware } from './common/middleware/logger.middleware';
import { CatsModule } from './cats/cats.module';
import { CatsController } from './cats/cats.controller';

@Module({
  imports: [CatsModule],
})
export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer
      .apply(LoggerMiddleware)
      .forRoutes(CatsController);
  }
}
```

```typescript

import { Module } from '@nestjs/common';
import { LoggerMiddleware } from './common/middleware/logger.middleware';
import { CatsModule } from './cats/cats.module';
import { CatsController } from './cats/cats.controller';

@Module({
  imports: [CatsModule],
})
export class AppModule {
  configure(consumer) {
    consumer
      .apply(LoggerMiddleware)
      .forRoutes(CatsController);
  }
}
```

> **Hint** The `apply()` method may either take a single middleware, or multiple arguments to specify [multiple middlewares](/middleware#multiple-middleware).

#### Excluding routes[#](/middleware#excluding-routes)

At times we want to **exclude** certain routes from having the middleware applied. We can easily exclude certain routes with the `exclude()` method. This method can take a single string, multiple strings, or a `RouteInfo` object identifying routes to be excluded, as shown below:

```typescript

consumer
  .apply(LoggerMiddleware)
  .exclude(
    { path: 'cats', method: RequestMethod.GET },
    { path: 'cats', method: RequestMethod.POST },
    'cats/(.*)',
  )
  .forRoutes(CatsController);
```

> **Hint** The `exclude()` method supports wildcard parameters using the [path-to-regexp](https://github.com/pillarjs/path-to-regexp#parameters) package.

With the example above, `LoggerMiddleware` will be bound to all routes defined inside `CatsController`**except** the three passed to the `exclude()` method.

#### Functional middleware[#](/middleware#functional-middleware)

The `LoggerMiddleware` class we've been using is quite simple. It has no members, no additional methods, and no dependencies. Why can't we just define it in a simple function instead of a class? In fact, we can. This type of middleware is called **functional middleware**. Let's transform the logger middleware from class-based into functional middleware to illustrate the difference:

logger.middleware.ts

JS TS

```typescript

import { Request, Response, NextFunction } from 'express';

export function logger(req: Request, res: Response, next: NextFunction) {
  console.log(`Request...`);
  next();
};
```

```typescript

export function logger(req, res, next) {
  console.log(`Request...`);
  next();
};
```

And use it within the `AppModule`:

app.module.ts

JS TS

```typescript

consumer
  .apply(logger)
  .forRoutes(CatsController);
```

> **Hint** Consider using the simpler **functional middleware** alternative any time your middleware doesn't need any dependencies.

#### Multiple middleware[#](/middleware#multiple-middleware)

As mentioned above, in order to bind multiple middleware that are executed sequentially, simply provide a comma separated list inside the `apply()` method:

```typescript

consumer.apply(cors(), helmet(), logger).forRoutes(CatsController);
```

#### Global middleware[#](/middleware#global-middleware)

If we want to bind middleware to every registered route at once, we can use the `use()` method that is supplied by the `INestApplication` instance:

main.ts

JS TS

```typescript

const app = await NestFactory.create(AppModule);
app.use(logger);
await app.listen(3000);
```

> **Hint** Accessing the DI container in a global middleware is not possible. You can use a [functional middleware](middleware#functional-middleware) instead when using `app.use()`. Alternatively, you can use a class middleware and consume it with `.forRoutes('*')` within the `AppModule` (or any other module).

----
url: https://docs.nestjs.com/v7/techniques/queues
----

* [Queues](https://docs.nestjs.com/v7/techniques/queues#queues)
* [Installation](https://docs.nestjs.com/v7/techniques/queues#installation)
* [Named configurations](https://docs.nestjs.com/v7/techniques/queues#named-configurations)
* [Producers](https://docs.nestjs.com/v7/techniques/queues#producers)
* [Named jobs](https://docs.nestjs.com/v7/techniques/queues#named-jobs)
* [Job options](https://docs.nestjs.com/v7/techniques/queues#job-options)
* [Consumers](https://docs.nestjs.com/v7/techniques/queues#consumers)
* [Request-scoped consumers](https://docs.nestjs.com/v7/techniques/queues#request-scoped-consumers)
* [Event listeners](https://docs.nestjs.com/v7/techniques/queues#event-listeners)
* [Queue management](https://docs.nestjs.com/v7/techniques/queues#queue-management)
* [Separate processes](https://docs.nestjs.com/v7/techniques/queues#separate-processes)
* [Async configuration](https://docs.nestjs.com/v7/techniques/queues#async-configuration)
* [Example](https://docs.nestjs.com/v7/techniques/queues#example)

```bash

$ npm install --save @nestjs/bull bull
$ npm install --save-dev @types/bull
```

Once the installation process is complete, we can import the `BullModule` into the root `AppModule`.

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { BullModule } from '@nestjs/bull';

@Module({
  imports: [
    BullModule.forRoot({
      redis: {
        host: 'localhost',
        port: 6379,
      },
    }),
  ],
})
export class AppModule {}
```

The `forRoot()` method is used to register a `bull` package configuration object that will be used by all queues registered in the application (unless specified otherwise). A configuration object consist of the following properties:

* `limiter: RateLimiter` - Options to control the rate at which the queue's jobs are processed. See [RateLimiter](https://github.com/OptimalBits/bull/blob/master/REFERENCE.md#queue) for more information. Optional.
* `redis: RedisOpts` - Options to configure the Redis connection. See [RedisOpts](https://github.com/OptimalBits/bull/blob/master/REFERENCE.md#queue) for more information. Optional.
* `prefix: string` - Prefix for all queue keys. Optional.
* `defaultJobOptions: JobOpts` - Options to control the default settings for new jobs. See [JobOpts](https://github.com/OptimalBits/bull/blob/master/REFERENCE.md#queueadd) for more information. Optional.
* `settings: AdvancedSettings` - Advanced Queue configuration settings. These should usually not be changed. See [AdvancedSettings](https://github.com/OptimalBits/bull/blob/master/REFERENCE.md#queue) for more information. Optional.

All the options are optional, providing detailed control over queue behavior. These are passed directly to the Bull `Queue` constructor. Read more about these options [here](https://github.com/OptimalBits/bull/blob/master/REFERENCE.md#queue).

To register a queue, import the `BullModule#registerQueue()` dynamic module, as follows:

```typescript

BullModule.registerQueue({
  name: 'audio',
});
```

> **Hint** Create multiple queues by passing multiple comma-separated configuration objects to the `registerQueue()` method.

The `registerQueue()` method is used to instantiate and/or register queues. Queues are shared across modules and processes that connect to the same underlying Redis database with the same credentials. Each queue is unique by its name property. A queue name is used as both an injection token (for injecting the queue into controllers/providers), and as an argument to decorators to associate consumer classes and listeners with queues.

You can also override some of the pre-configured options for a specific queue, as follows:

```typescript

BullModule.registerQueue({
  name: 'audio',
  redis: {
    port: 6380,
  },
});
```

```typescript

BullModule.forRoot('alternative-config', {
  redis: {
    port: 6381,
  },
});
```

In the example above, `'alternative-config'` is just a configuration key (it can be any arbitrary string).

With this in place, you can now point to this configuration in the `registerQueue()` options object:

```typescript

BullModule.registerQueue({
  configKey: 'alternative-queue'
  name: 'video',
});
```

#### Producers[#](/techniques/queues#producers)

Job producers add jobs to queues. Producers are typically application services (Nest [providers](/v7/providers)). To add jobs to a queue, first inject the queue into the service as follows:

```typescript

import { Injectable } from '@nestjs/common';
import { Queue } from 'bull';
import { InjectQueue } from '@nestjs/bull';

@Injectable()
export class AudioService {
  constructor(@InjectQueue('audio') private audioQueue: Queue) {}
}
```

> **Hint** The `@InjectQueue()` decorator identifies the queue by its name, as provided in the `registerQueue()` method call (e.g., `'audio'`).

Now, add a job by calling the queue's `add()` method, passing a user-defined job object. Jobs are represented as serializable JavaScript objects (since that is how they are stored in the Redis database). The shape of the job you pass is arbitrary; use it to represent the semantics of your job object.

```typescript

const job = await this.audioQueue.add({
  foo: 'bar',
});
```

#### Named jobs[#](/techniques/queues#named-jobs)

Jobs may have unique names. This allows you to create specialized [consumers](techniques/queues#consumers) that will only process jobs with a given name.

```typescript

const job = await this.audioQueue.add('transcode', {
  foo: 'bar',
});
```

> **Warning** When using named jobs, you must create processors for each unique name added to a queue, or the queue will complain that you are missing a processor for the given job. See [here](techniques/queues#consumers) for more information on consuming named jobs.

```typescript

const job = await this.audioQueue.add(
  {
    foo: 'bar',
  },
  { delay: 3000 }, // 3 seconds delayed
);
```

To add a job to the right end of the queue (process the job as **LIFO** (Last In First Out)), set the `lifo` property of the configuration object to `true`.

```typescript

const job = await this.audioQueue.add(
  {
    foo: 'bar',
  },
  { lifo: true },
);
```

To prioritize a job, use the `priority` property.

```typescript

const job = await this.audioQueue.add(
  {
    foo: 'bar',
  },
  { priority: 2 },
);
```

#### Consumers[#](/techniques/queues#consumers)

A consumer is a **class** defining methods that either process jobs added into the queue, or listen for events on the queue, or both. Declare a consumer class using the `@Processor()` decorator as follows:

```typescript

import { Processor } from '@nestjs/bull';

@Processor('audio')
export class AudioConsumer {}
```

Where the decorator's string argument (e.g., `'audio'`) is the name of the queue to be associated with the class methods.

Within a consumer class, declare job handlers by decorating handler methods with the `@Process()` decorator.

```typescript

import { Processor, Process } from '@nestjs/bull';
import { Job } from 'bull';

@Processor('audio')
export class AudioConsumer {
  @Process()
  async transcode(job: Job<unknown>) {
    let progress = 0;
    for (i = 0; i < 100; i++) {
      await doSomething(job.data);
      progress += 10;
      job.progress(progress);
    }
    return {};
  }
}
```

The decorated method (e.g., `transcode()`) is called whenever the worker is idle and there are jobs to process in the queue. This handler method receives the `job` object as its only argument. The value returned by the handler method is stored in the job object and can be accessed later on, for example in a listener for the completed event.

`Job` objects have multiple methods that allow you to interact with their state. For example, the above code uses the `progress()` method to update the job's progress. See [here](https://github.com/OptimalBits/bull/blob/master/REFERENCE.md#job) for the complete `Job` object API reference.

You can designate that a job handler method will handle **only** jobs of a certain type (jobs with a specific `name`) by passing that `name` to the `@Process()` decorator as shown below. You can have multiple `@Process()` handlers in a given consumer class, corresponding to each job type (`name`). When you use named jobs, be sure to have a handler corresponding to each name.

```typescript

@Process('transcode')
async transcode(job: Job<unknown>) { ... }
```

#### Request-scoped consumers[#](/techniques/queues#request-scoped-consumers)

When a consumer is flagged as request-scoped (learn more about the injection scopes [here](/fundamentals/injection-scopes#provider-scope)), a new instance of the class will be created exclusively for each job. The instance will be garbage-collected after the job has completed.

```typescript

@Processor({
  name: 'audio',
  scope: Scope.REQUEST,
})
```

Since request-scoped consumer classes are instantiated dynamically and scoped to a single job, you can inject a `JOB_REF` through the constructor using a standard approach.

```typescript

constructor(@Inject(JOB_REF) jobRef: Job) {
  console.log(jobRef);
}
```

> **Hint** The `JOB_REF` token is imported from the `@nestjs/bull` package.

#### Event listeners[#](/techniques/queues#event-listeners)

Bull generates a set of useful events when queue and/or job state changes occur. Nest provides a set of decorators that allow subscribing to a core set of standard events. These are exported from the `@nestjs/bull` package.

Event listeners must be declared within a [consumer](techniques/queues#consumers) class (i.e., within a class decorated with the `@Processor()` decorator). To listen for an event, use one of the decorators in the table below to declare a handler for the event. For example, to listen to the event emitted when a job enters the active state in the `audio` queue, use the following construct:

```typescript

import { Processor, Process } from '@nestjs/bull';
import { Job } from 'bull';

@Processor('audio')
export class AudioConsumer {

  @OnQueueActive()
  onActive(job: Job) {
    console.log(
      `Processing job ${job.id} of type ${job.name} with data ${job.data}...`,
    );
  }
  ...
```

Since Bull operates in a distributed (multi-node) environment, it defines the concept of event locality. This concept recognizes that events may be triggered either entirely within a single process, or on shared queues from different processes. A **local** event is one that is produced when an action or state change is triggered on a queue in the local process. In other words, when your event producers and consumers are local to a single process, all events happening on queues are local.

When a queue is shared across multiple processes, we encounter the possibility of **global** events. For a listener in one process to receive an event notification triggered by another process, it must register for a global event.

Event handlers are invoked whenever their corresponding event is emitted. The handler is called with the signature shown in the table below, providing access to information relevant to the event. We discuss one key difference between local and global event handler signatures below.

| Local event listeners | Global event listeners      | Handler method signature / When fired                                                                                                                                 |
| --------------------- | --------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `@OnQueueError()`     | `@OnGlobalQueueError()`     | `handler(error: Error)` - An error occurred. `error` contains the triggering error.                                                                                   |
| `@OnQueueWaiting()`   | `@OnGlobalQueueWaiting()`   | `handler(jobId: number \| string)` - A Job is waiting to be processed as soon as a worker is idling. `jobId` contains the id for the job that has entered this state. |
| `@OnQueueActive()`    | `@OnGlobalQueueActive()`    | `handler(job: Job)` - Job `job`has started.                                                                                                                           |
| `@OnQueueStalled()`   | `@OnGlobalQueueStalled()`   | `handler(job: Job)` - Job `job` has been marked as stalled. This is useful for debugging job workers that crash or pause the event loop.                              |
| `@OnQueueProgress()`  | `@OnGlobalQueueProgress()`  | `handler(job: Job, progress: number)` - Job `job`'s progress was updated to value `progress`.                                                                         |
| `@OnQueueCompleted()` | `@OnGlobalQueueCompleted()` | `handler(job: Job, result: any)` Job `job` successfully completed with a result `result`.                                                                             |
| `@OnQueueFailed()`    | `@OnGlobalQueueFailed()`    | `handler(job: Job, err: Error)` Job `job` failed with reason `err`.                                                                                                   |
| `@OnQueuePaused()`    | `@OnGlobalQueuePaused()`    | `handler()` The queue has been paused.                                                                                                                                |
| `@OnQueueResumed()`   | `@OnGlobalQueueResumed()`   | `handler(job: Job)` The queue has been resumed.                                                                                                                       |
| `@OnQueueCleaned()`   | `@OnGlobalQueueCleaned()`   | `handler(jobs: Job[], type: string)` Old jobs have been cleaned from the queue. `jobs` is an array of cleaned jobs, and `type` is the type of jobs cleaned.           |
| `@OnQueueDrained()`   | `@OnGlobalQueueDrained()`   | `handler()` Emitted whenever the queue has processed all the waiting jobs (even if there can be some delayed jobs not yet processed).                                 |
| `@OnQueueRemoved()`   | `@OnGlobalQueueRemoved()`   | `handler(job: Job)` Job `job` was successfully removed.                                                                                                               |

When listening for global events, the method signatures can be slightly different from their local counterpart. Specifically, any method signature that receives `job` objects in the local version, instead receives a `jobId` (`number`) in the global version. To get a reference to the actual `job` object in such a case, use the `Queue#getJob` method. This call should be awaited, and therefore the handler should be declared `async`. For example:

```typescript

@OnGlobalQueueCompleted()
async onGlobalCompleted(jobId: number, result: any) {
  const job = await this.immediateQueue.getJob(jobId);
  console.log('(Global) on completed: job ', job.id, ' -> result: ', result);
}
```

> **Hint** To access the `Queue` object (to make a `getJob()` call), you must of course inject it. Also, the Queue must be registered in the module where you are injecting it.

In addition to the specific event listener decorators, you can also use the generic `@OnQueueEvent()` decorator in combination with either `BullQueueEvents` or `BullQueueGlobalEvents` enums. Read more about events [here](https://github.com/OptimalBits/bull/blob/master/REFERENCE.md#events).

#### Queue management[#](/techniques/queues#queue-management)

Queue's have an API that allows you to perform management functions like pausing and resuming, retrieving the count of jobs in various states, and several more. You can find the full queue API [here](https://github.com/OptimalBits/bull/blob/master/REFERENCE.md#queue). Invoke any of these methods directly on the `Queue` object, as shown below with the pause/resume examples.

Pause a queue with the `pause()` method call. A paused queue will not process new jobs until resumed, but current jobs being processed will continue until they are finalized.

```typescript

await audioQueue.pause();
```

To resume a paused queue, use the `resume()` method, as follows:

```typescript

await audioQueue.resume();
```

```ts

import { Module } from '@nestjs/common';
import { BullModule } from '@nestjs/bull';
import { join } from 'path';

@Module({
  imports: [
    BullModule.registerQueue({
      name: 'audio',
      processors: [join(__dirname, 'processor.js')],
    }),
  ],
})
export class AppModule {}
```

Please note that because your function is being executed in a forked process, Dependency Injection (and IoC container) won't be available. That means that your processor function will need to contain (or create) all instances of external dependencies it needs.

processor.ts

JS TS

```ts

import { Job, DoneCallback } from 'bull';

export default function (job: Job, cb: DoneCallback) {
  console.log(`[${process.pid}] ${JSON.stringify(job.data)}`);
  cb(null, 'It works');
}
```

#### Async configuration[#](/techniques/queues#async-configuration)

You may want to pass `bull` options asynchronously instead of statically. In this case, use the `forRootAsync()` method which provides several ways to deal with async configuration. Likewise, if you want to pass queue options asynchronously, use the `registerQueueAsync()` method.

One approach is to use a factory function:

```typescript

BullModule.forRootAsync({
  useFactory: () => ({
    redis: {
      host: 'localhost',
      port: 6379,
    },
  }),
});
```

Our factory behaves like any other [asynchronous provider](https://docs.nestjs.com/fundamentals/async-providers) (e.g., it can be `async` and it's able to inject dependencies through `inject`).

```typescript

BullModule.forRootAsync({
  imports: [ConfigModule],
  useFactory: async (configService: ConfigService) => ({
    redis: {
      host: configService.get('QUEUE_HOST'),
      port: +configService.get('QUEUE_PORT'),
    },
  }),
  inject: [ConfigService],
});
```

Alternatively, you can use the `useClass` syntax:

```typescript

BullModule.forRootAsync({
  useClass: BullConfigService,
});
```

The construction above will instantiate `BullConfigService` inside `BullModule` and use it to provide an options object by calling `createBullOptions()`. Note that this means that the `BullConfigService` has to implement the `BullOptionsFactory` interface, as shown below:

```typescript

@Injectable()
class BullConfigService implements BullOptionsFactory {
  createBullOptions(): BullModuleOptions {
    return {
      redis: {
        host: 'localhost',
        port: 6379,
      },
    };
  }
}
```

In order to prevent the creation of `BullConfigService` inside `BullModule` and use a provider imported from a different module, you can use the `useExisting` syntax.

```typescript

BullModule.forRootAsync({
  imports: [ConfigModule],
  useExisting: ConfigService,
});
```

This construction works the same as `useClass` with one critical difference - `BullModule` will lookup imported modules to reuse an existing `ConfigService` instead of instantiating a new one.

#### Example[#](/techniques/queues#example)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/26-queues).

----
url: https://docs.nestjs.com/graphql/plugins
----

[Skip to content](#content)

On this page

* [Plugins with Apollo](https://docs.nestjs.com/graphql/plugins#plugins-with-apollo)
* [Custom plugins](https://docs.nestjs.com/graphql/plugins#custom-plugins)
* [Using external plugins](https://docs.nestjs.com/graphql/plugins#using-external-plugins)
* [Plugins with Mercurius](https://docs.nestjs.com/graphql/plugins#plugins-with-mercurius)

### Plugins with Apollo

Plugins let you extend Apollo Server's core functionality by performing custom operations in response to certain events. These events correspond to individual phases of the GraphQL request lifecycle, and to the startup of Apollo Server itself (see [plugins](https://www.apollographql.com/docs/apollo-server/integrations/plugins/) in the Apollo documentation). For example, a basic logging plugin might log the GraphQL query string of each request sent to Apollo Server.

#### Custom plugins[#](/graphql/plugins#custom-plugins)

To create a plugin, declare a class annotated with the `@Plugin()` decorator, exported from the `@nestjs/apollo` package. For better code autocompletion, also implement the `ApolloServerPlugin` interface from the `@apollo/server` package.

```typescript

import { ApolloServerPlugin, GraphQLRequestListener } from '@apollo/server';
import { Plugin } from '@nestjs/apollo';

@Plugin()
export class LoggingPlugin implements ApolloServerPlugin {
  async requestDidStart(): Promise<GraphQLRequestListener<any>> {
    console.log('Request started');
    return {
      async willSendResponse() {
        console.log('Will send response');
      },
    };
  }
}
```

With this in place, register `LoggingPlugin` as a provider:

```typescript

@Module({
  providers: [LoggingPlugin],
})
export class CommonModule {}
```

Nest automatically instantiates the plugin and applies it to Apollo Server.

#### Using external plugins[#](/graphql/plugins#using-external-plugins)

Apollo Server provides several plugins out of the box. To use an existing plugin, import it and add it to the `plugins` array:

```typescript

import { ApolloServerPluginCacheControl } from '@apollo/server/plugin/cacheControl';

GraphQLModule.forRoot({
  // ...
  plugins: [ApolloServerPluginCacheControl({ defaultMaxAge: 5 })],
}),
```

> **Hint** The `ApolloServerPluginCacheControl` plugin is exported from the `@apollo/server/plugin/cacheControl` entry point of the `@apollo/server` package.

#### Plugins with Mercurius[#](/graphql/plugins#plugins-with-mercurius)

Some of the existing Mercurius-specific Fastify plugins must be loaded after the Mercurius plugin in the plugin tree (see [plugins](https://mercurius.dev/#/docs/plugins) in the Mercurius documentation).

> **Warning**[mercurius-upload](https://github.com/mercurius-js/mercurius-upload) is an exception: register it in the main file.

For this, `MercuriusDriver` exposes an optional `plugins` configuration option. It takes an array of objects with two properties: `plugin` and its `options`. For example, registering the [cache plugin](https://github.com/mercurius-js/cache) looks like this:

```typescript

GraphQLModule.forRoot({
  driver: MercuriusDriver,
  // ...
  plugins: [
    {
      plugin: cache,
      options: {
        ttl: 10,
        policy: {
          Query: {
            add: true
          }
        }
      },
    }
  ]
}),
```

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/plugins.md)

----
url: https://docs.nestjs.com/v11/recipes/documentation
----

* [Documentation](https://docs.nestjs.com/v11/recipes/documentation#documentation)
* [Setup](https://docs.nestjs.com/v11/recipes/documentation#setup)
* [Generation](https://docs.nestjs.com/v11/recipes/documentation#generation)
* [Contribute](https://docs.nestjs.com/v11/recipes/documentation#contribute)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/recipes/documentation.md "Suggest Edits")

### Documentation

**Compodoc** is a documentation tool for Angular applications. Since Nest and Angular share similar project and code structures, **Compodoc** works with Nest applications as well.

#### Setup[#](/recipes/documentation#setup)

Setting up Compodoc inside an existing Nest project is very simple. Start by adding the dev-dependency with the following command in your OS terminal:

```bash

$ npm i -D @compodoc/compodoc
```

#### Generation[#](/recipes/documentation#generation)

Generate project documentation using the following command (npm 6 is required for `npx` support). See [the official documentation](https://compodoc.app/guides/usage.html) for more options.

```bash

$ npx @compodoc/compodoc -p tsconfig.json -s
```

Open your browser and navigate to <http://localhost:8080>. You should see an initial Nest CLI project:

#### Contribute[#](/recipes/documentation#contribute)

You can participate and contribute to the Compodoc project [here](https://github.com/compodoc/compodoc).

----
url: https://docs.nestjs.com/v10/security/cors
----

* [CORS](https://docs.nestjs.com/v10/security/cors#cors)
* [Getting started](https://docs.nestjs.com/v10/security/cors#getting-started)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/security/cors.md "Suggest Edits")

### CORS

Cross-origin resource sharing (CORS) is a mechanism that allows resources to be requested from another domain. Under the hood, Nest makes use of the Express [cors](https://github.com/expressjs/cors) or Fastify [@fastify/cors](https://github.com/fastify/fastify-cors) packages depending on the underlying platform. These packages provide various options that you can customize based on your requirements.

#### Getting started[#](/security/cors#getting-started)

To enable CORS, call the `enableCors()` method on the Nest application object.

```typescript

const app = await NestFactory.create(AppModule);
app.enableCors();
await app.listen(process.env.PORT ?? 3000);
```

The `enableCors()` method takes an optional configuration object argument. The available properties of this object are described in the official [CORS](https://github.com/expressjs/cors#configuration-options) documentation. Another way is to pass a [callback function](https://github.com/expressjs/cors#configuring-cors-asynchronously) that lets you define the configuration object asynchronously based on the request (on the fly).

Alternatively, enable CORS via the `create()` method's options object. Set the `cors` property to `true` to enable CORS with default settings. Or, pass a [CORS configuration object](https://github.com/expressjs/cors#configuration-options) or [callback function](https://github.com/expressjs/cors#configuring-cors-asynchronously) as the `cors` property value to customize its behavior.

```typescript

const app = await NestFactory.create(AppModule, { cors: true });
await app.listen(process.env.PORT ?? 3000);
```

----
url: https://docs.nestjs.com/v7/faq/multiple-servers
----

* [HTTPS](https://docs.nestjs.com/v7/faq/multiple-servers#https)
* [Multiple simultaneous servers](https://docs.nestjs.com/v7/faq/multiple-servers#multiple-simultaneous-servers)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/faq/multiple-servers.md "Suggest Edits")

### HTTPS

To create an application that uses the HTTPS protocol, set the `httpsOptions` property in the options object passed to the `create()` method of the `NestFactory` class:

```typescript

const httpsOptions = {
  key: fs.readFileSync('./secrets/private-key.pem'),
  cert: fs.readFileSync('./secrets/public-certificate.pem'),
};
const app = await NestFactory.create(AppModule, {
  httpsOptions,
});
await app.listen(3000);
```

If you use the `FastifyAdapter`, create the application as follows:

```typescript

const app = await NestFactory.create<NestFastifyApplication>(
  AppModule,
  new FastifyAdapter({ https: httpsOptions }),
);
```

#### Multiple simultaneous servers[#](/faq/multiple-servers#multiple-simultaneous-servers)

The following recipe shows how to instantiate a Nest application that listens on multiple ports (for example, on a non-HTTPS port and an HTTPS port) simultaneously.

```typescript

const httpsOptions = {
  key: fs.readFileSync('./secrets/private-key.pem'),
  cert: fs.readFileSync('./secrets/public-certificate.pem'),
};

const server = express();
const app = await NestFactory.create(
  AppModule,
  new ExpressAdapter(server),
);
await app.init();

http.createServer(server).listen(3000);
https.createServer(httpsOptions, server).listen(443);
```

> **Hint** The `ExpressAdapter` is imported from the `@nestjs/platform-express` package. The `http` and `https` packages are native Node.js packages.

> **Warning** This recipe does not work with [GraphQL Subscriptions](/v7/graphql/subscriptions).

----
url: https://docs.nestjs.com/v8/recipes/mongodb
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [MongoDB (Mongoose)](https://docs.nestjs.com/v8/recipes/mongodb#mongodb-mongoose)
* [Getting started](https://docs.nestjs.com/v8/recipes/mongodb#getting-started)
* [Model injection](https://docs.nestjs.com/v8/recipes/mongodb#model-injection)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/recipes/mongodb.md "Suggest Edits")

### MongoDB (Mongoose)

> **Warning** In this article, you'll learn how to create a `DatabaseModule` based on the **Mongoose** package from scratch using custom components. As a consequence, this solution contains a lot of overhead that you can omit using ready to use and available out-of-the-box dedicated `@nestjs/mongoose` package. To learn more, see [here](/v8/techniques/mongodb).

[Mongoose](https://mongoosejs.com) is the most popular [MongoDB](https://www.mongodb.org/) object modeling tool.

#### Getting started[#](/recipes/mongodb#getting-started)

To start the adventure with this library we have to install all required dependencies:

```typescript

$ npm install --save mongoose
```

The first step we need to do is to establish the connection with our database using `connect()` function. The `connect()` function returns a `Promise`, and therefore we have to create an [async provider](/v8/fundamentals/async-components).

database.providers.ts

JS TS

```typescript

import * as mongoose from 'mongoose';

export const databaseProviders = [
  {
    provide: 'DATABASE_CONNECTION',
    useFactory: (): Promise<typeof mongoose> =>
      mongoose.connect('mongodb://localhost/nest'),
  },
];
```

```typescript

import * as mongoose from 'mongoose';

export const databaseProviders = [
  {
    provide: 'DATABASE_CONNECTION',
    useFactory: () => mongoose.connect('mongodb://localhost/nest'),
  },
];
```

> **Hint** Following best practices, we declared the custom provider in the separated file which has a `*.providers.ts` suffix.

Then, we need to export these providers to make them **accessible** for the rest part of the application.

database.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { databaseProviders } from './database.providers';

@Module({
  providers: [...databaseProviders],
  exports: [...databaseProviders],
})
export class DatabaseModule {}
```

Now we can inject the `Connection` object using `@Inject()` decorator. Each class that would depend on the `Connection` async provider will wait until a `Promise` is resolved.

#### Model injection[#](/recipes/mongodb#model-injection)

With Mongoose, everything is derived from a [Schema](https://mongoosejs.com/docs/guide.html). Let's define the `CatSchema`:

schemas/cat.schema.ts

JS TS

```typescript

import * as mongoose from 'mongoose';

export const CatSchema = new mongoose.Schema({
  name: String,
  age: Number,
  breed: String,
});
```

The `CatsSchema` belongs to the `cats` directory. This directory represents the `CatsModule`.

Now it's time to create a **Model** provider:

cats.providers.ts

JS TS

```typescript

import { Connection } from 'mongoose';
import { CatSchema } from './schemas/cat.schema';

export const catsProviders = [
  {
    provide: 'CAT_MODEL',
    useFactory: (connection: Connection) => connection.model('Cat', CatSchema),
    inject: ['DATABASE_CONNECTION'],
  },
];
```

```typescript

import { CatSchema } from './schemas/cat.schema';

export const catsProviders = [
  {
    provide: 'CAT_MODEL',
    useFactory: (connection) => connection.model('Cat', CatSchema),
    inject: ['DATABASE_CONNECTION'],
  },
];
```

> **Warning** In the real-world applications you should avoid **magic strings**. Both `CAT_MODEL` and `DATABASE_CONNECTION` should be kept in the separated `constants.ts` file.

Now we can inject the `CAT_MODEL` to the `CatsService` using the `@Inject()` decorator:

cats.service.ts

JS TS

```typescript

import { Model } from 'mongoose';
import { Injectable, Inject } from '@nestjs/common';
import { Cat } from './interfaces/cat.interface';
import { CreateCatDto } from './dto/create-cat.dto';

@Injectable()
export class CatsService {
  constructor(
    @Inject('CAT_MODEL')
    private catModel: Model<Cat>,
  ) {}

  async create(createCatDto: CreateCatDto): Promise<Cat> {
    const createdCat = new this.catModel(createCatDto);
    return createdCat.save();
  }

  async findAll(): Promise<Cat[]> {
    return this.catModel.find().exec();
  }
}
```

```typescript

import { Injectable, Dependencies } from '@nestjs/common';

@Injectable()
@Dependencies('CAT_MODEL')
export class CatsService {
  constructor(catModel) {
    this.catModel = catModel;
  }

  async create(createCatDto) {
    const createdCat = new this.catModel(createCatDto);
    return createdCat.save();
  }

  async findAll() {
    return this.catModel.find().exec();
  }
}
```

In the above example we have used the `Cat` interface. This interface extends the `Document` from the mongoose package:

```typescript

import { Document } from 'mongoose';

export interface Cat extends Document {
  readonly name: string;
  readonly age: number;
  readonly breed: string;
}
```

The database connection is **asynchronous**, but Nest makes this process completely invisible for the end-user. The `CatModel` class is waiting for the db connection, and the `CatsService` is delayed until model is ready to use. The entire application can start when each class is instantiated.

Here is a final `CatsModule`:

cats.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';
import { catsProviders } from './cats.providers';
import { DatabaseModule } from '../database/database.module';

@Module({
  imports: [DatabaseModule],
  controllers: [CatsController],
  providers: [
    CatsService,
    ...catsProviders,
  ],
})
export class CatsModule {}
```

> **Hint** Do not forget to import the `CatsModule` into the root `AppModule`.

----
url: https://docs.nestjs.com/modules
----

[Skip to content](#content)

On this page

* [Modules](https://docs.nestjs.com/modules#modules)
* [Feature modules](https://docs.nestjs.com/modules#feature-modules)
* [Shared modules](https://docs.nestjs.com/modules#shared-modules)
* [Module re-exporting](https://docs.nestjs.com/modules#module-re-exporting)
* [Dependency injection](https://docs.nestjs.com/modules#dependency-injection)
* [Global modules](https://docs.nestjs.com/modules#global-modules)
* [Dynamic modules](https://docs.nestjs.com/modules#dynamic-modules)

[](https://srv.carbonads.net/ads/click/x/GTND4277CVSD5KJUCAYLYKQUF67D62Q7CW7DTZ3JCAAI623WCTBIT2QKCVSILK7JC67ITKJLCTSDLKJYCKBDE23KC6SILKJUCT7DEK3EHJNCLSIZ)[Learn AWS from the people who built it. Start learning. ](https://srv.carbonads.net/ads/click/x/GTND4277CVSD5KJUCAYLYKQUF67D62Q7CW7DTZ3JCAAI623WCTBIT2QKCVSILK7JC67ITKJLCTSDLKJYCKBDE23KC6SILKJUCT7DEK3EHJNCLSIZ)[ads via Carbon](http://carbonads.net/?utm_source=nestjscom\&utm_medium=ad_via_link\&utm_campaign=in_unit\&utm_term=carbon)

### Modules

A module is a class annotated with the `@Module()` decorator. The decorator provides metadata that **Nest** uses to organize and manage the application structure.

Every Nest application has at least one module, the **root module**. It is the starting point from which Nest builds the **application graph**, the internal structure Nest uses to resolve relationships and dependencies between modules and providers. A very small application may have only a root module, but most applications have multiple modules, each encapsulating a closely related set of **capabilities**. Modules are the **recommended** way to organize your components.

The `@Module()` decorator takes a single object with properties that describe the module:

| `providers`   | the providers that will be instantiated by the Nest injector and that may be shared at least across this module                                                                           |
| ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `controllers` | the set of controllers defined in this module that must be instantiated                                                                                                                   |
| `imports`     | the list of imported modules that export the providers required in this module                                                                                                            |
| `exports`     | the subset of `providers` that this module provides and that should be available to other modules importing it. You can use either the provider itself or its token (the `provide` value) |

A module **encapsulates** its providers by default: you can inject only providers that are part of the current module or that are explicitly exported by an imported module. A module's exported providers form its public interface, or API.

#### Feature modules[#](/modules#feature-modules)

In our example, `CatsController` and `CatsService` are closely related and serve the same application domain, so it makes sense to group them into a feature module. A feature module organizes the code for a specific feature, which keeps boundaries clear. This becomes more important as the application or team grows, and it aligns with the [SOLID](https://en.wikipedia.org/wiki/SOLID) principles.

Next, we'll create a `CatsModule` that groups the controller and the service:

cats/cats.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { CatsController } from './cats.controller.js';
import { CatsService } from './cats.service.js';

@Module({
  controllers: [CatsController],
  providers: [CatsService],
})
export class CatsModule {}
```

> **Hint** To create a module with the CLI, run `$ nest g module cats`.

Above, we defined `CatsModule` in the `cats.module.ts` file and moved everything related to it into the `cats` directory. The last step is to import this module into the root module (`AppModule`, defined in the `app.module.ts` file):

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { CatsModule } from './cats/cats.module.js';

@Module({
  imports: [CatsModule],
})
export class AppModule {}
```

The directory structure now looks like this:

src

cats

dto

create-cat.dto.ts

interfaces

cat.interface.ts

cats.controller.ts

cats.module.ts

cats.service.ts

app.module.ts

main.ts

#### Shared modules[#](/modules#shared-modules)

In Nest, modules are **singletons** by default, so you can share the same instance of any provider between multiple modules.

Every module is automatically a **shared module**: once created, it can be reused by any other module. Suppose you want to share an instance of `CatsService` between several other modules. To do so, first **export** the `CatsService` provider by adding it to the module's `exports` array:

cats.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { CatsController } from './cats.controller.js';
import { CatsService } from './cats.service.js';

@Module({
  controllers: [CatsController],
  providers: [CatsService],
  exports: [CatsService],
})
export class CatsModule {}
```

Any module that imports `CatsModule` now has access to `CatsService` and shares the same instance with every other module that imports it.

Registering `CatsService` directly in every module that needs it would also work, but each module would then get its own separate instance of the service. Multiple instances increase memory usage and can cause unexpected behavior, such as inconsistent state if the service holds internal state.

Encapsulating `CatsService` in a module such as `CatsModule` and exporting it ensures that every module importing `CatsModule` reuses the same instance. This reduces memory consumption and makes behavior more predictable, because shared state and resources are managed in one place. Sharing services efficiently across the application is one of the key benefits of modularity and dependency injection.

## Debug production with NestJS Observe

* Every request traced
* Errors with source code
* Logs in context
* Zero config, free plan

[Start for free](https://observe.nestjs.com "Observe | NestJS - A progressive Node.js framework")

#### Module re-exporting[#](/modules#module-re-exporting)

As shown above, modules can export their internal providers. They can also re-export modules that they import. In the example below, `CommonModule` is both imported into **and** exported from `CoreModule`, which makes it available to any module that imports `CoreModule`.

```typescript

@Module({
  imports: [CommonModule],
  exports: [CommonModule],
})
export class CoreModule {}
```

#### Dependency injection[#](/modules#dependency-injection)

A module class can also **inject** providers (e.g., for configuration purposes):

cats.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { CatsController } from './cats.controller.js';
import { CatsService } from './cats.service.js';

@Module({
  controllers: [CatsController],
  providers: [CatsService],
})
export class CatsModule {
  constructor(private catsService: CatsService) {}
}
```

```typescript

import { Module, Dependencies } from '@nestjs/common';
import { CatsController } from './cats.controller.js';
import { CatsService } from './cats.service.js';

@Module({
  controllers: [CatsController],
  providers: [CatsService],
})
@Dependencies(CatsService)
export class CatsModule {
  constructor(catsService) {
    this.catsService = catsService;
  }
}
```

However, module classes themselves cannot be injected as providers due to [circular dependencies](/fundamentals/circular-dependency).

#### Global modules[#](/modules#global-modules)

Importing the same set of modules everywhere can become tedious. In [Angular](https://angular.dev), `providers` are registered in the global scope and, once defined, are available everywhere. Nest, by contrast, encapsulates providers inside the module scope: you can't use a module's providers elsewhere without first importing the module that encapsulates them.

To make a set of providers available everywhere out of the box (e.g., helpers or database connections), make the module **global** with the `@Global()` decorator:

```typescript

import { Module, Global } from '@nestjs/common';
import { CatsController } from './cats.controller.js';
import { CatsService } from './cats.service.js';

@Global()
@Module({
  controllers: [CatsController],
  providers: [CatsService],
  exports: [CatsService],
})
export class CatsModule {}
```

The `@Global()` decorator makes the module global-scoped. Register global modules **only once**, typically in the root or core module. In the example above, the `CatsService` provider is available everywhere, and modules that inject it don't need to add `CatsModule` to their `imports` array.

> **Hint** Making everything global is not a recommended design practice. Global modules reduce boilerplate, but the `imports` array makes a module's API available to other modules in a controlled, explicit way. This keeps the application structure maintainable, shares only the parts of a module that others need, and avoids unnecessary coupling between unrelated parts of the application.

#### Dynamic modules[#](/modules#dynamic-modules)

Dynamic modules let you create modules that are configured at runtime. They are useful when a module's providers depend on options supplied by the module that imports it. For example, the following `FeatureFlagsModule` receives the application's feature flags through its static `forRoot()` method:

feature-flags.module.ts

JS TS

```typescript

import { DynamicModule, Module } from '@nestjs/common';
import { FEATURE_FLAGS } from './feature-flags.constants.js';
import { FeatureFlagsService } from './feature-flags.service.js';

@Module({
  providers: [FeatureFlagsService],
  exports: [FeatureFlagsService],
})
export class FeatureFlagsModule {
  static forRoot(flags: Record<string, boolean>): DynamicModule {
    return {
      module: FeatureFlagsModule,
      providers: [{ provide: FEATURE_FLAGS, useValue: flags }],
    };
  }
}
```

```typescript

import { Module } from '@nestjs/common';
import { FEATURE_FLAGS } from './feature-flags.constants.js';
import { FeatureFlagsService } from './feature-flags.service.js';

@Module({
  providers: [FeatureFlagsService],
  exports: [FeatureFlagsService],
})
export class FeatureFlagsModule {
  static forRoot(flags) {
    return {
      module: FeatureFlagsModule,
      providers: [{ provide: FEATURE_FLAGS, useValue: flags }],
    };
  }
}
```

The `FEATURE_FLAGS` injection token is a plain constant (`export const FEATURE_FLAGS = 'FEATURE_FLAGS';`), as described in [Non-class-based provider tokens](/fundamentals/custom-providers#non-class-based-provider-tokens).

> **Hint** The `forRoot()` method may return a dynamic module either synchronously or asynchronously (i.e., via a `Promise`).

The properties returned by `forRoot()`**extend** (rather than override) the metadata defined in the `@Module()` decorator. The resulting module therefore has both the statically declared `FeatureFlagsService` and the dynamically registered `FEATURE_FLAGS` provider. Because they belong to the same module, the service can inject the flags:

feature-flags.service.ts

JS TS

```typescript

import { Inject, Injectable } from '@nestjs/common';
import { FEATURE_FLAGS } from './feature-flags.constants.js';

@Injectable()
export class FeatureFlagsService {
  constructor(
    @Inject(FEATURE_FLAGS) private readonly flags: Record<string, boolean>,
  ) {}

  isEnabled(flag: string): boolean {
    return this.flags[flag] ?? false;
  }
}
```

```typescript

import { Dependencies, Injectable } from '@nestjs/common';
import { FEATURE_FLAGS } from './feature-flags.constants.js';

@Injectable()
@Dependencies(FEATURE_FLAGS)
export class FeatureFlagsService {
  constructor(flags) {
    this.flags = flags;
  }

  isEnabled(flag) {
    return this.flags[flag] ?? false;
  }
}
```

The module exports only `FeatureFlagsService`, so the flags themselves stay an implementation detail of the module.

Import and configure the `FeatureFlagsModule` as follows:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { FeatureFlagsModule } from './feature-flags/feature-flags.module.js';

@Module({
  imports: [
    FeatureFlagsModule.forRoot({
      newCheckout: true,
      betaDashboard: false,
    }),
  ],
})
export class AppModule {}
```

Only the module that imports `FeatureFlagsModule.forRoot()` can inject `FeatureFlagsService`. Calling `forRoot()` again in another module would create a second, separately configured instance. To share a single instance, configure the module once and re-export it. To re-export a dynamic module, list the module class in the `exports` array, without calling `forRoot()` again:

core.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { FeatureFlagsModule } from '../feature-flags/feature-flags.module.js';

@Module({
  imports: [
    FeatureFlagsModule.forRoot({
      newCheckout: true,
      betaDashboard: false,
    }),
  ],
  exports: [FeatureFlagsModule],
})
export class CoreModule {}
```

Every module that imports `CoreModule` can now inject `FeatureFlagsService`, and all of them share the same flags.

Alternatively, to register a dynamic module in the global scope, set the `global` property to `true` in the object returned by `forRoot()`. `FeatureFlagsService` then becomes injectable everywhere, without importing any module:

```typescript

return {
  global: true,
  module: FeatureFlagsModule,
  providers: [{ provide: FEATURE_FLAGS, useValue: flags }],
};
```

> **Warning** As mentioned above, making everything global **is not a good design decision**.

Options known only at runtime, such as values read by `ConfigService`, call for an asynchronous variant of `forRoot()`. The [Dynamic modules](/fundamentals/dynamic-modules) chapter covers this and more.

> **Hint** To learn how to build highly customizable dynamic modules with `ConfigurableModuleBuilder`, see the [Configurable module builder](/fundamentals/dynamic-modules#configurable-module-builder) section.

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/modules.md)

----
url: https://docs.nestjs.com/v10/fundamentals/dynamic-modules
----

* [Dynamic modules](https://docs.nestjs.com/v10/fundamentals/dynamic-modules#dynamic-modules)
* [Introduction](https://docs.nestjs.com/v10/fundamentals/dynamic-modules#introduction)
* [Dynamic module use case](https://docs.nestjs.com/v10/fundamentals/dynamic-modules#dynamic-module-use-case)
* [Config module example](https://docs.nestjs.com/v10/fundamentals/dynamic-modules#config-module-example)
* [Module configuration](https://docs.nestjs.com/v10/fundamentals/dynamic-modules#module-configuration)
* [Example](https://docs.nestjs.com/v10/fundamentals/dynamic-modules#example)
* [Community guidelines](https://docs.nestjs.com/v10/fundamentals/dynamic-modules#community-guidelines)
* [Configurable module builder](https://docs.nestjs.com/v10/fundamentals/dynamic-modules#configurable-module-builder)
* [Custom method key](https://docs.nestjs.com/v10/fundamentals/dynamic-modules#custom-method-key)
* [Custom options factory class](https://docs.nestjs.com/v10/fundamentals/dynamic-modules#custom-options-factory-class)
* [Extra options](https://docs.nestjs.com/v10/fundamentals/dynamic-modules#extra-options)
* [Extending auto-generated methods](https://docs.nestjs.com/v10/fundamentals/dynamic-modules#extending-auto-generated-methods)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/fundamentals/dynamic-modules.md "Suggest Edits")

### Dynamic modules

The [Modules chapter](/v10/modules) covers the basics of Nest modules, and includes a brief introduction to [dynamic modules](https://docs.nestjs.com/modules#dynamic-modules). This chapter expands on the subject of dynamic modules. Upon completion, you should have a good grasp of what they are and how and when to use them.

#### Introduction[#](/fundamentals/dynamic-modules#introduction)

Most application code examples in the **Overview** section of the documentation make use of regular, or static, modules. Modules define groups of components like [providers](/v10/providers) and [controllers](/v10/controllers) that fit together as a modular part of an overall application. They provide an execution context, or scope, for these components. For example, providers defined in a module are visible to other members of the module without the need to export them. When a provider needs to be visible outside of a module, it is first exported from its host module, and then imported into its consuming module.

Let's walk through a familiar example.

First, we'll define a `UsersModule` to provide and export a `UsersService`. `UsersModule` is the **host** module for `UsersService`.

```typescript

import { Module } from '@nestjs/common';
import { UsersService } from './users.service';

@Module({
  providers: [UsersService],
  exports: [UsersService],
})
export class UsersModule {}
```

Next, we'll define an `AuthModule`, which imports `UsersModule`, making `UsersModule`'s exported providers available inside `AuthModule`:

```typescript

import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { UsersModule } from '../users/users.module';

@Module({
  imports: [UsersModule],
  providers: [AuthService],
  exports: [AuthService],
})
export class AuthModule {}
```

These constructs allow us to inject `UsersService` in, for example, the `AuthService` that is hosted in `AuthModule`:

```typescript

import { Injectable } from '@nestjs/common';
import { UsersService } from '../users/users.service';

@Injectable()
export class AuthService {
  constructor(private usersService: UsersService) {}
  /*
    Implementation that makes use of this.usersService
  */
}
```

```typescript

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { ConfigModule } from './config/config.module';

@Module({
  imports: [ConfigModule],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}
```

Let's consider what a *dynamic module* import, where we're passing in a configuration object, might look like. Compare the difference in the `imports` array between these two examples:

```typescript

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { ConfigModule } from './config/config.module';

@Module({
  imports: [ConfigModule.register({ folder: './config' })],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}
```

Let's see what's happening in the dynamic example above. What are the moving parts?

1. `ConfigModule` is a normal class, so we can infer that it must have a **static method** called `register()`. We know it's static because we're calling it on the `ConfigModule` class, not on an **instance** of the class. Note: this method, which we will create soon, can have any arbitrary name, but by convention we should call it either `forRoot()` or `register()`.
2. The `register()` method is defined by us, so we can accept any input arguments we like. In this case, we're going to accept a simple `options` object with suitable properties, which is the typical case.
3. We can infer that the `register()` method must return something like a `module` since its return value appears in the familiar `imports` list, which we've seen so far includes a list of modules.

In fact, what our `register()` method will return is a `DynamicModule`. A dynamic module is nothing more than a module created at run-time, with the same exact properties as a static module, plus one additional property called `module`. Let's quickly review a sample static module declaration, paying close attention to the module options passed in to the decorator:

```typescript

@Module({
  imports: [DogsModule],
  controllers: [CatsController],
  providers: [CatsService],
  exports: [CatsService]
})
```

Dynamic modules must return an object with the exact same interface, plus one additional property called `module`. The `module` property serves as the name of the module, and should be the same as the class name of the module, as shown in the example below.

> **Hint** For a dynamic module, all properties of the module options object are optional **except**`module`.

What about the static `register()` method? We can now see that its job is to return an object that has the `DynamicModule` interface. When we call it, we are effectively providing a module to the `imports` list, similar to the way we would do so in the static case by listing a module class name. In other words, the dynamic module API simply returns a module, but rather than fix the properties in the `@Module` decorator, we specify them programmatically.

There are still a couple of details to cover to help make the picture complete:

1. We can now state that the `@Module()` decorator's `imports` property can take not only a module class name (e.g., `imports: [UsersModule]`), but also a function **returning** a dynamic module (e.g., `imports: [ConfigModule.register(...)]`).
2. A dynamic module can itself import other modules. We won't do so in this example, but if the dynamic module depends on providers from other modules, you would import them using the optional `imports` property. Again, this is exactly analogous to the way you'd declare metadata for a static module using the `@Module()` decorator.

Armed with this understanding, we can now look at what our dynamic `ConfigModule` declaration must look like. Let's take a crack at it.

```typescript

import { DynamicModule, Module } from '@nestjs/common';
import { ConfigService } from './config.service';

@Module({})
export class ConfigModule {
  static register(): DynamicModule {
    return {
      module: ConfigModule,
      providers: [ConfigService],
      exports: [ConfigService],
    };
  }
}
```

It should now be clear how the pieces tie together. Calling `ConfigModule.register(...)` returns a `DynamicModule` object with properties which are essentially the same as those that, until now, we've provided as metadata via the `@Module()` decorator.

> **Hint** Import `DynamicModule` from `@nestjs/common`.

Our dynamic module isn't very interesting yet, however, as we haven't introduced any capability to **configure** it as we said we would like to do. Let's address that next.

#### Module configuration[#](/fundamentals/dynamic-modules#module-configuration)

The obvious solution for customizing the behavior of the `ConfigModule` is to pass it an `options` object in the static `register()` method, as we guessed above. Let's look once again at our consuming module's `imports` property:

```typescript

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { ConfigModule } from './config/config.module';

@Module({
  imports: [ConfigModule.register({ folder: './config' })],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}
```

That nicely handles passing an `options` object to our dynamic module. How do we then use that `options` object in the `ConfigModule`? Let's consider that for a minute. We know that our `ConfigModule` is basically a host for providing and exporting an injectable service - the `ConfigService` - for use by other providers. It's actually our `ConfigService` that needs to read the `options` object to customize its behavior. Let's assume for the moment that we know how to somehow get the `options` from the `register()` method into the `ConfigService`. With that assumption, we can make a few changes to the service to customize its behavior based on the properties from the `options` object. (**Note**: for the time being, since we *haven't* actually determined how to pass it in, we'll just hard-code `options`. We'll fix this in a minute).

```typescript

import { Injectable } from '@nestjs/common';
import * as dotenv from 'dotenv';
import * as fs from 'fs';
import * as path from 'path';
import { EnvConfig } from './interfaces';

@Injectable()
export class ConfigService {
  private readonly envConfig: EnvConfig;

  constructor() {
    const options = { folder: './config' };

    const filePath = `${process.env.NODE_ENV || 'development'}.env`;
    const envFile = path.resolve(__dirname, '../../', options.folder, filePath);
    this.envConfig = dotenv.parse(fs.readFileSync(envFile));
  }

  get(key: string): string {
    return this.envConfig[key];
  }
}
```

Now our `ConfigService` knows how to find the `.env` file in the folder we've specified in `options`.

Our remaining task is to somehow inject the `options` object from the `register()` step into our `ConfigService`. And of course, we'll use *dependency injection* to do it. This is a key point, so make sure you understand it. Our `ConfigModule` is providing `ConfigService`. `ConfigService` in turn depends on the `options` object that is only supplied at run-time. So, at run-time, we'll need to first bind the `options` object to the Nest IoC container, and then have Nest inject it into our `ConfigService`. Remember from the **Custom providers** chapter that providers can [include any value](https://docs.nestjs.com/fundamentals/custom-providers#non-service-based-providers) not just services, so we're fine using dependency injection to handle a simple `options` object.

Let's tackle binding the options object to the IoC container first. We do this in our static `register()` method. Remember that we are dynamically constructing a module, and one of the properties of a module is its list of providers. So what we need to do is define our options object as a provider. This will make it injectable into the `ConfigService`, which we'll take advantage of in the next step. In the code below, pay attention to the `providers` array:

```typescript

import { DynamicModule, Module } from '@nestjs/common';
import { ConfigService } from './config.service';

@Module({})
export class ConfigModule {
  static register(options: Record<string, any>): DynamicModule {
    return {
      module: ConfigModule,
      providers: [
        {
          provide: 'CONFIG_OPTIONS',
          useValue: options,
        },
        ConfigService,
      ],
      exports: [ConfigService],
    };
  }
}
```

Now we can complete the process by injecting the `'CONFIG_OPTIONS'` provider into the `ConfigService`. Recall that when we define a provider using a non-class token we need to use the `@Inject()` decorator [as described here](https://docs.nestjs.com/fundamentals/custom-providers#non-class-based-provider-tokens).

```typescript

import * as dotenv from 'dotenv';
import * as fs from 'fs';
import * as path from 'path';
import { Injectable, Inject } from '@nestjs/common';
import { EnvConfig } from './interfaces';

@Injectable()
export class ConfigService {
  private readonly envConfig: EnvConfig;

  constructor(@Inject('CONFIG_OPTIONS') private options: Record<string, any>) {
    const filePath = `${process.env.NODE_ENV || 'development'}.env`;
    const envFile = path.resolve(__dirname, '../../', options.folder, filePath);
    this.envConfig = dotenv.parse(fs.readFileSync(envFile));
  }

  get(key: string): string {
    return this.envConfig[key];
  }
}
```

One final note: for simplicity we used a string-based injection token (`'CONFIG_OPTIONS'`) above, but best practice is to define it as a constant (or `Symbol`) in a separate file, and import that file. For example:

```typescript

export const CONFIG_OPTIONS = 'CONFIG_OPTIONS';
```

```typescript

export interface ConfigModuleOptions {
  folder: string;
}
```

With this in place, create a new dedicated file (alongside the existing `config.module.ts` file) and name it `config.module-definition.ts`. In this file, let's utilize the `ConfigurableModuleBuilder` to construct `ConfigModule` definition.

config.module-definition.ts

JS TS

```typescript

import { ConfigurableModuleBuilder } from '@nestjs/common';
import { ConfigModuleOptions } from './interfaces/config-module-options.interface';

export const { ConfigurableModuleClass, MODULE_OPTIONS_TOKEN } =
  new ConfigurableModuleBuilder<ConfigModuleOptions>().build();
```

```typescript

import { ConfigurableModuleBuilder } from '@nestjs/common';

export const { ConfigurableModuleClass, MODULE_OPTIONS_TOKEN } =
  new ConfigurableModuleBuilder().build();
```

Now let's open up the `config.module.ts` file and modify its implementation to leverage the auto-generated `ConfigurableModuleClass`:

```typescript

import { Module } from '@nestjs/common';
import { ConfigService } from './config.service';
import { ConfigurableModuleClass } from './config.module-definition';

@Module({
  providers: [ConfigService],
  exports: [ConfigService],
})
export class ConfigModule extends ConfigurableModuleClass {}
```

Extending the `ConfigurableModuleClass` means that `ConfigModule` provides now not only the `register` method (as previously with the custom implementation), but also the `registerAsync` method which allows consumers asynchronously configure that module, for example, by supplying async factories:

```typescript

@Module({
  imports: [
    ConfigModule.register({ folder: './config' }),
    // or alternatively:
    // ConfigModule.registerAsync({
    //   useFactory: () => {
    //     return {
    //       folder: './config',
    //     }
    //   },
    //   inject: [...any extra dependencies...]
    // }),
  ],
})
export class AppModule {}
```

Lastly, let's update the `ConfigService` class to inject the generated module options' provider instead of the `'CONFIG_OPTIONS'` that we used so far.

```typescript

@Injectable()
export class ConfigService {
  constructor(@Inject(MODULE_OPTIONS_TOKEN) private options: ConfigModuleOptions) { ... }
}
```

#### Custom method key[#](/fundamentals/dynamic-modules#custom-method-key)

`ConfigurableModuleClass` by default provides the `register` and its counterpart `registerAsync` methods. To use a different method name, use the `ConfigurableModuleBuilder#setClassMethodName` method, as follows:

config.module-definition.ts

JS TS

```typescript

export const { ConfigurableModuleClass, MODULE_OPTIONS_TOKEN } =
  new ConfigurableModuleBuilder<ConfigModuleOptions>().setClassMethodName('forRoot').build();
```

```typescript

export const { ConfigurableModuleClass, MODULE_OPTIONS_TOKEN } =
  new ConfigurableModuleBuilder().setClassMethodName('forRoot').build();
```

This construction will instruct `ConfigurableModuleBuilder` to generate a class that exposes `forRoot` and `forRootAsync` instead. Example:

```typescript

@Module({
  imports: [
    ConfigModule.forRoot({ folder: './config' }), // <-- note the use of "forRoot" instead of "register"
    // or alternatively:
    // ConfigModule.forRootAsync({
    //   useFactory: () => {
    //     return {
    //       folder: './config',
    //     }
    //   },
    //   inject: [...any extra dependencies...]
    // }),
  ],
})
export class AppModule {}
```

#### Custom options factory class[#](/fundamentals/dynamic-modules#custom-options-factory-class)

Since the `registerAsync` method (or `forRootAsync` or any other name, depending on the configuration) lets consumer pass a provider definition that resolves to the module configuration, a library consumer could potentially supply a class to be used to construct the configuration object.

```typescript

@Module({
  imports: [
    ConfigModule.registerAsync({
      useClass: ConfigModuleOptionsFactory,
    }),
  ],
})
export class AppModule {}
```

This class, by default, must provide the `create()` method that returns a module configuration object. However, if your library follows a different naming convention, you can change that behavior and instruct `ConfigurableModuleBuilder` to expect a different method, for example, `createConfigOptions`, using the `ConfigurableModuleBuilder#setFactoryMethodName` method:

config.module-definition.ts

JS TS

```typescript

export const { ConfigurableModuleClass, MODULE_OPTIONS_TOKEN } =
  new ConfigurableModuleBuilder<ConfigModuleOptions>().setFactoryMethodName('createConfigOptions').build();
```

```typescript

export const { ConfigurableModuleClass, MODULE_OPTIONS_TOKEN } =
  new ConfigurableModuleBuilder().setFactoryMethodName('createConfigOptions').build();
```

Now, `ConfigModuleOptionsFactory` class must expose the `createConfigOptions` method (instead of `create`):

```typescript

@Module({
  imports: [
    ConfigModule.registerAsync({
      useClass: ConfigModuleOptionsFactory, // <-- this class must provide the "createConfigOptions" method
    }),
  ],
})
export class AppModule {}
```

#### Extra options[#](/fundamentals/dynamic-modules#extra-options)

There are edge-cases when your module may need to take extra options that determine how it is supposed to behave (a nice example of such an option is the `isGlobal` flag - or just `global`) that at the same time, shouldn't be included in the `MODULE_OPTIONS_TOKEN` provider (as they are irrelevant to services/providers registered within that module, for example, `ConfigService` does not need to know whether its host module is registered as a global module).

In such cases, the `ConfigurableModuleBuilder#setExtras` method can be used. See the following example:

```typescript

export const { ConfigurableModuleClass, MODULE_OPTIONS_TOKEN } = new ConfigurableModuleBuilder<ConfigModuleOptions>()
  .setExtras(
    {
      isGlobal: true,
    },
    (definition, extras) => ({
      ...definition,
      global: extras.isGlobal,
    }),
  )
  .build();
```

In the example above, the first argument passed into the `setExtras` method is an object containing default values for the "extra" properties. The second argument is a function that takes an auto-generated module definitions (with `provider`, `exports`, etc.) and `extras` object which represents extra properties (either specified by the consumer or defaults). The returned value of this function is a modified module definition. In this specific example, we're taking the `extras.isGlobal` property and assigning it to the `global` property of the module definition (which in turn determines whether a module is global or not, read more [here](/modules#dynamic-modules)).

Now when consuming this module, the additional `isGlobal` flag can be passed in, as follows:

```typescript

@Module({
  imports: [
    ConfigModule.register({
      isGlobal: true,
      folder: './config',
    }),
  ],
})
export class AppModule {}
```

However, since `isGlobal` is declared as an "extra" property, it won't be available in the `MODULE_OPTIONS_TOKEN` provider:

```typescript

@Injectable()
export class ConfigService {
  constructor(@Inject(MODULE_OPTIONS_TOKEN) private options: ConfigModuleOptions) {
    // "options" object will not have the "isGlobal" property
    // ...
  }
}
```

#### Extending auto-generated methods[#](/fundamentals/dynamic-modules#extending-auto-generated-methods)

The auto-generated static methods (`register`, `registerAsync`, etc.) can be extended if needed, as follows:

```typescript

import { Module } from '@nestjs/common';
import { ConfigService } from './config.service';
import { ConfigurableModuleClass, ASYNC_OPTIONS_TYPE, OPTIONS_TYPE } from './config.module-definition';

@Module({
  providers: [ConfigService],
  exports: [ConfigService],
})
export class ConfigModule extends ConfigurableModuleClass {
  static register(options: typeof OPTIONS_TYPE): DynamicModule {
    return {
      // your custom logic here
      ...super.register(options),
    };
  }

  static registerAsync(options: typeof ASYNC_OPTIONS_TYPE): DynamicModule {
    return {
      // your custom logic here
      ...super.registerAsync(options),
    };
  }
}
```

Note the use of `OPTIONS_TYPE` and `ASYNC_OPTIONS_TYPE` types that must be exported from the module definition file:

```typescript

export const { ConfigurableModuleClass, MODULE_OPTIONS_TOKEN, OPTIONS_TYPE, ASYNC_OPTIONS_TYPE } = new ConfigurableModuleBuilder<ConfigModuleOptions>().build();
```

----
url: https://docs.nestjs.com/v9/faq/serverless
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Serverless](https://docs.nestjs.com/v9/faq/serverless#serverless)
* [Cold start](https://docs.nestjs.com/v9/faq/serverless#cold-start)
* [Benchmarks](https://docs.nestjs.com/v9/faq/serverless#benchmarks)
* [Runtime optimizations](https://docs.nestjs.com/v9/faq/serverless#runtime-optimizations)
* [Example integration](https://docs.nestjs.com/v9/faq/serverless#example-integration)
* [Using standalone application feature](https://docs.nestjs.com/v9/faq/serverless#using-standalone-application-feature)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/faq/serverless.md "Suggest Edits")

### Serverless

Serverless computing is a cloud computing execution model in which the cloud provider allocates machine resources on-demand, taking care of the servers on behalf of their customers. When an app is not in use, there are no computing resources allocated to the app. Pricing is based on the actual amount of resources consumed by an application ([source](https://en.wikipedia.org/wiki/Serverless_computing)).

With a **serverless architecture**, you focus purely on the individual functions in your application code. Services such as AWS Lambda, Google Cloud Functions, and Microsoft Azure Functions take care of all the physical hardware, virtual machine operating system, and web server software management.

> **Hint** This chapter does not cover the pros and cons of serverless functions nor dives into the specifics of any cloud providers.

#### Cold start[#](/faq/serverless#cold-start)

A cold start is the first time your code has been executed in a while. Depending on a cloud provider you use, it may span several different operations, from downloading the code and bootstrapping the runtime to eventually running your code. This process adds **significant latency** depending on several factors, the language, the number of packages your application require, etc.

The cold start is important and although there are things which are beyond our control, there's still a lot of things we can do on our side to make it as short as possible.

While you can think of Nest as a fully-fledged framework designed to be used in complex, enterprise applications, it is also **suitable for much "simpler" applications** (or scripts). For example, with the use of [Standalone applications](/v9/standalone-applications) feature, you can take advantage of Nest's DI system in simple workers, CRON jobs, CLIs, or serverless functions.

#### Benchmarks[#](/faq/serverless#benchmarks)

To better understand what's the cost of using Nest or other, well-known libraries (like `express`) in the context of serverless functions, let's compare how much time Node runtime needs to run the following scripts:

```typescript

// #1 Express
import * as express from 'express';

async function bootstrap() {
  const app = express();
  app.get('/', (req, res) => res.send('Hello world!'));
  await new Promise<void>((resolve) => app.listen(3000, resolve));
}
bootstrap();

// #2 Nest (with @nestjs/platform-express)
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule, { logger: ['error'] });
  await app.listen(3000);
}
bootstrap();

// #3 Nest as a Standalone application (no HTTP server)
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { AppService } from './app.service';

async function bootstrap() {
  const app = await NestFactory.createApplicationContext(AppModule, {
    logger: ['error'],
  });
  console.log(app.get(AppService).getHello());
}
bootstrap();

// #4 Raw Node.js script
async function bootstrap() {
  console.log('Hello world!');
}
bootstrap();
```

For all these scripts, we used the `tsc` (TypeScript) compiler and so the code remains unbundled (`webpack` isn't used).

| Express                              | 0.0079s (7.9ms)   |
| ------------------------------------ | ----------------- |
| Nest with `@nestjs/platform-express` | 0.1974s (197.4ms) |
| Nest (standalone application)        | 0.1117s (111.7ms) |
| Raw Node.js script                   | 0.0071s (7.1ms)   |

> **Note** Machine: MacBook Pro Mid 2014, 2.5 GHz Quad-Core Intel Core i7, 16 GB 1600 MHz DDR3, SSD.

Now, let's repeat all benchmarks but this time, using `webpack` (if you have [Nest CLI](/v9/cli/overview) installed, you can run `nest build --webpack`) to bundle our application into a single executable JavaScript file. However, instead of using the default `webpack` configuration that Nest CLI ships with, we'll make sure to bundle all dependencies (`node_modules`) together, as follows:

```javascript

module.exports = (options, webpack) => {
  const lazyImports = [
    '@nestjs/microservices/microservices-module',
    '@nestjs/websockets/socket-module',
  ];

  return {
    ...options,
    externals: [],
    plugins: [
      ...options.plugins,
      new webpack.IgnorePlugin({
        checkResource(resource) {
          if (lazyImports.includes(resource)) {
            try {
              require.resolve(resource);
            } catch (err) {
              return true;
            }
          }
          return false;
        },
      }),
    ],
  };
};
```

> **Hint** To instruct Nest CLI to use this configuration, create a new `webpack.config.js` file in the root directory of your project.

With this configuration, we received the following results:

| Express                              | 0.0068s (6.8ms)  |
| ------------------------------------ | ---------------- |
| Nest with `@nestjs/platform-express` | 0.0815s (81.5ms) |
| Nest (standalone application)        | 0.0319s (31.9ms) |
| Raw Node.js script                   | 0.0066s (6.6ms)  |

> **Note** Machine: MacBook Pro Mid 2014, 2.5 GHz Quad-Core Intel Core i7, 16 GB 1600 MHz DDR3, SSD.

> **Hint** You could optimize it even further by applying additional code minification & optimization techniques (using `webpack` plugins, etc.).

As you can see, the way you compile (and whether you bundle your code) is crucial and has a significant impact on the overall startup time. With `webpack`, you can get the bootstrap time of a standalone Nest application (starter project with one module, controller, and service) down to \~32ms on average, and down to \~81.5ms for a regular HTTP, express-based NestJS app.

For more complicated Nest applications, for example, with 10 resources (generated through `$ nest g resource` schematic = 10 modules, 10 controllers, 10 services, 20 DTO classes, 50 HTTP endpoints + `AppModule`), the overall startup on MacBook Pro Mid 2014, 2.5 GHz Quad-Core Intel Core i7, 16 GB 1600 MHz DDR3, SSD is approximately 0.1298s (129.8ms). Running a monolithic application as a serverless function typically doesn't make too much sense anyway, so think of this benchmark more as an example of how the bootstrap time may potentially increase as your application grows.

#### Runtime optimizations[#](/faq/serverless#runtime-optimizations)

Thus far we covered compile-time optimizations. These are unrelated to the way you define providers and load Nest modules in your application, and that plays an essential role as your application gets bigger.

For example, imagine having a database connection defined as an [asynchronous provider](/v9/fundamentals/async-providers). Async providers are designed to delay the application start until one or more asynchronous tasks are completed. That means, if your serverless function on average requires 2s to connect to the database (on bootstrap), your endpoint will need at least two extra seconds (because it must wait till the connection is established) to send a response back (when it's a cold start and your application wasn't running already).

As you can see, the way you structure your providers is somewhat different in a **serverless environment** where bootstrap time is important. Another good example is if you use Redis for caching, but only in certain scenarios. Perhaps, in this case, you should not define a Redis connection as an async provider, as it would slow down the bootstrap time, even if it's not required for this specific function invocation.

Also, sometimes you could lazy-load entire modules, using the `LazyModuleLoader` class, as described in [this chapter](/v9/fundamentals/lazy-loading-modules). Caching is a great example here too. Imagine that your application has, let's say, `CacheModule` which internally connects to Redis and also, exports the `CacheService` to interact with the Redis storage. If you don't need it for all potential function invocations, you can just load it on-demand, lazily. This way you'll get a faster startup time (when a cold start occurs) for all invocations that don't require caching.

```typescript

if (request.method === RequestMethod[RequestMethod.GET]) {
  const { CacheModule } = await import('./cache.module');
  const moduleRef = await this.lazyModuleLoader.load(() => CacheModule);

  const { CacheService } = await import('./cache.service');
  const cacheService = moduleRef.get(CacheService);

  return cacheService.get(ENDPOINT_KEY);
}
```

Another great example is a webhook or worker, which depending on some specific conditions (e.g., input arguments), may perform different operations. In such a case, you could specify a condition inside your route handler that lazily loads an appropriate module for the specific function invocation, and just load every other module lazily.

```typescript

if (workerType === WorkerType.A) {
  const { WorkerAModule } = await import('./worker-a.module');
  const moduleRef = await this.lazyModuleLoader.load(() => WorkerAModule);
  // ...
} else if (workerType === WorkerType.B) {
  const { WorkerBModule } = await import('./worker-b.module');
  const moduleRef = await this.lazyModuleLoader.load(() => WorkerBModule);
  // ...
}
```

#### Example integration[#](/faq/serverless#example-integration)

The way your application's entry file (typically `main.ts` file) is supposed to look like **depends on several factors** and so **there's no single template** that just works for every scenario. For example, the initialization file required to spin up your serverless function varies by cloud providers (AWS, Azure, GCP, etc.). Also, depending on whether you want to run a typical HTTP application with multiple routes/endpoints or just provide a single route (or execute a specific portion of code), your application's code will look different (for example, for the endpoint-per-function approach you could use the `NestFactory.createApplicationContext` instead of booting the HTTP server, setting up middleware, etc.).

Just for illustration purposes, we'll integrate Nest (using `@nestjs/platform-express` and so spinning up the whole, fully functional HTTP router) with the [Serverless](https://www.serverless.com/) framework (in this case, targeting AWS Lambda). As we've mentioned earlier, your code will differ depending on the cloud provider you choose, and many other factors.

First, let's install the required packages:

```bash

$ npm i @vendia/serverless-express aws-lambda
$ npm i -D @types/aws-lambda serverless-offline
```

> **Hint** To speed up development cycles, we install the `serverless-offline` plugin which emulates AWS λ and API Gateway.

Once the installation process is complete, let's create the `serverless.yml` file to configure the Serverless framework:

```yaml

service: serverless-example

plugins:
  - serverless-offline

provider:
  name: aws
  runtime: nodejs14.x

functions:
  main:
    handler: dist/main.handler
    events:
      - http:
          method: ANY
          path: /
      - http:
          method: ANY
          path: '{proxy+}'
```

> **Hint** To learn more about the Serverless framework, visit the [official documentation](https://www.serverless.com/framework/docs/).

With this place, we can now navigate to the `main.ts` file and update our bootstrap code with the required boilerplate:

```typescript

import { NestFactory } from '@nestjs/core';
import serverlessExpress from '@vendia/serverless-express';
import { Callback, Context, Handler } from 'aws-lambda';
import { AppModule } from './app.module';

let server: Handler;

async function bootstrap(): Promise<Handler> {
  const app = await NestFactory.create(AppModule);
  await app.init();

  const expressApp = app.getHttpAdapter().getInstance();
  return serverlessExpress({ app: expressApp });
}

export const handler: Handler = async (
  event: any,
  context: Context,
  callback: Callback,
) => {
  server = server ?? (await bootstrap());
  return server(event, context, callback);
};
```

> **Hint** For creating multiple serverless functions and sharing common modules between them, we recommend using the [CLI Monorepo mode](/cli/monorepo#monorepo-mode).

> **Warning** If you use `@nestjs/swagger` package, there are a few additional steps required to make it work properly in the context of serverless function. Check out this [article](https://javascript.plainenglish.io/serverless-nestjs-document-your-api-with-swagger-and-aws-api-gateway-64a53962e8a2) for more information.

Next, open up the `tsconfig.json` file and make sure to enable the `esModuleInterop` option to make the `@vendia/serverless-express` package load properly.

```json

{
  "compilerOptions": {
    ...
    "esModuleInterop": true
  }
}
```

Now we can build our application (with `nest build` or `tsc`) and use the `serverless` CLI to start our lambda function locally:

```bash

$ npm run build
$ npx serverless offline
```

Once the application is running, open your browser and navigate to `http://localhost:3000/dev/[ANY_ROUTE]` (where `[ANY_ROUTE]` is any endpoint registered in your application).

In the sections above, we've shown that using `webpack` and bundling your app can have significant impact on the overall bootstrap time. However, to make it work with our example, there are a few additional configurations you must add in your `webpack.config.js` file. Generally, to make sure our `handler` function will be picked up, we must change the `output.libraryTarget` property to `commonjs2`.

```javascript

return {
  ...options,
  externals: [],
  output: {
    ...options.output,
    libraryTarget: 'commonjs2',
  },
  // ... the rest of the configuration
};
```

With this in place, you can now use `$ nest build --webpack` to compile your function's code (and then `$ npx serverless offline` to test it).

It's also recommended (but **not required** as it will slow down your build process) to install the `terser-webpack-plugin` package and override its configuration to keep classnames intact when minifying your production build. Not doing so can result in incorrect behavior when using `class-validator` within your application.

```javascript

const TerserPlugin = require('terser-webpack-plugin');

return {
  ...options,
  externals: [],
  optimization: {
    minimizer: [
      new TerserPlugin({
        terserOptions: {
          keep_classnames: true,
        },
      }),
    ],
  },
  output: {
    ...options.output,
    libraryTarget: 'commonjs2',
  },
  // ... the rest of the configuration
};
```

#### Using standalone application feature[#](/faq/serverless#using-standalone-application-feature)

Alternatively, if you want to keep your function very lightweight and you don't need any HTTP-related features (routing, but also guards, interceptors, pipes, etc.), you can just use `NestFactory.createApplicationContext` (as mentioned earlier) instead of running the entire HTTP server (and `express` under the hood), as follows:

main.ts

JS TS

```typescript

import { HttpStatus } from '@nestjs/common';
import { NestFactory } from '@nestjs/core';
import { Callback, Context, Handler } from 'aws-lambda';
import { AppModule } from './app.module';
import { AppService } from './app.service';

export const handler: Handler = async (
  event: any,
  context: Context,
  callback: Callback,
) => {
  const appContext = await NestFactory.createApplicationContext(AppModule);
  const appService = appContext.get(AppService);

  return {
    body: appService.getHello(),
    statusCode: HttpStatus.OK,
  };
};
```

> **Hint** Be aware that `NestFactory.createApplicationContext` does not wrap controller methods with enhancers (guard, interceptors, etc.). For this, you must use the `NestFactory.create` method.

You could also pass the `event` object down to, let's say, `EventsService` provider that could process it and return a corresponding value (depending on the input value and your business logic).

```typescript

export const handler: Handler = async (
  event: any,
  context: Context,
  callback: Callback,
) => {
  const appContext = await NestFactory.createApplicationContext(AppModule);
  const eventsService = appContext.get(EventsService);
  return eventsService.process(event);
};
```

----
url: https://docs.nestjs.com/v11/microservices/interceptors
----

* [Interceptors](https://docs.nestjs.com/v11/microservices/interceptors#interceptors)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/microservices/interceptors.md "Suggest Edits")

### Interceptors

There is no difference between [regular interceptors](/v11/interceptors) and microservices interceptors. The following example uses a manually instantiated method-scoped interceptor. Just as with HTTP based applications, you can also use controller-scoped interceptors (i.e., prefix the controller class with a `@UseInterceptors()` decorator).

JS TS

```typescript

@UseInterceptors(new TransformInterceptor())
@MessagePattern({ cmd: 'sum' })
accumulate(data: number[]): number {
  return (data || []).reduce((a, b) => a + b);
}
```

```typescript

@UseInterceptors(new TransformInterceptor())
@MessagePattern({ cmd: 'sum' })
accumulate(data) {
  return (data || []).reduce((a, b) => a + b);
}
```

----
url: https://docs.nestjs.com/v9/microservices/grpc
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [gRPC](https://docs.nestjs.com/v9/microservices/grpc#grpc)
* [Installation](https://docs.nestjs.com/v9/microservices/grpc#installation)
* [Overview](https://docs.nestjs.com/v9/microservices/grpc#overview)
* [Options](https://docs.nestjs.com/v9/microservices/grpc#options)
* [Sample gRPC service](https://docs.nestjs.com/v9/microservices/grpc#sample-grpc-service)
* [Client](https://docs.nestjs.com/v9/microservices/grpc#client)
* [Example](https://docs.nestjs.com/v9/microservices/grpc#example)
* [gRPC Streaming](https://docs.nestjs.com/v9/microservices/grpc#grpc-streaming)
* [Streaming sample](https://docs.nestjs.com/v9/microservices/grpc#streaming-sample)
* [Subject strategy](https://docs.nestjs.com/v9/microservices/grpc#subject-strategy)
* [Call stream handler](https://docs.nestjs.com/v9/microservices/grpc#call-stream-handler)
* [gRPC Metadata](https://docs.nestjs.com/v9/microservices/grpc#grpc-metadata)

```bash

$ npm i --save @grpc/grpc-js @grpc/proto-loader
```

#### Overview[#](/microservices/grpc#overview)

Like other Nest microservices transport layer implementations, you select the gRPC transporter mechanism using the `transport` property of the options object passed to the `createMicroservice()` method. In the following example, we'll set up a hero service. The `options` property provides metadata about that service; its properties are described [below](microservices/grpc#options).

main.ts

JS TS

```typescript

const app = await NestFactory.createMicroservice<MicroserviceOptions>(AppModule, {
  transport: Transport.GRPC,
  options: {
    package: 'hero',
    protoPath: join(__dirname, 'hero/hero.proto'),
  },
});
```

```typescript

const app = await NestFactory.createMicroservice(AppModule, {
  transport: Transport.GRPC,
  options: {
    package: 'hero',
    protoPath: join(__dirname, 'hero/hero.proto'),
  },
});
```

> **Hint** The `join()` function is imported from the `path` package; the `Transport` enum is imported from the `@nestjs/microservices` package.

In the `nest-cli.json` file, we add the `assets` property that allows us to distribute non-TypeScript files, and `watchAssets` - to turn on watching all non-TypeScript assets. In our case, we want `.proto` files to be automatically copied to the `dist` folder.

```json

{
  "compilerOptions": {
    "assets": ["**/*.proto"],
    "watchAssets": true
  }
}
```

#### Options[#](/microservices/grpc#options)

The **gRPC** transporter options object exposes the properties described below.

|               |                                                                                                                                                                                                                          |
| ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `package`     | Protobuf package name (matches `package` setting from `.proto` file). Required                                                                                                                                           |
| `protoPath`   | Absolute (or relative to the root dir) path to the `.proto` file. Required                                                                                                                                               |
| `url`         | Connection url. String in the format `ip address/dns name:port` (for example, `'localhost:50051'`) defining the address/port on which the transporter establishes a connection. Optional. Defaults to `'localhost:5000'` |
| `protoLoader` | NPM package name for the utility to load `.proto` files. Optional. Defaults to `'@grpc/proto-loader'`                                                                                                                    |
| `loader`      | `@grpc/proto-loader` options. These provide detailed control over the behavior of `.proto` files. Optional. See [here](https://github.com/grpc/grpc-node/blob/master/packages/proto-loader/README.md) for more details   |
| `credentials` | Server credentials. Optional. [Read more here](https://grpc.io/grpc/node/grpc.ServerCredentials.html)                                                                                                                    |

#### Sample gRPC service[#](/microservices/grpc#sample-grpc-service)

Let's define our sample gRPC service called `HeroesService`. In the above `options` object, the`protoPath` property sets a path to the `.proto` definitions file `hero.proto`. The `hero.proto` file is structured using [protocol buffers](https://developers.google.com/protocol-buffers). Here's what it looks like:

```typescript

// hero/hero.proto
syntax = "proto3";

package hero;

service HeroesService {
  rpc FindOne (HeroById) returns (Hero) {}
}

message HeroById {
  int32 id = 1;
}

message Hero {
  int32 id = 1;
  string name = 2;
}
```

Our `HeroesService` exposes a `FindOne()` method. This method expects an input argument of type `HeroById` and returns a `Hero` message (protocol buffers use `message` elements to define both parameter types and return types).

Next, we need to implement the service. To define a handler that fulfills this definition, we use the `@GrpcMethod()` decorator in a controller, as shown below. This decorator provides the metadata needed to declare a method as a gRPC service method.

> **Hint** The `@MessagePattern()` decorator ([read more](microservices/basics#request-response)) introduced in previous microservices chapters is not used with gRPC-based microservices. The `@GrpcMethod()` decorator effectively takes its place for gRPC-based microservices.

heroes.controller.ts

JS TS

```typescript

@Controller()
export class HeroesController {
  @GrpcMethod('HeroesService', 'FindOne')
  findOne(data: HeroById, metadata: Metadata, call: ServerUnaryCall<any, any>): Hero {
    const items = [
      { id: 1, name: 'John' },
      { id: 2, name: 'Doe' },
    ];
    return items.find(({ id }) => id === data.id);
  }
}
```

```typescript

@Controller()
export class HeroesController {
  @GrpcMethod('HeroesService', 'FindOne')
  findOne(data, metadata, call) {
    const items = [
      { id: 1, name: 'John' },
      { id: 2, name: 'Doe' },
    ];
    return items.find(({ id }) => id === data.id);
  }
}
```

> **Hint** The `@GrpcMethod()` decorator is imported from the `@nestjs/microservices` package, while `Metadata` and `ServerUnaryCall` from the `grpc` package.

The decorator shown above takes two arguments. The first is the service name (e.g., `'HeroesService'`), corresponding to the `HeroesService` service definition in `hero.proto`. The second (the string `'FindOne'`) corresponds to the `FindOne()` rpc method defined within `HeroesService` in the `hero.proto` file.

The `findOne()` handler method takes three arguments, the `data` passed from the caller, `metadata` that stores gRPC request metadata and `call` to obtain the `GrpcCall` object properties such as `sendMetadata` for send metadata to client.

Both `@GrpcMethod()` decorator arguments are optional. If called without the second argument (e.g., `'FindOne'`), Nest will automatically associate the `.proto` file rpc method with the handler based on converting the handler name to upper camel case (e.g., the `findOne` handler is associated with the `FindOne` rpc call definition). This is shown below.

heroes.controller.ts

JS TS

```typescript

@Controller()
export class HeroesController {
  @GrpcMethod('HeroesService')
  findOne(data: HeroById, metadata: Metadata, call: ServerUnaryCall<any, any>): Hero {
    const items = [
      { id: 1, name: 'John' },
      { id: 2, name: 'Doe' },
    ];
    return items.find(({ id }) => id === data.id);
  }
}
```

```typescript

@Controller()
export class HeroesController {
  @GrpcMethod('HeroesService')
  findOne(data, metadata, call) {
    const items = [
      { id: 1, name: 'John' },
      { id: 2, name: 'Doe' },
    ];
    return items.find(({ id }) => id === data.id);
  }
}
```

You can also omit the first `@GrpcMethod()` argument. In this case, Nest automatically associates the handler with the service definition from the proto definitions file based on the **class** name where the handler is defined. For example, in the following code, class `HeroesService` associates its handler methods with the `HeroesService` service definition in the `hero.proto` file based on the matching of the name `'HeroesService'`.

heroes.controller.ts

JS TS

```typescript

@Controller()
export class HeroesService {
  @GrpcMethod()
  findOne(data: HeroById, metadata: Metadata, call: ServerUnaryCall<any, any>): Hero {
    const items = [
      { id: 1, name: 'John' },
      { id: 2, name: 'Doe' },
    ];
    return items.find(({ id }) => id === data.id);
  }
}
```

```typescript

@Controller()
export class HeroesService {
  @GrpcMethod()
  findOne(data, metadata, call) {
    const items = [
      { id: 1, name: 'John' },
      { id: 2, name: 'Doe' },
    ];
    return items.find(({ id }) => id === data.id);
  }
}
```

#### Client[#](/microservices/grpc#client)

Nest applications can act as gRPC clients, consuming services defined in `.proto` files. You access remote services through a `ClientGrpc` object. You can obtain a `ClientGrpc` object in several ways.

The preferred technique is to import the `ClientsModule`. Use the `register()` method to bind a package of services defined in a `.proto` file to an injection token, and to configure the service. The `name` property is the injection token. For gRPC services, use `transport: Transport.GRPC`. The `options` property is an object with the same properties described [above](microservices/grpc#options).

```typescript

imports: [
  ClientsModule.register([
    {
      name: 'HERO_PACKAGE',
      transport: Transport.GRPC,
      options: {
        package: 'hero',
        protoPath: join(__dirname, 'hero/hero.proto'),
      },
    },
  ]),
];
```

> **Hint** The `register()` method takes an array of objects. Register multiple packages by providing a comma separated list of registration objects.

Once registered, we can inject the configured `ClientGrpc` object with `@Inject()`. Then we use the `ClientGrpc` object's `getService()` method to retrieve the service instance, as shown below.

```typescript

@Injectable()
export class AppService implements OnModuleInit {
  private heroesService: HeroesService;

  constructor(@Inject('HERO_PACKAGE') private client: ClientGrpc) {}

  onModuleInit() {
    this.heroesService = this.client.getService<HeroesService>('HeroesService');
  }

  getHero(): Observable<string> {
    return this.heroesService.findOne({ id: 1 });
  }
}
```

> **Warning** gRPC Client will not send fields that contain underscore `_` in their names unless the `keepCase` options is set to `true` in the proto loader configuration (`options.loader.keepcase` in the microservice transporter configuration).

Notice that there is a small difference compared to the technique used in other microservice transport methods. Instead of the `ClientProxy` class, we use the `ClientGrpc` class, which provides the `getService()` method. The `getService()` generic method takes a service name as an argument and returns its instance (if available).

Alternatively, you can use the `@Client()` decorator to instantiate a `ClientGrpc` object, as follows:

```typescript

@Injectable()
export class AppService implements OnModuleInit {
  @Client({
    transport: Transport.GRPC,
    options: {
      package: 'hero',
      protoPath: join(__dirname, 'hero/hero.proto'),
    },
  })
  client: ClientGrpc;

  private heroesService: HeroesService;

  onModuleInit() {
    this.heroesService = this.client.getService<HeroesService>('HeroesService');
  }

  getHero(): Observable<string> {
    return this.heroesService.findOne({ id: 1 });
  }
}
```

Finally, for more complex scenarios, we can inject a dynamically configured client using the `ClientProxyFactory` class as described [here](/microservices/basics#client).

In either case, we end up with a reference to our `HeroesService` proxy object, which exposes the same set of methods that are defined inside the `.proto` file. Now, when we access this proxy object (i.e., `heroesService`), the gRPC system automatically serializes requests, forwards them to the remote system, returns a response, and deserializes the response. Because gRPC shields us from these network communication details, `heroesService` looks and acts like a local provider.

Note, all service methods are **lower camel cased** (in order to follow the natural convention of the language). So, for example, while our `.proto` file `HeroesService` definition contains the `FindOne()` function, the `heroesService` instance will provide the `findOne()` method.

```typescript

interface HeroesService {
  findOne(data: { id: number }): Observable<any>;
}
```

A message handler is also able to return an `Observable`, in which case the result values will be emitted until the stream is completed.

heroes.controller.ts

JS TS

```typescript

@Get()
call(): Observable<any> {
  return this.heroesService.findOne({ id: 1 });
}
```

```typescript

@Get()
call() {
  return this.heroesService.findOne({ id: 1 });
}
```

To send gRPC metadata (along with the request), you can pass a second argument, as follows:

```typescript

call(): Observable<any> {
  const metadata = new Metadata();
  metadata.add('Set-Cookie', 'yummy_cookie=choco');

  return this.heroesService.findOne({ id: 1 }, metadata);
}
```

> **Hint** The `Metadata` class is imported from the `grpc` package.

```typescript

// hello/hello.proto
syntax = "proto3";

package hello;

service HelloService {
  rpc BidiHello(stream HelloRequest) returns (stream HelloResponse);
  rpc LotsOfGreetings(stream HelloRequest) returns (HelloResponse);
}

message HelloRequest {
  string greeting = 1;
}

message HelloResponse {
  string reply = 1;
}
```

> **Hint** The `LotsOfGreetings` method can be simply implemented with the `@GrpcMethod` decorator (as in the examples above) since the returned stream can emit multiple values.

Based on this `.proto` file, let's define the `HelloService` interface:

```typescript

interface HelloService {
  bidiHello(upstream: Observable<HelloRequest>): Observable<HelloResponse>;
  lotsOfGreetings(
    upstream: Observable<HelloRequest>,
  ): Observable<HelloResponse>;
}

interface HelloRequest {
  greeting: string;
}

interface HelloResponse {
  reply: string;
}
```

> **Hint** The proto interface can be automatically generated by the [ts-proto](https://github.com/stephenh/ts-proto) package, learn more [here](https://github.com/stephenh/ts-proto/blob/main/NESTJS.markdown).

#### Subject strategy[#](/microservices/grpc#subject-strategy)

The `@GrpcStreamMethod()` decorator provides the function parameter as an RxJS `Observable`. Thus, we can receive and process multiple messages.

```typescript

@GrpcStreamMethod()
bidiHello(messages: Observable<any>, metadata: Metadata, call: ServerDuplexStream<any, any>): Observable<any> {
  const subject = new Subject();

  const onNext = message => {
    console.log(message);
    subject.next({
      reply: 'Hello, world!'
    });
  };
  const onComplete = () => subject.complete();
  messages.subscribe({
    next: onNext,
    complete: onComplete,
  });


  return subject.asObservable();
}
```

> **Warning** For supporting full-duplex interaction with the `@GrpcStreamMethod()` decorator, the controller method must return an RxJS `Observable`.

> **Hint** The `Metadata` and `ServerUnaryCall` classes/interfaces are imported from the `grpc` package.

According to the service definition (in the `.proto` file), the `BidiHello` method should stream requests to the service. To send multiple asynchronous messages to the stream from a client, we leverage an RxJS `ReplaySubject` class.

```typescript

const helloService = this.client.getService<HelloService>('HelloService');
const helloRequest$ = new ReplaySubject<HelloRequest>();

helloRequest$.next({ greeting: 'Hello (1)!' });
helloRequest$.next({ greeting: 'Hello (2)!' });
helloRequest$.complete();

return helloService.bidiHello(helloRequest$);
```

In the example above, we wrote two messages to the stream (`next()` calls) and notified the service that we've completed sending the data (`complete()` call).

#### Call stream handler[#](/microservices/grpc#call-stream-handler)

When the method return value is defined as `stream`, the `@GrpcStreamCall()` decorator provides the function parameter as `grpc.ServerDuplexStream`, which supports standard methods like `.on('data', callback)`, `.write(message)` or `.cancel()`. Full documentation on available methods can be found [here](https://grpc.github.io/grpc/node/grpc-ClientDuplexStream.html).

Alternatively, when the method return value is not a `stream`, the `@GrpcStreamCall()` decorator provides two function parameters, respectively `grpc.ServerReadableStream` (read more [here](https://grpc.github.io/grpc/node/grpc-ServerReadableStream.html)) and `callback`.

Let's start with implementing the `BidiHello` which should support a full-duplex interaction.

```typescript

@GrpcStreamCall()
bidiHello(requestStream: any) {
  requestStream.on('data', message => {
    console.log(message);
    requestStream.write({
      reply: 'Hello, world!'
    });
  });
}
```

> **Hint** This decorator does not require any specific return parameter to be provided. It is expected that the stream will be handled similar to any other standard stream type.

In the example above, we used the `write()` method to write objects to the response stream. The callback passed into the `.on()` method as a second parameter will be called every time our service receives a new chunk of data.

Let's implement the `LotsOfGreetings` method.

```typescript

@GrpcStreamCall()
lotsOfGreetings(requestStream: any, callback: (err: unknown, value: HelloResponse) => void) {
  requestStream.on('data', message => {
    console.log(message);
  });
  requestStream.on('end', () => callback(null, { reply: 'Hello, world!' }));
}
```

```typescript

@Controller()
export class HeroesService {
  @GrpcMethod()
  findOne(data: HeroById, metadata: Metadata, call: ServerUnaryCall<any, any>): Hero {
    const serverMetadata = new Metadata();
    const items = [
      { id: 1, name: 'John' },
      { id: 2, name: 'Doe' },
    ];

    serverMetadata.add('Set-Cookie', 'yummy_cookie=choco');
    call.sendMetadata(serverMetadata);

    return items.find(({ id }) => id === data.id);
  }
}
```

```typescript

@Controller()
export class HeroesService {
  @GrpcMethod()
  findOne(data, metadata, call) {
    const serverMetadata = new Metadata();
    const items = [
      { id: 1, name: 'John' },
      { id: 2, name: 'Doe' },
    ];

    serverMetadata.add('Set-Cookie', 'yummy_cookie=choco');
    call.sendMetadata(serverMetadata);

    return items.find(({ id }) => id === data.id);
  }
}
```

Likewise, to read the metadata in handlers annotated with the `@GrpcStreamMethod()` handler ([subject strategy](microservices/grpc#subject-strategy)), use the second argument (metadata), which is of type `Metadata` (imported from the `grpc` package).

To send back metadata from the handler, use the `ServerDuplexStream#sendMetadata()` method (third handler argument).

To read metadata from within the [call stream handlers](microservices/grpc#call-stream-handler) (handlers annotated with `@GrpcStreamCall()` decorator), listen to the `metadata` event on the `requestStream` reference, as follows:

```typescript

requestStream.on('metadata', (metadata: Metadata) => {
  const meta = metadata.get('X-Meta');
});
```

----
url: https://docs.nestjs.com/v6/support
----

* [Support](https://docs.nestjs.com/v6/support#support)
* [How can you help?](https://docs.nestjs.com/v6/support#how-can-you-help)

----
url: https://docs.nestjs.com/v4/techniques/mvc
----

### MVC

Nest uses [express](https://github.com/expressjs/express) library under the hood, therefore every tutorial about MVC (Model-View-Controller) pattern in express concerns Nest as well. Firstly, let's clone a Nest [starter](https://github.com/nestjs/typescript-starter) project:

JavaScript TypeScript

```bash

$ git clone https://github.com/nestjs/typescript-starter.git project
$ cd project
$ npm install
$ npm run start
```

```bash

$ git clone https://github.com/nestjs/javascript-starter.git project
$ cd project
$ npm install
$ npm run start
```

In order to create a simple MVC app, we have to install a [template engine](http://expressjs.com/en/guide/using-template-engines.html):

```bash

$ npm install --save jade
```

I have chosen `jade` because it's the most popular engine at the moment, but personally, I prefer a [Mustache](https://github.com/bryanburgers/node-mustache-express). Once the installation process is completed, we need to configure the express instance using following code:

main.ts

JavaScript TypeScript

TypeScript

```typescript

import * as express from 'express';
import * as path from 'path';
import { NestFactory } from '@nestjs/core';
import { ApplicationModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(ApplicationModule);

  app.use(express.static(path.join(__dirname, 'public')));
  app.set('views', __dirname + '/views');
  app.set('view engine', 'jade');

  await app.listen(3000);
}
bootstrap();
```

We told [express](https://github.com/expressjs/express) that the `public` directory will be used for storing static assets, `views` will contain templates, and a `jade` template engine should be used to render an HTML output.

Now, let's create a `views` directory and an `index.jade` template inside this folder. Inside template, we are gonna print a `message` passed from the controller:

index.jade

TypeScript

```typescript

html
head
body
  p= message
```

Afterwards, open the `app.controller` file and replace the `root()` method with the following code:

app.controller.ts

JavaScript TypeScript

TypeScript

```typescript

@Get()
root(@Res() res) {
  res.render('index', { message: 'Hello world!' });
}
```

TypeScript

```typescript

@Get()
@Bind(Res())
root(res) {
  res.render('index', { message: 'Hello world!' });
}
```

> **Hint** In fact, when Nest detects `@Res()` decorator, it injects express `response` object. Learn more about its abilities [here](http://expressjs.com/en/api.html).

That's all. While the application is running, open your browser and navigate to `http://localhost:3000/`. You should see the `Hello world!` message.

#### Sponsors

[](https://valor-software.com/)

Nest is an MIT-licensed open source project. It can grow thanks to the support by these awesome people. If you'd like to join them, please read more [here](https://opencollective.com/nest). Thanks!

[](https://opencollective.com/nest/backer/0/website)[](https://opencollective.com/nest/backer/1/website)[](https://opencollective.com/nest/backer/2/website)[](https://opencollective.com/nest/backer/3/website)[](https://opencollective.com/nest/backer/4/website)[](https://opencollective.com/nest/backer/5/website)[](https://opencollective.com/nest/backer/6/website)[](https://opencollective.com/nest/backer/7/website)[](https://opencollective.com/nest/backer/8/website)[](https://opencollective.com/nest/backer/9/website)[](https://opencollective.com/nest/backer/10/website)[](https://opencollective.com/nest/backer/11/website)[](https://opencollective.com/nest/backer/12/website)[](https://opencollective.com/nest/backer/13/website)[](https://opencollective.com/nest/backer/14/website)[](https://opencollective.com/nest/backer/15/website)[](https://opencollective.com/nest/backer/16/website)[](https://opencollective.com/nest/backer/17/website)[](https://opencollective.com/nest/backer/18/website)[](https://opencollective.com/nest/backer/19/website)[](https://opencollective.com/nest/backer/20/website)[](https://opencollective.com/nest/backer/21/website)[](https://opencollective.com/nest/backer/22/website)[](https://opencollective.com/nest/backer/23/website)[](https://opencollective.com/nest/backer/24/website)[](https://opencollective.com/nest/backer/25/website)[](https://opencollective.com/nest/backer/26/website)[](https://opencollective.com/nest/backer/27/website)[](https://opencollective.com/nest/backer/28/website)[](https://opencollective.com/nest/backer/29/website)

[Become a sponsor](https://opencollective.com/nest)

----
url: https://docs.nestjs.com/v8/discover/companies
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Who is using Nest?](https://docs.nestjs.com/v8/discover/companies#who-is-using-nest)
* [Companies](https://docs.nestjs.com/v8/discover/companies#companies)

### Who is using Nest?

We are proudly helping various companies building their products at scale. If you are using Nest and would you like to be listed here, see this [thread](https://github.com/nestjs/nest/issues/1006). We are willing to put your logo here!

#### Companies[#](/discover/companies#companies)

According to our knowledge, all the following companies have built awesome projects on top of our framework:

[](https://roche.com)[](https://adidas.com)[](https://capgemini.com)[](https://www.societegenerale.fr/)[](https://rewe-digital.com/)[](https://www.decathlon.com/)[](https://www.autodesk.com/)[](https://www.neo4j.com/)[](https://www.shipt.com/)[](https://github.com/Sanofi-IADC)[](https://valor-software.com/)[](https://sitepen.com)[](https://gojob.com/)[](https://neoteric.eu/)[](https://trellis.org/)[](https://scal.io)[](https://swingdev.io/)[](https://culturacolectiva.com)[](https://trilon.io)[](http://architectnow.net)[](https://www.iflix.com)[](https://genuinebee.com/)[](https://runplayersleague.com)[](http://www.yanrongyun.com)[](https://sclable.com)[](https://www.dozto.com)[](https://www.qingtui.cn/)[](https://crowdlinker.com/)[](https://nothing.ch/)[](https://swissdevjobs.ch/jobs/Dev-Ops/All)[](https://zeo.org/tr/)[](https://valueadd.pl/)[](https://bedu.org)[](https://shopback.com)[](https://www.facile.it)[](https://interfacewerk.de)[](https://www.ottonova.de)[](https://radity.com)[](https://globalctoforum.org/)[](https://rivvy.app)[](https://www.vuestorefront.io/)[](https://fuseautotech.com)[](https://amplication.com)

|                                     |
| ----------------------------------- |
| <https://gorrion.io/>               |
| <http://balticdatascience.com/>     |
| <https://prohabits.com/>            |
| <https://komed-health.com/>         |
| <https://kerberus.com.co/>          |
| <http://xtremis.com/>               |
| <https://notadd.com/>               |
| <http://jsdaddy.io/>                |
| <https://yumpingo.com/>             |
| <https://analytics-importer.cz/>    |
| <https://dayzim.com/>               |
| <https://wizkids.co.uk/>            |
| <https://pilvia.com/>               |
| <https://wi-q.com/>                 |
| <http://agrofel.com.br>             |
| <https://societegenerale.com/>      |
| <https://trashpanda.hulan.nl/>      |
| <https://bytedance.com/>            |
| <https://votercircle.com>           |
| <https://erento.com>                |
| <https://ideas.manticore-labs.com/> |
| <https://smartexlab.com/>           |
| <https://automama.ru/>              |
| <https://iflix.com/>                |
| <https://frontendwatch.com/>        |
| <https://mobilejazz.com/>           |
| <https://cgiandi.com/>              |
| <https://www.titlex.com.au/>        |
| <https://codengage.com/>            |
| <https://budacode.com/>             |
| <https://blueanchor.io/>            |
| <https://www.easymetrics.com/>      |
| <https://getapollo.io/>             |
| <https://big-bench.com/>            |
| <https://www.qingtui.cn/>           |
| <https://www.rosebayconsult.com/>   |
| <https://www.patrocinium.com/>      |
| <https://creatorsdaily.com>         |
| <https://autoscar.com.br>           |
| <https://www.mediktiv.com>          |
| <https://harmonize.health>          |
| <https://accerlery.be>              |
| <https://www.facile.it>             |
| <https://shopback.com>              |
| <https://www.ottonova.de>           |
| <https://www.radity.com>            |
| <https://globalctoforum.org>        |
| <https://halojasa.com>              |
| <https://hexito.com>                |
| <https://rivvy.app>                 |
| <https://padfever.com/>             |
| <https://datenlotse.org>            |
| <https://bemum.co>                  |
| <https://weoptimeye.ai>             |
| <https://nemovote.com>              |
| <https://selleo.com>                |
| <https://pchas.ir>                  |
| <https://tayeh.ir>                  |
| <https://forwardigital.co.uk>       |
| <https://rozetka.com.ua>            |
| <https://www.itrio.net>             |
| <https://alexishr.com>              |
| <https://dyrector.io>               |
| <https://stijlbreuk.nl>             |
| <https://polygon-software.ch>       |
| <https://bewith.io>                 |

and a lot more but we don't have enough time to update above list. Feel free to create a [pull request](https://github.com/nestjs/docs.nestjs.com/pulls) though!

----
url: https://docs.nestjs.com/v7/openapi/cli-plugin
----

* [CLI Plugin](https://docs.nestjs.com/v7/openapi/cli-plugin#cli-plugin)
* [Overview](https://docs.nestjs.com/v7/openapi/cli-plugin#overview)
* [Comments introspection](https://docs.nestjs.com/v7/openapi/cli-plugin#comments-introspection)
* [Using the CLI plugin](https://docs.nestjs.com/v7/openapi/cli-plugin#using-the-cli-plugin)
* [Integration with ts-jest (e2e tests)](https://docs.nestjs.com/v7/openapi/cli-plugin#integration-with-ts-jest-e2e-tests)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/openapi/cli-plugin.md "Suggest Edits")

### CLI Plugin

TypeScript's metadata reflection system has several limitations which make it impossible to, for instance, determine what properties a class consists of or recognize whether a given property is optional or required. However, some of these constraints can be addressed at compilation time. Nest provides a plugin that enhances the TypeScript compilation process to reduce the amount of boilerplate code required.

> **Hint** This plugin is **opt-in**. If you prefer, you can declare all decorators manually, or only specific decorators where you need them.

```typescript

export class CreateUserDto {
  @ApiProperty()
  email: string;

  @ApiProperty()
  password: string;

  @ApiProperty({ enum: RoleEnum, default: [], isArray: true })
  roles: RoleEnum[] = [];

  @ApiProperty({ required: false, default: true })
  isEnabled?: boolean = true;
}
```

While not a significant issue with medium-sized projects, it becomes verbose & hard to maintain once you have a large set of classes.

By enabling the Swagger plugin, the above class definition can be declared simply:

```typescript

export class CreateUserDto {
  email: string;
  password: string;
  roles: RoleEnum[] = [];
  isEnabled?: boolean = true;
}
```

The plugin adds appropriate decorators on the fly based on the **Abstract Syntax Tree**. Thus you won't have to struggle with `@ApiProperty` decorators scattered throughout the code.

> **Hint** The plugin will automatically generate any missing swagger properties, but if you need to override them, you simply set them explicitly via `@ApiProperty()`.

#### Comments introspection[#](/openapi/cli-plugin#comments-introspection)

With the comments introspection feature enabled, CLI plugin will generate descriptions and example values for properties based on comments.

For example, given an example `roles` property:

```typescript

/**
 * A list of user's roles
 * @example ['admin']
 */
@ApiProperty({
  description: `A list of user's roles`,
  example: ['admin'],
})
roles: RoleEnum[] = [];
```

You must duplicate both description and example values. With `introspectComments` enabled, the CLI plugin can extract these comments and automatically provide descriptions (and examples, if defined) for properties. Now, the above property can be declared simply as follows:

```typescript

/**
 * A list of user's roles
 * @example ['admin']
 */
roles: RoleEnum[] = [];
```

#### Using the CLI plugin[#](/openapi/cli-plugin#using-the-cli-plugin)

To enable the plugin, open `nest-cli.json` (if you use [Nest CLI](/v7/cli/overview)) and add the following `plugins` configuration:

```javascript

{
  "collection": "@nestjs/schematics",
  "sourceRoot": "src",
  "compilerOptions": {
    "plugins": ["@nestjs/swagger"]
  }
}
```

You can use the `options` property to customize the behavior of the plugin.

```javascript

"plugins": [
  {
    "name": "@nestjs/swagger",
    "options": {
      "classValidatorShim": false,
      "introspectComments": true
    }
  }
]
```

The `options` property has to fulfill the following interface:

```typescript

export interface PluginOptions {
  dtoFileNameSuffix?: string[];
  controllerFileNameSuffix?: string[];
  classValidatorShim?: boolean;
  introspectComments?: boolean;
}
```

| Option                     | Default                     | Description                                                                                                                             |
| -------------------------- | --------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| `dtoFileNameSuffix`        | `['.dto.ts', '.entity.ts']` | DTO (Data Transfer Object) files suffix                                                                                                 |
| `controllerFileNameSuffix` | `.controller.ts`            | Controller files suffix                                                                                                                 |
| `classValidatorShim`       | `true`                      | If set to true, the module will reuse `class-validator` validation decorators (e.g. `@Max(10)` will add `max: 10` to schema definition) |
| `introspectComments`       | `false`                     | If set to true, plugin will generate descriptions and example values for properties based on comments                                   |

If you don't use the CLI but instead have a custom `webpack` configuration, you can use this plugin in combination with `ts-loader`:

```javascript

getCustomTransformers: (program: any) => ({
  before: [require('@nestjs/swagger/plugin').before({}, program)]
}),
```

#### Integration with `ts-jest` (e2e tests)[#](/openapi/cli-plugin#integration-with-ts-jest-e2e-tests)

To run e2e tests, `ts-jest` compiles your source code files on the fly, in memory. This means, it doesn't use Nest CLI compiler and does not apply any plugins or perform AST transformations.

To enable the plugin, create the following file in your e2e tests directory:

```javascript

const transformer = require('@nestjs/swagger/plugin');

module.exports.name = 'nestjs-swagger-transformer';
// you should change the version number anytime you change the configuration below - otherwise, jest will not detect changes
module.exports.version = 1;

module.exports.factory = (cs) => {
  return transformer.before(
    {
      // @nestjs/swagger/plugin options (can be empty)
    },
    cs.tsCompiler.program,
  );
};
```

With this in place, import AST transformer within your `jest` configuration file. By default (in the starter application), e2e tests configuration file is located under the `test` folder and is named `jest-e2e.json`.

```json

{
  ... // other configuration
  "globals": {
    "ts-jest": {
      "astTransformers": {
        "before": ["<path to the file created above>"],
      }
    }
  }
}
```

----
url: https://docs.nestjs.com/v6/graphql/scalars
----

* [Scalars](https://docs.nestjs.com/v6/graphql/scalars#scalars)
* [Schema first](https://docs.nestjs.com/v6/graphql/scalars#schema-first)
* [Code first](https://docs.nestjs.com/v6/graphql/scalars#code-first)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/scalars.md "Suggest Edits")

### Scalars

GraphQL includes the following default types: `Int`, `Float`, `String`, `Boolean` and `ID`. In addition to these built-in types, you may need to support custom atomic data types (e.g., `Date`).

#### Schema first[#](/graphql/scalars#schema-first)

To define a custom scalar (read more about scalars [here](https://www.apollographql.com/docs/graphql-tools/scalars.html)), create a type definition and a dedicated resolver. Here (as in the official documentation), we’ll use the `graphql-type-json` package for demonstration purposes. This npm package defines a `JSON` GraphQL scalar type.

Start by installing the package:

```bash

$ npm i --save graphql-type-json
```

Once the package is installed, we pass a custom resolver to the `forRoot()` method:

```typescript

import * as GraphQLJSON from 'graphql-type-json';

@Module({
  imports: [
    GraphQLModule.forRoot({
      typePaths: ['./**/*.graphql'],
      resolvers: { JSON: GraphQLJSON },
    }),
  ],
})
export class ApplicationModule {}
```

Now we can use the `JSON` scalar in our type definitions:

```graphql

scalar JSON

type Foo {
  field: JSON
}
```

Another method to define a scalar type is to create a simple class. Assume we want to enhance our schema with the `Date` type.

```typescript

import { Scalar, CustomScalar } from '@nestjs/graphql';
import { Kind, ValueNode } from 'graphql';

@Scalar('Date')
export class DateScalar implements CustomScalar<number, Date> {
  description = 'Date custom scalar type';

  parseValue(value: number): Date {
    return new Date(value); // value from the client
  }

  serialize(value: Date): number {
    return value.getTime(); // value sent to the client
  }

  parseLiteral(ast: ValueNode): Date {
    if (ast.kind === Kind.INT) {
      return new Date(ast.value);
    }
    return null;
  }
}
```

With this in place, register `DateScalar` as a provider.

```typescript

@Module({
  providers: [DateScalar],
})
export class CommonModule {}
```

Now we can use the `Date` scalar in type definitions.

```graphql

scalar Date
```

#### Code first[#](/graphql/scalars#code-first)

To create a `Date` scalar, simply create a new class.

```typescript

import { Scalar, CustomScalar } from '@nestjs/graphql';
import { Kind, ValueNode } from 'graphql';

@Scalar('Date', type => Date)
export class DateScalar implements CustomScalar<number, Date> {
  description = 'Date custom scalar type';

  parseValue(value: number): Date {
    return new Date(value); // value from the client
  }

  serialize(value: Date): number {
    return value.getTime(); // value sent to the client
  }

  parseLiteral(ast: ValueNode): Date {
    if (ast.kind === Kind.INT) {
      return new Date(ast.value);
    }
    return null;
  }
}
```

With this in place, register `DateScalar` as a provider.

```typescript

@Module({
  providers: [DateScalar],
})
export class CommonModule {}
```

Now we can use the `Date` type in our classes.

```typescript

@Field()
creationDate: Date;
```

----
url: https://docs.nestjs.com/v7/interceptors
----

* [Interceptors](https://docs.nestjs.com/v7/interceptors#interceptors)
* [Basics](https://docs.nestjs.com/v7/interceptors#basics)
* [Execution context](https://docs.nestjs.com/v7/interceptors#execution-context)
* [Call handler](https://docs.nestjs.com/v7/interceptors#call-handler)
* [Aspect interception](https://docs.nestjs.com/v7/interceptors#aspect-interception)
* [Binding interceptors](https://docs.nestjs.com/v7/interceptors#binding-interceptors)
* [Response mapping](https://docs.nestjs.com/v7/interceptors#response-mapping)
* [Exception mapping](https://docs.nestjs.com/v7/interceptors#exception-mapping)
* [Stream overriding](https://docs.nestjs.com/v7/interceptors#stream-overriding)
* [More operators](https://docs.nestjs.com/v7/interceptors#more-operators)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/interceptors.md "Suggest Edits")

### Interceptors

An interceptor is a class annotated with the `@Injectable()` decorator. Interceptors should implement the `NestInterceptor` interface.

Each interceptor implements the `intercept()` method, which takes two arguments. The first one is the `ExecutionContext` instance (exactly the same object as for [guards](/v7/guards)). The `ExecutionContext` inherits from `ArgumentsHost`. We saw `ArgumentsHost` before in the exception filters chapter. There, we saw that it's a wrapper around arguments that have been passed to the original handler, and contains different arguments arrays based on the type of the application. You can refer back to the [exception filters](https://docs.nestjs.com/exception-filters#arguments-host) for more on this topic.

#### Execution context[#](/interceptors#execution-context)

By extending `ArgumentsHost`, `ExecutionContext` also adds several new helper methods that provide additional details about the current execution process. These details can be helpful in building more generic interceptors that can work across a broad set of controllers, methods, and execution contexts. Learn more about `ExecutionContext`[here](/v7/fundamentals/execution-context).

```typescript

import { Injectable, NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
import { Observable } from 'rxjs';
import { tap } from 'rxjs/operators';

@Injectable()
export class LoggingInterceptor implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    console.log('Before...');

    const now = Date.now();
    return next
      .handle()
      .pipe(
        tap(() => console.log(`After... ${Date.now() - now}ms`)),
      );
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';
import { Observable } from 'rxjs';
import { tap } from 'rxjs/operators';

@Injectable()
export class LoggingInterceptor {
  intercept(context, next) {
    console.log('Before...');

    const now = Date.now();
    return next
      .handle()
      .pipe(
        tap(() => console.log(`After... ${Date.now() - now}ms`)),
      );
  }
}
```

> **Hint** The `NestInterceptor<T, R>` is a generic interface in which `T` indicates the type of an `Observable<T>` (supporting the response stream), and `R` is the type of the value wrapped by `Observable<R>`.

> **Notice** Interceptors, like controllers, providers, guards, and so on, can **inject dependencies** through their `constructor`.

Since `handle()` returns an RxJS `Observable`, we have a wide choice of operators we can use to manipulate the stream. In the example above, we used the `tap()` operator, which invokes our anonymous logging function upon graceful or exceptional termination of the observable stream, but doesn't otherwise interfere with the response cycle.

#### Binding interceptors[#](/interceptors#binding-interceptors)

In order to set up the interceptor, we use the `@UseInterceptors()` decorator imported from the `@nestjs/common` package. Like [pipes](/v7/pipes) and [guards](/v7/guards), interceptors can be controller-scoped, method-scoped, or global-scoped.

cats.controller.ts

JS TS

```typescript

@UseInterceptors(LoggingInterceptor)
export class CatsController {}
```

> **Hint** The `@UseInterceptors()` decorator is imported from the `@nestjs/common` package.

Using the above construction, each route handler defined in `CatsController` will use `LoggingInterceptor`. When someone calls the `GET /cats` endpoint, you'll see the following output in your standard output:

```typescript

Before...
After... 1ms
```

Note that we passed the `LoggingInterceptor` type (instead of an instance), leaving responsibility for instantiation to the framework and enabling dependency injection. As with pipes, guards, and exception filters, we can also pass an in-place instance:

cats.controller.ts

JS TS

```typescript

@UseInterceptors(new LoggingInterceptor())
export class CatsController {}
```

As mentioned, the construction above attaches the interceptor to every handler declared by this controller. If we want to restrict the interceptor's scope to a single method, we simply apply the decorator at the **method level**.

In order to set up a global interceptor, we use the `useGlobalInterceptors()` method of the Nest application instance:

```typescript

const app = await NestFactory.create(AppModule);
app.useGlobalInterceptors(new LoggingInterceptor());
```

Global interceptors are used across the whole application, for every controller and every route handler. In terms of dependency injection, global interceptors registered from outside of any module (with `useGlobalInterceptors()`, as in the example above) cannot inject dependencies since this is done outside the context of any module. In order to solve this issue, you can set up an interceptor **directly from any module** using the following construction:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { APP_INTERCEPTOR } from '@nestjs/core';

@Module({
  providers: [
    {
      provide: APP_INTERCEPTOR,
      useClass: LoggingInterceptor,
    },
  ],
})
export class AppModule {}
```

> **Hint** When using this approach to perform dependency injection for the interceptor, note that regardless of the module where this construction is employed, the interceptor is, in fact, global. Where should this be done? Choose the module where the interceptor (`LoggingInterceptor` in the example above) is defined. Also, `useClass` is not the only way of dealing with custom provider registration. Learn more [here](/v7/fundamentals/custom-providers).

#### Response mapping[#](/interceptors#response-mapping)

We already know that `handle()` returns an `Observable`. The stream contains the value **returned** from the route handler, and thus we can easily mutate it using RxJS's `map()` operator.

> **Warning** The response mapping feature doesn't work with the library-specific response strategy (using the `@Res()` object directly is forbidden).

Let's create the `TransformInterceptor`, which will modify each response in a trivial way to demonstrate the process. It will use RxJS's `map()` operator to assign the response object to the `data` property of a newly created object, returning the new object to the client.

transform.interceptor.ts

JS TS

```typescript

import { Injectable, NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';

export interface Response<T> {
  data: T;
}

@Injectable()
export class TransformInterceptor<T> implements NestInterceptor<T, Response<T>> {
  intercept(context: ExecutionContext, next: CallHandler): Observable<Response<T>> {
    return next.handle().pipe(map(data => ({ data })));
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';
import { map } from 'rxjs/operators';

@Injectable()
export class TransformInterceptor {
  intercept(context, next) {
    return next.handle().pipe(map(data => ({ data })));
  }
}
```

> **Hint** Nest interceptors work with both synchronous and asynchronous `intercept()` methods. You can simply switch the method to `async` if necessary.

With the above construction, when someone calls the `GET /cats` endpoint, the response would look like the following (assuming that route handler returns an empty array `[]`):

```json

{
  "data": []
}
```

Interceptors have great value in creating re-usable solutions to requirements that occur across an entire application. For example, imagine we need to transform each occurrence of a `null` value to an empty string `''`. We can do it using one line of code and bind the interceptor globally so that it will automatically be used by each registered handler.

JS TS

```typescript

import { Injectable, NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';

@Injectable()
export class ExcludeNullInterceptor implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    return next
      .handle()
      .pipe(map(value => value === null ? '' : value ));
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';
import { map } from 'rxjs/operators';

@Injectable()
export class ExcludeNullInterceptor {
  intercept(context, next) {
    return next
      .handle()
      .pipe(map(value => value === null ? '' : value ));
  }
}
```

#### Exception mapping[#](/interceptors#exception-mapping)

Another interesting use-case is to take advantage of RxJS's `catchError()` operator to override thrown exceptions:

errors.interceptor.ts

JS TS

```typescript

import {
  Injectable,
  NestInterceptor,
  ExecutionContext,
  BadGatewayException,
  CallHandler,
} from '@nestjs/common';
import { Observable, throwError } from 'rxjs';
import { catchError } from 'rxjs/operators';

@Injectable()
export class ErrorsInterceptor implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    return next
      .handle()
      .pipe(
        catchError(err => throwError(new BadGatewayException())),
      );
  }
}
```

```typescript

import { Injectable, BadGatewayException } from '@nestjs/common';
import { throwError } from 'rxjs';
import { catchError } from 'rxjs/operators';

@Injectable()
export class ErrorsInterceptor {
  intercept(context, next) {
    return next
      .handle()
      .pipe(
        catchError(err => throwError(new BadGatewayException())),
      );
  }
}
```

#### Stream overriding[#](/interceptors#stream-overriding)

There are several reasons why we may sometimes want to completely prevent calling the handler and return a different value instead. An obvious example is to implement a cache to improve response time. Let's take a look at a simple **cache interceptor** that returns its response from a cache. In a realistic example, we'd want to consider other factors like TTL, cache invalidation, cache size, etc., but that's beyond the scope of this discussion. Here we'll provide a basic example that demonstrates the main concept.

cache.interceptor.ts

JS TS

```typescript

import { Injectable, NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
import { Observable, of } from 'rxjs';

@Injectable()
export class CacheInterceptor implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    const isCached = true;
    if (isCached) {
      return of([]);
    }
    return next.handle();
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';
import { of } from 'rxjs';

@Injectable()
export class CacheInterceptor {
  intercept(context, next) {
    const isCached = true;
    if (isCached) {
      return of([]);
    }
    return next.handle();
  }
}
```

Our `CacheInterceptor` has a hardcoded `isCached` variable and a hardcoded response `[]` as well. The key point to note is that we return a new stream here, created by the RxJS `of()` operator, therefore the route handler **won't be called** at all. When someone calls an endpoint that makes use of `CacheInterceptor`, the response (a hardcoded, empty array) will be returned immediately. In order to create a generic solution, you can take advantage of `Reflector` and create a custom decorator. The `Reflector` is well described in the [guards](/v7/guards) chapter.

#### More operators[#](/interceptors#more-operators)

The possibility of manipulating the stream using RxJS operators gives us many capabilities. Let's consider another common use case. Imagine you would like to handle **timeouts** on route requests. When your endpoint doesn't return anything after a period of time, you want to terminate with an error response. The following construction enables this:

timeout.interceptor.ts

JS TS

```typescript

import { Injectable, NestInterceptor, ExecutionContext, CallHandler, RequestTimeoutException } from '@nestjs/common';
import { Observable, throwError, TimeoutError } from 'rxjs';
import { catchError, timeout } from 'rxjs/operators';

@Injectable()
export class TimeoutInterceptor implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    return next.handle().pipe(
      timeout(5000),
      catchError(err => {
        if (err instanceof TimeoutError) {
          return throwError(new RequestTimeoutException());
        }
        return throwError(err);
      }),
    );
  };
};
```

```typescript

import { Injectable, RequestTimeoutException } from '@nestjs/common';
import { Observable, throwError, TimeoutError } from 'rxjs';
import { catchError, timeout } from 'rxjs/operators';

@Injectable()
export class TimeoutInterceptor {
  intercept(context, next) {
    return next.handle().pipe(
      timeout(5000),
      catchError(err => {
        if (err instanceof TimeoutError) {
          return throwError(new RequestTimeoutException());
        }
        return throwError(err);
      }),
    );
  };
};
```

After 5 seconds, request processing will be canceled. You can also add custom logic before throwing `RequestTimeoutException` (e.g. release resources).

----
url: https://docs.nestjs.com/v9/first-steps
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [First steps](https://docs.nestjs.com/v9/first-steps#first-steps)
* [Language](https://docs.nestjs.com/v9/first-steps#language)
* [Prerequisites](https://docs.nestjs.com/v9/first-steps#prerequisites)
* [Setup](https://docs.nestjs.com/v9/first-steps#setup)
* [Platform](https://docs.nestjs.com/v9/first-steps#platform)
* [Running the application](https://docs.nestjs.com/v9/first-steps#running-the-application)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/first-steps.md "Suggest Edits")

### First steps

In this set of articles, you'll learn the **core fundamentals** of Nest. To get familiar with the essential building blocks of Nest applications, we'll build a basic CRUD application with features that cover a lot of ground at an introductory level.

#### Language[#](/first-steps#language)

We're in love with [TypeScript](https://www.typescriptlang.org/), but above all - we love [Node.js](https://nodejs.org/en/). That's why Nest is compatible with both TypeScript and **pure JavaScript**. Nest takes advantage of the latest language features, so to use it with vanilla JavaScript we need a [Babel](https://babeljs.io/) compiler.

We'll mostly use TypeScript in the examples we provide, but you can always **switch the code snippets** to vanilla JavaScript syntax (simply click to toggle the language button in the upper right hand corner of each snippet).

#### Prerequisites[#](/first-steps#prerequisites)

Please make sure that [Node.js](https://nodejs.org) (version >= 12, except for v13) is installed on your operating system.

#### Setup[#](/first-steps#setup)

Setting up a new project is quite simple with the [Nest CLI](/v9/cli/overview). With [npm](https://www.npmjs.com/) installed, you can create a new Nest project with the following commands in your OS terminal:

```bash

$ npm i -g @nestjs/cli
$ nest new project-name
```

> **Hint** To create a new project with TypeScript's [strict](https://www.typescriptlang.org/tsconfig#strict) mode enabled, pass the `--strict` flag to the `nest new` command.

| `app.controller.ts`      | A basic controller with a single route.                                                                             |
| ------------------------ | ------------------------------------------------------------------------------------------------------------------- |
| `app.controller.spec.ts` | The unit tests for the controller.                                                                                  |
| `app.module.ts`          | The root module of the application.                                                                                 |
| `app.service.ts`         | A basic service with a single method.                                                                               |
| `main.ts`                | The entry file of the application which uses the core function `NestFactory` to create a Nest application instance. |

The `main.ts` includes an async function, which will **bootstrap** our application:

main.ts

JS TS

```typescript

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  await app.listen(3000);
}
bootstrap();
```

```typescript

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  await app.listen(3000);
}
bootstrap();
```

To create a Nest application instance, we use the core `NestFactory` class. `NestFactory` exposes a few static methods that allow creating an application instance. The `create()` method returns an application object, which fulfills the `INestApplication` interface. This object provides a set of methods which are described in the coming chapters. In the `main.ts` example above, we simply start up our HTTP listener, which lets the application await inbound HTTP requests.

Note that a project scaffolded with the Nest CLI creates an initial project structure that encourages developers to follow the convention of keeping each module in its own dedicated directory.

> **Hint** By default, if any error happens while creating the application your app will exit with the code `1`. If you want to make it throw an error instead disable the option `abortOnError` (e.g., `NestFactory.create(AppModule, { abortOnError: false })`).

| `platform-express` | [Express](https://expressjs.com/) is a well-known minimalist web framework for node. It's a battle tested, production-ready library with lots of resources implemented by the community. The `@nestjs/platform-express` package is used by default. Many users are well served with Express, and need take no action to enable it. |
| ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `platform-fastify` | [Fastify](https://www.fastify.io/) is a high performance and low overhead framework highly focused on providing maximum efficiency and speed. Read how to use it [here](/v9/techniques/performance).                                                                                                                               |

Whichever platform is used, it exposes its own application interface. These are seen respectively as `NestExpressApplication` and `NestFastifyApplication`.

When you pass a type to the `NestFactory.create()` method, as in the example below, the `app` object will have methods available exclusively for that specific platform. Note, however, you don't **need** to specify a type **unless** you actually want to access the underlying platform API.

```typescript

const app = await NestFactory.create<NestExpressApplication>(AppModule);
```

#### Running the application[#](/first-steps#running-the-application)

Once the installation process is complete, you can run the following command at your OS command prompt to start the application listening for inbound HTTP requests:

```bash

$ npm run start
```

This command starts the app with the HTTP server listening on the port defined in the `src/main.ts` file. Once the application is running, open your browser and navigate to `http://localhost:3000/`. You should see the `Hello World!` message.

To watch for changes in your files, you can run the following command to start the application:

```bash

$ npm run start:dev
```

This command will watch your files, automatically recompiling and reloading the server.

----
url: https://docs.nestjs.com/v7/graphql/interfaces
----

* [Interfaces](https://docs.nestjs.com/v7/graphql/interfaces#interfaces)
* [Code first](https://docs.nestjs.com/v7/graphql/interfaces#code-first)
* [Schema first](https://docs.nestjs.com/v7/graphql/interfaces#schema-first)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/interfaces.md "Suggest Edits")

### Interfaces

Like many type systems, GraphQL supports interfaces. An **Interface** is an abstract type that includes a certain set of fields that a type must include to implement the interface (read more [here](https://graphql.org/learn/schema/#interfaces)).

#### Code first

When using the code first approach, you define a GraphQL interface by creating an abstract class annotated with the `@InterfaceType()` decorator exported from the `@nestjs/graphql`.

```typescript

import { Field, ID, InterfaceType } from '@nestjs/graphql';

@InterfaceType()
export abstract class Character {
  @Field(type => ID)
  id: string;

  @Field()
  name: string;
}
```

> **Warning** TypeScript interfaces cannot be used to define GraphQL interfaces.

This will result in generating the following part of the GraphQL schema in SDL:

```graphql

interface Character {
  id: ID!
  name: String!
}
```

Now, to implement the `Character` interface, use the `implements` key:

```typescript

@ObjectType({
  implements: () => [Character],
})
export class Human implements Character {
  id: string;
  name: string;
}
```

> **Hint** The `@ObjectType()` decorator is exported from the `@nestjs/graphql` package.

The default `resolveType()` function generated by the library extracts the type based on the value returned from the resolver method. This means that you must return class instances (you cannot return literal JavaScript objects).

To provide a customized `resolveType()` function, pass the `resolveType` property to the options object passed into the `@InterfaceType()` decorator, as follows:

```typescript

@InterfaceType({
  resolveType(book) {
    if (book.colors) {
      return ColoringBook;
    }
    return TextBook;
  },
})
export abstract class Book {
  @Field(type => ID)
  id: string;

  @Field()
  title: string;
}
```

#### Schema first

To define an interface in the schema first approach, simply create a GraphQL interface with SDL.

```graphql

interface Character {
  id: ID!
  name: String!
}
```

Then, you can use the typings generation feature (as shown in the [quick start]() chapter) to generate corresponding TypeScript definitions:

```typescript

export interface Character {
  id: string;
  name: string;
}
```

Interfaces require an extra `__resolveType` field in the resolver map to determine which type the interface should resolve to. Let's create a `CharactersResolver` class and define the `__resolveType` method:

```typescript

@Resolver('Character')
export class CharactersResolver {
  @ResolveField()
  __resolveType(value) {
    if ('age' in value) {
      return Person;
    }
    return null;
  }
}
```

> **Hint** All decorators are exported from the `@nestjs/graphql` package.

----
url: https://docs.nestjs.com/v8/faq/multiple-servers
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [HTTPS](https://docs.nestjs.com/v8/faq/multiple-servers#https)
* [Multiple simultaneous servers](https://docs.nestjs.com/v8/faq/multiple-servers#multiple-simultaneous-servers)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/faq/multiple-servers.md "Suggest Edits")

### HTTPS

To create an application that uses the HTTPS protocol, set the `httpsOptions` property in the options object passed to the `create()` method of the `NestFactory` class:

```typescript

const httpsOptions = {
  key: fs.readFileSync('./secrets/private-key.pem'),
  cert: fs.readFileSync('./secrets/public-certificate.pem'),
};
const app = await NestFactory.create(AppModule, {
  httpsOptions,
});
await app.listen(3000);
```

If you use the `FastifyAdapter`, create the application as follows:

```typescript

const app = await NestFactory.create<NestFastifyApplication>(
  AppModule,
  new FastifyAdapter({ https: httpsOptions }),
);
```

#### Multiple simultaneous servers[#](/faq/multiple-servers#multiple-simultaneous-servers)

The following recipe shows how to instantiate a Nest application that listens on multiple ports (for example, on a non-HTTPS port and an HTTPS port) simultaneously.

```typescript

const httpsOptions = {
  key: fs.readFileSync('./secrets/private-key.pem'),
  cert: fs.readFileSync('./secrets/public-certificate.pem'),
};

const server = express();
const app = await NestFactory.create(
  AppModule,
  new ExpressAdapter(server),
);
await app.init();

http.createServer(server).listen(3000);
https.createServer(httpsOptions, server).listen(443);
```

> **Hint** The `ExpressAdapter` is imported from the `@nestjs/platform-express` package. The `http` and `https` packages are native Node.js packages.

> **Warning** This recipe does not work with [GraphQL Subscriptions](/v8/graphql/subscriptions).

----
url: https://docs.nestjs.com/v7/graphql/field-middleware
----

* [Field middleware](https://docs.nestjs.com/v7/graphql/field-middleware#field-middleware)
* [Getting started](https://docs.nestjs.com/v7/graphql/field-middleware#getting-started)
* [Global field middleware](https://docs.nestjs.com/v7/graphql/field-middleware#global-field-middleware)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/field-middleware.md "Suggest Edits")

### Field middleware

> **Warning** This chapter applies only to the code first approach.

Field Middleware lets you run arbitrary code **before or after** a field is resolved. A field middleware can be used to convert the result of a field, validate the arguments of a field, or even check field-level roles (for example, required to access a target field for which a middleware function is executed).

You can connect multiple middleware functions to a field. In this case, they will be called sequentially along the chain where the previous middleware decides to call the next one. The order of the middleware functions in the `middleware` array is important. The first resolver is the "most-outer" layer, so it gets executed first and last (similarly to the `graphql-middleware` package). The second resolver is the "second-outer" layer, so it gets executed second and second to last.

#### Getting started[#](/graphql/field-middleware#getting-started)

Let's start off by creating a simple middleware that will log a field value before it's sent back to the client:

```typescript

import { FieldMiddleware, MiddlewareContext, NextFn } from '@nestjs/graphql';

const loggerMiddleware: FieldMiddleware = async (
  ctx: MiddlewareContext,
  next: NextFn,
) => {
  const value = await next();
  console.log(value);
  return value;
};
```

> **Hint** The `MiddlewareContext` is an object that consist of the same arguments that are normally received by the GraphQL resolver function (`{ source, args, context, info }`), while `NextFn` is a function that let you execute the next middleware in the stack (bound to this field) or the actual field resolver.

> **Warning** Field middleware functions cannot inject dependencies nor access Nest's DI container as they are designed to be very lightweight and shouldn't perform any potentially time-consuming operations (like retrieving data from the database). If you need to call external services/query data from the data source, you should do it in a guard/interceptor bounded to a root query/mutation handler and assign it to `context` object which you can access from within the field middleware (specifically, from the `MiddlewareContext` object).

Note that field middleware must match the `FieldMiddleware` interface. In the example above, we first run the `next()` function (which executes the actual field resolver and returns a field value) and then, we log this value to our terminal. Also, the value returned from the middleware function completely overrides the previous value and since we don't want to perform any changes, we simply return the original value.

With this in place, we can register our middleware directly in the `@Field()` decorator, as follows:

```typescript

@ObjectType()
export class Recipe {
  @Field({ middleware: [loggerMiddleware] })
  title: string;
}
```

Now whenever we request the `title` field of `Recipe` object type, the original field's value will be logged to the console.

> **Hint** To learn how you can implement a field-level permissions system with the use of [extensions](/v7/graphql/extensions) feature, check out this [section](/graphql/extensions#using-custom-metadata).

Also, as mentioned above, we can control the field's value from within the middleware function. For demonstration purposes, let's capitalise a recipe's title (if present):

```typescript

const value = await next();
return value?.toUpperCase();
```

In this case, every title will be automatically uppercased, when requested.

Likewise, you can bind a field middleware to a custom field resolver (a method annotated with the `@ResolveField()` decorator), as follows:

```typescript

@ResolveField(() => String, { middleware: [loggerMiddleware] })
title() {
  return 'Placeholder';
}
```

> **Warning** In case enhancers are enabled at the field resolver level ([read more](/graphl//other-features#execute-enhancers-at-the-field-resolver-level)), field middleware functions will run before any interceptors, guards, etc., **bounded to the method** (but after the root-level enhancers registered for query or mutation handlers).

#### Global field middleware[#](/graphql/field-middleware#global-field-middleware)

In addition to binding a middleware directly to a specific field, you can also register one or multiple middleware functions globally. In this case, they will be automatically connected to all fields of your object types.

```typescript

GraphQLModule.forRoot({
  autoSchemaFile: 'schema.gql',
  buildSchemaOptions: {
    fieldMiddleware: [loggerMiddleware],
  },
}),
```

> **Hint** Globally registered field middleware functions will be executed **before** locally registered ones (those bound directly to specific fields).

----
url: https://docs.nestjs.com/v7/techniques/mvc
----

* [Model-View-Controller](https://docs.nestjs.com/v7/techniques/mvc#model-view-controller)
* [Template rendering](https://docs.nestjs.com/v7/techniques/mvc#template-rendering)
* [Dynamic template rendering](https://docs.nestjs.com/v7/techniques/mvc#dynamic-template-rendering)
* [Example](https://docs.nestjs.com/v7/techniques/mvc#example)
* [Fastify](https://docs.nestjs.com/v7/techniques/mvc#fastify)
* [Example](https://docs.nestjs.com/v7/techniques/mvc#example-1)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/techniques/mvc.md "Suggest Edits")

### Model-View-Controller

Nest, by default, makes use of the [Express](https://github.com/expressjs/express) library under the hood. Hence, every technique for using the MVC (Model-View-Controller) pattern in Express applies to Nest as well.

First, let's scaffold a simple Nest application using the [CLI](https://github.com/nestjs/nest-cli) tool:

```bash

$ npm i -g @nestjs/cli
$ nest new project
```

In order to create an MVC app, we also need a [template engine](https://expressjs.com/en/guide/using-template-engines.html) to render our HTML views:

```bash

$ npm install --save hbs
```

We've used the `hbs` ([Handlebars](https://github.com/pillarjs/hbs#readme)) engine, though you can use whatever fits your requirements. Once the installation process is complete, we need to configure the express instance using the following code:

main.ts

JS TS

```typescript

import { NestFactory } from '@nestjs/core';
import { NestExpressApplication } from '@nestjs/platform-express';
import { join } from 'path';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create<NestExpressApplication>(
    AppModule,
  );

  app.useStaticAssets(join(__dirname, '..', 'public'));
  app.setBaseViewsDir(join(__dirname, '..', 'views'));
  app.setViewEngine('hbs');

  await app.listen(3000);
}
bootstrap();
```

```typescript

import { NestFactory } from '@nestjs/core';
import { join } from 'path';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(
    AppModule,
  );

  app.useStaticAssets(join(__dirname, '..', 'public'));
  app.setBaseViewsDir(join(__dirname, '..', 'views'));
  app.setViewEngine('hbs');

  await app.listen(3000);
}
bootstrap();
```

We told [Express](https://github.com/expressjs/express) that the `public` directory will be used for storing static assets, `views` will contain templates, and the `hbs` template engine should be used to render HTML output.

#### Template rendering[#](/techniques/mvc#template-rendering)

Now, let's create a `views` directory and `index.hbs` template inside it. In the template, we'll print a `message` passed from the controller:

```html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>App</title>
  </head>
  <body>
    {{ message }}
  </body>
</html>
```

Next, open the `app.controller` file and replace the `root()` method with the following code:

app.controller.ts

JS TS

```typescript

import { Get, Controller, Render } from '@nestjs/common';

@Controller()
export class AppController {
  @Get()
  @Render('index')
  root() {
    return { message: 'Hello world!' };
  }
}
```

In this code, we are specifying the template to use in the `@Render()` decorator, and the return value of the route handler method is passed to the template for rendering. Notice that the return value is an object with a property `message`, matching the `message` placeholder we created in the template.

While the application is running, open your browser and navigate to `http://localhost:3000`. You should see the `Hello world!` message.

#### Dynamic template rendering[#](/techniques/mvc#dynamic-template-rendering)

If the application logic must dynamically decide which template to render, then we should use the `@Res()` decorator, and supply the view name in our route handler, rather than in the `@Render()` decorator:

> **Hint** When Nest detects the `@Res()` decorator, it injects the library-specific `response` object. We can use this object to dynamically render the template. Learn more about the `response` object API [here](https://expressjs.com/en/api.html).

app.controller.ts

JS TS

```typescript

import { Get, Controller, Res, Render } from '@nestjs/common';
import { Response } from 'express';
import { AppService } from './app.service';

@Controller()
export class AppController {
  constructor(private appService: AppService) {}

  @Get()
  root(@Res() res: Response) {
    return res.render(
      this.appService.getViewName(),
      { message: 'Hello world!' },
    );
  }
}
```

#### Example[#](/techniques/mvc#example)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/15-mvc).

#### Fastify[#](/techniques/mvc#fastify)

As mentioned in this [chapter](/v7/techniques/performance), we are able to use any compatible HTTP provider together with Nest. One such library is [Fastify](https://github.com/fastify/fastify). In order to create an MVC application with Fastify, we have to install the following packages:

```bash

$ npm i --save fastify point-of-view handlebars
```

The next steps cover almost the same process used with Express, with minor differences specific to the platform. Once the installation process is complete, open the `main.ts` file and update its contents:

main.ts

JS TS

```typescript

import { NestFactory } from '@nestjs/core';
import { NestFastifyApplication, FastifyAdapter } from '@nestjs/platform-fastify';
import { AppModule } from './app.module';
import { join } from 'path';

async function bootstrap() {
  const app = await NestFactory.create<NestFastifyApplication>(
    AppModule,
    new FastifyAdapter(),
  );
  app.useStaticAssets({
    root: join(__dirname, '..', 'public'),
    prefix: '/public/',
  });
  app.setViewEngine({
    engine: {
      handlebars: require('handlebars'),
    },
    templates: join(__dirname, '..', 'views'),
  });
  await app.listen(3000);
}
bootstrap();
```

```typescript

import { NestFactory } from '@nestjs/core';
import { FastifyAdapter } from '@nestjs/platform-fastify';
import { AppModule } from './app.module';
import { join } from 'path';

async function bootstrap() {
  const app = await NestFactory.create(AppModule, new FastifyAdapter());
  app.useStaticAssets({
    root: join(__dirname, '..', 'public'),
    prefix: '/public/',
  });
  app.setViewEngine({
    engine: {
      handlebars: require('handlebars'),
    },
    templates: join(__dirname, '..', 'views'),
  });
  await app.listen(3000);
}
bootstrap();
```

The Fastify API is slightly different but the end result of those methods calls remains the same. One difference to notice with Fastify is that the template name passed into the `@Render()` decorator must include a file extension.

app.controller.ts

JS TS

```typescript

import { Get, Controller, Render } from '@nestjs/common';

@Controller()
export class AppController {
  @Get()
  @Render('index.hbs')
  root() {
    return { message: 'Hello world!' };
  }
}
```

While the application is running, open your browser and navigate to `http://localhost:3000`. You should see the `Hello world!` message.

#### Example[#](/techniques/mvc#example-1)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/17-mvc-fastify).

----
url: https://docs.nestjs.com/v8/fundamentals/testing
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Testing](https://docs.nestjs.com/v8/fundamentals/testing#testing)
* [Installation](https://docs.nestjs.com/v8/fundamentals/testing#installation)
* [Unit testing](https://docs.nestjs.com/v8/fundamentals/testing#unit-testing)
* [Testing utilities](https://docs.nestjs.com/v8/fundamentals/testing#testing-utilities)
* [Auto mocking](https://docs.nestjs.com/v8/fundamentals/testing#auto-mocking)
* [End-to-end testing](https://docs.nestjs.com/v8/fundamentals/testing#end-to-end-testing)
* [Overriding globally registered enhancers](https://docs.nestjs.com/v8/fundamentals/testing#overriding-globally-registered-enhancers)
* [Testing request-scoped instances](https://docs.nestjs.com/v8/fundamentals/testing#testing-request-scoped-instances)

```bash

$ npm i --save-dev @nestjs/testing
```

#### Unit testing[#](/fundamentals/testing#unit-testing)

In the following example, we test two classes: `CatsController` and `CatsService`. As mentioned, [Jest](https://github.com/facebook/jest) is provided as the default testing framework. It serves as a test-runner and also provides assert functions and test-double utilities that help with mocking, spying, etc. In the following basic test, we manually instantiate these classes, and ensure that the controller and service fulfill their API contract.

cats.controller.spec.ts

JS TS

```typescript

import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

describe('CatsController', () => {
  let catsController: CatsController;
  let catsService: CatsService;

  beforeEach(() => {
    catsService = new CatsService();
    catsController = new CatsController(catsService);
  });

  describe('findAll', () => {
    it('should return an array of cats', async () => {
      const result = ['test'];
      jest.spyOn(catsService, 'findAll').mockImplementation(() => result);

      expect(await catsController.findAll()).toBe(result);
    });
  });
});
```

```typescript

import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

describe('CatsController', () => {
  let catsController;
  let catsService;

  beforeEach(() => {
    catsService = new CatsService();
    catsController = new CatsController(catsService);
  });

  describe('findAll', () => {
    it('should return an array of cats', async () => {
      const result = ['test'];
      jest.spyOn(catsService, 'findAll').mockImplementation(() => result);

      expect(await catsController.findAll()).toBe(result);
    });
  });
});
```

> **Hint** Keep your test files located near the classes they test. Testing files should have a `.spec` or `.test` suffix.

Because the above sample is trivial, we aren't really testing anything Nest-specific. Indeed, we aren't even using dependency injection (notice that we pass an instance of `CatsService` to our `catsController`). This form of testing - where we manually instantiate the classes being tested - is often called **isolated testing** as it is independent from the framework. Let's introduce some more advanced capabilities that help you test applications that make more extensive use of Nest features.

#### Testing utilities[#](/fundamentals/testing#testing-utilities)

The `@nestjs/testing` package provides a set of utilities that enable a more robust testing process. Let's rewrite the previous example using the built-in `Test` class:

cats.controller.spec.ts

JS TS

```typescript

import { Test } from '@nestjs/testing';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

describe('CatsController', () => {
  let catsController: CatsController;
  let catsService: CatsService;

  beforeEach(async () => {
    const moduleRef = await Test.createTestingModule({
        controllers: [CatsController],
        providers: [CatsService],
      }).compile();

    catsService = moduleRef.get<CatsService>(CatsService);
    catsController = moduleRef.get<CatsController>(CatsController);
  });

  describe('findAll', () => {
    it('should return an array of cats', async () => {
      const result = ['test'];
      jest.spyOn(catsService, 'findAll').mockImplementation(() => result);

      expect(await catsController.findAll()).toBe(result);
    });
  });
});
```

```typescript

import { Test } from '@nestjs/testing';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

describe('CatsController', () => {
  let catsController;
  let catsService;

  beforeEach(async () => {
    const moduleRef = await Test.createTestingModule({
        controllers: [CatsController],
        providers: [CatsService],
      }).compile();

    catsService = moduleRef.get(CatsService);
    catsController = moduleRef.get(CatsController);
  });

  describe('findAll', () => {
    it('should return an array of cats', async () => {
      const result = ['test'];
      jest.spyOn(catsService, 'findAll').mockImplementation(() => result);

      expect(await catsController.findAll()).toBe(result);
    });
  });
});
```

The `Test` class is useful for providing an application execution context that essentially mocks the full Nest runtime, but gives you hooks that make it easy to manage class instances, including mocking and overriding. The `Test` class has a `createTestingModule()` method that takes a module metadata object as its argument (the same object you pass to the `@Module()` decorator). This method returns a `TestingModule` instance which in turn provides a few methods. For unit tests, the important one is the `compile()` method. This method bootstraps a module with its dependencies (similar to the way an application is bootstrapped in the conventional `main.ts` file using `NestFactory.create()`), and returns a module that is ready for testing.

> **Hint** The `compile()` method is **asynchronous** and therefore has to be awaited. Once the module is compiled you can retrieve any **static** instance it declares (controllers and providers) using the `get()` method.

`TestingModule` inherits from the [module reference](/v8/fundamentals/module-ref) class, and therefore its ability to dynamically resolve scoped providers (transient or request-scoped). Do this with the `resolve()` method (the `get()` method can only retrieve static instances).

```typescript

const moduleRef = await Test.createTestingModule({
  controllers: [CatsController],
  providers: [CatsService],
}).compile();

catsService = await moduleRef.resolve(CatsService);
```

> **Warning** The `resolve()` method returns a unique instance of the provider, from its own **DI container sub-tree**. Each sub-tree has a unique context identifier. Thus, if you call this method more than once and compare instance references, you will see that they are not equal.

> **Hint** Learn more about the module reference features [here](/v8/fundamentals/module-ref).

Instead of using the production version of any provider, you can override it with a [custom provider](/v8/fundamentals/custom-providers) for testing purposes. For example, you can mock a database service instead of connecting to a live database. We'll cover overrides in the next section, but they're available for unit tests as well.

```typescript

// ...
import { ModuleMocker, MockFunctionMetadata } from 'jest-mock';

const moduleMocker = new ModuleMocker(global);

describe('CatsController', () => {
  let controller: CatsController;

  beforeEach(async () => {
    const moduleRef = await Test.createTestingModule({
      controllers: [CatsController],
    })
    .useMocker((token) => {
      if (token === CatsService) {
        return { findAll: jest.fn().mockResolvedValue(results) };
      }
      if (typeof token === 'function') {
        const mockMetadata = moduleMocker.getMetadata(token) as MockFunctionMetadata<any, any>;
        const Mock = moduleMocker.generateFromMetadata(mockMetadata);
        return new Mock();
      }
    })
    .compile();
    
    controller = moduleRef.get(CatsController);
  });
});
```

> **Hint** A general mock factory, like `createMock` from [`@golevelup/ts-jest`](https://github.com/golevelup/nestjs/tree/master/packages/testing) can also be passed directly.

You can also retrieve these mocks out of the testing container as you normally would custom providers, `moduleRef.get(CatsService)`.

#### End-to-end testing[#](/fundamentals/testing#end-to-end-testing)

Unlike unit testing, which focuses on individual modules and classes, end-to-end (e2e) testing covers the interaction of classes and modules at a more aggregate level -- closer to the kind of interaction that end-users will have with the production system. As an application grows, it becomes hard to manually test the end-to-end behavior of each API endpoint. Automated end-to-end tests help us ensure that the overall behavior of the system is correct and meets project requirements. To perform e2e tests we use a similar configuration to the one we just covered in **unit testing**. In addition, Nest makes it easy to use the [Supertest](https://github.com/visionmedia/supertest) library to simulate HTTP requests.

cats.e2e-spec.ts

JS TS

```typescript

import * as request from 'supertest';
import { Test } from '@nestjs/testing';
import { CatsModule } from '../../src/cats/cats.module';
import { CatsService } from '../../src/cats/cats.service';
import { INestApplication } from '@nestjs/common';

describe('Cats', () => {
  let app: INestApplication;
  let catsService = { findAll: () => ['test'] };

  beforeAll(async () => {
    const moduleRef = await Test.createTestingModule({
      imports: [CatsModule],
    })
      .overrideProvider(CatsService)
      .useValue(catsService)
      .compile();

    app = moduleRef.createNestApplication();
    await app.init();
  });

  it(`/GET cats`, () => {
    return request(app.getHttpServer())
      .get('/cats')
      .expect(200)
      .expect({
        data: catsService.findAll(),
      });
  });

  afterAll(async () => {
    await app.close();
  });
});
```

```typescript

import * as request from 'supertest';
import { Test } from '@nestjs/testing';
import { CatsModule } from '../../src/cats/cats.module';
import { CatsService } from '../../src/cats/cats.service';
import { INestApplication } from '@nestjs/common';

describe('Cats', () => {
  let app: INestApplication;
  let catsService = { findAll: () => ['test'] };

  beforeAll(async () => {
    const moduleRef = await Test.createTestingModule({
      imports: [CatsModule],
    })
      .overrideProvider(CatsService)
      .useValue(catsService)
      .compile();

    app = moduleRef.createNestApplication();
    await app.init();
  });

  it(`/GET cats`, () => {
    return request(app.getHttpServer())
      .get('/cats')
      .expect(200)
      .expect({
        data: catsService.findAll(),
      });
  });

  afterAll(async () => {
    await app.close();
  });
});
```

> **Hint** If you're using [Fastify](/v8/techniques/performance) as your HTTP adapter, it requires a slightly different configuration, and has built-in testing capabilities:
>
> ```ts
>
> let app: NestFastifyApplication;
>
> beforeAll(async () => {
>   app = moduleRef.createNestApplication<NestFastifyApplication>(
>     new FastifyAdapter(),
>   );
>
>   await app.init();
>   await app.getHttpAdapter().getInstance().ready();
> });
>
> it(`/GET cats`, () => {
>   return app
>     .inject({
>       method: 'GET',
>       url: '/cats',
>     })
>     .then((result) => {
>       expect(result.statusCode).toEqual(200);
>       expect(result.payload).toEqual(/* expectedPayload */);
>     });
> });
>
> afterAll(async () => {
>   await app.close();
> });
> ```

|                            |                                                                                                                                                                                                                                                   |
| -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `createNestApplication()`  | Creates and returns a Nest application (`INestApplication` instance) based on the given module. Note that you must manually initialize the application using the `init()` method.                                                                 |
| `createNestMicroservice()` | Creates and returns a Nest microservice (`INestMicroservice` instance) based on the given module.                                                                                                                                                 |
| `get()`                    | Retrieves a static instance of a controller or provider (including guards, filters, etc.) available in the application context. Inherited from the [module reference](/fundamentals/module-ref) class.                                            |
| `resolve()`                | Retrieves a dynamically created scoped instance (request or transient) of a controller or provider (including guards, filters, etc.) available in the application context. Inherited from the [module reference](/fundamentals/module-ref) class. |
| `select()`                 | Navigates through the module's dependency graph; can be used to retrieve a specific instance from the selected module (used along with strict mode (`strict: true`) in `get()` method).                                                           |

> **Hint** Keep your e2e test files inside the `test` directory. The testing files should have a `.e2e-spec` suffix.

#### Overriding globally registered enhancers[#](/fundamentals/testing#overriding-globally-registered-enhancers)

If you have a globally registered guard (or pipe, interceptor, or filter), you need to take a few more steps to override that enhancer. To recap the original registration looks like this:

```typescript

providers: [
  {
    provide: APP_GUARD,
    useClass: JwtAuthGuard,
  },
],
```

This is registering the guard as a "multi"-provider through the `APP_*` token. To be able to replace the `JwtAuthGuard` here, the registration needs to use an existing provider in this slot:

```typescript

providers: [
  {
    provide: APP_GUARD,
    useExisting: JwtAuthGuard,
    // ^^^^^^^^ notice the use of 'useExisting' instead of 'useClass'
  },
  JwtAuthGuard,
],
```

> **Hint** Change the `useClass` to `useExisting` to reference a registered provider instead of having Nest instantiate it behind the token.

Now the `JwtAuthGuard` is visible to Nest as a regular provider that can be overridden when creating the `TestingModule`:

```typescript

const moduleRef = await Test.createTestingModule({
  imports: [AppModule],
})
  .overrideProvider(JwtAuthGuard)
  .useClass(MockAuthGuard)
  .compile();
```

Now all your tests will use the `MockAuthGuard` on every request.

#### Testing request-scoped instances[#](/fundamentals/testing#testing-request-scoped-instances)

[Request-scoped](/v8/fundamentals/injection-scopes) providers are created uniquely for each incoming **request**. The instance is garbage-collected after the request has completed processing. This poses a problem, because we can't access a dependency injection sub-tree generated specifically for a tested request.

We know (based on the sections above) that the `resolve()` method can be used to retrieve a dynamically instantiated class. Also, as described [here](https://docs.nestjs.com/fundamentals/module-ref#resolving-scoped-providers), we know we can pass a unique context identifier to control the lifecycle of a DI container sub-tree. How do we leverage this in a testing context?

The strategy is to generate a context identifier beforehand and force Nest to use this particular ID to create a sub-tree for all incoming requests. In this way we'll be able to retrieve instances created for a tested request.

To accomplish this, use `jest.spyOn()` on the `ContextIdFactory`:

```typescript

const contextId = ContextIdFactory.create();
jest
  .spyOn(ContextIdFactory, 'getByRequest')
  .mockImplementation(() => contextId);
```

Now we can use the `contextId` to access a single generated DI container sub-tree for any subsequent request.

```typescript

catsService = await moduleRef.resolve(CatsService, contextId);
```

----
url: https://docs.nestjs.com/v8/graphql/extensions
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Extensions](https://docs.nestjs.com/v8/graphql/extensions#extensions)
* [Adding custom metadata](https://docs.nestjs.com/v8/graphql/extensions#adding-custom-metadata)
* [Using custom metadata](https://docs.nestjs.com/v8/graphql/extensions#using-custom-metadata)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/extensions.md "Suggest Edits")

### Extensions

> **Warning** This chapter applies only to the code first approach.

Extensions is an **advanced, low-level feature** that lets you define arbitrary data in the types configuration. Attaching custom metadata to certain fields allows you to create more sophisticated, generic solutions. For example, with extensions, you can define field-level roles required to access particular fields. Such roles can be reflected at runtime to determine whether the caller has sufficient permissions to retrieve a specific field.

#### Adding custom metadata[#](/graphql/extensions#adding-custom-metadata)

To attach custom metadata for a field, use the `@Extensions()` decorator exported from the `@nestjs/graphql` package.

```typescript

@Field()
@Extensions({ role: Role.ADMIN })
password: string;
```

In the example above, we assigned the `role` metadata property the value of `Role.ADMIN`. `Role` is a simple TypeScript enum that groups all the user roles available in our system.

Note, in addition to setting metadata on fields, you can use the `@Extensions()` decorator at the class level and method level (e.g., on the query handler).

#### Using custom metadata[#](/graphql/extensions#using-custom-metadata)

Logic that leverages the custom metadata can be as complex as needed. For example, you can create a simple interceptor that stores/logs events per method invocation, or a [field middleware](/v8/graphql/field-middleware) that matches roles required to retrieve a field with the caller permissions (field-level permissions system).

For illustration purposes, let's define a `checkRoleMiddleware` that compares a user's role (hardcoded here) with a role required to access a target field:

```typescript

export const checkRoleMiddleware: FieldMiddleware = async (
  ctx: MiddlewareContext,
  next: NextFn,
) => {
  const { info } = ctx;
  const { extensions } = info.parentType.getFields()[info.fieldName];

  /**
   * In a real-world application, the "userRole" variable
   * should represent the caller's (user) role (for example, "ctx.user.role").
   */
  const userRole = Role.USER;
  if (userRole === extensions.role) {
    // or just "return null" to ignore
    throw new ForbiddenException(
      `User does not have sufficient permissions to access "${info.fieldName}" field.`,
    );
  }
  return next();
};
```

With this in place, we can register a middleware for the `password` field, as follows:

```typescript

@Field({ middleware: [checkRoleMiddleware] })
@Extensions({ role: Role.ADMIN })
password: string;
```

----
url: https://docs.nestjs.com/v8/recipes/serve-static
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Serve Static](https://docs.nestjs.com/v8/recipes/serve-static#serve-static)
* [Installation](https://docs.nestjs.com/v8/recipes/serve-static#installation)
* [Bootstrap](https://docs.nestjs.com/v8/recipes/serve-static#bootstrap)
* [Configuration](https://docs.nestjs.com/v8/recipes/serve-static#configuration)
* [Example](https://docs.nestjs.com/v8/recipes/serve-static#example)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/recipes/serve-static.md "Suggest Edits")

### Serve Static

In order to serve static content like a Single Page Application (SPA) we can use the `ServeStaticModule` from the [`@nestjs/serve-static`](https://www.npmjs.com/package/@nestjs/serve-static) package.

#### Installation[#](/recipes/serve-static#installation)

First we need to install the required package:

```bash

$ npm install --save @nestjs/serve-static
```

#### Bootstrap[#](/recipes/serve-static#bootstrap)

Once the installation process is done, we can import the `ServeStaticModule` into the root `AppModule` and configure it by passing in a configuration object to the `forRoot()` method.

```typescript

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { ServeStaticModule } from '@nestjs/serve-static';
import { join } from 'path';

@Module({
  imports: [
    ServeStaticModule.forRoot({
      rootPath: join(__dirname, '..', 'client'),
    }),
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}
```

With this in place, build the static website and place its content in the location specified by the `rootPath` property.

#### Configuration[#](/recipes/serve-static#configuration)

[ServeStaticModule](https://github.com/nestjs/serve-static) can be configured with a variety of options to customize its behavior. You can set the path to render your static app, specify excluded paths, enable or disable setting Cache-Control response header, etc. See the full list of options [here](https://github.com/nestjs/serve-static/blob/master/lib/interfaces/serve-static-options.interface.ts).

> **Notice** The default `renderPath` of the Static App is `*` (all paths), and the module will send "index.html" files in response. It lets you create Client-Side routing for your SPA. Paths, specified in your controllers will fallback to the server. You can change this behavior setting `serveRoot`, `renderPath` combining them with other options.

#### Example[#](/recipes/serve-static#example)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/24-serve-static).

----
url: https://docs.nestjs.com/v7/exception-filters
----

* [Exception filters](https://docs.nestjs.com/v7/exception-filters#exception-filters)
* [Throwing standard exceptions](https://docs.nestjs.com/v7/exception-filters#throwing-standard-exceptions)
* [Custom exceptions](https://docs.nestjs.com/v7/exception-filters#custom-exceptions)
* [Built-in HTTP exceptions](https://docs.nestjs.com/v7/exception-filters#built-in-http-exceptions)
* [Exception filters](https://docs.nestjs.com/v7/exception-filters#exception-filters-1)
* [Arguments host](https://docs.nestjs.com/v7/exception-filters#arguments-host)
* [Binding filters](https://docs.nestjs.com/v7/exception-filters#binding-filters)
* [Catch everything](https://docs.nestjs.com/v7/exception-filters#catch-everything)
* [Inheritance](https://docs.nestjs.com/v7/exception-filters#inheritance)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/exception-filters.md "Suggest Edits")

### Exception filters

Nest comes with a built-in **exceptions layer** which is responsible for processing all unhandled exceptions across an application. When an exception is not handled by your application code, it is caught by this layer, which then automatically sends an appropriate user-friendly response.

Out of the box, this action is performed by a built-in **global exception filter**, which handles exceptions of type `HttpException` (and subclasses of it). When an exception is **unrecognized** (is neither `HttpException` nor a class that inherits from `HttpException`), the built-in exception filter generates the following default JSON response:

```json

{
  "statusCode": 500,
  "message": "Internal server error"
}
```

#### Throwing standard exceptions[#](/exception-filters#throwing-standard-exceptions)

Nest provides a built-in `HttpException` class, exposed from the `@nestjs/common` package. For typical HTTP REST/GraphQL API based applications, it's best practice to send standard HTTP response objects when certain error conditions occur.

For example, in the `CatsController`, we have a `findAll()` method (a `GET` route handler). Let's assume that this route handler throws an exception for some reason. To demonstrate this, we'll hard-code it as follows:

cats.controller.ts

JS TS

```typescript

@Get()
async findAll() {
  throw new HttpException('Forbidden', HttpStatus.FORBIDDEN);
}
```

> **Hint** We used the `HttpStatus` here. This is a helper enum imported from the `@nestjs/common` package.

When the client calls this endpoint, the response looks like this:

```json

{
  "statusCode": 403,
  "message": "Forbidden"
}
```

```typescript

@Get()
async findAll() {
  throw new HttpException({
    status: HttpStatus.FORBIDDEN,
    error: 'This is a custom message',
  }, HttpStatus.FORBIDDEN);
}
```

Using the above, this is how the response would look:

```json

{
  "status": 403,
  "error": "This is a custom message"
}
```

#### Custom exceptions[#](/exception-filters#custom-exceptions)

In many cases, you will not need to write custom exceptions, and can use the built-in Nest HTTP exception, as described in the next section. If you do need to create customized exceptions, it's good practice to create your own **exceptions hierarchy**, where your custom exceptions inherit from the base `HttpException` class. With this approach, Nest will recognize your exceptions, and automatically take care of the error responses. Let's implement such a custom exception:

forbidden.exception.ts

JS TS

```typescript

export class ForbiddenException extends HttpException {
  constructor() {
    super('Forbidden', HttpStatus.FORBIDDEN);
  }
}
```

Since `ForbiddenException` extends the base `HttpException`, it will work seamlessly with the built-in exception handler, and therefore we can use it inside the `findAll()` method.

cats.controller.ts

JS TS

```typescript

@Get()
async findAll() {
  throw new ForbiddenException();
}
```

```typescript

import { ExceptionFilter, Catch, ArgumentsHost, HttpException } from '@nestjs/common';
import { Request, Response } from 'express';

@Catch(HttpException)
export class HttpExceptionFilter implements ExceptionFilter {
  catch(exception: HttpException, host: ArgumentsHost) {
    const ctx = host.switchToHttp();
    const response = ctx.getResponse<Response>();
    const request = ctx.getRequest<Request>();
    const status = exception.getStatus();

    response
      .status(status)
      .json({
        statusCode: status,
        timestamp: new Date().toISOString(),
        path: request.url,
      });
  }
}
```

```typescript

import { Catch, HttpException } from '@nestjs/common';

@Catch(HttpException)
export class HttpExceptionFilter {
  catch(exception, host) {
    const ctx = host.switchToHttp();
    const response = ctx.getResponse();
    const request = ctx.getRequest();
    const status = exception.getStatus();

    response
      .status(status)
      .json({
        statusCode: status,
        timestamp: new Date().toISOString(),
        path: request.url,
      });
  }
}
```

> **Hint** All exception filters should implement the generic `ExceptionFilter<T>` interface. This requires you to provide the `catch(exception: T, host: ArgumentsHost)` method with its indicated signature. `T` indicates the type of the exception.

The `@Catch(HttpException)` decorator binds the required metadata to the exception filter, telling Nest that this particular filter is looking for exceptions of type `HttpException` and nothing else. The `@Catch()` decorator may take a single parameter, or a comma-separated list. This lets you set up the filter for several types of exceptions at once.

#### Arguments host[#](/exception-filters#arguments-host)

Let's look at the parameters of the `catch()` method. The `exception` parameter is the exception object currently being processed. The `host` parameter is an `ArgumentsHost` object. `ArgumentsHost` is a powerful utility object that we'll examine further in the [execution context chapter](/v7/fundamentals/execution-context)\*. In this code sample, we use it to obtain a reference to the `Request` and `Response` objects that are being passed to the original request handler (in the controller where the exception originates). In this code sample, we've used some helper methods on `ArgumentsHost` to get the desired `Request` and `Response` objects. Learn more about `ArgumentsHost`[here](/v7/fundamentals/execution-context).

```typescript

@Post()
@UseFilters(new HttpExceptionFilter())
async create(@Body() createCatDto: CreateCatDto) {
  throw new ForbiddenException();
}
```

```typescript

@Post()
@UseFilters(new HttpExceptionFilter())
@Bind(Body())
async create(createCatDto) {
  throw new ForbiddenException();
}
```

> **Hint** The `@UseFilters()` decorator is imported from the `@nestjs/common` package.

We have used the `@UseFilters()` decorator here. Similar to the `@Catch()` decorator, it can take a single filter instance, or a comma-separated list of filter instances. Here, we created the instance of `HttpExceptionFilter` in place. Alternatively, you may pass the class (instead of an instance), leaving responsibility for instantiation to the framework, and enabling **dependency injection**.

cats.controller.ts

JS TS

```typescript

@Post()
@UseFilters(HttpExceptionFilter)
async create(@Body() createCatDto: CreateCatDto) {
  throw new ForbiddenException();
}
```

```typescript

@Post()
@UseFilters(HttpExceptionFilter)
@Bind(Body())
async create(createCatDto) {
  throw new ForbiddenException();
}
```

> **Hint** Prefer applying filters by using classes instead of instances when possible. It reduces **memory usage** since Nest can easily reuse instances of the same class across your entire module.

In the example above, the `HttpExceptionFilter` is applied only to the single `create()` route handler, making it method-scoped. Exception filters can be scoped at different levels: method-scoped, controller-scoped, or global-scoped. For example, to set up a filter as controller-scoped, you would do the following:

cats.controller.ts

JS TS

```typescript

@UseFilters(new HttpExceptionFilter())
export class CatsController {}
```

This construction sets up the `HttpExceptionFilter` for every route handler defined inside the `CatsController`.

To create a global-scoped filter, you would do the following:

main.ts

JS TS

```typescript

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.useGlobalFilters(new HttpExceptionFilter());
  await app.listen(3000);
}
bootstrap();
```

> **Warning** The `useGlobalFilters()` method does not set up filters for gateways or hybrid applications.

Global-scoped filters are used across the whole application, for every controller and every route handler. In terms of dependency injection, global filters registered from outside of any module (with `useGlobalFilters()` as in the example above) cannot inject dependencies since this is done outside the context of any module. In order to solve this issue, you can register a global-scoped filter **directly from any module** using the following construction:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { APP_FILTER } from '@nestjs/core';

@Module({
  providers: [
    {
      provide: APP_FILTER,
      useClass: HttpExceptionFilter,
    },
  ],
})
export class AppModule {}
```

> **Hint** When using this approach to perform dependency injection for the filter, note that regardless of the module where this construction is employed, the filter is, in fact, global. Where should this be done? Choose the module where the filter (`HttpExceptionFilter` in the example above) is defined. Also, `useClass` is not the only way of dealing with custom provider registration. Learn more [here](/v7/fundamentals/custom-providers).

You can add as many filters with this technique as needed; simply add each to the providers array.

#### Catch everything[#](/exception-filters#catch-everything)

In order to catch **every** unhandled exception (regardless of the exception type), leave the `@Catch()` decorator's parameter list empty, e.g., `@Catch()`.

```typescript

import {
  ExceptionFilter,
  Catch,
  ArgumentsHost,
  HttpException,
  HttpStatus,
} from '@nestjs/common';

@Catch()
export class AllExceptionsFilter implements ExceptionFilter {
  catch(exception: unknown, host: ArgumentsHost) {
    const ctx = host.switchToHttp();
    const response = ctx.getResponse();
    const request = ctx.getRequest();

    const status =
      exception instanceof HttpException
        ? exception.getStatus()
        : HttpStatus.INTERNAL_SERVER_ERROR;

    response.status(status).json({
      statusCode: status,
      timestamp: new Date().toISOString(),
      path: request.url,
    });
  }
}
```

In the example above the filter will catch each exception thrown, regardless of its type (class).

#### Inheritance[#](/exception-filters#inheritance)

Typically, you'll create fully customized exception filters crafted to fulfill your application requirements. However, there might be use-cases when you would like to simply extend the built-in default **global exception filter**, and override the behavior based on certain factors.

In order to delegate exception processing to the base filter, you need to extend `BaseExceptionFilter` and call the inherited `catch()` method.

all-exceptions.filter.ts

JS TS

```typescript

import { Catch, ArgumentsHost } from '@nestjs/common';
import { BaseExceptionFilter } from '@nestjs/core';

@Catch()
export class AllExceptionsFilter extends BaseExceptionFilter {
  catch(exception: unknown, host: ArgumentsHost) {
    super.catch(exception, host);
  }
}
```

```typescript

import { Catch } from '@nestjs/common';
import { BaseExceptionFilter } from '@nestjs/core';

@Catch()
export class AllExceptionsFilter extends BaseExceptionFilter {
  catch(exception, host) {
    super.catch(exception, host);
  }
}
```

> **Warning** Method-scoped and Controller-scoped filters that extend the `BaseExceptionFilter` should not be instantiated with `new`. Instead, let the framework instantiate them automatically.

The above implementation is just a shell demonstrating the approach. Your implementation of the extended exception filter would include your tailored **business** logic (e.g., handling various conditions).

Global filters **can** extend the base filter. This can be done in either of two ways.

The first method is to inject the `HttpServer` reference when instantiating the custom global filter:

```typescript

async function bootstrap() {
  const app = await NestFactory.create(AppModule);

  const { httpAdapter } = app.get(HttpAdapterHost);
  app.useGlobalFilters(new AllExceptionsFilter(httpAdapter));

  await app.listen(3000);
}
bootstrap();
```

The second method is to use the `APP_FILTER` token [as shown here](exception-filters#binding-filters).

----
url: https://docs.nestjs.com/openapi/cli-plugin
----

[Skip to content](#content)

On this page

* [CLI Plugin](https://docs.nestjs.com/openapi/cli-plugin#cli-plugin)
* [Overview](https://docs.nestjs.com/openapi/cli-plugin#overview)
* [Comments introspection](https://docs.nestjs.com/openapi/cli-plugin#comments-introspection)
* [Using the CLI plugin](https://docs.nestjs.com/openapi/cli-plugin#using-the-cli-plugin)
* [SWC builder](https://docs.nestjs.com/openapi/cli-plugin#swc-builder)
* [Integration with ts-jest (e2e tests)](https://docs.nestjs.com/openapi/cli-plugin#integration-with-ts-jest-e2e-tests)
* [Troubleshooting jest (e2e tests)](https://docs.nestjs.com/openapi/cli-plugin#troubleshooting-jest-e2e-tests)

### CLI Plugin

[TypeScript](https://www.typescriptlang.org/docs/handbook/decorators.html)'s metadata reflection system has several limitations. For instance, it can't determine which properties a class consists of, or whether a given property is optional or required. However, some of these constraints can be addressed at compile time. Nest provides a plugin that enhances the TypeScript compilation process to reduce the amount of boilerplate code required.

> **Hint** This plugin is **opt-in**. If you prefer, you can declare all decorators manually, or only specific decorators where you need them.

#### Overview[#](/openapi/cli-plugin#overview)

The Swagger plugin automatically:

* annotates all DTO properties with `@ApiProperty()`, unless `@ApiHideProperty()` is used
* sets the `required` property depending on the question mark (e.g., `name?: string` sets `required: false`)
* sets the `type` or `enum` property depending on the type (arrays are supported as well)
* sets the `default` property based on the assigned default value
* sets several validation rules based on `class-validator` decorators (if `classValidatorShim` is set to `true`)
* adds a response decorator to every endpoint with a proper status and `type` (response model)
* generates descriptions for properties and endpoints based on comments (if `introspectComments` is set to `true`)
* generates example values for properties based on comments (if `introspectComments` is set to `true`)

For the plugin to analyze a DTO file, its filename **must have** one of the following suffixes: `['.dto.ts', '.entity.ts']` (e.g., `create-user.dto.ts`).

If you use a different suffix, adjust the plugin's behavior with the `dtoFileNameSuffix` option (see below).

Without the plugin, providing an interactive experience with the Swagger UI means duplicating a lot of code to tell the package how your models/components should be declared in the specification. For example, you could define a simple `CreateUserDto` class as follows:

```typescript

export class CreateUserDto {
  @ApiProperty()
  email: string;

  @ApiProperty()
  password: string;

  @ApiProperty({ enum: RoleEnum, default: [], isArray: true })
  roles: RoleEnum[] = [];

  @ApiProperty({ required: false, default: true })
  isEnabled?: boolean = true;
}
```

While not a significant issue in medium-sized projects, this becomes verbose and hard to maintain once you have a large set of classes.

With the [Swagger plugin enabled](/openapi/cli-plugin#using-the-cli-plugin), you can declare the class above without any decorators:

```typescript

export class CreateUserDto {
  email: string;
  password: string;
  roles: RoleEnum[] = [];
  isEnabled?: boolean = true;
}
```

> **Note** The Swagger plugin derives the `@ApiProperty()` annotations from the TypeScript types and `class-validator` decorators, which describe your API in the generated Swagger UI documentation. Runtime validation, however, is still handled by the `class-validator` decorators, so you must keep using validators like `IsEmail()`, `IsNumber()`, etc.

In other words, if you rely on automatic annotations for the documentation and still want runtime validation, you still need the `class-validator` decorators.

> **Hint** When you use [mapped type utilities](/openapi/mapped-types) (like `PartialType`) in DTOs, import them from `@nestjs/swagger` instead of `@nestjs/mapped-types` so that the plugin picks up the schema.

The plugin adds the appropriate decorators on the fly, based on the **Abstract Syntax Tree**, so you don't have to scatter `@ApiProperty()` decorators throughout the code.

> **Hint** The plugin generates any missing Swagger properties. To override one, set it explicitly via `@ApiProperty()`.

#### Comments introspection[#](/openapi/cli-plugin#comments-introspection)

With the comments introspection feature enabled, the CLI plugin generates descriptions and example values for properties based on comments.

For example, consider a `roles` property:

```typescript

/**
 * A list of user's roles
 * @example ['admin']
 */
@ApiProperty({
  description: `A list of user's roles`,
  example: ['admin'],
})
roles: RoleEnum[] = [];
```

You must duplicate both the description and the example values. With `introspectComments` enabled, the CLI plugin extracts these comments and provides descriptions (and examples, if defined) for properties automatically. The property above can then be declared as follows:

```typescript

/**
 * A list of user's roles
 * @example ['admin']
 */
roles: RoleEnum[] = [];
```

The `dtoKeyOfComment` and `controllerKeyOfComment` plugin options customize how the plugin assigns comment values to the `ApiProperty` and `ApiOperation` decorators, respectively. See the example below:

```typescript

export class SomeController {
  /**
   * Create some resource
   */
  @Post()
  create() {}
}
```

This is equivalent to the following:

```typescript

@ApiOperation({ summary: "Create some resource" })
```

> **Hint** For models, the same logic applies, but with the `ApiProperty` decorator instead.

For controllers, you can provide not only a summary but also a description (remarks), tags (such as `@deprecated`), and response examples, like this:

```ts

/**
 * Create a new cat
 *
 * @remarks This operation allows you to create a new cat.
 *
 * @deprecated
 * @throws {500} Something went wrong.
 * @throws {400} Bad Request.
 */
@Post()
async create(): Promise<Cat> {}
```

As of `@nestjs/swagger` v12, the plugin (with `introspectComments` enabled) picks up `@param` tags as well, so route parameter descriptions can come from the same doc comment:

```ts

/**
 * List cats
 *
 * @param breed Filter results by breed
 * @param limit Maximum number of results to return
 */
@Get()
findAll(@Query('breed') breed?: string, @Query('limit') limit?: number) {}
```

The plugin adds a `description` to the `@ApiQuery()` it already generates for optional `@Query()` parameters, generates `@ApiQuery({ name, description })` for documented required query parameters, and generates `@ApiParam({ name, description })` for documented `@Param()` parameters.

Descriptions are matched by the **variable name**, which is what `@param` documents. So `@Query('order_by') orderBy: string` is documented as `@param orderBy ...`, not `@param order_by ...`. Explicit `@ApiQuery()` / `@ApiParam()` decorators always take precedence and are never overwritten.

#### Using the CLI plugin[#](/openapi/cli-plugin#using-the-cli-plugin)

To enable the plugin, open `nest-cli.json` (if you use [Nest CLI](/cli/overview)) and add the following `plugins` configuration:

```javascript

{
  "collection": "@nestjs/schematics",
  "sourceRoot": "src",
  "compilerOptions": {
    "plugins": ["@nestjs/swagger"]
  }
}
```

Use the `options` property to customize the behavior of the plugin:

```javascript

{
  "collection": "@nestjs/schematics",
  "sourceRoot": "src",
  "compilerOptions": {
    "plugins": [
      {
        "name": "@nestjs/swagger",
        "options": {
          "classValidatorShim": false,
          "introspectComments": true,
          "skipAutoHttpCode": true
        }
      }
    ]
  }
}
```

The `options` property accepts the following options (among others):

```typescript

export interface PluginOptions {
  dtoFileNameSuffix?: string | string[];
  controllerFileNameSuffix?: string | string[];
  classValidatorShim?: boolean;
  classTransformerShim?: boolean | 'exclusive';
  dtoKeyOfComment?: string;
  controllerKeyOfComment?: string;
  introspectComments?: boolean;
  skipAutoHttpCode?: boolean;
  skipDefaultValues?: boolean;
  autoFillEnumName?: boolean;
  esmCompatible?: boolean;
}
```

| Option                     | Default                     | Description                                                                                                                                                                                           |
| -------------------------- | --------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `dtoFileNameSuffix`        | `['.dto.ts', '.entity.ts']` | DTO (Data Transfer Object) files suffix                                                                                                                                                               |
| `controllerFileNameSuffix` | `['.controller.ts']`        | Controller files suffix                                                                                                                                                                               |
| `classValidatorShim`       | `true`                      | If set to `true`, the plugin reuses `class-validator` validation decorators (e.g., `@Max(10)` adds `max: 10` to the schema definition)                                                                |
| `classTransformerShim`     | `false`                     | If set to `true`, the plugin skips properties decorated with `class-transformer`'s `@Exclude()`. If set to `'exclusive'`, it documents only properties decorated with `@Expose()` or `@ApiProperty()` |
| `dtoKeyOfComment`          | `'description'`             | The property key to set the comment text to on `ApiProperty`.                                                                                                                                         |
| `controllerKeyOfComment`   | `'summary'`                 | The property key to set the comment text to on `ApiOperation`.                                                                                                                                        |
| `introspectComments`       | `false`                     | If set to `true`, the plugin generates descriptions and example values for properties based on comments                                                                                               |
| `skipAutoHttpCode`         | `false`                     | Disables the automatic addition of `@HttpCode()` in controllers                                                                                                                                       |
| `skipDefaultValues`        | `false`                     | If set to `true`, the plugin doesn't set the `default` property from property initializers                                                                                                            |
| `autoFillEnumName`         | `false`                     | If set to `true`, the plugin sets `enumName` to the name of the enum type for enum properties that don't declare one                                                                                  |
| `esmCompatible`            | Detected per file           | Makes the generated code compatible with ESM (`{ "type": "module" }`). When omitted, the plugin detects whether each file is emitted as ESM from your compiler options and `package.json`             |

Delete the `/dist` folder and rebuild your application whenever you update plugin options.

If you don't use the CLI but have a custom `webpack` configuration instead, you can use this plugin in combination with `ts-loader`:

```javascript

getCustomTransformers: (program: any) => ({
  before: [require('@nestjs/swagger/plugin').before({}, program)]
}),
```

#### SWC builder[#](/openapi/cli-plugin#swc-builder)

For standard (non-monorepo) setups, using CLI plugins with the SWC builder requires type checking to be enabled, as described in the [SWC recipe](/recipes/swc#type-checking).

```bash

$ nest start -b swc --type-check
```

For monorepo setups, follow the [monorepo and CLI plugins](/recipes/swc#monorepo-and-cli-plugins) instructions to create a `generate-metadata.ts` file, and then run it:

```bash

$ npx ts-node src/generate-metadata.ts
# OR npx ts-node apps/{YOUR_APP}/src/generate-metadata.ts
```

Then load the serialized metadata file with the `SwaggerModule#loadPluginMetadata()` method, as shown below:

```typescript

import metadata from './metadata.js'; // <-- file auto-generated by the "PluginMetadataGenerator"

await SwaggerModule.loadPluginMetadata(metadata); // <-- here
const document = SwaggerModule.createDocument(app, config);
```

#### Integration with `ts-jest` (e2e tests)[#](/openapi/cli-plugin#integration-with-ts-jest-e2e-tests)

To run e2e tests, `ts-jest` compiles your source code files on the fly, in memory. This means it doesn't use the Nest CLI compiler, and it doesn't apply any plugins or perform AST transformations.

To enable the plugin, create the following file in your e2e tests directory:

```javascript

const transformer = require('@nestjs/swagger/plugin');

module.exports.name = 'nestjs-swagger-transformer';
// you should change the version number anytime you change the configuration below - otherwise, jest will not detect changes
module.exports.version = 1;

module.exports.factory = (cs) => {
  return transformer.before(
    {
      // @nestjs/swagger/plugin options (can be empty)
    },
    cs.program, // "cs.tsCompiler.program" for older versions of Jest (<= v27)
  );
};
```

With this in place, import the AST transformer in your `jest` configuration file. By default (in the starter application), the e2e test configuration file is located in the `test` folder and is named `jest-e2e.json`.

If you use `jest@<29`, use the snippet below:

```json

{
  ... // other configuration
  "globals": {
    "ts-jest": {
      "astTransformers": {
        "before": ["<path to the file created above>"]
      }
    }
  }
}
```

If you use `jest@^29`, use the snippet below instead, because the previous approach is deprecated:

```json

{
  ... // other configuration
  "transform": {
    "^.+\\.(t|j)s$": [
      "ts-jest",
      {
        "astTransformers": {
          "before": ["<path to the file created above>"]
        }
      }
    ]
  }
}
```

#### Troubleshooting `jest` (e2e tests)[#](/openapi/cli-plugin#troubleshooting-jest-e2e-tests)

If `jest` doesn't seem to pick up your configuration changes, Jest may have **cached** the build result. To apply the new configuration, clear Jest's cache directory by running the following command in your NestJS project folder:

```bash

$ npx jest --clearCache
```

If the automatic cache clearance fails, remove the cache folder manually with the following commands:

```bash

# Find jest cache directory (usually /tmp/jest_rs)
# by running the following command in your NestJS project root
$ npx jest --showConfig | grep cache
# ex result:
#   "cache": true,
#   "cacheDirectory": "/tmp/jest_rs"

# Remove or empty the Jest cache directory
$ rm -rf  <cacheDirectory value>
# ex:
# rm -rf /tmp/jest_rs
```

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/openapi/cli-plugin.md)

----
url: https://docs.nestjs.com/v9/cli/overview
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Overview](https://docs.nestjs.com/v9/cli/overview#overview)
* [Installation](https://docs.nestjs.com/v9/cli/overview#installation)
* [Basic workflow](https://docs.nestjs.com/v9/cli/overview#basic-workflow)
* [Project structure](https://docs.nestjs.com/v9/cli/overview#project-structure)
* [CLI command syntax](https://docs.nestjs.com/v9/cli/overview#cli-command-syntax)
* [Command overview](https://docs.nestjs.com/v9/cli/overview#command-overview)
* [Requirements](https://docs.nestjs.com/v9/cli/overview#requirements)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/cli/overview.md "Suggest Edits")

### Overview

The [Nest CLI](https://github.com/nestjs/nest-cli) is a command-line interface tool that helps you to initialize, develop, and maintain your Nest applications. It assists in multiple ways, including scaffolding the project, serving it in development mode, and building and bundling the application for production distribution. It embodies best-practice architectural patterns to encourage well-structured apps.

#### Installation[#](/cli/overview#installation)

**Note**: In this guide we describe using [npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm) to install packages, including the Nest CLI. Other package managers may be used at your discretion. With npm, you have several options available for managing how your OS command line resolves the location of the `nest` CLI binary file. Here, we describe installing the `nest` binary globally using the `-g` option. This provides a measure of convenience, and is the approach we assume throughout the documentation. Note that installing **any**`npm` package globally leaves the responsibility of ensuring they're running the correct version up to the user. It also means that if you have different projects, each will run the **same** version of the CLI. A reasonable alternative is to use the [npx](https://github.com/npm/cli/blob/latest/docs/lib/content/commands/npx.md) program, built into the `npm` cli (or similar features with other package managers) to ensure that you run a **managed version** of the Nest CLI. We recommend you consult the [npx documentation](https://github.com/npm/cli/blob/latest/docs/lib/content/commands/npx.md) and/or your DevOps support staff for more information.

Install the CLI globally using the `npm install -g` command (see the **Note** above for details about global installs).

```bash

$ npm install -g @nestjs/cli
```

> **Hint** Alternatively, you can use this command `npx @nestjs/cli@latest` without installing the cli globally.

#### Basic workflow[#](/cli/overview#basic-workflow)

Once installed, you can invoke CLI commands directly from your OS command line through the `nest` executable. See the available `nest` commands by entering the following:

```bash

$ nest --help
```

Get help on an individual command using the following construct. Substitute any command, like `new`, `add`, etc., where you see `generate` in the example below to get detailed help on that command:

```bash

$ nest generate --help
```

To create, build and run a new basic Nest project in development mode, go to the folder that should be the parent of your new project, and run the following commands:

```bash

$ nest new my-nest-project
$ cd my-nest-project
$ npm run start:dev
```

In your browser, open <http://localhost:3000> to see the new application running. The app will automatically recompile and reload when you change any of the source files.

#### Project structure[#](/cli/overview#project-structure)

When you run `nest new`, Nest generates a boilerplate application structure by creating a new folder and populating an initial set of files. You can continue working in this default structure, adding new components, as described throughout this documentation. We refer to the project structure generated by `nest new` as **standard mode**. Nest also supports an alternate structure for managing multiple projects and libraries called **monorepo mode**.

Aside from a few specific considerations around how the **build** process works (essentially, monorepo mode simplifies build complexities that can sometimes arise from monorepo-style project structures), and built-in [library](/v9/cli/libraries) support, the rest of the Nest features, and this documentation, apply equally to both standard and monorepo mode project structures. In fact, you can easily switch from standard mode to monorepo mode at any time in the future, so you can safely defer this decision while you're still learning about Nest.

You can use either mode to manage multiple projects. Here's a quick summary of the differences:

| Feature                                               | Standard Mode                                                      | Monorepo Mode                                              |
| ----------------------------------------------------- | ------------------------------------------------------------------ | ---------------------------------------------------------- |
| Multiple projects                                     | Separate file system structure                                     | Single file system structure                               |
| `node_modules` & `package.json`                       | Separate instances                                                 | Shared across monorepo                                     |
| Default compiler                                      | `tsc`                                                              | webpack                                                    |
| Compiler settings                                     | Specified separately                                               | Monorepo defaults that can be overridden per project       |
| Config files like `.eslintrc.js`, `.prettierrc`, etc. | Specified separately                                               | Shared across monorepo                                     |
| `nest build` and `nest start` commands                | Target defaults automatically to the (only) project in the context | Target defaults to the **default project** in the monorepo |
| Libraries                                             | Managed manually, usually via npm packaging                        | Built-in support, including path management and bundling   |

Read the sections on [Workspaces](/v9/cli/monorepo) and [Libraries](/v9/cli/libraries) for more detailed information to help you decide which mode is most suitable for you.

```bash

nest commandOrAlias requiredArg [optionalArg] [options]
```

For example:

```bash

$ nest new my-nest-project --dry-run
```

Here, `new` is the *commandOrAlias*. The `new` command has an alias of `n`. `my-nest-project` is the *requiredArg*. If a *requiredArg* is not supplied on the command line, `nest` will prompt for it. Also, `--dry-run` has an equivalent short-hand form `-d`. With this in mind, the following command is the equivalent of the above:

```bash

$ nest n my-nest-project -d
```

Most commands, and some options, have aliases. Try running `nest new --help` to see these options and aliases, and to confirm your understanding of the above constructs.

#### Command overview[#](/cli/overview#command-overview)

Run `nest <command> --help` for any of the following commands to see command-specific options.

See [usage](/v9/cli/usages) for detailed descriptions for each command.

| Command    | Alias | Description                                                                                    |
| ---------- | ----- | ---------------------------------------------------------------------------------------------- |
| `new`      | `n`   | Scaffolds a new *standard mode* application with all boilerplate files needed to run.          |
| `generate` | `g`   | Generates and/or modifies files based on a schematic.                                          |
| `build`    |       | Compiles an application or workspace into an output folder.                                    |
| `start`    |       | Compiles and runs an application (or default project in a workspace).                          |
| `add`      |       | Imports a library that has been packaged as a **nest library**, running its install schematic. |
| `info`     | `i`   | Displays information about installed nest packages and other helpful system info.              |

#### Requirements[#](/cli/overview#requirements)

Nest CLI requires a Node.js binary built with [internationalization support](https://nodejs.org/api/intl.html) (ICU), such as the official binaries from the [Node.js project page](https://nodejs.org/en/download). If you encounter errors related to ICU, check that your binary meets this requirement.

```bash

node -p process.versions.icu
```

If the command prints `undefined`, your Node.js binary has no internationalization support.

----
url: https://docs.nestjs.com/v8/microservices/custom-transport
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Custom transporters](https://docs.nestjs.com/v8/microservices/custom-transport#custom-transporters)
* [Creating a strategy](https://docs.nestjs.com/v8/microservices/custom-transport#creating-a-strategy)
* [Client proxy](https://docs.nestjs.com/v8/microservices/custom-transport#client-proxy)
* [Message serialization](https://docs.nestjs.com/v8/microservices/custom-transport#message-serialization)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/microservices/custom-transport.md "Suggest Edits")

### Custom transporters

Nest provides a variety of **transporters** out-of-the-box, as well as an API allowing developers to build new custom transport strategies. Transporters enable you to connect components over a network using a pluggable communications layer and a very simple application-level message protocol (read full [article](https://dev.to/nestjs/integrate-nestjs-with-external-services-using-microservice-transporters-part-1-p3)).

> **Hint** Building a microservice with Nest does not necessarily mean you must use the `@nestjs/microservices` package. For example, if you want to communicate with external services (let's say other microservices written in different languages), you may not need all the features provided by `@nestjs/microservice` library. In fact, if you don't need decorators (`@EventPattern` or `@MessagePattern`) that let you declaratively define subscribers, running a [Standalone Application](/v8/application-context) and manually maintaining connection/subscribing to channels should be enough for most use-cases and will provide you with more flexibility.

With a custom transporter, you can integrate any messaging system/protocol (including Google Cloud Pub/Sub, Amazon Kinesis, and others) or extend the existing one, adding extra features on top (for example, [QoS](https://github.com/mqttjs/MQTT.js/blob/master/README.md#qos) for MQTT).

> **Hint** To better understand how Nest microservices work and how you can extend the capabilities of existing transporters, we recommend reading the [NestJS Microservices in Action](https://dev.to/johnbiundo/series/4724) and [Advanced NestJS Microservices](https://dev.to/nestjs/part-1-introduction-and-setup-1a2l) article series.

#### Creating a strategy[#](/microservices/custom-transport#creating-a-strategy)

First, let's define a class representing our custom transporter.

```typescript

import { CustomTransportStrategy, Server } from '@nestjs/microservices';

class GoogleCloudPubSubServer
  extends Server
  implements CustomTransportStrategy {
  /**
   * This method is triggered when you run "app.listen()".
   */
  listen(callback: () => void) {
    callback();
  }

  /**
   * This method is triggered on application shutdown.
   */
  close() {}
}
```

> **Warning** Please, note we won't be implementing a fully-featured Google Cloud Pub/Sub server in this chapter as this would require diving into transporter specific technical details.

In our example above, we declared the `GoogleCloudPubSubServer` class and provided `listen()` and `close()` methods enforced by the `CustomTransportStrategy` interface. Also, our class extends the `Server` class imported from the `@nestjs/microservices` package that provides a few useful methods, for example, methods used by Nest runtime to register message handlers. Alternatively, in case you want to extend the capabilities of an existing transport strategy, you could extend the corresponding server class, for example, `ServerRedis`. Conventionally, we added the `"Server"` suffix to our class as it will be responsible for subscribing to messages/events (and responding to them, if necessary).

With this in place, we can now use our custom strategy instead of using a built-in transporter, as follows:

```typescript

const app = await NestFactory.createMicroservice<MicroserviceOptions>(
  AppModule,
  {
    strategy: new GoogleCloudPubSubServer(),
  },
);
```

Basically, instead of passing the normal transporter options object with `transport` and `options` properties, we pass a single property, `strategy`, whose value is an instance of our custom transporter class.

Back to our `GoogleCloudPubSubServer` class, in a real-world application, we would be establishing a connection to our message broker/external service and registering subscribers/listening to specific channels in `listen()` method (and then removing subscriptions & closing the connection in the `close()` teardown method), but since this requires a good understanding of how Nest microservices communicate with each other, we recommend reading this [article series](https://dev.to/nestjs/part-1-introduction-and-setup-1a2l). In this chapter instead, we'll focus on the capabilities the `Server` class provides and how you can leverage them to build custom strategies.

For example, let's say that somewhere in our application, the following message handler is defined:

```typescript

@MessagePattern('echo')
echo(@Payload() data: object) {
  return data;
}
```

This message handler will be automatically registered by Nest runtime. With `Server` class, you can see what message patterns have been registered and also, access and execute the actual methods that were assigned to them. To test this out, let's add a simple `console.log` inside `listen()` method before `callback` function is called:

```typescript

listen(callback: () => void) {
  console.log(this.messageHandlers);
  callback();
}
```

After your application restarts, you'll see the following log in your terminal:

```typescript

Map { 'echo' => [AsyncFunction] { isEventHandler: false } }
```

> **Hint** If we used the `@EventPattern` decorator, you would see the same output, but with the `isEventHandler` property set to `true`.

As you can see, the `messageHandlers` property is a `Map` collection of all message (and event) handlers, in which patterns are being used as keys. Now, you can use a key (for example, `"echo"`) to receive a reference to the message handler:

```typescript

async listen(callback: () => void) {
  const echoHandler = this.messageHandlers.get('echo');
  console.log(await echoHandler('Hello world!'));
  callback();
}
```

Once we execute the `echoHandler` passing an arbitrary string as an argument (`"Hello world!"` here), we should see it in the console:

```json

Hello world!
```

Which means that our method handler was properly executed.

#### Client proxy[#](/microservices/custom-transport#client-proxy)

As we mentioned in the first section, you don't necessarily need to use the `@nestjs/microservices` package to create microservices, but if you decide to do so and you need to integrate a custom strategy, you will need to provide a "client" class too.

> **Hint** Again, implementing a fully-featured client class compatible with all `@nestjs/microservices` features (e.g., streaming) requires a good understading of communication techniques used by the framework. To learn more, check out this [article](https://dev.to/nestjs/part-4-basic-client-component-16f9).

To communicate with an external service/emit & publish messages (or events) you can either use a library-specific SDK package, or implement a custom client class that extends the `ClientProxy`, as follows:

```typescript

import { ClientProxy, ReadPacket, WritePacket } from '@nestjs/microservices';

class GoogleCloudPubSubClient extends ClientProxy {
  async connect(): Promise<any> {}
  async close() {}
  async dispatchEvent(packet: ReadPacket<any>): Promise<any> {}
  publish(
    packet: ReadPacket<any>,
    callback: (packet: WritePacket<any>) => void,
  ): Function {}
}
```

> **Warning** Please, note we won't be implementing a fully-featured Google Cloud Pub/Sub client in this chapter as this would require diving into transporter specific technical details.

As you can see, `ClientProxy` class requires us to provide several methods for establishing & closing the connection and publishing messages (`publish`) and events (`dispatchEvent`). Note, if you don't need a request-response communication style support, you can leave the `publish()` method empty. Likewise, if you don't need to support event-based communication, skip the `dispatchEvent()` method.

To observe what and when those methods are executed, let's add multiple `console.log` calls, as follows:

```typescript

class GoogleCloudPubSubClient extends ClientProxy {
  async connect(): Promise<any> {
    console.log('connect');
  }

  async close() {
    console.log('close');
  }

  async dispatchEvent(packet: ReadPacket<any>): Promise<any> {
    return console.log('event to dispatch: ', packet);
  }

  publish(
    packet: ReadPacket<any>,
    callback: (packet: WritePacket<any>) => void,
  ): Function {
    console.log('message:', packet);

    // In a real-world application, the "callback" function should be executed
    // with payload sent back from the responder. Here, we'll simply simulate (5 seconds delay)
    // that response came through by passing the same "data" as we've originally passed in.
    setTimeout(() => callback({ response: packet.data }), 5000);

    return () => console.log('teardown');
  }
}
```

With this in place, let's create an instance of `GoogleCloudPubSubClient` class and run the `send()` method (which you might have seen in earlier chapters), subscribing to the returned observable stream.

```typescript

const googlePubSubClient = new GoogleCloudPubSubClient();
googlePubSubClient
  .send('pattern', 'Hello world!')
  .subscribe((response) => console.log(response));
```

Now, you should see the following output in your terminal:

```typescript

connect
message: { pattern: 'pattern', data: 'Hello world!' }
Hello world! // <-- after 5 seconds
```

To test if our "teardown" method (which our `publish()` method returns) is properly executed, let's apply a timeout operator to our stream, setting it to 2 seconds to make sure it throws earlier then our `setTimeout` calls the `callback` function.

```typescript

const googlePubSubClient = new GoogleCloudPubSubClient();
googlePubSubClient
  .send('pattern', 'Hello world!')
  .pipe(timeout(2000))
  .subscribe(
    (response) => console.log(response),
    (error) => console.error(error.message),
  );
```

> **Hint** The `timeout` operator is imported from the `rxjs/operators` package.

With `timeout` operator applied, your terminal output should look as follows:

```typescript

connect
message: { pattern: 'pattern', data: 'Hello world!' }
teardown // <-- teardown
Timeout has occurred
```

To dispatch an event (instead of sending a message), use the `emit()` method:

```typescript

googlePubSubClient.emit('event', 'Hello world!');
```

And that's what you should see in the console:

```typescript

connect
event to dispatch:  { pattern: 'event', data: 'Hello world!' }
```

#### Message serialization[#](/microservices/custom-transport#message-serialization)

If you need to add some custom logic around the serialization of responses on the client side, you can use a custom class that extends the `ClientProxy` class or one of its child classes. For modifying successful requests you can override the `serializeResponse` method, and for modifying any errors that go through this client you can override the `serializeError` method. To make use of this custom class, you can pass the class itself to the `ClientsModule.register()` method using the `customClass` property. Below is an example of a custom `ClientProxy` that serializes each error into an `RpcException`.

error-handling.proxy.ts

JS TS

```typescript

import { ClientTcp, RpcException } from '@nestjs/microservices';

class ErrorHandlingProxy extends ClientTCP {
  serializeError(err: Error) {
    return new RpcException(err);
  }
}
```

and then use it in the `ClientsModule` like so:

app.module.ts

JS TS

```typescript

@Module({
  imports: [
    ClientsModule.register({
      name: 'CustomProxy',
      customClass: ErrorHandlingProxy,
    }),
  ]
})
export class AppModule
```

> **hint** This is the class itself being passed to `customClass`, not an instance of the class. Nest will create the instance under the hood for you, and will pass any options given to the `options` property to the new `ClientProxy`.

----
url: https://docs.nestjs.com/v8/graphql/unions-and-enums
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Unions](https://docs.nestjs.com/v8/graphql/unions-and-enums#unions)
* [Code first](https://docs.nestjs.com/v8/graphql/unions-and-enums#code-first)
* [Schema first](https://docs.nestjs.com/v8/graphql/unions-and-enums#schema-first)
* [Enums](https://docs.nestjs.com/v8/graphql/unions-and-enums#enums)
* [Code first](https://docs.nestjs.com/v8/graphql/unions-and-enums#code-first-1)
* [Schema first](https://docs.nestjs.com/v8/graphql/unions-and-enums#schema-first-1)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/unions-and-enums.md "Suggest Edits")

### Unions

Union types are very similar to interfaces, but they don't get to specify any common fields between the types (read more [here](https://graphql.org/learn/schema/#union-types)). Unions are useful for returning disjoint data types from a single field.

#### Code first[#](/graphql/unions-and-enums#code-first)

To define a GraphQL union type, we must define classes that this union will be composed of. Following the [example](https://www.apollographql.com/docs/apollo-server/schema/unions-interfaces/#union-type) from the Apollo documentation, we'll create two classes. First, `Book`:

```typescript

import { Field, ObjectType } from '@nestjs/graphql';

@ObjectType()
export class Book {
  @Field()
  title: string;
}
```

And then `Author`:

```typescript

import { Field, ObjectType } from '@nestjs/graphql';

@ObjectType()
export class Author {
  @Field()
  name: string;
}
```

With this in place, register the `ResultUnion` union using the `createUnionType` function exported from the `@nestjs/graphql` package:

```typescript

export const ResultUnion = createUnionType({
  name: 'ResultUnion',
  types: () => [Author, Book] as const,
});
```

> **Warning** The array returned by the `types` property of the `createUnionType` function should be given a const assertion. If the const assertion is not given, a wrong declaration file will be generated at compile time, and an error will occur when using it from another project.

Now, we can reference the `ResultUnion` in our query:

```typescript

@Query(returns => [ResultUnion])
search(): Array<typeof ResultUnion> {
  return [new Author(), new Book()];
}
```

This will result in generating the following part of the GraphQL schema in SDL:

```graphql

type Author {
  name: String!
}

type Book {
  title: String!
}

union ResultUnion = Author | Book

type Query {
  search: [ResultUnion!]!
}
```

The default `resolveType()` function generated by the library will extract the type based on the value returned from the resolver method. That means returning class instances instead of literal JavaScript object is obligatory.

To provide a customized `resolveType()` function, pass the `resolveType` property to the options object passed into the `createUnionType()` function, as follows:

```typescript

export const ResultUnion = createUnionType({
  name: 'ResultUnion',
  types: () => [Author, Book] as const,
  resolveType(value) {
    if (value.name) {
      return Author;
    }
    if (value.title) {
      return Book;
    }
    return null;
  },
});
```

#### Schema first[#](/graphql/unions-and-enums#schema-first)

To define a union in the schema first approach, simply create a GraphQL union with SDL.

```graphql

type Author {
  name: String!
}

type Book {
  title: String!
}

union ResultUnion = Author | Book
```

Then, you can use the typings generation feature (as shown in the [quick start](/v8/graphql/quick-start) chapter) to generate corresponding TypeScript definitions:

```typescript

export class Author {
  name: string;
}

export class Book {
  title: string;
}

export type ResultUnion = Author | Book;
```

Unions require an extra `__resolveType` field in the resolver map to determine which type the union should resolve to. Also, note that the `ResultUnionResolver` class has to be registered as a provider in any module. Let's create a `ResultUnionResolver` class and define the `__resolveType` method.

```typescript

@Resolver('ResultUnion')
export class ResultUnionResolver {
  @ResolveField()
  __resolveType(value) {
    if (value.name) {
      return 'Author';
    }
    if (value.title) {
      return 'Book';
    }
    return null;
  }
}
```

> **Hint** All decorators are exported from the `@nestjs/graphql` package.

### Enums

Enumeration types are a special kind of scalar that is restricted to a particular set of allowed values (read more [here](https://graphql.org/learn/schema/#enumeration-types)). This allows you to:

* validate that any arguments of this type are one of the allowed values
* communicate through the type system that a field will always be one of a finite set of values

#### Code first[#](/graphql/unions-and-enums#code-first-1)

When using the code first approach, you define a GraphQL enum type by simply creating a TypeScript enum.

```typescript

export enum AllowedColor {
  RED,
  GREEN,
  BLUE,
}
```

With this in place, register the `AllowedColor` enum using the `registerEnumType` function exported from the `@nestjs/graphql` package:

```typescript

registerEnumType(AllowedColor, {
  name: 'AllowedColor',
});
```

Now you can reference the `AllowedColor` in our types:

```typescript

@Field(type => AllowedColor)
favoriteColor: AllowedColor;
```

This will result in generating the following part of the GraphQL schema in SDL:

```graphql

enum AllowedColor {
  RED
  GREEN
  BLUE
}
```

To provide a description for the enum, pass the `description` property into the `registerEnumType()` function.

```typescript

registerEnumType(AllowedColor, {
  name: 'AllowedColor',
  description: 'The supported colors.',
});
```

To provide a description for the enum values, or to mark a value as deprecated, pass the `valuesMap` property, as follows:

```typescript

registerEnumType(AllowedColor, {
  name: 'AllowedColor',
  description: 'The supported colors.',
  valuesMap: {
    RED: {
      description: 'The default color.',
    },
    BLUE: {
      deprecationReason: 'Too blue.',
    },
  },
});
```

This will generate the following GraphQL schema in SDL:

```graphql

"""
The supported colors.
"""
enum AllowedColor {
  """
  The default color.
  """
  RED
  GREEN
  BLUE @deprecated(reason: "Too blue.")
}
```

#### Schema first[#](/graphql/unions-and-enums#schema-first-1)

To define an enumerator in the schema first approach, simply create a GraphQL enum with SDL.

```graphql

enum AllowedColor {
  RED
  GREEN
  BLUE
}
```

Then you can use the typings generation feature (as shown in the [quick start](/v8/graphql/quick-start) chapter) to generate corresponding TypeScript definitions:

```typescript

export enum AllowedColor {
  RED
  GREEN
  BLUE
}
```

Sometimes a backend forces a different value for an enum internally than in the public API. In this example the API contains `RED`, however in resolvers we may use `#f00` instead (read more [here](https://www.apollographql.com/docs/apollo-server/schema/scalars-enums/#internal-values)). To accomplish this, declare a resolver object for the `AllowedColor` enum:

```typescript

export const allowedColorResolver: Record<keyof typeof AllowedColor, any> = {
  RED: '#f00',
};
```

> **Hint** All decorators are exported from the `@nestjs/graphql` package.

Then use this resolver object together with the `resolvers` property of the `GraphQLModule#forRoot()` method, as follows:

```typescript

GraphQLModule.forRoot({
  resolvers: {
    AllowedColor: allowedColorResolver,
  },
});
```

----
url: https://docs.nestjs.com/v6/websockets/interceptors
----

* [Interceptors](https://docs.nestjs.com/v6/websockets/interceptors#interceptors)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/websockets/interceptors.md "Suggest Edits")

### Interceptors

There is no difference between [regular interceptors](/v6/interceptors) and web sockets interceptors. The following example uses a manually instantiated method-scoped interceptor. Just as with HTTP based applications, you can also use gateway-scoped interceptors (i.e., prefix the gateway class with a `@UseInterceptors()` decorator).

JS TS

```typescript

@UseInterceptors(new TransformInterceptor())
@SubscribeMessage('events')
handleEvent(client: Client, data: unknown): WsResponse<unknown> {
  const event = 'events';
  return { event, data };
}
```

```typescript

@UseInterceptors(new TransformInterceptor())
@SubscribeMessage('events')
handleEvent(client, data) {
  const event = 'events';
  return { event, data };
}
```

----
url: https://docs.nestjs.com/v6/pipes
----

* [Pipes](https://docs.nestjs.com/v6/pipes#pipes)
* [Built-in pipes](https://docs.nestjs.com/v6/pipes#built-in-pipes)
* [Validation use case](https://docs.nestjs.com/v6/pipes#validation-use-case)
* [Object schema validation](https://docs.nestjs.com/v6/pipes#object-schema-validation)
* [Binding pipes](https://docs.nestjs.com/v6/pipes#binding-pipes)
* [Class validator](https://docs.nestjs.com/v6/pipes#class-validator)
* [Transformation use case](https://docs.nestjs.com/v6/pipes#transformation-use-case)
* [The built-in ValidationPipe](https://docs.nestjs.com/v6/pipes#the-built-in-validationpipe)

[](https://srv.carbonads.net/ads/click/x/GTND4277CVSD5KJUCAYLYKQUF67D62QUF6BILZ3JCAAI623WC67D45QKCESDT537CAAI427WCKYIK2J7CTYDC23KC6SILKJUCT7DEK3EHJNCLSIZ)[Start your AI journey with free access to leading cloud products and services. ](https://srv.carbonads.net/ads/click/x/GTND4277CVSD5KJUCAYLYKQUF67D62QUF6BILZ3JCAAI623WC67D45QKCESDT537CAAI427WCKYIK2J7CTYDC23KC6SILKJUCT7DEK3EHJNCLSIZ)[ads via Carbon](http://carbonads.net/?utm_source=nestjscom\&utm_medium=ad_via_link\&utm_campaign=in_unit\&utm_term=carbon)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/pipes.md "Suggest Edits")

### Pipes

A pipe is a class annotated with the `@Injectable()` decorator. Pipes should implement the `PipeTransform` interface.

Pipes have two typical use cases:

* **transformation**: transform input data to the desired output
* **validation**: evaluate input data and if valid, simply pass it through unchanged; otherwise, throw an exception when the data is incorrect

In both cases, pipes operate on the `arguments` being processed by a [controller route handler](controllers#route-parameters). Nest interposes a pipe just before a method is invoked, and the pipe receives the arguments destined for the method. Any transformation or validation operation takes place at that time, after which the route handler is invoked with any (potentially) transformed arguments.

> **Hint** Pipes run inside the exceptions zone. This means that when a Pipe throws an exception it is handled by the exceptions layer (global exceptions filter and any [exceptions filters](/v6/exception-filters) that are applied to the current context). Given the above, it should be clear that when an exception is thrown in a Pipe, no controller method is subsequently executed.

#### Built-in pipes[#](/pipes#built-in-pipes)

Nest comes with three pipes available right out-of-the-box: `ValidationPipe`, `ParseIntPipe` and `ParseUUIDPipe`. They're exported from the `@nestjs/common` package. In order to better understand how they work, let's build them from scratch.

Let's start with the `ValidationPipe`. Initially, we'll have it simply take an input value and immediately return the same value, behaving like an identity function.

validation.pipe.ts

JS TS

```typescript

import { PipeTransform, Injectable, ArgumentMetadata } from '@nestjs/common';

@Injectable()
export class ValidationPipe implements PipeTransform {
  transform(value: any, metadata: ArgumentMetadata) {
    return value;
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';

@Injectable()
export class ValidationPipe {
  transform(value, metadata) {
    return value;
  }
}
```

> **Hint**`PipeTransform<T, R>` is a generic interface in which `T` indicates the type of the input `value`, and `R` indicates the return type of the `transform()` method.

Every pipe has to provide the `transform()` method. This method has two parameters:

* `value`
* `metadata`

The `value` is the currently processed argument (before it is received by the route handling method), while `metadata` is its metadata. The metadata object has these properties:

```typescript

export interface ArgumentMetadata {
  type: 'body' | 'query' | 'param' | 'custom';
  metatype?: Type<any>;
  data?: string;
}
```

These properties describe the currently processed argument.

|            |                                                                                                                                                                                                      |
| ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `type`     | Indicates whether the argument is a body `@Body()`, query `@Query()`, param `@Param()`, or a custom parameter (read more [here](/v6/custom-decorators)).                                             |
| `metatype` | Provides the metatype of the argument, for example, `String`. Note: the value is `undefined` if you either omit a type declaration in the route handler method signature, or use vanilla JavaScript. |
| `data`     | The string passed to the decorator, for example `@Body('string')`. It's `undefined` if you leave the decorator parenthesis empty.                                                                    |

> **Warning** TypeScript interfaces disappear during transpilation. Thus, if a method parameter's type is declared as an interface instead of a class, the `metatype` value will be `Object`.

#### Validation use case[#](/pipes#validation-use-case)

Let's take a closer look at the `create()` method of the `CatsController`.

JS TS

```typescript

@Post()
async create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

```typescript

@Post()
async create(@Body() createCatDto) {
  this.catsService.create(createCatDto);
}
```

Let's focus in on the `createCatDto` body parameter. Its type is `CreateCatDto`:

create-cat.dto.ts

JS TS

```typescript

export class CreateCatDto {
  name: string;
  age: number;
  breed: string;
}
```

We want to ensure that any incoming request to the create method contains a valid body. So we have to validate the three members of the `createCatDto` object. We could do this inside the route handler method, but we would break the **single responsibility rule** (SRP). Another approach could be to create a **validator class** and delegate the task there, but we would have to use this validator at the beginning of each method. How about creating a validation middleware? This could be a good idea, but it's not possible to create **generic middleware** which can be used across the whole application (because middleware is unaware of the **execution context**, including the handler that will be called and any of its parameters).

It turns out that this is a case ideally suited for a **Pipe**. So let's go ahead and build one.

## Learn the right way!

* 60+ chapters
* 4+ hours of videos
* Official certificate
* Deep-dive sessions

[Explore official courses](https://courses.nestjs.com "Courses | NestJS - A node.js framework built on top of TypeScript")

#### Object schema validation[#](/pipes#object-schema-validation)

There are several approaches available for object validation. One common approach is to use **schema-based** validation. The [Joi](https://github.com/hapijs/joi) library allows you to create schemas in a pretty straightforward way, with a readable API. Let's look at a pipe that makes use of Joi-based schemas.

Start by installing the required package:

```bash

$ npm install --save @hapi/joi
$ npm install --save-dev @types/hapi__joi
```

In the code sample below, we create a simple class that takes a schema as a `constructor` argument. We then apply the `schema.validate()` method, which validates our incoming argument against the provided schema.

As noted earlier, a **validation pipe** either returns the value unchanged, or throws an exception.

In the next section, you'll see how we supply the appropriate schema for a given controller method using the `@UsePipes()` decorator.

JS TS

```typescript

import { PipeTransform, Injectable, ArgumentMetadata, BadRequestException } from '@nestjs/common';

@Injectable()
export class JoiValidationPipe implements PipeTransform {
  constructor(private readonly schema: Object) {}

  transform(value: any, metadata: ArgumentMetadata) {
    const { error } = this.schema.validate(value);
    if (error) {
      throw new BadRequestException('Validation failed');
    }
    return value;
  }
}
```

```typescript

import { Injectable, BadRequestException } from '@nestjs/common';

@Injectable()
export class JoiValidationPipe {
  constructor(schema) {
    this.schema = schema;
  }

  transform(value, metadata) {
    const { error } = this.schema.validate(value);
    if (error) {
      throw new BadRequestException('Validation failed');
    }
    return value;
  }
}
```

#### Binding pipes[#](/pipes#binding-pipes)

Binding pipes (tying them to the appropriate controller or handler) is very straightforward. We use the `@UsePipes()` decorator and create a pipe instance, passing it a Joi validation schema.

JS TS

```typescript

@Post()
@UsePipes(new JoiValidationPipe(createCatSchema))
async create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

```typescript

@Post()
@Bind(Body())
@UsePipes(new JoiValidationPipe(createCatSchema))
async create(createCatDto) {
  this.catsService.create(createCatDto);
}
```

#### Class validator[#](/pipes#class-validator)

> **Warning** The techniques in this section require TypeScript, and are not available if your app is written using vanilla JavaScript.

Let's look at an alternate implementation of our validation technique.

Nest works well with the [class-validator](https://github.com/typestack/class-validator) library. This amazing library allows you to use decorator-based validation. Decorator-based validation is extremely powerful, especially when combined with Nest's **Pipe** capabilities since we have access to the `metatype` of the processed property. Before we start, we need to install the required packages:

```bash

$ npm i --save class-validator class-transformer
```

Once these are installed, we can add a few decorators to the `CreateCatDto` class.

create-cat.dto.ts

JS TS

```typescript

import { IsString, IsInt } from 'class-validator';

export class CreateCatDto {
  @IsString()
  name: string;

  @IsInt()
  age: number;

  @IsString()
  breed: string;
}
```

> **Hint** Read more about the class-validator decorators [here](https://github.com/typestack/class-validator#usage).

Now we can create a `ValidationPipe` class.

validation.pipe.ts

JS TS

```typescript

import { PipeTransform, Injectable, ArgumentMetadata, BadRequestException } from '@nestjs/common';
import { validate } from 'class-validator';
import { plainToClass } from 'class-transformer';

@Injectable()
export class ValidationPipe implements PipeTransform<any> {
  async transform(value: any, { metatype }: ArgumentMetadata) {
    if (!metatype || !this.toValidate(metatype)) {
      return value;
    }
    const object = plainToClass(metatype, value);
    const errors = await validate(object);
    if (errors.length > 0) {
      throw new BadRequestException('Validation failed');
    }
    return value;
  }

  private toValidate(metatype: Function): boolean {
    const types: Function[] = [String, Boolean, Number, Array, Object];
    return !types.includes(metatype);
  }
}
```

> **Notice** Above, we have used the [class-transformer](https://github.com/typestack/class-transformer) library. It's made by the same author as the **class-validator** library, and as a result, they play very well together.

Let's go through this code. First, note that the `transform()` function is `async`. This is possible because Nest supports both synchronous and **asynchronous** pipes. We do this because some of the class-validator validations [can be async](https://github.com/typestack/class-validator#custom-validation-classes) (utilize Promises).

Next note that we are using destructuring to extract the metatype field (extracting just this member from an `ArgumentMetadata`) into our `metatype` parameter. This is just shorthand for getting the full `ArgumentMetadata` and then having an additional statement to assign the metatype variable.

Next, note the helper function `toValidate()`. It's responsible for bypassing the validation step when the current argument being processed is a native JavaScript type (these can't have schemas attached, so there's no reason to run them through the validation step).

Next, we use the class-transformer function `plainToClass()` to transform our plain JavaScript argument object into a typed object so that we can apply validation. The incoming body, when deserialized from the network request, does not have any type information. Class-validator needs to use the validation decorators we defined for our DTO earlier, so we need to perform this transformation.

Finally, as noted earlier, since this is a **validation pipe** it either returns the value unchanged, or throws an exception.

The last step is to bind the `ValidationPipe`. Pipes, similar to [exception filters](/v6/exception-filters), can be method-scoped, controller-scoped, or global-scoped. Additionally, a pipe can be param-scoped. In the example below, we'll directly tie the pipe instance to the route param `@Body()` decorator.

cats.controller.ts

JS TS

```typescript

@Post()
async create(
  @Body(new ValidationPipe()) createCatDto: CreateCatDto,
) {
  this.catsService.create(createCatDto);
}
```

Param-scoped pipes are useful when the validation logic concerns only one specified parameter.

Alternatively, to set up a pipe at a method level, use the `@UsePipes()` decorator.

cats.controller.ts

JS TS

```typescript

@Post()
@UsePipes(new ValidationPipe())
async create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

> **Hint** The `@UsePipes()` decorator is imported from the `@nestjs/common` package.

In the example above, an instance of `ValidationPipe` has been created immediately in-place. Alternatively, pass the class (not an instance), thus leaving instantiation up to the framework, and enabling **dependency injection**.

cats.controller.ts

JS TS

```typescript

@Post()
@UsePipes(ValidationPipe)
async create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

Since the `ValidationPipe` was created to be as generic as possible, let's set it up as a **global-scoped** pipe, applied to every route handler across the entire application.

main.ts

JS TS

```typescript

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.useGlobalPipes(new ValidationPipe());
  await app.listen(3000);
}
bootstrap();
```

> **Notice** In the case of [hybrid apps](faq/hybrid-application) the `useGlobalPipes()` method doesn't set up pipes for gateways and micro services. For "standard" (non-hybrid) microservice apps, `useGlobalPipes()` does mount pipes globally.

Global pipes are used across the whole application, for every controller and every route handler. In terms of dependency injection, global pipes registered from outside of any module (with `useGlobalPipes()` as in the example above) cannot inject dependencies since this is done outside the context of any module. In order to solve this issue, you can set up a global pipe **directly from any module** using the following construction:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { APP_PIPE } from '@nestjs/core';

@Module({
  providers: [
    {
      provide: APP_PIPE,
      useClass: ValidationPipe,
    },
  ],
})
export class AppModule {}
```

> **Hint** When using this approach to perform dependency injection for the pipe, note that regardless of the module where this construction is employed, the pipe is, in fact, global. Where should this be done? Choose the module where the pipe (`ValidationPipe` in the example above) is defined. Also, `useClass` is not the only way of dealing with custom provider registration. Learn more [here](/v6/fundamentals/custom-providers).

#### Transformation use case[#](/pipes#transformation-use-case)

Validation isn't the sole use case for **Pipes**. At the beginning of this chapter, we mentioned that a pipe can also **transform** the input data to the desired output. This is possible because the value returned from the `transform` function completely overrides the previous value of the argument. When is this useful? Consider that sometimes the data passed from the client needs to undergo some change - for example converting a string to an integer - before it can be properly handled by the route handler method. Furthermore, some required data fields may be missing, and we would like to apply default values. **Transformer pipes** can perform these functions by interposing a processing function between the client request and the request handler.

Here's a `ParseIntPipe` which is responsible for parsing a string into an integer value.

parse-int.pipe.ts

JS TS

```typescript

import { PipeTransform, Injectable, ArgumentMetadata, BadRequestException } from '@nestjs/common';

@Injectable()
export class ParseIntPipe implements PipeTransform<string, number> {
  transform(value: string, metadata: ArgumentMetadata): number {
    const val = parseInt(value, 10);
    if (isNaN(val)) {
      throw new BadRequestException('Validation failed');
    }
    return val;
  }
}
```

```typescript

import { Injectable, BadRequestException} from '@nestjs/common';

@Injectable()
export class ParseIntPipe {
  transform(value, metadata) {
    const val = parseInt(value, 10);
    if (isNaN(val)) {
      throw new BadRequestException('Validation failed');
    }
    return val;
  }
}
```

We can simply tie this pipe to the selected param as shown below:

JS TS

```typescript

@Get(':id')
async findOne(@Param('id', new ParseIntPipe()) id) {
  return this.catsService.findOne(id);
}
```

```typescript

@Get(':id')
@Bind(Param('id', new ParseIntPipe()))
async findOne(id) {
  return this.catsService.findOne(id);
}
```

If you prefer you can use the `ParseUUIDPipe` which is responsible for parsing a string and validate if is a UUID.

JS TS

```typescript

@Get(':id')
async findOne(@Param('id', new ParseUUIDPipe()) id) {
  return this.catsService.findOne(id);
}
```

```typescript

@Get(':id')
@Bind(Param('id', new ParseUUIDPipe()))
async findOne(id) {
  return this.catsService.findOne(id);
}
```

> **Hint** When using `ParseUUIDPipe()` you are parsing UUID in version 3, 4 or 5, if you only requires a specific version of UUID you can pass a version in the pipe options.

With this in place, `ParseIntPipe` or `ParseUUIDPipe` will be executed before the request reaches the corresponding handler, ensuring that it will always receive an integer or uuid (according on the used pipe) for the `id` parameter.

Another useful case would be to select an **existing user** entity from the database by id:

JS TS

```typescript

@Get(':id')
findOne(@Param('id', UserByIdPipe) userEntity: UserEntity) {
  return userEntity;
}
```

```typescript

@Get(':id')
@Bind(Param('id', UserByIdPipe))
findOne(userEntity) {
  return userEntity;
}
```

We leave the implementation of this pipe to the reader, but note that like all other transformation pipes, it receives an input value (an `id`) and returns an output value (a `UserEntity` object). This can make your code more declarative and [DRY](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself) by abstracting boilerplate code out of your handler and into a common pipe.

#### The built-in ValidationPipe[#](/pipes#the-built-in-validationpipe)

Fortunately, you don't have to build these pipes on your own since the `ValidationPipe` and the `ParseIntPipe` are provided by Nest out-of-the-box. (Keep in mind that `ValidationPipe` requires both `class-validator` and `class-transformer` packages to be installed).

The built-in `ValidationPipe` offers more options than in the sample we built in this chapter, which has been kept basic for the sake of illustrating the basic mechanics of a pipe. You can find lots of examples [here](/v6/techniques/validation).

One such option is `transform`. Recall the earlier discussion about deserialized body objects being vanilla JavaScript objects (i.e., not having our DTO type). So far, we've used the pipe to validate our payload. You may recall that in the process, we used `class-transform` to temporarily convert our plain object into a typed object so that we could do the validation. The built-in ValidationPipe can also, optionally, return this converted object. We enable this behavior by passing in a configuration object to the pipe. For this option, pass a config object with the field `transform` with a value `true` as shown below:

cats.controller.ts

JS TS

```typescript

@Post()
@UsePipes(new ValidationPipe({ transform: true }))
async create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

> **Hint** The `ValidationPipe` is imported from the `@nestjs/common` package.

Because this pipe is based on the `class-validator` and `class-transformer` libraries, there are many additional options available. Like the `transform` option above, you configure these settings via a configuration object passed to the pipe. Following are the built-in options:

```typescript

export interface ValidationPipeOptions extends ValidatorOptions {
  transform?: boolean;
  disableErrorMessages?: boolean;
  exceptionFactory?: (errors: ValidationError[]) => any;
}
```

In addition to these, all `class-validator` options (inherited from the `ValidatorOptions` interface) are available:

| Option                   | Type       | Description                                                                                                                       |
| ------------------------ | ---------- | --------------------------------------------------------------------------------------------------------------------------------- |
| `skipMissingProperties`  | `boolean`  | If set to true, validator will skip validation of all properties that are missing in the validating object.                       |
| `whitelist`              | `boolean`  | If set to true, validator will strip validated (returned) object of any properties that do not use any validation decorators.     |
| `forbidNonWhitelisted`   | `boolean`  | If set to true, instead of stripping non-whitelisted properties validator will throw an exception.                                |
| `forbidUnknownValues`    | `boolean`  | If set to true, attempts to validate unknown objects fail immediately.                                                            |
| `disableErrorMessages`   | `boolean`  | If set to true, validation errors will not be returned to the client.                                                             |
| `exceptionFactory`       | `Function` | Takes an array of the validation errors and returns an exception object to be thrown.                                             |
| `groups`                 | `string[]` | Groups to be used during validation of the object.                                                                                |
| `dismissDefaultMessages` | `boolean`  | If set to true, the validation will not use default messages. Error message always will be `undefined` if its not explicitly set. |
| `validationError.target` | `boolean`  | Indicates if target should be exposed in `ValidationError`                                                                        |
| `validationError.value`  | `boolean`  | Indicates if validated value should be exposed in `ValidationError`.                                                              |

> **Notice** Find more information about the `class-validator` package in its [repository](https://github.com/typestack/class-validator).

----
url: https://docs.nestjs.com/graphql/federation
----

[Skip to content](#content)

On this page

* [Federation](https://docs.nestjs.com/graphql/federation#federation)
* [Federation with Apollo](https://docs.nestjs.com/graphql/federation#federation-with-apollo)
* [Schema first](https://docs.nestjs.com/graphql/federation#schema-first)
* [Code first](https://docs.nestjs.com/graphql/federation#code-first)
* [Federated example: Posts](https://docs.nestjs.com/graphql/federation#federated-example-posts)
* [Schema first](https://docs.nestjs.com/graphql/federation#schema-first-1)
* [Code first](https://docs.nestjs.com/graphql/federation#code-first-1)
* [Federated example: Gateway](https://docs.nestjs.com/graphql/federation#federated-example-gateway)
* [Federation with Mercurius](https://docs.nestjs.com/graphql/federation#federation-with-mercurius)
* [Schema first](https://docs.nestjs.com/graphql/federation#schema-first-2)
* [Code first](https://docs.nestjs.com/graphql/federation#code-first-2)
* [Federated example: Posts](https://docs.nestjs.com/graphql/federation#federated-example-posts-1)
* [Schema first](https://docs.nestjs.com/graphql/federation#schema-first-3)
* [Code first](https://docs.nestjs.com/graphql/federation#code-first-3)
* [Federated example: Gateway](https://docs.nestjs.com/graphql/federation#federated-example-gateway-1)
* [Federation 2](https://docs.nestjs.com/graphql/federation#federation-2)
* [Federated example: Users](https://docs.nestjs.com/graphql/federation#federated-example-users)
* [Schema first](https://docs.nestjs.com/graphql/federation#schema-first-4)
* [Code first](https://docs.nestjs.com/graphql/federation#code-first-4)
* [Federated example: Posts](https://docs.nestjs.com/graphql/federation#federated-example-posts-2)
* [Schema first](https://docs.nestjs.com/graphql/federation#schema-first-5)
* [Code first](https://docs.nestjs.com/graphql/federation#code-first-5)

### Federation

Federation lets you split a monolithic GraphQL server into independent microservices. It consists of two components: a gateway and one or more federated microservices. Each microservice holds part of the schema, and the gateway merges the schemas into a single schema that clients consume.

As described in [Apollo's introduction to federation](https://blog.apollographql.com/apollo-federation-f260cf525d21), federation is designed around these core principles:

* Building a graph should be **declarative.** With federation, you compose a graph declaratively from within your schema instead of writing imperative schema stitching code.
* Code should be separated by **concern**, not by types. Often no single team controls every aspect of an important type like a User or Product, so the definition of these types should be distributed across teams and codebases, rather than centralized.
* The graph should be simple for clients to consume. Together, federated services can form a complete, product-focused graph that accurately reflects how it's being consumed on the client.
* It's just **GraphQL**, using only spec-compliant features of the language. Any language, not just JavaScript, can implement federation.

> **Warning** Federation currently does not support subscriptions.

In the following sections, we'll set up a demo application that consists of a gateway and two federated endpoints: a Users service and a Posts service.

#### Federation with Apollo[#](/graphql/federation#federation-with-apollo)

Start by installing the required dependencies:

```bash

$ npm install --save @apollo/subgraph
```

#### Schema first[#](/graphql/federation#schema-first)

The Users service provides a simple schema. The `@key` directive tells the Apollo query planner that a particular instance of `User` can be fetched by its `id`. Also note that the schema extends the `Query` type.

```graphql

type User @key(fields: "id") {
  id: ID!
  name: String!
}

extend type Query {
  getUser(id: ID!): User
}
```

The resolver provides one additional method named `resolveReference()`. The Apollo gateway calls this method whenever a related resource requires a `User` instance. You'll see an example of this in the Posts service later. The method must be annotated with the `@ResolveReference()` decorator.

```typescript

import { Args, Query, Resolver, ResolveReference } from '@nestjs/graphql';
import { UsersService } from './users.service.js';

@Resolver('User')
export class UsersResolver {
  constructor(private usersService: UsersService) {}

  @Query()
  getUser(@Args('id') id: string) {
    return this.usersService.findById(id);
  }

  @ResolveReference()
  resolveReference(reference: { __typename: string; id: string }) {
    return this.usersService.findById(reference.id);
  }
}
```

Finally, wire everything up by registering the `GraphQLModule` with the `ApolloFederationDriver` driver in the configuration object:

```typescript

import {
  ApolloFederationDriver,
  ApolloFederationDriverConfig,
} from '@nestjs/apollo';
import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';
import { UsersResolver } from './users.resolver.js';

@Module({
  imports: [
    GraphQLModule.forRoot<ApolloFederationDriverConfig>({
      driver: ApolloFederationDriver,
      typePaths: ['**/*.graphql'],
    }),
  ],
  providers: [UsersResolver],
})
export class AppModule {}
```

#### Code first[#](/graphql/federation#code-first)

Start by adding some extra decorators to the `User` entity:

```ts

import { Directive, Field, ID, ObjectType } from '@nestjs/graphql';

@ObjectType()
@Directive('@key(fields: "id")')
export class User {
  @Field(() => ID)
  id: number;

  @Field()
  name: string;
}
```

The resolver provides one additional method named `resolveReference()`. The Apollo gateway calls this method whenever a related resource requires a `User` instance. You'll see an example of this in the Posts service later. The method must be annotated with the `@ResolveReference()` decorator.

```ts

import { Args, Query, Resolver, ResolveReference } from '@nestjs/graphql';
import { User } from './user.entity.js';
import { UsersService } from './users.service.js';

@Resolver(() => User)
export class UsersResolver {
  constructor(private usersService: UsersService) {}

  @Query(() => User)
  getUser(@Args('id') id: number): User {
    return this.usersService.findById(id);
  }

  @ResolveReference()
  resolveReference(reference: { __typename: string; id: number }): User {
    return this.usersService.findById(reference.id);
  }
}
```

Finally, wire everything up by registering the `GraphQLModule` with the `ApolloFederationDriver` driver in the configuration object:

```typescript

import {
  ApolloFederationDriver,
  ApolloFederationDriverConfig,
} from '@nestjs/apollo';
import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';
import { UsersResolver } from './users.resolver.js';
import { UsersService } from './users.service.js'; // Not included in this example

@Module({
  imports: [
    GraphQLModule.forRoot<ApolloFederationDriverConfig>({
      driver: ApolloFederationDriver,
      autoSchemaFile: true,
    }),
  ],
  providers: [UsersResolver, UsersService],
})
export class AppModule {}
```

Working examples are available for the [code first](https://github.com/nestjs/nest/tree/master/sample/31-graphql-federation-code-first/users-application) and [schema first](https://github.com/nestjs/nest/tree/master/sample/32-graphql-federation-schema-first/users-application) approaches.

#### Federated example: Posts[#](/graphql/federation#federated-example-posts)

The Posts service serves aggregated posts through the `getPosts` query, and also extends the `User` type with a `user.posts` field.

#### Schema first[#](/graphql/federation#schema-first-1)

The Posts service references the `User` type in its schema by marking it with the `extend` keyword. It also declares one additional field on the `User` type (`posts`). Note the `@key` directive, used to match `User` instances, and the `@external` directive, which indicates that the `id` field is managed elsewhere.

```graphql

type Post @key(fields: "id") {
  id: ID!
  title: String!
  body: String!
  user: User
}

extend type User @key(fields: "id") {
  id: ID! @external
  posts: [Post]
}

extend type Query {
  getPosts: [Post]
}
```

In the following example, the `PostsResolver` provides a `getUser()` method that returns a reference containing `__typename` plus any additional properties your application needs to resolve the reference, in this case `id`. The gateway uses `__typename` to pinpoint the microservice responsible for the `User` type and retrieve the corresponding instance. To resolve the reference, the gateway sends a request to the Users service described above, which executes its `resolveReference()` method.

```typescript

import { Query, Resolver, Parent, ResolveField } from '@nestjs/graphql';
import { PostsService } from './posts.service.js';
import type { Post } from './posts.interfaces.js';

@Resolver('Post')
export class PostsResolver {
  constructor(private postsService: PostsService) {}

  @Query('getPosts')
  getPosts() {
    return this.postsService.findAll();
  }

  @ResolveField('user')
  getUser(@Parent() post: Post) {
    return { __typename: 'User', id: post.userId };
  }
}
```

Lastly, register the `GraphQLModule`, as in the Users service.

```typescript

import {
  ApolloFederationDriver,
  ApolloFederationDriverConfig,
} from '@nestjs/apollo';
import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';
import { PostsResolver } from './posts.resolver.js';

@Module({
  imports: [
    GraphQLModule.forRoot<ApolloFederationDriverConfig>({
      driver: ApolloFederationDriver,
      typePaths: ['**/*.graphql'],
    }),
  ],
  providers: [PostsResolver],
})
export class AppModule {}
```

#### Code first[#](/graphql/federation#code-first-1)

First, declare a class representing the `User` entity. Although the entity itself lives in another service, this service uses it (and extends its definition). Note the `@extends` and `@external` directives.

```ts

import { Directive, ObjectType, Field, ID } from '@nestjs/graphql';
import { Post } from './post.entity.js';

@ObjectType()
@Directive('@extends')
@Directive('@key(fields: "id")')
export class User {
  @Field(() => ID)
  @Directive('@external')
  id: number;

  @Field(() => [Post])
  posts?: Post[];
}
```

Next, create the resolver for the extension of the `User` entity:

```ts

import { Parent, ResolveField, Resolver } from '@nestjs/graphql';
import { PostsService } from './posts.service.js';
import { Post } from './post.entity.js';
import { User } from './user.entity.js';

@Resolver(() => User)
export class UsersResolver {
  constructor(private readonly postsService: PostsService) {}

  @ResolveField(() => [Post])
  public posts(@Parent() user: User): Post[] {
    return this.postsService.forAuthor(user.id);
  }
}
```

Then define the `Post` entity class:

```ts

import { Directive, Field, ID, Int, ObjectType } from '@nestjs/graphql';
import { User } from './user.entity.js';

@ObjectType()
@Directive('@key(fields: "id")')
export class Post {
  @Field(() => ID)
  id: number;

  @Field()
  title: string;

  @Field(() => Int)
  authorId: number;

  @Field(() => User)
  user?: User;
}
```

And its resolver:

```ts

import { Query, Args, ResolveField, Resolver, Parent } from '@nestjs/graphql';
import { PostsService } from './posts.service.js';
import { Post } from './post.entity.js';
import { User } from './user.entity.js';

@Resolver(() => Post)
export class PostsResolver {
  constructor(private readonly postsService: PostsService) {}

  @Query(() => Post)
  findPost(@Args('id') id: number): Post {
    return this.postsService.findOne(id);
  }

  @Query(() => [Post])
  getPosts(): Post[] {
    return this.postsService.all();
  }

  @ResolveField(() => User)
  user(@Parent() post: Post): any {
    return { __typename: 'User', id: post.authorId };
  }
}
```

Finally, tie everything together in a module. Note the schema build options, which specify that `User` is an orphaned (external) type.

```ts

import {
  ApolloFederationDriver,
  ApolloFederationDriverConfig,
} from '@nestjs/apollo';
import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';
import { User } from './user.entity.js';
import { PostsResolver } from './posts.resolver.js';
import { UsersResolver } from './users.resolver.js';
import { PostsService } from './posts.service.js'; // Not included in this example

@Module({
  imports: [
    GraphQLModule.forRoot<ApolloFederationDriverConfig>({
      driver: ApolloFederationDriver,
      autoSchemaFile: true,
      buildSchemaOptions: {
        orphanedTypes: [User],
      },
    }),
  ],
  providers: [PostsResolver, UsersResolver, PostsService],
})
export class AppModule {}
```

Working examples are available for the [code first](https://github.com/nestjs/nest/tree/master/sample/31-graphql-federation-code-first/posts-application) and [schema first](https://github.com/nestjs/nest/tree/master/sample/32-graphql-federation-schema-first/posts-application) approaches.

#### Federated example: Gateway[#](/graphql/federation#federated-example-gateway)

Start by installing the required dependency:

```bash

$ npm install --save @apollo/gateway
```

The gateway requires a list of endpoints, and it discovers the corresponding schemas automatically. Therefore, the gateway implementation is the same for both the code first and schema first approaches.

```typescript

import { IntrospectAndCompose } from '@apollo/gateway';
import { ApolloGatewayDriver, ApolloGatewayDriverConfig } from '@nestjs/apollo';
import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';

@Module({
  imports: [
    GraphQLModule.forRoot<ApolloGatewayDriverConfig>({
      driver: ApolloGatewayDriver,
      server: {
        // ... Apollo Server options
      },
      gateway: {
        supergraphSdl: new IntrospectAndCompose({
          subgraphs: [
            { name: 'users', url: 'http://user-service/graphql' },
            { name: 'posts', url: 'http://post-service/graphql' },
          ],
        }),
      },
    }),
  ],
})
export class AppModule {}
```

Working examples are available for the [code first](https://github.com/nestjs/nest/tree/master/sample/31-graphql-federation-code-first/gateway) and [schema first](https://github.com/nestjs/nest/tree/master/sample/32-graphql-federation-schema-first/gateway) approaches.

#### Federation with Mercurius[#](/graphql/federation#federation-with-mercurius)

Start by installing the required dependencies:

```bash

$ npm install --save @apollo/subgraph @nestjs/mercurius
```

> **Note** The `@apollo/subgraph` package is required to build a subgraph schema (the `buildSubgraphSchema` and `printSubgraphSchema` functions).

#### Schema first[#](/graphql/federation#schema-first-2)

The Users service provides a simple schema. The `@key` directive tells the Mercurius query planner that a particular instance of `User` can be fetched by its `id`. Also note that the schema extends the `Query` type.

```graphql

type User @key(fields: "id") {
  id: ID!
  name: String!
}

extend type Query {
  getUser(id: ID!): User
}
```

The resolver provides one additional method named `resolveReference()`. The Mercurius gateway calls this method whenever a related resource requires a `User` instance. You'll see an example of this in the Posts service later. The method must be annotated with the `@ResolveReference()` decorator.

```typescript

import { Args, Query, Resolver, ResolveReference } from '@nestjs/graphql';
import { UsersService } from './users.service.js';

@Resolver('User')
export class UsersResolver {
  constructor(private usersService: UsersService) {}

  @Query()
  getUser(@Args('id') id: string) {
    return this.usersService.findById(id);
  }

  @ResolveReference()
  resolveReference(reference: { __typename: string; id: string }) {
    return this.usersService.findById(reference.id);
  }
}
```

Finally, wire everything up by registering the `GraphQLModule` with the `MercuriusFederationDriver` driver in the configuration object:

```typescript

import {
  MercuriusFederationDriver,
  MercuriusFederationDriverConfig,
} from '@nestjs/mercurius';
import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';
import { UsersResolver } from './users.resolver.js';

@Module({
  imports: [
    GraphQLModule.forRoot<MercuriusFederationDriverConfig>({
      driver: MercuriusFederationDriver,
      typePaths: ['**/*.graphql'],
    }),
  ],
  providers: [UsersResolver],
})
export class AppModule {}
```

#### Code first[#](/graphql/federation#code-first-2)

Start by adding some extra decorators to the `User` entity:

```ts

import { Directive, Field, ID, ObjectType } from '@nestjs/graphql';

@ObjectType()
@Directive('@key(fields: "id")')
export class User {
  @Field(() => ID)
  id: number;

  @Field()
  name: string;
}
```

The resolver provides one additional method named `resolveReference()`. The Mercurius gateway calls this method whenever a related resource requires a `User` instance. You'll see an example of this in the Posts service later. The method must be annotated with the `@ResolveReference()` decorator.

```ts

import { Args, Query, Resolver, ResolveReference } from '@nestjs/graphql';
import { User } from './user.entity.js';
import { UsersService } from './users.service.js';

@Resolver(() => User)
export class UsersResolver {
  constructor(private usersService: UsersService) {}

  @Query(() => User)
  getUser(@Args('id') id: number): User {
    return this.usersService.findById(id);
  }

  @ResolveReference()
  resolveReference(reference: { __typename: string; id: number }): User {
    return this.usersService.findById(reference.id);
  }
}
```

Finally, wire everything up by registering the `GraphQLModule` with the `MercuriusFederationDriver` driver in the configuration object:

```typescript

import {
  MercuriusFederationDriver,
  MercuriusFederationDriverConfig,
} from '@nestjs/mercurius';
import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';
import { UsersResolver } from './users.resolver.js';
import { UsersService } from './users.service.js'; // Not included in this example

@Module({
  imports: [
    GraphQLModule.forRoot<MercuriusFederationDriverConfig>({
      driver: MercuriusFederationDriver,
      autoSchemaFile: true,
    }),
  ],
  providers: [UsersResolver, UsersService],
})
export class AppModule {}
```

#### Federated example: Posts[#](/graphql/federation#federated-example-posts-1)

The Posts service serves aggregated posts through the `getPosts` query, and also extends the `User` type with a `user.posts` field.

#### Schema first[#](/graphql/federation#schema-first-3)

The Posts service references the `User` type in its schema by marking it with the `extend` keyword. It also declares one additional field on the `User` type (`posts`). Note the `@key` directive, used to match `User` instances, and the `@external` directive, which indicates that the `id` field is managed elsewhere.

```graphql

type Post @key(fields: "id") {
  id: ID!
  title: String!
  body: String!
  user: User
}

extend type User @key(fields: "id") {
  id: ID! @external
  posts: [Post]
}

extend type Query {
  getPosts: [Post]
}
```

In the following example, the `PostsResolver` provides a `getUser()` method that returns a reference containing `__typename` plus any additional properties your application needs to resolve the reference, in this case `id`. The gateway uses `__typename` to pinpoint the microservice responsible for the `User` type and retrieve the corresponding instance. To resolve the reference, the gateway sends a request to the Users service described above, which executes its `resolveReference()` method.

```typescript

import { Query, Resolver, Parent, ResolveField } from '@nestjs/graphql';
import { PostsService } from './posts.service.js';
import type { Post } from './posts.interfaces.js';

@Resolver('Post')
export class PostsResolver {
  constructor(private postsService: PostsService) {}

  @Query('getPosts')
  getPosts() {
    return this.postsService.findAll();
  }

  @ResolveField('user')
  getUser(@Parent() post: Post) {
    return { __typename: 'User', id: post.userId };
  }
}
```

Lastly, register the `GraphQLModule`, as in the Users service.

```typescript

import {
  MercuriusFederationDriver,
  MercuriusFederationDriverConfig,
} from '@nestjs/mercurius';
import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';
import { PostsResolver } from './posts.resolver.js';

@Module({
  imports: [
    GraphQLModule.forRoot<MercuriusFederationDriverConfig>({
      driver: MercuriusFederationDriver,
      typePaths: ['**/*.graphql'],
    }),
  ],
  providers: [PostsResolver],
})
export class AppModule {}
```

#### Code first[#](/graphql/federation#code-first-3)

First, declare a class representing the `User` entity. Although the entity itself lives in another service, this service uses it (and extends its definition). Note the `@extends` and `@external` directives.

```ts

import { Directive, ObjectType, Field, ID } from '@nestjs/graphql';
import { Post } from './post.entity.js';

@ObjectType()
@Directive('@extends')
@Directive('@key(fields: "id")')
export class User {
  @Field(() => ID)
  @Directive('@external')
  id: number;

  @Field(() => [Post])
  posts?: Post[];
}
```

Next, create the resolver for the extension of the `User` entity:

```ts

import { Parent, ResolveField, Resolver } from '@nestjs/graphql';
import { PostsService } from './posts.service.js';
import { Post } from './post.entity.js';
import { User } from './user.entity.js';

@Resolver(() => User)
export class UsersResolver {
  constructor(private readonly postsService: PostsService) {}

  @ResolveField(() => [Post])
  public posts(@Parent() user: User): Post[] {
    return this.postsService.forAuthor(user.id);
  }
}
```

Then define the `Post` entity class:

```ts

import { Directive, Field, ID, Int, ObjectType } from '@nestjs/graphql';
import { User } from './user.entity.js';

@ObjectType()
@Directive('@key(fields: "id")')
export class Post {
  @Field(() => ID)
  id: number;

  @Field()
  title: string;

  @Field(() => Int)
  authorId: number;

  @Field(() => User)
  user?: User;
}
```

And its resolver:

```ts

import { Query, Args, ResolveField, Resolver, Parent } from '@nestjs/graphql';
import { PostsService } from './posts.service.js';
import { Post } from './post.entity.js';
import { User } from './user.entity.js';

@Resolver(() => Post)
export class PostsResolver {
  constructor(private readonly postsService: PostsService) {}

  @Query(() => Post)
  findPost(@Args('id') id: number): Post {
    return this.postsService.findOne(id);
  }

  @Query(() => [Post])
  getPosts(): Post[] {
    return this.postsService.all();
  }

  @ResolveField(() => User)
  user(@Parent() post: Post): any {
    return { __typename: 'User', id: post.authorId };
  }
}
```

Finally, tie everything together in a module. Note the schema build options, which specify that `User` is an orphaned (external) type.

```ts

import {
  MercuriusFederationDriver,
  MercuriusFederationDriverConfig,
} from '@nestjs/mercurius';
import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';
import { User } from './user.entity.js';
import { PostsResolver } from './posts.resolver.js';
import { UsersResolver } from './users.resolver.js';
import { PostsService } from './posts.service.js'; // Not included in this example

@Module({
  imports: [
    GraphQLModule.forRoot<MercuriusFederationDriverConfig>({
      driver: MercuriusFederationDriver,
      autoSchemaFile: true,
      buildSchemaOptions: {
        orphanedTypes: [User],
      },
    }),
  ],
  providers: [PostsResolver, UsersResolver, PostsService],
})
export class AppModule {}
```

#### Federated example: Gateway[#](/graphql/federation#federated-example-gateway-1)

Start by installing the required dependency:

```bash

$ npm install --save @mercuriusjs/gateway
```

The gateway requires a list of endpoints, and it discovers the corresponding schemas automatically. Therefore, the gateway implementation is the same for both the code first and schema first approaches.

```typescript

import {
  MercuriusGatewayDriver,
  MercuriusGatewayDriverConfig,
} from '@nestjs/mercurius';
import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';

@Module({
  imports: [
    GraphQLModule.forRoot<MercuriusGatewayDriverConfig>({
      driver: MercuriusGatewayDriver,
      gateway: {
        services: [
          { name: 'users', url: 'http://user-service/graphql' },
          { name: 'posts', url: 'http://post-service/graphql' },
        ],
      },
    }),
  ],
})
export class AppModule {}
```

### Federation 2

According to the [Apollo docs](https://www.apollographql.com/docs/federation/federation-2/new-in-federation-2), Federation 2 improves the developer experience of the original Apollo Federation (called Federation 1 in this section) and is backward compatible with most original supergraphs.

> **Warning** Mercurius doesn't fully support Federation 2. See Apollo's list of [subgraph libraries that support Federation 2](https://www.apollographql.com/docs/federation/supported-subgraphs#javascript--typescript).

In the following sections, we'll upgrade the previous example to Federation 2.

#### Federated example: Users[#](/graphql/federation#federated-example-users)

In Federation 2, entities have no originating subgraph, so you no longer need to extend `Query`. For more details, see the [entities topic](https://www.apollographql.com/docs/federation/federation-2/new-in-federation-2#entities) in the Apollo Federation 2 docs.

#### Schema first[#](/graphql/federation#schema-first-4)

Remove the `extend` keyword from the schema. To opt in to Federation 2, the schema must also import the federation directives it uses with the `@link` directive:

```graphql

extend schema @link(url: "https://specs.apollo.dev/federation/v2.0", import: ["@key"])

type User @key(fields: "id") {
  id: ID!
  name: String!
}

type Query {
  getUser(id: ID!): User
}
```

#### Code first[#](/graphql/federation#code-first-4)

To use Federation 2, specify the federation version in the `autoSchemaFile` option. Nest then adds the `@link` directive to the generated schema for you.

```ts

import {
  ApolloFederationDriver,
  ApolloFederationDriverConfig,
} from '@nestjs/apollo';
import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';
import { UsersResolver } from './users.resolver.js';
import { UsersService } from './users.service.js'; // Not included in this example

@Module({
  imports: [
    GraphQLModule.forRoot<ApolloFederationDriverConfig>({
      driver: ApolloFederationDriver,
      autoSchemaFile: {
        federation: 2,
      },
    }),
  ],
  providers: [UsersResolver, UsersService],
})
export class AppModule {}
```

#### Federated example: Posts[#](/graphql/federation#federated-example-posts-2)

For the same reason, you no longer need to extend `User` and `Query`.

#### Schema first[#](/graphql/federation#schema-first-5)

Remove the `extend` keyword and the `@external` directive from the schema, and add the `@link` directive:

```graphql

extend schema @link(url: "https://specs.apollo.dev/federation/v2.0", import: ["@key"])

type Post @key(fields: "id") {
  id: ID!
  title: String!
  body: String!
  user: User
}

type User @key(fields: "id") {
  id: ID!
  posts: [Post]
}

type Query {
  getPosts: [Post]
}
```

#### Code first[#](/graphql/federation#code-first-5)

Because the `User` entity is no longer extended, remove the `@extends` and `@external` directives from `User`:

```ts

import { Directive, ObjectType, Field, ID } from '@nestjs/graphql';
import { Post } from './post.entity.js';

@ObjectType()
@Directive('@key(fields: "id")')
export class User {
  @Field(() => ID)
  id: number;

  @Field(() => [Post])
  posts?: Post[];
}
```

As in the Users service, configure the `GraphQLModule` to use Federation 2:

```ts

import {
  ApolloFederationDriver,
  ApolloFederationDriverConfig,
} from '@nestjs/apollo';
import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';
import { User } from './user.entity.js';
import { PostsResolver } from './posts.resolver.js';
import { UsersResolver } from './users.resolver.js';
import { PostsService } from './posts.service.js'; // Not included in this example

@Module({
  imports: [
    GraphQLModule.forRoot<ApolloFederationDriverConfig>({
      driver: ApolloFederationDriver,
      autoSchemaFile: {
        federation: 2,
      },
      buildSchemaOptions: {
        orphanedTypes: [User],
      },
    }),
  ],
  providers: [PostsResolver, UsersResolver, PostsService],
})
export class AppModule {}
```

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/federation.md)

----
url: https://docs.nestjs.com/v11
----

* [Introduction](https://docs.nestjs.com/v11/#introduction)
* [Philosophy](https://docs.nestjs.com/v11/#philosophy)
* [Installation](https://docs.nestjs.com/v11/#installation)
* [Alternatives](https://docs.nestjs.com/v11/#alternatives)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/introduction.md "Suggest Edits")

### Introduction

Nest (NestJS) is a framework for building efficient, scalable [Node.js](https://nodejs.org/) server-side applications. It uses progressive JavaScript, is built with and fully supports [TypeScript](http://www.typescriptlang.org/) (yet still enables developers to code in pure JavaScript) and combines elements of OOP (Object Oriented Programming), FP (Functional Programming), and FRP (Functional Reactive Programming).

Under the hood, Nest makes use of robust HTTP Server frameworks like [Express](https://expressjs.com/) (the default) and optionally can be configured to use [Fastify](https://github.com/fastify/fastify) as well!

Nest provides a level of abstraction above these common Node.js frameworks (Express/Fastify), but also exposes their APIs directly to the developer. This gives developers the freedom to use the myriad of third-party modules which are available for the underlying platform.

#### Philosophy[#](/#philosophy)

In recent years, thanks to Node.js, JavaScript has become the “lingua franca” of the web for both front and backend applications. This has given rise to awesome projects like [Angular](https://angular.dev/), [React](https://github.com/facebook/react) and [Vue](https://github.com/vuejs/core), which improve developer productivity and enable the creation of fast, testable, and extensible frontend applications. However, while plenty of superb libraries, helpers, and tools exist for Node (and server-side JavaScript), none of them effectively solve the main problem of **architecture**.

Nest provides an out-of-the-box application architecture which allows developers and teams to create highly testable, scalable, loosely coupled, and easily maintainable applications. The architecture is heavily inspired by Angular.

#### Installation[#](/#installation)

To get started, you can either scaffold the project with the [Nest CLI](/v11/cli/overview), or [clone a starter project](#alternatives) (both will produce the same outcome).

To scaffold the project with the Nest CLI, run the following commands. This will create a new project directory, and populate the directory with the initial core Nest files and supporting modules, creating a conventional base structure for your project. Creating a new project with the **Nest CLI** is recommended for first-time users. We'll continue with this approach in [First Steps](/v11/first-steps).

```bash

$ npm i -g @nestjs/cli
$ nest new project-name
```

> **Hint** To create a new TypeScript project with stricter feature set, pass the `--strict` flag to the `nest new` command.

#### Alternatives[#](/#alternatives)

Alternatively, to install the TypeScript starter project with **Git**:

```bash

$ git clone https://github.com/nestjs/typescript-starter.git project
$ cd project
$ npm install
$ npm run start
```

> **Hint** If you'd like to clone the repository without the git history, you can use [degit](https://github.com/Rich-Harris/degit).

Open your browser and navigate to [`http://localhost:3000/`](http://localhost:3000/).

To install the JavaScript flavor of the starter project, use `javascript-starter.git` in the command sequence above.

You can also start a new project from scratch by installing the core and supporting packages. Keep in mind that you'll need to set up the project boilerplate files on your own. At a minimum, you'll need these dependencies: `@nestjs/core`, `@nestjs/common`, `rxjs`, and `reflect-metadata`. Check out this short article on how to create a complete project: [5 steps to create a bare minimum NestJS app from scratch!](https://dev.to/micalevisk/5-steps-to-create-a-bare-minimum-nestjs-app-from-scratch-5c3b).

----
url: https://docs.nestjs.com/v10/cli/monorepo
----

* [Workspaces](https://docs.nestjs.com/v10/cli/monorepo#workspaces)
* [Standard mode](https://docs.nestjs.com/v10/cli/monorepo#standard-mode)
* [Monorepo mode](https://docs.nestjs.com/v10/cli/monorepo#monorepo-mode)
* [Workspace projects](https://docs.nestjs.com/v10/cli/monorepo#workspace-projects)
* [Applications](https://docs.nestjs.com/v10/cli/monorepo#applications)
* [Libraries](https://docs.nestjs.com/v10/cli/monorepo#libraries)
* [CLI properties](https://docs.nestjs.com/v10/cli/monorepo#cli-properties)
* [Global compiler options](https://docs.nestjs.com/v10/cli/monorepo#global-compiler-options)
* [Global generate options](https://docs.nestjs.com/v10/cli/monorepo#global-generate-options)
* [Project-specific generate options](https://docs.nestjs.com/v10/cli/monorepo#project-specific-generate-options)
* [Specified compiler](https://docs.nestjs.com/v10/cli/monorepo#specified-compiler)
* [Webpack options](https://docs.nestjs.com/v10/cli/monorepo#webpack-options)
* [Assets](https://docs.nestjs.com/v10/cli/monorepo#assets)
* [Project properties](https://docs.nestjs.com/v10/cli/monorepo#project-properties)

```bash

$ nest new my-project
```

```bash

$ cd my-project
$ nest generate app my-app
```

> **Warning** The conversion of a standard mode structure to monorepo only works for projects that have followed the canonical Nest project structure. Specifically, during conversion, the schematic attempts to relocate the `src` and `test` folders in a project folder beneath the `apps` folder in the root. If a project does not use this structure, the conversion will fail or produce unreliable results.

#### Workspace projects[#](/cli/monorepo#workspace-projects)

A monorepo uses the concept of a workspace to manage its member entities. Workspaces are composed of **projects**. A project may be either:

* an **application**: a full Nest application including a `main.ts` file to bootstrap the application. Aside from compile and build considerations, an application-type project within a workspace is functionally identical to an application within a *standard mode* structure.
* a **library**: a library is a way of packaging a general purpose set of features (modules, providers, controllers, etc.) that can be used within other projects. A library cannot run on its own, and has no `main.ts` file. Read more about libraries [here](/v10/cli/libraries).

All workspaces have a **default project** (which should be an application-type project). This is defined by the top-level `"root"` property in the `nest-cli.json` file, which points at the root of the default project (see [CLI properties](/cli/monorepo#cli-properties) below for more details). Usually, this is the **standard mode** application you started with, and later converted to a monorepo using `nest generate app`. When you follow these steps, this property is populated automatically.

Default projects are used by `nest` commands like `nest build` and `nest start` when a project name is not supplied.

For example, in the above monorepo structure, running

```bash

$ nest start
```

will start up the `my-project` app. To start `my-app`, we'd use:

```bash

$ nest start my-app
```

#### Applications[#](/cli/monorepo#applications)

Application-type projects, or what we might informally refer to as just "applications", are complete Nest applications that you can run and deploy. You generate an application-type project with `nest generate app`.

This command automatically generates a project skeleton, including the standard `src` and `test` folders from the [typescript starter](https://github.com/nestjs/typescript-starter). Unlike standard mode, an application project in a monorepo does not have any of the package dependency (`package.json`) or other project configuration artifacts like `.prettierrc` and `.eslintrc.js`. Instead, the monorepo-wide dependencies and config files are used.

However, the schematic does generate a project-specific `tsconfig.app.json` file in the root folder of the project. This config file automatically sets appropriate build options, including setting the compilation output folder properly. The file extends the top-level (monorepo) `tsconfig.json` file, so you can manage global settings monorepo-wide, but override them if needed at the project level.

#### Libraries[#](/cli/monorepo#libraries)

As mentioned, library-type projects, or simply "libraries", are packages of Nest components that need to be composed into applications in order to run. You generate a library-type project with `nest generate library`. Deciding what belongs in a library is an architectural design decision. We discuss libraries in depth in the [libraries](/v10/cli/libraries) chapter.

#### CLI properties[#](/cli/monorepo#cli-properties)

Nest keeps the metadata needed to organize, build and deploy both standard and monorepo structured projects in the `nest-cli.json` file. Nest automatically adds to and updates this file as you add projects, so you usually do not have to think about it or edit its contents. However, there are some settings you may want to change manually, so it's helpful to have an overview understanding of the file.

After running the steps above to create a monorepo, our `nest-cli.json` file looks like this:

```javascript

{
  "collection": "@nestjs/schematics",
  "sourceRoot": "apps/my-project/src",
  "monorepo": true,
  "root": "apps/my-project",
  "compilerOptions": {
    "webpack": true,
    "tsConfigPath": "apps/my-project/tsconfig.app.json"
  },
  "projects": {
    "my-project": {
      "type": "application",
      "root": "apps/my-project",
      "entryFile": "main",
      "sourceRoot": "apps/my-project/src",
      "compilerOptions": {
        "tsConfigPath": "apps/my-project/tsconfig.app.json"
      }
    },
    "my-app": {
      "type": "application",
      "root": "apps/my-app",
      "entryFile": "main",
      "sourceRoot": "apps/my-app/src",
      "compilerOptions": {
        "tsConfigPath": "apps/my-app/tsconfig.app.json"
      }
    }
  }
}
```

| Property Name       | Property Value Type | Description                                                                                                                                                                                                                                                               |
| ------------------- | ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `webpack`           | boolean             | If `true`, use [webpack compiler](https://webpack.js.org/). If `false` or not present, use `tsc`. In monorepo mode, the default is `true` (use webpack), in standard mode, the default is `false` (use `tsc`). See below for details. (deprecated: use `builder` instead) |
| `tsConfigPath`      | string              | (**monorepo only**) Points at the file containing the `tsconfig.json` settings that will be used when `nest build` or `nest start` is called without a `project` option (e.g., when the default project is built or started).                                             |
| `webpackConfigPath` | string              | Points at a webpack options file. If not specified, Nest looks for the file `webpack.config.js`. See below for more details.                                                                                                                                              |
| `deleteOutDir`      | boolean             | If `true`, whenever the compiler is invoked, it will first remove the compilation output directory (as configured in `tsconfig.json`, where the default is `./dist`).                                                                                                     |
| `assets`            | array               | Enables automatically distributing non-TypeScript assets whenever a compilation step begins (asset distribution does **not** happen on incremental compiles in `--watch` mode). See below for details.                                                                    |
| `watchAssets`       | boolean             | If `true`, run in watch-mode, watching **all** non-TypeScript assets. (For more fine-grained control of the assets to watch, see [Assets](cli/monorepo#assets) section below).                                                                                            |
| `manualRestart`     | boolean             | If `true`, enables the shortcut `rs` to manually restart the server. Default value is `false`.                                                                                                                                                                            |
| `builder`           | string/object       | Instructs CLI on what `builder` to use to compile the project (`tsc`, `swc`, or `webpack`). To customize builder's behavior, you can pass an object containing two attributes: `type` (`tsc`, `swc`, or `webpack`) and `options`.                                         |
| `typeCheck`         | boolean             | If `true`, enables type checking for SWC-driven projects (when `builder` is `swc`). Default value is `false`.                                                                                                                                                             |

#### Global generate options[#](/cli/monorepo#global-generate-options)

These properties specify the default generate options to be used by the `nest generate` command.

| Property Name | Property Value Type | Description                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| ------------- | ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `spec`        | boolean *or* object | If the value is boolean, a value of `true` enables `spec` generation by default and a value of `false` disables it. A flag passed on the CLI command line overrides this setting, as does a project-specific `generateOptions` setting (more below). If the value is an object, each key represents a schematic name, and the boolean value determines whether the default spec generation is enabled / disabled for that specific schematic. |
| `flat`        | boolean             | If true, all generate commands will generate a flat structure                                                                                                                                                                                                                                                                                                                                                                                 |

The following example uses a boolean value to specify that spec file generation should be disabled by default for all projects:

```javascript

{
  "generateOptions": {
    "spec": false
  },
  ...
}
```

The following example uses a boolean value to specify flat file generation should be the default for all projects:

```javascript

{
  "generateOptions": {
    "flat": true
  },
  ...
}
```

In the following example, `spec` file generation is disabled only for `service` schematics (e.g., `nest generate service...`):

```javascript

{
  "generateOptions": {
    "spec": {
      "service": false
    }
  },
  ...
}
```

> **Warning** When specifying the `spec` as an object, the key for the generation schematic does not currently support automatic alias handling. This means that specifying a key as for example `service: false` and trying to generate a service via the alias `s`, the spec would still be generated. To make sure both the normal schematic name and the alias work as intended, specify both the normal command name as well as the alias, as seen below.
>
> ```javascript
>
> {
>   "generateOptions": {
>     "spec": {
>       "service": false,
>       "s": false
>     }
>   },
>   ...
> }
> ```

#### Project-specific generate options[#](/cli/monorepo#project-specific-generate-options)

In addition to providing global generate options, you may also specify project-specific generate options. The project specific generate options follow the exact same format as the global generate options, but are specified directly on each project.

Project-specific generate options override global generate options.

```javascript

{
  "projects": {
    "cats-project": {
      "generateOptions": {
        "spec": {
          "service": false
        }
      },
      ...
    }
  },
  ...
}
```

> **Warning** The order of precedence for generate options is as follows. Options specified on the CLI command line take precedence over project-specific options. Project-specific options override global options.

#### Specified compiler[#](/cli/monorepo#specified-compiler)

The reason for the different default compilers is that for larger projects (e.g., more typical in a monorepo) webpack can have significant advantages in build times and in producing a single file bundling all project components together. If you wish to generate individual files, set `"webpack"` to `false`, which will cause the build process to use `tsc` (or `swc`).

#### Webpack options[#](/cli/monorepo#webpack-options)

The webpack options file can contain standard [webpack configuration options](https://webpack.js.org/configuration/). For example, to tell webpack to bundle `node_modules` (which are excluded by default), add the following to `webpack.config.js`:

```javascript

module.exports = {
  externals: [],
};
```

Since the webpack config file is a JavaScript file, you can even expose a function that takes default options and returns a modified object:

```javascript

module.exports = function (options) {
  return {
    ...options,
    externals: [],
  };
};
```

#### Assets[#](/cli/monorepo#assets)

TypeScript compilation automatically distributes compiler output (`.js` and `.d.ts` files) to the specified output directory. It can also be convenient to distribute non-TypeScript files, such as `.graphql` files, `images`, `.html` files and other assets. This allows you to treat `nest build` (and any initial compilation step) as a lightweight **development build** step, where you may be editing non-TypeScript files and iteratively compiling and testing. The assets should be located in the `src` folder otherwise they will not be copied.

The value of the `assets` key should be an array of elements specifying the files to be distributed. The elements can be simple strings with `glob`-like file specs, for example:

```typescript

"assets": ["**/*.graphql"],
"watchAssets": true,
```

For finer control, the elements can be objects with the following keys:

* `"include"`: `glob`-like file specifications for the assets to be distributed
* `"exclude"`: `glob`-like file specifications for assets to be **excluded** from the `include` list
* `"outDir"`: a string specifying the path (relative to the root folder) where the assets should be distributed. Defaults to the same output directory configured for compiler output.
* `"watchAssets"`: boolean; if `true`, run in watch mode watching specified assets

For example:

```typescript

"assets": [
  { "include": "**/*.graphql", "exclude": "**/omitted.graphql", "watchAssets": true },
]
```

> **Warning** Setting `watchAssets` in a top-level `compilerOptions` property overrides any `watchAssets` settings within the `assets` property.

#### Project properties[#](/cli/monorepo#project-properties)

This element exists only for monorepo-mode structures. You generally should not edit these properties, as they are used by Nest to locate projects and their configuration options within the monorepo.

----
url: https://docs.nestjs.com/v7/microservices/mqtt
----

* [MQTT](https://docs.nestjs.com/v7/microservices/mqtt#mqtt)
* [Installation](https://docs.nestjs.com/v7/microservices/mqtt#installation)
* [Overview](https://docs.nestjs.com/v7/microservices/mqtt#overview)
* [Options](https://docs.nestjs.com/v7/microservices/mqtt#options)
* [Client](https://docs.nestjs.com/v7/microservices/mqtt#client)
* [Context](https://docs.nestjs.com/v7/microservices/mqtt#context)
* [Wildcards](https://docs.nestjs.com/v7/microservices/mqtt#wildcards)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/microservices/mqtt.md "Suggest Edits")

### MQTT

[MQTT](https://mqtt.org/) (Message Queuing Telemetry Transport) is an open source, lightweight messaging protocol, optimized for high-latency. This protocol provides a scalable and cost-efficient way to connect devices using a **publish/subscribe** model. A communication system built on MQTT consists of the publishing server, a broker and one or more clients. It is designed for constrained devices and low-bandwidth, high-latency or unreliable networks.

#### Installation[#](/microservices/mqtt#installation)

To start building MQTT-based microservices, first install the required package:

```bash

$ npm i --save mqtt
```

#### Overview[#](/microservices/mqtt#overview)

To use the MQTT transporter, pass the following options object to the `createMicroservice()` method:

main.ts

JS TS

```typescript

const app = await NestFactory.createMicroservice<MicroserviceOptions>(AppModule, {
  transport: Transport.MQTT,
  options: {
    url: 'mqtt://localhost:1883',
  },
});
```

```typescript

const app = await NestFactory.createMicroservice(AppModule, {
  transport: Transport.MQTT,
  options: {
    url: 'mqtt://localhost:1883',
  },
});
```

> **Hint** The `Transport` enum is imported from the `@nestjs/microservices` package.

#### Options[#](/microservices/mqtt#options)

The `options` object is specific to the chosen transporter. The **MQTT** transporter exposes the properties described [here](https://github.com/mqttjs/MQTT.js/#mqttclientstreambuilder-options).

#### Client[#](/microservices/mqtt#client)

Like other microservice transporters, you have [several options](https://docs.nestjs.com/microservices/basics#client) for creating a MQTT `ClientProxy` instance.

One method for creating an instance is to use use the `ClientsModule`. To create a client instance with the `ClientsModule`, import it and use the `register()` method to pass an options object with the same properties shown above in the `createMicroservice()` method, as well as a `name` property to be used as the injection token. Read more about `ClientsModule`[here](https://docs.nestjs.com/microservices/basics#client).

```typescript

@Module({
  imports: [
    ClientsModule.register([
      {
        name: 'MATH_SERVICE',
        transport: Transport.MQTT,
        options: {
          url: 'mqtt://localhost:1883',
        }
      },
    ]),
  ]
  ...
})
```

Other options to create a client (either `ClientProxyFactory` or `@Client()`) can be used as well. You can read about them [here](https://docs.nestjs.com/microservices/basics#client).

#### Context[#](/microservices/mqtt#context)

In more sophisticated scenarios, you may want to access more information about the incoming request. When using the MQTT transporter, you can access the `MqttContext` object.

JS TS

```typescript

@MessagePattern('notifications')
getNotifications(@Payload() data: number[], @Ctx() context: MqttContext) {
  console.log(`Topic: ${context.getTopic()}`);
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('notifications')
getNotifications(data, context) {
  console.log(`Topic: ${context.getTopic()}`);
}
```

> **Hint**`@Payload()`, `@Ctx()` and `MqttContext` are imported from the `@nestjs/microservices` package.

To access the original mqtt [packet](https://github.com/mqttjs/mqtt-packet), use the `getPacket()` method of the `MqttContext` object, as follows:

JS TS

```typescript

@MessagePattern('notifications')
getNotifications(@Payload() data: number[], @Ctx() context: MqttContext) {
  console.log(context.getPacket());
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('notifications')
getNotifications(data, context) {
  console.log(context.getPacket());
}
```

#### Wildcards[#](/microservices/mqtt#wildcards)

A subscription may be to an explicit topic, or it may include wildcards. Two wildcards are available, `+` and `#`. `+` is a single-level wildcard, while `#` is a multi-level wildcard which covers many topic levels.

JS TS

```typescript

@MessagePattern('sensors/+/temperature/+')
getTemperature(@Ctx() context: MqttContext) {
  console.log(`Topic: ${context.getTopic()}`);
}
```

```typescript

@Bind(Ctx())
@MessagePattern('sensors/+/temperature/+')
getTemperature(context) {
  console.log(`Topic: ${context.getTopic()}`);
}
```

----
url: https://docs.nestjs.com/v6/techniques/http-module
----

* [HTTP module](https://docs.nestjs.com/v6/techniques/http-module#http-module)
* [Configuration](https://docs.nestjs.com/v6/techniques/http-module#configuration)
* [Async configuration](https://docs.nestjs.com/v6/techniques/http-module#async-configuration)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/techniques/http-module.md "Suggest Edits")

### HTTP module

[Axios](https://github.com/axios/axios) is richly featured HTTP client package that is widely used. Nest wraps Axios and exposes it via the built-in `HttpModule`. The `HttpModule` exports the `HttpService` class, which exposes Axios-based methods to perform HTTP requests. The library also transforms the resulting HTTP responses into `Observables`.

To use the `HttpService`, first import `HttpModule`.

```typescript

@Module({
  imports: [HttpModule],
  providers: [CatsService],
})
export class CatsModule {}
```

Next, inject `HttpService` using normal constructor injection.

> **Hint**`HttpModule` and `HttpService` are imported from `@nestjs/common` package.

JS TS

```typescript

@Injectable()
export class CatsService {
  constructor(private readonly httpService: HttpService) {}

  findAll(): Observable<AxiosResponse<Cat[]>> {
    return this.httpService.get('http://localhost:3000/cats');
  }
}
```

```typescript

@Injectable()
@Dependencies(HttpService)
export class CatsService {
  constructor(httpService) {
    this.httpService = httpService;
  }

  findAll() {
    return this.httpService.get('http://localhost:3000/cats');
  }
}
```

All `HttpService` methods return an `AxiosResponse` wrapped in an `Observable` object.

#### Configuration[#](/techniques/http-module#configuration)

[Axios](https://github.com/axios/axios) can be configured with a variety of options to customize the behavior of the `HttpService`. Read more about them [here](https://github.com/axios/axios#request-config). To configure the underlying Axios instance, pass an optional options object to the `register()` method of `HttpModule` when importing it. This options object will be passed directly to the underlying Axios constructor.

```typescript

@Module({
  imports: [
    HttpModule.register({
      timeout: 5000,
      maxRedirects: 5,
    }),
  ],
  providers: [CatsService],
})
export class CatsModule {}
```

#### Async configuration[#](/techniques/http-module#async-configuration)

When you need to pass module options asynchronously instead of statically, use the `registerAsync()` method. As with most dynamic modules, Nest provides several techniques to deal with async configuration.

One technique is to use a factory function:

```typescript

HttpModule.registerAsync({
  useFactory: () => ({
    timeout: 5000,
    maxRedirects: 5,
  }),
});
```

Like other factory providers, our factory function can be [async](https://docs.nestjs.com/fundamentals/custom-providers#factory-providers-usefactory) and can inject dependencies through `inject`.

```typescript

HttpModule.registerAsync({
  imports: [ConfigModule],
  useFactory: async (configService: ConfigService) => ({
    timeout: configService.getString('HTTP_TIMEOUT'),
    maxRedirects: configService.getString('HTTP_MAX_REDIRECTS'),
  }),
  inject: [ConfigService],
});
```

Alternatively, you can configure the `HttpModule` using a class instead of a factory, as shown below.

```typescript

HttpModule.registerAsync({
  useClass: HttpConfigService,
});
```

The construction above instantiates `HttpConfigService` inside `HttpModule`, using it to create an options object. Note that in this example, the `HttpConfigService` has to implement `HttpModuleOptionsFactory` interface as shown below. The `HttpModule` will call the `createHttpOptions()` method on the instantiated object of the supplied class.

```typescript

@Injectable()
class HttpConfigService implements HttpModuleOptionsFactory {
  createHttpOptions(): HttpModuleOptions {
    return {
      timeout: 5000,
      maxRedirects: 5,
    };
  }
}
```

If you want to reuse an existing options provider instead of creating a private copy inside the `HttpModule`, use the `useExisting` syntax.

```typescript

HttpModule.registerAsync({
  imports: [ConfigModule],
  useExisting: ConfigService,
});
```

----
url: https://docs.nestjs.com/v6/websockets/gateways
----

* [Gateways](https://docs.nestjs.com/v6/websockets/gateways#gateways)
* [Installation](https://docs.nestjs.com/v6/websockets/gateways#installation)
* [Overview](https://docs.nestjs.com/v6/websockets/gateways#overview)
* [Multiple responses](https://docs.nestjs.com/v6/websockets/gateways#multiple-responses)
* [Asynchronous responses](https://docs.nestjs.com/v6/websockets/gateways#asynchronous-responses)
* [Lifecycle hooks](https://docs.nestjs.com/v6/websockets/gateways#lifecycle-hooks)
* [Server](https://docs.nestjs.com/v6/websockets/gateways#server)
* [Example](https://docs.nestjs.com/v6/websockets/gateways#example)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/websockets/gateways.md "Suggest Edits")

### Gateways

Most of the concepts discussed elsewhere in this documentation, such as dependency injection, decorators, exception filters, pipes, guards and interceptors, apply equally to gateways. Wherever possible, Nest abstracts implementation details so that the same components can run across HTTP-based platforms, WebSockets, and Microservices. This section covers the aspects of Nest that are specific to WebSockets.

In Nest, a gateway is simply a class annotated with `@WebSocketGateway()` decorator. Technically, gateways are platform-agnostic which makes them compatible with any WebSockets library once an adapter is created. There are two WS platforms supported out-of-the-box: [socket.io](https://github.com/socketio/socket.io) and [ws](https://github.com/websockets/ws). You can choose the one that best suits your needs. Also, you can build your own adapter by following this [guide](/v6/websockets/adapter).

> **Hint** Gateways can be treated as [providers](/v6/providers); this means they can inject dependencies through the class constructor. Also, gateways can be injected by other classes (providers and controllers) as well.

#### Installation[#](/websockets/gateways#installation)

To start building WebSockets-based applications, first install the required package:

JS TS

```typescript

$ npm i --save @nestjs/websockets @nestjs/platform-socket.io
$ npm i --save-dev @types/socket.io
```

```typescript

$ npm i --save @nestjs/websockets @nestjs/platform-socket.io
```

#### Overview[#](/websockets/gateways#overview)

In general, each gateway is listening on the same port as the **HTTP server**, unless your app is not a web application, or you have changed the port manually. This default behavior can be modified by passing an argument to the `@WebSocketGateway(80)` decorator where `80` is a chosen port number. You can also set a [namespace](https://socket.io/docs/rooms-and-namespaces/) used by the gateway using the following construction:

```typescript

@WebSocketGateway(80, { namespace: 'events' })
```

> **Warning** Gateways aren't instantiated until they are referenced in the providers array of an existing module.

You can pass any supported [option](https://socket.io/docs/server-api/) to the socket constructor with the second argument to the `@WebSocketGateway()` decorator, as shown below:

```typescript

@WebSocketGateway(81, { transports: ['websocket'] })
```

The gateway is now listening, but we have not yet subscribed to any incoming messages. Let's create a handler that will subscribe to the `events` messages and respond to the user with the exact same data.

events.gateway.ts

JS TS

```typescript

@SubscribeMessage('events')
handleEvent(@MessageBody() data: string): string {
  return data;
}
```

```typescript

@Bind(MessageBody())
@SubscribeMessage('events')
handleEvent(data) {
  return data;
}
```

> **Hint**`@SubscribeMessage()` and `@MessageBody()` decorators are imported from `@nestjs/websockets` package.

If you would prefer not to use decorators, the following code is functionally equivalent:

events.gateway.ts

JS TS

```typescript

@SubscribeMessage('events')
handleEvent(client: Socket, data: string): string {
  return data;
}
```

```typescript

@SubscribeMessage('events')
handleEvent(client, data) {
  return data;
}
```

In the example above, the `handleEvent()` function takes two arguments. The first one is a platform-specific [socket instance](https://socket.io/docs/server-api/#socket), while the second one is the data received from the client. This approach is not recommended though, because it requires mocking the `socket` instance in each unit test.

Once the `events` message is received, the handler sends an acknowledgment with the same data that was sent over the network. In addition, it's possible to emit messages using a library-specific approach, for example, by making use of `client.emit()` method. In order to access a connected socket instance, use `@ConnectedSocket()` decorator.

events.gateway.ts

JS TS

```typescript

@SubscribeMessage('events')
handleEvent(
  @MessageBody() data: string,
  @ConnectedSocket() client: Socket,
): string {
  return data;
}
```

```typescript

@Bind(MessageBody(), ConnectedSocket())
@SubscribeMessage('events')
handleEvent(data, client) {
  return data;
}
```

> **Hint**`@ConnectedSocket()` decorator is imported from `@nestjs/websockets` package.

However, in this case, you won't be able to leverage interceptors. If you don't want to respond to the user, you can simple skip the `return` statement (or explicitly return "falsy" value, e.g. `undefined`).

Now when a client emits the message as follows:

```typescript

socket.emit('events', { name: 'Nest' });
```

The `handleEvent()` method will be executed. In order to listen for messages emitted from within the above handler, the client has to attach a corresponding acknowledgment listener:

```typescript

socket.emit('events', { name: 'Nest' }, data => console.log(data));
```

#### Multiple responses[#](/websockets/gateways#multiple-responses)

The acknowledgment is dispatched only once. Furthermore, it is not supported by native WebSockets implementation. To solve this limitation, you may return an object which consist of two properties. The `event` which is a name of the emitted event and the `data` that has to be forwarded to the client.

events.gateway.ts

JS TS

```typescript

@SubscribeMessage('events')
handleEvent(@MessageBody() data: unknown): WsResponse<unknown> {
  const event = 'events';
  return { event, data };
}
```

```typescript

@Bind(MessageBody())
@SubscribeMessage('events')
handleEvent(data) {
  const event = 'events';
  return { event, data };
}
```

> **Hint** The `WsResponse` interface is imported from `@nestjs/websockets` package.

In order to listen for the incoming response(s), the client has to apply another event listener.

```typescript

socket.on('events', data => console.log(data));
```

#### Asynchronous responses[#](/websockets/gateways#asynchronous-responses)

Message handlers are able to respond either synchronously or **asynchronously**. Hence, `async` methods are supported. A message handler is also able to return an `Observable`, in which case the result values will be emitted until the stream is completed.

events.gateway.ts

JS TS

```typescript

@SubscribeMessage('events')
onEvent(@MessageBody() data: unknown): Observable<WsResponse<number>> {
  const event = 'events';
  const response = [1, 2, 3];

  return from(response).pipe(
    map(data => ({ event, data })),
  );
}
```

```typescript

@Bind(MessageBody())
@SubscribeMessage('events')
onEvent(data) {
  const event = 'events';
  const response = [1, 2, 3];

  return from(response).pipe(
    map(data => ({ event, data })),
  );
}
```

In the example above, the message handler will respond **3 times** (with each item from the array).

#### Lifecycle hooks[#](/websockets/gateways#lifecycle-hooks)

There are 3 useful lifecycle hooks available. All of them have corresponding interfaces and are described in the following table:

|                       |                                                                                                                                         |
| --------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| `OnGatewayInit`       | Forces to implement the `afterInit()` method. Takes library-specific server instance as an argument (and spreads the rest if required). |
| `OnGatewayConnection` | Forces to implement the `handleConnection()` method. Takes library-specific client socket instance as an argument.                      |
| `OnGatewayDisconnect` | Forces to implement the `handleDisconnect()` method. Takes library-specific client socket instance as an argument.                      |

> **Hint** Each lifecycle interface is exposed from `@nestjs/websockets` package.

#### Server[#](/websockets/gateways#server)

Occasionally, you may want to have a direct access to the native, **platform-specific** server instance. The reference to this object is passed as an argument to the `afterInit()` method (`OnGatewayInit` interface). Another option is to use the `@WebSocketServer()` decorator.

```typescript

@WebSocketServer()
server: Server;
```

> **Notice** The `@WebSocketServer()` decorator is imported from the `@nestjs/websockets` package.

----
url: https://docs.nestjs.com/v4/controllers
----

### Controllers

The controllers layer is responsible for handling incoming **requests** and returning a **response** to the client.

To create a basic controller you have to attach the **metadata** to the class. Thanks to the metadata Nest knows how to map your controller to the appropriate routes. To attach the metadata we're using the **decorators** (in this case `@Controller('cats')`).

cats.controller.ts

JavaScript TypeScript

TypeScript

```typescript

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

@Controller('cats')
export class CatsController {
  @Get()
  findAll() {
    return [];
  }
}
```

#### Metadata

We're using the `@Controller('cats')` decorator, which is **obligatory**. The `cats` is an optional prefix for each route registered in the class. Using a prefix allows you to avoid repeating yourself when all your routes share a common prefix.

The `@Get()` decorator on the `findAll()` method tells Nest to create an endpoint for this route path and map every corresponding request to this handler. Since we declared a prefix for every route (`cats`), Nest will map every `/cats` **GET** request to this method.

When a GET request is made to this endpoint, Nest will return a 200 status code and the parsed **JSON**, in this case just an empty array. How is that possible?

There're **two possible approaches** to manipulate the response:

|                        |                                                                                                                                                                                                                                                                                                                                                                                                        |
| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Standard (recommended) | When we return a JavaScript object or array, it'll be **automatically** parsed to JSON. When we return a string, Nest will send just a string without trying to parse it to JSON. Furthermore, the response's **status code** is always 200 by default, except for POST requests, which uses **201**. We can easily change this behaviour by adding the `@HttpCode(...)` decorator at a handler-level. |
| Express                | We can use the express [response object](http://expressjs.com/en/api.html#res), which we can inject using `@Res()` decorator in the function signature, for example `findAll(@Res() response)`.                                                                                                                                                                                                        |

> **Notice!** It's forbidden to use both approaches at the same time. Nest detects whether the handler is using `@Res()` or `@Next()`, if that's the case - the standard way is disabled for this single route.

#### Request object

A lot of endpoints need an access to the client **request** details. In fact, Nest is using express [request object](http://expressjs.com/en/api.html#req). We can force Nest to inject the request object into handler using `@Req()` decorator.

> **Hint** There's a `@types/express` package and we strongly recommend to use it (`Request` has its own typings).

cats.controller.ts

JavaScript TypeScript

TypeScript

```typescript

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

@Controller('cats')
export class CatsController {
  @Get()
  findAll(@Req() request) {
    return [];
  }
}
```

TypeScript

```typescript

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

@Controller('cats')
export class CatsController {
  @Get()
  @Bind(Req())
  findAll(request) {
    return [];
  }
}
```

The request object represents the HTTP request and has properties for the request query string, parameters, HTTP headers, and e.g. body (read more [here](http://expressjs.com/en/api.html#req)), but in most cases, it's not necessary to grab them manually. We can use **dedicated decorators** instead, such as `@Body()` or `@Query()`, which are available out of the box. Below is a comparison of the decorators with the plain express objects.

|                            |                                      |
| -------------------------- | ------------------------------------ |
| `@Request()`               | `req`                                |
| `@Response()`              | `res`                                |
| `@Next()`                  | `next`                               |
| `@Session()`               | `req.session`                        |
| `@Param(param?: string)`   | `req.params` / `req.params[param]`   |
| `@Body(param?: string)`    | `req.body` / `req.body[param]`       |
| `@Query(param?: string)`   | `req.query` / `req.query[param]`     |
| `@Headers(param?: string)` | `req.headers` / `req.headers[param]` |

#### More endpoints

We have already created an endpoint to fetch the data (**GET** route). It'd be great to provide a way of creating the new records too. Let's create the **POST** handler:

cats.controller.ts

JavaScript TypeScript

TypeScript

```typescript

import { Controller, Get, Post } from '@nestjs/common';

@Controller('cats')
export class CatsController {
  @Post()
  create() {
    // TODO: Add some logic here
  }

  @Get()
  findAll() {
    return [];
  }
}
```

It's really easy. Nest provides the rest of those endpoints decorators in the same fashion - `@Put()`, `@Delete()`, `@Patch()`, `@Options()`, `@Head()`, and `@All()`.

#### Status code manipulation

As mentioned, the response **status code** is always 200 by default, except POST requests, when it's **201**. We can easily change this behaviour by adding the `@HttpCode(...)` decorator at a handler-level.

cats.controller.ts

JavaScript TypeScript

TypeScript

```typescript

import { Controller, Get, Post, HttpCode } from '@nestjs/common';

@Controller('cats')
export class CatsController {
  @HttpCode(204)
  @Post()
  create() {
    // TODO: Add some logic here
  }

  @Get()
  findAll() {
    return [];
  }
}
```

#### Route parameters

Routes with static paths can't help when you need to accept **dynamic data** as part of the URL. To define routes with parameters, simply specify the route parameters in the path of the route as shown below.

TypeScript

```typescript

@Get(':id')
findOne(@Param() params) {
  console.log(params.id);
  return {};
}
```

#### Async / await

We love modern JavaScript, and we know that the data extraction is mostly **asynchronous**. That's why Nest supports `async` functions and works pretty well with them.

> **Hint** Learn more about `async / await` [here](https://kamilmysliwiec.com/typescript-2-1-introduction-async-await)!

Every async function has to return a `Promise`. It means that you can return deferred value and Nest will resolve it by itself. Let's have a look at the example below:

cats.controller.ts

JavaScript TypeScript

TypeScript

```typescript

@Get()
async findAll(): Promise<any[]> {
  return [];
}
```

TypeScript

```typescript

@Get()
async findAll() {
  return [];
}
```

It's fully valid.

Furthermore, Nest route handlers are even more powerful. They can return RxJS [observable streams](http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html). It makes the migration between a simple web application and the Nest microservice much easier.

cats.controller.ts

JavaScript TypeScript

TypeScript

```typescript

@Get()
findAll(): Observable<any[]> {
  return Observable.of([]);
}
```

TypeScript

```typescript

@Get()
findAll() {
  return Observable.of([]);
}
```

There's no recommended way. You can use whatever you want.

#### POST handler

Our previous example of POST route handler doesn't accept any client params. Let's fix this by adding the `@Body()` argument here.

Firstly, we need to establish the **DTO** (Data Transfer Object) schema. A DTO is an object that defines how the data will be sent over the network. We could do this by using **TypeScript** interfaces, or by simple classes. What may be surprising, we recommend using **classes** here. Why? Classes are part of the JavaScript ES6 standard, so they're just plain functions. On the other hand, TypeScript interfaces are removed during the transpilation, Nest can't refer to them. It's important because features such as **Pipes** enable additional possibilities when they have access to the metatype of the variable.

Let's create the `CreateCatDto`:

dto/create-cat.dto.ts

JavaScript TypeScript

TypeScript

```typescript

export class CreateCatDto {
  readonly name: string;
  readonly age: number;
  readonly breed: string;
}
```

It has only three basic properties. All of them are marked as `readonly`, because we should always try to make our functions as [pure](https://medium.com/javascript-scene/master-the-javascript-interview-what-is-a-pure-function-d1c076bec976) as possible.

Now we can use the schema inside the `CatsController`:

cats.controller.ts

JavaScript TypeScript

TypeScript

```typescript

@Post()
async create(@Body() createCatDto: CreateCatDto) {
  // TODO: Add some logic here
}
```

TypeScript

```typescript

@Post()
@Bind(Body())
async create(createCatDto) {
// TODO: Add some logic here
}
```

#### Handling errors

There's a separate chapter about working with the exceptions [here](/v4/exception-filters).

#### Last step

The controller is prepared, and ready to use, but Nest doesn't know that `CatsController` exists yet, so it won't create an instance of this class. We need to tell Nest about it.

The controller always belongs to the module, that's why we hold the `controllers` array within the `@Module()` decorator. Since we don't have any other modules except the root `ApplicationModule`, let's use it for now:

app.module.ts

JavaScript TypeScript

TypeScript

```typescript

import { Module } from '@nestjs/common';
import { CatsController } from './cats/cats.controller';

@Module({
    controllers: [CatsController],
})
export class ApplicationModule {}
```

Tada! We attached the metadata to the module class, so now Nest can easily reflect which controllers have to be mounted.

#### Express approach

So far we've discussed the Nest standard way of manipulating responses. The second way of manipulating the response is to use express the [response object](http://expressjs.com/en/api.html#res). It was the only available option until **Nest 4**. To inject the response object, we need to use `@Res()` decorator. To show the differences, let's rewrite the `CatsController`:

JavaScript TypeScript

TypeScript

```typescript

import { Controller, Get, Post, Res, Body, HttpStatus } from '@nestjs/common';
import { CreateCatDto } from './dto/create-cat.dto';

@Controller('cats')
export class CatsController {
  @Post()
  create(@Res() res, @Body() createCatDto: CreateCatDto) {
    // TODO: Add some logic here
    res.status(HttpStatus.CREATED).send();
  }

  @Get()
  findAll(@Res() res) {
     res.status(HttpStatus.OK).json([]);
  }
}
```

TypeScript

```typescript

import { Controller, Get, Post, Bind, Res, Body, HttpStatus } from '@nestjs/common';

@Controller('cats')
export class CatsController {
  @Post()
  @Bind(Res(), Body())
  create(res, createCatDto) {
    // TODO: Add some logic here
    res.status(HttpStatus.CREATED).send();
  }

  @Get()
  @Bind(Res())
  findAll(res) {
     res.status(HttpStatus.OK).json([]);
  }
}
```

This manner is much less clear from my point of view. I definitely prefer the first approach, but to make the Nest **backward compatible** with the previous versions, this method is still available. Also, the **response object** gives more flexibility - you have full control of the express response object.

#### Sponsors

[](https://valor-software.com/)

Nest is an MIT-licensed open source project. It can grow thanks to the support by these awesome people. If you'd like to join them, please read more [here](https://opencollective.com/nest). Thanks!

[](https://opencollective.com/nest/backer/0/website)[](https://opencollective.com/nest/backer/1/website)[](https://opencollective.com/nest/backer/2/website)[](https://opencollective.com/nest/backer/3/website)[](https://opencollective.com/nest/backer/4/website)[](https://opencollective.com/nest/backer/5/website)[](https://opencollective.com/nest/backer/6/website)[](https://opencollective.com/nest/backer/7/website)[](https://opencollective.com/nest/backer/8/website)[](https://opencollective.com/nest/backer/9/website)[](https://opencollective.com/nest/backer/10/website)[](https://opencollective.com/nest/backer/11/website)[](https://opencollective.com/nest/backer/12/website)[](https://opencollective.com/nest/backer/13/website)[](https://opencollective.com/nest/backer/14/website)[](https://opencollective.com/nest/backer/15/website)[](https://opencollective.com/nest/backer/16/website)[](https://opencollective.com/nest/backer/17/website)[](https://opencollective.com/nest/backer/18/website)[](https://opencollective.com/nest/backer/19/website)[](https://opencollective.com/nest/backer/20/website)[](https://opencollective.com/nest/backer/21/website)[](https://opencollective.com/nest/backer/22/website)[](https://opencollective.com/nest/backer/23/website)[](https://opencollective.com/nest/backer/24/website)[](https://opencollective.com/nest/backer/25/website)[](https://opencollective.com/nest/backer/26/website)[](https://opencollective.com/nest/backer/27/website)[](https://opencollective.com/nest/backer/28/website)[](https://opencollective.com/nest/backer/29/website)

[Become a sponsor](https://opencollective.com/nest)

----
url: https://docs.nestjs.com/v10/discover/companies
----

* [Who is using Nest?](https://docs.nestjs.com/v10/discover/companies#who-is-using-nest)
* [Companies](https://docs.nestjs.com/v10/discover/companies#companies)

### Who is using Nest?

We are proudly helping various companies building their products at scale. If you are using Nest and would you like to be listed here, see this [thread](https://github.com/nestjs/nest/issues/1006). We are willing to put your logo here!

#### Companies[#](/discover/companies#companies)

According to our knowledge, all the following companies have built awesome projects on top of our framework:

[](https://roche.com)[](https://adidas.com)[](https://capgemini.com)[](https://www.societegenerale.fr/)[](https://rewe-digital.com/)[](https://www.decathlon.com/)[](https://www.autodesk.com/)[](https://www.neo4j.com/)[](https://bmw.com)[](https://gitlab.com/)[](https://www.ibm.com/)[](https://www.jetbrains.com/)[](https://www.mercedes-benz.com/)[](https://totalenergies.com/)[](https://www.bytedance.com)[](https://www.shipt.com/)[](https://github.com/Sanofi-IADC)[](https://sitepen.com)[](https://trilon.io)[](https://www.vuestorefront.io/)[](https://hingehealth.com)[](https://whiskeyhouse.com)

|                                     |
| ----------------------------------- |
| <https://gorrion.io/>               |
| <http://balticdatascience.com/>     |
| <https://prohabits.com/>            |
| <https://komed-health.com/>         |
| <https://kerberus.com.co/>          |
| <http://xtremis.com/>               |
| <https://notadd.com/>               |
| <http://jsdaddy.io/>                |
| <https://yumpingo.com/>             |
| <https://analytics-importer.cz/>    |
| <https://dayzim.com/>               |
| <https://wizkids.co.uk/>            |
| <https://pilvia.com/>               |
| <https://wi-q.com/>                 |
| <http://agrofel.com.br>             |
| <https://societegenerale.com/>      |
| <https://trashpanda.hulan.nl/>      |
| <https://bytedance.com/>            |
| <https://votercircle.com>           |
| <https://erento.com>                |
| <https://ideas.manticore-labs.com/> |
| <https://smartexlab.com/>           |
| <https://automama.ru/>              |
| <https://iflix.com/>                |
| <https://frontendwatch.com/>        |
| <https://mobilejazz.com/>           |
| <https://cgiandi.com/>              |
| <https://www.titlex.com.au/>        |
| <https://codengage.com/>            |
| <https://budacode.com/>             |
| <https://blueanchor.io/>            |
| <https://www.easymetrics.com/>      |
| <https://getapollo.io/>             |
| <https://big-bench.com/>            |
| <https://www.qingtui.cn/>           |
| <https://www.rosebayconsult.com/>   |
| <https://www.patrocinium.com/>      |
| <https://creatorsdaily.com>         |
| <https://autoscar.com.br>           |
| <https://www.mediktiv.com>          |
| <https://harmonize.health>          |
| <https://accerlery.be>              |
| <https://www.facile.it>             |
| <https://shopback.com>              |
| <https://www.ottonova.de>           |
| <https://www.radity.com>            |
| <https://globalctoforum.org>        |
| <https://halojasa.com>              |
| <https://hexito.com>                |
| <https://rivvy.app>                 |
| <https://padfever.com/>             |
| <https://datenlotse.org>            |
| <https://bemum.co>                  |
| <https://weoptimeye.ai>             |
| <https://nemovote.com>              |
| <https://selleo.com>                |
| <https://pchas.ir>                  |
| <https://tayeh.ir>                  |
| <https://forwardigital.co.uk>       |
| <https://rozetka.com.ua>            |
| <https://www.itrio.net>             |
| <https://alexishr.com>              |
| <https://dyrector.io>               |
| <https://stijlbreuk.nl>             |
| <https://polygon-software.ch>       |
| <https://bewith.io>                 |
| <https://swetrix.com>               |
| <https://swyftlogistics.com>        |
| <https://evershop.io>               |
| <https://e-design.ca>               |
| <https://growthmill.com>            |
| <https://tarken.com.br>             |
| <https://remato.com>                |
| <https://remberg.de/en>             |
| <https://uninterrupted.tech>        |
| <https://www.digando.com>           |
| <https://novu.co>                   |
| <https://aqreach.com>               |
| <https://phalco.de>                 |
| <https://www.tesseractpro.io>       |
| <https://www.kwanso.com>            |
| <https://cmdn.io>                   |
| <https://ayo.so>                    |
| <https://devitjobs.com>             |
| <https://formation.tech>            |
| <https://gofirmex.com>              |

and a lot more but we don't have enough time to update above list. Feel free to create a [pull request](https://github.com/nestjs/docs.nestjs.com/pulls) though!

----
url: https://docs.nestjs.com/http/session
----

[Skip to content](#content)

On this page

* [Session](https://docs.nestjs.com/http/session#session)
* [Use with Express (default)](https://docs.nestjs.com/http/session#use-with-express-default)
* [Use with Fastify](https://docs.nestjs.com/http/session#use-with-fastify)

### Session

**HTTP sessions** store information about the user across multiple requests, which is particularly useful for [MVC](/http/mvc) applications.

#### Use with Express (default)[#](/http/session#use-with-express-default)

First, install the [express-session](https://github.com/expressjs/session) package (and its types, for TypeScript users):

```shell

$ npm i express-session
$ npm i -D @types/express-session
```

Once the installation is complete, apply the `express-session` middleware as global middleware (for example, in your `main.ts` file):

```typescript

import session from 'express-session';
// somewhere in your initialization file
app.use(
  session({
    secret: 'my-secret',
    resave: false,
    saveUninitialized: false,
  }),
);
```

> **Notice** The default server-side session storage is purposely not designed for a production environment. It leaks memory under most conditions, does not scale past a single process, and is meant for debugging and development. Read more in the [express-session repository](https://github.com/expressjs/session).

The `secret` is used to sign the session ID cookie. It can be either a string (a single secret) or an array of secrets. If you provide an array, only the first element is used to sign the session ID cookie, while all elements are considered when verifying the signature in requests. The secret should not be easily guessed; a random set of characters works best.

Enabling the `resave` option forces the session to be saved back to the session store, even if the session was never modified during the request. The default value is `true`, but relying on the default is deprecated because the default will change in the future.

Likewise, enabling the `saveUninitialized` option forces a session that is "uninitialized" to be saved to the store. A session is uninitialized when it is new but not modified. Choosing `false` is useful for implementing login sessions, reducing server storage usage, or complying with laws that require permission before setting a cookie. Choosing `false` also helps with race conditions where a client makes multiple parallel requests without a session (see the [`saveUninitialized` documentation](https://github.com/expressjs/session#saveuninitialized)).

The `session` middleware accepts several other options. Read more about them in the [express-session API documentation](https://github.com/expressjs/session#options).

> **Hint** The `cookie.secure: true` option is recommended. However, it requires an HTTPS-enabled website, because secure cookies are only sent over HTTPS. If `secure` is set and you access your site over HTTP, the cookie is not set. If your Node.js server runs behind a proxy and you use `secure: true`, you need to set `"trust proxy"` in Express.

With this in place, you can set and read session values from within route handlers, as follows:

```typescript

@Get()
findAll(@Req() request: Request) {
  request.session.visits = request.session.visits ? request.session.visits + 1 : 1;
}
```

> **Hint** The `@Req()` decorator is imported from the `@nestjs/common` package, while `Request` is imported from the `express` package.

Alternatively, you can use the `@Session()` decorator to extract a session object from the request, as follows:

```typescript

@Get()
findAll(@Session() session: Record<string, any>) {
  session.visits = session.visits ? session.visits + 1 : 1;
}
```

> **Hint** The `@Session()` decorator is imported from the `@nestjs/common` package.

#### Use with Fastify[#](/http/session#use-with-fastify)

First, install the required package:

```shell

$ npm i @fastify/secure-session
```

Once the installation is complete, register the `@fastify/secure-session` plugin:

```typescript

import secureSession from '@fastify/secure-session';

// somewhere in your initialization file
const app = await NestFactory.create<NestFastifyApplication>(
  AppModule,
  new FastifyAdapter(),
);
await app.register(secureSession, {
  secret: 'averylogphrasebiggerthanthirtytwochars',
  salt: 'mq9hDxBVDbspDR6n',
});
```

> **Hint** You can also [pregenerate a key](https://github.com/fastify/fastify-secure-session) or use [key rotation](https://github.com/fastify/fastify-secure-session#using-keys-with-key-rotation).

Read more about the available options in the [@fastify/secure-session repository](https://github.com/fastify/fastify-secure-session).

With this in place, you can set and read session values from within route handlers, as follows:

```typescript

@Get()
findAll(@Req() request: FastifyRequest) {
  const visits = request.session.get('visits');
  request.session.set('visits', visits ? visits + 1 : 1);
}
```

Alternatively, you can use the `@Session()` decorator to extract a session object from the request, as follows:

```typescript

@Get()
findAll(@Session() session: secureSession.Session) {
  const visits = session.get('visits');
  session.set('visits', visits ? visits + 1 : 1);
}
```

> **Hint** The `@Session()` decorator is imported from the `@nestjs/common` package, while `secureSession.Session` comes from the `@fastify/secure-session` package (import statement: `import * as secureSession from '@fastify/secure-session'`).

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/http/sessions.md)

----
url: https://docs.nestjs.com/v11/recipes/swc
----

* [SWC](https://docs.nestjs.com/v11/recipes/swc#swc)
* [Installation](https://docs.nestjs.com/v11/recipes/swc#installation)
* [Getting started](https://docs.nestjs.com/v11/recipes/swc#getting-started)
* [Type checking](https://docs.nestjs.com/v11/recipes/swc#type-checking)
* [CLI Plugins (SWC)](https://docs.nestjs.com/v11/recipes/swc#cli-plugins-swc)
* [SWC configuration](https://docs.nestjs.com/v11/recipes/swc#swc-configuration)
* [Monorepo](https://docs.nestjs.com/v11/recipes/swc#monorepo)
* [Monorepo and CLI plugins](https://docs.nestjs.com/v11/recipes/swc#monorepo-and-cli-plugins)
* [Common pitfalls](https://docs.nestjs.com/v11/recipes/swc#common-pitfalls)
* [Jest + SWC](https://docs.nestjs.com/v11/recipes/swc#jest--swc)
* [Vitest](https://docs.nestjs.com/v11/recipes/swc#vitest)
* [Installation](https://docs.nestjs.com/v11/recipes/swc#installation-1)
* [Configuration](https://docs.nestjs.com/v11/recipes/swc#configuration)
* [Path aliases](https://docs.nestjs.com/v11/recipes/swc#path-aliases)
* [Update imports in E2E tests](https://docs.nestjs.com/v11/recipes/swc#update-imports-in-e2e-tests)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/recipes/swc.md "Suggest Edits")

### SWC

[SWC](https://swc.rs/) (Speedy Web Compiler) is an extensible Rust-based platform that can be used for both compilation and bundling. Using SWC with Nest CLI is a great and simple way to significantly speed up your development process.

> **Hint** SWC is approximately **x20 times faster** than the default TypeScript compiler.

#### Installation[#](/recipes/swc#installation)

To get started, first install a few packages:

```bash

$ npm i --save-dev @swc/cli @swc/core
```

#### Getting started[#](/recipes/swc#getting-started)

Once the installation process is complete, you can use the `swc` builder with Nest CLI, as follows:

```bash

$ nest start -b swc
# OR nest start --builder swc
```

> **Hint** If your repository is a monorepo, check out [this section](/recipes/swc#monorepo).

Instead of passing the `-b` flag you can also just set the `compilerOptions.builder` property to `"swc"` in your `nest-cli.json` file, like so:

```json

{
  "compilerOptions": {
    "builder": "swc"
  }
}
```

To customize builder's behavior, you can pass an object containing two attributes, `type` (`"swc"`) and `options`, as follows:

```json

{
  "compilerOptions": {
    "builder": {
      "type": "swc",
      "options": {
        "swcrcPath": "infrastructure/.swcrc",
      }
    }
  }
}
```

For example, to make the swc compile `.jsx` and `.tsx` files, do:

```json

{
  "compilerOptions": {
    "builder": {
      "type": "swc",
      "options": { "extensions": [".ts", ".tsx", ".js", ".jsx"] }
    },
  }
}
```

To run the application in watch mode, use the following command:

```bash

$ nest start -b swc -w
# OR nest start --builder swc --watch
```

#### Type checking[#](/recipes/swc#type-checking)

SWC does not perform any type checking itself (as opposed to the default TypeScript compiler), so to turn it on, you need to use the `--type-check` flag:

```bash

$ nest start -b swc --type-check
```

This command will instruct the Nest CLI to run `tsc` in `noEmit` mode alongside SWC, which will asynchronously perform type checking. Again, instead of passing the `--type-check` flag you can also just set the `compilerOptions.typeCheck` property to `true` in your `nest-cli.json` file, like so:

```json

{
  "compilerOptions": {
    "builder": "swc",
    "typeCheck": true
  }
}
```

#### CLI Plugins (SWC)[#](/recipes/swc#cli-plugins-swc)

The `--type-check` flag will automatically execute **NestJS CLI plugins** and produce a serialized metadata file which then can be loaded by the application at runtime.

#### SWC configuration[#](/recipes/swc#swc-configuration)

SWC builder is pre-configured to match the requirements of NestJS applications. However, you can customize the configuration by creating a `.swcrc` file in the root directory and tweaking the options as you wish.

```json

{
  "$schema": "https://swc.rs/schema.json",
  "sourceMaps": true,
  "jsc": {
    "parser": {
      "syntax": "typescript",
      "decorators": true,
      "dynamicImport": true
    },
    "baseUrl": "./"
  },
  "minify": false
}
```

#### Monorepo[#](/recipes/swc#monorepo)

If your repository is a monorepo, then instead of using `swc` builder you have to configure `webpack` to use `swc-loader`.

First, let's install the required package:

```bash

$ npm i --save-dev swc-loader
```

Once the installation is complete, create a `webpack.config.js` file in the root directory of your application with the following content:

```js

const swcDefaultConfig = require('@nestjs/cli/lib/compiler/defaults/swc-defaults').swcDefaultsFactory().swcOptions;

module.exports = {
  module: {
    rules: [
      {
        test: /\.ts$/,
        exclude: /node_modules/,
        use: {
          loader: 'swc-loader',
          options: swcDefaultConfig,
        },
      },
    ],
  },
};
```

#### Monorepo and CLI plugins[#](/recipes/swc#monorepo-and-cli-plugins)

Now if you use CLI plugins, `swc-loader` will not load them automatically. Instead, you have to create a separate file that will load them manually. To do so, declare a `generate-metadata.ts` file near the `main.ts` file with the following content:

```ts

import { PluginMetadataGenerator } from '@nestjs/cli/lib/compiler/plugins/plugin-metadata-generator';
import { ReadonlyVisitor } from '@nestjs/swagger/dist/plugin';

const generator = new PluginMetadataGenerator();
generator.generate({
  visitors: [new ReadonlyVisitor({ introspectComments: true, pathToSource: __dirname })],
  outputDir: __dirname,
  watch: true,
  tsconfigPath: 'apps/<name>/tsconfig.app.json',
});
```

> **Hint** In this example we used `@nestjs/swagger` plugin, but you can use any plugin of your choice.

The `generate()` method accepts the following options:

| `watch`            | Whether to watch the project for changes.                                                      |
| ------------------ | ---------------------------------------------------------------------------------------------- |
| `tsconfigPath`     | Path to the `tsconfig.json` file. Relative to the current working directory (`process.cwd()`). |
| `outputDir`        | Path to the directory where the metadata file will be saved.                                   |
| `visitors`         | An array of visitors that will be used to generate metadata.                                   |
| `filename`         | The name of the metadata file. Defaults to `metadata.ts`.                                      |
| `printDiagnostics` | Whether to print diagnostics to the console. Defaults to `true`.                               |

Finally, you can run the `generate-metadata` script in a separate terminal window with the following command:

```bash

$ npx ts-node src/generate-metadata.ts
# OR npx ts-node apps/{YOUR_APP}/src/generate-metadata.ts
```

#### Common pitfalls[#](/recipes/swc#common-pitfalls)

If you use TypeORM/MikroORM or any other ORM in your application, you may stumble upon circular import issues. SWC doesn't handle **circular imports** well, so you should use the following workaround:

```typescript

@Entity()
export class User {
  @OneToOne(() => Profile, (profile) => profile.user)
  profile: Relation<Profile>; // <--- see "Relation<>" type here instead of just "Profile"
}
```

> **Hint**`Relation` type is exported from the `typeorm` package.

Doing this prevents the type of the property from being saved in the transpiled code in the property metadata, preventing circular dependency issues.

If your ORM does not provide a similar workaround, you can define the wrapper type yourself:

```typescript

/**
 * Wrapper type used to circumvent ESM modules circular dependency issue
 * caused by reflection metadata saving the type of the property.
 */
export type WrapperType<T> = T; // WrapperType === Relation
```

For all [circular dependency injections](/v11/fundamentals/circular-dependency) in your project, you will also need to use the custom wrapper type described above:

```typescript

@Injectable()
export class UsersService {
  constructor(
    @Inject(forwardRef(() => ProfileService))
    private readonly profileService: WrapperType<ProfileService>,
  ) {};
}
```

### Jest + SWC

To use SWC with Jest, you need to install the following packages:

```bash

$ npm i --save-dev jest @swc/core @swc/jest
```

Once the installation is complete, update the `package.json`/`jest.config.js` file (depending on your configuration) with the following content:

```json

{
  "jest": {
    "transform": {
      "^.+\\.(t|j)s?$": ["@swc/jest"]
    }
  }
}
```

Additionally you would need to add the following `transform` properties to your `.swcrc` file: `legacyDecorator`, `decoratorMetadata`:

```json

{
  "$schema": "https://swc.rs/schema.json",
  "sourceMaps": true,
  "jsc": {
    "parser": {
      "syntax": "typescript",
      "decorators": true,
      "dynamicImport": true
    },
    "transform": {
      "legacyDecorator": true,
      "decoratorMetadata": true
    },
    "baseUrl": "./"
  },
  "minify": false
}
```

If you use NestJS CLI Plugins in your project, you'll have to run `PluginMetadataGenerator` manually. Navigate to [this section](/recipes/swc#monorepo-and-cli-plugins) to learn more.

### Vitest

[Vitest](https://vitest.dev/) is a fast and lightweight test runner designed to work with Vite. It provides a modern, fast, and easy-to-use testing solution that can be integrated with NestJS projects.

#### Installation[#](/recipes/swc#installation-1)

To get started, first install the required packages:

```bash

$ npm i --save-dev vitest unplugin-swc @swc/core @vitest/coverage-v8
```

#### Configuration[#](/recipes/swc#configuration)

Create a `vitest.config.ts` file in the root directory of your application with the following content:

```ts

import swc from 'unplugin-swc';
import { defineConfig } from 'vitest/config';

export default defineConfig({
  test: {
    globals: true,
    root: './',
  },
  plugins: [
    // This is required to build the test files with SWC
    swc.vite({
      // Explicitly set the module type to avoid inheriting this value from a `.swcrc` config file
      module: { type: 'es6' },
    }),
  ],
  resolve: {
    alias: {
      // Ensure Vitest correctly resolves TypeScript path aliases
      'src': resolve(__dirname, './src'),
    },
  },
});
```

This configuration file sets up the Vitest environment, root directory, and SWC plugin. You should also create a separate configuration file for e2e tests, with an additional `include` field that specifies the test path regex:

```ts

import swc from 'unplugin-swc';
import { defineConfig } from 'vitest/config';

export default defineConfig({
  test: {
    include: ['**/*.e2e-spec.ts'],
    globals: true,
    root: './',
  },
  plugins: [swc.vite()],
});
```

Additionally, you can set the `alias` options to support TypeScript paths in your tests:

```ts

import swc from 'unplugin-swc';
import { defineConfig } from 'vitest/config';

export default defineConfig({
  test: {
    include: ['**/*.e2e-spec.ts'],
    globals: true,
    alias: {
      '@src': './src',
      '@test': './test',
    },
    root: './',
  },
  resolve: {
    alias: {
      '@src': './src',
      '@test': './test',
    },
  },
  plugins: [swc.vite()],
});
```

### Path aliases

Unlike Jest, Vitest does not automatically resolve TypeScript path aliases like `src/`. This may lead to dependency resolution errors during testing. To resolve this issue, add the following `resolve.alias` configuration in your `vitest.config.ts` file:

```ts

import { resolve } from 'path';

export default defineConfig({
  resolve: {
    alias: {
      'src': resolve(__dirname, './src'),
    },
  },
});
```

This ensures that Vitest correctly resolves module imports, preventing errors related to missing dependencies.

#### Update imports in E2E tests[#](/recipes/swc#update-imports-in-e2e-tests)

Change any E2E test imports using `import * as request from 'supertest'` to `import request from 'supertest'`. This is necessary because Vitest, when bundled with Vite, expects a default import for supertest. Using a namespace import may cause issues in this specific setup.

Lastly, update the test scripts in your package.json file to the following:

```json

{
  "scripts": {
    "test": "vitest run",
    "test:watch": "vitest",
    "test:cov": "vitest run --coverage",
    "test:debug": "vitest --inspect-brk --inspect --logHeapUsage --threads=false",
    "test:e2e": "vitest run --config ./vitest.config.e2e.ts"
  }
}
```

These scripts configure Vitest for running tests, watching for changes, generating code coverage reports, and debugging. The test:e2e script is specifically for running E2E tests with a custom configuration file.

With this setup, you can now enjoy the benefits of using Vitest in your NestJS project, including faster test execution and a more modern testing experience.

> **Hint** You can check out a working example in this [repository](https://github.com/TrilonIO/nest-vitest)

----
url: https://docs.nestjs.com/v10/fundamentals/lifecycle-events
----

* [Lifecycle Events](https://docs.nestjs.com/v10/fundamentals/lifecycle-events#lifecycle-events)
* [Lifecycle sequence](https://docs.nestjs.com/v10/fundamentals/lifecycle-events#lifecycle-sequence)
* [Lifecycle events](https://docs.nestjs.com/v10/fundamentals/lifecycle-events#lifecycle-events-1)
* [Usage](https://docs.nestjs.com/v10/fundamentals/lifecycle-events#usage)
* [Asynchronous initialization](https://docs.nestjs.com/v10/fundamentals/lifecycle-events#asynchronous-initialization)
* [Application shutdown](https://docs.nestjs.com/v10/fundamentals/lifecycle-events#application-shutdown)

| Lifecycle hook method           | Lifecycle event triggering the hook method call                                                                                                                                                              |
| ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `onModuleInit()`                | Called once the host module's dependencies have been resolved.                                                                                                                                               |
| `onApplicationBootstrap()`      | Called once all modules have been initialized, but before listening for connections.                                                                                                                         |
| `onModuleDestroy()`\*           | Called after a termination signal (e.g., `SIGTERM`) has been received.                                                                                                                                       |
| `beforeApplicationShutdown()`\* | Called after all `onModuleDestroy()` handlers have completed (Promises resolved or rejected); once complete (Promises resolved or rejected), all existing connections will be closed (`app.close()` called). |
| `onApplicationShutdown()`\*     | Called after connections close (`app.close()` resolves).                                                                                                                                                     |

\* For these events, if you're not calling `app.close()` explicitly, you must opt-in to make them work with system signals such as `SIGTERM`. See [Application shutdown](fundamentals/lifecycle-events#application-shutdown) below.

> **Warning** The lifecycle hooks listed above are not triggered for **request-scoped** classes. Request-scoped classes are not tied to the application lifecycle and their lifespan is unpredictable. They are exclusively created for each request and automatically garbage-collected after the response is sent.

> **Hint** Execution order of `onModuleInit()` and `onApplicationBootstrap()` directly depends on the order of module imports, awaiting the previous hook.

#### Usage[#](/fundamentals/lifecycle-events#usage)

Each lifecycle hook is represented by an interface. Interfaces are technically optional because they do not exist after TypeScript compilation. Nonetheless, it's good practice to use them in order to benefit from strong typing and editor tooling. To register a lifecycle hook, implement the appropriate interface. For example, to register a method to be called during module initialization on a particular class (e.g., Controller, Provider or Module), implement the `OnModuleInit` interface by supplying an `onModuleInit()` method, as shown below:

JS TS

```typescript

import { Injectable, OnModuleInit } from '@nestjs/common';

@Injectable()
export class UsersService implements OnModuleInit {
  onModuleInit() {
    console.log(`The module has been initialized.`);
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';

@Injectable()
export class UsersService {
  onModuleInit() {
    console.log(`The module has been initialized.`);
  }
}
```

#### Asynchronous initialization[#](/fundamentals/lifecycle-events#asynchronous-initialization)

Both the `OnModuleInit` and `OnApplicationBootstrap` hooks allow you to defer the application initialization process (return a `Promise` or mark the method as `async` and `await` an asynchronous method completion in the method body).

JS TS

```typescript

async onModuleInit(): Promise<void> {
  await this.fetch();
}
```

```typescript

async onModuleInit() {
  await this.fetch();
}
```

#### Application shutdown[#](/fundamentals/lifecycle-events#application-shutdown)

The `onModuleDestroy()`, `beforeApplicationShutdown()` and `onApplicationShutdown()` hooks are called in the terminating phase (in response to an explicit call to `app.close()` or upon receipt of system signals such as SIGTERM if opted-in). This feature is often used with [Kubernetes](https://kubernetes.io/) to manage containers' lifecycles, by [Heroku](https://www.heroku.com/) for dynos or similar services.

Shutdown hook listeners consume system resources, so they are disabled by default. To use shutdown hooks, you **must enable listeners** by calling `enableShutdownHooks()`:

```typescript

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);

  // Starts listening for shutdown hooks
  app.enableShutdownHooks();

  await app.listen(process.env.PORT ?? 3000);
}
bootstrap();
```

> **warning** Due to inherent platform limitations, NestJS has limited support for application shutdown hooks on Windows. You can expect `SIGINT` to work, as well as `SIGBREAK` and to some extent `SIGHUP` - [read more](https://nodejs.org/api/process.html#process_signal_events). However `SIGTERM` will never work on Windows because killing a process in the task manager is unconditional, "i.e., there's no way for an application to detect or prevent it". Here's some [relevant documentation](https://docs.libuv.org/en/v1.x/signal.html) from libuv to learn more about how `SIGINT`, `SIGBREAK` and others are handled on Windows. Also, see Node.js documentation of [Process Signal Events](https://nodejs.org/api/process.html#process_signal_events)

> **Info**`enableShutdownHooks` consumes memory by starting listeners. In cases where you are running multiple Nest apps in a single Node process (e.g., when running parallel tests with Jest), Node may complain about excessive listener processes. For this reason, `enableShutdownHooks` is not enabled by default. Be aware of this condition when you are running multiple instances in a single Node process.

When the application receives a termination signal it will call any registered `onModuleDestroy()`, `beforeApplicationShutdown()`, then `onApplicationShutdown()` methods (in the sequence described above) with the corresponding signal as the first parameter. If a registered function awaits an asynchronous call (returns a promise), Nest will not continue in the sequence until the promise is resolved or rejected.

JS TS

```typescript

@Injectable()
class UsersService implements OnApplicationShutdown {
  onApplicationShutdown(signal: string) {
    console.log(signal); // e.g. "SIGINT"
  }
}
```

```typescript

@Injectable()
class UsersService implements OnApplicationShutdown {
  onApplicationShutdown(signal) {
    console.log(signal); // e.g. "SIGINT"
  }
}
```

> **Info** Calling `app.close()` doesn't terminate the Node process but only triggers the `onModuleDestroy()` and `onApplicationShutdown()` hooks, so if there are some intervals, long-running background tasks, etc. the process won't be automatically terminated.

----
url: https://docs.nestjs.com/v5/recipes/mongodb
----

### MongoDB (Mongoose)

> **Warning** In this article, you'll learn how to create a `DatabaseModule` based on the **Mongoose** package from scratch using custom components. As a consequence, this solution contains a lot of overhead that you can omit using ready to use and available out-of-the-box dedicated `@nestjs/mongoose` package. To learn more, see [here](/v5/techniques/mongodb).

[Mongoose](http://mongoosejs.com) is the most popular [MongoDB](https://www.mongodb.org/) object modeling tool. To start the adventure with this library we have to install all required dependencies:

JS TS

TypeScript

```typescript

$ npm install --save mongoose
$ npm install --save-dev @types/mongoose
```

TypeScript

```typescript

$ npm install --save mongoose
```

The first step we need to do is to establish the connection with our database using `connect()` function. The `connect()` function returns a `Promise`, therefore we have to create an [async provider](/v5/fundamentals/async-components).

database.providers.ts

JS TS

TypeScript

```typescript

import * as mongoose from 'mongoose';

export const databaseProviders = [
  {
    provide: 'DbConnectionToken',
    useFactory: async (): Promise<typeof mongoose> =>
      await mongoose.connect('mongodb://localhost/nest'),
  },
];
```

> **Hint** Following best practices, we declared the custom provider in the separated file which has a `*.providers.ts` suffix.

Then, we need to export these providers to make them **accessible** for the rest part of the application.

database.module.ts

JS TS

TypeScript

```typescript

import { Module } from '@nestjs/common';
import { databaseProviders } from './database.providers';

@Module({
  providers: [...databaseProviders],
  exports: [...databaseProviders],
})
export class DatabaseModule {}
```

Now we can inject the `Connection` object using `@Inject()` decorator. Each class that would depend on the `Connection` async provider will wait until a `Promise` is resolved.

#### Model injection

With Mongoose, everything is derived from a [Schema](http://mongoosejs.com/docs/guide.html). Let's define the `CatSchema`:

cats/schemas/cat.schema.ts

JS TS

TypeScript

```typescript

import * as mongoose from 'mongoose';

export const CatSchema = new mongoose.Schema({
  name: String,
  age: Number,
  breed: String,
});
```

The `CatsSchema` belongs to the `cats` directory. This directory represents the `CatsModule`.

Now it's time to create a **Model** provider:

cats.providers.ts

JS TS

TypeScript

```typescript

import { Connection } from 'mongoose';
import { CatSchema } from './schemas/cat.schema';

export const catsProviders = [
  {
    provide: 'CatModelToken',
    useFactory: (connection: Connection) => connection.model('Cat', CatSchema),
    inject: ['DbConnectionToken'],
  },
];
```

TypeScript

```typescript

import { CatSchema } from './schemas/cat.schema';

export const catsProviders = [
  {
    provide: 'CatModelToken',
    useFactory: (connection) => connection.model('Cat', CatSchema),
    inject: ['DbConnectionToken'],
  },
];
```

> **Notice** In the real-world applications you should avoid **magic strings**. Both `CatModelToken` and `DbConnectionToken` should be kept in the separated `constants.ts` file.

Now we can inject the `CatModelToken` to the `CatsService` using the `@Inject()` decorator:

cats.service.ts

JS TS

TypeScript

```typescript

import { Model } from 'mongoose';
import { Injectable, Inject } from '@nestjs/common';
import { Cat } from './interfaces/cat.interface';
import { CreateCatDto } from './dto/create-cat.dto';

@Injectable()
export class CatsService {
  constructor(
    @Inject('CatModelToken')
    private readonly catModel: Model<Cat>,
  ) {}

  async create(createCatDto: CreateCatDto): Promise<Cat> {
    const createdCat = new this.catModel(createCatDto);
    return await createdCat.save();
  }

  async findAll(): Promise<Cat[]> {
    return await this.catModel.find().exec();
  }
}
```

TypeScript

```typescript

import { Injectable, Dependencies } from '@nestjs/common';

@Injectable()
@Dependencies('CatModelToken')
export class CatsService {
  constructor(catModel) {
    this.catModel = catModel;
  }

  async create(createCatDto) {
    const createdCat = new this.catModel(createCatDto);
    return await createdCat.save();
  }

  async findAll() {
    return await this.catModel.find().exec();
  }
}
```

In the above example we have used the `Cat` interface. This interface extends the `Document` from the mongoose package:

cat.interface.ts

TypeScript

```typescript

import { Document } from 'mongoose';

export interface Cat extends Document {
  readonly name: string;
  readonly age: number;
  readonly breed: string;
}
```

The database connection is **asynchronous**, but Nest makes this process completely invisible for the end-user. The `CatModel` class is waiting for the db connection, and the `CatsService` is delayed until model is ready to use. The entire application can start when each class is instantiated.

Here is a final `CatsModule`:

cats.module.ts

JS TS

TypeScript

```typescript

import { Module } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';
import { catsProviders } from './cats.providers';
import { DatabaseModule } from '../database/database.module';

@Module({
  imports: [DatabaseModule],
  controllers: [CatsController],
  providers: [
    CatsService,
    ...catsProviders,
  ],
})
export class CatsModule {}
```

> **Hint** Don't forget to import the `CatsModule` into the root `ApplicationModule`.

* MongoDB (Mongoose)

----
url: https://docs.nestjs.com/v4/advanced/hierarchical-injector
----

### Hierarchical Injector

The Nest injector is **hierarchical**. To understand this useful treat, you first have to get acquainted with the process of creating the class instance. When any class depends on the other class, the injector's trying to find the appropriate instance in the current **scope**. The current scope isn't always the module to which the class belongs to.

Let's consider an example. We've a `CoreModule`:

core.module.ts

JavaScript TypeScript

TypeScript

```typescript

@Module({
  imports: [CommonModule],
  components: [CoreService, ContextService],
})
export class CoreModule {}
```

This module imports the `CommonModule` and contains 2 components, successively `CoreService` and `ContextService`. The `CommonModule` contains single component, the `CommonService`. This component is exported, so it's available within `CoreModule` as well.

common.module.ts

JavaScript TypeScript

TypeScript

```typescript

@Module({
  components: [CommonService],
  exports: [CommonService],
})
export class CommonModule {}
```

Let's take a look at `ContextService` now:

core/context.service.ts

JavaScript TypeScript

TypeScript

```typescript

@Component()
export class ContextService {
  constructor(private readonly commonService: CommonService) {}
}
```

TypeScript

```typescript

@Component()
@Dependencies(CommonService)
export class ContextService {
  constructor(commonService) {
    this.commonService = commonService;
  }
}
```

This class depends on the `CommonService`. This service's imported from the child module (`CommonModule`), so it's a typical situation. Now something that may turn out to be surprising, the `CommonService`:

common/common.service.ts

JavaScript TypeScript

TypeScript

```typescript

@Component()
export class CommonService {
  constructor(private readonly coreService: CoreService) {}
}
```

TypeScript

```typescript

@Component()
@Dependencies(CoreService)
export class CommonService {
  constructor(coreService) {
    this.coreService = coreService;
  }
}
```

The `CommonService` depends on the `CoreService`. It's possible, because the `CommonService` instance was resolved within the `CoreModule` **context** (was injected by the component, which belongs to the parent module).

#### Motivation

This technique makes possible to create reusable modules using **boundless abstraction**. Moreover, it allows overriding every component from the imported module using [custom components](/v4/fundamentals/dependency-injection) feature. For example, you can create a default implementation of the class inside the feature module, but then overload it inside the currently processed context.

> **Notice** This technique is powerful, but also very dangerous. Be careful whenever you're gonna use this feature, and make sure that you exactly know what you're doing.

#### Sponsors

[](https://valor-software.com/)

Nest is an MIT-licensed open source project. It can grow thanks to the support by these awesome people. If you'd like to join them, please read more [here](https://opencollective.com/nest). Thanks!

[](https://opencollective.com/nest/backer/0/website)[](https://opencollective.com/nest/backer/1/website)[](https://opencollective.com/nest/backer/2/website)[](https://opencollective.com/nest/backer/3/website)[](https://opencollective.com/nest/backer/4/website)[](https://opencollective.com/nest/backer/5/website)[](https://opencollective.com/nest/backer/6/website)[](https://opencollective.com/nest/backer/7/website)[](https://opencollective.com/nest/backer/8/website)[](https://opencollective.com/nest/backer/9/website)[](https://opencollective.com/nest/backer/10/website)[](https://opencollective.com/nest/backer/11/website)[](https://opencollective.com/nest/backer/12/website)[](https://opencollective.com/nest/backer/13/website)[](https://opencollective.com/nest/backer/14/website)[](https://opencollective.com/nest/backer/15/website)[](https://opencollective.com/nest/backer/16/website)[](https://opencollective.com/nest/backer/17/website)[](https://opencollective.com/nest/backer/18/website)[](https://opencollective.com/nest/backer/19/website)[](https://opencollective.com/nest/backer/20/website)[](https://opencollective.com/nest/backer/21/website)[](https://opencollective.com/nest/backer/22/website)[](https://opencollective.com/nest/backer/23/website)[](https://opencollective.com/nest/backer/24/website)[](https://opencollective.com/nest/backer/25/website)[](https://opencollective.com/nest/backer/26/website)[](https://opencollective.com/nest/backer/27/website)[](https://opencollective.com/nest/backer/28/website)[](https://opencollective.com/nest/backer/29/website)

[Become a sponsor](https://opencollective.com/nest)

----
url: https://docs.nestjs.com/v11/devtools/ci-cd-integration
----

* [CI/CD integration](https://docs.nestjs.com/v11/devtools/ci-cd-integration#cicd-integration)
* [Publishing graphs](https://docs.nestjs.com/v11/devtools/ci-cd-integration#publishing-graphs)
* [Reports](https://docs.nestjs.com/v11/devtools/ci-cd-integration#reports)
* [Build preview](https://docs.nestjs.com/v11/devtools/ci-cd-integration#build-preview)
* [Integrations: GitHub Actions](https://docs.nestjs.com/v11/devtools/ci-cd-integration#integrations-github-actions)
* [Integrations: Gitlab Pipelines](https://docs.nestjs.com/v11/devtools/ci-cd-integration#integrations-gitlab-pipelines)
* [Other CI/CD tools](https://docs.nestjs.com/v11/devtools/ci-cd-integration#other-cicd-tools)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/devtools/ci-cd.md "Suggest Edits")

### CI/CD integration

> **Hint** This chapter covers the Nest Devtools integration with the Nest framework. If you are looking for the Devtools application, please visit the [Devtools](https://devtools.nestjs.com) website.

CI/CD integration is available for users with the **Enterprise** plan.

You can watch this video to learn why & how CI/CD integration can help you:

#### Publishing graphs[#](/devtools/ci-cd-integration#publishing-graphs)

Let's first configure the application bootstrap file (`main.ts`) to use the `GraphPublisher` class (exported from the `@nestjs/devtools-integration` - see previous chapter for more details), as follows:

```typescript

async function bootstrap() {
  const shouldPublishGraph = process.env.PUBLISH_GRAPH === "true";

  const app = await NestFactory.create(AppModule, {
    snapshot: true,
    preview: shouldPublishGraph,
  });

  if (shouldPublishGraph) {
    await app.init();

    const publishOptions = { ... } // NOTE: this options object will vary depending on the CI/CD provider you're using
    const graphPublisher = new GraphPublisher(app);
    await graphPublisher.publish(publishOptions);

    await app.close();
  } else {
    await app.listen(process.env.PORT ?? 3000);
  }
}
```

```yaml

name: Devtools

on:
  push:
    branches:
      - master
  pull_request:
    branches:
      - '*'

jobs:
  publish:
    if: github.actor!= 'dependabot[bot]'
    name: Publish graph
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: '16'
          cache: 'npm'
      - name: Install dependencies
        run: npm ci
      - name: Setup Environment (PR)
        if: ${{ github.event_name == 'pull_request' }}
        shell: bash
        run: |
          echo "COMMIT_SHA=${{ github.event.pull_request.head.sha }}" >>\${GITHUB_ENV}
      - name: Setup Environment (Push)
        if: ${{ github.event_name == 'push' }}
        shell: bash
        run: |
          echo "COMMIT_SHA=\${GITHUB_SHA}" >> \${GITHUB_ENV}
      - name: Publish
        run: PUBLISH_GRAPH=true npm run start
        env:
          DEVTOOLS_API_KEY: CHANGE_THIS_TO_YOUR_API_KEY
          REPOSITORY_NAME: ${{ github.event.repository.name }}
          BRANCH_NAME: ${{ github.head_ref || github.ref_name }}
          TARGET_SHA: ${{ github.event.pull_request.base.sha }}
```

Ideally, `DEVTOOLS_API_KEY` environment variable should be retrieved from GitHub Secrets, read more [here](https://docs.github.com/en/actions/security-guides/encrypted-secrets#creating-encrypted-secrets-for-a-repository) .

This workflow will run per each pull request that's targeting the `master` branch OR in case there's a direct commit to the `master` branch. Feel free to align this configuration to whatever your project needs. What's essential here is that we provide necessary environment variables for our `GraphPublisher` class (to run).

However, there's one variable that needs to be updated before we can start using this workflow - `DEVTOOLS_API_KEY`. We can generate an API key dedicated for our project on this [page](https://devtools.nestjs.com/settings/manage-api-keys).

Lastly, let's navigate to the `main.ts` file again and update the `publishOptions` object we previously left empty.

```typescript

const publishOptions = {
  apiKey: process.env.DEVTOOLS_API_KEY,
  repository: process.env.REPOSITORY_NAME,
  owner: process.env.GITHUB_REPOSITORY_OWNER,
  sha: process.env.COMMIT_SHA,
  target: process.env.TARGET_SHA,
  trigger: process.env.GITHUB_BASE_REF ? 'pull' : 'push',
  branch: process.env.BRANCH_NAME,
};
```

For the best developer experience, make sure to integrate the **GitHub application** for your project by clicking on the "Integrate GitHub app" button (see screenshot below). Note - this isn't required.

With this integration, you'll be able to see the status of the preview/report generation process right in your pull request:

#### Integrations: Gitlab Pipelines[#](/devtools/ci-cd-integration#integrations-gitlab-pipelines)

First let's start from creating a new Gitlab CI configuration file in the root directory of our project and call it, for example, `.gitlab-ci.yml`. Inside this file, let's use the following definition:

```typescript

const publishOptions = {
  apiKey: process.env.DEVTOOLS_API_KEY,
  repository: process.env.REPOSITORY_NAME,
  owner: process.env.GITHUB_REPOSITORY_OWNER,
  sha: process.env.COMMIT_SHA,
  target: process.env.TARGET_SHA,
  trigger: process.env.GITHUB_BASE_REF ? 'pull' : 'push',
  branch: process.env.BRANCH_NAME,
};
```

> **Hint** Ideally, `DEVTOOLS_API_KEY` environment variable should be retrieved from secrets.

This workflow will run per each pull request that's targeting the `master` branch OR in case there's a direct commit to the `master` branch. Feel free to align this configuration to whatever your project needs. What's essential here is that we provide necessary environment variables for our `GraphPublisher` class (to run).

However, there's one variable (in this workflow definition) that needs to be updated before we can start using this workflow - `DEVTOOLS_API_KEY`. We can generate an API key dedicated for our project on this **page** .

Lastly, let's navigate to the `main.ts` file again and update the `publishOptions` object we previously left empty.

```yaml

image: node:16

stages:
  - build

cache:
  key:
    files:
      - package-lock.json
  paths:
    - node_modules/

workflow:
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
      when: always
    - if: $CI_COMMIT_BRANCH == "master" && $CI_PIPELINE_SOURCE == "push"
      when: always
    - when: never

install_dependencies:
  stage: build
  script:
    - npm ci

publish_graph:
  stage: build
  needs:
    - install_dependencies
  script: npm run start
  variables:
    PUBLISH_GRAPH: 'true'
    DEVTOOLS_API_KEY: 'CHANGE_THIS_TO_YOUR_API_KEY'
```

#### Other CI/CD tools[#](/devtools/ci-cd-integration#other-cicd-tools)

Nest Devtools CI/CD integration can be used with any CI/CD tool of your choice (e.g., [Bitbucket Pipelines](https://bitbucket.org/product/features/pipelines) , [CircleCI](https://circleci.com/), etc) so don't feel limited to providers we described here.

Look at the following `publishOptions` object configuration to understand what information is required to publish the graph for a given commit/build/PR.

```typescript

const publishOptions = {
  apiKey: process.env.DEVTOOLS_API_KEY,
  repository: process.env.CI_PROJECT_NAME,
  owner: process.env.CI_PROJECT_ROOT_NAMESPACE,
  sha: process.env.CI_COMMIT_SHA,
  target: process.env.CI_MERGE_REQUEST_DIFF_BASE_SHA,
  trigger: process.env.CI_MERGE_REQUEST_DIFF_BASE_SHA ? 'pull' : 'push',
  branch: process.env.CI_COMMIT_BRANCH ?? process.env.CI_MERGE_REQUEST_SOURCE_BRANCH_NAME,
};
```

Most of this information is provided through CI/CD built-in environment variables (see [CircleCI built-in environment list](https://circleci.com/docs/variables/#built-in-environment-variables) and [Bitbucket variables](https://support.atlassian.com/bitbucket-cloud/docs/variables-and-secrets/) ).

When it comes to the pipeline configuration for publishing graphs, we recommend using the following triggers:

* `push` event - only if the current branch represents a deployment environment, for example `master`, `main`, `staging`, `production`, etc.
* `pull request` event - always, or when the **target branch** represents a deployment environment (see above)

----
url: https://docs.nestjs.com/cli/scripts
----

[Skip to content](#content)

On this page

* [Nest CLI and scripts](https://docs.nestjs.com/cli/scripts#nest-cli-and-scripts)
* [The nest binary](https://docs.nestjs.com/cli/scripts#the-nest-binary)
* [Build](https://docs.nestjs.com/cli/scripts#build)
* [Execution](https://docs.nestjs.com/cli/scripts#execution)
* [Generation](https://docs.nestjs.com/cli/scripts#generation)
* [Package scripts](https://docs.nestjs.com/cli/scripts#package-scripts)
* [Backward compatibility](https://docs.nestjs.com/cli/scripts#backward-compatibility)
* [Migration](https://docs.nestjs.com/cli/scripts#migration)

### Nest CLI and scripts

This section explains how the `nest` command interacts with compilers and scripts, to help DevOps personnel manage the development environment.

A Nest application is a **standard** TypeScript application that must be compiled to JavaScript before it can run. There are various ways to handle the compilation step, and developers and teams are free to choose the one that works best for them. With that in mind, Nest provides a set of tools out of the box that aim to:

* Provide a standard build/execute process, available at the command line, that works with reasonable defaults.
* Keep the build/execute process **open**, so developers can access the underlying tools directly and customize them using their native features and options.
* Remain a completely standard TypeScript/Node.js framework, so that any external tools the team chooses can manage the entire compile/deploy/execute pipeline.

Nest achieves this through a combination of the `nest` command, a locally installed TypeScript compiler, and `package.json` scripts. The sections below describe how these pieces work together, what happens at each step of the build/execute process, and how to customize that behavior.

#### The nest binary[#](/cli/scripts#the-nest-binary)

The `nest` command is an OS-level binary (i.e., it runs from the OS command line). It covers three distinct areas, described below. We recommend running the build (`nest build`) and execution (`nest start`) subcommands through the `package.json` scripts that are generated when you scaffold a project (see the [typescript starter](https://github.com/nestjs/typescript-starter) if you prefer to start by cloning a repository instead of running `nest new`).

#### Build[#](/cli/scripts#build)

`nest build` is a wrapper around the standard `tsc` or `swc` compiler (for [standard projects](/cli/overview#project-structure)) or the Rspack bundler (for [monorepos](/cli/overview#project-structure)). Apart from handling `tsconfig-paths` and running any enabled CLI plugins, it adds no compilation features or steps of its own. It exists because most developers, especially when starting out with Nest, don't need to adjust compiler options (e.g., in the `tsconfig.json` file), which can be tricky.

See the [nest build](/cli/usages#nest-build) documentation for more details.

#### Execution[#](/cli/scripts#execution)

`nest start` ensures the project has been built (same as `nest build`), then invokes the `node` command in a portable way to execute the compiled application. As with builds, you can customize this process through the `nest start` command and its options, or replace it entirely. The whole process is a standard TypeScript build and execute pipeline, and you can manage it as such.

See the [nest start](/cli/usages#nest-start) documentation for more details.

#### Generation[#](/cli/scripts#generation)

The `nest generate` commands generate new components, or new applications and libraries within a workspace. (To create a new project, use `nest new`.)

#### Package scripts[#](/cli/scripts#package-scripts)

Running `nest` commands at the OS command level requires the `nest` binary to be installed globally. This is a standard npm feature, outside Nest's direct control. One consequence is that the globally installed `nest` binary is **not** managed as a project dependency in `package.json`, so two developers can run two different versions of it. The standard solution is to use package scripts, so that you can treat the tools used in the build and execute steps as development dependencies.

When you run `nest new`, or clone the [typescript starter](https://github.com/nestjs/typescript-starter), Nest populates the new project's `package.json` scripts with commands such as `build` and `start`. It also installs the underlying compiler tools (such as `typescript`) as **dev dependencies**.

You run the build and execute scripts with commands such as:

```bash

$ npm run build
```

and

```bash

$ npm run start
```

These commands use npm's script runner to execute `nest build` or `nest start` with the **locally installed**`nest` binary. By using these built-in package scripts, you get full dependency management over the Nest CLI commands\*. By following this **recommended** usage, all members of your organization run the same version of the commands.

\*This applies to the `build` and `start` commands. The `nest new` and `nest generate` commands aren't part of the build/execute pipeline, so they operate in a different context and don't come with built-in `package.json` scripts.

We recommend that most developers and teams use the package scripts to build and run their Nest projects. You can customize the behavior of these scripts through their options, and customize the `tsc`, `swc`, or Rspack configuration files (e.g., `tsconfig.json`) as needed. You are also free to run a completely custom build process to compile the TypeScript (or even to execute TypeScript directly with `ts-node`).

#### Backward compatibility[#](/cli/scripts#backward-compatibility)

Because Nest applications are pure TypeScript applications, previous versions of the Nest build/execute scripts continue to work. You are not required to upgrade them. You can adopt the `nest build` and `nest start` commands when you're ready, or keep running your previous or customized scripts.

#### Migration[#](/cli/scripts#migration)

You are not required to make any changes, but you may want to switch to the CLI commands instead of tools such as `tsc-watch` or `ts-node`. To do so, install the latest version of `@nestjs/cli` both globally and locally:

```bash

$ npm install -g @nestjs/cli
$ cd /some/project/root/folder
$ npm install -D @nestjs/cli
```

Then replace the `scripts` defined in `package.json` with the following:

```typescript

"build": "nest build",
"start": "nest start",
"start:dev": "nest start --watch",
"start:debug": "nest start --debug --watch",
```

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/cli/scripts.md)

----
url: https://docs.nestjs.com/v11/techniques/server-sent-events
----

* [Server-Sent Events](https://docs.nestjs.com/v11/techniques/server-sent-events#server-sent-events)
* [Usage](https://docs.nestjs.com/v11/techniques/server-sent-events#usage)
* [Client disconnection](https://docs.nestjs.com/v11/techniques/server-sent-events#client-disconnection)
* [Signal lifetime](https://docs.nestjs.com/v11/techniques/server-sent-events#signal-lifetime)
* [Example](https://docs.nestjs.com/v11/techniques/server-sent-events#example)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/techniques/server-sent-events.md "Suggest Edits")

### Server-Sent Events

Server-Sent Events (SSE) is a server push technology enabling a client to receive automatic updates from a server via HTTP connection. Each notification is sent as a block of text terminated by a pair of newlines (learn more [here](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events)).

#### Usage[#](/techniques/server-sent-events#usage)

To enable Server-Sent events on a route (route registered within a **controller class**), annotate the method handler with the `@Sse()` decorator.

```typescript

@Sse('sse')
sse(): Observable<MessageEvent> {
  return interval(1000).pipe(map((_) => ({ data: { hello: 'world' } })));
}
```

> **Hint** The `@Sse()` decorator and `MessageEvent` interface are imported from the `@nestjs/common`, while `Observable`, `interval`, and `map` are imported from the `rxjs` package.

> **Warning** Server-Sent Events routes must return an `Observable` stream.

In the example above, we defined a route named `sse` that will allow us to propagate real-time updates. These events can be listened to using the [EventSource API](https://developer.mozilla.org/en-US/docs/Web/API/EventSource).

The `sse` method returns an `Observable` that emits multiple `MessageEvent` (in this example, it emits a new `MessageEvent` every second). The `MessageEvent` object should respect the following interface to match the specification:

```typescript

export interface MessageEvent {
  data: string | object;
  id?: string;
  type?: string;
  retry?: number;
}
```

With this in place, we can now create an instance of the `EventSource` class in our client-side application, passing the `/sse` route (which matches the endpoint we have passed into the `@Sse()` decorator above) as a constructor argument.

`EventSource` instance opens a persistent connection to an HTTP server, which sends events in `text/event-stream` format. The connection remains open until closed by calling `EventSource.close()`.

Once the connection is opened, incoming messages from the server are delivered to your code in the form of events. If there is an event field in the incoming message, the triggered event is the same as the event field value. If no event field is present, then a generic `message` event is fired ([source](https://developer.mozilla.org/en-US/docs/Web/API/EventSource)).

```javascript

const eventSource = new EventSource('/sse');
eventSource.onmessage = ({ data }) => {
  console.log('New message', JSON.parse(data));
};
```

#### Client disconnection[#](/techniques/server-sent-events#client-disconnection)

When a client closes the SSE connection (e.g., `eventSource.close()`), NestJS automatically unsubscribes from the returned Observable, which stops the event stream and cleans up any associated resources — including the interval timer in the example above.

To run custom teardown logic when a client disconnects, use the `finalize` operator:

```typescript

@Sse('sse')
sse(): Observable<MessageEvent> {
  return interval(1000).pipe(
    map((_) => ({ data: { hello: 'world' } })),
    finalize(() => console.log('Client disconnected')),
  );
}
```

> **Hint** The `finalize` operator (imported from `rxjs`) executes its callback whenever the Observable terminates — by completion, error, or unsubscription (which includes client disconnect). This makes it the right place to release external resources such as database cursors or file handles tied to the stream.

An `@Sse()` handler may be asynchronous — returning a `Promise<Observable>` rather than an `Observable` directly. This is common when the stream needs expensive setup before the first event can be produced: opening a database cursor, acquiring a model session, or authorizing against a downstream service.

```typescript

@Sse('stream')
async stream(): Promise<Observable<MessageEvent>> {
  const session = await createSession();

  return new Observable(subscriber => {
    // ...produce events from `session`
  });
}
```

There is a gap here. If the client disconnects **while the promise is still resolving**, the returned `Observable` is never subscribed — Nest will not start a producer whose consumer has already gone away. That is the right behaviour for the stream, but it means the `Observable`'s teardown logic never runs, and anything allocated during setup (the `session` above) is leaked.

To close that gap, inject the request's `AbortSignal` with the `@SseSignal()` decorator:

```typescript

import { MessageEvent, Sse, SseSignal } from '@nestjs/common';
import { EMPTY, Observable } from 'rxjs';

@Sse('stream')
async stream(@SseSignal() signal: AbortSignal): Promise<Observable<MessageEvent>> {
  const session = await createSession();

  if (signal.aborted) {
    // The client disconnected during setup. The Observable below will never be
    // subscribed, so release the resource here.
    await session.close();
    return EMPTY;
  }

  return new Observable(subscriber => {
    const stream = session.start();
    stream.on('data', data => subscriber.next({ data }));

    return () => {
      stream.stop();
      session.close();
    };
  });
}
```

#### Signal lifetime[#](/techniques/server-sent-events#signal-lifetime)

The signal represents the lifetime of the **SSE response**, not just the connection. It is aborted once the stream terminates for any reason:

* the client disconnected;
* the `Observable` completed;
* the `Observable` errored.

This makes the signal a single cleanup hook for the whole request. Rather than duplicating teardown across an `abort` listener and the `Observable`'s own teardown function, you can wire resources to the signal once and have them released on every exit path:

```typescript

@Sse('stream')
async stream(@SseSignal() signal: AbortSignal): Promise<Observable<MessageEvent>> {
  // The signal aborts when the response ends, so the fetch is cancelled whether
  // the client disconnected or the stream simply finished.
  const upstream = await fetch(UPSTREAM_URL, { signal });

  return new Observable(subscriber => {
    // ...
  });
}
```

Because the signal also aborts on normal completion, `signal.aborted` is only meaningful as a "did the client go away?" check **during setup** — before the `Observable` is returned. At that point the stream cannot have completed yet, so an aborted signal unambiguously means the client disconnected.

> **Notice** Cleanup wired to the `abort` event may run alongside the `Observable`'s teardown function, so make it idempotent.

Inside a producer, the signal is also a convenient way to end the stream when the client leaves:

```typescript

return new Observable<MessageEvent>(subscriber => {
  const timer = setInterval(() => subscriber.next({ data: 'tick' }), 1000);
  const onAbort = () => subscriber.complete();

  signal.addEventListener('abort', onAbort, { once: true });

  return () => {
    clearInterval(timer);
    signal.removeEventListener('abort', onAbort);
  };
});
```

> **Hint**`@SseSignal()` is only populated on `@Sse()` routes; on any other handler it resolves to `undefined`. It works identically on both the Express and Fastify platforms.

#### Example[#](/techniques/server-sent-events#example)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/28-sse).

----
url: https://docs.nestjs.com/v8/techniques/performance
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Performance (Fastify)](https://docs.nestjs.com/v8/techniques/performance#performance-fastify)
* [Installation](https://docs.nestjs.com/v8/techniques/performance#installation)
* [Adapter](https://docs.nestjs.com/v8/techniques/performance#adapter)
* [Platform specific packages](https://docs.nestjs.com/v8/techniques/performance#platform-specific-packages)
* [Redirect response](https://docs.nestjs.com/v8/techniques/performance#redirect-response)
* [Fastify options](https://docs.nestjs.com/v8/techniques/performance#fastify-options)
* [Example](https://docs.nestjs.com/v8/techniques/performance#example)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/techniques/performance.md "Suggest Edits")

### Performance (Fastify)

By default, Nest makes use of the [Express](https://expressjs.com/) framework. As mentioned earlier, Nest also provides compatibility with other libraries such as, for example, [Fastify](https://github.com/fastify/fastify). Nest achieves this framework independence by implementing a framework adapter whose primary function is to proxy middleware and handlers to appropriate library-specific implementations.

> **Hint** Note that in order for a framework adapter to be implemented, the target library has to provide similar request/response pipeline processing as found in Express.

[Fastify](https://github.com/fastify/fastify) provides a good alternative framework for Nest because it solves design issues in a similar manner to Express. However, fastify is much **faster** than Express, achieving almost two times better benchmarks results. A fair question is why does Nest use Express as the default HTTP provider? The reason is that Express is widely-used, well-known, and has an enormous set of compatible middleware, which is available to Nest users out-of-the-box.

But since Nest provides framework-independence, you can easily migrate between them. Fastify can be a better choice when you place high value on very fast performance. To utilize Fastify, simply choose the built-in `FastifyAdapter` as shown in this chapter.

#### Installation[#](/techniques/performance#installation)

First, we need to install the required package:

```bash

$ npm i --save @nestjs/platform-fastify
```

#### Adapter[#](/techniques/performance#adapter)

Once the Fastify platform is installed, we can use the `FastifyAdapter`.

main.ts

JS TS

```typescript

import { NestFactory } from '@nestjs/core';
import {
  FastifyAdapter,
  NestFastifyApplication,
} from '@nestjs/platform-fastify';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create<NestFastifyApplication>(
    AppModule,
    new FastifyAdapter()
  );
  await app.listen(3000);
}
bootstrap();
```

By default, Fastify listens only on the `localhost 127.0.0.1` interface ([read more](https://www.fastify.io/docs/latest/Guides/Getting-Started/#your-first-server)). If you want to accept connections on other hosts, you should specify `'0.0.0.0'` in the `listen()` call:

```typescript

async function bootstrap() {
  const app = await NestFactory.create<NestFastifyApplication>(
    AppModule,
    new FastifyAdapter(),
  );
  await app.listen(3000, '0.0.0.0');
}
```

#### Platform specific packages[#](/techniques/performance#platform-specific-packages)

Keep in mind that when you use the `FastifyAdapter`, Nest uses Fastify as the **HTTP provider**. This means that each recipe that relies on Express may no longer work. You should, instead, use Fastify equivalent packages.

#### Redirect response[#](/techniques/performance#redirect-response)

Fastify handles redirect responses slightly differently than Express. To do a proper redirect with Fastify, return both the status code and the URL, as follows:

```typescript

@Get()
index(@Res() res) {
  res.status(302).redirect('/login');
}
```

#### Fastify options[#](/techniques/performance#fastify-options)

You can pass options into the Fastify constructor through the `FastifyAdapter` constructor. For example:

```typescript

new FastifyAdapter({ logger: true });
```

#### Example[#](/techniques/performance#example)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/10-fastify).

----
url: https://docs.nestjs.com/v7/fundamentals/execution-context
----

* [Execution context](https://docs.nestjs.com/v7/fundamentals/execution-context#execution-context)
* [ArgumentsHost class](https://docs.nestjs.com/v7/fundamentals/execution-context#argumentshost-class)
* [Current application context](https://docs.nestjs.com/v7/fundamentals/execution-context#current-application-context)
* [Host handler arguments](https://docs.nestjs.com/v7/fundamentals/execution-context#host-handler-arguments)
* [ExecutionContext class](https://docs.nestjs.com/v7/fundamentals/execution-context#executioncontext-class)
* [Reflection and metadata](https://docs.nestjs.com/v7/fundamentals/execution-context#reflection-and-metadata)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/fundamentals/execution-context.md "Suggest Edits")

### Execution context

Nest provides several utility classes that help make it easy to write applications that function across multiple application contexts (e.g., Nest HTTP server-based, microservices and WebSockets application contexts). These utilities provide information about the current execution context which can be used to build generic [guards](/v7/guards), [filters](/v7/exception-filters), and [interceptors](/v7/interceptors) that can work across a broad set of controllers, methods, and execution contexts.

We cover two such classes in this chapter: `ArgumentsHost` and `ExecutionContext`.

#### ArgumentsHost class[#](/fundamentals/execution-context#argumentshost-class)

The `ArgumentsHost` class provides methods for retrieving the arguments being passed to a handler. It allows choosing the appropriate context (e.g., HTTP, RPC (microservice), or WebSockets) to retrieve the arguments from. The framework provides an instance of `ArgumentsHost`, typically referenced as a `host` parameter, in places where you may want to access it. For example, the `catch()` method of an [exception filter](https://docs.nestjs.com/exception-filters#arguments-host) is called with an `ArgumentsHost`instance.

`ArgumentsHost` simply acts as an abstraction over a handler's arguments. For example, for HTTP server applications (when `@nestjs/platform-express` is being used), the `host` object encapsulates Express's `[request, response, next]` array, where `request` is the request object, `response` is the response object, and `next` is a function that controls the application's request-response cycle. On the other hand, for [GraphQL](/v7/graphql/quick-start) applications, the `host` object contains the `[root, args, context, info]` array.

#### Current application context[#](/fundamentals/execution-context#current-application-context)

When building generic [guards](/v7/guards), [filters](/v7/exception-filters), and [interceptors](/v7/interceptors) which are meant to run across multiple application contexts, we need a way to determine the type of application that our method is currently running in. Do this with the `getType()` method of `ArgumentsHost`:

```typescript

if (host.getType() === 'http') {
  // do something that is only important in the context of regular HTTP requests (REST)
} else if (host.getType() === 'rpc') {
  // do something that is only important in the context of Microservice requests
} else if (host.getType<GqlContextType>() === 'graphql') {
  // do something that is only important in the context of GraphQL requests
}
```

> **Hint** The `GqlContextType` is imported from the `@nestjs/graphql` package.

With the application type available, we can write more generic components, as shown below.

#### Host handler arguments[#](/fundamentals/execution-context#host-handler-arguments)

To retrieve the array of arguments being passed to the handler, one approach is to use the host object's `getArgs()` method.

```typescript

const [req, res, next] = host.getArgs();
```

You can pluck a particular argument by index using the `getArgByIndex()` method:

```typescript

const request = host.getArgByIndex(0);
const response = host.getArgByIndex(1);
```

In these examples we retrieved the request and response objects by index, which is not typically recommended as it couples the application to a particular execution context. Instead, you can make your code more robust and reusable by using one of the `host` object's utility methods to switch to the appropriate application context for your application. The context switch utility methods are shown below.

```typescript

/**
 * Switch context to RPC.
 */
switchToRpc(): RpcArgumentsHost;
/**
 * Switch context to HTTP.
 */
switchToHttp(): HttpArgumentsHost;
/**
 * Switch context to WebSockets.
 */
switchToWs(): WsArgumentsHost;
```

Let's rewrite the previous example using the `switchToHttp()` method. The `host.switchToHttp()` helper call returns an `HttpArgumentsHost` object that is appropriate for the HTTP application context. The `HttpArgumentsHost` object has two useful methods we can use to extract the desired objects. We also use the Express type assertions in this case to return native Express typed objects:

```typescript

const ctx = host.switchToHttp();
const request = ctx.getRequest<Request>();
const response = ctx.getResponse<Response>();
```

Similarly `WsArgumentsHost` and `RpcArgumentsHost` have methods to return appropriate objects in the microservices and WebSockets contexts. Here are the methods for `WsArgumentsHost`:

```typescript

export interface WsArgumentsHost {
  /**
   * Returns the data object.
   */
  getData<T>(): T;
  /**
   * Returns the client object.
   */
  getClient<T>(): T;
}
```

Following are the methods for `RpcArgumentsHost`:

```typescript

export interface RpcArgumentsHost {
  /**
   * Returns the data object.
   */
  getData<T>(): T;

  /**
   * Returns the context object.
   */
  getContext<T>(): T;
}
```

#### ExecutionContext class[#](/fundamentals/execution-context#executioncontext-class)

`ExecutionContext` extends `ArgumentsHost`, providing additional details about the current execution process. Like `ArgumentsHost`, Nest provides an instance of `ExecutionContext` in places you may need it, such as in the `canActivate()` method of a [guard](https://docs.nestjs.com/guards#execution-context) and the `intercept()` method of an [interceptor](https://docs.nestjs.com/interceptors#execution-context). It provides the following methods:

```typescript

export interface ExecutionContext extends ArgumentsHost {
  /**
   * Returns the type of the controller class which the current handler belongs to.
   */
  getClass<T>(): Type<T>;
  /**
   * Returns a reference to the handler (method) that will be invoked next in the
   * request pipeline.
   */
  getHandler(): Function;
}
```

The `getHandler()` method returns a reference to the handler about to be invoked. The `getClass()` method returns the type of the `Controller` class which this particular handler belongs to. For example, in an HTTP context, if the currently processed request is a `POST` request, bound to the `create()` method on the `CatsController`, `getHandler()` returns a reference to the `create()` method and `getClass()` returns the `CatsController`**type** (not instance).

```typescript

const methodKey = ctx.getHandler().name; // "create"
const className = ctx.getClass().name; // "CatsController"
```

The ability to access references to both the current class and handler method provides great flexibility. Most importantly, it gives us the opportunity to access the metadata set through the `@SetMetadata()` decorator from within guards or interceptors. We cover this use case below.

Nest provides the ability to attach **custom metadata** to route handlers through the `@SetMetadata()` decorator. We can then access this metadata from within our class to make certain decisions.

cats.controller.ts

JS TS

```typescript

@Post()
@SetMetadata('roles', ['admin'])
async create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

```typescript

@Post()
@SetMetadata('roles', ['admin'])
@Bind(Body())
async create(createCatDto) {
  this.catsService.create(createCatDto);
}
```

> **Hint** The `@SetMetadata()` decorator is imported from the `@nestjs/common` package.

With the construction above, we attached the `roles` metadata (`roles` is a metadata key and `['admin']` is the associated value) to the `create()` method. While this works, it's not good practice to use `@SetMetadata()` directly in your routes. Instead, create your own decorators, as shown below:

roles.decorator.ts

JS TS

```typescript

import { SetMetadata } from '@nestjs/common';

export const Roles = (...roles: string[]) => SetMetadata('roles', roles);
```

```typescript

import { SetMetadata } from '@nestjs/common';

export const Roles = (...roles) => SetMetadata('roles', roles);
```

This approach is much cleaner and more readable, and is strongly typed. Now that we have a custom `@Roles()` decorator, we can use it to decorate the `create()` method.

cats.controller.ts

JS TS

```typescript

@Post()
@Roles('admin')
async create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

```typescript

@Post()
@Roles('admin')
@Bind(Body())
async create(createCatDto) {
  this.catsService.create(createCatDto);
}
```

To access the route's role(s) (custom metadata), we'll use the `Reflector` helper class, which is provided out of the box by the framework and exposed from the `@nestjs/core` package. `Reflector` can be injected into a class in the normal way:

roles.guard.ts

JS TS

```typescript

@Injectable()
export class RolesGuard {
  constructor(private reflector: Reflector) {}
}
```

```typescript

@Injectable()
@Dependencies(Reflector)
export class CatsService {
  constructor(reflector) {
    this.reflector = reflector;
  }
}
```

> **Hint** The `Reflector` class is imported from the `@nestjs/core` package.

Now, to read the handler metadata, use the `get()` method.

```typescript

const roles = this.reflector.get<string[]>('roles', context.getHandler());
```

The `Reflector#get` method allows us to easily access the metadata by passing in two arguments: a metadata **key** and a **context** (decorator target) to retrieve the metadata from. In this example, the specified **key** is `'roles'` (refer back to the `roles.decorator.ts` file above and the `SetMetadata()` call made there). The context is provided by the call to `context.getHandler()`, which results in extracting the metadata for the currently processed route handler. Remember, `getHandler()` gives us a **reference** to the route handler function.

Alternatively, we may organize our controller by applying metadata at the controller level, applying to all routes in the controller class.

cats.controller.ts

JS TS

```typescript

@Roles('admin')
@Controller('cats')
export class CatsController {}
```

```typescript

@Roles('admin')
@Controller('cats')
export class CatsController {}
```

In this case, to extract controller metadata, we pass `context.getClass()` as the second argument (to provide the controller class as the context for metadata extraction) instead of `context.getHandler()`:

roles.guard.ts

JS TS

```typescript

const roles = this.reflector.get<string[]>('roles', context.getClass());
```

```typescript

const roles = this.reflector.get('roles', context.getClass());
```

Given the ability to provide metadata at multiple levels, you may need to extract and merge metadata from several contexts. The `Reflector` class provides two utility methods used to help with this. These methods extract **both** controller and method metadata at once, and combine them in different ways.

Consider the following scenario, where you've supplied `'roles'` metadata at both levels.

cats.controller.ts

JS TS

```typescript

@Roles('user')
@Controller('cats')
export class CatsController {
  @Post()
  @Roles('admin')
  async create(@Body() createCatDto: CreateCatDto) {
    this.catsService.create(createCatDto);
  }
}
```

```typescript

@Roles('user')
@Controller('cats')
export class CatsController {}
  @Post()
  @Roles('admin')
  @Bind(Body())
  async create(createCatDto) {
    this.catsService.create(createCatDto);
  }
}
```

If your intent is to specify `'user'` as the default role, and override it selectively for certain methods, you would probably use the `getAllAndOverride()` method.

```typescript

const roles = this.reflector.getAllAndOverride<string[]>('roles', [
  context.getHandler(),
  context.getClass(),
]);
```

A guard with this code, running in the context of the `create()` method, with the above metadata, would result in `roles` containing `['admin']`.

To get metadata for both and merge it (this method merges both arrays and objects), use the `getAllAndMerge()` method:

```typescript

const roles = this.reflector.getAllAndMerge<string[]>('roles', [
  context.getHandler(),
  context.getClass(),
]);
```

This would result in `roles` containing `['user', 'admin']`.

For both of these merge methods, you pass the metadata key as the first argument, and an array of metadata target contexts (i.e., calls to the `getHandler()` and/or `getClass())` methods) as the second argument.

----
url: https://docs.nestjs.com/v7/faq/request-lifecycle
----

* [Request lifecycle](https://docs.nestjs.com/v7/faq/request-lifecycle#request-lifecycle)
* [Middleware](https://docs.nestjs.com/v7/faq/request-lifecycle#middleware)
* [Guards](https://docs.nestjs.com/v7/faq/request-lifecycle#guards)
* [Interceptors](https://docs.nestjs.com/v7/faq/request-lifecycle#interceptors)
* [Pipes](https://docs.nestjs.com/v7/faq/request-lifecycle#pipes)
* [Filters](https://docs.nestjs.com/v7/faq/request-lifecycle#filters)
* [Summary](https://docs.nestjs.com/v7/faq/request-lifecycle#summary)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/faq/request-lifecycle.md "Suggest Edits")

### Request lifecycle

Nest applications handle requests and produce responses in a sequence we refer to as the **request lifecycle**. With the use of middleware, pipes, guards, and interceptors, it can be challenging to track down where a particular piece of code executes during the request lifecycle, especially as global, controller level, and route level components come into play. In general, a request flows through middleware to guards, then to interceptors, then to pipes and finally back to interceptors on the return path (as the response is generated).

#### Middleware[#](/faq/request-lifecycle#middleware)

Middleware is executed in a particular sequence. First, Nest runs globally bound middleware (such as middleware bound with `app.use`) and then it runs [module bound middleware](/v7/middleware), which are determined on paths. Middleware are run sequentially in the order they are bound, similar to the way middleware in Express works. In the case of middleware bound across different modules, the middleware bound to the root module will run first, and then middleware will run in the order that the modules are added to the imports array.

#### Guards[#](/faq/request-lifecycle#guards)

Guard execution starts with global guards, then proceeds to controller guards, and finally to route guards. As with middleware, guards run in the order in which they are bound. For example:

```typescript

@UseGuards(Guard1, Guard2)
@Controller('cats')
export class CatsController {
  constructor(private catsService: CatsService) {}

  @UseGuards(Guard3)
  @Get()
  getCats(): Cats[] {
    return this.catsService.getCats();
  }
}
```

`Guard1` will execute before `Guard2` and both will execute before `Guard3`.

> **Hint** When speaking about globally bound vs controller or locally bound, the difference is where the guard (or other component is bound). If you are using `app.useGlobalGuard()` or providing the component via a module, it is globally bound. Otherwise, it is bound to a controller if the decorator precedes a controller class, or to a route if the decorator proceeds a route declaration.

#### Interceptors[#](/faq/request-lifecycle#interceptors)

Interceptors, for the most part, follow the same pattern as guards, with one catch: as interceptors return [RxJS Observables](https://github.com/ReactiveX/rxjs), the observables will be resolved in a first in last out manner. So inbound requests will go through the standard global, controller, route level resolution, but the response side of the request (i.e., after returning from the controller method handler) will be resolved from route to controller to global. Also, any errors thrown by pipes, controllers, or services can be read in the `catchError` operator of an interceptor.

#### Pipes[#](/faq/request-lifecycle#pipes)

Pipes follow the standard global to controller to route bound sequence, with the same first in first out in regards to the `@usePipes()` parameters. However, at a route parameter level, if you have multiple pipes running, they will run in the order of the last parameter with a pipe to the first. This also applies to the route level and controller level pipes. For example, if we have the following controller:

```typescript

@UsePipes(GeneralValidationPipe)
@Controller('cats')
export class CatsController {
  constructor(private catsService: CatsService) {}

  @UsePipes(RouteSpecificPipe)
  @Patch(':id')
  updateCat(
    @Body() body: UpdateCatDTO,
    @Param() params: UpdateCatParams,
    @Query() query: UpdateCatQuery,
  ) {
    return this.catsService.updateCat(body, params, query);
  }
}
```

then the `GeneralValidationPipe` will run for the `query`, then the `params`, and then the `body` objects before moving on to the `RouteSpecificPipe`, which follows the same order. If any parameter-specific pipes were in place, they would run (again, from the last to first parameter) after the controller and route level pipes.

#### Filters[#](/faq/request-lifecycle#filters)

Filters are the only component that do not resolve global first. Instead, filters resolve from the lowest level possible, meaning execution starts with any route bound filters and proceeding next to controller level, and finally to global filters. Note that exceptions cannot be passed from filter to filter; if a route level filter catches the exception, a controller or global level filter cannot catch the same exception. The only way to achieve an effect like this is to use inheritance between the filters.

> **Hint** Filters are only executed if any uncaught exception occurs during the request process. Caught exceptions, such as those caught with a `try/catch` will not trigger Exception Filters to fire. As soon as an uncaught exception is encountered, the rest of the lifecycle is ignored and the request skips straight to the filter.

----
url: https://docs.nestjs.com/v7/techniques/session
----

* [Session](https://docs.nestjs.com/v7/techniques/session#session)
* [Use with Express (default)](https://docs.nestjs.com/v7/techniques/session#use-with-express-default)
* [Use with Fastify](https://docs.nestjs.com/v7/techniques/session#use-with-fastify)

[](https://srv.carbonads.net/ads/click/x/GTND4277CVSIC2JEFTBLYKQUF67D62JIFTSIVZ3JCAAI6KQJFT7ITK3KCEYI5KJUCYBDT2JEFTSI453IFTSIPZ3JCAAI627ECVADTK3K2JWNABY)[Solve problems faster with builders who've already shipped. Join builders. ](https://srv.carbonads.net/ads/click/x/GTND4277CVSIC2JEFTBLYKQUF67D62JIFTSIVZ3JCAAI6KQJFT7ITK3KCEYI5KJUCYBDT2JEFTSI453IFTSIPZ3JCAAI627ECVADTK3K2JWNABY)[ads via Carbon](http://carbonads.net/?utm_source=nestjscom\&utm_medium=ad_via_link\&utm_campaign=in_unit\&utm_term=carbon)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/techniques/sessions.md "Suggest Edits")

### Session

**HTTP sessions** provide a way to store information about the user across multiple requests, which is particularly useful for [MVC](/v7/techniques/mvc) applications.

#### Use with Express (default)[#](/techniques/session#use-with-express-default)

First install the required package (and its types for TypeScript users):

```shell

$ npm i express-session
$ npm i -D @types/express-session
```

Once the installation is complete, apply the `express-session` middleware as global middleware (for example, in your `main.ts` file).

```typescript

import * as session from 'express-session';
// somewhere in your initialization file
app.use(
  session({
    secret: 'my-secret',
    resave: false,
    saveUninitialized: false,
  }),
);
```

> **Notice** The default server-side session storage is purposely not designed for a production environment. It will leak memory under most conditions, does not scale past a single process, and is meant for debugging and developing. Read more in the [official repository](https://github.com/expressjs/session).

The `secret` is used to sign the session ID cookie. This can be either a string for a single secret, or an array of multiple secrets. If an array of secrets is provided, only the first element will be used to sign the session ID cookie, while all the elements will be considered when verifying the signature in requests. The secret itself should be not easily parsed by a human and would best be a random set of characters.

Enabling the `resave` option forces the session to be saved back to the session store, even if the session was never modified during the request. The default value is `true`, but using the default has been deprecated, as the default will change in the future.

Likewise, enabling the `saveUninitialized` option Forces a session that is "uninitialized" to be saved to the store. A session is uninitialized when it is new but not modified. Choosing `false` is useful for implementing login sessions, reducing server storage usage, or complying with laws that require permission before setting a cookie. Choosing `false` will also help with race conditions where a client makes multiple parallel requests without a session ([source](https://github.com/expressjs/session#saveuninitialized)).

You can pass several other options to the `session` middleware, read more about them in the [API documentation](https://github.com/expressjs/session#options).

> **Hint** Please note that `secure: true` is a recommended option. However, it requires an https-enabled website, i.e., HTTPS is necessary for secure cookies. If secure is set, and you access your site over HTTP, the cookie will not be set. If you have your node.js behind a proxy and are using `secure: true`, you need to set `"trust proxy"` in express.

With this in place, you can now set and read session values from within the route handlers, as follows:

```typescript

@Get()
findAll(@Req() request: Request) {
  req.session.visits = req.session.visits ? req.session.visits + 1 : 1;
}
```

> **Hint** The `@Req()` decorator is imported from the `@nestjs/common`, while `Request` from the `express` package.

Alternatively, you can use the `@Session()` decorator to extract a session object from the request, as follows:

```typescript

@Get()
findAll(@Session() session: Record<string, any>) {
  session.visits = session.visits ? session.visits + 1 : 1;
}
```

> **Hint** The `@Session()` decorator is imported from the `@nestjs/common` package.

#### Use with Fastify[#](/techniques/session#use-with-fastify)

First install the required package:

```shell

$ npm i fastify-secure-session
```

Once the installation is complete, register the `fastify-secure-session` plugin:

```typescript

import secureSession from 'fastify-secure-session';

// somewhere in your initialization file
const app = await NestFactory.create<NestFastifyApplication>(
  AppModule,
  new FastifyAdapter(),
);
app.register(secureSession, {
  secret: 'averylogphrasebiggerthanthirtytwochars',
  salt: 'mq9hDxBVDbspDR6n',
});
```

> **Hint** You can also pregenerate a key ([see instructions](https://github.com/fastify/fastify-secure-session)) or use [keys rotation](https://github.com/fastify/fastify-secure-session#using-keys-with-key-rotation).

Read more about the available options in the [official repository](https://github.com/fastify/fastify-secure-session).

With this in place, you can now set and read session values from within the route handlers, as follows:

```typescript

@Get()
findAll(@Req() request: FastifyRequest) {
  const visits = request.session.get('visits');
  request.session.set('visits', visits ? visits + 1 : 1);
}
```

Alternatively, you can use the `@Session()` decorator to extract a session object from the request, as follows:

```typescript

@Get()
findAll(@Session() session: secureSession.Session) {
  const visits = session.get('visits');
  session.set('visits', visits ? visits + 1 : 1);
}
```

> **Hint** The `@Session()` decorator is imported from the `@nestjs/common`, while `secureSession.Session` from the `fastify-secure-session` package (import statement: `import * as secureSession from 'fastify-secure-session'`).

----
url: https://docs.nestjs.com/reliability/outbox
----

[Skip to content](#content)

On this page

* [Outbox](https://docs.nestjs.com/reliability/outbox#outbox)
* [Prerequisites](https://docs.nestjs.com/reliability/outbox#prerequisites)
* [Keep messages in your database](https://docs.nestjs.com/reliability/outbox#keep-messages-in-your-database)
* [Register the outbox](https://docs.nestjs.com/reliability/outbox#register-the-outbox)
* [Save the order and its messages in one transaction](https://docs.nestjs.com/reliability/outbox#save-the-order-and-its-messages-in-one-transaction)
* [Handle order.placed in-process](https://docs.nestjs.com/reliability/outbox#handle-orderplaced-in-process)
* [Publish to the analytics microservice](https://docs.nestjs.com/reliability/outbox#publish-to-the-analytics-microservice)
* [Retries and the dead-letter queue](https://docs.nestjs.com/reliability/outbox#retries-and-the-dead-letter-queue)
* [Run several instances](https://docs.nestjs.com/reliability/outbox#run-several-instances)
* [Try it](https://docs.nestjs.com/reliability/outbox#try-it)
* [Testing](https://docs.nestjs.com/reliability/outbox#testing)
* [Delivery guarantees](https://docs.nestjs.com/reliability/outbox#delivery-guarantees)
* [Production checklist](https://docs.nestjs.com/reliability/outbox#production-checklist)
* [The store contract](https://docs.nestjs.com/reliability/outbox#the-store-contract)
* [Using BullMQ on Postgres instead](https://docs.nestjs.com/reliability/outbox#using-bullmq-on-postgres-instead)
* [Example](https://docs.nestjs.com/reliability/outbox#example)
* [Reference](https://docs.nestjs.com/reliability/outbox#reference)

### Outbox

When a customer places an order at an online store for cat food and supplies, the order API saves the order and announces it with an `OrderPlaced` event. Three things react to that event: a confirmation email goes out, stock is reserved, and a separate analytics service records the sale.

Saving the order and publishing the event are two writes to two different systems, and no transaction spans both:

* **Save, then publish.** If the process crashes or the broker is down between the two, the order exists but `OrderPlaced` is lost. The customer gets no email, the stock isn't reserved, and analytics undercounts.
* **Publish, then save.** If the insert fails, the customer is thanked for an order that doesn't exist.
* **Retry the publish on error.** A timeout after a successful send looks like a failure, so the retry sends it again and the customer gets two emails.

This is the dual-write problem. `ClientProxy.emit()`, `EventEmitter2` and the CQRS `EventBus` all publish from memory, so they all have it.

A transactional outbox removes it by turning the event into a row. `Outbox.add()` inserts the message into an outbox table in **the same database transaction as the order**, so both commit or neither does. A relay then publishes committed messages. It retries failures with backoff and moves messages that never succeed to a dead-letter table. Retries mean a consumer can see a message twice, so each consumer keeps an **inbox** of the message ids it has processed and skips repeats.

In this tutorial, you'll add the outbox to the store's order API, on PostgreSQL with Drizzle:

* `POST /orders` saves the order and its messages in one transaction.
* Two in-process handlers send the confirmation email and reserve stock.
* A separate analytics microservice, with a database of its own, receives order events over TCP, in order for each order.
* Failures are retried, and a small admin API lists, requeues and purges dead letters.
* Several instances of the API share the work safely.

#### Prerequisites[#](/reliability/outbox#prerequisites)

* PostgreSQL, with [Drizzle ORM](https://orm.drizzle.team) on the `pg` driver, registered through [`@nestjs/drizzle`](/data/drizzle). The outbox's messages commit with your rows, so they live in the database your orders live in, on a database server that outlives any instance of the application. Using TypeORM, Prisma or MySQL? Follow the tutorial for what the application does: [Keep messages in your database](/reliability/outbox#keep-messages-in-your-database) shows the store with each of them.
* `@nestjs/microservices`, for the TCP link to the analytics service in [Publish to the analytics microservice](/reliability/outbox#publish-to-the-analytics-microservice).

Install the package:

```bash

$ npm i --save @nestjs/outbox
```

The example application, the online store's order API, keeps its products and orders in two tables of its own, which the later sections read and write. They're the example's data, not something the outbox needs: the outbox's tables belong to its store, which creates them, as [Keep messages in your database](/reliability/outbox#keep-messages-in-your-database) shows.

`products` is the catalog, and reserving stock for an order moves units from its `in_stock` to its `reserved`:

| Column     | Type      | Notes                                             |
| ---------- | --------- | ------------------------------------------------- |
| `id`       | `text`    | Primary key, such as `salmon-kibble-2kg`          |
| `name`     | `text`    | The display name, such as `Salmon kibble, 2 kg`   |
| `price`    | `integer` | In cents                                          |
| `in_stock` | `integer` | The units available to order                      |
| `reserved` | `integer` | The units held for placed orders. Defaults to `0` |

`orders` holds the orders that `POST /orders` saves:

| Column    | Type      | Notes                                                                                               |
| --------- | --------- | --------------------------------------------------------------------------------------------------- |
| `id`      | `text`    | Primary key                                                                                         |
| `user_id` | `text`    | The customer who placed the order                                                                   |
| `items`   | `jsonb`   | The order's lines, as a JSON array: each line's `productId`, `quantity` and unit `price` (in cents) |
| `total`   | `integer` | In cents                                                                                            |
| `status`  | `text`    | `placed` or `cancelled`                                                                             |

No column in either table is nullable.

The catalog has two products: `salmon-kibble-2kg`, at 2499 cents with 10 in stock, and `clumping-litter-10l`, at 1599 cents with one in stock.

#### Keep messages in your database[#](/reliability/outbox#keep-messages-in-your-database)

There's nothing to create for the outbox: no tables, entities or Prisma models. Register its store, and the store creates its own schema, `nest_outbox`, and migrates it: at startup in development and in tests, and in production with `npx @nestjs/outbox migrate`, or with `migrationSql()` in your own migrations.

The outbox keeps its messages, its dead letters and the consumers' inboxes in the same database as your own tables, because they must commit with your rows. Until you register a store for them, the outbox keeps them in memory: fine for a first run, but a restart loses every message that wasn't published yet, two instances don't share them, and nothing joins your transactions.

> **Warning** With `NODE_ENV=production` and no store registered, startup fails, unless you set `allowInMemoryStorage: true`.

On PostgreSQL, register the package's store, `PostgresOutboxStore` from `@nestjs/outbox/postgres`. It runs its SQL through the database client your application already has, so it can join your transactions, and it keeps its tables in a schema of its own. It's an ordinary provider, registered once, in the root module, next to `OutboxModule`: both are application-wide, and every `outbox.add()` in any module goes through it. The root module creates it with a factory that injects the Drizzle database and the `OutboxStorage` registry, which the store registers itself with:

app.module.ts

JS TS

```typescript

{
  // Messages and inbox records in your database, in a schema of their own (nest_outbox)
  provide: PostgresOutboxStore,
  inject: [getDrizzleToken(), OutboxStorage],
  useFactory: (db: Database, outboxStorage: OutboxStorage) =>
    new PostgresOutboxStore({ executor: fromDrizzle(db) }, outboxStorage),
},
```

`fromDrizzle(db)` is the store's **executor**: it runs the store's statements through your Drizzle database, whichever driver it uses, such as `pg` or PGlite. `fromPg(pool)`, `fromTypeOrm(dataSource)`, `fromPrisma(prisma)` and `fromKysely(db)` do the same for a node-postgres pool, TypeORM, Prisma and Kysely. At startup, the module logs `OutboxStorage: PostgresOutboxStore`.

**The schema.** The store keeps its tables in a schema of its own, `nest_outbox` (the `schema` option names another). On MySQL, which has no schemas, they're tables of the connection's database, with the schema's name as their prefix: `nest_outbox_messages` and so on.

| Table                      | What it holds                                                                                |
| -------------------------- | -------------------------------------------------------------------------------------------- |
| `nest_outbox.messages`     | Each message from `add()` until it's published or dead-lettered, with its attempts and lease |
| `nest_outbox.dead_letters` | The messages that failed, with the reason and the error of every attempt                     |
| `nest_outbox.inbox`        | The ids of the messages each consumer has processed                                          |
| `nest_outbox.migrations`   | The versions of the store's schema applied                                                   |

They belong to the store: your migrations don't create them, your ORM's schema doesn't declare them, and your own tables can't collide with them. drizzle-kit and Prisma Migrate work on the `public` schema unless told otherwise, and TypeORM on its entities' tables, so their tools leave `nest_outbox` alone.

**Migrations.** The package ships the schema as versioned migrations, and the store applies them itself. With the `migrate` option, it applies the ones the schema hasn't had yet when the application starts, before the relay runs, in one transaction that holds an advisory lock: of several instances that start together, one migrates, and the others find nothing left to do. `migrate` defaults to `true`, except with `NODE_ENV=production`. So in development and in tests, the store creates its schema on the first start, and your migrations only create your own tables, here `products` and `orders`.

In production, apply the migrations before the new version of your application starts, as you apply your own, so that no instance changes the schema while it boots: in the middle of a rolling deploy, that would lock busy tables, and a least-privilege database user can't do it anyway. The package's command line does it from your deploy step, next to `npx drizzle-kit migrate`. It reads the database from `DATABASE_URL`, or from `--url`, and needs `pg` installed:

```bash

$ npx @nestjs/outbox status
Schema "nest_outbox" is at version 0; this version of @nestjs/outbox needs version 1.
$ npx @nestjs/outbox migrate
Migrated schema "nest_outbox" to version 1 (applied 1).
```

`status` exits with 1 while the schema is behind, which makes it a check for CI. To apply the migrations with your own migration tool instead, take their SQL from `npx @nestjs/outbox sql`, or from `PostgresOutboxStore.migrationSql()` in code: the statements of every migration, one per paragraph, with the bookkeeping that records the version. Run them in one transaction, as TypeORM's and Drizzle's migrators do. With TypeORM, that's a migration of your own, next to the ones it generates for your entities:

typeorm/migrations/1790801276314-OutboxStore.ts

JS TS

```typescript

import { PostgresOutboxStore } from '@nestjs/outbox/postgres';
import type { MigrationInterface, QueryRunner } from 'typeorm';

export class OutboxStore1790801276314 implements MigrationInterface {
  async up(queryRunner: QueryRunner): Promise<void> {
    await queryRunner.query(PostgresOutboxStore.migrationSql());
  }

  // The store's migrations only ever add tables, columns and indexes: it has no down migrations.
  async down(): Promise<void> {}
}
```

With drizzle-kit, create a custom migration, and fill it with the SQL, a `--> statement-breakpoint` line between the statements: Drizzle's migrator then runs them one at a time, which PGlite requires. In code, `migrationSql()` with `statementBreakpoints: true` returns the same.

```bash

$ npx drizzle-kit generate --custom --name=outbox
$ npx @nestjs/outbox sql --statement-breakpoints > drizzle/0002_outbox.sql
```

On MySQL, `MySqlOutboxStore.migrationStatements()` returns the statements one per string, and a TypeORM migration runs them one per call:

typeorm/mysql-migrations/1790801276314-OutboxStore.ts

JS TS

```typescript

for (const statement of MySqlOutboxStore.migrationStatements()) {
  await queryRunner.query(statement);
}
```

With `migrate` off, a store whose schema is behind fails the startup with an `OutboxSchemaError` that names these three ways, and fails every call the same way until the schema catches up, which it notices without a restart. Migrations only ever add tables, columns and indexes, so during a rolling deploy, the previous version of your application keeps running on the migrated schema. There are no down migrations.

**Transactions.**`outbox.add()` takes your transaction, as [Save the order and its messages in one transaction](/reliability/outbox#save-the-order-and-its-messages-in-one-transaction) shows, and so does a handler's `processInTransaction()`: with Drizzle, the `tx` that `db.transaction()` hands its callback. The store runs its statements on that transaction, so they commit or roll back with your writes. It refuses the database itself, whose statements would commit on their own, with an `OutboxTransactionRequiredError` that says what to pass. With the other executors, pass a node-postgres client after `BEGIN` (not the pool), TypeORM's `EntityManager` from `dataSource.transaction()`, Prisma's interactive transaction client, or a Kysely transaction.

**Isolation.** The store's own transactions (claims, dead-letter moves, requeues) rely on READ COMMITTED, PostgreSQL's default isolation level: at startup, the store checks the database's `default_transaction_isolation`, and fails if it's stricter. Yours may run at any level. `add()` first takes a lock per key on your transaction, so transactions that add messages with the same key take turns, and a key's messages are numbered in the order their transactions commit. Under REPEATABLE READ or SERIALIZABLE, two deliveries of one message that race to `processInTransaction()` can fail the second with a serialization error instead of skipping it as a duplicate: its handler fails, and the relay's retry finds the record.

**With TypeORM.**`TypeOrmModule` takes the place of `DrizzleModule` in the root module, and the store runs on the `DataSource` it provides, through `fromTypeOrm()`:

typeorm/app.module.ts

JS TS

```typescript

{
  // Messages and inbox records in your database, in a schema of their own (nest_outbox)
  provide: PostgresOutboxStore,
  inject: [DataSource, OutboxStorage],
  useFactory: (dataSource: DataSource, outboxStorage: OutboxStorage) =>
    new PostgresOutboxStore({ executor: fromTypeOrm(dataSource) }, outboxStorage),
},
```

Where the tutorial passes Drizzle's `tx` to `outbox.add()`, pass the `EntityManager` that `dataSource.transaction()` hands its callback, and type the outbox with it. The store refuses `dataSource.manager`, whose writes would commit on their own. This is the order service with TypeORM:

typeorm/orders.service.ts

JS TS

```typescript

@Injectable()
export class OrdersService {
  constructor(
    private readonly dataSource: DataSource,
    private readonly outbox: Outbox<EntityManager>,
  ) {}

  async placeOrder({ userId, items }: PlaceOrderDto): Promise<Order> {
    if (!items?.length) {
      throw new BadRequestException('An order needs at least one item');
    }

    const order = await this.dataSource.transaction(async (manager) => {
      // ... price the items through manager (an unknown product throws) and build the order
      await manager.insert(OrderEntity, order);

      // The transaction's EntityManager: the message commits or rolls back with the order.
      await this.outbox.add(manager, { topic: 'order.placed', payload: order });
      return order;
    });

    this.outbox.notify(); // publish now instead of at the next poll
    return order;
  }
}
```

**With Prisma.** Pass your `PrismaService` to `fromPrisma()` in the factory, and to `outbox.add()` the transaction client that `prisma.$transaction()` hands its callback. Only that interactive form has one to pass: the array form, `prisma.$transaction([query1, query2])`, can't include an `outbox.add()`. The store refuses the client itself, whose statements would commit on their own. Its own transactions wait up to 10 seconds for a connection and run for up to a minute, longer than Prisma's defaults: the second argument of `fromPrisma()` changes that, with `maxWait` and `timeout`.

**With MySQL.** For MySQL 8.4 LTS and 9.x, `@nestjs/outbox/mysql` has `MySqlOutboxStore`. Import the store and its executor from there: the provider is the same, and so are the options and the executors' names. This is the order API on MySQL, with Drizzle on the `mysql2` driver:

mysql/app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { DrizzleModule, getDrizzleToken } from '@nestjs/drizzle';
import { OutboxModule, OutboxStorage } from '@nestjs/outbox';
import { fromDrizzle, MySqlOutboxStore } from '@nestjs/outbox/mysql';
import { drizzle } from 'drizzle-orm/mysql2';
import { NotificationsModule } from '../notifications/notifications.module.js';
import type { Database } from './drizzle.js';
import { OrdersService } from './orders.service.js';

@Module({
  imports: [
    DrizzleModule.forRootAsync({
      // A mysql2 pool on DATABASE_URL (mysql://...), whose path names the database
      useFactory: () => ({ drizzle, connection: { uri: process.env.DATABASE_URL! } }),
    }),
    OutboxModule.forRoot({ relay: { pollInterval: '1s' } }),
    NotificationsModule,
  ],
  providers: [
    {
      // Messages and inbox records in your database, in tables of their own (nest_outbox_*)
      provide: MySqlOutboxStore,
      inject: [getDrizzleToken(), OutboxStorage],
      useFactory: (db: Database, outboxStorage: OutboxStorage) =>
        new MySqlOutboxStore({ executor: fromDrizzle(db) }, outboxStorage),
    },
    OrdersService,
  ],
})
export class AppModule {}
```

`fromMysql2(pool)`, `fromTypeOrm(dataSource)` for a data source of type `mysql`, `fromPrisma(prisma)` with the `@prisma/adapter-mariadb` driver adapter (the one that serves MySQL), and `fromKysely(db)` serve the other clients. What differs from PostgreSQL:

* **Tables, not a schema.** A MySQL database has no schemas, so the store keeps its tables in the connection's database, the one the URL's path names, and the `schema` option is their prefix: `nest_outbox_messages`, `nest_outbox_dead_letters` and `nest_outbox_inbox`, next to `nest_outbox_migrations` and `nest_outbox_locks`. It takes lowercase letters, digits and underscores, up to 40 characters. A connection without a database fails the startup.
* **Bounded keys.** Ids, topics, keys and consumer names are indexed columns of at most 255 characters, compared byte for byte: `order-1` and `Order-1` are two keys. A longer one is refused with a `RangeError`, before any statement: by `add()`, and by the inbox before it runs a handler.
* **Your isolation level.** Your transactions may run at REPEATABLE READ, MySQL's default, or at READ COMMITTED. A delivery that races another to `processInTransaction()` waits for it, then skips the handler as a duplicate, at either level.
* **Deadlocks reach your transaction.**`add()` locks a row per key in your transaction, one of 16,384 that the keys share, which the store creates when it starts: producers of two keys that share a row take turns, as producers of one key do, which slows an unrelated producer only rarely. When MySQL breaks a deadlock in your transaction (error 1213), it rolls the whole transaction back, and the store can't run your work again: the error reaches your code as your client's error, so run the transaction again. With those rows in place, two things can still cause one: three deliveries of one message that race to `processInTransaction()` while the first rolls back, and transactions of yours that take the same locks in different orders. The store's own transactions retry on deadlock by themselves.
* **Migrations that aren't transactional.** MySQL commits each DDL statement on its own, so `migrate` and `npx @nestjs/outbox migrate --url mysql://...` apply the statements one at a time under a lock, and a run that stopped halfway resumes where it stopped. Your own tool must send one statement per call too, as the TypeORM migration in **Migrations** above does, and a drizzle-kit custom migration takes `npx @nestjs/outbox sql --dialect mysql --statement-breakpoints`, since its MySQL migrator sends one statement per breakpoint.

#### Register the outbox[#](/reliability/outbox#register-the-outbox)

Register `OutboxModule` in the root module, next to `DrizzleModule`, which registers the Drizzle database, and with the store from [Keep messages in your database](/reliability/outbox#keep-messages-in-your-database). The feature modules it imports are built in the next steps:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { DrizzleModule, getDrizzleToken } from '@nestjs/drizzle';
import { ClientsModule, Transport } from '@nestjs/microservices';
import { ClientProxyTransport, OutboxModule, OutboxStorage } from '@nestjs/outbox';
import { fromDrizzle, PostgresOutboxStore } from '@nestjs/outbox/postgres';
import { drizzle } from 'drizzle-orm/node-postgres';
import type { Database } from './database/drizzle.js';
import * as schema from './database/schema.js';
import { InventoryModule } from './inventory/inventory.module.js';
import { NotificationsModule } from './notifications/notifications.module.js';
import { OrdersModule } from './orders/orders.module.js';
import { OutboxAdminModule } from './outbox-admin/outbox-admin.module.js';

export const ANALYTICS_SERVICE = 'ANALYTICS_SERVICE';

@Module({
  imports: [
    DrizzleModule.forRootAsync({
      // A pg pool on DATABASE_URL, closed in onApplicationShutdown(), after the relay drained.
      useFactory: () => ({ drizzle, connection: process.env.DATABASE_URL!, schema }),
    }),
    OutboxModule.forRootAsync({
      imports: [
        ClientsModule.registerAsync([
          {
            name: ANALYTICS_SERVICE,
            useFactory: () => ({
              transport: Transport.TCP,
              options: {
                host: process.env.ANALYTICS_HOST ?? '127.0.0.1',
                port: Number(process.env.ANALYTICS_PORT ?? 4001),
              },
            }),
          },
        ]),
      ],
      transports: { analytics: ClientProxyTransport(ANALYTICS_SERVICE) },
      useFactory: () => ({
        // Each message goes to exactly one transport; `local` runs @OnOutboxMessage() handlers.
        route: (message) => (message.topic.startsWith('analytics.') ? 'analytics' : 'local'),
        relay: {
          enabled: process.env.OUTBOX_RELAY !== 'off',
          pollInterval: '1s',
          lease: '30s',
          publishTimeout: '10s',
        },
        retry: {
          attempts: 10,
          backoff: { delay: '1s', maxDelay: '1m' },
        },
      }),
    }),
    OrdersModule,
    NotificationsModule,
    InventoryModule,
    OutboxAdminModule,
  ],
  providers: [
    {
      // Messages and inbox records in your database, in a schema of their own (nest_outbox)
      provide: PostgresOutboxStore,
      inject: [getDrizzleToken(), OutboxStorage],
      useFactory: (db: Database, outboxStorage: OutboxStorage) =>
        new PostgresOutboxStore({ executor: fromDrizzle(db) }, outboxStorage),
    },
  ],
})
export class AppModule {}
```

`ClientProxyTransport(ANALYTICS_SERVICE)` is a class that Nest instantiates inside `OutboxModule`, so `transports` sits next to `useFactory`, where classes go. The factory runs when the application starts and returns the rest of the options:

* `transports` and `route`: where each message is published. The `local` transport is built in and runs `@OnOutboxMessage()` handlers in this process ([Handle order.placed in-process](/reliability/outbox#handle-orderplaced-in-process)). `ClientProxyTransport(ANALYTICS_SERVICE)` publishes through the TCP client that `ClientsModule` registers under that name, which is why that module is in `imports` ([Publish to the analytics microservice](/reliability/outbox#publish-to-the-analytics-microservice)). `route` picks exactly one transport per message.
* `relay`: the background publisher. It polls every `pollInterval`, leases what it claims for `lease`, and gives up on a single publish after `publishTimeout`. Setting `OUTBOX_RELAY=off` turns it off in API-only instances ([Run several instances](/reliability/outbox#run-several-instances)).
* `retry`: 10 attempts, with exponential backoff that starts at 1 second and is capped at 1 minute ([Retries and the dead-letter queue](/reliability/outbox#retries-and-the-dead-letter-queue)).

> **Hint** The tutorial reads `process.env` directly, to stay short. In an application, load the environment through [`@nestjs/config`](/application/configuration) with a validation schema, so a missing `DATABASE_URL` stops the application at startup, and read the values from `ConfigService` in the factories.

Durations are milliseconds or strings such as `'30s'` and `'1m'`. `OutboxModule` is global: `Outbox`, `OutboxStorage`, `OutboxRelay`, `OutboxEvents`, `OutboxDeadLetters` and `OutboxInbox` can be injected anywhere in the application.

#### Save the order and its messages in one transaction[#](/reliability/outbox#save-the-order-and-its-messages-in-one-transaction)

This is the order model:

orders/order.ts

JS TS

```typescript

export interface OrderItem {
  productId: string;
  quantity: number;
  /** Unit price in cents, copied from the catalog when the order is placed. */
  price: number;
}

export interface Order {
  id: string;
  userId: string;
  items: OrderItem[];
  /** In cents. */
  total: number;
  status: 'placed' | 'cancelled';
}

export class PlaceOrderDto {
  userId: string;
  items: { productId: string; quantity: number }[];
}
```

`OrdersService.placeOrder()` opens a Drizzle transaction, prices the items, inserts the order and adds the messages, all through the same `tx`:

orders/orders.service.ts

JS TS

```typescript

import { BadRequestException, Injectable } from '@nestjs/common';
import { InjectDrizzle } from '@nestjs/drizzle';
import { Outbox } from '@nestjs/outbox';
import type { Database, Transaction } from '../database/drizzle.js';
import { orders, products } from '../database/schema.js';
import type { Order, PlaceOrderDto } from './order.js';

@Injectable()
export class OrdersService {
  constructor(
    @InjectDrizzle() private readonly db: Database,
    private readonly outbox: Outbox<Transaction>,
  ) {}

  async placeOrder({ userId, items }: PlaceOrderDto): Promise<Order> {
    if (!items?.length) {
      throw new BadRequestException('An order needs at least one item');
    }

    const order = await this.db.transaction(async (tx) => {
      // ... price the items through tx (an unknown product throws) and build the order
      await tx.insert(orders).values(order);

      // Drizzle's tx: the messages commit or roll back with the order.
      await this.outbox.add(tx, [
        { topic: 'order.placed', payload: order },
        { topic: 'analytics.order.placed', key: order.id, payload: order },
      ]);
      return order;
    });

    this.outbox.notify(); // publish now instead of at the next poll
    return order;
  }
}
```

`outbox.add()` takes the transaction handle first, then the message or an array of messages. With Drizzle, the handle is the `tx` that `db.transaction()` passes its callback, whose type the service gives the outbox: `Outbox<Transaction>`. The store inserts them through that `tx`, so the messages commit with the order, or roll back with it. The store is asynchronous, so await `add()` like any other query. Every API in the package that joins your transaction takes the handle as its first argument.

A few details:

* **One message per destination.** Each message goes to exactly one transport. The same event goes to the in-process handlers and to the analytics service, so the service adds two messages, `order.placed` and `analytics.order.placed`, in the same transaction.
* **Payloads are snapshots.**`add()` serializes the payload right away, so later changes to the `order` object aren't published.
* **Ids.** Every message gets a time-ordered UUIDv7 `id`. Consumers deduplicate by it.
* **`notify()`.** Nothing is published inside the transaction. After the commit, `notify()` wakes the relay. Without it, the message goes out at the next poll, up to `pollInterval` later.

If anything throws inside the transaction, the order and its messages roll back together, and the relay never sees them. That includes an unknown product, a failed insert, and anything that fails after `add()`. The [Testing](/reliability/outbox#testing) section proves it by failing the transaction after the messages were written.

Pass the transaction, never the database: `outbox.add(this.db, message)` would write the message on its own, in autocommit mode, which is exactly the dual write you're removing. The store refuses it with `OutboxTransactionRequiredError`, and so does `add()` itself when it gets no handle at all.

Expose the service over HTTP:

orders/orders.controller.ts

JS TS

```typescript

import { Body, Controller, HttpCode, HttpStatus, Param, Post } from '@nestjs/common';
import { PlaceOrderDto } from './order.js';
import { OrdersService } from './orders.service.js';

@Controller('orders')
export class OrdersController {
  constructor(private readonly ordersService: OrdersService) {}

  @Post()
  place(@Body() dto: PlaceOrderDto) {
    return this.ordersService.placeOrder(dto);
  }

  @Post(':id/cancel')
  @HttpCode(HttpStatus.OK)
  cancel(@Param('id') id: string) {
    return this.ordersService.cancelOrder(id);
  }
}
```

#### Handle order.placed in-process[#](/reliability/outbox#handle-orderplaced-in-process)

The confirmation email is a handler for `order.placed`. The mailer is a stand-in for your email provider's SDK:

notifications/mailer.service.ts

JS TS

```typescript

import { Injectable, Logger } from '@nestjs/common';
import type { Order } from '../orders/order.js';

/** Stand-in for your email provider's SDK. */
@Injectable()
export class MailerService {
  private readonly logger = new Logger(MailerService.name);

  async sendOrderConfirmation(order: Order): Promise<void> {
    this.logger.log(`Order confirmation for ${order.id} sent to ${order.userId}`);
  }
}
```

notifications/order-emails.handler.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { OnOutboxMessage } from '@nestjs/outbox';
import type { Order } from '../orders/order.js';
import { MailerService } from './mailer.service.js';

@Injectable()
export class OrderEmailsHandler {
  constructor(private readonly mailerService: MailerService) {}

  // The consumer's inbox skips messages it has already handled.
  @OnOutboxMessage('order.placed', { consumer: 'order-confirmation-email' })
  async sendConfirmation(order: Order) {
    await this.mailerService.sendOrderConfirmation(order);
  }
}
```

`@OnOutboxMessage()` handlers are discovered on providers, so register `MailerService` and `OrderEmailsHandler` as providers of a `NotificationsModule`. They must be singletons: a handler on a request-scoped provider fails at startup. The handler gets the payload, here the order, and a context as its second argument. The context's `message` holds the message's `id`, `topic`, `key` and `headers`.

Every handler has an inbox, named by `consumer`. Before calling the handler, the local transport checks whether the `order-confirmation-email` consumer has already processed this message id. After the handler succeeds, it records the id. `consumer` is required, and it must stay stable: a new name makes every past message look new.

The inbox has a gap: if the process dies after the email is sent but before the id is recorded, the email is sent again on redelivery. That's acceptable for an email. It isn't for a stock reservation, which lives in the same database as the inbox. The reservation handler closes the gap by recording the id inside its own transaction:

inventory/stock-reservation.handler.ts

JS TS

```typescript

import { Injectable, Logger } from '@nestjs/common';
import { InjectDrizzle } from '@nestjs/drizzle';
import { NonRetryableMessageError, OnOutboxMessage, type OutboxHandlerContext } from '@nestjs/outbox';
import { and, eq, gte, sql } from 'drizzle-orm';
import type { Database, Transaction } from '../database/drizzle.js';
import { products } from '../database/schema.js';
import type { Order } from '../orders/order.js';

@Injectable()
export class StockReservationHandler {
  private readonly logger = new Logger(StockReservationHandler.name);

  constructor(@InjectDrizzle() private readonly db: Database) {}

  @OnOutboxMessage('order.placed', { consumer: 'stock-reservation' })
  async reserve(order: Order, ctx: OutboxHandlerContext<Transaction>) {
    await this.db.transaction(async (tx) => {
      // Records the message id through tx, then runs the callback only if this consumer
      // hasn't processed it yet. Await it: the record commits with the reservation.
      await ctx.processInTransaction(tx, async () => {
        for (const { productId, quantity } of order.items) {
          const reserved = await tx
            .update(products)
            .set({ inStock: sql`${products.inStock} - ${quantity}`, reserved: sql`${products.reserved} + ${quantity}` })
            .where(and(eq(products.id, productId), gte(products.inStock, quantity)))
            .returning({ id: products.id });
          if (reserved.length === 0) {
            // Retrying won't create stock: dead-letter it now and let a human decide.
            throw new NonRetryableMessageError(`Not enough stock for "${productId}" (order ${order.id})`);
          }
        }
        this.logger.log(`Reserved stock for order ${order.id}`);
      });
    });
  }
}
```

`ctx.processInTransaction(tx, work)` inserts the inbox record through the handler's transaction, then calls `work` only if this consumer hasn't processed the message yet. Otherwise it skips `work` and returns a result whose `duplicate` flag is `true`. The record and the stock update commit together, so the reservation happens exactly once: a redelivery finds the record and skips the handler, and if `work` throws, both roll back and the retry starts clean. Await it inside the transaction's callback, so the record is written before `COMMIT`; the duplicate check happens inside the call, so a missing `await` can't make it pass. Register the handler in an `InventoryModule`.

| Handler                                    | Behavior                                                                             | Guarantee                                                                                                                                  |
| ------------------------------------------ | ------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------ |
| Default                                    | Skips the handler if its inbox has the id, records the id after the handler succeeds | Once, unless the process dies between the handler finishing and the record, or another instance delivers the same message at the same time |
| Calls `ctx.processInTransaction(tx, work)` | Records the id in the handler's own transaction, with its writes                     | Exactly once for writes to the same database                                                                                               |
| `inbox: false`                             | Every delivery runs the handler                                                      | At least once                                                                                                                              |

Both handlers run concurrently for each `order.placed` message. If one of them fails, the publish fails and the whole message is retried. On the retry, each handler that already succeeded is skipped by its inbox.

The relay gives the handlers `publishTimeout` (10 seconds here). If they take longer, the attempt counts as failed and the context's `signal` aborts: pass `ctx.signal` to the calls a handler makes, such as the `signal` option of `fetch()`, so they stop too. A handler that ignores it keeps running, and if the retry reaches the same process while it does, the inbox waits for it instead of running the handler a second time.

#### Publish to the analytics microservice[#](/reliability/outbox#publish-to-the-analytics-microservice)

The API side is already wired. In `AppModule`, `ClientProxyTransport(ANALYTICS_SERVICE)` publishes through the `ClientProxy` that `ClientsModule` registered under that name, and `route` sends every `analytics.*` topic to it. The transport calls `client.emit(topic, envelope)`, the same call you'd make without an outbox. The envelope has the message's `id`, `topic`, `key`, `headers`, `createdAt` and `payload`.

Cancelling an order produces a second analytics event for the same order. Add a `cancelOrder()` method to `OrdersService`, and import `NotFoundException` and `ConflictException` from `@nestjs/common`:

orders/orders.service.ts

JS TS

```typescript

async cancelOrder(id: string): Promise<Order> {
  const order = await this.db.transaction(async (tx) => {
    const [row] = await tx.select().from(orders).where(eq(orders.id, id)).for('update');
    if (!row) {
      throw new NotFoundException(`Order ${id} not found`);
    }
    if (row.status !== 'placed') {
      throw new ConflictException(`Order ${id} is ${row.status}`);
    }

    await tx.update(orders).set({ status: 'cancelled' }).where(eq(orders.id, id));
    const order: Order = { ...row, status: 'cancelled' };
    await this.outbox.add(tx, { topic: 'analytics.order.cancelled', key: order.id, payload: order });
    return order;
  });

  this.outbox.notify();
  return order;
}
```

The orders controller already routes `POST /orders/:id/cancel` to it. The `SELECT ... FOR UPDATE` locks the order's row, so two cancellations of the same order take turns, and the second one sees `cancelled` and answers `409`. Both analytics messages use the order id as their `key`. Messages that share a key are published one at a time, in the order their transactions committed. While `analytics.order.placed` is being retried, `analytics.order.cancelled` waits behind it, so analytics doesn't see a cancellation before the order it cancels. Messages with other keys keep flowing. A key waits only as long as the retries last, though: once a message is dead-lettered (see the next section), the messages behind it go out.

The `order.placed` message for the in-process handlers has no key, on purpose. A key is shared by every message that carries it, whatever the topic or transport. If the email message used the order id as well, a mail outage would hold back the analytics events for that order.

The analytics service is a separate Nest application, and like any service it owns its data: a PostgreSQL database of its own, with its own schema and migrations. It never reads the order API's tables. It records each order event in a table of its own, again the example's data:

`order_events` has one row per order event, and the revenue is the sum of its `amount` column:

| Column        | Type                         | Notes                                                                                             |
| ------------- | ---------------------------- | ------------------------------------------------------------------------------------------------- |
| `seq`         | `bigint`, generated identity | Primary key, in arrival order                                                                     |
| `order_id`    | `text`                       | Indexed                                                                                           |
| `event`       | `text`                       | `placed` or `cancelled`                                                                           |
| `amount`      | `integer`                    | The change to revenue, in cents: the order's total when it's placed, minus it when it's cancelled |
| `recorded_at` | `timestamptz`                | Defaults to `now()`                                                                               |

Being an application of its own, it has its own root module, `AppModule`, which registers `OutboxModule` and the store once, as the order API's does. The service only consumes, so the relay is turned off, and the store runs on the service's own database. `OutboxInbox` keeps the service's inbox there, next to `order_events`, so an event and the record that it was processed commit together. The store's tables for messages stay empty, and with the relay off, nothing polls them:

analytics-service/app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { DrizzleModule, getDrizzleToken } from '@nestjs/drizzle';
import { OutboxModule, OutboxStorage } from '@nestjs/outbox';
import { fromDrizzle, PostgresOutboxStore } from '@nestjs/outbox/postgres';
import { drizzle } from 'drizzle-orm/node-postgres';
import { AnalyticsController } from './analytics.controller.js';
import type { Database } from './database/drizzle.js';
import * as schema from './database/schema.js';
import { OrderStatsService } from './order-stats.service.js';

@Module({
  imports: [
    DrizzleModule.forRootAsync({
      // This service's own database, not the order API's.
      useFactory: () => ({ drizzle, connection: process.env.DATABASE_URL!, schema }),
    }),
    // Consumer only: no relay runs.
    OutboxModule.forRoot({ relay: { enabled: false } }),
  ],
  controllers: [AnalyticsController],
  providers: [
    {
      // This service's inbox, in its own database (the store's tables for messages stay empty)
      provide: PostgresOutboxStore,
      inject: [getDrizzleToken(), OutboxStorage],
      useFactory: (db: Database, outboxStorage: OutboxStorage) =>
        new PostgresOutboxStore({ executor: fromDrizzle(db) }, outboxStorage),
    },
    OrderStatsService,
  ],
})
export class AppModule {}
```

`OrderStatsService` records an event and returns the revenue so far. It opens a transaction and calls `inbox.processInTransaction(tx, 'analytics', messageId, work)`: the inbox record and the `order_events` row commit together, so a redelivered event changes nothing, even if the service crashes halfway:

analytics-service/order-stats.service.ts

JS TS

```typescript

import { Injectable, Logger } from '@nestjs/common';
import { InjectDrizzle } from '@nestjs/drizzle';
import { OutboxInbox } from '@nestjs/outbox';
import type { Database, Transaction } from './database/drizzle.js';
import { orderEvents } from './database/schema.js';

/** The fields of the order API's `Order` that this service reads. */
export interface OrderSnapshot {
  id: string;
  total: number;
}

export type OrderEvent = 'placed' | 'cancelled';

@Injectable()
export class OrderStatsService {
  private readonly logger = new Logger(OrderStatsService.name);

  constructor(
    @InjectDrizzle() private readonly db: Database,
    private readonly outboxInbox: OutboxInbox,
  ) {}

  /**
   * Records an order event once per message id. The inbox record and the event commit in
   * one transaction, so a redelivered message changes nothing. `false` for a duplicate.
   */
  async record(messageId: string, event: OrderEvent, order: OrderSnapshot): Promise<boolean> {
    const outcome = await this.db.transaction(async (tx) =>
      // Records the message id through tx, then runs the callback only if it is new here.
      this.outboxInbox.processInTransaction(tx, 'analytics', messageId, async () => {
        const amount = event === 'placed' ? order.total : -order.total;
        await tx.insert(orderEvents).values({ orderId: order.id, event, amount });
        return this.revenue(tx);
      }),
    );
    if (outcome.duplicate) {
      return false;
    }
    this.logger.log(`Order ${order.id} ${event}, revenue is now ${outcome.result}`);
    return true;
  }

  /** Total revenue in cents. */
  async revenue(db: Database | Transaction = this.db): Promise<number> {
    // ... the sum of amount in order_events, read through db
  }

  // ...
}
```

analytics-service/analytics.controller.ts

JS TS

```typescript

import { Controller, Logger } from '@nestjs/common';
import { EventPattern, Payload } from '@nestjs/microservices';
import type { OutboxEnvelope } from '@nestjs/outbox';
import { OrderStatsService, type OrderEvent, type OrderSnapshot } from './order-stats.service.js';

@Controller()
export class AnalyticsController {
  private readonly logger = new Logger(AnalyticsController.name);
  /** The last event handled for each key: one order's events run one at a time. */
  private readonly queues = new Map<string, Promise<void>>();

  constructor(private readonly orderStatsService: OrderStatsService) {}

  @EventPattern('analytics.order.placed')
  onPlaced(@Payload() envelope: OutboxEnvelope<OrderSnapshot>) {
    return this.apply('placed', envelope);
  }

  @EventPattern('analytics.order.cancelled')
  onCancelled(@Payload() envelope: OutboxEnvelope<OrderSnapshot>) {
    return this.apply('cancelled', envelope);
  }

  private apply(event: OrderEvent, envelope: OutboxEnvelope<OrderSnapshot>) {
    // Events arrive in the order the relay published them, but handlers are asynchronous:
    // without a queue, a cancellation could commit before the placement it follows.
    return this.inOrder(envelope.key ?? envelope.id, async () => {
      // The envelope id is the outbox message id: stable across redeliveries.
      const recorded = await this.orderStatsService.record(envelope.id, event, envelope.payload);
      if (!recorded) {
        this.logger.warn(`Skipped duplicate ${envelope.topic} ${envelope.id}`);
      }
    });
  }

  private inOrder(key: string, work: () => Promise<void>): Promise<void> {
    const next = (this.queues.get(key) ?? Promise.resolve()).then(work, work);
    this.queues.set(key, next);
    const forget = () => {
      if (this.queues.get(key) === next) {
        this.queues.delete(key);
      }
    };
    next.then(forget, forget);
    return next;
  }
}
```

The events for an order arrive in the order the relay published them, but the handlers are asynchronous: two of them can run at once, and a cancellation could commit before the placement it follows. The controller runs one key's events one at a time, in arrival order, and different orders in parallel.

analytics-service/main.ts

JS TS

```typescript

import { NestFactory } from '@nestjs/core';
import { Transport, type MicroserviceOptions } from '@nestjs/microservices';
import { AppModule } from './app.module.js';

async function bootstrap() {
  const app = await NestFactory.createMicroservice<MicroserviceOptions>(AppModule, {
    transport: Transport.TCP,
    options: { host: '127.0.0.1', port: Number(process.env.PORT ?? 4001) },
  });
  app.enableShutdownHooks();
  await app.listen();
}
await bootstrap();
```

`inbox.processInTransaction()` is what an `@OnOutboxMessage()` handler gets with `ctx.processInTransaction()`: exactly once for writes to the consumer's own database. When a consumer's side effect is outside its database, such as an email, use `inbox.process(consumer, id, work)` instead: it skips `work` if the consumer has seen this id, and records it after `work` succeeds.

> **Warning** Over TCP, "published" only means the bytes left the order API. If the analytics service crashes after receiving an event but before processing it, the event is lost. For events you can't lose, use a transport whose broker acknowledges receipt: Kafka, RabbitMQ with publisher confirms, or NATS JetStream. `ClientProxyTransport` accepts a `toPacket` option that maps a message to that transport's record, with its own key and headers.

#### Retries and the dead-letter queue[#](/reliability/outbox#retries-and-the-dead-letter-queue)

When a publish fails, because a handler threw, the TCP connection was refused, or the publish took longer than `publishTimeout`, the relay reschedules the message:

* Each retry waits longer: 1 s, 2 s, 4 s and so on, capped at `maxDelay` (1 minute here). Each wait is randomized between half and the full value, so retries don't arrive in lockstep.
* Each failure is logged as a warning, with the attempt number and the wait before the next one.
* After `retry.attempts` failures (10 here), the message moves to the dead-letter table with the reason `exhausted` and the error of every attempt.
* A `NonRetryableMessageError` skips the retries. The message is dead-lettered at once with the reason `rejected`. So is any error for which the optional `retry.retryIf(error, attempt, message)` function returns `false`. When several handlers fail, the message is rejected only if all of them threw `NonRetryableMessageError`. Otherwise it's retried, the handlers that succeeded are skipped, and it's rejected once only the permanent failures remain.
* A topic with no `@OnOutboxMessage()` handler is retried, not dead-lettered. During a rolling deploy, an old instance's relay can see a topic that only the new version handles.
* A dead-lettered message no longer holds back its key: the later messages with that key are published without it. Size `retry` so that the outages you expect don't use it up.

The stock handler throws `NonRetryableMessageError` when there isn't enough stock. Retrying won't create stock, so the message goes straight to the dead-letter table, where a person can decide what to do.

`OutboxDeadLetters` lists, inspects, requeues and purges dead letters. The package doesn't mount any HTTP routes, so expose it behind your own guard. The same controller serves the outbox's stats, from the `OutboxMetrics` service built in the next section:

outbox-admin/outbox-admin.controller.ts

JS TS

```typescript

import {
  Controller,
  Delete,
  Get,
  HttpCode,
  HttpStatus,
  Param,
  Post,
  Query,
  UseGuards,
} from '@nestjs/common';
import { OutboxDeadLetters } from '@nestjs/outbox';
import { AdminGuard } from './admin.guard.js';
import { OutboxMetrics } from './outbox-metrics.service.js';

@Controller('admin/outbox')
@UseGuards(AdminGuard)
export class OutboxAdminController {
  constructor(
    private readonly outboxDeadLetters: OutboxDeadLetters,
    private readonly outboxMetrics: OutboxMetrics,
  ) {}

  @Get('dead-letters')
  list(@Query('topic') topic?: string) {
    return this.outboxDeadLetters.list({ topic });
  }

  @Post('dead-letters/:id/requeue')
  @HttpCode(HttpStatus.OK)
  async requeue(@Param('id') id: string) {
    return { requeued: await this.outboxDeadLetters.requeue(id) };
  }

  @Delete('dead-letters/:id')
  async purge(@Param('id') id: string) {
    return { purged: await this.outboxDeadLetters.purge(id) };
  }

  @Get('stats')
  stats() {
    return this.outboxMetrics.snapshot();
  }
}
```

outbox-admin/admin.guard.ts

JS TS

```typescript

import { Injectable, type CanActivate, type ExecutionContext } from '@nestjs/common';
import { createHash, timingSafeEqual } from 'node:crypto';

type HttpRequest = { headers: Record<string, string | string[] | undefined> };

/** Placeholder: protect these routes with your application's real authorization. */
@Injectable()
export class AdminGuard implements CanActivate {
  canActivate(context: ExecutionContext): boolean {
    const request = context.switchToHttp().getRequest<HttpRequest>();
    const token = process.env.ADMIN_TOKEN;
    const given = request.headers['x-admin-token'];
    return !!token && typeof given === 'string' && sameSecret(given, token);
  }
}

/** Compares in constant time, so response times don't give the token away. */
function sameSecret(given: string, expected: string): boolean {
  const digest = (value: string) => createHash('sha256').update(value).digest();
  return timingSafeEqual(digest(given), digest(expected));
}
```

> **Hint**`AdminGuard` is a placeholder. Dead letters contain full payloads, customer data included, so protect these routes with your application's real [authorization](/security/authorization).

`requeue()` moves a dead letter back to the outbox with a fresh retry budget and **the same id**. Consumers that already processed it skip it through their inbox. So after you restock, requeueing the out-of-stock order reserves the stock without sending a second confirmation email. `requeue()` and `purge()` also accept an array of ids, or a filter by `topic`, `key` or `failedBefore`. They refuse an empty filter; pass `all: true` to target every dead letter.

#### Run several instances[#](/reliability/outbox#run-several-instances)

Every instance of the order API runs its relay against the same tables, on any number of hosts. The database decides who gets what:

* **Claims.** A relay claims a batch of messages by writing a lease on them for `lease` (30 s), with a random token for that claim. Claims take turns under the store's claim lock, and `SKIP LOCKED` passes over rows another relay is writing, so two relays never get the same message. They publish their batches in parallel.
* **Fencing.** Every later write for a message (published, rescheduled, dead-lettered) must present the lease token, so a relay that stalled past its lease can't overwrite the work of the relay that took over.
* **Order across instances.** A key's messages go out in the order their transactions committed, whichever instance added them: `add()` makes the transactions adding the same key take turns. Keep transactions that add keyed messages short.
* **Exactly-once reservations.** Two deliveries of the same message that run at the same time, on different instances, meet at the inbox's primary key: the second waits for the first transaction, then skips the handler if it committed.
* **Crashes.** If an instance dies while holding a lease, its messages are published by another instance once the lease expires. If it died after publishing but before recording that, the message is published a second time, and the consumers' inboxes drop the duplicate. Nothing is lost with the instance, because nothing lives on it: the messages are rows in the database.
* **Lease budget.** A relay never starts a publish with less than `publishTimeout` (10 s) of lease left. It releases the rest of the batch instead. Keep `publishTimeout` well below `lease`.
* **Clocks.** Leases use the relay's clock, so keep the hosts' clocks synchronized with NTP, well within `lease`.
* **API-only instances.** Start an instance with `OUTBOX_RELAY=off` to make it produce messages without publishing them. `notify()` wakes only the relay of the instance that added the message, so a relay instance picks the messages up within one `pollInterval`.
* **Relay-only workers.** The reverse also works: a worker started with `NestFactory.createApplicationContext(AppModule)` and no HTTP server publishes what the API instances add. The relay's poll timer keeps that process alive until a shutdown hook stops it.

Graceful shutdown needs shutdown hooks:

main.ts

JS TS

```typescript

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module.js';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  // On SIGTERM the relay stops claiming, finishes in-flight publishes and releases its leases.
  app.enableShutdownHooks();
  await app.listen(process.env.PORT ?? 3000);
}
await bootstrap();
```

On `SIGTERM`, the relay stops claiming and waits for in-flight publishes to finish, each for at most `publishTimeout`. It then releases the leases on messages it claimed but hasn't started, so another instance can take them at once instead of waiting out the lease. This happens in `onModuleDestroy()`, before `ClientsModule` closes the TCP client in `onApplicationShutdown()`.

To watch the outbox, subscribe to `OutboxEvents` and read `relay.stats()`:

outbox-admin/outbox-metrics.service.ts

JS TS

```typescript

import { Injectable, type OnModuleInit } from '@nestjs/common';
import { OutboxEvents, OutboxRelay } from '@nestjs/outbox';

@Injectable()
export class OutboxMetrics implements OnModuleInit {
  readonly counters = { published: 0, retried: 0, deadLettered: 0, leaseLost: 0 };
  /** Time from add() to a successful publish, for the latest message. */
  lastPublishLagMs = 0;

  constructor(
    private readonly outboxEvents: OutboxEvents,
    private readonly outboxRelay: OutboxRelay,
  ) {}

  onModuleInit() {
    this.outboxEvents.events$.subscribe((event) => {
      switch (event.type) {
        case 'published':
          this.counters.published++;
          this.lastPublishLagMs = Date.now() - event.message.createdAt;
          break;
        case 'retry-scheduled':
          this.counters.retried++;
          break;
        case 'dead-lettered':
          this.counters.deadLettered++;
          break;
        case 'lease-lost':
          this.counters.leaseLost++;
          break;
      }
    });
  }

  async snapshot() {
    // pending, ready, leased, deadLetters, lagMs (how long the longest-waiting message has waited)...
    const stats = await this.outboxRelay.stats();
    return { ...stats, ...this.counters, lastPublishLagMs: this.lastPublishLagMs };
  }
}
```

`relay.stats()` reports `lagMs`, how long the longest-waiting message has waited. It grows while a downstream is down, which makes it the number to alert on, along with `deadLetters`. A message scheduled with `delay` doesn't count until it is due. The `published` event carries the message, so `Date.now() - message.createdAt` is the end-to-end publish lag. `OutboxEvents` emits the four events the `switch` counts. `lease-lost` means another relay took a message over while this one was publishing it, so that message may reach its consumers twice. Register `OutboxAdminController`, `AdminGuard` and `OutboxMetrics` in an `OutboxAdminModule`.

Each event is also published on a [`node:diagnostics_channel`](https://nodejs.org/api/diagnostics_channel.html) channel, `nestjs:outbox:published` and so on. Tracing and metrics libraries can subscribe to those without any Nest code, and they see every Nest application in the process.

Catch errors inside your subscribers. RxJS and `diagnostics_channel` both rethrow a subscriber's error as an uncaught exception, which stops the process. The relay has already saved the message's outcome by then, so the message itself is safe.

The example application runs this section against a PostgreSQL server: two relays sharing 20 orders, three instances (one of them API-only) placing and cancelling 12 orders with every message published once and each order's events in order, a transaction that waits for another instance's lock on the same key, an instance that crashes holding a lease, and a graceful shutdown.

#### Try it[#](/reliability/outbox#try-it)

Create the two databases, `store` for the order API and `analytics` for the analytics service, and apply each service's own migrations: the order API's create its tables and products from [Prerequisites](/reliability/outbox#prerequisites), and the analytics service's create `order_events`.

Start the analytics service (TCP port 4001) on `analytics`, and the order API (port 3000) on `store`, with `ADMIN_TOKEN=s3cret` in the API's environment. Each logs the store it registered, and the store creates its schema on the first start:

```bash

[Nest] 52654  - 09/30/2026, 6:45:43 PM     LOG [OutboxModule] OutboxStorage: PostgresOutboxStore
[Nest] 52654  - 09/30/2026, 6:45:43 PM     LOG [OutboxModule] PostgresOutboxStore: migrated schema "nest_outbox" to version 1.
[Nest] 52743  - 09/30/2026, 6:45:59 PM     LOG [OutboxModule] OutboxStorage: PostgresOutboxStore
[Nest] 52743  - 09/30/2026, 6:46:00 PM     LOG [OutboxModule] PostgresOutboxStore: migrated schema "nest_outbox" to version 1.
```

Place an order:

```bash

$ curl -X POST localhost:3000/orders \
    -H 'Content-Type: application/json' \
    -d '{"userId":"user-42","items":[{"productId":"salmon-kibble-2kg","quantity":2}]}'
{"id":"07fafff6-9892-4298-aeef-dc2c3d5d6bf5","userId":"user-42","items":[{"productId":"salmon-kibble-2kg","quantity":2,"price":2499}],"total":4998,"status":"placed"}
```

The API's log shows the two in-process handlers:

```bash

[Nest] 52743  - 09/30/2026, 6:46:07 PM     LOG [MailerService] Order confirmation for 07fafff6-9892-4298-aeef-dc2c3d5d6bf5 sent to user-42
[Nest] 52743  - 09/30/2026, 6:46:07 PM     LOG [StockReservationHandler] Reserved stock for order 07fafff6-9892-4298-aeef-dc2c3d5d6bf5
```

And the analytics service's log shows the TCP consumer:

```bash

[Nest] 52654  - 09/30/2026, 6:46:07 PM     LOG [OrderStatsService] Order 07fafff6-9892-4298-aeef-dc2c3d5d6bf5 placed, revenue is now 4998
```

An order for an unknown product fails validation inside the transaction. The response is a `400`, and nothing reaches the outbox:

```bash

$ curl -X POST localhost:3000/orders \
    -H 'Content-Type: application/json' \
    -d '{"userId":"user-42","items":[{"productId":"catnip-mouse","quantity":1}]}'
{"message":"Unknown product \"catnip-mouse\"","error":"Bad Request","statusCode":400}
```

Now order two bags of clumping litter (`clumping-litter-10l`), which has one in stock. The API accepts the order, because stock is reserved asynchronously. The confirmation email goes out, and the reservation is dead-lettered on its first attempt:

```bash

$ curl -X POST localhost:3000/orders \
    -H 'Content-Type: application/json' \
    -d '{"userId":"user-7","items":[{"productId":"clumping-litter-10l","quantity":2}]}'
{"id":"bf4b8bb3-fd47-4c03-9650-ee991cce3dbe","userId":"user-7","items":[{"productId":"clumping-litter-10l","quantity":2,"price":1599}],"total":3198,"status":"placed"}
```

```bash

[Nest] 52743  - 09/30/2026, 6:46:15 PM     LOG [MailerService] Order confirmation for bf4b8bb3-fd47-4c03-9650-ee991cce3dbe sent to user-7
[Nest] 52743  - 09/30/2026, 6:46:15 PM    WARN [OutboxRelay] Dead-lettered order.placed 01a0f335-aae8-7027-b795-ca9dab21e44d after 1 attempt(s) (rejected): NonRetryableMessageError: Not enough stock for "clumping-litter-10l" (order bf4b8bb3-fd47-4c03-9650-ee991cce3dbe)
```

Inspect the dead-letter queue. Without the `x-admin-token` header, the guard answers `403`:

```bash

$ curl localhost:3000/admin/outbox/dead-letters -H 'x-admin-token: s3cret'
```

```json

[
  {
    "id": "01a0f335-aae8-7027-b795-ca9dab21e44d",
    "topic": "order.placed",
    "payload": {
      "id": "bf4b8bb3-fd47-4c03-9650-ee991cce3dbe",
      "items": [{ "price": 1599, "quantity": 2, "productId": "clumping-litter-10l" }],
      "total": 3198,
      "status": "placed",
      "userId": "user-7"
    },
    "headers": {},
    "key": null,
    "createdAt": 1790786775784,
    "attempts": 1,
    "lastError": "NonRetryableMessageError: Not enough stock for \"clumping-litter-10l\" (order bf4b8bb3-fd47-4c03-9650-ee991cce3dbe)",
    "history": [
      {
        "at": 1790786775809,
        "error": "NonRetryableMessageError: Not enough stock for \"clumping-litter-10l\" (order bf4b8bb3-fd47-4c03-9650-ee991cce3dbe)",
        "attempt": 1,
        "transport": "local"
      }
    ],
    "reason": "rejected",
    "failedAt": 1790786775809
  }
]
```

The payload is stored as `jsonb`, which keeps its own key order, so it comes back with its keys in a different order than they were added.

Restock, then requeue the message by its id:

```bash

$ psql postgres://localhost:5432/store -c "UPDATE products SET in_stock = in_stock + 5 WHERE id = 'clumping-litter-10l'"
UPDATE 1
$ curl -X POST localhost:3000/admin/outbox/dead-letters/01a0f335-aae8-7027-b795-ca9dab21e44d/requeue \
    -H 'x-admin-token: s3cret'
{"requeued":1}
```

The reservation goes through. The email handler's inbox already has this message id, so no second email is sent:

```bash

[Nest] 52743  - 09/30/2026, 6:46:24 PM     LOG [StockReservationHandler] Reserved stock for order bf4b8bb3-fd47-4c03-9650-ee991cce3dbe
```

Finally, stop the analytics service with `Ctrl+C`, then place an order and cancel it:

```bash

$ curl -X POST localhost:3000/orders \
    -H 'Content-Type: application/json' \
    -d '{"userId":"user-42","items":[{"productId":"salmon-kibble-2kg","quantity":1}]}'
{"id":"908139a7-2bab-4dd8-988a-bdde8c087074","userId":"user-42","items":[{"productId":"salmon-kibble-2kg","quantity":1,"price":2499}],"total":2499,"status":"placed"}
$ curl -X POST localhost:3000/orders/908139a7-2bab-4dd8-988a-bdde8c087074/cancel
{"id":"908139a7-2bab-4dd8-988a-bdde8c087074","userId":"user-42","items":[{"price":2499,"quantity":1,"productId":"salmon-kibble-2kg"}],"total":2499,"status":"cancelled"}
$ curl localhost:3000/admin/outbox/stats -H 'x-admin-token: s3cret'
{"pending":2,"ready":0,"leased":0,"deadLetters":0,"oldestDueAt":1790786821554,"lagMs":3351,"inFlight":0,"published":5,"retried":3,"deadLettered":1,"leaseLost":0,"lastPublishLagMs":62}
```

Both analytics messages are pending. `lagMs` grows while the outage lasts, and `retried` counts the failed attempts. `ready` is 0: the placement is waiting for its next retry, and the cancellation is due but waits behind it, because they share a key. The API logs each failed attempt:

```bash

[Nest] 52743  - 09/30/2026, 6:47:01 PM    WARN [OutboxRelay] Retrying analytics.order.placed 01a0f336-5db2-72ad-80c8-17c07908dfa1 in 546ms (attempt 1 of 10 failed): Error: connect ECONNREFUSED 127.0.0.1:4001
[Nest] 52743  - 09/30/2026, 6:47:02 PM    WARN [OutboxRelay] Retrying analytics.order.placed 01a0f336-5db2-72ad-80c8-17c07908dfa1 in 1617ms (attempt 2 of 10 failed): Error: connect ECONNREFUSED 127.0.0.1:4001
[Nest] 52743  - 09/30/2026, 6:47:04 PM    WARN [OutboxRelay] Retrying analytics.order.placed 01a0f336-5db2-72ad-80c8-17c07908dfa1 in 2084ms (attempt 3 of 10 failed): Error: connect ECONNREFUSED 127.0.0.1:4001
```

Start the analytics service again. At its next retry, the relay publishes the placement, then the cancellation. The revenue picks up where it was, because it lives in the service's database, not in its memory:

```bash

[Nest] 53368  - 09/30/2026, 6:47:29 PM     LOG [OrderStatsService] Order 908139a7-2bab-4dd8-988a-bdde8c087074 placed, revenue is now 10695
[Nest] 53368  - 09/30/2026, 6:47:29 PM     LOG [OrderStatsService] Order 908139a7-2bab-4dd8-988a-bdde8c087074 cancelled, revenue is now 8196
```

#### Testing[#](/reliability/outbox#testing)

In an e2e test, run PostgreSQL in-process with [PGlite](https://pglite.dev) and your real migrations, turn the poll loop off, and drive the relay yourself. `relay.runOnce()` claims and processes one batch, and resolves when the batch is done:

test/orders.e2e-spec.ts

JS TS

```typescript

import { PGlite } from '@electric-sql/pglite';
import { getDrizzleToken } from '@nestjs/drizzle';
import { Outbox, OutboxRelay } from '@nestjs/outbox';
import { Test, type TestingModule } from '@nestjs/testing';
import { drizzle } from 'drizzle-orm/pglite';
import { migrate } from 'drizzle-orm/pglite/migrator';
import { fileURLToPath } from 'node:url';
import { of } from 'rxjs';
import { afterAll, beforeAll, describe, expect, it, vi } from 'vitest';
import { ANALYTICS_SERVICE, AppModule } from '../src/app.module.js';
import * as schema from '../src/database/schema.js';
import { MailerService } from '../src/notifications/mailer.service.js';
import { OrdersService } from '../src/orders/orders.service.js';

describe('OrdersService (outbox)', () => {
  const client = new PGlite(); // PostgreSQL, in-process
  const db = drizzle(client, { schema });
  const mailer = { sendOrderConfirmation: vi.fn() };
  const analytics = { emit: vi.fn(() => of(undefined)) };
  let moduleRef: TestingModule;
  let orders: OrdersService;
  let relay: OutboxRelay;

  beforeAll(async () => {
    // Your migrations: the order tables. The outbox's store creates its schema in init().
    await migrate(db, { migrationsFolder: fileURLToPath(new URL('../drizzle', import.meta.url)) });
    process.env.OUTBOX_RELAY = 'off'; // no poll loop: the test drives the relay
    moduleRef = await Test.createTestingModule({ imports: [AppModule] })
      .overrideProvider(getDrizzleToken())
      .useValue(db) // the outbox's store runs on it too
      .overrideProvider(MailerService)
      .useValue(mailer)
      .overrideProvider(ANALYTICS_SERVICE)
      .useValue(analytics)
      .compile();
    await moduleRef.init();
    orders = moduleRef.get(OrdersService);
    relay = moduleRef.get(OutboxRelay);
  });

  afterAll(async () => {
    await moduleRef.close();
    await client.close();
  });

  it('publishes order events only after the order commits', async () => {
    const order = await orders.placeOrder({ userId: 'user-42', items: [{ productId: 'salmon-kibble-2kg', quantity: 1 }] });
    expect(mailer.sendOrderConfirmation).not.toHaveBeenCalled();

    await relay.runOnce(); // claim and publish one batch

    expect(mailer.sendOrderConfirmation).toHaveBeenCalledWith(order);
    expect(analytics.emit).toHaveBeenCalledWith(
      'analytics.order.placed',
      expect.objectContaining({ key: order.id, payload: order }),
    );
    expect(await relay.stats()).toMatchObject({ pending: 0, deadLetters: 0 });
  });

  it('publishes nothing when the transaction rolls back', async () => {
    const outbox = moduleRef.get(Outbox);
    const add = outbox.add.bind(outbox);
    vi.spyOn(outbox, 'add').mockImplementationOnce(async (tx, messages) => {
      await add(tx, messages); // the messages are written...
      throw new Error('Connection terminated unexpectedly'); // ...then the transaction fails
    });

    await expect(
      orders.placeOrder({ userId: 'user-42', items: [{ productId: 'salmon-kibble-2kg', quantity: 1 }] }),
    ).rejects.toThrow('Connection terminated unexpectedly');

    expect(await relay.stats()).toMatchObject({ pending: 0 });
    expect(await relay.runOnce()).toMatchObject({ claimed: 0 });
  });
});
```

* The outbox, its store, the migrations and the in-process dispatch are real. Only the mailer and the analytics client are stubbed.
* Override the database `DrizzleModule` registers, whose token `getDrizzleToken()` returns, with the PGlite one. The store's factory injects the same token, so the orders and the outbox share the database, as they share the pool in production, and the store creates its schema there when the module initializes. The module still opens its `pg` pool, which never connects.
* The rollback test lets `outbox.add()` write the messages, then fails the transaction. The order and its messages disappear together, and `runOnce()` finds nothing to claim.
* For behavior that depends on time, such as backoff and lease expiry, move `Date.now()` forward with `vi.spyOn(Date, 'now')`. The relay takes the time from it, for itself and for the store, and real timers keep running for sockets and HTTP.
* PGlite has a single connection, so it runs transactions one at a time. Test races between instances against a PostgreSQL server, the same major version as production, as the example does for [several instances](/reliability/outbox#run-several-instances).
* To keep the outbox out of a test, replace the store: `overrideProvider(PostgresOutboxStore).useValue(new InMemoryOutboxStore())`. A plain instance doesn't register itself, so the outbox falls back to its in-memory store, and the store's schema isn't created. It can't join your Drizzle transactions, though: a rolled-back message is still published, and the store logs a warning the first time it gets your transaction.

#### Delivery guarantees[#](/reliability/outbox#delivery-guarantees)

The overall guarantee is **at least once**, with consumer inboxes absorbing the duplicates.

| Situation                                                | Outcome                                                                                                                                 |
| -------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| The order transaction rolls back                         | The message never existed and is never published                                                                                        |
| The order transaction commits                            | Published eventually, or dead-lettered with its error history                                                                           |
| A relay dies after claiming                              | Published by another instance once its lease expires                                                                                    |
| A relay dies after publishing, before recording it       | Published twice. Inboxes drop the duplicate                                                                                             |
| A publish or handler fails                               | Retried with backoff, then dead-lettered (`exhausted`)                                                                                  |
| A publish or handler outlives `publishTimeout`           | Counted as a failed attempt, and `ctx.signal` aborts. A handler that ignores it keeps running; a retry in the same process waits for it |
| `NonRetryableMessageError`, or `retryIf` returns `false` | Dead-lettered at once (`rejected`)                                                                                                      |
| Messages share a `key`                                   | Published in the order they were added. A retrying message holds back the rest of its key                                               |
| A message is dead-lettered                               | Its key is unblocked, so later messages with that key overtake it                                                                       |
| TCP, Redis or core NATS transport                        | "Published" means the write left the process. A consumer crash after that loses the message                                             |

Order within a key is the order in which the store numbered the messages, not their ids: an id comes from its instance's clock, and clocks differ. PostgreSQL runs transactions concurrently, so the store makes the transactions that add messages with the same key take turns, and the numbering follows commit order (see [Keep messages in your database](/reliability/outbox#keep-messages-in-your-database)).

#### Production checklist[#](/reliability/outbox#production-checklist)

* Register a store on your application's database, on a database server: `PostgresOutboxStore`, `MySqlOutboxStore`, or one of your own ([The store contract](/reliability/outbox#the-store-contract)). Never keep the outbox on the instance itself, in memory or in a file database such as SQLite on its disk: a container's filesystem goes away when the task is replaced, and every message that hadn't been published goes with it. The production guard refuses to start without a store; set `allowInMemoryStorage` only for a process whose messages you can afford to lose.
* Apply the store's migrations before a new version starts, with `npx @nestjs/outbox migrate` or your migration tool, and check them in CI with `npx @nestjs/outbox status`. With `NODE_ENV=production`, the store doesn't migrate at startup: a schema that's behind fails it instead.
* On PostgreSQL, keep the database's default isolation level at READ COMMITTED, the default: the store refuses a stricter one at startup.
* Alert on `lagMs` and `deadLetters` from `relay.stats()`, and on `dead-lettered` events, from `OutboxEvents` or the `nestjs:outbox:dead-lettered` diagnostics channel.
* Size `retry` to how long your downstreams can be down. The package default is 20 attempts, about 30 to 60 minutes in total. This tutorial's 10 attempts capped at 1 minute give up after 2 to 4 minutes, and then a key's later messages overtake the dead-lettered one.
* Keep `consumer` names stable. Inbox entries are keyed by them, so a renamed consumer sees every past message as new.
* Prune inboxes. Nothing calls `OutboxInbox.prune()` for you. Run it from a [cron job](/application/task-scheduling#declarative-cron-jobs), for example `inbox.prune('30d')`, with a window longer than any redelivery, requeues included.
* Keep handlers shorter than `publishTimeout`, and pass `ctx.signal` to the calls they make. A slower handler counts as a failed attempt; leases aren't extended.
* Call `app.enableShutdownHooks()`, so deploys drain the relay instead of leaving messages leased. `DrizzleModule` ends the pool after that, in `onApplicationShutdown()`.
* Protect the dead-letter routes. They expose full payloads.
* Version payloads. A message added by the previous release can still be delivered after a deploy.
* Give each ordered stream its own key, and don't share a key between messages for different transports.
* Keep transactions that call `outbox.add()` short. The per-key lock makes transactions adding messages with the same key take turns. Prisma's interactive transactions time out after 5 seconds by default (`transactionOptions` on the client, or per call).
* On MySQL, run a transaction that calls `outbox.add()` again when it fails with a deadlock (error 1213): MySQL rolled all of it back.
* Size the connection pool for both your requests and the relay: each claim holds a connection for one short transaction.
* Run the contract suites with `concurrent: true` in CI against a store of your own, on a pool, against the database engine and major version you run in production.

#### The store contract[#](/reliability/outbox#the-store-contract)

`PostgresOutboxStore` and `MySqlOutboxStore` implement the package's two storage interfaces: `OutboxStore` for the messages and dead letters, and `OutboxInboxStore` for the consumers' inboxes. For another database, implement them in a provider of your own. The JSDoc of each method on those interfaces says what it must do, and which race each rule prevents.

**Registration.** The store is an ordinary singleton provider that calls `registerSource()` on the injectable `OutboxStorage` in its constructor, for the contracts it implements, by name: `messages` and `inbox`. A service that only consumes may register an inbox store alone. The registry checks the shape at once (every method is a function), refuses a second registration unless it passes `replace: true`, and locks when `OutboxModule` initializes, logging the store in use. A request-scoped provider, a provider in a lazy-loaded module, or a lifecycle hook registers too late, and throws.

With nothing registered, the outbox runs on its in-memory store, and says so at startup:

```bash

[Nest] 19039  - 09/23/2026, 11:28:45 AM     LOG [OutboxModule] OutboxStorage: InMemoryOutboxStore (the default: state is lost on restart and not shared between instances)
```

That is more than a lost-on-restart shortcut. An in-memory store can't join your transaction, so it applies `add()` at once, and warns the first time it receives a transaction handle. In this run, the order's transaction added its message and then failed, and the confirmation email went out anyway:

```bash

[Nest] 19039  - 09/23/2026, 11:28:45 AM    WARN [OutboxModule] InMemoryOutboxStore.add() received your transaction handle, and can't join it: the write applies at once, so a rolled-back transaction won't undo it. Register a store for your database with OutboxStorage.registerSource(). (Logged once.)
[Nest] 19039  - 09/23/2026, 11:28:46 AM     LOG [MailerService] Order confirmation for 7435d418-5d9a-48a0-b186-6cfd2e34b9f4 sent to user-7
```

With `NODE_ENV=production`, the same application doesn't start:

```bash

Error: OutboxStorage: no store is registered for `messages` (OutboxStore) and `inbox` (OutboxInboxStore), and NODE_ENV is "production": in memory, messages and inbox records would be lost on restart and not shared between instances. Register a store on your database: PostgresOutboxStore (@nestjs/outbox/postgres), MySqlOutboxStore (@nestjs/outbox/mysql), or your own OutboxStore and OutboxInboxStore in a provider that injects OutboxStorage and calls `storage.registerSource({ messages: this, inbox: this })` in its constructor. Or set `allowInMemoryStorage: true` in the OutboxModule options to run in memory anyway.
```

`allowInMemoryStorage: true` in the module's options is the deliberate way out, for a single instance that may lose its state.

**Atomicity.** Producers, relays and deliveries race each other through the store. `add()` must number a key's messages in the order their transactions commit, `claim()` must never lease a message to two relays or run ahead of an older message of its key, a relay's later writes must apply only while its lease holds, and two deliveries of one message must meet at `recordInbox()`. So every method that changes state is one conditional statement, or one transaction with the right lock, never a read followed by a write. `add()` and `recordInbox()` receive your transaction object untouched: they must write through it, and refuse anything that isn't one, such as the database itself, with `OutboxTransactionRequiredError`.

**Test it** with the suites from `@nestjs/outbox/testing`. `outboxStoreContract()` and `outboxInboxStoreContract()` return the contracts as test cases for any test runner: each case is a `name` and a `run()` function that throws on failure. The tutorial's tests run them against `PostgresOutboxStore` through Drizzle, as you would against yours, with a function that returns the store on emptied tables, a way to open one of your transactions, and `notATransaction`, a handle the store must refuse:

test/drizzle-outbox.store.e2e-spec.ts

JS TS

```typescript

/** A store on emptied tables, built the way Nest builds it: with the database and a registry. */
async function freshStore(db: Database): Promise<OutboxStoreHarness<Transaction> & { store: PostgresOutboxStore }> {
  await db.execute(sql`TRUNCATE nest_outbox.messages, nest_outbox.dead_letters, nest_outbox.inbox RESTART IDENTITY`);
  return {
    store: new PostgresOutboxStore({ executor: fromDrizzle(db) }, new OutboxStorage()),
    transaction: (work) => db.transaction(work),
    notATransaction: db,
  };
}

describe('PostgresOutboxStore through fromDrizzle on PGlite: the store contract', () => {
  // ...
  // The concurrency cases run too; with one connection, PGlite runs them one transaction at a time.
  for (const c of outboxStoreContract(() => freshStore(db), { concurrent: true })) {
    it(c.name, c.run);
  }
  describe('the inbox contract', () => {
    for (const c of outboxInboxStoreContract(() => freshStore(db), { concurrent: true })) {
      it(c.name, c.run);
    }
  });
});
```

`concurrent: true` adds the races a naive store fails: producers of a key whose transactions overlap, relays claiming side by side, producers and relays racing, a stale relay's writes racing a takeover, and two deliveries of one message. On PGlite they pass one transaction at a time, so run them against a server with a pool too, where the transactions really overlap, on the database engine and major version you run in production. The tutorial runs both suites through each of its clients: Drizzle on PGlite and on PostgreSQL, TypeORM and Prisma on PostgreSQL, and Drizzle on MySQL, against `MySqlOutboxStore`. The package's own tests run them against stores written by hand with Drizzle, TypeORM and Prisma too, as the proof that a store written against the interfaces passes them.

Other packages' stores can live elsewhere: the idempotency store fits Redis. The outbox's store can't, because its messages must commit with your rows, in your database.

#### Using BullMQ on Postgres instead[#](/reliability/outbox#using-bullmq-on-postgres-instead)

BullMQ 6 has a PostgreSQL backend, so it's fair to ask whether its job table could be the outbox. The package's research into BullMQ 6.3.x (from reading its published code, not a live run) says: not today.

* `Queue.add()` always runs on BullMQ's own connection pool, in autocommit mode. The backend interface deliberately exposes no connection or transaction type, so an `add()` can't join the transaction that inserts your order.
* The enqueue itself is one SQL function, `bullmq.add_job(...)`. Calling it on your own transaction would be atomic, but the function is internal, its signature changes with BullMQ's schema migrations, and every transaction that calls it would take Postgres's global NOTIFY lock at commit.
* `@nestjs/bullmq` 12.0.0 can't select the Postgres backend for a single queue. The only way is BullMQ's process-wide `setDefaultBackendFactory()`.

What's needed is an upstream option to run `add()` on a caller-supplied client (so the job commits with the order), plus a backend option in `@nestjs/bullmq`. With both, the job table would be the outbox, and BullMQ's workers would provide the claims, retries and failed set with no relay in between. Until then, use this outbox and publish to BullMQ from an `OutboxTransport` that calls `queue.add(topic, payload)` with the outbox message `id` as the `jobId`, so a republished message is ignored while the job still exists.

#### Example[#](/reliability/outbox#example)

A working example is available in the [37-outbox sample](https://github.com/nestjs/nest/tree/master/sample/37-outbox): the order API on PostgreSQL with Drizzle, its in-process handlers, the analytics microservice with a database of its own, the dead-letter admin API, and the tests.

#### Reference[#](/reliability/outbox#reference)

##### Module options[#](/reliability/outbox#module-options)

`OutboxModule.forRoot()` takes these options. `forRootAsync()` takes `transports` classes, `imports` and `isGlobal` at its top level, and the rest from `useFactory`, `useClass` or `useExisting` (a class implementing `OutboxOptionsFactory`), as in [Register the outbox](/reliability/outbox#register-the-outbox). The options token is `OUTBOX_MODULE_OPTIONS`. The store isn't an option: register it as a provider, as in [Keep messages in your database](/reliability/outbox#keep-messages-in-your-database). Durations are milliseconds, or strings such as `'30s'` and `'1m'`.

| Option                 | Default                                    | Meaning                                                                                                                                            |
| ---------------------- | ------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| `transports`           | None                                       | Named `OutboxTransport` classes or instances. `local`, the `@OnOutboxMessage()` handlers, is built in and reserved                                 |
| `imports`              | None                                       | Modules whose exports the transport classes inject                                                                                                 |
| `route`                | The only destination                       | `(message) => name`: the one transport a message goes to. Required with handlers and transports, or several transports                             |
| `relay.enabled`        | `true`                                     | `false` in instances that only produce or only consume                                                                                             |
| `relay.pollInterval`   | `'1s'`                                     | The wait between polls when idle                                                                                                                   |
| `relay.batchSize`      | `100`                                      | Messages per claim                                                                                                                                 |
| `relay.lease`          | `'30s'`                                    | How long a claim is exclusive                                                                                                                      |
| `relay.concurrency`    | `10`                                       | Key groups published in parallel within a batch                                                                                                    |
| `relay.publishTimeout` | A third of `lease`                         | A slower publish counts as a failed attempt, and its `signal` aborts                                                                               |
| `retry.attempts`       | `20`                                       | Total attempts, including the first, before the message is dead-lettered. `retry: 5` means 5 attempts; `retry: false`, a single attempt            |
| `retry.backoff`        | `'1s'` doubling up to `'5m'`, equal jitter | An object with `delay`, `factor`, `maxDelay` and `jitter` (`'equal'`, `'full'` or `'none'`), or a function `(attempt, error, message) => duration` |
| `retry.retryIf`        | Every error                                | `(error, attempt, message) => boolean`: `false` dead-letters the message at once                                                                   |
| `allowInMemoryStorage` | `false`                                    | With `NODE_ENV=production` and no registered store, startup fails; `true` runs on the in-memory store anyway                                       |
| `isGlobal`             | `true`                                     | Registers the module globally                                                                                                                      |

##### Stores[#](/reliability/outbox#stores)

`new PostgresOutboxStore(options, outboxStorage)`, from `@nestjs/outbox/postgres`, and `new MySqlOutboxStore(options, outboxStorage)`, from `@nestjs/outbox/mysql`, take these options. Without `outboxStorage`, the store registers nowhere, which suits a script or a test.

| Option     | Default                                   | Meaning                                                                                                                                                                                                                                                                                                                     |
| ---------- | ----------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `executor` | Required                                  | How the store reaches the database: one of the executors below, from the same entry point as the store. The other dialect's doesn't compile                                                                                                                                                                                 |
| `schema`   | `'nest_outbox'`                           | On PostgreSQL, the schema of its tables, which its first migration creates: letters, digits and underscores, not starting with a digit, at most 63 characters. On MySQL, the prefix of its tables in the connection's database: lowercase letters, digits and underscores, not starting with a digit, at most 40 characters |
| `migrate`  | `true`, except with `NODE_ENV=production` | Apply the pending migrations when the application starts. With `false`, startup fails with an `OutboxSchemaError` while the schema is behind                                                                                                                                                                                |

Each executor takes your database client, and its own kind of transaction object, which `outbox.add()` and `processInTransaction()` then take:

| Executor                      | Takes                                                                                                                                                                                                         | Transaction object                                                                                                    |
| ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- |
| `fromDrizzle(db)`             | A Drizzle database: on PostgreSQL, whichever its driver; on MySQL, `mysql2`                                                                                                                                   | The `tx` that `db.transaction()` hands its callback                                                                   |
| `fromTypeOrm(dataSource)`     | A `DataSource` of type `postgres` or `mysql`                                                                                                                                                                  | The `EntityManager` that `dataSource.transaction()` hands its callback, or a `QueryRunner` after `startTransaction()` |
| `fromPrisma(prisma, options)` | A Prisma client, through a driver adapter such as `@prisma/adapter-pg`, or `@prisma/adapter-mariadb` for MySQL. `maxWait` (default `'10s'`) and `timeout` (default `'1m'`) limit the store's own transactions | The transaction client that `prisma.$transaction()` hands its callback                                                |
| `fromKysely(db)`              | A `Kysely` instance with a PostgreSQL or MySQL dialect                                                                                                                                                        | The transaction that `db.transaction().execute()` hands its callback                                                  |
| `fromPg(pool)`                | PostgreSQL: a node-postgres `Pool`, or a connected `Client`                                                                                                                                                   | A client, such as one from `pool.connect()`, after `BEGIN`                                                            |
| `fromMysql2(pool)`            | MySQL: a `mysql2/promise` pool, or a connection                                                                                                                                                               | A connection, such as one from `pool.getConnection()`, after `beginTransaction()`                                     |

The store's `migrate()` method applies the pending migrations at once, whatever the `migrate` option says, and resolves with the versions it applied. The static `migrationSql()` returns their SQL, with the bookkeeping, and `MySqlOutboxStore.migrationStatements()` returns the same statements, one per string. They take the `schema`, the versions to go `from` (default `0`, a new database) and `to` (default: the one the package needs), and `migrationSql()` takes `statementBreakpoints` too. From version 0 on PostgreSQL, the SQL starts with `CREATE SCHEMA IF NOT EXISTS`, which needs the CREATE privilege on the database: leave it out if someone created the schema for you. The static `schemaVersion` is the version the package needs.

The command line, `npx @nestjs/outbox`, takes `--url` (default `DATABASE_URL`) and `--schema` (default `nest_outbox`). A `mysql://` URL picks `MySqlOutboxStore`'s migrations, and needs `mysql2` installed:

| Command   | What it does                                                                                                                                                                                                            |
| --------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `migrate` | Applies the pending migrations, as `migrate: true` does at startup                                                                                                                                                      |
| `status`  | Prints the schema's version and the one the package needs, and exits with 1 while the schema is behind                                                                                                                  |
| `sql`     | Prints the SQL of `migrationSql()`, from `--from` to `--to`, without a database: PostgreSQL's, or MySQL's with `--dialect mysql`. `--statement-breakpoints` separates the statements for a drizzle-kit custom migration |

On MySQL, the store needs MySQL 8.4 LTS or 9.x with a strict `sql_mode`, MySQL's default: a lax `sql_mode`, or MariaDB, fails the startup.

##### Messages and handlers[#](/reliability/outbox#messages-and-handlers)

A message passed to `outbox.add(tx, message)` ([Save the order and its messages in one transaction](/reliability/outbox#save-the-order-and-its-messages-in-one-transaction)) has these fields:

| Field                    | Required | Meaning                                                                               |
| ------------------------ | -------- | ------------------------------------------------------------------------------------- |
| `topic`                  | Yes      | What `route` and the handlers match on                                                |
| `payload`                | Yes      | Serialized to JSON when `add()` runs                                                  |
| `key`                    | No       | The ordering key: messages that share it are published one at a time, in commit order |
| `headers`                | No       | String headers, passed to transports                                                  |
| `id`                     | No       | Your own unique id. The default is a UUIDv7; consumers deduplicate by it              |
| `delay` or `availableAt` | No       | Publish no earlier than this long from now, or than this point in time. Not both      |

* `@OnOutboxMessage(topic, options)` takes `consumer` (required: the name of the handler's inbox) and `inbox` (default `true`; `false` runs every delivery). [Handle order.placed in-process](/reliability/outbox#handle-orderplaced-in-process)
* A handler's context has `message`, `consumer`, `attempt`, `signal` and `processInTransaction(tx, work)`.
* `ClientProxyTransport(token, options)` emits the topic with an envelope of `id`, `topic`, `key`, `headers`, `createdAt` and `payload` (`OutboxEnvelope`). Its `toPacket(message, envelope)` option returns your own `pattern` and `data`. [Publish to the analytics microservice](/reliability/outbox#publish-to-the-analytics-microservice)

##### Services[#](/reliability/outbox#services)

| Service             | Methods                                                                                                                                                                                                                                                                                                                 |
| ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `Outbox`            | `add(tx, messages)`, `notify()`                                                                                                                                                                                                                                                                                         |
| `OutboxRelay`       | `stats()`: `pending`, `ready`, `leased`, `deadLetters`, `oldestDueAt`, `lagMs`, `inFlight`. `runOnce()`: `claimed`, `published`, `retried`, `deadLettered`, `released`, `leaseLost`. Also `notify()`, `start()` and `stop()`                                                                                            |
| `OutboxDeadLetters` | `list(query)` (by `topic`, `key`, `limit`, `offset`; newest first), `get(id)`, `requeue(target)`, `purge(target)`. A target is an id, an array of ids, or a filter by `ids`, `topic`, `key`, `failedBefore`, or `all: true`. [Retries and the dead-letter queue](/reliability/outbox#retries-and-the-dead-letter-queue) |
| `OutboxInbox`       | `process(consumer, id, work)`, `processInTransaction(tx, consumer, id, work)`, `prune(olderThan)`. Both `process` methods resolve `duplicate`, and `result` when `work` ran                                                                                                                                             |

##### Events[#](/reliability/outbox#events)

`OutboxEvents.events$` emits each event, and publishes it on its `node:diagnostics_channel` channel. Every payload has `type` and the `message`. [Run several instances](/reliability/outbox#run-several-instances) counts them. Catch errors inside your subscribers: RxJS and `diagnostics_channel` both rethrow a subscriber's error as an uncaught exception.

| Event             | Channel                         | Other fields                               | When                                                                          |
| ----------------- | ------------------------------- | ------------------------------------------ | ----------------------------------------------------------------------------- |
| `published`       | `nestjs:outbox:published`       | `transport`, `durationMs`                  | A transport accepted the message                                              |
| `retry-scheduled` | `nestjs:outbox:retry-scheduled` | `transport`, `error`, `attempt`, `delayMs` | A publish failed and will be retried                                          |
| `dead-lettered`   | `nestjs:outbox:dead-lettered`   | `transport`, `error`, `attempt`, `reason`  | The message moved to the dead letters. Alert on it                            |
| `lease-lost`      | `nestjs:outbox:lease-lost`      | None                                       | Another relay took the message over mid-publish, so it may be published twice |

A dead letter's `reason` is `exhausted` (the retries ran out) or `rejected` (a `NonRetryableMessageError`, or `retryIf` returned `false`).

##### Errors[#](/reliability/outbox#errors)

None of them carries an HTTP status. `OutboxError` is the base class of the four that the package throws.

| Error                            | Raised when                                                                                                                                                                                                                                                                          |
| -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `OutboxTransactionRequiredError` | `add()` or `processInTransaction()` got no transaction handle, or a store refused a handle that isn't a transaction                                                                                                                                                                  |
| `OutboxPublishTimeoutError`      | A publish outlived `relay.publishTimeout` (`timeoutMs`). Counted as a failed attempt                                                                                                                                                                                                 |
| `OutboxNoHandlerError`           | No `@OnOutboxMessage()` handler for the topic in this process (`topic`). Retried                                                                                                                                                                                                     |
| `OutboxSchemaError`              | The store's schema is behind the package's migrations while `migrate` is off, or applying them failed (`cause`): startup and every call fail until it's fixed. With the `schema`, its `version` and the `requiredVersion`. From `@nestjs/outbox/postgres` and `@nestjs/outbox/mysql` |
| `NonRetryableMessageError`       | You throw it from a handler or transport to dead-letter the message without retrying                                                                                                                                                                                                 |

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/reliability/outbox.md)

----
url: https://docs.nestjs.com/v11/openapi/mapped-types
----

* [Mapped types](https://docs.nestjs.com/v11/openapi/mapped-types#mapped-types)
* [Partial](https://docs.nestjs.com/v11/openapi/mapped-types#partial)
* [Pick](https://docs.nestjs.com/v11/openapi/mapped-types#pick)
* [Omit](https://docs.nestjs.com/v11/openapi/mapped-types#omit)
* [Intersection](https://docs.nestjs.com/v11/openapi/mapped-types#intersection)
* [Composition](https://docs.nestjs.com/v11/openapi/mapped-types#composition)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/openapi/mapped-types.md "Suggest Edits")

### Mapped types

As you build out features like **CRUD** (Create/Read/Update/Delete) it's often useful to construct variants on a base entity type. Nest provides several utility functions that perform type transformations to make this task more convenient.

#### Partial[#](/openapi/mapped-types#partial)

When building input validation types (also called DTOs), it's often useful to build **create** and **update** variations on the same type. For example, the **create** variant may require all fields, while the **update** variant may make all fields optional.

Nest provides the `PartialType()` utility function to make this task easier and minimize boilerplate.

The `PartialType()` function returns a type (class) with all the properties of the input type set to optional. For example, suppose we have a **create** type as follows:

```typescript

import { ApiProperty } from '@nestjs/swagger';

export class CreateCatDto {
  @ApiProperty()
  name: string;

  @ApiProperty()
  age: number;

  @ApiProperty()
  breed: string;
}
```

By default, all of these fields are required. To create a type with the same fields, but with each one optional, use `PartialType()` passing the class reference (`CreateCatDto`) as an argument:

```typescript

export class UpdateCatDto extends PartialType(CreateCatDto) {}
```

> **Hint** The `PartialType()` function is imported from the `@nestjs/swagger` package.

#### Pick[#](/openapi/mapped-types#pick)

The `PickType()` function constructs a new type (class) by picking a set of properties from an input type. For example, suppose we start with a type like:

```typescript

import { ApiProperty } from '@nestjs/swagger';

export class CreateCatDto {
  @ApiProperty()
  name: string;

  @ApiProperty()
  age: number;

  @ApiProperty()
  breed: string;
}
```

We can pick a set of properties from this class using the `PickType()` utility function:

```typescript

export class UpdateCatAgeDto extends PickType(CreateCatDto, ['age'] as const) {}
```

> **Hint** The `PickType()` function is imported from the `@nestjs/swagger` package.

#### Omit[#](/openapi/mapped-types#omit)

The `OmitType()` function constructs a type by picking all properties from an input type and then removing a particular set of keys. For example, suppose we start with a type like:

```typescript

import { ApiProperty } from '@nestjs/swagger';

export class CreateCatDto {
  @ApiProperty()
  name: string;

  @ApiProperty()
  age: number;

  @ApiProperty()
  breed: string;
}
```

We can generate a derived type that has every property **except**`name` as shown below. In this construct, the second argument to `OmitType` is an array of property names.

```typescript

export class UpdateCatDto extends OmitType(CreateCatDto, ['name'] as const) {}
```

> **Hint** The `OmitType()` function is imported from the `@nestjs/swagger` package.

#### Intersection[#](/openapi/mapped-types#intersection)

The `IntersectionType()` function combines two types into one new type (class). For example, suppose we start with two types like:

```typescript

import { ApiProperty } from '@nestjs/swagger';

export class CreateCatDto {
  @ApiProperty()
  name: string;

  @ApiProperty()
  breed: string;
}

export class AdditionalCatInfo {
  @ApiProperty()
  color: string;
}
```

We can generate a new type that combines all properties in both types.

```typescript

export class UpdateCatDto extends IntersectionType(
  CreateCatDto,
  AdditionalCatInfo,
) {}
```

> **Hint** The `IntersectionType()` function is imported from the `@nestjs/swagger` package.

#### Composition[#](/openapi/mapped-types#composition)

The type mapping utility functions are composable. For example, the following will produce a type (class) that has all of the properties of the `CreateCatDto` type except for `name`, and those properties will be set to optional:

```typescript

export class UpdateCatDto extends PartialType(
  OmitType(CreateCatDto, ['name'] as const),
) {}
```

----
url: https://docs.nestjs.com/fundamentals/lifecycle-events
----

[Skip to content](#content)

On this page

* [Lifecycle Events](https://docs.nestjs.com/fundamentals/lifecycle-events#lifecycle-events)
* [Lifecycle sequence](https://docs.nestjs.com/fundamentals/lifecycle-events#lifecycle-sequence)
* [Lifecycle events](https://docs.nestjs.com/fundamentals/lifecycle-events#lifecycle-events-1)
* [Usage](https://docs.nestjs.com/fundamentals/lifecycle-events#usage)
* [Asynchronous initialization](https://docs.nestjs.com/fundamentals/lifecycle-events#asynchronous-initialization)
* [Application shutdown](https://docs.nestjs.com/fundamentals/lifecycle-events#application-shutdown)

[](https://srv.carbonads.net/ads/click/x/GTND4277CVSD5KJUCAYLYKQUF67D62QUF6BIKZ3JCAAI623WC6YICK7KC67DE27WC6SI4KQ7CESI42JNCTADL23EHEYI55QLCAYD653ECTNCYBZ52K)[Automatic backups, patching, replication, and failover. Focus on your app, not your database. ](https://srv.carbonads.net/ads/click/x/GTND4277CVSD5KJUCAYLYKQUF67D62QUF6BIKZ3JCAAI623WC6YICK7KC67DE27WC6SI4KQ7CESI42JNCTADL23EHEYI55QLCAYD653ECTNCYBZ52K)[ads via Carbon](http://carbonads.net/?utm_source=nestjscom\&utm_medium=ad_via_link\&utm_campaign=in_unit\&utm_term=carbon)

### Lifecycle Events

A Nest application, as well as every application element, has a lifecycle managed by Nest. Nest provides **lifecycle hooks** that give you visibility into key lifecycle events and let you act (run registered code on your modules, providers, or controllers) when they occur.

#### Lifecycle sequence[#](/fundamentals/lifecycle-events#lifecycle-sequence)

The following diagram depicts the sequence of key application lifecycle events, from the time the application is bootstrapped until the Node.js process exits. The overall lifecycle divides into three phases: **initializing**, **running**, and **terminating**. With this lifecycle in mind, you can plan for the appropriate initialization of modules and services, manage active connections, and gracefully shut down your application when it receives a termination signal.

#### Lifecycle events[#](/fundamentals/lifecycle-events#lifecycle-events-1)

Lifecycle events happen during application bootstrapping and shutdown. Nest calls registered lifecycle hook methods on modules, providers, and controllers at each of the following lifecycle events (**shutdown hooks** must be enabled first, as described in [Application shutdown](/fundamentals/lifecycle-events#application-shutdown)). As shown in the diagram above, Nest also calls the appropriate underlying methods to begin and stop listening for connections.

In the following table, `onModuleInit()` and `onApplicationBootstrap()` are triggered only when the application is initialized: when you call `app.init()` or `app.listen()` explicitly, or when you create a standalone application with `NestFactory.createApplicationContext()`, which initializes it for you.

The `onModuleDestroy()`, `beforeApplicationShutdown()`, and `onApplicationShutdown()` hooks are triggered only when you call `app.close()` explicitly, or when the process receives a system signal (such as `SIGTERM`) and you have called `enableShutdownHooks()` at application bootstrap (see [Application shutdown](/fundamentals/lifecycle-events#application-shutdown) below).

| Lifecycle hook method           | Lifecycle event triggering the hook method call                                                                                                                                                              |
| ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `onModuleInit()`                | Called once the host module's dependencies have been resolved.                                                                                                                                               |
| `onApplicationBootstrap()`      | Called once all modules have been initialized, but before listening for connections.                                                                                                                         |
| `onModuleDestroy()`\*           | Called after a termination signal (e.g., `SIGTERM`) has been received.                                                                                                                                       |
| `beforeApplicationShutdown()`\* | Called after all `onModuleDestroy()` handlers have completed (Promises resolved or rejected); once complete (Promises resolved or rejected), all existing connections will be closed (`app.close()` called). |
| `onApplicationShutdown()`\*     | Called after connections close, as the last step of `app.close()`.                                                                                                                                           |

\* For these events, if you're not calling `app.close()` explicitly, you must opt in to make them work with system signals such as `SIGTERM`. See [Application shutdown](/fundamentals/lifecycle-events#application-shutdown) below.

> **Warning** The lifecycle hooks listed above are not triggered for **request-scoped** classes. Request-scoped classes are not tied to the application lifecycle, and their lifespan is unpredictable. They are created exclusively for each request and garbage-collected after the response is sent.

> **Hint** Nest calls `onModuleInit()` and `onApplicationBootstrap()` module by module, ordered by each module's distance from the root module in the import graph: the most deeply imported modules (and global modules) go first, and the root module goes last. Each module's hooks are awaited before Nest moves on to the next module. The shutdown hooks run in the reverse order.

#### Usage[#](/fundamentals/lifecycle-events#usage)

Each lifecycle hook is represented by an interface. Interfaces are technically optional because they do not exist after TypeScript compilation. Nonetheless, it's good practice to use them to benefit from strong typing and editor tooling. To register a lifecycle hook, implement the appropriate interface. For example, to register a method to be called during module initialization on a particular class (e.g., a controller, provider, or module), implement the `OnModuleInit` interface by supplying an `onModuleInit()` method:

JS TS

```typescript

import { Injectable, OnModuleInit } from '@nestjs/common';

@Injectable()
export class UsersService implements OnModuleInit {
  onModuleInit() {
    console.log(`The module has been initialized.`);
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';

@Injectable()
export class UsersService {
  onModuleInit() {
    console.log(`The module has been initialized.`);
  }
}
```

#### Asynchronous initialization[#](/fundamentals/lifecycle-events#asynchronous-initialization)

Both the `OnModuleInit` and `OnApplicationBootstrap` hooks let you defer the application initialization process. Return a `Promise`, or mark the method as `async` and `await` the completion of an asynchronous operation in the method body.

JS TS

```typescript

async onModuleInit(): Promise<void> {
  await this.fetch();
}
```

```typescript

async onModuleInit() {
  await this.fetch();
}
```

#### Application shutdown[#](/fundamentals/lifecycle-events#application-shutdown)

The `onModuleDestroy()`, `beforeApplicationShutdown()`, and `onApplicationShutdown()` hooks are called in the terminating phase, in response to an explicit call to `app.close()` or, if you opted in, upon receipt of system signals such as `SIGTERM`. This feature is often used with [Kubernetes](https://kubernetes.io/) to manage container lifecycles, with [Heroku](https://www.heroku.com/) dynos, and with similar services.

Shutdown hook listeners consume system resources, so they are disabled by default. To use shutdown hooks, you **must enable listeners** by calling `enableShutdownHooks()`:

```typescript

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module.js';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);

  // Starts listening for shutdown hooks
  app.enableShutdownHooks();

  await app.listen(process.env.PORT ?? 3000);
}
await bootstrap();
```

> **Warning** Due to inherent platform limitations, NestJS has limited support for application shutdown hooks on Windows. You can expect `SIGINT` to work, as well as `SIGBREAK` and, to some extent, `SIGHUP`. However, `SIGTERM` never works on Windows, because killing a process in the Task Manager is unconditional (there is no way for an application to detect or prevent it). To learn more about how `SIGINT`, `SIGBREAK`, and other signals are handled on Windows, see the [libuv signal handling documentation](https://docs.libuv.org/en/v1.x/signal.html) and the Node.js documentation on [signal events](https://nodejs.org/api/process.html#process_signal_events).

> **Hint**`enableShutdownHooks()` consumes memory by starting listeners. When you run multiple Nest apps in a single Node.js process (e.g., during parallel test runs), Node.js may warn about too many listeners. For this reason, shutdown hooks are not enabled by default. Keep this in mind when running multiple instances in a single Node.js process.

When the application receives a termination signal, it calls any registered `onModuleDestroy()`, `beforeApplicationShutdown()`, and `onApplicationShutdown()` methods, in that order. `beforeApplicationShutdown()` and `onApplicationShutdown()` receive the corresponding signal as their first parameter (`onModuleDestroy()` takes no arguments). If a registered method returns a promise, Nest doesn't continue the sequence until the promise is resolved or rejected.

JS TS

```typescript

@Injectable()
class UsersService implements OnApplicationShutdown {
  onApplicationShutdown(signal: string) {
    console.log(signal); // e.g., "SIGINT"
  }
}
```

```typescript

@Injectable()
class UsersService {
  onApplicationShutdown(signal) {
    console.log(signal); // e.g., "SIGINT"
  }
}
```

> **Hint** Calling `app.close()` doesn't terminate the Node.js process. It only runs the shutdown sequence (the `onModuleDestroy()`, `beforeApplicationShutdown()`, and `onApplicationShutdown()` hooks, plus closing the underlying server). If there are active intervals, long-running background tasks, and so on, the process won't exit on its own.

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/fundamentals/lifecycle-events.md)

----
url: https://docs.nestjs.com/v10/techniques/mongodb
----

* [Mongo](https://docs.nestjs.com/v10/techniques/mongodb#mongo)
* [Model injection](https://docs.nestjs.com/v10/techniques/mongodb#model-injection)
* [Connection](https://docs.nestjs.com/v10/techniques/mongodb#connection)
* [Sessions](https://docs.nestjs.com/v10/techniques/mongodb#sessions)
* [Multiple databases](https://docs.nestjs.com/v10/techniques/mongodb#multiple-databases)
* [Hooks (middleware)](https://docs.nestjs.com/v10/techniques/mongodb#hooks-middleware)
* [Plugins](https://docs.nestjs.com/v10/techniques/mongodb#plugins)
* [Discriminators](https://docs.nestjs.com/v10/techniques/mongodb#discriminators)
* [Testing](https://docs.nestjs.com/v10/techniques/mongodb#testing)
* [Async configuration](https://docs.nestjs.com/v10/techniques/mongodb#async-configuration)
* [Connection events](https://docs.nestjs.com/v10/techniques/mongodb#connection-events)
* [Subdocuments](https://docs.nestjs.com/v10/techniques/mongodb#subdocuments)
* [Virtuals](https://docs.nestjs.com/v10/techniques/mongodb#virtuals)
* [Example](https://docs.nestjs.com/v10/techniques/mongodb#example)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/techniques/mongo.md "Suggest Edits")

### Mongo

Nest supports two methods for integrating with the [MongoDB](https://www.mongodb.com/) database. You can either use the built-in [TypeORM](https://github.com/typeorm/typeorm) module described [here](/v10/techniques/database), which has a connector for MongoDB, or use [Mongoose](https://mongoosejs.com), the most popular MongoDB object modeling tool. In this chapter we'll describe the latter, using the dedicated `@nestjs/mongoose` package.

Start by installing the [required dependencies](https://github.com/Automattic/mongoose):

```bash

$ npm i @nestjs/mongoose mongoose
```

Once the installation process is complete, we can import the `MongooseModule` into the root `AppModule`.

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';

@Module({
  imports: [MongooseModule.forRoot('mongodb://localhost/nest')],
})
export class AppModule {}
```

```typescript

import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
import { HydratedDocument } from 'mongoose';

export type CatDocument = HydratedDocument<Cat>;

@Schema()
export class Cat {
  @Prop()
  name: string;

  @Prop()
  age: number;

  @Prop()
  breed: string;
}

export const CatSchema = SchemaFactory.createForClass(Cat);
```

> **Hint** Note you can also generate a raw schema definition using the `DefinitionsFactory` class (from the `nestjs/mongoose`). This allows you to manually modify the schema definition generated based on the metadata you provided. This is useful for certain edge-cases where it may be hard to represent everything with decorators.

The `@Schema()` decorator marks a class as a schema definition. It maps our `Cat` class to a MongoDB collection of the same name, but with an additional “s” at the end - so the final mongo collection name will be `cats`. This decorator accepts a single optional argument which is a schema options object. Think of it as the object you would normally pass as a second argument of the `mongoose.Schema` class' constructor (e.g., `new mongoose.Schema(_, options)`)). To learn more about available schema options, see [this](https://mongoosejs.com/docs/guide.html#options) chapter.

The `@Prop()` decorator defines a property in the document. For example, in the schema definition above, we defined three properties: `name`, `age`, and `breed`. The [schema types](https://mongoosejs.com/docs/schematypes.html) for these properties are automatically inferred thanks to TypeScript metadata (and reflection) capabilities. However, in more complex scenarios in which types cannot be implicitly reflected (for example, arrays or nested object structures), types must be indicated explicitly, as follows:

```typescript

@Prop([String])
tags: string[];
```

Alternatively, the `@Prop()` decorator accepts an options object argument ([read more](https://mongoosejs.com/docs/schematypes.html#schematype-options) about the available options). With this, you can indicate whether a property is required or not, specify a default value, or mark it as immutable. For example:

```typescript

@Prop({ required: true })
name: string;
```

In case you want to specify relation to another model, later for populating, you can use `@Prop()` decorator as well. For example, if `Cat` has `Owner` which is stored in a different collection called `owners`, the property should have type and ref. For example:

```typescript

import * as mongoose from 'mongoose';
import { Owner } from '../owners/schemas/owner.schema';

// inside the class definition
@Prop({ type: mongoose.Schema.Types.ObjectId, ref: 'Owner' })
owner: Owner;
```

In case there are multiple owners, your property configuration should look as follows:

```typescript

@Prop({ type: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Owner' }] })
owners: Owner[];
```

Finally, the **raw** schema definition can also be passed to the decorator. This is useful when, for example, a property represents a nested object which is not defined as a class. For this, use the `raw()` function from the `@nestjs/mongoose` package, as follows:

```typescript

@Prop(raw({
  firstName: { type: String },
  lastName: { type: String }
}))
details: Record<string, any>;
```

Alternatively, if you prefer **not using decorators**, you can define a schema manually. For example:

```typescript

export const CatSchema = new mongoose.Schema({
  name: String,
  age: Number,
  breed: String,
});
```

The `cat.schema` file resides in a folder in the `cats` directory, where we also define the `CatsModule`. While you can store schema files wherever you prefer, we recommend storing them near their related **domain** objects, in the appropriate module directory.

Let's look at the `CatsModule`:

cats.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';
import { Cat, CatSchema } from './schemas/cat.schema';

@Module({
  imports: [MongooseModule.forFeature([{ name: Cat.name, schema: CatSchema }])],
  controllers: [CatsController],
  providers: [CatsService],
})
export class CatsModule {}
```

The `MongooseModule` provides the `forFeature()` method to configure the module, including defining which models should be registered in the current scope. If you also want to use the models in another module, add MongooseModule to the `exports` section of `CatsModule` and import `CatsModule` in the other module.

Once you've registered the schema, you can inject a `Cat` model into the `CatsService` using the `@InjectModel()` decorator:

cats.service.ts

JS TS

```typescript

import { Model } from 'mongoose';
import { Injectable } from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import { Cat } from './schemas/cat.schema';
import { CreateCatDto } from './dto/create-cat.dto';

@Injectable()
export class CatsService {
  constructor(@InjectModel(Cat.name) private catModel: Model<Cat>) {}

  async create(createCatDto: CreateCatDto): Promise<Cat> {
    const createdCat = new this.catModel(createCatDto);
    return createdCat.save();
  }

  async findAll(): Promise<Cat[]> {
    return this.catModel.find().exec();
  }
}
```

```typescript

import { Model } from 'mongoose';
import { Injectable, Dependencies } from '@nestjs/common';
import { getModelToken } from '@nestjs/mongoose';
import { Cat } from './schemas/cat.schema';

@Injectable()
@Dependencies(getModelToken(Cat.name))
export class CatsService {
  constructor(catModel) {
    this.catModel = catModel;
  }

  async create(createCatDto) {
    const createdCat = new this.catModel(createCatDto);
    return createdCat.save();
  }

  async findAll() {
    return this.catModel.find().exec();
  }
}
```

#### Connection[#](/techniques/mongodb#connection)

At times you may need to access the native [Mongoose Connection](https://mongoosejs.com/docs/api.html#Connection) object. For example, you may want to make native API calls on the connection object. You can inject the Mongoose Connection by using the `@InjectConnection()` decorator as follows:

```typescript

import { Injectable } from '@nestjs/common';
import { InjectConnection } from '@nestjs/mongoose';
import { Connection } from 'mongoose';

@Injectable()
export class CatsService {
  constructor(@InjectConnection() private connection: Connection) {}
}
```

#### Sessions[#](/techniques/mongodb#sessions)

To start a session with Mongoose, it's recommended to inject the database connection using `@InjectConnection` rather than calling `mongoose.startSession()` directly. This approach allows better integration with the NestJS dependency injection system, ensuring proper connection management.

Here's an example of how to start a session:

```typescript

import { InjectConnection } from '@nestjs/mongoose';
import { Connection } from 'mongoose';

@Injectable()
export class CatsService {
  constructor(@InjectConnection() private readonly connection: Connection) {}

  async startTransaction() {
    const session = await this.connection.startSession();
    session.startTransaction();
    // Your transaction logic here
  }
}
```

In this example, `@InjectConnection()` is used to inject the Mongoose connection into the service. Once the connection is injected, you can use `connection.startSession()` to begin a new session. This session can be used to manage database transactions, ensuring atomic operations across multiple queries. After starting the session, remember to commit or abort the transaction based on your logic.

#### Multiple databases[#](/techniques/mongodb#multiple-databases)

Some projects require multiple database connections. This can also be achieved with this module. To work with multiple connections, first create the connections. In this case, connection naming becomes **mandatory**.

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';

@Module({
  imports: [
    MongooseModule.forRoot('mongodb://localhost/test', {
      connectionName: 'cats',
    }),
    MongooseModule.forRoot('mongodb://localhost/users', {
      connectionName: 'users',
    }),
  ],
})
export class AppModule {}
```

> **Notice** Please note that you shouldn't have multiple connections without a name, or with the same name, otherwise they will get overridden.

With this setup, you have to tell the `MongooseModule.forFeature()` function which connection should be used.

```typescript

@Module({
  imports: [
    MongooseModule.forFeature([{ name: Cat.name, schema: CatSchema }], 'cats'),
  ],
})
export class CatsModule {}
```

You can also inject the `Connection` for a given connection:

```typescript

import { Injectable } from '@nestjs/common';
import { InjectConnection } from '@nestjs/mongoose';
import { Connection } from 'mongoose';

@Injectable()
export class CatsService {
  constructor(@InjectConnection('cats') private connection: Connection) {}
}
```

To inject a given `Connection` to a custom provider (for example, factory provider), use the `getConnectionToken()` function passing the name of the connection as an argument.

```typescript

{
  provide: CatsService,
  useFactory: (catsConnection: Connection) => {
    return new CatsService(catsConnection);
  },
  inject: [getConnectionToken('cats')],
}
```

If you are just looking to inject the model from a named database, you can use the connection name as a second parameter to the `@InjectModel()` decorator.

cats.service.ts

JS TS

```typescript

@Injectable()
export class CatsService {
  constructor(@InjectModel(Cat.name, 'cats') private catModel: Model<Cat>) {}
}
```

```typescript

@Injectable()
@Dependencies(getModelToken(Cat.name, 'cats'))
export class CatsService {
  constructor(catModel) {
    this.catModel = catModel;
  }
}
```

#### Hooks (middleware)[#](/techniques/mongodb#hooks-middleware)

Middleware (also called pre and post hooks) are functions which are passed control during execution of asynchronous functions. Middleware is specified on the schema level and is useful for writing plugins ([source](https://mongoosejs.com/docs/middleware.html)). Calling `pre()` or `post()` after compiling a model does not work in Mongoose. To register a hook **before** model registration, use the `forFeatureAsync()` method of the `MongooseModule` along with a factory provider (i.e., `useFactory`). With this technique, you can access a schema object, then use the `pre()` or `post()` method to register a hook on that schema. See example below:

```typescript

@Module({
  imports: [
    MongooseModule.forFeatureAsync([
      {
        name: Cat.name,
        useFactory: () => {
          const schema = CatsSchema;
          schema.pre('save', function () {
            console.log('Hello from pre save');
          });
          return schema;
        },
      },
    ]),
  ],
})
export class AppModule {}
```

Like other [factory providers](https://docs.nestjs.com/fundamentals/custom-providers#factory-providers-usefactory), our factory function can be `async` and can inject dependencies through `inject`.

```typescript

@Module({
  imports: [
    MongooseModule.forFeatureAsync([
      {
        name: Cat.name,
        imports: [ConfigModule],
        useFactory: (configService: ConfigService) => {
          const schema = CatsSchema;
          schema.pre('save', function() {
            console.log(
              `${configService.get('APP_NAME')}: Hello from pre save`,
            ),
          });
          return schema;
        },
        inject: [ConfigService],
      },
    ]),
  ],
})
export class AppModule {}
```

#### Plugins[#](/techniques/mongodb#plugins)

To register a [plugin](https://mongoosejs.com/docs/plugins.html) for a given schema, use the `forFeatureAsync()` method.

```typescript

@Module({
  imports: [
    MongooseModule.forFeatureAsync([
      {
        name: Cat.name,
        useFactory: () => {
          const schema = CatsSchema;
          schema.plugin(require('mongoose-autopopulate'));
          return schema;
        },
      },
    ]),
  ],
})
export class AppModule {}
```

To register a plugin for all schemas at once, call the `.plugin()` method of the `Connection` object. You should access the connection before models are created; to do this, use the `connectionFactory`:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';

@Module({
  imports: [
    MongooseModule.forRoot('mongodb://localhost/test', {
      connectionFactory: (connection) => {
        connection.plugin(require('mongoose-autopopulate'));
        return connection;
      }
    }),
  ],
})
export class AppModule {}
```

#### Discriminators[#](/techniques/mongodb#discriminators)

[Discriminators](https://mongoosejs.com/docs/discriminators.html) are a schema inheritance mechanism. They enable you to have multiple models with overlapping schemas on top of the same underlying MongoDB collection.

Suppose you wanted to track different types of events in a single collection. Every event will have a timestamp.

event.schema.ts

JS TS

```typescript

@Schema({ discriminatorKey: 'kind' })
export class Event {
  @Prop({
    type: String,
    required: true,
    enum: [ClickedLinkEvent.name, SignUpEvent.name],
  })
  kind: string;

  @Prop({ type: Date, required: true })
  time: Date;
}

export const EventSchema = SchemaFactory.createForClass(Event);
```

> **Hint** The way mongoose tells the difference between the different discriminator models is by the "discriminator key", which is `__t` by default. Mongoose adds a String path called `__t` to your schemas that it uses to track which discriminator this document is an instance of. You may also use the `discriminatorKey` option to define the path for discrimination.

`SignedUpEvent` and `ClickedLinkEvent` instances will be stored in the same collection as generic events.

Now, let's define the `ClickedLinkEvent` class, as follows:

click-link-event.schema.ts

JS TS

```typescript

@Schema()
export class ClickedLinkEvent {
  kind: string;
  time: Date;

  @Prop({ type: String, required: true })
  url: string;
}

export const ClickedLinkEventSchema = SchemaFactory.createForClass(ClickedLinkEvent);
```

And `SignUpEvent` class:

sign-up-event.schema.ts

JS TS

```typescript

@Schema()
export class SignUpEvent {
  kind: string;
  time: Date;

  @Prop({ type: String, required: true })
  user: string;
}

export const SignUpEventSchema = SchemaFactory.createForClass(SignUpEvent);
```

With this in place, use the `discriminators` option to register a discriminator for a given schema. It works on both `MongooseModule.forFeature` and `MongooseModule.forFeatureAsync`:

event.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';

@Module({
  imports: [
    MongooseModule.forFeature([
      {
        name: Event.name,
        schema: EventSchema,
        discriminators: [
          { name: ClickedLinkEvent.name, schema: ClickedLinkEventSchema },
          { name: SignUpEvent.name, schema: SignUpEventSchema },
        ],
      },
    ]),
  ]
})
export class EventsModule {}
```

#### Testing[#](/techniques/mongodb#testing)

When unit testing an application, we usually want to avoid any database connection, making our test suites simpler to set up and faster to execute. But our classes might depend on models that are pulled from the connection instance. How do we resolve these classes? The solution is to create mock models.

To make this easier, the `@nestjs/mongoose` package exposes a `getModelToken()` function that returns a prepared [injection token](https://docs.nestjs.com/fundamentals/custom-providers#di-fundamentals) based on a token name. Using this token, you can easily provide a mock implementation using any of the standard [custom provider](/v10/fundamentals/custom-providers) techniques, including `useClass`, `useValue`, and `useFactory`. For example:

```typescript

@Module({
  providers: [
    CatsService,
    {
      provide: getModelToken(Cat.name),
      useValue: catModel,
    },
  ],
})
export class CatsModule {}
```

```typescript

MongooseModule.forRootAsync({
  useFactory: () => ({
    uri: 'mongodb://localhost/nest',
  }),
});
```

Like other [factory providers](https://docs.nestjs.com/fundamentals/custom-providers#factory-providers-usefactory), our factory function can be `async` and can inject dependencies through `inject`.

```typescript

MongooseModule.forRootAsync({
  imports: [ConfigModule],
  useFactory: async (configService: ConfigService) => ({
    uri: configService.get<string>('MONGODB_URI'),
  }),
  inject: [ConfigService],
});
```

Alternatively, you can configure the `MongooseModule` using a class instead of a factory, as shown below:

```typescript

MongooseModule.forRootAsync({
  useClass: MongooseConfigService,
});
```

The construction above instantiates `MongooseConfigService` inside `MongooseModule`, using it to create the required options object. Note that in this example, the `MongooseConfigService` has to implement the `MongooseOptionsFactory` interface, as shown below. The `MongooseModule` will call the `createMongooseOptions()` method on the instantiated object of the supplied class.

```typescript

@Injectable()
export class MongooseConfigService implements MongooseOptionsFactory {
  createMongooseOptions(): MongooseModuleOptions {
    return {
      uri: 'mongodb://localhost/nest',
    };
  }
}
```

If you want to reuse an existing options provider instead of creating a private copy inside the `MongooseModule`, use the `useExisting` syntax.

```typescript

MongooseModule.forRootAsync({
  imports: [ConfigModule],
  useExisting: ConfigService,
});
```

#### Connection events[#](/techniques/mongodb#connection-events)

You can listen to Mongoose [connection events](https://mongoosejs.com/docs/connections.html#connection-events) by using the `onConnectionCreate` configuration option. This allows you to implement custom logic whenever a connection is established. For instance, you can register event listeners for the `connected`, `open`, `disconnected`, `reconnected`, and `disconnecting` events, as demonstrated below:

```typescript

MongooseModule.forRoot('mongodb://localhost/test', {
  onConnectionCreate: (connection: Connection) => {
    connection.on('connected', () => console.log('connected'));
    connection.on('open', () => console.log('open'));
    connection.on('disconnected', () => console.log('disconnected'));
    connection.on('reconnected', () => console.log('reconnected'));
    connection.on('disconnecting', () => console.log('disconnecting'));

    return connection;
  },
}),
```

```typescript

MongooseModule.forRootAsync({
  useFactory: () => ({
    uri: 'mongodb://localhost/test',
    onConnectionCreate: (connection: Connection) => {
      // Register event listeners here
      return connection;
    },
  }),
}),
```

This provides a flexible way to manage connection events, enabling you to handle changes in connection status effectively.

#### Subdocuments[#](/techniques/mongodb#subdocuments)

To nest subdocuments within a parent document, you can define your schemas as follows:

name.schema.ts

JS TS

```typescript

@Schema()
export class Name {
  @Prop()
  firstName: string;

  @Prop()
  lastName: string;
}

export const NameSchema = SchemaFactory.createForClass(Name);
```

And then reference the subdocument in the parent schema:

person.schema.ts

JS TS

```typescript

@Schema()
export class Person {
  @Prop(NameSchema)
  name: Name;
}

export const PersonSchema = SchemaFactory.createForClass(Person);

export type PersonDocumentOverride = {
  name: Types.Subdocument<Types.ObjectId & Name>;
};

export type PersonDocument = HydratedDocument<Person, PersonDocumentOverride>;
```

If you want to include multiple subdocuments, you can use an array of subdocuments. It's important to override the type of the property accordingly:

name.schema.ts

JS TS

```typescript

@Schema()
export class Person {
  @Prop([NameSchema])
  name: Name[];
}

export const PersonSchema = SchemaFactory.createForClass(Person);

export type PersonDocumentOverride = {
  name: Types.DocumentArray<Name>;
};

export type PersonDocument = HydratedDocument<Person, PersonDocumentOverride>;
```

#### Virtuals[#](/techniques/mongodb#virtuals)

In Mongoose, a **virtual** is a property that exists on a document but is not persisted to MongoDB. It is not stored in the database but is computed dynamically whenever it's accessed. Virtuals are typically used for derived or computed values, like combining fields (e.g., creating a `fullName` property by concatenating `firstName` and `lastName`), or for creating properties that rely on existing data in the document.

```ts

class Person {
  @Prop()
  firstName: string;

  @Prop()
  lastName: string;

  @Virtual({
    get: function (this: Person) {
      return `${this.firstName} ${this.lastName}`;
    },
  })
  fullName: string;
}
```

> **Hint** The `@Virtual()` decorator is imported from the `@nestjs/mongoose` package.

In this example, the `fullName` virtual is derived from `firstName` and `lastName`. Even though it behaves like a normal property when accessed, it’s never saved to the MongoDB document.:

#### Example[#](/techniques/mongodb#example)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/06-mongoose).

----
url: https://docs.nestjs.com/v8/techniques/session
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Session](https://docs.nestjs.com/v8/techniques/session#session)
* [Use with Express (default)](https://docs.nestjs.com/v8/techniques/session#use-with-express-default)
* [Use with Fastify](https://docs.nestjs.com/v8/techniques/session#use-with-fastify)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/techniques/sessions.md "Suggest Edits")

### Session

**HTTP sessions** provide a way to store information about the user across multiple requests, which is particularly useful for [MVC](/v8/techniques/mvc) applications.

#### Use with Express (default)[#](/techniques/session#use-with-express-default)

First install the [required package](https://github.com/expressjs/session) (and its types for TypeScript users):

```shell

$ npm i express-session
$ npm i -D @types/express-session
```

Once the installation is complete, apply the `express-session` middleware as global middleware (for example, in your `main.ts` file).

```typescript

import * as session from 'express-session';
// somewhere in your initialization file
app.use(
  session({
    secret: 'my-secret',
    resave: false,
    saveUninitialized: false,
  }),
);
```

> **Notice** The default server-side session storage is purposely not designed for a production environment. It will leak memory under most conditions, does not scale past a single process, and is meant for debugging and developing. Read more in the [official repository](https://github.com/expressjs/session).

The `secret` is used to sign the session ID cookie. This can be either a string for a single secret, or an array of multiple secrets. If an array of secrets is provided, only the first element will be used to sign the session ID cookie, while all the elements will be considered when verifying the signature in requests. The secret itself should be not easily parsed by a human and would best be a random set of characters.

Enabling the `resave` option forces the session to be saved back to the session store, even if the session was never modified during the request. The default value is `true`, but using the default has been deprecated, as the default will change in the future.

Likewise, enabling the `saveUninitialized` option Forces a session that is "uninitialized" to be saved to the store. A session is uninitialized when it is new but not modified. Choosing `false` is useful for implementing login sessions, reducing server storage usage, or complying with laws that require permission before setting a cookie. Choosing `false` will also help with race conditions where a client makes multiple parallel requests without a session ([source](https://github.com/expressjs/session#saveuninitialized)).

You can pass several other options to the `session` middleware, read more about them in the [API documentation](https://github.com/expressjs/session#options).

> **Hint** Please note that `secure: true` is a recommended option. However, it requires an https-enabled website, i.e., HTTPS is necessary for secure cookies. If secure is set, and you access your site over HTTP, the cookie will not be set. If you have your node.js behind a proxy and are using `secure: true`, you need to set `"trust proxy"` in express.

With this in place, you can now set and read session values from within the route handlers, as follows:

```typescript

@Get()
findAll(@Req() request: Request) {
  request.session.visits = request.session.visits ? request.session.visits + 1 : 1;
}
```

> **Hint** The `@Req()` decorator is imported from the `@nestjs/common`, while `Request` from the `express` package.

Alternatively, you can use the `@Session()` decorator to extract a session object from the request, as follows:

```typescript

@Get()
findAll(@Session() session: Record<string, any>) {
  session.visits = session.visits ? session.visits + 1 : 1;
}
```

> **Hint** The `@Session()` decorator is imported from the `@nestjs/common` package.

#### Use with Fastify[#](/techniques/session#use-with-fastify)

First install the required package:

```shell

$ npm i fastify-secure-session
```

Once the installation is complete, register the `fastify-secure-session` plugin:

```typescript

import secureSession from 'fastify-secure-session';

// somewhere in your initialization file
const app = await NestFactory.create<NestFastifyApplication>(
  AppModule,
  new FastifyAdapter(),
);
await app.register(secureSession, {
  secret: 'averylogphrasebiggerthanthirtytwochars',
  salt: 'mq9hDxBVDbspDR6n',
});
```

> **Hint** You can also pregenerate a key ([see instructions](https://github.com/fastify/fastify-secure-session)) or use [keys rotation](https://github.com/fastify/fastify-secure-session#using-keys-with-key-rotation).

Read more about the available options in the [official repository](https://github.com/fastify/fastify-secure-session).

With this in place, you can now set and read session values from within the route handlers, as follows:

```typescript

@Get()
findAll(@Req() request: FastifyRequest) {
  const visits = request.session.get('visits');
  request.session.set('visits', visits ? visits + 1 : 1);
}
```

Alternatively, you can use the `@Session()` decorator to extract a session object from the request, as follows:

```typescript

@Get()
findAll(@Session() session: secureSession.Session) {
  const visits = session.get('visits');
  session.set('visits', visits ? visits + 1 : 1);
}
```

> **Hint** The `@Session()` decorator is imported from the `@nestjs/common`, while `secureSession.Session` from the `fastify-secure-session` package (import statement: `import * as secureSession from 'fastify-secure-session'`).

----
url: https://docs.nestjs.com/v9/graphql/federation
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Federation](https://docs.nestjs.com/v9/graphql/federation#federation)
* [Federation with Apollo](https://docs.nestjs.com/v9/graphql/federation#federation-with-apollo)
* [Schema first](https://docs.nestjs.com/v9/graphql/federation#schema-first)
* [Code first](https://docs.nestjs.com/v9/graphql/federation#code-first)
* [Federated example: Posts](https://docs.nestjs.com/v9/graphql/federation#federated-example-posts)
* [Schema first](https://docs.nestjs.com/v9/graphql/federation#schema-first-1)
* [Code first](https://docs.nestjs.com/v9/graphql/federation#code-first-1)
* [Federated example: Gateway](https://docs.nestjs.com/v9/graphql/federation#federated-example-gateway)
* [Federation with Mercurius](https://docs.nestjs.com/v9/graphql/federation#federation-with-mercurius)
* [Schema first](https://docs.nestjs.com/v9/graphql/federation#schema-first-2)
* [Code first](https://docs.nestjs.com/v9/graphql/federation#code-first-2)
* [Federated example: Posts](https://docs.nestjs.com/v9/graphql/federation#federated-example-posts-1)
* [Schema first](https://docs.nestjs.com/v9/graphql/federation#schema-first-3)
* [Code first](https://docs.nestjs.com/v9/graphql/federation#code-first-3)
* [Federated example: Gateway](https://docs.nestjs.com/v9/graphql/federation#federated-example-gateway-1)
* [Federation 2](https://docs.nestjs.com/v9/graphql/federation#federation-2)
* [Federated example: Users](https://docs.nestjs.com/v9/graphql/federation#federated-example-users)
* [Schema first](https://docs.nestjs.com/v9/graphql/federation#schema-first-4)
* [Code first](https://docs.nestjs.com/v9/graphql/federation#code-first-4)
* [Federated example: Posts](https://docs.nestjs.com/v9/graphql/federation#federated-example-posts-2)
* [Schema first](https://docs.nestjs.com/v9/graphql/federation#schema-first-5)
* [Code first](https://docs.nestjs.com/v9/graphql/federation#code-first-5)

> **Warning** Federation currently does not support subscriptions.

In the following sections, we'll set up a demo application that consists of a gateway and two federated endpoints: Users service and Posts service.

#### Federation with Apollo[#](/graphql/federation#federation-with-apollo)

Start by installing the required dependencies:

```bash

$ npm install --save @apollo/federation @apollo/subgraph
```

#### Schema first[#](/graphql/federation#schema-first)

The "User service" provides a simple schema. Note the `@key` directive: it instructs the Apollo query planner that a particular instance of `User` can be fetched if you specify its `id`. Also, note that we `extend` the `Query` type.

```graphql

type User @key(fields: "id") {
  id: ID!
  name: String!
}

extend type Query {
  getUser(id: ID!): User
}
```

Resolver provides one additional method named `resolveReference()`. This method is triggered by the Apollo Gateway whenever a related resource requires a User instance. We'll see an example of this in the Posts service later. Please note that the method must be annotated with the `@ResolveReference()` decorator.

```typescript

import { Args, Query, Resolver, ResolveReference } from '@nestjs/graphql';
import { UsersService } from './users.service';

@Resolver('User')
export class UsersResolver {
  constructor(private usersService: UsersService) {}

  @Query()
  getUser(@Args('id') id: string) {
    return this.usersService.findById(id);
  }

  @ResolveReference()
  resolveReference(reference: { __typename: string; id: string }) {
    return this.usersService.findById(reference.id);
  }
}
```

Finally, we hook everything up by registering the `GraphQLModule` passing the `ApolloFederationDriver` driver in the configuration object:

```typescript

import {
  ApolloFederationDriver,
  ApolloFederationDriverConfig,
} from '@nestjs/apollo';
import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';
import { UsersResolver } from './users.resolver';

@Module({
  imports: [
    GraphQLModule.forRoot<ApolloFederationDriverConfig>({
      driver: ApolloFederationDriver,
      typePaths: ['**/*.graphql'],
    }),
  ],
  providers: [UsersResolver],
})
export class AppModule {}
```

#### Code first[#](/graphql/federation#code-first)

Start by adding some extra decorators to the `User` entity.

```ts

import { Directive, Field, ID, ObjectType } from '@nestjs/graphql';

@ObjectType()
@Directive('@key(fields: "id")')
export class User {
  @Field((type) => ID)
  id: number;

  @Field()
  name: string;
}
```

Resolver provides one additional method named `resolveReference()`. This method is triggered by the Apollo Gateway whenever a related resource requires a User instance. We'll see an example of this in the Posts service later. Please note that the method must be annotated with the `@ResolveReference()` decorator.

```ts

import { Args, Query, Resolver, ResolveReference } from '@nestjs/graphql';
import { User } from './user.entity';
import { UsersService } from './users.service';

@Resolver((of) => User)
export class UsersResolver {
  constructor(private usersService: UsersService) {}

  @Query((returns) => User)
  getUser(@Args('id') id: number): User {
    return this.usersService.findById(id);
  }

  @ResolveReference()
  resolveReference(reference: { __typename: string; id: number }): User {
    return this.usersService.findById(reference.id);
  }
}
```

Finally, we hook everything up by registering the `GraphQLModule` passing the `ApolloFederationDriver` driver in the configuration object:

```typescript

import {
  ApolloFederationDriver,
  ApolloFederationDriverConfig,
} from '@nestjs/apollo';
import { Module } from '@nestjs/common';
import { UsersResolver } from './users.resolver';
import { UsersService } from './users.service'; // Not included in this example

@Module({
  imports: [
    GraphQLModule.forRoot<ApolloFederationDriverConfig>({
      driver: ApolloFederationDriver,
      autoSchemaFile: true,
    }),
  ],
  providers: [UsersResolver, UsersService],
})
export class AppModule {}
```

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/31-graphql-federation-code-first/users-application) in code first mode and [here](https://github.com/nestjs/nest/tree/master/sample/32-graphql-federation-schema-first/users-application) in schema first mode.

#### Federated example: Posts[#](/graphql/federation#federated-example-posts)

Post service is supposed to serve aggregated posts through the `getPosts` query, but also extend our `User` type with the `user.posts` field.

#### Schema first[#](/graphql/federation#schema-first-1)

"Posts service" references the `User` type in its schema by marking it with the `extend` keyword. It also declares one additional property on the `User` type (`posts`). Note the `@key` directive used for matching instances of User, and the `@external` directive indicating that the `id` field is managed elsewhere.

```graphql

type Post @key(fields: "id") {
  id: ID!
  title: String!
  body: String!
  user: User
}

extend type User @key(fields: "id") {
  id: ID! @external
  posts: [Post]
}

extend type Query {
  getPosts: [Post]
}
```

In the following example, the `PostsResolver` provides the `getUser()` method that returns a reference containing `__typename` and some additional properties your application may need to resolve the reference, in this case `id`. `__typename` is used by the GraphQL Gateway to pinpoint the microservice responsible for the User type and retrieve the corresponding instance. The "Users service" described above will be requested upon execution of the `resolveReference()` method.

```typescript

import { Query, Resolver, Parent, ResolveField } from '@nestjs/graphql';
import { PostsService } from './posts.service';
import { Post } from './posts.interfaces';

@Resolver('Post')
export class PostsResolver {
  constructor(private postsService: PostsService) {}

  @Query('getPosts')
  getPosts() {
    return this.postsService.findAll();
  }

  @ResolveField('user')
  getUser(@Parent() post: Post) {
    return { __typename: 'User', id: post.userId };
  }
}
```

Lastly, we must register the `GraphQLModule`, similarly to what we did in the "Users service" section.

```typescript

import {
  ApolloFederationDriver,
  ApolloFederationDriverConfig,
} from '@nestjs/apollo';
import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';
import { PostsResolver } from './posts.resolver';

@Module({
  imports: [
    GraphQLModule.forRoot<ApolloFederationDriverConfig>({
      driver: ApolloFederationDriver,
      typePaths: ['**/*.graphql'],
    }),
  ],
  providers: [PostsResolvers],
})
export class AppModule {}
```

#### Code first[#](/graphql/federation#code-first-1)

First, we will have to declare a class representing the `User` entity. Although the entity itself lives in another service, we will be using it (extending its definition) here. Note the `@extends` and `@external` directives.

```ts

import { Directive, ObjectType, Field, ID } from '@nestjs/graphql';
import { Post } from './post.entity';

@ObjectType()
@Directive('@extends')
@Directive('@key(fields: "id")')
export class User {
  @Field((type) => ID)
  @Directive('@external')
  id: number;

  @Field((type) => [Post])
  posts?: Post[];
}
```

Now let's create the corresponding resolver for our extension on the `User` entity, as follows:

```ts

import { Parent, ResolveField, Resolver } from '@nestjs/graphql';
import { PostsService } from './posts.service';
import { Post } from './post.entity';
import { User } from './user.entity';

@Resolver((of) => User)
export class UsersResolver {
  constructor(private readonly postsService: PostsService) {}

  @ResolveField((of) => [Post])
  public posts(@Parent() user: User): Post[] {
    return this.postsService.forAuthor(user.id);
  }
}
```

We also have to define the `Post` entity class:

```ts

import { Directive, Field, ID, Int, ObjectType } from '@nestjs/graphql';
import { User } from './user.entity';

@ObjectType()
@Directive('@key(fields: "id")')
export class Post {
  @Field((type) => ID)
  id: number;

  @Field()
  title: string;

  @Field((type) => Int)
  authorId: number;

  @Field((type) => User)
  user?: User;
}
```

And its resolver:

```ts

import { Query, Args, ResolveField, Resolver, Parent } from '@nestjs/graphql';
import { PostsService } from './posts.service';
import { Post } from './post.entity';
import { User } from './user.entity';

@Resolver((of) => Post)
export class PostsResolver {
  constructor(private readonly postsService: PostsService) {}

  @Query((returns) => Post)
  findPost(@Args('id') id: number): Post {
    return this.postsService.findOne(id);
  }

  @Query((returns) => [Post])
  getPosts(): Post[] {
    return this.postsService.all();
  }

  @ResolveField((of) => User)
  user(@Parent() post: Post): any {
    return { __typename: 'User', id: post.authorId };
  }
}
```

And finally, tie it together in a module. Note the schema build options, where we specify that `User` is an orphaned (external) type.

```ts

import {
  ApolloFederationDriver,
  ApolloFederationDriverConfig,
} from '@nestjs/apollo';
import { Module } from '@nestjs/common';
import { User } from './user.entity';
import { PostsResolvers } from './posts.resolvers';
import { UsersResolvers } from './users.resolvers';
import { PostsService } from './posts.service'; // Not included in example

@Module({
  imports: [
    GraphQLModule.forRoot<ApolloFederationDriverConfig>({
      driver: ApolloFederationDriver,
      autoSchemaFile: true,
      buildSchemaOptions: {
        orphanedTypes: [User],
      },
    }),
  ],
  providers: [PostsResolver, UsersResolver, PostsService],
})
export class AppModule {}
```

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/31-graphql-federation-code-first/posts-application) for the code first mode and [here](https://github.com/nestjs/nest/tree/master/sample/32-graphql-federation-schema-first/posts-application) for the schema first mode.

#### Federated example: Gateway[#](/graphql/federation#federated-example-gateway)

Start by installing the required dependency:

```bash

$ npm install --save @apollo/gateway
```

The gateway requires a list of endpoints to be specified and it will auto-discover the corresponding schemas. Therefore the implementation of the gateway service will remain the same for both code and schema first approaches.

```typescript

import { IntrospectAndCompose } from '@apollo/gateway';
import { ApolloGatewayDriver, ApolloGatewayDriverConfig } from '@nestjs/apollo';
import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';

@Module({
  imports: [
    GraphQLModule.forRoot<ApolloGatewayDriverConfig>({
      driver: ApolloGatewayDriver,
      server: {
        // ... Apollo server options
        cors: true,
      },
      gateway: {
        supergraphSdl: new IntrospectAndCompose({
          subgraphs: [
            { name: 'users', url: 'http://user-service/graphql' },
            { name: 'posts', url: 'http://post-service/graphql' },
          ],
        }),
      },
    }),
  ],
})
export class AppModule {}
```

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/31-graphql-federation-code-first/gateway) for the code first mode and [here](https://github.com/nestjs/nest/tree/master/sample/32-graphql-federation-schema-first/gateway) for the schema first mode.

#### Federation with Mercurius[#](/graphql/federation#federation-with-mercurius)

Start by installing the required dependencies:

```bash

$ npm install --save @apollo/subgraph @nestjs/mercurius
```

> **Note** The `@apollo/subgraph` package is required to build a subgraph schema (`buildSubgraphSchema`, `printSubgraphSchema` functions).

#### Schema first[#](/graphql/federation#schema-first-2)

The "User service" provides a simple schema. Note the `@key` directive: it instructs the Mercurius query planner that a particular instance of `User` can be fetched if you specify its `id`. Also, note that we `extend` the `Query` type.

```graphql

type User @key(fields: "id") {
  id: ID!
  name: String!
}

extend type Query {
  getUser(id: ID!): User
}
```

Resolver provides one additional method named `resolveReference()`. This method is triggered by the Mercurius Gateway whenever a related resource requires a User instance. We'll see an example of this in the Posts service later. Please note that the method must be annotated with the `@ResolveReference()` decorator.

```typescript

import { Args, Query, Resolver, ResolveReference } from '@nestjs/graphql';
import { UsersService } from './users.service';

@Resolver('User')
export class UsersResolver {
  constructor(private usersService: UsersService) {}

  @Query()
  getUser(@Args('id') id: string) {
    return this.usersService.findById(id);
  }

  @ResolveReference()
  resolveReference(reference: { __typename: string; id: string }) {
    return this.usersService.findById(reference.id);
  }
}
```

Finally, we hook everything up by registering the `GraphQLModule` passing the `MercuriusFederationDriver` driver in the configuration object:

```typescript

import {
  MercuriusFederationDriver,
  MercuriusFederationDriverConfig,
} from '@nestjs/mercurius';
import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';
import { UsersResolver } from './users.resolver';

@Module({
  imports: [
    GraphQLModule.forRoot<MercuriusFederationDriverConfig>({
      driver: MercuriusFederationDriver,
      typePaths: ['**/*.graphql'],
      federationMetadata: true,
    }),
  ],
  providers: [UsersResolver],
})
export class AppModule {}
```

#### Code first[#](/graphql/federation#code-first-2)

Start by adding some extra decorators to the `User` entity.

```ts

import { Directive, Field, ID, ObjectType } from '@nestjs/graphql';

@ObjectType()
@Directive('@key(fields: "id")')
export class User {
  @Field((type) => ID)
  id: number;

  @Field()
  name: string;
}
```

Resolver provides one additional method named `resolveReference()`. This method is triggered by the Mercurius Gateway whenever a related resource requires a User instance. We'll see an example of this in the Posts service later. Please note that the method must be annotated with the `@ResolveReference()` decorator.

```ts

import { Args, Query, Resolver, ResolveReference } from '@nestjs/graphql';
import { User } from './user.entity';
import { UsersService } from './users.service';

@Resolver((of) => User)
export class UsersResolver {
  constructor(private usersService: UsersService) {}

  @Query((returns) => User)
  getUser(@Args('id') id: number): User {
    return this.usersService.findById(id);
  }

  @ResolveReference()
  resolveReference(reference: { __typename: string; id: number }): User {
    return this.usersService.findById(reference.id);
  }
}
```

Finally, we hook everything up by registering the `GraphQLModule` passing the `MercuriusFederationDriver` driver in the configuration object:

```typescript

import {
  MercuriusFederationDriver,
  MercuriusFederationDriverConfig,
} from '@nestjs/mercurius';
import { Module } from '@nestjs/common';
import { UsersResolver } from './users.resolver';
import { UsersService } from './users.service'; // Not included in this example

@Module({
  imports: [
    GraphQLModule.forRoot<MercuriusFederationDriverConfig>({
      driver: MercuriusFederationDriver,
      autoSchemaFile: true,
      federationMetadata: true,
    }),
  ],
  providers: [UsersResolver, UsersService],
})
export class AppModule {}
```

#### Federated example: Posts[#](/graphql/federation#federated-example-posts-1)

Post service is supposed to serve aggregated posts through the `getPosts` query, but also extend our `User` type with the `user.posts` field.

#### Schema first[#](/graphql/federation#schema-first-3)

"Posts service" references the `User` type in its schema by marking it with the `extend` keyword. It also declares one additional property on the `User` type (`posts`). Note the `@key` directive used for matching instances of User, and the `@external` directive indicating that the `id` field is managed elsewhere.

```graphql

type Post @key(fields: "id") {
  id: ID!
  title: String!
  body: String!
  user: User
}

extend type User @key(fields: "id") {
  id: ID! @external
  posts: [Post]
}

extend type Query {
  getPosts: [Post]
}
```

In the following example, the `PostsResolver` provides the `getUser()` method that returns a reference containing `__typename` and some additional properties your application may need to resolve the reference, in this case `id`. `__typename` is used by the GraphQL Gateway to pinpoint the microservice responsible for the User type and retrieve the corresponding instance. The "Users service" described above will be requested upon execution of the `resolveReference()` method.

```typescript

import { Query, Resolver, Parent, ResolveField } from '@nestjs/graphql';
import { PostsService } from './posts.service';
import { Post } from './posts.interfaces';

@Resolver('Post')
export class PostsResolver {
  constructor(private postsService: PostsService) {}

  @Query('getPosts')
  getPosts() {
    return this.postsService.findAll();
  }

  @ResolveField('user')
  getUser(@Parent() post: Post) {
    return { __typename: 'User', id: post.userId };
  }
}
```

Lastly, we must register the `GraphQLModule`, similarly to what we did in the "Users service" section.

```typescript

import {
  MercuriusFederationDriver,
  MercuriusFederationDriverConfig,
} from '@nestjs/mercurius';
import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';
import { PostsResolver } from './posts.resolver';

@Module({
  imports: [
    GraphQLModule.forRoot<MercuriusFederationDriverConfig>({
      driver: MercuriusFederationDriver,
      federationMetadata: true,
      typePaths: ['**/*.graphql'],
    }),
  ],
  providers: [PostsResolvers],
})
export class AppModule {}
```

#### Code first[#](/graphql/federation#code-first-3)

First, we will have to declare a class representing the `User` entity. Although the entity itself lives in another service, we will be using it (extending its definition) here. Note the `@extends` and `@external` directives.

```ts

import { Directive, ObjectType, Field, ID } from '@nestjs/graphql';
import { Post } from './post.entity';

@ObjectType()
@Directive('@extends')
@Directive('@key(fields: "id")')
export class User {
  @Field((type) => ID)
  @Directive('@external')
  id: number;

  @Field((type) => [Post])
  posts?: Post[];
}
```

Now let's create the corresponding resolver for our extension on the `User` entity, as follows:

```ts

import { Parent, ResolveField, Resolver } from '@nestjs/graphql';
import { PostsService } from './posts.service';
import { Post } from './post.entity';
import { User } from './user.entity';

@Resolver((of) => User)
export class UsersResolver {
  constructor(private readonly postsService: PostsService) {}

  @ResolveField((of) => [Post])
  public posts(@Parent() user: User): Post[] {
    return this.postsService.forAuthor(user.id);
  }
}
```

We also have to define the `Post` entity class:

```ts

import { Directive, Field, ID, Int, ObjectType } from '@nestjs/graphql';
import { User } from './user.entity';

@ObjectType()
@Directive('@key(fields: "id")')
export class Post {
  @Field((type) => ID)
  id: number;

  @Field()
  title: string;

  @Field((type) => Int)
  authorId: number;

  @Field((type) => User)
  user?: User;
}
```

And its resolver:

```ts

import { Query, Args, ResolveField, Resolver, Parent } from '@nestjs/graphql';
import { PostsService } from './posts.service';
import { Post } from './post.entity';
import { User } from './user.entity';

@Resolver((of) => Post)
export class PostsResolver {
  constructor(private readonly postsService: PostsService) {}

  @Query((returns) => Post)
  findPost(@Args('id') id: number): Post {
    return this.postsService.findOne(id);
  }

  @Query((returns) => [Post])
  getPosts(): Post[] {
    return this.postsService.all();
  }

  @ResolveField((of) => User)
  user(@Parent() post: Post): any {
    return { __typename: 'User', id: post.authorId };
  }
}
```

And finally, tie it together in a module. Note the schema build options, where we specify that `User` is an orphaned (external) type.

```ts

import {
  MercuriusFederationDriver,
  MercuriusFederationDriverConfig,
} from '@nestjs/mercurius';
import { Module } from '@nestjs/common';
import { User } from './user.entity';
import { PostsResolvers } from './posts.resolvers';
import { UsersResolvers } from './users.resolvers';
import { PostsService } from './posts.service'; // Not included in example

@Module({
  imports: [
    GraphQLModule.forRoot<MercuriusFederationDriverConfig>({
      driver: MercuriusFederationDriver,
      autoSchemaFile: true,
      federationMetadata: true,
      buildSchemaOptions: {
        orphanedTypes: [User],
      },
    }),
  ],
  providers: [PostsResolver, UsersResolver, PostsService],
})
export class AppModule {}
```

#### Federated example: Gateway[#](/graphql/federation#federated-example-gateway-1)

The gateway requires a list of endpoints to be specified and it will auto-discover the corresponding schemas. Therefore the implementation of the gateway service will remain the same for both code and schema first approaches.

```typescript

import {
  MercuriusGatewayDriver,
  MercuriusGatewayDriverConfig,
} from '@nestjs/mercurius';
import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';

@Module({
  imports: [
    GraphQLModule.forRoot<MercuriusGatewayDriverConfig>({
      driver: MercuriusGatewayDriver,
      gateway: {
        services: [
          { name: 'users', url: 'http://user-service/graphql' },
          { name: 'posts', url: 'http://post-service/graphql' },
        ],
      },
    }),
  ],
})
export class AppModule {}
```

### Federation 2

To quote the [Apollo docs](https://www.apollographql.com/docs/federation/federation-2/new-in-federation-2), Federation 2 improves developer experience from the original Apollo Federation (called Federation 1 in this doc), which is backward compatible with most original supergraphs.

> **Warning** Mercurius doesn't fully support Federation 2. You can see the list of libraries that support Federation 2 [here](https://www.apollographql.com/docs/federation/supported-subgraphs#javascript--typescript).

In the following sections, we'll upgrade the previous example to Federation 2.

#### Federated example: Users[#](/graphql/federation#federated-example-users)

One change in Federation 2 is that entities have no originating subgraph, so we don't need to extend `Query` anymore. For more detail please refer to [the entities topic](https://www.apollographql.com/docs/federation/federation-2/new-in-federation-2#entities) in Apollo Federation 2 docs.

#### Schema first[#](/graphql/federation#schema-first-4)

We can simply remove `extend` keyword from the schema.

```graphql

type User @key(fields: "id") {
  id: ID!
  name: String!
}

type Query {
  getUser(id: ID!): User
}
```

#### Code first[#](/graphql/federation#code-first-4)

To use Federation 2, we need to specify the federation version in `autoSchemaFile` option.

```ts

import {
  ApolloFederationDriver,
  ApolloFederationDriverConfig,
} from '@nestjs/apollo';
import { Module } from '@nestjs/common';
import { UsersResolver } from './users.resolver';
import { UsersService } from './users.service'; // Not included in this example

@Module({
  imports: [
    GraphQLModule.forRoot<ApolloFederationDriverConfig>({
      driver: ApolloFederationDriver,
      autoSchemaFile: {
        federation: 2,
      },
    }),
  ],
  providers: [UsersResolver, UsersService],
})
export class AppModule {}
```

#### Federated example: Posts[#](/graphql/federation#federated-example-posts-2)

With the same reason as above, we don't need to extend `User` and `Query` anymore.

#### Schema first[#](/graphql/federation#schema-first-5)

We can simply remove `extend` and `external` directives from the schema

```graphql

type Post @key(fields: "id") {
  id: ID!
  title: String!
  body: String!
  user: User
}

type User @key(fields: "id") {
  id: ID!
  posts: [Post]
}

type Query {
  getPosts: [Post]
}
```

#### Code first[#](/graphql/federation#code-first-5)

Since we don't extend `User` entity anymore, we can simply remove `extends` and `external` directives from `User`.

```ts

import { Directive, ObjectType, Field, ID } from '@nestjs/graphql';
import { Post } from './post.entity';

@ObjectType()
@Directive('@key(fields: "id")')
export class User {
  @Field((type) => ID)
  id: number;

  @Field((type) => [Post])
  posts?: Post[];
}
```

Also, similarly to the User service, we need to specify in the `GraphQLModule` to use Federation 2.

```ts

import {
  ApolloFederationDriver,
  ApolloFederationDriverConfig,
} from '@nestjs/apollo';
import { Module } from '@nestjs/common';
import { User } from './user.entity';
import { PostsResolvers } from './posts.resolvers';
import { UsersResolvers } from './users.resolvers';
import { PostsService } from './posts.service'; // Not included in example

@Module({
  imports: [
    GraphQLModule.forRoot<ApolloFederationDriverConfig>({
      driver: ApolloFederationDriver,
      autoSchemaFile: {
        federation: 2,
      },
      buildSchemaOptions: {
        orphanedTypes: [User],
      },
    }),
  ],
  providers: [PostsResolver, UsersResolver, PostsService],
})
export class AppModule {}
```

----
url: https://docs.nestjs.com/v7/first-steps
----

* [First steps](https://docs.nestjs.com/v7/first-steps#first-steps)
* [Language](https://docs.nestjs.com/v7/first-steps#language)
* [Prerequisites](https://docs.nestjs.com/v7/first-steps#prerequisites)
* [Setup](https://docs.nestjs.com/v7/first-steps#setup)
* [Platform](https://docs.nestjs.com/v7/first-steps#platform)
* [Running the application](https://docs.nestjs.com/v7/first-steps#running-the-application)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/first-steps.md "Suggest Edits")

Setting up a new project is quite simple with the [Nest CLI](/v7/cli/overview). With [npm](https://www.npmjs.com/) installed, you can create a new Nest project with the following commands in your OS terminal:

```bash

$ npm i -g @nestjs/cli
$ nest new project-name
```

The `project` directory will be created, node modules and a few other boilerplate files will be installed, and a `src/` directory will be created and populated with several core files.

src

app.controller.ts

app.controller.spec.ts

app.module.ts

app.service.ts

main.ts

Here's a brief overview of those core files:

| `app.controller.ts`      | A basic controller with a single route.                                                                             |
| ------------------------ | ------------------------------------------------------------------------------------------------------------------- |
| `app.controller.spec.ts` | The unit tests for the controller.                                                                                  |
| `app.module.ts`          | The root module of the application.                                                                                 |
| `app.service.ts`         | A basic service with a single method.                                                                               |
| `main.ts`                | The entry file of the application which uses the core function `NestFactory` to create a Nest application instance. |

The `main.ts` includes an async function, which will **bootstrap** our application:

main.ts

JS TS

```typescript

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  await app.listen(3000);
}
bootstrap();
```

```typescript

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  await app.listen(3000);
}
bootstrap();
```

To create a Nest application instance, we use the core `NestFactory` class. `NestFactory` exposes a few static methods that allow creating an application instance. The `create()` method returns an application object, which fulfills the `INestApplication` interface. This object provides a set of methods which are described in the coming chapters. In the `main.ts` example above, we simply start up our HTTP listener, which lets the application await inbound HTTP requests.

Note that a project scaffolded with the Nest CLI creates an initial project structure that encourages developers to follow the convention of keeping each module in its own dedicated directory.

| `platform-express` | [Express](https://expressjs.com/) is a well-known minimalist web framework for node. It's a battle tested, production-ready library with lots of resources implemented by the community. The `@nestjs/platform-express` package is used by default. Many users are well served with Express, and need take no action to enable it. |
| ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `platform-fastify` | [Fastify](https://www.fastify.io/) is a high performance and low overhead framework highly focused on providing maximum efficiency and speed. Read how to use it [here](/v7/techniques/performance).                                                                                                                               |

Whichever platform is used, it exposes its own application interface. These are seen respectively as `NestExpressApplication` and `NestFastifyApplication`.

When you pass a type to the `NestFactory.create()` method, as in the example below, the `app` object will have methods available exclusively for that specific platform. Note, however, you don't **need** to specify a type **unless** you actually want to access the underlying platform API.

```typescript

const app = await NestFactory.create<NestExpressApplication>(AppModule);
```

#### Running the application[#](/first-steps#running-the-application)

Once the installation process is complete, you can run the following command at your OS command prompt to start the application listening for inbound HTTP requests:

```bash

$ npm run start
```

This command starts the app with the HTTP server listening on the port defined in the `src/main.ts` file. Once the application is running, open your browser and navigate to `http://localhost:3000/`. You should see the `Hello World!` message.

----
url: https://docs.nestjs.com/v5/graphql/scalars
----

### Scalars

In order to define a custom scalar (read more about scalars [here](https://www.apollographql.com/docs/graphql-tools/scalars.html)), we have to create a type definition and a dedicated resolver as well. Here (as in the official documentation), we’ll take the `graphql-type-json` package for demonstration purposes. This npm package defines a `JSON` GraphQL scalar type. Firstly, let's install the package:

```bash

$ npm i --save graphql-type-json
```

Once the package is installed, we have to pass a custom resolver to the `forRoot()` method:

TypeScript

```typescript

import * as GraphQLJSON from 'graphql-type-json';

@Module({
  imports: [
    GraphQLModule.forRoot({
      typePaths: ['./**/*.graphql'],
      resolvers: { JSON: GraphQLJSON },
    }),
  ],
})
export class ApplicationModule {}
```

Now we can use `JSON` scalar in our type definitions:

Java

```java

scalar JSON

type Foo {
  field: JSON
}
```

#### Classes

Another form of defining the scalar type is to create a simple class. Let's say that we would like to enhance our schema with the `Date` type.

TypeScript

```typescript

import { Scalar } from '@nestjs/graphql';
import { Kind } from 'graphql';

@Scalar('Date')
export class DateScalar {
  description = 'Date custom scalar type';

  parseValue(value) {
    return new Date(value); // value from the client
  }

  serialize(value) {
    return value.getTime(); // value sent to the client
  }

  parseLiteral(ast) {
    if (ast.kind === Kind.INT) {
      return parseInt(ast.value, 10); // ast value is always in string format
    }
    return null;
  }
}
```

Afterward, we need to register `DateScalar` as a provider.

TypeScript

```typescript

@Module({
  providers: [DateScalar],
})
export class CommonModule {}
```

And now we are able to use `Date` scalar in our type definitions.

* Scalars
* Classes

----
url: https://docs.nestjs.com/data/mongodb
----

[Skip to content](#content)

On this page

* [Mongo](https://docs.nestjs.com/data/mongodb#mongo)
* [Model injection](https://docs.nestjs.com/data/mongodb#model-injection)
* [Connection](https://docs.nestjs.com/data/mongodb#connection)
* [Sessions](https://docs.nestjs.com/data/mongodb#sessions)
* [Multiple databases](https://docs.nestjs.com/data/mongodb#multiple-databases)
* [Hooks (middleware)](https://docs.nestjs.com/data/mongodb#hooks-middleware)
* [Plugins](https://docs.nestjs.com/data/mongodb#plugins)
* [Discriminators](https://docs.nestjs.com/data/mongodb#discriminators)
* [Testing](https://docs.nestjs.com/data/mongodb#testing)
* [Async configuration](https://docs.nestjs.com/data/mongodb#async-configuration)
* [Connection events](https://docs.nestjs.com/data/mongodb#connection-events)
* [Subdocuments](https://docs.nestjs.com/data/mongodb#subdocuments)
* [Virtuals](https://docs.nestjs.com/data/mongodb#virtuals)
* [Example](https://docs.nestjs.com/data/mongodb#example)

### Mongo

Nest supports two methods for integrating with the [MongoDB](https://www.mongodb.com/) database. You can either use the [TypeORM](https://github.com/typeorm/typeorm) module described in the [TypeORM chapter](/data/typeorm), which has a connector for MongoDB, or use [Mongoose](https://mongoosejs.com), the most popular MongoDB object modeling tool. This chapter describes the latter, using the dedicated `@nestjs/mongoose` package.

Start by installing the required dependencies:

```bash

$ npm i @nestjs/mongoose mongoose
```

Once the installation process is complete, import the `MongooseModule` into the root `AppModule`:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';

@Module({
  imports: [MongooseModule.forRoot('mongodb://localhost/nest')],
})
export class AppModule {}
```

The `forRoot()` method accepts the same configuration object as `mongoose.connect()` from the Mongoose package, as described in the [Mongoose connections guide](https://mongoosejs.com/docs/connections.html).

#### Model injection[#](/data/mongodb#model-injection)

With Mongoose, everything is derived from a [Schema](https://mongoosejs.com/docs/guide.html). Each schema maps to a MongoDB collection and defines the shape of the documents within that collection. Schemas are used to define [Models](https://mongoosejs.com/docs/models.html). Models are responsible for creating and reading documents from the underlying MongoDB database.

You can create schemas with NestJS decorators, or manually with Mongoose itself. Using decorators to create schemas greatly reduces boilerplate and improves overall code readability.

Let's define the `CatSchema`:

schemas/cat.schema.ts

JS TS

```typescript

import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
import { HydratedDocument } from 'mongoose';

export type CatDocument = HydratedDocument<Cat>;

@Schema()
export class Cat {
  @Prop()
  name: string;

  @Prop()
  age: number;

  @Prop()
  breed: string;
}

export const CatSchema = SchemaFactory.createForClass(Cat);
```

> **Hint** You can also generate a raw schema definition using the `DefinitionsFactory` class (from the `@nestjs/mongoose` package). This allows you to manually modify the schema definition generated from the metadata you provided, which is useful for edge cases where it may be hard to represent everything with decorators.

The `@Schema()` decorator marks a class as a schema definition. It maps the `Cat` class to a MongoDB collection of the same name, but with an additional "s" at the end, so the final collection name is `cats`. This decorator accepts a single optional argument, a schema options object. Think of it as the object you would normally pass as the second argument of the `mongoose.Schema` class constructor (e.g., `new mongoose.Schema(_, options)`). To learn more about the available schema options, see the [Mongoose schema options](https://mongoosejs.com/docs/guide.html#options) documentation.

The `@Prop()` decorator defines a property in the document. For example, the schema definition above defines three properties: `name`, `age`, and `breed`. The [schema types](https://mongoosejs.com/docs/schematypes.html) for these properties are automatically inferred thanks to TypeScript metadata (and reflection) capabilities. However, in more complex scenarios in which types cannot be implicitly reflected (for example, arrays or nested object structures), you must indicate the types explicitly, as follows:

```typescript

@Prop([String])
tags: string[];
```

Alternatively, the `@Prop()` decorator accepts an options object argument (read more about the [available schema type options](https://mongoosejs.com/docs/schematypes.html#schematype-options)). With it, you can indicate whether a property is required, specify a default value, or mark it as immutable. For example:

```typescript

@Prop({ required: true })
name: string;
```

To specify a relation to another model (for populating later), use the `@Prop()` decorator as well. For example, if `Cat` has an `Owner` that is stored in a different collection called `owners`, the property should have `type` and `ref` options:

```typescript

import mongoose from 'mongoose';
import { Owner } from '../owners/schemas/owner.schema.js';

// inside the class definition
@Prop({ type: mongoose.Schema.Types.ObjectId, ref: 'Owner' })
owner: Owner;
```

If there are multiple owners, your property configuration should look as follows:

```typescript

@Prop({ type: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Owner' }] })
owners: Owner[];
```

If you don't intend to always populate a reference to another collection, consider using `mongoose.Types.ObjectId` as the type instead:

```typescript

@Prop({ type: mongoose.Schema.Types.ObjectId, ref: 'Owner' })
// This ensures the field is not confused with a populated reference
owner: mongoose.Types.ObjectId;
```

Then, when you need to selectively populate it later, use a repository function that specifies the correct type:

```typescript

import { Owner } from './schemas/owner.schema.js';

// e.g. inside a service or repository
async findAllPopulated() {
  return this.catModel.find().populate<{ owner: Owner }>("owner");
}
```

> **Hint** If there is no foreign document to populate, the type could be `Owner | null`, depending on your [Mongoose configuration](https://mongoosejs.com/docs/populate.html#doc-not-found). Alternatively, it might throw an error, in which case the type is `Owner`.

Finally, you can also pass a **raw** schema definition to the decorator. This is useful when, for example, a property represents a nested object that is not defined as a class. For this, use the `raw()` function from the `@nestjs/mongoose` package, as follows:

```typescript

@Prop(raw({
  firstName: { type: String },
  lastName: { type: String }
}))
details: Record<string, any>;
```

Alternatively, if you prefer **not using decorators**, you can define a schema manually. For example:

```typescript

export const CatSchema = new mongoose.Schema({
  name: String,
  age: Number,
  breed: String,
});
```

The `cat.schema` file resides in a `schemas` folder in the `cats` directory, where the `CatsModule` is also defined. While you can store schema files wherever you prefer, we recommend storing them near their related **domain** objects, in the appropriate module directory.

Let's look at the `CatsModule`:

cats.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';
import { CatsController } from './cats.controller.js';
import { CatsService } from './cats.service.js';
import { Cat, CatSchema } from './schemas/cat.schema.js';

@Module({
  imports: [MongooseModule.forFeature([{ name: Cat.name, schema: CatSchema }])],
  controllers: [CatsController],
  providers: [CatsService],
})
export class CatsModule {}
```

The `MongooseModule` provides the `forFeature()` method to configure the module, including defining which models should be registered in the current scope. To use the models in another module as well, add `MongooseModule` to the `exports` array of `CatsModule` and import `CatsModule` in the other module.

Once you've registered the schema, you can inject a `Cat` model into the `CatsService` using the `@InjectModel()` decorator:

cats.service.ts

JS TS

```typescript

import { Model } from 'mongoose';
import { Injectable } from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import { Cat } from './schemas/cat.schema.js';
import { CreateCatDto } from './dto/create-cat.dto.js';

@Injectable()
export class CatsService {
  constructor(@InjectModel(Cat.name) private catModel: Model<Cat>) {}

  async create(createCatDto: CreateCatDto): Promise<Cat> {
    const createdCat = new this.catModel(createCatDto);
    return createdCat.save();
  }

  async findAll(): Promise<Cat[]> {
    return this.catModel.find().exec();
  }
}
```

```typescript

import { Model } from 'mongoose';
import { Injectable, Dependencies } from '@nestjs/common';
import { getModelToken } from '@nestjs/mongoose';
import { Cat } from './schemas/cat.schema.js';

@Injectable()
@Dependencies(getModelToken(Cat.name))
export class CatsService {
  constructor(catModel) {
    this.catModel = catModel;
  }

  async create(createCatDto) {
    const createdCat = new this.catModel(createCatDto);
    return createdCat.save();
  }

  async findAll() {
    return this.catModel.find().exec();
  }
}
```

#### Connection[#](/data/mongodb#connection)

At times, you may need to access the native [Mongoose Connection](https://mongoosejs.com/docs/api.html#Connection) object, for example, to make native API calls on it. Inject the Mongoose connection with the `@InjectConnection()` decorator as follows:

```typescript

import { Injectable } from '@nestjs/common';
import { InjectConnection } from '@nestjs/mongoose';
import { Connection } from 'mongoose';

@Injectable()
export class CatsService {
  constructor(@InjectConnection() private connection: Connection) {}
}
```

#### Sessions[#](/data/mongodb#sessions)

To start a session with Mongoose, inject the database connection using `@InjectConnection()` rather than calling `mongoose.startSession()` directly. This integrates with the Nest dependency injection system and ensures the session is started on the connection that Nest manages.

Here's an example of how to start a session:

```typescript

import { Injectable } from '@nestjs/common';
import { InjectConnection } from '@nestjs/mongoose';
import { Connection } from 'mongoose';

@Injectable()
export class CatsService {
  constructor(@InjectConnection() private readonly connection: Connection) {}

  async startTransaction() {
    const session = await this.connection.startSession();
    session.startTransaction();
    // Your transaction logic here
  }
}
```

In this example, `@InjectConnection()` injects the Mongoose connection into the service. You can then call `connection.startSession()` to begin a new session and use it to manage database transactions, ensuring atomic operations across multiple queries. After starting the transaction, remember to commit or abort it based on your logic, and end the session when you're done.

#### Multiple databases[#](/data/mongodb#multiple-databases)

Some projects require multiple database connections, which this module also supports. To work with multiple connections, first create the connections. In this case, naming the connections is **mandatory**.

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';

@Module({
  imports: [
    MongooseModule.forRoot('mongodb://localhost/test', {
      connectionName: 'cats',
    }),
    MongooseModule.forRoot('mongodb://localhost/users', {
      connectionName: 'users',
    }),
  ],
})
export class AppModule {}
```

> **Notice** Don't create multiple connections without a name or with the same name, otherwise they will override each other.

With this setup, you have to tell the `MongooseModule.forFeature()` method which connection to use:

```typescript

@Module({
  imports: [
    MongooseModule.forFeature([{ name: Cat.name, schema: CatSchema }], 'cats'),
  ],
})
export class CatsModule {}
```

You can also inject the `Connection` object for a given connection:

```typescript

import { Injectable } from '@nestjs/common';
import { InjectConnection } from '@nestjs/mongoose';
import { Connection } from 'mongoose';

@Injectable()
export class CatsService {
  constructor(@InjectConnection('cats') private connection: Connection) {}
}
```

To inject a given `Connection` into a custom provider (for example, a factory provider), use the `getConnectionToken()` function, passing the name of the connection as an argument:

```typescript

{
  provide: CatsService,
  useFactory: (catsConnection: Connection) => {
    return new CatsService(catsConnection);
  },
  inject: [getConnectionToken('cats')],
}
```

To inject a model from a named connection, pass the connection name as the second argument to the `@InjectModel()` decorator:

cats.service.ts

JS TS

```typescript

@Injectable()
export class CatsService {
  constructor(@InjectModel(Cat.name, 'cats') private catModel: Model<Cat>) {}
}
```

```typescript

@Injectable()
@Dependencies(getModelToken(Cat.name, 'cats'))
export class CatsService {
  constructor(catModel) {
    this.catModel = catModel;
  }
}
```

#### Hooks (middleware)[#](/data/mongodb#hooks-middleware)

Middleware (also called pre and post hooks) are functions that are passed control during the execution of asynchronous functions. Middleware is specified at the schema level and is useful for writing plugins (see the [Mongoose middleware documentation](https://mongoosejs.com/docs/middleware.html)). Calling `pre()` or `post()` after compiling a model does not work in Mongoose. To register a hook **before** model registration, use the `forFeatureAsync()` method of the `MongooseModule` along with a factory provider (i.e., `useFactory`). With this technique, you can access a schema object, then use its `pre()` or `post()` method to register a hook on that schema. For example:

```typescript

@Module({
  imports: [
    MongooseModule.forFeatureAsync([
      {
        name: Cat.name,
        useFactory: () => {
          const schema = CatSchema;
          schema.pre('save', function () {
            console.log('Hello from pre save');
          });
          return schema;
        },
      },
    ]),
  ],
})
export class AppModule {}
```

Like other [factory providers](/fundamentals/custom-providers#factory-providers-usefactory), the factory function can be `async` and can inject dependencies through `inject`.

```typescript

@Module({
  imports: [
    MongooseModule.forFeatureAsync([
      {
        name: Cat.name,
        imports: [ConfigModule],
        useFactory: (configService: ConfigService) => {
          const schema = CatSchema;
          schema.pre('save', function() {
            console.log(
              `${configService.get('APP_NAME')}: Hello from pre save`,
            );
          });
          return schema;
        },
        inject: [ConfigService],
      },
    ]),
  ],
})
export class AppModule {}
```

#### Plugins[#](/data/mongodb#plugins)

To register a [plugin](https://mongoosejs.com/docs/plugins.html) for a given schema, use the `forFeatureAsync()` method:

```typescript

import autopopulate from 'mongoose-autopopulate';

@Module({
  imports: [
    MongooseModule.forFeatureAsync([
      {
        name: Cat.name,
        useFactory: () => {
          const schema = CatSchema;
          schema.plugin(autopopulate);
          return schema;
        },
      },
    ]),
  ],
})
export class AppModule {}
```

To register a plugin for all schemas at once, call the `.plugin()` method of the `Connection` object. You must access the connection before models are created; to do this, use the `connectionFactory` option:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';
import autopopulate from 'mongoose-autopopulate';

@Module({
  imports: [
    MongooseModule.forRoot('mongodb://localhost/test', {
      connectionFactory: (connection) => {
        connection.plugin(autopopulate);
        return connection;
      }
    }),
  ],
})
export class AppModule {}
```

#### Discriminators[#](/data/mongodb#discriminators)

[Discriminators](https://mongoosejs.com/docs/discriminators.html) are a schema inheritance mechanism. They enable you to have multiple models with overlapping schemas on top of the same underlying MongoDB collection.

Suppose you want to track different types of events in a single collection. Every event has a timestamp.

event.schema.ts

JS TS

```typescript

@Schema({ discriminatorKey: 'kind' })
export class Event {
  @Prop({
    type: String,
    required: true,
    enum: [ClickedLinkEvent.name, SignUpEvent.name],
  })
  kind: string;

  @Prop({ type: Date, required: true })
  time: Date;
}

export const EventSchema = SchemaFactory.createForClass(Event);
```

> **Hint** Mongoose tells discriminator models apart by the "discriminator key", which is `__t` by default. Mongoose adds a String path called `__t` to your schemas and uses it to track which discriminator a document is an instance of. You may also use the `discriminatorKey` option to define the path for discrimination.

`SignUpEvent` and `ClickedLinkEvent` instances will be stored in the same collection as generic events.

Now, let's define the `ClickedLinkEvent` class, as follows:

click-link-event.schema.ts

JS TS

```typescript

@Schema()
export class ClickedLinkEvent {
  kind: string;
  time: Date;

  @Prop({ type: String, required: true })
  url: string;
}

export const ClickedLinkEventSchema = SchemaFactory.createForClass(ClickedLinkEvent);
```

And `SignUpEvent` class:

sign-up-event.schema.ts

JS TS

```typescript

@Schema()
export class SignUpEvent {
  kind: string;
  time: Date;

  @Prop({ type: String, required: true })
  user: string;
}

export const SignUpEventSchema = SchemaFactory.createForClass(SignUpEvent);
```

With this in place, use the `discriminators` option to register discriminators for a given schema. It works with both `MongooseModule.forFeature()` and `MongooseModule.forFeatureAsync()`:

event.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';

@Module({
  imports: [
    MongooseModule.forFeature([
      {
        name: Event.name,
        schema: EventSchema,
        discriminators: [
          { name: ClickedLinkEvent.name, schema: ClickedLinkEventSchema },
          { name: SignUpEvent.name, schema: SignUpEventSchema },
        ],
      },
    ]),
  ]
})
export class EventsModule {}
```

#### Testing[#](/data/mongodb#testing)

When unit testing an application, you usually want to avoid any database connection, which keeps test suites simpler to set up and faster to execute. However, your classes might depend on models that are pulled from the connection instance. To resolve these classes, create mock models.

To make this easier, the `@nestjs/mongoose` package exposes a `getModelToken()` function that returns a prepared [injection token](/fundamentals/custom-providers#di-fundamentals) based on a model name. Using this token, you can provide a mock implementation using any of the standard [custom provider](/fundamentals/custom-providers) techniques, including `useClass`, `useValue`, and `useFactory`. For example:

```typescript

@Module({
  providers: [
    CatsService,
    {
      provide: getModelToken(Cat.name),
      useValue: catModel,
    },
  ],
})
export class CatsModule {}
```

In this example, a hardcoded `catModel` (object instance) is provided whenever any consumer injects a `Model<Cat>` using the `@InjectModel()` decorator.

## Learn the right way!

* 80+ chapters
* 5+ hours of videos
* Official certificate
* Deep-dive sessions

[Explore official courses](https://courses.nestjs.com "Courses | NestJS - A node.js framework built on top of TypeScript")

#### Async configuration[#](/data/mongodb#async-configuration)

When you need to pass module options asynchronously instead of statically, use the `forRootAsync()` method. As with most dynamic modules, Nest provides several techniques for async configuration.

One technique is to use a factory function:

```typescript

MongooseModule.forRootAsync({
  useFactory: () => ({
    uri: 'mongodb://localhost/nest',
  }),
});
```

Like other [factory providers](/fundamentals/custom-providers#factory-providers-usefactory), the factory function can be `async` and can inject dependencies through `inject`.

```typescript

MongooseModule.forRootAsync({
  imports: [ConfigModule],
  useFactory: async (configService: ConfigService) => ({
    uri: configService.get<string>('MONGODB_URI'),
  }),
  inject: [ConfigService],
});
```

Alternatively, you can configure the `MongooseModule` using a class instead of a factory, as shown below:

```typescript

MongooseModule.forRootAsync({
  useClass: MongooseConfigService,
});
```

The construction above instantiates `MongooseConfigService` inside `MongooseModule`, using it to create the required options object. In this example, the `MongooseConfigService` has to implement the `MongooseOptionsFactory` interface, as shown below. The `MongooseModule` calls the `createMongooseOptions()` method on the instantiated object of the supplied class.

```typescript

@Injectable()
export class MongooseConfigService implements MongooseOptionsFactory {
  createMongooseOptions(): MongooseModuleOptions {
    return {
      uri: 'mongodb://localhost/nest',
    };
  }
}
```

To reuse an existing options provider instead of creating a private copy inside the `MongooseModule`, use the `useExisting` syntax. The provider must implement the `MongooseOptionsFactory` interface:

```typescript

MongooseModule.forRootAsync({
  imports: [ConfigModule],
  useExisting: ConfigService,
});
```

#### Connection events[#](/data/mongodb#connection-events)

You can listen to Mongoose [connection events](https://mongoosejs.com/docs/connections.html#connection-events) using the `onConnectionCreate` configuration option. Nest calls this function with each connection as soon as the connection is created, before it opens, so you can register listeners for the `connected`, `open`, `disconnected`, `reconnected`, and `disconnecting` events, as demonstrated below:

```typescript

MongooseModule.forRoot('mongodb://localhost/test', {
  onConnectionCreate: (connection: Connection) => {
    connection.on('connected', () => console.log('connected'));
    connection.on('open', () => console.log('open'));
    connection.on('disconnected', () => console.log('disconnected'));
    connection.on('reconnected', () => console.log('reconnected'));
    connection.on('disconnecting', () => console.log('disconnecting'));

    return connection;
  },
}),
```

This code snippet establishes a connection to a MongoDB database at `mongodb://localhost/test`. The `onConnectionCreate` option sets up event listeners for monitoring the connection's status:

* `connected`: Triggered when the connection is successfully established.
* `open`: Fires when the connection is fully opened and ready for operations.
* `disconnected`: Called when the connection is lost.
* `reconnected`: Invoked when the connection is re-established after being disconnected.
* `disconnecting`: Occurs when the connection is in the process of closing.

You can also use the `onConnectionCreate` property in async configurations created with `MongooseModule.forRootAsync()`:

```typescript

MongooseModule.forRootAsync({
  useFactory: () => ({
    uri: 'mongodb://localhost/test',
    onConnectionCreate: (connection: Connection) => {
      // Register event listeners here
      return connection;
    },
  }),
}),
```

#### Subdocuments[#](/data/mongodb#subdocuments)

To nest subdocuments within a parent document, define your schemas as follows:

name.schema.ts

JS TS

```typescript

@Schema()
export class Name {
  @Prop()
  firstName: string;

  @Prop()
  lastName: string;
}

export const NameSchema = SchemaFactory.createForClass(Name);
```

And then reference the subdocument in the parent schema:

person.schema.ts

JS TS

```typescript

@Schema()
export class Person {
  @Prop(NameSchema)
  name: Name;
}

export const PersonSchema = SchemaFactory.createForClass(Person);

export type PersonDocumentOverride = {
  name: Types.Subdocument<Types.ObjectId> & Name;
};

export type PersonDocument = HydratedDocument<Person, PersonDocumentOverride>;
```

To include multiple subdocuments, use an array of subdocuments. Make sure to override the type of the property accordingly:

person.schema.ts

JS TS

```typescript

@Schema()
export class Person {
  @Prop([NameSchema])
  name: Name[];
}

export const PersonSchema = SchemaFactory.createForClass(Person);

export type PersonDocumentOverride = {
  name: Types.DocumentArray<Name>;
};

export type PersonDocument = HydratedDocument<Person, PersonDocumentOverride>;
```

#### Virtuals[#](/data/mongodb#virtuals)

In Mongoose, a **virtual** is a property that exists on a document but is not persisted to MongoDB. Instead, it is computed dynamically whenever it's accessed. Virtuals are typically used for derived or computed values, like combining fields (e.g., creating a `fullName` property by concatenating `firstName` and `lastName`), or for creating properties that rely on existing data in the document.

```ts

class Person {
  @Prop()
  firstName: string;

  @Prop()
  lastName: string;

  @Virtual({
    get: function (this: Person) {
      return `${this.firstName} ${this.lastName}`;
    },
  })
  fullName: string;
}
```

> **Hint** The `@Virtual()` decorator is imported from the `@nestjs/mongoose` package.

In this example, the `fullName` virtual is derived from `firstName` and `lastName`. Even though it behaves like a normal property when accessed, it's never saved to the MongoDB document.

#### Example[#](/data/mongodb#example)

A working example is available in the [nestjs/nest repository](https://github.com/nestjs/nest/tree/master/sample/06-mongoose).

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/data/mongo.md)

----
url: https://docs.nestjs.com/v7/security/authorization
----

* [Authorization](https://docs.nestjs.com/v7/security/authorization#authorization)
* [Basic RBAC implementation](https://docs.nestjs.com/v7/security/authorization#basic-rbac-implementation)
* [Claims-based authorization](https://docs.nestjs.com/v7/security/authorization#claims-based-authorization)
* [Integrating CASL](https://docs.nestjs.com/v7/security/authorization#integrating-casl)
* [Advanced: Implementing a PoliciesGuard](https://docs.nestjs.com/v7/security/authorization#advanced-implementing-a-policiesguard)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/security/authorization.md "Suggest Edits")

### Authorization

**Authorization** refers to the process that determines what a user is able to do. For example, an administrative user is allowed to create, edit, and delete posts. A non-administrative user is only authorized to read the posts.

Authorization is orthogonal and independent from authentication. However, authorization requires an authentication mechanism.

There are many different approaches and strategies to handle authorization. The approach taken for any project depends on its particular application requirements. This chapter presents a few approaches to authorization that can be adapted to a variety of different requirements.

#### Basic RBAC implementation[#](/security/authorization#basic-rbac-implementation)

Role-based access control (**RBAC**) is a policy-neutral access-control mechanism defined around roles and privileges. In this section, we'll demonstrate how to implement a very basic RBAC mechanism using Nest [guards](/v7/guards).

First, let's create a `Role` enum representing roles in the system:

role.enum.ts

JS TS

```typescript

export enum Role {
  User = 'user',
  Admin = 'admin',
}
```

> **Hint** In more sophisticated systems, you may store roles within a database, or pull them from the external authentication provider.

With this in place, we can create a `@Roles()` decorator. This decorator allows specifying what roles are required to access specific resources.

roles.decorator.ts

JS TS

```typescript

import { SetMetadata } from '@nestjs/common';
import { Role } from '../enums/role.enum';

export const ROLES_KEY = 'roles';
export const Roles = (...roles: Role[]) => SetMetadata(ROLES_KEY, roles);
```

```typescript

import { SetMetadata } from '@nestjs/common';

export const ROLES_KEY = 'roles';
export const Roles = (...roles) => SetMetadata(ROLES_KEY, roles);
```

Now that we have a custom `@Roles()` decorator, we can use it to decorate any route handler.

cats.controller.ts

JS TS

```typescript

@Post()
@Roles(Role.Admin)
create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

```typescript

@Post()
@Roles(Role.Admin)
@Bind(Body())
create(createCatDto) {
  this.catsService.create(createCatDto);
}
```

Finally, we create a `RolesGuard` class which will compare the roles assigned to the current user to the actual roles required by the current route being processed. In order to access the route's role(s) (custom metadata), we'll use the `Reflector` helper class, which is provided out of the box by the framework and exposed from the `@nestjs/core` package.

roles.guard.ts

JS TS

```typescript

import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
import { Reflector } from '@nestjs/core';

@Injectable()
export class RolesGuard implements CanActivate {
  constructor(private reflector: Reflector) {}

  canActivate(context: ExecutionContext): boolean {
    const requiredRoles = this.reflector.getAllAndOverride<Role[]>(ROLES_KEY, [
      context.getHandler(),
      context.getClass(),
    ]);
    if (!requiredRoles) {
      return true;
    }
    const { user } = context.switchToHttp().getRequest();
    return requiredRoles.some((role) => user.roles?.includes(role));
  }
}
```

```typescript

import { Injectable, Dependencies } from '@nestjs/common';
import { Reflector } from '@nestjs/core';

@Injectable()
@Dependencies(Reflector)
export class RolesGuard {
  constructor(reflector) {
    this.reflector = reflector;
  }

  canActivate(context) {
    const requiredRoles = this.reflector.getAllAndOverride(ROLES_KEY, [
      context.getHandler(),
      context.getClass(),
    ]);
    if (!requiredRoles) {
      return true;
    }
    const { user } = context.switchToHttp().getRequest();
    return requiredRoles.some((role) => user.roles.includes(role));
  }
}
```

> **Hint** Refer to the [Reflection and metadata](/fundamentals/execution-context#reflection-and-metadata) section of the Execution context chapter for more details on utilizing `Reflector` in a context-sensitive way.

> **Notice** This example is named "**basic**" as we only check for the presence of roles on the route handler level. In real-world applications, you may have endpoints/handlers that involve several operations, in which each of them requires a specific set of permissions. In this case, you'll have to provide a mechanism to check roles somewhere within your business-logic, making it somewhat harder to maintain as there will be no centralized place that associates permissions with specific actions.

In this example, we assumed that `request.user` contains the user instance and allowed roles (under the `roles` property). In your app, you will probably make that association in your custom **authentication guard** - see [authentication](/v7/security/authentication) chapter for more details.

To make sure this example works, your `User` class must look as follows:

```typescript

class User {
  // ...other properties
  roles: Role[];
}
```

Lastly, make sure to register the `RolesGuard`, for example, at the controller level, or globally:

```typescript

providers: [
  {
    provide: APP_GUARD,
    useClass: RolesGuard,
  },
],
```

When a user with insufficient privileges requests an endpoint, Nest automatically returns the following response:

```typescript

{
  "statusCode": 403,
  "message": "Forbidden resource",
  "error": "Forbidden"
}
```

> **Hint** If you want to return a different error response, you should throw your own specific exception instead of returning a boolean value.

#### Claims-based authorization[#](/security/authorization#claims-based-authorization)

When an identity is created it may be assigned one or more claims issued by a trusted party. A claim is a name-value pair that represents what the subject can do, not what the subject is.

To implement a Claims-based authorization in Nest, you can follow the same steps we have shown above in the [RBAC](/security/authorization#basic-rbac-implementation) section with one significant difference: instead of checking for specific roles, you should compare **permissions**. Every user would have a set of permissions assigned. Likewise, each resource/endpoint would define what permissions are required (for example, through a dedicated `@RequirePermissions()` decorator) to access them.

cats.controller.ts

JS TS

```typescript

@Post()
@RequirePermissions(Permission.CREATE_CAT)
create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

```typescript

@Post()
@RequirePermissions(Permission.CREATE_CAT)
@Bind(Body())
create(createCatDto) {
  this.catsService.create(createCatDto);
}
```

> **Hint** In the example above, `Permission` (similar to `Role` we have shown in RBAC section) is a TypeScript enum that contains all the permissions available in your system.

#### Integrating CASL[#](/security/authorization#integrating-casl)

[CASL](https://casl.js.org/) is an isomorphic authorization library which restricts what resources a given client is allowed to access. It's designed to be incrementally adoptable and can easily scale between a simple claim based and fully featured subject and attribute based authorization.

To start, first install the `@casl/ability` package:

```bash

$ npm i @casl/ability
```

> **Hint** In this example, we chose CASL, but you can use any other library like `accesscontrol` or `acl`, depending on your preferences and project needs.

Once the installation is complete, for the sake of illustrating the mechanics of CASL, we'll define two entity classes: `User` and `Article`.

```typescript

class User {
  id: number;
  isAdmin: boolean;
}
```

`User` class consists of two properties, `id`, which is a unique user identifier, and `isAdmin`, indicating whether a user has administrator privileges.

```typescript

class Article {
  id: number;
  isPublished: boolean;
  authorId: string;
}
```

```typescript

export enum Action {
  Manage = 'manage',
  Create = 'create',
  Read = 'read',
  Update = 'update',
  Delete = 'delete',
}
```

> **Notice**`manage` is a special keyword in CASL which represents "any" action.

To encapsulate CASL library, let's generate the `CaslModule` and `CaslAbilityFactory` now.

```bash

$ nest g module casl
$ nest g class casl/casl-ability.factory
```

With this in place, we can define the `createForUser()` method on the `CaslAbilityFactory`. This method will create the `Ability` object for a given user:

```typescript

type Subjects = InferSubjects<typeof Article | typeof User> | 'all';

export type AppAbility = Ability<[Action, Subjects]>;

@Injectable()
export class CaslAbilityFactory {
  createForUser(user: User) {
    const { can, cannot, build } = new AbilityBuilder<
      Ability<[Action, Subjects]>
    >(Ability as AbilityClass<AppAbility>);

    if (user.isAdmin) {
      can(Action.Manage, 'all'); // read-write access to everything
    } else {
      can(Action.Read, 'all'); // read-only access to everything
    }

    can(Action.Update, Article, { authorId: user.id });
    cannot(Action.Delete, Article, { isPublished: true });

    return build({
      // Read https://casl.js.org/v5/en/guide/subject-type-detection#use-classes-as-subject-types for details
      detectSubjectType: item => item.constructor as ExtractSubjectType<Subjects>
    });
  }
}
```

> **Notice**`all` is a special keyword in CASL that represents "any subject".

> **Hint**`Ability`, `AbilityBuilder`, `AbilityClass`, and `ExtractSubjectType` classes are exported from the `@casl/ability` package.

> **Hint**`detectSubjectType` option let CASL understand how to get subject type out of an object. For more information read [CASL documentation](https://casl.js.org/v5/en/guide/subject-type-detection#use-classes-as-subject-types) for details.

In the example above, we created the `Ability` instance using the `AbilityBuilder` class. As you probably guessed, `can` and `cannot` accept the same arguments but has different meanings, `can` allows to do an action on the specified subject and `cannot` forbids. Both may accept up to 4 arguments. To learn more about these functions, visit the official [CASL documentation](https://casl.js.org/v5/en/guide/intro).

Lastly, make sure to add the `CaslAbilityFactory` to the `providers` and `exports` arrays in the `CaslModule` module definition:

```typescript

import { Module } from '@nestjs/common';
import { CaslAbilityFactory } from './casl-ability.factory';

@Module({
  providers: [CaslAbilityFactory],
  exports: [CaslAbilityFactory],
})
export class CaslModule {}
```

With this in place, we can inject the `CaslAbilityFactory` to any class using standard constructor injection as long as the `CaslModule` is imported in the host context:

```typescript

constructor(private caslAbilityFactory: CaslAbilityFactory) {}
```

Then use it in a class as follows.

```typescript

const ability = this.caslAbilityFactory.createForUser(user);
if (ability.can(Action.Read, 'all')) {
  // "user" has read access to everything
}
```

> **Hint** Learn more about the `Ability` class in the official [CASL documentation](https://casl.js.org/v5/en/guide/intro).

For example, let's say we have a user who is not an admin. In this case, the user should be able to read articles, but creating new ones or removing the existing articles should be prohibited.

```typescript

const user = new User();
user.isAdmin = false;

const ability = this.caslAbilityFactory.createForUser(user);
ability.can(Action.Read, Article); // true
ability.can(Action.Delete, Article); // false
ability.can(Action.Create, Article); // false
```

> **Hint** Although both `Ability` and `AbilityBuilder` classes provide `can` and `cannot` methods, they have different purposes and accept slightly different arguments.

Also, as we have specified in our requirements, the user should be able to update its articles:

```typescript

const user = new User();
user.id = 1;

const article = new Article();
article.authorId = user.id;

const ability = this.caslAbilityFactory.createForUser(user);
ability.can(Action.Update, article); // true

article.authorId = 2;
ability.can(Action.Update, article); // false
```

As you can see, `Ability` instance allows us to check permissions in pretty readable way. Likewise, `AbilityBuilder` allows us to define permissions (and specify various conditions) in a similar fashion. To find more examples, visit the official documentation.

#### Advanced: Implementing a `PoliciesGuard`[#](/security/authorization#advanced-implementing-a-policiesguard)

In this section, we'll demonstrate how to build a somewhat more sophisticated guard, which checks if a user meets specific **authorization policies** that can be configured on the method-level (you can extend it to respect policies configured on the class-level too). In this example, we are going to use the CASL package just for illustration purposes, but using this library is not required. Also, we will use the `CaslAbilityFactory` provider that we've created in the previous section.

First, let's flesh out the requirements. The goal is to provide a mechanism that allows specifying policy checks per route handler. We will support both objects and functions (for simpler checks and for those who prefer more functional-style code).

Let's start off by defining interfaces for policy handlers:

```typescript

import { AppAbility } from '../casl/casl-ability.factory';

interface IPolicyHandler {
  handle(ability: AppAbility): boolean;
}

type PolicyHandlerCallback = (ability: AppAbility) => boolean;

export type PolicyHandler = IPolicyHandler | PolicyHandlerCallback;
```

As mentioned above, we provided two possible ways of defining a policy handler, an object (instance of a class that implements the `IPolicyHandler` interface) and a function (which meets the `PolicyHandlerCallback` type).

With this in place, we can create a `@CheckPolicies()` decorator. This decorator allows specifying what policies have to be met to access specific resources.

```typescript

export const CHECK_POLICIES_KEY = 'check_policy';
export const CheckPolicies = (...handlers: PolicyHandler[]) =>
  SetMetadata(CHECK_POLICIES_KEY, handlers);
```

Now let's create a `PoliciesGuard` that will extract and execute all the policy handlers bound to a route handler.

```typescript

@Injectable()
export class PoliciesGuard implements CanActivate {
  constructor(
    private reflector: Reflector,
    private caslAbilityFactory: CaslAbilityFactory,
  ) {}

  async canActivate(context: ExecutionContext): Promise<boolean> {
    const policyHandlers =
      this.reflector.get<PolicyHandler[]>(
        CHECK_POLICIES_KEY,
        context.getHandler(),
      ) || [];

    const { user } = context.switchToHttp().getRequest();
    const ability = this.caslAbilityFactory.createForUser(user);

    return policyHandlers.every((handler) =>
      this.execPolicyHandler(handler, ability),
    );
  }

  private execPolicyHandler(handler: PolicyHandler, ability: AppAbility) {
    if (typeof handler === 'function') {
      return handler(ability);
    }
    return handler.handle(ability);
  }
}
```

> **Hint** In this example, we assumed that `request.user` contains the user instance. In your app, you will probably make that association in your custom **authentication guard** - see [authentication](/v7/security/authentication) chapter for more details.

Let's break this example down. The `policyHandlers` is an array of handlers assigned to the method through the `@CheckPolicies()` decorator. Next, we use the `CaslAbilityFactory#create` method which constructs the `Ability` object, allowing us to verify whether a user has sufficient permissions to perform specific actions. We are passing this object to the policy handler which is either a function or an instance of a class that implements the `IPolicyHandler`, exposing the `handle()` method that returns a boolean. Lastly, we use the `Array#every` method to make sure that every handler returned `true` value.

Finally, to test this guard, bind it to any route handler, and register an inline policy handler (functional approach), as follows:

```typescript

@Get()
@UseGuards(PoliciesGuard)
@CheckPolicies((ability: AppAbility) => ability.can(Action.Read, Article))
findAll() {
  return this.articlesService.findAll();
}
```

Alternatively, we can define a class which implements the `IPolicyHandler` interface:

```typescript

export class ReadArticlePolicyHandler implements IPolicyHandler {
  handle(ability: AppAbility) {
    return ability.can(Action.Read, Article);
  }
}
```

And use it as follows:

```typescript

@Get()
@UseGuards(PoliciesGuard)
@CheckPolicies(new ReadArticlePolicyHandler())
findAll() {
  return this.articlesService.findAll();
}
```

> **Notice** Since we must instantiate the policy handler in-place using the `new` keyword, `CreateArticlePolicyHandler` class cannot use the Dependency Injection. This can be addressed with the `ModuleRef#get` method (read more [here](/v7/fundamentals/module-ref)). Basically, instead of registering functions and instances through the `@CheckPolicies()` decorator, you must allow passing a `Type<IPolicyHandler>`. Then, inside your guard, you could retrieve an instance using a type reference: `moduleRef.get(YOUR_HANDLER_TYPE)` or even dynamically instantiate it using the `ModuleRef#create` method.

----
url: https://docs.nestjs.com/v11/fundamentals/platform-agnosticism
----

* [Platform agnosticism](https://docs.nestjs.com/v11/fundamentals/platform-agnosticism#platform-agnosticism)
* [Build once, use everywhere](https://docs.nestjs.com/v11/fundamentals/platform-agnosticism#build-once-use-everywhere)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/fundamentals/platform-agnosticism.md "Suggest Edits")

### Platform agnosticism

Nest is a platform-agnostic framework. This means you can develop **reusable logical parts** that can be used across different types of applications. For example, most components can be re-used without change across different underlying HTTP server frameworks (e.g., Express and Fastify), and even across different *types* of applications (e.g., HTTP server frameworks, Microservices with different transport layers, and Web Sockets).

#### Build once, use everywhere[#](/fundamentals/platform-agnosticism#build-once-use-everywhere)

The **Overview** section of the documentation primarily shows coding techniques using HTTP server frameworks (e.g., apps providing a REST API or providing an MVC-style server-side rendered app). However, all those building blocks can be used on top of different transport layers ([microservices](/v11/microservices/basics) or [websockets](/v11/websockets/gateways)).

Furthermore, Nest comes with a dedicated [GraphQL](/v11/graphql/quick-start) module. You can use GraphQL as your API layer interchangeably with providing a REST API.

In addition, the [application context](/v11/application-context) feature helps to create any kind of Node.js application - including things like CRON jobs and CLI apps - on top of Nest.

Nest aspires to be a full-fledged platform for Node.js apps that brings a higher-level of modularity and reusability to your applications. Build once, use everywhere!

----
url: https://docs.nestjs.com/v10/fundamentals/module-ref
----

* [Module reference](https://docs.nestjs.com/v10/fundamentals/module-ref#module-reference)
* [Retrieving instances](https://docs.nestjs.com/v10/fundamentals/module-ref#retrieving-instances)
* [Resolving scoped providers](https://docs.nestjs.com/v10/fundamentals/module-ref#resolving-scoped-providers)
* [Registering REQUEST provider](https://docs.nestjs.com/v10/fundamentals/module-ref#registering-request-provider)
* [Getting current sub-tree](https://docs.nestjs.com/v10/fundamentals/module-ref#getting-current-sub-tree)
* [Instantiating custom classes dynamically](https://docs.nestjs.com/v10/fundamentals/module-ref#instantiating-custom-classes-dynamically)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/fundamentals/module-reference.md "Suggest Edits")

### Module reference

Nest provides the `ModuleRef` class to navigate the internal list of providers and obtain a reference to any provider using its injection token as a lookup key. The `ModuleRef` class also provides a way to dynamically instantiate both static and scoped providers. `ModuleRef` can be injected into a class in the normal way:

cats.service.ts

JS TS

```typescript

@Injectable()
export class CatsService {
  constructor(private moduleRef: ModuleRef) {}
}
```

```typescript

@Injectable()
@Dependencies(ModuleRef)
export class CatsService {
  constructor(moduleRef) {
    this.moduleRef = moduleRef;
  }
}
```

> **Hint** The `ModuleRef` class is imported from the `@nestjs/core` package.

#### Retrieving instances[#](/fundamentals/module-ref#retrieving-instances)

The `ModuleRef` instance (hereafter we'll refer to it as the **module reference**) has a `get()` method. By default, this method returns a provider, controller, or injectable (e.g., guard, interceptor, etc.) that was registered and has been instantiated in the *current module* using its injection token/class name. If the instance is not found, an exception will be raised.

cats.service.ts

JS TS

```typescript

@Injectable()
export class CatsService implements OnModuleInit {
  private service: Service;
  constructor(private moduleRef: ModuleRef) {}

  onModuleInit() {
    this.service = this.moduleRef.get(Service);
  }
}
```

```typescript

@Injectable()
@Dependencies(ModuleRef)
export class CatsService {
  constructor(moduleRef) {
    this.moduleRef = moduleRef;
  }

  onModuleInit() {
    this.service = this.moduleRef.get(Service);
  }
}
```

> **Warning** You can't retrieve scoped providers (transient or request-scoped) with the `get()` method. Instead, use the technique described [below](https://docs.nestjs.com/fundamentals/module-ref#resolving-scoped-providers). Learn how to control scopes [here](/v10/fundamentals/injection-scopes).

To retrieve a provider from the global context (for example, if the provider has been injected in a different module), pass the `{ strict: false }` option as a second argument to `get()`.

```typescript

this.moduleRef.get(Service, { strict: false });
```

#### Resolving scoped providers[#](/fundamentals/module-ref#resolving-scoped-providers)

To dynamically resolve a scoped provider (transient or request-scoped), use the `resolve()` method, passing the provider's injection token as an argument.

cats.service.ts

JS TS

```typescript

@Injectable()
export class CatsService implements OnModuleInit {
  private transientService: TransientService;
  constructor(private moduleRef: ModuleRef) {}

  async onModuleInit() {
    this.transientService = await this.moduleRef.resolve(TransientService);
  }
}
```

```typescript

@Injectable()
@Dependencies(ModuleRef)
export class CatsService {
  constructor(moduleRef) {
    this.moduleRef = moduleRef;
  }

  async onModuleInit() {
    this.transientService = await this.moduleRef.resolve(TransientService);
  }
}
```

The `resolve()` method returns a unique instance of the provider, from its own **DI container sub-tree**. Each sub-tree has a unique **context identifier**. Thus, if you call this method more than once and compare instance references, you will see that they are not equal.

cats.service.ts

JS TS

```typescript

@Injectable()
export class CatsService implements OnModuleInit {
  constructor(private moduleRef: ModuleRef) {}

  async onModuleInit() {
    const transientServices = await Promise.all([
      this.moduleRef.resolve(TransientService),
      this.moduleRef.resolve(TransientService),
    ]);
    console.log(transientServices[0] === transientServices[1]); // false
  }
}
```

```typescript

@Injectable()
@Dependencies(ModuleRef)
export class CatsService {
  constructor(moduleRef) {
    this.moduleRef = moduleRef;
  }

  async onModuleInit() {
    const transientServices = await Promise.all([
      this.moduleRef.resolve(TransientService),
      this.moduleRef.resolve(TransientService),
    ]);
    console.log(transientServices[0] === transientServices[1]); // false
  }
}
```

To generate a single instance across multiple `resolve()` calls, and ensure they share the same generated DI container sub-tree, you can pass a context identifier to the `resolve()` method. Use the `ContextIdFactory` class to generate a context identifier. This class provides a `create()` method that returns an appropriate unique identifier.

cats.service.ts

JS TS

```typescript

@Injectable()
export class CatsService implements OnModuleInit {
  constructor(private moduleRef: ModuleRef) {}

  async onModuleInit() {
    const contextId = ContextIdFactory.create();
    const transientServices = await Promise.all([
      this.moduleRef.resolve(TransientService, contextId),
      this.moduleRef.resolve(TransientService, contextId),
    ]);
    console.log(transientServices[0] === transientServices[1]); // true
  }
}
```

```typescript

@Injectable()
@Dependencies(ModuleRef)
export class CatsService {
  constructor(moduleRef) {
    this.moduleRef = moduleRef;
  }

  async onModuleInit() {
    const contextId = ContextIdFactory.create();
    const transientServices = await Promise.all([
      this.moduleRef.resolve(TransientService, contextId),
      this.moduleRef.resolve(TransientService, contextId),
    ]);
    console.log(transientServices[0] === transientServices[1]); // true
  }
}
```

> **Hint** The `ContextIdFactory` class is imported from the `@nestjs/core` package.

#### Registering `REQUEST` provider[#](/fundamentals/module-ref#registering-request-provider)

Manually generated context identifiers (with `ContextIdFactory.create()`) represent DI sub-trees in which `REQUEST` provider is `undefined` as they are not instantiated and managed by the Nest dependency injection system.

To register a custom `REQUEST` object for a manually created DI sub-tree, use the `ModuleRef#registerRequestByContextId()` method, as follows:

```typescript

const contextId = ContextIdFactory.create();
this.moduleRef.registerRequestByContextId(/* YOUR_REQUEST_OBJECT */, contextId);
```

#### Getting current sub-tree[#](/fundamentals/module-ref#getting-current-sub-tree)

Occasionally, you may want to resolve an instance of a request-scoped provider within a **request context**. Let's say that `CatsService` is request-scoped and you want to resolve the `CatsRepository` instance which is also marked as a request-scoped provider. In order to share the same DI container sub-tree, you must obtain the current context identifier instead of generating a new one (e.g., with the `ContextIdFactory.create()` function, as shown above). To obtain the current context identifier, start by injecting the request object using `@Inject()` decorator.

cats.service.ts

JS TS

```typescript

@Injectable()
export class CatsService {
  constructor(
    @Inject(REQUEST) private request: Record<string, unknown>,
  ) {}
}
```

```typescript

@Injectable()
@Dependencies(REQUEST)
export class CatsService {
  constructor(request) {
    this.request = request;
  }
}
```

> **Hint** Learn more about the request provider [here](https://docs.nestjs.com/fundamentals/injection-scopes#request-provider).

Now, use the `getByRequest()` method of the `ContextIdFactory` class to create a context id based on the request object, and pass this to the `resolve()` call:

```typescript

const contextId = ContextIdFactory.getByRequest(this.request);
const catsRepository = await this.moduleRef.resolve(CatsRepository, contextId);
```

#### Instantiating custom classes dynamically[#](/fundamentals/module-ref#instantiating-custom-classes-dynamically)

To dynamically instantiate a class that **wasn't previously registered** as a **provider**, use the module reference's `create()` method.

cats.service.ts

JS TS

```typescript

@Injectable()
export class CatsService implements OnModuleInit {
  private catsFactory: CatsFactory;
  constructor(private moduleRef: ModuleRef) {}

  async onModuleInit() {
    this.catsFactory = await this.moduleRef.create(CatsFactory);
  }
}
```

```typescript

@Injectable()
@Dependencies(ModuleRef)
export class CatsService {
  constructor(moduleRef) {
    this.moduleRef = moduleRef;
  }

  async onModuleInit() {
    this.catsFactory = await this.moduleRef.create(CatsFactory);
  }
}
```

This technique enables you to conditionally instantiate different classes outside of the framework container.

## Explore your graph with NestJS Devtools

* Graph visualizer
* Routes navigator
* Interactive playground
* CI/CD integration

----
url: https://docs.nestjs.com/v7/faq/hybrid-application
----

* [Hybrid application](https://docs.nestjs.com/v7/faq/hybrid-application#hybrid-application)
* [Sharing configuration](https://docs.nestjs.com/v7/faq/hybrid-application#sharing-configuration)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/faq/hybrid-application.md "Suggest Edits")

### Hybrid application

A hybrid application is one that both listens for HTTP requests, as well as makes use of connected microservices. The `INestApplication` instance can be connected with `INestMicroservice` instances through the `connectMicroservice()` method.

```typescript

const app = await NestFactory.create(AppModule);
const microservice = app.connectMicroservice({
  transport: Transport.TCP,
});

await app.startAllMicroservicesAsync();
await app.listen(3001);
```

To connect multiple microservice instances, issue the call to `connectMicroservice()` for each microservice:

```typescript

const app = await NestFactory.create(AppModule);
// microservice #1
const microserviceTcp = app.connectMicroservice<MicroserviceOptions>({
  transport: Transport.TCP,
  options: {
    port: 3001,
  },
});
// microservice #2
const microserviceRedis = app.connectMicroservice<MicroserviceOptions>({
  transport: Transport.REDIS,
  options: {
    url: 'redis://localhost:6379',
  },
});

await app.startAllMicroservicesAsync();
await app.listen(3001);
```

To bind `@MessagePattern()` to only one transport strategy (for example, MQTT) in a hybrid application with multiple microservices, we can pass the second argument of type `Transport` which is an enum with all the built-in transport strategies defined.

JS TS

```typescript

@MessagePattern('time.us.*', Transport.NATS)
getDate(@Payload() data: number[], @Ctx() context: NatsContext) {
  console.log(`Subject: ${context.getSubject()}`); // e.g. "time.us.east"
  return new Date().toLocaleTimeString(...);
}
@MessagePattern({ cmd: 'time.us' }, Transport.TCP)
getTCPDate(@Payload() data: number[]) {
  return new Date().toLocaleTimeString(...);
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('time.us.*', Transport.NATS)
getDate(data, context) {
  console.log(`Subject: ${context.getSubject()}`); // e.g. "time.us.east"
  return new Date().toLocaleTimeString(...);
}
@Bind(Payload(), Ctx())
@MessagePattern({ cmd: 'time.us' }, Transport.TCP)
getTCPDate(data, context) {
  return new Date().toLocaleTimeString(...);
}
```

> **Hint**`@Payload()`, `@Ctx()`, `Transport` and `NatsContext` are imported from `@nestjs/microservices`.

#### Sharing configuration[#](/faq/hybrid-application#sharing-configuration)

By default a hybrid application will not inherit global pipes, interceptors, guards and filters configured for the main (HTTP-based) application. To inherit these configuration properties from the main application, set the `inheritAppConfig` property in the second argument (an optional options object) of the `connectMicroservice()` call, as follow:

```typescript

const microservice = app.connectMicroservice({
  transport: Transport.TCP
}, { inheritAppConfig: true });
```

----
url: https://docs.nestjs.com/v6
----

* [Introduction](https://docs.nestjs.com/v6/#introduction)
* [Philosophy](https://docs.nestjs.com/v6/#philosophy)
* [Installation](https://docs.nestjs.com/v6/#installation)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/introduction.md "Suggest Edits")

### Introduction

Nest (NestJS) is a framework for building efficient, scalable [Node.js](https://nodejs.org/) server-side applications. It uses progressive JavaScript, is built with and fully supports [TypeScript](http://www.typescriptlang.org/) (yet still enables developers to code in pure JavaScript) and combines elements of OOP (Object Oriented Programming), FP (Functional Programming), and FRP (Functional Reactive Programming).

Under the hood, Nest makes use of robust HTTP Server frameworks like [Express](https://expressjs.com/) (the default) and optionally can be configured to use [Fastify](https://github.com/fastify/fastify) as well!

Nest provides a level of abstraction above these common Node.js frameworks (Express/Fastify), but also exposes their APIs directly to the developer. This allows developers the freedom to use the myriad of third-party modules which are available for the underlying platform.

#### Philosophy[#](/#philosophy)

In recent years, thanks to Node.js, JavaScript has become the “lingua franca” of the web for both front and backend applications. This has given rise to awesome projects like [Angular](https://angular.io/), [React](https://github.com/facebook/react) and [Vue](https://github.com/vuejs/vue), which improve developer productivity and enable the creation of fast, testable, and extensible frontend applications. However, while plenty of superb libraries, helpers, and tools exist for Node (and server-side JavaScript), none of them effectively solve the main problem of - **Architecture**.

Nest provides an out-of-the-box application architecture which allows developers and teams to create highly testable, scalable, loosely coupled, and easily maintainable applications.

#### Installation[#](/#installation)

To get started, you can either scaffold the project with the [Nest CLI](/v6/cli/overview), or clone a starter project (both will produce the same outcome).

To scaffold the project with the Nest CLI, run the following commands. This will create a new project directory, and populate the directory with the initial core Nest files and supporting modules, creating a conventional base structure for your project. Creating a new project with the **Nest CLI** is recommended for first-time users. We'll continue with this approach in [First Steps](/v6/first-steps).

```bash

$ npm i -g @nestjs/cli
$ nest new project-name
```

Alternatively, to install the TypeScript starter project with **Git**:

```bash

$ git clone https://github.com/nestjs/typescript-starter.git project
$ cd project
$ npm install
$ npm run start
```

Open your browser and navigate to `http://localhost:3000/`.

To install the JavaScript flavor of the starter project, use `javascript-starter.git` in the command sequence above.

You can also manually create a new project from scratch by installing the core and supporting files with **npm** (or **yarn**). In this case, of course, you'll be responsible for creating the project boilerplate files yourself.

```bash

$ npm i --save @nestjs/core @nestjs/common rxjs reflect-metadata
```

----
url: https://docs.nestjs.com/v6/techniques/file-upload
----

* [File upload](https://docs.nestjs.com/v6/techniques/file-upload#file-upload)
* [Basic example](https://docs.nestjs.com/v6/techniques/file-upload#basic-example)
* [Array of files](https://docs.nestjs.com/v6/techniques/file-upload#array-of-files)
* [Multiple files](https://docs.nestjs.com/v6/techniques/file-upload#multiple-files)
* [Any files](https://docs.nestjs.com/v6/techniques/file-upload#any-files)
* [Default options](https://docs.nestjs.com/v6/techniques/file-upload#default-options)
* [Async configuration](https://docs.nestjs.com/v6/techniques/file-upload#async-configuration)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/techniques/file-upload.md "Suggest Edits")

### File upload

To handle file uploading, Nest provides a built-in module based on the [multer](https://github.com/expressjs/multer) middleware package for Express. Multer handles data posted in the `multipart/form-data` format, which is primarily used for uploading files via an HTTP `POST` request. This module is fully configurable and you can adjust its behavior to your application requirements.

> **Warning** Multer cannot process data which is not in the supported multipart format (`multipart/form-data`). Also, note that this package is not compatible with the `FastifyAdapter`.

#### Basic example[#](/techniques/file-upload#basic-example)

To upload a single file, simply tie the `FileInterceptor()` interceptor to the route handler and extract `file` from the `request` using the `@UploadedFile()` decorator.

JS TS

```typescript

@Post('upload')
@UseInterceptors(FileInterceptor('file'))
uploadFile(@UploadedFile() file) {
  console.log(file);
}
```

```typescript

@Post('upload')
@UseInterceptors(FileInterceptor('file'))
@Bind(UploadedFile())
uploadFile(file) {
  console.log(file);
}
```

> **Hint** The `FileInterceptor()` decorator is exported from the `@nestjs/platform-express` package. The `@UploadedFile()` decorator is exported from `@nestjs/common`.

The `FileInterceptor()` decorator takes two arguments:

* `fieldName`: string that supplies the name of the field from the HTML form that holds a file
* `options`: optional object of type `MulterOptions`. This is the same object used by the multer constructor (more details [here](https://github.com/expressjs/multer#multeropts)).

```typescript

@Post('upload')
@UseInterceptors(FilesInterceptor('files'))
uploadFile(@UploadedFiles() files) {
  console.log(files);
}
```

```typescript

@Post('upload')
@UseInterceptors(FilesInterceptor('files'))
@Bind(UploadedFiles())
uploadFile(files) {
  console.log(files);
}
```

> **Hint** The `FilesInterceptor()` decorator is exported from the `@nestjs/platform-express` package. The `@UploadedFiles()` decorator is exported from `@nestjs/common`.

#### Multiple files[#](/techniques/file-upload#multiple-files)

To upload multiple fields (all with different field name keys), use the `FileFieldsInterceptor()` decorator. This decorator takes two arguments:

* `uploadedFields`: an array of objects, where each object specifies a required `name` property with a string value specifying a field name, as described above, and an optional `maxCount` property, as described above
* `options`: optional `MulterOptions` object, as described above

When using `FileFieldsInterceptor()`, extract files from the `request` with the `@UploadedFiles()` decorator.

JS TS

```typescript

@Post('upload')
@UseInterceptors(FileFieldsInterceptor([
  { name: 'avatar', maxCount: 1 },
  { name: 'background', maxCount: 1 },
]))
uploadFile(@UploadedFiles() files) {
  console.log(files);
}
```

```typescript

@Post('upload')
@Bind(UploadedFiles())
@UseInterceptors(FileFieldsInterceptor([
  { name: 'avatar', maxCount: 1 },
  { name: 'background', maxCount: 1 },
]))
uploadFile(files) {
  console.log(files);
}
```

#### Any files[#](/techniques/file-upload#any-files)

To upload all fields with arbitrary field name keys, use the `AnyFilesInterceptor()` decorator. This decorator can accept an optional `options` object as described above.

When using `AnyFilesInterceptor()`, extract files from the `request` with the `@UploadedFiles()` decorator.

JS TS

```typescript

@Post('upload')
@UseInterceptors(AnyFilesInterceptor())
uploadFile(@UploadedFiles() files) {
  console.log(files);
}
```

```typescript

@Post('upload')
@Bind(UploadedFiles())
@UseInterceptors(AnyFilesInterceptor())
uploadFile(files) {
  console.log(files);
}
```

#### Default options[#](/techniques/file-upload#default-options)

You can specify multer options in the file interceptors as described above. To set default options, you can call the static `register()` method when you import the `MulterModule`, passing in supported options. You can use all options listed [here](https://github.com/expressjs/multer#multeropts).

```typescript

MulterModule.register({
  dest: '/upload',
});
```

> **Hint** The `MulterModule` class is exported from the `@nestjs/platform-express` package.

#### Async configuration[#](/techniques/file-upload#async-configuration)

When you need to set `MulterModule` options asynchronously instead of statically, use the `registerAsync()` method. As with most dynamic modules, Nest provides several techniques to deal with async configuration.

One technique is to use a factory function:

```typescript

MulterModule.registerAsync({
  useFactory: () => ({
    dest: '/upload',
  }),
});
```

Like other [factory providers](https://docs.nestjs.com/fundamentals/custom-providers#factory-providers-usefactory), our factory function can be `async` and can inject dependencies through `inject`.

```typescript

MulterModule.registerAsync({
  imports: [ConfigModule],
  useFactory: async (configService: ConfigService) => ({
    dest: configService.getString('MULTER_DEST'),
  }),
  inject: [ConfigService],
});
```

Alternatively, you can configure the `MulterModule` using a class instead of a factory, as shown below:

```typescript

MulterModule.registerAsync({
  useClass: MulterConfigService,
});
```

The construction above instantiates `MulterConfigService` inside `MulterModule`, using it to create the required options object. Note that in this example, the `MulterConfigService` has to implement the `MulterOptionsFactory` interface, as shown below. The `MulterModule` will call the `createMulterOptions()` method on the instantiated object of the supplied class.

```typescript

@Injectable()
class MulterConfigService implements MulterOptionsFactory {
  createMulterOptions(): MulterModuleOptions {
    return {
      dest: '/upload',
    };
  }
}
```

If you want to reuse an existing options provider instead of creating a private copy inside the `MulterModule`, use the `useExisting` syntax.

```typescript

MulterModule.registerAsync({
  imports: [ConfigModule],
  useExisting: ConfigService,
});
```

----
url: https://docs.nestjs.com/v5/websockets/gateways
----

### Gateways

Gateway is a class annotated with `@WebSocketGateway()` decorator. Gateways, by default, make use of [socket.io](https://github.com/socketio/socket.io) package under the hood, but also, provide compatibility with a wide range of other libraries, including native web sockets implementation, read more [here](/v5/websockets/adapter).

> **Hint** Gateway behaves same as a simple **provider**, therefore it can effortlessly inject dependencies through constructor. Also, gateway might be injected by other classes (providers and controllers) as well.

#### Installation

Firstly, we need to install the required package:

TypeScript

```typescript

$ npm i --save @nestjs/websockets
```

#### Overview

In general, each gateway is listening to the same port as **HTTP server** is running on, unless your app is not a web application, or you have changed the port manually. We can change this behavior by passing an argument to the `@WebSocketGateway(81)` decorator where `81` is a chosen port number. Additionally, you can set a [namespace](https://socket.io/docs/rooms-and-namespaces/) used by this gateway with the following construction:

TypeScript

```typescript

@WebSocketGateway(81, { namespace: 'events' })
```

> **Warning** The gateway won't start until you put it inside the `providers` array.

The `namespace` is not a sole available option. You can pass any other property that is mentioned [here](https://socket.io/docs/server-api/). Those properties will be passed to the socket constructor during the instantiation process.

TypeScript

```typescript

@WebSocketGateway(81, { transports: ['websocket'] })
```

Alright, the gateway is listening now, but we are not subscribing to the incoming messages so far. Let's create a handler that will subscribe to the `events` messages and respond to the user with the exact same data.

events.gateway.ts

JS TS

TypeScript

```typescript

@SubscribeMessage('events')
onEvent(client, data: string): string {
  return data;
}
```

TypeScript

```typescript

@SubscribeMessage('events')
onEvent(client, data) {
  return data;
}
```

> **Hint** The `@SubscribeMessage()` decorator is imported from `@nestjs/websockets` package.

The `onEvent()` function takes two arguments. First one is a library-specific [socket instance](https://socket.io/docs/server-api/#socket) and the second one is the data received from the client. Once we get the message, we send an acknowledgment with the same data that someone has sent over the network. Also, it is possible to emit messages using a library-specific approach, for example, by making use of `client.emit()` method. However, in this case, you aren't able to use interceptors. If you don't want to respond to the user, just don't return anything (or explicitly return "falsy" value, e.g. `undefined`).

Now when the client emits a message in the following manner:

TypeScript

```typescript

socket.emit('events', { name: 'Nest' });
```

The `onEvent()` method will be executed. In order to listen for messages emitted from within above handler, the client has to attach a corresponding acknowledgment's listener:

TypeScript

```typescript

socket.emit('events', { name: 'Nest' }, (data) => console.log(data));
```

#### Multiple responses

The acknowledgment is dispatched only once. Furthermore, it is not supported by native WebSockets implementation. To solve this limitation, you may return an object which consist of two properties. The `event` which is a name of the emitted event and the `data` that has to be forwarded to the client.

events.gateway.ts

JS TS

TypeScript

```typescript

@SubscribeMessage('events')
onEvent(client, data: any): WsResponse<any> {
  const event = 'events';
  return { event, data };
}
```

TypeScript

```typescript

@SubscribeMessage('events')
onEvent(client, data) {
  const event = 'events';
  return { event, data };
}
```

> **Hint** The `WsResponse` interface is imported from `@nestjs/websockets` package.

In order to listen for the incoming response(s), the client has to apply another event listener.

TypeScript

```typescript

socket.on('events', (data) => console.log(data));
```

#### Asynchronous responses

Each message handler can be either synchronous or **asynchronous** (`async`), thereby you're able to return the `Promise`. Moreover, you can return the [Rx](https://github.com/reactivex/rxjs)  `Observable`, which means that you can return multiple values (they will be emitted until the stream is completed).

events.gateway.ts

JS TS

TypeScript

```typescript

@SubscribeMessage('events')
onEvent(client, data: any): Observable<WsResponse<number>> {
  const event = 'events';
  const response = [1, 2, 3];

  return from(response).pipe(
    map(data => ({ event, data })),
  );
}
```

TypeScript

```typescript

@SubscribeMessage('events')
onEvent(client, data) {
  const event = 'events';
  const response = [1, 2, 3];

  return from(response).pipe(
    map(data => ({ event, data })),
  );
}
```

The above message handler will respond **3 times** (sequentially, with each item from the `response` array).

#### Lifecycle hooks

There are 3 useful lifecycle hooks. All of them have corresponding interfaces and are described in the following table:

|                       |                                                                                                                                         |
| --------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| `OnGatewayInit`       | Forces to implement the `afterInit()` method. Takes library-specific server instance as an argument (and spreads the rest if required). |
| `OnGatewayConnection` | Forces to implement the `handleConnection()` method. Takes library-specific client socket instance as an argument.                      |
| `OnGatewayDisconnect` | Forces to implement the `handleDisconnect()` method. Takes library-specific client socket instance as an argument.                      |

> **Hint** Each lifecycle interface is exposed from `@nestjs/websockets` package.

#### Server

Occasionally, you may want to have a direct access to the native, **library-specific** server instance. The reference to this object is passed as an argument to the `afterInit()` method (`OnGatewayInit` interface). The second approach is to make use of `@WebSocketServer()` decorator.

TypeScript

```typescript

@WebSocketServer() server;
```

> **Notice** The `@WebSocketServer()` decorator is imported from the `@nestjs/websockets` package.

Nest will automatically assign the server instance to this property when it's ready to use.

#### Example

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/02-gateways).

* Gateways
* Installation
* Overview
* Multiple responses
* Asynchronous responses
* Lifecycle hooks
* Server

----
url: https://docs.nestjs.com/v11/microservices/custom-transport
----

* [Custom transporters](https://docs.nestjs.com/v11/microservices/custom-transport#custom-transporters)
* [Creating a strategy](https://docs.nestjs.com/v11/microservices/custom-transport#creating-a-strategy)
* [Client proxy](https://docs.nestjs.com/v11/microservices/custom-transport#client-proxy)
* [Message serialization](https://docs.nestjs.com/v11/microservices/custom-transport#message-serialization)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/microservices/custom-transport.md "Suggest Edits")

### Custom transporters

Nest provides a variety of **transporters** out-of-the-box, as well as an API allowing developers to build new custom transport strategies. Transporters enable you to connect components over a network using a pluggable communications layer and a very simple application-level message protocol (read full [article](https://dev.to/nestjs/integrate-nestjs-with-external-services-using-microservice-transporters-part-1-p3)).

> **Hint** Building a microservice with Nest does not necessarily mean you must use the `@nestjs/microservices` package. For example, if you want to communicate with external services (let's say other microservices written in different languages), you may not need all the features provided by `@nestjs/microservice` library. In fact, if you don't need decorators (`@EventPattern` or `@MessagePattern`) that let you declaratively define subscribers, running a [Standalone Application](/v11/application-context) and manually maintaining connection/subscribing to channels should be enough for most use-cases and will provide you with more flexibility.

With a custom transporter, you can integrate any messaging system/protocol (including Google Cloud Pub/Sub, Amazon Kinesis, and others) or extend the existing one, adding extra features on top (for example, [QoS](https://github.com/mqttjs/MQTT.js/blob/master/README.md#qos) for MQTT).

> **Hint** To better understand how Nest microservices work and how you can extend the capabilities of existing transporters, we recommend reading the [NestJS Microservices in Action](https://dev.to/johnbiundo/series/4724) and [Advanced NestJS Microservices](https://dev.to/nestjs/part-1-introduction-and-setup-1a2l) article series.

#### Creating a strategy[#](/microservices/custom-transport#creating-a-strategy)

First, let's define a class representing our custom transporter.

```typescript

import { CustomTransportStrategy, Server } from '@nestjs/microservices';

class GoogleCloudPubSubServer
  extends Server
  implements CustomTransportStrategy
{
  /**
   * Triggered when you run "app.listen()".
   */
  listen(callback: () => void) {
    callback();
  }

  /**
   * Triggered on application shutdown.
   */
  close() {}

  /**
   * You can ignore this method if you don't want transporter users
   * to be able to register event listeners. Most custom implementations
   * will not need this.
   */
  on(event: string, callback: Function) {
    throw new Error('Method not implemented.');
  }

  /**
   * You can ignore this method if you don't want transporter users
   * to be able to retrieve the underlying native server. Most custom implementations
   * will not need this.
   */
  unwrap<T = never>(): T {
    throw new Error('Method not implemented.');
  }
}
```

> **Warning** Please, note we won't be implementing a fully-featured Google Cloud Pub/Sub server in this chapter as this would require diving into transporter specific technical details.

In our example above, we declared the `GoogleCloudPubSubServer` class and provided `listen()` and `close()` methods enforced by the `CustomTransportStrategy` interface. Also, our class extends the `Server` class imported from the `@nestjs/microservices` package that provides a few useful methods, for example, methods used by Nest runtime to register message handlers. Alternatively, in case you want to extend the capabilities of an existing transport strategy, you could extend the corresponding server class, for example, `ServerRedis`. Conventionally, we added the `"Server"` suffix to our class as it will be responsible for subscribing to messages/events (and responding to them, if necessary).

With this in place, we can now use our custom strategy instead of using a built-in transporter, as follows:

```typescript

const app = await NestFactory.createMicroservice<MicroserviceOptions>(
  AppModule,
  {
    strategy: new GoogleCloudPubSubServer(),
  },
);
```

Basically, instead of passing the normal transporter options object with `transport` and `options` properties, we pass a single property, `strategy`, whose value is an instance of our custom transporter class.

Back to our `GoogleCloudPubSubServer` class, in a real-world application, we would be establishing a connection to our message broker/external service and registering subscribers/listening to specific channels in `listen()` method (and then removing subscriptions & closing the connection in the `close()` teardown method), but since this requires a good understanding of how Nest microservices communicate with each other, we recommend reading this [article series](https://dev.to/nestjs/part-1-introduction-and-setup-1a2l). In this chapter instead, we'll focus on the capabilities the `Server` class provides and how you can leverage them to build custom strategies.

For example, let's say that somewhere in our application, the following message handler is defined:

```typescript

@MessagePattern('echo')
echo(@Payload() data: object) {
  return data;
}
```

This message handler will be automatically registered by Nest runtime. With `Server` class, you can see what message patterns have been registered and also, access and execute the actual methods that were assigned to them. To test this out, let's add a simple `console.log` inside `listen()` method before `callback` function is called:

```typescript

listen(callback: () => void) {
  console.log(this.messageHandlers);
  callback();
}
```

After your application restarts, you'll see the following log in your terminal:

```typescript

Map { 'echo' => [AsyncFunction] { isEventHandler: false } }
```

> **Hint** If we used the `@EventPattern` decorator, you would see the same output, but with the `isEventHandler` property set to `true`.

As you can see, the `messageHandlers` property is a `Map` collection of all message (and event) handlers, in which patterns are being used as keys. Now, you can use a key (for example, `"echo"`) to receive a reference to the message handler:

```typescript

async listen(callback: () => void) {
  const echoHandler = this.messageHandlers.get('echo');
  console.log(await echoHandler('Hello world!'));
  callback();
}
```

Once we execute the `echoHandler` passing an arbitrary string as an argument (`"Hello world!"` here), we should see it in the console:

```json

Hello world!
```

Which means that our method handler was properly executed.

When using a `CustomTransportStrategy` with [Interceptors](/v11/interceptors) the handlers are wrapped into RxJS streams. This means that you need to subscribe to them in order to execute the streams underlying logic (e.g. continue into the controller logic after an interceptor has been executed).

An example of this can be seen below:

```typescript

async listen(callback: () => void) {
  const echoHandler = this.messageHandlers.get('echo');
  const streamOrResult = await echoHandler('Hello World');
  if (isObservable(streamOrResult)) {
    streamOrResult.subscribe();
  }
  callback();
}
```

#### Client proxy[#](/microservices/custom-transport#client-proxy)

As we mentioned in the first section, you don't necessarily need to use the `@nestjs/microservices` package to create microservices, but if you decide to do so and you need to integrate a custom strategy, you will need to provide a "client" class too.

> **Hint** Again, implementing a fully-featured client class compatible with all `@nestjs/microservices` features (e.g., streaming) requires a good understanding of communication techniques used by the framework. To learn more, check out this [article](https://dev.to/nestjs/part-4-basic-client-component-16f9).

To communicate with an external service/emit & publish messages (or events) you can either use a library-specific SDK package, or implement a custom client class that extends the `ClientProxy`, as follows:

```typescript

import { ClientProxy, ReadPacket, WritePacket } from '@nestjs/microservices';

class GoogleCloudPubSubClient extends ClientProxy {
  async connect(): Promise<any> {}
  async close() {}
  async dispatchEvent(packet: ReadPacket<any>): Promise<any> {}
  publish(
    packet: ReadPacket<any>,
    callback: (packet: WritePacket<any>) => void,
  ): Function {}
  unwrap<T = never>(): T {
    throw new Error('Method not implemented.');
  }
}
```

> **Warning** Please, note we won't be implementing a fully-featured Google Cloud Pub/Sub client in this chapter as this would require diving into transporter specific technical details.

As you can see, `ClientProxy` class requires us to provide several methods for establishing & closing the connection and publishing messages (`publish`) and events (`dispatchEvent`). Note, if you don't need a request-response communication style support, you can leave the `publish()` method empty. Likewise, if you don't need to support event-based communication, skip the `dispatchEvent()` method.

To observe what and when those methods are executed, let's add multiple `console.log` calls, as follows:

```typescript

class GoogleCloudPubSubClient extends ClientProxy {
  async connect(): Promise<any> {
    console.log('connect');
  }

  async close() {
    console.log('close');
  }

  async dispatchEvent(packet: ReadPacket<any>): Promise<any> {
    return console.log('event to dispatch: ', packet);
  }

  publish(
    packet: ReadPacket<any>,
    callback: (packet: WritePacket<any>) => void,
  ): Function {
    console.log('message:', packet);

    // In a real-world application, the "callback" function should be executed
    // with payload sent back from the responder. Here, we'll simply simulate (5 seconds delay)
    // that response came through by passing the same "data" as we've originally passed in.
    //
    // The "isDisposed" bool on the WritePacket tells the response that no further data is
    // expected. If not sent or is false, this will simply emit data to the Observable.
    setTimeout(() => callback({ 
      response: packet.data,
      isDisposed: true,
    }), 5000);

    return () => console.log('teardown');
  }

  unwrap<T = never>(): T {
    throw new Error('Method not implemented.');
  }
}
```

With this in place, let's create an instance of `GoogleCloudPubSubClient` class and run the `send()` method (which you might have seen in earlier chapters), subscribing to the returned observable stream.

```typescript

const googlePubSubClient = new GoogleCloudPubSubClient();
googlePubSubClient
  .send('pattern', 'Hello world!')
  .subscribe((response) => console.log(response));
```

Now, you should see the following output in your terminal:

```typescript

connect
message: { pattern: 'pattern', data: 'Hello world!' }
Hello world! // <-- after 5 seconds
```

To test if our "teardown" method (which our `publish()` method returns) is properly executed, let's apply a timeout operator to our stream, setting it to 2 seconds to make sure it throws earlier then our `setTimeout` calls the `callback` function.

```typescript

const googlePubSubClient = new GoogleCloudPubSubClient();
googlePubSubClient
  .send('pattern', 'Hello world!')
  .pipe(timeout(2000))
  .subscribe(
    (response) => console.log(response),
    (error) => console.error(error.message),
  );
```

> **Hint** The `timeout` operator is imported from the `rxjs/operators` package.

With `timeout` operator applied, your terminal output should look as follows:

```typescript

connect
message: { pattern: 'pattern', data: 'Hello world!' }
teardown // <-- teardown
Timeout has occurred
```

To dispatch an event (instead of sending a message), use the `emit()` method:

```typescript

googlePubSubClient.emit('event', 'Hello world!');
```

And that's what you should see in the console:

```typescript

connect
event to dispatch:  { pattern: 'event', data: 'Hello world!' }
```

#### Message serialization[#](/microservices/custom-transport#message-serialization)

If you need to add some custom logic around the serialization of responses on the client side, you can use a custom class that extends the `ClientProxy` class or one of its child classes. For modifying successful requests you can override the `serializeResponse` method, and for modifying any errors that go through this client you can override the `serializeError` method. To make use of this custom class, you can pass the class itself to the `ClientsModule.register()` method using the `customClass` property. Below is an example of a custom `ClientProxy` that serializes each error into an `RpcException`.

error-handling.proxy.ts

JS TS

```typescript

import { ClientTCP, RpcException } from '@nestjs/microservices';

class ErrorHandlingProxy extends ClientTCP {
  serializeError(err: Error) {
    return new RpcException(err);
  }
}
```

and then use it in the `ClientsModule` like so:

app.module.ts

JS TS

```typescript

@Module({
  imports: [
    ClientsModule.register([{
      name: 'CustomProxy',
      customClass: ErrorHandlingProxy,
    }]),
  ]
})
export class AppModule
```

> **hint** This is the class itself being passed to `customClass`, not an instance of the class. Nest will create the instance under the hood for you, and will pass any options given to the `options` property to the new `ClientProxy`.

----
url: https://docs.nestjs.com/v7/discover/companies
----

* [Who is using Nest?](https://docs.nestjs.com/v7/discover/companies#who-is-using-nest)
* [Companies](https://docs.nestjs.com/v7/discover/companies#companies)

### Who is using Nest?

We are proudly helping various companies building their products at scale. If you are using Nest and would you like to be listed here, see this [thread](https://github.com/nestjs/nest/issues/1006). We are willing to put your logo here!

#### Companies[#](/discover/companies#companies)

According to our knowledge, all the following companies have built awesome projects on top of our framework:

[](https://roche.com)[](https://adidas.com)[](https://capgemini.com)[](https://www.societegenerale.fr/)[](https://rewe-digital.com/)[](https://www.decathlon.com/)[](https://www.autodesk.com/)[](https://www.neo4j.com/)[](https://www.shipt.com/)[](https://github.com/Sanofi-IADC)[](https://valor-software.com/)[](https://sitepen.com)[](https://gojob.com/)[](https://neoteric.eu/)[](https://trellis.org/)[](https://scal.io)[](https://swingdev.io/)[](https://culturacolectiva.com)[](https://trilon.io)[](http://architectnow.net)[](https://www.iflix.com)[](https://genuinebee.com/)[](https://runplayersleague.com)[](http://www.yanrongyun.com)[](https://sclable.com)[](https://www.dozto.com)[](https://www.qingtui.cn/)[](https://crowdlinker.com/)[](https://nothing.ch/)[](https://swissdevjobs.ch/jobs/Dev-Ops/All)[](https://zeo.org/tr/)[](https://valueadd.pl/)[](https://bedu.org)[](https://shopback.com)[](https://www.facile.it)[](https://interfacewerk.de)[](https://www.ottonova.de)[](https://radity.com)[](https://globalctoforum.org/)[](https://rivvy.app)

|                                     |
| ----------------------------------- |
| <https://gorrion.io/>               |
| <http://balticdatascience.com/>     |
| <https://prohabits.com/>            |
| <https://komed-health.com/>         |
| <https://kerberus.com.co/>          |
| <http://xtremis.com/>               |
| <https://notadd.com/>               |
| <http://jsdaddy.io/>                |
| <https://yumpingo.com/>             |
| <https://analytics-importer.cz/>    |
| <https://dayzim.com/>               |
| <https://wizkids.co.uk/>            |
| <https://pilvia.com/>               |
| <https://wi-q.com/>                 |
| <http://agrofel.com.br>             |
| <https://societegenerale.com/>      |
| <https://trashpanda.hulan.nl/>      |
| <https://bytedance.com/>            |
| <https://votercircle.com>           |
| <https://erento.com>                |
| <https://ideas.manticore-labs.com/> |
| <https://smartexlab.com/>           |
| <https://automama.ru/>              |
| <https://iflix.com/>                |
| <https://frontendwatch.com/>        |
| <https://mobilejazz.com/>           |
| <https://cgiandi.com/>              |
| <https://www.titlex.com.au/>        |
| <https://codengage.com/>            |
| <https://budacode.com/>             |
| <https://blueanchor.io/>            |
| <https://www.easymetrics.com/>      |
| <https://getapollo.io/>             |
| <https://big-bench.com/>            |
| <https://www.qingtui.cn/>           |
| <https://www.rosebayconsult.com/>   |
| <https://www.patrocinium.com/>      |
| <https://creatorsdaily.com>         |
| <https://autoscar.com.br>           |
| <https://www.mediktiv.com>          |
| <https://harmonize.health>          |
| <https://accerlery.be>              |
| <https://www.facile.it>             |
| <https://shopback.com>              |
| <https://www.ottonova.de>           |
| <https://www.radity.com>            |
| <https://globalctoforum.org>        |
| <https://halojasa.com>              |
| <https://hexito.com>                |
| <https://rivvy.app>                 |
| <https://padfever.com/>             |
| <https://datenlotse.org>            |
| <https://bemum.co>                  |
| <https://weoptimeye.ai>             |

and a lot more but we don't have enough time to update above list. Feel free to create a [pull request](https://github.com/nestjs/docs.nestjs.com/pulls) though!

----
url: https://docs.nestjs.com/v6/cli/usages
----

* [CLI command reference](https://docs.nestjs.com/v6/cli/usages#cli-command-reference)
* [nest new](https://docs.nestjs.com/v6/cli/usages#nest-new)
* [nest generate](https://docs.nestjs.com/v6/cli/usages#nest-generate)
* [nest build](https://docs.nestjs.com/v6/cli/usages#nest-build)
* [nest start](https://docs.nestjs.com/v6/cli/usages#nest-start)
* [nest add](https://docs.nestjs.com/v6/cli/usages#nest-add)
* [nest update](https://docs.nestjs.com/v6/cli/usages#nest-update)
* [nest info](https://docs.nestjs.com/v6/cli/usages#nest-info)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/cli/usages.md "Suggest Edits")

### CLI command reference

#### nest new[#](/cli/usages#nest-new)

Creates a new (standard mode) Nest project.

```bash

$ nest new <name> [options]
$ nest n <name> [options]
```

| Argument | Description                 |
| -------- | --------------------------- |
| `<name>` | The name of the new project |

##### Options

| Option                                | Description                                                                                                |
| ------------------------------------- | ---------------------------------------------------------------------------------------------------------- |
| `--dry-run`                           | Reports changes that would be made, but does not change the filesystem. Alias: `-d`                        |
| `--skip-git`                          | Skip git repository initialization. Alias: `-g`                                                            |
| `--skip-install`                      | Skip package installation. Alias: `-s`                                                                     |
| `--package-manager [package-manager]` | Specify package manager. Use `npm` or `yarn`. Package manager must be installed globally. Alias: `-p`      |
| `--language [language]`               | Specify programming language (`TS` or `JS`). Alias: `-l`                                                   |
| `--collection [collectionName]`       | Specify schematics collection. Use package name of installed npm package containing schematic. Alias: `-c` |

#### nest generate[#](/cli/usages#nest-generate)

Generates and/or modifies files based on a schematic

```bash

$ nest generate <schematic> <name> [options]
$ nest g <schematic> <name> [options]
```

##### Arguments

| Argument      | Description                                                                                              |
| ------------- | -------------------------------------------------------------------------------------------------------- |
| `<schematic>` | The `schematic` or `collection:schematic` to generate. See the table below for the available schematics. |
| `<name>`      | The name of the generated component.                                                                     |

##### Schematics

| Name          | Alias | Description                                                                                         |
| ------------- | ----- | --------------------------------------------------------------------------------------------------- |
| `application` |       | Generate a new application within a monorepo (converting to monorepo if it's a standard structure). |
| `library`     | `lib` | Generate a new library within a monorepo (converting to monorepo if it's a standard structure).     |
| `class`       | `cl`  | Generate a new class.                                                                               |
| `controller`  | `co`  | Generate a controller declaration.                                                                  |
| `decorator`   | `d`   | Generate a custom decorator.                                                                        |
| `filter`      | `f`   | Generate a filter declaration.                                                                      |
| `gateway`     | `ga`  | Generate a gateway declaration.                                                                     |
| `guard`       | `gu`  | Generate a guard declaration.                                                                       |
| `interface`   |       | Generate an interface.                                                                              |
| `interceptor` | `in`  | Generate an interceptor declaration.                                                                |
| `middleware`  | `mi`  | Generate a middleware declaration.                                                                  |
| `module`      | `mo`  | Generate a module declaration.                                                                      |
| `pipe`        | `pi`  | Generate a pipe declaration.                                                                        |
| `provider`    | `pr`  | Generate a provider declaration.                                                                    |
| `resolver`    | `r`   | Generate a resolver declaration.                                                                    |
| `service`     | `s`   | Generate a service declaration.                                                                     |

##### Options

| Option                          | Description                                                                                                |
| ------------------------------- | ---------------------------------------------------------------------------------------------------------- |
| `--dry-run`                     | Reports changes that would be made, but does not change the filesystem. Alias: `-d`                        |
| `--project [project]`           | Project that element should be added to. Alias: `-p`                                                       |
| `--flat`                        | Do not generate a folder for the element.                                                                  |
| `--collection [collectionName]` | Specify schematics collection. Use package name of installed npm package containing schematic. Alias: `-c` |
| `--spec`                        | Enforce spec files generation (default)                                                                    |
| `--no-spec`                     | Disable spec files generation                                                                              |

#### nest build[#](/cli/usages#nest-build)

Compiles an application or workspace into an output folder.

```bash

$ nest build <name> [options]
```

##### Arguments

| Argument | Description                       |
| -------- | --------------------------------- |
| `<name>` | The name of the project to build. |

##### Options

| Option            | Description                                       |
| ----------------- | ------------------------------------------------- |
| `--path [path]`   | Path to `tsconfig` file. Alias `-p`               |
| `--config [path]` | Path to `nest-cli` configuration file. Alias `-c` |
| `--watch`         | Run in watch mode (live-reload) Alias `-w`        |
| `--webpack`       | Use webpack for compilation.                      |
| `--webpackPath`   | Path to webpack configuration.                    |
| `--tsc`           | Force use `tsc` for compilation.                  |

#### nest start[#](/cli/usages#nest-start)

Compiles and runs an application (or default project in a workspace).

```bash

$ nest start <name> [options]
```

##### Arguments

| Argument | Description                     |
| -------- | ------------------------------- |
| `<name>` | The name of the project to run. |

##### Options

| Option               | Description                                        |
| -------------------- | -------------------------------------------------- |
| `--path [path]`      | Path to `tsconfig` file. Alias `-p`                |
| `--config [path]`    | Path to `nest-cli` configuration file. Alias `-c`  |
| `--watch`            | Run in watch mode (live-reload) Alias `-w`         |
| `--debug [hostport]` | Run in debug mode (with --inspect flag) Alias `-d` |
| `--webpack`          | Use webpack for compilation.                       |
| `--webpackPath`      | Path to webpack configuration.                     |
| `--tsc`              | Force use `tsc` for compilation.                   |
| `--exec [binary]`    | Binary to run (default: `node`). Alias `-e`        |

#### nest add[#](/cli/usages#nest-add)

Imports a library that has been packaged as a **nest library**, running its install schematic.

```bash

$ nest add <name> [options]
```

##### Arguments

| Argument | Description                        |
| -------- | ---------------------------------- |
| `<name>` | The name of the library to import. |

#### nest update[#](/cli/usages#nest-update)

Updates `@nestjs` dependencies in the `package.json``"dependencies"` list to their `@latest` version.

##### Options

| Option    | Description                                                         |
| --------- | ------------------------------------------------------------------- |
| `--force` | Do **upgrade** instead of update Alias `-f`                         |
| `--tag`   | Update to tagged version (use `@latest`, `@<tag>`, etc) Alias `-wt` |

#### nest info[#](/cli/usages#nest-info)

Displays information about installed nest packages and other helpful system info. For example:

```bash

 _   _             _      ___  _____  _____  _     _____
| \ | |           | |    |_  |/  ___|/  __ \| |   |_   _|
|  \| |  ___  ___ | |_     | |\ `--. | /  \/| |     | |
| . ` | / _ \/ __|| __|    | | `--. \| |    | |     | |
| |\  ||  __/\__ \| |_ /\__/ //\__/ /| \__/\| |_____| |_
\_| \_/ \___||___/ \__|\____/ \____/  \____/\_____/\___/

[System Information]
OS Version : macOS High Sierra
NodeJS Version : v8.9.0
YARN Version : 1.5.1
[Nest Information]
microservices version : 6.0.0
websockets version : 6.0.0
testing version : 6.0.0
common version : 6.0.0
core version : 6.0.0
```

----
url: https://docs.nestjs.com/v7/security/authentication
----

* [Authentication](https://docs.nestjs.com/v7/security/authentication#authentication)
* [Authentication requirements](https://docs.nestjs.com/v7/security/authentication#authentication-requirements)
* [Implementing Passport strategies](https://docs.nestjs.com/v7/security/authentication#implementing-passport-strategies)
* [Implementing Passport local](https://docs.nestjs.com/v7/security/authentication#implementing-passport-local)
* [Built-in Passport Guards](https://docs.nestjs.com/v7/security/authentication#built-in-passport-guards)
* [Login route](https://docs.nestjs.com/v7/security/authentication#login-route)
* [JWT functionality](https://docs.nestjs.com/v7/security/authentication#jwt-functionality)
* [Implementing Passport JWT](https://docs.nestjs.com/v7/security/authentication#implementing-passport-jwt)
* [Implement protected route and JWT strategy guards](https://docs.nestjs.com/v7/security/authentication#implement-protected-route-and-jwt-strategy-guards)
* [Example](https://docs.nestjs.com/v7/security/authentication#example)
* [Extending guards](https://docs.nestjs.com/v7/security/authentication#extending-guards)
* [Enable authentication globally](https://docs.nestjs.com/v7/security/authentication#enable-authentication-globally)
* [Request-scoped strategies](https://docs.nestjs.com/v7/security/authentication#request-scoped-strategies)
* [Customize Passport](https://docs.nestjs.com/v7/security/authentication#customize-passport)
* [Named strategies](https://docs.nestjs.com/v7/security/authentication#named-strategies)
* [GraphQL](https://docs.nestjs.com/v7/security/authentication#graphql)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/security/authentication.md "Suggest Edits")

```bash

$ npm install --save @nestjs/passport passport passport-local
$ npm install --save-dev @types/passport-local
```

> **Notice** For **any** Passport strategy you choose, you'll always need the `@nestjs/passport` and `passport` packages. Then, you'll need to install the strategy-specific package (e.g., `passport-jwt` or `passport-local`) that implements the particular authentication strategy you are building. In addition, you can also install the type definitions for any Passport strategy, as shown above with `@types/passport-local`, which provides assistance while writing TypeScript code.

```bash

$ nest g module auth
$ nest g service auth
```

As we implement the `AuthService`, we'll find it useful to encapsulate user operations in a `UsersService`, so let's generate that module and service now:

```bash

$ nest g module users
$ nest g service users
```

Replace the default contents of these generated files as shown below. For our sample app, the `UsersService` simply maintains a hard-coded in-memory list of users, and a find method to retrieve one by username. In a real app, this is where you'd build your user model and persistence layer, using your library of choice (e.g., TypeORM, Sequelize, Mongoose, etc.).

users/users.service.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';

// This should be a real class/interface representing a user entity
export type User = any;

@Injectable()
export class UsersService {
  private readonly users = [
    {
      userId: 1,
      username: 'john',
      password: 'changeme',
    },
    {
      userId: 2,
      username: 'maria',
      password: 'guess',
    },
  ];

  async findOne(username: string): Promise<User | undefined> {
    return this.users.find(user => user.username === username);
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';

@Injectable()
export class UsersService {
  constructor() {
    this.users = [
      {
        userId: 1,
        username: 'john',
        password: 'changeme',
      },
      {
        userId: 2,
        username: 'maria',
        password: 'guess',
      },
    ];
  }

  async findOne(username) {
    return this.users.find(user => user.username === username);
  }
}
```

In the `UsersModule`, the only change needed is to add the `UsersService` to the exports array of the `@Module` decorator so that it is visible outside this module (we'll soon use it in our `AuthService`).

users/users.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { UsersService } from './users.service';

@Module({
  providers: [UsersService],
  exports: [UsersService],
})
export class UsersModule {}
```

```typescript

import { Module } from '@nestjs/common';
import { UsersService } from './users.service';

@Module({
  providers: [UsersService],
  exports: [UsersService],
})
export class UsersModule {}
```

Our `AuthService` has the job of retrieving a user and verifying the password. We create a `validateUser()` method for this purpose. In the code below, we use a convenient ES6 spread operator to strip the password property from the user object before returning it. We'll be calling into the `validateUser()` method from our Passport local strategy in a moment.

auth/auth.service.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { UsersService } from '../users/users.service';

@Injectable()
export class AuthService {
  constructor(private usersService: UsersService) {}

  async validateUser(username: string, pass: string): Promise<any> {
    const user = await this.usersService.findOne(username);
    if (user && user.password === pass) {
      const { password, ...result } = user;
      return result;
    }
    return null;
  }
}
```

```typescript

import { Injectable, Dependencies } from '@nestjs/common';
import { UsersService } from '../users/users.service';

@Injectable()
@Dependencies(UsersService)
export class AuthService {
  constructor(usersService) {
    this.usersService = usersService;
  }

  async validateUser(username, pass) {
    const user = await this.usersService.findOne(username);
    if (user && user.password === pass) {
      const { password, ...result } = user;
      return result;
    }
    return null;
  }
}
```

> **Warning** Of course in a real application, you wouldn't store a password in plain text. You'd instead use a library like [bcrypt](https://github.com/kelektiv/node.bcrypt.js#readme), with a salted one-way hash algorithm. With that approach, you'd only store hashed passwords, and then compare the stored password to a hashed version of the **incoming** password, thus never storing or exposing user passwords in plain text. To keep our sample app simple, we violate that absolute mandate and use plain text. **Don't do this in your real app!**

Now, we update our `AuthModule` to import the `UsersModule`.

auth/auth.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { UsersModule } from '../users/users.module';

@Module({
  imports: [UsersModule],
  providers: [AuthService],
})
export class AuthModule {}
```

```typescript

import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { UsersModule } from '../users/users.module';

@Module({
  imports: [UsersModule],
  providers: [AuthService],
})
export class AuthModule {}
```

#### Implementing Passport local[#](/security/authentication#implementing-passport-local)

Now we can implement our Passport **local authentication strategy**. Create a file called `local.strategy.ts` in the `auth` folder, and add the following code:

auth/local.strategy.ts

JS TS

```typescript

import { Strategy } from 'passport-local';
import { PassportStrategy } from '@nestjs/passport';
import { Injectable, UnauthorizedException } from '@nestjs/common';
import { AuthService } from './auth.service';

@Injectable()
export class LocalStrategy extends PassportStrategy(Strategy) {
  constructor(private authService: AuthService) {
    super();
  }

  async validate(username: string, password: string): Promise<any> {
    const user = await this.authService.validateUser(username, password);
    if (!user) {
      throw new UnauthorizedException();
    }
    return user;
  }
}
```

```typescript

import { Strategy } from 'passport-local';
import { PassportStrategy } from '@nestjs/passport';
import { Injectable, UnauthorizedException, Dependencies } from '@nestjs/common';
import { AuthService } from './auth.service';

@Injectable()
@Dependencies(AuthService)
export class LocalStrategy extends PassportStrategy(Strategy) {
  constructor(authService) {
    super();
    this.authService = authService;
  }

  async validate(username, password) {
    const user = await this.authService.validateUser(username, password);
    if (!user) {
      throw new UnauthorizedException();
    }
    return user;
  }
}
```

We've followed the recipe described earlier for all Passport strategies. In our use case with passport-local, there are no configuration options, so our constructor simply calls `super()`, without an options object.

> **Hint** We can pass an options object in the call to `super()` to customize the behavior of the passport strategy. In this example, the passport-local strategy by default expects properties called `username` and `password` in the request body. Pass an options object to specify different property names, for example: `super({ usernameField: 'email' })`. See the [Passport documentation](http://www.passportjs.org/docs/configure/) for more information.

We've also implemented the `validate()` method. For each strategy, Passport will call the verify function (implemented with the `validate()` method in `@nestjs/passport`) using an appropriate strategy-specific set of parameters. For the local-strategy, Passport expects a `validate()` method with the following signature: `validate(username: string, password:string): any`.

Most of the validation work is done in our `AuthService` (with the help of our `UsersService`), so this method is quite straightforward. The `validate()` method for **any** Passport strategy will follow a similar pattern, varying only in the details of how credentials are represented. If a user is found and the credentials are valid, the user is returned so Passport can complete its tasks (e.g., creating the `user` property on the `Request` object), and the request handling pipeline can continue. If it's not found, we throw an exception and let our [exceptions layer](exception-filters) handle it.

Typically, the only significant difference in the `validate()` method for each strategy is **how** you determine if a user exists and is valid. For example, in a JWT strategy, depending on requirements, we may evaluate whether the `userId` carried in the decoded token matches a record in our user database, or matches a list of revoked tokens. Hence, this pattern of sub-classing and implementing strategy-specific validation is consistent, elegant and extensible.

We need to configure our `AuthModule` to use the Passport features we just defined. Update `auth.module.ts` to look like this:

auth/auth.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { UsersModule } from '../users/users.module';
import { PassportModule } from '@nestjs/passport';
import { LocalStrategy } from './local.strategy';

@Module({
  imports: [UsersModule, PassportModule],
  providers: [AuthService, LocalStrategy],
})
export class AuthModule {}
```

```typescript

import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { UsersModule } from '../users/users.module';
import { PassportModule } from '@nestjs/passport';
import { LocalStrategy } from './local.strategy';

@Module({
  imports: [UsersModule, PassportModule],
  providers: [AuthService, LocalStrategy],
})
export class AuthModule {}
```

* **80+ chapters
* **5+ hours of videos
* **Official certificate
* **Deep-dive sessions

[Explore official courses](https://courses.nestjs.com "Courses | NestJS - A node.js framework built on top of TypeScript")

#### Login route[#](/security/authentication#login-route)

With the strategy in place, we can now implement a bare-bones `/auth/login` route, and apply the built-in Guard to initiate the passport-local flow.

Open the `app.controller.ts` file and replace its contents with the following:

app.controller.ts

JS TS

```typescript

import { Controller, Request, Post, UseGuards } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';

@Controller()
export class AppController {
  @UseGuards(AuthGuard('local'))
  @Post('auth/login')
  async login(@Request() req) {
    return req.user;
  }
}
```

```typescript

import { Controller, Bind, Request, Post, UseGuards } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';

@Controller()
export class AppController {
  @UseGuards(AuthGuard('local'))
  @Post('auth/login')
  @Bind(Request())
  async login(req) {
    return req.user;
  }
}
```

With `@UseGuards(AuthGuard('local'))` we are using an `AuthGuard` that `@nestjs/passport`**automatically provisioned** for us when we extended the passport-local strategy. Let's break that down. Our Passport local strategy has a default name of `'local'`. We reference that name in the `@UseGuards()` decorator to associate it with code supplied by the `passport-local` package. This is used to disambiguate which strategy to invoke in case we have multiple Passport strategies in our app (each of which may provision a strategy-specific `AuthGuard`). While we only have one such strategy so far, we'll shortly add a second, so this is needed for disambiguation.

In order to test our route we'll have our `/auth/login` route simply return the user for now. This also lets us demonstrate another Passport feature: Passport automatically creates a `user` object, based on the value we return from the `validate()` method, and assigns it to the `Request` object as `req.user`. Later, we'll replace this with code to create and return a JWT instead.

Since these are API routes, we'll test them using the commonly available [cURL](https://curl.haxx.se/) library. You can test with any of the `user` objects hard-coded in the `UsersService`.

```bash

$ # POST to /auth/login
$ curl -X POST http://localhost:3000/auth/login -d '{"username": "john", "password": "changeme"}' -H "Content-Type: application/json"
$ # result -> {"userId":1,"username":"john"}
```

While this works, passing the strategy name directly to the `AuthGuard()` introduces magic strings in the codebase. Instead, we recommend creating your own class, as shown below:

auth/local-auth.guard.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';

@Injectable()
export class LocalAuthGuard extends AuthGuard('local') {}
```

Now, we can update the `/auth/login` route handler and use the `LocalAuthGuard` instead:

```typescript

@UseGuards(LocalAuthGuard)
@Post('auth/login')
async login(@Request() req) {
  return req.user;
}
```

#### JWT functionality[#](/security/authentication#jwt-functionality)

We're ready to move on to the JWT portion of our auth system. Let's review and refine our requirements:

* Allow users to authenticate with username/password, returning a JWT for use in subsequent calls to protected API endpoints. We're well on our way to meeting this requirement. To complete it, we'll need to write the code that issues a JWT.
* Create API routes which are protected based on the presence of a valid JWT as a bearer token

We'll need to install a couple more packages to support our JWT requirements:

```bash

$ npm install --save @nestjs/jwt passport-jwt
$ npm install --save-dev @types/passport-jwt
```

```typescript

import { Injectable } from '@nestjs/common';
import { UsersService } from '../users/users.service';
import { JwtService } from '@nestjs/jwt';

@Injectable()
export class AuthService {
  constructor(
    private usersService: UsersService,
    private jwtService: JwtService
  ) {}

  async validateUser(username: string, pass: string): Promise<any> {
    const user = await this.usersService.findOne(username);
    if (user && user.password === pass) {
      const { password, ...result } = user;
      return result;
    }
    return null;
  }

  async login(user: any) {
    const payload = { username: user.username, sub: user.userId };
    return {
      access_token: this.jwtService.sign(payload),
    };
  }
}
```

```typescript

import { Injectable, Dependencies } from '@nestjs/common';
import { UsersService } from '../users/users.service';
import { JwtService } from '@nestjs/jwt';

@Dependencies(UsersService, JwtService)
@Injectable()
export class AuthService {
  constructor(usersService, jwtService) {
    this.usersService = usersService;
    this.jwtService = jwtService;
  }

  async validateUser(username, pass) {
    const user = await this.usersService.findOne(username);
    if (user && user.password === pass) {
      const { password, ...result } = user;
      return result;
    }
    return null;
  }

  async login(user) {
    const payload = { username: user.username, sub: user.userId };
    return {
      access_token: this.jwtService.sign(payload),
    };
  }
}
```

We're using the `@nestjs/jwt` library, which supplies a `sign()` function to generate our JWT from a subset of the `user` object properties, which we then return as a simple object with a single `access_token` property. Note: we choose a property name of `sub` to hold our `userId` value to be consistent with JWT standards. Don't forget to inject the JwtService provider into the `AuthService`.

We now need to update the `AuthModule` to import the new dependencies and configure the `JwtModule`.

First, create `constants.ts` in the `auth` folder, and add the following code:

auth/constants.ts

JS TS

```typescript

export const jwtConstants = {
  secret: 'secretKey',
};
```

```typescript

export const jwtConstants = {
  secret: 'secretKey',
};
```

We'll use this to share our key between the JWT signing and verifying steps.

> **Warning****Do not expose this key publicly**. We have done so here to make it clear what the code is doing, but in a production system **you must protect this key** using appropriate measures such as a secrets vault, environment variable, or configuration service.

Now, open `auth.module.ts` in the `auth` folder and update it to look like this:

auth/auth.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { LocalStrategy } from './local.strategy';
import { UsersModule } from '../users/users.module';
import { PassportModule } from '@nestjs/passport';
import { JwtModule } from '@nestjs/jwt';
import { jwtConstants } from './constants';

@Module({
  imports: [
    UsersModule,
    PassportModule,
    JwtModule.register({
      secret: jwtConstants.secret,
      signOptions: { expiresIn: '60s' },
    }),
  ],
  providers: [AuthService, LocalStrategy],
  exports: [AuthService, JwtModule],
})
export class AuthModule {}
```

```typescript

import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { LocalStrategy } from './local.strategy';
import { UsersModule } from '../users/users.module';
import { PassportModule } from '@nestjs/passport';
import { JwtModule } from '@nestjs/jwt';
import { jwtConstants } from './constants';

@Module({
  imports: [
    UsersModule,
    PassportModule,
    JwtModule.register({
      secret: jwtConstants.secret,
      signOptions: { expiresIn: '60s' },
    }),
  ],
  providers: [AuthService, LocalStrategy],
  exports: [AuthService],
})
export class AuthModule {}
```

We configure the `JwtModule` using `register()`, passing in a configuration object. See [here](https://github.com/nestjs/jwt/blob/master/README.md) for more on the Nest `JwtModule` and [here](https://github.com/auth0/node-jsonwebtoken#usage) for more details on the available configuration options.

Now we can update the `/auth/login` route to return a JWT.

app.controller.ts

JS TS

```typescript

import { Controller, Request, Post, UseGuards } from '@nestjs/common';
import { LocalAuthGuard } from './auth/local-auth.guard';
import { AuthService } from './auth/auth.service';

@Controller()
export class AppController {
  constructor(private authService: AuthService) {}

  @UseGuards(LocalAuthGuard)
  @Post('auth/login')
  async login(@Request() req) {
    return this.authService.login(req.user);
  }
}
```

```typescript

import { Controller, Bind, Request, Post, UseGuards } from '@nestjs/common';
import { LocalAuthGuard } from './auth/local-auth.guard';
import { AuthService } from './auth/auth.service';

@Controller()
export class AppController {
  constructor(private authService: AuthService) {}

  @UseGuards(LocalAuthGuard)
  @Post('auth/login')
  @Bind(Request())
  async login(req) {
    return this.authService.login(req.user);
  }
}
```

Let's go ahead and test our routes using cURL again. You can test with any of the `user` objects hard-coded in the `UsersService`.

```bash

$ # POST to /auth/login
$ curl -X POST http://localhost:3000/auth/login -d '{"username": "john", "password": "changeme"}' -H "Content-Type: application/json"
$ # result -> {"access_token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."}
$ # Note: above JWT truncated
```

#### Implementing Passport JWT[#](/security/authentication#implementing-passport-jwt)

We can now address our final requirement: protecting endpoints by requiring a valid JWT be present on the request. Passport can help us here too. It provides the [passport-jwt](https://github.com/mikenicholson/passport-jwt) strategy for securing RESTful endpoints with JSON Web Tokens. Start by creating a file called `jwt.strategy.ts` in the `auth` folder, and add the following code:

auth/jwt.strategy.ts

JS TS

```typescript

import { ExtractJwt, Strategy } from 'passport-jwt';
import { PassportStrategy } from '@nestjs/passport';
import { Injectable } from '@nestjs/common';
import { jwtConstants } from './constants';

@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
  constructor() {
    super({
      jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
      ignoreExpiration: false,
      secretOrKey: jwtConstants.secret,
    });
  }

  async validate(payload: any) {
    return { userId: payload.sub, username: payload.username };
  }
}
```

```typescript

import { ExtractJwt, Strategy } from 'passport-jwt';
import { PassportStrategy } from '@nestjs/passport';
import { Injectable } from '@nestjs/common';
import { jwtConstants } from './constants';

@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
  constructor() {
    super({
      jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
      ignoreExpiration: false,
      secretOrKey: jwtConstants.secret,
    });
  }

  async validate(payload) {
    return { userId: payload.sub, username: payload.username };
  }
}
```

```typescript

import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { LocalStrategy } from './local.strategy';
import { JwtStrategy } from './jwt.strategy';
import { UsersModule } from '../users/users.module';
import { PassportModule } from '@nestjs/passport';
import { JwtModule } from '@nestjs/jwt';
import { jwtConstants } from './constants';

@Module({
  imports: [
    UsersModule,
    PassportModule,
    JwtModule.register({
      secret: jwtConstants.secret,
      signOptions: { expiresIn: '60s' },
    }),
  ],
  providers: [AuthService, LocalStrategy, JwtStrategy],
  exports: [AuthService],
})
export class AuthModule {}
```

```typescript

import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { LocalStrategy } from './local.strategy';
import { JwtStrategy } from './jwt.strategy';
import { UsersModule } from '../users/users.module';
import { PassportModule } from '@nestjs/passport';
import { JwtModule } from '@nestjs/jwt';
import { jwtConstants } from './constants';

@Module({
  imports: [
    UsersModule,
    PassportModule,
    JwtModule.register({
      secret: jwtConstants.secret,
      signOptions: { expiresIn: '60s' },
    }),
  ],
  providers: [AuthService, LocalStrategy, JwtStrategy],
  exports: [AuthService],
})
export class AuthModule {}
```

By importing the same secret used when we signed the JWT, we ensure that the **verify** phase performed by Passport, and the **sign** phase performed in our AuthService, use a common secret.

Finally, we define the `JwtAuthGuard` class which extends the built-in `AuthGuard`:

auth/jwt-auth.guard.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';

@Injectable()
export class JwtAuthGuard extends AuthGuard('jwt') {}
```

#### Implement protected route and JWT strategy guards[#](/security/authentication#implement-protected-route-and-jwt-strategy-guards)

We can now implement our protected route and its associated Guard.

Open the `app.controller.ts` file and update it as shown below:

app.controller.ts

JS TS

```typescript

import { Controller, Get, Request, Post, UseGuards } from '@nestjs/common';
import { JwtAuthGuard } from './auth/jwt-auth.guard';
import { LocalAuthGuard } from './auth/local-auth.guard';
import { AuthService } from './auth/auth.service';

@Controller()
export class AppController {
  constructor(private authService: AuthService) {}

  @UseGuards(LocalAuthGuard)
  @Post('auth/login')
  async login(@Request() req) {
    return this.authService.login(req.user);
  }

  @UseGuards(JwtAuthGuard)
  @Get('profile')
  getProfile(@Request() req) {
    return req.user;
  }
}
```

```typescript

import { Controller, Dependencies, Bind, Get, Request, Post, UseGuards } from '@nestjs/common';
import { JwtAuthGuard } from './auth/jwt-auth.guard';
import { LocalAuthGuard } from './auth/local-auth.guard';
import { AuthService } from './auth/auth.service';

@Dependencies(AuthService)
@Controller()
export class AppController {
  constructor(authService) {
    this.authService = authService;
  }

  @UseGuards(LocalAuthGuard)
  @Post('auth/login')
  @Bind(Request())
  async login(req) {
    return this.authService.login(req.user);
  }

  @UseGuards(JwtAuthGuard)
  @Get('profile')
  @Bind(Request())
  getProfile(req) {
    return req.user;
  }
}
```

Once again, we're applying the `AuthGuard` that the `@nestjs/passport` module has automatically provisioned for us when we configured the passport-jwt module. This Guard is referenced by its default name, `jwt`. When our `GET /profile` route is hit, the Guard will automatically invoke our passport-jwt custom configured logic, validating the JWT, and assigning the `user` property to the `Request` object.

Ensure the app is running, and test the routes using `cURL`.

```bash

$ # GET /profile
$ curl http://localhost:3000/profile
$ # result -> {"statusCode":401,"error":"Unauthorized"}

$ # POST /auth/login
$ curl -X POST http://localhost:3000/auth/login -d '{"username": "john", "password": "changeme"}' -H "Content-Type: application/json"
$ # result -> {"access_token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2Vybm... }

$ # GET /profile using access_token returned from previous step as bearer code
$ curl http://localhost:3000/profile -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2Vybm..."
$ # result -> {"userId":1,"username":"john"}
```

Note that in the `AuthModule`, we configured the JWT to have an expiration of `60 seconds`. This is probably too short an expiration, and dealing with the details of token expiration and refresh is beyond the scope of this article. However, we chose that to demonstrate an important quality of JWTs and the passport-jwt strategy. If you wait 60 seconds after authenticating before attempting a `GET /profile` request, you'll receive a `401 Unauthorized` response. This is because Passport automatically checks the JWT for its expiration time, saving you the trouble of doing so in your application.

We've now completed our JWT authentication implementation. JavaScript clients (such as Angular/React/Vue), and other JavaScript apps, can now authenticate and communicate securely with our API Server.

#### Example[#](/security/authentication#example)

You can find a complete version of the code in this chapter [here](https://github.com/nestjs/nest/tree/master/sample/19-auth-jwt).

#### Extending guards[#](/security/authentication#extending-guards)

In most cases, using a provided `AuthGuard` class is sufficient. However, there might be use-cases when you would like to simply extend the default error handling or authentication logic. For this, you can extend the built-in class and override methods within a sub-class.

```typescript

import {
  ExecutionContext,
  Injectable,
  UnauthorizedException,
} from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';

@Injectable()
export class JwtAuthGuard extends AuthGuard('jwt') {
  canActivate(context: ExecutionContext) {
    // Add your custom authentication logic here
    // for example, call super.logIn(request) to establish a session.
    return super.canActivate(context);
  }

  handleRequest(err, user, info) {
    // You can throw an exception based on either "info" or "err" arguments
    if (err || !user) {
      throw err || new UnauthorizedException();
    }
    return user;
  }
}
```

In addition to extending the default error handling and authentication logic, we can allow authentication to go through a chain of strategies. The first strategy to succeed, redirect, or error will halt the chain. Authentication failures will proceed through each strategy in series, ultimately failing if all strategies fail.

```typescript

export class JwtAuthGuard extends AuthGuard(['strategy_jwt_1', 'strategy_jwt_2', '...']) { ... }
```

#### Enable authentication globally[#](/security/authentication#enable-authentication-globally)

If the vast of your endpoints should be protected by default, you can register the authentication guard as a [global guard](/guards#binding-guards) and instead of using `@UseGuards()` decorator on top of each controller, you could simply flag which routes should be public.

First, register the `JwtAuthGuard` as a global guard using the following construction (in any module):

```typescript

providers: [
  {
    provide: APP_GUARD,
    useClass: JwtAuthGuard,
  },
],
```

With this in place, Nest will automatically bind `JwtAuthGuard` to all endpoints.

Now we must provide a mechanism for declaring routes as public. For this, we can create a custom decorator using the `SetMetadata` decorator factory function.

```typescript

import { SetMetadata } from '@nestjs/common';

export const IS_PUBLIC_KEY = 'isPublic';
export const Public = () => SetMetadata(IS_PUBLIC_KEY, true);
```

In the file above, we exported two constants. One being our metadata key named `IS_PUBLIC_KEY`, and the other being our new decorator itself that we’re going to call `Public` (you can alternatively name it `SkipAuth` or `AllowAnon`, whatever fits your project).

Now that we have a custom `@Public()` decorator, we can use it to decorate any method, as follows:

```typescript

@Public()
@Get()
findAll() {
  return [];
}
```

Lastly, we need the `JwtAuthGuard` to return `true` when the `"isPublic"` metadata is found. For this, we'll use the `Reflector` class (read more [here](/guards#putting-it-all-together)).

```typescript

@Injectable()
export class JwtAuthGuard extends AuthGuard('jwt') {
  constructor(private reflector: Reflector) {
    super();
  }

  canActivate(context: ExecutionContext) {
    const isPublic = this.reflector.getAllAndOverride<boolean>(IS_PUBLIC_KEY, [
      context.getHandler(),
      context.getClass(),
    ]);
    if (isPublic) {
      return true;
    }
    return super.canActivate(context);
  }
}
```

#### Request-scoped strategies[#](/security/authentication#request-scoped-strategies)

The passport API is based on registering strategies to the global instance of the library. Therefore strategies are not designed to have request-dependent options or to be dynamically instantiated per request (read more about the [request-scoped](/v7/fundamentals/injection-scopes) providers). When you configure your strategy to be request-scoped, Nest will never instantiate it since it's not tied to any specific route. There is no physical way to determine which "request-scoped" strategies should be executed per request.

However, there are ways to dynamically resolve request-scoped providers within the strategy. For this, we leverage the [module reference](/v7/fundamentals/module-ref) feature.

First, open the `local.strategy.ts` file and inject the `ModuleRef` in the normal way:

```typescript

constructor(private moduleRef: ModuleRef) {
  super({
    passReqToCallback: true,
  });
}
```

> **Hint** The `ModuleRef` class is imported from the `@nestjs/core` package.

Be sure to set the `passReqToCallback` configuration property to `true`, as shown above.

In the next step, the request instance will be used to obtain the current context identifier, instead of generating a new one (read more about request context [here](/fundamentals/module-ref#getting-current-sub-tree)).

Now, inside the `validate()` method of the `LocalStrategy` class, use the `getByRequest()` method of the `ContextIdFactory` class to create a context id based on the request object, and pass this to the `resolve()` call:

```typescript

async validate(
  request: Request,
  username: string,
  password: string,
) {
  const contextId = ContextIdFactory.getByRequest(request);
  // "AuthService" is a request-scoped provider
  const authService = await this.moduleRef.resolve(AuthService, contextId);
  ...
}
```

In the example above, the `resolve()` method will asynchronously return the request-scoped instance of the `AuthService` provider (we assumed that `AuthService` is marked as a request-scoped provider).

#### Customize Passport[#](/security/authentication#customize-passport)

Any standard Passport customization options can be passed the same way, using the `register()` method. The available options depend on the strategy being implemented. For example:

```typescript

PassportModule.register({ session: true });
```

You can also pass strategies an options object in their constructors to configure them. For the local strategy you can pass e.g.:

```typescript

constructor(private authService: AuthService) {
  super({
    usernameField: 'email',
    passwordField: 'password',
  });
}
```

Take a look at the official [Passport Website](http://www.passportjs.org/docs/oauth/) for property names.

#### Named strategies[#](/security/authentication#named-strategies)

When implementing a strategy, you can provide a name for it by passing a second argument to the `PassportStrategy` function. If you don't do this, each strategy will have a default name (e.g., 'jwt' for jwt-strategy):

```typescript

export class JwtStrategy extends PassportStrategy(Strategy, 'myjwt')
```

Then, you refer to this via a decorator like `@UseGuards(AuthGuard('myjwt'))`.

#### GraphQL[#](/security/authentication#graphql)

In order to use an AuthGuard with [GraphQL](https://docs.nestjs.com/graphql/quick-start), extend the built-in AuthGuard class and override the getRequest() method.

```typescript

@Injectable()
export class GqlAuthGuard extends AuthGuard('jwt') {
  getRequest(context: ExecutionContext) {
    const ctx = GqlExecutionContext.create(context);
    return ctx.getContext().req;
  }
}
```

To get the current authenticated user in your graphql resolver, you can define a `@CurrentUser()` decorator:

```typescript

import { createParamDecorator, ExecutionContext } from '@nestjs/common';
import { GqlExecutionContext } from '@nestjs/graphql';

export const CurrentUser = createParamDecorator(
  (data: unknown, context: ExecutionContext) => {
    const ctx = GqlExecutionContext.create(context);
    return ctx.getContext().req.user;
  },
);
```

To use above decorator in your resolver, be sure to include it as a parameter of your query or mutation:

```typescript

@Query(returns => User)
@UseGuards(GqlAuthGuard)
whoAmI(@CurrentUser() user: User) {
  return this.usersService.findById(user.id);
}
```

----
url: https://docs.nestjs.com/v6/microservices/nats
----

* [NATS](https://docs.nestjs.com/v6/microservices/nats#nats)
* [Installation](https://docs.nestjs.com/v6/microservices/nats#installation)
* [Overview](https://docs.nestjs.com/v6/microservices/nats#overview)
* [Options](https://docs.nestjs.com/v6/microservices/nats#options)
* [Client](https://docs.nestjs.com/v6/microservices/nats#client)
* [Request-response](https://docs.nestjs.com/v6/microservices/nats#request-response)
* [Event-based](https://docs.nestjs.com/v6/microservices/nats#event-based)
* [Queue groups](https://docs.nestjs.com/v6/microservices/nats#queue-groups)
* [Context](https://docs.nestjs.com/v6/microservices/nats#context)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/microservices/nats.md "Suggest Edits")

### NATS

[NATS](https://nats.io) is a simple, secure and high performance open source messaging system for cloud native applications, IoT messaging, and microservices architectures. The NATS server is written in the Go programming language, but client libraries to interact with the server are available for dozens of major programming languages. NATS supports both **At Most Once** and **At Least Once** delivery. It can run anywhere, from large servers and cloud instances, through edge gateways and even Internet of Things devices.

#### Installation[#](/microservices/nats#installation)

To start building NATS-based microservices, first install the required package:

```bash

$ npm i --save nats
```

#### Overview[#](/microservices/nats#overview)

To use the NATS transporter, pass the following options object to the `createMicroservice()` method:

main.ts

JS TS

```typescript

const app = await NestFactory.createMicroservice(ApplicationModule, {
  transport: Transport.NATS,
  options: {
    url: 'nats://localhost:4222',
  },
});
```

> **Hint** The `Transport` enum is imported from the `@nestjs/microservices` package.

#### Options[#](/microservices/nats#options)

The `options` object is specific to the chosen transporter. The **NATS** transporter exposes the properties described [here](https://github.com/nats-io/node-nats#connect-options). Additionally, there is a `queue` property which allows you to specify the name of the queue that your server should subscribe to (leave `undefined` to ignore this setting). Read more about NATS queue groups [below](https://docs.nestjs.com/microservices/nats#queue-groups).

#### Client[#](/microservices/nats#client)

Like other microservice transporters, you have [several options](https://docs.nestjs.com/microservices/basics#client) for creating a NATS `ClientProxy` instance.

One method for creating an instance is to use use the `ClientsModule`. To create a client instance with the `ClientsModule`, import it and use the `register()` method to pass an options object with the same properties shown above in the `createMicroservice()` method, as well as a `name` property to be used as the injection token. Read more about `ClientsModule`[here](https://docs.nestjs.com/microservices/basics#client).

```typescript

@Module({
  imports: [
    ClientsModule.register([
      {
        name: 'MATH_SERVICE',
        transport: Transport.NATS,
        options: {
          url: 'nats://localhost:4222',
        }
      },
    ]),
  ]
  ...
})
```

```typescript

const app = await NestFactory.createMicroservice(ApplicationModule, {
  transport: Transport.NATS,
  options: {
    url: 'nats://localhost:4222',
    queue: 'cats_queue',
  },
});
```

#### Context[#](/microservices/nats#context)

In more sophisticated scenarios, you may want to access more information about the incoming request. When using the NATS transporter, you can access the `NatsContext` object.

JS TS

```typescript

@MessagePattern('notifications')
getNotifications(@Payload() data: number[], @Ctx() context: NatsContext) {
  console.log(`Subject: ${context.getSubject()}`);
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('notifications')
getNotifications(data, context) {
  console.log(`Subject: ${context.getSubject()}`);
}
```

> **Hint**`@Payload()`, `@Ctx()` and `NatsContext` are imported from the `@nestjs/microservices` package.

----
url: https://docs.nestjs.com/fundamentals/circular-dependency
----

[Skip to content](#content)

On this page

* [Circular dependency](https://docs.nestjs.com/fundamentals/circular-dependency#circular-dependency)
* [Forward reference](https://docs.nestjs.com/fundamentals/circular-dependency#forward-reference)
* [ModuleRef class alternative](https://docs.nestjs.com/fundamentals/circular-dependency#moduleref-class-alternative)
* [Module forward reference](https://docs.nestjs.com/fundamentals/circular-dependency#module-forward-reference)

[](https://srv.carbonads.net/ads/click/x/GTND4277CVSD5KJUCAYLYKQUF67D62Q7CW7DTZ3JCAAI6KQJCASI4KQKCKBIE2JICWADE27UCY7D65Q7CYBD6Z3JCAAI627ECVADTK3K2JWNABY)[Architectural guidance, code that runs. Free, for all levels. Start building ](https://srv.carbonads.net/ads/click/x/GTND4277CVSD5KJUCAYLYKQUF67D62Q7CW7DTZ3JCAAI6KQJCASI4KQKCKBIE2JICWADE27UCY7D65Q7CYBD6Z3JCAAI627ECVADTK3K2JWNABY)[ads via Carbon](http://carbonads.net/?utm_source=nestjscom\&utm_medium=ad_via_link\&utm_campaign=in_unit\&utm_term=carbon)

### Circular dependency

A circular dependency occurs when two classes depend on each other. For example, class A needs class B, and class B also needs class A. Circular dependencies can arise in Nest between modules and between providers.

Avoid circular dependencies where possible, but you can't always do so. In such cases, Nest lets you resolve circular dependencies between providers in two ways: with **forward referencing**, or by using the **ModuleRef** class to retrieve a provider instance from the DI container. This chapter describes both techniques, as well as how to resolve circular dependencies between modules.

> **Warning** A circular dependency can also be caused by using "barrel files" (`index.ts` files) to group imports. Avoid barrel files for module and provider classes. In particular, don't use a barrel file to import files within the same directory as the barrel file, i.e., `cats/cats.controller` should not import `cats` to import the `cats/cats.service` file. For more details, see [this GitHub issue on barrel files and circular dependencies](https://github.com/nestjs/nest/issues/1181#issuecomment-430197191).

#### Forward reference[#](/fundamentals/circular-dependency#forward-reference)

A **forward reference**, created with the `forwardRef()` utility function, lets Nest reference classes that aren't defined yet. For example, if `CatsService` and `CommonService` depend on each other, both sides of the relationship can use `@Inject()` and the `forwardRef()` utility to resolve the circular dependency. Otherwise, Nest won't instantiate them, because not all of the essential metadata will be available. Here's an example:

cats.service.ts

JS TS

```typescript

@Injectable()
export class CatsService {
  constructor(
    @Inject(forwardRef(() => CommonService))
    private commonService: CommonService,
  ) {}
}
```

```typescript

@Injectable()
@Dependencies(forwardRef(() => CommonService))
export class CatsService {
  constructor(commonService) {
    this.commonService = commonService;
  }
}
```

> **Hint** The `forwardRef()` function is imported from the `@nestjs/common` package.

That covers one side of the relationship. Now do the same with `CommonService`:

common.service.ts

JS TS

```typescript

@Injectable()
export class CommonService {
  constructor(
    @Inject(forwardRef(() => CatsService))
    private catsService: CatsService,
  ) {}
}
```

```typescript

@Injectable()
@Dependencies(forwardRef(() => CatsService))
export class CommonService {
  constructor(catsService) {
    this.catsService = catsService;
  }
}
```

> **Warning** The order of instantiation is indeterminate. Make sure your code does not depend on which constructor is called first. Circular dependencies that depend on providers with `Scope.REQUEST` can lead to undefined dependencies. See [this GitHub issue on request-scoped circular dependencies](https://github.com/nestjs/nest/issues/5778) for more information.

#### ModuleRef class alternative[#](/fundamentals/circular-dependency#moduleref-class-alternative)

An alternative to `forwardRef()` is to refactor your code and use the `ModuleRef` class to retrieve a provider on one side of the (otherwise) circular relationship. Learn more about the `ModuleRef` utility class in the [module reference](/fundamentals/module-ref) chapter.

#### Module forward reference[#](/fundamentals/circular-dependency#module-forward-reference)

To resolve circular dependencies between modules, use the same `forwardRef()` utility function on both sides of the module association. For example:

common.module.ts

JS TS

```typescript

@Module({
  imports: [forwardRef(() => CatsModule)],
})
export class CommonModule {}
```

That covers one side of the relationship. Now do the same with `CatsModule`:

cats.module.ts

JS TS

```typescript

@Module({
  imports: [forwardRef(() => CommonModule)],
})
export class CatsModule {}
```

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/fundamentals/circular-dependency.md)

----
url: https://docs.nestjs.com/v9/techniques/events
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Events](https://docs.nestjs.com/v9/techniques/events#events)
* [Getting started](https://docs.nestjs.com/v9/techniques/events#getting-started)
* [Dispatching Events](https://docs.nestjs.com/v9/techniques/events#dispatching-events)
* [Listening to Events](https://docs.nestjs.com/v9/techniques/events#listening-to-events)
* [Example](https://docs.nestjs.com/v9/techniques/events#example)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/techniques/events.md "Suggest Edits")

### Events

[Event Emitter](https://www.npmjs.com/package/@nestjs/event-emitter) package (`@nestjs/event-emitter`) provides a simple observer implementation, allowing you to subscribe and listen for various events that occur in your application. Events serve as a great way to decouple various aspects of your application, since a single event can have multiple listeners that do not depend on each other.

`EventEmitterModule` internally uses the [eventemitter2](https://github.com/EventEmitter2/EventEmitter2) package.

#### Getting started[#](/techniques/events#getting-started)

First install the required package:

```shell

$ npm i --save @nestjs/event-emitter
```

Once the installation is complete, import the `EventEmitterModule` into the root `AppModule` and run the `forRoot()` static method as shown below:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { EventEmitterModule } from '@nestjs/event-emitter';

@Module({
  imports: [
    EventEmitterModule.forRoot()
  ],
})
export class AppModule {}
```

The `.forRoot()` call initializes the event emitter and registers any declarative event listeners that exist within your app. Registration occurs when the `onApplicationBootstrap` lifecycle hook occurs, ensuring that all modules have loaded and declared any scheduled jobs.

To configure the underlying `EventEmitter` instance, pass the configuration object to the `.forRoot()` method, as follows:

```typescript

EventEmitterModule.forRoot({
  // set this to `true` to use wildcards
  wildcard: false,
  // the delimiter used to segment namespaces
  delimiter: '.',
  // set this to `true` if you want to emit the newListener event
  newListener: false,
  // set this to `true` if you want to emit the removeListener event
  removeListener: false,
  // the maximum amount of listeners that can be assigned to an event
  maxListeners: 10,
  // show event name in memory leak message when more than maximum amount of listeners is assigned
  verboseMemoryLeak: false,
  // disable throwing uncaughtException if an error event is emitted and it has no listeners
  ignoreErrors: false,
});
```

#### Dispatching Events[#](/techniques/events#dispatching-events)

To dispatch (i.e., fire) an event, first inject `EventEmitter2` using standard constructor injection:

```typescript

constructor(private eventEmitter: EventEmitter2) {}
```

> **Hint** Import the `EventEmitter2` from the `@nestjs/event-emitter` package.

Then use it in a class as follows:

```typescript

this.eventEmitter.emit(
  'order.created',
  new OrderCreatedEvent({
    orderId: 1,
    payload: {},
  }),
);
```

#### Listening to Events[#](/techniques/events#listening-to-events)

To declare an event listener, decorate a method with the `@OnEvent()` decorator preceding the method definition containing the code to be executed, as follows:

```typescript

@OnEvent('order.created')
handleOrderCreatedEvent(payload: OrderCreatedEvent) {
  // handle and process "OrderCreatedEvent" event
}
```

> **Warning** Event subscribers cannot be request-scoped.

The first argument can be a `string` or `symbol` for a simple event emitter and a `string | symbol | Array<string | symbol>` in a case of a wildcard emitter. The second argument (optional) is a listener options object ([read more](https://github.com/EventEmitter2/EventEmitter2#emitteronevent-listener-options-objectboolean)).

```typescript

@OnEvent('order.created', { async: true })
handleOrderCreatedEvent(payload: OrderCreatedEvent) {
  // handle and process "OrderCreatedEvent" event
}
```

To use namespaces/wildcards, pass the `wildcard` option into the `EventEmitterModule#forRoot()` method. When namespaces/wildcards are enabled, events can either be strings (`foo.bar`) separated by a delimiter or arrays (`['foo', 'bar']`). The delimiter is also configurable as a configuration property (`delimiter`). With namespaces feature enabled, you can subscribe to events using a wildcard:

```typescript

@OnEvent('order.*')
handleOrderEvents(payload: OrderCreatedEvent | OrderRemovedEvent | OrderUpdatedEvent) {
  // handle and process an event
}
```

Note that such a wildcard only applies to one block. The argument `order.*` will match, for example, the events `order.created` and `order.shipped` but not `order.delayed.out_of_stock`. In order to listen to such events, use the `multilevel wildcard` pattern (i.e, `**`), described in the `EventEmitter2`[documentation](https://github.com/EventEmitter2/EventEmitter2#multi-level-wildcards).

With this pattern, you can, for example, create an event listener that catches all events.

```typescript

@OnEvent('**')
handleEverything(payload: any) {
  // handle and process an event
}
```

> **Hint**`EventEmitter2` class provides several useful methods for interacting with events, like `waitFor` and `onAny`. You can read more about them [here](https://github.com/EventEmitter2/EventEmitter2).

#### Example[#](/techniques/events#example)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/30-event-emitter).

----
url: https://docs.nestjs.com/v8/recipes/nest-commander
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Nest Commander](https://docs.nestjs.com/v8/recipes/nest-commander#nest-commander)
* [Installation](https://docs.nestjs.com/v8/recipes/nest-commander#installation)
* [A Command file](https://docs.nestjs.com/v8/recipes/nest-commander#a-command-file)
* [Running the Command](https://docs.nestjs.com/v8/recipes/nest-commander#running-the-command)
* [Testing](https://docs.nestjs.com/v8/recipes/nest-commander#testing)
* [Putting it all together](https://docs.nestjs.com/v8/recipes/nest-commander#putting-it-all-together)
* [More Information](https://docs.nestjs.com/v8/recipes/nest-commander#more-information)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/recipes/nest-commander.md "Suggest Edits")

### Nest Commander

Expanding on the [standalone application](/v8/standalone-applications) docs there's also the [nest-commander](https://jmcdo29.github.io/nest-commander) package for writing command line applications in a structure similar to your typical Nest application.

> **info**`nest-commander` is a third party package and is not managed by the entirety of the NestJS core team. Please, report any issues found with the library in the [appropriate repository](https://github.com/jmcdo29/nest-commander/issues/new/choose)

#### Installation[#](/recipes/nest-commander#installation)

Just like any other package, you've got to install it before you can use it.

```bash

$ npm i nest-commander
```

#### A Command file[#](/recipes/nest-commander#a-command-file)

`nest-commander` makes it easy to write new command-line applications with [decorators](https://www.typescriptlang.org/docs/handbook/decorators.html) via the `@Command()` decorator for classes and the `@Option()` decorator for methods of that class. Every command file should implement the `CommandRunner` interface and should be decorated with a `@Command()` decorator.

Every command is seen as an `@Injectable()` by Nest, so your normal Dependency Injection still works as you would expect it to. The only thing to take note of is the interface `CommandRunner`, which should be implemented by each command. The `CommandRunner` interface ensures that all commands have a `run` method that returns a `Promise<void>` and takes in the parameters `string[], Record<string, any>`. The `run` command is where you can kick all of your logic off from, it will take in whatever parameters did not match option flags and pass them in as an array, just in case you are really meaning to work with multiple parameters. As for the options, the `Record<string, any>`, the names of these properties match the `name` property given to the `@Option()` decorators, while their value matches the return of the option handler. If you'd like better type safety, you are welcome to create an interface for your options as well.

#### Running the Command[#](/recipes/nest-commander#running-the-command)

Similar to how in a NestJS application we can use the `NestFactory` to create a server for us, and run it using `listen`, the `nest-commander` package exposes a simple to use API to run your server. Import the `CommandFactory` and use the `static` method `run` and pass in the root module of your application. This would probably look like below

```ts

import { CommandFactory } from 'nest-commander';
import { AppModule } from './app.module';

async function bootstrap() {
  await CommandFactory.run(AppModule);
}

bootstrap();
```

By default, Nest's logger is disabled when using the `CommandFactory`. It's possible to provide it though, as the second argument to the `run` function. You can either provide a custom NestJS logger, or an array of log levels you want to keep - it might be useful to at least provide `['error']` here, if you only want to print out Nest's error logs.

```ts

import { CommandFactory } from 'nest-commander';
import { AppModule } from './app.module';
import { LogService } './log.service';

async function bootstrap() {
  await CommandFactory.run(AppModule, new LogService());

  // or, if you only want to print Nest's warnings and errors
  await CommandFactory.run(AppModule, ['warn', 'error']);
}

bootstrap();
```

And that's it. Under the hood, `CommandFactory` will worry about calling `NestFactory` for you and calling `app.close()` when necessary, so you shouldn't need to worry about memory leaks there. If you need to add in some error handling, there's always `try/catch` wrapping the `run` command, or you can chain on some `.catch()` method to the `bootstrap()` call.

#### Testing[#](/recipes/nest-commander#testing)

So what's the use of writing a super awesome command line script if you can't test it super easily, right? Fortunately, `nest-commander` has some utilities you can make use of that fits in perfectly with the NestJS ecosystem, it'll feel right at home to any Nestlings out there. Instead of using the `CommandFactory` for building the command in test mode, you can use `CommandTestFactory` and pass in your metadata, very similarly to how `Test.createTestingModule` from `@nestjs/testing` works. In fact, it uses this package under the hood. You're also still able to chain on the `overrideProvider` methods before calling `compile()` so you can swap out DI pieces right in the test.

#### Putting it all together[#](/recipes/nest-commander#putting-it-all-together)

The following class would equate to having a CLI command that can take in the subcommand `basic` or be called directly, with `-n`, `-s`, and `-b` (along with their long flags) all being supported and with custom parsers for each option. The `--help` flag is also supported, as is customary with commander.

```ts

import { Command, CommandRunner, Option } from 'nest-commander';
import { LogService } from './log.service';

interface BasicCommandOptions {
  string?: string;
  boolean?: boolean;
  number?: number;
}

@Command({ name: 'basic', description: 'A parameter parse' })
export class BasicCommand implements CommandRunner {
  constructor(private readonly logService: LogService) {}

  async run(
    passedParam: string[],
    options?: BasicCommandOptions,
  ): Promise<void> {
    if (options?.boolean !== undefined && options?.boolean !== null) {
      this.runWithBoolean(passedParam, options.boolean);
    } else if (options?.number) {
      this.runWithNumber(passedParam, options.number);
    } else if (options?.string) {
      this.runWithString(passedParam, options.string);
    } else {
      this.runWithNone(passedParam);
    }
  }

  @Option({
    flags: '-n, --number [number]',
    description: 'A basic number parser',
  })
  parseNumber(val: string): number {
    return Number(val);
  }

  @Option({
    flags: '-s, --string [string]',
    description: 'A string return',
  })
  parseString(val: string): string {
    return val;
  }

  @Option({
    flags: '-b, --boolean [boolean]',
    description: 'A boolean parser',
  })
  parseBoolean(val: string): boolean {
    return JSON.parse(val);
  }

  runWithString(param: string[], option: string): void {
    this.logService.log({ param, string: option });
  }

  runWithNumber(param: string[], option: number): void {
    this.logService.log({ param, number: option });
  }

  runWithBoolean(param: string[], option: boolean): void {
    this.logService.log({ param, boolean: option });
  }

  runWithNone(param: string[]): void {
    this.logService.log({ param });
  }
}
```

Make sure the command class is added to a module

```ts

@Module({
  providers: [LogService, BasicCommand],
})
export class AppModule {}
```

And now to be able to run the CLI in your main.ts you can do the following

```ts

async function bootstrap() {
  await CommandFactory.run(AppModule);
}

bootstrap();
```

And just like that, you've got a command line application.

#### More Information[#](/recipes/nest-commander#more-information)

Visit the [nest-commander docs site](https://jmcdo29.github.io/nest-commander) for more information, examples, and API documentation.

----
url: https://docs.nestjs.com/v11/security/csrf
----

* [CSRF Protection](https://docs.nestjs.com/v11/security/csrf#csrf-protection)
* [Use with Express (default)](https://docs.nestjs.com/v11/security/csrf#use-with-express-default)
* [Use with Fastify](https://docs.nestjs.com/v11/security/csrf#use-with-fastify)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/security/csrf.md "Suggest Edits")

### CSRF Protection

Cross-site request forgery (CSRF or XSRF) is a type of attack where **unauthorized** commands are sent from a trusted user to a web application. To help prevent this, you can use the [csrf-csrf](https://github.com/Psifi-Solutions/csrf-csrf) package.

#### Use with Express (default)[#](/security/csrf#use-with-express-default)

Start by installing the required package:

```bash

$ npm i csrf-csrf
```

> **Warning** As noted in the [csrf-csrf documentation](https://github.com/Psifi-Solutions/csrf-csrf?tab=readme-ov-file#getting-started), this middleware requires session middleware or `cookie-parser` to be initialized beforehand. Please refer to the documentation for further details.

Once the installation is complete, register the `csrf-csrf` middleware as global middleware.

```typescript

import { doubleCsrf } from 'csrf-csrf';
// ...
// somewhere in your initialization file
const {
  invalidCsrfTokenError, // This is provided purely for convenience if you plan on creating your own middleware.
  generateToken, // Use this in your routes to generate and provide a CSRF hash, along with a token cookie and token.
  validateRequest, // Also a convenience if you plan on making your own middleware.
  doubleCsrfProtection, // This is the default CSRF protection middleware.
} = doubleCsrf(doubleCsrfOptions);
app.use(doubleCsrfProtection);
```

#### Use with Fastify[#](/security/csrf#use-with-fastify)

Start by installing the required package:

```bash

$ npm i --save @fastify/csrf-protection
```

Once the installation is complete, register the `@fastify/csrf-protection` plugin, as follows:

```typescript

import fastifyCsrf from '@fastify/csrf-protection';
// ...
// somewhere in your initialization file after registering some storage plugin
await app.register(fastifyCsrf);
```

> **Warning** As explained in the `@fastify/csrf-protection` docs [here](https://github.com/fastify/csrf-protection#usage), this plugin requires a storage plugin to be initialized first. Please, see that documentation for further instructions.

----
url: https://docs.nestjs.com/v11/techniques/session
----

* [Session](https://docs.nestjs.com/v11/techniques/session#session)
* [Use with Express (default)](https://docs.nestjs.com/v11/techniques/session#use-with-express-default)
* [Use with Fastify](https://docs.nestjs.com/v11/techniques/session#use-with-fastify)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/techniques/sessions.md "Suggest Edits")

### Session

**HTTP sessions** provide a way to store information about the user across multiple requests, which is particularly useful for [MVC](/v11/techniques/mvc) applications.

#### Use with Express (default)[#](/techniques/session#use-with-express-default)

First install the [required package](https://github.com/expressjs/session) (and its types for TypeScript users):

```shell

$ npm i express-session
$ npm i -D @types/express-session
```

Once the installation is complete, apply the `express-session` middleware as global middleware (for example, in your `main.ts` file).

```typescript

import * as session from 'express-session';
// somewhere in your initialization file
app.use(
  session({
    secret: 'my-secret',
    resave: false,
    saveUninitialized: false,
  }),
);
```

> **Notice** The default server-side session storage is purposely not designed for a production environment. It will leak memory under most conditions, does not scale past a single process, and is meant for debugging and developing. Read more in the [official repository](https://github.com/expressjs/session).

The `secret` is used to sign the session ID cookie. This can be either a string for a single secret, or an array of multiple secrets. If an array of secrets is provided, only the first element will be used to sign the session ID cookie, while all the elements will be considered when verifying the signature in requests. The secret itself should be not easily parsed by a human and would best be a random set of characters.

Enabling the `resave` option forces the session to be saved back to the session store, even if the session was never modified during the request. The default value is `true`, but using the default has been deprecated, as the default will change in the future.

Likewise, enabling the `saveUninitialized` option Forces a session that is "uninitialized" to be saved to the store. A session is uninitialized when it is new but not modified. Choosing `false` is useful for implementing login sessions, reducing server storage usage, or complying with laws that require permission before setting a cookie. Choosing `false` will also help with race conditions where a client makes multiple parallel requests without a session ([source](https://github.com/expressjs/session#saveuninitialized)).

You can pass several other options to the `session` middleware, read more about them in the [API documentation](https://github.com/expressjs/session#options).

> **Hint** Please note that `secure: true` is a recommended option. However, it requires an https-enabled website, i.e., HTTPS is necessary for secure cookies. If secure is set, and you access your site over HTTP, the cookie will not be set. If you have your node.js behind a proxy and are using `secure: true`, you need to set `"trust proxy"` in express.

With this in place, you can now set and read session values from within the route handlers, as follows:

```typescript

@Get()
findAll(@Req() request: Request) {
  request.session.visits = request.session.visits ? request.session.visits + 1 : 1;
}
```

> **Hint** The `@Req()` decorator is imported from the `@nestjs/common`, while `Request` from the `express` package.

Alternatively, you can use the `@Session()` decorator to extract a session object from the request, as follows:

```typescript

@Get()
findAll(@Session() session: Record<string, any>) {
  session.visits = session.visits ? session.visits + 1 : 1;
}
```

> **Hint** The `@Session()` decorator is imported from the `@nestjs/common` package.

#### Use with Fastify[#](/techniques/session#use-with-fastify)

First install the required package:

```shell

$ npm i @fastify/secure-session
```

Once the installation is complete, register the `fastify-secure-session` plugin:

```typescript

import secureSession from '@fastify/secure-session';

// somewhere in your initialization file
const app = await NestFactory.create<NestFastifyApplication>(
  AppModule,
  new FastifyAdapter(),
);
await app.register(secureSession, {
  secret: 'averylogphrasebiggerthanthirtytwochars',
  salt: 'mq9hDxBVDbspDR6n',
});
```

> **Hint** You can also pregenerate a key ([see instructions](https://github.com/fastify/fastify-secure-session)) or use [keys rotation](https://github.com/fastify/fastify-secure-session#using-keys-with-key-rotation).

Read more about the available options in the [official repository](https://github.com/fastify/fastify-secure-session).

With this in place, you can now set and read session values from within the route handlers, as follows:

```typescript

@Get()
findAll(@Req() request: FastifyRequest) {
  const visits = request.session.get('visits');
  request.session.set('visits', visits ? visits + 1 : 1);
}
```

Alternatively, you can use the `@Session()` decorator to extract a session object from the request, as follows:

```typescript

@Get()
findAll(@Session() session: secureSession.Session) {
  const visits = session.get('visits');
  session.set('visits', visits ? visits + 1 : 1);
}
```

> **Hint** The `@Session()` decorator is imported from the `@nestjs/common`, while `secureSession.Session` from the `@fastify/secure-session` package (import statement: `import * as secureSession from '@fastify/secure-session'`).

----
url: https://docs.nestjs.com/v10/microservices/interceptors
----

* [Interceptors](https://docs.nestjs.com/v10/microservices/interceptors#interceptors)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/microservices/interceptors.md "Suggest Edits")

### Interceptors

There is no difference between [regular interceptors](/v10/interceptors) and microservices interceptors. The following example uses a manually instantiated method-scoped interceptor. Just as with HTTP based applications, you can also use controller-scoped interceptors (i.e., prefix the controller class with a `@UseInterceptors()` decorator).

JS TS

```typescript

@UseInterceptors(new TransformInterceptor())
@MessagePattern({ cmd: 'sum' })
accumulate(data: number[]): number {
  return (data || []).reduce((a, b) => a + b);
}
```

```typescript

@UseInterceptors(new TransformInterceptor())
@MessagePattern({ cmd: 'sum' })
accumulate(data) {
  return (data || []).reduce((a, b) => a + b);
}
```

----
url: https://docs.nestjs.com/v8/guards
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Guards](https://docs.nestjs.com/v8/guards#guards)
* [Authorization guard](https://docs.nestjs.com/v8/guards#authorization-guard)
* [Execution context](https://docs.nestjs.com/v8/guards#execution-context)
* [Role-based authentication](https://docs.nestjs.com/v8/guards#role-based-authentication)
* [Binding guards](https://docs.nestjs.com/v8/guards#binding-guards)
* [Setting roles per handler](https://docs.nestjs.com/v8/guards#setting-roles-per-handler)
* [Putting it all together](https://docs.nestjs.com/v8/guards#putting-it-all-together)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/guards.md "Suggest Edits")

### Guards

A guard is a class annotated with the `@Injectable()` decorator, which implements the `CanActivate` interface.

Guards have a **single responsibility**. They determine whether a given request will be handled by the route handler or not, depending on certain conditions (like permissions, roles, ACLs, etc.) present at run-time. This is often referred to as **authorization**. Authorization (and its cousin, **authentication**, with which it usually collaborates) has typically been handled by [middleware](/v8/middleware) in traditional Express applications. Middleware is a fine choice for authentication, since things like token validation and attaching properties to the `request` object are not strongly connected with a particular route context (and its metadata).

But middleware, by its nature, is dumb. It doesn't know which handler will be executed after calling the `next()` function. On the other hand, **Guards** have access to the `ExecutionContext` instance, and thus know exactly what's going to be executed next. They're designed, much like exception filters, pipes, and interceptors, to let you interpose processing logic at exactly the right point in the request/response cycle, and to do so declaratively. This helps keep your code DRY and declarative.

> **Hint** Guards are executed **after** all middleware, but **before** any interceptor or pipe.

#### Authorization guard[#](/guards#authorization-guard)

As mentioned, **authorization** is a great use case for Guards because specific routes should be available only when the caller (usually a specific authenticated user) has sufficient permissions. The `AuthGuard` that we'll build now assumes an authenticated user (and that, therefore, a token is attached to the request headers). It will extract and validate the token, and use the extracted information to determine whether the request can proceed or not.

auth.guard.ts

JS TS

```typescript

import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
import { Observable } from 'rxjs';

@Injectable()
export class AuthGuard implements CanActivate {
  canActivate(
    context: ExecutionContext,
  ): boolean | Promise<boolean> | Observable<boolean> {
    const request = context.switchToHttp().getRequest();
    return validateRequest(request);
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';

@Injectable()
export class AuthGuard {
  async canActivate(context) {
    const request = context.switchToHttp().getRequest();
    return validateRequest(request);
  }
}
```

> **Hint** If you are looking for a real-world example on how to implement an authentication mechanism in your application, visit [this chapter](/v8/security/authentication). Likewise, for more sophisticated authorization example, check [this page](/v8/security/authorization).

By extending `ArgumentsHost`, `ExecutionContext` also adds several new helper methods that provide additional details about the current execution process. These details can be helpful in building more generic guards that can work across a broad set of controllers, methods, and execution contexts. Learn more about `ExecutionContext`[here](/v8/fundamentals/execution-context).

#### Role-based authentication[#](/guards#role-based-authentication)

Let's build a more functional guard that permits access only to users with a specific role. We'll start with a basic guard template, and build on it in the coming sections. For now, it allows all requests to proceed:

roles.guard.ts

JS TS

```typescript

import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
import { Observable } from 'rxjs';

@Injectable()
export class RolesGuard implements CanActivate {
  canActivate(
    context: ExecutionContext,
  ): boolean | Promise<boolean> | Observable<boolean> {
    return true;
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';

@Injectable()
export class RolesGuard {
  canActivate(context) {
    return true;
  }
}
```

#### Binding guards[#](/guards#binding-guards)

Like pipes and exception filters, guards can be **controller-scoped**, method-scoped, or global-scoped. Below, we set up a controller-scoped guard using the `@UseGuards()` decorator. This decorator may take a single argument, or a comma-separated list of arguments. This lets you easily apply the appropriate set of guards with one declaration.

JS TS

```typescript

@Controller('cats')
@UseGuards(RolesGuard)
export class CatsController {}
```

> **Hint** The `@UseGuards()` decorator is imported from the `@nestjs/common` package.

Above, we passed the `RolesGuard` type (instead of an instance), leaving responsibility for instantiation to the framework and enabling dependency injection. As with pipes and exception filters, we can also pass an in-place instance:

JS TS

```typescript

@Controller('cats')
@UseGuards(new RolesGuard())
export class CatsController {}
```

The construction above attaches the guard to every handler declared by this controller. If we wish the guard to apply only to a single method, we apply the `@UseGuards()` decorator at the **method level**.

In order to set up a global guard, use the `useGlobalGuards()` method of the Nest application instance:

JS TS

```typescript

const app = await NestFactory.create(AppModule);
app.useGlobalGuards(new RolesGuard());
```

> **Notice** In the case of hybrid apps the `useGlobalGuards()` method doesn't set up guards for gateways and micro services by default (see [Hybrid application](/v8/faq/hybrid-application) for information on how to change this behavior). For "standard" (non-hybrid) microservice apps, `useGlobalGuards()` does mount the guards globally.

Global guards are used across the whole application, for every controller and every route handler. In terms of dependency injection, global guards registered from outside of any module (with `useGlobalGuards()` as in the example above) cannot inject dependencies since this is done outside the context of any module. In order to solve this issue, you can set up a guard directly from any module using the following construction:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { APP_GUARD } from '@nestjs/core';

@Module({
  providers: [
    {
      provide: APP_GUARD,
      useClass: RolesGuard,
    },
  ],
})
export class AppModule {}
```

> **Hint** When using this approach to perform dependency injection for the guard, note that regardless of the module where this construction is employed, the guard is, in fact, global. Where should this be done? Choose the module where the guard (`RolesGuard` in the example above) is defined. Also, `useClass` is not the only way of dealing with custom provider registration. Learn more [here](/v8/fundamentals/custom-providers).

#### Setting roles per handler[#](/guards#setting-roles-per-handler)

Our `RolesGuard` is working, but it's not very smart yet. We're not yet taking advantage of the most important guard feature - the [execution context](/v8/fundamentals/execution-context). It doesn't yet know about roles, or which roles are allowed for each handler. The `CatsController`, for example, could have different permission schemes for different routes. Some might be available only for an admin user, and others could be open for everyone. How can we match roles to routes in a flexible and reusable way?

This is where **custom metadata** comes into play (learn more [here](https://docs.nestjs.com/fundamentals/execution-context#reflection-and-metadata)). Nest provides the ability to attach custom **metadata** to route handlers through the `@SetMetadata()` decorator. This metadata supplies our missing `role` data, which a smart guard needs to make decisions. Let's take a look at using `@SetMetadata()`:

cats.controller.ts

JS TS

```typescript

@Post()
@SetMetadata('roles', ['admin'])
async create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

```typescript

@Post()
@SetMetadata('roles', ['admin'])
@Bind(Body())
async create(createCatDto) {
  this.catsService.create(createCatDto);
}
```

> **Hint** The `@SetMetadata()` decorator is imported from the `@nestjs/common` package.

With the construction above, we attached the `roles` metadata (`roles` is a key, while `['admin']` is a particular value) to the `create()` method. While this works, it's not good practice to use `@SetMetadata()` directly in your routes. Instead, create your own decorators, as shown below:

roles.decorator.ts

JS TS

```typescript

import { SetMetadata } from '@nestjs/common';

export const Roles = (...roles: string[]) => SetMetadata('roles', roles);
```

```typescript

import { SetMetadata } from '@nestjs/common';

export const Roles = (...roles) => SetMetadata('roles', roles);
```

This approach is much cleaner and more readable, and is strongly typed. Now that we have a custom `@Roles()` decorator, we can use it to decorate the `create()` method.

cats.controller.ts

JS TS

```typescript

@Post()
@Roles('admin')
async create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

```typescript

@Post()
@Roles('admin')
@Bind(Body())
async create(createCatDto) {
  this.catsService.create(createCatDto);
}
```

#### Putting it all together[#](/guards#putting-it-all-together)

Let's now go back and tie this together with our `RolesGuard`. Currently, it simply returns `true` in all cases, allowing every request to proceed. We want to make the return value conditional based on the comparing the **roles assigned to the current user** to the actual roles required by the current route being processed. In order to access the route's role(s) (custom metadata), we'll use the `Reflector` helper class, which is provided out of the box by the framework and exposed from the `@nestjs/core` package.

roles.guard.ts

JS TS

```typescript

import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
import { Reflector } from '@nestjs/core';

@Injectable()
export class RolesGuard implements CanActivate {
  constructor(private reflector: Reflector) {}

  canActivate(context: ExecutionContext): boolean {
    const roles = this.reflector.get<string[]>('roles', context.getHandler());
    if (!roles) {
      return true;
    }
    const request = context.switchToHttp().getRequest();
    const user = request.user;
    return matchRoles(roles, user.roles);
  }
}
```

```typescript

import { Injectable, Dependencies } from '@nestjs/common';
import { Reflector } from '@nestjs/core';

@Injectable()
@Dependencies(Reflector)
export class RolesGuard {
  constructor(reflector) {
    this.reflector = reflector;
  }

  canActivate(context) {
    const roles = this.reflector.get('roles', context.getHandler());
    if (!roles) {
      return true;
    }
    const request = context.switchToHttp().getRequest();
    const user = request.user;
    return matchRoles(roles, user.roles);
  }
}
```

> **Hint** In the node.js world, it's common practice to attach the authorized user to the `request` object. Thus, in our sample code above, we are assuming that `request.user` contains the user instance and allowed roles. In your app, you will probably make that association in your custom **authentication guard** (or middleware). Check [this chapter](/v8/security/authentication) for more information on this topic.

> **Warning** The logic inside the `matchRoles()` function can be as simple or sophisticated as needed. The main point of this example is to show how guards fit into the request/response cycle.

Refer to the [Reflection and metadata](https://docs.nestjs.com/fundamentals/execution-context#reflection-and-metadata) section of the **Execution context** chapter for more details on utilizing `Reflector` in a context-sensitive way.

When a user with insufficient privileges requests an endpoint, Nest automatically returns the following response:

```typescript

{
  "statusCode": 403,
  "message": "Forbidden resource",
  "error": "Forbidden"
}
```

Note that behind the scenes, when a guard returns `false`, the framework throws a `ForbiddenException`. If you want to return a different error response, you should throw your own specific exception. For example:

```typescript

throw new UnauthorizedException();
```

Any exception thrown by a guard will be handled by the [exceptions layer](/v8/exception-filters) (global exceptions filter and any exceptions filters that are applied to the current context).

> **Hint** If you are looking for a real-world example on how to implement authorization, check [this chapter](/v8/security/authorization).

----
url: https://docs.nestjs.com/v9/microservices/basics
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Overview](https://docs.nestjs.com/v9/microservices/basics#overview)
* [Installation](https://docs.nestjs.com/v9/microservices/basics#installation)
* [Getting started](https://docs.nestjs.com/v9/microservices/basics#getting-started)
* [Patterns](https://docs.nestjs.com/v9/microservices/basics#patterns)
* [Request-response](https://docs.nestjs.com/v9/microservices/basics#request-response)
* [Asynchronous responses](https://docs.nestjs.com/v9/microservices/basics#asynchronous-responses)
* [Event-based](https://docs.nestjs.com/v9/microservices/basics#event-based)
* [Decorators](https://docs.nestjs.com/v9/microservices/basics#decorators)
* [Client](https://docs.nestjs.com/v9/microservices/basics#client)
* [Sending messages](https://docs.nestjs.com/v9/microservices/basics#sending-messages)
* [Publishing events](https://docs.nestjs.com/v9/microservices/basics#publishing-events)
* [Scopes](https://docs.nestjs.com/v9/microservices/basics#scopes)
* [Handling timeouts](https://docs.nestjs.com/v9/microservices/basics#handling-timeouts)

```bash

$ npm i --save @nestjs/microservices
```

#### Getting started[#](/microservices/basics#getting-started)

To instantiate a microservice, use the `createMicroservice()` method of the `NestFactory` class:

main.ts

JS TS

```typescript

import { NestFactory } from '@nestjs/core';
import { Transport, MicroserviceOptions } from '@nestjs/microservices';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.createMicroservice<MicroserviceOptions>(
    AppModule,
    {
      transport: Transport.TCP,
    },
  );
  await app.listen();
}
bootstrap();
```

```typescript

import { NestFactory } from '@nestjs/core';
import { Transport } from '@nestjs/microservices';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.createMicroservice(AppModule, {
    transport: Transport.TCP,
  });
  await app.listen();
}
bootstrap();
```

> **Hint** Microservices use the **TCP** transport layer by default.

The second argument of the `createMicroservice()` method is an `options` object. This object may consist of two members:

|             |                                                                            |
| ----------- | -------------------------------------------------------------------------- |
| `transport` | Specifies the transporter (for example, `Transport.NATS`)                  |
| `options`   | A transporter-specific options object that determines transporter behavior |

The `options` object is specific to the chosen transporter. The **TCP** transporter exposes the properties described below. For other transporters (e.g, Redis, MQTT, etc.), see the relevant chapter for a description of the available options.

|                 |                                                          |
| --------------- | -------------------------------------------------------- |
| `host`          | Connection hostname                                      |
| `port`          | Connection port                                          |
| `retryAttempts` | Number of times to retry message (default: `0`)          |
| `retryDelay`    | Delay between message retry attempts (ms) (default: `0`) |

```typescript

import { Controller } from '@nestjs/common';
import { MessagePattern } from '@nestjs/microservices';

@Controller()
export class MathController {
  @MessagePattern({ cmd: 'sum' })
  accumulate(data: number[]): number {
    return (data || []).reduce((a, b) => a + b);
  }
}
```

```typescript

import { Controller } from '@nestjs/common';
import { MessagePattern } from '@nestjs/microservices';

@Controller()
export class MathController {
  @MessagePattern({ cmd: 'sum' })
  accumulate(data) {
    return (data || []).reduce((a, b) => a + b);
  }
}
```

In the above code, the `accumulate()`**message handler** listens for messages that fulfill the `{ cmd: 'sum' }` message pattern. The message handler takes a single argument, the `data` passed from the client. In this case, the data is an array of numbers which are to be accumulated.

#### Asynchronous responses[#](/microservices/basics#asynchronous-responses)

Message handlers are able to respond either synchronously or **asynchronously**. Hence, `async` methods are supported.

JS TS

```typescript

@MessagePattern({ cmd: 'sum' })
async accumulate(data: number[]): Promise<number> {
  return (data || []).reduce((a, b) => a + b);
}
```

```typescript

@MessagePattern({ cmd: 'sum' })
async accumulate(data) {
  return (data || []).reduce((a, b) => a + b);
}
```

A message handler is also able to return an `Observable`, in which case the result values will be emitted until the stream is completed.

JS TS

```typescript

@MessagePattern({ cmd: 'sum' })
accumulate(data: number[]): Observable<number> {
  return from([1, 2, 3]);
}
```

```typescript

@MessagePattern({ cmd: 'sum' })
accumulate(data: number[]): Observable<number> {
  return from([1, 2, 3]);
}
```

In the example above, the message handler will respond **3 times** (with each item from the array).

#### Event-based[#](/microservices/basics#event-based)

While the request-response method is ideal for exchanging messages between services, it is less suitable when your message style is event-based - when you just want to publish **events** without waiting for a response. In that case, you do not want the overhead required by request-response for maintaining two channels.

Suppose you would like to simply notify another service that a certain condition has occurred in this part of the system. This is the ideal use case for the event-based message style.

To create an event handler, we use the `@EventPattern()` decorator, which is imported from the `@nestjs/microservices` package.

JS TS

```typescript

@EventPattern('user_created')
async handleUserCreated(data: Record<string, unknown>) {
  // business logic
}
```

```typescript

@EventPattern('user_created')
async handleUserCreated(data) {
  // business logic
}
```

> **Hint** You can register multiple event handlers for a **single** event pattern and all of them will be automatically triggered in parallel.

```typescript

@MessagePattern('time.us.*')
getDate(@Payload() data: number[], @Ctx() context: NatsContext) {
  console.log(`Subject: ${context.getSubject()}`); // e.g. "time.us.east"
  return new Date().toLocaleTimeString(...);
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('time.us.*')
getDate(data, context) {
  console.log(`Subject: ${context.getSubject()}`); // e.g. "time.us.east"
  return new Date().toLocaleTimeString(...);
}
```

> **Hint**`@Payload()`, `@Ctx()` and `NatsContext` are imported from `@nestjs/microservices`.

> **Hint** You can also pass in a property key to the `@Payload()` decorator to extract a specific property from the incoming payload object, for example, `@Payload('id')`.

#### Client[#](/microservices/basics#client)

A client Nest application can exchange messages or publish events to a Nest microservice using the `ClientProxy` class. This class defines several methods, such as `send()` (for request-response messaging) and `emit()` (for event-driven messaging) that let you communicate with a remote microservice. Obtain an instance of this class in one of the following ways.

One technique is to import the `ClientsModule`, which exposes the static `register()` method. This method takes an argument which is an array of objects representing microservice transporters. Each such object has a `name` property, an optional `transport` property (default is `Transport.TCP`), and an optional transporter-specific `options` property.

The `name` property serves as an **injection token** that can be used to inject an instance of a `ClientProxy` where needed. The value of the `name` property, as an injection token, can be an arbitrary string or JavaScript symbol, as described [here](https://docs.nestjs.com/fundamentals/custom-providers#non-class-based-provider-tokens).

The `options` property is an object with the same properties we saw in the `createMicroservice()` method earlier.

```typescript

@Module({
  imports: [
    ClientsModule.register([
      { name: 'MATH_SERVICE', transport: Transport.TCP },
    ]),
  ]
  ...
})
```

Once the module has been imported, we can inject an instance of the `ClientProxy` configured as specified via the `'MATH_SERVICE'` transporter options shown above, using the `@Inject()` decorator.

```typescript

constructor(
  @Inject('MATH_SERVICE') private client: ClientProxy,
) {}
```

> **Hint** The `ClientsModule` and `ClientProxy` classes are imported from the `@nestjs/microservices` package.

At times we may need to fetch the transporter configuration from another service (say a `ConfigService`), rather than hard-coding it in our client application. To do this, we can register a [custom provider](/v9/fundamentals/custom-providers) using the `ClientProxyFactory` class. This class has a static `create()` method, which accepts a transporter options object, and returns a customized `ClientProxy` instance.

```typescript

@Module({
  providers: [
    {
      provide: 'MATH_SERVICE',
      useFactory: (configService: ConfigService) => {
        const mathSvcOptions = configService.getMathSvcOptions();
        return ClientProxyFactory.create(mathSvcOptions);
      },
      inject: [ConfigService],
    }
  ]
  ...
})
```

> **Hint** The `ClientProxyFactory` is imported from the `@nestjs/microservices` package.

Another option is to use the `@Client()` property decorator.

```typescript

@Client({ transport: Transport.TCP })
client: ClientProxy;
```

> **Hint** The `@Client()` decorator is imported from the `@nestjs/microservices` package.

Using the `@Client()` decorator is not the preferred technique, as it is harder to test and harder to share a client instance.

The `ClientProxy` is **lazy**. It doesn't initiate a connection immediately. Instead, it will be established before the first microservice call, and then reused across each subsequent call. However, if you want to delay the application bootstrapping process until a connection is established, you can manually initiate a connection using the `ClientProxy` object's `connect()` method inside the `OnApplicationBootstrap` lifecycle hook.

JS TS

```typescript

async onApplicationBootstrap() {
  await this.client.connect();
}
```

If the connection cannot be created, the `connect()` method will reject with the corresponding error object.

#### Sending messages[#](/microservices/basics#sending-messages)

The `ClientProxy` exposes a `send()` method. This method is intended to call the microservice and returns an `Observable` with its response. Thus, we can subscribe to the emitted values easily.

JS TS

```typescript

accumulate(): Observable<number> {
  const pattern = { cmd: 'sum' };
  const payload = [1, 2, 3];
  return this.client.send<number>(pattern, payload);
}
```

```typescript

accumulate() {
  const pattern = { cmd: 'sum' };
  const payload = [1, 2, 3];
  return this.client.send(pattern, payload);
}
```

The `send()` method takes two arguments, `pattern` and `payload`. The `pattern` should match one defined in a `@MessagePattern()` decorator. The `payload` is a message that we want to transmit to the remote microservice. This method returns a **cold `Observable`**, which means that you have to explicitly subscribe to it before the message will be sent.

#### Publishing events[#](/microservices/basics#publishing-events)

To send an event, use the `ClientProxy` object's `emit()` method. This method publishes an event to the message broker.

JS TS

```typescript

async publish() {
  this.client.emit<number>('user_created', new UserCreatedEvent());
}
```

```typescript

async publish() {
  this.client.emit('user_created', new UserCreatedEvent());
}
```

The `emit()` method takes two arguments, `pattern` and `payload`. The `pattern`should match one defined in an `@EventPattern()` decorator. The `payload` is an event payload that we want to transmit to the remote microservice. This method returns a **hot `Observable`** (unlike the cold `Observable` returned by `send()`), which means that whether or not you explicitly subscribe to the observable, the proxy will immediately try to deliver the event.

## Hoodies, T-shirts, and accessories!

Support our future development by shopping in the official store!

[See more](https://nestjs.threadless.com/ "Shop | NestJS - A node.js framework built on top of TypeScript")

#### Scopes[#](/microservices/basics#scopes)

For people coming from different programming language backgrounds, it might be unexpected to learn that in Nest, almost everything is shared across incoming requests. We have a connection pool to the database, singleton services with global state, etc. Remember that Node.js doesn't follow the request/response Multi-Threaded Stateless Model in which every request is processed by a separate thread. Hence, using singleton instances is fully **safe** for our applications.

However, there are edge-cases when request-based lifetime of the handler may be the desired behavior, for instance per-request caching in GraphQL applications, request tracking or multi-tenancy. Learn how to control scopes [here](/v9/fundamentals/injection-scopes).

Request-scoped handlers and providers can inject `RequestContext` using the `@Inject()` decorator in combination with `CONTEXT` token:

```typescript

import { Injectable, Scope, Inject } from '@nestjs/common';
import { CONTEXT, RequestContext } from '@nestjs/microservices';

@Injectable({ scope: Scope.REQUEST })
export class CatsService {
  constructor(@Inject(CONTEXT) private ctx: RequestContext) {}
}
```

This provides access to the `RequestContext` object, which has two properties:

```typescript

export interface RequestContext<T = any> {
  pattern: string | Record<string, any>;
  data: T;
}
```

The `data` property is the message payload sent by the message producer. The `pattern` property is the pattern used to identify an appropriate handler to handle the incoming message.

#### Handling timeouts[#](/microservices/basics#handling-timeouts)

In distributed systems, sometimes microservices might be down or not available. To avoid infinitely long waiting, you can use Timeouts. A timeout is an incredibly useful pattern when communicating with other services. To apply timeouts to your microservice calls, you can use the [RxJS](https://rxjs.dev)`timeout` operator. If the microservice does not respond to the request within a certain time, an exception is thrown, which can be caught and handled appropriately.

To solve this problem you have to use [`rxjs`](https://github.com/ReactiveX/rxjs) package. Just use the `timeout` operator in the pipe:

JS TS

```typescript

this.client
      .send<TResult, TInput>(pattern, data)
      .pipe(timeout(5000));
```

```typescript

this.client
      .send(pattern, data)
      .pipe(timeout(5000));
```

> **Hint** The `timeout` operator is imported from the `rxjs/operators` package.

After 5 seconds, if the microservice isn't responding, it will throw an error.

----
url: https://docs.nestjs.com/application/events
----

[Skip to content](#content)

On this page

* [Events](https://docs.nestjs.com/application/events#events)
* [Getting started](https://docs.nestjs.com/application/events#getting-started)
* [Dispatching events](https://docs.nestjs.com/application/events#dispatching-events)
* [Listening to events](https://docs.nestjs.com/application/events#listening-to-events)
* [Preventing event loss](https://docs.nestjs.com/application/events#preventing-event-loss)
* [Example](https://docs.nestjs.com/application/events#example)

### Events

The [Event Emitter](https://www.npmjs.com/package/@nestjs/event-emitter) package (`@nestjs/event-emitter`) provides an observer implementation that lets you subscribe to and listen for events that occur in your application. Events are a good way to decouple different parts of your application, since a single event can have multiple listeners that don't depend on each other.

`EventEmitterModule` internally uses the [eventemitter2](https://github.com/EventEmitter2/EventEmitter2) package.

#### Getting started[#](/application/events#getting-started)

First, install the required package:

```shell

$ npm i --save @nestjs/event-emitter
```

Once the installation is complete, import the `EventEmitterModule` into the root `AppModule` and call its `forRoot()` static method, as shown below:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { EventEmitterModule } from '@nestjs/event-emitter';

@Module({
  imports: [
    EventEmitterModule.forRoot()
  ],
})
export class AppModule {}
```

The `.forRoot()` call initializes the event emitter and registers any declarative event listeners that exist within your app. Registration happens in the `onApplicationBootstrap` lifecycle hook, which ensures that all modules have loaded and declared their event listeners. The module is registered as a [global module](/modules#global-modules) by default, so you can inject the event emitter anywhere without importing `EventEmitterModule` again. To change this, set the `global` option to `false`.

To configure the underlying `EventEmitter2` instance, pass a configuration object to the `.forRoot()` method, as follows:

```typescript

EventEmitterModule.forRoot({
  // set this to `true` to use wildcards
  wildcard: false,
  // the delimiter used to segment namespaces
  delimiter: '.',
  // set this to `true` if you want to emit the newListener event
  newListener: false,
  // set this to `true` if you want to emit the removeListener event
  removeListener: false,
  // the maximum amount of listeners that can be assigned to an event
  maxListeners: 10,
  // show event name in memory leak message when more than maximum amount of listeners is assigned
  verboseMemoryLeak: false,
  // disable throwing uncaughtException if an error event is emitted and it has no listeners
  ignoreErrors: false,
});
```

#### Dispatching events[#](/application/events#dispatching-events)

To dispatch (i.e., fire) an event, first inject `EventEmitter2` through the constructor:

```typescript

constructor(private eventEmitter: EventEmitter2) {}
```

> **Hint** Import `EventEmitter2` from the `@nestjs/event-emitter` package.

Then use it in the class as follows:

```typescript

this.eventEmitter.emit(
  'order.created',
  new OrderCreatedEvent({
    orderId: 1,
    payload: {},
  }),
);
```

#### Listening to events[#](/application/events#listening-to-events)

To declare an event listener, decorate the method that handles the event with the `@OnEvent()` decorator, as follows:

```typescript

@OnEvent('order.created')
handleOrderCreatedEvent(payload: OrderCreatedEvent) {
  // handle and process "OrderCreatedEvent" event
}
```

> **Hint** If an event listener belongs to a [request-scoped](/fundamentals/injection-scopes) provider, Nest creates a new instance of that provider for every event it handles. The event payload takes the place of the request object, so injecting `REQUEST` in that provider gives you the payload. If the payload you emit is the incoming request object itself (or carries its context ID), set the `inheritRequestContextId` option of `forRoot()` to `true` so that the listener reuses that request's DI sub-tree instead of creating a new one.

The first argument can be a `string` or a `symbol` for a simple event emitter, and a `string | symbol | Array<string | symbol>` for a wildcard emitter.

The optional second argument is a listener options object:

```typescript

export type OnEventOptions = OnOptions & {
  /**
   * If "true", prepends (instead of appends) the given listener to the array of listeners.
   *
   * @see https://github.com/EventEmitter2/EventEmitter2#emitterprependlistenerevent-listener-options
   *
   * @default false
   */
  prependListener?: boolean;

  /**
   * If "true", errors thrown by the onEvent callback are logged instead of rethrown. If "false", they are rethrown.
   *
   * @default true
   */
  suppressErrors?: boolean;
};
```

> **Hint** To learn more about the `OnOptions` object, see the [`eventemitter2` documentation](https://github.com/EventEmitter2/EventEmitter2#emitteronevent-listener-options-objectboolean).

For example, the following listener runs asynchronously:

```typescript

@OnEvent('order.created', { async: true })
handleOrderCreatedEvent(payload: OrderCreatedEvent) {
  // handle and process "OrderCreatedEvent" event
}
```

To use namespaces and wildcards, pass the `wildcard` option to the `EventEmitterModule#forRoot()` method. When namespaces and wildcards are enabled, events can be either delimiter-separated strings (`foo.bar`) or arrays (`['foo', 'bar']`). You can configure the delimiter with the `delimiter` option. With namespaces enabled, you can subscribe to events using a wildcard:

```typescript

@OnEvent('order.*')
handleOrderEvents(payload: OrderCreatedEvent | OrderRemovedEvent | OrderUpdatedEvent) {
  // handle and process an event
}
```

A single wildcard matches exactly one segment. For example, `order.*` matches the events `order.created` and `order.shipped`, but not `order.delayed.out_of_stock`. To listen to such events, use the multi-level wildcard pattern (i.e., `**`), described in the [EventEmitter2 documentation on multi-level wildcards](https://github.com/EventEmitter2/EventEmitter2#multi-level-wildcards).

With this pattern, you can, for example, create an event listener that catches all events:

```typescript

@OnEvent('**')
handleEverything(payload: any) {
  // handle and process an event
}
```

> **Hint** The `EventEmitter2` class provides several useful methods for interacting with events, such as `waitFor()` and `onAny()`. See the [EventEmitter2 documentation](https://github.com/EventEmitter2/EventEmitter2) for details.

#### Preventing event loss[#](/application/events#preventing-event-loss)

Events emitted before or during the `onApplicationBootstrap` lifecycle hook (for example, from constructors or `onModuleInit()` methods) may be missed, because the listeners might not be registered yet.

To avoid this, use the `waitUntilReady()` method of `EventEmitterReadinessWatcher` (exported from `@nestjs/event-emitter`). It returns a promise that resolves once all listeners have been registered. Call it in the `onApplicationBootstrap` lifecycle hook of your provider before emitting events:

```typescript

await this.eventEmitterReadinessWatcher.waitUntilReady();
this.eventEmitter.emit(
  'order.created',
  new OrderCreatedEvent({ orderId: 1, payload: {} }),
);
```

> **Note** This is only necessary for events emitted before the `onApplicationBootstrap` lifecycle hook completes.

#### Example[#](/application/events#example)

A working example is available in the [event emitter sample](https://github.com/nestjs/nest/tree/master/sample/30-event-emitter).

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/application/events.md)

----
url: https://docs.nestjs.com/reliability/locks
----

[Skip to content](#content)

On this page

* [Distributed locks](https://docs.nestjs.com/reliability/locks#distributed-locks)
* [Installation](https://docs.nestjs.com/reliability/locks#installation)
* [See the problem](https://docs.nestjs.com/reliability/locks#see-the-problem)
* [Keep locks in your database](https://docs.nestjs.com/reliability/locks#keep-locks-in-your-database)
* [Run each job on one instance](https://docs.nestjs.com/reliability/locks#run-each-job-on-one-instance)
* [Don't let a long run overlap itself](https://docs.nestjs.com/reliability/locks#dont-let-a-long-run-overlap-itself)
* [Fence the writes](https://docs.nestjs.com/reliability/locks#fence-the-writes)
* [Run the export by hand](https://docs.nestjs.com/reliability/locks#run-the-export-by-hand)
* [The store on Redis](https://docs.nestjs.com/reliability/locks#the-store-on-redis)
* [Hold the warehouse feed on one instance](https://docs.nestjs.com/reliability/locks#hold-the-warehouse-feed-on-one-instance)
* [Try it](https://docs.nestjs.com/reliability/locks#try-it)
* [Testing](https://docs.nestjs.com/reliability/locks#testing)
* [Production checklist](https://docs.nestjs.com/reliability/locks#production-checklist)
* [The store contract](https://docs.nestjs.com/reliability/locks#the-store-contract)
* [Reference](https://docs.nestjs.com/reliability/locks#reference)

### Distributed locks

An online store for cat food and supplies runs two scheduled jobs with `@nestjs/schedule`. Every night at 02:00 an export sends the day's invoices to the accounting system, and every five minutes a reconciliation asks the warehouse for a full stock count and writes it to the products table. Both work on one instance. In production the order API runs on three, and `@nestjs/schedule` fires every `@Cron()` on each of them:

* The accounting system records every invoice three times.
* The warehouse is asked for three full counts every five minutes. A full count pages through the whole catalog, and at month end it takes longer than five minutes, so the next tick starts a second count alongside the first, then a third.

The usual fixes have holes. A `RUN_JOBS=true` instance works until a rolling deploy has two of them for a minute, or the job instance is the one that dies. A `SET NX` key in Redis at the top of the job works until its holder pauses for longer than the key's TTL, in a stop-the-world garbage collection or behind a network partition: another instance takes the key, and when the first one wakes up it finishes its run believing it still holds it. Two writers again, and neither knows. `waitForCompletion: true` on `@Cron()` stops a job from overlapping itself, on one instance.

`@nestjs/locks` turns a job into something one instance holds: a **lease** that the holder keeps renewing while it is up, checked in a store every instance shares. Two decorators put it on a scheduled job, `@OnOneInstance()` and `@WithoutOverlapping()`, in the spirit of Laravel's `onOneServer()` and `withoutOverlapping()`. Under them is a distributed lock you can also take yourself, with the two things a lock needs to be trusted: an `AbortSignal` that aborts when the lease is lost, and a **fencing token** that grows with every acquisition of a key, so a write from a holder that paused past its lease can be refused. A leader election is the same lease, held for as long as the leader lives.

In this tutorial, you'll add it to the store, on PostgreSQL with Drizzle:

* Prove the duplicate runs with a test, on three instances of the app.
* Keep the locks in a table of the application's database.
* Run each job on one instance, with a handover when that instance dies.
* Keep a long stock count from overlapping itself.
* Fence the stock writes, so a paused instance can't overwrite a fresher count.
* Run the export by hand from an admin endpoint, never alongside the scheduled run.
* Keep the locks in Redis instead.
* Hold the warehouse's alert feed on one instance, with a leader election.

#### Installation[#](/reliability/locks#installation)

To get started, install the required dependency:

```bash

$ npm i --save @nestjs/locks
```

#### See the problem[#](/reliability/locks#see-the-problem)

This is the application before the tutorial. The nightly export takes every placed order that has no invoice yet, uploads the batch, and marks the orders with the batch id:

invoices/invoice-export.job.step-1.ts

JS TS

```typescript

import { Injectable, Logger } from '@nestjs/common';
import { InjectDrizzle } from '@nestjs/drizzle';
import { Cron } from '@nestjs/schedule';
import { and, eq, inArray, isNull } from 'drizzle-orm';
import type { Database } from '../database/drizzle.js';
import { orders } from '../database/schema.js';
import { AccountingClient } from './accounting.client.js';

@Injectable()
export class InvoiceExportJob {
  private readonly logger = new Logger(InvoiceExportJob.name);

  constructor(
    @InjectDrizzle() private readonly db: Database,
    private readonly accountingClient: AccountingClient,
  ) {}

  @Cron(process.env.INVOICE_EXPORT_CRON ?? '0 2 * * *', { name: 'invoice-export', timeZone: 'Europe/Warsaw' })
  async exportInvoices() {
    // Every placed order without an invoice, not "yesterday's orders": a night
    // the export didn't run is caught up the next night.
    const pending = await this.db
      .select()
      .from(orders)
      .where(and(eq(orders.status, 'placed'), isNull(orders.invoicedAt)))
      .orderBy(orders.placedAt);
    if (pending.length === 0) {
      return;
    }

    const batch = await this.accountingClient.uploadInvoices(
      pending.map((order) => ({
        orderId: order.id,
        userId: order.userId,
        total: order.total,
        placedAt: order.placedAt.toISOString(),
      })),
    );
    await this.db
      .update(orders)
      .set({ invoicedAt: new Date(), invoiceBatch: batch.batchId })
      .where(inArray(orders.id, pending.map((order) => order.id)));
    this.logger.log(`Exported ${pending.length} invoices in batch ${batch.batchId}`);
  }
}
```

The accounting system records every batch it receives, so a batch uploaded twice is recorded twice. The reconciliation asks the warehouse for the counts and writes them:

inventory/stock-reconciliation.job.step-1.ts

JS TS

```typescript

import { Injectable, Logger } from '@nestjs/common';
import { Cron, CronExpression } from '@nestjs/schedule';
import { StockRepository } from './stock.repository.step-1.js';
import { WarehouseClient } from './warehouse.client.js';

@Injectable()
export class StockReconciliationJob {
  private readonly logger = new Logger(StockReconciliationJob.name);

  constructor(
    private readonly warehouseClient: WarehouseClient,
    private readonly stockRepository: StockRepository,
  ) {}

  @Cron(process.env.STOCK_RECONCILIATION_CRON ?? CronExpression.EVERY_5_MINUTES, { name: 'stock-reconciliation' })
  async reconcileStock() {
    const counts = await this.warehouseClient.stockCounts();
    const written = await this.stockRepository.writeStock(counts);
    this.logger.log(`Reconciled stock for ${written} products`);
  }
}
```

The cron expressions come from the environment, with the real schedule as the default, so the tests and the [Try it](/reliability/locks#try-it) section can speed them up or turn them off. `AccountingClient` and `WarehouseClient` stand in for the two external systems; each counts what it was asked to do. The database is the application's, registered with `DrizzleModule` in `app.module.ts` and injected with `@InjectDrizzle()`.

> **Hint** The tutorial reads `process.env` directly, to stay short. In an application, load the environment through [`@nestjs/config`](/application/configuration) with a validation schema, so a missing variable stops the application at startup rather than at the first request, and read the values from `ConfigService`.

Before changing anything, prove the problem. The test starts three instances of the application in one process, on one database (PostgreSQL in-process with [PGlite](https://pglite.dev), or a PostgreSQL server when one is configured), and fires the schedules on each of them through `@nestjs/schedule`'s own registry, the way 02:00 would:

test/step-1.duplicate-runs.e2e-spec.ts

JS TS

```typescript

describe.each(targets)('three instances with plain @Cron() jobs, on %s', (_, target) => {
  let database: TestDatabase;
  let accounting: FakeAccounting;
  let warehouse: FakeWarehouse;
  let instances: TestingModule[];
  let logger: CapturingLogger;

  beforeEach(async (context) => {
    if (!target) {
      return context.skip();
    }
    database = await openDatabase(target, 'locks_step_1');
    accounting = new FakeAccounting();
    warehouse = new FakeWarehouse();
    logger = new CapturingLogger();
    instances = [];
    for (let i = 0; i < 3; i++) {
      instances.push(await startInstance({ database, module: StepOneApp, accounting, warehouse, logger }));
    }
  });
  afterEach(async () => {
    for (const app of instances ?? []) {
      await app.close();
    }
    await database?.close();
  });

  /**
   * 02:00: every instance's scheduler fires the job, through @nestjs/schedule's own
   * callback (which doesn't wait for the job to finish).
   */
  const tick = (name: string) =>
    Promise.all(instances.map((app) => app.get(SchedulerRegistry).getCronJob(name).fireOnTick()));

  it('records every invoice three times', async () => {
    await tick('invoice-export');
    await until(() => logger.matching('Exported 3 invoices').length === 3);
    const orders = ['ord_1001', 'ord_1002', 'ord_1004'];
    expect(booked(accounting)).toEqual([orders, orders, orders]);
    // The orders point at whichever batch wrote last; the accounting system has all three.
    const rows = await database.query<{ invoice_batch: string }>(
      "SELECT DISTINCT invoice_batch FROM orders WHERE status = 'placed'",
    );
    expect(rows).toHaveLength(1);
  });

  it('asks the warehouse for three full counts every five minutes', async () => {
    await tick('stock-reconciliation');
    await until(() => logger.matching('Reconciled stock').length === 3);
    expect(warehouse.counts).toBe(3);
  });
});
```

Three batches, each with the same three orders, and three full counts. The `orders` table looks fine afterwards, every order has a batch id, which is why this goes unnoticed until accounting calls.

#### Keep locks in your database[#](/reliability/locks#keep-locks-in-your-database)

`@nestjs/locks` works as soon as you import `LocksModule`, on an in-memory store. That store excludes callers in one process only: three instances would each have their own, all three would take "the" lock, and nothing would change. The locks need a store every instance shares, and the package doesn't ship one. It defines the contract, the `LockStore` interface, and you implement it in a provider of your application with the database it already has.

This section shows that store twice: first with Drizzle on PostgreSQL, registered through [`@nestjs/drizzle`](/data/drizzle) with the `pg` driver, which is the tutorial's path, and then, under "With TypeORM" at the end of the section, the same store for an application whose ORM is TypeORM. Take one of the two, or keep the locks in Redis with [the store on Redis](/reliability/locks#the-store-on-redis). With Drizzle, a lock is one row per key:

database/schema.ts

JS TS

```typescript

// The locks, read and written by DrizzleLockStore: one row per lock key.

export const locks = pgTable('locks', {
  key: text('key').primaryKey(),
  /** The holder's id; null once released. */
  owner: text('owner'),
  fencingToken: bigint('fencing_token', { mode: 'number' }).notNull(),
  /** On the database's clock: every instance agrees on it. */
  expiresAt: timestamp('expires_at', { withTimezone: true }).notNull(),
});

/** Fencing tokens for every key: a sequence never goes back, so they only grow. */
export const locksFencingTokenSeq = pgSequence('locks_fencing_token_seq');
```

drizzle-kit writes the migration:

```bash

$ npx drizzle-kit generate --name=locks
$ npx drizzle-kit migrate
```

drizzle/0002\_locks.sql

JS TS

```sql

CREATE SEQUENCE "public"."locks_fencing_token_seq" INCREMENT BY 1 MINVALUE 1 MAXVALUE 9223372036854775807 START WITH 1 CACHE 1;--> statement-breakpoint
CREATE TABLE "locks" (
	"key" text PRIMARY KEY NOT NULL,
	"owner" text,
	"fencing_token" bigint NOT NULL,
	"expires_at" timestamp with time zone NOT NULL
);
```

The contract has three methods, and each takes the lock key and an `owner` first: a random id the package draws for each acquisition. Durations arrive in whole milliseconds.

* `acquire(key, owner, ttl)` takes the key if no live lock holds it, and returns the lock's fencing token, or reports that the key is taken. It must be atomic: of any number of concurrent callers, exactly one may win.
* `renew(key, owner, ttl)` is the heartbeat. It moves the expiry to `ttl` from now, if `owner` still holds a live lock on the key. The package calls it every `ttl / 3` while a lock is held.
* `release(key, owner)` gives the lock back, if `owner` still holds it.

"If `owner` still holds it" has to be checked in the same statement that writes: checked in a separate read first, a takeover could slip in between. And the store measures `ttl` with its own clock, so every instance agrees on when a lock expires whatever their clocks say. With Drizzle, that is one conditional insert and two conditional updates:

database/drizzle-lock.store.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { InjectDrizzle } from '@nestjs/drizzle';
import { LocksStorage, type LockAcquireResult, type LockStore } from '@nestjs/locks';
import { and, eq, gt, sql } from 'drizzle-orm';
import type { Database } from './drizzle.js';
import { locks } from './schema.js';

/** `ttl` from now, on the database's clock. */
const expiresIn = (ttl: number) => sql`clock_timestamp() + ${ttl} * interval '1 millisecond'`;

/** The lock on `key`, if `owner` still holds it: the compare-and-set of renew() and release(). */
const heldBy = (key: string, owner: string) =>
  and(eq(locks.key, key), eq(locks.owner, owner), gt(locks.expiresAt, sql`clock_timestamp()`));

@Injectable()
export class DrizzleLockStore implements LockStore {
  constructor(
    @InjectDrizzle() private readonly db: Database,
    storage: LocksStorage,
  ) {
    storage.registerSource(this);
  }

  async acquire(key: string, owner: string, ttl: number): Promise<LockAcquireResult> {
    // One statement: insert the lock, or take over a released or expired one. Of any number
    // of concurrent callers, one inserts or updates the row; the others find it held.
    const [row] = await this.db
      .insert(locks)
      .values({ key, owner, fencingToken: sql`nextval('locks_fencing_token_seq')`, expiresAt: expiresIn(ttl) })
      .onConflictDoUpdate({
        target: locks.key,
        // nextval() here runs after the row is locked: a later holder always gets a
        // greater token than the one before it. The row's own token is the floor, so a
        // sequence that went back (a restore, a failover) can't hand a key an old token.
        set: {
          owner,
          fencingToken: sql`greatest(nextval('locks_fencing_token_seq'), ${locks.fencingToken} + 1)`,
          expiresAt: expiresIn(ttl),
        },
        setWhere: sql`${locks.owner} is null or ${locks.expiresAt} <= clock_timestamp()`,
      })
      .returning({ fencingToken: locks.fencingToken });
    return row ? { acquired: true, fencingToken: row.fencingToken } : { acquired: false };
  }

  async renew(key: string, owner: string, ttl: number): Promise<boolean> {
    const rows = await this.db
      .update(locks)
      .set({ expiresAt: expiresIn(ttl) })
      .where(heldBy(key, owner))
      .returning({ key: locks.key });
    return rows.length === 1;
  }

  async release(key: string, owner: string): Promise<boolean> {
    // Keep the row, so the next acquire() always takes the update path above, whose token is
    // drawn after the row is locked.
    const rows = await this.db
      .update(locks)
      .set({ owner: null })
      .where(heldBy(key, owner))
      .returning({ key: locks.key });
    return rows.length === 1;
  }
}
```

A few things about this store:

* **`acquire()` is one statement.** The insert wins a key that has no row; the `ON CONFLICT DO UPDATE` with its `WHERE` takes over a released or expired one, and PostgreSQL re-checks that `WHERE` against the row after it locked it. Of many callers racing for the same key, one gets a row back and the rest get nothing. A `SELECT` followed by an `INSERT` would let several of them in.
* **The fencing token comes from a sequence**, drawn inside the statement, after the row lock. A sequence never goes back, so every acquisition of a key gets a greater token than the one before, across releases and expiries. It has gaps, because a caller that lost the race still consumed a value; that doesn't matter. The `greatest()` makes the row's own token the floor of the next one: if the sequence ever does go back (a restore from a backup, a failover to a replica that lagged), a key still can't get a token it had before. [Fence the writes](/reliability/locks#fence-the-writes) shows what the token is for.
* **`release()` keeps the row** and clears the owner, so the next acquisition always takes the update path. With a delete, an insert that drew its token early could win the key after a later holder had already released it, and hand out a smaller token.
* **`clock_timestamp()`**, not `now()`: `now()` is the transaction's start time, which is what a lock's expiry must not depend on.
* Why a table and not `pg_advisory_lock()`: an advisory lock is bound to a session, so the holder would have to keep one connection checked out of the pool for the whole critical section, would lose the lock without knowing when that connection drops, can't renew it, and gets no expiry for a paused holder and no fencing token. A row has all of that, through any pool.

The package ships the contract as a test suite, so you can prove the store before you rely on it. `lockStoreContract()` returns cases for any test runner, and `concurrent: true` adds the races:

test/step-2.drizzle-lock-store.e2e-spec.ts

JS TS

```typescript

describe('DrizzleLockStore on PGlite, the LockStore contract', () => {
  const client = new PGlite();
  const db = drizzlePglite(client, { schema }) as unknown as Database;
  beforeAll(() => migratePglite(db as never, { migrationsFolder }));
  afterAll(() => client.close());

  // The concurrency cases run too; with one connection, PGlite runs them one statement at a time.
  const cases = lockStoreContract(() => new DrizzleLockStore(db, new LocksStorage()), { concurrent: true });
  for (const c of cases) {
    it(c.name, c.run);
  }
});
```

The example runs the same suite against a PostgreSQL server with a pool of 20 connections and 32 racing callers, where the statements really overlap. Run it that way in CI, on the PostgreSQL version you run in production.

Now register the module and the store, next to the application's `DrizzleModule`. The store is a plain provider; its constructor registers it, so there is nothing to configure:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { DrizzleModule } from '@nestjs/drizzle';
import { LocksModule } from '@nestjs/locks';
import { ScheduleModule } from '@nestjs/schedule';
import { drizzle } from 'drizzle-orm/node-postgres';
import { DrizzleLockStore } from './database/drizzle-lock.store.js';
import * as schema from './database/schema.js';
import { InventoryModule } from './inventory/inventory.module.js';
import { InvoicesModule } from './invoices/invoices.module.js';

@Module({
  imports: [
    // A pg pool on DATABASE_URL, closed in onApplicationShutdown(), after running jobs
    // finished and handed their locks back. The jobs and the store inject it with @InjectDrizzle().
    DrizzleModule.forRootAsync({
      useFactory: () => ({ drizzle, connection: process.env.DATABASE_URL!, schema }),
    }),
    ScheduleModule.forRoot(),
    LocksModule.forRoot(),
    InvoicesModule,
    InventoryModule,
  ],
  providers: [DrizzleLockStore],
})
export class AppModule {}
```

`LocksModule.forRoot()` takes a `ttl` (the default is `'30s'`: how long a lock lives without a renewal, so how soon another instance takes over after a crash), a `storeTimeout` (the default is `'10s'`: how long to wait for each store call before it fails, so a store that stops answering can't hang a job, a request or the shutdown), a `clock` for tests, and `allowInMemoryStorage`. `forRootAsync()` takes the same options from a factory. The module is global, so `Locks`, `LocksContext` and `LocksStorage` are available everywhere. When it initializes, it logs the store in use:

```bash

[Nest] 1270  - 09/24/2026, 9:44:02 AM     LOG [LocksModule] LocksStorage: DrizzleLockStore
```

With nothing registered, the line names `InMemoryLockStore` and what that means. With `NODE_ENV=production` and nothing registered, the application doesn't start, because in memory every instance would take the same lock and run the same job:

```bash

Error: LocksStorage: no LockStore is registered, and NODE_ENV is "production": in memory, a lock only excludes callers in this process, so every instance of the app would take the same lock and run the same job. Implement LockStore in a provider that injects LocksStorage and calls `storage.registerSource(this)` in its constructor, or set `allowInMemoryStorage: true` in the LocksModule options to run in memory anyway (one instance).
```

**With TypeORM.** The same store for an application whose ORM is TypeORM, on the same table and sequence. Drizzle stays the tutorial's path: take this store instead of the one above, not next to it. The table is an entity, and every column states its type, so that the TypeORM CLI, which loads it without decorator metadata, sees the same schema as the application:

typeorm/lock.entity.ts

JS TS

```typescript

import { Column, Entity, PrimaryColumn } from 'typeorm';

// The locks table, read and written by TypeOrmLockStore: the same table as the Drizzle
// schema in src/database/schema.ts. Every column states its type, so the entity loads the
// same with or without emitted decorator metadata (the TypeORM CLI runs it through tsx,
// which emits none).

@Entity('locks')
export class LockEntity {
  @PrimaryColumn({ type: 'text' })
  key: string;

  /** The holder's id; null once released. */
  @Column({ type: 'text', nullable: true })
  owner: string | null;

  /** Drawn from locks_fencing_token_seq, which the migration creates. `pg` returns a bigint as a string. */
  @Column({ type: 'bigint', name: 'fencing_token' })
  fencingToken: string;

  /** On the database's clock: every instance agrees on it. */
  @Column({ type: 'timestamptz', name: 'expires_at' })
  expiresAt: Date;
}
```

The TypeORM CLI and `TypeOrmModule` share one set of options, in a data source file:

typeorm/data-source.ts

JS TS

```typescript

import { DataSource, type DataSourceOptions } from 'typeorm';
import { LockEntity } from './lock.entity.js';
import { Locks1790321710846 } from './migrations/1790321710846-Locks.js';

/** What the application's TypeOrmModule and the TypeORM CLI share. */
export const dataSourceOptions = {
  type: 'postgres',
  url: process.env.DATABASE_URL,
  entities: [LockEntity],
  migrations: [Locks1790321710846],
} satisfies DataSourceOptions;

// The TypeORM CLI's data source: `migration:generate` compares the entities with this database.
export default new DataSource(dataSourceOptions);
```

Generate the migration from the entity, against a database with your previous migrations applied. The CLI needs a TypeScript loader for the data source file; this uses `tsx`:

```bash

$ npx tsx ./node_modules/typeorm/cli.js migration:generate src/typeorm/migrations/Locks -d src/typeorm/data-source.ts --pretty
Migration /store/src/typeorm/migrations/1790321710846-Locks.ts has been generated successfully.
```

TypeORM has no entity for a sequence, so the migration it writes creates the table alone. Add the sequence to it yourself, before the table, and drop it in `down()`:

typeorm/migrations/1790321710846-Locks.ts

JS TS

```typescript

import { MigrationInterface, QueryRunner } from "typeorm";

export class Locks1790321710846 implements MigrationInterface {
    name = 'Locks1790321710846'

    public async up(queryRunner: QueryRunner): Promise<void> {
        // Added by hand: TypeORM has no entity for a sequence, so the CLI doesn't generate it.
        await queryRunner.query(`
            CREATE SEQUENCE "locks_fencing_token_seq"
        `);
        await queryRunner.query(`
            CREATE TABLE "locks" (
                "key" text NOT NULL,
                "owner" text,
                "fencing_token" bigint NOT NULL,
                "expires_at" TIMESTAMP WITH TIME ZONE NOT NULL,
                CONSTRAINT "PK_c6e1e10d298aec42ba087dd57e5" PRIMARY KEY ("key")
            )
        `);
    }

    public async down(queryRunner: QueryRunner): Promise<void> {
        await queryRunner.query(`
            DROP TABLE "locks"
        `);
        await queryRunner.query(`
            DROP SEQUENCE "locks_fencing_token_seq"
        `);
    }

}
```

`migrations` in the data source lists it. Apply it, and check that the entity and the database agree. The check doesn't compare sequences, so the one you added doesn't count as a change:

```bash

$ npx tsx ./node_modules/typeorm/cli.js migration:run -d src/typeorm/data-source.ts
$ npx tsx ./node_modules/typeorm/cli.js migration:generate src/typeorm/migrations/Check -d src/typeorm/data-source.ts --check
No changes in database schema were found
```

Now the store, under the same rules as the Drizzle one:

typeorm/typeorm-lock.store.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { LocksStorage, type LockAcquireResult, type LockStore } from '@nestjs/locks';
import { DataSource } from 'typeorm';
import { LockEntity } from './lock.entity.js';

/** `ttl` from now, on the database's clock. */
const EXPIRES_IN = "clock_timestamp() + :ttl * interval '1 millisecond'";

/** The lock on `key`, if `owner` still holds it: the compare-and-set of renew() and release(). */
const HELD_BY = 'key = :key AND owner = :owner AND expires_at > clock_timestamp()';

@Injectable()
export class TypeOrmLockStore implements LockStore {
  constructor(
    private readonly dataSource: DataSource,
    storage: LocksStorage,
  ) {
    storage.registerSource(this);
  }

  async acquire(key: string, owner: string, ttl: number): Promise<LockAcquireResult> {
    // One statement: insert the lock, or take over a released or expired one. It is SQL
    // because the takeover draws its token from the locked row, which orUpdate() can't
    // express: it sets each column from EXCLUDED, whose nextval() ran before the row lock.
    const rows: { fencing_token: string }[] = await this.dataSource.query(
      `INSERT INTO locks (key, owner, fencing_token, expires_at)
       VALUES ($1, $2, nextval('locks_fencing_token_seq'), clock_timestamp() + $3 * interval '1 millisecond')
       ON CONFLICT (key) DO UPDATE SET
         owner = EXCLUDED.owner,
         fencing_token = greatest(nextval('locks_fencing_token_seq'), locks.fencing_token + 1),
         expires_at = clock_timestamp() + $3 * interval '1 millisecond'
       WHERE locks.owner IS NULL OR locks.expires_at <= clock_timestamp()
       RETURNING fencing_token`,
      [key, owner, ttl],
    );
    const [row] = rows;
    // `pg` returns a bigint as a string; the package takes the token as a number.
    return row ? { acquired: true, fencingToken: Number(row.fencing_token) } : { acquired: false };
  }

  async renew(key: string, owner: string, ttl: number): Promise<boolean> {
    const { affected } = await this.dataSource
      .createQueryBuilder()
      .update(LockEntity)
      .set({ expiresAt: () => EXPIRES_IN })
      .where(HELD_BY, { key, owner, ttl })
      .execute();
    return affected === 1;
  }

  async release(key: string, owner: string): Promise<boolean> {
    // Keep the row, so the next acquire() always takes the update path above, whose token is
    // drawn after the row is locked.
    const { affected } = await this.dataSource
      .createQueryBuilder()
      .update(LockEntity)
      .set({ owner: null })
      .where(HELD_BY, { key, owner })
      .execute();
    return affected === 1;
  }
}
```

* **`acquire()` is the one statement written as SQL**, through `dataSource.query()`. The insert query builder's `orUpdate()` writes an `ON CONFLICT DO UPDATE`, with the `WHERE` in its `overwriteCondition` option, but it sets every column from `EXCLUDED`: the token would be the one the insert drew before the row was locked, which a later holder of the key may already have passed. The SQL draws it in the `SET`, after the row lock, as the Drizzle store does.
* **`renew()` and `release()`** are the update query builder with the owner and the expiry in the `WHERE`, and read `affected`. Never `save()`, and no `findOneBy()` first: a read before the write lets a takeover slip in between.
* **The token is converted with `Number()`.**`pg` returns a `bigint` column as a string, and the package refuses a string token.
* **Use it** in place of the Drizzle store: `TypeOrmModule.forRoot(dataSourceOptions)` in `AppModule`, and `TypeOrmLockStore` in its providers instead of `DrizzleLockStore`. It injects the `DataSource` that `TypeOrmModule` provides, and the startup line names `TypeOrmLockStore`.

The contract suite runs on it unchanged, with the concurrency cases. TypeORM connects through `pg`, so the suite needs a PostgreSQL server and is skipped without one. Three more cases check that a key's tokens keep growing after the sequence went back, that the entity and the migration agree (what `migration:generate --check` checks), and that the store registers itself when provided in a module:

test/typeorm-lock.store.e2e-spec.ts

JS TS

```typescript

/**
 * TypeOrmLockStore against the package's contract suite (`@nestjs/locks/testing`), on
 * PostgreSQL (the server in SQL_TEST_PG_URL, else a throwaway local cluster; see
 * test-support/postgres.ts), with the migration the TypeORM CLI generated. A pool, so the
 * concurrency cases race for real. Skipped, with the reason, without a server.
 */
import { Logger } from '@nestjs/common';
import { LocksModule, LocksStorage } from '@nestjs/locks';
import { lockStoreContract } from '@nestjs/locks/testing';
import { Test } from '@nestjs/testing';
import { TypeOrmModule } from '@nestjs/typeorm';
import { DataSource } from 'typeorm';
import { startPostgres } from '../../../test-support/postgres.js';
import { dataSourceOptions } from '../src/typeorm/data-source.js';
import { TypeOrmLockStore } from '../src/typeorm/typeorm-lock.store.js';

const { postgres, reason } = await startPostgres();
afterAll(() => postgres?.stop());

describe.skipIf(!postgres)(`TypeOrmLockStore on PostgreSQL${postgres ? '' : ` (skipped: ${reason})`}`, () => {
  let dataSource: DataSource;
  let url: string;

  beforeAll(async () => {
    url = await postgres!.createDatabase('locks_typeorm_store');
    dataSource = await new DataSource({ ...dataSourceOptions, url, poolSize: 20 }).initialize();
    await dataSource.runMigrations();
  });
  afterAll(() => dataSource?.destroy());

  describe('the LockStore contract', () => {
    // The expiry cases wait in real time: the store reads the database's clock.
    const cases = lockStoreContract(() => new TypeOrmLockStore(dataSource, new LocksStorage()), { concurrent: { callers: 32 } });
    for (const c of cases) {
      it(c.name, c.run);
    }
  });

  it("keeps a key's tokens growing after the sequence went back (a restore, a failover to a lagging replica)", async () => {
    const store = new TypeOrmLockStore(dataSource, new LocksStorage());
    const key = `reset-${Date.now()}`;
    await dataSource.query("SELECT setval('locks_fencing_token_seq', 1000)");
    const before = await store.acquire(key, 'a', 5_000);
    expect(before.acquired).toBe(true);
    expect(await store.release(key, 'a')).toBe(true);
    await dataSource.query('ALTER SEQUENCE locks_fencing_token_seq RESTART WITH 1');
    const after = await store.acquire(key, 'b', 5_000);
    expect(after.acquired).toBe(true);
    expect((after as { fencingToken: number }).fencingToken).toBeGreaterThan((before as { fencingToken: number }).fencingToken);
  });

  it('has a migration that matches the entity (what `migration:generate --check` checks)', async () => {
    const { upQueries } = await dataSource.driver.createSchemaBuilder().log();
    expect(upQueries.map((query) => query.query)).toEqual([]);
  });

  it('registers itself when provided in a module', async () => {
    const log = vi.spyOn(Logger.prototype, 'log').mockImplementation(() => {});
    const app = await Test.createTestingModule({
      imports: [TypeOrmModule.forRoot({ ...dataSourceOptions, url }), LocksModule.forRoot()],
      providers: [TypeOrmLockStore],
    }).compile();
    await app.init();
    try {
      expect(app.get(LocksStorage).source).toBe(app.get(TypeOrmLockStore));
      expect(log).toHaveBeenCalledWith('LocksStorage: TypeOrmLockStore');
    } finally {
      log.mockRestore();
      await app.close();
    }
  });
});
```

> **Hint** Using Prisma? [The store contract](/reliability/locks#the-store-contract), after the tutorial, lists what the store must guarantee and how Prisma expresses the atomic methods. Test your store against the same cases.

#### Run each job on one instance[#](/reliability/locks#run-each-job-on-one-instance)

Add `@OnOneInstance()` to both jobs, next to `@Cron()`:

invoices/invoice-export.job.step-3.ts

JS TS

```typescript

import { OnOneInstance } from '@nestjs/locks';
import { Cron } from '@nestjs/schedule';
```

invoices/invoice-export.job.step-3.ts

JS TS

```typescript

@Cron(process.env.INVOICE_EXPORT_CRON ?? '0 2 * * *', { name: 'invoice-export', timeZone: 'Europe/Warsaw' })
@OnOneInstance({ key: 'invoices:nightly-export' })
async exportInvoices() {
```

inventory/stock-reconciliation.job.step-3.ts

JS TS

```typescript

@Cron(process.env.STOCK_RECONCILIATION_CRON ?? CronExpression.EVERY_5_MINUTES, { name: 'stock-reconciliation' })
@OnOneInstance({ key: 'inventory:stock-reconciliation' })
async reconcileStock() {
```

That is the whole change. What it does:

* **The first instance whose scheduler fires the job takes the job's lease**, a lock named after the key with an `:owner` suffix, and keeps renewing it every `ttl / 3` for as long as it is up. It runs this tick and every tick after it.
* **On the other instances, the tick is skipped**: the call resolves without running the method, and a debug line says why. Nothing is queued; the job's schedule is the schedule.
* **When the owner dies**, it stops renewing, the lease expires `ttl` (30 seconds) later, and the first instance whose tick comes after that takes the job over. When the owner shuts down cleanly, it finishes the runs in progress, hands the lease back, and the next tick anywhere takes it.
* **The decorators wrap the method.**`@nestjs/schedule` isn't patched, and it doesn't know they are there: its explorer finds the `@Cron()` metadata on the wrapper, in either decorator order, and calls the wrapper, which asks `LocksModule` whether this call may run. `@Interval()` and `@Timeout()` jobs work the same way, and so does calling the method yourself.
* **The key** defaults to `ClassName.methodName`. Set it on a job that must never run twice: a renamed class or method changes the default, and during a rolling deploy the old and the new instances would each run the job once. Two jobs with the same default key fail at startup, and so does a job whose key is another job's lease (`<key>:owner`) or an election's key: they would exclude each other silently.

Ownership is sticky on purpose. A race per tick would be simpler, but a tick isn't an instant: the instances' clocks differ by tens of milliseconds, so a per-tick lock would have to outlive the run by the skew, and a fast job would need a "ran at" record to stop a lagging instance from running the tick again. A lease held between ticks has none of that, at the cost of one instance running all of a job's ticks, which a scheduled job rarely minds.

What about a tick that nobody runs? While the owner is down, up to `ttl` of ticks are skipped, and the nightly export can fall on those thirty seconds. **Missed ticks aren't caught up**: nothing records when a job last ran. Write jobs that do everything that is due rather than "yesterday's". The export takes every order without an invoice, so a night it didn't run is caught up the next night; the reconciliation writes the current counts, so a missed tick costs five minutes of staleness. A job whose ticks each do something distinct keeps that record in its own table.

The test from [See the problem](/reliability/locks#see-the-problem), with the new jobs and the store, now records every invoice once, and the test that stops an instance from renewing (its clock stands still, as if the process had died) shows the handover:

test/step-3.one-instance.e2e-spec.ts

JS TS

```typescript

it('records every invoice once, and counts the stock once per tick', async () => {
  const apps = [await start(), await start(), await start()];
  await tick(apps, 'export');
  expect(booked(accounting)).toEqual([['ord_1001', 'ord_1002', 'ord_1004']]);
  await tick(apps, 'reconcile');
  await tick(apps, 'reconcile');
  expect(warehouse.counts).toBe(2);
  expect(logger.matching(/runs on this instance \(lease "inventory:stock-reconciliation:owner"/)).toHaveLength(1);
  expect(logger.matching('Skipped StockReconciliationJob.reconcileStock: it runs on another instance')).toHaveLength(4);
});
```

test/step-3.one-instance.e2e-spec.ts

JS TS

```typescript

it('moves the job to another instance when its owner dies, after ttl', async () => {
  // A's clock stands still: it stops renewing, as if its process died.
  const crashed = await start({ clock: new ManualLockClock(), ttl: '1s' });
  const survivor = await start({ ttl: '1s' });
  await tick([crashed, survivor], 'export');
  expect(booked(accounting)).toHaveLength(1);

  await database.query("INSERT INTO orders (id, user_id, items, total, status, placed_at) VALUES ('ord_1005', 'usr_dave', '[]', 999, 'placed', now())");
  expect(await survivor.get(InvoiceExportJob).exportInvoices()).toBeUndefined(); // the lease is still A's
  await sleep(1_200); // the database's clock passes A's lease
  await survivor.get(InvoiceExportJob).exportInvoices();
  expect(booked(accounting)).toEqual([['ord_1001', 'ord_1002', 'ord_1004'], ['ord_1005']]);
});
```

`ManualLockClock` is the package's clock for tests: it only moves when told to. An instance on it never renews, so the database, on its own clock, expires the instance's locks after `ttl`.

#### Don't let a long run overlap itself[#](/reliability/locks#dont-let-a-long-run-overlap-itself)

`@OnOneInstance()` puts the reconciliation on one instance. It doesn't stop that instance from starting the next count while the last one is still running, and neither does a plain `@Cron()`. At month end the count takes longer than five minutes, so the warehouse gets a second full count, then a third. Add `@WithoutOverlapping()`:

inventory/stock-reconciliation.job.step-4.ts

JS TS

```typescript

@Cron(process.env.STOCK_RECONCILIATION_CRON ?? CronExpression.EVERY_5_MINUTES, { name: 'stock-reconciliation' })
@OnOneInstance({ key: 'inventory:stock-reconciliation' })
@WithoutOverlapping()
async reconcileStock() {
```

A run now takes a second lock, named after the same key (the two decorators on one method share it), holds it for the whole run, renewing it, and releases it when the run ends. A tick that finds the lock held is skipped, on this instance or any other: the ticks during a long count are dropped, and the first tick after it runs. If the run crashes, the lock expires after `ttl` and the next tick runs. `@WithoutOverlapping()` on its own, without `@OnOneInstance()`, means "any instance, one run at a time".

The test drives two instances on one `ManualLockClock`, holds a count open, and advances the clock through three ticks:

test/step-4.without-overlapping.e2e-spec.ts

JS TS

```typescript

it('with @WithoutOverlapping(), every tick during the run is skipped, then the next one runs', async () => {
  const [owner, other] = [await start(StepFourJob), await start(StepFourJob)];
  const slow = warehouse.pauseNext();
  const first = owner!.reconcileStock();
  await until(() => warehouse.counts === 1);
  for (let tick = 0; tick < 3; tick++) {
    await clock.advance('5m'); // the run goes on, its locks renewed
    await Promise.all([owner!.reconcileStock(), other!.reconcileStock()]);
  }
  expect(warehouse.counts).toBe(1);
  expect(logger.matching('Skipped StockReconciliationJob.reconcileStock: a run is still in progress')).toHaveLength(3);
  expect(logger.matching('Skipped StockReconciliationJob.reconcileStock: it runs on another instance')).toHaveLength(3);
  slow.resume();
  await first;
  await clock.advance('5m');
  await Promise.all([owner!.reconcileStock(), other!.reconcileStock()]);
  expect(warehouse.counts).toBe(2);
});
```

`clock.advance('5m')` fires every renewal that falls due on the way, in order, and waits for each to reach the store, so fifteen minutes of a long run take a moment, with the run's locks renewed the whole time.

#### Fence the writes[#](/reliability/locks#fence-the-writes)

A lease can't stop a holder that is paused. Take the reconciliation on instance A: it reads the counts from the warehouse (salmon kibble: 12), and then A stalls, in a stop-the-world garbage collection, a swap, a VM migration, a debugger. It stops renewing. Thirty seconds later the database expires its locks, and B takes the job over at its next tick: it reads fresher counts (three bags were sold and shipped since: salmon kibble: 9) and writes them. Then A wakes up and finishes its run, with the counts it read before the pause. Salmon kibble is back at 12, and the store sells three bags it doesn't have.

A's signal aborts at its next renewal, when the database refuses it, but a write that is already on its way goes through. Note what the lease does and doesn't promise. A holder counts its own deadline, `ttl` from the moment it sent the last renewal the store confirmed, which is before the store processed it: a holder that is running gives up no later than the store's expiry, so its signal aborts before any other instance can take the key. The window exists only for a holder that isn't running (paused, stopped, its event loop blocked): from the store's expiry until it runs again, it still believes it holds the lock. What stops its write is the **fencing token**: every acquisition of a key gets a token greater than every token the key had before, and the resource being written keeps the highest token it has seen and refuses a lower one. A's token is lower than B's, so A's late write updates nothing.

The products table gets a column for it:

database/schema.ts

JS TS

```typescript

export const products = pgTable('products', {
  id: text('id').primaryKey(),
  name: text('name').notNull(),
  /** In cents. */
  price: integer('price').notNull(),
  inStock: integer('in_stock').notNull(),
  /** The fencing token of the stock reconciliation run that last wrote `inStock`. */
  stockFencingToken: bigint('stock_fencing_token', { mode: 'number' }).notNull().default(0),
});
```

```bash

$ npx drizzle-kit generate --name=stock_fencing_token
$ npx drizzle-kit migrate
```

drizzle/0003\_stock\_fencing\_token.sql

JS TS

```sql

ALTER TABLE "products" ADD COLUMN "stock_fencing_token" bigint DEFAULT 0 NOT NULL;
```

The repository writes a count only if no run with a greater token has written that product, and records the token it wrote with, in the same statement:

inventory/stock.repository.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { InjectDrizzle } from '@nestjs/drizzle';
import { and, eq, lte } from 'drizzle-orm';
import type { Database } from '../database/drizzle.js';
import { products } from '../database/schema.js';
import type { StockCount } from './warehouse.client.js';

@Injectable()
export class StockRepository {
  constructor(@InjectDrizzle() private readonly db: Database) {}

  /**
   * Writes the counts a reconciliation run read, fenced by the run's token: a product that a
   * newer run (a greater token) already wrote is left alone.
   */
  async writeStock(counts: StockCount[], fencingToken: number): Promise<{ written: number; stale: number }> {
    let written = 0;
    for (const { productId, count } of counts) {
      const rows = await this.db
        .update(products)
        .set({ inStock: count, stockFencingToken: fencingToken })
        .where(and(eq(products.id, productId), lte(products.stockFencingToken, fencingToken)))
        .returning({ id: products.id });
      written += rows.length;
    }
    return { written, stale: counts.length - written };
  }
}
```

The job gets its token, and its signal, from `LocksContext`. `@nestjs/schedule` calls the method without arguments, so the context carries them, through `AsyncLocalStorage`, to every service the job calls:

inventory/stock-reconciliation.job.ts

JS TS

```typescript

import { Injectable, Logger } from '@nestjs/common';
import { LocksContext, OnOneInstance, WithoutOverlapping } from '@nestjs/locks';
import { Cron, CronExpression } from '@nestjs/schedule';
import { StockRepository } from './stock.repository.js';
import { WarehouseClient } from './warehouse.client.js';

@Injectable()
export class StockReconciliationJob {
  private readonly logger = new Logger(StockReconciliationJob.name);

  constructor(
    private readonly warehouseClient: WarehouseClient,
    private readonly stockRepository: StockRepository,
    private readonly locksContext: LocksContext,
  ) {}

  @Cron(process.env.STOCK_RECONCILIATION_CRON ?? CronExpression.EVERY_5_MINUTES, { name: 'stock-reconciliation' })
  @OnOneInstance({ key: 'inventory:stock-reconciliation' })
  @WithoutOverlapping()
  async reconcileStock() {
    const { fencingToken, signal } = this.locksContext;
    // Aborts the count if this run loses its lock...
    const counts = await this.warehouseClient.stockCounts({ signal });
    // ...and the token stops a write that slips through anyway.
    const { written, stale } = await this.stockRepository.writeStock(counts, fencingToken!);
    if (stale > 0) {
      this.logger.warn(`Skipped ${stale} stale stock writes: a newer run (token > ${fencingToken}) wrote those products`);
    }
    this.logger.log(`Reconciled stock for ${written} products (fencing token ${fencingToken})`);
  }
}
```

The token is the run lock's, a new and higher one for every run. The signal aborts when the run's lock or the instance's lease is lost, and its reason is a `LockLostError` that says how the loss was detected: the store refused a renewal, or `ttl` passed without one reaching the store. Pass the signal to what the job calls, `fetch`, the database driver, an HTTP client; a job that ignores it keeps running, as it would in any process. Nothing is killed.

The test reproduces the pause against PostgreSQL. Instance A runs on a `ManualLockClock`, so it stops renewing; the warehouse client holds A's count open after A read it; the shelves change; B takes over 1.2 seconds later (the test's `ttl` is one second) and writes salmon kibble: 9. Then A's count resumes:

test/step-5.fencing.e2e-spec.ts

JS TS

```typescript

it('without fencing, the paused instance overwrites the fresh count with its stale one', async () => {
  const { stale, resume } = await pauseAWhileBTakesOver(UnfencedJob);
  resume(); // A wakes up and writes what it read before the pause
  expect(await stale).toBeUndefined();
  expect(await kibble()).toBe(12); // three bags the store doesn't have
});

it("with the run's fencing token, the database refuses the stale write", async () => {
  const { stale, resume } = await pauseAWhileBTakesOver(StockReconciliationJob);
  resume(); // A wakes up before it noticed it lost its locks, and writes
  expect(await stale).toBeUndefined();
  expect(await kibble()).toBe(9);
  expect(logger.matching(/WARN Skipped 3 stale stock writes: a newer run \(token > \d+\) wrote those products/)).toHaveLength(1);
  const tokens = await database.query<{ stock_fencing_token: string }>('SELECT DISTINCT stock_fencing_token FROM products');
  expect(tokens).toHaveLength(1); // every product carries B's token
});

it('a run that notices it lost its lock stops at its signal, before writing', async () => {
  const { stale, resume } = await pauseAWhileBTakesOver(StockReconciliationJob);
  await clockA.advance('1s'); // A's clock moves: its next renewal is refused
  expect(await stale).toBeInstanceOf(LockLostError);
  resume();
  expect(await kibble()).toBe(9);
  expect(logger.matching(/WARN Lost the lock "inventory:stock-reconciliation(:owner)?"/).length).toBeGreaterThan(0);
});
```

With the previous section's job, the stale write goes through and salmon kibble is back at 12. With the token, the database refuses it, and the job logs that it skipped three stale writes. And a run that gets to its next renewal before writing stops at the signal, with a `LockLostError`, and writes nothing. The package logs a warning for every lost lock and emits a `lock-lost` event, because a lost lock means another instance may be in the same critical section right now: only the token keeps the two apart.

#### Run the export by hand[#](/reliability/locks#run-the-export-by-hand)

Accounting sometimes asks for the export before 02:00. An admin endpoint runs it, and it must never run alongside the scheduled run, on any instance. The scheduled run holds the lock named by its key; the endpoint takes the same lock with `Locks.withLock()`, waiting up to two seconds for a run that is about to finish:

invoices/invoice-exports.controller.ts

JS TS

```typescript

import { ConflictException, Controller, HttpCode, Post, UseGuards } from '@nestjs/common';
import { LockNotAcquiredError, Locks } from '@nestjs/locks';
import { AdminGuard } from '../admin/admin.guard.js';
import { INVOICE_EXPORT_LOCK, InvoiceExportJob } from './invoice-export.job.js';

@Controller('admin/invoice-exports')
@UseGuards(AdminGuard)
export class InvoiceExportsController {
  constructor(
    private readonly locks: Locks,
    private readonly invoiceExportJob: InvoiceExportJob,
  ) {}

  /** Runs the export now, unless a run (scheduled or not) holds its lock. */
  @Post()
  @HttpCode(200)
  async exportNow() {
    try {
      return await this.locks.withLock(INVOICE_EXPORT_LOCK, () => this.invoiceExportJob.export(), { wait: '2s' });
    } catch (error) {
      if (error instanceof LockNotAcquiredError) {
        throw new ConflictException('An invoice export is already running. Try again when it has finished.');
      }
      throw error;
    }
  }
}
```

The job exports the key as a constant, gets `@WithoutOverlapping()` too, and splits the work out of the scheduled method so the endpoint can call it and return its result:

invoices/invoice-export.job.ts

JS TS

```typescript

/** The export's lock: held by a run, scheduled or started by hand. */
export const INVOICE_EXPORT_LOCK = 'invoices:nightly-export';

export interface InvoiceExportResult {
  exported: number;
  batchId?: string;
}
```

invoices/invoice-export.job.ts

JS TS

```typescript

@Cron(process.env.INVOICE_EXPORT_CRON ?? '0 2 * * *', { name: 'invoice-export', timeZone: 'Europe/Warsaw' })
@OnOneInstance({ key: INVOICE_EXPORT_LOCK })
@WithoutOverlapping()
async exportInvoices() {
  await this.export();
}

/** Call it under the INVOICE_EXPORT_LOCK lock. */
async export(): Promise<InvoiceExportResult> {
```

`withLock(key, fn, options)` runs `fn` under the lock and releases it whether `fn` resolves or throws. `wait` is how long to keep trying, with backoff, before it gives up with a `LockNotAcquiredError`; the default is to try once. `acquire(key, options)` is the same without the callback: it resolves a `Lock`, or `null` when the key was taken, and you release it yourself, or with `await using`. A `Lock` has the `fencingToken` and the `signal`, and inside `withLock()` so does `LocksContext`, exactly as in a job.

Both also take a `signal` of their own, the request's for example, which stops the waiting. It stops the wait for the store too: a call still waiting for the store's answer rejects with the signal's reason, `fn` doesn't run, and a lock the store grants after that goes back to it. `wait` doesn't cut short a store call already on its way; the module's `storeTimeout` does, so a call takes at most `wait` plus `storeTimeout`. A store that doesn't answer within `storeTimeout` fails the call with a `LockStoreTimeoutError`.

Neither `LockNotAcquiredError` nor `LockStoreTimeoutError` carries an HTTP status: contention and a stalled store aren't the caller's mistake, so the handler decides. Here a taken lock is a `409`, and anything else is rethrown. While the export runs by hand, the scheduled tick on any instance finds the lock held and skips.

> **Hint**`AdminGuard` is a placeholder. Protect the route with your application's real [authorization](/security/authorization).

#### The store on Redis[#](/reliability/locks#the-store-on-redis)

The store is a contract, so it can live wherever your instances already meet. If that is Redis, each method is one Lua script, which Redis runs atomically:

redis/redis-lock.store.ts

JS TS

```typescript

import { Inject, Injectable } from '@nestjs/common';
import { LocksStorage, type LockAcquireResult, type LockStore } from '@nestjs/locks';
import { REDIS } from './redis.module.js';

/** The one ioredis method this store needs. */
export interface RedisEval {
  eval(script: string, numKeys: number, ...args: (string | number)[]): Promise<unknown>;
}

// Takes the lock if nobody holds it, expiring on Redis's clock, and draws a fencing token
// from a counter that never goes back. Returns the token, or 0.
const ACQUIRE = `
if redis.call('SET', KEYS[1], ARGV[1], 'NX', 'PX', ARGV[2]) then
  return redis.call('INCR', KEYS[2])
end
return 0
`;

// Renews the lock, if it is still ours.
const RENEW = `
if redis.call('GET', KEYS[1]) == ARGV[1] then
  return redis.call('PEXPIRE', KEYS[1], ARGV[2])
end
return 0
`;

// Deletes the lock, if it is still ours.
const RELEASE = `
if redis.call('GET', KEYS[1]) == ARGV[1] then
  return redis.call('DEL', KEYS[1])
end
return 0
`;

/** Where the fencing counter lives; no lock key can be named like it. */
const FENCING_COUNTER = 'locks:fencing-token';

@Injectable()
export class RedisLockStore implements LockStore {
  constructor(
    @Inject(REDIS) private readonly redis: RedisEval,
    storage: LocksStorage,
  ) {
    storage.registerSource(this);
  }

  async acquire(key: string, owner: string, ttl: number): Promise<LockAcquireResult> {
    const token = Number(await this.redis.eval(ACQUIRE, 2, this.key(key), FENCING_COUNTER, owner, ttl));
    return token > 0 ? { acquired: true, fencingToken: token } : { acquired: false };
  }

  async renew(key: string, owner: string, ttl: number): Promise<boolean> {
    return (await this.redis.eval(RENEW, 1, this.key(key), owner, ttl)) === 1;
  }

  async release(key: string, owner: string): Promise<boolean> {
    return (await this.redis.eval(RELEASE, 1, this.key(key), owner)) === 1;
  }

  private key(key: string) {
    return `locks:key:${key}`;
  }
}
```

`SET NX PX` takes the key only if it is free, expiring on Redis's clock in milliseconds, and the `INCR` in the same script draws the token from one counter for every key. Fencing is only as durable as that counter. It never expires, and it must never go back: give Redis persistence (AOF, or RDB with a short interval) and `maxmemory-policy noeviction`, because a counter that restarts at 1 (a restart without persistence, a `FLUSHALL`) hands out tokens that holders already have, and a lock evicted under memory pressure is a lock lost. A failover to an asynchronous replica can lose the last writes too: a lock taken just before it, which is the paused-holder case the token covers, but also the counter's last increments, after which the next holder may draw a token the previous one already has, and the token no longer tells them apart. Where fencing must hold across a failover, keep the locks in the database, whose sequence is in the same WAL as the rows, or replicate Redis synchronously.

On Redis Cluster, `ACQUIRE` fails with a `CROSSSLOT` error as written: a cluster runs a script only when all its keys hash to the same slot, and the lock's key and the counter don't. Name both under one hash tag, `{locks}:key:<key>` and `{locks}:fencing-token`: the cluster then hashes only `locks`, so the counter and every lock share one slot, on one shard. A counter under a new name, or on a new cluster, starts again at 1, which is the restart it must never make. Before the first acquire on it, stop the instances that use the old keys and set the new counter to the old one's value (`SET {locks}:fencing-token <value>`), so the next token is higher than any already handed out.

The `redis.module` provides the client under the `REDIS` token; the example uses a minimal client with ioredis's `eval()` signature, to stay free of dependencies, and in your application it is `new Redis(process.env.REDIS_URL)`:

redis/redis.module.ts

JS TS

```typescript

import { Global, Inject, Module, type OnApplicationShutdown } from '@nestjs/common';
import { RedisClient } from './redis.client.js';

export const REDIS = Symbol('REDIS');

@Global()
@Module({
  providers: [
    {
      provide: REDIS,
      // With ioredis: new Redis(process.env.REDIS_URL)
      useFactory: () => new RedisClient(process.env.REDIS_URL ?? 'redis://127.0.0.1:6379'),
    },
  ],
  exports: [REDIS],
})
export class RedisModule implements OnApplicationShutdown {
  constructor(@Inject(REDIS) private readonly redis: RedisClient) {}

  // After onModuleDestroy(), where running jobs finish and hand their locks back.
  async onApplicationShutdown() {
    await this.redis.quit();
  }
}
```

Swap the provider in the application module, and nothing else changes:

app.module.step-7.ts

JS TS

```typescript

@Module({
  imports: [
    DrizzleModule.forRootAsync({
      useFactory: () => ({ drizzle, connection: process.env.DATABASE_URL!, schema }),
    }),
    RedisModule,
    ScheduleModule.forRoot(),
    LocksModule.forRoot(),
    InvoicesModule,
    InventoryModule,
  ],
  providers: [RedisLockStore],
})
export class AppModule {}
```

The example runs the contract suite against a real `redis-server`, on eight connections so the calls overlap, and then three instances of the application on it:

test/step-7.redis-lock-store.e2e-spec.ts

JS TS

```typescript

describe('the LockStore contract', () => {
  // Several connections, so calls really overlap; expiry is Redis's own clock (real time).
  const pool = Array.from({ length: 8 }, () => new RedisLockStore(connect(), new LocksStorage()));
  let next = 0;
  const cases = lockStoreContract(() => pool[next++ % pool.length]!, { concurrent: true });
  for (const c of cases) {
    it(c.name, c.run);
  }
});
```

Close the Redis client in `onApplicationShutdown()`, as the module does; `@nestjs/drizzle` closes the database pool in the same phase. Nest runs each shutdown phase for the whole application before the next: the package hands the leases back in `onModuleDestroy()` and releases every other lock still held in `beforeApplicationShutdown()`, so by the time any module's `onApplicationShutdown()` runs, nothing of the package's needs the connection, whatever the import order. A tick or an election still waiting for the store when the shutdown begins stops waiting: the tick is skipped, and a lock the store grants after that goes back to it, so a stalled store doesn't hold up the deploy.

#### Hold the warehouse feed on one instance[#](/reliability/locks#hold-the-warehouse-feed-on-one-instance)

The warehouse pushes low-stock alerts over a feed that allows one connection per shop. That isn't a scheduled job; it's a connection one instance should hold for as long as it lives, and another should take over when it goes down. That is a leader election, and it is the same lease as a job's ownership, held on purpose:

inventory/warehouse-feed.ts

JS TS

```typescript

import { Injectable, Logger } from '@nestjs/common';
import { LeaderElection, type Lock, type OnLeadershipAcquired, type OnLeadershipLost } from '@nestjs/locks';
import { WarehouseClient } from './warehouse.client.js';

/**
 * The warehouse's alert feed allows one connection per shop, so one instance of the app
 * holds it: the leader. When the leader goes down, another instance connects within the
 * lease's `ttl`.
 */
@Injectable()
@LeaderElection('inventory:warehouse-feed')
export class WarehouseFeed implements OnLeadershipAcquired, OnLeadershipLost {
  private readonly logger = new Logger(WarehouseFeed.name);

  constructor(private readonly warehouseClient: WarehouseClient) {}

  onLeadershipAcquired(lock: Lock) {
    this.logger.log(`Connected to the warehouse feed (fencing token ${lock.fencingToken})`);
    // The connection ends with the leadership: `lock.signal` aborts when the lease is lost
    // or this instance steps down.
    this.warehouseClient.subscribe(
      (alert) => this.logger.warn(`Low stock: ${alert.count} left of ${alert.productId}`),
      { signal: lock.signal },
    );
  }

  onLeadershipLost() {
    this.logger.log('Disconnected from the warehouse feed');
  }
}
```

inventory/inventory.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { StockReconciliationJob } from './stock-reconciliation.job.js';
import { StockRepository } from './stock.repository.js';
import { WarehouseClient } from './warehouse.client.js';
import { WarehouseFeed } from './warehouse-feed.js';

@Module({
  providers: [StockReconciliationJob, StockRepository, WarehouseClient, WarehouseFeed],
})
export class InventoryModule {}
```

`@LeaderElection(key)` goes on a singleton provider. From `onApplicationBootstrap`, every instance tries to take the lease on the key, and keeps trying every `ttl / 3`; the one that has it renews it. `onLeadershipAcquired(lock)` runs when this instance becomes the leader, with the lease's `signal` and `fencingToken`; `onLeadershipLost(lock)` when it stops leading, because the lease was lost or because it stepped down, at shutdown or after `onLeadershipAcquired()` threw. The `ttl` option sets the lease's; the default is the module's 30 seconds, so a crashed leader is replaced within half a minute, and a leader that shuts down cleanly is replaced at the others' next try.

The test starts three instances and shows one connection, a handover at shutdown, and the paused leader's blind spot:

test/step-8.leader-election.e2e-spec.ts

JS TS

```typescript

await until(() => connected().length === 2, 10_000); // the lease expired in the database
warehouse.notify({ productId: 'salmon-kibble-2kg', count: 2 });
// Both receive it: the paused leader hasn't noticed yet. Anything it writes on the feed's
// behalf needs its fencing token, which is lower than the new leader's.
expect(logger.matching('WARN Low stock: 2 left of salmon-kibble-2kg')).toHaveLength(2);
// The old leader wakes up: its renewal is refused, and it learns it lost the lease.
await clock.advance('3s');
expect(leading.get(crashed)).toBe(false);
expect(disconnected()).toHaveLength(1);
```

A leader that pauses is still connected until its next renewal fails, and receives what the feed sends in between. That is the same blind spot as in [Fence the writes](/reliability/locks#fence-the-writes), with the same answer: what the leader does on the group's behalf carries the lease's token.

#### Try it[#](/reliability/locks#try-it)

Create the database and apply the migrations:

```bash

$ psql postgres://localhost:5432/postgres -c 'CREATE DATABASE store'
$ DATABASE_URL=postgres://localhost:5432/store npx drizzle-kit migrate
```

Start three instances on ports 3001, 3002 and 3003, with `ADMIN_TOKEN=s3cret` and a stock reconciliation every ten seconds instead of five minutes, so there is something to watch: `STOCK_RECONCILIATION_CRON='*/10 * * * * *'`. Each logs the lock store it registered. The first one up leads the warehouse feed, and takes the reconciliation at the first tick, before the other two are up:

```bash

[Nest] 48817  - 09/25/2026, 8:59:26 AM     LOG [LocksModule] LocksStorage: DrizzleLockStore
[Nest] 48817  - 09/25/2026, 8:59:26 AM     LOG [NestApplication] Nest application successfully started +9ms
[Nest] 48817  - 09/25/2026, 8:59:26 AM     LOG [Locks] Leading "inventory:warehouse-feed" (fencing token 1)
[Nest] 48817  - 09/25/2026, 8:59:26 AM     LOG [WarehouseFeed] Connected to the warehouse feed (fencing token 1)
[Nest] 48817  - 09/25/2026, 8:59:30 AM     LOG [Locks] StockReconciliationJob.reconcileStock runs on this instance (lease "inventory:stock-reconciliation:owner", fencing token 2)
[Nest] 48817  - 09/25/2026, 8:59:30 AM     LOG [WarehouseClient] Counted 3 products
[Nest] 48817  - 09/25/2026, 8:59:30 AM     LOG [StockReconciliationJob] Reconciled stock for 3 products (fencing token 3)
[Nest] 48817  - 09/25/2026, 8:59:40 AM     LOG [WarehouseClient] Counted 3 products
[Nest] 48817  - 09/25/2026, 8:59:40 AM     LOG [StockReconciliationJob] Reconciled stock for 3 products (fencing token 9)
```

The other two skip every tick, at debug level:

```bash

[Nest] 48849  - 09/25/2026, 8:59:40 AM   DEBUG [Locks] Skipped StockReconciliationJob.reconcileStock: it runs on another instance
[Nest] 48849  - 09/25/2026, 8:59:50 AM   DEBUG [Locks] Skipped StockReconciliationJob.reconcileStock: it runs on another instance
```

The locks table shows the lease, the run lock (released, so its owner is null, and its token grows with every run) and the feed's lease. Every lock expires thirty seconds after its last renewal, on the database's clock:

```bash

$ psql postgres://localhost:5432/store -c "SELECT key, owner, fencing_token, expires_at - clock_timestamp() AS expires_in FROM locks ORDER BY key"
                 key                  |                owner                 | fencing_token |   expires_in
--------------------------------------+--------------------------------------+---------------+-----------------
 inventory:stock-reconciliation       |                                      |             9 | 00:00:26.026727
 inventory:stock-reconciliation:owner | 1feff401-d3c9-41b1-a559-d7b458e2905f |             2 | 00:00:26.054034
 inventory:warehouse-feed             | a4980740-ae27-4d95-af0b-0935d65fffb9 |             1 | 00:00:22.784351
(3 rows)
```

The fencing tokens have gaps: a refused acquisition still consumed a value from the sequence. Run the export by hand. Without the admin token the guard answers `403`; then send two requests at once, to two different instances:

```bash

$ curl -s -o /dev/null -w '%{http_code}\n' -X POST localhost:3002/admin/invoice-exports
403
$ for port in 3002 3003; do (curl -s -X POST localhost:$port/admin/invoice-exports -H 'x-admin-token: s3cret'; echo) & done; wait
{"exported":3,"batchId":"acc_447817af"}
{"exported":0}
```

One request took the lock and exported the three pending orders. The other waited for it, took the lock when it was released, and found nothing left. A request that waits more than two seconds gets a `409`. The instance that ran the export logs the batch:

```bash

[Nest] 48849  - 09/25/2026, 8:59:44 AM     LOG [AccountingClient] Booked batch acc_447817af: ord_1001, ord_1002, ord_1004
[Nest] 48849  - 09/25/2026, 8:59:44 AM     LOG [InvoiceExportJob] Exported 3 invoices in batch acc_447817af
```

Now kill the first instance, which runs the reconciliation and leads the feed, without giving it a chance to clean up:

```bash

$ kill -9 48817
```

Nothing happens for a while: the other two keep skipping, because the leases are still in the table. Thirty seconds after its last renewal each one expires. The feed's lease goes first, since it was renewed on its own schedule, and the next tick takes the job over:

```bash

[Nest] 48849  - 09/25/2026, 9:00:11 AM     LOG [Locks] Leading "inventory:warehouse-feed" (fencing token 28)
[Nest] 48849  - 09/25/2026, 9:00:11 AM     LOG [WarehouseFeed] Connected to the warehouse feed (fencing token 28)
[Nest] 48849  - 09/25/2026, 9:00:20 AM     LOG [Locks] StockReconciliationJob.reconcileStock runs on this instance (lease "inventory:stock-reconciliation:owner", fencing token 32)
[Nest] 48849  - 09/25/2026, 9:00:20 AM     LOG [WarehouseClient] Counted 3 products
[Nest] 48849  - 09/25/2026, 9:00:20 AM     LOG [StockReconciliationJob] Reconciled stock for 3 products (fencing token 34)
```

Stop the new owner with `Ctrl+C` instead. Its shutdown hooks hand both leases back (`main.ts` calls `app.enableShutdownHooks()`):

```bash

[Nest] 48849  - 09/25/2026, 9:00:35 AM     LOG [Locks] Stepped down from "inventory:warehouse-feed"
[Nest] 48849  - 09/25/2026, 9:00:35 AM     LOG [WarehouseFeed] Disconnected from the warehouse feed
```

The last instance takes the job at its next tick, and the feed at its next campaign, seconds later rather than thirty:

```bash

[Nest] 48859  - 09/25/2026, 9:00:40 AM     LOG [Locks] StockReconciliationJob.reconcileStock runs on this instance (lease "inventory:stock-reconciliation:owner", fencing token 41)
[Nest] 48859  - 09/25/2026, 9:00:40 AM     LOG [WarehouseClient] Counted 3 products
[Nest] 48859  - 09/25/2026, 9:00:40 AM     LOG [StockReconciliationJob] Reconciled stock for 3 products (fencing token 43)
[Nest] 48859  - 09/25/2026, 9:00:41 AM     LOG [Locks] Leading "inventory:warehouse-feed" (fencing token 45)
[Nest] 48859  - 09/25/2026, 9:00:41 AM     LOG [WarehouseFeed] Connected to the warehouse feed (fencing token 45)
```

Finally stop the last one with `Ctrl+C`. It steps down from the feed before it goes:

```bash

[Nest] 48859  - 09/25/2026, 9:00:50 AM     LOG [Locks] Stepped down from "inventory:warehouse-feed"
[Nest] 48859  - 09/25/2026, 9:00:50 AM     LOG [WarehouseFeed] Disconnected from the warehouse feed
```

#### Testing[#](/reliability/locks#testing)

An application that imports `LocksModule` and registers no store runs on the in-memory store, so an end-to-end test of one instance needs nothing: every tick runs, once. To keep the Drizzle store out of a test, override its provider with a plain `InMemoryLockStore`; a plain instance doesn't register itself, so the in-memory default applies.

To test what the package is for, run several instances in one process. An instance is a Nest application; instances of one application share a store. The example's helper starts one on the shared database, with the fakes and the test's `LocksModule` options:

test/helpers.ts

JS TS

```typescript

export async function startInstance(options: InstanceOptions): Promise<TestingModule> {
  if (options.database.url) {
    process.env.DATABASE_URL = options.database.url;
  }
  let builder = Test.createTestingModule({ imports: [options.module] })
    .overrideProvider(AccountingClient)
    .useValue(options.accounting)
    .overrideProvider(WarehouseClient)
    .useValue(options.warehouse);
  if (options.database.pglite) {
    builder = builder.overrideProvider(getDrizzleToken()).useValue(options.database.pglite);
  }
  if (options.locks) {
    builder = builder.overrideProvider(LOCKS_MODULE_OPTIONS).useValue(options.locks);
  }
  const app = await builder.compile();
  app.useLogger(options.logger);
  options.onCompiled?.(app);
  await app.init();
  return app;
}
```

* **Share the database.** On PGlite, every instance gets the same Drizzle database by overriding the one `DrizzleModule` registers (`getDrizzleToken()`), with the real migrations applied; `DrizzleLockStore` injects it with `@InjectDrizzle()`, so the instances share the locks table as they share it in production. Against a PostgreSQL server, each instance opens its own pool from the database's URL. Without a database, share one `InMemoryLockStore` between the instances by registering it in each with `LocksStorage.registerSource()` and its `replace` option before `init()`.
* **Fire the jobs yourself.** Call the method (`await job.exportInvoices()`) on each instance, or go through `@nestjs/schedule` with `schedulerRegistry.getCronJob(name).fireOnTick()`. Both reach the wrapper. Point the real schedules at a date that never comes: the example's `vitest.config.mts` sets the two cron variables to February 29th at 3 AM.
* **Control time.** Override `LOCKS_MODULE_OPTIONS` with a `ManualLockClock`, and every renewal, deadline and `wait` in that instance moves only when the test advances the clock: `await clock.advance('5m')` fires what falls due on the way, in order, and waits for each renewal to reach the store. An instance whose clock you don't advance is a paused process. Against PGlite or a server, the store's clock is real time, so a short `ttl` (`'1s'`) and a `sleep` expire a paused instance's locks; with the in-memory store, give it the same `ManualLockClock` and expiries move with it.
* **Assert on the log** or on `LocksEvents.events$`: which instance runs a job, every skipped tick, every lost lock, every leadership change. The events are also published on the `nestjs:locks:lock-lost`, `nestjs:locks:leadership-acquired` and `nestjs:locks:leadership-lost` diagnostics channels.
* **Test your store** with the contract suite, as the Drizzle, TypeORM and Redis stores do, against the server you run in production.

See [End-to-end testing](/fundamentals/testing#end-to-end-testing) for more about the testing setup.

#### Production checklist[#](/reliability/locks#production-checklist)

* Register a shared store, on your database or Redis, and run the contract suite against it with `concurrent` on, in CI, on the version you run in production. In production the application refuses to start without one, unless `allowInMemoryStorage` is set, which is only right for a single instance.
* Set `key` on every job that must never run twice, so a rename or a minifier can't change it during a rolling deploy.
* Pick a `ttl` well above the store's round trip and the longest event-loop stall you accept, and short enough that a crash doesn't skip too many ticks. Renewals go out every `ttl / 3`; 30 seconds fits most jobs. A long job's run lock is renewed at the same pace, so its `ttl` doesn't need to cover the run.
* Leave `storeTimeout` well above the store's slowest healthy answer: a store call that runs past it fails, so the tick doesn't run and `acquire()` rejects with `LockStoreTimeoutError`. The default, 10 seconds, also bounds how long a stalled store (an exhausted pool, a failover, a Redis client queueing commands while offline) holds up a job, a request or a renewal.
* Write jobs that do what is due, not what the tick was for. Missed ticks aren't caught up: a crashed owner costs up to `ttl` of ticks, and ticks during a long run are skipped.
* Pass `LocksContext.signal` to what a job calls, and fence the writes that can't be undone with `LocksContext.fencingToken`, in the same statement that writes. Alert on `lock-lost` from `LocksEvents` or the diagnostics channel: it means renewals failed for longer than `ttl`, because the store was unreachable or the event loop was blocked, and another instance may be running the same critical section.
* Call `app.enableShutdownHooks()`, so a deploy hands the leases over at once instead of leaving them to expire. Close the Redis client in `onApplicationShutdown()`, the phase in which `@nestjs/drizzle` closes the database pool: the package hands the leases back in `onModuleDestroy()` and releases every other lock in `beforeApplicationShutdown()`, phases Nest completes for the whole application first. A lease whose job started less than a second before the shutdown is kept for the rest of that second rather than handed back, so that instances firing the same tick skip it instead of running it a second time.
* With the Redis store, give Redis persistence and `maxmemory-policy noeviction`. The fencing counter must never go back, and a lock must never be evicted.
* With the database store, create the table and the sequence through your migrations, and size the connection pool for one short statement per renewal per held lock, plus one per tick per instance.
* Keep the instances' clocks synchronized with NTP anyway. Expiry is measured on the store's clock, but a holder counts its own deadline, and `@nestjs/schedule` fires on the instance's clock.
* Log level: the skipped ticks are logged at `debug`. Keep that level on for a while after the rollout, to see the jobs settle on one instance.

#### The store contract[#](/reliability/locks#the-store-contract)

The tutorial wrote the store with Drizzle, with TypeORM and with Redis. This section sums up what any `LockStore` must do, for writing one with another database or ORM. The [`LockStore` interface](https://github.com/nestjs/locks/blob/master/lib/interfaces/lock-store.interface.ts) documents the full contract and the races each rule prevents.

**Registration.** The store is an ordinary singleton provider that calls `registerSource(this)` on the injectable `LocksStorage` in its constructor. The registry checks the shape at once, refuses a second registration unless it passes `replace: true`, and locks when `LocksModule` initializes, logging the store in use. With nothing registered, the module uses `InMemoryLockStore`, which excludes callers in one process only. With `NODE_ENV=production`, startup fails instead, unless you set `allowInMemoryStorage: true`.

**The methods.** All three are atomic: each decides who holds a key, and a read followed by a separate write lets two callers into the critical section, which is the duplicate run the package exists to prevent.

| Method                     | What it does                                                                                                                          | How it stays atomic                                                                                                                                                                                 |
| -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `acquire(key, owner, ttl)` | Takes the key if no live lock holds it (none, released, or expired), with a fencing token greater than every token the key had before | One insert that takes over a released or expired row in the same statement, re-checking the expiry in the write, so of many concurrent callers exactly one wins; the token is drawn after the check |
| `renew(key, owner, ttl)`   | Moves the owner's live lock's expiry to `ttl` from now                                                                                | A compare-and-set: the owner and the expiry are in the `WHERE` of the statement that writes                                                                                                         |
| `release(key, owner)`      | Frees the owner's live lock (deletes it, or marks it released), so the next caller takes it at once. Never resets the key's token     | A compare-and-set, as `renew()`                                                                                                                                                                     |

**What else the store must get right**, all of it checked by the suite: an expired lock doesn't exist, for every method, whether or not it has been deleted (`expires_at > now` in every condition, or let the server expire it); `ttl` is measured on the store's clock, in milliseconds, and can be weeks (past a 32-bit integer: `bigint`, `PEXPIRE`); keys are strings of up to 500 characters, any Unicode, kept apart exactly; tokens are positive safe integers returned as numbers. PostgreSQL returns a `bigint` column as a string unless the ORM converts it; the package refuses such a token at once, with a message naming the fix, rather than let fencing break silently.

**With Prisma.** The Drizzle store is the model, with the same table and sequence; [Keep locks in your database](/reliability/locks#keep-locks-in-your-database) also shows it with TypeORM. `acquire()` is one `INSERT ... ON CONFLICT (key) DO UPDATE ... WHERE owner IS NULL OR expires_at <= clock_timestamp() RETURNING fencing_token`, with the token drawn in the `SET`, after the row lock. Prisma's `upsert()` has no condition on the update, so use `$queryRaw`. `renew()` and `release()` put the owner and the expiry in the `WHERE` of `updateMany()` and check `count === 1`. Not `update()` after a `findUnique()`: it reads first.

**Test it** with the suite from `@nestjs/locks/testing`. `lockStoreContract()` returns cases for any test runner. `concurrent: true` races 16 callers for each key, and its `callers` option raises that; run it against a server with a connection pool, where the calls really overlap. `advanceTime` moves the store's clock for the expiry cases; without it they wait in real time, about twenty-five seconds in total, on locks of `ttl` (2.5 seconds by default, checked still held halfway through and free a sixth past it: raise it for a store whose round trips are slow).

#### Reference[#](/reliability/locks#reference)

##### Module options[#](/reliability/locks#module-options)

`LocksModule.forRoot()` takes these options; `forRootAsync()` takes them from `useFactory`, `useClass` or `useExisting` (a class implementing `LocksOptionsFactory`). The store isn't an option: register it with `LocksStorage`, as in [Keep locks in your database](/reliability/locks#keep-locks-in-your-database).

| Option                 | Default          | Meaning                                                                                                                                                                                                                                                                      |
| ---------------------- | ---------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `ttl`                  | `'30s'`          | How long a lock lives without a renewal, so how soon another instance takes over after a crash. The default for every lock, lease and election. A duration: milliseconds, or a string such as `'15s'` or `'2m'`                                                              |
| `storeTimeout`         | `'10s'`          | How long to wait for each store call (`acquire()`, `renew()`, `release()`). Past it, the call fails with `LockStoreTimeoutError`: `acquire()` rejects, a tick doesn't run, a renewal is tried again at the next beat, and a lock the store grants after that goes back to it |
| `clock`                | The system clock | A `LockClock`. Tests pass a `ManualLockClock` ([Testing](/reliability/locks#testing))                                                                                                                                                                                        |
| `allowInMemoryStorage` | `false`          | With `NODE_ENV=production` and no registered store, startup fails; `true` runs on the in-memory store anyway (one instance)                                                                                                                                                  |
| `isGlobal`             | `true`           | Registers the module globally. Top level of `forRoot()` and `forRootAsync()`                                                                                                                                                                                                 |

##### Decorators and methods[#](/reliability/locks#decorators-and-methods)

| API                                | Options                 | Notes                                                                                                                                                                                          |
| ---------------------------------- | ----------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `@OnOneInstance()`                 | `key`, `ttl`            | Runs the job on the instance holding the `<key>:owner` lease; other instances skip the tick. [Run each job on one instance](/reliability/locks#run-each-job-on-one-instance)                   |
| `@WithoutOverlapping()`            | `key`, `ttl`            | Skips a tick while a run holds the `<key>` lock, on any instance. [Don't let a long run overlap itself](/reliability/locks#dont-let-a-long-run-overlap-itself)                                 |
| `@LeaderElection(key)`             | `ttl`                   | On a singleton provider implementing `OnLeadershipAcquired`, `OnLeadershipLost` or both. [Hold the warehouse feed on one instance](/reliability/locks#hold-the-warehouse-feed-on-one-instance) |
| `Locks.acquire(key, options)`      | `ttl`, `wait`, `signal` | Resolves a `Lock`, or `null` when the key stayed taken. [Run the export by hand](/reliability/locks#run-the-export-by-hand)                                                                    |
| `Locks.withLock(key, fn, options)` | `ttl`, `wait`, `signal` | Runs `fn(lock)` under the lock and releases it; rejects with `LockNotAcquiredError` when the key stayed taken                                                                                  |

* `key` defaults to `ClassName.methodName`, and the two job decorators on one method share it. `ttl` defaults to the module's.
* `wait` defaults to `0` (try once); a longer wait retries with backoff. `signal` stops the waiting, also for a store call in flight. Neither `wait` nor `ttl` bounds a store call: the module's `storeTimeout` does.
* A `Lock` has `key`, `owner`, `fencingToken`, `signal`, `held`, `release()` and `[Symbol.asyncDispose]`, so `await using` releases it.
* `LocksContext` has `lock`, `fencingToken` and `signal` inside a job, a `withLock()` callback, or `run(lock, fn)`; outside one, they are `undefined`. [Fence the writes](/reliability/locks#fence-the-writes)

##### Events[#](/reliability/locks#events)

`LocksEvents.events$` emits each event, and publishes it on its `node:diagnostics_channel` channel. Every payload has `type`, `key` and `fencingToken`.

| Event                 | Channel                            | Other fields                              | When                                                                  |
| --------------------- | ---------------------------------- | ----------------------------------------- | --------------------------------------------------------------------- |
| `lock-lost`           | `nestjs:locks:lock-lost`           | `detectedBy`: `'renewal'` or `'deadline'` | A holder lost a lock it was using. Alert on it                        |
| `leadership-acquired` | `nestjs:locks:leadership-acquired` | None                                      | This instance became the leader of `key`                              |
| `leadership-lost`     | `nestjs:locks:leadership-lost`     | `reason`: `'lost'` or `'released'`        | This instance stopped leading: the lease was lost, or it stepped down |

##### Errors[#](/reliability/locks#errors)

None of them carries an HTTP status: contention isn't the caller's mistake, so the handler picks the response ([Run the export by hand](/reliability/locks#run-the-export-by-hand) answers `409`).

| Error                   | Properties                          | Raised when                                                                                                                                      |
| ----------------------- | ----------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| `LocksError`            | None                                | The base class of the three below                                                                                                                |
| `LockNotAcquiredError`  | `key`, `waitMs`                     | `withLock()` couldn't take the lock within `wait`                                                                                                |
| `LockLostError`         | `key`, `fencingToken`, `detectedBy` | The reason a lost lock's `signal` aborts with: the store refused a renewal (`'renewal'`), or `ttl` passed without a confirmed one (`'deadline'`) |
| `LockStoreTimeoutError` | `key`, `method`, `timeoutMs`        | A store call (`method`: `'acquire'`, `'renew'` or `'release'`) didn't answer within `storeTimeout`                                               |

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/reliability/locks.md)

----
url: https://docs.nestjs.com/v11/fundamentals/async-providers
----

* [Asynchronous providers](https://docs.nestjs.com/v11/fundamentals/async-providers#asynchronous-providers)
* [Injection](https://docs.nestjs.com/v11/fundamentals/async-providers#injection)
* [Example](https://docs.nestjs.com/v11/fundamentals/async-providers#example)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/fundamentals/async-components.md "Suggest Edits")

### Asynchronous providers

At times, the application start should be delayed until one or more **asynchronous tasks** are completed. For example, you may not want to start accepting requests until the connection with the database has been established. You can achieve this using asynchronous providers.

The syntax for this is to use `async/await` with the `useFactory` syntax. The factory returns a `Promise`, and the factory function can `await` asynchronous tasks. Nest will await resolution of the promise before instantiating any class that depends on (injects) such a provider.

```typescript

{
  provide: 'ASYNC_CONNECTION',
  useFactory: async () => {
    const connection = await createConnection(options);
    return connection;
  },
}
```

> **Hint** Learn more about custom provider syntax [here](/v11/fundamentals/custom-providers).

#### Injection[#](/fundamentals/async-providers#injection)

Asynchronous providers are injected to other components by their tokens, like any other provider. In the example above, you would use the construct `@Inject('ASYNC_CONNECTION')`.

#### Example[#](/fundamentals/async-providers#example)

[The TypeORM recipe](/v11/recipes/sql-typeorm) has a more substantial example of an asynchronous provider.

----
url: https://docs.nestjs.com/v6/websockets/pipes
----

* [Pipes](https://docs.nestjs.com/v6/websockets/pipes#pipes)
* [Binding pipes](https://docs.nestjs.com/v6/websockets/pipes#binding-pipes)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/websockets/pipes.md "Suggest Edits")

### Pipes

There is no fundamental difference between [regular pipes](/v6/pipes) and microservices pipes. The only difference is that instead of throwing `HttpException`, you should use `WsException`. In addition, all pipes will be only applied to the `data` parameter (because validating or transforming `client` instance is useless).

> **Hint** The `WsException` class is exposed from `@nestjs/websockets` package.

#### Binding pipes[#](/websockets/pipes#binding-pipes)

The following example uses a manually instantiated method-scoped pipe. Just as with HTTP based applications, you can also use gateway-scoped pipes (i.e., prefix the gateway class with a `@UsePipes()` decorator).

JS TS

```typescript

@UsePipes(new ValidationPipe())
@SubscribeMessage('events')
handleEvent(client: Client, data: unknown): WsResponse<unknown> {
  const event = 'events';
  return { event, data };
}
```

```typescript

@UsePipes(new ValidationPipe())
@SubscribeMessage('events')
handleEvent(client, data) {
  const event = 'events';
  return { event, data };
}
```

----
url: https://docs.nestjs.com/microservices/pipes
----

[Skip to content](#content)

On this page

* [Pipes](https://docs.nestjs.com/microservices/pipes#pipes)
* [Binding pipes](https://docs.nestjs.com/microservices/pipes#binding-pipes)

### Pipes

Microservice pipes work the same way as [regular pipes](/pipes). The only difference is that they should throw `RpcException` instead of `HttpException`. Unless a custom exception filter handles it, an `HttpException` thrown during message handling reaches the client as a generic `Internal server error` message.

> **Hint** The `RpcException` class is exposed from the `@nestjs/microservices` package.

#### Binding pipes[#](/microservices/pipes#binding-pipes)

The following example uses a manually instantiated method-scoped pipe. The `exceptionFactory` option makes `ValidationPipe` throw an `RpcException` instead of its default `BadRequestException`. As with HTTP-based applications, you can also use controller-scoped pipes (i.e., prefix the controller class with a `@UsePipes()` decorator).

JS TS

```typescript

@UsePipes(new ValidationPipe({ exceptionFactory: (errors) => new RpcException(errors) }))
@MessagePattern({ cmd: 'sum' })
accumulate(data: number[]): number {
  return (data || []).reduce((a, b) => a + b);
}
```

```typescript

@UsePipes(new ValidationPipe({ exceptionFactory: (errors) => new RpcException(errors) }))
@MessagePattern({ cmd: 'sum' })
accumulate(data) {
  return (data || []).reduce((a, b) => a + b);
}
```

The `@Payload()` decorator also accepts a `schema` option, which lets `StandardSchemaValidationPipe` (exported from `@nestjs/common`) validate the payload against a [Standard Schema](/application/validation#schema-based-validation) (e.g., a Zod schema). Configure its `exceptionFactory` option in the same way, so that validation errors are thrown as `RpcException`:

JS TS

```typescript

@UsePipes(new StandardSchemaValidationPipe({ exceptionFactory: (issues) => new RpcException(issues) }))
@MessagePattern({ cmd: 'sum' })
accumulate(@Payload({ schema: z.array(z.number()) }) data: number[]): number {
  return data.reduce((a, b) => a + b, 0);
}
```

```typescript

@UsePipes(new StandardSchemaValidationPipe({ exceptionFactory: (issues) => new RpcException(issues) }))
@Bind(Payload({ schema: z.array(z.number()) }))
@MessagePattern({ cmd: 'sum' })
accumulate(data) {
  return data.reduce((a, b) => a + b, 0);
}
```

> **Hint** Global pipes registered on the main HTTP application don't apply to microservices connected to a [hybrid application](/faq/hybrid-application) unless you set the `inheritAppConfig` option. See [sharing configuration](/faq/hybrid-application#sharing-configuration).

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/microservices/pipes.md)

----
url: https://docs.nestjs.com/openapi/introduction
----

[Skip to content](#content)

On this page

* [Introduction](https://docs.nestjs.com/openapi/introduction#introduction)
* [Installation](https://docs.nestjs.com/openapi/introduction#installation)
* [Bootstrap](https://docs.nestjs.com/openapi/introduction#bootstrap)
* [Document options](https://docs.nestjs.com/openapi/introduction#document-options)
* [Standard Schema (Zod, Valibot)](https://docs.nestjs.com/openapi/introduction#standard-schema-zod-valibot)
* [Setup options](https://docs.nestjs.com/openapi/introduction#setup-options)
* [Example](https://docs.nestjs.com/openapi/introduction#example)

### Introduction

The [OpenAPI](https://swagger.io/specification/) specification is a language-agnostic definition format for describing RESTful APIs. Nest provides a dedicated [module](https://github.com/nestjs/swagger) that generates such a specification from decorators in your code.

#### Installation[#](/openapi/introduction#installation)

To begin, install the required dependency:

```bash

$ npm install --save @nestjs/swagger
```

> **Warning** If you use Fastify, also install `@fastify/static`:
>
> ```bash
>
> $ npm install --save @fastify/static
> ```

#### Bootstrap[#](/openapi/introduction#bootstrap)

Once the installation is complete, open the `main.ts` file and initialize Swagger using the `SwaggerModule` class:

main.ts

JS TS

```typescript

import { NestFactory } from '@nestjs/core';
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
import { AppModule } from './app.module.js';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);

  const config = new DocumentBuilder()
    .setTitle('Cats example')
    .setDescription('The cats API description')
    .setVersion('1.0')
    .addTag('cats')
    .build();
  const documentFactory = () => SwaggerModule.createDocument(app, config);
  SwaggerModule.setup('api', app, documentFactory);

  await app.listen(process.env.PORT ?? 3000);
}
await bootstrap();
```

> **Hint** Wrapping `SwaggerModule.createDocument()` in a factory function defers document generation until the document is first requested, which saves initialization time. The resulting document is a serializable object that conforms to the [OpenAPI Document](https://swagger.io/specification/#openapi-document) specification. Instead of serving it over HTTP, you can also save it as a JSON or YAML file and use it elsewhere.

> **Warning** If you call `createDocument()` eagerly (rather than in a factory function, as shown above), make sure `app.enableVersioning()` runs first. Otherwise, the generated `paths` are missing the version prefix. The factory pattern is unaffected, because the document isn't built until it is first requested.

`DocumentBuilder` structures a base document that conforms to the OpenAPI Specification. Its methods let you set properties such as the title, description, and version. To create a full document (with all HTTP routes defined), use the `createDocument()` method of the `SwaggerModule` class. It takes two arguments: an application instance and the base document configuration returned by `DocumentBuilder#build()`. An optional third argument, of type `SwaggerDocumentOptions`, is covered in the [document options](/openapi/introduction#document-options) section.

Next, call the `setup()` method. It accepts:

1. The path to mount the Swagger UI on
2. An application instance
3. The document object, or a factory function that returns it (as above)
4. An optional configuration object (see [setup options](/openapi/introduction#setup-options))

Now run the following command to start the HTTP server:

```bash

$ npm run start
```

While the application is running, open your browser and navigate to `http://localhost:3000/api`. You should see the Swagger UI.

The `SwaggerModule` automatically reflects all of your endpoints.

> **Hint** To generate and download a Swagger JSON file, navigate to `http://localhost:3000/api-json` (assuming that your Swagger documentation is available under `http://localhost:3000/api`). You can also expose it on a route of your choice with the `jsonDocumentUrl` option of the `setup()` method:
>
> ```typescript
>
> SwaggerModule.setup('swagger', app, documentFactory, {
>   jsonDocumentUrl: 'swagger/json',
> });
> ```
>
> This exposes it at `http://localhost:3000/swagger/json`.

> **Hint** Swagger UI works with the default [Content Security Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP) of Nest's built-in [security headers](/security/helmet). If you add scripts through `customJs`/`customJsStr`, or serve Swagger UI over plain HTTP outside local development, see [Swagger UI and GraphQL IDEs](/security/helmet#swagger-ui-and-graphql-ides) for the directives to adjust.

> **Warning** When you register `helmet` directly with Fastify instead, its [CSP](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP) can block the Swagger UI. To resolve this conflict, configure the CSP as shown below:
>
> ```typescript
>
> app.register(helmet, {
>   contentSecurityPolicy: {
>     directives: {
>       defaultSrc: [`'self'`],
>       styleSrc: [`'self'`, `'unsafe-inline'`],
>       imgSrc: [`'self'`, 'data:', 'validator.swagger.io'],
>       scriptSrc: [`'self'`, `https:`, `'unsafe-inline'`],
>     },
>   },
> });
>
> // If you are not going to use CSP at all, you can use this:
> app.register(helmet, {
>   contentSecurityPolicy: false,
> });
> ```

#### Document options[#](/openapi/introduction#document-options)

When creating a document, you can pass extra options to fine-tune the library's behavior. These options are of type `SwaggerDocumentOptions`:

```typescript

export interface SwaggerDocumentOptions {
  /**
   * List of modules to include in the specification
   */
  include?: Function[];

  /**
   * Additional, extra models that should be inspected and included in the specification
   */
  extraModels?: Function[];

  /**
   * If `true`, swagger will ignore the global prefix set through `setGlobalPrefix()` method
   */
  ignoreGlobalPrefix?: boolean;

  /**
   * If `true`, swagger will also load routes from the modules imported by `include` modules
   */
  deepScanRoutes?: boolean;

  /**
   * Custom operationIdFactory that will be used to generate the `operationId`
   * based on the `controllerKey`, `methodKey`, and version.
   * @default () => controllerKey_methodKey_version
   */
  operationIdFactory?: OperationIdFactory;

  /**
   * Custom linkNameFactory that will be used to generate the name of links
   * in the `links` field of responses
   *
   * @see [Link objects](https://swagger.io/docs/specification/links/)
   *
   * @default () => `${controllerKey}_${methodKey}_from_${fieldKey}`
   */
  linkNameFactory?: (
    controllerKey: string,
    methodKey: string,
    fieldKey: string
  ) => string;

  /*
   * Generate tags automatically based on the controller name.
   * If `false`, you must use the `@ApiTags()` decorator to define tags.
   * Otherwise, the controller name without the suffix `Controller` will be used.
   * @default true
   */
  autoTagControllers?: boolean;

  /**
   * If `true`, swagger will only include routes that are decorated with the `@ApiIncludeEndpoint()` decorator
   * @default false
   */
  onlyIncludeDecoratedEndpoints?: boolean;

  /**
   * If `true`, `default` values that are non-plain objects at runtime
   * (e.g., `new Date()` or class instances) are omitted from the document,
   * so the document doesn't change on every restart.
   * @default false
   */
  excludeDynamicDefaults?: boolean;

  /**
   * If set, `example` and `examples` values on component schemas are
   * truncated once their nested object/array depth exceeds this number.
   * Per-property `@ApiProperty({ exampleMaxDepth })` overrides it.
   * @default undefined
   */
  exampleMaxDepth?: number;

  /**
   * Converts Standard Schema instances passed to route parameter decorators
   * into OpenAPI schemas (see "Standard Schema (Zod, Valibot)" below).
   */
  standardSchemaConverter?: StandardSchemaConverter;
}
```

For example, to generate operation names like `createUser` instead of `UsersController_createUser`, set the following:

```typescript

const options: SwaggerDocumentOptions =  {
  operationIdFactory: (
    controllerKey: string,
    methodKey: string
  ) => methodKey
};
const documentFactory = () => SwaggerModule.createDocument(app, config, options);
```

#### Standard Schema (Zod, Valibot)[#](/openapi/introduction#standard-schema-zod-valibot)

Nest route parameter decorators accept a [Standard Schema](https://standardschema.dev/) compatible schema through their `schema` option (see the [controllers](/controllers#request-object) chapter):

cats.controller.ts

JS TS

```typescript

import { Body, Controller, Post } from '@nestjs/common';
import { z } from 'zod';

const createCatSchema = z.object({
  name: z.string(),
  age: z.number().int().positive(),
  breed: z.string(),
});
type CreateCatDto = z.infer<typeof createCatSchema>;

@Controller('cats')
export class CatsController {
  @Post()
  create(@Body({ schema: createCatSchema }) createCatDto: CreateCatDto) {
    return this.catsService.create(createCatDto);
  }
}
```

The Swagger module picks up these schemas and turns them into request bodies and parameters in the generated document.

##### Libraries that need no configuration[#](/openapi/introduction#libraries-that-need-no-configuration)

If your validation library implements the **Standard JSON Schema** extension (that is, its schemas expose `~standard.jsonSchema`), Nest converts the schemas itself, and there is nothing to configure. Zod 4.2 and later implements this extension, for example. Nest requests the `openapi-3.0` target and uses the `input` or `output` variant, depending on whether the schema describes a request or a response.

##### Supplying a converter[#](/openapi/introduction#supplying-a-converter)

For libraries that don't expose that extension (or when you want to control the conversion yourself), provide a `standardSchemaConverter` in `SwaggerDocumentOptions`. It receives the raw schema and the `schemaType` being generated, and returns the converted OpenAPI schema:

```typescript

standardSchemaConverter?: (
  schema: unknown,
  options: { schemaType: 'input' | 'output' },
) => { schema: unknown; components?: Record<string, any> } | undefined;
```

Nest calls the converter before trying the native conversion. Returning `undefined` tells Nest that the converter doesn't handle this schema, so Nest falls back to the native conversion described above. This makes it safe to support several libraries from one converter.

For **Zod**, you can use [zod-openapi](https://github.com/samchungy/zod-openapi):

```bash

$ npm i --save-dev zod-openapi
```

main.ts

JS TS

```typescript

import { SwaggerDocumentOptions, SwaggerModule } from '@nestjs/swagger';
import { createSchema } from 'zod-openapi';

const documentOptions: SwaggerDocumentOptions = {
  standardSchemaConverter: (schema, { schemaType }) => {
    const converted = createSchema(schema as never, {
      io: schemaType,
      openapiVersion: '3.0.0',
    });
    return { schema: converted.schema, components: converted.components };
  },
};

const documentFactory = () =>
  SwaggerModule.createDocument(app, config, documentOptions);
```

For **Valibot**, use [@valibot/to-json-schema](https://github.com/fabian-hiller/valibot/tree/main/packages/to-json-schema):

```bash

$ npm i --save-dev @valibot/to-json-schema
```

main.ts

JS TS

```typescript

import { SwaggerDocumentOptions } from '@nestjs/swagger';
import { toJsonSchema } from '@valibot/to-json-schema';

const documentOptions: SwaggerDocumentOptions = {
  standardSchemaConverter: (schema, { schemaType }) => ({
    schema: toJsonSchema(schema as never, {
      target: 'openapi-3.0',
      typeMode: schemaType,
    }),
  }),
};
```

The two converters differ in one respect. `createSchema()` can hoist reusable definitions, so its result carries a `components` map, which you pass through and Nest merges into the document's shared components. `toJsonSchema()` returns a single self-contained schema, so the Valibot converter omits `components`.

##### Supporting several libraries at once[#](/openapi/introduction#supporting-several-libraries-at-once)

Because the converter receives the schema as `unknown`, you can branch on the schema's vendor and support more than one library in the same application. Every Standard Schema exposes its vendor at `~standard.vendor`:

main.ts

JS TS

```typescript

import { SwaggerDocumentOptions } from '@nestjs/swagger';
import { toJsonSchema } from '@valibot/to-json-schema';
import { createSchema } from 'zod-openapi';

function hasVendor(schema: unknown, vendor: string) {
  return (
    !!schema &&
    typeof schema === 'object' &&
    (schema as { '~standard'?: { vendor?: string } })['~standard']?.vendor ===
      vendor
  );
}

const documentOptions: SwaggerDocumentOptions = {
  standardSchemaConverter: (schema, { schemaType }) => {
    if (hasVendor(schema, 'zod')) {
      const converted = createSchema(schema as never, {
        io: schemaType,
        openapiVersion: '3.0.0',
      });
      return { schema: converted.schema, components: converted.components };
    }

    if (hasVendor(schema, 'valibot')) {
      return {
        schema: toJsonSchema(schema as never, {
          target: 'openapi-3.0',
          typeMode: schemaType,
        }),
      };
    }

    // Not handled here - let Nest fall back to native conversion
    return undefined;
  },
};
```

> **Warning** Always narrow by vendor before calling a library-specific converter. Passing a Valibot schema to `createSchema()` (or the reverse) throws at document generation time instead of failing gracefully.

> **Hint**`schemaType` matters when your schema performs transformations: the `input` shape is what clients send, and the `output` shape is what your handler receives after parsing. Nest requests the variant that fits the position being documented, so pass the value straight through to your converter instead of hardcoding one.

#### Setup options[#](/openapi/introduction#setup-options)

You can configure Swagger UI by passing an options object that implements the `SwaggerCustomOptions` interface as the fourth argument of the `SwaggerModule#setup()` method.

```typescript

export interface SwaggerCustomOptions {
  /**
   * If `true`, Swagger resources paths will be prefixed by the global prefix set through `setGlobalPrefix()`.
   * Default: `false`.
   * @see https://docs.nestjs.com/faq/global-prefix
   */
  useGlobalPrefix?: boolean;

  /**
   * If `false`, the Swagger UI will not be served. Only API definitions (JSON and YAML)
   * will be accessible (on `/{path}-json` and `/{path}-yaml`). To fully disable both the Swagger UI and API definitions, use `raw: false`.
   * Default: `true`.
   * @deprecated Use `ui` instead.
   */
  swaggerUiEnabled?: boolean;

  /**
   * If `false`, the Swagger UI will not be served. Only API definitions (JSON and YAML)
   * will be accessible (on `/{path}-json` and `/{path}-yaml`). To fully disable both the Swagger UI and API definitions, use `raw: false`.
   * Default: `true`.
   */
  ui?: boolean;

  /**
   * If `true`, raw definitions for all formats will be served.
   * Alternatively, you can pass an array to specify the formats to be served, e.g., `raw: ['json']` to serve only JSON definitions.
   * If set to `false` or an empty array, no definitions (JSON or YAML) will be served.
   * Use this option to control the availability of Swagger-related endpoints.
   * Default: `true`.
   */
  raw?: boolean | Array<'json' | 'yaml'>;

  /**
   * Url point the API definition to load in Swagger UI.
   */
  swaggerUrl?: string;

  /**
   * Path of the JSON API definition to serve.
   * Default: `<path>-json`.
   */
  jsonDocumentUrl?: string;

  /**
   * Path of the YAML API definition to serve.
   * Default: `<path>-yaml`.
   */
  yamlDocumentUrl?: string;

  /**
   * Hook allowing to alter the OpenAPI document before being served.
   * It's called after the document is generated and before it is served as JSON & YAML.
   * The hook can return either a plain `OpenAPIObject` or a `Promise<OpenAPIObject>`.
   */
  patchDocumentOnRequest?: <TRequest = any, TResponse = any>(
    req: TRequest,
    res: TResponse,
    document: OpenAPIObject
  ) => OpenAPIObject | Promise<OpenAPIObject>;

  /**
   * If `true`, the selector of OpenAPI definitions is displayed in the Swagger UI interface.
   * Default: `false`.
   */
  explorer?: boolean;

  /**
   * Additional Swagger UI options
   */
  swaggerOptions?: SwaggerUiOptions;

  /**
   * Custom CSS styles to inject in Swagger UI page.
   */
  customCss?: string;

  /**
   * URL(s) of a custom CSS stylesheet to load in Swagger UI page.
   */
  customCssUrl?: string | string[];

  /**
   * URL(s) of custom JavaScript files to load in Swagger UI page.
   */
  customJs?: string | string[];

  /**
   * Custom JavaScript scripts to load in Swagger UI page.
   */
  customJsStr?: string | string[];

  /**
   * Custom favicon for Swagger UI page.
   */
  customfavIcon?: string;

  /**
   * Custom title for Swagger UI page.
   */
  customSiteTitle?: string;

  /**
   * File system path (ex: ./node_modules/swagger-ui-dist) containing static Swagger UI assets.
   */
  customSwaggerUiPath?: string;

  /**
   * @deprecated This property has no effect.
   */
  validatorUrl?: string;

  /**
   * @deprecated This property has no effect.
   */
  url?: string;

  /**
   * @deprecated This property has no effect.
   */
  urls?: Record<'url' | 'name', string>[];
}
```

> **Hint**`ui` and `raw` are independent options. Disabling the Swagger UI (`ui: false`) doesn't disable the API definitions (JSON/YAML). Conversely, disabling the API definitions (`raw: []`) doesn't disable the Swagger UI.
>
> For example, the following configuration disables the Swagger UI but keeps the JSON API definition available:
>
> ```typescript
>
> const options: SwaggerCustomOptions = {
>   ui: false, // Swagger UI is disabled
>   raw: ['json'], // JSON API definition is still accessible (YAML is disabled)
> };
> SwaggerModule.setup('api', app, documentFactory, options);
> ```
>
> In this case, `http://localhost:3000/api-json` is still accessible, but `http://localhost:3000/api` (the Swagger UI) is not.

#### Example[#](/openapi/introduction#example)

A working example is available in the [Nest repository](https://github.com/nestjs/nest/tree/master/sample/11-swagger).

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/openapi/introduction.md)

----
url: https://docs.nestjs.com/v7/support
----

* [Support](https://docs.nestjs.com/v7/support#support)
* [How can you help?](https://docs.nestjs.com/v7/support#how-can-you-help)

----
url: https://docs.nestjs.com/v6/fundamentals/dynamic-modules
----

* [Dynamic modules](https://docs.nestjs.com/v6/fundamentals/dynamic-modules#dynamic-modules)
* [Introduction](https://docs.nestjs.com/v6/fundamentals/dynamic-modules#introduction)
* [Dynamic module use case](https://docs.nestjs.com/v6/fundamentals/dynamic-modules#dynamic-module-use-case)
* [Config module example](https://docs.nestjs.com/v6/fundamentals/dynamic-modules#config-module-example)
* [Module configuration](https://docs.nestjs.com/v6/fundamentals/dynamic-modules#module-configuration)
* [Example](https://docs.nestjs.com/v6/fundamentals/dynamic-modules#example)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/fundamentals/dynamic-modules.md "Suggest Edits")

### Dynamic modules

The [Modules chapter](/v6/modules) covers the basics of Nest modules, and includes a brief introduction to [dynamic modules](https://docs.nestjs.com/modules#dynamic-modules). This chapter expands on the subject of dynamic modules. Upon completion, you should have a good grasp of what they are and how and when to use them.

#### Introduction[#](/fundamentals/dynamic-modules#introduction)

Most application code examples in the **Overview** section of the documentation make use of regular, or *static*, modules. Modules define groups of components like [providers](/v6/providers) and [controllers](/v6/controllers) that fit together as a modular part of an overall application. They provide an execution context, or scope, for these components. For example, providers defined in a module are visible to other members of the module without the need to export them. When a provider needs to be visible outside of a module, it is first *exported* from its host module, and then *imported* into its consuming module.

Let's walk through a familiar example.

First, we'll define a `UsersModule` to provide and export a `UsersService`. `UsersModule` is the **host** module for `UsersService`.

```typescript

import { Module } from '@nestjs/common';
import { UsersService } from './users.service';

@Module({
  providers: [UsersService],
  exports: [UsersService],
})
export class UsersModule {}
```

Next, we'll define an `AuthModule`, which imports `UsersModule`, making `UsersModule`'s exported providers available inside `AuthModule`:

```typescript

import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { UsersModule } from '../users/users.module';

@Module({
  imports: [UsersModule],
  providers: [AuthService],
  exports: [AuthService],
})
export class AuthModule {}
```

These constructs allow us to inject `UsersService` in, for example, the `AuthService` that is hosted in `AuthModule`:

```typescript

import { Injectable } from '@nestjs/common';
import { UsersService } from '../users/users.service';

@Injectable()
export class AuthService {
  constructor(private readonly usersService: UsersService) {}
  /*
    Implementation that makes use of this.usersService
  */
}
```

```typescript

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { ConfigModule } from './config/config.module';

@Module({
  imports: [ConfigModule],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}
```

Let's consider what a *dynamic module* import, where we're passing in a configuration object, might look like. Compare the difference in the `imports` array between these two examples:

```typescript

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { ConfigModule } from './config/config.module';

@Module({
  imports: [ConfigModule.register({ folder: './config' })],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}
```

Let's see what's happening in the dynamic example above. What are the moving parts?

1. `ConfigModule` is a normal class, so we can infer that it must have a **static method** called `register()`. We know it's static because we're calling it on the `ConfigModule` class, not on an **instance** of the class. Note: this method, which we will create soon, can have any arbitrary name, but by convention we should call it either `forRoot()` or `register()`.
2. The `register()` method is defined by us, so we can accept any input arguments we like. In this case, we're going to accept a simple `options` object with suitable properties, which is the typical case.
3. We can infer that the `register()` method must return something like a `module` since its return value appears in the familiar `imports` list, which we've seen so far includes a list of modules.

In fact, what our `register()` method will return is a `DynamicModule`. A dynamic module is nothing more than a module created at run-time, with the same exact properties as a static module, plus one additional property called `module`. Let's quickly review a sample static module declaration, paying close attention to the module options passed in to the decorator:

```typescript

@Module({
  imports: [DogsService],
  controllers: [CatsController],
  providers: [CatsService],
  exports: [CatsService]
})
```

Dynamic modules must return an object with the exact same interface, plus one additional property called `module`. The `module` property serves as the name of the module, and should be the same as the class name of the module, as shown in the example below.

> **Hint** For a dynamic module, all properties of the module options object are optional **except**`module`.

What about the static `register()` method? We can now see that its job is to return an object that has the `DynamicModule` interface. When we call it, we are effectively providing a module to the `imports` list, similar to the way we would do so in the static case by listing a module class name. In other words, the dynamic module API simply returns a module, but rather than fix the properties in the `@Modules` decorator, we specify them programmatically.

There are still a couple of details to cover to help make the picture complete:

1. We can now state that the `@Module()` decorator's `imports` property can take not only a module class name (e.g., `imports: [UsersModule]`), but also a function **returning** a dynamic module (e.g., `imports: [ConfigModule.register(...)]`).
2. A dynamic module can itself import other modules. We won't do so in this example, but if the dynamic module depends on providers from other modules, you would import them using the optional `imports` property. Again, this is exactly analogous to the way you'd declare metadata for a static module using the `@Module()` decorator.

Armed with this understanding, we can now look at what our dynamic `ConfigModule` declaration must look like. Let's take a crack at it.

```typescript

import { DynamicModule, Module } from '@nestjs/common';
import { ConfigService } from './config.service';

@Module({})
export class ConfigModule {
  static register(): DynamicModule {
    return {
      module: ConfigModule,
      providers: [ConfigService],
      exports: [ConfigService],
    };
  }
}
```

It should now be clear how the pieces tie together. Calling `ConfigModule.register(...)` returns a `DynamicModule` object with properties which are essentially the same as those that, until now, we've provided as metadata via the `@Module()` decorator.

> **Hint** Import `DynamicModule` from `@nestjs/common`.

Our dynamic module isn't very interesting yet, however, as we haven't introduced any capability to **configure** it as we said we would like to do. Let's address that next.

### Module configuration

The obvious solution for customizing the behavior of the `ConfigModule` is to pass it an `options` object in the static `register()` method, as we guessed above. Let's look once again at our consuming module's `imports` property:

```typescript

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { ConfigModule } from './config/config.module';

@Module({
  imports: [ConfigModule.register({ folder: './config' })],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}
```

That nicely handles passing an `options` object to our dynamic module. How do we then use that `options` object in the `ConfigModule`? Let's consider that for a minute. We know that our `ConfigModule` is basically a host for providing and exporting an injectable service - the `ConfigService` - for use by other providers. It's actually our `ConfigService` that needs to read the `options` object to customize its behavior. Let's assume for the moment that we know how to somehow get the `options` from the `register()` method into the `ConfigService`. With that assumption, we can make a few changes to the service to customize its behavior based on the properties from the `options` object. (**Note**: for the time being, since we *haven't* actually determined how to pass it in, we'll just hard-code `options`. We'll fix this in a minute).

```typescript

import { Injectable } from '@nestjs/common';
import * as dotenv from 'dotenv';
import * as fs from 'fs';
import { EnvConfig } from './interfaces';

@Injectable()
export class ConfigService {
  private readonly envConfig: EnvConfig;

  constructor() {
    const options = { folder: './config' };

    const filePath = `${process.env.NODE_ENV || 'development'}.env`;
    const envFile = path.resolve(__dirname, '../../', options.folder, filePath);
    this.envConfig = dotenv.parse(fs.readFileSync(envFile));
  }

  get(key: string): string {
    return this.envConfig[key];
  }
}
```

Now our `ConfigService` knows how to find the `.env` file in the folder we've specified in `options`.

Our remaining task is to somehow inject the `options` object from the `register()` step into our `ConfigService`. And of course, we'll use *dependency injection* to do it. This is a key point, so make sure you understand it. Our `ConfigModule` is providing `ConfigService`. `ConfigService` in turn depends on the `options` object that is only supplied at run-time. So, at run-time, we'll need to first bind the `options` object to the Nest IoC container, and then have Nest inject it into our `ConfigService`. Remember from the **Custom providers** chapter that providers can [include any value](https://docs.nestjs.com/fundamentals/custom-providers#non-service-based-providers) not just services, so we're fine using dependency injection to handle a simple `options` object.

Let's tackle binding the options object to the IoC container first. We do this in our static `register()` method. Remember that we are dynamically constructing a module, and one of the properties of a module is its list of providers. So what we need to do is define our options object as a provider. This will make it injectable into the `ConfigService`, which we'll take advantage of in the next step. In the code below, pay attention to the `providers` array:

```typescript

import { DynamicModule, Module } from '@nestjs/common';

import { ConfigService } from './config.service';

@Module({})
export class ConfigModule {
  static register(options): DynamicModule {
    return {
      module: ConfigModule,
      providers: [
        {
          provide: 'CONFIG_OPTIONS',
          useValue: options,
        },
        ConfigService,
      ],
      exports: [ConfigService],
    };
  }
}
```

Now we can complete the process by injecting the `'CONFIG_OPTIONS'` provider into the `ConfigService`. Recall that when we define a provider using a non-class token we need to use the `@Inject()` decorator [as described here](https://docs.nestjs.com/fundamentals/custom-providers#non-class-based-provider-tokens).

```typescript

import { Injectable, Inject } from '@nestjs/common';

import * as dotenv from 'dotenv';
import * as fs from 'fs';

import { EnvConfig } from './interfaces';

@Injectable()
export class ConfigService {
  private readonly envConfig: EnvConfig;

  constructor(@Inject('CONFIG_OPTIONS') private options) {
    const filePath = `${process.env.NODE_ENV || 'development'}.env`;
    const envFile = path.resolve(__dirname, '../../', options.folder, filePath);
    this.envConfig = dotenv.parse(fs.readFileSync(envFile));
  }

  get(key: string): string {
    return this.envConfig[key];
  }
}
```

One final note: for simplicity we used a string-based injection token (`'CONFIG_OPTIONS'`) above, but best practice is to define it as a constant (or `Symbol`) in a separate file, and import that file. For example:

```typescript

export const CONFIG_OPTIONS = 'CONFIG_OPTIONS';
```

### Example

A full example of the code in this chapter can be found [here](https://github.com/nestjs/nest/tree/master/sample/25-dynamic-modules).

----
url: https://docs.nestjs.com/v4/microservices/interceptors
----

### Interceptors

There's one difference between [regular interceptors](/v4/interceptors) and the microservices **interceptors**. The microservices interceptors takes the `data` passed from the client instead of expressjs request object as an argument of the `intercept()` function.

#### Sponsors

[](https://valor-software.com/)

Nest is an MIT-licensed open source project. It can grow thanks to the support by these awesome people. If you'd like to join them, please read more [here](https://opencollective.com/nest). Thanks!

[](https://opencollective.com/nest/backer/0/website)[](https://opencollective.com/nest/backer/1/website)[](https://opencollective.com/nest/backer/2/website)[](https://opencollective.com/nest/backer/3/website)[](https://opencollective.com/nest/backer/4/website)[](https://opencollective.com/nest/backer/5/website)[](https://opencollective.com/nest/backer/6/website)[](https://opencollective.com/nest/backer/7/website)[](https://opencollective.com/nest/backer/8/website)[](https://opencollective.com/nest/backer/9/website)[](https://opencollective.com/nest/backer/10/website)[](https://opencollective.com/nest/backer/11/website)[](https://opencollective.com/nest/backer/12/website)[](https://opencollective.com/nest/backer/13/website)[](https://opencollective.com/nest/backer/14/website)[](https://opencollective.com/nest/backer/15/website)[](https://opencollective.com/nest/backer/16/website)[](https://opencollective.com/nest/backer/17/website)[](https://opencollective.com/nest/backer/18/website)[](https://opencollective.com/nest/backer/19/website)[](https://opencollective.com/nest/backer/20/website)[](https://opencollective.com/nest/backer/21/website)[](https://opencollective.com/nest/backer/22/website)[](https://opencollective.com/nest/backer/23/website)[](https://opencollective.com/nest/backer/24/website)[](https://opencollective.com/nest/backer/25/website)[](https://opencollective.com/nest/backer/26/website)[](https://opencollective.com/nest/backer/27/website)[](https://opencollective.com/nest/backer/28/website)[](https://opencollective.com/nest/backer/29/website)

[Become a sponsor](https://opencollective.com/nest)

----
url: https://docs.nestjs.com/v11/graphql/generating-sdl
----

* [Generating SDL](https://docs.nestjs.com/v11/graphql/generating-sdl#generating-sdl)
* [Usage](https://docs.nestjs.com/v11/graphql/generating-sdl#usage)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/schema-generator.md "Suggest Edits")

### Generating SDL

> **Warning** This chapter applies only to the code first approach.

To manually generate a GraphQL SDL schema (i.e., without running an application, connecting to the database, hooking up resolvers, etc.), use the `GraphQLSchemaBuilderModule`.

```typescript

async function generateSchema() {
  const app = await NestFactory.create(GraphQLSchemaBuilderModule);
  await app.init();

  const gqlSchemaFactory = app.get(GraphQLSchemaFactory);
  const schema = await gqlSchemaFactory.create([RecipesResolver]);
  console.log(printSchema(schema));
}
```

> **Hint** The `GraphQLSchemaBuilderModule` and `GraphQLSchemaFactory` are imported from the `@nestjs/graphql` package. The `printSchema` function is imported from the `graphql` package.

#### Usage[#](/graphql/generating-sdl#usage)

The `gqlSchemaFactory.create()` method takes an array of resolver class references. For example:

```typescript

const schema = await gqlSchemaFactory.create([
  RecipesResolver,
  AuthorsResolver,
  PostsResolver,
]);
```

It also takes a second optional argument with an array of scalar classes:

```typescript

const schema = await gqlSchemaFactory.create(
  [RecipesResolver, AuthorsResolver, PostsResolver],
  [DurationScalar, DateScalar],
);
```

Lastly, you can pass an options object:

```typescript

const schema = await gqlSchemaFactory.create([RecipesResolver], {
  skipCheck: true,
  orphanedTypes: [],
});
```

* `skipCheck`: ignore schema validation; boolean, defaults to `false`
* `orphanedTypes`: list of classes that are not explicitly referenced (not part of the object graph) to be generated. Normally, if a class is declared but isn't otherwise referenced in the graph, it's omitted. The property value is an array of class references.

----
url: https://docs.nestjs.com/v9/custom-decorators
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Custom route decorators](https://docs.nestjs.com/v9/custom-decorators#custom-route-decorators)
* [Param decorators](https://docs.nestjs.com/v9/custom-decorators#param-decorators)
* [Passing data](https://docs.nestjs.com/v9/custom-decorators#passing-data)
* [Working with pipes](https://docs.nestjs.com/v9/custom-decorators#working-with-pipes)
* [Decorator composition](https://docs.nestjs.com/v9/custom-decorators#decorator-composition)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/custom-decorators.md "Suggest Edits")

### Custom route decorators

Nest is built around a language feature called **decorators**. Decorators are a well-known concept in a lot of commonly used programming languages, but in the JavaScript world, they're still relatively new. In order to better understand how decorators work, we recommend reading [this article](https://medium.com/google-developers/exploring-es7-decorators-76ecb65fb841). Here's a simple definition:

> An ES2016 decorator is an expression which returns a function and can take a target, name and property descriptor as arguments. You apply it by prefixing the decorator with an `@` character and placing this at the very top of what you are trying to decorate. Decorators can be defined for either a class, a method or a property.

#### Param decorators[#](/custom-decorators#param-decorators)

Nest provides a set of useful **param decorators** that you can use together with the HTTP route handlers. Below is a list of the provided decorators and the plain Express (or Fastify) objects they represent

|                            |                                      |
| -------------------------- | ------------------------------------ |
| `@Request(), @Req()`       | `req`                                |
| `@Response(), @Res()`      | `res`                                |
| `@Next()`                  | `next`                               |
| `@Session()`               | `req.session`                        |
| `@Param(param?: string)`   | `req.params` / `req.params[param]`   |
| `@Body(param?: string)`    | `req.body` / `req.body[param]`       |
| `@Query(param?: string)`   | `req.query` / `req.query[param]`     |
| `@Headers(param?: string)` | `req.headers` / `req.headers[param]` |
| `@Ip()`                    | `req.ip`                             |
| `@HostParam()`             | `req.hosts`                          |

Additionally, you can create your own **custom decorators**. Why is this useful?

In the node.js world, it's common practice to attach properties to the **request** object. Then you manually extract them in each route handler, using code like the following:

```typescript

const user = req.user;
```

In order to make your code more readable and transparent, you can create a `@User()` decorator and reuse it across all of your controllers.

user.decorator.ts

JS TS

```typescript

import { createParamDecorator, ExecutionContext } from '@nestjs/common';

export const User = createParamDecorator(
  (data: unknown, ctx: ExecutionContext) => {
    const request = ctx.switchToHttp().getRequest();
    return request.user;
  },
);
```

Then, you can simply use it wherever it fits your requirements.

JS TS

```typescript

@Get()
async findOne(@User() user: UserEntity) {
  console.log(user);
}
```

```typescript

@Get()
@Bind(User())
async findOne(user) {
  console.log(user);
}
```

#### Passing data[#](/custom-decorators#passing-data)

When the behavior of your decorator depends on some conditions, you can use the `data` parameter to pass an argument to the decorator's factory function. One use case for this is a custom decorator that extracts properties from the request object by key. Let's assume, for example, that our [authentication layer](techniques/authentication#implementing-passport-strategies) validates requests and attaches a user entity to the request object. The user entity for an authenticated request might look like:

```json

{
  "id": 101,
  "firstName": "Alan",
  "lastName": "Turing",
  "email": "alan@email.com",
  "roles": ["admin"]
}
```

Let's define a decorator that takes a property name as key, and returns the associated value if it exists (or undefined if it doesn't exist, or if the `user` object has not been created).

user.decorator.ts

JS TS

```typescript

import { createParamDecorator, ExecutionContext } from '@nestjs/common';

export const User = createParamDecorator(
  (data: string, ctx: ExecutionContext) => {
    const request = ctx.switchToHttp().getRequest();
    const user = request.user;

    return data ? user?.[data] : user;
  },
);
```

```typescript

import { createParamDecorator } from '@nestjs/common';

export const User = createParamDecorator((data, ctx) => {
  const request = ctx.switchToHttp().getRequest();
  const user = request.user;

  return data ? user && user[data] : user;
});
```

Here's how you could then access a particular property via the `@User()` decorator in the controller:

JS TS

```typescript

@Get()
async findOne(@User('firstName') firstName: string) {
  console.log(`Hello ${firstName}`);
}
```

```typescript

@Get()
@Bind(User('firstName'))
async findOne(firstName) {
  console.log(`Hello ${firstName}`);
}
```

You can use this same decorator with different keys to access different properties. If the `user` object is deep or complex, this can make for easier and more readable request handler implementations.

> **Hint** For TypeScript users, note that `createParamDecorator<T>()` is a generic. This means you can explicitly enforce type safety, for example `createParamDecorator<string>((data, ctx) => ...)`. Alternatively, specify a parameter type in the factory function, for example `createParamDecorator((data: string, ctx) => ...)`. If you omit both, the type for `data` will be `any`.

#### Working with pipes[#](/custom-decorators#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:

JS TS

```typescript

@Get()
async findOne(
  @User(new ValidationPipe({ validateCustomDecorators: true }))
  user: UserEntity,
) {
  console.log(user);
}
```

```typescript

@Get()
@Bind(User(new ValidationPipe({ validateCustomDecorators: true })))
async findOne(user) {
  console.log(user);
}
```

> **Hint** Note that `validateCustomDecorators` option must be set to true. `ValidationPipe` does not validate arguments annotated with the custom decorators by default.

#### Decorator composition[#](/custom-decorators#decorator-composition)

Nest provides a helper method to compose multiple decorators. For example, suppose you want to combine all decorators related to authentication into a single decorator. This could be done with the following construction:

auth.decorator.ts

JS TS

```typescript

import { applyDecorators } from '@nestjs/common';

export function Auth(...roles: Role[]) {
  return applyDecorators(
    SetMetadata('roles', roles),
    UseGuards(AuthGuard, RolesGuard),
    ApiBearerAuth(),
    ApiUnauthorizedResponse({ description: 'Unauthorized' }),
  );
}
```

```typescript

import { applyDecorators } from '@nestjs/common';

export function Auth(...roles) {
  return applyDecorators(
    SetMetadata('roles', roles),
    UseGuards(AuthGuard, RolesGuard),
    ApiBearerAuth(),
    ApiUnauthorizedResponse({ description: 'Unauthorized' }),
  );
}
```

You can then use this custom `@Auth()` decorator as follows:

```typescript

@Get('users')
@Auth('admin')
findAllUsers() {}
```

This has the effect of applying all four decorators with a single declaration.

> **Warning** The `@ApiHideProperty()` decorator from the `@nestjs/swagger` package is not composable and won't work properly with the `applyDecorators` function.

----
url: https://docs.nestjs.com/v8/fundamentals/async-providers
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Asynchronous providers](https://docs.nestjs.com/v8/fundamentals/async-providers#asynchronous-providers)
* [Injection](https://docs.nestjs.com/v8/fundamentals/async-providers#injection)
* [Example](https://docs.nestjs.com/v8/fundamentals/async-providers#example)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/fundamentals/async-components.md "Suggest Edits")

### Asynchronous providers

At times, the application start should be delayed until one or more **asynchronous tasks** are completed. For example, you may not want to start accepting requests until the connection with the database has been established. You can achieve this using asynchronous providers.

The syntax for this is to use `async/await` with the `useFactory` syntax. The factory returns a `Promise`, and the factory function can `await` asynchronous tasks. Nest will await resolution of the promise before instantiating any class that depends on (injects) such a provider.

```typescript

{
  provide: 'ASYNC_CONNECTION',
  useFactory: async () => {
    const connection = await createConnection(options);
    return connection;
  },
}
```

> **Hint** Learn more about custom provider syntax [here](/v8/fundamentals/custom-providers).

#### Injection[#](/fundamentals/async-providers#injection)

Asynchronous providers are injected to other components by their tokens, like any other provider. In the example above, you would use the construct `@Inject('ASYNC_CONNECTION')`.

#### Example[#](/fundamentals/async-providers#example)

[The TypeORM recipe](/v8/recipes/sql-typeorm) has a more substantial example of an asynchronous provider.

----
url: https://docs.nestjs.com/v6/techniques/queues
----

* [Queues](https://docs.nestjs.com/v6/techniques/queues#queues)
* [Installation](https://docs.nestjs.com/v6/techniques/queues#installation)
* [Producers](https://docs.nestjs.com/v6/techniques/queues#producers)
* [Named jobs](https://docs.nestjs.com/v6/techniques/queues#named-jobs)
* [Job options](https://docs.nestjs.com/v6/techniques/queues#job-options)
* [Consumers](https://docs.nestjs.com/v6/techniques/queues#consumers)
* [Event listeners](https://docs.nestjs.com/v6/techniques/queues#event-listeners)
* [Queue management](https://docs.nestjs.com/v6/techniques/queues#queue-management)
* [Async configuration](https://docs.nestjs.com/v6/techniques/queues#async-configuration)
* [Example](https://docs.nestjs.com/v6/techniques/queues#example)

```bash

$ npm install --save @nestjs/bull bull
$ npm install --save-dev @types/bull
```

Once the installation process is complete, we can import the `BullModule` into the root `AppModule`.

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { BullModule } from '@nestjs/bull';

@Module({
  imports: [
    BullModule.registerQueue({
      name: 'audio',
      redis: {
        host: 'localhost',
        port: 6379,
      },
    }),
  ],
})
export class AppModule {}
```

The `registerQueue()` method is used to instantiate and/or register queues. Queues are shared across modules and processes that connect to the same underlying Redis database with the same credentials. Each queue is unique by its name property (see below). When sharing queues (across modules/processes), the first `registerQueue()` method to run both **instantiates** the queue and **registers** it for that module. Other modules (in the same or separate processes) simply **register** the queue. Queue registration creates an **injection token** that can be used to access the queue in a given Nest module.

For each queue, pass a configuration object containing the following properties:

* `name: string` - A queue name, which will be used as both an injection token (for injecting the queue into controllers/providers), and as an argument to decorators to associate consumer classes and listeners with queues. Required.
* `limiter: RateLimiter` - Options to control the rate at which the queue's jobs are processed. See [RateLimiter](https://github.com/OptimalBits/bull/blob/master/REFERENCE.md#queue) for more information. Optional.
* `redis: RedisOpts` - Options to configure the Redis connection. See [RedisOpts](https://github.com/OptimalBits/bull/blob/master/REFERENCE.md#queue) for more information. Optional.
* `prefix: string` - Prefix for all queue keys. Optional.
* `defaultJobOptions: JobOpts` - Options to control the default settings for new jobs. See [JobOpts](https://github.com/OptimalBits/bull/blob/master/REFERENCE.md#queueadd) for more information. Optional.
* `settings: AdvancedSettings` - Advanced Queue configuration settings. These should usually not be changed. See [AdvancedSettings](https://github.com/OptimalBits/bull/blob/master/REFERENCE.md#queue) for more information. Optional.

As noted, the `name` property is required. The rest of the options are optional, providing detailed control over queue behavior. These are passed directly to the Bull `Queue` constructor. Read more about these options [here](https://github.com/OptimalBits/bull/blob/master/REFERENCE.md#queue). When registering a queue in a second or subsequent module, it is best practice to omit all options but the `name` property from the configuration object. These options should be specified only in the module that **instantiates** the queue.

> **Hint** Create multiple queues by passing multiple comma-separated configuration objects to the `registerQueue()` method.

Since jobs are persisted in Redis, each time a specific named queue is instantiated (e.g., when an app is started/restarted), it attempts to process any old jobs that may exist from a previous unfinished session.

Each queue can have one or many producers, consumers, and listeners. Consumers retrieve jobs from the queue in a specific order: FIFO (the default), LIFO, or according to priorities. Controlling queue processing order is discussed [here](techniques/queues#consumers).

## Official enterprise support

* Providing technical guidance
* Performing in-depth code reviews
* Mentoring team members
* Advising best practices

[Explore more](https://enterprise.nestjs.com "Enterprise | NestJS - A progressive Node.js framework")

#### Producers[#](/techniques/queues#producers)

Job producers add jobs to queues. Producers are typically application services (Nest [providers](/v6/providers)). To add jobs to a queue, first inject the queue into the service as follows:

```typescript

import { Injectable } from '@nestjs/common';
import { Queue } from 'bull';
import { InjectQueue } from '@nestjs/bull';

@Injectable()
export class AudioService {
  constructor(@InjectQueue('audio') private readonly audioQueue: Queue) {}
}
```

> **Hint** The `@InjectQueue()` decorator identifies the queue by its name, as provided in the `registerQueue()` method call (e.g., `'audio'`).

Now, add a job by calling the queue's `add()` method, passing a user-defined job object. Jobs are represented as serializable JavaScript objects (since that is how they are stored in the Redis database). The shape of the job you pass is arbitrary; use it to represent the semantics of your job object.

```typescript

const job = await this.audioQueue.add({
  foo: 'bar',
});
```

#### Named jobs[#](/techniques/queues#named-jobs)

Jobs may have unique names. This allows you to create specialized [consumers](techniques/queues#consumers) that will only process jobs with a given name.

```typescript

const job = await this.audioQueue.add('transcode', {
  foo: 'bar',
});
```

> **Warning** When using named jobs, you must create processors for each unique name added to a queue, or the queue will complain that you are missing a processor for the given job. See [here](techniques/queues#consumers) for more information on consuming named jobs.

```typescript

const job = await this.audioQueue.add(
  {
    foo: 'bar',
  },
  { delay: 3000 }, // 3 seconds delayed
);
```

To add a job to the right end of the queue (process the job as **LIFO** (Last In First Out)), set the `lifo` property of the configuration object to `true`.

```typescript

const job = await this.audioQueue.add(
  {
    foo: 'bar',
  },
  { lifo: true },
);
```

To prioritize a job, use the `priority` property.

```typescript

const job = await this.audioQueue.add(
  {
    foo: 'bar',
  },
  { priority: 2 },
);
```

#### Consumers[#](/techniques/queues#consumers)

A consumer is a **class** defining methods that either process jobs added into the queue, or listen for events on the queue, or both. Declare a consumer class using the `@Processor()` decorator as follows:

```typescript

import { Processor } from '@nestjs/bull';

@Processor('audio')
export class AudioConsumer {}
```

Where the decorator's string argument (e.g., `'audio'`) is the name of the queue to be associated with the class methods.

Within a consumer class, declare job handlers by decorating handler methods with the `@Process()` decorator.

```typescript

import { Processor, Process } from '@nestjs/bull';
import { Job } from 'bull';

@Processor('audio')
export class AudioConsumer {
  @Process()
  async transcode(job: Job<unknown>) {
    let progress = 0;
    for (i = 0; i < 100; i++) {
      await doSomething(job.data);
      progress += 10;
      job.progress(progress);
    }
    return {};
  }
}
```

The decorated method (e.g., `transcode()`) is called whenever the worker is idle and there are jobs to process in the queue. This handler method receives the `job` object as its only argument. The value returned by the handler method is stored in the job object and can be accessed later on, for example in a listener for the completed event.

`Job` objects have multiple methods that allow you to interact with their state. For example, the above code uses the `progress()` method to update the job's progress. See [here](https://github.com/OptimalBits/bull/blob/master/REFERENCE.md#job) for the complete `Job` object API reference.

You can designate that a job handler method will handle **only** jobs of a certain type (jobs with a specific `name`) by passing that `name` to the `@Process()` decorator as shown below. You can have multiple `@Process()` handlers in a given consumer class, corresponding to each job type (`name`). When you use named jobs, be sure to have a handler corresponding to each name.

```typescript

@Process('transcode')
async transcode(job: Job<unknown>) { ... }
```

#### Event listeners[#](/techniques/queues#event-listeners)

Bull generates a set of useful events when queue and/or job state changes occur. Nest provides a set of decorators that allow subscribing to a core set of standard events. These are exported from the `@nestjs/bull` package.

Event listeners must be declared within a [consumer](techniques/queues#consumers) class (i.e., within a class decorated with the `@Processor()` decorator). To listen for an event, use one of the decorators in the table below to declare a handler for the event. For example, to listen to the event emitted when a job enters the active state in the `audio` queue, use the following construct:

```typescript

import { Processor, Process } from '@nestjs/bull';
import { Job } from 'bull';

@Processor('audio')
export class AudioConsumer {

  @OnQueueActive()
  onActive(job: Job) {
    console.log(
      `Processing job ${job.id} of type ${job.name} with data ${job.data}...`,
    );
  }
  ...
```

Since Bull operates in a distributed (multi-node) environment, it defines the concept of event locality. This concept recognizes that events may be triggered either entirely within a single process, or on shared queues from different processes. A **local** event is one that is produced when an action or state change is triggered on a queue in the local process. In other words, when your event producers and consumers are local to a single process, all events happening on queues are local.

When a queue is shared across multiple processes, we encounter the possibility of **global** events. For a listener in one process to receive an event notification triggered by another process, it must register for a global event.

Event handlers are invoked whenever their corresponding event is emitted. The handler is called with the signature shown in the table below, providing access to information relevant to the event. We discuss one key difference between local and global event handler signatures below.

| Local event listeners | Global event listeners      | Handler method signature / When fired                                                                                                                                 |
| --------------------- | --------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `@OnQueueError()`     | `@OnGlobalQueueError()`     | `handler(error: Error)` - An error occurred. `error` contains the triggering error.                                                                                   |
| `@OnQueueWaiting()`   | `@OnGlobalQueueWaiting()`   | `handler(jobId: number \| string)` - A Job is waiting to be processed as soon as a worker is idling. `jobId` contains the id for the job that has entered this state. |
| `@OnQueueActive()`    | `@OnGlobalQueueActive()`    | `handler(job: Job)` - Job `job`has started.                                                                                                                           |
| `@OnQueueStalled()`   | `@OnGlobalQueueStalled()`   | `handler(job: Job)` - Job `job` has been marked as stalled. This is useful for debugging job workers that crash or pause the event loop.                              |
| `@OnQueueProgress()`  | `@OnGlobalQueueProgress()`  | `handler(job: Job, progress: number)` - Job `job`'s progress was updated to value `progress`.                                                                         |
| `@OnQueueCompleted()` | `@OnGlobalQueueCompleted()` | `handler(job: Job, result: any)` Job `job` successfully completed with a result `result`.                                                                             |
| `@OnQueueFailed()`    | `@OnGlobalQueueFailed()`    | `handler(job: Job, err: Error)` Job `job` failed with reason `err`.                                                                                                   |
| `@OnQueuePaused()`    | `@OnGlobalQueuePaused()`    | `handler()` The queue has been paused.                                                                                                                                |
| `@OnQueueResumed()`   | `@OnGlobalQueueResumed()`   | `handler(job: Job)` The queue has been resumed.                                                                                                                       |
| `@OnQueueCleaned()`   | `@OnGlobalQueueCleaned()`   | `handler(jobs: Job[], type: string)` Old jobs have been cleaned from the queue. `jobs` is an array of cleaned jobs, and `type` is the type of jobs cleaned.           |
| `@OnQueueDrained()`   | `@OnGlobalQueueDrained()`   | `handler()` Emitted whenever the queue has processed all the waiting jobs (even if there can be some delayed jobs not yet processed).                                 |
| `@OnQueueRemoved()`   | `@OnGlobalQueueRemoved()`   | `handler(job: Job)` Job `job` was successfully removed.                                                                                                               |

When listening for global events, the method signatures can be slightly different from their local counterpart. Specifically, any method signature that receives `job` objects in the local version, instead receives a `jobId` (`number`) in the global version. To get a reference to the actual `job` object in such a case, use the `Queue#getJob` method. This call should be awaited, and therefore the handler should be declared `async`. For example:

```typescript

@OnGlobalQueueCompleted()
async onGlobalCompleted(jobId: number, result: any) {
  const job = await this.immediateQueue.getJob(jobId);
  console.log('(Global) on completed: job ', job.id, ' -> result: ', result);
}
```

> **Hint** To access the `Queue` object (to make a `getJob()` call), you must of course inject it. Also, the Queue must be registered in the module where you are injecting it.

In addition to the specific event listener decorators, you can also use the generic `@OnQueueEvent()` decorator in combination with either `BullQueueEvents` or `BullQueueGlobalEvents` enums. Read more about events [here](https://github.com/OptimalBits/bull/blob/master/REFERENCE.md#events).

#### Queue management[#](/techniques/queues#queue-management)

Queue's have an API that allows you to perform management functions like pausing and resuming, retrieving the count of jobs in various states, and several more. You can find the full queue API [here](https://github.com/OptimalBits/bull/blob/master/REFERENCE.md#queue). Invoke any of these methods directly on the `Queue` object, as shown below with the pause/resume examples.

Pause a queue with the `pause()` method call. A paused queue will not process new jobs until resumed, but current jobs being processed will continue until they are finalized.

```typescript

await audioQueue.pause();
```

To resume a paused queue, use the `resume()` method, as follows:

```typescript

await audioQueue.resume();
```

#### Async configuration[#](/techniques/queues#async-configuration)

You may want to pass your queue options asynchronously instead of statically. In this case, use the `registerQueueAsync()` method, which provides several ways to deal with async configuration.

One approach is to use a factory function:

```typescript

BullModule.registerQueueAsync({
  name: 'audio',
  useFactory: () => ({
    redis: {
      host: 'localhost',
      port: 6379,
    },
  }),
});
```

Our factory behaves like any other [asynchronous provider](https://docs.nestjs.com/fundamentals/async-providers) (e.g., it can be `async` and it's able to inject dependencies through `inject`).

```typescript

BullModule.registerQueueAsync({
  name: 'audio',
  imports: [ConfigModule],
  useFactory: async (configService: ConfigService) => ({
    redis: {
      host: configService.get('QUEUE_HOST'),
      port: +configService.get('QUEUE_PORT'),
    },
  }),
  inject: [ConfigService],
});
```

Alternatively, you can use the `useClass` syntax:

```typescript

BullModule.registerQueueAsync({
  name: 'audio',
  useClass: BullConfigService,
});
```

The construction above will instantiate `BullConfigService` inside `BullModule` and use it to provide an options object by calling `createBullOptions()`. Note that this means that the `BullConfigService` has to implement the `BullOptionsFactory` interface, as shown below:

```typescript

@Injectable()
class BullConfigService implements BullOptionsFactory {
  createBullOptions(): BullModuleOptions {
    return {
      redis: {
        host: 'localhost',
        port: 6379,
      },
    };
  }
}
```

In order to prevent the creation of `BullConfigService` inside `BullModule` and use a provider imported from a different module, you can use the `useExisting` syntax.

```typescript

BullModule.registerQueueAsync({
  name: 'audio',
  imports: [ConfigModule],
  useExisting: ConfigService,
});
```

This construction works the same as `useClass` with one critical difference - `BullModule` will lookup imported modules to reuse an existing `ConfigService` instead of instantiating a new one.

#### Example[#](/techniques/queues#example)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/26-queues).

----
url: https://docs.nestjs.com/v4/websockets/guards
----

### Guards

There's one difference between [regular guards](/v4/guards) and the websockets **guards**. The websockets guards takes the `data` passed from the client instead of expressjs request object as an argument of the `canActivate()` function. Also, when the guard returns `false`, it throws `WsException` (not `HttpException`).

> **Hint** The `WsException` class is available within the `@nestjs/websockets` package.

#### Sponsors

[](https://valor-software.com/)

Nest is an MIT-licensed open source project. It can grow thanks to the support by these awesome people. If you'd like to join them, please read more [here](https://opencollective.com/nest). Thanks!

[](https://opencollective.com/nest/backer/0/website)[](https://opencollective.com/nest/backer/1/website)[](https://opencollective.com/nest/backer/2/website)[](https://opencollective.com/nest/backer/3/website)[](https://opencollective.com/nest/backer/4/website)[](https://opencollective.com/nest/backer/5/website)[](https://opencollective.com/nest/backer/6/website)[](https://opencollective.com/nest/backer/7/website)[](https://opencollective.com/nest/backer/8/website)[](https://opencollective.com/nest/backer/9/website)[](https://opencollective.com/nest/backer/10/website)[](https://opencollective.com/nest/backer/11/website)[](https://opencollective.com/nest/backer/12/website)[](https://opencollective.com/nest/backer/13/website)[](https://opencollective.com/nest/backer/14/website)[](https://opencollective.com/nest/backer/15/website)[](https://opencollective.com/nest/backer/16/website)[](https://opencollective.com/nest/backer/17/website)[](https://opencollective.com/nest/backer/18/website)[](https://opencollective.com/nest/backer/19/website)[](https://opencollective.com/nest/backer/20/website)[](https://opencollective.com/nest/backer/21/website)[](https://opencollective.com/nest/backer/22/website)[](https://opencollective.com/nest/backer/23/website)[](https://opencollective.com/nest/backer/24/website)[](https://opencollective.com/nest/backer/25/website)[](https://opencollective.com/nest/backer/26/website)[](https://opencollective.com/nest/backer/27/website)[](https://opencollective.com/nest/backer/28/website)[](https://opencollective.com/nest/backer/29/website)

[Become a sponsor](https://opencollective.com/nest)

----
url: https://docs.nestjs.com/v8/graphql/cli-plugin
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [CLI Plugin](https://docs.nestjs.com/v8/graphql/cli-plugin#cli-plugin)
* [Overview](https://docs.nestjs.com/v8/graphql/cli-plugin#overview)
* [Comments introspection](https://docs.nestjs.com/v8/graphql/cli-plugin#comments-introspection)
* [Using the CLI plugin](https://docs.nestjs.com/v8/graphql/cli-plugin#using-the-cli-plugin)
* [Integration with ts-jest (e2e tests)](https://docs.nestjs.com/v8/graphql/cli-plugin#integration-with-ts-jest-e2e-tests)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/cli-plugin.md "Suggest Edits")

### CLI Plugin

> **Warning** This chapter applies only to the code first approach.

TypeScript's metadata reflection system has several limitations which make it impossible to, for instance, determine what properties a class consists of or recognize whether a given property is optional or required. However, some of these constraints can be addressed at compilation time. Nest provides a plugin that enhances the TypeScript compilation process to reduce the amount of boilerplate code required.

> **Hint** This plugin is **opt-in**. If you prefer, you can declare all decorators manually, or only specific decorators where you need them.

```typescript

@ObjectType()
export class Author {
  @Field(type => ID)
  id: number;

  @Field({ nullable: true })
  firstName?: string;

  @Field({ nullable: true })
  lastName?: string;

  @Field(type => [Post])
  posts: Post[];
}
```

While not a significant issue with medium-sized projects, it becomes verbose & hard to maintain once you have a large set of classes.

By enabling the GraphQL plugin, the above class definition can be declared simply:

authors/models/author.model.ts

JS TS

```typescript

@ObjectType()
export class Author {
  @Field(type => ID)
  id: number;
  firstName?: string;
  lastName?: string;
  posts: Post[];
}
```

The plugin adds appropriate decorators on-the-fly based on the **Abstract Syntax Tree**. Thus, you won't have to struggle with `@Field` decorators scattered throughout the code.

> **Hint** The plugin will automatically generate any missing GraphQL properties, but if you need to override them, simply set them explicitly via `@Field()`.

#### Comments introspection[#](/graphql/cli-plugin#comments-introspection)

With the comments introspection feature enabled, CLI plugin will generate descriptions for fields based on comments.

For example, given an example `roles` property:

```typescript

/**
 * A list of user's roles
 */
@Field(() => [String], {
  description: `A list of user's roles`
})
roles: string[];
```

You must duplicate description values. With `introspectComments` enabled, the CLI plugin can extract these comments and automatically provide descriptions for properties. Now, the above field can be declared simply as follows:

```typescript

/**
 * A list of user's roles
 */
roles: string[];
```

#### Using the CLI plugin[#](/graphql/cli-plugin#using-the-cli-plugin)

To enable the plugin, open `nest-cli.json` (if you use [Nest CLI](/v8/cli/overview)) and add the following `plugins` configuration:

```javascript

{
  "collection": "@nestjs/schematics",
  "sourceRoot": "src",
  "compilerOptions": {
    "plugins": ["@nestjs/graphql"]
  }
}
```

You can use the `options` property to customize the behavior of the plugin.

```javascript

"plugins": [
  {
    "name": "@nestjs/graphql",
    "options": {
      "typeFileNameSuffix": [".input.ts", ".args.ts"],
      "introspectComments": true
    }
  }
]
```

The `options` property has to fulfill the following interface:

```typescript

export interface PluginOptions {
  typeFileNameSuffix?: string[];
  introspectComments?: boolean;
}
```

| Option               | Default                                                | Description                                                                        |
| -------------------- | ------------------------------------------------------ | ---------------------------------------------------------------------------------- |
| `typeFileNameSuffix` | `['.input.ts', '.args.ts', '.entity.ts', '.model.ts']` | GraphQL types files suffix                                                         |
| `introspectComments` | `false`                                                | If set to true, plugin will generate descriptions for properties based on comments |

If you don't use the CLI but instead have a custom `webpack` configuration, you can use this plugin in combination with `ts-loader`:

```javascript

getCustomTransformers: (program: any) => ({
  before: [require('@nestjs/graphql/plugin').before({}, program)]
}),
```

#### Integration with `ts-jest` (e2e tests)[#](/graphql/cli-plugin#integration-with-ts-jest-e2e-tests)

When running e2e tests with this plugin enabled, you may run into issues with compiling schema. For example, one of the most common errors is:

```json

Object type <name> must define one or more fields.
```

This happens because `jest` configuration does not import `@nestjs/graphql/plugin` plugin anywhere.

To fix this, create the following file in your e2e tests directory:

```javascript

const transformer = require('@nestjs/graphql/plugin');

module.exports.name = 'nestjs-graphql-transformer';
// you should change the version number anytime you change the configuration below - otherwise, jest will not detect changes
module.exports.version = 1;

module.exports.factory = (cs) => {
  return transformer.before(
    {
      // @nestjs/graphql/plugin options (can be empty)
    },
    cs.program, // "cs.tsCompiler.program" for older versions of Jest (<= v27)
  );
};
```

With this in place, import AST transformer within your `jest` configuration file. By default (in the starter application), e2e tests configuration file is located under the `test` folder and is named `jest-e2e.json`.

```json

{
  ... // other configuration
  "globals": {
    "ts-jest": {
      "astTransformers": {
        "before": ["<path to the file created above>"],
      }
    }
  }
}
```

----
url: https://docs.nestjs.com/v5/faq/global-prefix
----

### Global Prefix

In order to set a prefix for each route registered in the application at once, you can use the `setGlobalPrefix()` method of the `INestApplication` instance.

TypeScript

```typescript

const app = await NestFactory.create(ApplicationModule);
app.setGlobalPrefix('v1');
```

* Global Prefix

----
url: https://docs.nestjs.com/v11/graphql/directives
----

* [Directives](https://docs.nestjs.com/v11/graphql/directives#directives)
* [Custom directives](https://docs.nestjs.com/v11/graphql/directives#custom-directives)
* [Code first](https://docs.nestjs.com/v11/graphql/directives#code-first)
* [Schema first](https://docs.nestjs.com/v11/graphql/directives#schema-first)

```typescript

import { getDirective, MapperKind, mapSchema } from '@graphql-tools/utils';
import { defaultFieldResolver, GraphQLSchema } from 'graphql';

export function upperDirectiveTransformer(
  schema: GraphQLSchema,
  directiveName: string,
) {
  return mapSchema(schema, {
    [MapperKind.OBJECT_FIELD]: (fieldConfig) => {
      const upperDirective = getDirective(
        schema,
        fieldConfig,
        directiveName,
      )?.[0];

      if (upperDirective) {
        const { resolve = defaultFieldResolver } = fieldConfig;

        // Replace the original resolver with a function that *first* calls
        // the original resolver, then converts its result to upper case
        fieldConfig.resolve = async function (source, args, context, info) {
          const result = await resolve(source, args, context, info);
          if (typeof result === 'string') {
            return result.toUpperCase();
          }
          return result;
        };
        return fieldConfig;
      }
    },
  });
}
```

Now, apply the `upperDirectiveTransformer` transformation function in the `GraphQLModule#forRoot` method using the `transformSchema` function:

```typescript

GraphQLModule.forRoot({
  // ...
  transformSchema: (schema) => upperDirectiveTransformer(schema, 'upper'),
});
```

Once registered, the `@upper` directive can be used in our schema. However, the way you apply the directive will vary depending on the approach you use (code first or schema first).

#### Code first[#](/graphql/directives#code-first)

In the code first approach, use the `@Directive()` decorator to apply the directive.

```typescript

@Directive('@upper')
@Field()
title: string;
```

> **Hint** The `@Directive()` decorator is exported from the `@nestjs/graphql` package.

Directives can be applied on fields, field resolvers, input and object types, as well as queries, mutations, and subscriptions. Here's an example of the directive applied on the query handler level:

```typescript

@Directive('@deprecated(reason: "This query will be removed in the next version")')
@Query(() => Author, { name: 'author' })
async getAuthor(@Args({ name: 'id', type: () => Int }) id: number) {
  return this.authorsService.findOneById(id);
}
```

> **Warning** Directives applied through the `@Directive()` decorator will not be reflected in the generated schema definition file.

Lastly, make sure to declare directives in the `GraphQLModule`, as follows:

```typescript

GraphQLModule.forRoot({
  // ...,
  transformSchema: schema => upperDirectiveTransformer(schema, 'upper'),
  buildSchemaOptions: {
    directives: [
      new GraphQLDirective({
        name: 'upper',
        locations: [DirectiveLocation.FIELD_DEFINITION],
      }),
    ],
  },
}),
```

> **Hint** Both `GraphQLDirective` and `DirectiveLocation` are exported from the `graphql` package.

#### Schema first[#](/graphql/directives#schema-first)

In the schema first approach, apply directives directly in SDL.

```graphql

directive @upper on FIELD_DEFINITION

type Post {
  id: Int!
  title: String! @upper
  votes: Int
}
```

----
url: https://docs.nestjs.com/v9/websockets/interceptors
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Interceptors](https://docs.nestjs.com/v9/websockets/interceptors#interceptors)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/websockets/interceptors.md "Suggest Edits")

### Interceptors

There is no difference between [regular interceptors](/v9/interceptors) and web sockets interceptors. The following example uses a manually instantiated method-scoped interceptor. Just as with HTTP based applications, you can also use gateway-scoped interceptors (i.e., prefix the gateway class with a `@UseInterceptors()` decorator).

JS TS

```typescript

@UseInterceptors(new TransformInterceptor())
@SubscribeMessage('events')
handleEvent(client: Client, data: unknown): WsResponse<unknown> {
  const event = 'events';
  return { event, data };
}
```

```typescript

@UseInterceptors(new TransformInterceptor())
@SubscribeMessage('events')
handleEvent(client, data) {
  const event = 'events';
  return { event, data };
}
```

----
url: https://docs.nestjs.com/v6/recipes/mongodb
----

* [MongoDB (Mongoose)](https://docs.nestjs.com/v6/recipes/mongodb#mongodb-mongoose)
* [Getting started](https://docs.nestjs.com/v6/recipes/mongodb#getting-started)
* [Model injection](https://docs.nestjs.com/v6/recipes/mongodb#model-injection)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/recipes/mongodb.md "Suggest Edits")

### MongoDB (Mongoose)

> **Warning** In this article, you'll learn how to create a `DatabaseModule` based on the **Mongoose** package from scratch using custom components. As a consequence, this solution contains a lot of overhead that you can omit using ready to use and available out-of-the-box dedicated `@nestjs/mongoose` package. To learn more, see [here](/v6/techniques/mongodb).

[Mongoose](http://mongoosejs.com) is the most popular [MongoDB](https://www.mongodb.org/) object modeling tool.

#### Getting started[#](/recipes/mongodb#getting-started)

To start the adventure with this library we have to install all required dependencies:

JS TS

```typescript

$ npm install --save mongoose
$ npm install --save-dev @types/mongoose
```

```typescript

$ npm install --save mongoose
```

The first step we need to do is to establish the connection with our database using `connect()` function. The `connect()` function returns a `Promise`, and therefore we have to create an [async provider](/v6/fundamentals/async-components).

database.providers.ts

JS TS

```typescript

import * as mongoose from 'mongoose';

export const databaseProviders = [
  {
    provide: 'DATABASE_CONNECTION',
    useFactory: (): Promise<typeof mongoose> =>
      mongoose.connect('mongodb://localhost/nest'),
  },
];
```

```typescript

import * as mongoose from 'mongoose';

export const databaseProviders = [
  {
    provide: 'DATABASE_CONNECTION',
    useFactory: () => mongoose.connect('mongodb://localhost/nest'),
  },
];
```

> **Hint** Following best practices, we declared the custom provider in the separated file which has a `*.providers.ts` suffix.

Then, we need to export these providers to make them **accessible** for the rest part of the application.

database.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { databaseProviders } from './database.providers';

@Module({
  providers: [...databaseProviders],
  exports: [...databaseProviders],
})
export class DatabaseModule {}
```

Now we can inject the `Connection` object using `@Inject()` decorator. Each class that would depend on the `Connection` async provider will wait until a `Promise` is resolved.

#### Model injection[#](/recipes/mongodb#model-injection)

With Mongoose, everything is derived from a [Schema](http://mongoosejs.com/docs/guide.html). Let's define the `CatSchema`:

schemas/cat.schema.ts

JS TS

```typescript

import * as mongoose from 'mongoose';

export const CatSchema = new mongoose.Schema({
  name: String,
  age: Number,
  breed: String,
});
```

The `CatsSchema` belongs to the `cats` directory. This directory represents the `CatsModule`.

Now it's time to create a **Model** provider:

cats.providers.ts

JS TS

```typescript

import { Connection } from 'mongoose';
import { CatSchema } from './schemas/cat.schema';

export const catsProviders = [
  {
    provide: 'CAT_MODEL',
    useFactory: (connection: Connection) => connection.model('Cat', CatSchema),
    inject: ['DATABASE_CONNECTION'],
  },
];
```

```typescript

import { CatSchema } from './schemas/cat.schema';

export const catsProviders = [
  {
    provide: 'CAT_MODEL',
    useFactory: (connection) => connection.model('Cat', CatSchema),
    inject: ['DATABASE_CONNECTION'],
  },
];
```

> **Notice** In the real-world applications you should avoid **magic strings**. Both `CAT_MODEL` and `DATABASE_CONNECTION` should be kept in the separated `constants.ts` file.

Now we can inject the `CAT_MODEL` to the `CatsService` using the `@Inject()` decorator:

cats.service.ts

JS TS

```typescript

import { Model } from 'mongoose';
import { Injectable, Inject } from '@nestjs/common';
import { Cat } from './interfaces/cat.interface';
import { CreateCatDto } from './dto/create-cat.dto';

@Injectable()
export class CatsService {
  constructor(
    @Inject('CAT_MODEL')
    private readonly catModel: Model<Cat>,
  ) {}

  async create(createCatDto: CreateCatDto): Promise<Cat> {
    const createdCat = new this.catModel(createCatDto);
    return createdCat.save();
  }

  async findAll(): Promise<Cat[]> {
    return this.catModel.find().exec();
  }
}
```

```typescript

import { Injectable, Dependencies } from '@nestjs/common';

@Injectable()
@Dependencies('CAT_MODEL')
export class CatsService {
  constructor(catModel) {
    this.catModel = catModel;
  }

  async create(createCatDto) {
    const createdCat = new this.catModel(createCatDto);
    return createdCat.save();
  }

  async findAll() {
    return this.catModel.find().exec();
  }
}
```

In the above example we have used the `Cat` interface. This interface extends the `Document` from the mongoose package:

```typescript

import { Document } from 'mongoose';

export interface Cat extends Document {
  readonly name: string;
  readonly age: number;
  readonly breed: string;
}
```

The database connection is **asynchronous**, but Nest makes this process completely invisible for the end-user. The `CatModel` class is waiting for the db connection, and the `CatsService` is delayed until model is ready to use. The entire application can start when each class is instantiated.

Here is a final `CatsModule`:

cats.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';
import { catsProviders } from './cats.providers';
import { DatabaseModule } from '../database/database.module';

@Module({
  imports: [DatabaseModule],
  controllers: [CatsController],
  providers: [
    CatsService,
    ...catsProviders,
  ],
})
export class CatsModule {}
```

> **Hint** Do not forget to import the `CatsModule` into the root `ApplicationModule`.

----
url: https://docs.nestjs.com/exception-filters
----

[Skip to content](#content)

On this page

* [Exception filters](https://docs.nestjs.com/exception-filters#exception-filters)
* [Throwing standard exceptions](https://docs.nestjs.com/exception-filters#throwing-standard-exceptions)
* [Exceptions logging](https://docs.nestjs.com/exception-filters#exceptions-logging)
* [Tracking errors in production](https://docs.nestjs.com/exception-filters#tracking-errors-in-production)
* [Custom exceptions](https://docs.nestjs.com/exception-filters#custom-exceptions)
* [Built-in HTTP exceptions](https://docs.nestjs.com/exception-filters#built-in-http-exceptions)
* [Machine-readable error codes](https://docs.nestjs.com/exception-filters#machine-readable-error-codes)
* [Exception filters](https://docs.nestjs.com/exception-filters#exception-filters-1)
* [Arguments host](https://docs.nestjs.com/exception-filters#arguments-host)
* [Binding filters](https://docs.nestjs.com/exception-filters#binding-filters)
* [Catch everything](https://docs.nestjs.com/exception-filters#catch-everything)
* [Inheritance](https://docs.nestjs.com/exception-filters#inheritance)

### Exception filters

Nest comes with a built-in **exceptions layer** that processes all unhandled exceptions across an application. When your application code does not handle an exception, this layer catches it and automatically sends an appropriate, user-friendly response.

Out of the box, this is done by a built-in **global exception filter**, which handles exceptions of type `HttpException` (and its subclasses). When an exception is **unrecognized** (it is neither an `HttpException` nor a class that inherits from `HttpException`), the built-in exception filter generates the following default JSON response:

```json

{
  "statusCode": 500,
  "message": "Internal server error"
}
```

> **Hint** The global exception filter partially supports the `http-errors` library. A thrown error that carries `statusCode` and `message` properties in the shape that library produces is sent back with those values, instead of the default `InternalServerErrorException` response for unrecognized exceptions.

#### Throwing standard exceptions[#](/exception-filters#throwing-standard-exceptions)

Nest provides a built-in `HttpException` class, exposed from the `@nestjs/common` package. For typical HTTP-based REST and GraphQL APIs, it's best practice to send standard HTTP response objects when certain error conditions occur.

For example, the `CatsController` has a `findAll()` method (a `GET` route handler). Let's assume that this route handler throws an exception. To demonstrate this, we'll hard-code it as follows:

cats.controller.ts

JS TS

```typescript

@Get()
async findAll() {
  throw new HttpException('Forbidden', HttpStatus.FORBIDDEN);
}
```

> **Hint**`HttpStatus` is a helper enum imported from the `@nestjs/common` package.

When the client calls this endpoint, the response looks like this:

```json

{
  "statusCode": 403,
  "message": "Forbidden"
}
```

The `HttpException` constructor takes two required arguments that determine the response:

* The `response` argument defines the JSON response body. It can be a `string` or an `object`, as described below.
* The `status` argument defines the [HTTP status code](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status).

By default, the JSON response body contains two properties:

* `statusCode`: defaults to the HTTP status code provided in the `status` argument
* `message`: a short description of the HTTP error based on the `status`

To override only the message portion of the JSON response body, supply a string in the `response` argument. To override the entire JSON response body, pass an object in the `response` argument. Nest serializes the object and returns it as the JSON response body.

> **Hint** An `Error` instance passed as the `response` argument is not serialized into the response body. Nest sends the default `{ statusCode, message }` body for the status instead, so the properties of the error are not exposed to the client. To keep the original error for logging, pass it as the `cause` instead.

The second constructor argument, `status`, should be a valid HTTP status code. Best practice is to use the `HttpStatus` enum imported from `@nestjs/common`.

An optional **third** constructor argument, `options`, can be used to provide an error [cause](https://nodejs.org/en/blog/release/v16.9.0/#error-cause). The `cause` object is not serialized into the response object, but it is useful for logging, as it provides information about the inner error that caused the `HttpException` to be thrown.

Here's an example that overrides the entire response body and provides an error cause:

cats.controller.ts

JS TS

```typescript

@Get()
async findAll() {
  try {
    await this.service.findAll();
  } catch (error) {
    throw new HttpException({
      status: HttpStatus.FORBIDDEN,
      error: 'This is a custom message',
    }, HttpStatus.FORBIDDEN, {
      cause: error
    });
  }
}
```

The response then looks like this:

```json

{
  "status": 403,
  "error": "This is a custom message"
}
```

#### Exceptions logging[#](/exception-filters#exceptions-logging)

By default, the exception filter does not log built-in exceptions such as `HttpException` (and any exceptions that inherit from it). These exceptions are treated as part of the normal application flow, so they don't appear in the console. The same applies to `WsException` and `RpcException` in their respective contexts.

`HttpException` inherits from the `IntrinsicException` class, which is exported from the `@nestjs/common` package. The built-in exception filters never log instances of `IntrinsicException`, which is how they distinguish exceptions that are part of normal operation from those that are not.

To log these exceptions, create a custom exception filter, as described in the [Exception filters](/exception-filters#exception-filters) section below.

#### Tracking errors in production[#](/exception-filters#tracking-errors-in-production)

An exception filter decides what the *client* sees. On its own, it does not tell you that a `TypeError` started firing in `OrdersService` twelve minutes ago, on 4% of checkouts, only for customers whose cart contains a discounted item. Nor does it tell you which line threw.

The usual approach is to log the stack trace and search for it later, which falls short: a stack trace in a log file points at compiled output (`/var/app/current/dist/orders/orders.service.js:35`), carries no source context, and does not tell you whether this is the first occurrence or the ten-thousandth.

[NestJS Observe](https://www.observe.nestjs.com/ "NestJS Observe") treats an unhandled error as a first-class object rather than a log line. Every error that reaches the exceptions layer is captured along with the request that caused it, and:

* **The stack trace comes with source code.** The frame is resolved through your source maps back to `src/orders/orders.service.ts:35`, and the surrounding lines are shown inline, so you can read the failing code in the error card without cloning anything.
* **Occurrences are grouped into defects.** Errors with the same class and stack shape collapse into one fingerprinted group with a count, first-seen and last-seen timestamps, and the release that introduced it. "New since v2.4.1" is a fact you read off the page rather than infer.
* **The failure keeps its context.** The trace it belonged to, the user who hit it, the logs written during that request, and the spans that ran before the throw are all attached, so you can see what the request was doing when it failed.

Because the error already carries its own code, you can hand it to a coding agent in one click: **Copy agent prompt** packages the error, the trimmed stack trace with source lines, the slow spans, and the surrounding logs into a self-contained prompt for Claude Code, Cursor, or any other tool that has your repository open.

This complements the filters described in this chapter rather than replacing them: filters shape the response, while instrumentation records what happened on the way there. See [Error monitoring](/observability/error-monitoring) for everything the SDK captures about a failure, the [Observability](/observability/overview) chapter for setup, and [Dashboard](/observability/dashboard#issues) for turning a recurring error into a tracked issue that verifies its own fix.

#### Custom exceptions[#](/exception-filters#custom-exceptions)

In most cases, you won't need to write custom exceptions and can use the built-in Nest HTTP exceptions described in the next section. If you do need custom exceptions, it's good practice to create your own **exception hierarchy**, in which your custom exceptions inherit from the base `HttpException` class. Nest then recognizes your exceptions and automatically takes care of the error responses. Let's implement such a custom exception:

forbidden.exception.ts

JS TS

```typescript

export class ForbiddenException extends HttpException {
  constructor() {
    super('Forbidden', HttpStatus.FORBIDDEN);
  }
}
```

Since `ForbiddenException` extends the base `HttpException`, it works with the built-in exception handler, so we can use it inside the `findAll()` method.

cats.controller.ts

JS TS

```typescript

@Get()
async findAll() {
  throw new ForbiddenException();
}
```

#### Built-in HTTP exceptions[#](/exception-filters#built-in-http-exceptions)

Nest provides a set of standard exceptions that inherit from the base `HttpException`. They are exposed from the `@nestjs/common` package and represent many of the most common HTTP exceptions:

* `HttpVersionNotSupportedException`
* `PayloadTooLargeException`
* `UnsupportedMediaTypeException`
* `UnprocessableEntityException`
* `InternalServerErrorException`
* `NotImplementedException`
* `ImATeapotException`
* `MethodNotAllowedException`
* `MisdirectedException`
* `BadGatewayException`
* `ServiceUnavailableException`
* `GatewayTimeoutException`
* `PreconditionFailedException`

All the built-in exceptions can also provide an error `cause` and an error description through the `options` parameter:

```typescript

throw new BadRequestException('Something bad happened', {
  cause: new Error(),
  description: 'Some error description',
});
```

The response then looks like this:

```json

{
  "message": "Something bad happened",
  "error": "Some error description",
  "statusCode": 400
}
```

#### Machine-readable error codes[#](/exception-filters#machine-readable-error-codes)

The `status` and `message` of an exception describe an error well enough for humans, but they are awkward for clients to branch on. Several distinct failures, such as an invalid email and a weak password, can all surface as `400 Bad Request`, which forces the client to parse the human-readable message string to tell them apart.

To avoid that, pass an `errorCode` through the `options` parameter. It is a stable, machine-readable identifier that is serialized into the response body:

```typescript

throw new BadRequestException('Password is too weak', {
  errorCode: 'WEAK_PASSWORD',
});
```

The response then carries the code alongside the usual fields:

```json

{
  "message": "Password is too weak",
  "errorCode": "WEAK_PASSWORD",
  "statusCode": 400
}
```

`errorCode` is optional and can be combined with `cause` and `description`. It is also available on `HttpException` itself, so custom exceptions can set it too:

```typescript

throw new HttpException(
  'Forbidden',
  HttpStatus.FORBIDDEN,
  { errorCode: 'ACCOUNT_SUSPENDED' },
);
```

> **Hint** Unlike `cause`, which is intended for logging and is never serialized, `errorCode` is part of the response body and is meant to be consumed by clients.

#### Exception filters[#](/exception-filters#exception-filters-1)

The built-in exception filter handles many cases automatically, but you may want **full control** over the exceptions layer, e.g., to add logging or to use a different JSON schema based on dynamic factors. **Exception filters** are designed for exactly this purpose. They let you control the exact flow of execution and the content of the response sent back to the client.

Let's create an exception filter that catches exceptions that are instances of the `HttpException` class and implements custom response logic for them. To do this, we need access to the underlying platform `Request` and `Response` objects. We'll use the `Request` object to extract the original `url` and include it in the response, and the `Response` object to take direct control of the response that is sent, using the `response.json()` method.

http-exception.filter.ts

JS TS

```typescript

import { ExceptionFilter, Catch, ArgumentsHost, HttpException } from '@nestjs/common';
import { Request, Response } from 'express';

@Catch(HttpException)
export class HttpExceptionFilter implements ExceptionFilter {
  catch(exception: HttpException, host: ArgumentsHost) {
    const ctx = host.switchToHttp();
    const response = ctx.getResponse<Response>();
    const request = ctx.getRequest<Request>();
    const status = exception.getStatus();

    response
      .status(status)
      .json({
        statusCode: status,
        timestamp: new Date().toISOString(),
        path: request.url,
      });
  }
}
```

```typescript

import { Catch, HttpException } from '@nestjs/common';

@Catch(HttpException)
export class HttpExceptionFilter {
  catch(exception, host) {
    const ctx = host.switchToHttp();
    const response = ctx.getResponse();
    const request = ctx.getRequest();
    const status = exception.getStatus();

    response
      .status(status)
      .json({
        statusCode: status,
        timestamp: new Date().toISOString(),
        path: request.url,
      });
  }
}
```

> **Hint** All exception filters should implement the generic `ExceptionFilter<T>` interface. This requires you to provide the `catch(exception: T, host: ArgumentsHost)` method with its indicated signature. `T` indicates the type of the exception.

> **Warning** If you are using `@nestjs/platform-fastify`, use `response.send()` instead of `response.json()`, and import the corresponding types from `fastify`.

The `@Catch(HttpException)` decorator binds the required metadata to the exception filter, telling Nest that this particular filter is looking for exceptions of type `HttpException` and nothing else. The `@Catch()` decorator accepts a single parameter or a comma-separated list, which lets you set up the filter for several types of exceptions at once.

#### Arguments host[#](/exception-filters#arguments-host)

Let's look at the parameters of the `catch()` method. The `exception` parameter is the exception object currently being processed. The `host` parameter is an `ArgumentsHost` object, a utility that gives you access to the arguments passed to the original handler, whatever context it was invoked in. In the code sample above, we use its helper methods to obtain the `Request` and `Response` objects of the request in which the exception originated. `ArgumentsHost` is covered in full in the [execution context chapter](/fundamentals/execution-context).

The reason for this level of abstraction is that `ArgumentsHost` works in every context: the HTTP server context used here, but also microservices and WebSockets. The execution context chapter shows how to reach the [underlying arguments](/fundamentals/execution-context#host-handler-arguments) for **any** context through the same object, which lets you write a single exception filter that operates across all of them.

## Learn the right way!

* 80+ chapters
* 5+ hours of videos
* Official certificate
* Deep-dive sessions

[Explore official courses](https://courses.nestjs.com "Courses | NestJS - A node.js framework built on top of TypeScript")

#### Binding filters[#](/exception-filters#binding-filters)

Let's bind our new `HttpExceptionFilter` to the `create()` method of the `CatsController`.

cats.controller.ts

JS TS

```typescript

@Post()
@UseFilters(new HttpExceptionFilter())
async create(@Body() createCatDto: CreateCatDto) {
  throw new ForbiddenException();
}
```

```typescript

@Post()
@UseFilters(new HttpExceptionFilter())
@Bind(Body())
async create(createCatDto) {
  throw new ForbiddenException();
}
```

> **Hint** The `@UseFilters()` decorator is imported from the `@nestjs/common` package.

Like the `@Catch()` decorator, `@UseFilters()` accepts a single filter instance or a comma-separated list of filter instances. Here, we created the `HttpExceptionFilter` instance in place. Alternatively, you can pass the class (instead of an instance), which leaves instantiation to the framework and enables **dependency injection**.

cats.controller.ts

JS TS

```typescript

@Post()
@UseFilters(HttpExceptionFilter)
async create(@Body() createCatDto: CreateCatDto) {
  throw new ForbiddenException();
}
```

```typescript

@Post()
@UseFilters(HttpExceptionFilter)
@Bind(Body())
async create(createCatDto) {
  throw new ForbiddenException();
}
```

> **Hint** Prefer binding filters by class instead of by instance when possible. This reduces **memory usage**, since Nest can reuse instances of the same class across your entire module.

In the example above, the `HttpExceptionFilter` is applied only to the `create()` route handler, which makes it method-scoped. Exception filters can be scoped at different levels: method-scoped (a method of a controller, resolver, or gateway), controller-scoped, or global-scoped. For example, to set up a controller-scoped filter, do the following:

cats.controller.ts

JS TS

```typescript

@Controller()
@UseFilters(new HttpExceptionFilter())
export class CatsController {}
```

This sets up the `HttpExceptionFilter` for every route handler defined inside the `CatsController`.

To create a global-scoped filter, do the following:

main.ts

JS TS

```typescript

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.useGlobalFilters(new HttpExceptionFilter());
  await app.listen(process.env.PORT ?? 3000);
}
await bootstrap();
```

> **Warning** The `useGlobalFilters()` method does not set up filters for gateways or hybrid applications.

Global-scoped filters are used across the whole application, for every controller and every route handler. In terms of dependency injection, global filters registered from outside of any module (with `useGlobalFilters()`, as in the example above) cannot inject dependencies, since this happens outside the context of any module. To solve this, you can register a global-scoped filter **directly from any module** using the following construction:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { APP_FILTER } from '@nestjs/core';

@Module({
  providers: [
    {
      provide: APP_FILTER,
      useClass: HttpExceptionFilter,
    },
  ],
})
export class AppModule {}
```

> **Hint** When you use this approach to perform dependency injection for the filter, the filter is global regardless of the module in which this construction is employed. Register it in the module where the filter (`HttpExceptionFilter` in the example above) is defined. Also, `useClass` is not the only way to register a custom provider. Learn more about [custom providers](/fundamentals/custom-providers).

> **Hint** Exceptions thrown from [middleware](/middleware#error-handling) are also processed by the exceptions layer. Because middleware runs before a route handler is selected, only **global** exception filters apply (`app.useGlobalFilters()` or `APP_FILTER`). Method-scoped and controller-scoped `@UseFilters()` bindings are not invoked.

You can register as many filters as needed with this technique by adding each one to the `providers` array.

#### Catch everything[#](/exception-filters#catch-everything)

To catch **every** unhandled exception, regardless of its type, leave the `@Catch()` decorator's parameter list empty, i.e., `@Catch()`.

The example below is platform-agnostic: it delivers the response through the [HTTP adapter](/exception-filters/faq/http-adapter) rather than using the platform-specific `Request` and `Response` objects directly, so the same filter works with both Express and Fastify.

```typescript

import {
  ExceptionFilter,
  Catch,
  ArgumentsHost,
  HttpException,
  HttpStatus,
} from '@nestjs/common';
import { HttpAdapterHost } from '@nestjs/core';

@Catch()
export class CatchEverythingFilter implements ExceptionFilter {
  constructor(private readonly httpAdapterHost: HttpAdapterHost) {}

  catch(exception: unknown, host: ArgumentsHost): void {
    // In certain situations `httpAdapter` might not be available in the
    // constructor, so resolve it here.
    const { httpAdapter } = this.httpAdapterHost;

    const ctx = host.switchToHttp();

    const httpStatus =
      exception instanceof HttpException
        ? exception.getStatus()
        : HttpStatus.INTERNAL_SERVER_ERROR;

    const responseBody = {
      statusCode: httpStatus,
      timestamp: new Date().toISOString(),
      path: httpAdapter.getRequestUrl(ctx.getRequest()),
    };

    httpAdapter.reply(ctx.getResponse(), responseBody, httpStatus);
  }
}
```

> **Warning** When combining a catch-everything filter with one bound to a specific exception type, declare the catch-everything filter **first**, so the more specific filter can still handle the type it is bound to.

#### Inheritance[#](/exception-filters#inheritance)

Typically, you'll create fully customized exception filters tailored to your application's requirements. However, in some cases you may want to extend the built-in **global exception filter** and override its behavior only under certain conditions.

To delegate exception processing to the base filter, extend `BaseExceptionFilter` and call the inherited `catch()` method.

all-exceptions.filter.ts

JS TS

```typescript

import { Catch, ArgumentsHost } from '@nestjs/common';
import { BaseExceptionFilter } from '@nestjs/core';

@Catch()
export class AllExceptionsFilter extends BaseExceptionFilter {
  catch(exception: unknown, host: ArgumentsHost) {
    super.catch(exception, host);
  }
}
```

```typescript

import { Catch } from '@nestjs/common';
import { BaseExceptionFilter } from '@nestjs/core';

@Catch()
export class AllExceptionsFilter extends BaseExceptionFilter {
  catch(exception, host) {
    super.catch(exception, host);
  }
}
```

> **Warning** Method-scoped and controller-scoped filters that extend the `BaseExceptionFilter` should not be instantiated with `new`. Instead, let the framework instantiate them automatically.

Global filters **can** extend the base filter, in one of two ways.

The first is to pass the `HttpAdapter` reference to the constructor when instantiating the custom global filter:

```typescript

async function bootstrap() {
  const app = await NestFactory.create(AppModule);

  const { httpAdapter } = app.get(HttpAdapterHost);
  app.useGlobalFilters(new AllExceptionsFilter(httpAdapter));

  await app.listen(process.env.PORT ?? 3000);
}
await bootstrap();
```

The second is to register the filter with the `APP_FILTER` token, [as shown earlier](exception-filters#binding-filters).

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/exception-filters.md)

----
url: https://docs.nestjs.com/v10/websockets/interceptors
----

* [Interceptors](https://docs.nestjs.com/v10/websockets/interceptors#interceptors)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/websockets/interceptors.md "Suggest Edits")

### Interceptors

There is no difference between [regular interceptors](/v10/interceptors) and web sockets interceptors. The following example uses a manually instantiated method-scoped interceptor. Just as with HTTP based applications, you can also use gateway-scoped interceptors (i.e., prefix the gateway class with a `@UseInterceptors()` decorator).

JS TS

```typescript

@UseInterceptors(new TransformInterceptor())
@SubscribeMessage('events')
handleEvent(client: Client, data: unknown): WsResponse<unknown> {
  const event = 'events';
  return { event, data };
}
```

```typescript

@UseInterceptors(new TransformInterceptor())
@SubscribeMessage('events')
handleEvent(client, data) {
  const event = 'events';
  return { event, data };
}
```

----
url: https://docs.nestjs.com/v10/graphql/quick-start
----

* [Installation](https://docs.nestjs.com/v10/graphql/quick-start#installation)
* [Overview](https://docs.nestjs.com/v10/graphql/quick-start#overview)
* [Getting started with GraphQL & TypeScript](https://docs.nestjs.com/v10/graphql/quick-start#getting-started-with-graphql--typescript)
* [GraphQL playground](https://docs.nestjs.com/v10/graphql/quick-start#graphql-playground)
* [Multiple endpoints](https://docs.nestjs.com/v10/graphql/quick-start#multiple-endpoints)
* [Code first](https://docs.nestjs.com/v10/graphql/quick-start#code-first)
* [Example](https://docs.nestjs.com/v10/graphql/quick-start#example)
* [Schema first](https://docs.nestjs.com/v10/graphql/quick-start#schema-first)
* [Apollo Sandbox](https://docs.nestjs.com/v10/graphql/quick-start#apollo-sandbox)
* [Example](https://docs.nestjs.com/v10/graphql/quick-start#example-1)
* [Accessing generated schema](https://docs.nestjs.com/v10/graphql/quick-start#accessing-generated-schema)
* [Async configuration](https://docs.nestjs.com/v10/graphql/quick-start#async-configuration)
* [Mercurius integration](https://docs.nestjs.com/v10/graphql/quick-start#mercurius-integration)
* [Third-party integrations](https://docs.nestjs.com/v10/graphql/quick-start#third-party-integrations)
* [Example](https://docs.nestjs.com/v10/graphql/quick-start#example-2)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/quick-start.md "Suggest Edits")

## Harnessing the power of TypeScript & GraphQL

[GraphQL](https://graphql.org/) is a powerful query language for APIs and a runtime for fulfilling those queries with your existing data. It's an elegant approach that solves many problems typically found with REST APIs. For background, we suggest reading this [comparison](https://www.apollographql.com/blog/graphql-vs-rest) between GraphQL and REST. GraphQL combined with [TypeScript](https://www.typescriptlang.org/) helps you develop better type safety with your GraphQL queries, giving you end-to-end typing.

In this chapter, we assume a basic understanding of GraphQL, and focus on how to work with the built-in `@nestjs/graphql` module. The `GraphQLModule` can be configured to use [Apollo](https://www.apollographql.com/) server (with the `@nestjs/apollo` driver) and [Mercurius](https://github.com/mercurius-js/mercurius) (with the `@nestjs/mercurius`). We provide official integrations for these proven GraphQL packages to provide a simple way to use GraphQL with Nest (see more integrations [here](https://docs.nestjs.com/graphql/quick-start#third-party-integrations)).

You can also build your own dedicated driver (read more on that [here](/graphql/other-features#creating-a-custom-driver)).

#### Installation[#](/graphql/quick-start#installation)

Start by installing the required packages:

```bash

# For Express and Apollo (default)
$ npm i @nestjs/graphql @nestjs/apollo @apollo/server graphql

# For Fastify and Apollo
# npm i @nestjs/graphql @nestjs/apollo @apollo/server @as-integrations/fastify graphql

# For Fastify and Mercurius
# npm i @nestjs/graphql @nestjs/mercurius graphql mercurius
```

> **Warning**`@nestjs/graphql@>=9` and `@nestjs/apollo^10` packages are compatible with **Apollo v3** (check out Apollo Server 3 [migration guide](https://www.apollographql.com/docs/apollo-server/migration/) for more details), while `@nestjs/graphql@^8` only supports **Apollo v2** (e.g., `apollo-server-express@2.x.x` package).

> **Hint** In the following chapters, we'll be integrating the `@nestjs/apollo` package. If you want to use `mercurius` package instead, navigate to [this section](/graphql/quick-start#mercurius-integration).

Once the packages are installed, we can import the `GraphQLModule` and configure it with the `forRoot()` static method.

JS TS

```typescript

import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';
import { ApolloDriver, ApolloDriverConfig } from '@nestjs/apollo';

@Module({
  imports: [
    GraphQLModule.forRoot<ApolloDriverConfig>({
      driver: ApolloDriver,
    }),
  ],
})
export class AppModule {}
```

> **Hint** For `mercurius` integration, you should be using the `MercuriusDriver` and `MercuriusDriverConfig` instead. Both are exported from the `@nestjs/mercurius` package.

The `forRoot()` method takes an options object as an argument. These options are passed through to the underlying driver instance (read more about available settings here: [Apollo](https://www.apollographql.com/docs/apollo-server/v2/api/apollo-server.html#constructor-options-lt-ApolloServer-gt) and [Mercurius](https://github.com/mercurius-js/mercurius/blob/master/docs/api/options.md#plugin-options)). For example, if you want to disable the `playground` and turn off `debug` mode (for Apollo), pass the following options:

JS TS

```typescript

import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';
import { ApolloDriver, ApolloDriverConfig } from '@nestjs/apollo';

@Module({
  imports: [
    GraphQLModule.forRoot<ApolloDriverConfig>({
      driver: ApolloDriver,
      playground: false,
    }),
  ],
})
export class AppModule {}
```

In this case, these options will be forwarded to the `ApolloServer` constructor.

#### GraphQL playground[#](/graphql/quick-start#graphql-playground)

The playground is a graphical, interactive, in-browser GraphQL IDE, available by default on the same URL as the GraphQL server itself. To access the playground, you need a basic GraphQL server configured and running. To see it now, you can install and build the [working example here](https://github.com/nestjs/nest/tree/master/sample/23-graphql-code-first). Alternatively, if you're following along with these code samples, once you've completed the steps in the [Resolvers chapter](/v10/graphql/resolvers-map), you can access the playground.

With that in place, and with your application running in the background, you can then open your web browser and navigate to `http://localhost:3000/graphql` (host and port may vary depending on your configuration). You will then see the GraphQL playground, as shown below.

> **Note**`@nestjs/mercurius` integration does not ship with the built-in GraphQL Playground integration. Instead, you can use [GraphiQL](https://github.com/graphql/graphiql) (set `graphiql: true`).

#### Multiple endpoints[#](/graphql/quick-start#multiple-endpoints)

Another useful feature of the `@nestjs/graphql` module is the ability to serve multiple endpoints at once. This lets you decide which modules should be included in which endpoint. By default, `GraphQL` searches for resolvers throughout the whole app. To limit this scan to only a subset of modules, use the `include` property.

```typescript

GraphQLModule.forRoot({
  include: [CatsModule],
}),
```

> **Warning** If you use the `@apollo/server` with `@as-integrations/fastify` package with multiple GraphQL endpoints in a single application, make sure to enable the `disableHealthCheck` setting in the `GraphQLModule` configuration.

#### Code first[#](/graphql/quick-start#code-first)

In the **code first** approach, you use decorators and TypeScript classes to generate the corresponding GraphQL schema.

To use the code first approach, start by adding the `autoSchemaFile` property to the options object:

```typescript

GraphQLModule.forRoot<ApolloDriverConfig>({
  driver: ApolloDriver,
  autoSchemaFile: join(process.cwd(), 'src/schema.gql'),
}),
```

The `autoSchemaFile` property value is the path where your automatically generated schema will be created. Alternatively, the schema can be generated on-the-fly in memory. To enable this, set the `autoSchemaFile` property to `true`:

```typescript

GraphQLModule.forRoot<ApolloDriverConfig>({
  driver: ApolloDriver,
  autoSchemaFile: true,
}),
```

By default, the types in the generated schema will be in the order they are defined in the included modules. To sort the schema lexicographically, set the `sortSchema` property to `true`:

```typescript

GraphQLModule.forRoot<ApolloDriverConfig>({
  driver: ApolloDriver,
  autoSchemaFile: join(process.cwd(), 'src/schema.gql'),
  sortSchema: true,
}),
```

#### Example[#](/graphql/quick-start#example)

A fully working code first sample is available [here](https://github.com/nestjs/nest/tree/master/sample/23-graphql-code-first).

#### Schema first[#](/graphql/quick-start#schema-first)

To use the schema first approach, start by adding a `typePaths` property to the options object. The `typePaths` property indicates where the `GraphQLModule` should look for GraphQL SDL schema definition files you'll be writing. These files will be combined in memory; this allows you to split your schemas into several files and locate them near their resolvers.

```typescript

GraphQLModule.forRoot<ApolloDriverConfig>({
  driver: ApolloDriver,
  typePaths: ['./**/*.graphql'],
}),
```

You will typically also need to have TypeScript definitions (classes and interfaces) that correspond to the GraphQL SDL types. Creating the corresponding TypeScript definitions by hand is redundant and tedious. It leaves us without a single source of truth -- each change made within SDL forces us to adjust TypeScript definitions as well. To address this, the `@nestjs/graphql` package can **automatically generate** TypeScript definitions from the abstract syntax tree ([AST](https://en.wikipedia.org/wiki/Abstract_syntax_tree)). To enable this feature, add the `definitions` options property when configuring the `GraphQLModule`.

```typescript

GraphQLModule.forRoot<ApolloDriverConfig>({
  driver: ApolloDriver,
  typePaths: ['./**/*.graphql'],
  definitions: {
    path: join(process.cwd(), 'src/graphql.ts'),
  },
}),
```

The path property of the `definitions` object indicates where to save generated TypeScript output. By default, all generated TypeScript types are created as interfaces. To generate classes instead, specify the `outputAs` property with a value of `'class'`.

```typescript

GraphQLModule.forRoot<ApolloDriverConfig>({
  driver: ApolloDriver,
  typePaths: ['./**/*.graphql'],
  definitions: {
    path: join(process.cwd(), 'src/graphql.ts'),
    outputAs: 'class',
  },
}),
```

The above approach dynamically generates TypeScript definitions each time the application starts. Alternatively, it may be preferable to build a simple script to generate these on demand. For example, assume we create the following script as `generate-typings.ts`:

```typescript

import { GraphQLDefinitionsFactory } from '@nestjs/graphql';
import { join } from 'path';

const definitionsFactory = new GraphQLDefinitionsFactory();
definitionsFactory.generate({
  typePaths: ['./src/**/*.graphql'],
  path: join(process.cwd(), 'src/graphql.ts'),
  outputAs: 'class',
});
```

Now you can run this script on demand:

```bash

$ ts-node generate-typings
```

> **Hint** You can compile the script beforehand (e.g., with `tsc`) and use `node` to execute it.

To enable watch mode for the script (to automatically generate typings whenever any `.graphql` file changes), pass the `watch` option to the `generate()` method.

```typescript

definitionsFactory.generate({
  typePaths: ['./src/**/*.graphql'],
  path: join(process.cwd(), 'src/graphql.ts'),
  outputAs: 'class',
  watch: true,
});
```

To automatically generate the additional `__typename` field for every object type, enable the `emitTypenameField` option.

```typescript

definitionsFactory.generate({
  // ...,
  emitTypenameField: true,
});
```

To generate resolvers (queries, mutations, subscriptions) as plain fields without arguments, enable the `skipResolverArgs` option.

```typescript

definitionsFactory.generate({
  // ...,
  skipResolverArgs: true,
});
```

#### Apollo Sandbox[#](/graphql/quick-start#apollo-sandbox)

To use [Apollo Sandbox](https://www.apollographql.com/blog/announcement/platform/apollo-sandbox-an-open-graphql-ide-for-local-development/) instead of the `graphql-playground` as a GraphQL IDE for local development, use the following configuration:

```typescript

import { ApolloDriver, ApolloDriverConfig } from '@nestjs/apollo';
import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';
import { ApolloServerPluginLandingPageLocalDefault } from '@apollo/server/plugin/landingPage/default';

@Module({
  imports: [
    GraphQLModule.forRoot<ApolloDriverConfig>({
      driver: ApolloDriver,
      playground: false,
      plugins: [ApolloServerPluginLandingPageLocalDefault()],
    }),
  ],
})
export class AppModule {}
```

#### Example[#](/graphql/quick-start#example-1)

A fully working schema first sample is available [here](https://github.com/nestjs/nest/tree/master/sample/12-graphql-schema-first).

#### Accessing generated schema[#](/graphql/quick-start#accessing-generated-schema)

In some circumstances (for example end-to-end tests), you may want to get a reference to the generated schema object. In end-to-end tests, you can then run queries using the `graphql` object without using any HTTP listeners.

You can access the generated schema (in either the code first or schema first approach), using the `GraphQLSchemaHost` class:

```typescript

const { schema } = app.get(GraphQLSchemaHost);
```

> **Hint** You must call the `GraphQLSchemaHost#schema` getter after the application has been initialized (after the `onModuleInit` hook has been triggered by either the `app.listen()` or `app.init()` method).

#### Async configuration[#](/graphql/quick-start#async-configuration)

When you need to pass module options asynchronously instead of statically, use the `forRootAsync()` method. As with most dynamic modules, Nest provides several techniques to deal with async configuration.

One technique is to use a factory function:

```typescript

 GraphQLModule.forRootAsync<ApolloDriverConfig>({
  driver: ApolloDriver,
  useFactory: () => ({
    typePaths: ['./**/*.graphql'],
  }),
}),
```

Like other factory providers, our factory function can be [async](https://docs.nestjs.com/fundamentals/custom-providers#factory-providers-usefactory) and can inject dependencies through `inject`.

```typescript

GraphQLModule.forRootAsync<ApolloDriverConfig>({
  driver: ApolloDriver,
  imports: [ConfigModule],
  useFactory: async (configService: ConfigService) => ({
    typePaths: configService.get<string>('GRAPHQL_TYPE_PATHS'),
  }),
  inject: [ConfigService],
}),
```

Alternatively, you can configure the `GraphQLModule` using a class instead of a factory, as shown below:

```typescript

GraphQLModule.forRootAsync<ApolloDriverConfig>({
  driver: ApolloDriver,
  useClass: GqlConfigService,
}),
```

The construction above instantiates `GqlConfigService` inside `GraphQLModule`, using it to create options object. Note that in this example, the `GqlConfigService` has to implement the `GqlOptionsFactory` interface, as shown below. The `GraphQLModule` will call the `createGqlOptions()` method on the instantiated object of the supplied class.

```typescript

@Injectable()
class GqlConfigService implements GqlOptionsFactory {
  createGqlOptions(): ApolloDriverConfig {
    return {
      typePaths: ['./**/*.graphql'],
    };
  }
}
```

If you want to reuse an existing options provider instead of creating a private copy inside the `GraphQLModule`, use the `useExisting` syntax.

```typescript

GraphQLModule.forRootAsync<ApolloDriverConfig>({
  imports: [ConfigModule],
  useExisting: ConfigService,
}),
```

#### Mercurius integration[#](/graphql/quick-start#mercurius-integration)

Instead of using Apollo, Fastify users (read more [here](/v10/techniques/performance)) can alternatively use the `@nestjs/mercurius` driver.

JS TS

```typescript

import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';
import { MercuriusDriver, MercuriusDriverConfig } from '@nestjs/mercurius';

@Module({
  imports: [
    GraphQLModule.forRoot<MercuriusDriverConfig>({
      driver: MercuriusDriver,
      graphiql: true,
    }),
  ],
})
export class AppModule {}
```

> **Hint** Once the application is running, open your browser and navigate to `http://localhost:3000/graphiql`. You should see the [GraphQL IDE](https://github.com/graphql/graphiql).

The `forRoot()` method takes an options object as an argument. These options are passed through to the underlying driver instance. Read more about available settings [here](https://github.com/mercurius-js/mercurius/blob/master/docs/api/options.md#plugin-options).

#### Third-party integrations[#](/graphql/quick-start#third-party-integrations)

* [GraphQL Yoga](https://github.com/dotansimha/graphql-yoga)

#### Example[#](/graphql/quick-start#example-2)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/33-graphql-mercurius).

----
url: https://docs.nestjs.com/v8/recipes/hot-reload
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Hot Reload](https://docs.nestjs.com/v8/recipes/hot-reload#hot-reload)
* [With CLI](https://docs.nestjs.com/v8/recipes/hot-reload#with-cli)
* [Installation](https://docs.nestjs.com/v8/recipes/hot-reload#installation)
* [Configuration](https://docs.nestjs.com/v8/recipes/hot-reload#configuration)
* [Hot-Module Replacement](https://docs.nestjs.com/v8/recipes/hot-reload#hot-module-replacement)
* [Without CLI](https://docs.nestjs.com/v8/recipes/hot-reload#without-cli)
* [Installation](https://docs.nestjs.com/v8/recipes/hot-reload#installation-1)
* [Configuration](https://docs.nestjs.com/v8/recipes/hot-reload#configuration-1)
* [Hot-Module Replacement](https://docs.nestjs.com/v8/recipes/hot-reload#hot-module-replacement-1)
* [Example](https://docs.nestjs.com/v8/recipes/hot-reload#example)
* [TypeORM](https://docs.nestjs.com/v8/recipes/hot-reload#typeorm)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/recipes/hot-reload.md "Suggest Edits")

### Hot Reload

The highest impact on your application's bootstrapping process is **TypeScript compilation**. Fortunately, with [webpack](https://github.com/webpack/webpack) HMR (Hot-Module Replacement), we don't need to recompile the entire project each time a change occurs. This significantly decreases the amount of time necessary to instantiate your application, and makes iterative development a lot easier.

> **Warning** Note that `webpack` won't automatically copy your assets (e.g. `graphql` files) to the `dist` folder. Similarly, `webpack` is not compatible with glob static paths (e.g., the `entities` property in `TypeOrmModule`).

### With CLI

If you are using the [Nest CLI](https://docs.nestjs.com/cli/overview), the configuration process is pretty straightforward. The CLI wraps `webpack`, which allows use of the `HotModuleReplacementPlugin`.

#### Installation[#](/recipes/hot-reload#installation)

First install the required packages:

```bash

$ npm i --save-dev webpack-node-externals run-script-webpack-plugin webpack
```

> **Hint** If you use **Yarn Berry** (not classic Yarn), install the `webpack-pnp-externals` package instead of the `webpack-node-externals`.

#### Configuration[#](/recipes/hot-reload#configuration)

Once the installation is complete, create a `webpack-hmr.config.js` file in the root directory of your application.

```typescript

const nodeExternals = require('webpack-node-externals');
const { RunScriptWebpackPlugin } = require('run-script-webpack-plugin');

module.exports = function (options, webpack) {
  return {
    ...options,
    entry: ['webpack/hot/poll?100', options.entry],
    externals: [
      nodeExternals({
        allowlist: ['webpack/hot/poll?100'],
      }),
    ],
    plugins: [
      ...options.plugins,
      new webpack.HotModuleReplacementPlugin(),
      new webpack.WatchIgnorePlugin({
        paths: [/\.js$/, /\.d\.ts$/],
      }),
      new RunScriptWebpackPlugin({ name: options.output.filename }),
    ],
  };
};
```

> **Hint** With **Yarn Berry** (not classic Yarn), instead of using the `nodeExternals` in the `externals` configuration property, use the `WebpackPnpExternals` from `webpack-pnp-externals` package: `WebpackPnpExternals({ exclude: ['webpack/hot/poll?100'] })`.

This function takes the original object containing the default webpack configuration as a first argument, and the reference to the underlying `webpack` package used by the Nest CLI as the second one. Also, it returns a modified webpack configuration with the `HotModuleReplacementPlugin`, `WatchIgnorePlugin`, and `RunScriptWebpackPlugin` plugins.

#### Hot-Module Replacement[#](/recipes/hot-reload#hot-module-replacement)

To enable **HMR**, open the application entry file (`main.ts`) and add the following webpack-related instructions:

```typescript

declare const module: any;

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  await app.listen(3000);

  if (module.hot) {
    module.hot.accept();
    module.hot.dispose(() => app.close());
  }
}
bootstrap();
```

To simplify the execution process, add a script to your `package.json` file.

```json

"start:dev": "nest build --webpack --webpackPath webpack-hmr.config.js --watch"
```

Now simply open your command line and run the following command:

```bash

$ npm run start:dev
```

### Without CLI

If you are not using the [Nest CLI](https://docs.nestjs.com/cli/overview), the configuration will be slightly more complex (will require more manual steps).

#### Installation[#](/recipes/hot-reload#installation-1)

First install the required packages:

```bash

$ npm i --save-dev webpack webpack-cli webpack-node-externals ts-loader run-script-webpack-plugin
```

> **Hint** If you use **Yarn Berry** (not classic Yarn), install the `webpack-pnp-externals` package instead of the `webpack-node-externals`.

#### Configuration[#](/recipes/hot-reload#configuration-1)

Once the installation is complete, create a `webpack.config.js` file in the root directory of your application.

```typescript

const webpack = require('webpack');
const path = require('path');
const nodeExternals = require('webpack-node-externals');
const { RunScriptWebpackPlugin } = require('run-script-webpack-plugin');

module.exports = {
  entry: ['webpack/hot/poll?100', './src/main.ts'],
  target: 'node',
  externals: [
    nodeExternals({
      allowlist: ['webpack/hot/poll?100'],
    }),
  ],
  module: {
    rules: [
      {
        test: /.tsx?$/,
        use: 'ts-loader',
        exclude: /node_modules/,
      },
    ],
  },
  mode: 'development',
  resolve: {
    extensions: ['.tsx', '.ts', '.js'],
  },
  plugins: [
    new webpack.HotModuleReplacementPlugin(),
    new RunScriptWebpackPlugin({ name: 'server.js' }),
  ],
  output: {
    path: path.join(__dirname, 'dist'),
    filename: 'server.js',
  },
};
```

> **Hint** With **Yarn Berry** (not classic Yarn), instead of using the `nodeExternals` in the `externals` configuration property, use the `WebpackPnpExternals` from `webpack-pnp-externals` package: `WebpackPnpExternals({ exclude: ['webpack/hot/poll?100'] })`.

This configuration tells webpack a few essential things about your application: location of the entry file, which directory should be used to hold **compiled** files, and what kind of loader we want to use to compile source files. Generally, you should be able to use this file as-is, even if you don't fully understand all of the options.

#### Hot-Module Replacement[#](/recipes/hot-reload#hot-module-replacement-1)

To enable **HMR**, open the application entry file (`main.ts`) and add the following webpack-related instructions:

```typescript

declare const module: any;

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  await app.listen(3000);

  if (module.hot) {
    module.hot.accept();
    module.hot.dispose(() => app.close());
  }
}
bootstrap();
```

To simplify the execution process, add a script to your `package.json` file.

```json

"start:dev": "webpack --config webpack.config.js --watch"
```

Now simply open your command line and run the following command:

```bash

$ npm run start:dev
```

#### Example[#](/recipes/hot-reload#example)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/08-webpack).

#### TypeORM[#](/recipes/hot-reload#typeorm)

If you're using `@nestjs/typeorm`, you'll need to add `keepConnectionAlive: true` to your TypeORM configuration.

----
url: https://docs.nestjs.com/v6/recipes/serve-static
----

* [Serve Static](https://docs.nestjs.com/v6/recipes/serve-static#serve-static)
* [Installation](https://docs.nestjs.com/v6/recipes/serve-static#installation)
* [Bootstrap](https://docs.nestjs.com/v6/recipes/serve-static#bootstrap)
* [Summary](https://docs.nestjs.com/v6/recipes/serve-static#summary)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/recipes/serve-static.md "Suggest Edits")

### Serve Static

In order to serve static content like a Single Page Application (SPA) we can use the `ServeStaticModule` from the `@nestjs/serve-static` package.

#### Installation[#](/recipes/serve-static#installation)

First we need to install the required package:

```bash

$ npm install --save @nestjs/serve-static
```

#### Bootstrap[#](/recipes/serve-static#bootstrap)

Once the installation process is done, we can import the `ServeStaticModule` into the root `AppModule` and configure it by passing in a configuration object to the `forRoot()` method.

```typescript

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { ServeStaticModule } from '@nestjs/serve-static';
import { join } from 'path';

@Module({
  imports: [
    ServeStaticModule.forRoot({
      rootPath: join(__dirname, '..', 'client'),
    }),
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}
```

With this in place, build the static website and place its content in the location specified by the `rootPath` property.

#### Summary[#](/recipes/serve-static#summary)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/24-serve-static).

----
url: https://docs.nestjs.com/observability/error-monitoring
----

[Skip to content](#content)

On this page

* [Error monitoring](https://docs.nestjs.com/observability/error-monitoring#error-monitoring)
* [What is captured](https://docs.nestjs.com/observability/error-monitoring#what-is-captured)
* [Source context](https://docs.nestjs.com/observability/error-monitoring#source-context)
* [Handled errors](https://docs.nestjs.com/observability/error-monitoring#handled-errors)
* [Grouping errors into defects](https://docs.nestjs.com/observability/error-monitoring#grouping-errors-into-defects)
* [Getting notified](https://docs.nestjs.com/observability/error-monitoring#getting-notified)
* [From an error to a fix](https://docs.nestjs.com/observability/error-monitoring#from-an-error-to-a-fix)

### Error monitoring

Error monitoring is included in every [NestJS Observe](https://www.observe.nestjs.com/ "NestJS Observe") plan, Free included, and needs nothing beyond the [SDK](/observability/sdk). Once your application is instrumented, every error that escapes a controller, resolver, or queue consumer is captured with the request it broke, the code that threw it, and the trace it ran in. This page covers what gets captured, how occurrences are grouped into defects, how you get told about a new one, and how an error turns into a verified fix.

> **Hint** To see it before installing anything, open the [live demo](https://www.observe-demo.nestjs.com/dashboard "NestJS Observe live demo"). It shows a busy service's errors, grouped defects, and stack traces with source, with no signup.

#### What is captured[#](/observability/error-monitoring#what-is-captured)

Errors that propagate out of a controller, resolver, job, or span are recorded automatically, across HTTP, GraphQL, gRPC, and `@nestjs/microservices` transports, and for queue consumers and cron runs. There is no error handler to register and nothing to call from your [exception filters](/exception-filters). A filter still decides what the client sees, and the SDK observes the failure on its way there, so the two work side by side.

An error is not stored as a detached log line. An individual error *is* the failed request, so its detail page is the request's own page with the failure leading: error class, message, stack trace, and source code first, then the request's context, then the trace waterfall and the logs written during that request. When an HTTP request fails, the SDK also records a small allow-list of its headers, and optionally its body (see [Capturing failed and slow requests](/observability/sdk#capturing-failed-and-slow-requests)). A job run that throws is recorded as a failed run, with its failure reason and attempt number, in the **Jobs** view.

Not every error is a bug. An exception your code throws on purpose, such as a `NotFoundException` or a failed validation, still shows up in the **Errors** view, since it is still a failed request, but it doesn't count as a new defect for alerting. Only unhandled failures do: an error whose request answered with a 5xx, or one that failed on an entry point with no HTTP status at all, such as an RPC handler or a gateway message.

#### Source context[#](/observability/error-monitoring#source-context)

A stack trace from production usually points at compiled output you don't have checked out. With `sourceContext` enabled (the default), the SDK reads the source lines around each in-app frame of a captured error and sends them with it, so the dashboard shows the failing code next to the stack trace:

app.module.ts

JS TS

```typescript

export const { ObserveModule, ObserveInstrument } = createObserveModule({
  sourceContext: {
    linesOfContext: 5,
    maxFrames: 5,
  },
});
```

To see your TypeScript rather than the compiled JavaScript, run Node with source map support (`--enable-source-maps`, or `process.setSourceMapsEnabled(true)`), or set `sourceContext.sourceMaps: true` to have the SDK resolve compiled frames itself. Frames inside `node_modules` and Node internals are never read. See [Error source context](/observability/sdk#error-source-context) for every option.

> **Warning** Source context ships a few lines of your application's source code to your dashboard, stored alongside the error. Set `sourceContext: false` if shipping any source is not acceptable for your codebase.

#### Handled errors[#](/observability/error-monitoring#handled-errors)

An error you catch and recover from never propagates, so it is never captured automatically. When you still want it visible, report it with `captureError()` on `TracerService`:

```typescript

try {
  await this.billing.sync(accountId);
} catch (error) {
  await this.tracerService.captureError(error as Error, {
    accountId,
    retryable: 'true',
  });
}
```

The error is attached to the current trace with the optional tags recorded alongside it, and gets the same source context as any other captured error. See [Capturing handled errors](/observability/manual-instrumentation#capturing-handled-errors).

#### Grouping errors into defects[#](/observability/error-monitoring#grouping-errors-into-defects)

A spike of 3,140 `TypeError`s is one bug, not 3,140. The **Group into defects** switch on the Errors page collapses occurrences with the same exception class and the same normalized stack shape into one **error group**, fingerprinted server-side, regardless of how the message was worded, which line numbers moved, or which deploy produced it.

A group carries what triage needs, rather than the details of a single occurrence:

| Field                    | What it tells you                                                       |
| ------------------------ | ----------------------------------------------------------------------- |
| Class and sample message | What the defect is, taken from its first occurrence                     |
| Status                   | Open, Resolved, or Ignored                                              |
| First and last seen      | Whether it's new, ongoing, or has gone away                             |
| Introduced in            | The release the first occurrence ran on, when it reported one           |
| Occurrences              | How often it fired in the selected window, not all time                 |
| Issue                    | The [issue](/observability/dashboard#issues) it was promoted to, if any |

**Introduced in** comes from the `serviceVersion` your application reports (a semantic version or a commit hash, passed to [`forRoot()`](/observability/sdk)). Without it, a group can't tell which deploy it arrived with.

The two closed states are deliberately asymmetric. **Resolved** is a claim about the code, so a resolved group reopens as soon as the error recurs; a fix that didn't hold surfaces instead of staying quietly green. **Ignored** is a decision about noise, and stays ignored.

#### Getting notified[#](/observability/error-monitoring#getting-notified)

Every plan, Free included, gets a built-in **new-error email** with no rule to set up: one email per project listing the errors it has never seen before, at most six a day. Each member can switch it off for themselves under **Settings → New error emails**.

On paid plans, [alert rules](/observability/dashboard#alerts) go further:

* A **new error groups** rule fires when a defect appears for the first time, for one application or the whole project. It notifies through email, Slack, a webhook, or an in-app notification, or by opening an issue.
* An **error rate** rule watches the share of failed requests for an application, or for one route and method, against a fixed threshold or against its own recent baseline with anomaly detection.
* A **job failure rate** rule does the same for queue consumers and cron runs.

On the higher tiers, an availability [SLO](/observability/dashboard#slos) (the share of requests that finished without an unhandled error) turns the same errors into an error budget with burn-rate alerts.

#### From an error to a fix[#](/observability/error-monitoring#from-an-error-to-a-fix)

Because each error already carries its stack trace, source lines, trace, and logs, **Copy agent prompt** on its page packages all of it into a self-contained prompt for a coding agent such as Claude Code, Cursor, or any other tool that has your repository open. An agent connected to the [MCP server](/observability/mcp-server) can go further on its own: list error groups with their introducing release, pull recent occurrences with their trace ids, tell whether an error is growing or decaying, and see which users it affected.

To track the work, promote an error group into an [issue](/observability/dashboard#issues) in one click; promoting a group that already has an open issue links to it instead of opening a second one. When you mark the issue resolved (optionally naming the release the fix shipped in), the dashboard watches the affected operation against its pre-incident baseline, and either closes the issue once the fix has held or reopens it with the reading that broke it.

After a deploy, the **Releases** view compares each `serviceVersion` against the one before it, error rate included, so a regression shows up as a difference between two versions rather than as a bump somewhere in a week-long chart.

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/observability/error-monitoring.md)

----
url: https://docs.nestjs.com/v11/observability/mcp-server
----

* [MCP server](https://docs.nestjs.com/v11/observability/mcp-server#mcp-server)
* [Getting a token](https://docs.nestjs.com/v11/observability/mcp-server#getting-a-token)
* [Connecting a client](https://docs.nestjs.com/v11/observability/mcp-server#connecting-a-client)
* [An example investigation](https://docs.nestjs.com/v11/observability/mcp-server#an-example-investigation)
* [Available tools](https://docs.nestjs.com/v11/observability/mcp-server#available-tools)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/observability/mcp-server.md "Suggest Edits")

### MCP server

NestJS Observe exposes a read-only [MCP](https://modelcontextprotocol.io/) server, so an MCP-compatible client - Claude Code, Claude Desktop, Cursor, VS Code, or an agent you wrote yourself - can ask questions about your projects directly instead of you copying dashboard data into a prompt. Regressions, slow operations, error groups, traces, jobs, alerts: the same data the dashboard shows, scoped to exactly what you can see.

> **Hint** MCP is one of two ways to get telemetry to an agent. The **Copy agent prompt** button (see [Dashboard](/observability/dashboard#handing-a-failure-to-a-coding-agent)) packages one page as text for a single paste; MCP is for an agent that needs to keep asking - follow a trace, check whether the error is still firing - without you relaying each answer.

The endpoint speaks Streamable HTTP at `POST https://<api-host>/mcp`. It's stateless - there's no session to open, nothing to keep alive, and no setup beyond the request itself. The exact host is shown next to your tokens in the dashboard.

#### Getting a token[#](/observability/mcp-server#getting-a-token)

Personal MCP tokens are minted in the dashboard under **MCP tokens**.

* Click **Create token**, give it a name, and optionally set an expiry. A token with no expiry never expires - MCP clients have no refresh flow.
* The secret (`omcp_...`) is shown **once**, in the response to creating it. Copy it immediately; only its hash is stored, so it cannot be retrieved again. Lost it? Revoke the token and mint another.
* Tokens act **as the user who created them**, with their exact project permissions. There is nothing to scope: if you can see it in the dashboard, the token can read it over MCP - and if you can't, neither can the token.

Revoking a token from the same page cuts it off immediately. Token management itself is dashboard-only, on purpose: an MCP token cannot mint or revoke MCP tokens, so a leaked credential can't extend its own life.

#### Connecting a client[#](/observability/mcp-server#connecting-a-client)

Any client that speaks Streamable HTTP can connect: there's one URL and one header, and no OAuth dance. What differs between clients is only where the config file lives and what its keys are called.

**Claude Code**

```bash

$ claude mcp add observe --transport http https://<api-host>/mcp --header "Authorization: Bearer <token>"
```

**Claude Desktop, and other `mcpServers` clients**

```json

{
  "mcpServers": {
    "observe": {
      "url": "https://<api-host>/mcp",
      "headers": { "Authorization": "Bearer <token>" }
    }
  }
}
```

**Cursor** uses the same `mcpServers` shape in `~/.cursor/mcp.json` (every project) or `.cursor/mcp.json` (one project), and expands `${env:...}` inside `url` and `headers`, which is how you keep the token out of a file you might commit:

```json

{
  "mcpServers": {
    "observe": {
      "url": "https://<api-host>/mcp",
      "headers": { "Authorization": "Bearer ${env:OBSERVE_MCP_TOKEN}" }
    }
  }
}
```

**VS Code (Copilot agent mode)** uses `servers` rather than `mcpServers`, wants an explicit `type`, and can prompt for the token once and store it encrypted. In `.vscode/mcp.json` for one workspace, or your user `mcp.json` for all of them:

```json

{
  "inputs": [
    {
      "type": "promptString",
      "id": "observe-token",
      "description": "NestJS Observe MCP token",
      "password": true
    }
  ],
  "servers": {
    "observe": {
      "type": "http",
      "url": "https://<api-host>/mcp",
      "headers": { "Authorization": "Bearer ${input:observe-token}" }
    }
  }
}
```

**Your own agent.** With the official TypeScript SDK, the endpoint is a `StreamableHTTPClientTransport` and the token rides in `requestInit.headers`:

```typescript

const client = new Client({ name: 'my-agent', version: '1.0.0' });

await client.connect(
  new StreamableHTTPClientTransport(new URL('https://<api-host>/mcp'), {
    requestInit: {
      headers: { Authorization: `Bearer ${process.env.OBSERVE_MCP_TOKEN}` },
    },
  }),
);

const { tools } = await client.listTools();
```

Before debugging a client's config, confirm the endpoint and token work at all - this lists the tools the server would advertise:

```bash

$ curl -s https://<api-host>/mcp \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
```

A tool list back means the credential is good and anything still broken is client-side. A **401** means the token is missing, expired, revoked, or the header is malformed; a **405** means the client sent `GET` or `DELETE` - every MCP request to this endpoint is a `POST`.

#### An example investigation[#](/observability/mcp-server#an-example-investigation)

The tools are shaped around investigations rather than endpoints, so each answer carries the key the next question needs. A deploy went out and something feels wrong:

1. **"What regressed after the last deploy?"** - `find_regressions` compares error rate and latency either side of each release boundary (your `serviceVersion` values) and names the release that made things worse, along with the operations it degraded.
2. **"Show me that operation."** - `get_operation_details` returns the route's latency and error summary plus recent individual requests, each with a `traceId`.
3. **"What did that request actually do?"** - `get_trace` resolves the trace id into the waterfall: every execution under it, across services, with span trees.
4. **"What did the code say while it happened?"** - `get_trace_logs` returns every log line emitted under the same trace id, in order.

Errors and background jobs follow the same shape: `list_error_groups` → `get_error_details` → `get_trace`, and `list_jobs` → `get_job_details` → `get_trace`. Start with `list_projects` in any case - almost every diagnostic tool takes a `projectId`.

#### Available tools[#](/observability/mcp-server#available-tools)

Every tool is read-only. Most diagnostic tools share a scope: a required `projectId`, an optional `applicationId` to narrow to one service, and an optional `timeInterval` look-back window (`1h`, `3h`, `12h`, `1d`, `3d`, `7d`, `30d`), defaulting to `1d`.

| Tool                                    | What it answers                                                                                                                                      |
| --------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| `list_projects`                         | Every project you're a member of, with team and application counts. Start here to resolve project ids.                                               |
| `get_project`                           | One project by id, including your access level and subscription state.                                                                               |
| `search`                                | Full-text search over your projects, applications, alert rules, SLOs, and issues.                                                                    |
| `find_regressions`                      | Releases that made things worse: error rate and latency before vs. after each release boundary, with the specific operations each one degraded.      |
| `list_slow_operations`                  | The slowest HTTP operations in the window, p95-ranked, with volume alongside - so effort goes to what's slow *and* hot.                              |
| `get_operation_details`                 | One route: latency and error summary plus recent individual requests, each with duration, status, and `traceId`.                                     |
| `get_trace`                             | A `traceId` resolved to every execution that ran under it - across services, requests, and jobs - each with its span tree.                           |
| `get_trace_logs`                        | Every log line emitted under a `traceId`, in order.                                                                                                  |
| `list_error_groups`                     | Errors grouped by fingerprint, ranked by occurrence count, with class, sample message and stack trace, first/last seen, and the introducing release. |
| `get_error_details`                     | Recent occurrences of one error class: per-occurrence message, status, user, and `traceId`, plus a summary.                                          |
| `get_error_trend`                       | Whether errors are growing or decaying over the window, already classified as a direction.                                                           |
| `get_affected_users`                    | The blast radius of one error class: which end users hit it and how often.                                                                           |
| `list_jobs`                             | Background job performance in the window, per job name and queue: volume, duration, and failure counts.                                              |
| `get_job_details`                       | One job name on one queue: duration and wait-time summaries plus recent individual executions, each with status and `traceId`.                       |
| `list_issues`, `get_issue`              | Issues across your projects, and one issue with its comments and activity.                                                                           |
| `list_slos`                             | A project's SLOs with current status and error-budget burn.                                                                                          |
| `list_alert_rules`, `list_alert_events` | Alert rules across every project you can see, and their firing history.                                                                              |

There is currently no way to create, resolve, or modify anything through MCP - not issues, not alert rules, not error-group status. Those stay in the dashboard. Tool results also drop the time-bucketed chart series the dashboard endpoints return, because hundreds of bucket values cost context and say less than the summary derived from them.

----
url: https://docs.nestjs.com/v9/fundamentals/module-ref
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Module reference](https://docs.nestjs.com/v9/fundamentals/module-ref#module-reference)
* [Retrieving instances](https://docs.nestjs.com/v9/fundamentals/module-ref#retrieving-instances)
* [Resolving scoped providers](https://docs.nestjs.com/v9/fundamentals/module-ref#resolving-scoped-providers)
* [Registering REQUEST provider](https://docs.nestjs.com/v9/fundamentals/module-ref#registering-request-provider)
* [Getting current sub-tree](https://docs.nestjs.com/v9/fundamentals/module-ref#getting-current-sub-tree)
* [Instantiating custom classes dynamically](https://docs.nestjs.com/v9/fundamentals/module-ref#instantiating-custom-classes-dynamically)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/fundamentals/module-reference.md "Suggest Edits")

### Module reference

Nest provides the `ModuleRef` class to navigate the internal list of providers and obtain a reference to any provider using its injection token as a lookup key. The `ModuleRef` class also provides a way to dynamically instantiate both static and scoped providers. `ModuleRef` can be injected into a class in the normal way:

cats.service.ts

JS TS

```typescript

@Injectable()
export class CatsService {
  constructor(private moduleRef: ModuleRef) {}
}
```

```typescript

@Injectable()
@Dependencies(ModuleRef)
export class CatsService {
  constructor(moduleRef) {
    this.moduleRef = moduleRef;
  }
}
```

> **Hint** The `ModuleRef` class is imported from the `@nestjs/core` package.

#### Retrieving instances[#](/fundamentals/module-ref#retrieving-instances)

The `ModuleRef` instance (hereafter we'll refer to it as the **module reference**) has a `get()` method. This method retrieves a provider, controller, or injectable (e.g., guard, interceptor, etc.) that exists (has been instantiated) in the **current** module using its injection token/class name.

cats.service.ts

JS TS

```typescript

@Injectable()
export class CatsService implements OnModuleInit {
  private service: Service;
  constructor(private moduleRef: ModuleRef) {}

  onModuleInit() {
    this.service = this.moduleRef.get(Service);
  }
}
```

```typescript

@Injectable()
@Dependencies(ModuleRef)
export class CatsService {
  constructor(moduleRef) {
    this.moduleRef = moduleRef;
  }

  onModuleInit() {
    this.service = this.moduleRef.get(Service);
  }
}
```

> **Warning** You can't retrieve scoped providers (transient or request-scoped) with the `get()` method. Instead, use the technique described [below](https://docs.nestjs.com/fundamentals/module-ref#resolving-scoped-providers). Learn how to control scopes [here](/v9/fundamentals/injection-scopes).

To retrieve a provider from the global context (for example, if the provider has been injected in a different module), pass the `{ strict: false }` option as a second argument to `get()`.

```typescript

this.moduleRef.get(Service, { strict: false });
```

#### Resolving scoped providers[#](/fundamentals/module-ref#resolving-scoped-providers)

To dynamically resolve a scoped provider (transient or request-scoped), use the `resolve()` method, passing the provider's injection token as an argument.

cats.service.ts

JS TS

```typescript

@Injectable()
export class CatsService implements OnModuleInit {
  private transientService: TransientService;
  constructor(private moduleRef: ModuleRef) {}

  async onModuleInit() {
    this.transientService = await this.moduleRef.resolve(TransientService);
  }
}
```

```typescript

@Injectable()
@Dependencies(ModuleRef)
export class CatsService {
  constructor(moduleRef) {
    this.moduleRef = moduleRef;
  }

  async onModuleInit() {
    this.transientService = await this.moduleRef.resolve(TransientService);
  }
}
```

The `resolve()` method returns a unique instance of the provider, from its own **DI container sub-tree**. Each sub-tree has a unique **context identifier**. Thus, if you call this method more than once and compare instance references, you will see that they are not equal.

cats.service.ts

JS TS

```typescript

@Injectable()
export class CatsService implements OnModuleInit {
  constructor(private moduleRef: ModuleRef) {}

  async onModuleInit() {
    const transientServices = await Promise.all([
      this.moduleRef.resolve(TransientService),
      this.moduleRef.resolve(TransientService),
    ]);
    console.log(transientServices[0] === transientServices[1]); // false
  }
}
```

```typescript

@Injectable()
@Dependencies(ModuleRef)
export class CatsService {
  constructor(moduleRef) {
    this.moduleRef = moduleRef;
  }

  async onModuleInit() {
    const transientServices = await Promise.all([
      this.moduleRef.resolve(TransientService),
      this.moduleRef.resolve(TransientService),
    ]);
    console.log(transientServices[0] === transientServices[1]); // false
  }
}
```

To generate a single instance across multiple `resolve()` calls, and ensure they share the same generated DI container sub-tree, you can pass a context identifier to the `resolve()` method. Use the `ContextIdFactory` class to generate a context identifier. This class provides a `create()` method that returns an appropriate unique identifier.

cats.service.ts

JS TS

```typescript

@Injectable()
export class CatsService implements OnModuleInit {
  constructor(private moduleRef: ModuleRef) {}

  async onModuleInit() {
    const contextId = ContextIdFactory.create();
    const transientServices = await Promise.all([
      this.moduleRef.resolve(TransientService, contextId),
      this.moduleRef.resolve(TransientService, contextId),
    ]);
    console.log(transientServices[0] === transientServices[1]); // true
  }
}
```

```typescript

@Injectable()
@Dependencies(ModuleRef)
export class CatsService {
  constructor(moduleRef) {
    this.moduleRef = moduleRef;
  }

  async onModuleInit() {
    const contextId = ContextIdFactory.create();
    const transientServices = await Promise.all([
      this.moduleRef.resolve(TransientService, contextId),
      this.moduleRef.resolve(TransientService, contextId),
    ]);
    console.log(transientServices[0] === transientServices[1]); // true
  }
}
```

> **Hint** The `ContextIdFactory` class is imported from the `@nestjs/core` package.

#### Registering `REQUEST` provider[#](/fundamentals/module-ref#registering-request-provider)

Manually generated context identifiers (with `ContextIdFactory.create()`) represent DI sub-trees in which `REQUEST` provider is `undefined` as they are not instantiated and managed by the Nest dependency injection system.

To register a custom `REQUEST` object for a manually created DI sub-tree, use the `ModuleRef#registerRequestByContextId()` method, as follows:

```typescript

const contextId = ContextIdFactory.create();
this.moduleRef.registerRequestByContextId(/* YOUR_REQUEST_OBJECT */, contextId);
```

#### Getting current sub-tree[#](/fundamentals/module-ref#getting-current-sub-tree)

Occasionally, you may want to resolve an instance of a request-scoped provider within a **request context**. Let's say that `CatsService` is request-scoped and you want to resolve the `CatsRepository` instance which is also marked as a request-scoped provider. In order to share the same DI container sub-tree, you must obtain the current context identifier instead of generating a new one (e.g., with the `ContextIdFactory.create()` function, as shown above). To obtain the current context identifier, start by injecting the request object using `@Inject()` decorator.

cats.service.ts

JS TS

```typescript

@Injectable()
export class CatsService {
  constructor(
    @Inject(REQUEST) private request: Record<string, unknown>,
  ) {}
}
```

```typescript

@Injectable()
@Dependencies(REQUEST)
export class CatsService {
  constructor(request) {
    this.request = request;
  }
}
```

> **Hint** Learn more about the request provider [here](https://docs.nestjs.com/fundamentals/injection-scopes#request-provider).

Now, use the `getByRequest()` method of the `ContextIdFactory` class to create a context id based on the request object, and pass this to the `resolve()` call:

```typescript

const contextId = ContextIdFactory.getByRequest(this.request);
const catsRepository = await this.moduleRef.resolve(CatsRepository, contextId);
```

#### Instantiating custom classes dynamically[#](/fundamentals/module-ref#instantiating-custom-classes-dynamically)

To dynamically instantiate a class that **wasn't previously registered** as a **provider**, use the module reference's `create()` method.

cats.service.ts

JS TS

```typescript

@Injectable()
export class CatsService implements OnModuleInit {
  private catsFactory: CatsFactory;
  constructor(private moduleRef: ModuleRef) {}

  async onModuleInit() {
    this.catsFactory = await this.moduleRef.create(CatsFactory);
  }
}
```

```typescript

@Injectable()
@Dependencies(ModuleRef)
export class CatsService {
  constructor(moduleRef) {
    this.moduleRef = moduleRef;
  }

  async onModuleInit() {
    this.catsFactory = await this.moduleRef.create(CatsFactory);
  }
}
```

This technique enables you to conditionally instantiate different classes outside of the framework container.

## Hoodies, T-shirts, and accessories!

Support our future development by shopping in the official store!

[See more](https://nestjs.threadless.com/ "Shop | NestJS - A node.js framework built on top of TypeScript")

----
url: https://docs.nestjs.com/v8/techniques/http-module
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [HTTP module](https://docs.nestjs.com/v8/techniques/http-module#http-module)
* [Installation](https://docs.nestjs.com/v8/techniques/http-module#installation)
* [Getting started](https://docs.nestjs.com/v8/techniques/http-module#getting-started)
* [Configuration](https://docs.nestjs.com/v8/techniques/http-module#configuration)
* [Async configuration](https://docs.nestjs.com/v8/techniques/http-module#async-configuration)
* [Using Axios directly](https://docs.nestjs.com/v8/techniques/http-module#using-axios-directly)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/techniques/http-module.md "Suggest Edits")

### HTTP module

[Axios](https://github.com/axios/axios) is richly featured HTTP client package that is widely used. Nest wraps Axios and exposes it via the built-in `HttpModule`. The `HttpModule` exports the `HttpService` class, which exposes Axios-based methods to perform HTTP requests. The library also transforms the resulting HTTP responses into `Observables`.

> **Hint** You can also use any general purpose Node.js HTTP client library directly, including [got](https://github.com/sindresorhus/got) or [undici](https://github.com/nodejs/undici).

#### Installation[#](/techniques/http-module#installation)

To begin using it, we first install the required dependency.

```bash

$ npm i --save @nestjs/axios
```

#### Getting started[#](/techniques/http-module#getting-started)

Once the installation process is complete, to use the `HttpService`, first import `HttpModule`.

```typescript

@Module({
  imports: [HttpModule],
  providers: [CatsService],
})
export class CatsModule {}
```

Next, inject `HttpService` using normal constructor injection.

> **Hint**`HttpModule` and `HttpService` are imported from `@nestjs/axios` package.

JS TS

```typescript

@Injectable()
export class CatsService {
  constructor(private readonly httpService: HttpService) {}

  findAll(): Observable<AxiosResponse<Cat[]>> {
    return this.httpService.get('http://localhost:3000/cats');
  }
}
```

```typescript

@Injectable()
@Dependencies(HttpService)
export class CatsService {
  constructor(httpService) {
    this.httpService = httpService;
  }

  findAll() {
    return this.httpService.get('http://localhost:3000/cats');
  }
}
```

> **Hint**`AxiosResponse` is an interface exported from the `axios` package (`$ npm i axios`).

All `HttpService` methods return an `AxiosResponse` wrapped in an `Observable` object.

#### Configuration[#](/techniques/http-module#configuration)

[Axios](https://github.com/axios/axios) can be configured with a variety of options to customize the behavior of the `HttpService`. Read more about them [here](https://github.com/axios/axios#request-config). To configure the underlying Axios instance, pass an optional options object to the `register()` method of `HttpModule` when importing it. This options object will be passed directly to the underlying Axios constructor.

```typescript

@Module({
  imports: [
    HttpModule.register({
      timeout: 5000,
      maxRedirects: 5,
    }),
  ],
  providers: [CatsService],
})
export class CatsModule {}
```

#### Async configuration[#](/techniques/http-module#async-configuration)

When you need to pass module options asynchronously instead of statically, use the `registerAsync()` method. As with most dynamic modules, Nest provides several techniques to deal with async configuration.

One technique is to use a factory function:

```typescript

HttpModule.registerAsync({
  useFactory: () => ({
    timeout: 5000,
    maxRedirects: 5,
  }),
});
```

Like other factory providers, our factory function can be [async](https://docs.nestjs.com/fundamentals/custom-providers#factory-providers-usefactory) and can inject dependencies through `inject`.

```typescript

HttpModule.registerAsync({
  imports: [ConfigModule],
  useFactory: async (configService: ConfigService) => ({
    timeout: configService.get('HTTP_TIMEOUT'),
    maxRedirects: configService.get('HTTP_MAX_REDIRECTS'),
  }),
  inject: [ConfigService],
});
```

Alternatively, you can configure the `HttpModule` using a class instead of a factory, as shown below.

```typescript

HttpModule.registerAsync({
  useClass: HttpConfigService,
});
```

The construction above instantiates `HttpConfigService` inside `HttpModule`, using it to create an options object. Note that in this example, the `HttpConfigService` has to implement `HttpModuleOptionsFactory` interface as shown below. The `HttpModule` will call the `createHttpOptions()` method on the instantiated object of the supplied class.

```typescript

@Injectable()
class HttpConfigService implements HttpModuleOptionsFactory {
  createHttpOptions(): HttpModuleOptions {
    return {
      timeout: 5000,
      maxRedirects: 5,
    };
  }
}
```

If you want to reuse an existing options provider instead of creating a private copy inside the `HttpModule`, use the `useExisting` syntax.

```typescript

HttpModule.registerAsync({
  imports: [ConfigModule],
  useExisting: HttpConfigService,
});
```

#### Using Axios directly[#](/techniques/http-module#using-axios-directly)

If you think that `HttpModule.register`'s options are not enough for you, or if you just want to access the underlying Axios instance created by `@nestjs/axios`, you can access it via `HttpService#axiosRef` as follows:

```typescript

@Injectable()
export class CatsService {
  constructor(private readonly httpService: HttpService) {}

  findAll(): Promise<AxiosResponse<Cat[]>> {
    return this.httpService.axiosRef.get('http://localhost:3000/cats');
    //                      ^ AxiosInstance interface
  }
}
```

----
url: https://docs.nestjs.com/v7/openapi/other-features
----

* [Other features](https://docs.nestjs.com/v7/openapi/other-features#other-features)
* [Global prefix](https://docs.nestjs.com/v7/openapi/other-features#global-prefix)
* [Multiple specifications](https://docs.nestjs.com/v7/openapi/other-features#multiple-specifications)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/openapi/other-features.md "Suggest Edits")

### Other features

#### Global prefix[#](/openapi/other-features#global-prefix)

To ignore a global prefix for routes set through `setGlobalPrefix()`, use `ignoreGlobalPrefix`:

```typescript

const document = SwaggerModule.createDocument(app, options, {
  ignoreGlobalPrefix: true,
});
```

#### Multiple specifications[#](/openapi/other-features#multiple-specifications)

The `SwaggerModule` provides a way to support multiple specifications. In other words, you can serve different documentation, with different UIs, on different endpoints.

To support multiple specifications, your application must be written with a modular approach. The `createDocument()` method takes a 3rd argument, `extraOptions`, which is an object with a property named `include`. The `include` property takes a value which is an array of modules.

You can setup multiple specifications support as shown below:

```typescript

import { NestFactory } from '@nestjs/core';
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
import { AppModule } from './app.module';
import { CatsModule } from './cats/cats.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);

  /**
   * createDocument(application, configurationOptions, extraOptions);
   *
   * createDocument method takes an optional 3rd argument "extraOptions"
   * which is an object with "include" property where you can pass an Array
   * of Modules that you want to include in that Swagger Specification
   * E.g: CatsModule and DogsModule will have two separate Swagger Specifications which
   * will be exposed on two different SwaggerUI with two different endpoints.
   */

  const options = new DocumentBuilder()
    .setTitle('Cats example')
    .setDescription('The cats API description')
    .setVersion('1.0')
    .addTag('cats')
    .build();

  const catDocument = SwaggerModule.createDocument(app, options, {
    include: [CatsModule],
  });
  SwaggerModule.setup('api/cats', app, catDocument);

  const secondOptions = new DocumentBuilder()
    .setTitle('Dogs example')
    .setDescription('The dogs API description')
    .setVersion('1.0')
    .addTag('dogs')
    .build();

  const dogDocument = SwaggerModule.createDocument(app, secondOptions, {
    include: [DogsModule],
  });
  SwaggerModule.setup('api/dogs', app, dogDocument);

  await app.listen(3000);
}
bootstrap();
```

Now you can start your server with the following command:

```bash

$ npm run start
```

Navigate to `http://localhost:3000/api/cats` to see the Swagger UI for cats:

In turn, `http://localhost:3000/api/dogs` will expose the Swagger UI for dogs:

----
url: https://docs.nestjs.com/graphql/resolvers
----

[Skip to content](#content)

On this page

* [Resolvers](https://docs.nestjs.com/graphql/resolvers#resolvers)
* [Code first](https://docs.nestjs.com/graphql/resolvers#code-first)
* [Object types](https://docs.nestjs.com/graphql/resolvers#object-types)
* [Code first resolver](https://docs.nestjs.com/graphql/resolvers#code-first-resolver)
* [Query type names](https://docs.nestjs.com/graphql/resolvers#query-type-names)
* [Query decorator options](https://docs.nestjs.com/graphql/resolvers#query-decorator-options)
* [Args decorator options](https://docs.nestjs.com/graphql/resolvers#args-decorator-options)
* [Dedicated arguments class](https://docs.nestjs.com/graphql/resolvers#dedicated-arguments-class)
* [Class inheritance](https://docs.nestjs.com/graphql/resolvers#class-inheritance)
* [Generics](https://docs.nestjs.com/graphql/resolvers#generics)
* [Schema first](https://docs.nestjs.com/graphql/resolvers#schema-first)
* [Schema first resolver](https://docs.nestjs.com/graphql/resolvers#schema-first-resolver)
* [Generating types](https://docs.nestjs.com/graphql/resolvers#generating-types)
* [GraphQL argument decorators](https://docs.nestjs.com/graphql/resolvers#graphql-argument-decorators)
* [Module](https://docs.nestjs.com/graphql/resolvers#module)

[](https://srv.carbonads.net/ads/click/x/GTND4277CVSD5KJUCAYLYKQUF67D62Q7CW7DTZ3JCAAI6KQJFT7ILKJKC6YDK53LF6AI527ICW7IL537F6ADK23JHEYI55QLCAYD653ECTNCYBZ52K)[Prove you can build it. Not just explain it. Earn a microcredential for free. ](https://srv.carbonads.net/ads/click/x/GTND4277CVSD5KJUCAYLYKQUF67D62Q7CW7DTZ3JCAAI6KQJFT7ILKJKC6YDK53LF6AI527ICW7IL537F6ADK23JHEYI55QLCAYD653ECTNCYBZ52K)[ads via Carbon](http://carbonads.net/?utm_source=nestjscom\&utm_medium=ad_via_link\&utm_campaign=in_unit\&utm_term=carbon)

### Resolvers

Resolvers provide the instructions for turning a [GraphQL](https://graphql.org/) operation (a query, mutation, or subscription) into data. They return data in the shape specified in the schema, either synchronously or as a promise that resolves to a result of that shape. Typically, you create a **resolver map** manually. The `@nestjs/graphql` package, on the other hand, generates the resolver map automatically from the metadata provided by the decorators you use to annotate classes. To demonstrate how to create a GraphQL API with the package, we'll build a simple authors API.

#### Code first[#](/graphql/resolvers#code-first)

In the code first approach, you don't write the GraphQL schema in SDL by hand. Instead, you use TypeScript decorators to generate the SDL from TypeScript class definitions. The `@nestjs/graphql` package reads the metadata defined through the decorators and generates the schema for you.

#### Object types[#](/graphql/resolvers#object-types)

Most of the definitions in a GraphQL schema are **object types**. Each object type you define should represent a domain object that an application client might need to interact with. For example, our sample API needs to fetch a list of authors and their posts, so we define an `Author` type and a `Post` type.

With the schema first approach, you would define the `Author` type in SDL like this:

```graphql

type Author {
  id: Int!
  firstName: String
  lastName: String
  posts: [Post!]!
}
```

With the code first approach, you define the schema with TypeScript classes and annotate their fields with TypeScript decorators. The equivalent of the above SDL in the code first approach is:

authors/models/author.model.ts

JS TS

```typescript

import { Field, Int, ObjectType } from '@nestjs/graphql';
import { Post } from '../../posts/models/post.model.js';

@ObjectType()
export class Author {
  @Field(type => Int)
  id: number;

  @Field({ nullable: true })
  firstName?: string;

  @Field({ nullable: true })
  lastName?: string;

  @Field(type => [Post])
  posts: Post[];
}
```

> **Hint** TypeScript's metadata reflection system has several limitations. For instance, it can't determine which properties a class consists of, or whether a given property is optional or required. Because of these limitations, you must either use the `@Field()` decorator in your schema definition classes to provide metadata about each field's GraphQL type and optionality, or use the [CLI plugin](/graphql/cli-plugin) to generate this metadata for you.

The `Author` object type, like any class, is made of a collection of fields, each declaring a type. A field's type corresponds to a [GraphQL type](https://graphql.org/learn/schema/), which can be either another object type or a scalar type. A GraphQL scalar type is a primitive (like `ID`, `String`, `Boolean`, or `Int`) that resolves to a single value.

> **Hint** In addition to GraphQL's built-in scalar types, you can define [custom scalar types](/graphql/scalars).

The `Author` object type definition above causes Nest to **generate** the SDL shown earlier:

```graphql

type Author {
  id: Int!
  firstName: String
  lastName: String
  posts: [Post!]!
}
```

The `@Field()` decorator accepts an optional type function (e.g., `type => Int`), and optionally an options object.

The type function is required when the mapping between the TypeScript type system and the GraphQL type system is ambiguous. Specifically, it is **not** required for `string` and `boolean` types, but it **is** required for `number`, which can map to either a GraphQL `Int` or `Float` (without a type function, `number` maps to `Float` by default). The type function returns the desired GraphQL type, as shown in the examples throughout these chapters.

The options object can have any of the following key/value pairs:

* `nullable`: whether the field is nullable (in `@nestjs/graphql`, each field is non-nullable by default); `boolean`
* `description`: the field description; `string`
* `deprecationReason`: marks the field as deprecated; `string`

For example:

```typescript

@Field({ description: `Book title`, deprecationReason: 'Not useful in v2 schema' })
title: string;
```

> **Hint** You can also add a description to, or deprecate, the whole object type: `@ObjectType({ description: 'Author model' })`. Likewise, if your application serves [multiple GraphQL endpoints](/graphql/quick-start#multiple-endpoints), you can scope a type to a specific module: `@ObjectType({ registerIn: () => AuthorsModule })`.

When the field is an array, you must indicate the array type in the `@Field()` decorator's type function, as shown below:

```typescript

@Field(type => [Post])
posts: Post[];
```

> **Hint** Array bracket notation (`[ ]`) indicates the depth of the array. For example, `[[Int]]` represents an integer matrix.

To declare that an array's items (not the array itself) are nullable, set the `nullable` property to `'items'` as shown below:

```typescript

@Field(type => [Post], { nullable: 'items' })
posts: Post[];
```

> **Hint** If both the array and its items are nullable, set `nullable` to `'itemsAndList'` instead.

With the `Author` object type in place, let's define the `Post` object type.

posts/models/post.model.ts

JS TS

```typescript

import { Field, Int, ObjectType } from '@nestjs/graphql';

@ObjectType()
export class Post {
  @Field(type => Int)
  id: number;

  @Field()
  title: string;

  @Field(type => Int, { nullable: true })
  votes?: number;
}
```

The `Post` object type generates the following part of the GraphQL schema in SDL:

```graphql

type Post {
  id: Int!
  title: String!
  votes: Int
}
```

#### Code first resolver[#](/graphql/resolvers#code-first-resolver)

At this point, we've defined the objects (type definitions) that can exist in our data graph, but clients don't yet have a way to interact with them. To address that, we need a resolver class. In the code first approach, a resolver class both defines resolver functions **and** generates the **Query type**. The example below shows how:

authors/authors.resolver.ts

JS TS

```typescript

@Resolver(() => Author)
export class AuthorsResolver {
  constructor(
    private authorsService: AuthorsService,
    private postsService: PostsService,
  ) {}

  @Query(() => Author)
  async author(@Args('id', { type: () => Int }) id: number) {
    return this.authorsService.findOneById(id);
  }

  @ResolveField()
  async posts(@Parent() author: Author) {
    const { id } = author;
    return this.postsService.findAll({ authorId: id });
  }
}
```

> **Hint** All decorators (e.g., `@Resolver`, `@ResolveField`, `@Args`, etc.) are exported from the `@nestjs/graphql` package.

You can define multiple resolver classes, and Nest combines them at run time. See the [Module](/graphql/resolvers#module) section below for more on code organization.

> **Note** The logic inside the `AuthorsService` and `PostsService` classes can be as simple or sophisticated as needed. The point of this example is to show how to construct resolvers and how they interact with other providers.

The `AuthorsResolver` above defines one query resolver function and one field resolver function. To create a resolver, create a class with resolver functions as methods, and annotate the class with the `@Resolver()` decorator.

The `author()` method is a query handler that returns the author object for the `id` sent in the request. To mark a method as a query handler, use the `@Query()` decorator.

The argument passed to the `@Resolver()` decorator is optional, but it comes into play once your graph becomes non-trivial: it supplies the parent object used by field resolver functions as they traverse down an object graph.

Because this class includes a **field resolver** function (for the `posts` property of the `Author` object type), you **must** pass the `@Resolver()` decorator a value that indicates the parent type (i.e., the corresponding `ObjectType` class) for all field resolvers defined within the class. A field resolver needs access to the parent object (the object that the field being resolved belongs to). Here, the field resolver populates an author's `posts` array by calling a service with the author's `id`, which is why the parent object must be identified in the `@Resolver()` decorator. The `@Parent()` method parameter decorator then extracts a reference to that parent object in the field resolver.

You can define multiple `@Query()` resolver functions (both within this class and in other resolver classes). They are aggregated into a single **Query type** definition in the generated SDL, along with the corresponding entries in the resolver map. This lets you define queries close to the models and services they use, and keep them well organized in modules.

> **Hint** The Nest CLI provides a generator (schematic) that generates **all the boilerplate code** for you. See the [CRUD generator](/recipes/crud-generator) recipe for details.

#### Query type names[#](/graphql/resolvers#query-type-names)

In the examples above, the `@Query()` decorator derives the GraphQL query name from the method name. For example, consider the following construction from the example above:

```typescript

@Query(() => Author)
async author(@Args('id', { type: () => Int }) id: number) {
  return this.authorsService.findOneById(id);
}
```

This generates the following entry for the author query in the schema (the query uses the same name as the method):

```graphql

type Query {
  author(id: Int!): Author!
}
```

> **Hint** Learn more about [GraphQL queries](https://graphql.org/learn/queries/).

Conventionally, these names are decoupled. For example, you might name the query handler method `getAuthor()` but still expose the query as `author`. The same applies to field resolvers. To do this, pass the mapping names as arguments to the `@Query()` and `@ResolveField()` decorators, as shown below:

authors/authors.resolver.ts

JS TS

```typescript

@Resolver(() => Author)
export class AuthorsResolver {
  constructor(
    private authorsService: AuthorsService,
    private postsService: PostsService,
  ) {}

  @Query(() => Author, { name: 'author' })
  async getAuthor(@Args('id', { type: () => Int }) id: number) {
    return this.authorsService.findOneById(id);
  }

  @ResolveField('posts', () => [Post])
  async getPosts(@Parent() author: Author) {
    const { id } = author;
    return this.postsService.findAll({ authorId: id });
  }
}
```

The `getAuthor()` handler method above generates the following part of the GraphQL schema in SDL:

```graphql

type Query {
  author(id: Int!): Author!
}
```

#### Query decorator options[#](/graphql/resolvers#query-decorator-options)

The `@Query()` decorator's options object (where we pass `{name: 'author'}` above) accepts a number of key/value pairs:

* `name`: name of the query; a `string`
* `description`: a description used to generate GraphQL schema documentation (e.g., in GraphiQL); a `string`
* `deprecationReason`: marks the query as deprecated in the schema metadata (e.g., shown in GraphiQL); a `string`
* `nullable`: whether the query can return a null data response; `boolean`, `'items'`, or `'itemsAndList'` (see above for details of `'items'` and `'itemsAndList'`)

#### Args decorator options[#](/graphql/resolvers#args-decorator-options)

Use the `@Args()` decorator to extract arguments from a request for use in the handler method. This works much like [REST route parameter extraction](/controllers#route-parameters).

Usually, the `@Args()` decorator doesn't need an options object. For example, if an identifier is a string, the following construction is sufficient: it plucks the named field from the inbound GraphQL request for use as a method argument.

```typescript

@Args('id') id: string
```

The `getAuthor()` method uses the `number` type, which presents a challenge: the TypeScript `number` type doesn't carry enough information about the expected GraphQL representation (e.g., `Int` vs. `Float`). You therefore have to pass the type reference **explicitly**, in an options object passed as the second argument to the `@Args()` decorator:

```typescript

@Query(() => Author, { name: 'author' })
async getAuthor(@Args('id', { type: () => Int }) id: number) {
  return this.authorsService.findOneById(id);
}
```

The options object accepts the following optional key/value pairs:

* `type`: a function returning the GraphQL type
* `defaultValue`: a default value; `any`
* `description`: description metadata; `string`
* `deprecationReason`: to deprecate a field and provide metadata describing why; `string`
* `nullable`: whether the field is nullable

Query handler methods can take multiple arguments. For example, to fetch an author by `firstName` and `lastName`, call `@Args()` twice:

```typescript

getAuthor(
  @Args('firstName', { nullable: true }) firstName?: string,
  @Args('lastName', { defaultValue: '' }) lastName?: string,
) {}
```

> **Hint** For a GraphQL nullable field like `firstName`, you don't need to add `null` or `undefined` to the field's TypeScript type. Be aware, however, that a nullable field lets these values through to your resolver, so you need to guard against them there.

#### Dedicated arguments class[#](/graphql/resolvers#dedicated-arguments-class)

With inline `@Args()` calls, code like the example above quickly becomes bloated. Instead, you can create a dedicated `GetAuthorArgs` arguments class and access it in the handler method as follows:

```typescript

@Args() args: GetAuthorArgs
```

Create the `GetAuthorArgs` class using `@ArgsType()` as shown below:

authors/dto/get-author.args.ts

JS TS

```typescript

import { MinLength } from 'class-validator';
import { Field, ArgsType } from '@nestjs/graphql';

@ArgsType()
export class GetAuthorArgs {
  @Field({ nullable: true })
  firstName?: string;

  @Field({ defaultValue: '' })
  @MinLength(3)
  lastName: string;
}
```

> **Hint** Again, due to the limitations of TypeScript's metadata reflection system, you must either use the `@Field()` decorator to indicate type and optionality, or use the [CLI plugin](/graphql/cli-plugin). As before, you don't need to add `null` or `undefined` to the type of the nullable `firstName` field, but you do need to guard against these values in your resolvers.

This generates the following part of the GraphQL schema in SDL:

```graphql

type Query {
  author(firstName: String, lastName: String! = ""): Author!
}
```

> **Hint** Argument classes like `GetAuthorArgs` work well with the `ValidationPipe` (see [Validation](/application/validation)).

#### Class inheritance[#](/graphql/resolvers#class-inheritance)

You can use standard TypeScript class inheritance to create extensible base classes with generic utility features (fields and field properties, validations, etc.). For example, you may have a set of pagination-related arguments that always include the standard `offset` and `limit` fields, plus other type-specific index fields. You can set up a class hierarchy as shown below.

Base `@ArgsType()` class:

```typescript

@ArgsType()
class PaginationArgs {
  @Field(() => Int)
  offset: number = 0;

  @Field(() => Int)
  limit: number = 10;
}
```

Type-specific subclass of the base `@ArgsType()` class:

```typescript

@ArgsType()
class GetAuthorArgs extends PaginationArgs {
  @Field({ nullable: true })
  firstName?: string;

  @Field({ defaultValue: '' })
  @MinLength(3)
  lastName: string;
}
```

The same approach can be taken with `@ObjectType()` objects. Define generic properties on the base class:

```typescript

@ObjectType()
class Character {
  @Field(() => Int)
  id: number;

  @Field()
  name: string;
}
```

Add type-specific properties on subclasses:

```typescript

@ObjectType()
class Warrior extends Character {
  @Field()
  level: number;
}
```

You can use inheritance with resolvers as well, and combine it with TypeScript generics to keep type safety. For example, to create a base class with a generic `findAll` query, use a construction like this:

```typescript

function BaseResolver<T extends Type<unknown>>(classRef: T): any {
  @Resolver({ isAbstract: true })
  abstract class BaseResolverHost {
    @Query(() => [classRef], { name: `findAll${classRef.name}` })
    async findAll(): Promise<T[]> {
      return [];
    }
  }
  return BaseResolverHost;
}
```

Note the following:

* An explicit return type (`any` above) is required; otherwise, TypeScript complains about the usage of a private class definition. We recommend defining an interface instead of using `any`.
* `Type` is imported from the `@nestjs/common` package.
* The `isAbstract: true` property indicates that SDL (Schema Definition Language statements) shouldn't be generated for this class. You can set this property on other types as well to suppress SDL generation.

Here's how you could create a concrete subclass of `BaseResolver`:

```typescript

@Resolver(() => Recipe)
export class RecipesResolver extends BaseResolver(Recipe) {
  constructor(private recipesService: RecipesService) {
    super();
  }
}
```

This construct would generate the following SDL:

```graphql

type Query {
  findAllRecipe: [Recipe!]!
}
```

#### Generics[#](/graphql/resolvers#generics)

We saw one use of generics above. Generics let you build reusable abstractions. For example, here's a cursor-based pagination implementation based on the [GraphQL pagination guide](https://graphql.org/learn/pagination/#pagination-and-edges):

```typescript

import { Field, ObjectType, Int } from '@nestjs/graphql';
import { Type } from '@nestjs/common';

interface IEdgeType<T> {
  cursor: string;
  node: T;
}

export interface IPaginatedType<T> {
  edges: IEdgeType<T>[];
  nodes: T[];
  totalCount: number;
  hasNextPage: boolean;
}

export function Paginated<T>(classRef: Type<T>): Type<IPaginatedType<T>> {
  @ObjectType(`${classRef.name}Edge`)
  abstract class EdgeType {
    @Field(() => String)
    cursor: string;

    @Field(() => classRef)
    node: T;
  }

  @ObjectType({ isAbstract: true })
  abstract class PaginatedType implements IPaginatedType<T> {
    @Field(() => [EdgeType], { nullable: true })
    edges: EdgeType[];

    @Field(() => [classRef], { nullable: true })
    nodes: T[];

    @Field(() => Int)
    totalCount: number;

    @Field()
    hasNextPage: boolean;
  }
  return PaginatedType as Type<IPaginatedType<T>>;
}
```

With this base class defined, you can create specialized types that inherit its behavior. For example:

```typescript

@ObjectType()
class PaginatedAuthor extends Paginated(Author) {}
```

#### Schema first[#](/graphql/resolvers#schema-first)

As mentioned in the [Quick start](/graphql/quick-start) chapter, in the schema first approach you start by manually defining schema types in SDL (see the [GraphQL type language](https://graphql.org/learn/schema/#type-language)). Consider the following SDL type definitions.

> **Hint** For convenience, this chapter keeps all of the SDL in one location (e.g., one `.graphql` file, as shown below). In practice, you may prefer a modular organization. For example, you can create individual SDL files with the type definitions for each domain entity, and keep them with the related services, resolver code, and Nest module class in a dedicated directory for that entity. Nest aggregates all the individual schema type definitions at run time.

```graphql

type Author {
  id: Int!
  firstName: String
  lastName: String
  posts: [Post]
}

type Post {
  id: Int!
  title: String!
  votes: Int
}

type Query {
  author(id: Int!): Author
}
```

#### Schema first resolver[#](/graphql/resolvers#schema-first-resolver)

The schema above exposes a single query: `author(id: Int!): Author`.

> **Hint** Learn more about [GraphQL queries](https://graphql.org/learn/queries/).

Now create an `AuthorsResolver` class that resolves author queries:

authors/authors.resolver.ts

JS TS

```typescript

@Resolver('Author')
export class AuthorsResolver {
  constructor(
    private authorsService: AuthorsService,
    private postsService: PostsService,
  ) {}

  @Query()
  async author(@Args('id') id: number) {
    return this.authorsService.findOneById(id);
  }

  @ResolveField()
  async posts(@Parent() author) {
    const { id } = author;
    return this.postsService.findAll({ authorId: id });
  }
}
```

> **Hint** All decorators (e.g., `@Resolver`, `@ResolveField`, `@Args`, etc.) are exported from the `@nestjs/graphql` package.

> **Note** The logic inside the `AuthorsService` and `PostsService` classes can be as simple or sophisticated as needed. The point of this example is to show how to construct resolvers and how they interact with other providers.

The `@Resolver()` decorator is required. It takes an optional string argument with the name of a type. This name is required whenever the class includes `@ResolveField()` decorators, to tell Nest which parent type the decorated methods are associated with (the `Author` type in this example). Alternatively, instead of applying `@Resolver()` to the class, you can apply it to each method:

```typescript

@Resolver('Author')
@ResolveField()
async posts(@Parent() author) {
  const { id } = author;
  return this.postsService.findAll({ authorId: id });
}
```

In this case (`@Resolver()` at the method level), if a class has multiple `@ResolveField()` methods, you must add `@Resolver()` to each of them. This is not considered best practice, as it adds overhead.

> **Hint** Any class name argument passed to `@Resolver()`**does not** affect queries (`@Query()` decorator) or mutations (`@Mutation()` decorator).

> **Warning** Using the `@Resolver` decorator at the method level is not supported with the **code first** approach.

In the examples above, the `@Query()` and `@ResolveField()` decorators are associated with GraphQL schema fields based on the method name. For example, consider the following construction from the example above:

```typescript

@Query()
async author(@Args('id') id: number) {
  return this.authorsService.findOneById(id);
}
```

This generates the following entry for the author query in the schema (the query uses the same name as the method):

```graphql

type Query {
  author(id: Int!): Author
}
```

Conventionally, these names are decoupled, using names like `getAuthor()` or `getPosts()` for the resolver methods. To do this, pass the mapping name as an argument to the decorator, as shown below:

authors/authors.resolver.ts

JS TS

```typescript

@Resolver('Author')
export class AuthorsResolver {
  constructor(
    private authorsService: AuthorsService,
    private postsService: PostsService,
  ) {}

  @Query('author')
  async getAuthor(@Args('id') id: number) {
    return this.authorsService.findOneById(id);
  }

  @ResolveField('posts')
  async getPosts(@Parent() author) {
    const { id } = author;
    return this.postsService.findAll({ authorId: id });
  }
}
```

> **Hint** The Nest CLI provides a generator (schematic) that generates **all the boilerplate code** for you. See the [CRUD generator](/recipes/crud-generator) recipe for details.

#### Generating types[#](/graphql/resolvers#generating-types)

If you use the schema first approach and have enabled typings generation (with `outputAs: 'class'`, as shown in the [Quick start](/graphql/quick-start) chapter), running the application generates the following file in the location you specified in the `GraphQLModule.forRoot()` method, e.g., `src/graphql.ts`:

graphql.ts

JS TS

```typescript

export class Author {
  id: number;
  firstName?: string;
  lastName?: string;
  posts?: Post[];
}
export class Post {
  id: number;
  title: string;
  votes?: number;
}

export abstract class IQuery {
  abstract author(id: number): Author | Promise<Author>;
}
```

Generating classes (instead of the default interfaces) lets you combine declarative validation **decorators** with the schema first approach (see [Validation](/application/validation)). For example, you could add `class-validator` decorators to a generated `CreatePostInput` class, as shown below, to enforce minimum and maximum string lengths on the `title` field:

```typescript

import { MinLength, MaxLength } from 'class-validator';

export class CreatePostInput {
  @MinLength(3)
  @MaxLength(50)
  title: string;
}
```

> **Notice** To enable automatic validation of your inputs (and parameters), use `ValidationPipe`. Learn more in the [Validation](/application/validation) and [Pipes](/pipes) chapters.

However, decorators added directly to the generated file are **overwritten** each time the file is regenerated. Instead, create a separate file and extend the generated class.

```typescript

import { MinLength, MaxLength } from 'class-validator';
import { Post } from '../../graphql.js';

export class CreatePostInput extends Post {
  @MinLength(3)
  @MaxLength(50)
  title: string;
}
```

#### GraphQL argument decorators[#](/graphql/resolvers#graphql-argument-decorators)

You can access the standard GraphQL resolver arguments with dedicated decorators. The table below maps the Nest decorators to the plain Apollo parameters they represent.

|                            |                              |
| -------------------------- | ---------------------------- |
| `@Root()` and `@Parent()`  | `root`/`parent`              |
| `@Context(param?: string)` | `context` / `context[param]` |
| `@Info(param?: string)`    | `info` / `info[param]`       |
| `@Args(param?: string)`    | `args` / `args[param]`       |

These arguments have the following meanings:

* `root`: an object that contains the result returned from the resolver on the parent field, or, in the case of a top-level `Query` field, the `rootValue` passed from the server configuration.
* `context`: an object shared by all resolvers in a particular query; typically used to contain per-request state.
* `info`: an object that contains information about the execution state of the query.
* `args`: an object with the arguments passed into the field in the query.

## Debug production with NestJS Observe

* Every request traced
* Errors with source code
* Logs in context
* Zero config, free plan

[Start for free](https://observe.nestjs.com "Observe | NestJS - A progressive Node.js framework")

#### Module[#](/graphql/resolvers#module)

With the steps above, we have declaratively specified all the information the `GraphQLModule` needs to generate a resolver map. The `GraphQLModule` uses reflection to introspect the metadata provided via the decorators, and transforms the classes into the correct resolver map automatically.

The only other thing you need to do is **provide** the resolver class (`AuthorsResolver`), i.e., list it as a provider in a module, and import that module (`AuthorsModule`) somewhere so Nest can use it.

For example, you can do this in an `AuthorsModule`, which can also provide other services needed in this context. Be sure to import `AuthorsModule` somewhere (e.g., in the root module, or in another module imported by the root module).

authors/authors.module.ts

JS TS

```typescript

@Module({
  imports: [PostsModule],
  providers: [AuthorsService, AuthorsResolver],
})
export class AuthorsModule {}
```

> **Hint** It helps to organize your code by **domain model** (similar to the way you would organize entry points in a REST API). In this approach, keep your models (`ObjectType` classes), resolvers, and services together within a Nest module representing the domain model, in a single folder per module. When you do this and use the [Nest CLI](/cli/overview) to generate each element, the CLI wires these parts together for you (placing files in the appropriate folders, adding entries to the `providers` and `imports` arrays, etc.).

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/resolvers-map.md)

----
url: https://docs.nestjs.com/recipes/async-local-storage
----

[Skip to content](#content)

On this page

* [Async Local Storage](https://docs.nestjs.com/recipes/async-local-storage#async-local-storage)
* [Custom implementation](https://docs.nestjs.com/recipes/async-local-storage#custom-implementation)
* [NestJS Observe](https://docs.nestjs.com/recipes/async-local-storage#nestjs-observe)
* [Setup](https://docs.nestjs.com/recipes/async-local-storage#setup)
* [Reading and writing the store](https://docs.nestjs.com/recipes/async-local-storage#reading-and-writing-the-store)
* [Typing the store](https://docs.nestjs.com/recipes/async-local-storage#typing-the-store)
* [Beyond HTTP](https://docs.nestjs.com/recipes/async-local-storage#beyond-http)
* [NestJS CLS](https://docs.nestjs.com/recipes/async-local-storage#nestjs-cls)
* [Installation](https://docs.nestjs.com/recipes/async-local-storage#installation)
* [Usage](https://docs.nestjs.com/recipes/async-local-storage#usage)
* [Testing](https://docs.nestjs.com/recipes/async-local-storage#testing)
* [More information](https://docs.nestjs.com/recipes/async-local-storage#more-information)

### Async Local Storage

`AsyncLocalStorage` is a [Node.js API](https://nodejs.org/api/async_context.html#class-asynclocalstorage) (based on the `async_hooks` API) that provides an alternative way of propagating local state through the application without explicitly passing it as a function parameter. It's similar to thread-local storage in other languages.

The main idea of Async Local Storage is that you can *wrap* a function call with the `AsyncLocalStorage#run` call. All code invoked within the wrapped call gets access to the same `store`, which is unique to each call chain.

In the context of NestJS, this means that if you find a place within the request's lifecycle to wrap the rest of the request's code, you can access and modify state visible only to that request. This can serve as an alternative to REQUEST-scoped providers, avoiding some of their limitations.

Alternatively, you can use ALS to propagate context for only a part of the system (e.g., the *transaction* object) without passing it around explicitly across services, which can increase isolation and encapsulation.

If your application is instrumented with [NestJS Observe](/observability/overview), you already have a request-scoped store and don't need to build one. See the [NestJS Observe](/recipes/async-local-storage#nestjs-observe) section below.

#### Custom implementation[#](/recipes/async-local-storage#custom-implementation)

The NestJS core framework doesn't provide a built-in abstraction for `AsyncLocalStorage`, so let's walk through how to implement it yourself for the simplest HTTP case, to get a better understanding of the whole concept:

> **Hint** For ready-made solutions, see the [`@nestjs/observe`](/recipes/async-local-storage#nestjs-observe) and [`nestjs-cls`](/recipes/async-local-storage#nestjs-cls) sections below.

1. First, create a new instance of `AsyncLocalStorage` in a shared source file. Since we're using NestJS, let's also turn it into a module with a custom provider.

als.module.ts

JS TS

```ts

@Module({
  providers: [
    {
      provide: AsyncLocalStorage,
      useValue: new AsyncLocalStorage(),
    },
  ],
  exports: [AsyncLocalStorage],
})
export class AlsModule {}
```

> **Hint**`AsyncLocalStorage` is imported from `node:async_hooks`.

2. We're only concerned with HTTP, so let's use a middleware to wrap the `next` function with `AsyncLocalStorage#run`. Since middleware is the first thing a request hits, this makes the `store` available in all enhancers and the rest of the system.

app.module.ts

JS TS

```typescript

@Module({
  imports: [AlsModule],
  providers: [CatsService],
  controllers: [CatsController],
})
export class AppModule implements NestModule {
  constructor(
    // inject the AsyncLocalStorage in the module constructor,
    private readonly als: AsyncLocalStorage
  ) {}

  configure(consumer: MiddlewareConsumer) {
    // bind the middleware,
    consumer
      .apply((req, res, next) => {
        // populate the store with some default values
        // based on the request,
        const store = {
          userId: req.headers['x-user-id'],
        };
        // and pass the "next" function as callback
        // to the "als.run" method together with the store.
        this.als.run(store, () => next());
      })
      .forRoutes('*path');
  }
}
```

```typescript

@Module({
  imports: [AlsModule],
  providers: [CatsService],
  controllers: [CatsController],
})
@Dependencies(AsyncLocalStorage)
export class AppModule {
  constructor(als) {
    // inject the AsyncLocalStorage in the module constructor,
    this.als = als;
  }

  configure(consumer) {
    // bind the middleware,
    consumer
      .apply((req, res, next) => {
        // populate the store with some default values
        // based on the request,
        const store = {
          userId: req.headers['x-user-id'],
        };
        // and pass the "next" function as callback
        // to the "als.run" method together with the store.
        this.als.run(store, () => next());
      })
      .forRoutes('*path');
  }
}
```

3. Now you can access the local store instance anywhere within the lifecycle of a request.

cats.service.ts

JS TS

```typescript

@Injectable()
export class CatsService {
  constructor(
    // We can inject the provided ALS instance.
    private readonly als: AsyncLocalStorage,
    private readonly catsRepository: CatsRepository,
  ) {}

  getCatForUser() {
    // The "getStore" method will always return the
    // store instance associated with the given request.
    const userId = this.als.getStore()["userId"] as number;
    return this.catsRepository.getForUser(userId);
  }
}
```

```typescript

@Injectable()
@Dependencies(AsyncLocalStorage, CatsRepository)
export class CatsService {
  constructor(als, catsRepository) {
    // We can inject the provided ALS instance.
    this.als = als;
    this.catsRepository = catsRepository;
  }

  getCatForUser() {
    // The "getStore" method will always return the
    // store instance associated with the given request.
    const userId = this.als.getStore()["userId"];
    return this.catsRepository.getForUser(userId);
  }
}
```

4. You now have a way to share request-related state without injecting the whole `REQUEST` object.

> **Warning** While this technique is useful for many use cases, it inherently obscures the code flow (by creating implicit context), so use it responsibly, and especially avoid creating contextual "[God objects](https://en.wikipedia.org/wiki/God_object)".

### NestJS Observe

If you run [NestJS Observe](/observability/overview), the `@nestjs/observe` SDK already maintains an `AsyncLocalStorage` store for every request, job, and message it instruments. This store carries the trace context through your call stack. `TracerService` exposes it, so request-scoped state is something you read and write rather than something you set up: there's no module to write, no middleware to mount, and nothing to re-wire per transport.

> **Hint** This is the same `TracerService` documented in [Manual instrumentation](/observability/manual-instrumentation). This section covers only its async local storage side; spans, handled errors, and custom metrics are described there.

#### Setup[#](/recipes/async-local-storage#setup)

No setup is needed beyond the standard SDK integration described in [Observability → SDK](/observability/sdk): install the package, import `ObserveModule.forRoot()`, and pass `ObserveInstrument` to `NestFactory.create()`.

```bash

$ npm i @nestjs/observe
```

`ObserveModule` exports `TracerService`, so you can inject it anywhere in your application:

cats.service.ts

JS TS

```ts

import { Injectable } from '@nestjs/common';
import { TracerService } from '@nestjs/observe';

@Injectable()
export class CatsService {
  constructor(private readonly tracerService: TracerService) {}
}
```

#### Reading and writing the store[#](/recipes/async-local-storage#reading-and-writing-the-store)

`setAttribute(key, value)` writes to the current context store, and `getAttribute(key)` reads the value back from anywhere downstream on the same request (a different service, a guard, or an interceptor) without threading it through every function signature:

cats.controller.ts

JS TS

```ts

@Get()
findAll(@Req() req: Request) {
  this.tracerService.setAttribute('userId', req.headers['x-user-id']);
  return this.catsService.getCatForUser();
}
```

cats.service.ts

JS TS

```ts

@Injectable()
export class CatsService {
  constructor(
    private readonly tracerService: TracerService,
    private readonly catsRepository: CatsRepository,
  ) {}

  getCatForUser() {
    const userId = this.tracerService.getAttribute('userId');
    return this.catsRepository.getForUser(userId);
  }
}
```

`getAttribute()` returns `undefined` for a key that was never set. Both methods throw when called outside a traced context, since there's no store to read from or write to. If a value may legitimately be read before any request exists, guard the call accordingly.

#### Typing the store[#](/recipes/async-local-storage#typing-the-store)

Pass the shape of your store as the first type argument of `TracerService` to have keys and values type-checked, including nested paths:

```ts

interface RequestStore {
  userId: number;
  flags: { betaCheckout: boolean };
}

@Injectable()
export class CatsService {
  constructor(private readonly tracerService: TracerService<RequestStore>) {}

  enableBeta() {
    this.tracerService.setAttribute('flags.betaCheckout', true);
  }
}
```

#### Beyond HTTP[#](/recipes/async-local-storage#beyond-http)

Because the store is created by the instrumentation rather than by a middleware, it exists wherever the SDK traces an operation: HTTP and GraphQL requests, gRPC and `@nestjs/microservices` messages, and background work such as BullMQ consumers and cron runs. The pattern above is identical in all of them. This is the practical difference from a hand-rolled, middleware-based implementation, which only covers HTTP.

The store also holds the current trace ID, so it doubles as the correlation key for logs and downstream services. `currentTraceId()` returns it. Unlike `getAttribute()`, it returns `null` outside a traced context instead of throwing:

```ts

const traceId = this.tracerService.currentTraceId();
```

> **Hint**`ObserveModule` also exports the underlying `AsyncLocalStorage` instance. `setAttribute()` and `getAttribute()` are the supported way to access the store; inject the instance directly only if you need something they don't expose.

### NestJS CLS

The [nestjs-cls](https://github.com/Papooch/nestjs-cls) package provides several developer experience improvements over plain `AsyncLocalStorage` (`CLS` is an abbreviation of *continuation-local storage*). It abstracts the implementation into a `ClsModule` that offers various ways of initializing the `store` for different transports (not only HTTP), as well as strong typing support.

You can then access the store with an injectable `ClsService`, or abstract it away from the business logic entirely by using [Proxy Providers](https://www.npmjs.com/package/nestjs-cls#proxy-providers).

> **Note**`nestjs-cls` is a third-party package and is not managed by the NestJS core team. Please report any issues with the library in the [nestjs-cls repository](https://github.com/Papooch/nestjs-cls/issues).

#### Installation[#](/recipes/async-local-storage#installation)

Apart from peer dependencies on the `@nestjs` packages, it uses only built-in Node.js APIs. Install it like any other package:

```bash

$ npm i nestjs-cls
```

#### Usage[#](/recipes/async-local-storage#usage)

You can implement functionality similar to the [custom implementation](/recipes/async-local-storage#custom-implementation) above using `nestjs-cls`, as follows:

1. Import the `ClsModule` in the root module.

app.module.ts

JS TS

```ts

@Module({
  imports: [
    // Register the ClsModule,
    ClsModule.forRoot({
      middleware: {
        // automatically mount the
        // ClsMiddleware for all routes
        mount: true,
        // and use the setup method to
        // provide default store values.
        setup: (cls, req) => {
          cls.set('userId', req.headers['x-user-id']);
        },
      },
    }),
  ],
  providers: [CatsService],
  controllers: [CatsController],
})
export class AppModule {}
```

2. Then use the `ClsService` to access the store values.

cats.service.ts

JS TS

```typescript

@Injectable()
export class CatsService {
  constructor(
    // We can inject the provided ClsService instance,
    private readonly cls: ClsService,
    private readonly catsRepository: CatsRepository,
  ) {}

  getCatForUser() {
    // and use the "get" method to retrieve any stored value.
    const userId = this.cls.get('userId');
    return this.catsRepository.getForUser(userId);
  }
}
```

```typescript

@Injectable()
@Dependencies(ClsService, CatsRepository)
export class CatsService {
  constructor(cls, catsRepository) {
    // We can inject the provided ClsService instance,
    this.cls = cls;
    this.catsRepository = catsRepository;
  }

  getCatForUser() {
    // and use the "get" method to retrieve any stored value.
    const userId = this.cls.get('userId');
    return this.catsRepository.getForUser(userId);
  }
}
```

3. To get strong typing of the store values managed by the `ClsService` (and auto-suggestions for the string keys), use the optional type parameter `ClsService<MyClsStore>` when injecting it.

```ts

export interface MyClsStore extends ClsStore {
  userId: number;
}
```

> **Hint** You can also let the package automatically generate a request ID and access it later with `cls.getId()`, or get the whole request object using `cls.get(CLS_REQ)`.

#### Testing[#](/recipes/async-local-storage#testing)

Since the `ClsService` is just another injectable provider, you can mock it out entirely in unit tests.

However, in certain integration tests, you might still want to use the real `ClsService` implementation. In that case, wrap the context-aware piece of code with a call to `ClsService#run` or `ClsService#runWith`:

```ts

describe('CatsService', () => {
  let service: CatsService
  let cls: ClsService
  const mockCatsRepository = createMock<CatsRepository>()

  beforeEach(async () => {
    const module = await Test.createTestingModule({
      // Set up most of the testing module as we normally would.
      providers: [
        CatsService,
        {
          provide: CatsRepository,
          useValue: mockCatsRepository,
        }
      ],
      imports: [
        // Import the static version of ClsModule which only provides
        // the ClsService, but does not set up the store in any way.
        ClsModule
      ],
    }).compile()

    service = module.get(CatsService)

    // Also retrieve the ClsService for later use.
    cls = module.get(ClsService)
  })

  describe('getCatForUser', () => {
    it('retrieves cat based on user id', async () => {
      const expectedUserId = 42
      mockCatsRepository.getForUser.mockImplementationOnce(
        (id) => ({ userId: id })
      )

      // Wrap the test call in the `runWith` method
      // in which we can pass hand-crafted store values.
      const cat = await cls.runWith(
        { userId: expectedUserId },
        () => service.getCatForUser()
      )

      expect(cat.userId).toEqual(expectedUserId)
    })
  })
})
```

#### More information[#](/recipes/async-local-storage#more-information)

Visit the [nestjs-cls GitHub page](https://github.com/Papooch/nestjs-cls) for the full API documentation and more code examples.

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/recipes/async-local-storage.md)

----
url: https://docs.nestjs.com/v11/microservices/basics
----

* [Overview](https://docs.nestjs.com/v11/microservices/basics#overview)
* [Installation](https://docs.nestjs.com/v11/microservices/basics#installation)
* [Getting started](https://docs.nestjs.com/v11/microservices/basics#getting-started)
* [Message and Event Patterns](https://docs.nestjs.com/v11/microservices/basics#message-and-event-patterns)
* [Request-response](https://docs.nestjs.com/v11/microservices/basics#request-response)
* [Asynchronous responses](https://docs.nestjs.com/v11/microservices/basics#asynchronous-responses)
* [Event-based](https://docs.nestjs.com/v11/microservices/basics#event-based)
* [Additional request details](https://docs.nestjs.com/v11/microservices/basics#additional-request-details)
* [Client (producer class)](https://docs.nestjs.com/v11/microservices/basics#client-producer-class)
* [Sending messages](https://docs.nestjs.com/v11/microservices/basics#sending-messages)
* [Publishing events](https://docs.nestjs.com/v11/microservices/basics#publishing-events)
* [Request-scoping](https://docs.nestjs.com/v11/microservices/basics#request-scoping)
* [Instance status updates](https://docs.nestjs.com/v11/microservices/basics#instance-status-updates)
* [Listening to internal events](https://docs.nestjs.com/v11/microservices/basics#listening-to-internal-events)
* [Underlying driver access](https://docs.nestjs.com/v11/microservices/basics#underlying-driver-access)
* [Handling timeouts](https://docs.nestjs.com/v11/microservices/basics#handling-timeouts)
* [TLS support](https://docs.nestjs.com/v11/microservices/basics#tls-support)
* [Dynamic configuration](https://docs.nestjs.com/v11/microservices/basics#dynamic-configuration)

```bash

$ npm i --save @nestjs/microservices
```

#### Getting started[#](/microservices/basics#getting-started)

To instantiate a microservice, use the `createMicroservice()` method of the `NestFactory` class:

main.ts

JS TS

```typescript

import { NestFactory } from '@nestjs/core';
import { Transport, MicroserviceOptions } from '@nestjs/microservices';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.createMicroservice<MicroserviceOptions>(
    AppModule,
    {
      transport: Transport.TCP,
    },
  );
  await app.listen();
}
bootstrap();
```

```typescript

import { NestFactory } from '@nestjs/core';
import { Transport } from '@nestjs/microservices';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.createMicroservice(AppModule, {
    transport: Transport.TCP,
  });
  await app.listen();
}
bootstrap();
```

> **Hint** Microservices use the **TCP** transport layer by default.

The second argument of the `createMicroservice()` method is an `options` object. This object may consist of two members:

|             |                                                                            |
| ----------- | -------------------------------------------------------------------------- |
| `transport` | Specifies the transporter (for example, `Transport.NATS`)                  |
| `options`   | A transporter-specific options object that determines transporter behavior |

The `options` object is specific to the chosen transporter. The **TCP** transporter exposes the properties described below. For other transporters (e.g, Redis, MQTT, etc.), see the relevant chapter for a description of the available options.

|                 |                                                                                                                                                     |
| --------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| `host`          | Connection hostname                                                                                                                                 |
| `port`          | Connection port                                                                                                                                     |
| `retryAttempts` | Number of times to retry message (default: `0`)                                                                                                     |
| `retryDelay`    | Delay between message retry attempts (ms) (default: `0`)                                                                                            |
| `serializer`    | Custom [serializer](https://github.com/nestjs/nest/blob/master/packages/microservices/interfaces/serializer.interface.ts) for outgoing messages     |
| `deserializer`  | Custom [deserializer](https://github.com/nestjs/nest/blob/master/packages/microservices/interfaces/deserializer.interface.ts) for incoming messages |
| `socketClass`   | A custom Socket that extends `TcpSocket` (default: `JsonSocket`)                                                                                    |
| `tlsOptions`    | Options to configure the tls protocol                                                                                                               |

> **Hint** The above properties are specific to the TCP transporter. For information on available options for other transporters, refer to the relevant chapter.

#### Message and Event Patterns[#](/microservices/basics#message-and-event-patterns)

Microservices recognize both messages and events by **patterns**. A pattern is a plain value, for example, a literal object or a string. Patterns are automatically serialized and sent over the network along with the data portion of a message. In this way, message senders and consumers can coordinate which requests are consumed by which handlers.

#### Request-response[#](/microservices/basics#request-response)

The request-response message style is useful when you need to **exchange** messages between various external services. This paradigm ensures that the service has actually received the message (without requiring you to manually implement an acknowledgment protocol). However, the request-response approach may not always be the best fit. For example, streaming transporters, such as [Kafka](https://docs.confluent.io/3.0.0/streams/) or [NATS streaming](https://github.com/nats-io/node-nats-streaming), which use log-based persistence, are optimized for addressing a different set of challenges, more aligned with the event messaging paradigm (see [event-based messaging](https://docs.nestjs.com/microservices/basics#event-based) for more details).

To enable the request-response message type, Nest creates two logical channels: one for transferring data and another for waiting for incoming responses. For some underlying transports, like [NATS](https://nats.io/), this dual-channel support is provided out-of-the-box. For others, Nest compensates by manually creating separate channels. While this is effective, it can introduce some overhead. Therefore, if you don’t require a request-response message style, you may want to consider using the event-based method.

To create a message handler based on the request-response paradigm, use the `@MessagePattern()` decorator, which is imported from the `@nestjs/microservices` package. This decorator should only be used within [controller](https://docs.nestjs.com/controllers) classes, as they serve as the entry points for your application. Using it in providers will have no effect, as they will be ignored by the Nest runtime.

math.controller.ts

JS TS

```typescript

import { Controller } from '@nestjs/common';
import { MessagePattern } from '@nestjs/microservices';

@Controller()
export class MathController {
  @MessagePattern({ cmd: 'sum' })
  accumulate(data: number[]): number {
    return (data || []).reduce((a, b) => a + b);
  }
}
```

```typescript

import { Controller } from '@nestjs/common';
import { MessagePattern } from '@nestjs/microservices';

@Controller()
export class MathController {
  @MessagePattern({ cmd: 'sum' })
  accumulate(data) {
    return (data || []).reduce((a, b) => a + b);
  }
}
```

In the above code, the `accumulate()`**message handler** listens for messages that match the `{ cmd: 'sum' }` message pattern. The message handler takes a single argument, the `data` passed from the client. In this case, the data is an array of numbers that need to be accumulated.

#### Asynchronous responses[#](/microservices/basics#asynchronous-responses)

Message handlers can respond either synchronously or **asynchronously**, meaning that `async` methods are supported.

JS TS

```typescript

@MessagePattern({ cmd: 'sum' })
async accumulate(data: number[]): Promise<number> {
  return (data || []).reduce((a, b) => a + b);
}
```

```typescript

@MessagePattern({ cmd: 'sum' })
async accumulate(data) {
  return (data || []).reduce((a, b) => a + b);
}
```

A message handler can also return an `Observable`, in which case the result values will be emitted until the stream completes.

JS TS

```typescript

@MessagePattern({ cmd: 'sum' })
accumulate(data: number[]): Observable<number> {
  return from([1, 2, 3]);
}
```

```typescript

@MessagePattern({ cmd: 'sum' })
accumulate(data: number[]): Observable<number> {
  return from([1, 2, 3]);
}
```

In the example above, the message handler will respond **three times**, once for each item in the array.

#### Event-based[#](/microservices/basics#event-based)

While the request-response method is perfect for exchanging messages between services, it is less suited for event-based messaging—when you simply want to publish **events** without waiting for a response. In such cases, the overhead of maintaining two channels for request-response is unnecessary.

For example, if you want to notify another service that a specific condition has occurred in this part of the system, the event-based message style is ideal.

To create an event handler, you can use the `@EventPattern()` decorator, which is imported from the `@nestjs/microservices` package.

JS TS

```typescript

@EventPattern('user_created')
async handleUserCreated(data: Record<string, unknown>) {
  // business logic
}
```

```typescript

@EventPattern('user_created')
async handleUserCreated(data) {
  // business logic
}
```

> **Hint** You can register multiple event handlers for a **single** event pattern, and all of them will be automatically triggered in parallel.

The `handleUserCreated()`**event handler** listens for the `'user_created'` event. The event handler takes a single argument, the `data` passed from the client (in this case, an event payload which has been sent over the network).

In more advanced scenarios, you might need to access additional details about the incoming request. For instance, when using NATS with wildcard subscriptions, you may want to retrieve the original subject that the producer sent the message to. Similarly, with Kafka, you may need to access the message headers. To achieve this, you can leverage built-in decorators as shown below:

JS TS

```typescript

@MessagePattern('time.us.*')
getDate(@Payload() data: number[], @Ctx() context: NatsContext) {
  console.log(`Subject: ${context.getSubject()}`); // e.g. "time.us.east"
  return new Date().toLocaleTimeString(...);
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('time.us.*')
getDate(data, context) {
  console.log(`Subject: ${context.getSubject()}`); // e.g. "time.us.east"
  return new Date().toLocaleTimeString(...);
}
```

> **Hint**`@Payload()`, `@Ctx()` and `NatsContext` are imported from `@nestjs/microservices`.

> **Hint** You can also pass in a property key to the `@Payload()` decorator to extract a specific property from the incoming payload object, for example, `@Payload('id')`.

#### Client (producer class)[#](/microservices/basics#client-producer-class)

A client Nest application can exchange messages or publish events to a Nest microservice using the `ClientProxy` class. This class provides several methods, such as `send()` (for request-response messaging) and `emit()` (for event-driven messaging), enabling communication with a remote microservice. You can obtain an instance of this class in the following ways:

One approach is to import the `ClientsModule`, which exposes the static `register()` method. This method takes an array of objects representing microservice transporters. Each object must include a `name` property, and optionally a `transport` property (defaulting to `Transport.TCP`), as well as an optional `options` property.

The `name` property acts as an **injection token**, which you can use to inject an instance of `ClientProxy` wherever needed. The value of this `name` property can be any arbitrary string or JavaScript symbol, as described [here](https://docs.nestjs.com/fundamentals/custom-providers#non-class-based-provider-tokens).

The `options` property is an object that includes the same properties we saw in the `createMicroservice()` method earlier.

```typescript

@Module({
  imports: [
    ClientsModule.register([
      { name: 'MATH_SERVICE', transport: Transport.TCP },
    ]),
  ],
})
```

Alternatively, you can use the `registerAsync()` method if you need to provide configuration or perform any other asynchronous processes during the setup.

```typescript

@Module({
  imports: [
    ClientsModule.registerAsync([
      {
        imports: [ConfigModule],
        name: 'MATH_SERVICE',
        useFactory: async (configService: ConfigService) => ({
          transport: Transport.TCP,
          options: {
            url: configService.get('URL'),
          },
        }),
        inject: [ConfigService],
      },
    ]),
  ],
})
```

Once the module has been imported, you can inject an instance of the `ClientProxy` configured with the specified options for the `'MATH_SERVICE'` transporter using the `@Inject()` decorator.

```typescript

constructor(
  @Inject('MATH_SERVICE') private client: ClientProxy,
) {}
```

> **Hint** The `ClientsModule` and `ClientProxy` classes are imported from the `@nestjs/microservices` package.

At times, you may need to fetch the transporter configuration from another service (such as a `ConfigService`), rather than hard-coding it in your client application. To achieve this, you can register a [custom provider](/v11/fundamentals/custom-providers) using the `ClientProxyFactory` class. This class provides a static `create()` method that accepts a transporter options object and returns a customized `ClientProxy` instance.

```typescript

@Module({
  providers: [
    {
      provide: 'MATH_SERVICE',
      useFactory: (configService: ConfigService) => {
        const mathSvcOptions = configService.getMathSvcOptions();
        return ClientProxyFactory.create(mathSvcOptions);
      },
      inject: [ConfigService],
    }
  ]
  ...
})
```

> **Hint** The `ClientProxyFactory` is imported from the `@nestjs/microservices` package.

Another option is to use the `@Client()` property decorator.

```typescript

@Client({ transport: Transport.TCP })
client: ClientProxy;
```

> **Hint** The `@Client()` decorator is imported from the `@nestjs/microservices` package.

Using the `@Client()` decorator is not the preferred technique, as it is harder to test and harder to share a client instance.

The `ClientProxy` is **lazy**. It doesn't initiate a connection immediately. Instead, it will be established before the first microservice call, and then reused across each subsequent call. However, if you want to delay the application bootstrapping process until a connection is established, you can manually initiate a connection using the `ClientProxy` object's `connect()` method inside the `OnApplicationBootstrap` lifecycle hook.

JS TS

```typescript

async onApplicationBootstrap() {
  await this.client.connect();
}
```

If the connection cannot be created, the `connect()` method will reject with the corresponding error object.

#### Sending messages[#](/microservices/basics#sending-messages)

The `ClientProxy` exposes a `send()` method. This method is intended to call the microservice and returns an `Observable` with its response. Thus, we can subscribe to the emitted values easily.

JS TS

```typescript

accumulate(): Observable<number> {
  const pattern = { cmd: 'sum' };
  const payload = [1, 2, 3];
  return this.client.send<number>(pattern, payload);
}
```

```typescript

accumulate() {
  const pattern = { cmd: 'sum' };
  const payload = [1, 2, 3];
  return this.client.send(pattern, payload);
}
```

The `send()` method takes two arguments, `pattern` and `payload`. The `pattern` should match one defined in a `@MessagePattern()` decorator. The `payload` is a message that we want to transmit to the remote microservice. This method returns a **cold `Observable`**, which means that you have to explicitly subscribe to it before the message will be sent.

#### Publishing events[#](/microservices/basics#publishing-events)

To send an event, use the `ClientProxy` object's `emit()` method. This method publishes an event to the message broker.

JS TS

```typescript

async publish() {
  this.client.emit<number>('user_created', new UserCreatedEvent());
}
```

```typescript

async publish() {
  this.client.emit('user_created', new UserCreatedEvent());
}
```

The `emit()` method takes two arguments: `pattern` and `payload`. The `pattern` should match one defined in an `@EventPattern()` decorator, while the `payload` represents the event data that you want to transmit to the remote microservice. This method returns a **hot `Observable`** (in contrast to the cold `Observable` returned by `send()`), meaning that regardless of whether you explicitly subscribe to the observable, the proxy will immediately attempt to deliver the event.

## Explore your graph with NestJS Devtools

* Graph visualizer
* Routes navigator
* Interactive playground
* CI/CD integration

[Sign up](https://devtools.nestjs.com "Devtools | NestJS - A node.js framework built on top of TypeScript")

#### Request-scoping[#](/microservices/basics#request-scoping)

For those coming from different programming language backgrounds, it may be surprising to learn that in Nest, most things are shared across incoming requests. This includes a connection pool to the database, singleton services with global state, and more. Keep in mind that Node.js does not follow the request/response multi-threaded stateless model, where each request is processed by a separate thread. As a result, using singleton instances is **safe** for our applications.

However, there are edge cases where a request-based lifetime for the handler might be desirable. This could include scenarios like per-request caching in GraphQL applications, request tracking, or multi-tenancy. You can learn more about how to control scopes [here](/v11/fundamentals/injection-scopes).

Request-scoped handlers and providers can inject `RequestContext` using the `@Inject()` decorator in combination with the `CONTEXT` token:

```typescript

import { Injectable, Scope, Inject } from '@nestjs/common';
import { CONTEXT, RequestContext } from '@nestjs/microservices';

@Injectable({ scope: Scope.REQUEST })
export class CatsService {
  constructor(@Inject(CONTEXT) private ctx: RequestContext) {}
}
```

This provides access to the `RequestContext` object, which has two properties:

```typescript

export interface RequestContext<T = any> {
  pattern: string | Record<string, any>;
  data: T;
}
```

The `data` property is the message payload sent by the message producer. The `pattern` property is the pattern used to identify an appropriate handler to handle the incoming message.

#### Instance status updates[#](/microservices/basics#instance-status-updates)

To get real-time updates on the connection and the state of the underlying driver instance, you can subscribe to the `status` stream. This stream provides status updates specific to the chosen driver. For instance, if you’re using the TCP transporter (the default), the `status` stream emits `connected` and `disconnected` events.

```typescript

this.client.status.subscribe((status: TcpStatus) => {
  console.log(status);
});
```

> **Hint** The `TcpStatus` type is imported from the `@nestjs/microservices` package.

Similarly, you can subscribe to the server's `status` stream to receive notifications about the server's status.

```typescript

const server = app.connectMicroservice<MicroserviceOptions>(...);
server.status.subscribe((status: TcpStatus) => {
  console.log(status);
});
```

#### Listening to internal events[#](/microservices/basics#listening-to-internal-events)

In some cases, you might want to listen to internal events emitted by the microservice. For example, you could listen for the `error` event to trigger additional operations when an error occurs. To do this, use the `on()` method, as shown below:

```typescript

this.client.on('error', (err) => {
  console.error(err);
});
```

Similarly, you can listen to the server's internal events:

```typescript

server.on<TcpEvents>('error', (err) => {
  console.error(err);
});
```

> **Hint** The `TcpEvents` type is imported from the `@nestjs/microservices` package.

#### Underlying driver access[#](/microservices/basics#underlying-driver-access)

For more advanced use cases, you may need to access the underlying driver instance. This can be useful for scenarios like manually closing the connection or using driver-specific methods. However, keep in mind that for most cases, you **shouldn't need** to access the driver directly.

To do so, you can use the `unwrap()` method, which returns the underlying driver instance. The generic type parameter should specify the type of driver instance you expect.

```typescript

const netServer = this.client.unwrap<Server>();
```

Here, `Server` is a type imported from the `net` module.

Similarly, you can access the server's underlying driver instance:

```typescript

const netServer = server.unwrap<Server>();
```

#### Handling timeouts[#](/microservices/basics#handling-timeouts)

In distributed systems, microservices might sometimes be down or unavailable. To prevent indefinitely long waiting, you can use timeouts. A timeout is a highly useful pattern when communicating with other services. To apply timeouts to your microservice calls, you can use the [RxJS](https://rxjs.dev)`timeout` operator. If the microservice does not respond within the specified time, an exception is thrown, which you can catch and handle appropriately.

To implement this, you'll need to use the [`rxjs`](https://github.com/ReactiveX/rxjs) package. Simply use the `timeout` operator within the pipe:

JS TS

```typescript

this.client
  .send<TResult, TInput>(pattern, data)
  .pipe(timeout(5000));
```

```typescript

this.client
  .send(pattern, data)
  .pipe(timeout(5000));
```

> **Hint** The `timeout` operator is imported from the `rxjs/operators` package.

After 5 seconds, if the microservice isn't responding, it will throw an error.

#### TLS support[#](/microservices/basics#tls-support)

When communicating outside of a private network, it’s important to encrypt traffic to ensure security. In NestJS, this can be achieved with TLS over TCP using Node's built-in [TLS](https://nodejs.org/api/tls.html) module. Nest provides built-in support for TLS in its TCP transport, allowing us to encrypt communication between microservices or clients.

To enable TLS for a TCP server, you'll need both a private key and a certificate in PEM format. These are added to the server's options by setting the `tlsOptions` and specifying the key and cert files, as shown below:

```typescript

import * as fs from 'fs';
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { MicroserviceOptions, Transport } from '@nestjs/microservices';

async function bootstrap() {
  const key = fs.readFileSync('<pathToKeyFile>', 'utf8').toString();
  const cert = fs.readFileSync('<pathToCertFile>', 'utf8').toString();

  const app = await NestFactory.createMicroservice<MicroserviceOptions>(
    AppModule,
    {
      transport: Transport.TCP,
      options: {
        tlsOptions: {
          key,
          cert,
        },
      },
    },
  );

  await app.listen();
}
bootstrap();
```

For a client to communicate securely over TLS, we also define the `tlsOptions` object but this time with the CA certificate. This is the certificate of the authority that signed the server's certificate. This ensures that the client trusts the server's certificate and can establish a secure connection.

```typescript

import { Module } from '@nestjs/common';
import { ClientsModule, Transport } from '@nestjs/microservices';

@Module({
  imports: [
    ClientsModule.register([
      {
        name: 'MATH_SERVICE',
        transport: Transport.TCP,
        options: {
          tlsOptions: {
            ca: [fs.readFileSync('<pathToCaFile>', 'utf-8').toString()],
          },
        },
      },
    ]),
  ],
})
export class AppModule {}
```

You can also pass an array of CAs if your setup involves multiple trusted authorities.

Once everything is set up, you can inject the `ClientProxy` as usual using the `@Inject()` decorator to use the client in your services. This ensures encrypted communication across your NestJS microservices, with Node's `TLS` module handling the encryption details.

For more information, refer to Node’s [TLS documentation](https://nodejs.org/api/tls.html).

#### Dynamic configuration[#](/microservices/basics#dynamic-configuration)

When a microservice needs to be configured using the `ConfigService` (from the `@nestjs/config` package), but the injection context is only available after the microservice instance is created, `AsyncMicroserviceOptions` offers a solution. This approach allows for dynamic configuration, ensuring smooth integration with the `ConfigService`.

```typescript

import { ConfigService } from '@nestjs/config';
import { AsyncMicroserviceOptions, Transport } from '@nestjs/microservices';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.createMicroservice<AsyncMicroserviceOptions>(
    AppModule,
    {
      useFactory: (configService: ConfigService) => ({
        transport: Transport.TCP,
        options: {
          host: configService.get<string>('HOST'),
          port: configService.get<number>('PORT'),
        },
      }),
      inject: [ConfigService],
    },
  );

  await app.listen();
}
bootstrap();
```

----
url: https://docs.nestjs.com/v10/exception-filters
----

* [Exception filters](https://docs.nestjs.com/v10/exception-filters#exception-filters)
* [Throwing standard exceptions](https://docs.nestjs.com/v10/exception-filters#throwing-standard-exceptions)
* [Custom exceptions](https://docs.nestjs.com/v10/exception-filters#custom-exceptions)
* [Built-in HTTP exceptions](https://docs.nestjs.com/v10/exception-filters#built-in-http-exceptions)
* [Exception filters](https://docs.nestjs.com/v10/exception-filters#exception-filters-1)
* [Arguments host](https://docs.nestjs.com/v10/exception-filters#arguments-host)
* [Binding filters](https://docs.nestjs.com/v10/exception-filters#binding-filters)
* [Catch everything](https://docs.nestjs.com/v10/exception-filters#catch-everything)
* [Inheritance](https://docs.nestjs.com/v10/exception-filters#inheritance)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/exception-filters.md "Suggest Edits")

### Exception filters

Nest comes with a built-in **exceptions layer** which is responsible for processing all unhandled exceptions across an application. When an exception is not handled by your application code, it is caught by this layer, which then automatically sends an appropriate user-friendly response.

Out of the box, this action is performed by a built-in **global exception filter**, which handles exceptions of type `HttpException` (and subclasses of it). When an exception is **unrecognized** (is neither `HttpException` nor a class that inherits from `HttpException`), the built-in exception filter generates the following default JSON response:

```json

{
  "statusCode": 500,
  "message": "Internal server error"
}
```

> **Hint** The global exception filter partially supports the `http-errors` library. Basically, any thrown exception containing the `statusCode` and `message` properties will be properly populated and sent back as a response (instead of the default `InternalServerErrorException` for unrecognized exceptions).

#### Throwing standard exceptions[#](/exception-filters#throwing-standard-exceptions)

Nest provides a built-in `HttpException` class, exposed from the `@nestjs/common` package. For typical HTTP REST/GraphQL API based applications, it's best practice to send standard HTTP response objects when certain error conditions occur.

For example, in the `CatsController`, we have a `findAll()` method (a `GET` route handler). Let's assume that this route handler throws an exception for some reason. To demonstrate this, we'll hard-code it as follows:

cats.controller.ts

JS TS

```typescript

@Get()
async findAll() {
  throw new HttpException('Forbidden', HttpStatus.FORBIDDEN);
}
```

> **Hint** We used the `HttpStatus` here. This is a helper enum imported from the `@nestjs/common` package.

When the client calls this endpoint, the response looks like this:

```json

{
  "statusCode": 403,
  "message": "Forbidden"
}
```

```typescript

@Get()
async findAll() {
  try {
    await this.service.findAll()
  } catch (error) {
    throw new HttpException({
      status: HttpStatus.FORBIDDEN,
      error: 'This is a custom message',
    }, HttpStatus.FORBIDDEN, {
      cause: error
    });
  }
}
```

Using the above, this is how the response would look:

```json

{
  "status": 403,
  "error": "This is a custom message"
}
```

#### Custom exceptions[#](/exception-filters#custom-exceptions)

In many cases, you will not need to write custom exceptions, and can use the built-in Nest HTTP exception, as described in the next section. If you do need to create customized exceptions, it's good practice to create your own **exceptions hierarchy**, where your custom exceptions inherit from the base `HttpException` class. With this approach, Nest will recognize your exceptions, and automatically take care of the error responses. Let's implement such a custom exception:

forbidden.exception.ts

JS TS

```typescript

export class ForbiddenException extends HttpException {
  constructor() {
    super('Forbidden', HttpStatus.FORBIDDEN);
  }
}
```

Since `ForbiddenException` extends the base `HttpException`, it will work seamlessly with the built-in exception handler, and therefore we can use it inside the `findAll()` method.

cats.controller.ts

JS TS

```typescript

@Get()
async findAll() {
  throw new ForbiddenException();
}
```

```typescript

throw new BadRequestException('Something bad happened', {
  cause: new Error(),
  description: 'Some error description',
});
```

Using the above, this is how the response would look:

```json

{
  "message": "Something bad happened",
  "error": "Some error description",
  "statusCode": 400
}
```

#### Exception filters[#](/exception-filters#exception-filters-1)

While the base (built-in) exception filter can automatically handle many cases for you, you may want **full control** over the exceptions layer. For example, you may want to add logging or use a different JSON schema based on some dynamic factors. **Exception filters** are designed for exactly this purpose. They let you control the exact flow of control and the content of the response sent back to the client.

Let's create an exception filter that is responsible for catching exceptions which are an instance of the `HttpException` class, and implementing custom response logic for them. To do this, we'll need to access the underlying platform `Request` and `Response` objects. We'll access the `Request` object so we can pull out the original `url` and include that in the logging information. We'll use the `Response` object to take direct control of the response that is sent, using the `response.json()` method.

http-exception.filter.ts

JS TS

```typescript

import { ExceptionFilter, Catch, ArgumentsHost, HttpException } from '@nestjs/common';
import { Request, Response } from 'express';

@Catch(HttpException)
export class HttpExceptionFilter implements ExceptionFilter {
  catch(exception: HttpException, host: ArgumentsHost) {
    const ctx = host.switchToHttp();
    const response = ctx.getResponse<Response>();
    const request = ctx.getRequest<Request>();
    const status = exception.getStatus();

    response
      .status(status)
      .json({
        statusCode: status,
        timestamp: new Date().toISOString(),
        path: request.url,
      });
  }
}
```

```typescript

import { Catch, HttpException } from '@nestjs/common';

@Catch(HttpException)
export class HttpExceptionFilter {
  catch(exception, host) {
    const ctx = host.switchToHttp();
    const response = ctx.getResponse();
    const request = ctx.getRequest();
    const status = exception.getStatus();

    response
      .status(status)
      .json({
        statusCode: status,
        timestamp: new Date().toISOString(),
        path: request.url,
      });
  }
}
```

> **Hint** All exception filters should implement the generic `ExceptionFilter<T>` interface. This requires you to provide the `catch(exception: T, host: ArgumentsHost)` method with its indicated signature. `T` indicates the type of the exception.

> **Warning** If you are using `@nestjs/platform-fastify` you can use `response.send()` instead of `response.json()`. Don't forget to import the correct types from `fastify`.

The `@Catch(HttpException)` decorator binds the required metadata to the exception filter, telling Nest that this particular filter is looking for exceptions of type `HttpException` and nothing else. The `@Catch()` decorator may take a single parameter, or a comma-separated list. This lets you set up the filter for several types of exceptions at once.

#### Arguments host[#](/exception-filters#arguments-host)

Let's look at the parameters of the `catch()` method. The `exception` parameter is the exception object currently being processed. The `host` parameter is an `ArgumentsHost` object. `ArgumentsHost` is a powerful utility object that we'll examine further in the [execution context chapter](/v10/fundamentals/execution-context)\*. In this code sample, we use it to obtain a reference to the `Request` and `Response` objects that are being passed to the original request handler (in the controller where the exception originates). In this code sample, we've used some helper methods on `ArgumentsHost` to get the desired `Request` and `Response` objects. Learn more about `ArgumentsHost`[here](/v10/fundamentals/execution-context).

```typescript

@Post()
@UseFilters(new HttpExceptionFilter())
async create(@Body() createCatDto: CreateCatDto) {
  throw new ForbiddenException();
}
```

```typescript

@Post()
@UseFilters(new HttpExceptionFilter())
@Bind(Body())
async create(createCatDto) {
  throw new ForbiddenException();
}
```

> **Hint** The `@UseFilters()` decorator is imported from the `@nestjs/common` package.

We have used the `@UseFilters()` decorator here. Similar to the `@Catch()` decorator, it can take a single filter instance, or a comma-separated list of filter instances. Here, we created the instance of `HttpExceptionFilter` in place. Alternatively, you may pass the class (instead of an instance), leaving responsibility for instantiation to the framework, and enabling **dependency injection**.

cats.controller.ts

JS TS

```typescript

@Post()
@UseFilters(HttpExceptionFilter)
async create(@Body() createCatDto: CreateCatDto) {
  throw new ForbiddenException();
}
```

```typescript

@Post()
@UseFilters(HttpExceptionFilter)
@Bind(Body())
async create(createCatDto) {
  throw new ForbiddenException();
}
```

> **Hint** Prefer applying filters by using classes instead of instances when possible. It reduces **memory usage** since Nest can easily reuse instances of the same class across your entire module.

In the example above, the `HttpExceptionFilter` is applied only to the single `create()` route handler, making it method-scoped. Exception filters can be scoped at different levels: method-scoped of the controller/resolver/gateway, controller-scoped, or global-scoped. For example, to set up a filter as controller-scoped, you would do the following:

cats.controller.ts

JS TS

```typescript

@UseFilters(new HttpExceptionFilter())
export class CatsController {}
```

This construction sets up the `HttpExceptionFilter` for every route handler defined inside the `CatsController`.

To create a global-scoped filter, you would do the following:

main.ts

JS TS

```typescript

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.useGlobalFilters(new HttpExceptionFilter());
  await app.listen(process.env.PORT ?? 3000);
}
bootstrap();
```

> **Warning** The `useGlobalFilters()` method does not set up filters for gateways or hybrid applications.

Global-scoped filters are used across the whole application, for every controller and every route handler. In terms of dependency injection, global filters registered from outside of any module (with `useGlobalFilters()` as in the example above) cannot inject dependencies since this is done outside the context of any module. In order to solve this issue, you can register a global-scoped filter **directly from any module** using the following construction:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { APP_FILTER } from '@nestjs/core';

@Module({
  providers: [
    {
      provide: APP_FILTER,
      useClass: HttpExceptionFilter,
    },
  ],
})
export class AppModule {}
```

> **Hint** When using this approach to perform dependency injection for the filter, note that regardless of the module where this construction is employed, the filter is, in fact, global. Where should this be done? Choose the module where the filter (`HttpExceptionFilter` in the example above) is defined. Also, `useClass` is not the only way of dealing with custom provider registration. Learn more [here](/v10/fundamentals/custom-providers).

You can add as many filters with this technique as needed; simply add each to the providers array.

#### Catch everything[#](/exception-filters#catch-everything)

In order to catch **every** unhandled exception (regardless of the exception type), leave the `@Catch()` decorator's parameter list empty, e.g., `@Catch()`.

In the example below we have a code that is platform-agnostic because it uses the [HTTP adapter](./faq/http-adapter) to deliver the response, and doesn't use any of the platform-specific objects (`Request` and `Response`) directly:

```typescript

import {
  ExceptionFilter,
  Catch,
  ArgumentsHost,
  HttpException,
  HttpStatus,
} from '@nestjs/common';
import { HttpAdapterHost } from '@nestjs/core';

@Catch()
export class CatchEverythingFilter implements ExceptionFilter {
  constructor(private readonly httpAdapterHost: HttpAdapterHost) {}

  catch(exception: unknown, host: ArgumentsHost): void {
    // In certain situations `httpAdapter` might not be available in the
    // constructor method, thus we should resolve it here.
    const { httpAdapter } = this.httpAdapterHost;

    const ctx = host.switchToHttp();

    const httpStatus =
      exception instanceof HttpException
        ? exception.getStatus()
        : HttpStatus.INTERNAL_SERVER_ERROR;

    const responseBody = {
      statusCode: httpStatus,
      timestamp: new Date().toISOString(),
      path: httpAdapter.getRequestUrl(ctx.getRequest()),
    };

    httpAdapter.reply(ctx.getResponse(), responseBody, httpStatus);
  }
}
```

> **Warning** When combining an exception filter that catches everything with a filter that is bound to a specific type, the "Catch anything" filter should be declared first to allow the specific filter to correctly handle the bound type.

#### Inheritance[#](/exception-filters#inheritance)

Typically, you'll create fully customized exception filters crafted to fulfill your application requirements. However, there might be use-cases when you would like to simply extend the built-in default **global exception filter**, and override the behavior based on certain factors.

In order to delegate exception processing to the base filter, you need to extend `BaseExceptionFilter` and call the inherited `catch()` method.

all-exceptions.filter.ts

JS TS

```typescript

import { Catch, ArgumentsHost } from '@nestjs/common';
import { BaseExceptionFilter } from '@nestjs/core';

@Catch()
export class AllExceptionsFilter extends BaseExceptionFilter {
  catch(exception: unknown, host: ArgumentsHost) {
    super.catch(exception, host);
  }
}
```

```typescript

import { Catch } from '@nestjs/common';
import { BaseExceptionFilter } from '@nestjs/core';

@Catch()
export class AllExceptionsFilter extends BaseExceptionFilter {
  catch(exception, host) {
    super.catch(exception, host);
  }
}
```

> **Warning** Method-scoped and Controller-scoped filters that extend the `BaseExceptionFilter` should not be instantiated with `new`. Instead, let the framework instantiate them automatically.

Global filters **can** extend the base filter. This can be done in either of two ways.

The first method is to inject the `HttpAdapter` reference when instantiating the custom global filter:

```typescript

async function bootstrap() {
  const app = await NestFactory.create(AppModule);

  const { httpAdapter } = app.get(HttpAdapterHost);
  app.useGlobalFilters(new AllExceptionsFilter(httpAdapter));

  await app.listen(process.env.PORT ?? 3000);
}
bootstrap();
```

The second method is to use the `APP_FILTER` token [as shown here](exception-filters#binding-filters).

----
url: https://docs.nestjs.com/v7/faq
----

----
url: https://docs.nestjs.com/v8/modules
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Modules](https://docs.nestjs.com/v8/modules#modules)
* [Feature modules](https://docs.nestjs.com/v8/modules#feature-modules)
* [Shared modules](https://docs.nestjs.com/v8/modules#shared-modules)
* [Module re-exporting](https://docs.nestjs.com/v8/modules#module-re-exporting)
* [Dependency injection](https://docs.nestjs.com/v8/modules#dependency-injection)
* [Global modules](https://docs.nestjs.com/v8/modules#global-modules)
* [Dynamic modules](https://docs.nestjs.com/v8/modules#dynamic-modules)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/modules.md "Suggest Edits")

### Modules

A module is a class annotated with a `@Module()` decorator. The `@Module()` decorator provides metadata that **Nest** makes use of to organize the application structure.

Each application has at least one module, a **root module**. The root module is the starting point Nest uses to build the **application graph** - the internal data structure Nest uses to resolve module and provider relationships and dependencies. While very small applications may theoretically have just the root module, this is not the typical case. We want to emphasize that modules are **strongly** recommended as an effective way to organize your components. Thus, for most applications, the resulting architecture will employ multiple modules, each encapsulating a closely related set of **capabilities**.

The `@Module()` decorator takes a single object whose properties describe the module:

| `providers`   | the providers that will be instantiated by the Nest injector and that may be shared at least across this module                                                                                          |
| ------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `controllers` | the set of controllers defined in this module which have to be instantiated                                                                                                                              |
| `imports`     | the list of imported modules that export the providers which are required in this module                                                                                                                 |
| `exports`     | the subset of `providers` that are provided by this module and should be available in other modules which import this module. You can use either the provider itself or just its token (`provide` value) |

The module **encapsulates** providers by default. This means that it's impossible to inject providers that are neither directly part of the current module nor exported from the imported modules. Thus, you may consider the exported providers from a module as the module's public interface, or API.

#### Feature modules[#](/modules#feature-modules)

The `CatsController` and `CatsService` belong to the same application domain. As they are closely related, it makes sense to move them into a feature module. A feature module simply organizes code relevant for a specific feature, keeping code organized and establishing clear boundaries. This helps us manage complexity and develop with [SOLID](https://en.wikipedia.org/wiki/SOLID) principles, especially as the size of the application and/or team grow.

To demonstrate this, we'll create the `CatsModule`.

cats/cats.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

@Module({
  controllers: [CatsController],
  providers: [CatsService],
})
export class CatsModule {}
```

> **Hint** To create a module using the CLI, simply execute the `$ nest g module cats` command.

Above, we defined the `CatsModule` in the `cats.module.ts` file, and moved everything related to this module into the `cats` directory. The last thing we need to do is import this module into the root module (the `AppModule`, defined in the `app.module.ts` file).

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { CatsModule } from './cats/cats.module';

@Module({
  imports: [CatsModule],
})
export class AppModule {}
```

```typescript

import { Module } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

@Module({
  controllers: [CatsController],
  providers: [CatsService],
  exports: [CatsService]
})
export class CatsModule {}
```

```typescript

@Module({
  imports: [CommonModule],
  exports: [CommonModule],
})
export class CoreModule {}
```

#### Dependency injection[#](/modules#dependency-injection)

A module class can **inject** providers as well (e.g., for configuration purposes):

cats.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

@Module({
  controllers: [CatsController],
  providers: [CatsService],
})
export class CatsModule {
  constructor(private catsService: CatsService) {}
}
```

```typescript

import { Module, Dependencies } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

@Module({
  controllers: [CatsController],
  providers: [CatsService],
})
@Dependencies(CatsService)
export class CatsModule {
  constructor(catsService) {
    this.catsService = catsService;
  }
}
```

However, module classes themselves cannot be injected as providers due to [circular dependency](/v8/fundamentals/circular-dependency) .

#### Global modules[#](/modules#global-modules)

If you have to import the same set of modules everywhere, it can get tedious. Unlike in Nest, [Angular](https://angular.io)`providers` are registered in the global scope. Once defined, they're available everywhere. Nest, however, encapsulates providers inside the module scope. You aren't able to use a module's providers elsewhere without first importing the encapsulating module.

When you want to provide a set of providers which should be available everywhere out-of-the-box (e.g., helpers, database connections, etc.), make the module **global** with the `@Global()` decorator.

```typescript

import { Module, Global } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

@Global()
@Module({
  controllers: [CatsController],
  providers: [CatsService],
  exports: [CatsService],
})
export class CatsModule {}
```

The `@Global()` decorator makes the module global-scoped. Global modules should be registered **only once**, generally by the root or core module. In the above example, the `CatsService` provider will be ubiquitous, and modules that wish to inject the service will not need to import the `CatsModule` in their imports array.

> **Hint** Making everything global is not a good design decision. Global modules are available to reduce the amount of necessary boilerplate. The `imports` array is generally the preferred way to make the module's API available to consumers.

#### Dynamic modules[#](/modules#dynamic-modules)

The Nest module system includes a powerful feature called **dynamic modules**. This feature enables you to easily create customizable modules that can register and configure providers dynamically. Dynamic modules are covered extensively [here](/v8/fundamentals/dynamic-modules). In this chapter, we'll give a brief overview to complete the introduction to modules.

Following is an example of a dynamic module definition for a `DatabaseModule`:

JS TS

```typescript

import { Module, DynamicModule } from '@nestjs/common';
import { createDatabaseProviders } from './database.providers';
import { Connection } from './connection.provider';

@Module({
  providers: [Connection],
})
export class DatabaseModule {
  static forRoot(entities = [], options?): DynamicModule {
    const providers = createDatabaseProviders(options, entities);
    return {
      module: DatabaseModule,
      providers: providers,
      exports: providers,
    };
  }
}
```

```typescript

import { Module } from '@nestjs/common';
import { createDatabaseProviders } from './database.providers';
import { Connection } from './connection.provider';

@Module({
  providers: [Connection],
})
export class DatabaseModule {
  static forRoot(entities = [], options?) {
    const providers = createDatabaseProviders(options, entities);
    return {
      module: DatabaseModule,
      providers: providers,
      exports: providers,
    };
  }
}
```

> **Hint** The `forRoot()` method may return a dynamic module either synchronously or asynchronously (i.e., via a `Promise`).

This module defines the `Connection` provider by default (in the `@Module()` decorator metadata), but additionally - depending on the `entities` and `options` objects passed into the `forRoot()` method - exposes a collection of providers, for example, repositories. Note that the properties returned by the dynamic module **extend** (rather than override) the base module metadata defined in the `@Module()` decorator. That's how both the statically declared `Connection` provider **and** the dynamically generated repository providers are exported from the module.

If you want to register a dynamic module in the global scope, set the `global` property to `true`.

```typescript

{
  global: true,
  module: DatabaseModule,
  providers: providers,
  exports: providers,
}
```

> **Warning** As mentioned above, making everything global **is not a good design decision**.

The `DatabaseModule` can be imported and configured in the following manner:

```typescript

import { Module } from '@nestjs/common';
import { DatabaseModule } from './database/database.module';
import { User } from './users/entities/user.entity';

@Module({
  imports: [DatabaseModule.forRoot([User])],
})
export class AppModule {}
```

If you want to in turn re-export a dynamic module, you can omit the `forRoot()` method call in the exports array:

```typescript

import { Module } from '@nestjs/common';
import { DatabaseModule } from './database/database.module';
import { User } from './users/entities/user.entity';

@Module({
  imports: [DatabaseModule.forRoot([User])],
  exports: [DatabaseModule],
})
export class AppModule {}
```

The [Dynamic modules](/v8/fundamentals/dynamic-modules) chapter covers this topic in greater detail, and includes a [working example](https://github.com/nestjs/nest/tree/master/sample/25-dynamic-modules).

----
url: https://docs.nestjs.com/v9/devtools/ci-cd-integration
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [CI/CD integration](https://docs.nestjs.com/v9/devtools/ci-cd-integration#cicd-integration)
* [Publishing graphs](https://docs.nestjs.com/v9/devtools/ci-cd-integration#publishing-graphs)
* [Reports](https://docs.nestjs.com/v9/devtools/ci-cd-integration#reports)
* [Build preview](https://docs.nestjs.com/v9/devtools/ci-cd-integration#build-preview)
* [Integrations: Github Actions](https://docs.nestjs.com/v9/devtools/ci-cd-integration#integrations-github-actions)
* [Integrations: Gitlab Pipelines](https://docs.nestjs.com/v9/devtools/ci-cd-integration#integrations-gitlab-pipelines)
* [Other CI/CD tools](https://docs.nestjs.com/v9/devtools/ci-cd-integration#other-cicd-tools)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/devtools/ci-cd.md "Suggest Edits")

### CI/CD integration

> **Hint** This chapter covers the Nest Devtools integration with the Nest framework. If you are looking for the Devtools application, please visit the [Devtools](https://devtools.nestjs.com) website.

CI/CD integration is available for users with the **[Enterprise](/v9/settings)** plan.

You can watch this video to learn why & how CI/CD integration can help you:

#### Publishing graphs[#](/devtools/ci-cd-integration#publishing-graphs)

Let's first configure the application bootstrap file (`main.ts`) to use the `GraphPublisher` class (exported from the `@nestjs/devtools-integration` - see previous chapter for more details), as follows:

```typescript

async function bootstrap() {
  const shouldPublishGraph = process.env.PUBLISH_GRAPH === "true";

  const app = await NestFactory.create(AppModule, {
    snapshot: true,
    preview: shouldPublishGraph,
  });

  if (shouldPublishGraph) {
    await app.init();

    const publishOptions = { ... } // NOTE: this options object will vary depending on the CI/CD provider you're using
    const graphPublisher = new GraphPublisher(app);
    await graphPublisher.publish(publishOptions);

    await app.close();
  } else {
    await app.listen(3000);
  }
}
```

As we can see, we're using the `GraphPublisher` here to publish our serialized graph to the centralized registry. The `PUBLISH_GRAPH` is a custom environment variable that will let us control whether the graph should be published (CI/CD workflow), or not (regular application bootstrap). Also, we set the `preview` attribute here to `true`. With this flag enabled, our application will bootstrap in the preview mode - which basically means that constructors (and lifecycle hooks) of all controllers, enhancers, and providers in our application will not be executed. Note - this isn't **required**, but makes things simpler for us since in this case we won't really have to connect to the database etc. when running our application in the CI/CD pipeline.

The `publishOptions` object will vary depending on the CI/CD provider you're using. We will provide you with instructions for the most popular CI/CD providers below, in later sections.

Once the graph is successfully published, you'll see the following output in your workflow view:

Every time our graph is published, we should see a new entry in the project's corresponding page:

#### Reports[#](/devtools/ci-cd-integration#reports)

Devtools generate a report for every build **IF** there's a corresponding snapshot already stored in the centralized registry. So for example, if you create a PR against the `master` branch for which the graph was already published - then the application will be able to detect differences and generate a report. Otherwise, the report will not be generated.

To see reports, navigate to the project's corresponding page (see organizations).

This is particularly helpful in identifying changes that may have gone unnoticed during code reviews. For instance, let's say someone has changed the scope of a **deeply nested provider**. This change might not be immediately obvious to the reviewer, but with Devtools, we can easily spot such changes and make sure that they're intentional. Or if we remove a guard from a specific endpoint, it will show up as affected in the report. Now if we didn't have integration or e2e tests for that route, we might not notice that it's no longer protected, and by the time we do, it could be too late.

Similarly, if we're working on a **large codebase** and we modify a module to be global, we'll see how many edges were added to the graph, and this - in most cases - is a sign that we're doing something wrong.

#### Build preview[#](/devtools/ci-cd-integration#build-preview)

For every published graph we can go back in time and preview how it looked before by clicking at the **Preview** button. Furthermore, if the report was generated, we should see the differences higlighted on our graph:

* green nodes represent added elements
* light white nodes represent updated elements
* red nodes represent deleted elements

See screenshot below:

The ability to go back in time lets you investigate and troubleshoot the issue by comparing the current graph with the previous one. Depending on how you set things up, every pull request (or even every commit) will have a corresponding snapshot in the registry, so you can easily go back in time and see what changed. Think of Devtools as a Git but with an understanding of how Nest constructs your application graph, and with the ability to **visualize** it.

#### Integrations: Github Actions[#](/devtools/ci-cd-integration#integrations-github-actions)

First let's start from creating a new Github workflow in the `.github/workflows` directory in our project and call it, for example, `publish-graph.yml`. Inside this file, let's use the following definition:

```yaml

name: Devtools

on:
  push:
    branches:
      - master
  pull_request:
    branches:
      - '*'

jobs:
  publish:
    if: github.actor!= 'dependabot[bot]'
    name: Publish graph
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: '16'
          cache: 'npm'
      - name: Install dependencies
        run: npm ci
      - name: Setup Environment (PR)
        if: ${{ github.event_name == 'pull_request' }}
        shell: bash
        run: |
          echo "COMMIT_SHA=${{ github.event.pull_request.head.sha }}" >>\${GITHUB_ENV}
      - name: Setup Environment (Push)
        if: ${{ github.event_name == 'push' }}
        shell: bash
        run: |
          echo "COMMIT_SHA=\${GITHUB_SHA}" >> \${GITHUB_ENV}
      - name: Publish
        run: PUBLISH_GRAPH=true npm run start
        env:
          DEVTOOLS_API_KEY: CHANGE_THIS_TO_YOUR_API_KEY
          REPOSITORY_NAME: ${{ github.event.repository.name }}
          BRANCH_NAME: ${{ github.head_ref || github.ref_name }}
          TARGET_SHA: ${{ github.event.pull_request.base.sha }}
```

Ideally, `DEVTOOLS_API_KEY` environment variable should be retrieved from Github Secrets, read more [here](https://docs.github.com/en/actions/security-guides/encrypted-secrets#creating-encrypted-secrets-for-a-repository) .

This workflow will run per each pull request that's targeting the `master` branch OR in case there's a direct commit to the `master` branch. Feel free to align this configuration to whatever your project needs. What's essential here is that we provide necessary environment varaiables for our `GraphPublisher` class (to run).

However, there's one variable that needs to be updated before we can start using this workflow - `DEVTOOLS_API_KEY`. We can generate an API key dedicated for our project on this **page** .

Lastly, let's navigate to the `main.ts` file again and update the `publishOptions` object we previously left empty.

```typescript

const publishOptions = {
  apiKey: process.env.DEVTOOLS_API_KEY,
  repository: process.env.REPOSITORY_NAME,
  owner: process.env.GITHUB_REPOSITORY_OWNER,
  sha: process.env.COMMIT_SHA,
  target: process.env.TARGET_SHA,
  trigger: process.env.GITHUB_BASE_REF ? 'pull' : 'push',
  branch: process.env.BRANCH_NAME,
};
```

For the best developer experience, make sure to integrate the **Github application** for your project by clicking on the "Integrate Github app" button (see screenshot below). Note - this isn't required.

With this integration, you'll be able to see the status of the preview/report generation process right in your pull request:

#### Integrations: Gitlab Pipelines[#](/devtools/ci-cd-integration#integrations-gitlab-pipelines)

First let's start from creating a new Gitlab CI configuration file in the root directory of our project and call it, for example, `.gitlab-ci.yml`. Inside this file, let's use the following definition:

```typescript

const publishOptions = {
  apiKey: process.env.DEVTOOLS_API_KEY,
  repository: process.env.REPOSITORY_NAME,
  owner: process.env.GITHUB_REPOSITORY_OWNER,
  sha: process.env.COMMIT_SHA,
  target: process.env.TARGET_SHA,
  trigger: process.env.GITHUB_BASE_REF ? 'pull' : 'push',
  branch: process.env.BRANCH_NAME,
};
```

> **Hint** Ideally, `DEVTOOLS_API_KEY` environment variable should be retrieved from secrets.

This workflow will run per each pull request that's targeting the `master` branch OR in case there's a direct commit to the `master` branch. Feel free to align this configuration to whatever your project needs. What's essential here is that we provide necessary environment variables for our `GraphPublisher` class (to run).

However, there's one variable (in this workflow definition) that needs to be updated before we can start using this workflow - `DEVTOOLS_API_KEY`. We can generate an API key dedicated for our project on this **page** .

Lastly, let's navigate to the `main.ts` file again and update the `publishOptions` object we previously left empty.

```yaml

image: node:16

stages:
  - build

cache:
  key:
    files:
      - package-lock.json
  paths:
    - node_modules/

workflow:
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
      when: always
    - if: $CI_COMMIT_BRANCH == "master" && $CI_PIPELINE_SOURCE == "push"
      when: always
    - when: never

install_dependencies:
  stage: build
  script:
    - npm ci

publish_graph:
  stage: build
  needs:
    - install_dependencies
  script: npm run start
  variables:
    PUBLISH_GRAPH: 'true'
    DEVTOOLS_API_KEY: 'CHANGE_THIS_TO_YOUR_API_KEY'
```

#### Other CI/CD tools[#](/devtools/ci-cd-integration#other-cicd-tools)

Nest Devtools CI/CD integration can be used with any CI/CD tool of your choice (e.g., [Bitbucket Pipelines](https://bitbucket.org/product/features/pipelines) , [CircleCI](https://circleci.com/), etc) so don't feel limited to providers we described here.

Look at the following `publishOptions` object configuration to understand what information is required to publish the graph for a given commit/build/PR.

```typescript

const publishOptions = {
  apiKey: process.env.DEVTOOLS_API_KEY,
  repository: process.env.CI_PROJECT_NAME,
  owner: process.env.CI_PROJECT_ROOT_NAMESPACE,
  sha: process.env.CI_COMMIT_SHA,
  target: process.env.CI_MERGE_REQUEST_DIFF_BASE_SHA,
  trigger: process.env.CI_MERGE_REQUEST_DIFF_BASE_SHA ? 'pull' : 'push',
  branch:
    process.env.CI_COMMIT_BRANCH ??
    process.env.CI_MERGE_REQUEST_SOURCE_BRANCH_NAME,
};
```

Most of this information is provided through CI/CD built-in environment variables (see [CircleCI built-in environment list](https://circleci.com/docs/variables/#built-in-environment-variables) and [Bitbucket variables](https://support.atlassian.com/bitbucket-cloud/docs/variables-and-secrets/) ).

When it comes to the pipeline configuration for publishing graphs, we recommend using the following triggers:

* `push` event - only if the current branch represents a deployment environment, for example `master`, `main`, `staging`, `production`, etc.
* `pull request` event - always, or when the **target branch** represents a deployment environment (see above)

----
url: https://docs.nestjs.com/v5/faq/hybrid-application
----

### Hybrid Application

The **hybrid application** is an application that listens for HTTP requests, as well as makes use of connected microservices The `INestApplication` can be combined with the endless number of the `INestMicroservice` instances through `connectMicroservice()` method.

TypeScript

```typescript

const app = await NestFactory.create(ApplicationModule);
const microservice = app.connectMicroservice({
  transport: Transport.TCP,
});

await app.startAllMicroservicesAsync();
await app.listen(3001);
```

* Hybrid Application

----
url: https://docs.nestjs.com/v11/pipes
----

* [Pipes](https://docs.nestjs.com/v11/pipes#pipes)
* [Built-in pipes](https://docs.nestjs.com/v11/pipes#built-in-pipes)
* [Binding pipes](https://docs.nestjs.com/v11/pipes#binding-pipes)
* [Custom pipes](https://docs.nestjs.com/v11/pipes#custom-pipes)
* [Schema based validation](https://docs.nestjs.com/v11/pipes#schema-based-validation)
* [Object schema validation](https://docs.nestjs.com/v11/pipes#object-schema-validation)
* [Binding validation pipes](https://docs.nestjs.com/v11/pipes#binding-validation-pipes)
* [Class validator](https://docs.nestjs.com/v11/pipes#class-validator)
* [Global scoped pipes](https://docs.nestjs.com/v11/pipes#global-scoped-pipes)
* [The built-in ValidationPipe](https://docs.nestjs.com/v11/pipes#the-built-in-validationpipe)
* [Transformation use case](https://docs.nestjs.com/v11/pipes#transformation-use-case)
* [Providing defaults](https://docs.nestjs.com/v11/pipes#providing-defaults)

> **Hint** Pipes run inside the exceptions zone. This means that when a Pipe throws an exception it is handled by the exceptions layer (global exceptions filter and any [exceptions filters](/v11/exception-filters) that are applied to the current context). Given the above, it should be clear that when an exception is thrown in a Pipe, no controller method is subsequently executed. This gives you a best-practice technique for validating data coming into the application from external sources at the system boundary.

#### Built-in pipes[#](/pipes#built-in-pipes)

Nest comes with several pipes available out-of-the-box:

* `ValidationPipe`

They're exported from the `@nestjs/common` package.

Let's take a quick look at using `ParseIntPipe`. This is an example of the **transformation** use case, where the pipe ensures that a method handler parameter is converted to a JavaScript integer (or throws an exception if the conversion fails). Later in this chapter, we'll show a simple custom implementation for a `ParseIntPipe`. The example techniques below also apply to the other built-in transformation pipes (`ParseBoolPipe`, `ParseFloatPipe`, `ParseEnumPipe`, `ParseArrayPipe`, `ParseDatePipe`, and `ParseUUIDPipe`, which we'll refer to as the `Parse*` pipes in this chapter).

#### Binding pipes[#](/pipes#binding-pipes)

To use a pipe, we need to bind an instance of the pipe class to the appropriate context. In our `ParseIntPipe` example, we want to associate the pipe with a particular route handler method, and make sure it runs before the method is called. We do so with the following construct, which we'll refer to as binding the pipe at the method parameter level:

```typescript

@Get(':id')
async findOne(@Param('id', ParseIntPipe) id: number) {
  return this.catsService.findOne(id);
}
```

This ensures that one of the following two conditions is true: either the parameter we receive in the `findOne()` method is a number (as expected in our call to `this.catsService.findOne()`), or an exception is thrown before the route handler is called.

For example, assume the route is called like:

```bash

GET localhost:3000/abc
```

Nest will throw an exception like this:

```json

{
  "statusCode": 400,
  "message": "Validation failed (numeric string is expected)",
  "error": "Bad Request"
}
```

The exception will prevent the body of the `findOne()` method from executing.

In the example above, we pass a class (`ParseIntPipe`), not an instance, leaving responsibility for instantiation to the framework and enabling dependency injection. As with pipes and guards, we can instead pass an in-place instance. Passing an in-place instance is useful if we want to customize the built-in pipe's behavior by passing options:

```typescript

@Get(':id')
async findOne(
  @Param('id', new ParseIntPipe({ errorHttpStatusCode: HttpStatus.NOT_ACCEPTABLE }))
  id: number,
) {
  return this.catsService.findOne(id);
}
```

Binding the other transformation pipes (all of the **Parse\*** pipes) works similarly. These pipes all work in the context of validating route parameters, query string parameters and request body values.

For example with a query string parameter:

```typescript

@Get()
async findOne(@Query('id', ParseIntPipe) id: number) {
  return this.catsService.findOne(id);
}
```

Here's an example of using the `ParseUUIDPipe` to parse a string parameter and validate if it is a UUID.

JS TS

```typescript

@Get(':uuid')
async findOne(@Param('uuid', new ParseUUIDPipe()) uuid: string) {
  return this.catsService.findOne(uuid);
}
```

```typescript

@Get(':uuid')
@Bind(Param('uuid', new ParseUUIDPipe()))
async findOne(uuid) {
  return this.catsService.findOne(uuid);
}
```

> **Hint** When using `ParseUUIDPipe()` you are parsing UUID in version 3, 4 or 5, if you only require a specific version of UUID you can pass a version in the pipe options.

Above we've seen examples of binding the various `Parse*` family of built-in pipes. Binding validation pipes is a little bit different; we'll discuss that in the following section.

> **Hint** Also, see [Validation techniques](/v11/techniques/validation) for extensive examples of validation pipes.

#### Custom pipes[#](/pipes#custom-pipes)

As mentioned, you can build your own custom pipes. While Nest provides a robust built-in `ParseIntPipe` and `ValidationPipe`, let's build simple custom versions of each from scratch to see how custom pipes are constructed.

We start with a simple `ValidationPipe`. Initially, we'll have it simply take an input value and immediately return the same value, behaving like an identity function.

validation.pipe.ts

JS TS

```typescript

import { PipeTransform, Injectable, ArgumentMetadata } from '@nestjs/common';

@Injectable()
export class ValidationPipe implements PipeTransform {
  transform(value: any, metadata: ArgumentMetadata) {
    return value;
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';

@Injectable()
export class ValidationPipe {
  transform(value, metadata) {
    return value;
  }
}
```

> **Hint**`PipeTransform<T, R>` is a generic interface that must be implemented by any pipe. The generic interface uses `T` to indicate the type of the input `value`, and `R` to indicate the return type of the `transform()` method.

Every pipe must implement the `transform()` method to fulfill the `PipeTransform` interface contract. This method has two parameters:

* `value`
* `metadata`

The `value` parameter is the currently processed method argument (before it is received by the route handling method), and `metadata` is the currently processed method argument's metadata. The metadata object has these properties:

```typescript

export interface ArgumentMetadata {
  type: 'body' | 'query' | 'param' | 'custom';
  metatype?: Type<unknown>;
  data?: string;
}
```

These properties describe the currently processed argument.

|            |                                                                                                                                                                                                      |
| ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `type`     | Indicates whether the argument is a body `@Body()`, query `@Query()`, param `@Param()`, or a custom parameter (read more [here](/v11/custom-decorators)).                                            |
| `metatype` | Provides the metatype of the argument, for example, `String`. Note: the value is `undefined` if you either omit a type declaration in the route handler method signature, or use vanilla JavaScript. |
| `data`     | The string passed to the decorator, for example `@Body('string')`. It's `undefined` if you leave the decorator parenthesis empty.                                                                    |

> **Warning** TypeScript interfaces disappear during transpilation. Thus, if a method parameter's type is declared as an interface instead of a class, the `metatype` value will be `Object`.

#### Schema based validation[#](/pipes#schema-based-validation)

Let's make our validation pipe a little more useful. Take a closer look at the `create()` method of the `CatsController`, where we probably would like to ensure that the post body object is valid before attempting to run our service method.

JS TS

```typescript

@Post()
async create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

```typescript

@Post()
async create(@Body() createCatDto) {
  this.catsService.create(createCatDto);
}
```

Let's focus in on the `createCatDto` body parameter. Its type is `CreateCatDto`:

create-cat.dto.ts

JS TS

```typescript

export class CreateCatDto {
  name: string;
  age: number;
  breed: string;
}
```

```bash

$ npm install --save zod
```

In the code sample below, we create a simple class that takes a schema as a `constructor` argument. We then apply the `schema.parse()` method, which validates our incoming argument against the provided schema.

As noted earlier, a **validation pipe** either returns the value unchanged or throws an exception.

In the next section, you'll see how we supply the appropriate schema for a given controller method using the `@UsePipes()` decorator. Doing so makes our validation pipe reusable across contexts, just as we set out to do.

JS TS

```typescript

import { PipeTransform, ArgumentMetadata, BadRequestException } from '@nestjs/common';
import { ZodSchema  } from 'zod';

export class ZodValidationPipe implements PipeTransform {
  constructor(private schema: ZodSchema) {}

  transform(value: unknown, metadata: ArgumentMetadata) {
    try {
      const parsedValue = this.schema.parse(value);
      return parsedValue;
    } catch (error) {
      throw new BadRequestException('Validation failed');
    }
  }
}
```

```typescript

import { BadRequestException } from '@nestjs/common';

export class ZodValidationPipe {
  constructor(private schema) {}

  transform(value, metadata) {
    try {
      const parsedValue = this.schema.parse(value);
      return parsedValue;
    } catch (error) {
      throw new BadRequestException('Validation failed');
    }
  }
}
```

```typescript

import { z } from 'zod';

export const createCatSchema = z
  .object({
    name: z.string(),
    age: z.number(),
    breed: z.string(),
  })
  .required();

export type CreateCatDto = z.infer<typeof createCatSchema>;
```

We do that using the `@UsePipes()` decorator as shown below:

cats.controller.ts

JS TS

```typescript

@Post()
@UsePipes(new ZodValidationPipe(createCatSchema))
async create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

```typescript

@Post()
@Bind(Body())
@UsePipes(new ZodValidationPipe(createCatSchema))
async create(createCatDto) {
  this.catsService.create(createCatDto);
}
```

> **Hint** The `@UsePipes()` decorator is imported from the `@nestjs/common` package.

The `ZodValidationPipe` can be applied to specific parameters and alongside built-in pipes. For example, where we want to validate the route path `id` parameter with the `ParseIntPipe` separately from the request body:

```typescript

@Put('/:id')
async update(
  @Param('id', ParseIntPipe) id: number,
  @Body(new ZodValidationPipe(createCatSchema)) body: CreateCatDto
): void {
  this.catsService.update(id, body);
}
```

> **Warning**`zod` library requires the `strictNullChecks` configuration to be enabled in your `tsconfig.json` file.

#### Class validator[#](/pipes#class-validator)

> **Warning** The techniques in this section require TypeScript and are not available if your app is written using vanilla JavaScript.

Let's look at an alternate implementation for our validation technique.

Nest works well with the [class-validator](https://github.com/typestack/class-validator) library. This powerful library allows you to use decorator-based validation. Decorator-based validation is extremely powerful, especially when combined with Nest's **Pipe** capabilities since we have access to the `metatype` of the processed property. Before we start, we need to install the required packages:

```bash

$ npm i --save class-validator class-transformer
```

Once these are installed, we can add a few decorators to the `CreateCatDto` class. Here we see a significant advantage of this technique: the `CreateCatDto` class remains the single source of truth for our Post body object (rather than having to create a separate validation class).

create-cat.dto.ts

JS TS

```typescript

import { IsString, IsInt } from 'class-validator';

export class CreateCatDto {
  @IsString()
  name: string;

  @IsInt()
  age: number;

  @IsString()
  breed: string;
}
```

> **Hint** Read more about the class-validator decorators [here](https://github.com/typestack/class-validator#usage).

Now we can create a `ValidationPipe` class that uses these annotations.

validation.pipe.ts

JS TS

```typescript

import { PipeTransform, Injectable, ArgumentMetadata, BadRequestException } from '@nestjs/common';
import { validate } from 'class-validator';
import { plainToInstance } from 'class-transformer';

@Injectable()
export class ValidationPipe implements PipeTransform<any> {
  async transform(value: any, { metatype }: ArgumentMetadata) {
    if (!metatype || !this.toValidate(metatype)) {
      return value;
    }
    const object = plainToInstance(metatype, value);
    const errors = await validate(object);
    if (errors.length > 0) {
      throw new BadRequestException('Validation failed');
    }
    return value;
  }

  private toValidate(metatype: Function): boolean {
    const types: Function[] = [String, Boolean, Number, Array, Object];
    return !types.includes(metatype);
  }
}
```

> **Hint** As a reminder, you don't have to build a generic validation pipe on your own since the `ValidationPipe` is provided by Nest out-of-the-box. The built-in `ValidationPipe` offers more options than the sample we built in this chapter, which has been kept basic for the sake of illustrating the mechanics of a custom-built pipe. You can find full details, along with lots of examples [here](/v11/techniques/validation).

> **Notice** We used the [class-transformer](https://github.com/typestack/class-transformer) library above which is made by the same author as the **class-validator** library, and as a result, they play very well together.

```typescript

@Post()
async create(
  @Body(new ValidationPipe()) createCatDto: CreateCatDto,
) {
  this.catsService.create(createCatDto);
}
```

Parameter-scoped pipes are useful when the validation logic concerns only one specified parameter.

#### Global scoped pipes[#](/pipes#global-scoped-pipes)

Since the `ValidationPipe` was created to be as generic as possible, we can realize its full utility by setting it up as a **global-scoped** pipe so that it is applied to every route handler across the entire application.

main.ts

JS TS

```typescript

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.useGlobalPipes(new ValidationPipe());
  await app.listen(process.env.PORT ?? 3000);
}
bootstrap();
```

> **Notice** In the case of [hybrid apps](faq/hybrid-application) the `useGlobalPipes()` method doesn't set up pipes for gateways and microservices. For "standard" (non-hybrid) microservice apps, `useGlobalPipes()` does mount pipes globally.

Global pipes are used across the whole application, for every controller and every route handler.

Note that in terms of dependency injection, global pipes registered from outside of any module (with `useGlobalPipes()` as in the example above) cannot inject dependencies since the binding has been done outside the context of any module. In order to solve this issue, you can set up a global pipe **directly from any module** using the following construction:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { APP_PIPE } from '@nestjs/core';

@Module({
  providers: [
    {
      provide: APP_PIPE,
      useClass: ValidationPipe,
    },
  ],
})
export class AppModule {}
```

> **Hint** When using this approach to perform dependency injection for the pipe, note that regardless of the module where this construction is employed, the pipe is, in fact, global. Where should this be done? Choose the module where the pipe (`ValidationPipe` in the example above) is defined. Also, `useClass` is not the only way of dealing with custom provider registration. Learn more [here](/v11/fundamentals/custom-providers).

#### The built-in ValidationPipe[#](/pipes#the-built-in-validationpipe)

As a reminder, you don't have to build a generic validation pipe on your own since the `ValidationPipe` is provided by Nest out-of-the-box. The built-in `ValidationPipe` offers more options than the sample we built in this chapter, which has been kept basic for the sake of illustrating the mechanics of a custom-built pipe. You can find full details, along with lots of examples [here](/v11/techniques/validation).

#### Transformation use case[#](/pipes#transformation-use-case)

Validation isn't the only use case for custom pipes. At the beginning of this chapter, we mentioned that a pipe can also **transform** the input data to the desired format. This is possible because the value returned from the `transform` function completely overrides the previous value of the argument.

When is this useful? Consider that sometimes the data passed from the client needs to undergo some change - for example converting a string to an integer - before it can be properly handled by the route handler method. Furthermore, some required data fields may be missing, and we would like to apply default values. **Transformation pipes** can perform these functions by interposing a processing function between the client request and the request handler.

Here's a simple `ParseIntPipe` which is responsible for parsing a string into an integer value. (As noted above, Nest has a built-in `ParseIntPipe` that is more sophisticated; we include this as a simple example of a custom transformation pipe).

parse-int.pipe.ts

JS TS

```typescript

import { PipeTransform, Injectable, ArgumentMetadata, BadRequestException } from '@nestjs/common';

@Injectable()
export class ParseIntPipe implements PipeTransform<string, number> {
  transform(value: string, metadata: ArgumentMetadata): number {
    const val = parseInt(value, 10);
    if (isNaN(val)) {
      throw new BadRequestException('Validation failed');
    }
    return val;
  }
}
```

```typescript

import { Injectable, BadRequestException } from '@nestjs/common';

@Injectable()
export class ParseIntPipe {
  transform(value, metadata) {
    const val = parseInt(value, 10);
    if (isNaN(val)) {
      throw new BadRequestException('Validation failed');
    }
    return val;
  }
}
```

We can then bind this pipe to the selected param as shown below:

JS TS

```typescript

@Get(':id')
async findOne(@Param('id', new ParseIntPipe()) id) {
  return this.catsService.findOne(id);
}
```

```typescript

@Get(':id')
@Bind(Param('id', new ParseIntPipe()))
async findOne(id) {
  return this.catsService.findOne(id);
}
```

Another useful transformation case would be to select an **existing user** entity from the database using an id supplied in the request:

JS TS

```typescript

@Get(':id')
findOne(@Param('id', UserByIdPipe) userEntity: UserEntity) {
  return userEntity;
}
```

```typescript

@Get(':id')
@Bind(Param('id', UserByIdPipe))
findOne(userEntity) {
  return userEntity;
}
```

We leave the implementation of this pipe to the reader, but note that like all other transformation pipes, it receives an input value (an `id`) and returns an output value (a `UserEntity` object). This can make your code more declarative and [DRY](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself) by abstracting boilerplate code out of your handler and into a common pipe.

#### Providing defaults[#](/pipes#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:

JS TS

```typescript

@Get()
async findAll(
  @Query('activeOnly', new DefaultValuePipe(false), ParseBoolPipe) activeOnly: boolean,
  @Query('page', new DefaultValuePipe(0), ParseIntPipe) page: number,
) {
  return this.catsService.findAll({ activeOnly, page });
}
```

----
url: https://docs.nestjs.com/v8/microservices/redis
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Redis](https://docs.nestjs.com/v8/microservices/redis#redis)
* [Installation](https://docs.nestjs.com/v8/microservices/redis#installation)
* [Overview](https://docs.nestjs.com/v8/microservices/redis#overview)
* [Options](https://docs.nestjs.com/v8/microservices/redis#options)
* [Client](https://docs.nestjs.com/v8/microservices/redis#client)
* [Context](https://docs.nestjs.com/v8/microservices/redis#context)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/microservices/redis.md "Suggest Edits")

### Redis

The [Redis](https://redis.io/) transporter implements the publish/subscribe messaging paradigm and leverages the [Pub/Sub](https://redis.io/topics/pubsub) feature of Redis. Published messages are categorized in channels, without knowing what subscribers (if any) will eventually receive the message. Each microservice can subscribe to any number of channels. In addition, more than one channel can be subscribed to at a time. Messages exchanged through channels are **fire-and-forget**, which means that if a message is published and there are no subscribers interested in it, the message is removed and cannot be recovered. Thus, you don't have a guarantee that either messages or events will be handled by at least one service. A single message can be subscribed to (and received) by multiple subscribers.

#### Installation[#](/microservices/redis#installation)

To start building Redis-based microservices, first install the required package (note as of now the supported Redis version is ^3, not the latest ^4):

```bash

$ npm i --save redis@^3
```

#### Overview[#](/microservices/redis#overview)

To use the Redis transporter, pass the following options object to the `createMicroservice()` method:

main.ts

JS TS

```typescript

const app = await NestFactory.createMicroservice<MicroserviceOptions>(AppModule, {
  transport: Transport.REDIS,
  options: {
    url: 'redis://localhost:6379',
  },
});
```

```typescript

const app = await NestFactory.createMicroservice(AppModule, {
  transport: Transport.REDIS,
  options: {
    url: 'redis://localhost:6379',
  },
});
```

> **Hint** The `Transport` enum is imported from the `@nestjs/microservices` package.

#### Options[#](/microservices/redis#options)

The `options` property is specific to the chosen transporter. The **Redis** transporter exposes the properties described below.

|                 |                                                          |
| --------------- | -------------------------------------------------------- |
| `url`           | Connection url                                           |
| `retryAttempts` | Number of times to retry message (default: `0`)          |
| `retryDelay`    | Delay between message retry attempts (ms) (default: `0`) |

All the properties supported by the official [redis](https://www.npmjs.com/package/redis#options-object-properties) client are also supported by this transporter.

#### Client[#](/microservices/redis#client)

Like other microservice transporters, you have [several options](https://docs.nestjs.com/microservices/basics#client) for creating a Redis `ClientProxy` instance.

One method for creating an instance is to use the `ClientsModule`. To create a client instance with the `ClientsModule`, import it and use the `register()` method to pass an options object with the same properties shown above in the `createMicroservice()` method, as well as a `name` property to be used as the injection token. Read more about `ClientsModule`[here](https://docs.nestjs.com/microservices/basics#client).

```typescript

@Module({
  imports: [
    ClientsModule.register([
      {
        name: 'MATH_SERVICE',
        transport: Transport.REDIS,
        options: {
          url: 'redis://localhost:6379',
        }
      },
    ]),
  ]
  ...
})
```

Other options to create a client (either `ClientProxyFactory` or `@Client()`) can be used as well. You can read about them [here](https://docs.nestjs.com/microservices/basics#client).

#### Context[#](/microservices/redis#context)

In more sophisticated scenarios, you may want to access more information about the incoming request. When using the Redis transporter, you can access the `RedisContext` object.

JS TS

```typescript

@MessagePattern('notifications')
getNotifications(@Payload() data: number[], @Ctx() context: RedisContext) {
  console.log(`Channel: ${context.getChannel()}`);
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('notifications')
getNotifications(data, context) {
  console.log(`Channel: ${context.getChannel()}`);
}
```

> **Hint**`@Payload()`, `@Ctx()` and `RedisContext` are imported from the `@nestjs/microservices` package.

----
url: https://docs.nestjs.com/v7/openapi/mapped-types
----

* [Mapped types](https://docs.nestjs.com/v7/openapi/mapped-types#mapped-types)
* [Partial](https://docs.nestjs.com/v7/openapi/mapped-types#partial)
* [Pick](https://docs.nestjs.com/v7/openapi/mapped-types#pick)
* [Omit](https://docs.nestjs.com/v7/openapi/mapped-types#omit)
* [Intersection](https://docs.nestjs.com/v7/openapi/mapped-types#intersection)
* [Composition](https://docs.nestjs.com/v7/openapi/mapped-types#composition)

```typescript

import { ApiProperty } from '@nestjs/swagger';

export class CreateCatDto {
  @ApiProperty()
  name: string;

  @ApiProperty()
  age: number;

  @ApiProperty()
  breed: string;
}
```

By default, all of these fields are required. To create a type with the same fields, but with each one optional, use `PartialType()` passing the class reference (`CreateCatDto`) as an argument:

```typescript

export class UpdateCatDto extends PartialType(CreateCatDto) {}
```

> **Hint** The `PartialType()` function is imported from the `@nestjs/swagger` package.

#### Pick[#](/openapi/mapped-types#pick)

The `PickType()` function constructs a new type (class) by picking a set of properties from an input type. For example, suppose we start with a type like:

```typescript

import { ApiProperty } from '@nestjs/swagger';

export class CreateCatDto {
  @ApiProperty()
  name: string;

  @ApiProperty()
  age: number;

  @ApiProperty()
  breed: string;
}
```

We can pick a set of properties from this class using the `PickType()` utility function:

```typescript

export class UpdateCatAgeDto extends PickType(CreateCatDto, ['age'] as const) {}
```

> **Hint** The `PickType()` function is imported from the `@nestjs/swagger` package.

#### Omit[#](/openapi/mapped-types#omit)

The `OmitType()` function constructs a type by picking all properties from an input type and then removing a particular set of keys. For example, suppose we start with a type like:

```typescript

import { ApiProperty } from '@nestjs/swagger';

export class CreateCatDto {
  @ApiProperty()
  name: string;

  @ApiProperty()
  age: number;

  @ApiProperty()
  breed: string;
}
```

We can generate a derived type that has every property **except**`name` as shown below. In this construct, the second argument to `OmitType` is an array of property names.

```typescript

export class UpdateCatDto extends OmitType(CreateCatDto, ['name'] as const) {}
```

> **Hint** The `OmitType()` function is imported from the `@nestjs/swagger` package.

#### Intersection[#](/openapi/mapped-types#intersection)

The `IntersectionType()` function combines two types into one new type (class). For example, suppose we start with two types like:

```typescript

import { ApiProperty } from '@nestjs/swagger';

export class CreateCatDto {
  @ApiProperty()
  name: string;

  @ApiProperty()
  breed: string;
}

export class AdditionalCatInfo {
  @ApiProperty()
  color: string;
}
```

We can generate a new type that combines all properties in both types.

```typescript

export class UpdateCatDto extends IntersectionType(
  CreateCatDto,
  AdditionalCatInfo,
) {}
```

> **Hint** The `IntersectionType()` function is imported from the `@nestjs/swagger` package.

#### Composition[#](/openapi/mapped-types#composition)

The type mapping utility functions are composable. For example, the following will produce a type (class) that has all of the properties of the `CreateCatDto` type except for `name`, and those properties will be set to optional:

```typescript

export class UpdateCatDto extends PartialType(
  OmitType(CreateCatDto, ['name'] as const),
) {}
```

----
url: https://docs.nestjs.com/v8/security/helmet
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Helmet](https://docs.nestjs.com/v8/security/helmet#helmet)
* [Use with Express (default)](https://docs.nestjs.com/v8/security/helmet#use-with-express-default)
* [Use with Fastify](https://docs.nestjs.com/v8/security/helmet#use-with-fastify)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/security/helmet.md "Suggest Edits")

### Helmet

[Helmet](https://github.com/helmetjs/helmet) can help protect your app from some well-known web vulnerabilities by setting HTTP headers appropriately. Generally, Helmet is just a collection of smaller middleware functions that set security-related HTTP headers (read [more](https://github.com/helmetjs/helmet#how-it-works)).

> **Hint** Note that applying `helmet` as global or registering it must come before other calls to `app.use()` or setup functions that may call `app.use()`. This is due to the way the underlying platform (i.e., Express or Fastify) works, where the order that middleware/routes are defined matters. If you use middleware like `helmet` or `cors` after you define a route, then that middleware will not apply to that route, it will only apply to routes defined after the middleware.

#### Use with Express (default)[#](/security/helmet#use-with-express-default)

Start by installing the required package.

```bash

$ npm i --save helmet
```

Once the installation is complete, apply it as a global middleware.

```typescript

import * as helmet from 'helmet';
// somewhere in your initialization file
app.use(helmet());
```

> **Hint** If you are getting the `This expression is not callable` error while trying to import `Helmet`, you very likely have the `allowSyntheticDefaultImports` and `esModuleInterop` options set to `true` in your project's `tsconfig.json` file. If that's the case, change the import statement to: `import helmet from 'helmet'` instead.

#### Use with Fastify[#](/security/helmet#use-with-fastify)

If you are using the `FastifyAdapter`, install the [fastify-helmet](https://github.com/fastify/fastify-helmet) package:

```bash

$ npm i --save fastify-helmet
```

[fastify-helmet](https://github.com/fastify/fastify-helmet) should not be used as a middleware, but as a [Fastify plugin](https://www.fastify.io/docs/latest/Reference/Plugins/), i.e., by using `app.register()`:

```typescript

import { fastifyHelmet } from 'fastify-helmet';
// somewhere in your initialization file
await app.register(fastifyHelmet);
```

> **Warning** When using `apollo-server-fastify` and `fastify-helmet`, there may be a problem with [CSP](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP) on the GraphQL playground, to solve this collision, configure the CSP as shown below:
>
> ```typescript
>
> await app.register(fastifyHelmet, {
>   contentSecurityPolicy: {
>     directives: {
>       defaultSrc: [`'self'`],
>       styleSrc: [
>         `'self'`,
>         `'unsafe-inline'`,
>         'cdn.jsdelivr.net',
>         'fonts.googleapis.com',
>       ],
>       fontSrc: [`'self'`, 'fonts.gstatic.com'],
>       imgSrc: [`'self'`, 'data:', 'cdn.jsdelivr.net'],
>       scriptSrc: [`'self'`, `https: 'unsafe-inline'`, `cdn.jsdelivr.net`],
>     },
>   },
> });
>
> // If you are not going to use CSP at all, you can use this:
> await app.register(fastifyHelmet, {
>   contentSecurityPolicy: false,
> });
> ```

----
url: https://docs.nestjs.com/v7/techniques/http-module
----

* [HTTP module](https://docs.nestjs.com/v7/techniques/http-module#http-module)
* [Configuration](https://docs.nestjs.com/v7/techniques/http-module#configuration)
* [Async configuration](https://docs.nestjs.com/v7/techniques/http-module#async-configuration)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/techniques/http-module.md "Suggest Edits")

### HTTP module

[Axios](https://github.com/axios/axios) is richly featured HTTP client package that is widely used. Nest wraps Axios and exposes it via the built-in `HttpModule`. The `HttpModule` exports the `HttpService` class, which exposes Axios-based methods to perform HTTP requests. The library also transforms the resulting HTTP responses into `Observables`.

To use the `HttpService`, first import `HttpModule`.

```typescript

@Module({
  imports: [HttpModule],
  providers: [CatsService],
})
export class CatsModule {}
```

Next, inject `HttpService` using normal constructor injection.

> **Hint**`HttpModule` and `HttpService` are imported from `@nestjs/common` package.

JS TS

```typescript

@Injectable()
export class CatsService {
  constructor(private httpService: HttpService) {}

  findAll(): Observable<AxiosResponse<Cat[]>> {
    return this.httpService.get('http://localhost:3000/cats');
  }
}
```

```typescript

@Injectable()
@Dependencies(HttpService)
export class CatsService {
  constructor(httpService) {
    this.httpService = httpService;
  }

  findAll() {
    return this.httpService.get('http://localhost:3000/cats');
  }
}
```

All `HttpService` methods return an `AxiosResponse` wrapped in an `Observable` object.

#### Configuration[#](/techniques/http-module#configuration)

[Axios](https://github.com/axios/axios) can be configured with a variety of options to customize the behavior of the `HttpService`. Read more about them [here](https://github.com/axios/axios#request-config). To configure the underlying Axios instance, pass an optional options object to the `register()` method of `HttpModule` when importing it. This options object will be passed directly to the underlying Axios constructor.

```typescript

@Module({
  imports: [
    HttpModule.register({
      timeout: 5000,
      maxRedirects: 5,
    }),
  ],
  providers: [CatsService],
})
export class CatsModule {}
```

#### Async configuration[#](/techniques/http-module#async-configuration)

When you need to pass module options asynchronously instead of statically, use the `registerAsync()` method. As with most dynamic modules, Nest provides several techniques to deal with async configuration.

One technique is to use a factory function:

```typescript

HttpModule.registerAsync({
  useFactory: () => ({
    timeout: 5000,
    maxRedirects: 5,
  }),
});
```

Like other factory providers, our factory function can be [async](https://docs.nestjs.com/fundamentals/custom-providers#factory-providers-usefactory) and can inject dependencies through `inject`.

```typescript

HttpModule.registerAsync({
  imports: [ConfigModule],
  useFactory: async (configService: ConfigService) => ({
    timeout: configService.getString('HTTP_TIMEOUT'),
    maxRedirects: configService.getString('HTTP_MAX_REDIRECTS'),
  }),
  inject: [ConfigService],
});
```

Alternatively, you can configure the `HttpModule` using a class instead of a factory, as shown below.

```typescript

HttpModule.registerAsync({
  useClass: HttpConfigService,
});
```

The construction above instantiates `HttpConfigService` inside `HttpModule`, using it to create an options object. Note that in this example, the `HttpConfigService` has to implement `HttpModuleOptionsFactory` interface as shown below. The `HttpModule` will call the `createHttpOptions()` method on the instantiated object of the supplied class.

```typescript

@Injectable()
class HttpConfigService implements HttpModuleOptionsFactory {
  createHttpOptions(): HttpModuleOptions {
    return {
      timeout: 5000,
      maxRedirects: 5,
    };
  }
}
```

If you want to reuse an existing options provider instead of creating a private copy inside the `HttpModule`, use the `useExisting` syntax.

```typescript

HttpModule.registerAsync({
  imports: [ConfigModule],
  useExisting: ConfigService,
});
```

----
url: https://docs.nestjs.com/v4/recipes/mongodb
----

### MongoDB (Mongoose)

> **Warning** In this article, you'll learn how to create a `DatabaseModule` based on the **Mongoose** package from scratch using custom components. As a consequence, this solution contains a lot of overhead that you can omit using ready to use and available out-of-the-box dedicated `@nestjs/mongoose` package. To learn more, see [here](/v4/techniques/mongodb).

[Mongoose](http://mongoosejs.com) is the most popular [MongoDB](https://www.mongodb.org/) object modeling tool. To start the adventure with this library we have to install all of the required dependencies:

JavaScript TypeScript

TypeScript

```typescript

$ npm install --save mongoose
$ npm install --save-dev @types/mongoose
```

TypeScript

```typescript

$ npm install --save mongoose
```

The first step we need to do is to establish the connection with our database using `connect()` function. The `connect()` function returns the `MongooseThenable` by default, but we can simply override it with the native `global.Promise` to avoid deprecation warnings. In fact, we're creating an [async component](/v4/fundamentals/async-components) here.

database.providers.ts

JavaScript TypeScript

TypeScript

```typescript

import * as mongoose from 'mongoose';

export const databaseProviders = [
  {
    provide: 'DbConnectionToken',
    useFactory: async () => {
      (mongoose as any).Promise = global.Promise;
      return await mongoose.connect('mongodb://localhost/nest', {
        useMongoClient: true,
      });
    },
  },
];
```

> **Hint** Following best practices, we've declared the custom component in the separated file which has a `*.providers.ts` suffix.

Then we need to export these providers to make them **accessible** for the rest part of the application.

database.module.ts

JavaScript TypeScript

TypeScript

```typescript

import { Module } from '@nestjs/common';
import { databaseProviders } from './database.providers';

@Module({
  components: [...databaseProviders],
  exports: [...databaseProviders],
})
export class DatabaseModule {}
```

It's everything. Now we can inject the `Connection` object using `@Inject()` decorator. Each component which would depend on the `Connection` async component will wait until the `Promise` would be resolved.

#### Model injection

With Mongoose, everything is derived from a [Schema](http://mongoosejs.com/docs/guide.html). Let's define the `CatSchema`:

cats/schemas/cat.schema.ts

JavaScript TypeScript

TypeScript

```typescript

import * as mongoose from 'mongoose';

export const CatSchema = new mongoose.Schema({
  name: String,
  age: Number,
  breed: String,
});
```

The `CatsSchema` belongs to the `cats` directory. This directory represents the `CatsModule`. It's your decision where you gonna keep your schema files. From my point of view, the best way's to hold them nearly their **domain**, in the appropriate module directory.

Now it's time to create a **Model** component:

cats.providers.ts

JavaScript TypeScript

TypeScript

```typescript

import { Connection } from 'mongoose';
import { CatSchema } from './schemas/cat.schema';

export const catsProviders = [
  {
    provide: 'CatModelToken',
    useFactory: (connection: Connection) => connection.model('Cat', CatSchema),
    inject: ['DbConnectionToken'],
  },
];
```

TypeScript

```typescript

import { CatSchema } from './schemas/cat.schema';

export const catsProviders = [
  {
    provide: 'CatModelToken',
    useFactory: (connection) => connection.model('Cat', CatSchema),
    inject: ['DbConnectionToken'],
  },
];
```

> **Notice** In the real-world applications you should avoid **magic strings** at all. Both `CatModelToken` and `DbConnectionToken` should be kept in the separated `constants.ts` file.

Now we can inject the `CatModelToken` to the `CatsService` using the `@Inject()` decorator:

cats.service.ts

JavaScript TypeScript

TypeScript

```typescript

import { Model } from 'mongoose';
import { Component, Inject } from '@nestjs/common';
import { Cat } from './interfaces/cat.interface';
import { CreateCatDto } from './dto/create-cat.dto';

@Component()
export class CatsService {
  constructor(
    @Inject('CatModelToken') private readonly catModel: Model<Cat>) {}

  async create(createCatDto: CreateCatDto): Promise<Cat> {
    const createdCat = new this.catModel(createCatDto);
    return await createdCat.save();
  }

  async findAll(): Promise<Cat[]> {
    return await this.catModel.find().exec();
  }
}
```

TypeScript

```typescript

import { Component, Dependencies } from '@nestjs/common';

@Component()
@Dependencies('CatModelToken')
export class CatsService {
  constructor(catModel) {
    this.catModel = catModel;
  }

  async create(createCatDto) {
    const createdCat = new this.catModel(createCatDto);
    return await createdCat.save();
  }

  async findAll() {
    return await this.catModel.find().exec();
  }
}
```

In the above example I've used the `Cat` interface. This interface extends the `Document` from the mongoose package:

cat.interface.ts

TypeScript

```typescript

import { Document } from 'mongoose';

export interface Cat extends Document {
  readonly name: string;
  readonly age: number;
  readonly breed: string;
}
```

The database connection's **asynchronous**, but Nest makes this process's completely invisible for the end-user. The `CatModel` component's waiting for the db connection, and the `CatsService` is delayed until model would be ready to use. The entire application can start when each component is instantiated.

Here's a final `CatsModule`:

cats.module.ts

JavaScript TypeScript

TypeScript

```typescript

import { Module } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';
import { catsProviders } from './cats.providers';
import { DatabaseModule } from '../database/database.module';

@Module({
  imports: [DatabaseModule],
  controllers: [CatsController],
  components: [
    CatsService,
    ...catsProviders,
  ],
})
export class CatsModule {}
```

> **Hint** Don't forget to import the `CatsModule` into the root `ApplicationModule`.

#### Sponsors

[](https://valor-software.com/)

Nest is an MIT-licensed open source project. It can grow thanks to the support by these awesome people. If you'd like to join them, please read more [here](https://opencollective.com/nest). Thanks!

[](https://opencollective.com/nest/backer/0/website)[](https://opencollective.com/nest/backer/1/website)[](https://opencollective.com/nest/backer/2/website)[](https://opencollective.com/nest/backer/3/website)[](https://opencollective.com/nest/backer/4/website)[](https://opencollective.com/nest/backer/5/website)[](https://opencollective.com/nest/backer/6/website)[](https://opencollective.com/nest/backer/7/website)[](https://opencollective.com/nest/backer/8/website)[](https://opencollective.com/nest/backer/9/website)[](https://opencollective.com/nest/backer/10/website)[](https://opencollective.com/nest/backer/11/website)[](https://opencollective.com/nest/backer/12/website)[](https://opencollective.com/nest/backer/13/website)[](https://opencollective.com/nest/backer/14/website)[](https://opencollective.com/nest/backer/15/website)[](https://opencollective.com/nest/backer/16/website)[](https://opencollective.com/nest/backer/17/website)[](https://opencollective.com/nest/backer/18/website)[](https://opencollective.com/nest/backer/19/website)[](https://opencollective.com/nest/backer/20/website)[](https://opencollective.com/nest/backer/21/website)[](https://opencollective.com/nest/backer/22/website)[](https://opencollective.com/nest/backer/23/website)[](https://opencollective.com/nest/backer/24/website)[](https://opencollective.com/nest/backer/25/website)[](https://opencollective.com/nest/backer/26/website)[](https://opencollective.com/nest/backer/27/website)[](https://opencollective.com/nest/backer/28/website)[](https://opencollective.com/nest/backer/29/website)

[Become a sponsor](https://opencollective.com/nest)

----
url: https://docs.nestjs.com/v4/execution-context
----

### Execution Context

There are several ways of mounting the Nest application. You can create a web app, microservice or just a Nest **execution context**. The Nest context is a wrapper around the Nest container, which holds all instantiated classes. We can grab any existing instance from within any imported module directly using application object. Thanks to that, you can take advantages of the Nest framework everywhere, including **CRON** jobs and even build a **CLI** on top of it.

To create a Nest application context, we are using the following syntax:

JavaScript TypeScript

TypeScript

```typescript

async function bootstrap() {
  const app = await NestFactory.createApplicationContext(ApplicationModule);
  // logic.. :)
}
bootstrap();
```

Afterwards, Nest allows you to pick any instance registered within Nest application. Let's imagine that we have a `TasksController` in the `TasksModule`. This class provides a set of usable methods, which we want to call from within CRON job.

JavaScript TypeScript

TypeScript

```typescript

const app = await NestFactory.create(ApplicationModule);
const tasksController = app
  .select(TasksModule)
  .get(TasksController);
```

And that's it. To grab `TasksController` instance we have used 2 methods, well-described in the below table:

|            |                                                                                                                        |
| ---------- | ---------------------------------------------------------------------------------------------------------------------- |
| `get()`    | Makes possible to retrieve the instance of the component or controller available inside the processed module.          |
| `select()` | Allows you to navigate through the module tree, for example, to pull out a specific instance from the selected module. |

> **Hint** The root module is selected by default. To select any other module, you need to go through entire modules stack (step by step).

#### Sponsors

[](https://valor-software.com/)

Nest is an MIT-licensed open source project. It can grow thanks to the support by these awesome people. If you'd like to join them, please read more [here](https://opencollective.com/nest). Thanks!

[](https://opencollective.com/nest/backer/0/website)[](https://opencollective.com/nest/backer/1/website)[](https://opencollective.com/nest/backer/2/website)[](https://opencollective.com/nest/backer/3/website)[](https://opencollective.com/nest/backer/4/website)[](https://opencollective.com/nest/backer/5/website)[](https://opencollective.com/nest/backer/6/website)[](https://opencollective.com/nest/backer/7/website)[](https://opencollective.com/nest/backer/8/website)[](https://opencollective.com/nest/backer/9/website)[](https://opencollective.com/nest/backer/10/website)[](https://opencollective.com/nest/backer/11/website)[](https://opencollective.com/nest/backer/12/website)[](https://opencollective.com/nest/backer/13/website)[](https://opencollective.com/nest/backer/14/website)[](https://opencollective.com/nest/backer/15/website)[](https://opencollective.com/nest/backer/16/website)[](https://opencollective.com/nest/backer/17/website)[](https://opencollective.com/nest/backer/18/website)[](https://opencollective.com/nest/backer/19/website)[](https://opencollective.com/nest/backer/20/website)[](https://opencollective.com/nest/backer/21/website)[](https://opencollective.com/nest/backer/22/website)[](https://opencollective.com/nest/backer/23/website)[](https://opencollective.com/nest/backer/24/website)[](https://opencollective.com/nest/backer/25/website)[](https://opencollective.com/nest/backer/26/website)[](https://opencollective.com/nest/backer/27/website)[](https://opencollective.com/nest/backer/28/website)[](https://opencollective.com/nest/backer/29/website)

[Become a sponsor](https://opencollective.com/nest)

----
url: https://docs.nestjs.com/v9/microservices/redis
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Redis](https://docs.nestjs.com/v9/microservices/redis#redis)
* [Installation](https://docs.nestjs.com/v9/microservices/redis#installation)
* [Overview](https://docs.nestjs.com/v9/microservices/redis#overview)
* [Options](https://docs.nestjs.com/v9/microservices/redis#options)
* [Client](https://docs.nestjs.com/v9/microservices/redis#client)
* [Context](https://docs.nestjs.com/v9/microservices/redis#context)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/microservices/redis.md "Suggest Edits")

### Redis

The [Redis](https://redis.io/) transporter implements the publish/subscribe messaging paradigm and leverages the [Pub/Sub](https://redis.io/topics/pubsub) feature of Redis. Published messages are categorized in channels, without knowing what subscribers (if any) will eventually receive the message. Each microservice can subscribe to any number of channels. In addition, more than one channel can be subscribed to at a time. Messages exchanged through channels are **fire-and-forget**, which means that if a message is published and there are no subscribers interested in it, the message is removed and cannot be recovered. Thus, you don't have a guarantee that either messages or events will be handled by at least one service. A single message can be subscribed to (and received) by multiple subscribers.

#### Installation[#](/microservices/redis#installation)

To start building Redis-based microservices, first install the required package:

```bash

$ npm i --save ioredis
```

#### Overview[#](/microservices/redis#overview)

To use the Redis transporter, pass the following options object to the `createMicroservice()` method:

main.ts

JS TS

```typescript

const app = await NestFactory.createMicroservice<MicroserviceOptions>(AppModule, {
  transport: Transport.REDIS,
  options: {
    host: 'localhost',
    port: 6379,
  },
});
```

```typescript

const app = await NestFactory.createMicroservice(AppModule, {
  transport: Transport.REDIS,
  options: {
    host: 'localhost',
    port: 6379,
  },
});
```

> **Hint** The `Transport` enum is imported from the `@nestjs/microservices` package.

#### Options[#](/microservices/redis#options)

The `options` property is specific to the chosen transporter. The **Redis** transporter exposes the properties described below.

|                 |                                                          |
| --------------- | -------------------------------------------------------- |
| `host`          | Connection url                                           |
| `port`          | Connection port                                          |
| `retryAttempts` | Number of times to retry message (default: `0`)          |
| `retryDelay`    | Delay between message retry attempts (ms) (default: `0`) |

All the properties supported by the official [ioredis](https://luin.github.io/ioredis/index.html#RedisOptions) client are also supported by this transporter.

#### Client[#](/microservices/redis#client)

Like other microservice transporters, you have [several options](https://docs.nestjs.com/microservices/basics#client) for creating a Redis `ClientProxy` instance.

One method for creating an instance is to use the `ClientsModule`. To create a client instance with the `ClientsModule`, import it and use the `register()` method to pass an options object with the same properties shown above in the `createMicroservice()` method, as well as a `name` property to be used as the injection token. Read more about `ClientsModule`[here](https://docs.nestjs.com/microservices/basics#client).

```typescript

@Module({
  imports: [
    ClientsModule.register([
      {
        name: 'MATH_SERVICE',
        transport: Transport.REDIS,
        options: {
          host: 'localhost',
          port: 6379,
        }
      },
    ]),
  ]
  ...
})
```

Other options to create a client (either `ClientProxyFactory` or `@Client()`) can be used as well. You can read about them [here](https://docs.nestjs.com/microservices/basics#client).

#### Context[#](/microservices/redis#context)

In more sophisticated scenarios, you may want to access more information about the incoming request. When using the Redis transporter, you can access the `RedisContext` object.

JS TS

```typescript

@MessagePattern('notifications')
getNotifications(@Payload() data: number[], @Ctx() context: RedisContext) {
  console.log(`Channel: ${context.getChannel()}`);
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('notifications')
getNotifications(data, context) {
  console.log(`Channel: ${context.getChannel()}`);
}
```

> **Hint**`@Payload()`, `@Ctx()` and `RedisContext` are imported from the `@nestjs/microservices` package.

----
url: https://docs.nestjs.com/v10/recipes/hot-reload
----

* [Hot Reload](https://docs.nestjs.com/v10/recipes/hot-reload#hot-reload)
* [With CLI](https://docs.nestjs.com/v10/recipes/hot-reload#with-cli)
* [Installation](https://docs.nestjs.com/v10/recipes/hot-reload#installation)
* [Configuration](https://docs.nestjs.com/v10/recipes/hot-reload#configuration)
* [Hot-Module Replacement](https://docs.nestjs.com/v10/recipes/hot-reload#hot-module-replacement)
* [Without CLI](https://docs.nestjs.com/v10/recipes/hot-reload#without-cli)
* [Installation](https://docs.nestjs.com/v10/recipes/hot-reload#installation-1)
* [Configuration](https://docs.nestjs.com/v10/recipes/hot-reload#configuration-1)
* [Hot-Module Replacement](https://docs.nestjs.com/v10/recipes/hot-reload#hot-module-replacement-1)
* [Example](https://docs.nestjs.com/v10/recipes/hot-reload#example)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/recipes/hot-reload.md "Suggest Edits")

### Hot Reload

The highest impact on your application's bootstrapping process is **TypeScript compilation**. Fortunately, with [webpack](https://github.com/webpack/webpack) HMR (Hot-Module Replacement), we don't need to recompile the entire project each time a change occurs. This significantly decreases the amount of time necessary to instantiate your application, and makes iterative development a lot easier.

> **Warning** Note that `webpack` won't automatically copy your assets (e.g. `graphql` files) to the `dist` folder. Similarly, `webpack` is not compatible with glob static paths (e.g., the `entities` property in `TypeOrmModule`).

### With CLI

If you are using the [Nest CLI](https://docs.nestjs.com/cli/overview), the configuration process is pretty straightforward. The CLI wraps `webpack`, which allows use of the `HotModuleReplacementPlugin`.

#### Installation[#](/recipes/hot-reload#installation)

First install the required packages:

```bash

$ npm i --save-dev webpack-node-externals run-script-webpack-plugin webpack
```

> **Hint** If you use **Yarn Berry** (not classic Yarn), install the `webpack-pnp-externals` package instead of the `webpack-node-externals`.

#### Configuration[#](/recipes/hot-reload#configuration)

Once the installation is complete, create a `webpack-hmr.config.js` file in the root directory of your application.

```typescript

const nodeExternals = require('webpack-node-externals');
const { RunScriptWebpackPlugin } = require('run-script-webpack-plugin');

module.exports = function (options, webpack) {
  return {
    ...options,
    entry: ['webpack/hot/poll?100', options.entry],
    externals: [
      nodeExternals({
        allowlist: ['webpack/hot/poll?100'],
      }),
    ],
    plugins: [
      ...options.plugins,
      new webpack.HotModuleReplacementPlugin(),
      new webpack.WatchIgnorePlugin({
        paths: [/\.js$/, /\.d\.ts$/],
      }),
      new RunScriptWebpackPlugin({ name: options.output.filename, autoRestart: false }),
    ],
  };
};
```

> **Hint** With **Yarn Berry** (not classic Yarn), instead of using the `nodeExternals` in the `externals` configuration property, use the `WebpackPnpExternals` from `webpack-pnp-externals` package: `WebpackPnpExternals({ exclude: ['webpack/hot/poll?100'] })`.

This function takes the original object containing the default webpack configuration as a first argument, and the reference to the underlying `webpack` package used by the Nest CLI as the second one. Also, it returns a modified webpack configuration with the `HotModuleReplacementPlugin`, `WatchIgnorePlugin`, and `RunScriptWebpackPlugin` plugins.

#### Hot-Module Replacement[#](/recipes/hot-reload#hot-module-replacement)

To enable **HMR**, open the application entry file (`main.ts`) and add the following webpack-related instructions:

```typescript

declare const module: any;

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  await app.listen(process.env.PORT ?? 3000);

  if (module.hot) {
    module.hot.accept();
    module.hot.dispose(() => app.close());
  }
}
bootstrap();
```

To simplify the execution process, add a script to your `package.json` file.

```json

"start:dev": "nest build --webpack --webpackPath webpack-hmr.config.js --watch"
```

Now simply open your command line and run the following command:

```bash

$ npm run start:dev
```

### Without CLI

If you are not using the [Nest CLI](https://docs.nestjs.com/cli/overview), the configuration will be slightly more complex (will require more manual steps).

#### Installation[#](/recipes/hot-reload#installation-1)

First install the required packages:

```bash

$ npm i --save-dev webpack webpack-cli webpack-node-externals ts-loader run-script-webpack-plugin
```

> **Hint** If you use **Yarn Berry** (not classic Yarn), install the `webpack-pnp-externals` package instead of the `webpack-node-externals`.

#### Configuration[#](/recipes/hot-reload#configuration-1)

Once the installation is complete, create a `webpack.config.js` file in the root directory of your application.

```typescript

const webpack = require('webpack');
const path = require('path');
const nodeExternals = require('webpack-node-externals');
const { RunScriptWebpackPlugin } = require('run-script-webpack-plugin');

module.exports = {
  entry: ['webpack/hot/poll?100', './src/main.ts'],
  target: 'node',
  externals: [
    nodeExternals({
      allowlist: ['webpack/hot/poll?100'],
    }),
  ],
  module: {
    rules: [
      {
        test: /.tsx?$/,
        use: 'ts-loader',
        exclude: /node_modules/,
      },
    ],
  },
  mode: 'development',
  resolve: {
    extensions: ['.tsx', '.ts', '.js'],
  },
  plugins: [new webpack.HotModuleReplacementPlugin(), new RunScriptWebpackPlugin({ name: 'server.js', autoRestart: false })],
  output: {
    path: path.join(__dirname, 'dist'),
    filename: 'server.js',
  },
};
```

> **Hint** With **Yarn Berry** (not classic Yarn), instead of using the `nodeExternals` in the `externals` configuration property, use the `WebpackPnpExternals` from `webpack-pnp-externals` package: `WebpackPnpExternals({ exclude: ['webpack/hot/poll?100'] })`.

This configuration tells webpack a few essential things about your application: location of the entry file, which directory should be used to hold **compiled** files, and what kind of loader we want to use to compile source files. Generally, you should be able to use this file as-is, even if you don't fully understand all of the options.

#### Hot-Module Replacement[#](/recipes/hot-reload#hot-module-replacement-1)

To enable **HMR**, open the application entry file (`main.ts`) and add the following webpack-related instructions:

```typescript

declare const module: any;

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  await app.listen(process.env.PORT ?? 3000);

  if (module.hot) {
    module.hot.accept();
    module.hot.dispose(() => app.close());
  }
}
bootstrap();
```

To simplify the execution process, add a script to your `package.json` file.

```json

"start:dev": "webpack --config webpack.config.js --watch"
```

Now simply open your command line and run the following command:

```bash

$ npm run start:dev
```

#### Example[#](/recipes/hot-reload#example)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/08-webpack).

----
url: https://docs.nestjs.com/v9/exception-filters
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Exception filters](https://docs.nestjs.com/v9/exception-filters#exception-filters)
* [Throwing standard exceptions](https://docs.nestjs.com/v9/exception-filters#throwing-standard-exceptions)
* [Custom exceptions](https://docs.nestjs.com/v9/exception-filters#custom-exceptions)
* [Built-in HTTP exceptions](https://docs.nestjs.com/v9/exception-filters#built-in-http-exceptions)
* [Exception filters](https://docs.nestjs.com/v9/exception-filters#exception-filters-1)
* [Arguments host](https://docs.nestjs.com/v9/exception-filters#arguments-host)
* [Binding filters](https://docs.nestjs.com/v9/exception-filters#binding-filters)
* [Catch everything](https://docs.nestjs.com/v9/exception-filters#catch-everything)
* [Inheritance](https://docs.nestjs.com/v9/exception-filters#inheritance)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/exception-filters.md "Suggest Edits")

### Exception filters

Nest comes with a built-in **exceptions layer** which is responsible for processing all unhandled exceptions across an application. When an exception is not handled by your application code, it is caught by this layer, which then automatically sends an appropriate user-friendly response.

Out of the box, this action is performed by a built-in **global exception filter**, which handles exceptions of type `HttpException` (and subclasses of it). When an exception is **unrecognized** (is neither `HttpException` nor a class that inherits from `HttpException`), the built-in exception filter generates the following default JSON response:

```json

{
  "statusCode": 500,
  "message": "Internal server error"
}
```

> **Hint** The global exception filter partially supports the `http-errors` library. Basically, any thrown exception containing the `statusCode` and `message` properties will be properly populated and sent back as a response (instead of the default `InternalServerErrorException` for unrecognized exceptions).

#### Throwing standard exceptions[#](/exception-filters#throwing-standard-exceptions)

Nest provides a built-in `HttpException` class, exposed from the `@nestjs/common` package. For typical HTTP REST/GraphQL API based applications, it's best practice to send standard HTTP response objects when certain error conditions occur.

For example, in the `CatsController`, we have a `findAll()` method (a `GET` route handler). Let's assume that this route handler throws an exception for some reason. To demonstrate this, we'll hard-code it as follows:

cats.controller.ts

JS TS

```typescript

@Get()
async findAll() {
  throw new HttpException('Forbidden', HttpStatus.FORBIDDEN);
}
```

> **Hint** We used the `HttpStatus` here. This is a helper enum imported from the `@nestjs/common` package.

When the client calls this endpoint, the response looks like this:

```json

{
  "statusCode": 403,
  "message": "Forbidden"
}
```

```typescript

@Get()
async findAll() {
  try {
    await this.service.findAll()
  } catch (error) { 
    throw new HttpException({
      status: HttpStatus.FORBIDDEN,
      error: 'This is a custom message',
    }, HttpStatus.FORBIDDEN, {
      cause: error
    });
  }
}
```

Using the above, this is how the response would look:

```json

{
  "status": 403,
  "error": "This is a custom message"
}
```

#### Custom exceptions[#](/exception-filters#custom-exceptions)

In many cases, you will not need to write custom exceptions, and can use the built-in Nest HTTP exception, as described in the next section. If you do need to create customized exceptions, it's good practice to create your own **exceptions hierarchy**, where your custom exceptions inherit from the base `HttpException` class. With this approach, Nest will recognize your exceptions, and automatically take care of the error responses. Let's implement such a custom exception:

forbidden.exception.ts

JS TS

```typescript

export class ForbiddenException extends HttpException {
  constructor() {
    super('Forbidden', HttpStatus.FORBIDDEN);
  }
}
```

Since `ForbiddenException` extends the base `HttpException`, it will work seamlessly with the built-in exception handler, and therefore we can use it inside the `findAll()` method.

cats.controller.ts

JS TS

```typescript

@Get()
async findAll() {
  throw new ForbiddenException();
}
```

```typescript

throw new BadRequestException('Something bad happened', { cause: new Error(), description: 'Some error description' })
```

Using the above, this is how the response would look:

```json

{
  "message": "Something bad happened",
  "error": "Some error description",
  "statusCode": 400,
}
```

#### Exception filters[#](/exception-filters#exception-filters-1)

While the base (built-in) exception filter can automatically handle many cases for you, you may want **full control** over the exceptions layer. For example, you may want to add logging or use a different JSON schema based on some dynamic factors. **Exception filters** are designed for exactly this purpose. They let you control the exact flow of control and the content of the response sent back to the client.

Let's create an exception filter that is responsible for catching exceptions which are an instance of the `HttpException` class, and implementing custom response logic for them. To do this, we'll need to access the underlying platform `Request` and `Response` objects. We'll access the `Request` object so we can pull out the original `url` and include that in the logging information. We'll use the `Response` object to take direct control of the response that is sent, using the `response.json()` method.

http-exception.filter.ts

JS TS

```typescript

import { ExceptionFilter, Catch, ArgumentsHost, HttpException } from '@nestjs/common';
import { Request, Response } from 'express';

@Catch(HttpException)
export class HttpExceptionFilter implements ExceptionFilter {
  catch(exception: HttpException, host: ArgumentsHost) {
    const ctx = host.switchToHttp();
    const response = ctx.getResponse<Response>();
    const request = ctx.getRequest<Request>();
    const status = exception.getStatus();

    response
      .status(status)
      .json({
        statusCode: status,
        timestamp: new Date().toISOString(),
        path: request.url,
      });
  }
}
```

```typescript

import { Catch, HttpException } from '@nestjs/common';

@Catch(HttpException)
export class HttpExceptionFilter {
  catch(exception, host) {
    const ctx = host.switchToHttp();
    const response = ctx.getResponse();
    const request = ctx.getRequest();
    const status = exception.getStatus();

    response
      .status(status)
      .json({
        statusCode: status,
        timestamp: new Date().toISOString(),
        path: request.url,
      });
  }
}
```

> **Hint** All exception filters should implement the generic `ExceptionFilter<T>` interface. This requires you to provide the `catch(exception: T, host: ArgumentsHost)` method with its indicated signature. `T` indicates the type of the exception.

> **Warning** If you are using `@nestjs/platform-fastify` you can use `response.send()` instead of `response.json()`. Don't forget to import the correct types from `fastify`.

The `@Catch(HttpException)` decorator binds the required metadata to the exception filter, telling Nest that this particular filter is looking for exceptions of type `HttpException` and nothing else. The `@Catch()` decorator may take a single parameter, or a comma-separated list. This lets you set up the filter for several types of exceptions at once.

#### Arguments host[#](/exception-filters#arguments-host)

Let's look at the parameters of the `catch()` method. The `exception` parameter is the exception object currently being processed. The `host` parameter is an `ArgumentsHost` object. `ArgumentsHost` is a powerful utility object that we'll examine further in the [execution context chapter](/v9/fundamentals/execution-context)\*. In this code sample, we use it to obtain a reference to the `Request` and `Response` objects that are being passed to the original request handler (in the controller where the exception originates). In this code sample, we've used some helper methods on `ArgumentsHost` to get the desired `Request` and `Response` objects. Learn more about `ArgumentsHost`[here](/v9/fundamentals/execution-context).

```typescript

@Post()
@UseFilters(new HttpExceptionFilter())
async create(@Body() createCatDto: CreateCatDto) {
  throw new ForbiddenException();
}
```

```typescript

@Post()
@UseFilters(new HttpExceptionFilter())
@Bind(Body())
async create(createCatDto) {
  throw new ForbiddenException();
}
```

> **Hint** The `@UseFilters()` decorator is imported from the `@nestjs/common` package.

We have used the `@UseFilters()` decorator here. Similar to the `@Catch()` decorator, it can take a single filter instance, or a comma-separated list of filter instances. Here, we created the instance of `HttpExceptionFilter` in place. Alternatively, you may pass the class (instead of an instance), leaving responsibility for instantiation to the framework, and enabling **dependency injection**.

cats.controller.ts

JS TS

```typescript

@Post()
@UseFilters(HttpExceptionFilter)
async create(@Body() createCatDto: CreateCatDto) {
  throw new ForbiddenException();
}
```

```typescript

@Post()
@UseFilters(HttpExceptionFilter)
@Bind(Body())
async create(createCatDto) {
  throw new ForbiddenException();
}
```

> **Hint** Prefer applying filters by using classes instead of instances when possible. It reduces **memory usage** since Nest can easily reuse instances of the same class across your entire module.

In the example above, the `HttpExceptionFilter` is applied only to the single `create()` route handler, making it method-scoped. Exception filters can be scoped at different levels: method-scoped, controller-scoped, or global-scoped. For example, to set up a filter as controller-scoped, you would do the following:

cats.controller.ts

JS TS

```typescript

@UseFilters(new HttpExceptionFilter())
export class CatsController {}
```

This construction sets up the `HttpExceptionFilter` for every route handler defined inside the `CatsController`.

To create a global-scoped filter, you would do the following:

main.ts

JS TS

```typescript

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.useGlobalFilters(new HttpExceptionFilter());
  await app.listen(3000);
}
bootstrap();
```

> **Warning** The `useGlobalFilters()` method does not set up filters for gateways or hybrid applications.

Global-scoped filters are used across the whole application, for every controller and every route handler. In terms of dependency injection, global filters registered from outside of any module (with `useGlobalFilters()` as in the example above) cannot inject dependencies since this is done outside the context of any module. In order to solve this issue, you can register a global-scoped filter **directly from any module** using the following construction:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { APP_FILTER } from '@nestjs/core';

@Module({
  providers: [
    {
      provide: APP_FILTER,
      useClass: HttpExceptionFilter,
    },
  ],
})
export class AppModule {}
```

> **Hint** When using this approach to perform dependency injection for the filter, note that regardless of the module where this construction is employed, the filter is, in fact, global. Where should this be done? Choose the module where the filter (`HttpExceptionFilter` in the example above) is defined. Also, `useClass` is not the only way of dealing with custom provider registration. Learn more [here](/v9/fundamentals/custom-providers).

You can add as many filters with this technique as needed; simply add each to the providers array.

#### Catch everything[#](/exception-filters#catch-everything)

In order to catch **every** unhandled exception (regardless of the exception type), leave the `@Catch()` decorator's parameter list empty, e.g., `@Catch()`.

In the example below we have a code that is platform-agnostic because it uses the [HTTP adapter](./faq/http-adapter) to deliver the response, and doesn't use any of the platform-specific objects (`Request` and `Response`) directly:

```typescript

import {
  ExceptionFilter,
  Catch,
  ArgumentsHost,
  HttpException,
  HttpStatus,
} from '@nestjs/common';
import { HttpAdapterHost } from '@nestjs/core';

@Catch()
export class AllExceptionsFilter implements ExceptionFilter {
  constructor(private readonly httpAdapterHost: HttpAdapterHost) {}

  catch(exception: unknown, host: ArgumentsHost): void {
    // In certain situations `httpAdapter` might not be available in the
    // constructor method, thus we should resolve it here.
    const { httpAdapter } = this.httpAdapterHost;

    const ctx = host.switchToHttp();

    const httpStatus =
      exception instanceof HttpException
        ? exception.getStatus()
        : HttpStatus.INTERNAL_SERVER_ERROR;

    const responseBody = {
      statusCode: httpStatus,
      timestamp: new Date().toISOString(),
      path: httpAdapter.getRequestUrl(ctx.getRequest()),
    };

    httpAdapter.reply(ctx.getResponse(), responseBody, httpStatus);
  }
}
```

> **Warning** When combining an exception filter that catches everything with a filter that is bound to a specific type, the "Catch anything" filter should be declared first to allow the specific filter to correctly handle the bound type.

#### Inheritance[#](/exception-filters#inheritance)

Typically, you'll create fully customized exception filters crafted to fulfill your application requirements. However, there might be use-cases when you would like to simply extend the built-in default **global exception filter**, and override the behavior based on certain factors.

In order to delegate exception processing to the base filter, you need to extend `BaseExceptionFilter` and call the inherited `catch()` method.

all-exceptions.filter.ts

JS TS

```typescript

import { Catch, ArgumentsHost } from '@nestjs/common';
import { BaseExceptionFilter } from '@nestjs/core';

@Catch()
export class AllExceptionsFilter extends BaseExceptionFilter {
  catch(exception: unknown, host: ArgumentsHost) {
    super.catch(exception, host);
  }
}
```

```typescript

import { Catch } from '@nestjs/common';
import { BaseExceptionFilter } from '@nestjs/core';

@Catch()
export class AllExceptionsFilter extends BaseExceptionFilter {
  catch(exception, host) {
    super.catch(exception, host);
  }
}
```

> **Warning** Method-scoped and Controller-scoped filters that extend the `BaseExceptionFilter` should not be instantiated with `new`. Instead, let the framework instantiate them automatically.

The above implementation is just a shell demonstrating the approach. Your implementation of the extended exception filter would include your tailored **business** logic (e.g., handling various conditions).

Global filters **can** extend the base filter. This can be done in either of two ways.

The first method is to inject the `HttpAdapter` reference when instantiating the custom global filter:

```typescript

async function bootstrap() {
  const app = await NestFactory.create(AppModule);

  const { httpAdapter } = app.get(HttpAdapterHost);
  app.useGlobalFilters(new AllExceptionsFilter(httpAdapter));

  await app.listen(3000);
}
bootstrap();
```

The second method is to use the `APP_FILTER` token [as shown here](exception-filters#binding-filters).

----
url: https://docs.nestjs.com/v9/microservices/nats
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [NATS](https://docs.nestjs.com/v9/microservices/nats#nats)
* [Installation](https://docs.nestjs.com/v9/microservices/nats#installation)
* [Overview](https://docs.nestjs.com/v9/microservices/nats#overview)
* [Options](https://docs.nestjs.com/v9/microservices/nats#options)
* [Client](https://docs.nestjs.com/v9/microservices/nats#client)
* [Request-response](https://docs.nestjs.com/v9/microservices/nats#request-response)
* [Event-based](https://docs.nestjs.com/v9/microservices/nats#event-based)
* [Queue groups](https://docs.nestjs.com/v9/microservices/nats#queue-groups)
* [Context](https://docs.nestjs.com/v9/microservices/nats#context)
* [Wildcards](https://docs.nestjs.com/v9/microservices/nats#wildcards)
* [Record builders](https://docs.nestjs.com/v9/microservices/nats#record-builders)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/microservices/nats.md "Suggest Edits")

### NATS

[NATS](https://nats.io) is a simple, secure and high performance open source messaging system for cloud native applications, IoT messaging, and microservices architectures. The NATS server is written in the Go programming language, but client libraries to interact with the server are available for dozens of major programming languages. NATS supports both **At Most Once** and **At Least Once** delivery. It can run anywhere, from large servers and cloud instances, through edge gateways and even Internet of Things devices.

#### Installation[#](/microservices/nats#installation)

To start building NATS-based microservices, first install the required package:

```bash

$ npm i --save nats
```

#### Overview[#](/microservices/nats#overview)

To use the NATS transporter, pass the following options object to the `createMicroservice()` method:

main.ts

JS TS

```typescript

const app = await NestFactory.createMicroservice<MicroserviceOptions>(AppModule, {
  transport: Transport.NATS,
  options: {
    servers: ['nats://localhost:4222'],
  },
});
```

```typescript

const app = await NestFactory.createMicroservice(AppModule, {
  transport: Transport.NATS,
  options: {
    servers: ['nats://localhost:4222'],
  },
});
```

> **Hint** The `Transport` enum is imported from the `@nestjs/microservices` package.

#### Options[#](/microservices/nats#options)

The `options` object is specific to the chosen transporter. The **NATS** transporter exposes the properties described [here](https://github.com/nats-io/node-nats#connect-options). Additionally, there is a `queue` property which allows you to specify the name of the queue that your server should subscribe to (leave `undefined` to ignore this setting). Read more about NATS queue groups [below](https://docs.nestjs.com/microservices/nats#queue-groups).

#### Client[#](/microservices/nats#client)

Like other microservice transporters, you have [several options](https://docs.nestjs.com/microservices/basics#client) for creating a NATS `ClientProxy` instance.

One method for creating an instance is to use the `ClientsModule`. To create a client instance with the `ClientsModule`, import it and use the `register()` method to pass an options object with the same properties shown above in the `createMicroservice()` method, as well as a `name` property to be used as the injection token. Read more about `ClientsModule`[here](https://docs.nestjs.com/microservices/basics#client).

```typescript

@Module({
  imports: [
    ClientsModule.register([
      {
        name: 'MATH_SERVICE',
        transport: Transport.NATS,
        options: {
          servers: ['nats://localhost:4222'],
        }
      },
    ]),
  ]
  ...
})
```

```typescript

const app = await NestFactory.createMicroservice<MicroserviceOptions>(AppModule, {
  transport: Transport.NATS,
  options: {
    servers: ['nats://localhost:4222'],
    queue: 'cats_queue',
  },
});
```

#### Context[#](/microservices/nats#context)

In more sophisticated scenarios, you may want to access more information about the incoming request. When using the NATS transporter, you can access the `NatsContext` object.

JS TS

```typescript

@MessagePattern('notifications')
getNotifications(@Payload() data: number[], @Ctx() context: NatsContext) {
  console.log(`Subject: ${context.getSubject()}`);
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('notifications')
getNotifications(data, context) {
  console.log(`Subject: ${context.getSubject()}`);
}
```

> **Hint**`@Payload()`, `@Ctx()` and `NatsContext` are imported from the `@nestjs/microservices` package.

#### Wildcards[#](/microservices/nats#wildcards)

A subscription may be to an explicit subject, or it may include wildcards.

JS TS

```typescript

@MessagePattern('time.us.*')
getDate(@Payload() data: number[], @Ctx() context: NatsContext) {
  console.log(`Subject: ${context.getSubject()}`); // e.g. "time.us.east"
  return new Date().toLocaleTimeString(...);
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('time.us.*')
getDate(data, context) {
  console.log(`Subject: ${context.getSubject()}`); // e.g. "time.us.east"
  return new Date().toLocaleTimeString(...);
}
```

#### Record builders[#](/microservices/nats#record-builders)

To configure message options, you can use the `NatsRecordBuilder` class (note: this is doable for event-based flows as well). For example, to add `x-version` header, use the `setHeaders` method, as follows:

```typescript

import * as nats from 'nats';

// somewhere in your code
const headers = nats.headers();
headers.set('x-version', '1.0.0');

const record = new NatsRecordBuilder(':cat:').setHeaders(headers).build();
this.client.send('replace-emoji', record).subscribe(...);
```

> **Hint**`NatsRecordBuilder` class is exported from the `@nestjs/microservices` package.

And you can read these headers on the server-side as well, by accessing the `NatsContext`, as follows:

JS TS

```typescript

@MessagePattern('replace-emoji')
replaceEmoji(@Payload() data: string, @Ctx() context: NatsContext): string {
  const headers = context.getHeaders();
  return headers['x-version'] === '1.0.0' ? '🐱' : '🐈';
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('replace-emoji')
replaceEmoji(data, context) {
  const headers = context.getHeaders();
  return headers['x-version'] === '1.0.0' ? '🐱' : '🐈';
}
```

In some cases you might want to configure headers for multiple requests, you can pass these as options to the `ClientProxyFactory`:

```typescript

import { Module } from '@nestjs/common';
import { ClientProxyFactory, Transport } from '@nestjs/microservices';

@Module({
  providers: [
    {
      provide: 'API_v1',
      useFactory: () =>
        ClientProxyFactory.create({
          transport: Transport.NATS,
          options: {
            servers: ['nats://localhost:4222'],
            headers: { 'x-version': '1.0.0' },
          },
        }),
    },
  ],
})
export class ApiModule {}
```

----
url: https://docs.nestjs.com/v5/techniques/authentication
----

### Authentication

Authentication is an **essential** part of most existing applications. There are a lot of different approaches, strategies, and ways to handle user authorization. What we eventually decide to use depends on the particular application requirements and is strongly associated with their needs.

[Passport](https://github.com/jaredhanson/passport) is the most popular node.js authentication library, well-known by community and successively used in many production applications. It's really simple to integrate this tool with **Nest** framework using dedicated passport utilities. For demonstration purposes, we'll set up both [passport-http-bearer](https://github.com/jaredhanson/passport-http-bearer) and [passport-jwt](https://github.com/themikenicholson/passport-jwt) strategy.

#### Installation

In order to start the adventure with this library, we have to install a few fundamental packages. Additionally, we'll start by implementing the bearer strategy, and thus we need to install `passport-http-bearer` package.

```bash

$ npm install --save @nestjs/passport passport passport-http-bearer
```

#### Bearer strategy

As has been said already, firstly, we'll implement [passport-http-bearer](https://github.com/jaredhanson/passport-http-bearer) library. Bearer tokens are typically used protect API endpoints, and are often issued using OAuth 2.0. The HTTP Bearer authentication strategy authenticates users using a bearer token.

Let's start by creating the `AuthService` class that will expose a single method, `validateUser()` which responsibility is to query user using provided bearer **token**.

auth.service.ts

JS TS

TypeScript

```typescript

import { Injectable } from '@nestjs/common';
import { UsersService } from '../users/users.service';

@Injectable()
export class AuthService {
  constructor(private readonly usersService: UsersService) {}

  async validateUser(token: string): Promise<any> {
    // Validate if token passed along with HTTP request
    // is associated with any registered account in the database
    return await this.usersService.findOneByToken(token);
  }
}
```

TypeScript

```typescript

import { Injectable, Dependencies } from '@nestjs/common';
import { UsersService } from '../users/users.service';

@Injectable()
@Dependencies(UsersService)
export class AuthService {
  constructor(usersService) {
    this.usersService = usersService;
  }

  async validateUser(token) {
    // Validate if token passed along with HTTP request
    // is associated with any registered account in the database
    return await this.usersService.findOneByToken(token);
  }
}
```

The `validateUser()` method takes `token` as an argument. This token is extracted from `Authorization` header that has been passed along with HTTP request. The `findOneByToken()` method's responsibility is to validate if passed token truly exists and is associated with any registered account in the database.

Once `AuthService` class is done, we have to create a corresponding **strategy** that passport will use to authenticate requests.

http.strategy.ts

JS TS

TypeScript

```typescript

import { Strategy } from 'passport-http-bearer';
import { PassportStrategy } from '@nestjs/passport';
import { Injectable, UnauthorizedException } from '@nestjs/common';
import { AuthService } from './auth.service';

@Injectable()
export class HttpStrategy extends PassportStrategy(Strategy) {
  constructor(private readonly authService: AuthService) {
    super();
  }

  async validate(token: string) {
    const user = await this.authService.validateUser(token);
    if (!user) {
      throw new UnauthorizedException();
    }
    return user;
  }
}
```

TypeScript

```typescript

import { Strategy } from 'passport-http-bearer';
import { PassportStrategy } from '@nestjs/passport';
import { Injectable, Dependencies, UnauthorizedException } from '@nestjs/common';
import { AuthService } from './auth.service';

@Injectable()
@Dependencies(AuthService)
export class HttpStrategy extends PassportStrategy(Strategy) {
  constructor(authService) {
    super();
    this.authService = authService;
  }

  async validate(token) {
    const user = await this.authService.validateUser(token);
    if (!user) {
      throw new UnauthorizedException();
    }
    return user;
  }
}
```

The `HttpStrategy` uses `AuthService` to validate the token. When the token is valid, passport allows further request processing. Otherwise, the user receives `401 Unauthorized` response.

Afterward, we can create the `AuthModule`.

auth.module.ts

JS TS

TypeScript

```typescript

import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { HttpStrategy } from './http.strategy';
import { UsersModule } from '../users/users.module';

@Module({
  imports: [UsersModule],
  providers: [AuthService, HttpStrategy],
})
export class AuthModule {}
```

TypeScript

```typescript

import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { HttpStrategy } from './http.strategy';
import { UsersModule } from '../users/users.module';

@Module({
  imports: [UsersModule],
  providers: [AuthService, HttpStrategy],
})
export class AuthModule {}
```

> **Notice** In order to make use of `UsersService`, the `AuthModule` imports `UsersModule`. The internal implementation is unimportant here and heavily depends on your technical project requirements (e.g. database).

Then, you can simply use the `AuthGuard` wherever you want to enable the authentication.

TypeScript

```typescript

@Get('users')
@UseGuards(AuthGuard('bearer'))
findAll() {
  return [];
}
```

The `@AuthGuard()` is imported from `@nestjs/passport` package. Also, `bearer` is a name of the strategy that passport will make use of. Let us check if endpoint is effectively secured. To ensure that everything work correctly, we'll perform a GET request to the `users` resource without setting a valid token.

```bash

$ curl localhost:3000/users
```

Application should respond with `401 Unauthorized` status code and following response body:

TypeScript

```typescript

"statusCode": 401,
"error": "Unauthorized"
```

If you create a valid token beforehand and pass it along with the HTTP request, the application will respectively identify a user, attach its object to the request, and allow further request processing.

```bash

$ curl localhost:3000/users -H "Authorization: Bearer TOKEN"
```

#### Default strategy

To determine default passport behavior, you can register the `PassportModule`.

auth.module.ts

JS TS

TypeScript

```typescript

import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { HttpStrategy } from './http.strategy';
import { UsersModule } from '../users/users.module';
import { PassportModule } from '@nestjs/passport';

@Module({
  imports: [
    PassportModule.register({ defaultStrategy: 'bearer' }),
    UsersModule,
  ],
  providers: [AuthService, HttpStrategy],
})
export class AuthModule {}
```

TypeScript

```typescript

import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { HttpStrategy } from './http.strategy';
import { UsersModule } from '../users/users.module';
import { PassportModule } from '@nestjs/passport';

@Module({
  imports: [
    PassportModule.register({ defaultStrategy: 'bearer' }),
    UsersModule,
  ],
  providers: [AuthService, HttpStrategy],
})
export class AuthModule {}
```

Once you set `defaultStrategy`, you no longer need to manually pass the strategy name in the `@AuthGuard()` decorator.

TypeScript

```typescript

@Get('users')
@UseGuards(AuthGuard())
findAll() {
  return [];
}
```

#### User object

When request is validated correctly, the user entity will be attached to the request object and accessible through `user` property (e.g. `req.user`). To change the property name, set `property` of the options object.

TypeScript

```typescript

PassportModule.register({ property: 'profile' })
```

#### Customize passport

Depending on the strategy that is being used, passport takes a bunch of properties that shape the library behavior. Use `register()` method to pass down options object directly to the passport instance.

TypeScript

```typescript

PassportModule.register({ session: true })
```

#### Inheritance

In most cases, `AuthGuard` will be sufficient. However, in order to adjust either default error handling or authentication logic, you can extend the class and override methods within a subclass.

TypeScript

```typescript

import {
  ExecutionContext,
  Injectable,
  UnauthorizedException,
} from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';

@Injectable()
export class JwtAuthGuard extends AuthGuard('jwt') {
  canActivate(context: ExecutionContext) {
    // Add your custom authentication logic here
    // for example, call super.logIn(request) to establish a session.
    return super.canActivate(context);
  }

  handleRequest(err, user, info) {
    if (err || !user) {
      throw err || new UnauthorizedException();
    }
    return user;
  }
}
```

#### JWT strategy

A second described approach is to authenticate endpoints using a **JSON web token** (JWT). To implement a JWT-based authentication flow, we need to install required packages.

```bash

$ npm install --save @nestjs/jwt passport-jwt
```

Once the installation process is done, we can focus on `AuthService` class. We need to switch from the token validation to a payload-based validation logic as well as provide a way to create a JWT token for the particular user which then could be used to authenticate the incoming request.

auth.service.ts

JS TS

TypeScript

```typescript

import { JwtService } from '@nestjs/jwt';
import { Injectable } from '@nestjs/common';
import { UsersService } from '../users/users.service';
import { JwtPayload } from './interfaces/jwt-payload.interface';

@Injectable()
export class AuthService {
  constructor(
    private readonly usersService: UsersService,
    private readonly jwtService: JwtService,
  ) {}

  async signIn(): Promise<string> {
    // In the real-world app you shouldn't expose this method publicly
    // instead, return a token once you verify user credentials
    const user: JwtPayload = { email: 'user@email.com' };
    return this.jwtService.sign(user);
  }

  async validateUser(payload: JwtPayload): Promise<any> {
    return await this.usersService.findOneByEmail(payload.email);
  }
}
```

TypeScript

```typescript

import { JwtService } from '@nestjs/jwt';
import { Injectable, Dependencies } from '@nestjs/common';
import { UsersService } from '../users/users.service';
import { JwtPayload } from './interfaces/jwt-payload.interface';

@Injectable()
@Dependencies(UsersService, JwtService)
export class AuthService {
  constructor(usersService, jwtService) {
    this.usersService = usersService;
    this.jwtService = jwtService;
  }

  async signIn() {
    // In the real-world app you shouldn't expose this method publicly
    // instead, return a token once you verify user credentials
    const user = { email: 'user@email.com' };
    return this.jwtService.sign(user);
  }

  async validateUser(payload) {
    return await this.usersService.findOneByEmail(payload.email);
  }
}
```

> **Hint** The `JwtPayload` is an interface with a single property, an `email`, and represents decoded JWT token.

In order to simplify an example, we created a fake user. The second step is to create a corresponding `JwtStrategy`.

jwt.strategy.ts

JS TS

TypeScript

```typescript

import { ExtractJwt, Strategy } from 'passport-jwt';
import { AuthService } from './auth.service';
import { PassportStrategy } from '@nestjs/passport';
import { Injectable, UnauthorizedException } from '@nestjs/common';
import { JwtPayload } from './interfaces/jwt-payload.interface';

@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
  constructor(private readonly authService: AuthService) {
    super({
      jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
      secretOrKey: 'secretKey',
    });
  }

  async validate(payload: JwtPayload) {
    const user = await this.authService.validateUser(payload);
    if (!user) {
      throw new UnauthorizedException();
    }
    return user;
  }
}
```

TypeScript

```typescript

import { ExtractJwt, Strategy } from 'passport-jwt';
import { AuthService } from './auth.service';
import { PassportStrategy } from '@nestjs/passport';
import { Injectable, Dependencies, UnauthorizedException } from '@nestjs/common';

@Injectable()
@Dependencies(AuthService)
export class JwtStrategy extends PassportStrategy(Strategy) {
  constructor(authService) {
    super({
      jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
      secretOrKey: 'secretKey',
    });
    this.authService = authService;
  }

  async validate(payload, done) {
    const user = await this.authService.validateUser(payload);
    if (!user) {
      return done(new UnauthorizedException(), false);
    }
    done(null, user);
  }
}
```

The `JwtStrategy` uses `AuthService` to validate the decoded payload. When the payload is valid (user exists), passport allows further request processing. Otherwise, the user receives `401 (Unauthorized)` response.

Afterward, we can move to the `AuthModule`.

auth.module.ts

JS TS

TypeScript

```typescript

import { Module } from '@nestjs/common';
import { JwtModule } from '@nestjs/jwt';
import { AuthService } from './auth.service';
import { JwtStrategy } from './jwt.strategy';
import { UsersModule } from '../users/users.module';
import { PassportModule } from '@nestjs/passport';

@Module({
  imports: [
    PassportModule.register({ defaultStrategy: 'jwt' }),
    JwtModule.register({
      secretOrPrivateKey: 'secretKey',
      signOptions: {
        expiresIn: 3600,
      },
    }),
    UsersModule,
  ],
  providers: [AuthService, JwtStrategy],
})
export class AuthModule {}
```

TypeScript

```typescript

import { Module } from '@nestjs/common';
import { JwtModule } from '@nestjs/jwt';
import { AuthService } from './auth.service';
import { JwtStrategy } from './jwt.strategy';
import { UsersModule } from '../users/users.module';
import { PassportModule } from '@nestjs/passport';

@Module({
  imports: [
    PassportModule.register({ defaultStrategy: 'jwt' }),
    JwtModule.register({
      secretOrPrivateKey: 'secretKey',
      signOptions: {
        expiresIn: 3600,
      },
    }),
    UsersModule,
  ],
  providers: [AuthService, JwtStrategy],
})
export class AuthModule {}
```

> **Hint** In order to make use of `UsersService`, the `AuthModule` imports `UsersModule`. The internal implementation is unimportant here. Besides, `JwtModule` has been registered statically. To switch to asynchronous configuration, read more [here](https://github.com/nestjs/passport).

Both expiration time and `secretKey` are hardcoded (in a real-world application you should rather consider using environment variables).

Then, you can simply use the `AuthGuard` wherever you want to enable the authentication.

TypeScript

```typescript

@Get('users')
@UseGuards(AuthGuard())
findAll() {
  return [];
}
```

Let us check if endpoint is effectively secured. To ensure that everything work correctly, we'll perform a GET request to the `users` resource without setting a valid token.

```bash

$ curl localhost:3000/users
```

Application should respond with `401 Unauthorized` status code and following response body:

TypeScript

```typescript

"statusCode": 401,
"error": "Unauthorized"
```

If you create a valid token beforehand and pass it along with the HTTP request, the application will respectively identify a user, attach its object to the request, and allow further request processing.

```bash

$ curl localhost:3000/users -H "Authorization: Bearer TOKEN"
```

#### Example

A full working example is available [here](https://github.com/nestjs/nest/tree/master/sample/19-auth).

#### Multiple strategies

Usually, you'll end up with single strategy reused across the whole application. However, there might be cases when you'd prefer to use different strategies for different scopes. In the case of multiple strategies, pass the second argument to the `PassportStrategy` function. Generally, this argument is a name of the strategy.

TypeScript

```typescript

export class JwtStrategy extends PassportStrategy(Strategy, 'jwt')
```

In above example, the `jwt` becomes the name of the `JwtStrategy`. Afterward, you can use `@AuthGuard('jwt')`, just the same as before.

#### GraphQL

In order to use `AuthGuard` together with [GraphQL](/v5/graphql/quick-start), you have to extend the built-in `AuthGuard` class and override `getRequest()` method.

TypeScript

```typescript

@Injectable()
export class GqlAuthGuard extends AuthGuard('jwt') {
  getRequest(context: ExecutionContext) {
    const ctx = GqlExecutionContext.create(context);
    return ctx.getContext().req;
  }
}
```

We assumed that `req` (request) has been passed as a part of the context value. We have to set this behavior in the module settings.

TypeScript

```typescript

GraphQLModule.forRoot({
  context: ({ req }) => ({ req }),
})
```

And now, context value will have `req` property.

* Authentication
* Installation
* Bearer strategy
* Default strategy
* User object
* Customize passport
* Inheritance
* JWT strategy
* Example
* Multiple strategies
* GraphQL

----
url: https://docs.nestjs.com/v4/guards
----

### Guards

A guard is a class with the `@Guard()` decorator. The guard should implements the `CanActivate` interface.

Guards have a **single responsibility**. They determine whether a request should be handled by the route handler or not. Until now, the access restriction logic was mostly inside [middlewares](/v4/middlewares). It's still fine since things such as token validation or attaching properties to the `req` object are not strongly connected with a particular routes.

But Middleware is dumb. It doesn't know which handler should be executed after calling the `next()` function. On the other hand, **Guards** have access to the `ExecutionContext` object, so we know exactly what's going to be evaluated.

> **Hint** Guards are executed **after** every middleware, but **before** pipes.

#### RolesGuard

One of the best guards use-cases is the **role-based authentication** because specific routes should only be available when the caller has sufficient permissions (e.g. `admin` role).

That's why we're gonna create a `RolesGuard`, this guard permits access only to users with a specific role.

roles.guard.ts

JavaScript TypeScript

TypeScript

```typescript

import { Guard, CanActivate, ExecutionContext } from '@nestjs/common';
import { Observable } from 'rxjs/Observable';

@Guard()
export class RolesGuard implements CanActivate {
  canActivate(dataOrRequest, context: ExecutionContext): boolean | Promise<boolean> | Observable<boolean> {
    return true;
  }
}
```

TypeScript

```typescript

import { Guard } from '@nestjs/common';

@Guard()
export class RolesGuard {
  canActivate(dataOrRequest, context) {
    return true;
  }
}
```

Every guard provides a `canActivate()` function. The guard might return its boolean answer synchronously or asynchronously via a (`Promise` or `Observable`). The returned value controls the Nest behavior:

* If it returns `true`, the request will be handled by the route handler.
* If it returns `false`, Nest will return a **Forbidden** response and a `403` status code.

The `canActivate()` function takes 2 arguments. The first one is `dataOrRequest`. This value of it depends on where you actually have used the guard. When it's a HTTP request, this variable is a native expressjs [request](http://expressjs.com/en/api.html#req) object, otherwise, it's the data passed to the micro service / or web socket. The second argument is a `context`. This object fulfils `ExecutionContext` interface and contains 2 members - `parent` and `handler`. The `parent` holds the type of the `Controller` class, which the `handler` belongs to. The `handler` is a reference to the route handler function.

> **Hint** Since `canActivate()` method can return a `Promise`, it can be marked as **async**.

#### Usage

The guards can be **controller-scoped**, method-scoped and global-scoped. To set up the guard, we're using a `@UseGuards()` decorator. This decorator can take an endless number of arguments.

cats.controller.ts

JavaScript TypeScript

TypeScript

```typescript

@Controller('cats')
@UseGuards(RolesGuard)
export class CatsController {}
```

> **Notice** The `@UseGuards()` decorator is imported from the `@nestjs/common` package.

The construction above attaches the guard to every handler declared by this controller. If we'd decide to restrict only one of them, we just need to set up the guard at **method level**. To bind the global guard, we're using the `useGlobalGuards()` method of the Nest application instance:

TypeScript

```typescript

const app = await NestFactory.create(ApplicationModule);
app.useGlobalGuards(new RolesGuard());
```

#### Reflector

The guard is working now, but we're still not taking advantage of the most important guard features, being the **execution context**.

Now, the `RolesGuard` isn't reusable. How would we know which roles need to be processed by the handler? The `CatsController` could have a lot of them. Some might be available only for admin, some for everyone.

That's why along with the guards, Nest provides the ability to attach **custom metadata** through `@ReflectMetadata()` decorator.

cats.controller.ts

JavaScript TypeScript

TypeScript

```typescript

@Post()
@ReflectMetadata('roles', ['admin'])
async create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

TypeScript

```typescript

@Post()
@ReflectMetadata('roles', ['admin'])
@Bind(Body())
async create(createCatDto) {
  this.catsService.create(createCatDto);
}
```

> **Notice** The `@ReflectMetadata()` decorator is imported from the `@nestjs/common` package.

With the construction above, we attached the `roles` metadata to the `create()` method. It's not a good practice to use `@ReflectMetadata()` directly. Instead, you should always create your own decorators.

roles.decorator.ts

JavaScript TypeScript

TypeScript

```typescript

import { ReflectMetadata } from '@nestjs/common';

export const Roles = (...roles: string[]) => ReflectMetadata('roles', roles);
```

TypeScript

```typescript

import { ReflectMetadata } from '@nestjs/common';

export const Roles = (...roles) => ReflectMetadata('roles', roles);
```

This way is much cleaner. Since we've a `@Roles()` decorator now, we can use it with on the `create()` method.

cats.controller.ts

JavaScript TypeScript

TypeScript

```typescript

@Post()
@Roles('admin')
async create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

TypeScript

```typescript

@Post()
@Roles('admin')
@Bind(Body())
async create(createCatDto) {
  this.catsService.create(createCatDto);
}
```

That's it. Let's focus on the `RolesGuard` again. Now, it simply returns `true` immediately, allowing request to proceed. To reflect the metadata, we'll use the `Reflector` helper class, which is provided out of the box within `@nestjs/core`.

roles.guard.ts

JavaScript TypeScript

TypeScript

```typescript

import { Guard, CanActivate, ExecutionContext } from '@nestjs/common';
import { Observable } from 'rxjs/Observable';
import { Reflector } from '@nestjs/core';

@Guard()
export class RolesGuard implements CanActivate {
  constructor(private readonly reflector: Reflector) {}

  canActivate(req, context: ExecutionContext): boolean {
    const { parent, handler } = context;
    const roles = this.reflector.get<string[]>('roles', handler);
    if (!roles) {
      return true;
    }

    const user = req.user;
    const hasRole = () => !!user.roles.find((role) => !!roles.find((item) => item === role));
    return user && user.roles && hasRole();
  }
}
```

TypeScript

```typescript

import { Guard, Dependencies } from '@nestjs/common';
import { Reflector } from '@nestjs/core';

@Guard()
@Dependencies(Reflector)
export class RolesGuard {
  constructor(reflector) {
    this.reflector = reflector;
  }

  canActivate(req, context) {
    const { parent, handler } = context;
    const roles = this.reflector.get('roles', handler);
    if (!roles) {
      return true;
    }

    const user = req.user;
    const hasRole = () => !!user.roles.find((role) => !!roles.find((item) => item === role));
    return user && user.roles && hasRole();
  }
}
```

> **Notice** Guards act the same as controllers, components, interceptors and middleware they can **inject dependencies** through the constructor.

> **Hint** In the node.js world, it's a common practice to attach the authorized user to the `req` object. That's why we've assumed that `req.user` contains the user object.

The `Reflector` allows us to easily reflect the metadata by the specified **key**. In example above, we reflected the `handler` because it's a **reference** to the route handler function. We could make this guard even **more generic** if we'd add also the controller reflection part. To extract **controller metadata**, we're just using `parent` instead of `handler` function.

JavaScript TypeScript

TypeScript

```typescript

const roles = this.reflector.get<string[]>('roles', parent);
```

TypeScript

```typescript

const roles = this.reflector.get('roles', parent);
```

Now, when the user would try to call the `/cats` POST endpoint without enough privileges, Nest will automatically return response below:

TypeScript

```typescript

{
  "statusCode": 403,
  "message": "Forbidden resource"
}
```

In fact, the guard which returns `false` forces Nest to throw a `HttpException`. This exception can be caught by the [exception filter](/v4/exception-filters).

#### Custom error responses

To change the default access refusal response, just throw a `HttpException` instead of returning a `false` value.

#### Global guards

The global guards don't belong to any scope. They live outside modules, thus as a result - they can't inject dependencies. We need to create an instance immediately. But quite often, global guards depend on other objects, for example, we'd love to authenticate request using `AuthService`, but this service is a part of the `AuthModule`. How do we solve this?

The solution is pretty easy. Each Nest application instance is in fact, a created **Nest context**. The Nest context is a wrapper around the Nest container, which holds all instantiated classes. We can grab any existing instance from within any imported module directly using the application object.

Let's assume that we have a `AuthGuard` registered in the `AuthModule`. This `AuthModule` is imported into the **root module**. We can pick the `AuthGuard` instance using following syntax:

TypeScript

```typescript

const app = await NestFactory.create(ApplicationModule);
const authGuard = app
  .select(AuthModule)
  .get(AuthGuard);

app.useGlobalGuards(authGuard);
```

To grab the `AuthGuard` instance we have to use 2 methods, well-described in the table below:

|            |                                                                                                                        |
| ---------- | ---------------------------------------------------------------------------------------------------------------------- |
| `get()`    | Makes it possible to retrieve the instance of the component or controller available inside the processed module.       |
| `select()` | Allows you to navigate through the module tree, for example, to pull out a specific instance from the selected module. |

> **Hint** The root module is selected by default. To select any other module, you need to go through the entire modules stack (step by step).

#### Sponsors

[](https://valor-software.com/)

Nest is an MIT-licensed open source project. It can grow thanks to the support by these awesome people. If you'd like to join them, please read more [here](https://opencollective.com/nest). Thanks!

[](https://opencollective.com/nest/backer/0/website)[](https://opencollective.com/nest/backer/1/website)[](https://opencollective.com/nest/backer/2/website)[](https://opencollective.com/nest/backer/3/website)[](https://opencollective.com/nest/backer/4/website)[](https://opencollective.com/nest/backer/5/website)[](https://opencollective.com/nest/backer/6/website)[](https://opencollective.com/nest/backer/7/website)[](https://opencollective.com/nest/backer/8/website)[](https://opencollective.com/nest/backer/9/website)[](https://opencollective.com/nest/backer/10/website)[](https://opencollective.com/nest/backer/11/website)[](https://opencollective.com/nest/backer/12/website)[](https://opencollective.com/nest/backer/13/website)[](https://opencollective.com/nest/backer/14/website)[](https://opencollective.com/nest/backer/15/website)[](https://opencollective.com/nest/backer/16/website)[](https://opencollective.com/nest/backer/17/website)[](https://opencollective.com/nest/backer/18/website)[](https://opencollective.com/nest/backer/19/website)[](https://opencollective.com/nest/backer/20/website)[](https://opencollective.com/nest/backer/21/website)[](https://opencollective.com/nest/backer/22/website)[](https://opencollective.com/nest/backer/23/website)[](https://opencollective.com/nest/backer/24/website)[](https://opencollective.com/nest/backer/25/website)[](https://opencollective.com/nest/backer/26/website)[](https://opencollective.com/nest/backer/27/website)[](https://opencollective.com/nest/backer/28/website)[](https://opencollective.com/nest/backer/29/website)

[Become a sponsor](https://opencollective.com/nest)

----
url: https://docs.nestjs.com/v7/techniques/validation
----

* [Validation](https://docs.nestjs.com/v7/techniques/validation#validation)
* [Overview](https://docs.nestjs.com/v7/techniques/validation#overview)
* [Using the built-in ValidationPipe](https://docs.nestjs.com/v7/techniques/validation#using-the-built-in-validationpipe)
* [Auto-validation](https://docs.nestjs.com/v7/techniques/validation#auto-validation)
* [Disable detailed errors](https://docs.nestjs.com/v7/techniques/validation#disable-detailed-errors)
* [Stripping properties](https://docs.nestjs.com/v7/techniques/validation#stripping-properties)
* [Transform payload objects](https://docs.nestjs.com/v7/techniques/validation#transform-payload-objects)
* [Explicit conversion](https://docs.nestjs.com/v7/techniques/validation#explicit-conversion)
* [Mapped types](https://docs.nestjs.com/v7/techniques/validation#mapped-types)
* [Parsing and validating arrays](https://docs.nestjs.com/v7/techniques/validation#parsing-and-validating-arrays)
* [WebSockets and Microservices](https://docs.nestjs.com/v7/techniques/validation#websockets-and-microservices)
* [Learn more](https://docs.nestjs.com/v7/techniques/validation#learn-more)

In the [Pipes](/v7/pipes) chapter, we went through the process of building simple pipes and binding them to controllers, methods or to the global app to demonstrate how the process works. Be sure to review that chapter to best understand the topics of this chapter. Here, we'll focus on various **real world** use cases of the `ValidationPipe`, and show how to use some of its advanced customization features.

#### Using the built-in ValidationPipe[#](/techniques/validation#using-the-built-in-validationpipe)

> **Hint** The `ValidationPipe` is exported from the `@nestjs/common` package.

Because this pipe uses the `class-validator` and `class-transformer` libraries, there are many options available. You configure these settings via a configuration object passed to the pipe. Following are the built-in options:

```typescript

export interface ValidationPipeOptions extends ValidatorOptions {
  transform?: boolean;
  disableErrorMessages?: boolean;
  exceptionFactory?: (errors: ValidationError[]) => any;
}
```

In addition to these, all `class-validator` options (inherited from the `ValidatorOptions` interface) are available:

| Option                   | Type       | Description                                                                                                                           |
| ------------------------ | ---------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| `skipMissingProperties`  | `boolean`  | If set to true, validator will skip validation of all properties that are missing in the validating object.                           |
| `whitelist`              | `boolean`  | If set to true, validator will strip validated (returned) object of any properties that do not use any validation decorators.         |
| `forbidNonWhitelisted`   | `boolean`  | If set to true, instead of stripping non-whitelisted properties validator will throw an exception.                                    |
| `forbidUnknownValues`    | `boolean`  | If set to true, attempts to validate unknown objects fail immediately.                                                                |
| `disableErrorMessages`   | `boolean`  | If set to true, validation errors will not be returned to the client.                                                                 |
| `errorHttpStatusCode`    | `number`   | This setting allows you to specify which exception type will be used in case of an error. By default it throws `BadRequestException`. |
| `exceptionFactory`       | `Function` | Takes an array of the validation errors and returns an exception object to be thrown.                                                 |
| `groups`                 | `string[]` | Groups to be used during validation of the object.                                                                                    |
| `dismissDefaultMessages` | `boolean`  | If set to true, the validation will not use default messages. Error message always will be `undefined` if its not explicitly set.     |
| `validationError.target` | `boolean`  | Indicates if target should be exposed in `ValidationError`                                                                            |
| `validationError.value`  | `boolean`  | Indicates if validated value should be exposed in `ValidationError`.                                                                  |

> **Notice** Find more information about the `class-validator` package in its [repository](https://github.com/typestack/class-validator).

#### Auto-validation[#](/techniques/validation#auto-validation)

We'll start by binding `ValidationPipe` at the application level, thus ensuring all endpoints are protected from receiving incorrect data.

```typescript

async function bootstrap() {
  const app = await NestFactory.create(ApplicationModule);
  app.useGlobalPipes(new ValidationPipe());
  await app.listen(3000);
}
bootstrap();
```

To test our pipe, let's create a basic endpoint.

```typescript

@Post()
create(@Body() createUserDto: CreateUserDto) {
  return 'This action adds a new user';
}
```

> **Hint** Since TypeScript does not store metadata about **generics or interfaces**, when you use them in your DTOs, `ValidationPipe` may not be able to properly validate incoming data. For this reason, consider using concrete classes in your DTOs.

Now we can add a few validation rules in our `CreateUserDto`. We do this using decorators provided by the `class-validator` package, described in detail [here](https://github.com/typestack/class-validator#validation-decorators). In this fashion, any route that uses the `CreateUserDto` will automatically enforce these validation rules.

```typescript

import { IsEmail, IsNotEmpty } from 'class-validator';

export class CreateUserDto {
  @IsEmail()
  email: string;

  @IsNotEmpty()
  password: string;
}
```

With these rules in place, if a request hits our endpoint with an invalid `email` property in the request body, the application will automatically respond with a `400 Bad Request` code, along with the following response body:

```json

{
  "statusCode": 400,
  "error": "Bad Request",
  "message": ["email must be an email"]
}
```

In addition to validating request bodies, the `ValidationPipe` can be used with other request object properties as well. Imagine that we would like to accept `:id` in the endpoint path. To ensure that only numbers are accepted for this request parameter, we can use the following construct:

```typescript

@Get(':id')
findOne(@Param() params: FindOneParams) {
  return 'This action returns a user';
}
```

`FindOneParams`, like a DTO, is simply a class that defines validation rules using `class-validator`. It would look like this:

```typescript

import { IsNumberString } from 'class-validator';

export class FindOneParams {
  @IsNumberString()
  id: number;
}
```

#### Disable detailed errors[#](/techniques/validation#disable-detailed-errors)

Error messages can be helpful to explain what was incorrect in a request. However, some production environments prefer to disable detailed errors. Do this by passing an options object to the `ValidationPipe`:

```typescript

app.useGlobalPipes(
  new ValidationPipe({
    disableErrorMessages: true,
  }),
);
```

As a result, detailed error messages won't be displayed in the response body.

#### Stripping properties[#](/techniques/validation#stripping-properties)

Our `ValidationPipe` can also filter out properties that should not be received by the method handler. In this case, we can **whitelist** the acceptable properties, and any property not included in the whitelist is automatically stripped from the resulting object. For example, if our handler expects `email` and `password` properties, but a request also includes an `age` property, this property can be automatically removed from the resulting DTO. To enable such behavior, set `whitelist` to `true`.

```typescript

app.useGlobalPipes(
  new ValidationPipe({
    whitelist: true,
  }),
);
```

```typescript

@Post()
@UsePipes(new ValidationPipe({ transform: true }))
async create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

To enable this behavior globally, set the option on a global pipe:

```typescript

app.useGlobalPipes(
  new ValidationPipe({
    transform: true,
  }),
);
```

With the auto-transformation option enabled, the `ValidationPipe` will also perform conversion of primitive types. In the following example, the `findOne()` method takes one argument which represents an extracted `id` path parameter:

```typescript

@Get(':id')
findOne(@Param('id') id: number) {
  console.log(typeof id === 'number'); // true
  return 'This action returns a user';
}
```

By default, every path parameter and query parameter comes over the network as a `string`. In the above example, we specified the `id` type as a `number` (in the method signature). Therefore, the `ValidationPipe` will try to automatically convert a string identifier to a number.

#### Explicit conversion[#](/techniques/validation#explicit-conversion)

In the above section, we showed how the `ValidationPipe` can implicitly transform query and path parameters based on the expected type. However, this feature requires having auto-transformation enabled.

Alternatively (with auto-transformation disabled), you can explicitly cast values using the `ParseIntPipe` or `ParseBoolPipe` (note that `ParseStringPipe` is not needed because, as mentioned earlier, every path parameter and query parameter comes over the network as a `string` by default).

```typescript

@Get(':id')
findOne(
  @Param('id', ParseIntPipe) id: number,
  @Query('sort', ParseBoolPipe) sort: boolean,
) {
  console.log(typeof id === 'number'); // true
  console.log(typeof sort === 'boolean'); // true
  return 'This action returns a user';
}
```

> **Hint** The `ParseIntPipe` and `ParseBoolPipe` are exported from the `@nestjs/common` package.

#### Mapped types[#](/techniques/validation#mapped-types)

As you build out features like **CRUD** (Create/Read/Update/Delete) it's often useful to construct variants on a base entity type. Nest provides several utility functions that perform type transformations to make this task more convenient.

> **Warning** If your application uses the `@nestjs/swagger` package, see [this chapter](/v7/openapi/mapped-types) for more information about Mapped Types. Likewise, if you use the `@nestjs/graphql` package see [this chapter](/v7/graphql/mapped-types). Both packages heavily rely on types and so they require a different import to be used. Therefore, if you used `@nestjs/mapped-types` (instead of an appropriate one, either `@nestjs/swagger` or `@nestjs/graphql` depending on the type of your app), you may face various, undocumented side-effects.

When building input validation types (also called DTOs), it's often useful to build **create** and **update** variations on the same type. For example, the **create** variant may require all fields, while the **update** variant may make all fields optional.

Nest provides the `PartialType()` utility function to make this task easier and minimize boilerplate.

The `PartialType()` function returns a type (class) with all the properties of the input type set to optional. For example, suppose we have a **create** type as follows:

```typescript

export class CreateCatDto {
  name: string;
  age: number;
  breed: string;
}
```

By default, all of these fields are required. To create a type with the same fields, but with each one optional, use `PartialType()` passing the class reference (`CreateCatDto`) as an argument:

```typescript

export class UpdateCatDto extends PartialType(CreateCatDto) {}
```

> **Hint** The `PartialType()` function is imported from the `@nestjs/mapped-types` package. The `PickType()` function constructs a new type (class) by picking a set of properties from an input type. For example, suppose we start with a type like:

```typescript

export class CreateCatDto {
  name: string;
  age: number;
  breed: string;
}
```

We can pick a set of properties from this class using the `PickType()` utility function:

```typescript

export class UpdateCatAgeDto extends PickType(CreateCatDto, ['age'] as const) {}
```

> **Hint** The `PickType()` function is imported from the `@nestjs/mapped-types` package. The `OmitType()` function constructs a type by picking all properties from an input type and then removing a particular set of keys. For example, suppose we start with a type like:

```typescript

export class CreateCatDto {
  name: string;
  age: number;
  breed: string;
}
```

We can generate a derived type that has every property **except**`name` as shown below. In this construct, the second argument to `OmitType` is an array of property names.

```typescript

export class UpdateCatDto extends OmitType(CreateCatDto, ['name'] as const) {}
```

> **Hint** The `OmitType()` function is imported from the `@nestjs/mapped-types` package. The `IntersectionType()` function combines two types into one new type (class). For example, suppose we start with two types like:

```typescript

export class CreateCatDto {
  name: string;
  breed: string;
}

export class AdditionalCatInfo {
  color: string;
}
```

We can generate a new type that combines all properties in both types.

```typescript

export class UpdateCatDto extends IntersectionType(
  CreateCatDto,
  AdditionalCatInfo,
) {}
```

> **Hint** The `IntersectionType()` function is imported from the `@nestjs/mapped-types` package.

The type mapping utility functions are composable. For example, the following will produce a type (class) that has all of the properties of the `CreateCatDto` type except for `name`, and those properties will be set to optional:

```typescript

export class UpdateCatDto extends PartialType(
  OmitType(CreateCatDto, ['name'] as const),
) {}
```

#### Parsing and validating arrays[#](/techniques/validation#parsing-and-validating-arrays)

TypeScript does not store metadata about generics or interfaces, so when you use them in your DTOs, `ValidationPipe` may not be able to properly validate incoming data. For instance, in the following code, `createUserDtos` won't be correctly validated:

```typescript

@Post()
createBulk(@Body() createUserDtos: CreateUserDto[]) {
  return 'This action adds new users';
}
```

To validate the array, create a dedicated class which contains a property that wraps the array, or use the `ParseArrayPipe`.

```typescript

@Post()
createBulk(
  @Body(new ParseArrayPipe({ items: CreateUserDto }))
  createUserDtos: CreateUserDto[],
) {
  return 'This action adds new users';
}
```

In addition, the `ParseArrayPipe` may come in handy when parsing query parameters. Let's consider a `findByIds()` method that returns users based on identifiers passed as query parameters.

```typescript

@Get()
findByIds(
  @Query('id', new ParseArrayPipe({ items: Number, separator: ',' }))
  ids: number[],
) {
  return 'This action returns users by ids';
}
```

This construction validates the incoming query parameters from an HTTP `GET` request like the following:

```bash

GET /?ids=1,2,3
```

#### WebSockets and Microservices[#](/techniques/validation#websockets-and-microservices)

While this chapter shows examples using HTTP style applications (e.g., Express or Fastify), the `ValidationPipe` works the same for WebSockets and microservices, regardless of the transport method that is used.

#### Learn more[#](/techniques/validation#learn-more)

Read more about custom validators, error messages, and available decorators as provided by the `class-validator` package [here](https://github.com/typestack/class-validator).

----
url: https://docs.nestjs.com/v6/microservices/grpc
----

* [gRPC](https://docs.nestjs.com/v6/microservices/grpc#grpc)
* [Installation](https://docs.nestjs.com/v6/microservices/grpc#installation)
* [Overview](https://docs.nestjs.com/v6/microservices/grpc#overview)
* [Options](https://docs.nestjs.com/v6/microservices/grpc#options)
* [Sample gRPC service](https://docs.nestjs.com/v6/microservices/grpc#sample-grpc-service)
* [Client](https://docs.nestjs.com/v6/microservices/grpc#client)
* [gRPC Streaming](https://docs.nestjs.com/v6/microservices/grpc#grpc-streaming)
* [Streaming sample](https://docs.nestjs.com/v6/microservices/grpc#streaming-sample)
* [Subject strategy](https://docs.nestjs.com/v6/microservices/grpc#subject-strategy)
* [Call stream handler](https://docs.nestjs.com/v6/microservices/grpc#call-stream-handler)

```bash

$ npm i --save grpc @grpc/proto-loader
```

#### Overview[#](/microservices/grpc#overview)

Like other Nest microservices transport layer implementations, you select the gRPC transporter mechanism using the `transport` property of the options object passed to the `createMicroservice()` method. In the following example, we'll set up a hero service. The `options` property provides metadata about that service; its properties are described [below](microservices/grpc#options).

main.ts

JS TS

```typescript

const app = await NestFactory.createMicroservice(AppModule, {
  transport: Transport.GRPC,
  options: {
    package: 'hero',
    protoPath: join(__dirname, 'hero/hero.proto'),
  },
});
```

> **Hint** The `join()` function is imported from the `path` package; the `Transport` enum is imported from the `@nestjs/microservices` package.

#### Options[#](/microservices/grpc#options)

The **gRPC** transporter options object exposes the properties described below.

|               |                                                                                                                                                                                                                          |
| ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `package`     | Protobuf package name (matches `package` setting from `.proto` file). Required                                                                                                                                           |
| `protoPath`   | Absolute (or relative to the root dir) path to the `.proto` file. Required                                                                                                                                               |
| `url`         | Connection url. String in the format `ip address/dns name:port` (for example, `'localhost:50051'`) defining the address/port on which the transporter establishes a connection. Optional. Defaults to `'localhost:5000'` |
| `protoLoader` | NPM package name for the utility to load `.proto` files. Optional. Defaults to `'@grpc/proto-loader'`                                                                                                                    |
| `loader`      | `@grpc/proto-loader` options. These provide detailed control over the behavior of `.proto` files. Optional. See [here](https://github.com/grpc/grpc-node/blob/master/packages/proto-loader/README.md) for more details   |
| `credentials` | Server credentials. Optional. [Read more here](https://grpc.io/grpc/node/grpc.ServerCredentials.html)                                                                                                                    |

#### Sample gRPC service[#](/microservices/grpc#sample-grpc-service)

Let's define our sample gRPC service called `HeroService`. In the above `options` object, the`protoPath` property sets a path to the `.proto` definitions file `hero.proto`. The `hero.proto` file is structured using [protocol buffers](https://developers.google.com/protocol-buffers). Here's what it looks like:

```typescript

// hero/hero.proto
syntax = "proto3";

package hero;

service HeroService {
  rpc FindOne (HeroById) returns (Hero) {}
}

message HeroById {
  int32 id = 1;
}

message Hero {
  int32 id = 1;
  string name = 2;
}
```

Our `HeroService` exposes a `FindOne()` method. This method expects an input argument of type `HeroById` and returns a `Hero` message (protocol buffers use `message` elements to define both parameter types and return types).

Next, we need to implement the service. To define a handler that fulfills this definition, we use the `@GrpcMethod()` decorator in a controller, as shown below. This decorator provides the metadata needed to declare a method as a gRPC service method.

> **Hint** The `@MessagePattern()` decorator ([read more](microservices/basics#request-response)) introduced in previous microservices chapters is not used with gRPC-based microservices. The `@GrpcMethod()` decorator effectively takes its place for gRPC-based microservices.

hero.controller.ts

JS TS

```typescript

@Controller()
export class HeroController {
  @GrpcMethod('HeroService', 'FindOne')
  findOne(data: HeroById, metadata: any): Hero {
    const items = [
      { id: 1, name: 'John' },
      { id: 2, name: 'Doe' },
    ];
    return items.find(({ id }) => id === data.id);
  }
}
```

```typescript

@Controller()
export class HeroController {
  @GrpcMethod('HeroService', 'FindOne')
  findOne(data, metadata) {
    const items = [
      { id: 1, name: 'John' },
      { id: 2, name: 'Doe' },
    ];
    return items.find(({ id }) => id === data.id);
  }
}
```

> **Hint** The `@GrpcMethod()` decorator is imported from the `@nestjs/microservices` package.

The decorator shown above takes two arguments. The first is the service name (e.g., `'HeroService'`), corresponding to the `HeroService` service definition in `hero.proto`. The second (the string `'FindOne'`) corresponds to the `FindOne()` rpc method defined within `HeroService` in the `hero.proto` file.

The `findOne()` handler method takes two arguments, the `data` passed from the caller and `metadata` that stores gRPC request metadata.

Both `@GrpcMethod()` decorator arguments are optional. If called without the second argument (e.g., `'FindOne'`), Nest will automatically associate the `.proto` file rpc method with the handler based on converting the handler name to upper camel case (e.g., the `findOne` handler is associated with the `FindOne` rpc call definition). This is shown below.

hero.controller.ts

JS TS

```typescript

@Controller()
export class HeroController {
  @GrpcMethod('HeroService')
  findOne(data: HeroById, metadata: any): Hero {
    const items = [
      { id: 1, name: 'John' },
      { id: 2, name: 'Doe' },
    ];
    return items.find(({ id }) => id === data.id);
  }
}
```

```typescript

@Controller()
export class HeroController {
  @GrpcMethod('HeroService')
  findOne(data, metadata) {
    const items = [
      { id: 1, name: 'John' },
      { id: 2, name: 'Doe' },
    ];
    return items.find(({ id }) => id === data.id);
  }
}
```

You can also omit the first `@GrpcMethod()` argument. In this case, Nest automatically associates the handler with the service definition from the proto definitions file based on the **class** name where the handler is defined. For example, in the following code, class `HeroService` associates its handler methods with the `HeroService` service definition in the `hero.proto` file based on the matching of the name `'HeroService'`.

hero.controller.ts

JS TS

```typescript

@Controller()
export class HeroService {
  @GrpcMethod()
  findOne(data: HeroById, metadata: any): Hero {
    const items = [
      { id: 1, name: 'John' },
      { id: 2, name: 'Doe' },
    ];
    return items.find(({ id }) => id === data.id);
  }
}
```

```typescript

@Controller()
export class HeroService {
  @GrpcMethod()
  findOne(data, metadata) {
    const items = [
      { id: 1, name: 'John' },
      { id: 2, name: 'Doe' },
    ];
    return items.find(({ id }) => id === data.id);
  }
}
```

#### Client[#](/microservices/grpc#client)

Nest applications can act as gRPC clients, consuming services defined in `.proto` files. You access remote services through a `ClientGrpc` object. You can obtain a `ClientGrpc` object in several ways.

The preferred technique is to import the `ClientsModule`. Use the `register()` method to bind a package of services defined in a `.proto` file to an injection token, and to configure the service. The `name` property is the injection token. For gRPC services, use `transport: Transport.GRPC`. The `options` property is an object with the same properties described [above](microservices/grpc#options).

```typescript

imports: [
  ClientsModule.register([
    {
      name: 'HERO_PACKAGE',
      transport: Transport.GRPC,
      options: {
        package: 'hero',
        protoPath: join(__dirname, 'hero/hero.proto'),
      },
    },
  ]),
];
```

> **Hint** The `register()` method takes an array of objects. Register multiple packages by providing a comma separated list of registration objects.

Once registered, we can inject the configured `ClientGrpc` object with `@Inject()`. Then we use the `ClientGrpc` object's `getService()` method to retrieve the service instance, as shown below.

```typescript

@Injectable()
export class AppService implements OnModuleInit {
  private heroService: HeroService;

  constructor(@Inject('HERO_PACKAGE') private readonly client: ClientGrpc) {}

  onModuleInit() {
    this.heroService = this.client.getService<HeroService>('HeroService');
  }

  getHero(): Observable<string> {
    return this.heroService.findOne({ id: 1 });
  }
}
```

Notice that there is a small difference compared to the technique used in other microservice transport methods. Instead of the `ClientProxy` class, we use the `ClientGrpc` class, which provides the `getService()` method. The `getService()` generic method takes a service name as an argument and returns its instance (if available).

Alternatively, you can use the `@Client()` decorator to instantiate a `ClientGrpc` object, as follows:

```typescript

@Injectable()
export class AppService implements OnModuleInit {
  @Client({
    transport: Transport.GRPC,
    options: {
      package: 'hero',
      protoPath: join(__dirname, 'hero/hero.proto'),
    },
  })
  client: ClientGrpc;

  private heroService: HeroService;

  onModuleInit() {
    this.heroService = this.client.getService<HeroService>('HeroService');
  }

  getHero(): Observable<string> {
    return this.heroService.findOne({ id: 1 });
  }
}
```

Finally, for more complex scenarios, we can inject a dynamically configured client using the `ClientProxyFactory` class as described [here](/microservices/basics#client).

In either case, we end up with a reference to our `HeroService` proxy object, which exposes the same set of methods that are defined inside the `.proto` file. Now, when we access this proxy object (i.e., `heroService`), the gRPC system automatically serializes requests, forwards them to the remote system, returns a response, and deserializes the response. Because gRPC shields us from these network communication details, `heroService` looks and acts like a local provider.

Note, all service methods are **lower camel cased** (in order to follow the natural convention of the language). So, for example, while our `.proto` file `HeroService` definition contains the `FindOne()` function, the `heroService` instance will provide the `findOne()` method.

```typescript

interface HeroService {
  findOne(data: { id: number }): Observable<any>;
}
```

A message handler is also able to return an `Observable`, in which case the result values will be emitted until the stream is completed.

hero.controller.ts

JS TS

```typescript

@Get()
call(): Observable<any> {
  return this.heroService.findOne({ id: 1 });
}
```

```typescript

@Get()
call() {
  return this.heroService.findOne({ id: 1 });
}
```

A full working example is available [here](https://github.com/nestjs/nest/tree/master/sample/04-grpc).

```typescript

// hello/hello.proto
syntax = "proto3";

package hello;

service HelloService {
  rpc BidiHello(stream HelloRequest) returns (stream HelloResponse)
  rpc LotsOfGreetings(stream HelloRequest) returns (HelloResponse)
}

message HelloRequest {
  string greeting = 1;
}

message HelloResponse {
  string reply = 1;
}
```

> **Hint** The `LotsOfGreetings` method can be simply implemented with the `@GrpcMethod` decorator (as in the examples above) since the returned stream can emit multiple values.

Based on this `.proto` file, let's define the `HelloService` interface:

```typescript

interface HelloService {
  bidiHello(upstream: Observable<HelloRequest>): Observable<HelloResponse>;
  lotsOfGreetings(
    upstream: Observable<HelloRequest>,
  ): Observable<HelloResponse>;
}

interface HelloRequest {
  greeting: string;
}

interface HelloResponse {
  reply: string;
}
```

#### Subject strategy[#](/microservices/grpc#subject-strategy)

The `@GrpcStreamMethod()` decorator provides the function parameter as an RxJS `Observable`. Thus, we can receive and process multiple messages.

```typescript

@GrpcStreamMethod()
bidiHello(messages: Observable<any>): Observable<any> {
  const subject = new Subject();

  const onNext = message => {
    console.log(message);
    subject.next({
      reply: 'Hello, world!'
    });
  };
  const onComplete = () => subject.complete();
  messages.subscribe(onNext, null, onComplete);

  return subject.asObservable();
}
```

> **Hint** For supporting full-duplex interaction with the `@GrpcStreamMethod()` decorator, the controller method must return an RxJS `Observable`.

According to the service definition (in the `.proto` file), the `BidiHello` method should stream requests to the service. To send multiple asynchronous messages to the stream from a client, we leverage an RxJS `ReplySubject` class.

```typescript

const helloService = this.client.getService<HelloService>('HelloService');
const helloRequest$ = new ReplySubject<HelloRequest>();

helloRequest$.next({ greeting: 'Hello (1)!' });
helloRequest$.next({ greeting: 'Hello (2)!' });
helloRequest$.complete();

return helloService.bidiHello(helloRequest$);
```

In the example above, we wrote two messages to the stream (`next()` calls) and notified the service that we've completed sending the data (`complete()` call).

#### Call stream handler[#](/microservices/grpc#call-stream-handler)

When the method return value is defined as `stream`, the `@GrpcStreamCall()` decorator provides the function parameter as `grpc.ServerDuplexStream`, which supports standard methods like `.on('data', callback)`, `.write(message)` or `.cancel()`. Full documentation on available methods can be found [here](https://grpc.github.io/grpc/node/grpc-ClientDuplexStream.html).

Alternatively, when the method return value is not a `stream`, the `@GrpcStreamCall()` decorator provides two function parameters, respectively `grpc.ServerReadableStream` (read more [here](https://grpc.github.io/grpc/node/grpc-ServerReadableStream.html)) and `callback`.

Let's start with implementing the `BidiHello` which should support a full-duplex interaction.

```typescript

@GrpcStreamCall()
bidiHello(requestStream: any) {
  requestStream.on('data', message => {
    console.log(message);
    requestStream.write({
      reply: 'Hello, world!'
    });
  });
}
```

> **Hint** This decorator does not require any specific return parameter to be provided. It is expected that the stream will be handled similar to any other standard stream type.

In the example above, we used the `write()` method to write objects to the response stream. The callback passed into the `.on()` method as a second parameter will be called every time our service receives a new chunk of data.

Let's implement the `LotsOfGreetings` method.

```typescript

@GrpcStreamCall()
lotsOfGreetings(requestStream: any, callback: (err: unknown, value: HelloResponse) => void) {
  requestStream.on('data', message => {
    console.log(message);
  });
  requestStream.on('end', () => callback(null, { reply: 'Hello, world!' }));
}
```

Here we used the `callback` function to send the response once processing of the `requestStream` has been completed.

----
url: https://docs.nestjs.com/v9/fundamentals/async-providers
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Asynchronous providers](https://docs.nestjs.com/v9/fundamentals/async-providers#asynchronous-providers)
* [Injection](https://docs.nestjs.com/v9/fundamentals/async-providers#injection)
* [Example](https://docs.nestjs.com/v9/fundamentals/async-providers#example)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/fundamentals/async-components.md "Suggest Edits")

### Asynchronous providers

At times, the application start should be delayed until one or more **asynchronous tasks** are completed. For example, you may not want to start accepting requests until the connection with the database has been established. You can achieve this using asynchronous providers.

The syntax for this is to use `async/await` with the `useFactory` syntax. The factory returns a `Promise`, and the factory function can `await` asynchronous tasks. Nest will await resolution of the promise before instantiating any class that depends on (injects) such a provider.

```typescript

{
  provide: 'ASYNC_CONNECTION',
  useFactory: async () => {
    const connection = await createConnection(options);
    return connection;
  },
}
```

> **Hint** Learn more about custom provider syntax [here](/v9/fundamentals/custom-providers).

#### Injection[#](/fundamentals/async-providers#injection)

Asynchronous providers are injected to other components by their tokens, like any other provider. In the example above, you would use the construct `@Inject('ASYNC_CONNECTION')`.

#### Example[#](/fundamentals/async-providers#example)

[The TypeORM recipe](/v9/recipes/sql-typeorm) has a more substantial example of an asynchronous provider.

----
url: https://docs.nestjs.com/v9/faq/multiple-servers
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [HTTPS](https://docs.nestjs.com/v9/faq/multiple-servers#https)
* [Multiple simultaneous servers](https://docs.nestjs.com/v9/faq/multiple-servers#multiple-simultaneous-servers)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/faq/multiple-servers.md "Suggest Edits")

### HTTPS

To create an application that uses the HTTPS protocol, set the `httpsOptions` property in the options object passed to the `create()` method of the `NestFactory` class:

```typescript

const httpsOptions = {
  key: fs.readFileSync('./secrets/private-key.pem'),
  cert: fs.readFileSync('./secrets/public-certificate.pem'),
};
const app = await NestFactory.create(AppModule, {
  httpsOptions,
});
await app.listen(3000);
```

If you use the `FastifyAdapter`, create the application as follows:

```typescript

const app = await NestFactory.create<NestFastifyApplication>(
  AppModule,
  new FastifyAdapter({ https: httpsOptions }),
);
```

#### Multiple simultaneous servers[#](/faq/multiple-servers#multiple-simultaneous-servers)

The following recipe shows how to instantiate a Nest application that listens on multiple ports (for example, on a non-HTTPS port and an HTTPS port) simultaneously.

```typescript

const httpsOptions = {
  key: fs.readFileSync('./secrets/private-key.pem'),
  cert: fs.readFileSync('./secrets/public-certificate.pem'),
};

const server = express();
const app = await NestFactory.create(
  AppModule,
  new ExpressAdapter(server),
);
await app.init();

http.createServer(server).listen(3000);
https.createServer(httpsOptions, server).listen(443);
```

> **Hint** The `ExpressAdapter` is imported from the `@nestjs/platform-express` package. The `http` and `https` packages are native Node.js packages.

> **Warning** This recipe does not work with [GraphQL Subscriptions](/v9/graphql/subscriptions).

----
url: https://docs.nestjs.com/v5/exception-filters
----

### Exception filters

The built-in **exceptions layer** is responsible for handling all thrown exceptions across your whole application. When an unhandled exception is caught, the end-user will receive an appropriate user-friendly response.

Each ocurred exception is handled by the global exception filter, and when it's **unrecognized** (is neither `HttpException` nor a class that inherits from `HttpException`), a user receives the below JSON response:

TypeScript

```typescript

{
  "statusCode": 500,
  "message": "Internal server error"
}
```

#### Base exceptions

There's a built-in `HttpException` class exposed from the `@nestjs/common` package. As you already know, when you throw a `HttpException` object, it'll be caught by the handler and afterwards, transformed to the relevant JSON response.

In the `CatsController`, we have a `create()` method (a `POST` route). Let's assume that this route handler would throw an exception for some reason. We're gonna hardcode it:

cats.controller.ts

JS TS

TypeScript

```typescript

@Post()
async create(@Body() createCatDto: CreateCatDto) {
  throw new HttpException('Forbidden', HttpStatus.FORBIDDEN);
}
```

TypeScript

```typescript

@Post()
@Bind(Body())
async create(createCatDto) {
  throw new HttpException('Forbidden', HttpStatus.FORBIDDEN);
}
```

> **Hint** We used the `HttpStatus` here. It is a helper enumerator imported from the `@nestjs/common` package.

When the client calls this endpoint, the response would look like this:

TypeScript

```typescript

{
  "statusCode": 403,
  "message": "Forbidden"
}
```

The `HttpException` constructor takes `string | object` as the first argument. If you pass an `object` instead of a `string`, you'll completely override the response body.

cats.controller.ts

JS TS

TypeScript

```typescript

@Post()
async create(@Body() createCatDto: CreateCatDto) {
  throw new HttpException({
    status: HttpStatus.FORBIDDEN,
    error: 'This is a custom message',
  }, 403);
}
```

TypeScript

```typescript

@Post()
@Bind(Body())
async create(createCatDto) {
  throw new HttpException({
    status: HttpStatus.FORBIDDEN,
    error: 'This is a custom message',
  }, 403);
}
```

And this's how the response would look like:

TypeScript

```typescript

{
  "status": 403,
  "error": "This is a custom message"
}
```

#### Exceptions hierarchy

A good practice is to create your own **exceptions hierarchy**. It means that every HTTP exception should inherit from the base `HttpException` class. As a result, Nest will recognize your exception, and will fully take care of the error responses.

forbidden.exception.ts

JS TS

TypeScript

```typescript

export class ForbiddenException extends HttpException {
  constructor() {
    super('Forbidden', HttpStatus.FORBIDDEN);
  }
}
```

Since `ForbiddenException` extends the base `HttpException`, it's going to work well with the core exceptions handler, and therefore we can use it inside the `create()` method.

cats.controller.ts

JS TS

TypeScript

```typescript

@Post()
async create(@Body() createCatDto: CreateCatDto) {
  throw new ForbiddenException();
}
```

TypeScript

```typescript

@Post()
@Bind(Body())
async create(createCatDto) {
  throw new ForbiddenException();
}
```

#### HTTP exceptions

In order to reduce the boilerplate code, Nest provides a set of usable exceptions that inherits from the core `HttpException`. All of them are exposed from the `@nestjs/common` package:

#### Exception filters

The base exception handler is fine, but sometimes you may want to have a **full control** over the exceptions layer, for example, add some logging or use a different JSON schema based on some chosen factors. We adore generic solutions and making your life easier, that's why the feature called **exception filters** has been created.

We are going to create a filter which is responsible for catching exceptions that are an instance of `HttpException` class and set up a custom response logic for them.

http-exception.filter.ts

JS TS

TypeScript

```typescript

import { ExceptionFilter, Catch, ArgumentsHost } from '@nestjs/common';
import { HttpException } from '@nestjs/common';

@Catch(HttpException)
export class HttpExceptionFilter implements ExceptionFilter {
  catch(exception: HttpException, host: ArgumentsHost) {
    const ctx = host.switchToHttp();
    const response = ctx.getResponse();
    const request = ctx.getRequest();
    const status = exception.getStatus();

    response
      .status(status)
      .json({
        statusCode: status,
        timestamp: new Date().toISOString(),
        path: request.url,
      });
  }
}
```

TypeScript

```typescript

import { Catch } from '@nestjs/common';
import { HttpException } from '@nestjs/common';

@Catch(HttpException)
export class HttpExceptionFilter {
  catch(exception, host) {
    const ctx = host.switchToHttp();
    const response = ctx.getResponse();
    const request = ctx.getRequest();
    const status = exception.getStatus();

    response
      .status(status)
      .json({
        statusCode: status,
        timestamp: new Date().toISOString(),
        path: request.url,
      });
  }
}
```

> **Hint** All exception filters should implement the generic `ExceptionFilter<T>` interface. It forces you to provide the `catch(exception: T, host: ArgumentsHost)` method with the valid signature. `T` indicates a type of the exception.

The `@Catch(HttpException)` decorator binds the required metadata to the exception filter, telling Nest that this particular filter is looking for `HttpException` and nothing else. In practice, the `@Catch()` decorator may take an endless number of parameters, therefore you can set up the filter for several types of exceptions, just separate them by a comma.

The `exception` property is a currently processed exception, while `host` is a `ArgumentsHost` object. The `ArgumentsHost` is a wrapper around arguments that have been passed to the **original** handler, and it contains different arguments array under the hood based on the type of the application.

TypeScript

```typescript

export interface ArgumentsHost {
  getArgs<T extends Array<any> = any[]>(): T;
  getArgByIndex<T = any>(index: number): T;
  switchToRpc(): RpcArgumentsHost;
  switchToHttp(): HttpArgumentsHost;
  switchToWs(): WsArgumentsHost;
}
```

The `ArgumentsHost` supplies us with a set of useful methods that helps to pick correct arguments from the underlying array. In other words, `ArgumentsHost` is nothing else than just an **array of arguments**. For example, when the filter is used within HTTP application context, `ArgumentsHost` will contain `[request, response]` array inside. However, when current context is a web sockets application, this array will be equal to `[client, data]`. This design decision enables you to access any argument that would be eventually passed to the corresponding handler.

#### Binding filters

Let's tie `HttpExceptionFilter` to the `create()` method.

cats.controller.ts

JS TS

TypeScript

```typescript

@Post()
@UseFilters(new HttpExceptionFilter())
async create(@Body() createCatDto: CreateCatDto) {
  throw new ForbiddenException();
}
```

TypeScript

```typescript

@Post()
@UseFilters(new HttpExceptionFilter())
@Bind(Body())
async create(createCatDto) {
  throw new ForbiddenException();
}
```

> **Hint** The `@UseFilters()` decorator is imported from the `@nestjs/common` package.

We have used the `@UseFilters()` decorator here. Same as `@Catch()`, it takes an endless number of parameters. The instance of `HttpExceptionFilter` has been created immediately in-place. Another available way is to pass the class (not instance), leaving framework the instantiation responsibility and enabling **dependency injection**.

cats.controller.ts

JS TS

TypeScript

```typescript

@Post()
@UseFilters(HttpExceptionFilter)
async create(@Body() createCatDto: CreateCatDto) {
  throw new ForbiddenException();
}
```

TypeScript

```typescript

@Post()
@UseFilters(HttpExceptionFilter)
@Bind(Body())
async create(createCatDto) {
  throw new ForbiddenException();
}
```

> **Hint** Prefer applying classes instead of instances when possible. It reduces **memory usage** since Nest can easily reuse instances of the same class across your whole application.

In the example above, the `HttpExceptionFilter` is applied only to the single `create()` route handler, but it's not the only available way. In fact, the exception filters can be method-scoped, controller-scoped, and also global-scoped.

cats.controller.ts

JS TS

TypeScript

```typescript

@UseFilters(new HttpExceptionFilter())
export class CatsController {}
```

This construction sets up the `HttpExceptionFilter` for every route handler defined inside the `CatsController`. It's the example of the controller-scoped exception filter. The last available scope is the global-scoped exception filter.

main.ts

JS TS

TypeScript

```typescript

async function bootstrap() {
  const app = await NestFactory.create(ApplicationModule);
  app.useGlobalFilters(new HttpExceptionFilter());
  await app.listen(3000);
}
bootstrap();
```

> **Warning** The `useGlobalFilters()` method neither set up filters for gateways nor microservices.

The global filters are used across the whole application, for every controller and every route handler. In terms of dependency injection, global filters registered from the outside of any module (as in the previous example above) cannot inject dependencies since they don't belong to any module. In order to solve this issue, you can set up a filter **directly from any module** using following construction:

app.module.ts

JS TS

TypeScript

```typescript

import { Module } from '@nestjs/common';
import { APP_FILTER } from '@nestjs/core';

@Module({
  providers: [
    {
      provide: APP_FILTER,
      useClass: HttpExceptionFilter,
    },
  ],
})
export class ApplicationModule {}
```

> **Hint** The alternative option is to use an [execution context](/v5/execution-context) feature. Also, `useClass` is not the only way of dealing with custom providers registration. Learn more [here](/v5/fundamentals/dependency-injection).

#### Catch everything

In order to handle every occurred exception (regardless of the exception type), you may leave the parentheses empty, e.g. `@Catch()`.

JS TS

TypeScript

```typescript

import { ExceptionFilter, Catch, ArgumentsHost } from '@nestjs/common';

@Catch()
export class AllExceptionsFilter implements ExceptionFilter {
  catch(exception: any, host: ArgumentsHost) {
    const ctx = host.switchToHttp();
    const response = ctx.getResponse();
    const request = ctx.getRequest();
    const status = exception.getStatus();

    response
      .status(status)
      .json({
        statusCode: status,
        timestamp: new Date().toISOString(),
        path: request.url,
      });
  }
}
```

TypeScript

```typescript

import { ExceptionFilter, Catch } from '@nestjs/common';

@Catch()
export class AllExceptionsFilter implements ExceptionFilter {
  catch(exception, host) {
    const ctx = host.switchToHttp();
    const response = ctx.getResponse();
    const request = ctx.getRequest();
    const status = exception.getStatus();

    response
      .status(status)
      .json({
        statusCode: status,
        timestamp: new Date().toISOString(),
        path: request.url,
      });
  }
}
```

In the example above the filter will catch each exception that has been thrown without limiting itself to a set of particular classes.

#### Inheritance

Typically, you'll create fully customized exception filters crafted to fulfill your application requirements. There might be use-cases though when you would like to reuse an already implemented, **core exception filter**, and override the behavior based on certain factors.

In order to delegate exception processing to the base filter, you need to extend `BaseExceptionFilter` and call inherited `catch()` method. Besides, `HttpServer` reference has to be injected and passed to the `super()` call.

JS TS

TypeScript

```typescript

import { Catch, ArgumentsHost, HttpServer } from '@nestjs/common';
import { BaseExceptionFilter, HTTP_SERVER_REF } from '@nestjs/core';

@Catch()
export class AllExceptionsFilter extends BaseExceptionFilter {
  constructor(@Inject(HTTP_SERVER_REF) applicationRef: HttpServer) {
    super(applicationRef);
  }

  catch(exception: any, host: ArgumentsHost) {
    super.catch(exception, host);
  }
}
```

TypeScript

```typescript

import { Catch } from '@nestjs/common';
import { BaseExceptionFilter, HTTP_SERVER_REF } from '@nestjs/core';

@Catch()
export class AllExceptionsFilter extends BaseExceptionFilter {
  constructor(@Inject(HTTP_SERVER_REF) applicationRef) {
    super(applicationRef);
  }

  catch(exception, host) {
    super.catch(exception, host);
  }
}
```

> **Warning** Filters that extend base classes have to be instantiated by the framework itself (don't manually create instances using `new` keyword but `@UseFilters()`).

You can use a global filter that extends the base filter by injecting the `HttpServer` reference.

TypeScript

```typescript

async function bootstrap() {
  const app = await NestFactory.create(ApplicationModule);
  const httpRef = app.get(HTTP_SERVER_REF);
  app.useGlobalFilters(new AllExceptionsFilter(httpRef));
  await app.listen(3000);
}
bootstrap();
```

Obviously, you should enhance above implementation with your tailored **business** logic (e.g. add various conditions).

* Exception filters
* Base exceptions
* Exceptions hierarchy
* HTTP exceptions
* Exception filters
* Binding filters
* Catch everything
* Inheritance

----
url: https://docs.nestjs.com/v7/techniques/cookies
----

* [Cookies](https://docs.nestjs.com/v7/techniques/cookies#cookies)
* [Use with Express (default)](https://docs.nestjs.com/v7/techniques/cookies#use-with-express-default)
* [Use with Fastify](https://docs.nestjs.com/v7/techniques/cookies#use-with-fastify)
* [Creating a custom decorator (cross-platform)](https://docs.nestjs.com/v7/techniques/cookies#creating-a-custom-decorator-cross-platform)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/techniques/cookies.md "Suggest Edits")

### Cookies

An **HTTP cookie** is a small piece of data stored by the user's browser. Cookies were designed to be a reliable mechanism for websites to remember stateful information. When the user visits the website again, the cookie is automatically sent with the request.

#### Use with Express (default)[#](/techniques/cookies#use-with-express-default)

First install the required package (and its types for TypeScript users):

```shell

$ npm i cookie-parser
$ npm i -D @types/cookie-parser
```

Once the installation is complete, apply the `cookie-parser` middleware as global middleware (for example, in your `main.ts` file).

```typescript

import * as cookieParser from 'cookie-parser';
// somewhere in your initialization file
app.use(cookieParser());
```

You can pass several options to the `cookieParser` middleware:

* `secret` a string or array used for signing cookies. This is optional and if not specified, will not parse signed cookies. If a string is provided, this is used as the secret. If an array is provided, an attempt will be made to unsign the cookie with each secret in order.
* `options` an object that is passed to `cookie.parse` as the second option. See [cookie](https://www.npmjs.org/package/cookie) for more information.

The middleware will parse the `Cookie` header on the request and expose the cookie data as the property `req.cookies` and, if a secret was provided, as the property `req.signedCookies`. These properties are name value pairs of the cookie name to cookie value.

When secret is provided, this module will unsign and validate any signed cookie values and move those name value pairs from req.cookies into `req.signedCookies`. A signed cookie is a cookie that has a value prefixed with `s:`. Signed cookies that fail signature validation will have the value `false` instead of the tampered value.

With this in place, you can now read cookies from within the route handlers, as follows:

```typescript

@Get()
findAll(@Req() request: Request) {
  console.log(request.cookies); // or "request.cookies['cookieKey']"
  // or console.log(request.signedCookies);
}
```

> **Hint** The `@Req()` decorator is imported from the `@nestjs/common`, while `Request` from the `express` package.

To attach a cookie to an outgoing response, use the `Response#cookie()` method:

```typescript

@Get()
findAll(@Res({ passthrough: true }) response: Response) {
  response.cookie('key', 'value')
}
```

> **Warning** If you want to leave the response handling logic to the framework, remember to set the `passthrough` option to `true`, as shown above. Read more [here](/controllers#appendix-library-specific-approach).

> **Hint** The `@Res()` decorator is imported from the `@nestjs/common`, while `Response` from the `express` package.

#### Use with Fastify[#](/techniques/cookies#use-with-fastify)

First install the required package:

```shell

$ npm i fastify-cookie
```

Once the installation is complete, register the `fastify-cookie` plugin:

```typescript

import fastifyCookie from 'fastify-cookie';

// somewhere in your initialization file
const app = await NestFactory.create<NestFastifyApplication>(
  AppModule,
  new FastifyAdapter(),
);
app.register(fastifyCookie, {
  secret: 'my-secret', // for cookies signature
});
```

With this in place, you can now read cookies from within the route handlers, as follows:

```typescript

@Get()
findAll(@Req() request: FastifyRequest) {
  console.log(request.cookies); // or "request.cookies['cookieKey']"
}
```

> **Hint** The `@Req()` decorator is imported from the `@nestjs/common`, while `FastifyRequest` from the `fastify` package.

To attach a cookie to an outgoing response, use the `FastifyReply#setCookie()` method:

```typescript

@Get()
findAll(@Res({ passthrough: true }) response: FastifyReply) {
  response.setCookie('key', 'value')
}
```

To read more about `FastifyReply#setCookie()` method, check out this [page](https://github.com/fastify/fastify-cookie#sending).

> **Warning** If you want to leave the response handling logic to the framework, remember to set the `passthrough` option to `true`, as shown above. Read more [here](/controllers#appendix-library-specific-approach).

> **Hint** The `@Res()` decorator is imported from the `@nestjs/common`, while `FastifyReply` from the `fastify` package.

#### Creating a custom decorator (cross-platform)[#](/techniques/cookies#creating-a-custom-decorator-cross-platform)

To provide a convenient, declarative way of accessing incoming cookies, we can create a [custom decorator](/v7/custom-decorators).

```typescript

import { createParamDecorator, ExecutionContext } from '@nestjs/common';

export const Cookies = createParamDecorator(
  (data: string, ctx: ExecutionContext) => {
    const request = ctx.switchToHttp().getRequest();
    return data ? request.cookies?.[data] : request.cookies;
  },
);
```

The `@Cookies()` decorator will extract all cookies, or a named cookie from the `req.cookies` object and populate the decorated parameter with that value.

With this in place, we can now use the decorator in a route handler signature, as follows:

```typescript

@Get()
findAll(@Cookies('name') name: string) {}
```

----
url: https://docs.nestjs.com/v5/techniques/compression
----

### Compression

Compression can greatly decrease the size of the response body and hence increase the speed of a web app. Use the [compression](https://github.com/expressjs/compression) middleware to enable gzip compression.

#### Installation

Firstly, install the required package:

```bash

$ npm i --save compression
```

Once the installation is completed, apply it as a global middleware.

TypeScript

```typescript

import * as compression from 'compression';
// somewhere in your initialization file
app.use(compression());
```

> **Hint** If you work wtih `FastifyAdapter`, consider using [fastify-compress](hhttps://github.com/fastify/fastify-compress) instead.

For a **high-traffic** website in production, the best way to put compression in place is to implement it at a reverse proxy level. In that case, you do not need to use compression middleware.

* Compression
* Installation

----
url: https://docs.nestjs.com/application/serialization
----

[Skip to content](#content)

On this page

* [Serialization](https://docs.nestjs.com/application/serialization#serialization)
* [Overview](https://docs.nestjs.com/application/serialization#overview)
* [Exclude properties](https://docs.nestjs.com/application/serialization#exclude-properties)
* [Expose properties](https://docs.nestjs.com/application/serialization#expose-properties)
* [Transform](https://docs.nestjs.com/application/serialization#transform)
* [Pass options](https://docs.nestjs.com/application/serialization#pass-options)
* [Transform plain objects](https://docs.nestjs.com/application/serialization#transform-plain-objects)
* [Schema-based serialization](https://docs.nestjs.com/application/serialization#schema-based-serialization)
* [Transforming responses with schemas](https://docs.nestjs.com/application/serialization#transforming-responses-with-schemas)
* [Binding the schema serializer](https://docs.nestjs.com/application/serialization#binding-the-schema-serializer)
* [Serialization errors](https://docs.nestjs.com/application/serialization#serialization-errors)
* [Example](https://docs.nestjs.com/application/serialization#example)
* [WebSockets and Microservices](https://docs.nestjs.com/application/serialization#websockets-and-microservices)
* [Learn more](https://docs.nestjs.com/application/serialization#learn-more)

### Serialization

Serialization happens before objects are returned in a network response. It is the right place to define rules for transforming and sanitizing the data sent to the client. For example, sensitive data such as passwords must always be excluded from the response, and some properties may need further transformation, such as returning only a subset of an entity's properties. Performing these transformations manually in every handler is tedious and error-prone, and makes it hard to be sure that every case is covered.

#### Overview[#](/application/serialization#overview)

Nest provides two built-in interceptors that apply these rules declaratively:

* `ClassSerializerInterceptor` uses the [class-transformer](https://github.com/typestack/class-transformer) package. It takes the value returned by a route handler and applies the `instanceToPlain()` function to it, which honors the `class-transformer` decorators declared on the entity or DTO class. The first part of this chapter covers this approach.

* `StandardSchemaSerializerInterceptor` validates and transforms responses with a schema written in [Zod](https://zod.dev/), [Valibot](https://valibot.dev/), [ArkType](https://arktype.io/), or any other [Standard Schema](https://standardschema.dev/) compatible library. See [Schema-based serialization](/application/serialization#schema-based-serialization).

> **Hint** Neither interceptor serializes [StreamableFile](/http/file-upload#streaming-files) responses.

#### Exclude properties[#](/application/serialization#exclude-properties)

Suppose you want to exclude the `password` property of a user entity from every response. Annotate the entity as follows:

```typescript

import { Exclude } from 'class-transformer';

export class UserEntity {
  id: number;
  firstName: string;
  lastName: string;

  @Exclude()
  password: string;

  constructor(partial: Partial<UserEntity>) {
    Object.assign(this, partial);
  }
}
```

Now consider a controller with a route handler that returns an instance of this class:

```typescript

@UseInterceptors(ClassSerializerInterceptor)
@Get()
findOne(): UserEntity {
  return new UserEntity({
    id: 1,
    firstName: 'John',
    lastName: 'Doe',
    password: 'password',
  });
}
```

> **Warning** The handler must return an instance of the class. A plain JavaScript object, such as `{ user: new UserEntity() }`, is not serialized correctly. To serialize plain objects, see [Transform plain objects](/application/serialization#transform-plain-objects).

> **Hint** The `ClassSerializerInterceptor` is imported from `@nestjs/common`.

When this endpoint is requested, the client receives the following response:

```json

{
  "id": 1,
  "firstName": "John",
  "lastName": "Doe"
}
```

The interceptor can also be bound application-wide (see [Binding interceptors](/interceptors#binding-interceptors)). Together, the interceptor and the entity class declaration ensure that **every** route handler that returns a `UserEntity` omits the `password` property, which enforces this rule in one place.

#### Expose properties[#](/application/serialization#expose-properties)

Use the `@Expose()` decorator to provide alias names for properties, or to compute a property value with a function (similar to a **getter**), as shown below.

```typescript

@Expose()
get fullName(): string {
  return `${this.firstName} ${this.lastName}`;
}
```

#### Transform[#](/application/serialization#transform)

Use the `@Transform()` decorator for additional data transformation. For example, the following construct returns the `name` property of the `RoleEntity` instead of the whole object.

```typescript

@Transform(({ value }) => value.name)
role: RoleEntity;
```

#### Pass options[#](/application/serialization#pass-options)

To override the default behavior of the transformation functions, pass options to the `@SerializeOptions()` decorator.

```typescript

@SerializeOptions({
  excludePrefixes: ['_'],
})
@Get()
findOne(): UserEntity {
  return new UserEntity();
}
```

> **Hint** The `@SerializeOptions()` decorator is imported from `@nestjs/common`.

Options passed to `@SerializeOptions()` are forwarded as the second argument of the underlying `instanceToPlain()` function. In this example, all properties that begin with the `_` prefix are excluded.

#### Transform plain objects[#](/application/serialization#transform-plain-objects)

The `type` option of `@SerializeOptions()` converts responses into instances of the specified class before they are serialized, so the class's `class-transformer` decorators apply even when the handler returns a plain object. This removes the need to instantiate the class or call `plainToInstance()` in every handler.

In the example below, both conditional branches return plain JavaScript objects, which are converted into `UserEntity` instances with the relevant decorators applied:

```typescript

@UseInterceptors(ClassSerializerInterceptor)
@SerializeOptions({ type: UserEntity })
@Get()
findOne(@Query() { id }: { id: number }): UserEntity {
  if (id === 1) {
    return {
      id: 1,
      firstName: 'John',
      lastName: 'Doe',
      password: 'password',
    };
  }

  return {
    id: 2,
    firstName: 'Kamil',
    lastName: 'Mysliwiec',
    password: 'password2',
  };
}
```

> **Hint** Declaring the handler's return type lets TypeScript check that the returned plain object matches the shape of the DTO or entity. The `plainToInstance()` function doesn't provide this type checking, so a mismatched object can go unnoticed.

> **Warning** The response is shaped by the `type` class, not by the class of the returned value. A value that isn't an instance of the `type` class, such as an instance of another entity, is converted like a plain object: the decorators of its own class, such as `@Exclude()`, are ignored, and properties that the `type` class doesn't declare are copied unchanged. To send only the properties of the `type` class, decorate each of them with `@Expose()` and add `excludeExtraneousValues: true` to the options of the same `@SerializeOptions()` decorator.

#### Schema-based serialization[#](/application/serialization#schema-based-serialization)

The `StandardSchemaSerializerInterceptor` shapes responses with a schema instead of class decorators. The schema describes exactly what leaves the API: the interceptor runs the value returned by the route handler through the schema and sends the schema's output to the client. It accepts any schema that implements the [Standard Schema](https://standardschema.dev/) specification. The examples in this section use Zod.

Because `z.object()` strips properties the schema doesn't declare, a response schema is also an allowlist. The following schema guarantees that a user's `password` is never sent, even when the service returns the full database row:

user-response.schema.ts

JS TS

```typescript

import { z } from 'zod';

export const userResponseSchema = z.object({
  id: z.number(),
  firstName: z.string(),
  lastName: z.string(),
});

export type UserResponse = z.infer<typeof userResponseSchema>;
```

Bind the interceptor and select the schema with the `schema` option of the `@SerializeOptions()` decorator:

users.controller.ts

JS TS

```typescript

import {
  Controller,
  Get,
  Param,
  ParseIntPipe,
  SerializeOptions,
  StandardSchemaSerializerInterceptor,
  UseInterceptors,
} from '@nestjs/common';
import { userResponseSchema } from './user-response.schema.js';
import { UsersService } from './users.service.js';

@Controller('users')
@UseInterceptors(StandardSchemaSerializerInterceptor)
export class UsersController {
  constructor(private readonly usersService: UsersService) {}

  @Get(':id')
  @SerializeOptions({ schema: userResponseSchema })
  findOne(@Param('id', ParseIntPipe) id: number) {
    return this.usersService.findOne(id);
  }

  @Get()
  @SerializeOptions({ schema: userResponseSchema })
  findAll() {
    return this.usersService.findAll();
  }
}
```

The service returns user records that include a `password` property, but the client receives only the declared properties:

```json

{
  "id": 1,
  "firstName": "John",
  "lastName": "Doe"
}
```

When a handler returns an array, as `findAll()` does, the interceptor applies the schema to **each element**. Pass the schema of a single item, not an array schema.

`null`, `undefined`, primitive values, and `StreamableFile` responses are sent unchanged, as are responses of handlers without a schema.

#### Transforming responses with schemas[#](/application/serialization#transforming-responses-with-schemas)

Schema transformations cover what `@Expose()` and `@Transform()` do for classes. The following schema adds a computed `fullName` property and replaces the nested `role` object with its name:

user-response.schema.ts

JS TS

```typescript

import { z } from 'zod';

export const userResponseSchema = z
  .object({
    id: z.number(),
    firstName: z.string(),
    lastName: z.string(),
    role: z.object({ id: z.number(), name: z.string() }),
  })
  .transform((user) => ({
    id: user.id,
    fullName: `${user.firstName} ${user.lastName}`,
    role: user.role.name,
  }));
```

For a user with the `admin` role, the client receives:

```json

{
  "id": 1,
  "fullName": "John Doe",
  "role": "admin"
}
```

The same schema written with Valibot uses `v.pipe()` and `v.transform()`:

```typescript

import * as v from 'valibot';

export const userResponseSchema = v.pipe(
  v.object({
    id: v.number(),
    firstName: v.string(),
    lastName: v.string(),
    role: v.object({ id: v.number(), name: v.string() }),
  }),
  v.transform((user) => ({
    id: user.id,
    fullName: `${user.firstName} ${user.lastName}`,
    role: user.role.name,
  })),
);
```

#### Binding the schema serializer[#](/application/serialization#binding-the-schema-serializer)

`@SerializeOptions()` can decorate a controller class as well as a route handler. A schema set on the class applies to all of its handlers, and a schema set on a handler takes precedence:

```typescript

@Controller('users')
@UseInterceptors(StandardSchemaSerializerInterceptor)
@SerializeOptions({ schema: userResponseSchema })
export class UsersController {}
```

To bind the interceptor application-wide, pass it the `Reflector` instance, which the interceptor uses to read the `@SerializeOptions()` metadata:

main.ts

JS TS

```typescript

const app = await NestFactory.create(AppModule);
app.useGlobalInterceptors(
  new StandardSchemaSerializerInterceptor(app.get(Reflector)),
);
```

Alternatively, register it with the `APP_INTERCEPTOR` token, as described in [Binding interceptors](/interceptors#binding-interceptors), and Nest injects the `Reflector` for you. Handlers without a schema are not affected by the global interceptor.

The interceptor constructor also accepts default options, which apply when neither the handler nor its controller sets a schema:

|                   |                                                                                                                                                                                           |
| ----------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `schema`          | The default schema used when `@SerializeOptions()` doesn't provide one.                                                                                                                   |
| `validateOptions` | Options forwarded to the schema's `~standard.validate()` method, for libraries that support them. A handler can override them with the `validateOptions` option of `@SerializeOptions()`. |

#### Serialization errors[#](/application/serialization#serialization-errors)

A response that doesn't match its schema, such as a record with a missing or mistyped property, indicates a bug on the server, not a problem with the request. In that case, the interceptor throws an error that lists the schema's issues, and the client receives a `500 Internal Server Error` response instead of partially serialized data. The error message, including the issues, is logged by the default exception filter.

A working example that uses Valibot is available [here](https://github.com/nestjs/nest/tree/master/sample/36-valibot-serializer).

#### Example[#](/application/serialization#example)

A working example of the `ClassSerializerInterceptor` is available [here](https://github.com/nestjs/nest/tree/master/sample/21-serializer).

#### WebSockets and Microservices[#](/application/serialization#websockets-and-microservices)

While this chapter shows examples using HTTP applications (e.g., Express or Fastify), both `ClassSerializerInterceptor` and `StandardSchemaSerializerInterceptor` work the same for WebSockets and microservices, regardless of the transport.

#### Learn more[#](/application/serialization#learn-more)

Read more about available decorators and options in the [class-transformer](https://github.com/typestack/class-transformer) repository. For schema libraries, see the [Zod](https://zod.dev/), [Valibot](https://valibot.dev/), and [ArkType](https://arktype.io/) documentation.

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/application/serialization.md)

----
url: https://docs.nestjs.com/v10/fundamentals/custom-providers
----

* [Custom providers](https://docs.nestjs.com/v10/fundamentals/custom-providers#custom-providers)
* [DI fundamentals](https://docs.nestjs.com/v10/fundamentals/custom-providers#di-fundamentals)
* [Standard providers](https://docs.nestjs.com/v10/fundamentals/custom-providers#standard-providers)
* [Custom providers](https://docs.nestjs.com/v10/fundamentals/custom-providers#custom-providers-1)
* [Value providers: useValue](https://docs.nestjs.com/v10/fundamentals/custom-providers#value-providers-usevalue)
* [Non-class-based provider tokens](https://docs.nestjs.com/v10/fundamentals/custom-providers#non-class-based-provider-tokens)
* [Class providers: useClass](https://docs.nestjs.com/v10/fundamentals/custom-providers#class-providers-useclass)
* [Factory providers: useFactory](https://docs.nestjs.com/v10/fundamentals/custom-providers#factory-providers-usefactory)
* [Alias providers: useExisting](https://docs.nestjs.com/v10/fundamentals/custom-providers#alias-providers-useexisting)
* [Non-service based providers](https://docs.nestjs.com/v10/fundamentals/custom-providers#non-service-based-providers)
* [Export custom provider](https://docs.nestjs.com/v10/fundamentals/custom-providers#export-custom-provider)

```typescript

import { Injectable } from '@nestjs/common';
import { Cat } from './interfaces/cat.interface';

@Injectable()
export class CatsService {
  private readonly cats: Cat[] = [];

  findAll(): Cat[] {
    return this.cats;
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';

@Injectable()
export class CatsService {
  constructor() {
    this.cats = [];
  }

  findAll() {
    return this.cats;
  }
}
```

Then we request that Nest inject the provider into our controller class:

cats.controller.ts

JS TS

```typescript

import { Controller, Get } from '@nestjs/common';
import { CatsService } from './cats.service';
import { Cat } from './interfaces/cat.interface';

@Controller('cats')
export class CatsController {
  constructor(private catsService: CatsService) {}

  @Get()
  async findAll(): Promise<Cat[]> {
    return this.catsService.findAll();
  }
}
```

```typescript

import { Controller, Get, Bind, Dependencies } from '@nestjs/common';
import { CatsService } from './cats.service';

@Controller('cats')
@Dependencies(CatsService)
export class CatsController {
  constructor(catsService) {
    this.catsService = catsService;
  }

  @Get()
  async findAll() {
    return this.catsService.findAll();
  }
}
```

Finally, we register the provider with the Nest IoC container:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { CatsController } from './cats/cats.controller';
import { CatsService } from './cats/cats.service';

@Module({
  controllers: [CatsController],
  providers: [CatsService],
})
export class AppModule {}
```

What exactly is happening under the covers to make this work? There are three key steps in the process:

1. In `cats.service.ts`, the `@Injectable()` decorator declares the `CatsService` class as a class that can be managed by the Nest IoC container.
2. In `cats.controller.ts`, `CatsController` declares a dependency on the `CatsService` token with constructor injection:

```typescript

  constructor(private catsService: CatsService)
```

```typescript

@Module({
  controllers: [CatsController],
  providers: [CatsService],
})
```

The `providers` property takes an array of `providers`. So far, we've supplied those providers via a list of class names. In fact, the syntax `providers: [CatsService]` is short-hand for the more complete syntax:

```typescript

providers: [
  {
    provide: CatsService,
    useClass: CatsService,
  },
];
```

> **Hint** If you are having problems with dependency resolution you can set the `NEST_DEBUG` environment variable and get extra dependency resolution logs during startup.

#### Value providers: `useValue`[#](/fundamentals/custom-providers#value-providers-usevalue)

The `useValue` syntax is useful for injecting a constant value, putting an external library into the Nest container, or replacing a real implementation with a mock object. Let's say you'd like to force Nest to use a mock `CatsService` for testing purposes.

```typescript

import { CatsService } from './cats.service';

const mockCatsService = {
  /* mock implementation
  ...
  */
};

@Module({
  imports: [CatsModule],
  providers: [
    {
      provide: CatsService,
      useValue: mockCatsService,
    },
  ],
})
export class AppModule {}
```

In this example, the `CatsService` token will resolve to the `mockCatsService` mock object. `useValue` requires a value - in this case a literal object that has the same interface as the `CatsService` class it is replacing. Because of TypeScript's [structural typing](https://www.typescriptlang.org/docs/handbook/type-compatibility.html), you can use any object that has a compatible interface, including a literal object or a class instance instantiated with `new`.

#### Non-class-based provider tokens[#](/fundamentals/custom-providers#non-class-based-provider-tokens)

So far, we've used class names as our provider tokens (the value of the `provide` property in a provider listed in the `providers` array). This is matched by the standard pattern used with [constructor based injection](https://docs.nestjs.com/providers#dependency-injection), where the token is also a class name. (Refer back to [DI Fundamentals](/fundamentals/custom-providers#di-fundamentals) for a refresher on tokens if this concept isn't entirely clear). Sometimes, we may want the flexibility to use strings or symbols as the DI token. For example:

```typescript

import { connection } from './connection';

@Module({
  providers: [
    {
      provide: 'CONNECTION',
      useValue: connection,
    },
  ],
})
export class AppModule {}
```

In this example, we are associating a string-valued token (`'CONNECTION'`) with a pre-existing `connection` object we've imported from an external file.

> **Notice** In addition to using strings as token values, you can also use JavaScript [symbols](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol) or TypeScript [enums](https://www.typescriptlang.org/docs/handbook/enums.html).

We've previously seen how to inject a provider using the standard [constructor based injection](https://docs.nestjs.com/providers#dependency-injection) pattern. This pattern **requires** that the dependency be declared with a class name. The `'CONNECTION'` custom provider uses a string-valued token. Let's see how to inject such a provider. To do so, we use the `@Inject()` decorator. This decorator takes a single argument - the token.

JS TS

```typescript

@Injectable()
export class CatsRepository {
  constructor(@Inject('CONNECTION') connection: Connection) {}
}
```

```typescript

@Injectable()
@Dependencies('CONNECTION')
export class CatsRepository {
  constructor(connection) {}
}
```

> **Hint** The `@Inject()` decorator is imported from `@nestjs/common` package.

While we directly use the string `'CONNECTION'` in the above examples for illustration purposes, for clean code organization, it's best practice to define tokens in a separate file, such as `constants.ts`. Treat them much as you would symbols or enums that are defined in their own file and imported where needed.

#### Class providers: `useClass`[#](/fundamentals/custom-providers#class-providers-useclass)

The `useClass` syntax allows you to dynamically determine a class that a token should resolve to. For example, suppose we have an abstract (or default) `ConfigService` class. Depending on the current environment, we want Nest to provide a different implementation of the configuration service. The following code implements such a strategy.

```typescript

const configServiceProvider = {
  provide: ConfigService,
  useClass:
    process.env.NODE_ENV === 'development'
      ? DevelopmentConfigService
      : ProductionConfigService,
};

@Module({
  providers: [configServiceProvider],
})
export class AppModule {}
```

```typescript

const connectionProvider = {
  provide: 'CONNECTION',
  useFactory: (optionsProvider: MyOptionsProvider, optionalProvider?: string) => {
    const options = optionsProvider.get();
    return new DatabaseConnection(options);
  },
  inject: [MyOptionsProvider, { token: 'SomeOptionalProvider', optional: true }],
  //       \______________/             \__________________/
  //        This provider                The provider with this token
  //        is mandatory.                can resolve to `undefined`.
};

@Module({
  providers: [
    connectionProvider,
    MyOptionsProvider, // class-based provider
    // { provide: 'SomeOptionalProvider', useValue: 'anything' },
  ],
})
export class AppModule {}
```

```typescript

const connectionProvider = {
  provide: 'CONNECTION',
  useFactory: (optionsProvider, optionalProvider) => {
    const options = optionsProvider.get();
    return new DatabaseConnection(options);
  },
  inject: [MyOptionsProvider, { token: 'SomeOptionalProvider', optional: true }],
  //       \______________/            \__________________/
  //        This provider               The provider with this token
  //        is mandatory.               can resolve to `undefined`.
};

@Module({
  providers: [
    connectionProvider,
    MyOptionsProvider, // class-base provider
    // { provide: 'SomeOptionalProvider', useValue: 'anything' },
  ],
})
export class AppModule {}
```

#### Alias providers: `useExisting`[#](/fundamentals/custom-providers#alias-providers-useexisting)

The `useExisting` syntax allows you to create aliases for existing providers. This creates two ways to access the same provider. In the example below, the (string-based) token `'AliasedLoggerService'` is an alias for the (class-based) token `LoggerService`. Assume we have two different dependencies, one for `'AliasedLoggerService'` and one for `LoggerService`. If both dependencies are specified with `SINGLETON` scope, they'll both resolve to the same instance.

```typescript

@Injectable()
class LoggerService {
  /* implementation details */
}

const loggerAliasProvider = {
  provide: 'AliasedLoggerService',
  useExisting: LoggerService,
};

@Module({
  providers: [LoggerService, loggerAliasProvider],
})
export class AppModule {}
```

#### Non-service based providers[#](/fundamentals/custom-providers#non-service-based-providers)

While providers often supply services, they are not limited to that usage. A provider can supply **any** value. For example, a provider may supply an array of configuration objects based on the current environment, as shown below:

```typescript

const configFactory = {
  provide: 'CONFIG',
  useFactory: () => {
    return process.env.NODE_ENV === 'development' ? devConfig : prodConfig;
  },
};

@Module({
  providers: [configFactory],
})
export class AppModule {}
```

#### Export custom provider[#](/fundamentals/custom-providers#export-custom-provider)

Like any provider, a custom provider is scoped to its declaring module. To make it visible to other modules, it must be exported. To export a custom provider, we can either use its token or the full provider object.

The following example shows exporting using the token:

JS TS

```typescript

const connectionFactory = {
  provide: 'CONNECTION',
  useFactory: (optionsProvider: OptionsProvider) => {
    const options = optionsProvider.get();
    return new DatabaseConnection(options);
  },
  inject: [OptionsProvider],
};

@Module({
  providers: [connectionFactory],
  exports: ['CONNECTION'],
})
export class AppModule {}
```

```typescript

const connectionFactory = {
  provide: 'CONNECTION',
  useFactory: (optionsProvider) => {
    const options = optionsProvider.get();
    return new DatabaseConnection(options);
  },
  inject: [OptionsProvider],
};

@Module({
  providers: [connectionFactory],
  exports: ['CONNECTION'],
})
export class AppModule {}
```

Alternatively, export with the full provider object:

JS TS

```typescript

const connectionFactory = {
  provide: 'CONNECTION',
  useFactory: (optionsProvider: OptionsProvider) => {
    const options = optionsProvider.get();
    return new DatabaseConnection(options);
  },
  inject: [OptionsProvider],
};

@Module({
  providers: [connectionFactory],
  exports: [connectionFactory],
})
export class AppModule {}
```

```typescript

const connectionFactory = {
  provide: 'CONNECTION',
  useFactory: (optionsProvider) => {
    const options = optionsProvider.get();
    return new DatabaseConnection(options);
  },
  inject: [OptionsProvider],
};

@Module({
  providers: [connectionFactory],
  exports: [connectionFactory],
})
export class AppModule {}
```

----
url: https://docs.nestjs.com/v9/faq/common-errors
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Common errors](https://docs.nestjs.com/v9/faq/common-errors#common-errors)
* ["Cannot resolve dependency" error](https://docs.nestjs.com/v9/faq/common-errors#cannot-resolve-dependency-error)
* ["Circular dependency" error](https://docs.nestjs.com/v9/faq/common-errors#circular-dependency-error)
* [Debugging dependency errors](https://docs.nestjs.com/v9/faq/common-errors#debugging-dependency-errors)
* ["File change detected" loops endlessly](https://docs.nestjs.com/v9/faq/common-errors#file-change-detected-loops-endlessly)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/faq/errors.md "Suggest Edits")

### Common errors

During your development with NestJS, you may encounter various errors as you learn the framework.

#### "Cannot resolve dependency" error[#](/faq/common-errors#cannot-resolve-dependency-error)

> **Hint** Check out the [NestJS Devtools](/devtools/overview#investigating-the-cannot-resolve-dependency-error) which can help you resolve the "Cannot resolve dependency" error effortlessly.

Probably the most common error message is about Nest not being able to resolve dependencies of a provider. The error message usually looks something like this:

```bash

Nest can't resolve dependencies of the <provider> (?). Please make sure that the argument <unknown_token> at index [<index>] is available in the <module> context.

Potential solutions:
- Is <module> a valid NestJS module?
- If <unknown_token> is a provider, is it part of the current <module>?
- If <unknown_token> is exported from a separate @Module, is that module imported within <module>?
  @Module({
    imports: [ /* the Module containing <unknown_token> */ ]
  })
```

The most common culprit of the error, is not having the `<provider>` in the module's `providers` array. Please make sure that the provider is indeed in the `providers` array and following [standard NestJS provider practices](/fundamentals/custom-providers#di-fundamentals).

There are a few gotchas, that are common. One is putting a provider in an `imports` array. If this is the case, the error will have the provider's name where `<module>` should be.

If you run across this error while developing, take a look at the module mentioned in the error message and look at its `providers`. For each provider in the `providers` array, make sure the module has access to all of the dependencies. Often times, `providers` are duplicated in a "Feature Module" and a "Root Module" which means Nest will try to instantiate the provider twice. More than likely, the module containing the `<provider>` being duplicated should be added in the "Root Module"'s `imports` array instead.

If the `<unknown_token>` above is the string `dependency`, you might have a circular file import. This is different from the [circular dependency](/faq/common-errors#circular-dependency-error) below because instead of having providers depend on each other in their constructors, it just means that two files end up importing each other. A common case would be a module file declaring a token and importing a provider, and the provider import the token constant from the module file. If you are using barrel files, ensure that your barrel imports do not end up creating these circular imports as well.

If the `<unknown_token>` above is the string `Object`, it means that you're injecting using an type/interface without a proper provider's token. To fix that, make sure you're importing the class reference or use a custom token with `@Inject()` decorator. Read the [custom providers page](/v9/fundamentals/custom-providers).

Also, make sure you didn't end up injecting the provider on itself because self-injections are not allowed in NestJS. When this happens, `<unknown_token>` will likely be equal to `<provider>`.

## Explore your graph with NestJS Devtools

* **Graph visualizer
* **Routes navigator
* **Interactive playground
* **CI/CD integration

[Sign up](https://devtools.nestjs.com "Devtools | NestJS - A node.js framework built on top of TypeScript")

If you are in a **monorepo setup**, you may face the same error as above but for core provider called `ModuleRef` as a `<unknown_token>`:

```bash

Nest can't resolve dependencies of the <provider> (?).
Please make sure that the argument ModuleRef at index [<index>] is available in the <module> context.
...
```

This likely happens when your project end up loading two Node modules of the package `@nestjs/core`, like this:

```text

.
├── package.json
├── apps
│   └── api
│       └── node_modules
│           └── @nestjs/bull
│               └── node_modules
│                   └── @nestjs/core
└── node_modules
    ├── (other packages)
    └── @nestjs/core
```

Solutions:

* For **Yarn** Workspaces, use the [nohoist feature](https://classic.yarnpkg.com/blog/2018/02/15/nohoist) to prevent hoisting the package `@nestjs/core`.
* For **pnpm** Workspaces, set `@nestjs/core` as a peerDependencies in your other module and `"dependenciesMeta": {"other-module-name": {"injected": true}}` in the app package.json where the module is imported. see: [dependenciesmetainjected](https://pnpm.io/package_json#dependenciesmetainjected)

#### "Circular dependency" error[#](/faq/common-errors#circular-dependency-error)

Occasionally you'll find it difficult to avoid [circular dependencies](https://docs.nestjs.com/fundamentals/circular-dependency) in your application. You'll need to take some steps to help Nest resolve these. Errors that arise from circular dependencies look like this:

```bash

Nest cannot create the <module> instance.
The module at index [<index>] of the <module> "imports" array is undefined.

Potential causes:
- A circular dependency between modules. Use forwardRef() to avoid it. Read more: https://docs.nestjs.com/fundamentals/circular-dependency
- The module at index [<index>] is of type "undefined". Check your import statements and the type of the module.

Scope [<module_import_chain>]
# example chain AppModule -> FooModule
```

Circular dependencies can arise from both providers depending on each other, or typescript files depending on each other for constants, such as exporting constants from a module file and importing them in a service file. In the latter case, it is advised to create a separate file for your constants. In the former case, please follow the guide on circular dependencies and make sure that both the modules **and** the providers are marked with `forwardRef`.

#### Debugging dependency errors[#](/faq/common-errors#debugging-dependency-errors)

Along with just manually verifying your dependencies are correct, as of Nest 8.1.0 you can set the `NEST_DEBUG` environment variable to a string that resolves as truthy, and get extra logging information while Nest is resolving all of the dependencies for the application.

In the above image, the string in yellow is the host class of the dependency being injected, the string in blue is the name of the injected dependency, or its injection token, and the string in purple is the module in which the dependency is being searched for. Using this, you can usually trace back the dependency resolution for what's happening and why you're getting dependency injection problems.

#### "File change detected" loops endlessly[#](/faq/common-errors#file-change-detected-loops-endlessly)

Windows users who are using TypeScript version 4.9 and up may encounter this problem. This happens when you're trying to run your application in watch mode, e.g `npm run start:dev` and see an endless loop of the log messages:

```bash

XX:XX:XX AM - File change detected. Starting incremental compilation...
XX:XX:XX AM - Found 0 errors. Watching for file changes.
```

When you're using the NestJS CLI to start your application in watch mode it is done by calling `tsc --watch`, and as of version 4.9 of TypeScript, a [new strategy](https://devblogs.microsoft.com/typescript/announcing-typescript-4-9/#file-watching-now-uses-file-system-events) for detecting file changes is used which is likely to be the cause of this problem. In order to fix this problem, you need to add a setting to your tsconfig.json file after the `"compilerOptions"` option as follows:

```bash

  "watchOptions": {
    "watchFile": "fixedPollingInterval"
  }
```

This tells TypeScript to use the polling method for checking for file changes instead of file system events (the new default method), which can cause issues on some machines. You can read more about the `"watchFile"` option in [TypeScript documentation](https://www.typescriptlang.org/tsconfig#watch-watchDirectory).

----
url: https://docs.nestjs.com/v9/pipes
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Pipes](https://docs.nestjs.com/v9/pipes#pipes)
* [Built-in pipes](https://docs.nestjs.com/v9/pipes#built-in-pipes)
* [Binding pipes](https://docs.nestjs.com/v9/pipes#binding-pipes)
* [Custom pipes](https://docs.nestjs.com/v9/pipes#custom-pipes)
* [Schema based validation](https://docs.nestjs.com/v9/pipes#schema-based-validation)
* [Object schema validation](https://docs.nestjs.com/v9/pipes#object-schema-validation)
* [Binding validation pipes](https://docs.nestjs.com/v9/pipes#binding-validation-pipes)
* [Class validator](https://docs.nestjs.com/v9/pipes#class-validator)
* [Global scoped pipes](https://docs.nestjs.com/v9/pipes#global-scoped-pipes)
* [The built-in ValidationPipe](https://docs.nestjs.com/v9/pipes#the-built-in-validationpipe)
* [Transformation use case](https://docs.nestjs.com/v9/pipes#transformation-use-case)
* [Providing defaults](https://docs.nestjs.com/v9/pipes#providing-defaults)

> **Hint** Pipes run inside the exceptions zone. This means that when a Pipe throws an exception it is handled by the exceptions layer (global exceptions filter and any [exceptions filters](/v9/exception-filters) that are applied to the current context). Given the above, it should be clear that when an exception is thrown in a Pipe, no controller method is subsequently executed. This gives you a best-practice technique for validating data coming into the application from external sources at the system boundary.

```typescript

@Get(':id')
async findOne(@Param('id', ParseIntPipe) id: number) {
  return this.catsService.findOne(id);
}
```

This ensures that one of the following two conditions is true: either the parameter we receive in the `findOne()` method is a number (as expected in our call to `this.catsService.findOne()`), or an exception is thrown before the route handler is called.

For example, assume the route is called like:

```bash

GET localhost:3000/abc
```

Nest will throw an exception like this:

```json

{
  "statusCode": 400,
  "message": "Validation failed (numeric string is expected)",
  "error": "Bad Request"
}
```

The exception will prevent the body of the `findOne()` method from executing.

In the example above, we pass a class (`ParseIntPipe`), not an instance, leaving responsibility for instantiation to the framework and enabling dependency injection. As with pipes and guards, we can instead pass an in-place instance. Passing an in-place instance is useful if we want to customize the built-in pipe's behavior by passing options:

```typescript

@Get(':id')
async findOne(
  @Param('id', new ParseIntPipe({ errorHttpStatusCode: HttpStatus.NOT_ACCEPTABLE }))
  id: number,
) {
  return this.catsService.findOne(id);
}
```

Binding the other transformation pipes (all of the **Parse\*** pipes) works similarly. These pipes all work in the context of validating route parameters, query string parameters and request body values.

For example with a query string parameter:

```typescript

@Get()
async findOne(@Query('id', ParseIntPipe) id: number) {
  return this.catsService.findOne(id);
}
```

Here's an example of using the `ParseUUIDPipe` to parse a string parameter and validate if it is a UUID.

JS TS

```typescript

@Get(':uuid')
async findOne(@Param('uuid', new ParseUUIDPipe()) uuid: string) {
  return this.catsService.findOne(uuid);
}
```

```typescript

@Get(':uuid')
@Bind(Param('uuid', new ParseUUIDPipe()))
async findOne(uuid) {
  return this.catsService.findOne(uuid);
}
```

> **Hint** When using `ParseUUIDPipe()` you are parsing UUID in version 3, 4 or 5, if you only require a specific version of UUID you can pass a version in the pipe options.

Above we've seen examples of binding the various `Parse*` family of built-in pipes. Binding validation pipes is a little bit different; we'll discuss that in the following section.

> **Hint** Also, see [Validation techniques](/v9/techniques/validation) for extensive examples of validation pipes.

#### Custom pipes[#](/pipes#custom-pipes)

As mentioned, you can build your own custom pipes. While Nest provides a robust built-in `ParseIntPipe` and `ValidationPipe`, let's build simple custom versions of each from scratch to see how custom pipes are constructed.

We start with a simple `ValidationPipe`. Initially, we'll have it simply take an input value and immediately return the same value, behaving like an identity function.

validation.pipe.ts

JS TS

```typescript

import { PipeTransform, Injectable, ArgumentMetadata } from '@nestjs/common';

@Injectable()
export class ValidationPipe implements PipeTransform {
  transform(value: any, metadata: ArgumentMetadata) {
    return value;
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';

@Injectable()
export class ValidationPipe {
  transform(value, metadata) {
    return value;
  }
}
```

> **Hint**`PipeTransform<T, R>` is a generic interface that must be implemented by any pipe. The generic interface uses `T` to indicate the type of the input `value`, and `R` to indicate the return type of the `transform()` method.

Every pipe must implement the `transform()` method to fulfill the `PipeTransform` interface contract. This method has two parameters:

* `value`
* `metadata`

The `value` parameter is the currently processed method argument (before it is received by the route handling method), and `metadata` is the currently processed method argument's metadata. The metadata object has these properties:

```typescript

export interface ArgumentMetadata {
  type: 'body' | 'query' | 'param' | 'custom';
  metatype?: Type<unknown>;
  data?: string;
}
```

These properties describe the currently processed argument.

|            |                                                                                                                                                                                                      |
| ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `type`     | Indicates whether the argument is a body `@Body()`, query `@Query()`, param `@Param()`, or a custom parameter (read more [here](/v9/custom-decorators)).                                             |
| `metatype` | Provides the metatype of the argument, for example, `String`. Note: the value is `undefined` if you either omit a type declaration in the route handler method signature, or use vanilla JavaScript. |
| `data`     | The string passed to the decorator, for example `@Body('string')`. It's `undefined` if you leave the decorator parenthesis empty.                                                                    |

> **Warning** TypeScript interfaces disappear during transpilation. Thus, if a method parameter's type is declared as an interface instead of a class, the `metatype` value will be `Object`.

#### Schema based validation[#](/pipes#schema-based-validation)

Let's make our validation pipe a little more useful. Take a closer look at the `create()` method of the `CatsController`, where we probably would like to ensure that the post body object is valid before attempting to run our service method.

JS TS

```typescript

@Post()
async create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

```typescript

@Post()
async create(@Body() createCatDto) {
  this.catsService.create(createCatDto);
}
```

Let's focus in on the `createCatDto` body parameter. Its type is `CreateCatDto`:

create-cat.dto.ts

JS TS

```typescript

export class CreateCatDto {
  name: string;
  age: number;
  breed: string;
}
```

We want to ensure that any incoming request to the create method contains a valid body. So we have to validate the three members of the `createCatDto` object. We could do this inside the route handler method, but doing so is not ideal as it would break the **single responsibility rule** (SRP).

Another approach could be to create a **validator class** and delegate the task there. This has the disadvantage that we would have to remember to call this validator at the beginning of each method.

How about creating validation middleware? This could work, but unfortunately it's not possible to create **generic middleware** which can be used across all contexts across the whole application. This is because middleware is unaware of the **execution context**, including the handler that will be called and any of its parameters.

This is, of course, exactly the use case for which pipes are designed. So let's go ahead and refine our validation pipe.

## Learn the right way!

* **80+ chapters
* **5+ hours of videos
* **Official certificate
* **Deep-dive sessions

[Explore official courses](https://courses.nestjs.com "Courses | NestJS - A node.js framework built on top of TypeScript")

#### Object schema validation[#](/pipes#object-schema-validation)

There are several approaches available for doing object validation in a clean, [DRY](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself) way. One common approach is to use **schema-based** validation. Let's go ahead and try that approach.

The [Joi](https://github.com/sideway/joi) library allows you to create schemas in a straightforward way, with a readable API. Let's build a validation pipe that makes use of Joi-based schemas.

Start by installing the required package:

```bash

$ npm install --save joi
```

In the code sample below, we create a simple class that takes a schema as a `constructor` argument. We then apply the `schema.validate()` method, which validates our incoming argument against the provided schema.

As noted earlier, a **validation pipe** either returns the value unchanged, or throws an exception.

In the next section, you'll see how we supply the appropriate schema for a given controller method using the `@UsePipes()` decorator. Doing so makes our validation pipe re-usable across contexts, just as we set out to do.

JS TS

```typescript

import { PipeTransform, Injectable, ArgumentMetadata, BadRequestException } from '@nestjs/common';
import { ObjectSchema } from 'joi';

@Injectable()
export class JoiValidationPipe implements PipeTransform {
  constructor(private schema: ObjectSchema) {}

  transform(value: any, metadata: ArgumentMetadata) {
    const { error } = this.schema.validate(value);
    if (error) {
      throw new BadRequestException('Validation failed');
    }
    return value;
  }
}
```

```typescript

import { Injectable, BadRequestException } from '@nestjs/common';

@Injectable()
export class JoiValidationPipe {
  constructor(schema) {
    this.schema = schema;
  }

  transform(value, metadata) {
    const { error } = this.schema.validate(value);
    if (error) {
      throw new BadRequestException('Validation failed');
    }
    return value;
  }
}
```

#### Binding validation pipes[#](/pipes#binding-validation-pipes)

Earlier, we saw how to bind transformation pipes (like `ParseIntPipe` and the rest of the `Parse*` pipes).

Binding validation pipes is also very straightforward.

In this case, we want to bind the pipe at the method call level. In our current example, we need to do the following to use the `JoiValidationPipe`:

1. Create an instance of the `JoiValidationPipe`
2. Pass the context-specific Joi schema in the class constructor of the pipe
3. Bind the pipe to the method

Joi schema example:

```typescript

const createCatSchema = Joi.object({
  name: Joi.string().required(),
  age: Joi.number().required(),
  breed: Joi.string().required(),
})

export interface CreateCatDto {
  name: string;
  age: number;
  breed: string;
}
```

We do that using the `@UsePipes()` decorator as shown below:

JS TS

```typescript

@Post()
@UsePipes(new JoiValidationPipe(createCatSchema))
async create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

```typescript

@Post()
@Bind(Body())
@UsePipes(new JoiValidationPipe(createCatSchema))
async create(createCatDto) {
  this.catsService.create(createCatDto);
}
```

> **Hint** The `@UsePipes()` decorator is imported from the `@nestjs/common` package.

#### Class validator[#](/pipes#class-validator)

> **Warning** The techniques in this section require TypeScript, and are not available if your app is written using vanilla JavaScript.

Let's look at an alternate implementation for our validation technique.

Nest works well with the [class-validator](https://github.com/typestack/class-validator) library. This powerful library allows you to use decorator-based validation. Decorator-based validation is extremely powerful, especially when combined with Nest's **Pipe** capabilities since we have access to the `metatype` of the processed property. Before we start, we need to install the required packages:

```bash

$ npm i --save class-validator class-transformer
```

Once these are installed, we can add a few decorators to the `CreateCatDto` class. Here we see a significant advantage of this technique: the `CreateCatDto` class remains the single source of truth for our Post body object (rather than having to create a separate validation class).

create-cat.dto.ts

JS TS

```typescript

import { IsString, IsInt } from 'class-validator';

export class CreateCatDto {
  @IsString()
  name: string;

  @IsInt()
  age: number;

  @IsString()
  breed: string;
}
```

> **Hint** Read more about the class-validator decorators [here](https://github.com/typestack/class-validator#usage).

Now we can create a `ValidationPipe` class that uses these annotations.

validation.pipe.ts

JS TS

```typescript

import { PipeTransform, Injectable, ArgumentMetadata, BadRequestException } from '@nestjs/common';
import { validate } from 'class-validator';
import { plainToInstance } from 'class-transformer';

@Injectable()
export class ValidationPipe implements PipeTransform<any> {
  async transform(value: any, { metatype }: ArgumentMetadata) {
    if (!metatype || !this.toValidate(metatype)) {
      return value;
    }
    const object = plainToInstance(metatype, value);
    const errors = await validate(object);
    if (errors.length > 0) {
      throw new BadRequestException('Validation failed');
    }
    return value;
  }

  private toValidate(metatype: Function): boolean {
    const types: Function[] = [String, Boolean, Number, Array, Object];
    return !types.includes(metatype);
  }
}
```

> **Notice** Above, we have used the [class-transformer](https://github.com/typestack/class-transformer) library. It's made by the same author as the **class-validator** library, and as a result, they play very well together.

Let's go through this code. First, note that the `transform()` method is marked as `async`. This is possible because Nest supports both synchronous and **asynchronous** pipes. We make this method `async` because some of the class-validator validations [can be async](https://github.com/typestack/class-validator#custom-validation-classes) (utilize Promises).

Next note that we are using destructuring to extract the metatype field (extracting just this member from an `ArgumentMetadata`) into our `metatype` parameter. This is just shorthand for getting the full `ArgumentMetadata` and then having an additional statement to assign the metatype variable.

Next, note the helper function `toValidate()`. It's responsible for bypassing the validation step when the current argument being processed is a native JavaScript type (these can't have validation decorators attached, so there's no reason to run them through the validation step).

Next, we use the class-transformer function `plainToInstance()` to transform our plain JavaScript argument object into a typed object so that we can apply validation. The reason we must do this is that the incoming post body object, when deserialized from the network request, does **not have any type information** (this is the way the underlying platform, such as Express, works). Class-validator needs to use the validation decorators we defined for our DTO earlier, so we need to perform this transformation to treat the incoming body as an appropriately decorated object, not just a plain vanilla object.

Finally, as noted earlier, since this is a **validation pipe** it either returns the value unchanged, or throws an exception.

The last step is to bind the `ValidationPipe`. Pipes can be parameter-scoped, method-scoped, controller-scoped, or global-scoped. Earlier, with our Joi-based validation pipe, we saw an example of binding the pipe at the method level. In the example below, we'll bind the pipe instance to the route handler `@Body()` decorator so that our pipe is called to validate the post body.

cats.controller.ts

JS TS

```typescript

@Post()
async create(
  @Body(new ValidationPipe()) createCatDto: CreateCatDto,
) {
  this.catsService.create(createCatDto);
}
```

Parameter-scoped pipes are useful when the validation logic concerns only one specified parameter.

#### Global scoped pipes[#](/pipes#global-scoped-pipes)

Since the `ValidationPipe` was created to be as generic as possible, we can realize it's full utility by setting it up as a **global-scoped** pipe so that it is applied to every route handler across the entire application.

main.ts

JS TS

```typescript

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.useGlobalPipes(new ValidationPipe());
  await app.listen(3000);
}
bootstrap();
```

> **Notice** In the case of [hybrid apps](faq/hybrid-application) the `useGlobalPipes()` method doesn't set up pipes for gateways and micro services. For "standard" (non-hybrid) microservice apps, `useGlobalPipes()` does mount pipes globally.

Global pipes are used across the whole application, for every controller and every route handler.

Note that in terms of dependency injection, global pipes registered from outside of any module (with `useGlobalPipes()` as in the example above) cannot inject dependencies since the binding has been done outside the context of any module. In order to solve this issue, you can set up a global pipe **directly from any module** using the following construction:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { APP_PIPE } from '@nestjs/core';

@Module({
  providers: [
    {
      provide: APP_PIPE,
      useClass: ValidationPipe,
    },
  ],
})
export class AppModule {}
```

> **Hint** When using this approach to perform dependency injection for the pipe, note that regardless of the module where this construction is employed, the pipe is, in fact, global. Where should this be done? Choose the module where the pipe (`ValidationPipe` in the example above) is defined. Also, `useClass` is not the only way of dealing with custom provider registration. Learn more [here](/v9/fundamentals/custom-providers).

#### The built-in ValidationPipe[#](/pipes#the-built-in-validationpipe)

As a reminder, you don't have to build a generic validation pipe on your own since the `ValidationPipe` is provided by Nest out-of-the-box. The built-in `ValidationPipe` offers more options than the sample we built in this chapter, which has been kept basic for the sake of illustrating the mechanics of a custom-built pipe. You can find full details, along with lots of examples [here](/v9/techniques/validation).

#### Transformation use case[#](/pipes#transformation-use-case)

Validation isn't the only use case for custom pipes. At the beginning of this chapter, we mentioned that a pipe can also **transform** the input data to the desired format. This is possible because the value returned from the `transform` function completely overrides the previous value of the argument.

When is this useful? Consider that sometimes the data passed from the client needs to undergo some change - for example converting a string to an integer - before it can be properly handled by the route handler method. Furthermore, some required data fields may be missing, and we would like to apply default values. **Transformation pipes** can perform these functions by interposing a processing function between the client request and the request handler.

Here's a simple `ParseIntPipe` which is responsible for parsing a string into an integer value. (As noted above, Nest has a built-in `ParseIntPipe` that is more sophisticated; we include this as a simple example of a custom transformation pipe).

parse-int.pipe.ts

JS TS

```typescript

import { PipeTransform, Injectable, ArgumentMetadata, BadRequestException } from '@nestjs/common';

@Injectable()
export class ParseIntPipe implements PipeTransform<string, number> {
  transform(value: string, metadata: ArgumentMetadata): number {
    const val = parseInt(value, 10);
    if (isNaN(val)) {
      throw new BadRequestException('Validation failed');
    }
    return val;
  }
}
```

```typescript

import { Injectable, BadRequestException } from '@nestjs/common';

@Injectable()
export class ParseIntPipe {
  transform(value, metadata) {
    const val = parseInt(value, 10);
    if (isNaN(val)) {
      throw new BadRequestException('Validation failed');
    }
    return val;
  }
}
```

We can then bind this pipe to the selected param as shown below:

JS TS

```typescript

@Get(':id')
async findOne(@Param('id', new ParseIntPipe()) id) {
  return this.catsService.findOne(id);
}
```

```typescript

@Get(':id')
@Bind(Param('id', new ParseIntPipe()))
async findOne(id) {
  return this.catsService.findOne(id);
}
```

Another useful transformation case would be to select an **existing user** entity from the database using an id supplied in the request:

JS TS

```typescript

@Get(':id')
findOne(@Param('id', UserByIdPipe) userEntity: UserEntity) {
  return userEntity;
}
```

```typescript

@Get(':id')
@Bind(Param('id', UserByIdPipe))
findOne(userEntity) {
  return userEntity;
}
```

We leave the implementation of this pipe to the reader, but note that like all other transformation pipes, it receives an input value (an `id`) and returns an output value (a `UserEntity` object). This can make your code more declarative and [DRY](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself) by abstracting boilerplate code out of your handler and into a common pipe.

#### Providing defaults[#](/pipes#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:

JS TS

```typescript

@Get()
async findAll(
  @Query('activeOnly', new DefaultValuePipe(false), ParseBoolPipe) activeOnly: boolean,
  @Query('page', new DefaultValuePipe(0), ParseIntPipe) page: number,
) {
  return this.catsService.findAll({ activeOnly, page });
}
```

----
url: https://docs.nestjs.com/v6/techniques/compression
----

* [Compression](https://docs.nestjs.com/v6/techniques/compression#compression)
* [Installation](https://docs.nestjs.com/v6/techniques/compression#installation)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/techniques/compression.md "Suggest Edits")

### Compression

Compression can greatly decrease the size of the response body, thereby increasing the speed of a web app. Use the [compression](https://github.com/expressjs/compression) middleware package to enable gzip compression.

#### Installation[#](/techniques/compression#installation)

First install the required package:

```bash

$ npm i --save compression
```

Once the installation is complete, apply the compression middleware as global middleware.

```typescript

import * as compression from 'compression';
// somewhere in your initialization file
app.use(compression());
```

> **Hint** If using the `FastifyAdapter`, consider using [fastify-compress](https://github.com/fastify/fastify-compress) instead.

For **high-traffic** websites in production, it is strongly recommended to offload compression from the application server - typically in a reverse proxy (e.g., Nginx). In that case, you should not use compression middleware.

----
url: https://docs.nestjs.com/v7/migration-guide
----

* [Migration guide](https://docs.nestjs.com/v7/migration-guide#migration-guide)
* [Custom route decorators](https://docs.nestjs.com/v7/migration-guide#custom-route-decorators)
* [Microservices](https://docs.nestjs.com/v7/migration-guide#microservices)
* [GraphQL](https://docs.nestjs.com/v7/migration-guide#graphql)
* [Terminus](https://docs.nestjs.com/v7/migration-guide#terminus)
* [HTTP exceptions body](https://docs.nestjs.com/v7/migration-guide#http-exceptions-body)
* [Validation errors schema](https://docs.nestjs.com/v7/migration-guide#validation-errors-schema)
* [Implicit type conversion (ValidationPipe)](https://docs.nestjs.com/v7/migration-guide#implicit-type-conversion-validationpipe)
* [Microservice channels (bidirectional communication)](https://docs.nestjs.com/v7/migration-guide#microservice-channels-bidirectional-communication)
* [Deprecations](https://docs.nestjs.com/v7/migration-guide#deprecations)
* [Node.js](https://docs.nestjs.com/v7/migration-guide#nodejs)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/migration.md "Suggest Edits")

### Migration guide

This article provides a set of guidelines for migrating from Nest version 6 to version 7.

#### Custom route decorators[#](/migration-guide#custom-route-decorators)

The [Custom decorators](/v7/custom-decorators) API has been unified for all types of applications. Now, whether you're creating a GraphQL application or a REST API, the factory passed into the `createParamDecorator()` function will take the `ExecutionContext` (read more [here](/v7/fundamentals/execution-context)) object as a second argument.

JS TS

```typescript

// Before
import { createParamDecorator } from '@nestjs/common';

export const User = createParamDecorator((data, req) => {
  return req.user;
});

// After
import { createParamDecorator, ExecutionContext } from '@nestjs/common';

export const User = createParamDecorator(
  (data: unknown, ctx: ExecutionContext) => {
    const request = ctx.switchToHttp().getRequest();
    return request.user;
  },
);
```

```typescript

// Before
import { createParamDecorator } from '@nestjs/common';

export const User = createParamDecorator((data, req) => {
  return req.user;
});

// After
import { createParamDecorator } from '@nestjs/common';

export const User = createParamDecorator((data, ctx) => {
  const request = ctx.switchToHttp().getRequest();
  return request.user;
});
```

#### Microservices[#](/migration-guide#microservices)

To avoid code duplication, the `MicroserviceOptions` interface has been removed from the `@nestjs/common` package. Therefore, now when you're creating a microservice (through either `createMicroservice()` or `connectMicroservice()` method), you should pass the type generic parameter to get code autocompletion.

JS TS

```typescript

// Before
const app = await NestFactory.createMicroservice(AppModule);

// After
const app = await NestFactory.createMicroservice<MicroserviceOptions>(AppModule);
```

```typescript

// Before
const app = await NestFactory.createMicroservice(AppModule);

// After
const app = await NestFactory.createMicroservice(AppModule);
```

> **Hint** The `MicroserviceOptions` interface is exported from the `@nestjs/microservices` package.

#### GraphQL[#](/migration-guide#graphql)

In the version 6 major release of NestJS, we introduced the code-first approach as a compatibility layer between the `type-graphql` package and the `@nestjs/graphql` module. Eventually, our team decided to reimplement all the features from scratch due to a lack of flexibility. To avoid numerous breaking changes, the public API is backward-compatible and may resemble `type-graphql`.

In order to migrate your existing application, simply rename all the `type-graphql` imports to the `@nestjs/graphql`. If you used more advanced features, you might need to also:

* use `Type` (imported from `@nestjs/common`) instead of `ClassType` (imported from `type-graphql`)
* move methods that require `@Args()` from object types (classes annotated with `@ObjectType()` decorator) under resolver classes (and use `@ResolveField()` decorator instead of `@Field()`)

#### Terminus[#](/migration-guide#terminus)

In the version 7 major release of `@nestjs/terminus`, a new simplified API has been introduced to run health checks. The previously required peer dependency `@godaddy/terminus` has been removed, which allows us to integrate our health checks automatically into Swagger! Read more about the removal of `@godaddy/terminus`[here](https://github.com/nestjs/terminus/issues/340).

For most users, the biggest change will be the removal of the `TerminusModule.forRootAsync` function. With the next major version, this function will be completely removed. To migrate to the new API, you will need to create a new controller, which will handle your health checks.

JS TS

```typescript

// Before
@Injectable()
export class TerminusOptionsService implements TerminusOptionsFactory {
  constructor(
    private http: HttpHealthIndicator,
  ) {}

  createTerminusOptions(): TerminusModuleOptions {
    const healthEndpoint: TerminusEndpoint = {
      url: '/health',
      healthIndicators: [
        async () => this.http.pingCheck('google', 'https://google.com'),
      ],
    };
    return {
      endpoints: [healthEndpoint],
    };
  }
}

@Module({
  imports: [
    TerminusModule.forRootAsync({
      useClass: TerminusOptionsService
    })
  ]
})
export class AppModule { }

// After
@Controller('health')
export class HealthController {
  constructor(
    private health: HealthCheckService,
    private http: HttpHealthIndicator,
  ) { }

  @Get()
  @HealthCheck()
  healthCheck() {
    return this.health.check([
      async () => this.http.pingCheck('google', 'https://google.com'),
    ]);
  }
}

@Module({
  controllers: [
    HealthController
  ],
  imports: [
    TerminusModule
  ]
})
export class AppModule { }
```

```typescript

// Before
@Injectable()
@Dependencies(HttpHealthIndicator)
export class TerminusOptionsService {
  constructor(
    private http,
  ) {}

  createTerminusOptions() {
    const healthEndpoint = {
      url: '/health',
      healthIndicators: [
        async () => this.http.pingCheck('google', 'https://google.com'),
      ],
    };
    return {
      endpoints: [healthEndpoint],
    };
  }
}

@Module({
  imports: [
    TerminusModule.forRootAsync({
      useClass: TerminusOptionsService
    })
  ]
})
export class AppModule { }

// After
@Controller('/health')
@Dependencies(HealthCheckService, HttpHealthIndicator)
export class HealthController {
  constructor(
    private health,
    private http,
  ) { }

  @Get('/')
  @HealthCheck()
  healthCheck() {
    return this.health.check([
      async () => this.http.pingCheck('google', 'https://google.com'),
    ])
  }
}

@Module({
  controllers: [
    HealthController
  ],
  imports: [
    TerminusModule
  ]
})
export class AppModule { }
```

> **Warning** If you have set a [Global Prefix](faq#global-prefix) in your Nest application and you have not used the `useGlobalPrefix` Terminus option, the URL of your health check will change. Make sure to update the reference to that URL, or use the legacy Terminus API until [nestjs/nest#963](https://github.com/nestjs/nest/issues/963) is fixed.

If you are forced to use the legacy API, you can also disable deprecation messages for the time being.

```typescript

TerminusModule.forRootAsync({
  useFactory: () => ({
    disableDeprecationWarnings: true,
    endpoints: [
      // ...
    ]
  })
}
```

You should enable shutdown hooks in your `main.ts` file. The Terminus integration will listen on POSIX signals such as SIGTERM (see the [Application shutdown chapter](fundamentals/lifecycle-events#application-shutdown) for more information). When enabled, the health check route(s) will automatically respond with a Service Unavailable (503) HTTP error response when the server is shutting down.

With the removal of `@godaddy/terminus`, you will need to update your `import` statements to use `@nestjs/terminus` instead. Most notable is the import of the `HealthCheckError`.

custom.health.ts

JS TS

```typescript

// Before
import { HealthCheckError } from '@godaddy/terminus';
// After
import { HealthCheckError } from '@nestjs/terminus';
```

Once you have fully migrated, make sure you uninstall `@godaddy/terminus`.

```bash

npm uninstall --save @godaddy/terminus
```

##### `DNSHealthIndicator` deprecation

The `DNSHealthIndicator` has been renamed to `HttpHealthIndicator` in order to improve consistency with the official [`HttpService`](/techniques/http-module#http-module) as well as choosing a better fitting name for its functionality.

Simply migrate by replacing the `DNSHealthIndicator` references with `HttpHealthIndicator`. The functionality has been untouched.

```typescript

// Before
@Controller('health')
export class HealthController {
  constructor(
    private dns: DNSHealthIndicator,
  ) { }
  ...
}
// After
@Controller('health')
export class HealthController {
  constructor(
    private http: HttpHealthIndicator,
  ) { }
  ...
}
```

#### HTTP exceptions body[#](/migration-guide#http-exceptions-body)

Previously, the generated response bodies for the `HttpException` class and other exceptions derived from it (e.g., `BadRequestException` or `NotFoundException`) were inconsistent. In the latest major release, these exception responses will follow the same structure.

```typescript

/*
 * Sample outputs for "throw new ForbiddenException('Forbidden resource')"
 */

// Before
{
  "statusCode": 403,
  "message": "Forbidden resource"
}

// After
{
  "statusCode": 403,
  "message": "Forbidden resource",
  "error": "Forbidden"
}
```

#### Validation errors schema[#](/migration-guide#validation-errors-schema)

In past releases, the `ValidationPipe` threw an array of the `ValidationError` objects returned by the `class-validator` package. Now, `ValidationPipe` will map errors to a list of plain strings representing error messages.

```typescript

// Before
{
  "statusCode": 400,
  "error": "Bad Request",
  "message": [
    {
      "target": {},
      "property": "email",
      "children": [],
      "constraints": {
        "isEmail": "email must be an email"
      }
    }
  ]
}

// After
{
  "statusCode": 400,
  "message": ["email must be an email"],
  "error": "Bad Request"
}
```

If you prefer the previous approach, you can restore it by setting the `exceptionFactory` function:

```typescript

new ValidationPipe({
  exceptionFactory: (errors) => new BadRequestException(errors),
});
```

#### Implicit type conversion (`ValidationPipe`)[#](/migration-guide#implicit-type-conversion-validationpipe)

With the auto-transformation option enabled (`transform: true`), the `ValidationPipe` will now perform conversion of primitive types. In the following example, the `findOne()` method takes one argument which represents an extracted `id` path parameter:

```typescript

@Get(':id')
findOne(@Param('id') id: number) {
  console.log(typeof id === 'number'); // true
  return 'This action returns a user';
}
```

By default, every path parameter and query parameter comes over the network as a `string`. In the above example, we specified the `id` type as a `number` (in the method signature). Therefore, the `ValidationPipe` will try to automatically convert a string identifier to a number.

#### Microservice channels (bidirectional communication)[#](/migration-guide#microservice-channels-bidirectional-communication)

To enable the request-response message type, Nest creates two logical channels - one is responsible for transferring the data while the other waits for incoming responses. For some underlying transports, such as NATS, this dual-channel support is provided out-of-the-box. For others, Nest compensates by manually creating separate channels.

Let's say that we have a single message handler `@MessagePattern('getUsers')`. In the past, Nest built two channels from this pattern: `getUsers_ack` (for requests) and `getUsers_res` (for responses). With version 7, this naming scheme changes. Now Nest will build `getUsers` (for requests) and `getUsers.reply` (for responses) instead. Also, specifically for the MQTT transport strategy, the response channel would be `getUsers/reply` (to avoid conflicts with topic wildcards).

#### Deprecations[#](/migration-guide#deprecations)

All deprecations (from Nest version 5 to version 6) have been finally removed (e.g., the deprecated `@ReflectMetadata` decorator).

#### Node.js[#](/migration-guide#nodejs)

This release drops support for Node v8. We strongly recommend using the latest LTS version.

----
url: https://docs.nestjs.com/v6/techniques/security
----

* [Security](https://docs.nestjs.com/v6/techniques/security#security)
* [Helmet](https://docs.nestjs.com/v6/techniques/security#helmet)
* [CORS](https://docs.nestjs.com/v6/techniques/security#cors)
* [CSRF](https://docs.nestjs.com/v6/techniques/security#csrf)
* [Rate limiting](https://docs.nestjs.com/v6/techniques/security#rate-limiting)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/techniques/security.md "Suggest Edits")

### Security

In this chapter we cover various techniques that help you to increase the security of your applications.

#### Helmet[#](/techniques/security#helmet)

[Helmet](https://github.com/helmetjs/helmet) can help protect your app from some well-known web vulnerabilities by setting HTTP headers appropriately. Generally, Helmet is just a collection of 14 smaller middleware functions that set security-related HTTP headers (read [more](https://github.com/helmetjs/helmet#how-it-works)).

Start by installing the required package:

```bash

$ npm i --save helmet
```

Once the installation is complete, apply it as a global middleware.

```typescript

import * as helmet from 'helmet';
// somewhere in your initialization file
app.use(helmet());
```

#### CORS[#](/techniques/security#cors)

Cross-origin resource sharing (CORS) is a mechanism that allows resources to be requested from another domain. Under the hood, Nest makes use of the Express [cors](https://github.com/expressjs/cors) package. This package provides various options that you can customize based on your requirements. To enable CORS, call the `enableCors()` method on the Nest application object.

```typescript

const app = await NestFactory.create(AppModule);
app.enableCors();
await app.listen(3000);
```

The `enableCors()` method takes an optional configuration object argument. The available properties of this object are described in the official [CORS](https://github.com/expressjs/cors#configuration-options) documentation.

Alternatively, enable CORS via the `create()` method's options object. Set the `cors` property to `true` to enable CORS with default settings. Alternatively, pass a [CORS configuration object](https://github.com/expressjs/cors#configuration-options) as the `cors` property value to customize its behavior.

```typescript

const app = await NestFactory.create(AppModule, { cors: true });
await app.listen(3000);
```

#### CSRF[#](/techniques/security#csrf)

Cross-site request forgery (also known as CSRF or XSRF) is a type of malicious exploit of a website where **unauthorized** commands are transmitted from a user that the web application trusts. To mitigate this kind of attack you can use the [csurf](https://github.com/expressjs/csurf) package.

Start by installing the required package:

```bash

$ npm i --save csurf
```

> **Warning** As explained on the [csurf middleware page](https://github.com/expressjs/csurf#csurf), the csurf module requires either session middleware or a cookie-parser to be initialized first. Please see that documentation for further instructions.

Once the installation is complete, apply the csurf middleware as global middleware.

```typescript

import * as csurf from 'csurf';
// somewhere in your initialization file
app.use(csurf());
```

#### Rate limiting[#](/techniques/security#rate-limiting)

A common technique to protect applications from brute-force attacks is **rate-limiting**. Many Express packages exist to provide a rate-limiting feature. A popular one is [express-rate-limit](https://github.com/nfriedly/express-rate-limit).

Start by installing the required package:

```bash

$ npm i --save express-rate-limit
```

Once the installation is complete, apply the rate-limiter as global middleware.

```typescript

import * as rateLimit from 'express-rate-limit';
// somewhere in your initialization file
app.use(
  rateLimit({
    windowMs: 15 * 60 * 1000, // 15 minutes
    max: 100, // limit each IP to 100 requests per windowMs
  }),
);
```

> **Hint** If you use the `FastifyAdapter`, consider using [fastify-rate-limit](https://github.com/fastify/fastify-rate-limit) instead.

----
url: https://docs.nestjs.com/v11/security/rate-limiting
----

* [Rate Limiting](https://docs.nestjs.com/v11/security/rate-limiting#rate-limiting)
* [Multiple Throttler Definitions](https://docs.nestjs.com/v11/security/rate-limiting#multiple-throttler-definitions)
* [Customization](https://docs.nestjs.com/v11/security/rate-limiting#customization)
* [Proxies](https://docs.nestjs.com/v11/security/rate-limiting#proxies)
* [Websockets](https://docs.nestjs.com/v11/security/rate-limiting#websockets)
* [GraphQL](https://docs.nestjs.com/v11/security/rate-limiting#graphql)
* [Configuration](https://docs.nestjs.com/v11/security/rate-limiting#configuration)
* [Async Configuration](https://docs.nestjs.com/v11/security/rate-limiting#async-configuration)
* [Storages](https://docs.nestjs.com/v11/security/rate-limiting#storages)
* [Time Helpers](https://docs.nestjs.com/v11/security/rate-limiting#time-helpers)
* [Migration Guide](https://docs.nestjs.com/v11/security/rate-limiting#migration-guide)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/security/rate-limiting.md "Suggest Edits")

### Rate Limiting

A common technique to protect applications from brute-force attacks is **rate-limiting**. To get started, you'll need to install the `@nestjs/throttler` package.

```bash

$ npm i --save @nestjs/throttler
```

Once the installation is complete, the `ThrottlerModule` can be configured as any other Nest package with `forRoot` or `forRootAsync` methods.

app.module.ts

JS TS

```typescript

@Module({
  imports: [
     ThrottlerModule.forRoot({
      throttlers: [
        {
          ttl: 60000,
          limit: 10,
        },
      ],
    }),
  ],
})
export class AppModule {}
```

The above will set the global options for the `ttl`, the time to live in milliseconds, and the `limit`, the maximum number of requests within the ttl, for the routes of your application that are guarded.

Once the module has been imported, you can then choose how you would like to bind the `ThrottlerGuard`. Any kind of binding as mentioned in the [guards](https://docs.nestjs.com/guards) section is fine. If you wanted to bind the guard globally, for example, you could do so by adding this provider to any module:

```typescript

{
  provide: APP_GUARD,
  useClass: ThrottlerGuard
}
```

#### Multiple Throttler Definitions[#](/security/rate-limiting#multiple-throttler-definitions)

There may come upon times where you want to set up multiple throttling definitions, like no more than 3 calls in a second, 20 calls in 10 seconds, and 100 calls in a minute. To do so, you can set up your definitions in the array with named options, that can later be referenced in the `@SkipThrottle()` and `@Throttle()` decorators to change the options again.

app.module.ts

JS TS

```typescript

@Module({
  imports: [
    ThrottlerModule.forRoot([
      {
        name: 'short',
        ttl: 1000,
        limit: 3,
      },
      {
        name: 'medium',
        ttl: 10000,
        limit: 20
      },
      {
        name: 'long',
        ttl: 60000,
        limit: 100
      }
    ]),
  ],
})
export class AppModule {}
```

#### Customization[#](/security/rate-limiting#customization)

There may be a time where you want to bind the guard to a controller or globally, but want to disable rate limiting for one or more of your endpoints. For that, you can use the `@SkipThrottle()` decorator, to negate the throttler for an entire class or a single route. The `@SkipThrottle()` decorator can also take in an object of string keys with boolean values for if there is a case where you want to exclude *most* of a controller, but not every route, and configure it per throttler set if you have more than one. If you do not pass an object, the default is to use `{ default: true }`

```typescript

@SkipThrottle()
@Controller('users')
export class UsersController {}
```

This `@SkipThrottle()` decorator can be used to skip a route or a class or to negate the skipping of a route in a class that is skipped.

```typescript

@SkipThrottle()
@Controller('users')
export class UsersController {
  // Rate limiting is applied to this route.
  @SkipThrottle({ default: false })
  dontSkip() {
    return 'List users work with Rate limiting.';
  }
  // This route will skip rate limiting.
  doSkip() {
    return 'List users work without Rate limiting.';
  }
}
```

There is also the `@Throttle()` decorator which can be used to override the `limit` and `ttl` set in the global module, to give tighter or looser security options. This decorator can be used on a class or a function as well. With version 5 and onwards, the decorator takes in an object with the string relating to the name of the throttler set, and an object with the limit and ttl keys and integer values, similar to the options passed to the root module. If you do not have a name set in your original options, use the string `default`. You have to configure it like this:

```typescript

// Override default configuration for Rate limiting and duration.
@Throttle({ default: { limit: 3, ttl: 60000 } })
@Get()
findAll() {
  return "List users works with custom rate limiting.";
}
```

#### Proxies[#](/security/rate-limiting#proxies)

If your application is running behind a proxy server, it’s essential to configure the HTTP adapter to trust the proxy. You can refer to the specific HTTP adapter options for [Express](http://expressjs.com/en/guide/behind-proxies.html) and [Fastify](https://www.fastify.io/docs/latest/Reference/Server/#trustproxy) to enable the `trust proxy` setting.

Here's an example that demonstrates how to enable `trust proxy` for the Express adapter:

main.ts

JS TS

```typescript

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { NestExpressApplication } from '@nestjs/platform-express';

async function bootstrap() {
  const app = await NestFactory.create<NestExpressApplication>(AppModule);
  app.set('trust proxy', 'loopback'); // Trust requests from the loopback address
  await app.listen(3000);
}

bootstrap();
```

```typescript

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { NestExpressApplication } from '@nestjs/platform-express';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.set('trust proxy', 'loopback'); // Trust requests from the loopback address
  await app.listen(3000);
}

bootstrap();
```

Enabling `trust proxy` allows you to retrieve the original IP address from the `X-Forwarded-For` header. You can also customize the behavior of your application by overriding the `getTracker()` method to extract the IP address from this header instead of relying on `req.ip`. The following example demonstrates how to achieve this for both Express and Fastify:

throttler-behind-proxy.guard.ts

JS TS

```typescript

import { ThrottlerGuard } from '@nestjs/throttler';
import { Injectable } from '@nestjs/common';

@Injectable()
export class ThrottlerBehindProxyGuard extends ThrottlerGuard {
  protected async getTracker(req: Record<string, any>): Promise<string> {
    return req.ips.length ? req.ips[0] : req.ip; // individualize IP extraction to meet your own needs
  }
}
```

> **Hint** You can find the API of the `req` Request object for express [here](https://expressjs.com/en/api.html#req.ips) and for fastify [here](https://www.fastify.io/docs/latest/Reference/Request/).

#### Websockets[#](/security/rate-limiting#websockets)

This module can work with websockets, but it requires some class extension. You can extend the `ThrottlerGuard` and override the `handleRequest` method like so:

```typescript

@Injectable()
export class WsThrottlerGuard extends ThrottlerGuard {
  async handleRequest(requestProps: ThrottlerRequest): Promise<boolean> {
    const {
      context,
      limit,
      ttl,
      throttler,
      blockDuration,
      getTracker,
      generateKey,
    } = requestProps;

    const client = context.switchToWs().getClient();
    const tracker = client._socket.remoteAddress;
    const key = generateKey(context, tracker, throttler.name);
    const { totalHits, timeToExpire, isBlocked, timeToBlockExpire } =
      await this.storageService.increment(
        key,
        ttl,
        limit,
        blockDuration,
        throttler.name,
      );

    const getThrottlerSuffix = (name: string) =>
      name === 'default' ? '' : `-${name}`;

    // Throw an error when the user reached their limit.
    if (isBlocked) {
      await this.throwThrottlingException(context, {
        limit,
        ttl,
        key,
        tracker,
        totalHits,
        timeToExpire,
        isBlocked,
        timeToBlockExpire,
      });
    }

    return true;
  }
}
```

> **Hint** If you are using ws, it is necessary to replace the `_socket` with `conn`

There's a few things to keep in mind when working with WebSockets:

* Guard cannot be registered with the `APP_GUARD` or `app.useGlobalGuards()`
* When a limit is reached, Nest will emit an `exception` event, so make sure there is a listener ready for this

> **Hint** If you are using the `@nestjs/platform-ws` package you can use `client._socket.remoteAddress` instead.

> **Hint** When you configure [multiple throttler definitions](/security/rate-limiting#multiple-throttler-definitions), `handleRequest()` runs once for each throttler set. Use the `throttler.name` from `ThrottlerRequest` when generating the storage key and when reporting the `ThrottlerLimitDetail`, as shown above, so each named throttler tracks its own limit.

#### GraphQL[#](/security/rate-limiting#graphql)

The `ThrottlerGuard` can also be used to work with GraphQL requests. Again, the guard can be extended, but this time the `getRequestResponse` method will be overridden

```typescript

@Injectable()
export class GqlThrottlerGuard extends ThrottlerGuard {
  getRequestResponse(context: ExecutionContext) {
    const gqlCtx = GqlExecutionContext.create(context);
    const ctx = gqlCtx.getContext();
    return { req: ctx.req, res: ctx.res };
  }
}
```

#### Configuration[#](/security/rate-limiting#configuration)

The following options are valid for the object passed to the array of the `ThrottlerModule`'s options:

|                    |                                                                                                                                                                |
| ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `name`             | the name for internal tracking of which throttler set is being used. Defaults to `default` if not passed                                                       |
| `ttl`              | the number of milliseconds that each request will last in storage                                                                                              |
| `limit`            | the maximum number of requests within the TTL limit                                                                                                            |
| `blockDuration`    | the number of milliseconds that request will be blocked for that time                                                                                          |
| `ignoreUserAgents` | an array of regular expressions of user-agents to ignore when it comes to throttling requests                                                                  |
| `skipIf`           | a function that takes in the `ExecutionContext` and returns a `boolean` to short circuit the throttler logic. Like `@SkipThrottle()`, but based on the request |

If you need to set up storage instead, or want to use some of the above options in a more global sense, applying to each throttler set, you can pass the options above via the `throttlers` option key and use the below table

|                    |                                                                                                                                                                                                                                                                           |
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `storage`          | a custom storage service for where the throttling should be kept track. [See here.](/security/rate-limiting#storages)                                                                                                                                                     |
| `ignoreUserAgents` | an array of regular expressions of user-agents to ignore when it comes to throttling requests                                                                                                                                                                             |
| `skipIf`           | a function that takes in the `ExecutionContext` and returns a `boolean` to short circuit the throttler logic. Like `@SkipThrottle()`, but based on the request                                                                                                            |
| `throttlers`       | an array of throttler sets, defined using the table above                                                                                                                                                                                                                 |
| `errorMessage`     | a `string` OR a function that takes in the `ExecutionContext` and the `ThrottlerLimitDetail` and returns a `string` which overrides the default throttler error message                                                                                                   |
| `getTracker`       | a function that takes in the `Request` and returns a `string` to override the default logic of the `getTracker` method                                                                                                                                                    |
| `generateKey`      | a function that takes in the `ExecutionContext`, the tacker `string` and the throttler name as a `string` and returns a `string` to override the final key which will be used to store the rate limit value. This overrides the default logic of the `generateKey` method |

#### Async Configuration[#](/security/rate-limiting#async-configuration)

You may want to get your rate-limiting configuration asynchronously instead of synchronously. You can use the `forRootAsync()` method, which allows for dependency injection and `async` methods.

One approach would be to use a factory function:

```typescript

@Module({
  imports: [
    ThrottlerModule.forRootAsync({
      imports: [ConfigModule],
      inject: [ConfigService],
      useFactory: (config: ConfigService) => [
        {
          ttl: config.get('THROTTLE_TTL'),
          limit: config.get('THROTTLE_LIMIT'),
        },
      ],
    }),
  ],
})
export class AppModule {}
```

You can also use the `useClass` syntax:

```typescript

@Module({
  imports: [
    ThrottlerModule.forRootAsync({
      imports: [ConfigModule],
      useClass: ThrottlerConfigService,
    }),
  ],
})
export class AppModule {}
```

This is doable, as long as `ThrottlerConfigService` implements the interface `ThrottlerOptionsFactory`.

#### Storages[#](/security/rate-limiting#storages)

The built in storage is an in memory cache that keeps track of the requests made until they have passed the TTL set by the global options. You can drop in your own storage option to the `storage` option of the `ThrottlerModule` so long as the class implements the `ThrottlerStorage` interface.

For distributed servers you could use the community storage provider for [Redis](https://github.com/jmcdo29/nest-lab/tree/main/packages/throttler-storage-redis) to have a single source of truth.

> **Note**`ThrottlerStorage` can be imported from `@nestjs/throttler`.

#### Time Helpers[#](/security/rate-limiting#time-helpers)

There are a couple of helper methods to make the timings more readable if you prefer to use them over the direct definition. `@nestjs/throttler` exports five different helpers, `seconds`, `minutes`, `hours`, `days`, and `weeks`. To use them, simply call `seconds(5)` or any of the other helpers, and the correct number of milliseconds will be returned.

#### Migration Guide[#](/security/rate-limiting#migration-guide)

For most people, wrapping your options in an array will be enough.

If you are using a custom storage, you should wrap your `ttl` and `limit` in an array and assign it to the `throttlers` property of the options object.

Any `@SkipThrottle()` decorator can be used to bypass throttling for specific routes or methods. It accepts an optional boolean parameter, which defaults to `true`. This is useful when you want to skip rate limiting on particular endpoints.

Any `@Throttle()` decorators should also now take in an object with string keys, relating to the names of the throttler contexts (again, `'default'` if no name) and values of objects that have `limit` and `ttl` keys.

> **Important** The `ttl` is now in **milliseconds**. If you want to keep your ttl in seconds for readability, use the `seconds` helper from this package. It just multiplies the ttl by 1000 to make it in milliseconds.

For more info, see the [Changelog](https://github.com/nestjs/throttler/blob/master/CHANGELOG.md#500)

----
url: https://docs.nestjs.com/websockets/pipes
----

[Skip to content](#content)

On this page

* [Pipes](https://docs.nestjs.com/websockets/pipes#pipes)
* [Binding pipes](https://docs.nestjs.com/websockets/pipes#binding-pipes)
* [Schema-based validation](https://docs.nestjs.com/websockets/pipes#schema-based-validation)

[](https://srv.carbonads.net/ads/click/x/GTND4277CVSIC2JEFTBLYKQUF67D62QYCT7IPZ3JCAAI623WC6YI453KC6YDP537CKAIP2J7C6BILKJICTBDL5QUHEYI55QLCAYD653ECTNCYBZ52K)[High-Performance PDF SDK for Developers. Code Without Limits. Try for Free. ](https://srv.carbonads.net/ads/click/x/GTND4277CVSIC2JEFTBLYKQUF67D62QYCT7IPZ3JCAAI623WC6YI453KC6YDP537CKAIP2J7C6BILKJICTBDL5QUHEYI55QLCAYD653ECTNCYBZ52K)[ads via Carbon](http://carbonads.net/?utm_source=nestjscom\&utm_medium=ad_via_link\&utm_campaign=in_unit\&utm_term=carbon)

### Pipes

There is no fundamental difference between [regular pipes](/pipes) and WebSocket pipes. The only difference is that instead of throwing `HttpException`, you should throw `WsException`. Only a `WsException` reaches the client with its own message. Any other exception, including the `BadRequestException` that the built-in validation pipes throw by default, is reported to the client as `'Internal server error'`.

> **Hint** The `WsException` class is exposed from the `@nestjs/websockets` package.

#### Binding pipes[#](/websockets/pipes#binding-pipes)

The following example uses a manually instantiated method-scoped pipe. As with HTTP-based applications, you can also use gateway-scoped pipes (i.e., decorate the gateway class with `@UsePipes()`). Global pipes registered with `app.useGlobalPipes()` or the `APP_PIPE` token apply to gateways as well.

JS TS

```typescript

@UsePipes(new ValidationPipe({ exceptionFactory: (errors) => new WsException(errors) }))
@SubscribeMessage('events')
handleEvent(client: Client, data: unknown): WsResponse<unknown> {
  const event = 'events';
  return { event, data };
}
```

```typescript

@UsePipes(new ValidationPipe({ exceptionFactory: (errors) => new WsException(errors) }))
@SubscribeMessage('events')
handleEvent(client, data) {
  const event = 'events';
  return { event, data };
}
```

Method-, gateway-, and global-scoped pipes run for every parameter of the message handler. To transform or validate only the message payload, bind the pipe at the parameter level instead, e.g., `@MessageBody(new ParseIntPipe())` or `@MessageBody('id', ParseIntPipe)`.

#### Schema-based validation[#](/websockets/pipes#schema-based-validation)

Like the HTTP parameter decorators, `@MessageBody()` accepts an options object with a `schema` property. The schema can come from any [Standard Schema](https://standardschema.dev/) compatible library, such as Zod, Valibot, or ArkType. The built-in `StandardSchemaValidationPipe` validates the payload against that schema, and passes parameters without a schema through unchanged. See [Schema-based validation](/application/validation#schema-based-validation) for details.

JS TS

```typescript

@UsePipes(
  new StandardSchemaValidationPipe({
    exceptionFactory: (issues) => new WsException(issues),
  }),
)
@SubscribeMessage('events')
handleEvent(@MessageBody({ schema: createEventSchema }) data: CreateEventDto) {
  return data;
}
```

```typescript

@UsePipes(
  new StandardSchemaValidationPipe({
    exceptionFactory: (issues) => new WsException(issues),
  }),
)
@Bind(MessageBody({ schema: createEventSchema }))
@SubscribeMessage('events')
handleEvent(data) {
  return data;
}
```

To extract a single property and validate it, pass the property key first: `@MessageBody('id', { schema: z.number() })`.

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/websockets/pipes.md)

----
url: https://docs.nestjs.com/v8/recipes/prisma
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Prisma](https://docs.nestjs.com/v8/recipes/prisma#prisma)
* [Getting started](https://docs.nestjs.com/v8/recipes/prisma#getting-started)
* [Create your NestJS project](https://docs.nestjs.com/v8/recipes/prisma#create-your-nestjs-project)
* [Set up Prisma](https://docs.nestjs.com/v8/recipes/prisma#set-up-prisma)
* [Set the database connection](https://docs.nestjs.com/v8/recipes/prisma#set-the-database-connection)
* [Create two database tables with Prisma Migrate](https://docs.nestjs.com/v8/recipes/prisma#create-two-database-tables-with-prisma-migrate)
* [Install and generate Prisma Client](https://docs.nestjs.com/v8/recipes/prisma#install-and-generate-prisma-client)
* [Use Prisma Client in your NestJS services](https://docs.nestjs.com/v8/recipes/prisma#use-prisma-client-in-your-nestjs-services)
* [Issues with enableShutdownHooks](https://docs.nestjs.com/v8/recipes/prisma#issues-with-enableshutdownhooks)
* [Summary](https://docs.nestjs.com/v8/recipes/prisma#summary)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/recipes/prisma.md "Suggest Edits")

### Prisma

[Prisma](https://www.prisma.io) is an [open-source](https://github.com/prisma/prisma) ORM for Node.js and TypeScript. It is used as an **alternative** to writing plain SQL, or using another database access tool such as SQL query builders (like [knex.js](https://knexjs.org/)) or ORMs (like [TypeORM](https://typeorm.io/) and [Sequelize](https://sequelize.org/)). Prisma currently supports PostgreSQL, MySQL, SQL Server, SQLite, MongoDB and CockroachDB (Preview).

While Prisma can be used with plain JavaScript, it embraces TypeScript and provides a level to type-safety that goes beyond the guarantees other ORMs in the TypeScript ecosystem. You can find an in-depth comparison of the type-safety guarantees of Prisma and TypeORM [here](https://www.prisma.io/docs/concepts/more/comparisons/prisma-and-typeorm#type-safety).

> **Note** If you want to get a quick overview of how Prisma works, you can follow the [Quickstart](https://www.prisma.io/docs/getting-started/quickstart) or read the [Introduction](https://www.prisma.io/docs/understand-prisma/introduction) in the [documentation](https://www.prisma.io/docs/). There also are ready-to-run examples for [REST](https://github.com/prisma/prisma-examples/tree/latest/typescript/rest-nestjs) and [GraphQL](https://github.com/prisma/prisma-examples/tree/latest/typescript/graphql-nestjs) in the [`prisma-examples`](https://github.com/prisma/prisma-examples/) repo.

#### Getting started[#](/recipes/prisma#getting-started)

In this recipe, you'll learn how to get started with NestJS and Prisma from scratch. You are going to build a sample NestJS application with a REST API that can read and write data in a database.

For the purpose of this guide, you'll use a [SQLite](https://sqlite.org/) database to save the overhead of setting up a database server. Note that you can still follow this guide, even if you're using PostgreSQL or MySQL – you'll get extra instructions for using these databases at the right places.

> **Note** If you already have an existing project and consider migrating to Prisma, you can follow the guide for [adding Prisma to an existing project](https://www.prisma.io/docs/getting-started/setup-prisma/add-to-existing-project-typescript-postgres). If you are migrating from TypeORM, you can read the guide [Migrating from TypeORM to Prisma](https://www.prisma.io/docs/guides/migrate-to-prisma/migrate-from-typeorm).

#### Create your NestJS project[#](/recipes/prisma#create-your-nestjs-project)

To get started, install the NestJS CLI and create your app skeleton with the following commands:

```bash

$ npm install -g @nestjs/cli
$ nest new hello-prisma
```

See the [First steps](https://docs.nestjs.com/first-steps) page to learn more about the project files created by this command. Note also that you can now run `npm start` to start your application. The REST API running at `http://localhost:3000/` currently serves a single route that's implemented in `src/app.controller.ts`. Over the course of this guide, you'll implement additional routes to store and retrieve data about *users* and *posts*.

#### Set up Prisma[#](/recipes/prisma#set-up-prisma)

Start by installing the Prisma CLI as a development dependency in your project:

```bash

$ cd hello-prisma
$ npm install prisma --save-dev
```

In the following steps, we'll be utilizing the [Prisma CLI](https://www.prisma.io/docs/reference/tools-and-interfaces/prisma-cli). As a best practice, it's recommended to invoke the CLI locally by prefixing it with `npx`:

```bash

$ npx prisma
```

Expand if you're using Yarn

If you're using Yarn, then you can install the Prisma CLI as follows:

```bash

$ yarn add prisma --dev
```

Once installed, you can invoke it by prefixing it with `yarn`:

```bash

$ yarn prisma
```

Now create your initial Prisma setup using the `init` command of the Prisma CLI:

```bash

$ npx prisma init
```

This command creates a new `prisma` directory with the following contents:

* `schema.prisma`: Specifies your database connection and contains the database schema
* `.env`: A [dotenv](https://github.com/motdotla/dotenv) file, typically used to store your database credentials in a group of environment variables

#### Set the database connection[#](/recipes/prisma#set-the-database-connection)

Your database connection is configured in the `datasource` block in your `schema.prisma` file. By default it's set to `postgresql`, but since you're using a SQLite database in this guide you need to adjust the `provider` field of the `datasource` block to `sqlite`:

```groovy

datasource db {
  provider = "sqlite"
  url      = env("DATABASE_URL")
}

generator client {
  provider = "prisma-client-js"
}
```

Now, open up `.env` and adjust the `DATABASE_URL` environment variable to look as follows:

```bash

DATABASE_URL="file:./dev.db"
```

SQLite databases are simple files; no server is required to use a SQLite database. So instead of configuring a connection URL with a *host* and *port*, you can just point it to a local file which in this case is called `dev.db`. This file will be created in the next step.

Expand if you're using PostgreSQL or MySQL

With PostgreSQL and MySQL, you need to configure the connection URL to point to the *database server*. You can learn more about the required connection URL format [here](https://www.prisma.io/docs/reference/database-reference/connection-urls).

**PostgreSQL**

If you're using PostgreSQL, you have to adjust the `schema.prisma` and `.env` files as follows:

**`schema.prisma`**

```groovy

datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}

generator client {
  provider = "prisma-client-js"
}
```

**`.env`**

```bash

DATABASE_URL="postgresql://USER:PASSWORD@HOST:PORT/DATABASE?schema=SCHEMA"
```

Replace the placeholders spelled in all uppercase letters with your database credentials. Note that if you're unsure what to provide for the `SCHEMA` placeholder, it's most likely the default value `public`:

```bash

DATABASE_URL="postgresql://USER:PASSWORD@HOST:PORT/DATABASE?schema=public"
```

If you want to learn how to set up a PostgreSQL database, you can follow this guide on [setting up a free PostgreSQL database on Heroku](https://dev.to/prisma/how-to-setup-a-free-postgresql-database-on-heroku-1dc1).

**MySQL**

If you're using MySQL, you have to adjust the `schema.prisma` and `.env` files as follows:

**`schema.prisma`**

```groovy

datasource db {
  provider = "mysql"
  url      = env("DATABASE_URL")
}

generator client {
  provider = "prisma-client-js"
}
```

**`.env`**

```bash

DATABASE_URL="mysql://USER:PASSWORD@HOST:PORT/DATABASE"
```

Replace the placeholders spelled in all uppercase letters with your database credentials.

#### Create two database tables with Prisma Migrate[#](/recipes/prisma#create-two-database-tables-with-prisma-migrate)

In this section, you'll create two new tables in your database using [Prisma Migrate](https://www.prisma.io/docs/concepts/components/prisma-migrate). Prisma Migrate generates SQL migration files for your declarative data model definition in the Prisma schema. These migration files are fully customizable so that you can configure any additional features of the underlying database or include additional commands, e.g. for seeding.

Add the following two models to your `schema.prisma` file:

```groovy

model User {
  id    Int     @default(autoincrement()) @id
  email String  @unique
  name  String?
  posts Post[]
}

model Post {
  id        Int      @default(autoincrement()) @id
  title     String
  content   String?
  published Boolean? @default(false)
  author    User?    @relation(fields: [authorId], references: [id])
  authorId  Int?
}
```

With your Prisma models in place, you can generate your SQL migration files and run them against the database. Run the following commands in your terminal:

```bash

$ npx prisma migrate dev --name init
```

This `prisma migrate dev` command generates SQL files and directly runs them against the database. In this case, the following migration files was created in the existing `prisma` directory:

```bash

$ tree prisma
prisma
├── dev.db
├── migrations
│   └── 20201207100915_init
│       └── migration.sql
└── schema.prisma
```

Expand to view the generated SQL statements

The following tables were created in your SQLite database:

```sql

-- CreateTable
CREATE TABLE "User" (
    "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
    "email" TEXT NOT NULL,
    "name" TEXT
);

-- CreateTable
CREATE TABLE "Post" (
    "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
    "title" TEXT NOT NULL,
    "content" TEXT,
    "published" BOOLEAN DEFAULT false,
    "authorId" INTEGER,

    FOREIGN KEY ("authorId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE
);

-- CreateIndex
CREATE UNIQUE INDEX "User.email_unique" ON "User"("email");
```

#### Install and generate Prisma Client[#](/recipes/prisma#install-and-generate-prisma-client)

Prisma Client is a type-safe database client that's *generated* from your Prisma model definition. Because of this approach, Prisma Client can expose [CRUD](https://www.prisma.io/docs/concepts/components/prisma-client/crud) operations that are *tailored* specifically to your models.

To install Prisma Client in your project, run the following command in your terminal:

```bash

$ npm install @prisma/client
```

Note that during installation, Prisma automatically invokes the `prisma generate` command for you. In the future, you need to run this command after *every* change to your Prisma models to update your generated Prisma Client.

> **Note** The `prisma generate` command reads your Prisma schema and updates the generated Prisma Client library inside `node_modules/@prisma/client`.

#### Use Prisma Client in your NestJS services[#](/recipes/prisma#use-prisma-client-in-your-nestjs-services)

You're now able to send database queries with Prisma Client. If you want to learn more about building queries with Prisma Client, check out the [API documentation](https://www.prisma.io/docs/reference/tools-and-interfaces/prisma-client/crud).

When setting up your NestJS application, you'll want to abstract away the Prisma Client API for database queries within a service. To get started, you can create a new `PrismaService` that takes care of instantiating `PrismaClient` and connecting to your database.

Inside the `src` directory, create a new file called `prisma.service.ts` and add the following code to it:

```typescript

import { INestApplication, Injectable, OnModuleInit } from '@nestjs/common';
import { PrismaClient } from '@prisma/client';

@Injectable()
export class PrismaService extends PrismaClient implements OnModuleInit {
  async onModuleInit() {
    await this.$connect();
  }

  async enableShutdownHooks(app: INestApplication) {
    this.$on('beforeExit', async () => {
      await app.close();
    });
  }
}
```

> **Note** The `onModuleInit` is optional — if you leave it out, Prisma will connect lazily on its first call to the database. We don't bother with `onModuleDestroy`, since Prisma has its own shutdown hooks where it will destroy the connection. For more info on `enableShutdownHooks`, please see [Issues with `enableShutdownHooks`](recipes/prisma#issues-with-enableshutdownhooks)

Next, you can write services that you can use to make database calls for the `User` and `Post` models from your Prisma schema.

Still inside the `src` directory, create a new file called `user.service.ts` and add the following code to it:

```typescript

import { Injectable } from '@nestjs/common';
import { PrismaService } from './prisma.service';
import { User, Prisma } from '@prisma/client';

@Injectable()
export class UserService {
  constructor(private prisma: PrismaService) {}

  async user(
    userWhereUniqueInput: Prisma.UserWhereUniqueInput,
  ): Promise<User | null> {
    return this.prisma.user.findUnique({
      where: userWhereUniqueInput,
    });
  }

  async users(params: {
    skip?: number;
    take?: number;
    cursor?: Prisma.UserWhereUniqueInput;
    where?: Prisma.UserWhereInput;
    orderBy?: Prisma.UserOrderByWithRelationInput;
  }): Promise<User[]> {
    const { skip, take, cursor, where, orderBy } = params;
    return this.prisma.user.findMany({
      skip,
      take,
      cursor,
      where,
      orderBy,
    });
  }

  async createUser(data: Prisma.UserCreateInput): Promise<User> {
    return this.prisma.user.create({
      data,
    });
  }

  async updateUser(params: {
    where: Prisma.UserWhereUniqueInput;
    data: Prisma.UserUpdateInput;
  }): Promise<User> {
    const { where, data } = params;
    return this.prisma.user.update({
      data,
      where,
    });
  }

  async deleteUser(where: Prisma.UserWhereUniqueInput): Promise<User> {
    return this.prisma.user.delete({
      where,
    });
  }
}
```

Notice how you're using Prisma Client's generated types to ensure that the methods that are exposed by your service are properly typed. You therefore save the boilerplate of typing your models and creating additional interface or DTO files.

Now do the same for the `Post` model.

Still inside the `src` directory, create a new file called `post.service.ts` and add the following code to it:

```typescript

import { Injectable } from '@nestjs/common';
import { PrismaService } from './prisma.service';
import { Post, Prisma } from '@prisma/client';

@Injectable()
export class PostService {
  constructor(private prisma: PrismaService) {}

  async post(
    postWhereUniqueInput: Prisma.PostWhereUniqueInput,
  ): Promise<Post | null> {
    return this.prisma.post.findUnique({
      where: postWhereUniqueInput,
    });
  }

  async posts(params: {
    skip?: number;
    take?: number;
    cursor?: Prisma.PostWhereUniqueInput;
    where?: Prisma.PostWhereInput;
    orderBy?: Prisma.PostOrderByWithRelationInput;
  }): Promise<Post[]> {
    const { skip, take, cursor, where, orderBy } = params;
    return this.prisma.post.findMany({
      skip,
      take,
      cursor,
      where,
      orderBy,
    });
  }

  async createPost(data: Prisma.PostCreateInput): Promise<Post> {
    return this.prisma.post.create({
      data,
    });
  }

  async updatePost(params: {
    where: Prisma.PostWhereUniqueInput;
    data: Prisma.PostUpdateInput;
  }): Promise<Post> {
    const { data, where } = params;
    return this.prisma.post.update({
      data,
      where,
    });
  }

  async deletePost(where: Prisma.PostWhereUniqueInput): Promise<Post> {
    return this.prisma.post.delete({
      where,
    });
  }
}
```

Your `UserService` and `PostService` currently wrap the CRUD queries that are available in Prisma Client. In a real world application, the service would also be the place to add business logic to your application. For example, you could have a method called `updatePassword` inside the `UserService` that would be responsible for updating the password of a user.

##### Implement your REST API routes in the main app controller

Finally, you'll use the services you created in the previous sections to implement the different routes of your app. For the purpose of this guide, you'll put all your routes into the already existing `AppController` class.

Replace the contents of the `app.controller.ts` file with the following code:

```typescript

import {
  Controller,
  Get,
  Param,
  Post,
  Body,
  Put,
  Delete,
} from '@nestjs/common';
import { UserService } from './user.service';
import { PostService } from './post.service';
import { User as UserModel, Post as PostModel } from '@prisma/client';

@Controller()
export class AppController {
  constructor(
    private readonly userService: UserService,
    private readonly postService: PostService,
  ) {}

  @Get('post/:id')
  async getPostById(@Param('id') id: string): Promise<PostModel> {
    return this.postService.post({ id: Number(id) });
  }

  @Get('feed')
  async getPublishedPosts(): Promise<PostModel[]> {
    return this.postService.posts({
      where: { published: true },
    });
  }

  @Get('filtered-posts/:searchString')
  async getFilteredPosts(
    @Param('searchString') searchString: string,
  ): Promise<PostModel[]> {
    return this.postService.posts({
      where: {
        OR: [
          {
            title: { contains: searchString },
          },
          {
            content: { contains: searchString },
          },
        ],
      },
    });
  }

  @Post('post')
  async createDraft(
    @Body() postData: { title: string; content?: string; authorEmail: string },
  ): Promise<PostModel> {
    const { title, content, authorEmail } = postData;
    return this.postService.createPost({
      title,
      content,
      author: {
        connect: { email: authorEmail },
      },
    });
  }

  @Post('user')
  async signupUser(
    @Body() userData: { name?: string; email: string },
  ): Promise<UserModel> {
    return this.userService.createUser(userData);
  }

  @Put('publish/:id')
  async publishPost(@Param('id') id: string): Promise<PostModel> {
    return this.postService.updatePost({
      where: { id: Number(id) },
      data: { published: true },
    });
  }

  @Delete('post/:id')
  async deletePost(@Param('id') id: string): Promise<PostModel> {
    return this.postService.deletePost({ id: Number(id) });
  }
}
```

    * `title: String` (required): The title of the post
    * `content: String` (optional): The content of the post
    * `authorEmail: String` (required): The email of the user that creates the post

* `/user`: Create a new user

  * Body:

    * `email: String` (required): The email address of the user
    * `name: String` (optional): The name of the user

###### `PUT`

* `/publish/:id`: Publish a post by its `id`

###### `DELETE`

* `/post/:id`: Delete a post by its `id`

#### Issues with `enableShutdownHooks`[#](/recipes/prisma#issues-with-enableshutdownhooks)

Prisma interferes with NestJS `enableShutdownHooks`. Prisma listens for shutdown signals and will call `process.exit()` before your application shutdown hooks fire. To deal with this, you would need to add a listener for Prisma `beforeExit` event.

```typescript

// main.ts
...
import { PrismaService } from './services/prisma/prisma.service';
...
async function bootstrap() {
  ...
  const prismaService = app.get(PrismaService);
  await prismaService.enableShutdownHooks(app)
  ...
}
bootstrap()
```

----
url: https://docs.nestjs.com/cli/overview
----

[Skip to content](#content)

On this page

* [Overview](https://docs.nestjs.com/cli/overview#overview)
* [Installation](https://docs.nestjs.com/cli/overview#installation)
* [Basic workflow](https://docs.nestjs.com/cli/overview#basic-workflow)
* [Project structure](https://docs.nestjs.com/cli/overview#project-structure)
* [CLI command syntax](https://docs.nestjs.com/cli/overview#cli-command-syntax)
* [Command overview](https://docs.nestjs.com/cli/overview#command-overview)
* [Requirements](https://docs.nestjs.com/cli/overview#requirements)

### Overview

The [Nest CLI](https://github.com/nestjs/nest-cli) is a command-line tool that helps you initialize, develop, and maintain Nest applications. It scaffolds projects, serves them in development mode, and builds and bundles them for production. It also embodies best-practice architectural patterns to encourage well-structured applications.

#### Installation[#](/cli/overview#installation)

**Note**: This guide uses [npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm) to install packages, including the Nest CLI. You can use another package manager if you prefer. npm offers several ways to control how your OS command line resolves the `nest` binary. Here, we install it globally with the `-g` option. This is convenient, and it is the approach the rest of the documentation assumes. Keep in mind that when you install **any** npm package globally, you are responsible for making sure you run the correct version. It also means that all your projects run the **same** version of the CLI. A reasonable alternative is the [npx](https://github.com/npm/cli/blob/latest/docs/lib/content/commands/npx.md) program built into the npm CLI (other package managers have similar features), which ensures that you run a **managed version** of the Nest CLI. For more information, consult the [npx documentation](https://github.com/npm/cli/blob/latest/docs/lib/content/commands/npx.md) or your DevOps team.

Install the CLI globally using the `npm install -g` command (see the **Note** above for details about global installs).

```bash

$ npm install -g @nestjs/cli
```

> **Hint** Alternatively, run `npx @nestjs/cli@latest` to use the CLI without installing it globally.

#### Basic workflow[#](/cli/overview#basic-workflow)

Once the CLI is installed, you can invoke its commands from your OS command line through the `nest` executable. To list the available commands, run:

```bash

$ nest --help
```

To get detailed help on an individual command, pass `--help` to it. Substitute any command, such as `new` or `add`, for `generate` in the example below:

```bash

$ nest generate --help
```

To create, build, and run a new Nest project in development mode, go to the folder that should contain your new project and run the following commands:

```bash

$ nest new my-nest-project
$ cd my-nest-project
$ npm run start:dev
```

The `new` command prompts you to choose a module system: ESM (the default), which uses Vitest for testing, or CommonJS, which uses Jest. Both use oxlint for linting. See [`nest new`](/cli/usages#nest-new) for the other prompts and options.

In your browser, open <http://localhost:3000> to see the new application running. The application recompiles and reloads automatically whenever you change a source file.

> **Hint** For faster builds, we recommend the [SWC builder](/recipes/swc), which is about 10x faster than the default TypeScript compiler.

#### Project structure[#](/cli/overview#project-structure)

When you run `nest new`, Nest creates a new folder and populates it with a boilerplate application. You can keep working in this default structure and add new components as described throughout this documentation. We refer to the project structure generated by `nest new` as **standard mode**. Nest also supports an alternate structure for managing multiple projects and libraries, called **monorepo mode**.

The two modes differ only in how the **build** process works (monorepo mode simplifies build complexities that can arise in monorepo-style project structures) and in built-in [library](/cli/libraries) support. All other Nest features, and this documentation, apply equally to both. You can switch from standard mode to monorepo mode at any time, so you can safely defer this decision while you're still learning Nest.

You can use either mode to manage multiple projects. The following table summarizes the differences:

| Feature                                | Standard Mode                                                      | Monorepo Mode                                              |
| -------------------------------------- | ------------------------------------------------------------------ | ---------------------------------------------------------- |
| Multiple projects                      | Separate file system structure                                     | Single file system structure                               |
| `node_modules` & `package.json`        | Separate instances                                                 | Shared across monorepo                                     |
| Default compiler                       | `tsc`                                                              | rspack                                                     |
| Compiler settings                      | Specified separately                                               | Monorepo defaults that can be overridden per project       |
| Lint and formatter config files        | Specified separately                                               | Shared across monorepo                                     |
| `nest build` and `nest start` commands | Target defaults automatically to the (only) project in the context | Target defaults to the **default project** in the monorepo |
| Libraries                              | Managed manually, usually via npm packaging                        | Built-in support, including path management and bundling   |

See [Workspaces](/cli/monorepo) and [Libraries](/cli/libraries) for more detail to help you decide which mode suits you best.

```bash

nest commandOrAlias requiredArg [optionalArg] [options]
```

For example:

```bash

$ nest new my-nest-project --dry-run
```

Here, `new` is the *commandOrAlias*; its alias is `n`. `my-nest-project` is the *requiredArg*. If you don't supply a *requiredArg* on the command line, `nest` prompts for it. The `--dry-run` option has the short form `-d`. The following command is therefore equivalent to the one above:

```bash

$ nest n my-nest-project -d
```

Most commands, and some options, have aliases. Run `nest new --help` to see them.

#### Command overview[#](/cli/overview#command-overview)

Run `nest <command> --help` for any of the following commands to see its options. See the [CLI command reference](/cli/usages) for a detailed description of each command.

| Command    | Alias    | Description                                                                                    |
| ---------- | -------- | ---------------------------------------------------------------------------------------------- |
| `new`      | `n`      | Scaffolds a new *standard mode* application with all the boilerplate files it needs to run.    |
| `generate` | `g`      | Generates and/or modifies files based on a schematic.                                          |
| `build`    |          | Compiles an application or workspace into an output folder.                                    |
| `start`    |          | Compiles and runs an application (or the default project in a workspace).                      |
| `add`      |          | Imports a library that has been packaged as a **nest library**, running its install schematic. |
| `upgrade`  | `update` | Upgrades an existing project to the latest NestJS major version.                               |
| `deploy`   |          | Deploys your application to the cloud, powered by [Mau](https://mau.nestjs.com/).              |
| `info`     | `i`      | Displays information about installed Nest packages and other useful system information.        |

#### Requirements[#](/cli/overview#requirements)

The CLI binary itself runs on **Node.js v20.11 or later**, but the schematics behind `nest new`, `nest generate`, and `nest upgrade` (`@nestjs/schematics`) require **Node.js v22.22.3+, v24.15+, or v26+**. Running a Nest application has a lower floor (see [Node.js requirements](/migration-guide#nodejs-requirements) in the migration guide). If you generate code on the machine you develop on, use the latest active LTS release.

The Nest CLI also requires a Node.js binary built with [internationalization support](https://nodejs.org/api/intl.html) (ICU), such as the official binaries from the [Node.js download page](https://nodejs.org/en/download). If you encounter ICU-related errors, check that your binary meets this requirement:

```bash

node -p process.versions.icu
```

If the command prints `undefined`, your Node.js binary has no internationalization support.

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/cli/overview.md)

----
url: https://docs.nestjs.com/v10/fundamentals/execution-context
----

* [Execution context](https://docs.nestjs.com/v10/fundamentals/execution-context#execution-context)
* [ArgumentsHost class](https://docs.nestjs.com/v10/fundamentals/execution-context#argumentshost-class)
* [Current application context](https://docs.nestjs.com/v10/fundamentals/execution-context#current-application-context)
* [Host handler arguments](https://docs.nestjs.com/v10/fundamentals/execution-context#host-handler-arguments)
* [ExecutionContext class](https://docs.nestjs.com/v10/fundamentals/execution-context#executioncontext-class)
* [Reflection and metadata](https://docs.nestjs.com/v10/fundamentals/execution-context#reflection-and-metadata)
* [Low-level approach](https://docs.nestjs.com/v10/fundamentals/execution-context#low-level-approach)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/fundamentals/execution-context.md "Suggest Edits")

### Execution context

Nest provides several utility classes that help make it easy to write applications that function across multiple application contexts (e.g., Nest HTTP server-based, microservices and WebSockets application contexts). These utilities provide information about the current execution context which can be used to build generic [guards](/v10/guards), [filters](/v10/exception-filters), and [interceptors](/v10/interceptors) that can work across a broad set of controllers, methods, and execution contexts.

We cover two such classes in this chapter: `ArgumentsHost` and `ExecutionContext`.

#### ArgumentsHost class[#](/fundamentals/execution-context#argumentshost-class)

The `ArgumentsHost` class provides methods for retrieving the arguments being passed to a handler. It allows choosing the appropriate context (e.g., HTTP, RPC (microservice), or WebSockets) to retrieve the arguments from. The framework provides an instance of `ArgumentsHost`, typically referenced as a `host` parameter, in places where you may want to access it. For example, the `catch()` method of an [exception filter](https://docs.nestjs.com/exception-filters#arguments-host) is called with an `ArgumentsHost`instance.

`ArgumentsHost` simply acts as an abstraction over a handler's arguments. For example, for HTTP server applications (when `@nestjs/platform-express` is being used), the `host` object encapsulates Express's `[request, response, next]` array, where `request` is the request object, `response` is the response object, and `next` is a function that controls the application's request-response cycle. On the other hand, for [GraphQL](/v10/graphql/quick-start) applications, the `host` object contains the `[root, args, context, info]` array.

#### Current application context[#](/fundamentals/execution-context#current-application-context)

When building generic [guards](/v10/guards), [filters](/v10/exception-filters), and [interceptors](/v10/interceptors) which are meant to run across multiple application contexts, we need a way to determine the type of application that our method is currently running in. Do this with the `getType()` method of `ArgumentsHost`:

```typescript

if (host.getType() === 'http') {
  // do something that is only important in the context of regular HTTP requests (REST)
} else if (host.getType() === 'rpc') {
  // do something that is only important in the context of Microservice requests
} else if (host.getType<GqlContextType>() === 'graphql') {
  // do something that is only important in the context of GraphQL requests
}
```

> **Hint** The `GqlContextType` is imported from the `@nestjs/graphql` package.

With the application type available, we can write more generic components, as shown below.

#### Host handler arguments[#](/fundamentals/execution-context#host-handler-arguments)

To retrieve the array of arguments being passed to the handler, one approach is to use the host object's `getArgs()` method.

```typescript

const [req, res, next] = host.getArgs();
```

You can pluck a particular argument by index using the `getArgByIndex()` method:

```typescript

const request = host.getArgByIndex(0);
const response = host.getArgByIndex(1);
```

In these examples we retrieved the request and response objects by index, which is not typically recommended as it couples the application to a particular execution context. Instead, you can make your code more robust and reusable by using one of the `host` object's utility methods to switch to the appropriate application context for your application. The context switch utility methods are shown below.

```typescript

/**
 * Switch context to RPC.
 */
switchToRpc(): RpcArgumentsHost;
/**
 * Switch context to HTTP.
 */
switchToHttp(): HttpArgumentsHost;
/**
 * Switch context to WebSockets.
 */
switchToWs(): WsArgumentsHost;
```

Let's rewrite the previous example using the `switchToHttp()` method. The `host.switchToHttp()` helper call returns an `HttpArgumentsHost` object that is appropriate for the HTTP application context. The `HttpArgumentsHost` object has two useful methods we can use to extract the desired objects. We also use the Express type assertions in this case to return native Express typed objects:

```typescript

const ctx = host.switchToHttp();
const request = ctx.getRequest<Request>();
const response = ctx.getResponse<Response>();
```

Similarly `WsArgumentsHost` and `RpcArgumentsHost` have methods to return appropriate objects in the microservices and WebSockets contexts. Here are the methods for `WsArgumentsHost`:

```typescript

export interface WsArgumentsHost {
  /**
   * Returns the data object.
   */
  getData<T>(): T;
  /**
   * Returns the client object.
   */
  getClient<T>(): T;
}
```

Following are the methods for `RpcArgumentsHost`:

```typescript

export interface RpcArgumentsHost {
  /**
   * Returns the data object.
   */
  getData<T>(): T;

  /**
   * Returns the context object.
   */
  getContext<T>(): T;
}
```

#### ExecutionContext class[#](/fundamentals/execution-context#executioncontext-class)

`ExecutionContext` extends `ArgumentsHost`, providing additional details about the current execution process. Like `ArgumentsHost`, Nest provides an instance of `ExecutionContext` in places you may need it, such as in the `canActivate()` method of a [guard](https://docs.nestjs.com/guards#execution-context) and the `intercept()` method of an [interceptor](https://docs.nestjs.com/interceptors#execution-context). It provides the following methods:

```typescript

export interface ExecutionContext extends ArgumentsHost {
  /**
   * Returns the type of the controller class which the current handler belongs to.
   */
  getClass<T>(): Type<T>;
  /**
   * Returns a reference to the handler (method) that will be invoked next in the
   * request pipeline.
   */
  getHandler(): Function;
}
```

The `getHandler()` method returns a reference to the handler about to be invoked. The `getClass()` method returns the type of the `Controller` class which this particular handler belongs to. For example, in an HTTP context, if the currently processed request is a `POST` request, bound to the `create()` method on the `CatsController`, `getHandler()` returns a reference to the `create()` method and `getClass()` returns the `CatsController`**class** (not instance).

```typescript

const methodKey = ctx.getHandler().name; // "create"
const className = ctx.getClass().name; // "CatsController"
```

The ability to access references to both the current class and handler method provides great flexibility. Most importantly, it gives us the opportunity to access the metadata set through either decorators created via `Reflector#createDecorator` or the built-in `@SetMetadata()` decorator from within guards or interceptors. We cover this use case below.

Nest provides the ability to attach **custom metadata** to route handlers through decorators created via `Reflector#createDecorator` method, and the built-in `@SetMetadata()` decorator. In this section, let's compare the two approaches and see how to access the metadata from within a guard or interceptor.

To create strongly-typed decorators using `Reflector#createDecorator`, we need to specify the type argument. For example, let's create a `Roles` decorator that takes an array of strings as an argument.

roles.decorator.ts

JS TS

```ts

import { Reflector } from '@nestjs/core';

export const Roles = Reflector.createDecorator<string[]>();
```

The `Roles` decorator here is a function that takes a single argument of type `string[]`.

Now, to use this decorator, we simply annotate the handler with it:

cats.controller.ts

JS TS

```typescript

@Post()
@Roles(['admin'])
async create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

```typescript

@Post()
@Roles(['admin'])
@Bind(Body())
async create(createCatDto) {
  this.catsService.create(createCatDto);
}
```

Here we've attached the `Roles` decorator metadata to the `create()` method, indicating that only users with the `admin` role should be allowed to access this route.

To access the route's role(s) (custom metadata), we'll use the `Reflector` helper class again. `Reflector` can be injected into a class in the normal way:

roles.guard.ts

JS TS

```typescript

@Injectable()
export class RolesGuard {
  constructor(private reflector: Reflector) {}
}
```

```typescript

@Injectable()
@Dependencies(Reflector)
export class CatsService {
  constructor(reflector) {
    this.reflector = reflector;
  }
}
```

> **Hint** The `Reflector` class is imported from the `@nestjs/core` package.

Now, to read the handler metadata, use the `get()` method:

```typescript

const roles = this.reflector.get(Roles, context.getHandler());
```

The `Reflector#get` method allows us to easily access the metadata by passing in two arguments: a decorator reference and a **context** (decorator target) to retrieve the metadata from. In this example, the specified **decorator** is `Roles` (refer back to the `roles.decorator.ts` file above). The context is provided by the call to `context.getHandler()`, which results in extracting the metadata for the currently processed route handler. Remember, `getHandler()` gives us a **reference** to the route handler function.

Alternatively, we may organize our controller by applying metadata at the controller level, applying to all routes in the controller class.

cats.controller.ts

JS TS

```typescript

@Roles(['admin'])
@Controller('cats')
export class CatsController {}
```

```typescript

@Roles(['admin'])
@Controller('cats')
export class CatsController {}
```

In this case, to extract controller metadata, we pass `context.getClass()` as the second argument (to provide the controller class as the context for metadata extraction) instead of `context.getHandler()`:

roles.guard.ts

JS TS

```typescript

const roles = this.reflector.get(Roles, context.getClass());
```

Given the ability to provide metadata at multiple levels, you may need to extract and merge metadata from several contexts. The `Reflector` class provides two utility methods used to help with this. These methods extract **both** controller and method metadata at once, and combine them in different ways.

Consider the following scenario, where you've supplied `Roles` metadata at both levels.

cats.controller.ts

JS TS

```typescript

@Roles(['user'])
@Controller('cats')
export class CatsController {
  @Post()
  @Roles(['admin'])
  async create(@Body() createCatDto: CreateCatDto) {
    this.catsService.create(createCatDto);
  }
}
```

```typescript

@Roles(['user'])
@Controller('cats')
export class CatsController {}
  @Post()
  @Roles(['admin'])
  @Bind(Body())
  async create(createCatDto) {
    this.catsService.create(createCatDto);
  }
}
```

If your intent is to specify `'user'` as the default role, and override it selectively for certain methods, you would probably use the `getAllAndOverride()` method.

```typescript

const roles = this.reflector.getAllAndOverride(Roles, [context.getHandler(), context.getClass()]);
```

A guard with this code, running in the context of the `create()` method, with the above metadata, would result in `roles` containing `['admin']`.

To get metadata for both and merge it (this method merges both arrays and objects), use the `getAllAndMerge()` method:

```typescript

const roles = this.reflector.getAllAndMerge(Roles, [context.getHandler(), context.getClass()]);
```

This would result in `roles` containing `['user', 'admin']`.

For both of these merge methods, you pass the metadata key as the first argument, and an array of metadata target contexts (i.e., calls to the `getHandler()` and/or `getClass()` methods) as the second argument.

#### Low-level approach[#](/fundamentals/execution-context#low-level-approach)

As mentioned earlier, instead of using `Reflector#createDecorator`, you can also use the built-in `@SetMetadata()` decorator to attach metadata to a handler.

cats.controller.ts

JS TS

```typescript

@Post()
@SetMetadata('roles', ['admin'])
async create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

```typescript

@Post()
@SetMetadata('roles', ['admin'])
@Bind(Body())
async create(createCatDto) {
  this.catsService.create(createCatDto);
}
```

> **Hint** The `@SetMetadata()` decorator is imported from the `@nestjs/common` package.

With the construction above, we attached the `roles` metadata (`roles` is a metadata key and `['admin']` is the associated value) to the `create()` method. While this works, it's not good practice to use `@SetMetadata()` directly in your routes. Instead, you can create your own decorators, as shown below:

roles.decorator.ts

JS TS

```typescript

import { SetMetadata } from '@nestjs/common';

export const Roles = (...roles: string[]) => SetMetadata('roles', roles);
```

```typescript

import { SetMetadata } from '@nestjs/common';

export const Roles = (...roles) => SetMetadata('roles', roles);
```

This approach is much cleaner and more readable, and somewhat resembles the `Reflector#createDecorator` approach. The difference is that with `@SetMetadata` you have more control over the metadata key and value, and also can create decorators that take more than one argument.

Now that we have a custom `@Roles()` decorator, we can use it to decorate the `create()` method.

cats.controller.ts

JS TS

```typescript

@Post()
@Roles('admin')
async create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

```typescript

@Post()
@Roles('admin')
@Bind(Body())
async create(createCatDto) {
  this.catsService.create(createCatDto);
}
```

To access the route's role(s) (custom metadata), we'll use the `Reflector` helper class again:

roles.guard.ts

JS TS

```typescript

@Injectable()
export class RolesGuard {
  constructor(private reflector: Reflector) {}
}
```

```typescript

@Injectable()
@Dependencies(Reflector)
export class CatsService {
  constructor(reflector) {
    this.reflector = reflector;
  }
}
```

> **Hint** The `Reflector` class is imported from the `@nestjs/core` package.

Now, to read the handler metadata, use the `get()` method.

```typescript

const roles = this.reflector.get<string[]>('roles', context.getHandler());
```

Here instead of passing a decorator reference, we pass the metadata **key** as the first argument (which in our case is `'roles'`). Everything else remains the same as in the `Reflector#createDecorator` example.

----
url: https://docs.nestjs.com/v10/faq/multiple-servers
----

* [HTTPS](https://docs.nestjs.com/v10/faq/multiple-servers#https)
* [Multiple simultaneous servers](https://docs.nestjs.com/v10/faq/multiple-servers#multiple-simultaneous-servers)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/faq/multiple-servers.md "Suggest Edits")

### HTTPS

To create an application that uses the HTTPS protocol, set the `httpsOptions` property in the options object passed to the `create()` method of the `NestFactory` class:

```typescript

const httpsOptions = {
  key: fs.readFileSync('./secrets/private-key.pem'),
  cert: fs.readFileSync('./secrets/public-certificate.pem'),
};
const app = await NestFactory.create(AppModule, {
  httpsOptions,
});
await app.listen(process.env.PORT ?? 3000);
```

If you use the `FastifyAdapter`, create the application as follows:

```typescript

const app = await NestFactory.create<NestFastifyApplication>(
  AppModule,
  new FastifyAdapter({ https: httpsOptions }),
);
```

#### Multiple simultaneous servers[#](/faq/multiple-servers#multiple-simultaneous-servers)

The following recipe shows how to instantiate a Nest application that listens on multiple ports (for example, on a non-HTTPS port and an HTTPS port) simultaneously.

```typescript

const httpsOptions = {
  key: fs.readFileSync('./secrets/private-key.pem'),
  cert: fs.readFileSync('./secrets/public-certificate.pem'),
};

const server = express();
const app = await NestFactory.create(AppModule, new ExpressAdapter(server));
await app.init();

const httpServer = http.createServer(server).listen(3000);
const httpsServer = https.createServer(httpsOptions, server).listen(443);
```

Because we called `http.createServer` / `https.createServer` ourselves, NestJS doesn't close them when calling `app.close` / on termination signal. We need to do this ourselves:

```typescript

@Injectable()
export class ShutdownObserver implements OnApplicationShutdown {
  private httpServers: http.Server[] = [];

  public addHttpServer(server: http.Server): void {
    this.httpServers.push(server);
  }

  public async onApplicationShutdown(): Promise<void> {
    await Promise.all(
      this.httpServers.map(
        (server) =>
          new Promise((resolve, reject) => {
            server.close((error) => {
              if (error) {
                reject(error);
              } else {
                resolve(null);
              }
            });
          }),
      ),
    );
  }
}

const shutdownObserver = app.get(ShutdownObserver);
shutdownObserver.addHttpServer(httpServer);
shutdownObserver.addHttpServer(httpsServer);
```

> **Hint** The `ExpressAdapter` is imported from the `@nestjs/platform-express` package. The `http` and `https` packages are native Node.js packages.

> **Warning** This recipe does not work with [GraphQL Subscriptions](/v10/graphql/subscriptions).

----
url: https://docs.nestjs.com/v7/microservices/rabbitmq
----

* [RabbitMQ](https://docs.nestjs.com/v7/microservices/rabbitmq#rabbitmq)
* [Installation](https://docs.nestjs.com/v7/microservices/rabbitmq#installation)
* [Overview](https://docs.nestjs.com/v7/microservices/rabbitmq#overview)
* [Options](https://docs.nestjs.com/v7/microservices/rabbitmq#options)
* [Client](https://docs.nestjs.com/v7/microservices/rabbitmq#client)
* [Context](https://docs.nestjs.com/v7/microservices/rabbitmq#context)
* [Message acknowledgement](https://docs.nestjs.com/v7/microservices/rabbitmq#message-acknowledgement)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/microservices/rabbitmq.md "Suggest Edits")

### RabbitMQ

[RabbitMQ](https://www.rabbitmq.com/) is an open-source and lightweight message broker which supports multiple messaging protocols. It can be deployed in distributed and federated configurations to meet high-scale, high-availability requirements. In addition, it's the most widely deployed message broker, used worldwide at small startups and large enterprises.

#### Installation[#](/microservices/rabbitmq#installation)

To start building RabbitMQ-based microservices, first install the required packages:

```bash

$ npm i --save amqplib amqp-connection-manager
```

#### Overview[#](/microservices/rabbitmq#overview)

To use the RabbitMQ transporter, pass the following options object to the `createMicroservice()` method:

main.ts

JS TS

```typescript

const app = await NestFactory.createMicroservice<MicroserviceOptions>(AppModule, {
  transport: Transport.RMQ,
  options: {
    urls: ['amqp://localhost:5672'],
    queue: 'cats_queue',
    queueOptions: {
      durable: false
    },
  },
});
```

```typescript

const app = await NestFactory.createMicroservice(AppModule, {
  transport: Transport.RMQ,
  options: {
    urls: ['amqp://localhost:5672'],
    queue: 'cats_queue',
    queueOptions: {
      durable: false
    },
  },
});
```

> **Hint** The `Transport` enum is imported from the `@nestjs/microservices` package.

#### Options[#](/microservices/rabbitmq#options)

The `options` property is specific to the chosen transporter. The **RabbitMQ** transporter exposes the properties described below.

|                         |                                                                                                                          |
| ----------------------- | ------------------------------------------------------------------------------------------------------------------------ |
| `urls`                  | Connection urls                                                                                                          |
| `queue`                 | Queue name which your server will listen to                                                                              |
| `prefetchCount`         | Sets the prefetch count for the channel                                                                                  |
| `isGlobalPrefetchCount` | Enables per channel prefetching                                                                                          |
| `noAck`                 | If `false`, manual acknowledgment mode enabled                                                                           |
| `queueOptions`          | Additional queue options (read more [here](https://www.squaremobius.net/amqp.node/channel_api.html#channel_assertQueue)) |
| `socketOptions`         | Additional socket options (read more [here](https://www.squaremobius.net/amqp.node/channel_api.html#socket-options))     |

#### Client[#](/microservices/rabbitmq#client)

Like other microservice transporters, you have [several options](https://docs.nestjs.com/microservices/basics#client) for creating a RabbitMQ `ClientProxy` instance.

One method for creating an instance is to use the `ClientsModule`. To create a client instance with the `ClientsModule`, import it and use the `register()` method to pass an options object with the same properties shown above in the `createMicroservice()` method, as well as a `name` property to be used as the injection token. Read more about `ClientsModule`[here](https://docs.nestjs.com/microservices/basics#client).

```typescript

@Module({
  imports: [
    ClientsModule.register([
      {
        name: 'MATH_SERVICE',
        transport: Transport.RMQ,
        options: {
          urls: ['amqp://localhost:5672'],
          queue: 'cats_queue',
          queueOptions: {
            durable: false
          },
        },
      },
    ]),
  ]
  ...
})
```

Other options to create a client (either `ClientProxyFactory` or `@Client()`) can be used as well. You can read about them [here](https://docs.nestjs.com/microservices/basics#client).

#### Context[#](/microservices/rabbitmq#context)

In more sophisticated scenarios, you may want to access more information about the incoming request. When using the RabbitMQ transporter, you can access the `RmqContext` object.

JS TS

```typescript

@MessagePattern('notifications')
getNotifications(@Payload() data: number[], @Ctx() context: RmqContext) {
  console.log(`Pattern: ${context.getPattern()}`);
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('notifications')
getNotifications(data, context) {
  console.log(`Pattern: ${context.getPattern()}`);
}
```

> **Hint**`@Payload()`, `@Ctx()` and `RmqContext` are imported from the `@nestjs/microservices` package.

To access the original RabbitMQ message (with the `properties`, `fields`, and `content`), use the `getMessage()` method of the `RmqContext` object, as follows:

JS TS

```typescript

@MessagePattern('notifications')
getNotifications(@Payload() data: number[], @Ctx() context: RmqContext) {
  console.log(context.getMessage());
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('notifications')
getNotifications(data, context) {
  console.log(context.getMessage());
}
```

To retrieve a reference to the RabbitMQ [channel](https://www.rabbitmq.com/channels.html), use the `getChannelRef` method of the `RmqContext` object, as follows:

JS TS

```typescript

@MessagePattern('notifications')
getNotifications(@Payload() data: number[], @Ctx() context: RmqContext) {
  console.log(context.getChannelRef());
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('notifications')
getNotifications(data, context) {
  console.log(context.getChannelRef());
}
```

#### Message acknowledgement[#](/microservices/rabbitmq#message-acknowledgement)

To make sure a message is never lost, RabbitMQ supports [message acknowledgements](https://www.rabbitmq.com/confirms.html). An acknowledgement is sent back by the consumer to tell RabbitMQ that a particular message has been received, processed and that RabbitMQ is free to delete it. If a consumer dies (its channel is closed, connection is closed, or TCP connection is lost) without sending an ack, RabbitMQ will understand that a message wasn't processed fully and will re-queue it.

To enable manual acknowledgment mode, set the `noAck` property to `false`:

```typescript

options: {
  urls: ['amqp://localhost:5672'],
  queue: 'cats_queue',
  noAck: false,
  queueOptions: {
    durable: false
  },
},
```

When manual consumer acknowledgements are turned on, we must send a proper acknowledgement from the worker to signal that we are done with a task.

JS TS

```typescript

@MessagePattern('notifications')
getNotifications(@Payload() data: number[], @Ctx() context: RmqContext) {
  const channel = context.getChannelRef();
  const originalMsg = context.getMessage();

  channel.ack(originalMsg);
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('notifications')
getNotifications(data, context) {
  const channel = context.getChannelRef();
  const originalMsg = context.getMessage();

  channel.ack(originalMsg);
}
```

----
url: https://docs.nestjs.com/v5/recipes/swagger
----

### OpenAPI (Swagger)

##### This chapter applies only to TypeScript

The [OpenAPI](https://swagger.io/specification/) (Swagger) specification is a powerful definition format to describe RESTful APIs. Nest provides a dedicated [module](https://github.com/nestjs/swagger) to work with it.

#### Installation

Firstly you have to install the module:

TypeScript

```typescript

$ npm install --save @nestjs/swagger
```

#### Bootstrap

Once the installation process is done, open your bootstrap file (mostly `main.ts`) and initialize the Swagger using `SwaggerModule` class:

TypeScript

```typescript

import { NestFactory } from '@nestjs/core';
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
import { ApplicationModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(ApplicationModule);

  const options = new DocumentBuilder()
    .setTitle('Cats example')
    .setDescription('The cats API description')
    .setVersion('1.0')
    .addTag('cats')
    .build();
  const document = SwaggerModule.createDocument(app, options);
  SwaggerModule.setup('api', app, document);

  await app.listen(3001);
}
bootstrap();
```

The `DocumentBuilder` is a helper class that helps to structure a base document for the `SwaggerModule`. It contains several methods that allow setting such properties like title, description, version, and so on.

In order to create a full document (with defined HTTP routes) we use the `createDocument()` method of the `SwaggerModule` class. This method takes two arguments, the application instance and the base Swagger options respectively.

The last step is to call `setup()`. It accepts sequentially **(1)** path to mount the Swagger, **(2)** application instance, and **(3)** the document that describes the Nest application.

Now you can run the following command to start the HTTP server:

```bash

$ npm run start
```

While the application is running, open your browser and navigate to `http://localhost:3000/api`. You should see similar page:

The `SwaggerModule` automatically reflects all of your endpoints. In the background, it's making use of `swagger-ui-express` and creates a live documentation.

#### Body, query, path parameters

During the examination of the defined controllers, the `SwaggerModule` is looking for all used `@Body()`, `@Query()`, and `@Param()` decorators in the route handlers. Thanks to them, the valid document can be created.

Moreover, the module creates the **models definitions** by taking advantage of the **reflection**. Take a look at the following code:

TypeScript

```typescript

@Post()
async create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

> **Notice** To implicitly set the body definition you can use the `@ApiImplicitBody()` decorator (`@nestjs/swagger` package).

Based on the `CreateCatDto`, the module definition will be created:

As you can see, the definition's empty although the class has few declared properties. In order to make the class properties accessible to the `SwaggerModule`, we have to mark all of them with `@ApiModelProperty()` decorator:

TypeScript

```typescript

import { ApiModelProperty } from '@nestjs/swagger';

export class CreateCatDto {
  @ApiModelProperty()
  readonly name: string;

  @ApiModelProperty()
  readonly age: number;

  @ApiModelProperty()
  readonly breed: string;
}
```

Let's open the browser and verify the generated `CreateCatDto` model:

The `@ApiModelProperty()` decorator accepts options object:

TypeScript

```typescript

export declare const ApiModelProperty: (metadata?: {
  description?: string;
  required?: boolean;
  type?: any;
  isArray?: boolean;
  collectionFormat?: string;
  default?: any;
  enum?: SwaggerEnumType;
  format?: string;
  multipleOf?: number;
  maximum?: number;
  exclusiveMaximum?: number;
  minimum?: number;
  exclusiveMinimum?: number;
  maxLength?: number;
  minLength?: number;
  pattern?: string;
  maxItems?: number;
  minItems?: number;
  uniqueItems?: boolean;
  maxProperties?: number;
  minProperties?: number;
  readOnly?: boolean;
  xml?: any;
  example?: any;
}) => PropertyDecorator;
```

> **Hint** There's an `@ApiModelPropertyOptional()` shortcut decorator which helps to avoid continuous typing `@ApiModelProperty({ required: false })`.

Thanks to that we can simply set the **default** value, determine whether the property is required or explicitly set the type.

#### Multiple specifications

Swagger module also provides a way to support multiple specifications. In other words, you can serve different documentations with different `SwaggerUI` on different endpoints.

In order to allow `SwaggerModule` to support multi-spec, your application must be written with modular approach. The `createDocument()` method takes in a 3rd argument: `extraOptions` which is an object where a property `include` expects an array of modules.

You can setup Multiple Specifications support as shown below:

TypeScript

```typescript

import { NestFactory } from '@nestjs/core';
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
import { ApplicationModule } from './app.module';

// imports CatsModule and DogsModule;

async function bootstrap() {
  const app = await NestFactory.create(ApplicationModule);

  /**
   * createDocument(application, configurationOptions, extraOptions);
   *
   * createDocument method takes in an optional 3rd argument "extraOptions"
   * which is an object with "include" property where you can pass an Array
   * of Modules that you want to include in that Swagger Specification
   * E.g: CatsModule and DogsModule will have two separate Swagger Specifications which
   * will be exposed on two different SwaggerUI with two different endpoints.
   */

  const options = new DocumentBuilder()
    .setTitle('Cats example')
    .setDescription('The cats API description')
    .setVersion('1.0')
    .addTag('cats')
    .build();
  const catDocument = SwaggerModule.createDocument(app, options, { include: [CatsModule] });
  SwaggerModule.setup('api/cats', app, catDocument);

  const secondOptions = new DocumentBuilder()
    .setTitle('Dogs example')
    .setDescription('The dogs API description')
    .setVersion('1.0')
    .addTag('dogs')
    .build();
  const dogDocument = SwaggerModule.createDocument(app, secondOptions, { include: [DogsModule] });
  SwaggerModule.setup('api/dogs', app, dogDocument);

  await app.listen(3001);
}
bootstrap();
```

Now you can start your server with the following command:

```bash

$ npm run start
```

Navigate to `http://localhost:3000/api/cats` to see SwaggerUI for your Cats:

While `http://localhost:3000/api/docs` will expose a SwaggerUI for your Dogs:

> **Notice** You have to construct a **SwaggerOptions** with `DocumentBuilder`, run `createDocument()` against newly constructed `options` then immediately "serve" it with `setup()` before you can start working on a second **SwaggerOptions** for a second Swagger Specification. This specific order is to prevent Swagger configurations being overriden by different options.

#### Working with enums

To be able for `SwaggerModule` to identify an `Enum`, we have to manually set the `enum` property on `@ApiModelProperty` with an array of values..

TypeScript

```typescript

@ApiModelProperty({ enum: ['Admin', 'Moderator', 'User']})
role: UserRole;
```

`UserRole` enum can be defined as following snippet:

TypeScript

```typescript

export enum UserRole {
  Admin = 'Admin',
  Moderator = 'Moderator',
  User = 'User'
}
```

> **Note** The above usage can only be applied to a **property** as part of a **model definition.**

Enums can be used by itself with the `@Query()` parameter decorator in combination with the `@ApiImplicitQuery()` decorator.

TypeScript

```typescript

@ApiImplicitQuery({ name: 'role', enum: ['Admin', 'Moderator', 'User'] })
async filterByRole(@Query('role') role: UserRole = UserRole.User) {
  // role returns: UserRole.Admin, UserRole.Moderator OR UserRole.User
}
```

> **Hint**`enum` and `isArray` can also be used in combination in `@ApiImplicitQuery()`

With `isArray` set to **true**, the `enum` now can be selected as a **multi-select**:

#### Working with arrays

We have to manually indicate a type when the property is actually an array:

TypeScript

```typescript

@ApiModelProperty({ type: [String] })
readonly names: string[];
```

Simply put your type as the first element of an array (as shown above) or set an `isArray` property to `true`.

#### Tags

At the beginning, we created a `cats` tag (by making use of `DocumentBuilder`). In order to attach the controller to the specified tag, we need to use `@ApiUseTags(...tags)` decorator.

TypeScript

```typescript

@ApiUseTags('cats')
@Controller('cats')
export class CatsController {}
```

#### Responses

To define a custom HTTP response, we use `@ApiResponse()` decorator.

TypeScript

```typescript

@Post()
@ApiResponse({ status: 201, description: 'The record has been successfully created.'})
@ApiResponse({ status: 403, description: 'Forbidden.'})
async create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

Same as common HTTP exceptions defined in [Exception Filters](/v5/exception-filters) section, Nest also provides a set of usable **API responses** that inherits from the core `@ApiResponse` decorator:


In addition to the available HTTP exceptions, Nest provides short-hand decorators for: `HttpStatus.OK`, `HttpStatus.CREATED` and `HttpStatus.METHOD_NOT_ALLOWED`

TypeScript

```typescript

@Post()
@ApiCreatedResponse({ description: 'The record has been successfully created.'})
@ApiForbiddenResponse({ description: 'Forbidden.'})
async create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

#### Authentication

You can enable the bearer authorization using `addBearerAuth()` method of the `DocumentBuilder` class. Then to restrict the chosen route or entire controller, use `@ApiBearerAuth()` decorator.

TypeScript

```typescript

@ApiUseTags('cats')
@ApiBearerAuth()
@Controller('cats')
export class CatsController {}
```

That's how the OpenAPI documentation should look like now:

#### File upload

You can enable file upload for a specific method with the `@ApiImplicitFile` decorator together with `@ApiConsumes()`. Here's a full example using [File Upload](/v5/techniques/file-upload) technique:

TypeScript

```typescript

@UseInterceptors(FileInterceptor('file'))
@ApiConsumes('multipart/form-data')
@ApiImplicitFile({ name: 'file', required: true, description: 'List of cats' })
uploadFile(@UploadedFile() file) {}
```

#### Decorators

All of the available OpenAPI decorators has an `Api` prefix to be clearly distinguishable from the core decorators. Below is a full list of the exported decorators with a defined use-level (where might be applied).

|                               |                     |
| ----------------------------- | ------------------- |
| `@ApiOperation()`             | Method              |
| `@ApiResponse()`              | Method / Controller |
| `@ApiProduces()`              | Method / Controller |
| `@ApiConsumes()`              | Method / Controller |
| `@ApiBearerAuth()`            | Method / Controller |
| `@ApiOAuth2Auth()`            | Method / Controller |
| `@ApiImplicitBody()`          | Method              |
| `@ApiImplicitParam()`         | Method              |
| `@ApiImplicitQuery()`         | Method              |
| `@ApiImplicitHeader()`        | Method              |
| `@ApiImplicitFile()`          | Method              |
| `@ApiExcludeEndpoint()`       | Method              |
| `@ApiUseTags()`               | Method / Controller |
| `@ApiModelProperty()`         | Model               |
| `@ApiModelPropertyOptional()` | Model               |

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/11-swagger).

* OpenAPI (Swagger)
* Installation
* Bootstrap
* Body, query, path parameters
* Multiple specifications
* Working with enums
* Working with arrays
* Tags
* Responses
* Authentication
* File upload
* Decorators

----
url: https://docs.nestjs.com/v4/microservices/exception-filters
----

### Exception Filters

The websockets **exceptions layer** works exact same as the [prime layer](/v4/exception-filters). The only difference is that instead of throwing `HttpException`, you should throw `RpcException`.

TypeScript

```typescript

throw new RpcException('Invalid credentials.');
```

> **Notice** The `RpcException` class is imported from the `@nestjs/microservices` package.

Nest would handle this exception and emits the `exception` message with the following data:

TypeScript

```typescript

{
  status: 'error',
  message: 'Invalid credentials.'
}
```

#### Exception Filters

The **Exception Filters** are also really similar, and works exactly in the same way as the primary ones. The only difference is that `catch()` method should returns an `Observable`.

rpc-exception.filter.ts

JavaScript TypeScript

TypeScript

```typescript

import { Catch, RpcExceptionFilter } from '@nestjs/common';
import { Observable } from 'rxjs/Observable';
import { RpcException } from '@nestjs/microservices';
import 'rxjs/add/observable/throw';

@Catch(RpcException)
export class ExceptionFilter implements RpcExceptionFilter {
  catch(exception: RpcException): Observable<any> {
    return Observable.throw(exception.getError());
  }
}
```

TypeScript

```typescript

import { Catch } from '@nestjs/common';
import { Observable } from 'rxjs/Observable';
import { RpcException } from '@nestjs/microservices';
import 'rxjs/add/observable/throw';

@Catch(RpcException)
export class ExceptionFilter {
  catch(exception) {
    return Observable.throw(exception.getError());
  }
}
```

> **Notice** It's impossible to set up the microservices exception filters globally.

#### Sponsors

[](https://valor-software.com/)

Nest is an MIT-licensed open source project. It can grow thanks to the support by these awesome people. If you'd like to join them, please read more [here](https://opencollective.com/nest). Thanks!

[](https://opencollective.com/nest/backer/0/website)[](https://opencollective.com/nest/backer/1/website)[](https://opencollective.com/nest/backer/2/website)[](https://opencollective.com/nest/backer/3/website)[](https://opencollective.com/nest/backer/4/website)[](https://opencollective.com/nest/backer/5/website)[](https://opencollective.com/nest/backer/6/website)[](https://opencollective.com/nest/backer/7/website)[](https://opencollective.com/nest/backer/8/website)[](https://opencollective.com/nest/backer/9/website)[](https://opencollective.com/nest/backer/10/website)[](https://opencollective.com/nest/backer/11/website)[](https://opencollective.com/nest/backer/12/website)[](https://opencollective.com/nest/backer/13/website)[](https://opencollective.com/nest/backer/14/website)[](https://opencollective.com/nest/backer/15/website)[](https://opencollective.com/nest/backer/16/website)[](https://opencollective.com/nest/backer/17/website)[](https://opencollective.com/nest/backer/18/website)[](https://opencollective.com/nest/backer/19/website)[](https://opencollective.com/nest/backer/20/website)[](https://opencollective.com/nest/backer/21/website)[](https://opencollective.com/nest/backer/22/website)[](https://opencollective.com/nest/backer/23/website)[](https://opencollective.com/nest/backer/24/website)[](https://opencollective.com/nest/backer/25/website)[](https://opencollective.com/nest/backer/26/website)[](https://opencollective.com/nest/backer/27/website)[](https://opencollective.com/nest/backer/28/website)[](https://opencollective.com/nest/backer/29/website)

[Become a sponsor](https://opencollective.com/nest)

----
url: https://docs.nestjs.com/security/encryption-and-hashing
----

[Skip to content](#content)

On this page

* [Encryption and Hashing](https://docs.nestjs.com/security/encryption-and-hashing#encryption-and-hashing)
* [Encryption](https://docs.nestjs.com/security/encryption-and-hashing#encryption)
* [Hashing](https://docs.nestjs.com/security/encryption-and-hashing#hashing)

### Encryption and Hashing

**Encryption** is the process of encoding information. This process converts the original representation of the information, known as plaintext, into an alternative form known as ciphertext. Ideally, only authorized parties can decipher a ciphertext back to plaintext and access the original information. Encryption does not itself prevent interference, but it denies the intelligible content to a would-be interceptor. Encryption is a two-way function: what is encrypted can be decrypted with the proper key.

**Hashing** is the process of converting a given key into another value. A hash function generates the new value according to a mathematical algorithm. Once a value has been hashed, it should be impossible to go from the output back to the input.

#### Encryption[#](/security/encryption-and-hashing#encryption)

Node.js provides a built-in [crypto module](https://nodejs.org/api/crypto.html) that you can use to encrypt and decrypt strings, numbers, buffers, streams, and more. Nest does not provide an additional package on top of this module, to avoid introducing unnecessary abstractions.

As an example, let's use the AES (Advanced Encryption Standard) `'aes-256-ctr'` algorithm, which uses the CTR encryption mode.

```typescript

import { createCipheriv, randomBytes, scrypt } from 'node:crypto';
import { promisify } from 'node:util';

const iv = randomBytes(16);
const password = 'Password used to generate key';

// The key length is dependent on the algorithm.
// In this case for aes256, it is 32 bytes.
const key = (await promisify(scrypt)(password, 'salt', 32)) as Buffer;
const cipher = createCipheriv('aes-256-ctr', key, iv);

const textToEncrypt = 'Nest';
const encryptedText = Buffer.concat([
  cipher.update(textToEncrypt),
  cipher.final(),
]);
```

To decrypt the `encryptedText` value:

```typescript

import { createDecipheriv } from 'node:crypto';

const decipher = createDecipheriv('aes-256-ctr', key, iv);
const decryptedText = Buffer.concat([
  decipher.update(encryptedText),
  decipher.final(),
]);
```

#### Hashing[#](/security/encryption-and-hashing#hashing)

To hash passwords, use `PasswordHasher` from [`@nestjs/authentication`](/security/authentication). It hashes with scrypt from `node:crypto`, at the parameters OWASP recommends (N=2^17, r=8, p=1: about 128 MiB of memory per hash), on the libuv thread pool, so it doesn't block the event loop and needs no native dependency. scrypt is memory-hard, which makes guessing passwords on GPUs far more expensive than with bcrypt.

When your application imports `AuthenticationModule`, `PasswordHasher` is a provider, so inject it where you store and check passwords:

```typescript

import { Injectable } from '@nestjs/common';
import { PasswordHasher } from '@nestjs/authentication';

@Injectable()
export class CredentialsService {
  constructor(private readonly passwordHasher: PasswordHasher) {}

  async hashPassword(password: string) {
    return this.passwordHasher.hash(password);
  }

  async checkPassword(password: string, storedHash: string | undefined) {
    return this.passwordHasher.verify(password, storedHash);
  }
}
```

* `hash()` returns a self-describing string, such as `$scrypt$ln=17,r=8,p=1$<salt>$<hash>`: the parameters and a random salt are stored with the hash, so there is nothing else to keep.
* `verify()` compares in constant time. Pass `undefined` for an unknown user: it checks a dummy hash instead, so the response time doesn't reveal which accounts exist.
* Passwords are Unicode-normalized (NFKC) before hashing, so the same password typed on different keyboards verifies.
* `hash()` refuses an empty password and one over 4 KiB with a `RangeError`, and `verify()` answers `false` for them without hashing. Any other rule, such as a minimum length, is yours to check first.
* `needsRehash()` tells you that a stored hash was made with weaker parameters than the current ones. Check it after a successful `verify()`, and store a new hash while you have the plaintext:

```typescript

if (this.passwordHasher.needsRehash(storedHash)) {
  await this.usersRepository.updatePasswordHash(user.id, await this.passwordHasher.hash(password));
}
```

The cost comes from the module's `password` option: set its `logN` to 18 to double it. It has a ceiling of 1 GiB of memory and 16 times the default work per hash, so with the default `r` of 8, `logN` stops at 20; parameters beyond it throw when the hasher is created, and a stored hash made with them never verifies. Outside the module, create one yourself with `new PasswordHasher()`. In tests, a cheaper instance keeps suites fast, with `logN` set to 10.

> **Hint** If you'd rather use argon2 or bcrypt, the [argon2](https://www.npmjs.com/package/argon2) and [bcrypt](https://www.npmjs.com/package/bcrypt) packages work with Nest as they are: call their `hash()` and `verify()` (argon2) or `compare()` (bcrypt) functions from your own provider. Both are native modules, and bcrypt reads only the first 72 bytes of a password.

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/security/encryption-hashing.md)

----
url: https://docs.nestjs.com/v11/graphql/other-features
----

* [Other features](https://docs.nestjs.com/v11/graphql/other-features#other-features)
* [Overview](https://docs.nestjs.com/v11/graphql/other-features#overview)
* [Execution context](https://docs.nestjs.com/v11/graphql/other-features#execution-context)
* [Exception filters](https://docs.nestjs.com/v11/graphql/other-features#exception-filters)
* [Custom decorators](https://docs.nestjs.com/v11/graphql/other-features#custom-decorators)
* [Execute enhancers at the field resolver level](https://docs.nestjs.com/v11/graphql/other-features#execute-enhancers-at-the-field-resolver-level)
* [Creating a custom driver](https://docs.nestjs.com/v11/graphql/other-features#creating-a-custom-driver)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/guards-interceptors.md "Suggest Edits")

### Other features

In the GraphQL world, there is a lot of debate about handling issues like **authentication**, or **side-effects** of operations. Should we handle things inside the business logic? Should we use a higher-order function to enhance queries and mutations with authorization logic? Or should we use [schema directives](https://www.apollographql.com/docs/apollo-server/schema/directives/)? There is no single one-size-fits-all answer to these questions.

Nest helps address these issues with its cross-platform features like [guards](/v11/guards) and [interceptors](/v11/interceptors). The philosophy is to reduce redundancy and provide tooling that helps create well-structured, readable, and consistent applications.

#### Overview[#](/graphql/other-features#overview)

You can use standard [guards](/v11/guards), [interceptors](/v11/interceptors), [filters](/v11/exception-filters) and [pipes](/v11/pipes) in the same fashion with GraphQL as with any RESTful application. Additionally, you can easily create your own decorators by leveraging the [custom decorators](/v11/custom-decorators) feature. Let's take a look at a sample GraphQL query handler.

```typescript

@Query('author')
@UseGuards(AuthGuard)
async getAuthor(@Args('id', ParseIntPipe) id: number) {
  return this.authorsService.findOneById(id);
}
```

As you can see, GraphQL works with both guards and pipes in the same way as HTTP REST handlers. Because of this, you can move your authentication logic to a guard; you can even reuse the same guard class across both a REST and GraphQL API interface. Similarly, interceptors work across both types of applications in the same way:

```typescript

@Mutation()
@UseInterceptors(EventsInterceptor)
async upvotePost(@Args('postId') postId: number) {
  return this.postsService.upvoteById({ id: postId });
}
```

#### Execution context[#](/graphql/other-features#execution-context)

Since GraphQL receives a different type of data in the incoming request, the [execution context](https://docs.nestjs.com/fundamentals/execution-context) received by both guards and interceptors is somewhat different with GraphQL vs. REST. GraphQL resolvers have a distinct set of arguments: `root`, `args`, `context`, and `info`. Thus guards and interceptors must transform the generic `ExecutionContext` to a `GqlExecutionContext`. This is straightforward:

```typescript

import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common';
import { GqlExecutionContext } from '@nestjs/graphql';

@Injectable()
export class AuthGuard implements CanActivate {
  canActivate(context: ExecutionContext): boolean {
    const ctx = GqlExecutionContext.create(context);
    return true;
  }
}
```

The GraphQL context object returned by `GqlExecutionContext.create()` exposes a **get** method for each GraphQL resolver argument (e.g., `getArgs()`, `getContext()`, etc). Once transformed, we can easily pick out any GraphQL argument for the current request.

#### Exception filters[#](/graphql/other-features#exception-filters)

Nest standard [exception filters](/v11/exception-filters) are compatible with GraphQL applications as well. As with `ExecutionContext`, GraphQL apps should transform the `ArgumentsHost` object to a `GqlArgumentsHost` object.

```typescript

@Catch(HttpException)
export class HttpExceptionFilter implements GqlExceptionFilter {
  catch(exception: HttpException, host: ArgumentsHost) {
    const gqlHost = GqlArgumentsHost.create(host);
    return exception;
  }
}
```

> **Hint** Both `GqlExceptionFilter` and `GqlArgumentsHost` are imported from the `@nestjs/graphql` package.

Note that unlike the REST case, you don't use the native `response` object to generate a response.

#### Custom decorators[#](/graphql/other-features#custom-decorators)

As mentioned, the [custom decorators](/v11/custom-decorators) feature works as expected with GraphQL resolvers.

```typescript

export const User = createParamDecorator(
  (data: unknown, ctx: ExecutionContext) =>
    GqlExecutionContext.create(ctx).getContext().user,
);
```

Use the `@User()` custom decorator as follows:

```typescript

@Mutation()
async upvotePost(
  @User() user: UserEntity,
  @Args('postId') postId: number,
) {}
```

> **Hint** In the above example, we have assumed that the `user` object is assigned to the context of your GraphQL application.

#### Execute enhancers at the field resolver level[#](/graphql/other-features#execute-enhancers-at-the-field-resolver-level)

In the GraphQL context, Nest does not run **enhancers** (the generic name for interceptors, guards and filters) at the field level [see this issue](https://github.com/nestjs/graphql/issues/320#issuecomment-511193229): they only run for the top level `@Query()`/`@Mutation()` method. You can tell Nest to execute interceptors, guards or filters for methods annotated with `@ResolveField()` by setting the `fieldResolverEnhancers` option in `GqlModuleOptions`. Pass it a list of `'interceptors'`, `'guards'`, and/or `'filters'` as appropriate:

```typescript

GraphQLModule.forRoot({
  fieldResolverEnhancers: ['interceptors']
}),
```

> **Warning** Enabling enhancers for field resolvers can cause performance issues when you are returning lots of records and your field resolver is executed thousands of times. For this reason, when you enable `fieldResolverEnhancers`, we advise you to skip execution of enhancers that are not strictly necessary for your field resolvers. You can do this using the following helper function:

```typescript

export function isResolvingGraphQLField(context: ExecutionContext): boolean {
  if (context.getType<GqlContextType>() === 'graphql') {
    const gqlContext = GqlExecutionContext.create(context);
    const info = gqlContext.getInfo();
    const parentType = info.parentType.name;
    return parentType !== 'Query' && parentType !== 'Mutation';
  }
  return false;
}
```

#### Creating a custom driver[#](/graphql/other-features#creating-a-custom-driver)

Nest provides two official drivers out-of-the-box: `@nestjs/apollo` and `@nestjs/mercurius`, as well as an API allowing developers to build new **custom drivers**. With a custom driver, you can integrate any GraphQL library or extend the existing integration, adding extra features on top.

For example, to integrate the `express-graphql` package, you could create the following driver class:

```typescript

import { AbstractGraphQLDriver, GqlModuleOptions } from '@nestjs/graphql';
import { graphqlHTTP } from 'express-graphql';

class ExpressGraphQLDriver extends AbstractGraphQLDriver {
  async start(options: GqlModuleOptions<any>): Promise<void> {
    options = await this.graphQlFactory.mergeWithSchema(options);

    const { httpAdapter } = this.httpAdapterHost;
    httpAdapter.use(
      '/graphql',
      graphqlHTTP({
        schema: options.schema,
        graphiql: true,
      }),
    );
  }

  async stop() {}
}
```

And then use it as follows:

```typescript

GraphQLModule.forRoot({
  driver: ExpressGraphQLDriver,
});
```

----
url: https://docs.nestjs.com/v10/recipes/serve-static
----

* [Serve Static](https://docs.nestjs.com/v10/recipes/serve-static#serve-static)
* [Installation](https://docs.nestjs.com/v10/recipes/serve-static#installation)
* [Bootstrap](https://docs.nestjs.com/v10/recipes/serve-static#bootstrap)
* [Configuration](https://docs.nestjs.com/v10/recipes/serve-static#configuration)
* [Example](https://docs.nestjs.com/v10/recipes/serve-static#example)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/recipes/serve-static.md "Suggest Edits")

### Serve Static

In order to serve static content like a Single Page Application (SPA) we can use the `ServeStaticModule` from the [`@nestjs/serve-static`](https://www.npmjs.com/package/@nestjs/serve-static) package.

#### Installation[#](/recipes/serve-static#installation)

First we need to install the required package:

```bash

$ npm install --save @nestjs/serve-static
```

#### Bootstrap[#](/recipes/serve-static#bootstrap)

Once the installation process is done, we can import the `ServeStaticModule` into the root `AppModule` and configure it by passing in a configuration object to the `forRoot()` method.

```typescript

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { ServeStaticModule } from '@nestjs/serve-static';
import { join } from 'path';

@Module({
  imports: [
    ServeStaticModule.forRoot({
      rootPath: join(__dirname, '..', 'client'),
    }),
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}
```

With this in place, build the static website and place its content in the location specified by the `rootPath` property.

#### Configuration[#](/recipes/serve-static#configuration)

[ServeStaticModule](https://github.com/nestjs/serve-static) can be configured with a variety of options to customize its behavior. You can set the path to render your static app, specify excluded paths, enable or disable setting Cache-Control response header, etc. See the full list of options [here](https://github.com/nestjs/serve-static/blob/master/lib/interfaces/serve-static-options.interface.ts).

> **Notice** The default `renderPath` of the Static App is `*` (all paths), and the module will send "index.html" files in response. It lets you create Client-Side routing for your SPA. Paths, specified in your controllers will fallback to the server. You can change this behavior setting `serveRoot`, `renderPath` combining them with other options.

#### Example[#](/recipes/serve-static#example)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/24-serve-static).

----
url: https://docs.nestjs.com/v9/microservices/exception-filters
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Exception filters](https://docs.nestjs.com/v9/microservices/exception-filters#exception-filters)
* [Filters](https://docs.nestjs.com/v9/microservices/exception-filters#filters)
* [Inheritance](https://docs.nestjs.com/v9/microservices/exception-filters#inheritance)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/microservices/exception-filters.md "Suggest Edits")

### Exception filters

The only difference between the HTTP [exception filter](/v9/exception-filters) layer and the corresponding microservices layer is that instead of throwing `HttpException`, you should use `RpcException`.

```typescript

throw new RpcException('Invalid credentials.');
```

> **Hint** The `RpcException` class is imported from the `@nestjs/microservices` package.

With the sample above, Nest will handle the thrown exception and return the `error` object with the following structure:

```json

{
  "status": "error",
  "message": "Invalid credentials."
}
```

#### Filters[#](/microservices/exception-filters#filters)

Microservice exception filters behave similarly to HTTP exception filters, with one small difference. The `catch()` method must return an `Observable`.

rpc-exception.filter.ts

JS TS

```typescript

import { Catch, RpcExceptionFilter, ArgumentsHost } from '@nestjs/common';
import { Observable, throwError } from 'rxjs';
import { RpcException } from '@nestjs/microservices';

@Catch(RpcException)
export class ExceptionFilter implements RpcExceptionFilter<RpcException> {
  catch(exception: RpcException, host: ArgumentsHost): Observable<any> {
    return throwError(() => exception.getError());
  }
}
```

```typescript

import { Catch } from '@nestjs/common';
import { throwError } from 'rxjs';

@Catch(RpcException)
export class ExceptionFilter {
  catch(exception, host) {
    return throwError(() => exception.getError());
  }
}
```

> **Warning** Global microservice exception filters aren't enabled by default when using a [hybrid application](/v9/faq/hybrid-application).

The following example uses a manually instantiated method-scoped filter. Just as with HTTP based applications, you can also use controller-scoped filters (i.e., prefix the controller class with a `@UseFilters()` decorator).

JS TS

```typescript

@UseFilters(new ExceptionFilter())
@MessagePattern({ cmd: 'sum' })
accumulate(data: number[]): number {
  return (data || []).reduce((a, b) => a + b);
}
```

```typescript

@UseFilters(new ExceptionFilter())
@MessagePattern({ cmd: 'sum' })
accumulate(data) {
  return (data || []).reduce((a, b) => a + b);
}
```

#### Inheritance[#](/microservices/exception-filters#inheritance)

Typically, you'll create fully customized exception filters crafted to fulfill your application requirements. However, there might be use-cases when you would like to simply extend the **core exception filter**, and override the behavior based on certain factors.

In order to delegate exception processing to the base filter, you need to extend `BaseExceptionFilter` and call the inherited `catch()` method.

JS TS

```typescript

import { Catch, ArgumentsHost } from '@nestjs/common';
import { BaseRpcExceptionFilter } from '@nestjs/microservices';

@Catch()
export class AllExceptionsFilter extends BaseRpcExceptionFilter {
  catch(exception: any, host: ArgumentsHost) {
    return super.catch(exception, host);
  }
}
```

```typescript

import { Catch } from '@nestjs/common';
import { BaseRpcExceptionFilter } from '@nestjs/microservices';

@Catch()
export class AllExceptionsFilter extends BaseRpcExceptionFilter {
  catch(exception, host) {
    return super.catch(exception, host);
  }
}
```

----
url: https://docs.nestjs.com/v11/recipes/suites
----

* [Suites](https://docs.nestjs.com/v11/recipes/suites#suites)
* [Getting started](https://docs.nestjs.com/v11/recipes/suites#getting-started)
* [Install Suites](https://docs.nestjs.com/v11/recipes/suites#install-suites)
* [Set up type definitions](https://docs.nestjs.com/v11/recipes/suites#set-up-type-definitions)
* [Create a sample service](https://docs.nestjs.com/v11/recipes/suites#create-a-sample-service)
* [Write a unit test](https://docs.nestjs.com/v11/recipes/suites#write-a-unit-test)
* [Pre-compile mock configuration](https://docs.nestjs.com/v11/recipes/suites#pre-compile-mock-configuration)
* [Testing with real dependencies](https://docs.nestjs.com/v11/recipes/suites#testing-with-real-dependencies)
* [Token-based dependencies](https://docs.nestjs.com/v11/recipes/suites#token-based-dependencies)
* [Using mock() and stub() directly](https://docs.nestjs.com/v11/recipes/suites#using-mock-and-stub-directly)
* [Summary](https://docs.nestjs.com/v11/recipes/suites#summary)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/recipes/suites.md "Suggest Edits")

### Suites

[Suites](https://suites.dev) is an [open-source](https://github.com/suites-dev/suites) unit-testing framework for TypeScript dependency injection frameworks. It is used as an **alternative** to manually creating mocks, verbose test setup with multiple mock configurations, or working with untyped test doubles (like mocks and stubs).

Suites reads metadata from nestjs services at runtime and automatically generates fully-typed mocks for all dependencies. This removes boilerplate mock setup and ensures type-safe tests. While Suites can be used alongside `Test.createTestingModule()`, it excels at focused unit testing. Use `Test.createTestingModule()` when validating module wiring, decorators, guards, and interceptors. Use Suites for fast unit tests with automatic mock generation.

For more information on module-based testing, see the [testing fundamentals](/v11/fundamentals/testing) chapter.

> **Note**`Suites` is a third-party package and is not maintained by the NestJS core team. Please report any issues to the [appropriate repository](https://github.com/suites-dev/suites).

#### Getting started[#](/recipes/suites#getting-started)

This guide demonstrates using Suites to test NestJS services. It covers both isolated testing (all dependencies mocked) and sociable testing (selected real implementations).

#### Install Suites[#](/recipes/suites#install-suites)

Verify NestJS runtime dependencies are installed:

```bash

$ npm install @nestjs/common @nestjs/core reflect-metadata
```

Install Suites core, the NestJS adapter, and the doubles adapter:

```bash

$ npm install --save-dev @suites/unit @suites/di.nestjs @suites/doubles.jest
```

The doubles adapter (`@suites/doubles.jest`) provides wrappers around Jest's mocking capabilities. It exposes `mock()` and `stub()` functions that create type-safe test doubles.

Ensure Jest and TypeScript are available:

```bash

$ npm install --save-dev ts-jest @types/jest jest typescript
```

Expand if you're using Vitest

```bash

$ npm install --save-dev @suites/unit @suites/di.nestjs @suites/doubles.vitest
```

Expand if you're using Sinon

```bash

$ npm install --save-dev @suites/unit @suites/di.nestjs @suites/doubles.sinon
```

> **Hint** Make sure to have `"emitDecoratorMetadata": true` in your tsconfig `compilerOptions` (NestJS standard).

#### Set up type definitions[#](/recipes/suites#set-up-type-definitions)

Create `global.d.ts` at your project root:

```typescript

/// <reference types="@suites/doubles.jest/unit" />
/// <reference types="@suites/di.nestjs/types" />
```

#### Create a sample service[#](/recipes/suites#create-a-sample-service)

This guide uses a simple `UserService` with two dependencies:

user.repository.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';

@Injectable()
export class UserRepository {
  async findById(id: string): Promise<User | null> {
    // Database query
  }

  async save(user: User): Promise<User> {
    // Database save
  }
}
```

user.service.ts

JS TS

```typescript

import { Injectable, NotFoundException } from '@nestjs/common';
import { Logger } from '@nestjs/common';

@Injectable()
export class UserService {
  constructor(
    private repository: UserRepository,
    private logger: Logger,
  ) {}

  async findById(id: string): Promise<User> {
    const user = await this.repository.findById(id);
    if (!user) {
      throw new NotFoundException(`User ${id} not found`);
    }
    this.logger.log(`Found user ${id}`);
    return user;
  }

  async create(email: string, name: string): Promise<User> {
    const user = { id: generateId(), email, name };
    await this.repository.save(user);
    this.logger.log(`Created user ${user.id}`);
    return user;
  }
}
```

#### Write a unit test[#](/recipes/suites#write-a-unit-test)

Use `TestBed.solitary()` to create isolated tests with all dependencies mocked:

user.service.spec.ts

JS TS

```typescript

import { TestBed, type Mocked } from '@suites/unit';
import { UserService } from './user.service';
import { UserRepository } from './user.repository';
import { Logger } from '@nestjs/common';

describe('User Service Unit Spec', () => {
  let userService: UserService;
  let repository: Mocked<UserRepository>;
  let logger: Mocked<Logger>;

  beforeAll(async () => {
    const { unit, unitRef } = await TestBed.solitary(UserService).compile();

    userService = unit;
    repository = unitRef.get(UserRepository);
    logger = unitRef.get(Logger);
  });

  it('should find user by id', async () => {
    const user = { id: '1', email: 'test@example.com', name: 'Test' };
    repository.findById.mockResolvedValue(user);

    const result = await userService.findById('1');

    expect(result).toEqual(user);
    expect(logger.log).toHaveBeenCalled();
  });
});
```

`TestBed.solitary()` analyzes the constructor and creates typed mocks for all dependencies. The `Mocked<T>` type provides IntelliSense support for mock configuration.

#### Pre-compile mock configuration[#](/recipes/suites#pre-compile-mock-configuration)

Configure mock behavior before compilation using `.mock().impl()`:

user.service.spec.ts

JS TS

```typescript

import { TestBed } from '@suites/unit';
import { UserService } from './user.service';
import { UserRepository } from './user.repository';

describe('User Service Unit Spec - pre-configured', () => {
  let unit: UserService;
  let repository: Mocked<UserRepository>;
  
  beforeAll(async () => {
    const { unit: underTest, unitRef } = await TestBed.solitary(UserService)
      .mock(UserRepository)
      .impl(stubFn => ({
        findById: stubFn().mockResolvedValue({ id: '1', email: 'test@example.com', name: 'Test' })
      }))
      .compile();
    
    repository = unitRef.get(UserRepository);
    unit = underTest;
  })
  
  it('should find user with pre-configured mock', async () => {
    const result = await unit.findById('1');
    
    expect(repository.findById).toHaveBeenCalled();
    expect(result.email).toBe('test@example.com');
  });
});
```

The `stubFn` parameter corresponds to the installed doubles adapter (`jest.fn()` for Jest, `vi.fn()` for Vitest, `sinon.stub()` for Sinon).

#### Testing with real dependencies[#](/recipes/suites#testing-with-real-dependencies)

Use `TestBed.sociable()` with `.expose()` to use real implementations for specific dependencies:

user.service.spec.ts

JS TS

```typescript

import { TestBed, Mocked } from '@suites/unit';
import { UserService } from './user.service';
import { UserRepository } from './user.repository';
import { Logger } from '@nestjs/common';

describe('UserService - with real logger', () => {
  let userService: UserService;
  let repository: Mocked<UserRepository>;

  beforeAll(async () => {
    const { unit, unitRef } = await TestBed.sociable(UserService)
      .expose(Logger)
      .compile();

    userService = unit;
    repository = unitRef.get(UserRepository);
  });

  it('should log when finding user', async () => {
    const user = { id: '1', email: 'test@example.com' };
    repository.findById.mockResolvedValue(user);

    await userService.findById('1');

    // Logger actually executes, no mock needed
  });
});
```

`.expose(Logger)` instantiates `Logger` with its real implementation while keeping other dependencies mocked.

#### Token-based dependencies[#](/recipes/suites#token-based-dependencies)

Suites handles custom injection tokens (strings or symbols):

config.service.ts

JS TS

```typescript

import { Injectable, Inject } from '@nestjs/common';

export const CONFIG_OPTIONS = 'CONFIG_OPTIONS';

@Injectable()
export class ConfigService {
  constructor(
    @Inject(CONFIG_OPTIONS) private options: { apiKey: string },
  ) {}

  getApiKey(): string {
    return this.options.apiKey;
  }
}
```

Access token-based dependencies with `unitRef.get()`:

config.service.spec.ts

JS TS

```typescript

import { TestBed } from '@suites/unit';
import { ConfigService, CONFIG_OPTIONS, ConfigOptions } from './config.service';

describe('Config Service Unit Spec', () => {
  let configService: ConfigService;
  let options: ConfigOptions;

  beforeAll(async () => {
    const { unit, unitRef } = await TestBed.solitary(ConfigService).compile();
    configService = unit;

    options = unitRef.get<ConfigOptions>(CONFIG_OPTIONS);
  });

  it('should return api key', () => { ... });
});
```

#### Using mock() and stub() directly[#](/recipes/suites#using-mock-and-stub-directly)

For those who prefer direct control without `TestBed`, the doubles adapter package provides `mock()` and `stub()` functions:

user.service.spec.ts

JS TS

```typescript

import { mock } from '@suites/unit';
import { UserRepository } from './user.repository';

describe('User Service Unit Spec', () => {
  it('should work with direct mocks', async () => {
    const repository = mock<UserRepository>();
    const logger = mock<Logger>();

    const service = new UserService(repository, logger);

    // ...
  });
});
```

`mock()` creates a typed mock object, and `stub()` wraps the underlying mocking library (Jest in this example) to provide methods like `mockResolvedValue()` These functions come from the installed doubles adapter (`@suites/doubles.jest`), which adapts the native mocking capabilities of the test framework.

> **Hint** The `mock()` function is an alternative to `createMock` from `@golevelup/ts-jest`. Both create typed mock objects. See the [testing fundamentals](/fundamentals/testing#auto-mocking) chapter for more on `createMock`.

#### Summary[#](/recipes/suites#summary)

**Use `Test.createTestingModule()` for:**

* Validating module configuration and provider wiring
* Testing decorators, guards, interceptors, and pipes
* Verifying dependency injection across modules
* Testing full application context with middleware

**Use Suites for:**

* Fast unit tests focused on business logic
* Automatic mock generation for multiple dependencies
* Type-safe test doubles with IntelliSense

Organize tests by purpose: use Suites for unit tests verifying individual service behavior, and use `Test.createTestingModule()` for integration tests verifying module configuration.

For more information:

* [Suites Documentation](https://suites.dev/docs)
* [Suites GitHub Repository](https://github.com/suites-dev/suites)
* [NestJS Testing Documentation](/v11/fundamentals/testing)

----
url: https://docs.nestjs.com/v9/recipes/swc
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [SWC](https://docs.nestjs.com/v9/recipes/swc#swc)
* [Installation](https://docs.nestjs.com/v9/recipes/swc#installation)
* [Scripts](https://docs.nestjs.com/v9/recipes/swc#scripts)
* [Common pitfalls](https://docs.nestjs.com/v9/recipes/swc#common-pitfalls)
* [Vitest](https://docs.nestjs.com/v9/recipes/swc#vitest)
* [Installation](https://docs.nestjs.com/v9/recipes/swc#installation-1)
* [Configuration](https://docs.nestjs.com/v9/recipes/swc#configuration)
* [Update imports in E2E tests](https://docs.nestjs.com/v9/recipes/swc#update-imports-in-e2e-tests)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/recipes/swc.md "Suggest Edits")

### SWC

> **Warning** SWC isn't compatible with **NestJS CLI plugins**. If you're using a plugin, you should stick to `tsc` or `webpack` (`nest build` and `nest start`).

[SWC](https://swc.rs/) (Speedy Web Compiler) is an extensible Rust-based platform that can be used for both compilation and bundling.

> **Hint** SWC is 20x faster than Babel on a single thread and 70x faster on four cores.

#### Installation[#](/recipes/swc#installation)

To get started, first install a few packages:

```bash

$ npm i --save-dev @swc/cli @swc/core nodemon
```

Once the installation process is complete, let's create a new `.swcrc` file in the root directory of your application:

```json

{
  "$schema": "https://json.schemastore.org/swcrc",
  "sourceMaps": true,
  "module": {
    "type": "commonjs"
  },
  "jsc": {
    "target": "es2017",
    "parser": {
      "syntax": "typescript",
      "decorators": true,
      "dynamicImport": true
    },
    "transform": {
      "legacyDecorator": true,
      "decoratorMetadata": true
    },
    "keepClassNames": true,
    "baseUrl": "./"
  },
  "minify": false
}
```

#### Scripts[#](/recipes/swc#scripts)

To make the development process easier, let's add a few scripts to the `package.json` file:

```json

{
  "scripts": {
    "build:swc": "npx swc --out-dir dist -w src",
    "start:swc": "nodemon dist/main"
  }
}
```

> **Hint** Both scripts are dedicated for development purposes only.

Now, open up the terminal and run the follwoing command:

```bash

$ npm run build:swc
```

In another terminal window, run the following command:

```bash

$ npm run start:swc
```

Every time you make a change to your application, the `build:swc` script will recompile your application and the `start:swc` script will restart the application.

#### Common pitfalls[#](/recipes/swc#common-pitfalls)

If you use TypeORM/MikroORM or any other ORM in your application, you may stumble upon circular import issues. SWC doesn't handle **circular imports** well, so you should use the following workaround:

```typescript

@Entity()
export class User {
  @OneToOne(() => Profile, (profile) => profile.user)
  profile: Relation<Profile>; // <--- see "Relation<>" type here instead of just "Profile"
}
```

> **Hint**`Relation` type is exported from the `typeorm` package.

Doing this prevents the type of the property from being saved in the transpiled code in the property metadata, preventing circular dependency issues.

If your ORM does not provide a similar workaround, you can define the wrapper type yourself:

```typescript

/**
 * Wrapper type used to circumvent ESM modules circular dependency issue
 * caused by reflection metadata saving the type of the property.
 */
export type WrapperType<T> = T; // WrapperType === Relation
```

### Vitest

[Vitest](https://vitest.dev/) is a fast and lightweight test runner designed to work with Vite. It provides a modern, fast, and easy-to-use testing solution that can be integrated with NestJS projects.

#### Installation[#](/recipes/swc#installation-1)

To get started, first install the required packages:

```bash

$ npm i --save-dev vitest unplugin-swc @swc/core @vitest/coverage-c8
```

#### Configuration[#](/recipes/swc#configuration)

Create a `vitest.config.ts` file in the root directory of your application with the following content:

```ts

import swc from 'unplugin-swc';
import { defineConfig } from 'vitest/config';

export default defineConfig({
  test: {
    globals: true,
    root: './',
  },
  plugins: [
    // This is required to build the test files with SWC
    swc.vite({
      // Explicitly set the module type to avoid inheriting this value from a `.swcrc` config file
      module: { type: 'es6' },
    }),
  ],
});
```

This configuration file sets up the Vitest environment, root directory, and SWC plugin. You should also create a separate configuration file for e2e tests, with an additional `include` field that specifies the test path regex:

```ts

import swc from 'unplugin-swc';
import { defineConfig } from 'vitest/config';

export default defineConfig({
  test: {
    include: ['**/*.e2e-spec.ts'],
    globals: true,
    root: './',
  },
  plugins: [swc.vite()],
});
```

Additionally, you can set the `alias` options to support TypeScript paths in your tests:

```ts

import swc from 'unplugin-swc';
import { defineConfig } from 'vitest/config';

export default defineConfig({
  test: {
    include: ['**/*.e2e-spec.ts'],
    globals: true,
    alias: {
      '@src': './src',
      '@test': './test',
    },
    root: './',
  },
  resolve: {
    alias: {
      '@src': './src',
      '@test': './test',
    },
  },
  plugins: [swc.vite()],
});
```

#### Update imports in E2E tests[#](/recipes/swc#update-imports-in-e2e-tests)

Change any E2E test imports using `import * as request from 'supertest'` to `import request from 'supertest'`. This is necessary because Vitest, when bundled with Vite, expects a default import for supertest. Using a namespace import may cause issues in this specific setup.

Lastly, update the test scripts in your package.json file to the following:

```json

{
  "scripts": {
    "test": "vitest run",
    "test:watch": "vitest",
    "test:cov": "vitest run --coverage",
    "test:debug": "vitest --inspect-brk --inspect --logHeapUsage --threads=false",
    "test:e2e": "vitest run --config ./vitest.config.e2e.ts"
  }
}
```

These scripts configure Vitest for running tests, watching for changes, generating code coverage reports, and debugging. The test:e2e script is specifically for running E2E tests with a custom configuration file.

With this setup, you can now enjoy the benefits of using Vitest in your NestJS project, including faster test execution and a more modern testing experience.

> **Hint** You can check out a working example in this [repository](https://github.com/TrilonIO/nest-vitest)

----
url: https://docs.nestjs.com/v4/recipes/sql-sequelize
----

### SQL (Sequelize)

##### This chapter applies only to TypeScript

[Sequelize](https://github.com/sequelize/sequelize) is the most popular Object Relational Mapper (ORM) available in the node.js world. It's written in plain JavaScript, but there's a [sequelize-typescript](https://github.com/RobinBuschmann/sequelize-typescript) TypeScript wrapper which provides a set of decorators and other extras for the base sequelize. To start the adventure with this library we have to install the following dependencies:

TypeScript

```typescript

  $ npm install --save sequelize sequelize-typescript mysql2
  $ npm install --save-dev @types/sequelize
```

The first step we need to do is create a **Sequelize** instance with an options object passed into the constructor. Also, we need to add all of the models (the alternative is to use `modelPaths` property) and `sync()` our database tables.

database.providers.ts

TypeScript

```typescript

import { Sequelize } from 'sequelize-typescript';
import { Cat } from '../cats/cat.entity';

export const databaseProviders = [
  {
    provide: 'SequelizeToken',
    useFactory: async () => {
      const sequelize = new Sequelize({
        dialect: 'mysql',
        host: 'localhost',
        port: 3306,
        username: 'root',
        password: 'password',
        database: 'nest',
      });
      sequelize.addModels([Cat]);
      await sequelize.sync();
      return sequelize;
    },
  },
];
```

> **Hint** Following best practices, we've declared the custom component in the separated file which has a `*.providers.ts` suffix.

Then we need to export these providers to make them **accessible** for the rest part of the application.

database.module.ts

TypeScript

```typescript

  import { Module } from '@nestjs/common';
  import { databaseProviders } from './database.providers';

  @Module({
    components: [...databaseProviders],
    exports: [...databaseProviders],
  })
  export class DatabaseModule {}
```

It's everything. Now we can inject the `Sequelize` object using `@Inject()` decorator. Each component which would depend on the `Sequelize` async component will wait until the `Promise` would be resolved.

#### Model injection

In [Sequelize](https://github.com/sequelize/sequelize) the **Model** represents a table in the database. Instances of this class represent a database row. Firstly, we need at least one entity:

cats/cat.entity.ts

TypeScript

```typescript

import { Table, Column, Model } from 'sequelize-typescript';

@Table
export class Cat extends Model<Cat> {
  @Column
  name: string;

  @Column
  age: number;

  @Column
  breed: string;
}
```

The `Cat` entity belongs to the `cats` directory. This directory represents the `CatsModule`. It's your decision where you gonna keep your model files. From my point of view, the best way's to hold them nearly their **domain**, in the appropriate module directory.

Now it's time to create a **Repository** component:

cats.providers.ts

TypeScript

```typescript

import { Cat } from './cat.entity';

export const catsProviders = [
  {
    provide: 'CatsRepository',
    useValue: Cat,
  },
];
```

> **Notice** In the real-world applications you should avoid **magic strings** at all. Both `CatsRepository` and `SequelizeToken` should be kept in the separated `constants.ts` file.

In Sequelize we're using static methods to manipulate the data, so we're just creating an **alias** here.

Now we can inject the `CatsRepository` to the `CatsService` using the `@Inject()` decorator:

cats.service.ts

TypeScript

```typescript

import { Component, Inject } from '@nestjs/common';
import { CreateCatDto } from './dto/create-cat.dto';
import { Cat } from './cat.entity';

@Component()
export class CatsService {
  constructor(
    @Inject('CatsRepository') private readonly catsRepository: typeof Cat) {}

  async findAll(): Promise<Cat[]> {
    return await this.catsRepository.findAll<Cat>();
  }
}
```

The database connection's **asynchronous**, but Nest makes this process's completely invisible for the end-user. The `CatsRepository` component's waiting for the db connection, and the `CatsService` is delayed until repository would be ready to use. The entire application can start when each component is instantiated.

Here's a final `CatsModule`:

cats.module.ts

TypeScript

```typescript

import { Module } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';
import { catsProviders } from './cats.providers';
import { DatabaseModule } from '../database/database.module';

@Module({
  imports: [DatabaseModule],
  controllers: [CatsController],
  components: [
    CatsService,
    ...catsProviders,
  ],
})
export class CatsModule {}
```

> **Hint** Don't forget to import the `CatsModule` into the root `ApplicationModule`.

The full source code's available [here](https://github.com/nestjs/nest/tree/master/examples/07-sequelize).

#### Sponsors

[](https://valor-software.com/)

Nest is an MIT-licensed open source project. It can grow thanks to the support by these awesome people. If you'd like to join them, please read more [here](https://opencollective.com/nest). Thanks!

[](https://opencollective.com/nest/backer/0/website)[](https://opencollective.com/nest/backer/1/website)[](https://opencollective.com/nest/backer/2/website)[](https://opencollective.com/nest/backer/3/website)[](https://opencollective.com/nest/backer/4/website)[](https://opencollective.com/nest/backer/5/website)[](https://opencollective.com/nest/backer/6/website)[](https://opencollective.com/nest/backer/7/website)[](https://opencollective.com/nest/backer/8/website)[](https://opencollective.com/nest/backer/9/website)[](https://opencollective.com/nest/backer/10/website)[](https://opencollective.com/nest/backer/11/website)[](https://opencollective.com/nest/backer/12/website)[](https://opencollective.com/nest/backer/13/website)[](https://opencollective.com/nest/backer/14/website)[](https://opencollective.com/nest/backer/15/website)[](https://opencollective.com/nest/backer/16/website)[](https://opencollective.com/nest/backer/17/website)[](https://opencollective.com/nest/backer/18/website)[](https://opencollective.com/nest/backer/19/website)[](https://opencollective.com/nest/backer/20/website)[](https://opencollective.com/nest/backer/21/website)[](https://opencollective.com/nest/backer/22/website)[](https://opencollective.com/nest/backer/23/website)[](https://opencollective.com/nest/backer/24/website)[](https://opencollective.com/nest/backer/25/website)[](https://opencollective.com/nest/backer/26/website)[](https://opencollective.com/nest/backer/27/website)[](https://opencollective.com/nest/backer/28/website)[](https://opencollective.com/nest/backer/29/website)

[Become a sponsor](https://opencollective.com/nest)

----
url: https://docs.nestjs.com/v11/recipes/serve-static
----

* [Serve Static](https://docs.nestjs.com/v11/recipes/serve-static#serve-static)
* [Installation](https://docs.nestjs.com/v11/recipes/serve-static#installation)
* [Bootstrap](https://docs.nestjs.com/v11/recipes/serve-static#bootstrap)
* [Configuration](https://docs.nestjs.com/v11/recipes/serve-static#configuration)
* [Example](https://docs.nestjs.com/v11/recipes/serve-static#example)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/recipes/serve-static.md "Suggest Edits")

### Serve Static

In order to serve static content like a Single Page Application (SPA) we can use the `ServeStaticModule` from the [`@nestjs/serve-static`](https://www.npmjs.com/package/@nestjs/serve-static) package.

#### Installation[#](/recipes/serve-static#installation)

First we need to install the required package:

```bash

$ npm install --save @nestjs/serve-static
```

#### Bootstrap[#](/recipes/serve-static#bootstrap)

Once the installation process is done, we can import the `ServeStaticModule` into the root `AppModule` and configure it by passing in a configuration object to the `forRoot()` method.

```typescript

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { ServeStaticModule } from '@nestjs/serve-static';
import { join } from 'path';

@Module({
  imports: [
    ServeStaticModule.forRoot({
      rootPath: join(__dirname, '..', 'client'),
    }),
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}
```

With this in place, build the static website and place its content in the location specified by the `rootPath` property.

#### Configuration[#](/recipes/serve-static#configuration)

[ServeStaticModule](https://github.com/nestjs/serve-static) can be configured with a variety of options to customize its behavior. You can set the path to render your static app, specify excluded paths, enable or disable setting Cache-Control response header, etc. See the full list of options [here](https://github.com/nestjs/serve-static/blob/master/lib/interfaces/serve-static-options.interface.ts).

> **Notice** The default `renderPath` of the Static App is `*` (all paths), and the module will send "index.html" files in response. It lets you create Client-Side routing for your SPA. Paths, specified in your controllers will fallback to the server. You can change this behavior setting `serveRoot`, `renderPath` combining them with other options. Additionally, the option `serveStaticOptions.fallthrough` has been implemented in the Fastify adapter to mimic Express's fallthrough behavior and needs to be set to `true` to send `index.html` instead of a 404 error for non existing route.

#### Example[#](/recipes/serve-static#example)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/24-serve-static).

----
url: https://docs.nestjs.com/v9/fundamentals/testing
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Testing](https://docs.nestjs.com/v9/fundamentals/testing#testing)
* [Installation](https://docs.nestjs.com/v9/fundamentals/testing#installation)
* [Unit testing](https://docs.nestjs.com/v9/fundamentals/testing#unit-testing)
* [Testing utilities](https://docs.nestjs.com/v9/fundamentals/testing#testing-utilities)
* [Auto mocking](https://docs.nestjs.com/v9/fundamentals/testing#auto-mocking)
* [End-to-end testing](https://docs.nestjs.com/v9/fundamentals/testing#end-to-end-testing)
* [Overriding globally registered enhancers](https://docs.nestjs.com/v9/fundamentals/testing#overriding-globally-registered-enhancers)
* [Testing request-scoped instances](https://docs.nestjs.com/v9/fundamentals/testing#testing-request-scoped-instances)

```bash

$ npm i --save-dev @nestjs/testing
```

#### Unit testing[#](/fundamentals/testing#unit-testing)

In the following example, we test two classes: `CatsController` and `CatsService`. As mentioned, [Jest](https://github.com/facebook/jest) is provided as the default testing framework. It serves as a test-runner and also provides assert functions and test-double utilities that help with mocking, spying, etc. In the following basic test, we manually instantiate these classes, and ensure that the controller and service fulfill their API contract.

cats.controller.spec.ts

JS TS

```typescript

import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

describe('CatsController', () => {
  let catsController: CatsController;
  let catsService: CatsService;

  beforeEach(() => {
    catsService = new CatsService();
    catsController = new CatsController(catsService);
  });

  describe('findAll', () => {
    it('should return an array of cats', async () => {
      const result = ['test'];
      jest.spyOn(catsService, 'findAll').mockImplementation(() => result);

      expect(await catsController.findAll()).toBe(result);
    });
  });
});
```

```typescript

import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

describe('CatsController', () => {
  let catsController;
  let catsService;

  beforeEach(() => {
    catsService = new CatsService();
    catsController = new CatsController(catsService);
  });

  describe('findAll', () => {
    it('should return an array of cats', async () => {
      const result = ['test'];
      jest.spyOn(catsService, 'findAll').mockImplementation(() => result);

      expect(await catsController.findAll()).toBe(result);
    });
  });
});
```

> **Hint** Keep your test files located near the classes they test. Testing files should have a `.spec` or `.test` suffix.

Because the above sample is trivial, we aren't really testing anything Nest-specific. Indeed, we aren't even using dependency injection (notice that we pass an instance of `CatsService` to our `catsController`). This form of testing - where we manually instantiate the classes being tested - is often called **isolated testing** as it is independent from the framework. Let's introduce some more advanced capabilities that help you test applications that make more extensive use of Nest features.

#### Testing utilities[#](/fundamentals/testing#testing-utilities)

The `@nestjs/testing` package provides a set of utilities that enable a more robust testing process. Let's rewrite the previous example using the built-in `Test` class:

cats.controller.spec.ts

JS TS

```typescript

import { Test } from '@nestjs/testing';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

describe('CatsController', () => {
  let catsController: CatsController;
  let catsService: CatsService;

  beforeEach(async () => {
    const moduleRef = await Test.createTestingModule({
        controllers: [CatsController],
        providers: [CatsService],
      }).compile();

    catsService = moduleRef.get<CatsService>(CatsService);
    catsController = moduleRef.get<CatsController>(CatsController);
  });

  describe('findAll', () => {
    it('should return an array of cats', async () => {
      const result = ['test'];
      jest.spyOn(catsService, 'findAll').mockImplementation(() => result);

      expect(await catsController.findAll()).toBe(result);
    });
  });
});
```

```typescript

import { Test } from '@nestjs/testing';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

describe('CatsController', () => {
  let catsController;
  let catsService;

  beforeEach(async () => {
    const moduleRef = await Test.createTestingModule({
        controllers: [CatsController],
        providers: [CatsService],
      }).compile();

    catsService = moduleRef.get(CatsService);
    catsController = moduleRef.get(CatsController);
  });

  describe('findAll', () => {
    it('should return an array of cats', async () => {
      const result = ['test'];
      jest.spyOn(catsService, 'findAll').mockImplementation(() => result);

      expect(await catsController.findAll()).toBe(result);
    });
  });
});
```

The `Test` class is useful for providing an application execution context that essentially mocks the full Nest runtime, but gives you hooks that make it easy to manage class instances, including mocking and overriding. The `Test` class has a `createTestingModule()` method that takes a module metadata object as its argument (the same object you pass to the `@Module()` decorator). This method returns a `TestingModule` instance which in turn provides a few methods. For unit tests, the important one is the `compile()` method. This method bootstraps a module with its dependencies (similar to the way an application is bootstrapped in the conventional `main.ts` file using `NestFactory.create()`), and returns a module that is ready for testing.

> **Hint** The `compile()` method is **asynchronous** and therefore has to be awaited. Once the module is compiled you can retrieve any **static** instance it declares (controllers and providers) using the `get()` method.

`TestingModule` inherits from the [module reference](/v9/fundamentals/module-ref) class, and therefore its ability to dynamically resolve scoped providers (transient or request-scoped). Do this with the `resolve()` method (the `get()` method can only retrieve static instances).

```typescript

const moduleRef = await Test.createTestingModule({
  controllers: [CatsController],
  providers: [CatsService],
}).compile();

catsService = await moduleRef.resolve(CatsService);
```

> **Warning** The `resolve()` method returns a unique instance of the provider, from its own **DI container sub-tree**. Each sub-tree has a unique context identifier. Thus, if you call this method more than once and compare instance references, you will see that they are not equal.

> **Hint** Learn more about the module reference features [here](/v9/fundamentals/module-ref).

Instead of using the production version of any provider, you can override it with a [custom provider](/v9/fundamentals/custom-providers) for testing purposes. For example, you can mock a database service instead of connecting to a live database. We'll cover overrides in the next section, but they're available for unit tests as well.

```typescript

// ...
import { ModuleMocker, MockFunctionMetadata } from 'jest-mock';

const moduleMocker = new ModuleMocker(global);

describe('CatsController', () => {
  let controller: CatsController;

  beforeEach(async () => {
    const moduleRef = await Test.createTestingModule({
      controllers: [CatsController],
    })
    .useMocker((token) => {
      const results = ['test1', 'test2'];
      if (token === CatsService) {
        return { findAll: jest.fn().mockResolvedValue(results) };
      }
      if (typeof token === 'function') {
        const mockMetadata = moduleMocker.getMetadata(token) as MockFunctionMetadata<any, any>;
        const Mock = moduleMocker.generateFromMetadata(mockMetadata);
        return new Mock();
      }
    })
    .compile();
    
    controller = moduleRef.get(CatsController);
  });
});
```

You can also retrieve these mocks out of the testing container as you normally would custom providers, `moduleRef.get(CatsService)`.

> **Hint** A general mock factory, like `createMock` from [`@golevelup/ts-jest`](https://github.com/golevelup/nestjs/tree/master/packages/testing) can also be passed directly.

> **Hint**`REQUEST` and `INQUIRER` providers cannot be auto-mocked because they're already pre-defined in the context. However, they can be *overwritten* using the custom provider syntax or by utilizing the `.overrideProvider` method.

#### End-to-end testing[#](/fundamentals/testing#end-to-end-testing)

Unlike unit testing, which focuses on individual modules and classes, end-to-end (e2e) testing covers the interaction of classes and modules at a more aggregate level -- closer to the kind of interaction that end-users will have with the production system. As an application grows, it becomes hard to manually test the end-to-end behavior of each API endpoint. Automated end-to-end tests help us ensure that the overall behavior of the system is correct and meets project requirements. To perform e2e tests we use a similar configuration to the one we just covered in **unit testing**. In addition, Nest makes it easy to use the [Supertest](https://github.com/visionmedia/supertest) library to simulate HTTP requests.

cats.e2e-spec.ts

JS TS

```typescript

import * as request from 'supertest';
import { Test } from '@nestjs/testing';
import { CatsModule } from '../../src/cats/cats.module';
import { CatsService } from '../../src/cats/cats.service';
import { INestApplication } from '@nestjs/common';

describe('Cats', () => {
  let app: INestApplication;
  let catsService = { findAll: () => ['test'] };

  beforeAll(async () => {
    const moduleRef = await Test.createTestingModule({
      imports: [CatsModule],
    })
      .overrideProvider(CatsService)
      .useValue(catsService)
      .compile();

    app = moduleRef.createNestApplication();
    await app.init();
  });

  it(`/GET cats`, () => {
    return request(app.getHttpServer())
      .get('/cats')
      .expect(200)
      .expect({
        data: catsService.findAll(),
      });
  });

  afterAll(async () => {
    await app.close();
  });
});
```

```typescript

import * as request from 'supertest';
import { Test } from '@nestjs/testing';
import { CatsModule } from '../../src/cats/cats.module';
import { CatsService } from '../../src/cats/cats.service';
import { INestApplication } from '@nestjs/common';

describe('Cats', () => {
  let app: INestApplication;
  let catsService = { findAll: () => ['test'] };

  beforeAll(async () => {
    const moduleRef = await Test.createTestingModule({
      imports: [CatsModule],
    })
      .overrideProvider(CatsService)
      .useValue(catsService)
      .compile();

    app = moduleRef.createNestApplication();
    await app.init();
  });

  it(`/GET cats`, () => {
    return request(app.getHttpServer())
      .get('/cats')
      .expect(200)
      .expect({
        data: catsService.findAll(),
      });
  });

  afterAll(async () => {
    await app.close();
  });
});
```

> **Hint** If you're using [Fastify](/v9/techniques/performance) as your HTTP adapter, it requires a slightly different configuration, and has built-in testing capabilities:
>
> ```ts
>
> let app: NestFastifyApplication;
>
> beforeAll(async () => {
>   app = moduleRef.createNestApplication<NestFastifyApplication>(
>     new FastifyAdapter(),
>   );
>
>   await app.init();
>   await app.getHttpAdapter().getInstance().ready();
> });
>
> it(`/GET cats`, () => {
>   return app
>     .inject({
>       method: 'GET',
>       url: '/cats',
>     })
>     .then((result) => {
>       expect(result.statusCode).toEqual(200);
>       expect(result.payload).toEqual(/* expectedPayload */);
>     });
> });
>
> afterAll(async () => {
>   await app.close();
> });
> ```

Also, sometimes you may want to provide a custom logger e.g. when the tests are run (for example, on a CI server). Use the `setLogger()` method and pass an object that fulfills the `LoggerService` interface to instruct the `TestModuleBuilder` how to log during tests (by default, only "error" logs will be logged to the console).

> **Warning** The `@nestjs/core` package exposes unique provider tokens with the `APP_` prefix to help on define global enhancers. Those tokens cannot be overridden since they can represent multiple providers. Thus you can't use `.overrideProvider(APP_GUARD)` (and so on). If you want to override some global enhancer, follow [this workaround](https://github.com/nestjs/nest/issues/4053#issuecomment-585612462).

The compiled module has several useful methods, as described in the following table:

|                            |                                                                                                                                                                                                                                                   |
| -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `createNestApplication()`  | Creates and returns a Nest application (`INestApplication` instance) based on the given module. Note that you must manually initialize the application using the `init()` method.                                                                 |
| `createNestMicroservice()` | Creates and returns a Nest microservice (`INestMicroservice` instance) based on the given module.                                                                                                                                                 |
| `get()`                    | Retrieves a static instance of a controller or provider (including guards, filters, etc.) available in the application context. Inherited from the [module reference](/fundamentals/module-ref) class.                                            |
| `resolve()`                | Retrieves a dynamically created scoped instance (request or transient) of a controller or provider (including guards, filters, etc.) available in the application context. Inherited from the [module reference](/fundamentals/module-ref) class. |
| `select()`                 | Navigates through the module's dependency graph; can be used to retrieve a specific instance from the selected module (used along with strict mode (`strict: true`) in `get()` method).                                                           |

> **Hint** Keep your e2e test files inside the `test` directory. The testing files should have a `.e2e-spec` suffix.

#### Overriding globally registered enhancers[#](/fundamentals/testing#overriding-globally-registered-enhancers)

If you have a globally registered guard (or pipe, interceptor, or filter), you need to take a few more steps to override that enhancer. To recap the original registration looks like this:

```typescript

providers: [
  {
    provide: APP_GUARD,
    useClass: JwtAuthGuard,
  },
],
```

This is registering the guard as a "multi"-provider through the `APP_*` token. To be able to replace the `JwtAuthGuard` here, the registration needs to use an existing provider in this slot:

```typescript

providers: [
  {
    provide: APP_GUARD,
    useExisting: JwtAuthGuard,
    // ^^^^^^^^ notice the use of 'useExisting' instead of 'useClass'
  },
  JwtAuthGuard,
],
```

> **Hint** Change the `useClass` to `useExisting` to reference a registered provider instead of having Nest instantiate it behind the token.

Now the `JwtAuthGuard` is visible to Nest as a regular provider that can be overridden when creating the `TestingModule`:

```typescript

const moduleRef = await Test.createTestingModule({
  imports: [AppModule],
})
  .overrideProvider(JwtAuthGuard)
  .useClass(MockAuthGuard)
  .compile();
```

Now all your tests will use the `MockAuthGuard` on every request.

#### Testing request-scoped instances[#](/fundamentals/testing#testing-request-scoped-instances)

[Request-scoped](/v9/fundamentals/injection-scopes) providers are created uniquely for each incoming **request**. The instance is garbage-collected after the request has completed processing. This poses a problem, because we can't access a dependency injection sub-tree generated specifically for a tested request.

We know (based on the sections above) that the `resolve()` method can be used to retrieve a dynamically instantiated class. Also, as described [here](https://docs.nestjs.com/fundamentals/module-ref#resolving-scoped-providers), we know we can pass a unique context identifier to control the lifecycle of a DI container sub-tree. How do we leverage this in a testing context?

The strategy is to generate a context identifier beforehand and force Nest to use this particular ID to create a sub-tree for all incoming requests. In this way we'll be able to retrieve instances created for a tested request.

To accomplish this, use `jest.spyOn()` on the `ContextIdFactory`:

```typescript

const contextId = ContextIdFactory.create();
jest
  .spyOn(ContextIdFactory, 'getByRequest')
  .mockImplementation(() => contextId);
```

Now we can use the `contextId` to access a single generated DI container sub-tree for any subsequent request.

```typescript

catsService = await moduleRef.resolve(CatsService, contextId);
```

----
url: https://docs.nestjs.com/v8/application-context
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Standalone applications](https://docs.nestjs.com/v8/standalone-applications#standalone-applications)
* [Getting started](https://docs.nestjs.com/v8/standalone-applications#getting-started)
* [Example](https://docs.nestjs.com/v8/standalone-applications#example)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/application-context.md "Suggest Edits")

### Standalone applications

There are several ways of mounting a Nest application. You can create a web app, a microservice or just a bare Nest **standalone application** (without any network listeners). The Nest standalone application is a wrapper around the Nest **IoC container**, which holds all instantiated classes. We can obtain a reference to any existing instance from within any imported module directly using the standalone application object. Thus, you can take advantage of the Nest framework anywhere, including, for example, scripted **CRON** jobs. You can even build a **CLI** on top of it.

#### Getting started[#](/standalone-applications#getting-started)

To create a Nest standalone application, use the following construction:

JS TS

```typescript

async function bootstrap() {
  const app = await NestFactory.createApplicationContext(AppModule);
  // application logic...
}
bootstrap();
```

The standalone application object allows you to obtain a reference to any instance registered within the Nest application. Let's imagine that we have a `TasksService` in the `TasksModule`. This class provides a set of methods that we want to call from within a CRON job.

JS TS

```typescript

const app = await NestFactory.createApplicationContext(AppModule);
const tasksService = app.get(TasksService);
```

To access the `TasksService` instance we use the `get()` method. The `get()` method acts like a **query** that searches for an instance in each registered module. Alternatively, for strict context checking, pass an options object with the `strict: true` property. With this option in effect, you have to navigate through specific modules to obtain a particular instance from the selected context.

JS TS

```typescript

const app = await NestFactory.createApplicationContext(AppModule);
const tasksService = app.select(TasksModule).get(TasksService, { strict: true });
```

Following is a summary of the methods available for retrieving instance references from the standalone application object.

|            |                                                                                                                                                  |
| ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| `get()`    | Retrieves an instance of a controller or provider (including guards, filters, and so on) available in the application context.                   |
| `select()` | Navigates through the module's graph to pull out a specific instance of the selected module (used together with strict mode as described above). |

> **Hint** In non-strict mode, the root module is selected by default. To select any other module, you need to navigate the modules graph manually, step by step.

If you want the node application to close after the script finishes (e.g., for a script running CRON jobs), add `await app.close()` to the end of your `bootstrap` function:

JS TS

```typescript

async function bootstrap() {
  const app = await NestFactory.createApplicationContext(AppModule);
  // application logic...
  await app.close();
}
bootstrap();
```

#### Example[#](/standalone-applications#example)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/18-context).

----
url: https://docs.nestjs.com/v7/websockets/gateways
----

* [Gateways](https://docs.nestjs.com/v7/websockets/gateways#gateways)
* [Installation](https://docs.nestjs.com/v7/websockets/gateways#installation)
* [Overview](https://docs.nestjs.com/v7/websockets/gateways#overview)
* [Multiple responses](https://docs.nestjs.com/v7/websockets/gateways#multiple-responses)
* [Asynchronous responses](https://docs.nestjs.com/v7/websockets/gateways#asynchronous-responses)
* [Lifecycle hooks](https://docs.nestjs.com/v7/websockets/gateways#lifecycle-hooks)
* [Server](https://docs.nestjs.com/v7/websockets/gateways#server)
* [Example](https://docs.nestjs.com/v7/websockets/gateways#example)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/websockets/gateways.md "Suggest Edits")

### Gateways

Most of the concepts discussed elsewhere in this documentation, such as dependency injection, decorators, exception filters, pipes, guards and interceptors, apply equally to gateways. Wherever possible, Nest abstracts implementation details so that the same components can run across HTTP-based platforms, WebSockets, and Microservices. This section covers the aspects of Nest that are specific to WebSockets.

In Nest, a gateway is simply a class annotated with `@WebSocketGateway()` decorator. Technically, gateways are platform-agnostic which makes them compatible with any WebSockets library once an adapter is created. There are two WS platforms supported out-of-the-box: [socket.io](https://github.com/socketio/socket.io) and [ws](https://github.com/websockets/ws). You can choose the one that best suits your needs. Also, you can build your own adapter by following this [guide](/v7/websockets/adapter).

> **Hint** Gateways can be treated as [providers](/v7/providers); this means they can inject dependencies through the class constructor. Also, gateways can be injected by other classes (providers and controllers) as well.

#### Installation[#](/websockets/gateways#installation)

To start building WebSockets-based applications, first install the required package:

JS TS

```typescript

$ npm i --save @nestjs/websockets @nestjs/platform-socket.io
$ npm i --save-dev @types/socket.io
```

```typescript

$ npm i --save @nestjs/websockets @nestjs/platform-socket.io
```

> **Warning**`@nestjs/platform-socket.io` currently depends on socket.io v2.3 and socket.io v3.0 client and server are not backward compatible. However, you can still implement a custom adapter to use socket.io v3.0. Please refer to [this issue](https://github.com/nestjs/nest/issues/5676) for further information.

#### Overview[#](/websockets/gateways#overview)

In general, each gateway is listening on the same port as the **HTTP server**, unless your app is not a web application, or you have changed the port manually. This default behavior can be modified by passing an argument to the `@WebSocketGateway(80)` decorator where `80` is a chosen port number. You can also set a [namespace](https://socket.io/docs/rooms-and-namespaces/) used by the gateway using the following construction:

```typescript

@WebSocketGateway(80, { namespace: 'events' })
```

> **Warning** Gateways are not instantiated until they are referenced in the providers array of an existing module.

You can pass any supported [option](https://socket.io/docs/server-api/) to the socket constructor with the second argument to the `@WebSocketGateway()` decorator, as shown below:

```typescript

@WebSocketGateway(81, { transports: ['websocket'] })
```

The gateway is now listening, but we have not yet subscribed to any incoming messages. Let's create a handler that will subscribe to the `events` messages and respond to the user with the exact same data.

events.gateway.ts

JS TS

```typescript

@SubscribeMessage('events')
handleEvent(@MessageBody() data: string): string {
  return data;
}
```

```typescript

@Bind(MessageBody())
@SubscribeMessage('events')
handleEvent(data) {
  return data;
}
```

> **Hint**`@SubscribeMessage()` and `@MessageBody()` decorators are imported from `@nestjs/websockets` package.

If you would prefer not to use decorators, the following code is functionally equivalent:

events.gateway.ts

JS TS

```typescript

@SubscribeMessage('events')
handleEvent(client: Socket, data: string): string {
  return data;
}
```

```typescript

@SubscribeMessage('events')
handleEvent(client, data) {
  return data;
}
```

In the example above, the `handleEvent()` function takes two arguments. The first one is a platform-specific [socket instance](https://socket.io/docs/server-api/#socket), while the second one is the data received from the client. This approach is not recommended though, because it requires mocking the `socket` instance in each unit test.

Once the `events` message is received, the handler sends an acknowledgment with the same data that was sent over the network. In addition, it's possible to emit messages using a library-specific approach, for example, by making use of `client.emit()` method. In order to access a connected socket instance, use `@ConnectedSocket()` decorator.

events.gateway.ts

JS TS

```typescript

@SubscribeMessage('events')
handleEvent(
  @MessageBody() data: string,
  @ConnectedSocket() client: Socket,
): string {
  return data;
}
```

```typescript

@Bind(MessageBody(), ConnectedSocket())
@SubscribeMessage('events')
handleEvent(data, client) {
  return data;
}
```

> **Hint**`@ConnectedSocket()` decorator is imported from `@nestjs/websockets` package.

However, in this case, you won't be able to leverage interceptors. If you don't want to respond to the user, you can simple skip the `return` statement (or explicitly return "falsy" value, e.g. `undefined`).

Now when a client emits the message as follows:

```typescript

socket.emit('events', { name: 'Nest' });
```

The `handleEvent()` method will be executed. In order to listen for messages emitted from within the above handler, the client has to attach a corresponding acknowledgment listener:

```typescript

socket.emit('events', { name: 'Nest' }, data => console.log(data));
```

#### Multiple responses[#](/websockets/gateways#multiple-responses)

The acknowledgment is dispatched only once. Furthermore, it is not supported by native WebSockets implementation. To solve this limitation, you may return an object which consist of two properties. The `event` which is a name of the emitted event and the `data` that has to be forwarded to the client.

events.gateway.ts

JS TS

```typescript

@SubscribeMessage('events')
handleEvent(@MessageBody() data: unknown): WsResponse<unknown> {
  const event = 'events';
  return { event, data };
}
```

```typescript

@Bind(MessageBody())
@SubscribeMessage('events')
handleEvent(data) {
  const event = 'events';
  return { event, data };
}
```

> **Hint** The `WsResponse` interface is imported from `@nestjs/websockets` package.

> **Warning** You should return a class instance that implements `WsResponse` if your `data` field relies on `ClassSerializerInterceptor`, as it ignores plain JavaScript objects responses.

In order to listen for the incoming response(s), the client has to apply another event listener.

```typescript

socket.on('events', data => console.log(data));
```

#### Asynchronous responses[#](/websockets/gateways#asynchronous-responses)

Message handlers are able to respond either synchronously or **asynchronously**. Hence, `async` methods are supported. A message handler is also able to return an `Observable`, in which case the result values will be emitted until the stream is completed.

events.gateway.ts

JS TS

```typescript

@SubscribeMessage('events')
onEvent(@MessageBody() data: unknown): Observable<WsResponse<number>> {
  const event = 'events';
  const response = [1, 2, 3];

  return from(response).pipe(
    map(data => ({ event, data })),
  );
}
```

```typescript

@Bind(MessageBody())
@SubscribeMessage('events')
onEvent(data) {
  const event = 'events';
  const response = [1, 2, 3];

  return from(response).pipe(
    map(data => ({ event, data })),
  );
}
```

In the example above, the message handler will respond **3 times** (with each item from the array).

#### Lifecycle hooks[#](/websockets/gateways#lifecycle-hooks)

There are 3 useful lifecycle hooks available. All of them have corresponding interfaces and are described in the following table:

|                       |                                                                                                                                         |
| --------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| `OnGatewayInit`       | Forces to implement the `afterInit()` method. Takes library-specific server instance as an argument (and spreads the rest if required). |
| `OnGatewayConnection` | Forces to implement the `handleConnection()` method. Takes library-specific client socket instance as an argument.                      |
| `OnGatewayDisconnect` | Forces to implement the `handleDisconnect()` method. Takes library-specific client socket instance as an argument.                      |

> **Hint** Each lifecycle interface is exposed from `@nestjs/websockets` package.

#### Server[#](/websockets/gateways#server)

Occasionally, you may want to have a direct access to the native, **platform-specific** server instance. The reference to this object is passed as an argument to the `afterInit()` method (`OnGatewayInit` interface). Another option is to use the `@WebSocketServer()` decorator.

```typescript

@WebSocketServer()
server: Server;
```

> **Notice** The `@WebSocketServer()` decorator is imported from the `@nestjs/websockets` package.

----
url: https://docs.nestjs.com/v7/fundamentals/lifecycle-events
----

* [Lifecycle Events](https://docs.nestjs.com/v7/fundamentals/lifecycle-events#lifecycle-events)
* [Lifecycle sequence](https://docs.nestjs.com/v7/fundamentals/lifecycle-events#lifecycle-sequence)
* [Lifecycle events](https://docs.nestjs.com/v7/fundamentals/lifecycle-events#lifecycle-events-1)
* [Usage](https://docs.nestjs.com/v7/fundamentals/lifecycle-events#usage)
* [Asynchronous initialization](https://docs.nestjs.com/v7/fundamentals/lifecycle-events#asynchronous-initialization)
* [Application shutdown](https://docs.nestjs.com/v7/fundamentals/lifecycle-events#application-shutdown)

| Lifecycle hook method           | Lifecycle event triggering the hook method call                                                                                                                                                              |
| ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `onModuleInit()`                | Called once the host module's dependencies have been resolved.                                                                                                                                               |
| `onApplicationBootstrap()`      | Called once all modules have been initialized, but before listening for connections.                                                                                                                         |
| `onModuleDestroy()`\*           | Called after a termination signal (e.g., `SIGTERM`) has been received.                                                                                                                                       |
| `beforeApplicationShutdown()`\* | Called after all `onModuleDestroy()` handlers have completed (Promises resolved or rejected); once complete (Promises resolved or rejected), all existing connections will be closed (`app.close()` called). |
| `onApplicationShutdown()`\*     | Called after connections close (`app.close()` resolves.                                                                                                                                                      |

\* For these events, if you're not calling `app.close()` explicitly, you must opt-in to make them work with system signals such as `SIGTERM`. See [Application shutdown](fundamentals/lifecycle-events#application-shutdown) below.

> **Warning** The lifecycle hooks listed above are not triggered for **request-scoped** classes. Request-scoped classes are not tied to the application lifecycle and their lifespan is unpredictable. They are exclusively created for each request and automatically garbage-collected after the response is sent.

#### Usage[#](/fundamentals/lifecycle-events#usage)

Each lifecycle hook is represented by an interface. Interfaces are technically optional because they do not exist after TypeScript compilation. Nonetheless, it's good practice to use them in order to benefit from strong typing and editor tooling. To register a lifecycle hook, implement the appropriate interface. For example, to register a method to be called during module initialization on a particular class (e.g., Controller, Provider or Module), implement the `OnModuleInit` interface by supplying an `onModuleInit()` method, as shown below:

JS TS

```typescript

import { Injectable, OnModuleInit } from '@nestjs/common';

@Injectable()
export class UsersService implements OnModuleInit {
  onModuleInit() {
    console.log(`The module has been initialized.`);
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';

@Injectable()
export class UsersService {
  onModuleInit() {
    console.log(`The module has been initialized.`);
  }
}
```

#### Asynchronous initialization[#](/fundamentals/lifecycle-events#asynchronous-initialization)

Both the `OnModuleInit` and `OnApplicationBootstrap` hooks allow you to defer the application initialization process (return a `Promise` or mark the method as `async` and `await` an asynchronous method completion in the method body).

JS TS

```typescript

async onModuleInit(): Promise<void> {
  await this.fetch();
}
```

```typescript

async onModuleInit() {
  await this.fetch();
}
```

#### Application shutdown[#](/fundamentals/lifecycle-events#application-shutdown)

The `onModuleDestroy()`, `beforeApplicationShutdown()` and `onApplicationShutdown()` hooks are called in the terminating phase (in response to an explicit call to `app.close()` or upon receipt of system signals such as SIGTERM if opted-in). This feature is often used with [Kubernetes](https://kubernetes.io/) to manage containers' lifecycles, by [Heroku](https://www.heroku.com/) for dynos or similar services.

Shutdown hook listeners consume system resources, so they are disabled by default. To use shutdown hooks, you **must enable listeners** by calling `enableShutdownHooks()`:

```typescript

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);

  // Starts listening for shutdown hooks
  app.enableShutdownHooks();

  await app.listen(3000);
}
bootstrap();
```

> **warning** Due to inherent platform limitations, NestJS has limited support for application shutdown hooks on Windows. You can expect `SIGINT` to work, as well as `SIGBREAK` and to some extent `SIGHUP` - [read more](https://nodejs.org/api/process.html#process_signal_events). However `SIGTERM` will never work on Windows because killing a process in the task manager is unconditional, "i.e., there's no way for an application to detect or prevent it". Here's some [relevant documentation](https://docs.libuv.org/en/v1.x/signal.html) from libuv to learn more about how `SIGINT`, `SIGBREAK` and others are handled on Windows. Also, see Node.js documentation of [Process Signal Events](https://nodejs.org/api/process.html#process_signal_events)

> **Info**`enableShutdownHooks` consumes memory by starting listeners. In cases where you are running multiple Nest apps in a single Node process (e.g., when running parallel tests with Jest), Node may complain about excessive listener processes. For this reason, `enableShutdownHooks` is not enabled by default. Be aware of this condition when you are running multiple instances in a single Node process.

When the application receives a termination signal it will call any registered `onModuleDestroy()`, `beforeApplicationShutdown()`, then `onApplicationShutdown()` methods (in the sequence described above) with the corresponding signal as the first parameter. If a registered function awaits an asynchronous call (returns a promise), Nest will not continue in the sequence until the promise is resolved or rejected.

JS TS

```typescript

@Injectable()
class UsersService implements OnApplicationShutdown {
  onApplicationShutdown(signal: string) {
    console.log(signal); // e.g. "SIGINT"
  }
}
```

```typescript

@Injectable()
class UsersService implements OnApplicationShutdown {
  onApplicationShutdown(signal) {
    console.log(signal); // e.g. "SIGINT"
  }
}
```

----
url: https://docs.nestjs.com/v5/microservices/mqtt
----

### MQTT

The [MQTT](http://mqtt.org/) is a lightweight messaging protocol, optimized for high-latency.

#### Installation

Before we start, we have to install required package:

```bash

$ npm i --save mqtt
```

#### Overview

In order to switch to **MQTT** transporter, we need to modify an options object passed to the `createMicroservice()` method.

main.ts

JS TS

TypeScript

```typescript

const app = await NestFactory.createMicroservice(ApplicationModule, {
  transport: Transport.MQTT,
  options: {
    host: 'localhost',
    port: 1883,
  },
});
```

#### Options

There are a bunch of available options that determine a transporter behavior. They are well-described [here](https://github.com/mqttjs/MQTT.js).

* MQTT

----
url: https://docs.nestjs.com/v5/recipes/sql-typeorm
----

### SQL (TypeORM)

##### This chapter applies only to TypeScript

> **Warning** In this article, you'll learn how to create a `DatabaseModule` based on the **TypeORM** package from scratch using custom providers mechanism. As a consequence, this solution contains a lot of overhead that you can omit using ready to use and available out-of-the-box dedicated `@nestjs/typeorm` package. To learn more, see [here](/v5/techniques/sql).

[TypeORM](https://github.com/typeorm/typeorm) is definitely the most mature Object Relational Mapper (ORM) available in the node.js world. Since it's written in TypeScript, it works pretty well with the Nest framework. To start the adventure with this library we have to install all required dependencies:

TypeScript

```typescript

$ npm install --save typeorm mysql
```

The first step we need to do is to establish the connection with our database using `createConnection()` function imported from the `typeorm` package. The `createConnection()` function returns a `Promise`, therefore we have to create an [async provider](/v5/fundamentals/async-components).

database.providers.ts

TypeScript

```typescript

import { createConnection } from 'typeorm';

export const databaseProviders = [
  {
    provide: 'DbConnectionToken',
    useFactory: async () => await createConnection({
      type: 'mysql',
      host: 'localhost',
      port: 3306,
      username: 'root',
      password: 'root',
      database: 'test',
      entities: [
          __dirname + '/../**/*.entity{.ts,.js}',
      ],
      synchronize: true,
    }),
  },
];
```

> **Hint** Following best practices, we declared the custom provider in the separated file which has a `*.providers.ts` suffix.

Then, we need to export these providers to make them **accessible** for the rest part of the application.

database.module.ts

TypeScript

```typescript

import { Module } from '@nestjs/common';
import { databaseProviders } from './database.providers';

@Module({
  providers: [...databaseProviders],
  exports: [...databaseProviders],
})
export class DatabaseModule {}
```

Now we can inject the `Connection` object using `@Inject()` decorator. Each class that would depend on the `Connection` async provider will wait until a `Promise` is resolved.

#### Repository pattern

The [TypeORM](https://github.com/typeorm/typeorm) supports the repository design pattern, thus each entity has its own Repository. These repositories can be obtained from the database connection.

But firstly, we need at least one entity. We are going to reuse the `Photo` entity from the offical documentation.

photo/photo.entity.ts

TypeScript

```typescript

import { Entity, Column, PrimaryGeneratedColumn } from 'typeorm';

@Entity()
export class Photo {
  @PrimaryGeneratedColumn()
  id: number;

  @Column({ length: 500 })
  name: string;

  @Column('text')
  description: string;

  @Column()
  filename: string;

  @Column('int')
  views: number;

  @Column()
  isPublished: boolean;
}
```

The `Photo` entity belongs to the `photo` directory. This directory represents the `PhotoModule`. Now, let's create a **Repository** provider:

photo.providers.ts

TypeScript

```typescript

import { Connection, Repository } from 'typeorm';
import { Photo } from './photo.entity';

export const photoProviders = [
  {
    provide: 'PhotoRepositoryToken',
    useFactory: (connection: Connection) => connection.getRepository(Photo),
    inject: ['DbConnectionToken'],
  },
];
```

> **Notice** In the real-world applications you should avoid **magic strings**. Both `PhotoRepositoryToken` and `DbConnectionToken` should be kept in the separated `constants.ts` file.

Now we can inject the `PhotoRepository` to the `PhotoService` using the `@Inject()` decorator:

photo.service.ts

TypeScript

```typescript

import { Injectable, Inject } from '@nestjs/common';
import { Repository } from 'typeorm';
import { Photo } from './photo.entity';

@Injectable()
export class PhotoService {
  constructor(
    @Inject('PhotoRepositoryToken')
    private readonly photoRepository: Repository<Photo>,
  ) {}

  async findAll(): Promise<Photo[]> {
    return await this.photoRepository.find();
  }
}
```

The database connection is **asynchronous**, but Nest makes this process completely invisible for the end-user. The `PhotoRepository` is waiting for the db connection, and the `PhotoService` is delayed until repository is ready to use. The entire application can start when each class is instantiated.

Here is a final `PhotoModule`:

photo.module.ts

TypeScript

```typescript

import { Module } from '@nestjs/common';
import { DatabaseModule } from '../database/database.module';
import { photoProviders } from './photo.providers';
import { PhotoService } from './photo.service';

@Module({
  imports: [DatabaseModule],
  providers: [
    ...photoProviders,
    PhotoService,
  ],
})
export class PhotoModule {}
```

> **Hint** Don't forget to import the `PhotoModule` into the root `ApplicationModule`.

* SQL (TypeORM)
* Repository pattern

----
url: https://docs.nestjs.com/v5/cli/usages
----

### Usage

In order to achieve a high user-experience, the CLI commands share the same command schema.

```bash

$ nest [command] [...options]
```

#### Options

Each command accepts a set of **options** that are listed below:

* **--dry-run**: allows to simulate the command execution in order to verify how it will affect your working directory

#### new (alias: n)

The **new** command generates a Nest project based on the [typescript-starter](https://github.com/nestjs/typescript-starter) as well as install the required packages. The CLI will ask you for missing information to create the project, for example, which package manager do you want to use to install dependencies.

| Option      | Description                  | Required | Default value |
| ----------- | ---------------------------- | -------- | ------------- |
| name        | Your application name        | false    | nest-app-name |
| description | Your application description | false    | description   |
| version     | Your application version     | false    | 1.0.0         |
| author      | Your application author      | false    | ''            |

Example usage:

```bash

$ nest new my-awesome-app
OR 
$ nest n my-awesome-app
```

#### generate (alias: g)

The **generate** command generates a Nest architecture component.

| Option    | Description                                                | Required | Default value |
| --------- | ---------------------------------------------------------- | -------- | ------------- |
| schematic | The schematic name from the list bellow.                   | true     | N/A           |
| name      | The name of the generated Nest architecture component.     | true     | N/A           |
| path      | The path from to generate the Nest architecture component. | false    | src           |

A list of available architecture components:

* class (alias: cl)
* controller (alias: co)
* decorator (alias: d)
* exception (alias: e)
* filter (alias: f)
* gateway (alias: ga)
* guard (alias: gu)
* interceptor (alias: i)
* middleware (alias: mi)
* module (alias: mo)
* pipe (alias: pi)
* provider (alias: pr)
* service (alias: s)

Example usage:

```bash

$ nest generate service users
OR
$ nest g s users
```

#### info (alias: i)

The **info** command will display your project information.

```bash

$ nest info
 _   _             _      ___  _____  _____  _     _____
| \ | |           | |    |_  |/  ___|/  __ \| |   |_   _|
|  \| |  ___  ___ | |_     | |\ `--. | /  \/| |     | |
| . ` | / _ \/ __|| __|    | | `--. \| |    | |     | |
| |\  ||  __/\__ \| |_ /\__/ //\__/ /| \__/\| |_____| |_
\_| \_/ \___||___/ \__|\____/ \____/  \____/\_____/\___/

[System Information]
OS Version     : macOS High Sierra
NodeJS Version : v8.9.0
YARN Version    : 1.5.1
[Nest Information]
microservices version : 5.0.0
websockets version    : 5.0.0
testing version       : 5.0.0
common version        : 5.0.0
core version          : 5.0.0
  
```

* Usage
* Options
* new (alias: n)
* generate (alias: g)
* info (alias: i)

----
url: https://docs.nestjs.com/v10/faq/common-errors
----

* [Common errors](https://docs.nestjs.com/v10/faq/common-errors#common-errors)
* ["Cannot resolve dependency" error](https://docs.nestjs.com/v10/faq/common-errors#cannot-resolve-dependency-error)
* ["Circular dependency" error](https://docs.nestjs.com/v10/faq/common-errors#circular-dependency-error)
* [Debugging dependency errors](https://docs.nestjs.com/v10/faq/common-errors#debugging-dependency-errors)
* ["File change detected" loops endlessly](https://docs.nestjs.com/v10/faq/common-errors#file-change-detected-loops-endlessly)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/faq/errors.md "Suggest Edits")

### Common errors

During your development with NestJS, you may encounter various errors as you learn the framework.

#### "Cannot resolve dependency" error[#](/faq/common-errors#cannot-resolve-dependency-error)

> **Hint** Check out the [NestJS Devtools](/devtools/overview#investigating-the-cannot-resolve-dependency-error) which can help you resolve the "Cannot resolve dependency" error effortlessly.

Probably the most common error message is about Nest not being able to resolve dependencies of a provider. The error message usually looks something like this:

```bash

Nest can't resolve dependencies of the <provider> (?). Please make sure that the argument <unknown_token> at index [<index>] is available in the <module> context.

Potential solutions:
- Is <module> a valid NestJS module?
- If <unknown_token> is a provider, is it part of the current <module>?
- If <unknown_token> is exported from a separate @Module, is that module imported within <module>?
  @Module({
    imports: [ /* the Module containing <unknown_token> */ ]
  })
```

The most common culprit of the error, is not having the `<provider>` in the module's `providers` array. Please make sure that the provider is indeed in the `providers` array and following [standard NestJS provider practices](/fundamentals/custom-providers#di-fundamentals).

There are a few gotchas, that are common. One is putting a provider in an `imports` array. If this is the case, the error will have the provider's name where `<module>` should be.

If you run across this error while developing, take a look at the module mentioned in the error message and look at its `providers`. For each provider in the `providers` array, make sure the module has access to all of the dependencies. Often times, `providers` are duplicated in a "Feature Module" and a "Root Module" which means Nest will try to instantiate the provider twice. More than likely, the module containing the `<provider>` being duplicated should be added in the "Root Module"'s `imports` array instead.

If the `<unknown_token>` above is `dependency`, you might have a circular file import. This is different from the [circular dependency](/faq/common-errors#circular-dependency-error) below because instead of having providers depend on each other in their constructors, it just means that two files end up importing each other. A common case would be a module file declaring a token and importing a provider, and the provider import the token constant from the module file. If you are using barrel files, ensure that your barrel imports do not end up creating these circular imports as well.

If the `<unknown_token>` above is `Object`, it means that you're injecting using an type/interface without a proper provider's token. To fix that, make sure that:

1. you're importing the class reference or use a custom token with `@Inject()` decorator. Read the [custom providers page](/v10/fundamentals/custom-providers), and

```bash

Nest can't resolve dependencies of the <provider> (?).
Please make sure that the argument ModuleRef at index [<index>] is available in the <module> context.
...
```

This likely happens when your project end up loading two Node modules of the package `@nestjs/core`, like this:

```text

.
├── package.json
├── apps
│   └── api
│       └── node_modules
│           └── @nestjs/bull
│               └── node_modules
│                   └── @nestjs/core
└── node_modules
    ├── (other packages)
    └── @nestjs/core
```

Solutions:

* For **Yarn** Workspaces, use the [nohoist feature](https://classic.yarnpkg.com/blog/2018/02/15/nohoist) to prevent hoisting the package `@nestjs/core`.
* For **pnpm** Workspaces, set `@nestjs/core` as a peerDependencies in your other module and `"dependenciesMeta": {"other-module-name": {"injected": true }}` in the app package.json where the module is imported. see: [dependenciesmetainjected](https://pnpm.io/package_json#dependenciesmetainjected)

#### "Circular dependency" error[#](/faq/common-errors#circular-dependency-error)

Occasionally you'll find it difficult to avoid [circular dependencies](https://docs.nestjs.com/fundamentals/circular-dependency) in your application. You'll need to take some steps to help Nest resolve these. Errors that arise from circular dependencies look like this:

```bash

Nest cannot create the <module> instance.
The module at index [<index>] of the <module> "imports" array is undefined.

Potential causes:
- A circular dependency between modules. Use forwardRef() to avoid it. Read more: https://docs.nestjs.com/fundamentals/circular-dependency
- The module at index [<index>] is of type "undefined". Check your import statements and the type of the module.

Scope [<module_import_chain>]
# example chain AppModule -> FooModule
```

Circular dependencies can arise from both providers depending on each other, or typescript files depending on each other for constants, such as exporting constants from a module file and importing them in a service file. In the latter case, it is advised to create a separate file for your constants. In the former case, please follow the guide on circular dependencies and make sure that both the modules **and** the providers are marked with `forwardRef`.

#### Debugging dependency errors[#](/faq/common-errors#debugging-dependency-errors)

Along with just manually verifying your dependencies are correct, as of Nest 8.1.0 you can set the `NEST_DEBUG` environment variable to a string that resolves as truthy, and get extra logging information while Nest is resolving all of the dependencies for the application.

In the above image, the string in yellow is the host class of the dependency being injected, the string in blue is the name of the injected dependency, or its injection token, and the string in purple is the module in which the dependency is being searched for. Using this, you can usually trace back the dependency resolution for what's happening and why you're getting dependency injection problems.

#### "File change detected" loops endlessly[#](/faq/common-errors#file-change-detected-loops-endlessly)

Windows users who are using TypeScript version 4.9 and up may encounter this problem. This happens when you're trying to run your application in watch mode, e.g `npm run start:dev` and see an endless loop of the log messages:

```bash

XX:XX:XX AM - File change detected. Starting incremental compilation...
XX:XX:XX AM - Found 0 errors. Watching for file changes.
```

When you're using the NestJS CLI to start your application in watch mode it is done by calling `tsc --watch`, and as of version 4.9 of TypeScript, a [new strategy](https://devblogs.microsoft.com/typescript/announcing-typescript-4-9/#file-watching-now-uses-file-system-events) for detecting file changes is used which is likely to be the cause of this problem. In order to fix this problem, you need to add a setting to your tsconfig.json file after the `"compilerOptions"` option as follows:

```bash

  "watchOptions": {
    "watchFile": "fixedPollingInterval"
  }
```

This tells TypeScript to use the polling method for checking for file changes instead of file system events (the new default method), which can cause issues on some machines. You can read more about the `"watchFile"` option in [TypeScript documentation](https://www.typescriptlang.org/tsconfig#watch-watchDirectory).

----
url: https://docs.nestjs.com/v8/openapi/migration-guide
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Migration guide](https://docs.nestjs.com/v8/openapi/migration-guide#migration-guide)
* [Breaking changes](https://docs.nestjs.com/v8/openapi/migration-guide#breaking-changes)
* [New methods](https://docs.nestjs.com/v8/openapi/migration-guide#new-methods)

----
url: https://docs.nestjs.com/v9/graphql/cli-plugin
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [CLI Plugin](https://docs.nestjs.com/v9/graphql/cli-plugin#cli-plugin)
* [Overview](https://docs.nestjs.com/v9/graphql/cli-plugin#overview)
* [Comments introspection](https://docs.nestjs.com/v9/graphql/cli-plugin#comments-introspection)
* [Using the CLI plugin](https://docs.nestjs.com/v9/graphql/cli-plugin#using-the-cli-plugin)
* [Integration with ts-jest (e2e tests)](https://docs.nestjs.com/v9/graphql/cli-plugin#integration-with-ts-jest-e2e-tests)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/cli-plugin.md "Suggest Edits")

### CLI Plugin

> **Warning** This chapter applies only to the code first approach.

TypeScript's metadata reflection system has several limitations which make it impossible to, for instance, determine what properties a class consists of or recognize whether a given property is optional or required. However, some of these constraints can be addressed at compilation time. Nest provides a plugin that enhances the TypeScript compilation process to reduce the amount of boilerplate code required.

> **Hint** This plugin is **opt-in**. If you prefer, you can declare all decorators manually, or only specific decorators where you need them.

```typescript

@ObjectType()
export class Author {
  @Field(type => ID)
  id: number;

  @Field({ nullable: true })
  firstName?: string;

  @Field({ nullable: true })
  lastName?: string;

  @Field(type => [Post])
  posts: Post[];
}
```

While not a significant issue with medium-sized projects, it becomes verbose & hard to maintain once you have a large set of classes.

By enabling the GraphQL plugin, the above class definition can be declared simply:

authors/models/author.model.ts

JS TS

```typescript

@ObjectType()
export class Author {
  @Field(type => ID)
  id: number;
  firstName?: string;
  lastName?: string;
  posts: Post[];
}
```

The plugin adds appropriate decorators on-the-fly based on the **Abstract Syntax Tree**. Thus, you won't have to struggle with `@Field` decorators scattered throughout the code.

> **Hint** The plugin will automatically generate any missing GraphQL properties, but if you need to override them, simply set them explicitly via `@Field()`.

#### Comments introspection[#](/graphql/cli-plugin#comments-introspection)

With the comments introspection feature enabled, CLI plugin will generate descriptions for fields based on comments.

For example, given an example `roles` property:

```typescript

/**
 * A list of user's roles
 */
@Field(() => [String], {
  description: `A list of user's roles`
})
roles: string[];
```

You must duplicate description values. With `introspectComments` enabled, the CLI plugin can extract these comments and automatically provide descriptions for properties. Now, the above field can be declared simply as follows:

```typescript

/**
 * A list of user's roles
 */
roles: string[];
```

#### Using the CLI plugin[#](/graphql/cli-plugin#using-the-cli-plugin)

To enable the plugin, open `nest-cli.json` (if you use [Nest CLI](/v9/cli/overview)) and add the following `plugins` configuration:

```javascript

{
  "collection": "@nestjs/schematics",
  "sourceRoot": "src",
  "compilerOptions": {
    "plugins": ["@nestjs/graphql"]
  }
}
```

You can use the `options` property to customize the behavior of the plugin.

```javascript

"plugins": [
  {
    "name": "@nestjs/graphql",
    "options": {
      "typeFileNameSuffix": [".input.ts", ".args.ts"],
      "introspectComments": true
    }
  }
]
```

The `options` property has to fulfill the following interface:

```typescript

export interface PluginOptions {
  typeFileNameSuffix?: string[];
  introspectComments?: boolean;
}
```

| Option               | Default                                                | Description                                                                        |
| -------------------- | ------------------------------------------------------ | ---------------------------------------------------------------------------------- |
| `typeFileNameSuffix` | `['.input.ts', '.args.ts', '.entity.ts', '.model.ts']` | GraphQL types files suffix                                                         |
| `introspectComments` | `false`                                                | If set to true, plugin will generate descriptions for properties based on comments |

If you don't use the CLI but instead have a custom `webpack` configuration, you can use this plugin in combination with `ts-loader`:

```javascript

getCustomTransformers: (program: any) => ({
  before: [require('@nestjs/graphql/plugin').before({}, program)]
}),
```

#### Integration with `ts-jest` (e2e tests)[#](/graphql/cli-plugin#integration-with-ts-jest-e2e-tests)

When running e2e tests with this plugin enabled, you may run into issues with compiling schema. For example, one of the most common errors is:

```json

Object type <name> must define one or more fields.
```

This happens because `jest` configuration does not import `@nestjs/graphql/plugin` plugin anywhere.

To fix this, create the following file in your e2e tests directory:

```javascript

const transformer = require('@nestjs/graphql/plugin');

module.exports.name = 'nestjs-graphql-transformer';
// you should change the version number anytime you change the configuration below - otherwise, jest will not detect changes
module.exports.version = 1;

module.exports.factory = (cs) => {
  return transformer.before(
    {
      // @nestjs/graphql/plugin options (can be empty)
    },
    cs.program, // "cs.tsCompiler.program" for older versions of Jest (<= v27)
  );
};
```

With this in place, import AST transformer within your `jest` configuration file. By default (in the starter application), e2e tests configuration file is located under the `test` folder and is named `jest-e2e.json`.

```json

{
  ... // other configuration
  "globals": {
    "ts-jest": {
      "astTransformers": {
        "before": ["<path to the file created above>"]
      }
    }
  }
}
```

If you use `jest@^29`, then use the snippet below, as the previous approach got deprecated.

```json

{
  ... // other configuration
  "transform": {
    "^.+\\.(t|j)s$": [
      "ts-jest",
      {
        "astTransformers": {
          "before": ["<path to the file created above>"]
        }
      }
    ]
  }
}
```

----
url: https://docs.nestjs.com/v9/faq/hybrid-application
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Hybrid application](https://docs.nestjs.com/v9/faq/hybrid-application#hybrid-application)
* [Sharing configuration](https://docs.nestjs.com/v9/faq/hybrid-application#sharing-configuration)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/faq/hybrid-application.md "Suggest Edits")

### Hybrid application

A hybrid application is one that both listens for HTTP requests, as well as makes use of connected microservices. The `INestApplication` instance can be connected with `INestMicroservice` instances through the `connectMicroservice()` method.

```typescript

const app = await NestFactory.create(AppModule);
const microservice = app.connectMicroservice<MicroserviceOptions>({
  transport: Transport.TCP,
});

await app.startAllMicroservices();
await app.listen(3001);
```

To connect multiple microservice instances, issue the call to `connectMicroservice()` for each microservice:

```typescript

const app = await NestFactory.create(AppModule);
// microservice #1
const microserviceTcp = app.connectMicroservice<MicroserviceOptions>({
  transport: Transport.TCP,
  options: {
    port: 3001,
  },
});
// microservice #2
const microserviceRedis = app.connectMicroservice<MicroserviceOptions>({
  transport: Transport.REDIS,
  options: {
    host: 'localhost',
    port: 6379,
  },
});

await app.startAllMicroservices();
await app.listen(3001);
```

To bind `@MessagePattern()` to only one transport strategy (for example, MQTT) in a hybrid application with multiple microservices, we can pass the second argument of type `Transport` which is an enum with all the built-in transport strategies defined.

JS TS

```typescript

@MessagePattern('time.us.*', Transport.NATS)
getDate(@Payload() data: number[], @Ctx() context: NatsContext) {
  console.log(`Subject: ${context.getSubject()}`); // e.g. "time.us.east"
  return new Date().toLocaleTimeString(...);
}
@MessagePattern({ cmd: 'time.us' }, Transport.TCP)
getTCPDate(@Payload() data: number[]) {
  return new Date().toLocaleTimeString(...);
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('time.us.*', Transport.NATS)
getDate(data, context) {
  console.log(`Subject: ${context.getSubject()}`); // e.g. "time.us.east"
  return new Date().toLocaleTimeString(...);
}
@Bind(Payload(), Ctx())
@MessagePattern({ cmd: 'time.us' }, Transport.TCP)
getTCPDate(data, context) {
  return new Date().toLocaleTimeString(...);
}
```

> **Hint**`@Payload()`, `@Ctx()`, `Transport` and `NatsContext` are imported from `@nestjs/microservices`.

#### Sharing configuration[#](/faq/hybrid-application#sharing-configuration)

By default a hybrid application will not inherit global pipes, interceptors, guards and filters configured for the main (HTTP-based) application. To inherit these configuration properties from the main application, set the `inheritAppConfig` property in the second argument (an optional options object) of the `connectMicroservice()` call, as follow:

```typescript

const microservice = app.connectMicroservice<MicroserviceOptions>(
  {
    transport: Transport.TCP,
  },
  { inheritAppConfig: true },
);
```

----
url: https://docs.nestjs.com/v4/microservices/redis
----

### Redis

There's' another way to play with the Nest microservices. Instead of TCP communication, we can use the great [Redis](https://redis.io/) feature – the **publish / subscribe**.

To switch from the TCP transport strategy to Redis **pub/sub**, we only need to change the options object passed to the `createMicroservice()` method.

main.ts

JavaScript TypeScript

TypeScript

```typescript

const app = await NestFactory.createMicroservice(ApplicationModule, {
  transport: Transport.REDIS,
  url: 'redis://localhost:6379',
});
```

> **Hint** Don't forget to change the `Transport.REDIS` in the `@Client()` decorator too.

#### Sponsors

[](https://valor-software.com/)

Nest is an MIT-licensed open source project. It can grow thanks to the support by these awesome people. If you'd like to join them, please read more [here](https://opencollective.com/nest). Thanks!

[](https://opencollective.com/nest/backer/0/website)[](https://opencollective.com/nest/backer/1/website)[](https://opencollective.com/nest/backer/2/website)[](https://opencollective.com/nest/backer/3/website)[](https://opencollective.com/nest/backer/4/website)[](https://opencollective.com/nest/backer/5/website)[](https://opencollective.com/nest/backer/6/website)[](https://opencollective.com/nest/backer/7/website)[](https://opencollective.com/nest/backer/8/website)[](https://opencollective.com/nest/backer/9/website)[](https://opencollective.com/nest/backer/10/website)[](https://opencollective.com/nest/backer/11/website)[](https://opencollective.com/nest/backer/12/website)[](https://opencollective.com/nest/backer/13/website)[](https://opencollective.com/nest/backer/14/website)[](https://opencollective.com/nest/backer/15/website)[](https://opencollective.com/nest/backer/16/website)[](https://opencollective.com/nest/backer/17/website)[](https://opencollective.com/nest/backer/18/website)[](https://opencollective.com/nest/backer/19/website)[](https://opencollective.com/nest/backer/20/website)[](https://opencollective.com/nest/backer/21/website)[](https://opencollective.com/nest/backer/22/website)[](https://opencollective.com/nest/backer/23/website)[](https://opencollective.com/nest/backer/24/website)[](https://opencollective.com/nest/backer/25/website)[](https://opencollective.com/nest/backer/26/website)[](https://opencollective.com/nest/backer/27/website)[](https://opencollective.com/nest/backer/28/website)[](https://opencollective.com/nest/backer/29/website)

[Become a sponsor](https://opencollective.com/nest)

----
url: https://docs.nestjs.com/v11/fundamentals/testing
----

* [Testing](https://docs.nestjs.com/v11/fundamentals/testing#testing)
* [Installation](https://docs.nestjs.com/v11/fundamentals/testing#installation)
* [Unit testing](https://docs.nestjs.com/v11/fundamentals/testing#unit-testing)
* [Testing utilities](https://docs.nestjs.com/v11/fundamentals/testing#testing-utilities)
* [Auto mocking](https://docs.nestjs.com/v11/fundamentals/testing#auto-mocking)
* [End-to-end testing](https://docs.nestjs.com/v11/fundamentals/testing#end-to-end-testing)
* [Overriding globally registered enhancers](https://docs.nestjs.com/v11/fundamentals/testing#overriding-globally-registered-enhancers)
* [Testing request-scoped instances](https://docs.nestjs.com/v11/fundamentals/testing#testing-request-scoped-instances)

```bash

$ npm i --save-dev @nestjs/testing
```

#### Unit testing[#](/fundamentals/testing#unit-testing)

In the following example, we test two classes: `CatsController` and `CatsService`. As mentioned, [Jest](https://github.com/facebook/jest) is provided as the default testing framework. It serves as a test-runner and also provides assert functions and test-double utilities that help with mocking, spying, etc. In the following basic test, we manually instantiate these classes, and ensure that the controller and service fulfill their API contract.

cats.controller.spec.ts

JS TS

```typescript

import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

describe('CatsController', () => {
  let catsController: CatsController;
  let catsService: CatsService;

  beforeEach(() => {
    catsService = new CatsService();
    catsController = new CatsController(catsService);
  });

  describe('findAll', () => {
    it('should return an array of cats', async () => {
      const result = ['test'];
      jest.spyOn(catsService, 'findAll').mockImplementation(() => result);

      expect(await catsController.findAll()).toBe(result);
    });
  });
});
```

```typescript

import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

describe('CatsController', () => {
  let catsController;
  let catsService;

  beforeEach(() => {
    catsService = new CatsService();
    catsController = new CatsController(catsService);
  });

  describe('findAll', () => {
    it('should return an array of cats', async () => {
      const result = ['test'];
      jest.spyOn(catsService, 'findAll').mockImplementation(() => result);

      expect(await catsController.findAll()).toBe(result);
    });
  });
});
```

> **Hint** Keep your test files located near the classes they test. Testing files should have a `.spec` or `.test` suffix.

Because the above sample is trivial, we aren't really testing anything Nest-specific. Indeed, we aren't even using dependency injection (notice that we pass an instance of `CatsService` to our `catsController`). This form of testing - where we manually instantiate the classes being tested - is often called **isolated testing** as it is independent from the framework. Let's introduce some more advanced capabilities that help you test applications that make more extensive use of Nest features.

#### Testing utilities[#](/fundamentals/testing#testing-utilities)

The `@nestjs/testing` package provides a set of utilities that enable a more robust testing process. Let's rewrite the previous example using the built-in `Test` class:

cats.controller.spec.ts

JS TS

```typescript

import { Test } from '@nestjs/testing';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

describe('CatsController', () => {
  let catsController: CatsController;
  let catsService: CatsService;

  beforeEach(async () => {
    const moduleRef = await Test.createTestingModule({
        controllers: [CatsController],
        providers: [CatsService],
      }).compile();

    catsService = moduleRef.get(CatsService);
    catsController = moduleRef.get(CatsController);
  });

  describe('findAll', () => {
    it('should return an array of cats', async () => {
      const result = ['test'];
      jest.spyOn(catsService, 'findAll').mockImplementation(() => result);

      expect(await catsController.findAll()).toBe(result);
    });
  });
});
```

```typescript

import { Test } from '@nestjs/testing';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

describe('CatsController', () => {
  let catsController;
  let catsService;

  beforeEach(async () => {
    const moduleRef = await Test.createTestingModule({
        controllers: [CatsController],
        providers: [CatsService],
      }).compile();

    catsService = moduleRef.get(CatsService);
    catsController = moduleRef.get(CatsController);
  });

  describe('findAll', () => {
    it('should return an array of cats', async () => {
      const result = ['test'];
      jest.spyOn(catsService, 'findAll').mockImplementation(() => result);

      expect(await catsController.findAll()).toBe(result);
    });
  });
});
```

The `Test` class is useful for providing an application execution context that essentially mocks the full Nest runtime, but gives you hooks that make it easy to manage class instances, including mocking and overriding. The `Test` class has a `createTestingModule()` method that takes a module metadata object as its argument (the same object you pass to the `@Module()` decorator). This method returns a `TestingModule` instance which in turn provides a few methods. For unit tests, the important one is the `compile()` method. This method bootstraps a module with its dependencies (similar to the way an application is bootstrapped in the conventional `main.ts` file using `NestFactory.create()`), and returns a module that is ready for testing.

> **Hint** The `compile()` method is **asynchronous** and therefore has to be awaited. Once the module is compiled you can retrieve any **static** instance it declares (controllers and providers) using the `get()` method.

`TestingModule` inherits from the [module reference](/v11/fundamentals/module-ref) class, and therefore its ability to dynamically resolve scoped providers (transient or request-scoped). Do this with the `resolve()` method (the `get()` method can only retrieve static instances).

```typescript

const moduleRef = await Test.createTestingModule({
  controllers: [CatsController],
  providers: [CatsService],
}).compile();

catsService = await moduleRef.resolve(CatsService);
```

> **Warning** The `resolve()` method returns a unique instance of the provider, from its own **DI container sub-tree**. Each sub-tree has a unique context identifier. Thus, if you call this method more than once and compare instance references, you will see that they are not equal.

> **Hint** Learn more about the module reference features [here](/v11/fundamentals/module-ref).

Instead of using the production version of any provider, you can override it with a [custom provider](/v11/fundamentals/custom-providers) for testing purposes. For example, you can mock a database service instead of connecting to a live database. We'll cover overrides in the next section, but they're available for unit tests as well.

```typescript

// ...
import { ModuleMocker, MockMetadata } from 'jest-mock';

const moduleMocker = new ModuleMocker(global);

describe('CatsController', () => {
  let controller: CatsController;

  beforeEach(async () => {
    const moduleRef = await Test.createTestingModule({
      controllers: [CatsController],
    })
      .useMocker((token) => {
        const results = ['test1', 'test2'];
        if (token === CatsService) {
          return { findAll: jest.fn().mockResolvedValue(results) };
        }
        if (typeof token === 'function') {
          const mockMetadata = moduleMocker.getMetadata(
            token,
          ) as MockMetadata<any, any>;
          const Mock = moduleMocker.generateFromMetadata(
            mockMetadata,
          ) as ObjectConstructor;
          return new Mock();
        }
      })
      .compile();

    controller = moduleRef.get(CatsController);
  });
});
```

You can also retrieve these mocks out of the testing container as you normally would custom providers, `moduleRef.get(CatsService)`.

> **Hint** A general mock factory, like `createMock` from [`@golevelup/ts-jest`](https://github.com/golevelup/nestjs/tree/master/packages/testing) can also be passed directly.

> **Hint**`REQUEST` and `INQUIRER` providers cannot be auto-mocked because they're already pre-defined in the context. However, they can be *overwritten* using the custom provider syntax or by utilizing the `.overrideProvider` method.

#### End-to-end testing[#](/fundamentals/testing#end-to-end-testing)

Unlike unit testing, which focuses on individual modules and classes, end-to-end (e2e) testing covers the interaction of classes and modules at a more aggregate level -- closer to the kind of interaction that end-users will have with the production system. As an application grows, it becomes hard to manually test the end-to-end behavior of each API endpoint. Automated end-to-end tests help us ensure that the overall behavior of the system is correct and meets project requirements. To perform e2e tests we use a similar configuration to the one we just covered in **unit testing**. In addition, Nest makes it easy to use the [Supertest](https://github.com/visionmedia/supertest) library to simulate HTTP requests.

cats.e2e-spec.ts

JS TS

```typescript

import * as request from 'supertest';
import { Test } from '@nestjs/testing';
import { CatsModule } from '../../src/cats/cats.module';
import { CatsService } from '../../src/cats/cats.service';
import { INestApplication } from '@nestjs/common';

describe('Cats', () => {
  let app: INestApplication;
  let catsService = { findAll: () => ['test'] };

  beforeAll(async () => {
    const moduleRef = await Test.createTestingModule({
      imports: [CatsModule],
    })
      .overrideProvider(CatsService)
      .useValue(catsService)
      .compile();

    app = moduleRef.createNestApplication();
    await app.init();
  });

  it(`/GET cats`, () => {
    return request(app.getHttpServer())
      .get('/cats')
      .expect(200)
      .expect({
        data: catsService.findAll(),
      });
  });

  afterAll(async () => {
    await app.close();
  });
});
```

```typescript

import * as request from 'supertest';
import { Test } from '@nestjs/testing';
import { CatsModule } from '../../src/cats/cats.module';
import { CatsService } from '../../src/cats/cats.service';
import { INestApplication } from '@nestjs/common';

describe('Cats', () => {
  let app: INestApplication;
  let catsService = { findAll: () => ['test'] };

  beforeAll(async () => {
    const moduleRef = await Test.createTestingModule({
      imports: [CatsModule],
    })
      .overrideProvider(CatsService)
      .useValue(catsService)
      .compile();

    app = moduleRef.createNestApplication();
    await app.init();
  });

  it(`/GET cats`, () => {
    return request(app.getHttpServer())
      .get('/cats')
      .expect(200)
      .expect({
        data: catsService.findAll(),
      });
  });

  afterAll(async () => {
    await app.close();
  });
});
```

> **Hint** If you're using [Fastify](/v11/techniques/performance) as your HTTP adapter, it requires a slightly different configuration, and has built-in testing capabilities:
>
> ```ts
>
> let app: NestFastifyApplication;
>
> beforeAll(async () => {
>   app = moduleRef.createNestApplication<NestFastifyApplication>(
>     new FastifyAdapter(),
>   );
>
>   await app.init();
>   await app.getHttpAdapter().getInstance().ready();
> });
>
> it(`/GET cats`, () => {
>   return app
>     .inject({
>       method: 'GET',
>       url: '/cats',
>     })
>     .then((result) => {
>       expect(result.statusCode).toEqual(200);
>       expect(result.payload).toEqual(/* expectedPayload */);
>     });
> });
>
> afterAll(async () => {
>   await app.close();
> });
> ```

```typescript

const moduleRef = await Test.createTestingModule({
  imports: [AppModule],
})
  .overrideModule(CatsModule)
  .useModule(AlternateCatsModule)
  .compile();
```

Each of the override method types, in turn, returns the `TestingModule` instance, and can thus be chained with other methods in the [fluent style](https://en.wikipedia.org/wiki/Fluent_interface). You should use `compile()` at the end of such a chain to cause Nest to instantiate and initialize the module.

Also, sometimes you may want to provide a custom logger e.g. when the tests are run (for example, on a CI server). Use the `setLogger()` method and pass an object that fulfills the `LoggerService` interface to instruct the `TestModuleBuilder` how to log during tests (by default, only "error" logs will be logged to the console).

The compiled module has several useful methods, as described in the following table:

|                            |                                                                                                                                                                                                                                                   |
| -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `createNestApplication()`  | Creates and returns a Nest application (`INestApplication` instance) based on the given module. Note that you must manually initialize the application using the `init()` method.                                                                 |
| `createNestMicroservice()` | Creates and returns a Nest microservice (`INestMicroservice` instance) based on the given module.                                                                                                                                                 |
| `get()`                    | Retrieves a static instance of a controller or provider (including guards, filters, etc.) available in the application context. Inherited from the [module reference](/fundamentals/module-ref) class.                                            |
| `resolve()`                | Retrieves a dynamically created scoped instance (request or transient) of a controller or provider (including guards, filters, etc.) available in the application context. Inherited from the [module reference](/fundamentals/module-ref) class. |
| `select()`                 | Navigates through the module's dependency graph; can be used to retrieve a specific instance from the selected module (used along with strict mode (`strict: true`) in `get()` method).                                                           |

> **Hint** Keep your e2e test files inside the `test` directory. The testing files should have a `.e2e-spec` suffix.

#### Overriding globally registered enhancers[#](/fundamentals/testing#overriding-globally-registered-enhancers)

If you have a globally registered guard (or pipe, interceptor, or filter), you need to take a few more steps to override that enhancer. To recap the original registration looks like this:

```typescript

providers: [
  {
    provide: APP_GUARD,
    useClass: JwtAuthGuard,
  },
],
```

This is registering the guard as a "multi"-provider through the `APP_*` token. To be able to replace the `JwtAuthGuard` here, the registration needs to use an existing provider in this slot:

```typescript

providers: [
  {
    provide: APP_GUARD,
    useExisting: JwtAuthGuard,
    // ^^^^^^^^ notice the use of 'useExisting' instead of 'useClass'
  },
  JwtAuthGuard,
],
```

> **Hint** Change the `useClass` to `useExisting` to reference a registered provider instead of having Nest instantiate it behind the token.

Now the `JwtAuthGuard` is visible to Nest as a regular provider that can be overridden when creating the `TestingModule`:

```typescript

const moduleRef = await Test.createTestingModule({
  imports: [AppModule],
})
  .overrideProvider(JwtAuthGuard)
  .useClass(MockAuthGuard)
  .compile();
```

Now all your tests will use the `MockAuthGuard` on every request.

#### Testing request-scoped instances[#](/fundamentals/testing#testing-request-scoped-instances)

[Request-scoped](/v11/fundamentals/injection-scopes) providers are created uniquely for each incoming **request**. The instance is garbage-collected after the request has completed processing. This poses a problem, because we can't access a dependency injection sub-tree generated specifically for a tested request.

We know (based on the sections above) that the `resolve()` method can be used to retrieve a dynamically instantiated class. Also, as described [here](https://docs.nestjs.com/fundamentals/module-ref#resolving-scoped-providers), we know we can pass a unique context identifier to control the lifecycle of a DI container sub-tree. How do we leverage this in a testing context?

The strategy is to generate a context identifier beforehand and force Nest to use this particular ID to create a sub-tree for all incoming requests. In this way we'll be able to retrieve instances created for a tested request.

To accomplish this, use `jest.spyOn()` on the `ContextIdFactory`:

```typescript

const contextId = ContextIdFactory.create();
jest
  .spyOn(ContextIdFactory, 'getByRequest')
  .mockImplementation(() => contextId);
```

Now we can use the `contextId` to access a single generated DI container sub-tree for any subsequent request.

```typescript

catsService = await moduleRef.resolve(CatsService, contextId);
```

----
url: https://docs.nestjs.com/v11/observability/distributed-tracing
----

* [Distributed tracing](https://docs.nestjs.com/v11/observability/distributed-tracing#distributed-tracing)
* [Reading the current trace id](https://docs.nestjs.com/v11/observability/distributed-tracing#reading-the-current-trace-id)
* [HTTP to HTTP](https://docs.nestjs.com/v11/observability/distributed-tracing#http-to-http)
* [gRPC](https://docs.nestjs.com/v11/observability/distributed-tracing#grpc)
* [TCP, Redis, NATS, and other microservice transports](https://docs.nestjs.com/v11/observability/distributed-tracing#tcp-redis-nats-and-other-microservice-transports)
* [GraphQL](https://docs.nestjs.com/v11/observability/distributed-tracing#graphql)
* [Queue jobs (BullMQ)](https://docs.nestjs.com/v11/observability/distributed-tracing#queue-jobs-bullmq)
* [What a trace looks like in the dashboard](https://docs.nestjs.com/v11/observability/distributed-tracing#what-a-trace-looks-like-in-the-dashboard)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/observability/distributed-tracing.md "Suggest Edits")

### Distributed tracing

A **trace** is everything your applications recorded under a single trace id: the request or job that started it, and every span underneath. Within a single service this is automatic - the SDK generates a trace id when work starts, and every span underneath, including ones you add manually with [`TracerService`](), inherits it.

Across services it isn't automatic by default. A single user action that touches more than one service - an API call that fans out to a gRPC service, a job that calls back into another application - only shows up as **one trace** in your dashboard if every service involved ends up using the same trace id. Left unconfigured, each service mints its own via `traceIdGenerator` and the action shows up as several disconnected traces instead, one per service.

Forwarding the trace id is application code, not a dashboard setting. The pattern is always the same: the caller puts its current trace id on whatever channel the protocol has, and the callee's `traceIdGenerator` reads it back out. This page shows that for each transport.

#### Reading the current trace id[#](/observability/distributed-tracing#reading-the-current-trace-id)

To forward a trace id downstream, a service first needs to read the one it's currently running under. `TracerService.currentTraceId()` returns it directly:

orders.service.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { TracerService } from '@nestjs/observe';

@Injectable()
export class OrdersService {
  constructor(private readonly tracerService: TracerService) {}

  async report(orderId: string) {
    const traceId = this.tracerService.currentTraceId();
    // ...forward traceId to the next service
  }
}
```

It reads from the same context store as `getAttribute()`/`setAttribute()`, but unlike those it doesn't throw outside a traced context - it returns `null`, so code that forwards a trace id from startup hooks or other untraced paths doesn't need a `try`/`catch` just to propagate an id that isn't there yet. Guard for `null` before setting a header if that can happen in your code.

#### HTTP to HTTP[#](/observability/distributed-tracing#http-to-http)

Works with no extra configuration. The default `traceIdGenerator` is `(req) => req.headers['x-request-id'] ?? randomUUID()`, so a service adopts whatever `x-request-id` an incoming request carries instead of minting a new one. Forward the trace id as `x-request-id` on the outgoing request and the receiving service picks it up:

```typescript

fetch(url, {
  headers: { 'x-request-id': this.tracerService.currentTraceId() },
});
```

If you use the [HTTP module](/techniques/http-module), the same header can be added in an Axios request interceptor once, rather than at every call site:

orders.module.ts

JS TS

```typescript

@Module({
  imports: [HttpModule, ObserveModule],
})
export class OrdersModule implements OnModuleInit {
  constructor(
    private readonly httpService: HttpService,
    private readonly tracerService: TracerService,
  ) {}

  onModuleInit() {
    this.httpService.axiosRef.interceptors.request.use((config) => {
      config.headers['x-request-id'] = this.tracerService.currentTraceId();
      return config;
    });
  }
}
```

> **Hint** Many reverse proxies and load balancers (nginx, Envoy, AWS ALB) can be configured to set `x-request-id` on every inbound request. When they do, the trace id in your dashboard matches the request id in your proxy's access logs with no further work.

#### gRPC[#](/observability/distributed-tracing#grpc)

gRPC has no headers, only metadata. The caller attaches the trace id as metadata, and the gRPC service overrides `traceIdGenerator` to read it back out, since the default generator only checks HTTP headers:

caller.ts

JS TS

```typescript

import { Metadata } from '@grpc/grpc-js';

const metadata = new Metadata();
metadata.set('x-request-id', this.tracerService.currentTraceId());
this.heroesService.findOne({ id: 1 }, metadata);
```

app.module.ts

JS TS

```typescript

import { randomUUID } from 'node:crypto';

// gRPC service - passed to createObserveModule(), not forRoot()
export const { ObserveModule, ObserveInstrument } = createObserveModule({
  traceIdGenerator: (call) => {
    const inbound = call.metadata?.get?.('x-request-id')?.[0];
    return typeof inbound === 'string' && inbound.length > 0
      ? inbound
      : randomUUID(); // no id was propagated - this call started its own trace
  },
});
```

See the [gRPC]() chapter for how metadata is read and written on both sides of a call.

#### TCP, Redis, NATS, and other microservice transports[#](/observability/distributed-tracing#tcp-redis-nats-and-other-microservice-transports)

The `@nestjs/microservices` transports have no metadata channel, only a message payload, so the trace id has to travel as a field inside the payload itself:

caller.ts

JS TS

```typescript

this.client.send('orders.report', {
  ...payload,
  traceId: this.tracerService.currentTraceId(),
});
```

app.module.ts

JS TS

```typescript

import { randomUUID } from 'node:crypto';

// receiving service
export const { ObserveModule, ObserveInstrument } = createObserveModule({
  traceIdGenerator: (ctx) => ctx.getData()?.traceId ?? randomUUID(),
});
```

The generator receives the transport's context object, so the same shape works for request-response (`send()`) and event-based (`emit()`) messages alike.

> **Warning** A service that only receives RPC calls still has a `traceIdGenerator` that expects an HTTP request by default. In a [hybrid application]() that serves both HTTP and a microservice transport, write the generator defensively - check for `headers` first, then fall back to the payload.

#### GraphQL[#](/observability/distributed-tracing#graphql)

No extra configuration is needed when the GraphQL server sits behind the same service's HTTP layer - it automatically joins whatever trace the HTTP agent already opened for that request, which may itself have been propagated via `x-request-id` as above. Only a GraphQL server with no enclosing HTTP trace - a subscription over a raw WebSocket with no HTTP agent involved, for example - needs to think about this separately, and there's no built-in propagation hook for that case today.

#### Queue jobs (BullMQ)[#](/observability/distributed-tracing#queue-jobs-bullmq)

Not currently propagatable. A job processor always starts its own new trace with a fresh random id, regardless of what trace was active when the job was enqueued - there's no `traceIdGenerator` hook for jobs the way there is for HTTP and RPC. Treat this as a current limitation rather than something to configure around. If you need to tie a job run back to the request that enqueued it, put the request's trace id in the job data and attach it as a tag from the processor:

orders.processor.ts

JS TS

```typescript

@Processor('orders')
export class OrdersProcessor extends WorkerHost {
  constructor(private readonly tracerService: TracerService) {
    super();
  }

  async process(job: Job<{ orderId: string; originTraceId: string }>) {
    const span = await this.tracerService.activeSpan();
    span.addTags({ originTraceId: job.data.originTraceId });
    // ...
  }
}
```

The job still gets its own trace, but the tag is searchable, so the path from a slow request to the job it kicked off is one search away.

#### What a trace looks like in the dashboard[#](/observability/distributed-tracing#what-a-trace-looks-like-in-the-dashboard)

Once services agree on a trace id, the trace detail page renders every execution that ran under it - across services, requests, and jobs - as one waterfall: nesting depth as indentation, duration as bar length, position as when the span ran. A few things worth knowing when reading it:

* **Self time** is the number that matters. A span's duration minus everything its children accounted for is the time the span spent in its own code. Ranking by total duration always puts the controller at the top (it contains everything); ranking by self time surfaces the repository call that actually burned the time. Every execution page carries a spans table sorted this way.
* **Overlapping children are flagged.** When a span's children sum to more than the span's own duration, they ran concurrently (`Promise.all`, a parallel fan-out) and the row says so.
* **Failing spans are marked**, and the execution page leads with an error card for the first span that threw - class, message, the trimmed stack trace with the throwing frame marked, and the source lines around it when [`sourceContext`](/observability/sdk#error-source-context) is on.
* **Logs sit on the trace's clock.** With `forwardLogs` enabled, each line is placed at its offset from the start of the trace and labelled with the span that was in flight when it was written; hovering a line marks that instant on the waterfall.

From any failed or unusually slow execution, the **Copy agent prompt** button packages the whole page - context, error, stack trace with source, top spans by self time, and the logs - as a self-contained markdown prompt for a coding agent. See [Dashboard](/observability/dashboard#handing-a-failure-to-a-coding-agent).

----
url: https://docs.nestjs.com/v9/openapi/mapped-types
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Mapped types](https://docs.nestjs.com/v9/openapi/mapped-types#mapped-types)
* [Partial](https://docs.nestjs.com/v9/openapi/mapped-types#partial)
* [Pick](https://docs.nestjs.com/v9/openapi/mapped-types#pick)
* [Omit](https://docs.nestjs.com/v9/openapi/mapped-types#omit)
* [Intersection](https://docs.nestjs.com/v9/openapi/mapped-types#intersection)
* [Composition](https://docs.nestjs.com/v9/openapi/mapped-types#composition)

```typescript

import { ApiProperty } from '@nestjs/swagger';

export class CreateCatDto {
  @ApiProperty()
  name: string;

  @ApiProperty()
  age: number;

  @ApiProperty()
  breed: string;
}
```

By default, all of these fields are required. To create a type with the same fields, but with each one optional, use `PartialType()` passing the class reference (`CreateCatDto`) as an argument:

```typescript

export class UpdateCatDto extends PartialType(CreateCatDto) {}
```

> **Hint** The `PartialType()` function is imported from the `@nestjs/swagger` package.

#### Pick[#](/openapi/mapped-types#pick)

The `PickType()` function constructs a new type (class) by picking a set of properties from an input type. For example, suppose we start with a type like:

```typescript

import { ApiProperty } from '@nestjs/swagger';

export class CreateCatDto {
  @ApiProperty()
  name: string;

  @ApiProperty()
  age: number;

  @ApiProperty()
  breed: string;
}
```

We can pick a set of properties from this class using the `PickType()` utility function:

```typescript

export class UpdateCatAgeDto extends PickType(CreateCatDto, ['age'] as const) {}
```

> **Hint** The `PickType()` function is imported from the `@nestjs/swagger` package.

#### Omit[#](/openapi/mapped-types#omit)

The `OmitType()` function constructs a type by picking all properties from an input type and then removing a particular set of keys. For example, suppose we start with a type like:

```typescript

import { ApiProperty } from '@nestjs/swagger';

export class CreateCatDto {
  @ApiProperty()
  name: string;

  @ApiProperty()
  age: number;

  @ApiProperty()
  breed: string;
}
```

We can generate a derived type that has every property **except**`name` as shown below. In this construct, the second argument to `OmitType` is an array of property names.

```typescript

export class UpdateCatDto extends OmitType(CreateCatDto, ['name'] as const) {}
```

> **Hint** The `OmitType()` function is imported from the `@nestjs/swagger` package.

#### Intersection[#](/openapi/mapped-types#intersection)

The `IntersectionType()` function combines two types into one new type (class). For example, suppose we start with two types like:

```typescript

import { ApiProperty } from '@nestjs/swagger';

export class CreateCatDto {
  @ApiProperty()
  name: string;

  @ApiProperty()
  breed: string;
}

export class AdditionalCatInfo {
  @ApiProperty()
  color: string;
}
```

We can generate a new type that combines all properties in both types.

```typescript

export class UpdateCatDto extends IntersectionType(
  CreateCatDto,
  AdditionalCatInfo,
) {}
```

> **Hint** The `IntersectionType()` function is imported from the `@nestjs/swagger` package.

#### Composition[#](/openapi/mapped-types#composition)

The type mapping utility functions are composable. For example, the following will produce a type (class) that has all of the properties of the `CreateCatDto` type except for `name`, and those properties will be set to optional:

```typescript

export class UpdateCatDto extends PartialType(
  OmitType(CreateCatDto, ['name'] as const),
) {}
```

----
url: https://docs.nestjs.com/v9/microservices/custom-transport
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Custom transporters](https://docs.nestjs.com/v9/microservices/custom-transport#custom-transporters)
* [Creating a strategy](https://docs.nestjs.com/v9/microservices/custom-transport#creating-a-strategy)
* [Client proxy](https://docs.nestjs.com/v9/microservices/custom-transport#client-proxy)
* [Message serialization](https://docs.nestjs.com/v9/microservices/custom-transport#message-serialization)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/microservices/custom-transport.md "Suggest Edits")

### Custom transporters

Nest provides a variety of **transporters** out-of-the-box, as well as an API allowing developers to build new custom transport strategies. Transporters enable you to connect components over a network using a pluggable communications layer and a very simple application-level message protocol (read full [article](https://dev.to/nestjs/integrate-nestjs-with-external-services-using-microservice-transporters-part-1-p3)).

> **Hint** Building a microservice with Nest does not necessarily mean you must use the `@nestjs/microservices` package. For example, if you want to communicate with external services (let's say other microservices written in different languages), you may not need all the features provided by `@nestjs/microservice` library. In fact, if you don't need decorators (`@EventPattern` or `@MessagePattern`) that let you declaratively define subscribers, running a [Standalone Application](/v9/application-context) and manually maintaining connection/subscribing to channels should be enough for most use-cases and will provide you with more flexibility.

With a custom transporter, you can integrate any messaging system/protocol (including Google Cloud Pub/Sub, Amazon Kinesis, and others) or extend the existing one, adding extra features on top (for example, [QoS](https://github.com/mqttjs/MQTT.js/blob/master/README.md#qos) for MQTT).

> **Hint** To better understand how Nest microservices work and how you can extend the capabilities of existing transporters, we recommend reading the [NestJS Microservices in Action](https://dev.to/johnbiundo/series/4724) and [Advanced NestJS Microservices](https://dev.to/nestjs/part-1-introduction-and-setup-1a2l) article series.

#### Creating a strategy[#](/microservices/custom-transport#creating-a-strategy)

First, let's define a class representing our custom transporter.

```typescript

import { CustomTransportStrategy, Server } from '@nestjs/microservices';

class GoogleCloudPubSubServer
  extends Server
  implements CustomTransportStrategy {
  /**
   * This method is triggered when you run "app.listen()".
   */
  listen(callback: () => void) {
    callback();
  }

  /**
   * This method is triggered on application shutdown.
   */
  close() {}
}
```

> **Warning** Please, note we won't be implementing a fully-featured Google Cloud Pub/Sub server in this chapter as this would require diving into transporter specific technical details.

In our example above, we declared the `GoogleCloudPubSubServer` class and provided `listen()` and `close()` methods enforced by the `CustomTransportStrategy` interface. Also, our class extends the `Server` class imported from the `@nestjs/microservices` package that provides a few useful methods, for example, methods used by Nest runtime to register message handlers. Alternatively, in case you want to extend the capabilities of an existing transport strategy, you could extend the corresponding server class, for example, `ServerRedis`. Conventionally, we added the `"Server"` suffix to our class as it will be responsible for subscribing to messages/events (and responding to them, if necessary).

With this in place, we can now use our custom strategy instead of using a built-in transporter, as follows:

```typescript

const app = await NestFactory.createMicroservice<MicroserviceOptions>(
  AppModule,
  {
    strategy: new GoogleCloudPubSubServer(),
  },
);
```

Basically, instead of passing the normal transporter options object with `transport` and `options` properties, we pass a single property, `strategy`, whose value is an instance of our custom transporter class.

Back to our `GoogleCloudPubSubServer` class, in a real-world application, we would be establishing a connection to our message broker/external service and registering subscribers/listening to specific channels in `listen()` method (and then removing subscriptions & closing the connection in the `close()` teardown method), but since this requires a good understanding of how Nest microservices communicate with each other, we recommend reading this [article series](https://dev.to/nestjs/part-1-introduction-and-setup-1a2l). In this chapter instead, we'll focus on the capabilities the `Server` class provides and how you can leverage them to build custom strategies.

For example, let's say that somewhere in our application, the following message handler is defined:

```typescript

@MessagePattern('echo')
echo(@Payload() data: object) {
  return data;
}
```

This message handler will be automatically registered by Nest runtime. With `Server` class, you can see what message patterns have been registered and also, access and execute the actual methods that were assigned to them. To test this out, let's add a simple `console.log` inside `listen()` method before `callback` function is called:

```typescript

listen(callback: () => void) {
  console.log(this.messageHandlers);
  callback();
}
```

After your application restarts, you'll see the following log in your terminal:

```typescript

Map { 'echo' => [AsyncFunction] { isEventHandler: false } }
```

> **Hint** If we used the `@EventPattern` decorator, you would see the same output, but with the `isEventHandler` property set to `true`.

As you can see, the `messageHandlers` property is a `Map` collection of all message (and event) handlers, in which patterns are being used as keys. Now, you can use a key (for example, `"echo"`) to receive a reference to the message handler:

```typescript

async listen(callback: () => void) {
  const echoHandler = this.messageHandlers.get('echo');
  console.log(await echoHandler('Hello world!'));
  callback();
}
```

Once we execute the `echoHandler` passing an arbitrary string as an argument (`"Hello world!"` here), we should see it in the console:

```json

Hello world!
```

Which means that our method handler was properly executed.

When using a `CustomTransportStrategy` with [Interceptors](/v9/interceptors) the handlers are wrapped into RxJS streams. This means that you need to subscribe to them in order to execute the streams underlying logic (e.g. continue into the controller logic after an interceptor has been executed).

An example of this can be seen below:

```typescript

async listen(callback: () => void) {
  const echoHandler = this.messageHandlers.get('echo');
  const streamOrResult = await echoHandler('Hello World');
  if (isObservable(streamOrResult)) {
    streamOrResult.subscribe();
  }
  callback();
}
```

#### Client proxy[#](/microservices/custom-transport#client-proxy)

As we mentioned in the first section, you don't necessarily need to use the `@nestjs/microservices` package to create microservices, but if you decide to do so and you need to integrate a custom strategy, you will need to provide a "client" class too.

> **Hint** Again, implementing a fully-featured client class compatible with all `@nestjs/microservices` features (e.g., streaming) requires a good understanding of communication techniques used by the framework. To learn more, check out this [article](https://dev.to/nestjs/part-4-basic-client-component-16f9).

To communicate with an external service/emit & publish messages (or events) you can either use a library-specific SDK package, or implement a custom client class that extends the `ClientProxy`, as follows:

```typescript

import { ClientProxy, ReadPacket, WritePacket } from '@nestjs/microservices';

class GoogleCloudPubSubClient extends ClientProxy {
  async connect(): Promise<any> {}
  async close() {}
  async dispatchEvent(packet: ReadPacket<any>): Promise<any> {}
  publish(
    packet: ReadPacket<any>,
    callback: (packet: WritePacket<any>) => void,
  ): Function {}
}
```

> **Warning** Please, note we won't be implementing a fully-featured Google Cloud Pub/Sub client in this chapter as this would require diving into transporter specific technical details.

As you can see, `ClientProxy` class requires us to provide several methods for establishing & closing the connection and publishing messages (`publish`) and events (`dispatchEvent`). Note, if you don't need a request-response communication style support, you can leave the `publish()` method empty. Likewise, if you don't need to support event-based communication, skip the `dispatchEvent()` method.

To observe what and when those methods are executed, let's add multiple `console.log` calls, as follows:

```typescript

class GoogleCloudPubSubClient extends ClientProxy {
  async connect(): Promise<any> {
    console.log('connect');
  }

  async close() {
    console.log('close');
  }

  async dispatchEvent(packet: ReadPacket<any>): Promise<any> {
    return console.log('event to dispatch: ', packet);
  }

  publish(
    packet: ReadPacket<any>,
    callback: (packet: WritePacket<any>) => void,
  ): Function {
    console.log('message:', packet);

    // In a real-world application, the "callback" function should be executed
    // with payload sent back from the responder. Here, we'll simply simulate (5 seconds delay)
    // that response came through by passing the same "data" as we've originally passed in.
    setTimeout(() => callback({ response: packet.data }), 5000);

    return () => console.log('teardown');
  }
}
```

With this in place, let's create an instance of `GoogleCloudPubSubClient` class and run the `send()` method (which you might have seen in earlier chapters), subscribing to the returned observable stream.

```typescript

const googlePubSubClient = new GoogleCloudPubSubClient();
googlePubSubClient
  .send('pattern', 'Hello world!')
  .subscribe((response) => console.log(response));
```

Now, you should see the following output in your terminal:

```typescript

connect
message: { pattern: 'pattern', data: 'Hello world!' }
Hello world! // <-- after 5 seconds
```

To test if our "teardown" method (which our `publish()` method returns) is properly executed, let's apply a timeout operator to our stream, setting it to 2 seconds to make sure it throws earlier then our `setTimeout` calls the `callback` function.

```typescript

const googlePubSubClient = new GoogleCloudPubSubClient();
googlePubSubClient
  .send('pattern', 'Hello world!')
  .pipe(timeout(2000))
  .subscribe(
    (response) => console.log(response),
    (error) => console.error(error.message),
  );
```

> **Hint** The `timeout` operator is imported from the `rxjs/operators` package.

With `timeout` operator applied, your terminal output should look as follows:

```typescript

connect
message: { pattern: 'pattern', data: 'Hello world!' }
teardown // <-- teardown
Timeout has occurred
```

To dispatch an event (instead of sending a message), use the `emit()` method:

```typescript

googlePubSubClient.emit('event', 'Hello world!');
```

And that's what you should see in the console:

```typescript

connect
event to dispatch:  { pattern: 'event', data: 'Hello world!' }
```

#### Message serialization[#](/microservices/custom-transport#message-serialization)

If you need to add some custom logic around the serialization of responses on the client side, you can use a custom class that extends the `ClientProxy` class or one of its child classes. For modifying successful requests you can override the `serializeResponse` method, and for modifying any errors that go through this client you can override the `serializeError` method. To make use of this custom class, you can pass the class itself to the `ClientsModule.register()` method using the `customClass` property. Below is an example of a custom `ClientProxy` that serializes each error into an `RpcException`.

error-handling.proxy.ts

JS TS

```typescript

import { ClientTcp, RpcException } from '@nestjs/microservices';

class ErrorHandlingProxy extends ClientTCP {
  serializeError(err: Error) {
    return new RpcException(err);
  }
}
```

and then use it in the `ClientsModule` like so:

app.module.ts

JS TS

```typescript

@Module({
  imports: [
    ClientsModule.register({
      name: 'CustomProxy',
      customClass: ErrorHandlingProxy,
    }),
  ]
})
export class AppModule
```

> **hint** This is the class itself being passed to `customClass`, not an instance of the class. Nest will create the instance under the hood for you, and will pass any options given to the `options` property to the new `ClientProxy`.

----
url: https://docs.nestjs.com/v8/fundamentals/module-ref
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Module reference](https://docs.nestjs.com/v8/fundamentals/module-ref#module-reference)
* [Retrieving instances](https://docs.nestjs.com/v8/fundamentals/module-ref#retrieving-instances)
* [Resolving scoped providers](https://docs.nestjs.com/v8/fundamentals/module-ref#resolving-scoped-providers)
* [Registering REQUEST provider](https://docs.nestjs.com/v8/fundamentals/module-ref#registering-request-provider)
* [Getting current sub-tree](https://docs.nestjs.com/v8/fundamentals/module-ref#getting-current-sub-tree)
* [Instantiating custom classes dynamically](https://docs.nestjs.com/v8/fundamentals/module-ref#instantiating-custom-classes-dynamically)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/fundamentals/module-reference.md "Suggest Edits")

### Module reference

Nest provides the `ModuleRef` class to navigate the internal list of providers and obtain a reference to any provider using its injection token as a lookup key. The `ModuleRef` class also provides a way to dynamically instantiate both static and scoped providers. `ModuleRef` can be injected into a class in the normal way:

cats.service.ts

JS TS

```typescript

@Injectable()
export class CatsService {
  constructor(private moduleRef: ModuleRef) {}
}
```

```typescript

@Injectable()
@Dependencies(ModuleRef)
export class CatsService {
  constructor(moduleRef) {
    this.moduleRef = moduleRef;
  }
}
```

> **Hint** The `ModuleRef` class is imported from the `@nestjs/core` package.

#### Retrieving instances[#](/fundamentals/module-ref#retrieving-instances)

The `ModuleRef` instance (hereafter we'll refer to it as the **module reference**) has a `get()` method. This method retrieves a provider, controller, or injectable (e.g., guard, interceptor, etc.) that exists (has been instantiated) in the **current** module using its injection token/class name.

cats.service.ts

JS TS

```typescript

@Injectable()
export class CatsService implements OnModuleInit {
  private service: Service;
  constructor(private moduleRef: ModuleRef) {}

  onModuleInit() {
    this.service = this.moduleRef.get(Service);
  }
}
```

```typescript

@Injectable()
@Dependencies(ModuleRef)
export class CatsService {
  constructor(moduleRef) {
    this.moduleRef = moduleRef;
  }

  onModuleInit() {
    this.service = this.moduleRef.get(Service);
  }
}
```

> **Warning** You can't retrieve scoped providers (transient or request-scoped) with the `get()` method. Instead, use the technique described [below](https://docs.nestjs.com/fundamentals/module-ref#resolving-scoped-providers). Learn how to control scopes [here](/v8/fundamentals/injection-scopes).

To retrieve a provider from the global context (for example, if the provider has been injected in a different module), pass the `{ strict: false }` option as a second argument to `get()`.

```typescript

this.moduleRef.get(Service, { strict: false });
```

#### Resolving scoped providers[#](/fundamentals/module-ref#resolving-scoped-providers)

To dynamically resolve a scoped provider (transient or request-scoped), use the `resolve()` method, passing the provider's injection token as an argument.

cats.service.ts

JS TS

```typescript

@Injectable()
export class CatsService implements OnModuleInit {
  private transientService: TransientService;
  constructor(private moduleRef: ModuleRef) {}

  async onModuleInit() {
    this.transientService = await this.moduleRef.resolve(TransientService);
  }
}
```

```typescript

@Injectable()
@Dependencies(ModuleRef)
export class CatsService {
  constructor(moduleRef) {
    this.moduleRef = moduleRef;
  }

  async onModuleInit() {
    this.transientService = await this.moduleRef.resolve(TransientService);
  }
}
```

The `resolve()` method returns a unique instance of the provider, from its own **DI container sub-tree**. Each sub-tree has a unique **context identifier**. Thus, if you call this method more than once and compare instance references, you will see that they are not equal.

cats.service.ts

JS TS

```typescript

@Injectable()
export class CatsService implements OnModuleInit {
  constructor(private moduleRef: ModuleRef) {}

  async onModuleInit() {
    const transientServices = await Promise.all([
      this.moduleRef.resolve(TransientService),
      this.moduleRef.resolve(TransientService),
    ]);
    console.log(transientServices[0] === transientServices[1]); // false
  }
}
```

```typescript

@Injectable()
@Dependencies(ModuleRef)
export class CatsService {
  constructor(moduleRef) {
    this.moduleRef = moduleRef;
  }

  async onModuleInit() {
    const transientServices = await Promise.all([
      this.moduleRef.resolve(TransientService),
      this.moduleRef.resolve(TransientService),
    ]);
    console.log(transientServices[0] === transientServices[1]); // false
  }
}
```

To generate a single instance across multiple `resolve()` calls, and ensure they share the same generated DI container sub-tree, you can pass a context identifier to the `resolve()` method. Use the `ContextIdFactory` class to generate a context identifier. This class provides a `create()` method that returns an appropriate unique identifier.

cats.service.ts

JS TS

```typescript

@Injectable()
export class CatsService implements OnModuleInit {
  constructor(private moduleRef: ModuleRef) {}

  async onModuleInit() {
    const contextId = ContextIdFactory.create();
    const transientServices = await Promise.all([
      this.moduleRef.resolve(TransientService, contextId),
      this.moduleRef.resolve(TransientService, contextId),
    ]);
    console.log(transientServices[0] === transientServices[1]); // true
  }
}
```

```typescript

@Injectable()
@Dependencies(ModuleRef)
export class CatsService {
  constructor(moduleRef) {
    this.moduleRef = moduleRef;
  }

  async onModuleInit() {
    const contextId = ContextIdFactory.create();
    const transientServices = await Promise.all([
      this.moduleRef.resolve(TransientService, contextId),
      this.moduleRef.resolve(TransientService, contextId),
    ]);
    console.log(transientServices[0] === transientServices[1]); // true
  }
}
```

> **Hint** The `ContextIdFactory` class is imported from the `@nestjs/core` package.

#### Registering `REQUEST` provider[#](/fundamentals/module-ref#registering-request-provider)

Manually generated context identifiers (with `ContextIdFactory.create()`) represent DI sub-trees in which `REQUEST` provider is `undefined` as they are not instantiated and managed by the Nest dependency injection system.

To register a custom `REQUEST` object for a manually created DI sub-tree, use the `ModuleRef#registerRequestByContextId()` method, as follows:

```typescript

const contextId = ContextIdFactory.create();
this.moduleRef.registerRequestByContextId(/* YOUR_REQUEST_OBJECT */, contextId);
```

#### Getting current sub-tree[#](/fundamentals/module-ref#getting-current-sub-tree)

Occasionally, you may want to resolve an instance of a request-scoped provider within a **request context**. Let's say that `CatsService` is request-scoped and you want to resolve the `CatsRepository` instance which is also marked as a request-scoped provider. In order to share the same DI container sub-tree, you must obtain the current context identifier instead of generating a new one (e.g., with the `ContextIdFactory.create()` function, as shown above). To obtain the current context identifier, start by injecting the request object using `@Inject()` decorator.

cats.service.ts

JS TS

```typescript

@Injectable()
export class CatsService {
  constructor(
    @Inject(REQUEST) private request: Record<string, unknown>,
  ) {}
}
```

```typescript

@Injectable()
@Dependencies(REQUEST)
export class CatsService {
  constructor(request) {
    this.request = request;
  }
}
```

> **Hint** Learn more about the request provider [here](https://docs.nestjs.com/fundamentals/injection-scopes#request-provider).

Now, use the `getByRequest()` method of the `ContextIdFactory` class to create a context id based on the request object, and pass this to the `resolve()` call:

```typescript

const contextId = ContextIdFactory.getByRequest(this.request);
const catsRepository = await this.moduleRef.resolve(CatsRepository, contextId);
```

#### Instantiating custom classes dynamically[#](/fundamentals/module-ref#instantiating-custom-classes-dynamically)

To dynamically instantiate a class that **wasn't previously registered** as a **provider**, use the module reference's `create()` method.

cats.service.ts

JS TS

```typescript

@Injectable()
export class CatsService implements OnModuleInit {
  private catsFactory: CatsFactory;
  constructor(private moduleRef: ModuleRef) {}

  async onModuleInit() {
    this.catsFactory = await this.moduleRef.create(CatsFactory);
  }
}
```

```typescript

@Injectable()
@Dependencies(ModuleRef)
export class CatsService {
  constructor(moduleRef) {
    this.moduleRef = moduleRef;
  }

  async onModuleInit() {
    this.catsFactory = await this.moduleRef.create(CatsFactory);
  }
}
```

This technique enables you to conditionally instantiate different classes outside of the framework container.

## Hoodies, T-shirts, and accessories!

Support our future development by shopping in the official store!

[See more](https://nestjs.threadless.com/ "Shop | NestJS - A node.js framework built on top of TypeScript")

----
url: https://docs.nestjs.com/v7/websockets/pipes
----

* [Pipes](https://docs.nestjs.com/v7/websockets/pipes#pipes)
* [Binding pipes](https://docs.nestjs.com/v7/websockets/pipes#binding-pipes)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/websockets/pipes.md "Suggest Edits")

### Pipes

There is no fundamental difference between [regular pipes](/v7/pipes) and web sockets pipes. The only difference is that instead of throwing `HttpException`, you should use `WsException`. In addition, all pipes will be only applied to the `data` parameter (because validating or transforming `client` instance is useless).

> **Hint** The `WsException` class is exposed from `@nestjs/websockets` package.

#### Binding pipes[#](/websockets/pipes#binding-pipes)

The following example uses a manually instantiated method-scoped pipe. Just as with HTTP based applications, you can also use gateway-scoped pipes (i.e., prefix the gateway class with a `@UsePipes()` decorator).

JS TS

```typescript

@UsePipes(new ValidationPipe())
@SubscribeMessage('events')
handleEvent(client: Client, data: unknown): WsResponse<unknown> {
  const event = 'events';
  return { event, data };
}
```

```typescript

@UsePipes(new ValidationPipe())
@SubscribeMessage('events')
handleEvent(client, data) {
  const event = 'events';
  return { event, data };
}
```

----
url: https://docs.nestjs.com/v4/faq/global-prefix
----

### Global Prefix

To set the prefix for each route in the application, let's use the `setGlobalPrefix()` method of the `INestApplication` object.

TypeScript

```typescript

const app = await NestFactory.create(ApplicationModule);
app.setGlobalPrefix('v1');
```

#### Sponsors

[](https://valor-software.com/)

Nest is an MIT-licensed open source project. It can grow thanks to the support by these awesome people. If you'd like to join them, please read more [here](https://opencollective.com/nest). Thanks!

[](https://opencollective.com/nest/backer/0/website)[](https://opencollective.com/nest/backer/1/website)[](https://opencollective.com/nest/backer/2/website)[](https://opencollective.com/nest/backer/3/website)[](https://opencollective.com/nest/backer/4/website)[](https://opencollective.com/nest/backer/5/website)[](https://opencollective.com/nest/backer/6/website)[](https://opencollective.com/nest/backer/7/website)[](https://opencollective.com/nest/backer/8/website)[](https://opencollective.com/nest/backer/9/website)[](https://opencollective.com/nest/backer/10/website)[](https://opencollective.com/nest/backer/11/website)[](https://opencollective.com/nest/backer/12/website)[](https://opencollective.com/nest/backer/13/website)[](https://opencollective.com/nest/backer/14/website)[](https://opencollective.com/nest/backer/15/website)[](https://opencollective.com/nest/backer/16/website)[](https://opencollective.com/nest/backer/17/website)[](https://opencollective.com/nest/backer/18/website)[](https://opencollective.com/nest/backer/19/website)[](https://opencollective.com/nest/backer/20/website)[](https://opencollective.com/nest/backer/21/website)[](https://opencollective.com/nest/backer/22/website)[](https://opencollective.com/nest/backer/23/website)[](https://opencollective.com/nest/backer/24/website)[](https://opencollective.com/nest/backer/25/website)[](https://opencollective.com/nest/backer/26/website)[](https://opencollective.com/nest/backer/27/website)[](https://opencollective.com/nest/backer/28/website)[](https://opencollective.com/nest/backer/29/website)

[Become a sponsor](https://opencollective.com/nest)

----
url: https://docs.nestjs.com/v11/graphql/complexity
----

* [Complexity](https://docs.nestjs.com/v11/graphql/complexity#complexity)
* [Installation](https://docs.nestjs.com/v11/graphql/complexity#installation)
* [Getting started](https://docs.nestjs.com/v11/graphql/complexity#getting-started)
* [Field-level complexity](https://docs.nestjs.com/v11/graphql/complexity#field-level-complexity)
* [Query/Mutation-level complexity](https://docs.nestjs.com/v11/graphql/complexity#querymutation-level-complexity)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/complexity.md "Suggest Edits")

### Complexity

> **Warning** This chapter applies only to the code first approach.

Query complexity allows you to define how complex certain fields are, and to restrict queries with a **maximum complexity**. The idea is to define how complex each field is by using a simple number. A common default is to give each field a complexity of `1`. In addition, the complexity calculation of a GraphQL query can be customized with so-called complexity estimators. A complexity estimator is a simple function that calculates the complexity for a field. You can add any number of complexity estimators to the rule, which are then executed one after another. The first estimator that returns a numeric complexity value determines the complexity for that field.

The `@nestjs/graphql` package integrates very well with tools like [graphql-query-complexity](https://github.com/slicknode/graphql-query-complexity) that provides a cost analysis-based solution. With this library, you can reject queries to your GraphQL server that are deemed too costly to execute.

#### Installation[#](/graphql/complexity#installation)

To begin using it, we first install the required dependency.

```bash

$ npm install --save graphql-query-complexity
```

#### Getting started[#](/graphql/complexity#getting-started)

Once the installation process is complete, we can define the `ComplexityPlugin` class:

```typescript

import { GraphQLSchemaHost } from '@nestjs/graphql';
import { Plugin } from '@nestjs/apollo';
import {
  ApolloServerPlugin,
  BaseContext,
  GraphQLRequestListener,
} from '@apollo/server';
import { GraphQLError } from 'graphql';
import {
  fieldExtensionsEstimator,
  getComplexity,
  simpleEstimator,
} from 'graphql-query-complexity';

@Plugin()
export class ComplexityPlugin implements ApolloServerPlugin {
  constructor(private gqlSchemaHost: GraphQLSchemaHost) {}

  async requestDidStart(): Promise<GraphQLRequestListener<BaseContext>> {
    const maxComplexity = 20;
    const { schema } = this.gqlSchemaHost;

    return {
      async didResolveOperation({ request, document }) {
        const complexity = getComplexity({
          schema,
          operationName: request.operationName,
          query: document,
          variables: request.variables,
          estimators: [
            fieldExtensionsEstimator(),
            simpleEstimator({ defaultComplexity: 1 }),
          ],
        });
        if (complexity > maxComplexity) {
          throw new GraphQLError(
            `Query is too complex: ${complexity}. Maximum allowed complexity: ${maxComplexity}`,
          );
        }
        console.log('Query Complexity:', complexity);
      },
    };
  }
}
```

For demonstration purposes, we specified the maximum allowed complexity as `20`. In the example above, we used 2 estimators, the `simpleEstimator` and the `fieldExtensionsEstimator`.

* `simpleEstimator`: the simple estimator returns a fixed complexity for each field
* `fieldExtensionsEstimator`: the field extensions estimator extracts the complexity value for each field of your schema

> **Hint** Remember to add this class to the providers array in any module.

#### Field-level complexity[#](/graphql/complexity#field-level-complexity)

With this plugin in place, we can now define the complexity for any field by specifying the `complexity` property in the options object passed into the `@Field()` decorator, as follows:

```typescript

@Field({ complexity: 3 })
title: string;
```

Alternatively, you can define the estimator function:

```typescript

@Field({ complexity: (options: ComplexityEstimatorArgs) => ... })
title: string;
```

#### Query/Mutation-level complexity[#](/graphql/complexity#querymutation-level-complexity)

In addition, `@Query()` and `@Mutation()` decorators may have a `complexity` property specified like so:

```typescript

@Query({ complexity: (options: ComplexityEstimatorArgs) => options.args.count * options.childComplexity })
items(@Args('count') count: number) {
  return this.itemsService.getItems({ count });
}
```

----
url: https://docs.nestjs.com/v10/websockets/exception-filters
----

* [Exception filters](https://docs.nestjs.com/v10/websockets/exception-filters#exception-filters)
* [Filters](https://docs.nestjs.com/v10/websockets/exception-filters#filters)
* [Inheritance](https://docs.nestjs.com/v10/websockets/exception-filters#inheritance)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/websockets/exception-filters.md "Suggest Edits")

### Exception filters

The only difference between the HTTP [exception filter](/v10/exception-filters) layer and the corresponding web sockets layer is that instead of throwing `HttpException`, you should use `WsException`.

```typescript

throw new WsException('Invalid credentials.');
```

> **Hint** The `WsException` class is imported from the `@nestjs/websockets` package.

With the sample above, Nest will handle the thrown exception and emit the `exception` message with the following structure:

```typescript

{
  status: 'error',
  message: 'Invalid credentials.'
}
```

#### Filters[#](/websockets/exception-filters#filters)

Web sockets exception filters behave equivalently to HTTP exception filters. The following example uses a manually instantiated method-scoped filter. Just as with HTTP based applications, you can also use gateway-scoped filters (i.e., prefix the gateway class with a `@UseFilters()` decorator).

```typescript

@UseFilters(new WsExceptionFilter())
@SubscribeMessage('events')
onEvent(client, data: any): WsResponse<any> {
  const event = 'events';
  return { event, data };
}
```

#### Inheritance[#](/websockets/exception-filters#inheritance)

Typically, you'll create fully customized exception filters crafted to fulfill your application requirements. However, there might be use-cases when you would like to simply extend the **core exception filter**, and override the behavior based on certain factors.

In order to delegate exception processing to the base filter, you need to extend `BaseWsExceptionFilter` and call the inherited `catch()` method.

JS TS

```typescript

import { Catch, ArgumentsHost } from '@nestjs/common';
import { BaseWsExceptionFilter } from '@nestjs/websockets';

@Catch()
export class AllExceptionsFilter extends BaseWsExceptionFilter {
  catch(exception: unknown, host: ArgumentsHost) {
    super.catch(exception, host);
  }
}
```

```typescript

import { Catch } from '@nestjs/common';
import { BaseWsExceptionFilter } from '@nestjs/websockets';

@Catch()
export class AllExceptionsFilter extends BaseWsExceptionFilter {
  catch(exception, host) {
    super.catch(exception, host);
  }
}
```

----
url: https://docs.nestjs.com/v10/openapi/security
----

* [Security](https://docs.nestjs.com/v10/openapi/security#security)
* [Basic authentication](https://docs.nestjs.com/v10/openapi/security#basic-authentication)
* [Bearer authentication](https://docs.nestjs.com/v10/openapi/security#bearer-authentication)
* [OAuth2 authentication](https://docs.nestjs.com/v10/openapi/security#oauth2-authentication)
* [Cookie authentication](https://docs.nestjs.com/v10/openapi/security#cookie-authentication)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/openapi/security.md "Suggest Edits")

### Security

To define which security mechanisms should be used for a specific operation, use the `@ApiSecurity()` decorator.

```typescript

@ApiSecurity('basic')
@Controller('cats')
export class CatsController {}
```

Before you run your application, remember to add the security definition to your base document using `DocumentBuilder`:

```typescript

const options = new DocumentBuilder().addSecurity('basic', {
  type: 'http',
  scheme: 'basic',
});
```

Some of the most popular authentication techniques are built-in (e.g., `basic` and `bearer`) and therefore you don't have to define security mechanisms manually as shown above.

#### Basic authentication[#](/openapi/security#basic-authentication)

To enable basic authentication, use `@ApiBasicAuth()`.

```typescript

@ApiBasicAuth()
@Controller('cats')
export class CatsController {}
```

Before you run your application, remember to add the security definition to your base document using `DocumentBuilder`:

```typescript

const options = new DocumentBuilder().addBasicAuth();
```

#### Bearer authentication[#](/openapi/security#bearer-authentication)

To enable bearer authentication, use `@ApiBearerAuth()`.

```typescript

@ApiBearerAuth()
@Controller('cats')
export class CatsController {}
```

Before you run your application, remember to add the security definition to your base document using `DocumentBuilder`:

```typescript

const options = new DocumentBuilder().addBearerAuth();
```

#### OAuth2 authentication[#](/openapi/security#oauth2-authentication)

To enable OAuth2, use `@ApiOAuth2()`.

```typescript

@ApiOAuth2(['pets:write'])
@Controller('cats')
export class CatsController {}
```

Before you run your application, remember to add the security definition to your base document using `DocumentBuilder`:

```typescript

const options = new DocumentBuilder().addOAuth2();
```

#### Cookie authentication[#](/openapi/security#cookie-authentication)

To enable cookie authentication, use `@ApiCookieAuth()`.

```typescript

@ApiCookieAuth()
@Controller('cats')
export class CatsController {}
```

Before you run your application, remember to add the security definition to your base document using `DocumentBuilder`:

```typescript

const options = new DocumentBuilder().addCookieAuth('optional-session-id');
```

----
url: https://docs.nestjs.com/v7/security/encryption-and-hashing
----

* [Encryption and Hashing](https://docs.nestjs.com/v7/security/encryption-and-hashing#encryption-and-hashing)
* [Encryption](https://docs.nestjs.com/v7/security/encryption-and-hashing#encryption)
* [Hashing](https://docs.nestjs.com/v7/security/encryption-and-hashing#hashing)

```typescript

import { createCipheriv, randomBytes } from 'crypto';
import { promisify } from 'util';

const iv = randomBytes(16);
const password = 'Password used to generate key';

// The key length is dependent on the algorithm.
// In this case for aes256, it is 32 bytes.
const key = (await promisify(scrypt)(password, 'salt', 32)) as Buffer;
const cipher = createCipheriv('aes-256-ctr', key, iv);

const textToEncrypt = 'Nest';
const encryptedText = Buffer.concat([
  cipher.update(textToEncrypt),
  cipher.final(),
]);
```

Now to decrypt `encryptedText` value:

```typescript

import { createDecipheriv } from 'crypto';

const decipher = createDecipheriv('aes-256-ctr', key, iv);
const decryptedText = Buffer.concat([
  decipher.update(encryptedText),
  decipher.final(),
]);
```

#### Hashing[#](/security/encryption-and-hashing#hashing)

For hashing, we recommend using either the [bcrypt](https://www.npmjs.com/package/bcrypt) or [argon2](https://www.npmjs.com/package/argon2) packages. Nest itself does not provide any additional wrappers on top of these modules to avoid introducing unnecessary abstractions (making the learning curve short).

As an example, let's use `bcrypt` to hash a random password.

First install required packages:

```shell

$ npm i bcrypt
$ npm i -D @types/bcrypt
```

Once the installation is complete, you can use the `hash` function, as follows:

```typescript

import * as bcrypt from 'bcrypt';

const saltOrRounds = 10;
const password = 'random_password';
const hash = await bcrypt.hash(password, saltOrRounds);
```

To generate a salt, use the `genSalt` function:

```typescript

const salt = await bcrypt.genSalt();
```

To compare/check a password, use the `compare` function:

```typescript

const isMatch = await bcrypt.compare(password, hash);
```

You can read more about available functions [here](https://www.npmjs.com/package/bcrypt).

----
url: https://docs.nestjs.com/v6/fundamentals/execution-context
----

* [Execution context](https://docs.nestjs.com/v6/fundamentals/execution-context#execution-context)
* [ArgumentsHost class](https://docs.nestjs.com/v6/fundamentals/execution-context#argumentshost-class)
* [Current application context](https://docs.nestjs.com/v6/fundamentals/execution-context#current-application-context)
* [Host handler arguments](https://docs.nestjs.com/v6/fundamentals/execution-context#host-handler-arguments)
* [ExecutionContext class](https://docs.nestjs.com/v6/fundamentals/execution-context#executioncontext-class)
* [Reflection and metadata](https://docs.nestjs.com/v6/fundamentals/execution-context#reflection-and-metadata)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/fundamentals/execution-context.md "Suggest Edits")

### Execution context

Nest provides several utility classes that help make it easy to write applications that function across multiple application contexts (e.g., Nest HTTP server-based, microservices and WebSockets application contexts). These utilities provide information about the current execution context which can be used to build generic [guards](/v6/guards), [filters](/v6/exception-filters), and [interceptors](/v6/interceptors) that can work across a broad set of controllers, methods, and execution contexts.

We cover two such classes in this chapter: `ArgumentsHost` and `ExecutionContext`.

#### ArgumentsHost class[#](/fundamentals/execution-context#argumentshost-class)

The `ArgumentsHost` class provides methods for retrieving the arguments being passed to a handler. It allows choosing the appropriate context (e.g., HTTP, RPC (microservice), or WebSockets) to retrieve the arguments from. The framework provides an instance of `ArgumentsHost`, typically referenced as a `host` parameter, in places where you may want to access it. For example, the `catch()` method of an [exception filter](https://docs.nestjs.com/exception-filters#arguments-host) is called with an `ArgumentsHost`instance.

`ArgumentsHost` simply acts as an abstraction over a handler's arguments. For example, for HTTP server applications (when `@nestjs/platform-express` is being used), the `host` object encapsulates Express's `[request, response, next]` array, where `request` is the request object, `response` is the response object, and `next` is a function that controls the application's request-response cycle. On the other hand, for [GraphQL](/v6/graphql/quick-start) applications, the `host` object contains the `[root, args, context, info]` array.

#### Current application context[#](/fundamentals/execution-context#current-application-context)

When building generic [guards](/v6/guards), [filters](/v6/exception-filters), and [interceptors](/v6/interceptors) which are meant to run across multiple application contexts, we need a way to determine the type of application that our method is currently running in. Do this with the `getType()` method of `ArgumentsHost`:

```typescript

const type = host.getType();
if (type === 'http') {
  // HTTP application
} else if (type === 'rpc') {
  // Microservice
}
```

With the application type available, we can write more generic components, as shown below.

#### Host handler arguments[#](/fundamentals/execution-context#host-handler-arguments)

To retrieve the array of arguments being passed to the handler, one approach is to use the host object's `getArgs()` method.

```typescript

const [req, res, next] = host.getArgs();
```

You can pluck a particular argument by index using the `getArgByIndex()` method:

```typescript

const request = host.getArgByIndex(0);
const response = host.getArgByIndex(1);
```

In these examples we retrieved the request and response objects by index, which is not typically recommended as it couples the application to a particular execution context. Instead, you can make your code more robust and reusable by using one of the `host` object's utility methods to switch to the appropriate application context for your application. The context switch utility methods are shown below.

```typescript

/**
 * Switch context to RPC.
 */
switchToRpc(): RpcArgumentsHost;
/**
 * Switch context to HTTP.
 */
switchToHttp(): HttpArgumentsHost;
/**
 * Switch context to WebSockets.
 */
switchToWs(): WsArgumentsHost;
```

Let's rewrite the previous example using the `switchToHttp()` method. The `host.switchToHttp()` helper call returns an `HttpArgumentsHost` object that is appropriate for the HTTP application context. The `HttpArgumentsHost` object has two useful methods we can use to extract the desired objects. We also use the Express type assertions in this case to return native Express typed objects:

```typescript

const ctx = host.switchToHttp();
const request = ctx.getRequest<Request>();
const response = ctx.getResponse<Response>();
```

Similarly `WsArgumentsHost` and `RpcArgumentsHost` have methods to return appropriate objects in the microservices and WebSockets contexts. Here are the methods for `WsArgumentsHost`:

```typescript

export interface WsArgumentsHost {
  /**
   * Returns the data object.
   */
  getData<T>(): T;
  /**
   * Returns the client object.
   */
  getClient<T>(): T;
}
```

Following are the methods for `RpcArgumentsHost`:

```typescript

export interface RpcArgumentsHost {
  /**
   * Returns the data object.
   */
  getData<T>(): T;

  /**
   * Returns the context object.
   */
  getContext<T>(): T;
}
```

#### ExecutionContext class[#](/fundamentals/execution-context#executioncontext-class)

`ExecutionContext` extends `ArgumentsHost`, providing additional details about the current execution process. Like `ArgumentsHost`, Nest provides an instance of `ExecutionContext` in places you may need it, such as in the `canActivate()` method of a [guard](https://docs.nestjs.com/guards#execution-context) and the `intercept()` method of an [interceptor](https://docs.nestjs.com/interceptors#execution-context). It provides the following methods:

```typescript

export interface ExecutionContext extends ArgumentsHost {
  /**
   * Returns the type of the controller class which the current handler belongs to.
   */
  getClass<T>(): Type<T>;
  /**
   * Returns a reference to the handler (method) that will be invoked next in the
   * request pipeline.
   */
  getHandler(): Function;
}
```

The `getHandler()` method returns a reference to the handler about to be invoked. The `getClass()` method returns the type of the `Controller` class which this particular handler belongs to. For example, in an HTTP context, if the currently processed request is a `POST` request, bound to the `create()` method on the `CatsController`, `getHandler()` returns a reference to the `create()` method and `getClass()` returns the `CatsController`**type** (not instance).

```typescript

const methodKey = ctx.getHandler().name; // "create"
const className = ctx.getClass().name; // "CatsController"
```

```typescript

@Post()
@SetMetadata('roles', ['admin'])
async create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

```typescript

@Post()
@SetMetadata('roles', ['admin'])
@Bind(Body())
async create(createCatDto) {
  this.catsService.create(createCatDto);
}
```

> **Hint** The `@SetMetadata()` decorator is imported from the `@nestjs/common` package.

With the construction above, we attached the `roles` metadata (`roles` is a metadata key and `['admin']` is the associated value) to the `create()` method. While this works, it's not good practice to use `@SetMetadata()` directly in your routes. Instead, create your own decorators, as shown below:

roles.decorator.ts

JS TS

```typescript

import { SetMetadata } from '@nestjs/common';

export const Roles = (...roles: string[]) => SetMetadata('roles', roles);
```

```typescript

import { SetMetadata } from '@nestjs/common';

export const Roles = (...roles) => SetMetadata('roles', roles);
```

This approach is much cleaner and more readable, and is strongly typed. Now that we have a custom `@Roles()` decorator, we can use it to decorate the `create()` method.

cats.controller.ts

JS TS

```typescript

@Post()
@Roles('admin')
async create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

```typescript

@Post()
@Roles('admin')
@Bind(Body())
async create(createCatDto) {
  this.catsService.create(createCatDto);
}
```

To access the route's role(s) (custom metadata), we'll use the `Reflector` helper class, which is provided out of the box by the framework and exposed from the `@nestjs/core` package. `Reflector` can be injected into a class in the normal way:

roles.guard.ts

JS TS

```typescript

@Injectable()
export class RolesGuard {
  constructor(private readonly reflector: Reflector) {}
}
```

```typescript

@Injectable()
@Dependencies(Reflector)
export class CatsService {
  constructor(reflector) {
    this.reflector = reflector;
  }
}
```

> **Hint** The `Reflector` class is imported from the `@nestjs/core` package.

Now, to read the handler metadata, use the `get()` method.

```typescript

const roles = this.reflector.get<string[]>('roles', context.getHandler());
```

The `Reflector#get` method allows us to easily access the metadata by passing in two arguments: a metadata **key** and a **context** (decorator target) to retrieve the metadata from. In this example, the specified **key** is `'roles'` (refer back to the `roles.decorator.ts` file above and the `SetMetadata()` call made there). The context is provided by the call to `context.getHandler()`, which results in extracting the metadata for the currently processed route handler. Remember, `getHandler()` gives us a **reference** to the route handler function.

Alternatively, we may organize our controller by applying metadata at the controller level, applying to all routes in the controller class.

cats.controller.ts

JS TS

```typescript

@Roles('admin')
@Controller('cats')
export class CatsController {}
```

```typescript

@Roles('admin')
@Controller('cats')
export class CatsController {}
```

In this case, to extract controller metadata, we pass `context.getClass()` as the second argument (to provide the controller class as the context for metadata extraction) instead of `context.getHandler()`:

roles.guard.ts

JS TS

```typescript

const roles = this.reflector.get<string[]>('roles', context.getClass());
```

```typescript

const roles = this.reflector.get('roles', context.getClass());
```

Given the ability to provide metadata at multiple levels, you may need to extract and merge metadata from several contexts. The `Reflector` class provides two utility methods used to help with this. These methods extract **both** controller and method metadata at once, and combine them in different ways.

Consider the following scenario, where you've supplied `'roles'` metadata at both levels.

cats.controller.ts

JS TS

```typescript

@Roles('user')
@Controller('cats')
export class CatsController {
  @Post()
  @Roles('admin')
  async create(@Body() createCatDto: CreateCatDto) {
    this.catsService.create(createCatDto);
  }
}
```

```typescript

@Roles('user')
@Controller('cats')
export class CatsController {}
  @Post()
  @Roles('admin')
  @Bind(Body())
  async create(createCatDto) {
    this.catsService.create(createCatDto);
  }
}
```

If your intent is to specify `'user'` as the default role, and override it selectively for certain methods, you would probably use the `getAllAndOverride()` method.

```typescript

const roles = this.reflector.getAllAndOverride<string[]>('roles', [
  context.getHandler(),
  context.getClass(),
]);
```

A guard with this code, running in the context of the `create()` method, with the above metadata, would result in `roles` containing `['admin']`.

To get metadata for both and merge it (this method merges both arrays and objects), use the `getAllAndMerge()` method:

```typescript

const roles = this.reflector.getAllAndMerge<string[]>('roles', [
  context.getHandler(),
  context.getClass(),
]);
```

This would result in `roles` containing `['user', 'admin']`.

For both of these merge methods, you pass the metadata key as the first argument, and an array of metadata target contexts (i.e., calls to the `getHandler()` and/or `getClass())` methods) as the second argument.

----
url: https://docs.nestjs.com/guards
----

[Skip to content](#content)

On this page

* [Guards](https://docs.nestjs.com/guards#guards)
* [Authorization guard](https://docs.nestjs.com/guards#authorization-guard)
* [Execution context](https://docs.nestjs.com/guards#execution-context)
* [Role-based authentication](https://docs.nestjs.com/guards#role-based-authentication)
* [Binding guards](https://docs.nestjs.com/guards#binding-guards)
* [Setting roles per handler](https://docs.nestjs.com/guards#setting-roles-per-handler)
* [Putting it all together](https://docs.nestjs.com/guards#putting-it-all-together)

### Guards

A guard is a class annotated with the `@Injectable()` decorator that implements the `CanActivate` interface.

Guards have a **single responsibility**: they determine whether a given request will be handled by the route handler, based on conditions present at runtime (such as permissions, roles, or ACLs). This is often referred to as **authorization**. In traditional Express applications, authorization (and its close relative, **authentication**, with which it usually collaborates) has typically been handled by [middleware](/middleware). Middleware is a good fit for authentication, because tasks such as validating a token and attaching properties to the `request` object are not tied to a particular route context (and its metadata).

Middleware, however, is context-blind by nature: it doesn't know which handler will be executed after it calls `next()`. **Guards**, on the other hand, have access to the `ExecutionContext` instance, so they know exactly what will be executed next. Like exception filters, pipes, and interceptors, guards let you interpose processing logic at exactly the right point in the request/response cycle, and do so declaratively. This helps keep your code DRY.

> **Hint** Guards are executed **after** all middleware, but **before** any interceptor or pipe.

#### Authorization guard[#](/guards#authorization-guard)

As mentioned, **authorization** is a common use case for guards, because specific routes should be available only when the caller (usually a specific authenticated user) has sufficient permissions. The `AuthGuard` we'll build now assumes an authenticated user, and therefore a token attached to the request headers. It extracts and validates the token, and uses the extracted information to determine whether the request can proceed.

auth.guard.ts

JS TS

```typescript

import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
import { Observable } from 'rxjs';

@Injectable()
export class AuthGuard implements CanActivate {
  canActivate(
    context: ExecutionContext,
  ): boolean | Promise<boolean> | Observable<boolean> {
    const request = context.switchToHttp().getRequest();
    return validateRequest(request);
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';

@Injectable()
export class AuthGuard {
  async canActivate(context) {
    const request = context.switchToHttp().getRequest();
    return validateRequest(request);
  }
}
```

> **Hint** For a real-world example of an authentication mechanism, see the [authentication](/security/authentication) chapter. For a more sophisticated authorization example, see the [authorization](/security/authorization) chapter.

The logic inside the `validateRequest()` function can be as simple or as sophisticated as needed. The point of this example is to show how guards fit into the request/response cycle.

Every guard must implement a `canActivate()` method. It returns a boolean indicating whether the current request is allowed, either synchronously or asynchronously (via a `Promise` or an `Observable`). Nest uses the return value to decide what happens next:

* if it returns `true`, the request is processed.
* if it returns `false`, Nest denies the request.

## Official enterprise support

* Providing technical guidance
* Performing in-depth code reviews
* Mentoring team members
* Advising best practices

[Explore more](https://enterprise.nestjs.com "Enterprise | NestJS - A progressive Node.js framework")

#### Execution context[#](/guards#execution-context)

The `canActivate()` method takes a single argument, the `ExecutionContext` instance. `ExecutionContext` extends `ArgumentsHost`, which we covered in the exception filters chapter. The sample above uses the same helper methods defined on `ArgumentsHost` to get a reference to the `Request` object. See the **Arguments host** section of the [exception filters](/exception-filters#arguments-host) chapter for more on this topic.

By extending `ArgumentsHost`, `ExecutionContext` adds several helper methods that provide additional details about the current execution process. These details help you build more generic guards that work across a broad set of controllers, methods, and execution contexts. See the [execution context](/fundamentals/execution-context) chapter to learn more about `ExecutionContext`.

#### Role-based authentication[#](/guards#role-based-authentication)

Let's build a more functional guard that permits access only to users with a specific role. We'll start with a basic guard template and build on it in the following sections. For now, it allows all requests to proceed:

roles.guard.ts

JS TS

```typescript

import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
import { Observable } from 'rxjs';

@Injectable()
export class RolesGuard implements CanActivate {
  canActivate(
    context: ExecutionContext,
  ): boolean | Promise<boolean> | Observable<boolean> {
    return true;
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';

@Injectable()
export class RolesGuard {
  canActivate(context) {
    return true;
  }
}
```

#### Binding guards[#](/guards#binding-guards)

Like pipes and exception filters, guards can be controller-scoped, method-scoped, or global-scoped. Below, we set up a controller-scoped guard using the `@UseGuards()` decorator. The decorator accepts a single guard or a comma-separated list of guards, so you can apply a whole set of guards with one declaration.

JS TS

```typescript

@Controller('cats')
@UseGuards(RolesGuard)
export class CatsController {}
```

> **Hint** The `@UseGuards()` decorator is imported from the `@nestjs/common` package.

Above, we passed the `RolesGuard` class (instead of an instance), leaving responsibility for instantiation to the framework and enabling dependency injection. As with pipes and exception filters, you can also pass an in-place instance:

JS TS

```typescript

@Controller('cats')
@UseGuards(new RolesGuard())
export class CatsController {}
```

The construction above attaches the guard to every handler declared by this controller. To apply the guard to a single method only, use the `@UseGuards()` decorator at the **method level**.

To set up a global guard, use the `useGlobalGuards()` method of the Nest application instance:

JS TS

```typescript

const app = await NestFactory.create(AppModule);
app.useGlobalGuards(new RolesGuard());
```

> **Notice** In a hybrid application, `useGlobalGuards()` doesn't set up guards for connected microservices by default (see [Hybrid application](/faq/hybrid-application) to change this behavior). In a standard (non-hybrid) microservice application, `useGlobalGuards()` does mount the guards globally.

Global guards apply to every controller and every route handler in the application. However, a global guard registered outside of any module (with `useGlobalGuards()`, as in the example above) cannot inject dependencies, because the registration happens outside the context of any module. To solve this, register the guard directly from any module using the following construction:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { APP_GUARD } from '@nestjs/core';

@Module({
  providers: [
    {
      provide: APP_GUARD,
      useClass: RolesGuard,
    },
  ],
})
export class AppModule {}
```

> **Hint** When you use this approach to perform dependency injection for the guard, the guard is global regardless of the module in which you register it. We recommend registering it in the module where the guard (`RolesGuard` in the example above) is defined. Also, `useClass` is not the only way to register a custom provider. See [Custom providers](/fundamentals/custom-providers) to learn more.

> **Hint** You can register the `APP_GUARD` token multiple times (in the same or different modules); every registered guard runs for each request, in registration order. `APP_GUARD` (like the other `APP_*` tokens) is a pseudo-provider that the framework consumes during bootstrap: it cannot be retrieved later with `app.get()` or injected elsewhere.

#### Setting roles per handler[#](/guards#setting-roles-per-handler)

Our `RolesGuard` works, but it isn't very smart yet: it doesn't take advantage of the most important guard feature, the [execution context](/fundamentals/execution-context). It doesn't know about roles, or which roles are allowed for each handler. The `CatsController`, for example, could have different permission schemes for different routes. Some routes might be available only to admin users, while others are open to everyone. How can we match roles to routes in a flexible and reusable way?

This is where **custom metadata** comes into play (see [Reflection and metadata](/fundamentals/execution-context#reflection-and-metadata)). Nest lets you attach custom **metadata** to route handlers, either through decorators created with the static `Reflector.createDecorator()` method or through the built-in `@SetMetadata()` decorator.

For example, let's create a `@Roles()` decorator with the `Reflector.createDecorator()` method that attaches the metadata to the handler. `Reflector` is provided by the framework out of the box and exported from the `@nestjs/core` package.

roles.decorator.ts

JS TS

```ts

import { Reflector } from '@nestjs/core';

export const Roles = Reflector.createDecorator<string[]>();
```

The `Roles` decorator is a function that takes a single argument of type `string[]`.

To use this decorator, annotate the handler with it:

cats.controller.ts

JS TS

```typescript

@Post()
@Roles(['admin'])
async create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

```typescript

@Post()
@Roles(['admin'])
@Bind(Body())
async create(createCatDto) {
  this.catsService.create(createCatDto);
}
```

Here we've attached the `Roles` decorator metadata to the `create()` method, indicating that only users with the `admin` role should be allowed to access this route.

Alternatively, instead of using the `Reflector.createDecorator()` method, you can use the built-in `@SetMetadata()` decorator. See the [low-level approach](/fundamentals/execution-context#low-level-approach) to learn more.

#### Putting it all together[#](/guards#putting-it-all-together)

Let's now tie this together with our `RolesGuard`. Currently, it returns `true` in all cases, allowing every request to proceed. We want to make the return value conditional, based on comparing the **roles assigned to the current user** with the roles required by the route being processed. To access the route's role(s) (custom metadata), we use the `Reflector` class again, as follows:

roles.guard.ts

JS TS

```typescript

import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
import { Reflector } from '@nestjs/core';
import { Roles } from './roles.decorator.js';

@Injectable()
export class RolesGuard implements CanActivate {
  constructor(private reflector: Reflector) {}

  canActivate(context: ExecutionContext): boolean {
    const roles = this.reflector.get(Roles, context.getHandler());
    if (!roles) {
      return true;
    }
    const request = context.switchToHttp().getRequest();
    const user = request.user;
    return matchRoles(roles, user.roles);
  }
}
```

```typescript

import { Injectable, Dependencies } from '@nestjs/common';
import { Reflector } from '@nestjs/core';
import { Roles } from './roles.decorator.js';

@Injectable()
@Dependencies(Reflector)
export class RolesGuard {
  constructor(reflector) {
    this.reflector = reflector;
  }

  canActivate(context) {
    const roles = this.reflector.get(Roles, context.getHandler());
    if (!roles) {
      return true;
    }
    const request = context.switchToHttp().getRequest();
    const user = request.user;
    return matchRoles(roles, user.roles);
  }
}
```

> **Hint** In Node.js applications, it's common practice to attach the authorized user to the `request` object. The sample above therefore assumes that `request.user` contains the user instance and its roles. In your app, you will probably make that association in a custom **authentication guard** (or middleware). See the [authentication](/security/authentication) chapter for more information on this topic.

> **Warning** The `matchRoles()` function is not provided by Nest. Its logic can be as simple or as sophisticated as your application requires; the point of this example is to show how guards fit into the request/response cycle.

See the [Reflection and metadata](/fundamentals/execution-context#reflection-and-metadata) section of the **Execution context** chapter for more details on using `Reflector` in a context-sensitive way.

When a user with insufficient privileges requests an endpoint, Nest automatically returns the following response:

```json

{
  "statusCode": 403,
  "message": "Forbidden resource",
  "error": "Forbidden"
}
```

Behind the scenes, when a guard returns `false`, the framework throws a `ForbiddenException`. To return a different error response, throw your own exception instead. For example:

```typescript

throw new UnauthorizedException();
```

Any exception thrown by a guard is handled by the [exceptions layer](/exception-filters) (the global exception filter and any exception filters applied to the current context).

> **Hint** For a real-world example of how to implement authorization, see the [authorization](/security/authorization) chapter.

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/guards.md)

----
url: https://docs.nestjs.com/v10/techniques/http-module
----

* [HTTP module](https://docs.nestjs.com/v10/techniques/http-module#http-module)
* [Installation](https://docs.nestjs.com/v10/techniques/http-module#installation)
* [Getting started](https://docs.nestjs.com/v10/techniques/http-module#getting-started)
* [Configuration](https://docs.nestjs.com/v10/techniques/http-module#configuration)
* [Async configuration](https://docs.nestjs.com/v10/techniques/http-module#async-configuration)
* [Using Axios directly](https://docs.nestjs.com/v10/techniques/http-module#using-axios-directly)
* [Full example](https://docs.nestjs.com/v10/techniques/http-module#full-example)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/techniques/http-module.md "Suggest Edits")

### HTTP module

[Axios](https://github.com/axios/axios) is a richly featured HTTP client package that is widely used. Nest wraps Axios and exposes it via the built-in `HttpModule`. The `HttpModule` exports the `HttpService` class, which exposes Axios-based methods to perform HTTP requests. The library also transforms the resulting HTTP responses into `Observables`.

> **Hint** You can also use any general purpose Node.js HTTP client library directly, including [got](https://github.com/sindresorhus/got) or [undici](https://github.com/nodejs/undici).

#### Installation[#](/techniques/http-module#installation)

To begin using it, we first install required dependencies.

```bash

$ npm i --save @nestjs/axios axios
```

#### Getting started[#](/techniques/http-module#getting-started)

Once the installation process is complete, to use the `HttpService`, first import `HttpModule`.

```typescript

@Module({
  imports: [HttpModule],
  providers: [CatsService],
})
export class CatsModule {}
```

Next, inject `HttpService` using normal constructor injection.

> **Hint**`HttpModule` and `HttpService` are imported from `@nestjs/axios` package.

JS TS

```typescript

@Injectable()
export class CatsService {
  constructor(private readonly httpService: HttpService) {}

  findAll(): Observable<AxiosResponse<Cat[]>> {
    return this.httpService.get('http://localhost:3000/cats');
  }
}
```

```typescript

@Injectable()
@Dependencies(HttpService)
export class CatsService {
  constructor(httpService) {
    this.httpService = httpService;
  }

  findAll() {
    return this.httpService.get('http://localhost:3000/cats');
  }
}
```

> **Hint**`AxiosResponse` is an interface exported from the `axios` package (`$ npm i axios`).

All `HttpService` methods return an `AxiosResponse` wrapped in an `Observable` object.

#### Configuration[#](/techniques/http-module#configuration)

[Axios](https://github.com/axios/axios) can be configured with a variety of options to customize the behavior of the `HttpService`. Read more about them [here](https://github.com/axios/axios#request-config). To configure the underlying Axios instance, pass an optional options object to the `register()` method of `HttpModule` when importing it. This options object will be passed directly to the underlying Axios constructor.

```typescript

@Module({
  imports: [
    HttpModule.register({
      timeout: 5000,
      maxRedirects: 5,
    }),
  ],
  providers: [CatsService],
})
export class CatsModule {}
```

#### Async configuration[#](/techniques/http-module#async-configuration)

When you need to pass module options asynchronously instead of statically, use the `registerAsync()` method. As with most dynamic modules, Nest provides several techniques to deal with async configuration.

One technique is to use a factory function:

```typescript

HttpModule.registerAsync({
  useFactory: () => ({
    timeout: 5000,
    maxRedirects: 5,
  }),
});
```

Like other factory providers, our factory function can be [async](https://docs.nestjs.com/fundamentals/custom-providers#factory-providers-usefactory) and can inject dependencies through `inject`.

```typescript

HttpModule.registerAsync({
  imports: [ConfigModule],
  useFactory: async (configService: ConfigService) => ({
    timeout: configService.get('HTTP_TIMEOUT'),
    maxRedirects: configService.get('HTTP_MAX_REDIRECTS'),
  }),
  inject: [ConfigService],
});
```

Alternatively, you can configure the `HttpModule` using a class instead of a factory, as shown below.

```typescript

HttpModule.registerAsync({
  useClass: HttpConfigService,
});
```

The construction above instantiates `HttpConfigService` inside `HttpModule`, using it to create an options object. Note that in this example, the `HttpConfigService` has to implement `HttpModuleOptionsFactory` interface as shown below. The `HttpModule` will call the `createHttpOptions()` method on the instantiated object of the supplied class.

```typescript

@Injectable()
class HttpConfigService implements HttpModuleOptionsFactory {
  createHttpOptions(): HttpModuleOptions {
    return {
      timeout: 5000,
      maxRedirects: 5,
    };
  }
}
```

If you want to reuse an existing options provider instead of creating a private copy inside the `HttpModule`, use the `useExisting` syntax.

```typescript

HttpModule.registerAsync({
  imports: [ConfigModule],
  useExisting: HttpConfigService,
});
```

You can also pass so-called `extraProviders` to the `registerAsync()` method. These providers will be merged with the module providers.

```typescript

HttpModule.registerAsync({
  imports: [ConfigModule],
  useClass: HttpConfigService,
  extraProviders: [MyAdditionalProvider],
});
```

This is useful when you want to provide additional dependencies to the factory function or the class constructor.

#### Using Axios directly[#](/techniques/http-module#using-axios-directly)

If you think that `HttpModule.register`'s options are not enough for you, or if you just want to access the underlying Axios instance created by `@nestjs/axios`, you can access it via `HttpService#axiosRef` as follows:

```typescript

@Injectable()
export class CatsService {
  constructor(private readonly httpService: HttpService) {}

  findAll(): Promise<AxiosResponse<Cat[]>> {
    return this.httpService.axiosRef.get('http://localhost:3000/cats');
    //                      ^ AxiosInstance interface
  }
}
```

#### Full example[#](/techniques/http-module#full-example)

Since the return value of the `HttpService` methods is an Observable, we can use `rxjs` - `firstValueFrom` or `lastValueFrom` to retrieve the data of the request in the form of a promise.

```typescript

import { catchError, firstValueFrom } from 'rxjs';

@Injectable()
export class CatsService {
  private readonly logger = new Logger(CatsService.name);
  constructor(private readonly httpService: HttpService) {}

  async findAll(): Promise<Cat[]> {
    const { data } = await firstValueFrom(
      this.httpService.get<Cat[]>('http://localhost:3000/cats').pipe(
        catchError((error: AxiosError) => {
          this.logger.error(error.response.data);
          throw 'An error happened!';
        }),
      ),
    );
    return data;
  }
}
```

> **Hint** Visit RxJS's documentation on [`firstValueFrom`](https://rxjs.dev/api/index/function/firstValueFrom) and [`lastValueFrom`](https://rxjs.dev/api/index/function/lastValueFrom) for differences between them.

----
url: https://docs.nestjs.com/v6/modules
----

* [Modules](https://docs.nestjs.com/v6/modules#modules)
* [Feature modules](https://docs.nestjs.com/v6/modules#feature-modules)
* [Shared modules](https://docs.nestjs.com/v6/modules#shared-modules)
* [Module re-exporting](https://docs.nestjs.com/v6/modules#module-re-exporting)
* [Dependency injection](https://docs.nestjs.com/v6/modules#dependency-injection)
* [Global modules](https://docs.nestjs.com/v6/modules#global-modules)
* [Dynamic modules](https://docs.nestjs.com/v6/modules#dynamic-modules)

[](https://srv.carbonads.net/ads/click/x/GTND4277CVSIC2JEFTBLYKQUF67D62Q7CTSDCZ3JCAAI623WCTADK5QKCEBDEKQECESIL27MC6AI453ICABDC27KC6SILKJUCT7DEK3EHJNCLSIZ)[Kubernetes, Proxmox of databases op AMD EPYC 4005-servers, klaar in enkele minuten. Configureer uw server. ](https://srv.carbonads.net/ads/click/x/GTND4277CVSIC2JEFTBLYKQUF67D62Q7CTSDCZ3JCAAI623WCTADK5QKCEBDEKQECESIL27MC6AI453ICABDC27KC6SILKJUCT7DEK3EHJNCLSIZ)[ads via Carbon](http://carbonads.net/?utm_source=nestjscom\&utm_medium=ad_via_link\&utm_campaign=in_unit\&utm_term=carbon)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/modules.md "Suggest Edits")

### Modules

A module is a class annotated with a `@Module()` decorator. The `@Module()` decorator provides metadata that **Nest** makes use of to organize the application structure.

Each application has at least one module, a **root module**. The root module is the starting point Nest uses to build the **application graph** - the internal data structure Nest uses to resolve module and provider relationships and dependencies. While very small applications may theoretically have just the root module, this is not the typical case. We want to emphasize that modules are **strongly** recommended as an effective way to organize your components. Thus, for most applications, the resulting architecture will employ multiple modules, each encapsulating a closely related set of **capabilities**.

The `@Module()` decorator takes a single object whose properties describe the module:

|               |                                                                                                                              |
| ------------- | ---------------------------------------------------------------------------------------------------------------------------- |
| `providers`   | the providers that will be instantiated by the Nest injector and that may be shared at least across this module              |
| `controllers` | the set of controllers defined in this module which have to be instantiated                                                  |
| `imports`     | the list of imported modules that export the providers which are required in this module                                     |
| `exports`     | the subset of `providers` that are provided by this module and should be available in other modules which import this module |

The module **encapsulates** providers by default. This means that it's impossible to inject providers that are neither directly part of the current module nor exported from the imported modules. Thus, you may consider the exported providers from a module as the module's public interface, or API.

#### Feature modules[#](/modules#feature-modules)

The `CatsController` and `CatsService` belong to the same application domain. As they are closely related, it makes sense to move them into a feature module. A feature module simply organizes code relevant for a specific feature, keeping code organized and establishing clear boundaries. This helps us manage complexity and develop with [SOLID](https://en.wikipedia.org/wiki/SOLID) principles, especially as the size of the application and/or team grow.

To demonstrate this, we'll create the `CatsModule`.

cats/cats.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

@Module({
  controllers: [CatsController],
  providers: [CatsService],
})
export class CatsModule {}
```

> **Hint** To create a module using the CLI, simply execute the `$ nest g module cats` command.

Above, we defined the `CatsModule` in the `cats.module.ts` file, and moved everything related to this module into the `cats` directory. The last thing we need to do is import this module into the root module (the `AppModule`, defined in the `app.module.ts` file).

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { CatsModule } from './cats/cats.module';

@Module({
  imports: [CatsModule],
})
export class AppModule {}
```

```typescript

import { Module } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

@Module({
  controllers: [CatsController],
  providers: [CatsService],
  exports: [CatsService]
})
export class CatsModule {}
```

```typescript

@Module({
  imports: [CommonModule],
  exports: [CommonModule],
})
export class CoreModule {}
```

#### Dependency injection[#](/modules#dependency-injection)

A module class can **inject** providers as well (e.g., for configuration purposes):

cats.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

@Module({
  controllers: [CatsController],
  providers: [CatsService],
})
export class CatsModule {
  constructor(private readonly catsService: CatsService) {}
}
```

```typescript

import { Module, Dependencies } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

@Module({
  controllers: [CatsController],
  providers: [CatsService],
})
@Dependencies(CatsService)
export class CatsModule {
  constructor(catsService) {
    this.catsService = catsService;
  }
}
```

However, module classes themselves cannot be injected as providers due to [circular dependency](/v6/fundamentals/circular-dependency) .

#### Global modules[#](/modules#global-modules)

If you have to import the same set of modules everywhere, it can get tedious. Unlike in Nest, [Angular](https://angular.io)`providers` are registered in the global scope. Once defined, they're available everywhere. Nest, however, encapsulates providers inside the module scope. You aren't able to use a module's providers elsewhere without first importing the encapsulating module.

When you want to provide a set of providers which should be available everywhere out-of-the-box (e.g., helpers, database connections, etc.), make the module **global** with the `@Global()` decorator.

```typescript

import { Module, Global } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

@Global()
@Module({
  controllers: [CatsController],
  providers: [CatsService],
  exports: [CatsService],
})
export class CatsModule {}
```

The `@Global()` decorator makes the module global-scoped. Global modules should be registered **only once**, generally by the root or core module. In the above example, the `CatsService` provider will be ubiquitous, and modules that wish to inject the service will not need to import the `CatsModule` in their imports array.

> **Hint** Making everything global is not a good design decision. Global modules are available to reduce the amount of necessary boilerplate. The `imports` array is generally the preferred way to make the module's API available to consumers.

#### Dynamic modules[#](/modules#dynamic-modules)

The Nest module system includes a powerful feature called **dynamic modules**. This feature enables you to easily create customizable modules that can register and configure providers dynamically. Dynamic modules are covered extensively [here](/v6/fundamentals/dynamic-modules). In this chapter, we'll give a brief overview to complete the introduction to modules.

Following is an example of a dynamic module definition for a `DatabaseModule`:

JS TS

```typescript

import { Module, DynamicModule } from '@nestjs/common';
import { createDatabaseProviders } from './database.providers';
import { Connection } from './connection.provider';

@Module({
  providers: [Connection],
})
export class DatabaseModule {
  static forRoot(entities = [], options?): DynamicModule {
    const providers = createDatabaseProviders(options, entities);
    return {
      module: DatabaseModule,
      providers: providers,
      exports: providers,
    };
  }
}
```

```typescript

import { Module } from '@nestjs/common';
import { createDatabaseProviders } from './database.providers';
import { Connection } from './connection.provider';

@Module({
  providers: [Connection],
})
export class DatabaseModule {
  static forRoot(entities = [], options?) {
    const providers = createDatabaseProviders(options, entities);
    return {
      module: DatabaseModule,
      providers: providers,
      exports: providers,
    };
  }
}
```

> **Hint** The `forRoot()` method may return a dynamic module either synchronously or asynchronously (i.e., via a `Promise`).

This module defines the `Connection` provider by default (in the `@Module()` decorator metadata), but additionally - depending on the `entities` and `options` objects passed into the `forRoot()` method - exposes a collection of providers, for example, repositories. Note that the properties returned by the dynamic module **extend** (rather than override) the base module metadata defined in the `@Module()` decorator. That's how both the statically declared `Connection` provider **and** the dynamically generated repository providers are exported from the module.

If you want to register a dynamic module in the global scope, set the `global` property to `true`.

```typescript

{
  global: true,
  module: DatabaseModule,
  providers: providers,
  exports: providers,
}
```

> **Warning** As mentioned above, making everything global **is not a good design decision**.

The `DatabaseModule` can be imported and configured in the following manner:

```typescript

import { Module } from '@nestjs/common';
import { DatabaseModule } from './database/database.module';
import { User } from './users/entities/user.entity';

@Module({
  imports: [DatabaseModule.forRoot([User])],
})
export class AppModule {}
```

If you want to in turn re-export a dynamic module, you can omit the `forRoot()` method call in the exports array:

```typescript

import { Module } from '@nestjs/common';
import { DatabaseModule } from './database/database.module';
import { User } from './users/entities/user.entity';

@Module({
  imports: [DatabaseModule.forRoot([User])],
  exports: [DatabaseModule],
})
export class AppModule {}
```

The [Dynamic modules](/v6/fundamentals/dynamic-modules) chapter covers this topic in greater detail, and includes a [working example](https://github.com/nestjs/nest/tree/master/sample/25-dynamic-modules).

----
url: https://docs.nestjs.com/v10/faq/request-lifecycle
----

* [Request lifecycle](https://docs.nestjs.com/v10/faq/request-lifecycle#request-lifecycle)
* [Middleware](https://docs.nestjs.com/v10/faq/request-lifecycle#middleware)
* [Guards](https://docs.nestjs.com/v10/faq/request-lifecycle#guards)
* [Interceptors](https://docs.nestjs.com/v10/faq/request-lifecycle#interceptors)
* [Pipes](https://docs.nestjs.com/v10/faq/request-lifecycle#pipes)
* [Filters](https://docs.nestjs.com/v10/faq/request-lifecycle#filters)
* [Summary](https://docs.nestjs.com/v10/faq/request-lifecycle#summary)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/faq/request-lifecycle.md "Suggest Edits")

### Request lifecycle

Nest applications handle requests and produce responses in a sequence we refer to as the **request lifecycle**. With the use of middleware, pipes, guards, and interceptors, it can be challenging to track down where a particular piece of code executes during the request lifecycle, especially as global, controller level, and route level components come into play. In general, a request flows through middleware to guards, then to interceptors, then to pipes and finally back to interceptors on the return path (as the response is generated).

#### Middleware[#](/faq/request-lifecycle#middleware)

Middleware is executed in a particular sequence. First, Nest runs globally bound middleware (such as middleware bound with `app.use`) and then it runs [module bound middleware](/v10/middleware), which are determined on paths. Middleware are run sequentially in the order they are bound, similar to the way middleware in Express works. In the case of middleware bound across different modules, the middleware bound to the root module will run first, and then middleware will run in the order that the modules are added to the imports array.

#### Guards[#](/faq/request-lifecycle#guards)

Guard execution starts with global guards, then proceeds to controller guards, and finally to route guards. As with middleware, guards run in the order in which they are bound. For example:

```typescript

@UseGuards(Guard1, Guard2)
@Controller('cats')
export class CatsController {
  constructor(private catsService: CatsService) {}

  @UseGuards(Guard3)
  @Get()
  getCats(): Cats[] {
    return this.catsService.getCats();
  }
}
```

`Guard1` will execute before `Guard2` and both will execute before `Guard3`.

> **Hint** When speaking about globally bound vs controller or locally bound, the difference is where the guard (or other component is bound). If you are using `app.useGlobalGuard()` or providing the component via a module, it is globally bound. Otherwise, it is bound to a controller if the decorator precedes a controller class, or to a route if the decorator precedes a route declaration.

#### Interceptors[#](/faq/request-lifecycle#interceptors)

Interceptors, for the most part, follow the same pattern as guards, with one catch: as interceptors return [RxJS Observables](https://github.com/ReactiveX/rxjs), the observables will be resolved in a first in last out manner. So inbound requests will go through the standard global, controller, route level resolution, but the response side of the request (i.e., after returning from the controller method handler) will be resolved from route to controller to global. Also, any errors thrown by pipes, controllers, or services can be read in the `catchError` operator of an interceptor.

#### Pipes[#](/faq/request-lifecycle#pipes)

Pipes follow the standard global to controller to route bound sequence, with the same first in first out in regards to the `@UsePipes()` parameters. However, at a route parameter level, if you have multiple pipes running, they will run in the order of the last parameter with a pipe to the first. This also applies to the route level and controller level pipes. For example, if we have the following controller:

```typescript

@UsePipes(GeneralValidationPipe)
@Controller('cats')
export class CatsController {
  constructor(private catsService: CatsService) {}

  @UsePipes(RouteSpecificPipe)
  @Patch(':id')
  updateCat(
    @Body() body: UpdateCatDTO,
    @Param() params: UpdateCatParams,
    @Query() query: UpdateCatQuery,
  ) {
    return this.catsService.updateCat(body, params, query);
  }
}
```

then the `GeneralValidationPipe` will run for the `query`, then the `params`, and then the `body` objects before moving on to the `RouteSpecificPipe`, which follows the same order. If any parameter-specific pipes were in place, they would run (again, from the last to first parameter) after the controller and route level pipes.

#### Filters[#](/faq/request-lifecycle#filters)

Filters are the only component that do not resolve global first. Instead, filters resolve from the lowest level possible, meaning execution starts with any route bound filters and proceeding next to controller level, and finally to global filters. Note that exceptions cannot be passed from filter to filter; if a route level filter catches the exception, a controller or global level filter cannot catch the same exception. The only way to achieve an effect like this is to use inheritance between the filters.

> **Hint** Filters are only executed if any uncaught exception occurs during the request process. Caught exceptions, such as those caught with a `try/catch` will not trigger Exception Filters to fire. As soon as an uncaught exception is encountered, the rest of the lifecycle is ignored and the request skips straight to the filter.

----
url: https://docs.nestjs.com/v9/security/helmet
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Helmet](https://docs.nestjs.com/v9/security/helmet#helmet)
* [Use with Express (default)](https://docs.nestjs.com/v9/security/helmet#use-with-express-default)
* [Use with Fastify](https://docs.nestjs.com/v9/security/helmet#use-with-fastify)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/security/helmet.md "Suggest Edits")

### Helmet

[Helmet](https://github.com/helmetjs/helmet) can help protect your app from some well-known web vulnerabilities by setting HTTP headers appropriately. Generally, Helmet is just a collection of smaller middleware functions that set security-related HTTP headers (read [more](https://github.com/helmetjs/helmet#how-it-works)).

> **Hint** Note that applying `helmet` as global or registering it must come before other calls to `app.use()` or setup functions that may call `app.use()`. This is due to the way the underlying platform (i.e., Express or Fastify) works, where the order that middleware/routes are defined matters. If you use middleware like `helmet` or `cors` after you define a route, then that middleware will not apply to that route, it will only apply to routes defined after the middleware.

#### Use with Express (default)[#](/security/helmet#use-with-express-default)

Start by installing the required package.

```bash

$ npm i --save helmet
```

Once the installation is complete, apply it as a global middleware.

```typescript

import helmet from 'helmet';
// somewhere in your initialization file
app.use(helmet());
```

> **Warning** When using `helmet`, `@apollo/server` (4.x), and the [Apollo Sandbox](https://docs.nestjs.com/graphql/quick-start#apollo-sandbox), there may be a problem with [CSP](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP) on the Apollo Sandbox. To solve this issue configure the CSP as shown below:
>
> ```typescript
>
> app.use(helmet({
>   crossOriginEmbedderPolicy: false,
>   contentSecurityPolicy: {
>     directives: {
>       imgSrc: [`'self'`, 'data:', 'apollo-server-landing-page.cdn.apollographql.com'],
>       scriptSrc: [`'self'`, `https: 'unsafe-inline'`],
>       manifestSrc: [`'self'`, 'apollo-server-landing-page.cdn.apollographql.com'],
>       frameSrc: [`'self'`, 'sandbox.embed.apollographql.com'],
>     },
>   },
> }));
> ```

#### Use with Fastify[#](/security/helmet#use-with-fastify)

If you are using the `FastifyAdapter`, install the [@fastify/helmet](https://github.com/fastify/fastify-helmet) package:

```bash

$ npm i --save @fastify/helmet
```

[fastify-helmet](https://github.com/fastify/fastify-helmet) should not be used as a middleware, but as a [Fastify plugin](https://www.fastify.io/docs/latest/Reference/Plugins/), i.e., by using `app.register()`:

```typescript

import helmet from '@fastify/helmet'
// somewhere in your initialization file
await app.register(helmet)
```

> **Warning** When using `apollo-server-fastify` and `@fastify/helmet`, there may be a problem with [CSP](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP) on the GraphQL playground, to solve this collision, configure the CSP as shown below:
>
> ```typescript
>
> await app.register(fastifyHelmet, {
>    contentSecurityPolicy: {
>      directives: {
>        defaultSrc: [`'self'`, 'unpkg.com'],
>        styleSrc: [
>          `'self'`,
>          `'unsafe-inline'`,
>          'cdn.jsdelivr.net',
>          'fonts.googleapis.com',
>          'unpkg.com',
>        ],
>        fontSrc: [`'self'`, 'fonts.gstatic.com', 'data:'],
>        imgSrc: [`'self'`, 'data:', 'cdn.jsdelivr.net'],
>        scriptSrc: [
>          `'self'`,
>          `https: 'unsafe-inline'`,
>          `cdn.jsdelivr.net`,
>          `'unsafe-eval'`,
>        ],
>      },
>    },
>  });
>
> // If you are not going to use CSP at all, you can use this:
> await app.register(fastifyHelmet, {
>   contentSecurityPolicy: false,
> });
> ```

----
url: https://docs.nestjs.com/v5/recipes/sql-sequelize
----

### SQL (Sequelize)

##### This chapter applies only to TypeScript

[Sequelize](https://github.com/sequelize/sequelize) is a popular Object Relational Mapper (ORM) written in a vanilla JavaScript, but there is a [sequelize-typescript](https://github.com/RobinBuschmann/sequelize-typescript) TypeScript wrapper which provides a set of decorators and other extras for the base sequelize. To start the adventure with this library we have to install the following dependencies:

TypeScript

```typescript

  $ npm install --save sequelize sequelize-typescript mysql2
  $ npm install --save-dev @types/sequelize
```

The first step we need to do is create a **Sequelize** instance with an options object passed into the constructor. Also, we need to add all models (the alternative is to use `modelPaths` property) and `sync()` our database tables.

database.providers.ts

TypeScript

```typescript

import { Sequelize } from 'sequelize-typescript';
import { Cat } from '../cats/cat.entity';

export const databaseProviders = [
  {
    provide: 'SequelizeToken',
    useFactory: async () => {
      const sequelize = new Sequelize({
        dialect: 'mysql',
        host: 'localhost',
        port: 3306,
        username: 'root',
        password: 'password',
        database: 'nest',
      });
      sequelize.addModels([Cat]);
      await sequelize.sync();
      return sequelize;
    },
  },
];
```

> **Hint** Following best practices, we declared the custom provider in the separated file which has a `*.providers.ts` suffix.

Then, we need to export these providers to make them **accessible** for the rest part of the application.

database.module.ts

TypeScript

```typescript

  import { Module } from '@nestjs/common';
  import { databaseProviders } from './database.providers';

  @Module({
    providers: [...databaseProviders],
    exports: [...databaseProviders],
  })
  export class DatabaseModule {}
```

Now we can inject the `Sequelize` object using `@Inject()` decorator. Each class that would depend on the `Sequelize` async provider will wait until a `Promise` is resolved.

#### Model injection

In [Sequelize](https://github.com/sequelize/sequelize) the **Model** defines a table in the database. Instances of this class represent a database row. Firstly, we need at least one entity:

cats/cat.entity.ts

TypeScript

```typescript

import { Table, Column, Model } from 'sequelize-typescript';

@Table
export class Cat extends Model<Cat> {
  @Column
  name: string;

  @Column
  age: number;

  @Column
  breed: string;
}
```

The `Cat` entity belongs to the `cats` directory. This directory represents the `CatsModule`. Now it's time to create a **Repository** component:

cats.providers.ts

TypeScript

```typescript

import { Cat } from './cat.entity';

export const catsProviders = [
  {
    provide: 'CatsRepository',
    useValue: Cat,
  },
];
```

> **Notice** In the real-world applications you should avoid **magic strings**. Both `CatsRepository` and `SequelizeToken` should be kept in the separated `constants.ts` file.

In Sequelize, we use static methods to manipulate the data, and thus we created an **alias** here.

Now we can inject the `CatsRepository` to the `CatsService` using the `@Inject()` decorator:

cats.service.ts

TypeScript

```typescript

import { Component, Inject } from '@nestjs/common';
import { CreateCatDto } from './dto/create-cat.dto';
import { Cat } from './cat.entity';

@Component()
export class CatsService {
  constructor(
    @Inject('CatsRepository') private readonly catsRepository: typeof Cat) {}

  async findAll(): Promise<Cat[]> {
    return await this.catsRepository.findAll<Cat>();
  }
}
```

The database connection is **asynchronous**, but Nest makes this process completely invisible for the end-user. The `CatsRepository` provider is waiting for the db connection, and the `CatsService` is delayed until repository is ready to use. The entire application can start when each class is instantiated.

Here is a final `CatsModule`:

cats.module.ts

TypeScript

```typescript

import { Module } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';
import { catsProviders } from './cats.providers';
import { DatabaseModule } from '../database/database.module';

@Module({
  imports: [DatabaseModule],
  controllers: [CatsController],
  providers: [
    CatsService,
    ...catsProviders,
  ],
})
export class CatsModule {}
```

> **Hint** Don't forget to import the `CatsModule` into the root `ApplicationModule`.

* SQL (Sequelize)

----
url: https://docs.nestjs.com/v10/cli/libraries
----

* [Libraries](https://docs.nestjs.com/v10/cli/libraries#libraries)
* [Nest libraries](https://docs.nestjs.com/v10/cli/libraries#nest-libraries)
* [Creating libraries](https://docs.nestjs.com/v10/cli/libraries#creating-libraries)
* [Using libraries](https://docs.nestjs.com/v10/cli/libraries#using-libraries)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/cli/libraries.md "Suggest Edits")

### Libraries

Many applications need to solve the same general problems, or re-use a modular component in several different contexts. Nest has a few ways of addressing this, but each works at a different level to solve the problem in a way that helps meet different architectural and organizational objectives.

Nest [modules](/v10/modules) are useful for providing an execution context that enables sharing components within a single application. Modules can also be packaged with [npm](https://npmjs.com) to create a reusable library that can be installed in different projects. This can be an effective way to distribute configurable, re-usable libraries that can be used by different, loosely connected or unaffiliated organizations (e.g., by distributing/installing 3rd party libraries).

```bash

$ nest g library my-library
```

When you run the command, the `library` schematic prompts you for a prefix (AKA alias) for the library:

```bash

What prefix would you like to use for the library (default: @app)?
```

```javascript

...
{
    "my-library": {
      "type": "library",
      "root": "libs/my-library",
      "entryFile": "index",
      "sourceRoot": "libs/my-library/src",
      "compilerOptions": {
        "tsConfigPath": "libs/my-library/tsconfig.lib.json"
      }
}
...
```

There are two differences in `nest-cli.json` metadata between libraries and applications:

* the `"type"` property is set to `"library"` instead of `"application"`
* the `"entryFile"` property is set to `"index"` instead of `"main"`

These differences key the build process to handle libraries appropriately. For example, a library exports its functions through the `index.js` file.

As with application-type projects, libraries each have their own `tsconfig.lib.json` file that extends the root (monorepo-wide) `tsconfig.json` file. You can modify this file, if necessary, to provide library-specific compiler options.

You can build the library with the CLI command:

```bash

$ nest build my-library
```

#### Using libraries[#](/cli/libraries#using-libraries)

With the automatically generated configuration files in place, using libraries is straightforward. How would we import `MyLibraryService` from the `my-library` library into the `my-project` application?

First, note that using library modules is the same as using any other Nest module. What the monorepo does is manage paths in a way that importing libraries and generating builds is now transparent. To use `MyLibraryService`, we need to import its declaring module. We can modify `my-project/src/app.module.ts` as follows to import `MyLibraryModule`.

```typescript

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { MyLibraryModule } from '@app/my-library';

@Module({
  imports: [MyLibraryModule],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}
```

Notice above that we've used a path alias of `@app` in the ES module `import` line, which was the `prefix` we supplied with the `nest g library` command above. Under the covers, Nest handles this through tsconfig path mapping. When adding a library, Nest updates the global (monorepo) `tsconfig.json` file's `"paths"` key like this:

```javascript

"paths": {
    "@app/my-library": [
        "libs/my-library/src"
    ],
    "@app/my-library/*": [
        "libs/my-library/src/*"
    ]
}
```

So, in a nutshell, the combination of the monorepo and library features has made it easy and intuitive to include library modules into applications.

This same mechanism enables building and deploying applications that compose libraries. Once you've imported the `MyLibraryModule`, running `nest build` handles all the module resolution automatically and bundles the app along with any library dependencies, for deployment. The default compiler for a monorepo is **webpack**, so the resulting distribution file is a single file that bundles all of the transpiled JavaScript files into a single file. You can also switch to `tsc` as described [here](https://docs.nestjs.com/cli/monorepo#global-compiler-options).

----
url: https://docs.nestjs.com/v9/recipes/nest-commander
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Nest Commander](https://docs.nestjs.com/v9/recipes/nest-commander#nest-commander)
* [Installation](https://docs.nestjs.com/v9/recipes/nest-commander#installation)
* [A Command file](https://docs.nestjs.com/v9/recipes/nest-commander#a-command-file)
* [Running the Command](https://docs.nestjs.com/v9/recipes/nest-commander#running-the-command)
* [Testing](https://docs.nestjs.com/v9/recipes/nest-commander#testing)
* [Putting it all together](https://docs.nestjs.com/v9/recipes/nest-commander#putting-it-all-together)
* [More Information](https://docs.nestjs.com/v9/recipes/nest-commander#more-information)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/recipes/nest-commander.md "Suggest Edits")

### Nest Commander

Expanding on the [standalone application](/v9/standalone-applications) docs there's also the [nest-commander](https://jmcdo29.github.io/nest-commander) package for writing command line applications in a structure similar to your typical Nest application.

> **info**`nest-commander` is a third party package and is not managed by the entirety of the NestJS core team. Please, report any issues found with the library in the [appropriate repository](https://github.com/jmcdo29/nest-commander/issues/new/choose)

#### Installation[#](/recipes/nest-commander#installation)

Just like any other package, you've got to install it before you can use it.

```bash

$ npm i nest-commander
```

#### A Command file[#](/recipes/nest-commander#a-command-file)

`nest-commander` makes it easy to write new command-line applications with [decorators](https://www.typescriptlang.org/docs/handbook/decorators.html) via the `@Command()` decorator for classes and the `@Option()` decorator for methods of that class. Every command file should implement the `CommandRunner` abstract class and should be decorated with a `@Command()` decorator.

Every command is seen as an `@Injectable()` by Nest, so your normal Dependency Injection still works as you would expect it to. The only thing to take note of is the abstract class `CommandRunner`, which should be implemented by each command. The `CommandRunner` abstract class ensures that all commands have a `run` method that returns a `Promise<void>` and takes in the parameters `string[], Record<string, any>`. The `run` command is where you can kick all of your logic off from, it will take in whatever parameters did not match option flags and pass them in as an array, just in case you are really meaning to work with multiple parameters. As for the options, the `Record<string, any>`, the names of these properties match the `name` property given to the `@Option()` decorators, while their value matches the return of the option handler. If you'd like better type safety, you are welcome to create an interface for your options as well.

#### Running the Command[#](/recipes/nest-commander#running-the-command)

Similar to how in a NestJS application we can use the `NestFactory` to create a server for us, and run it using `listen`, the `nest-commander` package exposes a simple to use API to run your server. Import the `CommandFactory` and use the `static` method `run` and pass in the root module of your application. This would probably look like below

```ts

import { CommandFactory } from 'nest-commander';
import { AppModule } from './app.module';

async function bootstrap() {
  await CommandFactory.run(AppModule);
}

bootstrap();
```

By default, Nest's logger is disabled when using the `CommandFactory`. It's possible to provide it though, as the second argument to the `run` function. You can either provide a custom NestJS logger, or an array of log levels you want to keep - it might be useful to at least provide `['error']` here, if you only want to print out Nest's error logs.

```ts

import { CommandFactory } from 'nest-commander';
import { AppModule } from './app.module';
import { LogService } './log.service';

async function bootstrap() {
  await CommandFactory.run(AppModule, new LogService());

  // or, if you only want to print Nest's warnings and errors
  await CommandFactory.run(AppModule, ['warn', 'error']);
}

bootstrap();
```

And that's it. Under the hood, `CommandFactory` will worry about calling `NestFactory` for you and calling `app.close()` when necessary, so you shouldn't need to worry about memory leaks there. If you need to add in some error handling, there's always `try/catch` wrapping the `run` command, or you can chain on some `.catch()` method to the `bootstrap()` call.

#### Testing[#](/recipes/nest-commander#testing)

So what's the use of writing a super awesome command line script if you can't test it super easily, right? Fortunately, `nest-commander` has some utilities you can make use of that fits in perfectly with the NestJS ecosystem, it'll feel right at home to any Nestlings out there. Instead of using the `CommandFactory` for building the command in test mode, you can use `CommandTestFactory` and pass in your metadata, very similarly to how `Test.createTestingModule` from `@nestjs/testing` works. In fact, it uses this package under the hood. You're also still able to chain on the `overrideProvider` methods before calling `compile()` so you can swap out DI pieces right in the test.

#### Putting it all together[#](/recipes/nest-commander#putting-it-all-together)

The following class would equate to having a CLI command that can take in the subcommand `basic` or be called directly, with `-n`, `-s`, and `-b` (along with their long flags) all being supported and with custom parsers for each option. The `--help` flag is also supported, as is customary with commander.

```ts

import { Command, CommandRunner, Option } from 'nest-commander';
import { LogService } from './log.service';

interface BasicCommandOptions {
  string?: string;
  boolean?: boolean;
  number?: number;
}

@Command({ name: 'basic', description: 'A parameter parse' })
export class BasicCommand extends CommandRunner {
  constructor(private readonly logService: LogService) {
    super()
  }

  async run(
    passedParam: string[],
    options?: BasicCommandOptions,
  ): Promise<void> {
    if (options?.boolean !== undefined && options?.boolean !== null) {
      this.runWithBoolean(passedParam, options.boolean);
    } else if (options?.number) {
      this.runWithNumber(passedParam, options.number);
    } else if (options?.string) {
      this.runWithString(passedParam, options.string);
    } else {
      this.runWithNone(passedParam);
    }
  }

  @Option({
    flags: '-n, --number [number]',
    description: 'A basic number parser',
  })
  parseNumber(val: string): number {
    return Number(val);
  }

  @Option({
    flags: '-s, --string [string]',
    description: 'A string return',
  })
  parseString(val: string): string {
    return val;
  }

  @Option({
    flags: '-b, --boolean [boolean]',
    description: 'A boolean parser',
  })
  parseBoolean(val: string): boolean {
    return JSON.parse(val);
  }

  runWithString(param: string[], option: string): void {
    this.logService.log({ param, string: option });
  }

  runWithNumber(param: string[], option: number): void {
    this.logService.log({ param, number: option });
  }

  runWithBoolean(param: string[], option: boolean): void {
    this.logService.log({ param, boolean: option });
  }

  runWithNone(param: string[]): void {
    this.logService.log({ param });
  }
}
```

Make sure the command class is added to a module

```ts

@Module({
  providers: [LogService, BasicCommand],
})
export class AppModule {}
```

And now to be able to run the CLI in your main.ts you can do the following

```ts

async function bootstrap() {
  await CommandFactory.run(AppModule);
}

bootstrap();
```

And just like that, you've got a command line application.

#### More Information[#](/recipes/nest-commander#more-information)

Visit the [nest-commander docs site](https://jmcdo29.github.io/nest-commander) for more information, examples, and API documentation.

----
url: https://docs.nestjs.com/v7/openapi/decorators
----

* [Decorators](https://docs.nestjs.com/v7/openapi/decorators#decorators)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/openapi/decorators.md "Suggest Edits")

### Decorators

All of the available OpenAPI decorators have an `Api` prefix to distinguish them from the core decorators. Below is a full list of the exported decorators along with a designation of the level at which the decorator may be applied.

| `@ApiOperation()`        | Method              |
| ------------------------ | ------------------- |
| `@ApiResponse()`         | Method / Controller |
| `@ApiProduces()`         | Method / Controller |
| `@ApiConsumes()`         | Method / Controller |
| `@ApiBearerAuth()`       | Method / Controller |
| `@ApiOAuth2()`           | Method / Controller |
| `@ApiBasicAuth()`        | Method / Controller |
| `@ApiSecurity()`         | Method / Controller |
| `@ApiExtraModels()`      | Method / Controller |
| `@ApiBody()`             | Method              |
| `@ApiParam()`            | Method              |
| `@ApiQuery()`            | Method              |
| `@ApiHeader()`           | Method / Controller |
| `@ApiExcludeEndpoint()`  | Method              |
| `@ApiTags()`             | Method / Controller |
| `@ApiProperty()`         | Model               |
| `@ApiPropertyOptional()` | Model               |
| `@ApiHideProperty()`     | Model               |
| `@ApiExtension()`        | Method              |

----
url: https://docs.nestjs.com/recipes/swc
----

[Skip to content](#content)

On this page

* [SWC](https://docs.nestjs.com/recipes/swc#swc)
* [Installation](https://docs.nestjs.com/recipes/swc#installation)
* [Getting started](https://docs.nestjs.com/recipes/swc#getting-started)
* [Type checking](https://docs.nestjs.com/recipes/swc#type-checking)
* [CLI Plugins (SWC)](https://docs.nestjs.com/recipes/swc#cli-plugins-swc)
* [SWC configuration](https://docs.nestjs.com/recipes/swc#swc-configuration)
* [Monorepo](https://docs.nestjs.com/recipes/swc#monorepo)
* [Monorepo and CLI plugins](https://docs.nestjs.com/recipes/swc#monorepo-and-cli-plugins)
* [Common pitfalls](https://docs.nestjs.com/recipes/swc#common-pitfalls)
* [Jest + SWC](https://docs.nestjs.com/recipes/swc#jest--swc)
* [Vitest](https://docs.nestjs.com/recipes/swc#vitest)
* [Installation](https://docs.nestjs.com/recipes/swc#installation-1)
* [Configuration](https://docs.nestjs.com/recipes/swc#configuration)
* [Path aliases](https://docs.nestjs.com/recipes/swc#path-aliases)
* [Update imports in E2E tests](https://docs.nestjs.com/recipes/swc#update-imports-in-e2e-tests)

### SWC

[SWC](https://swc.rs/) (Speedy Web Compiler) is an extensible Rust-based platform that can be used for both compilation and bundling. Using SWC with the Nest CLI is a straightforward way to significantly speed up your development process.

> **Hint** SWC is approximately **20 times faster** than the default TypeScript compiler.

#### Installation[#](/recipes/swc#installation)

To get started, first install a few packages:

```bash

$ npm i --save-dev @swc/cli @swc/core
```

#### Getting started[#](/recipes/swc#getting-started)

Once the installation is complete, you can use the `swc` builder with the Nest CLI, as follows:

```bash

$ nest start -b swc
# OR nest start --builder swc
```

> **Hint** If your repository is a monorepo, see the [Monorepo](/recipes/swc#monorepo) section.

Instead of passing the `-b` flag, you can set the `compilerOptions.builder` property to `"swc"` in your `nest-cli.json` file:

```json

{
  "compilerOptions": {
    "builder": "swc"
  }
}
```

To customize the builder's behavior, pass an object containing two attributes, `type` (`"swc"`) and `options`, as follows:

```json

{
  "compilerOptions": {
    "builder": {
      "type": "swc",
      "options": {
        "swcrcPath": "infrastructure/.swcrc",
      }
    }
  }
}
```

For example, to make SWC compile `.jsx` and `.tsx` files, use the following configuration:

```json

{
  "compilerOptions": {
    "builder": {
      "type": "swc",
      "options": { "extensions": [".ts", ".tsx", ".js", ".jsx"] }
    },
  }
}
```

To run the application in watch mode, use the following command:

```bash

$ nest start -b swc -w
# OR nest start --builder swc --watch
```

#### Type checking[#](/recipes/swc#type-checking)

Unlike the default TypeScript compiler, SWC doesn't perform any type checking itself. To turn type checking on, use the `--type-check` flag:

```bash

$ nest start -b swc --type-check
```

This command instructs the Nest CLI to run `tsc` in `noEmit` mode alongside SWC, which performs type checking asynchronously. Instead of passing the `--type-check` flag, you can also set the `compilerOptions.typeCheck` property to `true` in your `nest-cli.json` file:

```json

{
  "compilerOptions": {
    "builder": "swc",
    "typeCheck": true
  }
}
```

#### CLI Plugins (SWC)[#](/recipes/swc#cli-plugins-swc)

The `--type-check` flag automatically executes **NestJS CLI plugins** and produces a serialized metadata file, which the application can then load at runtime.

#### SWC configuration[#](/recipes/swc#swc-configuration)

The SWC builder is preconfigured to match the requirements of NestJS applications. However, you can customize the configuration by creating a `.swcrc` file in the root directory and adjusting the options as needed:

```json

{
  "$schema": "https://swc.rs/schema.json",
  "sourceMaps": true,
  "jsc": {
    "parser": {
      "syntax": "typescript",
      "decorators": true,
      "dynamicImport": true
    },
    "baseUrl": "./"
  },
  "minify": false
}
```

> **Hint** The SWC builder emits the same module format as the TypeScript compiler would: ES modules when your `package.json` file sets `"type": "module"` (the default for new projects), and CommonJS otherwise. A `module` setting in `.swcrc` overrides this.

#### Monorepo[#](/recipes/swc#monorepo)

> **Hint** As of NestJS v12, monorepos use the Rspack builder by default, which already compiles your code with SWC (through Rspack's built-in `swc-loader`). The following setup applies only if you use the deprecated webpack builder.

If your repository is a monorepo, then instead of using the `swc` builder, you have to configure `webpack` to use `swc-loader`.

First, install the required package:

```bash

$ npm i --save-dev swc-loader
```

Once the installation is complete, create a `webpack.config.js` file in the root directory of your application with the following content:

```js

const swcDefaultConfig = require('@nestjs/cli/lib/compiler/defaults/swc-defaults').swcDefaultsFactory().swcOptions;

module.exports = {
  module: {
    rules: [
      {
        test: /\.ts$/,
        exclude: /node_modules/,
        use: {
          loader: 'swc-loader',
          options: swcDefaultConfig,
        },
      },
    ],
  },
};
```

#### Monorepo and CLI plugins[#](/recipes/swc#monorepo-and-cli-plugins)

If you use CLI plugins, `swc-loader` doesn't load them automatically. Instead, you have to create a separate file that loads them manually. To do so, create a `generate-metadata.ts` file next to the `main.ts` file with the following content:

```ts

import { PluginMetadataGenerator } from '@nestjs/cli/lib/compiler/plugins/plugin-metadata-generator.js';
import { ReadonlyVisitor } from '@nestjs/swagger/plugin';

const generator = new PluginMetadataGenerator();
generator.generate({
  visitors: [new ReadonlyVisitor({ introspectComments: true, pathToSource: import.meta.dirname })],
  outputDir: import.meta.dirname,
  watch: true,
  tsconfigPath: 'apps/<name>/tsconfig.app.json',
});
```

> **Hint** This example uses the `@nestjs/swagger` plugin, but you can use any plugin of your choice.

The `generate()` method accepts the following options:

| `watch`            | Whether to watch the project for changes.                                                      |
| ------------------ | ---------------------------------------------------------------------------------------------- |
| `tsconfigPath`     | Path to the `tsconfig.json` file. Relative to the current working directory (`process.cwd()`). |
| `outputDir`        | Path to the directory where the metadata file is saved.                                        |
| `visitors`         | An array of visitors used to generate metadata.                                                |
| `filename`         | The name of the metadata file. Defaults to `metadata.ts`.                                      |
| `printDiagnostics` | Whether to print diagnostics to the console. Defaults to `true`.                               |

Finally, run the `generate-metadata` script in a separate terminal window with the following command:

```bash

$ npx ts-node src/generate-metadata.ts
# OR npx ts-node apps/{YOUR_APP}/src/generate-metadata.ts
```

#### Common pitfalls[#](/recipes/swc#common-pitfalls)

If you use TypeORM, MikroORM, or any other ORM in your application, you may run into circular import issues. SWC doesn't handle **circular imports** well, so use the following workaround:

```typescript

@Entity()
export class User {
  @OneToOne(() => Profile, (profile) => profile.user)
  profile: Relation<Profile>; // <--- see "Relation<>" type here instead of just "Profile"
}
```

> **Hint** The `Relation` type is exported from the `typeorm` package.

This prevents the property's type from being saved in the property metadata of the transpiled code, which avoids circular dependency issues.

If your ORM does not provide a similar workaround, you can define the wrapper type yourself:

```typescript

/**
 * Wrapper type used to circumvent ESM modules circular dependency issue
 * caused by reflection metadata saving the type of the property.
 */
export type WrapperType<T> = T; // WrapperType === Relation
```

For all [circular dependency injections](/fundamentals/circular-dependency) in your project, you also need to use the custom wrapper type described above:

```typescript

@Injectable()
export class UsersService {
  constructor(
    @Inject(forwardRef(() => ProfileService))
    private readonly profileService: WrapperType<ProfileService>,
  ) {}
}
```

### Jest + SWC

To use SWC with Jest (the default test runner for CommonJS projects), install the following packages:

```bash

$ npm i --save-dev jest @swc/core @swc/jest
```

Once the installation is complete, update your `package.json` or `jest.config.js` file (depending on your configuration) with the following content:

```json

{
  "jest": {
    "transform": {
      "^.+\\.(t|j)s?$": ["@swc/jest"]
    }
  }
}
```

Additionally, add the `legacyDecorator` and `decoratorMetadata``transform` properties to your `.swcrc` file:

```json

{
  "$schema": "https://swc.rs/schema.json",
  "sourceMaps": true,
  "jsc": {
    "parser": {
      "syntax": "typescript",
      "decorators": true,
      "dynamicImport": true
    },
    "transform": {
      "legacyDecorator": true,
      "decoratorMetadata": true
    },
    "baseUrl": "./"
  },
  "minify": false
}
```

If you use NestJS CLI plugins in your project, you have to run `PluginMetadataGenerator` manually. See the [Monorepo and CLI plugins](/recipes/swc#monorepo-and-cli-plugins) section to learn more.

### Vitest

[Vitest](https://vitest.dev/) is a fast, lightweight test runner designed to work with Vite. New NestJS projects that use ES modules (the default) are already set up with Vitest. This section shows how to configure Vitest to build your test files with SWC.

#### Installation[#](/recipes/swc#installation-1)

To get started, first install the required packages:

```bash

$ npm i --save-dev vitest unplugin-swc @swc/core @vitest/coverage-v8
```

#### Configuration[#](/recipes/swc#configuration)

Create a `vitest.config.ts` file in the root directory of your application with the following content:

```ts

import { resolve } from 'node:path';
import swc from 'unplugin-swc';
import { defineConfig } from 'vitest/config';

export default defineConfig({
  test: {
    globals: true,
    root: './',
  },
  plugins: [
    // This is required to build the test files with SWC
    swc.vite({
      // Explicitly set the module type to avoid inheriting this value from a `.swcrc` config file
      module: { type: 'es6' },
    }),
  ],
  resolve: {
    alias: {
      // Ensure Vitest correctly resolves TypeScript path aliases
      'src': resolve(import.meta.dirname, './src'),
    },
  },
});
```

This configuration file sets up the Vitest environment, root directory, and SWC plugin. You should also create a separate configuration file for e2e tests (e.g., `vitest.config.e2e.ts`), with an additional `include` field that specifies the glob pattern for the test files:

```ts

import swc from 'unplugin-swc';
import { defineConfig } from 'vitest/config';

export default defineConfig({
  test: {
    include: ['**/*.e2e-spec.ts'],
    globals: true,
    root: './',
  },
  plugins: [swc.vite()],
});
```

Additionally, you can set the `alias` options to support TypeScript paths in your tests:

```ts

import swc from 'unplugin-swc';
import { defineConfig } from 'vitest/config';

export default defineConfig({
  test: {
    include: ['**/*.e2e-spec.ts'],
    globals: true,
    alias: {
      '@src': './src',
      '@test': './test',
    },
    root: './',
  },
  resolve: {
    alias: {
      '@src': './src',
      '@test': './test',
    },
  },
  plugins: [swc.vite()],
});
```

### Path aliases

Vitest doesn't automatically resolve TypeScript path aliases such as `src/`, which can lead to dependency resolution errors during testing. To fix this, add the following `resolve.alias` configuration to your `vitest.config.ts` file:

```ts

import { resolve } from 'node:path';

export default defineConfig({
  resolve: {
    alias: {
      'src': resolve(import.meta.dirname, './src'),
    },
  },
});
```

This ensures that Vitest correctly resolves module imports, preventing errors related to missing dependencies.

#### Update imports in E2E tests[#](/recipes/swc#update-imports-in-e2e-tests)

Change any E2E test imports that use `import * as request from 'supertest'` to `import request from 'supertest'`. `supertest` is a CommonJS module that exports a function, and in an ES module setup like Vitest's, a namespace import isn't callable, so you need the default import.

Lastly, update the test scripts in your `package.json` file:

```json

{
  "scripts": {
    "test": "vitest run",
    "test:watch": "vitest",
    "test:cov": "vitest run --coverage",
    "test:debug": "vitest --inspect-brk --no-file-parallelism",
    "test:e2e": "vitest run --config ./vitest.config.e2e.ts"
  }
}
```

These scripts run the tests, watch for changes, generate code coverage reports, and start a debugging session. The `test:e2e` script runs the E2E tests with the dedicated configuration file.

> **Hint** A working example is available in the [nest-vitest repository](https://github.com/TrilonIO/nest-vitest).

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/recipes/swc.md)

----
url: https://docs.nestjs.com/v10/techniques/file-upload
----

* [File upload](https://docs.nestjs.com/v10/techniques/file-upload#file-upload)
* [Basic example](https://docs.nestjs.com/v10/techniques/file-upload#basic-example)
* [File validation](https://docs.nestjs.com/v10/techniques/file-upload#file-validation)
* [Array of files](https://docs.nestjs.com/v10/techniques/file-upload#array-of-files)
* [Multiple files](https://docs.nestjs.com/v10/techniques/file-upload#multiple-files)
* [Any files](https://docs.nestjs.com/v10/techniques/file-upload#any-files)
* [No files](https://docs.nestjs.com/v10/techniques/file-upload#no-files)
* [Default options](https://docs.nestjs.com/v10/techniques/file-upload#default-options)
* [Async configuration](https://docs.nestjs.com/v10/techniques/file-upload#async-configuration)
* [Example](https://docs.nestjs.com/v10/techniques/file-upload#example)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/techniques/file-upload.md "Suggest Edits")

### File upload

To handle file uploading, Nest provides a built-in module based on the [multer](https://github.com/expressjs/multer) middleware package for Express. Multer handles data posted in the `multipart/form-data` format, which is primarily used for uploading files via an HTTP `POST` request. This module is fully configurable and you can adjust its behavior to your application requirements.

> **Warning** Multer cannot process data which is not in the supported multipart format (`multipart/form-data`). Also, note that this package is not compatible with the `FastifyAdapter`.

For better type safety, let's install Multer typings package:

```shell

$ npm i -D @types/multer
```

With this package installed, we can now use the `Express.Multer.File` type (you can import this type as follows: `import { Express } from 'express'`).

#### Basic example[#](/techniques/file-upload#basic-example)

To upload a single file, simply tie the `FileInterceptor()` interceptor to the route handler and extract `file` from the `request` using the `@UploadedFile()` decorator.

JS TS

```typescript

@Post('upload')
@UseInterceptors(FileInterceptor('file'))
uploadFile(@UploadedFile() file: Express.Multer.File) {
  console.log(file);
}
```

```typescript

@Post('upload')
@UseInterceptors(FileInterceptor('file'))
@Bind(UploadedFile())
uploadFile(file) {
  console.log(file);
}
```

> **Hint** The `FileInterceptor()` decorator is exported from the `@nestjs/platform-express` package. The `@UploadedFile()` decorator is exported from `@nestjs/common`.

The `FileInterceptor()` decorator takes two arguments:

* `fieldName`: string that supplies the name of the field from the HTML form that holds a file
* `options`: optional object of type `MulterOptions`. This is the same object used by the multer constructor (more details [here](https://github.com/expressjs/multer#multeropts)).

> **Warning**`FileInterceptor()` may not be compatible with third party cloud providers like Google Firebase or others.

#### File validation[#](/techniques/file-upload#file-validation)

Often times it can be useful to validate incoming file metadata, like file size or file mime-type. For this, you can create your own [Pipe](https://docs.nestjs.com/pipes) and bind it to the parameter annotated with the `UploadedFile` decorator. The example below demonstrates how a basic file size validator pipe could be implemented:

```typescript

import { PipeTransform, Injectable, ArgumentMetadata } from '@nestjs/common';

@Injectable()
export class FileSizeValidationPipe implements PipeTransform {
  transform(value: any, metadata: ArgumentMetadata) {
    // "value" is an object containing the file's attributes and metadata
    const oneKb = 1000;
    return value.size < oneKb;
  }
}
```

This can be used in conjunction with the `FileInterceptor` as follows:

```typescript

@Post('file')
@UseInterceptors(FileInterceptor('file'))
uploadFileAndValidate(@UploadedFile(
  new FileSizeValidationPipe(),
  // other pipes can be added here
) file: Express.Multer.File, ) {
  return file;
}
```

Nest provides a built-in pipe to handle common use cases and facilitate/standardize the addition of new ones. This pipe is called `ParseFilePipe`, and you can use it as follows:

```typescript

@Post('file')
uploadFileAndPassValidation(
  @Body() body: SampleDto,
  @UploadedFile(
    new ParseFilePipe({
      validators: [
        // ... Set of file validator instances here
      ]
    })
  )
  file: Express.Multer.File,
) {
  return {
    body,
    file: file.buffer.toString(),
  };
}
```

As you can see, it's required to specify an array of file validators that will be executed by the `ParseFilePipe`. We'll discuss the interface of a validator, but it's worth mentioning this pipe also has two additional **optional** options:

|                       |                                                                                                   |
| --------------------- | ------------------------------------------------------------------------------------------------- |
| `errorHttpStatusCode` | The HTTP status code to be thrown in case **any** validator fails. Default is `400` (BAD REQUEST) |
| `exceptionFactory`    | A factory which receives the error message and returns an error.                                  |

Now, back to the `FileValidator` interface. To integrate validators with this pipe, you have to either use built-in implementations or provide your own custom `FileValidator`. See example below:

```typescript

export abstract class FileValidator<TValidationOptions = Record<string, any>> {
  constructor(protected readonly validationOptions: TValidationOptions) {}

  /**
   * Indicates if this file should be considered valid, according to the options passed in the constructor.
   * @param file the file from the request object
   */
  abstract isValid(file?: any): boolean | Promise<boolean>;

  /**
   * Builds an error message in case the validation fails.
   * @param file the file from the request object
   */
  abstract buildErrorMessage(file: any): string;
}
```

> **Hint** The `FileValidator` interfaces supports async validation via its `isValid` function. To leverage type security, you can also type the `file` parameter as `Express.Multer.File` in case you are using express (default) as a driver.

`FileValidator` is a regular class that has access to the file object and validates it according to the options provided by the client. Nest has two built-in `FileValidator` implementations you can use in your project:

* `MaxFileSizeValidator` - Checks if a given file's size is less than the provided value (measured in `bytes`)
* `FileTypeValidator` - Checks if a given file's mime-type matches the given value.

> **Warning** To verify file type, [FileTypeValidator](https://github.com/nestjs/nest/blob/master/packages/common/pipes/file/file-type.validator.ts) class uses the type as detected by multer. By default, multer derives file type from file extension on user's device. However, it does not check actual file contents. As files can be renamed to arbitrary extensions, consider using a custom implementation (like checking the file's [magic number](https://www.ibm.com/support/pages/what-magic-number)) if your app requires a safer solution.

To understand how these can be used in conjunction with the aforementioned `FileParsePipe`, we'll use an altered snippet of the last presented example:

```typescript

@UploadedFile(
  new ParseFilePipe({
    validators: [
      new MaxFileSizeValidator({ maxSize: 1000 }),
      new FileTypeValidator({ fileType: 'image/jpeg' }),
    ],
  }),
)
file: Express.Multer.File,
```

> **Hint** If the number of validators increase largely or their options are cluttering the file, you can define this array in a separate file and import it here as a named constant like `fileValidators`.

Finally, you can use the special `ParseFilePipeBuilder` class that lets you compose & construct your validators. By using it as shown below you can avoid manual instantiation of each validator and just pass their options directly:

```typescript

@UploadedFile(
  new ParseFilePipeBuilder()
    .addFileTypeValidator({
      fileType: 'jpeg',
    })
    .addMaxSizeValidator({
      maxSize: 1000
    })
    .build({
      errorHttpStatusCode: HttpStatus.UNPROCESSABLE_ENTITY
    }),
)
file: Express.Multer.File,
```

> **Hint** File presence is required by default, but you can make it optional by adding `fileIsRequired: false` parameter inside `build` function options (at the same level as `errorHttpStatusCode`).

```typescript

@Post('upload')
@UseInterceptors(FilesInterceptor('files'))
uploadFile(@UploadedFiles() files: Array<Express.Multer.File>) {
  console.log(files);
}
```

```typescript

@Post('upload')
@UseInterceptors(FilesInterceptor('files'))
@Bind(UploadedFiles())
uploadFile(files) {
  console.log(files);
}
```

> **Hint** The `FilesInterceptor()` decorator is exported from the `@nestjs/platform-express` package. The `@UploadedFiles()` decorator is exported from `@nestjs/common`.

#### Multiple files[#](/techniques/file-upload#multiple-files)

To upload multiple files (all with different field name keys), use the `FileFieldsInterceptor()` decorator. This decorator takes two arguments:

* `uploadedFields`: an array of objects, where each object specifies a required `name` property with a string value specifying a field name, as described above, and an optional `maxCount` property, as described above
* `options`: optional `MulterOptions` object, as described above

When using `FileFieldsInterceptor()`, extract files from the `request` with the `@UploadedFiles()` decorator.

JS TS

```typescript

@Post('upload')
@UseInterceptors(FileFieldsInterceptor([
  { name: 'avatar', maxCount: 1 },
  { name: 'background', maxCount: 1 },
]))
uploadFile(@UploadedFiles() files: { avatar?: Express.Multer.File[], background?: Express.Multer.File[] }) {
  console.log(files);
}
```

```typescript

@Post('upload')
@Bind(UploadedFiles())
@UseInterceptors(FileFieldsInterceptor([
  { name: 'avatar', maxCount: 1 },
  { name: 'background', maxCount: 1 },
]))
uploadFile(files) {
  console.log(files);
}
```

#### Any files[#](/techniques/file-upload#any-files)

To upload all fields with arbitrary field name keys, use the `AnyFilesInterceptor()` decorator. This decorator can accept an optional `options` object as described above.

When using `AnyFilesInterceptor()`, extract files from the `request` with the `@UploadedFiles()` decorator.

JS TS

```typescript

@Post('upload')
@UseInterceptors(AnyFilesInterceptor())
uploadFile(@UploadedFiles() files: Array<Express.Multer.File>) {
  console.log(files);
}
```

```typescript

@Post('upload')
@Bind(UploadedFiles())
@UseInterceptors(AnyFilesInterceptor())
uploadFile(files) {
  console.log(files);
}
```

#### No files[#](/techniques/file-upload#no-files)

To accept `multipart/form-data` but not allow any files to be uploaded, use the `NoFilesInterceptor`. This sets multipart data as attributes on the request body. Any files sent with the request will throw a `BadRequestException`.

```typescript

@Post('upload')
@UseInterceptors(NoFilesInterceptor())
handleMultiPartData(@Body() body) {
  console.log(body)
}
```

#### Default options[#](/techniques/file-upload#default-options)

You can specify multer options in the file interceptors as described above. To set default options, you can call the static `register()` method when you import the `MulterModule`, passing in supported options. You can use all options listed [here](https://github.com/expressjs/multer#multeropts).

```typescript

MulterModule.register({
  dest: './upload',
});
```

> **Hint** The `MulterModule` class is exported from the `@nestjs/platform-express` package.

#### Async configuration[#](/techniques/file-upload#async-configuration)

When you need to set `MulterModule` options asynchronously instead of statically, use the `registerAsync()` method. As with most dynamic modules, Nest provides several techniques to deal with async configuration.

One technique is to use a factory function:

```typescript

MulterModule.registerAsync({
  useFactory: () => ({
    dest: './upload',
  }),
});
```

Like other [factory providers](https://docs.nestjs.com/fundamentals/custom-providers#factory-providers-usefactory), our factory function can be `async` and can inject dependencies through `inject`.

```typescript

MulterModule.registerAsync({
  imports: [ConfigModule],
  useFactory: async (configService: ConfigService) => ({
    dest: configService.get<string>('MULTER_DEST'),
  }),
  inject: [ConfigService],
});
```

Alternatively, you can configure the `MulterModule` using a class instead of a factory, as shown below:

```typescript

MulterModule.registerAsync({
  useClass: MulterConfigService,
});
```

The construction above instantiates `MulterConfigService` inside `MulterModule`, using it to create the required options object. Note that in this example, the `MulterConfigService` has to implement the `MulterOptionsFactory` interface, as shown below. The `MulterModule` will call the `createMulterOptions()` method on the instantiated object of the supplied class.

```typescript

@Injectable()
class MulterConfigService implements MulterOptionsFactory {
  createMulterOptions(): MulterModuleOptions {
    return {
      dest: './upload',
    };
  }
}
```

If you want to reuse an existing options provider instead of creating a private copy inside the `MulterModule`, use the `useExisting` syntax.

```typescript

MulterModule.registerAsync({
  imports: [ConfigModule],
  useExisting: ConfigService,
});
```

You can also pass so-called `extraProviders` to the `registerAsync()` method. These providers will be merged with the module providers.

```typescript

MulterModule.registerAsync({
  imports: [ConfigModule],
  useClass: ConfigService,
  extraProviders: [MyAdditionalProvider],
});
```

This is useful when you want to provide additional dependencies to the factory function or the class constructor.

#### Example[#](/techniques/file-upload#example)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/29-file-upload).

----
url: https://docs.nestjs.com/v11/techniques/events
----

* [Events](https://docs.nestjs.com/v11/techniques/events#events)
* [Getting started](https://docs.nestjs.com/v11/techniques/events#getting-started)
* [Dispatching events](https://docs.nestjs.com/v11/techniques/events#dispatching-events)
* [Listening to events](https://docs.nestjs.com/v11/techniques/events#listening-to-events)
* [Preventing event loss](https://docs.nestjs.com/v11/techniques/events#preventing-event-loss)
* [Example](https://docs.nestjs.com/v11/techniques/events#example)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/techniques/events.md "Suggest Edits")

### Events

[Event Emitter](https://www.npmjs.com/package/@nestjs/event-emitter) package (`@nestjs/event-emitter`) provides a simple observer implementation, allowing you to subscribe and listen for various events that occur in your application. Events serve as a great way to decouple various aspects of your application, since a single event can have multiple listeners that do not depend on each other.

`EventEmitterModule` internally uses the [eventemitter2](https://github.com/EventEmitter2/EventEmitter2) package.

#### Getting started[#](/techniques/events#getting-started)

First install the required package:

```shell

$ npm i --save @nestjs/event-emitter
```

Once the installation is complete, import the `EventEmitterModule` into the root `AppModule` and run the `forRoot()` static method as shown below:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { EventEmitterModule } from '@nestjs/event-emitter';

@Module({
  imports: [
    EventEmitterModule.forRoot()
  ],
})
export class AppModule {}
```

The `.forRoot()` call initializes the event emitter and registers any declarative event listeners that exist within your app. Registration occurs when the `onApplicationBootstrap` lifecycle hook occurs, ensuring that all modules have loaded and declared any scheduled jobs.

To configure the underlying `EventEmitter` instance, pass the configuration object to the `.forRoot()` method, as follows:

```typescript

EventEmitterModule.forRoot({
  // set this to `true` to use wildcards
  wildcard: false,
  // the delimiter used to segment namespaces
  delimiter: '.',
  // set this to `true` if you want to emit the newListener event
  newListener: false,
  // set this to `true` if you want to emit the removeListener event
  removeListener: false,
  // the maximum amount of listeners that can be assigned to an event
  maxListeners: 10,
  // show event name in memory leak message when more than maximum amount of listeners is assigned
  verboseMemoryLeak: false,
  // disable throwing uncaughtException if an error event is emitted and it has no listeners
  ignoreErrors: false,
});
```

#### Dispatching events[#](/techniques/events#dispatching-events)

To dispatch (i.e., fire) an event, first inject `EventEmitter2` using standard constructor injection:

```typescript

constructor(private eventEmitter: EventEmitter2) {}
```

> **Hint** Import the `EventEmitter2` from the `@nestjs/event-emitter` package.

Then use it in a class as follows:

```typescript

this.eventEmitter.emit(
  'order.created',
  new OrderCreatedEvent({
    orderId: 1,
    payload: {},
  }),
);
```

#### Listening to events[#](/techniques/events#listening-to-events)

To declare an event listener, decorate a method with the `@OnEvent()` decorator preceding the method definition containing the code to be executed, as follows:

```typescript

@OnEvent('order.created')
handleOrderCreatedEvent(payload: OrderCreatedEvent) {
  // handle and process "OrderCreatedEvent" event
}
```

> **Warning** Event subscribers cannot be request-scoped.

The first argument can be a `string` or `symbol` for a simple event emitter and a `string | symbol | Array<string | symbol>` in a case of a wildcard emitter.

The second argument (optional) is a listener options object as follows:

```typescript

export type OnEventOptions = OnOptions & {
  /**
   * If "true", prepends (instead of append) the given listener to the array of listeners.
   *
   * @see https://github.com/EventEmitter2/EventEmitter2#emitterprependlistenerevent-listener-options
   *
   * @default false
   */
  prependListener?: boolean;

  /**
   * If "true", the onEvent callback will not throw an error while handling the event. Otherwise, if "false" it will throw an error.
   *
   * @default true
   */
  suppressErrors?: boolean;
};
```

> **Hint** Read more about the `OnOptions` options object from [`eventemitter2`](https://github.com/EventEmitter2/EventEmitter2#emitteronevent-listener-options-objectboolean).

```typescript

@OnEvent('order.created', { async: true })
handleOrderCreatedEvent(payload: OrderCreatedEvent) {
  // handle and process "OrderCreatedEvent" event
}
```

To use namespaces/wildcards, pass the `wildcard` option into the `EventEmitterModule#forRoot()` method. When namespaces/wildcards are enabled, events can either be strings (`foo.bar`) separated by a delimiter or arrays (`['foo', 'bar']`). The delimiter is also configurable as a configuration property (`delimiter`). With namespaces feature enabled, you can subscribe to events using a wildcard:

```typescript

@OnEvent('order.*')
handleOrderEvents(payload: OrderCreatedEvent | OrderRemovedEvent | OrderUpdatedEvent) {
  // handle and process an event
}
```

Note that such a wildcard only applies to one block. The argument `order.*` will match, for example, the events `order.created` and `order.shipped` but not `order.delayed.out_of_stock`. In order to listen to such events, use the `multilevel wildcard` pattern (i.e, `**`), described in the `EventEmitter2`[documentation](https://github.com/EventEmitter2/EventEmitter2#multi-level-wildcards).

With this pattern, you can, for example, create an event listener that catches all events.

```typescript

@OnEvent('**')
handleEverything(payload: any) {
  // handle and process an event
}
```

> **Hint**`EventEmitter2` class provides several useful methods for interacting with events, like `waitFor` and `onAny`. You can read more about them [here](https://github.com/EventEmitter2/EventEmitter2).

#### Preventing event loss[#](/techniques/events#preventing-event-loss)

Events triggered before or during the `onApplicationBootstrap` lifecycle hook—such as those from module constructors or the `onModuleInit` method—may be missed because the `EventSubscribersLoader` might not have finished setting up the listeners.

To avoid this issue, you can use the `waitUntilReady` method of the `EventEmitterReadinessWatcher`, which returns a promise that resolves once all listeners have been registered. This method can be called in the `onApplicationBootstrap` lifecycle hook of a module to ensure that all events are properly captured.

```typescript

await this.eventEmitterReadinessWatcher.waitUntilReady();
this.eventEmitter.emit(
  'order.created',
  new OrderCreatedEvent({ orderId: 1, payload: {} }),
);
```

> **Note** This is only necessary for events emitted before the `onApplicationBootstrap` lifecycle hook is complete.

#### Example[#](/techniques/events#example)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/30-event-emitter).

----
url: https://docs.nestjs.com/websockets/adapter
----

[Skip to content](#content)

On this page

* [Adapters](https://docs.nestjs.com/websockets/adapter#adapters)
* [Extend socket.io](https://docs.nestjs.com/websockets/adapter#extend-socketio)
* [Ws library](https://docs.nestjs.com/websockets/adapter#ws-library)
* [Advanced (custom adapter)](https://docs.nestjs.com/websockets/adapter#advanced-custom-adapter)
* [Example](https://docs.nestjs.com/websockets/adapter#example)

### Adapters

The WebSockets module is platform-agnostic, so you can bring your own library (or even a native implementation) by implementing the `WebSocketAdapter` interface. The interface requires the methods described in the following table:

|                        |                                                                 |
| ---------------------- | --------------------------------------------------------------- |
| `create`               | Creates a socket server instance based on the passed arguments  |
| `bindClientConnect`    | Binds the client connection event                               |
| `bindClientDisconnect` | Binds the client disconnection event (optional)                 |
| `bindMessageHandlers`  | Binds the incoming message to the corresponding message handler |
| `close`                | Terminates a server instance                                    |

#### Extend socket.io[#](/websockets/adapter#extend-socketio)

The [socket.io](https://github.com/socketio/socket.io) package is wrapped in an `IoAdapter` class. You can extend this class to enhance the adapter's basic functionality. For example, suppose your application must broadcast events across multiple load-balanced instances of your web service. To support this, extend `IoAdapter` and override the single method responsible for instantiating new socket.io servers. First, install the required packages.

> **Warning** To use socket.io with multiple load-balanced instances, you must either disable polling by setting `transports: ['websocket']` in your clients' socket.io configuration, or enable cookie-based routing (sticky sessions) in your load balancer. Redis alone is not enough. See [Enabling sticky session](https://socket.io/docs/v4/using-multiple-nodes/#enabling-sticky-session) in the socket.io documentation for more information.

```bash

$ npm i --save redis socket.io @socket.io/redis-adapter
```

Once the packages are installed, create a `RedisIoAdapter` class.

```typescript

import { IoAdapter } from '@nestjs/platform-socket.io';
import { ServerOptions } from 'socket.io';
import { createAdapter } from '@socket.io/redis-adapter';
import { createClient } from 'redis';

export class RedisIoAdapter extends IoAdapter {
  private adapterConstructor: ReturnType<typeof createAdapter>;

  async connectToRedis(): Promise<void> {
    const pubClient = createClient({ url: `redis://localhost:6379` });
    const subClient = pubClient.duplicate();

    await Promise.all([pubClient.connect(), subClient.connect()]);

    this.adapterConstructor = createAdapter(pubClient, subClient);
  }

  createIOServer(port: number, options?: ServerOptions): any {
    const server = super.createIOServer(port, options);
    server.adapter(this.adapterConstructor);
    return server;
  }
}
```

Then switch to your newly created Redis adapter.

```typescript

const app = await NestFactory.create(AppModule);
const redisIoAdapter = new RedisIoAdapter(app);
await redisIoAdapter.connectToRedis();

app.useWebSocketAdapter(redisIoAdapter);
```

#### Ws library[#](/websockets/adapter#ws-library)

Another available adapter is `WsAdapter`, which acts as a proxy between the framework and the fast, thoroughly tested [ws](https://github.com/websockets/ws) library. This adapter is fully compatible with native browser WebSockets and is faster than the socket.io package. However, it offers significantly fewer features out of the box, which many applications don't need.

> **Hint** The `ws` library doesn't support namespaces (communication channels popularized by `socket.io`), and `WsAdapter` throws an error if you set the `namespace` option. To mimic this feature, mount multiple `ws` servers on different paths (e.g., `@WebSocketGateway({ path: '/users' })`).

To use `ws`, first install the required package:

```bash

$ npm i --save @nestjs/platform-ws
```

Once the package is installed, switch the adapter:

```typescript

const app = await NestFactory.create(AppModule);
app.useWebSocketAdapter(new WsAdapter(app));
```

> **Hint** The `WsAdapter` is imported from `@nestjs/platform-ws`.

The `WsAdapter` handles messages in the `{ event: string, data: any }` format. To receive and process messages in a different format, configure a message parser that converts them into this format.

```typescript

const wsAdapter = new WsAdapter(app, {
  // To handle messages in the [event, data] format
  messageParser: (data) => {
    const [event, payload] = JSON.parse(data.toString());
    return { event, data: payload };
  },
});
```

Alternatively, you can set the message parser after creating the adapter with the `setMessageParser()` method.

#### Advanced (custom adapter)[#](/websockets/adapter#advanced-custom-adapter)

For demonstration purposes, we'll integrate the [ws](https://github.com/websockets/ws) library manually. As mentioned, an adapter for this library already exists: the `WsAdapter` class exposed from the `@nestjs/platform-ws` package. A simplified implementation could look like this:

ws-adapter.ts

JS TS

```typescript

import WebSocket from 'ws';
import { WebSocketAdapter, INestApplicationContext } from '@nestjs/common';
import { MessageMappingProperties } from '@nestjs/websockets';
import { Observable, fromEvent, EMPTY } from 'rxjs';
import { mergeMap, filter } from 'rxjs/operators';

export class WsAdapter implements WebSocketAdapter {
  constructor(private app: INestApplicationContext) {}

  create(port: number, options: any = {}): any {
    return new WebSocket.Server({ port, ...options });
  }

  bindClientConnect(server, callback: Function) {
    server.on('connection', callback);
  }

  bindMessageHandlers(
    client: WebSocket,
    handlers: MessageMappingProperties[],
    process: (data: any) => Observable<any>,
  ) {
    fromEvent(client, 'message')
      .pipe(
        mergeMap(data => this.bindMessageHandler(data, handlers, process)),
        filter(result => result),
      )
      .subscribe(response => client.send(JSON.stringify(response)));
  }

  bindMessageHandler(
    buffer,
    handlers: MessageMappingProperties[],
    process: (data: any) => Observable<any>,
  ): Observable<any> {
    const message = JSON.parse(buffer.data);
    const messageHandler = handlers.find(
      handler => handler.message === message.event,
    );
    if (!messageHandler) {
      return EMPTY;
    }
    return process(messageHandler.callback(message.data));
  }

  close(server) {
    server.close();
  }
}
```

> **Hint** To use the [ws](https://github.com/websockets/ws) library, use the built-in `WsAdapter` instead of creating your own.

Then set up the custom adapter with the `useWebSocketAdapter()` method:

main.ts

JS TS

```typescript

const app = await NestFactory.create(AppModule);
app.useWebSocketAdapter(new WsAdapter(app));
```

#### Example[#](/websockets/adapter#example)

A working example that uses `WsAdapter` is available in the [16-gateways-ws sample](https://github.com/nestjs/nest/tree/master/sample/16-gateways-ws).

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/websockets/adapter.md)

----
url: https://docs.nestjs.com/faq/common-errors
----

[Skip to content](#content)

On this page

* [Common errors](https://docs.nestjs.com/faq/common-errors#common-errors)
* ["Cannot resolve dependency" error](https://docs.nestjs.com/faq/common-errors#cannot-resolve-dependency-error)
* ["Circular dependency" error](https://docs.nestjs.com/faq/common-errors#circular-dependency-error)
* [Debugging dependency errors](https://docs.nestjs.com/faq/common-errors#debugging-dependency-errors)
* ["File change detected" loops endlessly](https://docs.nestjs.com/faq/common-errors#file-change-detected-loops-endlessly)

### Common errors

While learning and working with NestJS, you may run into the errors described on this page.

#### "Cannot resolve dependency" error[#](/faq/common-errors#cannot-resolve-dependency-error)

> **Hint**[NestJS Devtools](/devtools/overview#debugging-cannot-resolve-dependency-errors) can help you resolve the "Cannot resolve dependency" error.

The most common error message says that Nest can't resolve the dependencies of a provider. It usually looks like this:

```bash

Nest can't resolve dependencies of the <provider> (?). Please make sure that the argument <unknown_token> at index [<index>] is available in the <module> module.

Potential solutions:
- Is <module> a valid NestJS module?
- If <unknown_token> is a provider, is it part of the current <module>?
- If <unknown_token> is exported from a separate @Module, is that module imported within <module>?
  @Module({
    imports: [ /* the Module containing <unknown_token> */ ]
  })

For more common dependency resolution issues, see: https://docs.nestjs.com/faq/common-errors
```

The most common cause is that `<unknown_token>` is not available in `<module>`: it is neither listed in the module's `providers` array nor exported by one of the modules in its `imports` array. Make sure the provider is registered and follows [standard NestJS provider practices](/fundamentals/custom-providers#di-fundamentals).

Another common mistake is putting a provider in a module's `imports` array. If the class is decorated with `@Injectable()`, Nest detects this at startup and throws an error stating that the class cannot appear in the "imports" array; move it to the `providers` array instead.

When you run into this error, open the module named in the error message and review its `providers`. For each provider in the `providers` array, make sure the module has access to all of its dependencies. Providers are often duplicated in a feature module and the root module, which makes Nest try to instantiate the provider twice. In most cases, you should remove the duplicate and add the module that contains the `<provider>` to the root module's `imports` array instead.

Also make sure you didn't inject a provider into itself: self-injection is not allowed in NestJS. When this happens, `<unknown_token>` is usually equal to `<provider>`.

If the dependency at the reported index resolves to `undefined` or `Object` at runtime, the error message omits the token name, refers to the **current** module, and lists a different set of potential solutions:

```bash

Nest can't resolve dependencies of the <provider> (?). Please make sure that the argument at index [<index>] is available in the current module.

Potential solutions:
- The dependency at index [<index>] appears to be undefined at runtime
- This commonly occurs when using 'import type' instead of 'import' for injectable classes
...
```

This usually has one of the following causes:

1. **A circular file import.** Unlike the [circular dependency](/faq/common-errors#circular-dependency-error) described below, the providers don't depend on each other in their constructors; two files end up importing each other. For example, a module file declares a token and imports a provider, and the provider imports that token constant from the module file. If you use barrel files, make sure your barrel imports don't create such circular imports.
2. **Injecting by a type or an interface.** Types and interfaces don't exist at runtime, so Nest can't use them as injection tokens. Inject the class reference instead, or use a custom token with the `@Inject()` decorator (see [custom providers](/fundamentals/custom-providers)).
3. **Type-only imports.** For class-based providers, import the concrete class instead of only its type with the [`import type ...`](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-8.html#type-only-imports-and-export) syntax.

## Debug production with NestJS Observe

* Every request traced
* Errors with source code
* Logs in context
* Zero config, free plan

[Start for free](https://observe.nestjs.com "Observe | NestJS - A progressive Node.js framework")

In a **monorepo setup**, you may see the same error for the core `ModuleRef` provider as the `<unknown_token>`:

```bash

Nest can't resolve dependencies of the <provider> (?).
Please make sure that the argument ModuleRef at index [<index>] is available in the <module> module.
...
```

This usually happens when your project loads two copies of the `@nestjs/core` package, like this:

```text

.
├── package.json
├── apps
│   └── api
│       └── node_modules
│           └── @nestjs/bull
│               └── node_modules
│                   └── @nestjs/core
└── node_modules
    ├── (other packages)
    └── @nestjs/core
```

Solutions:

* For **Yarn** workspaces, use the [nohoist feature](https://classic.yarnpkg.com/blog/2018/02/15/nohoist) to prevent hoisting the `@nestjs/core` package.
* For **pnpm** workspaces, declare `@nestjs/core` as a peer dependency in your other module, and set `"dependenciesMeta": {"other-module-name": {"injected": true }}` in the package.json of the app that imports the module. See [dependenciesMeta.injected](https://pnpm.io/package_json#dependenciesmetainjected) in the pnpm documentation.

#### "Circular dependency" error[#](/faq/common-errors#circular-dependency-error)

Occasionally, you'll find it difficult to avoid [circular dependencies](/fundamentals/circular-dependency) in your application, and you'll need to help Nest resolve them. Errors caused by circular dependencies look like this:

```bash

Nest cannot create the <module> instance.
The module at index [<index>] of the <module> "imports" array is undefined.

Potential causes:
- A circular dependency between modules. Use forwardRef() to avoid it. Read more: https://docs.nestjs.com/fundamentals/circular-dependency
- The module at index [<index>] is of type "undefined". Check your import statements and the type of the module.

Scope [<module_import_chain>]
# example chain AppModule -> FooModule
```

Circular dependencies can arise from providers that depend on each other, or from TypeScript files that depend on each other for constants (e.g., a module file exports a constant that a service file imports). In the latter case, move the constants to a separate file. In the former case, follow the [circular dependency](/fundamentals/circular-dependency) guide and make sure that both the modules **and** the providers are wrapped with `forwardRef()`.

#### Debugging dependency errors[#](/faq/common-errors#debugging-dependency-errors)

Besides verifying your dependencies manually, you can set the `NEST_DEBUG` environment variable to any non-empty string to get extra logging while Nest resolves the application's dependencies.

In the image above, the string in yellow is the host class of the dependency being injected, the string in blue is the name (or injection token) of the injected dependency, and the string in purple is the module in which Nest searches for the dependency. With this output, you can usually trace the dependency resolution and find out why injection fails.

#### "File change detected" loops endlessly[#](/faq/common-errors#file-change-detected-loops-endlessly)

Windows users on TypeScript 4.9 or later may encounter this problem. When you run your application in watch mode (e.g., `npm run start:dev`), you see an endless loop of the following log messages:

```bash

XX:XX:XX AM - File change detected. Starting incremental compilation...
XX:XX:XX AM - Found 0 errors. Watching for file changes.
```

When you start your application in watch mode with the Nest CLI, it runs the TypeScript compiler in watch mode (the equivalent of `tsc --watch`). TypeScript 4.9 introduced a [new strategy](https://devblogs.microsoft.com/typescript/announcing-typescript-4-9/#file-watching-now-uses-file-system-events) for detecting file changes, which is the likely cause of this problem. To fix it, add the following setting to your `tsconfig.json` file, after the `"compilerOptions"` option:

```json

  "watchOptions": {
    "watchFile": "fixedPollingInterval"
  }
```

This tells TypeScript to poll for file changes instead of using file system events (the default since 4.9), which can cause issues on some machines. To learn more, see the [`watchFile` option](https://www.typescriptlang.org/tsconfig#watch-watchFile) in the TypeScript documentation.

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/faq/errors.md)

----
url: https://docs.nestjs.com/v8/techniques/events
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Events](https://docs.nestjs.com/v8/techniques/events#events)
* [Getting started](https://docs.nestjs.com/v8/techniques/events#getting-started)
* [Dispatching Events](https://docs.nestjs.com/v8/techniques/events#dispatching-events)
* [Listening to Events](https://docs.nestjs.com/v8/techniques/events#listening-to-events)
* [Example](https://docs.nestjs.com/v8/techniques/events#example)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/techniques/events.md "Suggest Edits")

### Events

[Event Emitter](https://www.npmjs.com/package/@nestjs/event-emitter) package (`@nestjs/event-emitter`) provides a simple observer implementation, allowing you to subscribe and listen for various events that occur in your application. Events serve as a great way to decouple various aspects of your application, since a single event can have multiple listeners that do not depend on each other.

`EventEmitterModule` internally uses the [eventemitter2](https://github.com/EventEmitter2/EventEmitter2) package.

#### Getting started[#](/techniques/events#getting-started)

First install the required package:

```shell

$ npm i --save @nestjs/event-emitter
```

Once the installation is complete, import the `EventEmitterModule` into the root `AppModule` and run the `forRoot()` static method as shown below:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { EventEmitterModule } from '@nestjs/event-emitter';

@Module({
  imports: [
    EventEmitterModule.forRoot()
  ],
})
export class AppModule {}
```

The `.forRoot()` call initializes the event emitter and registers any declarative event listeners that exist within your app. Registration occurs when the `onApplicationBootstrap` lifecycle hook occurs, ensuring that all modules have loaded and declared any scheduled jobs.

To configure the underlying `EventEmitter` instance, pass the configuration object to the `.forRoot()` method, as follows:

```typescript

EventEmitterModule.forRoot({
  // set this to `true` to use wildcards
  wildcard: false,
  // the delimiter used to segment namespaces
  delimiter: '.',
  // set this to `true` if you want to emit the newListener event
  newListener: false,
  // set this to `true` if you want to emit the removeListener event
  removeListener: false,
  // the maximum amount of listeners that can be assigned to an event
  maxListeners: 10,
  // show event name in memory leak message when more than maximum amount of listeners is assigned
  verboseMemoryLeak: false,
  // disable throwing uncaughtException if an error event is emitted and it has no listeners
  ignoreErrors: false,
});
```

#### Dispatching Events[#](/techniques/events#dispatching-events)

To dispatch (i.e., fire) an event, first inject `EventEmitter2` using standard constructor injection:

```typescript

constructor(private eventEmitter: EventEmitter2) {}
```

> **Hint** Import the `EventEmitter2` from the `@nestjs/event-emitter` package.

Then use it in a class as follows:

```typescript

this.eventEmitter.emit(
  'order.created',
  new OrderCreatedEvent({
    orderId: 1,
    payload: {},
  }),
);
```

#### Listening to Events[#](/techniques/events#listening-to-events)

To declare an event listener, decorate a method with the `@OnEvent()` decorator preceding the method definition containing the code to be executed, as follows:

```typescript

@OnEvent('order.created')
handleOrderCreatedEvent(payload: OrderCreatedEvent) {
  // handle and process "OrderCreatedEvent" event
}
```

> **Warning** Event subscribers cannot be request-scoped.

The first argument can be a `string` or `symbol` for a simple event emitter and a `string | symbol | Array<string | symbol>` in a case of a wildcard emitter. The second argument (optional) is a listener options object ([read more](https://github.com/EventEmitter2/EventEmitter2#emitteronevent-listener-options-objectboolean)).

```typescript

@OnEvent('order.created', { async: true })
handleOrderCreatedEvent(payload: OrderCreatedEvent) {
  // handle and process "OrderCreatedEvent" event
}
```

To use namespaces/wildcards, pass the `wildcard` option into the `EventEmitterModule#forRoot()` method. When namespaces/wildcards are enabled, events can either be strings (`foo.bar`) separated by a delimiter or arrays (`['foo', 'bar']`). The delimiter is also configurable as a configuration property (`delimiter`). With namespaces feature enabled, you can subscribe to events using a wildcard:

```typescript

@OnEvent('order.*')
handleOrderEvents(payload: OrderCreatedEvent | OrderRemovedEvent | OrderUpdatedEvent) {
  // handle and process an event
}
```

Note that such a wildcard only applies to one block. The argument `order.*` will match, for example, the events `order.created` and `order.shipped` but not `order.delayed.out_of_stock`. In order to listen to such events, use the `multilevel wildcard` pattern (i.e, `**`), described in the `EventEmitter2`[documentation](https://github.com/EventEmitter2/EventEmitter2#multi-level-wildcards).

With this pattern, you can, for example, create an event listener that catches all events.

```typescript

@OnEvent('**')
handleEverything(payload: any) {
  // handle and process an event
}
```

> **Hint**`EventEmitter2` class provides several useful methods for interacting with events, like `waitFor` and `onAny`. You can read more about them [here](https://github.com/EventEmitter2/EventEmitter2).

#### Example[#](/techniques/events#example)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/30-event-emitter).

----
url: https://docs.nestjs.com/v4/graphql/ide
----

### IDE

One of the most popular GraphQL in-browser IDE is called [GraphiQL](https://github.com/graphql/graphiql). To use a GraphiQL with your application, you need to set up a middleware. This particular middleware comes with `apollo-server-express` package that we had to install already. Its name is a `graphiqlExpress()`.

In order to set up a middleware, we need to open an `app.module.ts` file once again:

app.module.ts

JavaScript TypeScript

TypeScript

```typescript

import {
  Module,
  MiddlewaresConsumer,
  NestModule,
  RequestMethod,
} from '@nestjs/common';
import { graphqlExpress, graphiqlExpress } from 'apollo-server-express';
import { GraphQLModule, GraphQLFactory } from '@nestjs/graphql';

@Module({
  imports: [GraphQLModule],
})
export class ApplicationModule implements NestModule {
  constructor(private readonly graphQLFactory: GraphQLFactory) {}

  configure(consumer: MiddlewaresConsumer) {
    const typeDefs = this.graphQLFactory.mergeTypesByPaths('./**/*.graphql');
    const schema = this.graphQLFactory.createSchema({ typeDefs });

    consumer
      .apply(graphiqlExpress({ endpointURL: '/graphql' }))
      .forRoutes({ path: '/graphiql', method: RequestMethod.GET })
      .apply(graphqlExpress(req => ({ schema, rootValue: req })))
      .forRoutes({ path: '/graphql', method: RequestMethod.ALL });
  }
}
```

TypeScript

```typescript

import { Module,  RequestMethod } from '@nestjs/common';
import { graphqlExpress, graphiqlExpress } from 'apollo-server-express';
import { GraphQLModule, GraphQLFactory } from '@nestjs/graphql';

@Dependencies(GraphQLFactory)
@Module({
  imports: [GraphQLModule],
})
export class ApplicationModule {
  constructor(graphQLFactory) {
    this.graphQLFactory = graphQLFactory;
  }

  configure(consumer) {
    const typeDefs = this.graphQLFactory.mergeTypesByPaths('./**/*.graphql');
    const schema = this.graphQLFactory.createSchema({ typeDefs });

    consumer
      .apply(graphiqlExpress({ endpointURL: '/graphql' }))
      .forRoutes({ path: '/graphiql', method: RequestMethod.GET })
      .apply(graphqlExpress(req => ({ schema, rootValue: req })))
      .forRoutes({ path: '/graphql', method: RequestMethod.ALL });
  }
}
```

> **Hint** The `graphiqlExpress()` offers few other options, read more about them [here](https://www.apollographql.com/docs/apollo-server/graphiql.html).

Now, when you navigate to the `http://localhost:PORT/graphiql` you should see a graphical interactive GraphiQL IDE.

#### Sponsors

[](https://valor-software.com/)

Nest is an MIT-licensed open source project. It can grow thanks to the support by these awesome people. If you'd like to join them, please read more [here](https://opencollective.com/nest). Thanks!

[](https://opencollective.com/nest/backer/0/website)[](https://opencollective.com/nest/backer/1/website)[](https://opencollective.com/nest/backer/2/website)[](https://opencollective.com/nest/backer/3/website)[](https://opencollective.com/nest/backer/4/website)[](https://opencollective.com/nest/backer/5/website)[](https://opencollective.com/nest/backer/6/website)[](https://opencollective.com/nest/backer/7/website)[](https://opencollective.com/nest/backer/8/website)[](https://opencollective.com/nest/backer/9/website)[](https://opencollective.com/nest/backer/10/website)[](https://opencollective.com/nest/backer/11/website)[](https://opencollective.com/nest/backer/12/website)[](https://opencollective.com/nest/backer/13/website)[](https://opencollective.com/nest/backer/14/website)[](https://opencollective.com/nest/backer/15/website)[](https://opencollective.com/nest/backer/16/website)[](https://opencollective.com/nest/backer/17/website)[](https://opencollective.com/nest/backer/18/website)[](https://opencollective.com/nest/backer/19/website)[](https://opencollective.com/nest/backer/20/website)[](https://opencollective.com/nest/backer/21/website)[](https://opencollective.com/nest/backer/22/website)[](https://opencollective.com/nest/backer/23/website)[](https://opencollective.com/nest/backer/24/website)[](https://opencollective.com/nest/backer/25/website)[](https://opencollective.com/nest/backer/26/website)[](https://opencollective.com/nest/backer/27/website)[](https://opencollective.com/nest/backer/28/website)[](https://opencollective.com/nest/backer/29/website)

[Become a sponsor](https://opencollective.com/nest)

----
url: https://docs.nestjs.com/v11/openapi/introduction
----

* [Introduction](https://docs.nestjs.com/v11/openapi/introduction#introduction)
* [Installation](https://docs.nestjs.com/v11/openapi/introduction#installation)
* [Bootstrap](https://docs.nestjs.com/v11/openapi/introduction#bootstrap)
* [Document options](https://docs.nestjs.com/v11/openapi/introduction#document-options)
* [Setup options](https://docs.nestjs.com/v11/openapi/introduction#setup-options)
* [Example](https://docs.nestjs.com/v11/openapi/introduction#example)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/openapi/introduction.md "Suggest Edits")

### Introduction

The [OpenAPI](https://swagger.io/specification/) specification is a language-agnostic definition format used to describe RESTful APIs. Nest provides a dedicated [module](https://github.com/nestjs/swagger) which allows generating such a specification by leveraging decorators.

#### Installation[#](/openapi/introduction#installation)

To begin using it, we first install the required dependency.

```bash

$ npm install --save @nestjs/swagger
```

#### Bootstrap[#](/openapi/introduction#bootstrap)

Once the installation process is complete, open the `main.ts` file and initialize Swagger using the `SwaggerModule` class:

main.ts

JS TS

```typescript

import { NestFactory } from '@nestjs/core';
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);

  const config = new DocumentBuilder()
    .setTitle('Cats example')
    .setDescription('The cats API description')
    .setVersion('1.0')
    .addTag('cats')
    .build();
  const documentFactory = () => SwaggerModule.createDocument(app, config);
  SwaggerModule.setup('api', app, documentFactory);

  await app.listen(process.env.PORT ?? 3000);
}
bootstrap();
```

> **Hint** The factory method `SwaggerModule.createDocument()` is used specifically to generate the Swagger document when you request it. This approach helps save some initialization time, and the resulting document is a serializable object that conforms to the [OpenAPI Document](https://swagger.io/specification/#openapi-document) specification. Instead of serving the document over HTTP, you can also save it as a JSON or YAML file and use it in various ways.

```bash

$ npm run start
```

While the application is running, open your browser and navigate to `http://localhost:3000/api`. You should see the Swagger UI.

As you can see, the `SwaggerModule` automatically reflects all of your endpoints.

> **Hint** To generate and download a Swagger JSON file, navigate to `http://localhost:3000/api-json` (assuming that your Swagger documentation is available under `http://localhost:3000/api`). It is also possible to expose it on a route of your choice using only the setup method from `@nestjs/swagger`, like this:
>
> ```typescript
>
> SwaggerModule.setup('swagger', app, documentFactory, {
>   jsonDocumentUrl: 'swagger/json',
> });
> ```
>
> Which would expose it at `http://localhost:3000/swagger/json`

> **Warning** When using `fastify` and `helmet`, there may be a problem with [CSP](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP), to solve this collision, configure the CSP as shown below:
>
> ```typescript
>
> app.register(helmet, {
>   contentSecurityPolicy: {
>     directives: {
>       defaultSrc: [`'self'`],
>       styleSrc: [`'self'`, `'unsafe-inline'`],
>       imgSrc: [`'self'`, 'data:', 'validator.swagger.io'],
>       scriptSrc: [`'self'`, `https:`, `'unsafe-inline'`],
>     },
>   },
> });
>
> // If you are not going to use CSP at all, you can use this:
> app.register(helmet, {
>   contentSecurityPolicy: false,
> });
> ```

#### Document options[#](/openapi/introduction#document-options)

When creating a document, it is possible to provide some extra options to fine tune the library's behavior. These options should be of type `SwaggerDocumentOptions`, which can be the following:

```typescript

export interface SwaggerDocumentOptions {
  /**
   * List of modules to include in the specification
   */
  include?: Function[];

  /**
   * Additional, extra models that should be inspected and included in the specification
   */
  extraModels?: Function[];

  /**
   * If `true`, swagger will ignore the global prefix set through `setGlobalPrefix()` method
   */
  ignoreGlobalPrefix?: boolean;

  /**
   * If `true`, swagger will also load routes from the modules imported by `include` modules
   */
  deepScanRoutes?: boolean;

  /**
   * Custom operationIdFactory that will be used to generate the `operationId`
   * based on the `controllerKey`, `methodKey`, and version.
   * @default () => controllerKey_methodKey_version
   */
  operationIdFactory?: OperationIdFactory;

  /**
   * Custom linkNameFactory that will be used to generate the name of links
   * in the `links` field of responses
   *
   * @see [Link objects](https://swagger.io/docs/specification/links/)
   *
   * @default () => `${controllerKey}_${methodKey}_from_${fieldKey}`
   */
  linkNameFactory?: (
    controllerKey: string,
    methodKey: string,
    fieldKey: string
  ) => string;

  /*
   * Generate tags automatically based on the controller name.
   * If `false`, you must use the `@ApiTags()` decorator to define tags.
   * Otherwise, the controller name without the suffix `Controller` will be used.
   * @default true
   */
  autoTagControllers?: boolean;
}
```

For example, if you want to make sure that the library generates operation names like `createUser` instead of `UsersController_createUser`, you can set the following:

```typescript

const options: SwaggerDocumentOptions =  {
  operationIdFactory: (
    controllerKey: string,
    methodKey: string
  ) => methodKey
};
const documentFactory = () => SwaggerModule.createDocument(app, config, options);
```

#### Setup options[#](/openapi/introduction#setup-options)

You can configure Swagger UI by passing the options object which fulfills the `SwaggerCustomOptions` interface as a fourth argument of the `SwaggerModule#setup` method.

```typescript

export interface SwaggerCustomOptions {
  /**
   * If `true`, Swagger resources paths will be prefixed by the global prefix set through `setGlobalPrefix()`.
   * Default: `false`.
   * @see https://docs.nestjs.com/faq/global-prefix
   */
  useGlobalPrefix?: boolean;

  /**
   * If `false`, the Swagger UI will not be served. Only API definitions (JSON and YAML)
   * will be accessible (on `/{path}-json` and `/{path}-yaml`). To fully disable both the Swagger UI and API definitions, use `raw: false`.
   * Default: `true`.
   * @deprecated Use `ui` instead.
   */
  swaggerUiEnabled?: boolean;

  /**
   * If `false`, the Swagger UI will not be served. Only API definitions (JSON and YAML)
   * will be accessible (on `/{path}-json` and `/{path}-yaml`). To fully disable both the Swagger UI and API definitions, use `raw: false`.
   * Default: `true`.
   */
  ui?: boolean;

  /**
   * If `true`, raw definitions for all formats will be served.
   * Alternatively, you can pass an array to specify the formats to be served, e.g., `raw: ['json']` to serve only JSON definitions.
   * If omitted or set to an empty array, no definitions (JSON or YAML) will be served.
   * Use this option to control the availability of Swagger-related endpoints.
   * Default: `true`.
   */
  raw?: boolean | Array<'json' | 'yaml'>;

  /**
   * Url point the API definition to load in Swagger UI.
   */
  swaggerUrl?: string;

  /**
   * Path of the JSON API definition to serve.
   * Default: `<path>-json`.
   */
  jsonDocumentUrl?: string;

  /**
   * Path of the YAML API definition to serve.
   * Default: `<path>-yaml`.
   */
  yamlDocumentUrl?: string;

  /**
   * Hook allowing to alter the OpenAPI document before being served.
   * It's called after the document is generated and before it is served as JSON & YAML.
   */
  patchDocumentOnRequest?: <TRequest = any, TResponse = any>(
    req: TRequest,
    res: TResponse,
    document: OpenAPIObject
  ) => OpenAPIObject;

  /**
   * If `true`, the selector of OpenAPI definitions is displayed in the Swagger UI interface.
   * Default: `false`.
   */
  explorer?: boolean;

  /**
   * Additional Swagger UI options
   */
  swaggerOptions?: SwaggerUiOptions;

  /**
   * Custom CSS styles to inject in Swagger UI page.
   */
  customCss?: string;

  /**
   * URL(s) of a custom CSS stylesheet to load in Swagger UI page.
   */
  customCssUrl?: string | string[];

  /**
   * URL(s) of custom JavaScript files to load in Swagger UI page.
   */
  customJs?: string | string[];

  /**
   * Custom JavaScript scripts to load in Swagger UI page.
   */
  customJsStr?: string | string[];

  /**
   * Custom favicon for Swagger UI page.
   */
  customfavIcon?: string;

  /**
   * Custom title for Swagger UI page.
   */
  customSiteTitle?: string;

  /**
   * File system path (ex: ./node_modules/swagger-ui-dist) containing static Swagger UI assets.
   */
  customSwaggerUiPath?: string;

  /**
   * @deprecated This property has no effect.
   */
  validatorUrl?: string;

  /**
   * @deprecated This property has no effect.
   */
  url?: string;

  /**
   * @deprecated This property has no effect.
   */
  urls?: Record<'url' | 'name', string>[];
}
```

> **Hint**`ui` and `raw` are independent options. Disabling Swagger UI (`ui: false`) does not disable API definitions (JSON/YAML). Conversely, disabling API definitions (`raw: []`) does not disable the Swagger UI.
>
> For example, the following configuration will disable the Swagger UI but still allow access to API definitions:
>
> ```typescript
>
> const options: SwaggerCustomOptions = {
>   ui: false, // Swagger UI is disabled
>   raw: ['json'], // JSON API definition is still accessible (YAML is disabled)
> };
> SwaggerModule.setup('api', app, options);
> ```
>
> In this case, <http://localhost:3000/api-json> will still be accessible, but <http://localhost:3000/api> (Swagger UI) will not.

#### Example[#](/openapi/introduction#example)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/11-swagger).

----
url: https://docs.nestjs.com/v11/microservices/exception-filters
----

* [Exception filters](https://docs.nestjs.com/v11/microservices/exception-filters#exception-filters)
* [Filters](https://docs.nestjs.com/v11/microservices/exception-filters#filters)
* [Inheritance](https://docs.nestjs.com/v11/microservices/exception-filters#inheritance)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/microservices/exception-filters.md "Suggest Edits")

### Exception filters

The only difference between the HTTP [exception filter](/v11/exception-filters) layer and the corresponding microservices layer is that instead of throwing `HttpException`, you should use `RpcException`.

```typescript

throw new RpcException('Invalid credentials.');
```

> **Hint** The `RpcException` class is imported from the `@nestjs/microservices` package.

With the sample above, Nest will handle the thrown exception and return the `error` object with the following structure:

```json

{
  "status": "error",
  "message": "Invalid credentials."
}
```

#### Filters[#](/microservices/exception-filters#filters)

Microservice exception filters behave similarly to HTTP exception filters, with one small difference. The `catch()` method must return an `Observable`.

rpc-exception.filter.ts

JS TS

```typescript

import { Catch, RpcExceptionFilter, ArgumentsHost } from '@nestjs/common';
import { Observable, throwError } from 'rxjs';
import { RpcException } from '@nestjs/microservices';

@Catch(RpcException)
export class ExceptionFilter implements RpcExceptionFilter<RpcException> {
  catch(exception: RpcException, host: ArgumentsHost): Observable<any> {
    return throwError(() => exception.getError());
  }
}
```

```typescript

import { Catch } from '@nestjs/common';
import { throwError } from 'rxjs';

@Catch(RpcException)
export class ExceptionFilter {
  catch(exception, host) {
    return throwError(() => exception.getError());
  }
}
```

> **Warning** Global microservice exception filters aren't enabled by default when using a [hybrid application](/v11/faq/hybrid-application).

The following example uses a manually instantiated method-scoped filter. Just as with HTTP based applications, you can also use controller-scoped filters (i.e., prefix the controller class with a `@UseFilters()` decorator).

JS TS

```typescript

@UseFilters(new ExceptionFilter())
@MessagePattern({ cmd: 'sum' })
accumulate(data: number[]): number {
  return (data || []).reduce((a, b) => a + b);
}
```

```typescript

@UseFilters(new ExceptionFilter())
@MessagePattern({ cmd: 'sum' })
accumulate(data) {
  return (data || []).reduce((a, b) => a + b);
}
```

#### Inheritance[#](/microservices/exception-filters#inheritance)

Typically, you'll create fully customized exception filters crafted to fulfill your application requirements. However, there might be use-cases when you would like to simply extend the **core exception filter**, and override the behavior based on certain factors.

In order to delegate exception processing to the base filter, you need to extend `BaseExceptionFilter` and call the inherited `catch()` method.

JS TS

```typescript

import { Catch, ArgumentsHost } from '@nestjs/common';
import { BaseRpcExceptionFilter } from '@nestjs/microservices';

@Catch()
export class AllExceptionsFilter extends BaseRpcExceptionFilter {
  catch(exception: any, host: ArgumentsHost) {
    return super.catch(exception, host);
  }
}
```

```typescript

import { Catch } from '@nestjs/common';
import { BaseRpcExceptionFilter } from '@nestjs/microservices';

@Catch()
export class AllExceptionsFilter extends BaseRpcExceptionFilter {
  catch(exception, host) {
    return super.catch(exception, host);
  }
}
```

----
url: https://docs.nestjs.com/v11/recipes/async-local-storage
----

* [Async Local Storage](https://docs.nestjs.com/v11/recipes/async-local-storage#async-local-storage)
* [Custom implementation](https://docs.nestjs.com/v11/recipes/async-local-storage#custom-implementation)
* [NestJS CLS](https://docs.nestjs.com/v11/recipes/async-local-storage#nestjs-cls)
* [Installation](https://docs.nestjs.com/v11/recipes/async-local-storage#installation)
* [Usage](https://docs.nestjs.com/v11/recipes/async-local-storage#usage)
* [Testing](https://docs.nestjs.com/v11/recipes/async-local-storage#testing)
* [More information](https://docs.nestjs.com/v11/recipes/async-local-storage#more-information)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/recipes/async-local-storage.md "Suggest Edits")

### Async Local Storage

`AsyncLocalStorage` is a [Node.js API](https://nodejs.org/api/async_context.html#class-asynclocalstorage) (based on the `async_hooks` API) that provides an alternative way of propagating local state through the application without the need to explicitly pass it as a function parameter. It is similar to a thread-local storage in other languages.

The main idea of Async Local Storage is that we can *wrap* some function call with the `AsyncLocalStorage#run` call. All code that is invoked within the wrapped call gets access to the same `store`, which will be unique to each call chain.

In the context of NestJS, that means if we can find a place within the request's lifecycle where we can wrap the rest of the request's code, we will be able to access and modify state visible only to that request, which may serve as an alternative to REQUEST-scoped providers and some of their limitations.

Alternatively, we can use ALS to propagate context for only a part of the system (for example the *transaction* object) without passing it around explicitly across services, which can increase isolation and encapsulation.

#### Custom implementation[#](/recipes/async-local-storage#custom-implementation)

NestJS itself does not provide any built-in abstraction for `AsyncLocalStorage`, so let's walk through how we could implement it ourselves for the simplest HTTP case to get a better understanding of the whole concept:

> **info** For a ready-made [dedicated package](recipes/async-local-storage#nestjs-cls), continue reading below.

1. First, create a new instance of the `AsyncLocalStorage` in some shared source file. Since we're using NestJS, let's also turn it into a module with a custom provider.

als.module.ts

JS TS

```ts

@Module({
  providers: [
    {
      provide: AsyncLocalStorage,
      useValue: new AsyncLocalStorage(),
    },
  ],
  exports: [AsyncLocalStorage],
})
export class AlsModule {}
```

> **Hint**`AsyncLocalStorage` is imported from `async_hooks`.

2. We're only concerned with HTTP, so let's use a middleware to wrap the `next` function with `AsyncLocalStorage#run`. Since a middleware is the first thing that the request hits, this will make the `store` available in all enhancers and the rest of the system.

app.module.ts

JS TS

```typescript

@Module({
  imports: [AlsModule],
  providers: [CatsService],
  controllers: [CatsController],
})
export class AppModule implements NestModule {
  constructor(
    // inject the AsyncLocalStorage in the module constructor,
    private readonly als: AsyncLocalStorage
  ) {}

  configure(consumer: MiddlewareConsumer) {
    // bind the middleware,
    consumer
      .apply((req, res, next) => {
        // populate the store with some default values
        // based on the request,
        const store = {
          userId: req.headers['x-user-id'],
        };
        // and pass the "next" function as callback
        // to the "als.run" method together with the store.
        this.als.run(store, () => next());
      })
      .forRoutes('*path');
  }
}
```

```typescript

@Module({
  imports: [AlsModule],
  providers: [CatsService],
  controllers: [CatsController],
})
@Dependencies(AsyncLocalStorage)
export class AppModule {
  constructor(als) {
    // inject the AsyncLocalStorage in the module constructor,
    this.als = als
  }

  configure(consumer) {
    // bind the middleware,
    consumer
      .apply((req, res, next) => {
        // populate the store with some default values
        // based on the request,
        const store = {
          userId: req.headers['x-user-id'],
        };
        // and pass the "next" function as callback
        // to the "als.run" method together with the store.
        this.als.run(store, () => next());
      })
      .forRoutes('*path');
  }
}
```

3. Now, anywhere within the lifecycle of a request, we can access the local store instance.

cats.service.ts

JS TS

```typescript

@Injectable()
export class CatsService {
  constructor(
    // We can inject the provided ALS instance.
    private readonly als: AsyncLocalStorage,
    private readonly catsRepository: CatsRepository,
  ) {}

  getCatForUser() {
    // The "getStore" method will always return the
    // store instance associated with the given request.
    const userId = this.als.getStore()["userId"] as number;
    return this.catsRepository.getForUser(userId);
  }
}
```

```typescript

@Injectable()
@Dependencies(AsyncLocalStorage, CatsRepository)
export class CatsService {
  constructor(als, catsRepository) {
    // We can inject the provided ALS instance.
    this.als = als
    this.catsRepository = catsRepository
  }

  getCatForUser() {
    // The "getStore" method will always return the
    // store instance associated with the given request.
    const userId = this.als.getStore()["userId"] as number;
    return this.catsRepository.getForUser(userId);
  }
}
```

4. That's it. Now we have a way to share request related state without needing to inject the whole `REQUEST` object.

> **warning** Please be aware that while the technique is useful for many use-cases, it inherently obfuscates the code flow (creating implicit context), so use it responsibly and especially avoid creating contextual "[God objects](https://en.wikipedia.org/wiki/God_object)".

### NestJS CLS

The [nestjs-cls](https://github.com/Papooch/nestjs-cls) package provides several DX improvements over using plain `AsyncLocalStorage` (`CLS` is an abbreviation of the term *continuation-local storage*). It abstracts the implementation into a `ClsModule` that offers various ways of initializing the `store` for different transports (not only HTTP), as well as a strong-typing support.

The store can then be accessed with an injectable `ClsService`, or entirely abstracted away from the business logic by using [Proxy Providers](https://www.npmjs.com/package/nestjs-cls#proxy-providers).

> **info**`nestjs-cls` is a third party package and is not managed by the NestJS core team. Please, report any issues found with the library in the [appropriate repository](https://github.com/Papooch/nestjs-cls/issues).

#### Installation[#](/recipes/async-local-storage#installation)

Apart from a peer dependency on the `@nestjs` libs, it only uses the built-in Node.js API. Install it as any other package.

```bash

npm i nestjs-cls
```

#### Usage[#](/recipes/async-local-storage#usage)

A similar functionality as described [above](recipes/async-local-storage#custom-implementation) can be implemented using `nestjs-cls` as follows:

1. Import the `ClsModule` in the root module.

app.module.ts

JS TS

```ts

@Module({
  imports: [
    // Register the ClsModule,
    ClsModule.forRoot({
      middleware: {
        // automatically mount the
        // ClsMiddleware for all routes
        mount: true,
        // and use the setup method to
        // provide default store values.
        setup: (cls, req) => {
          cls.set('userId', req.headers['x-user-id']);
        },
      },
    }),
  ],
  providers: [CatsService],
  controllers: [CatsController],
})
export class AppModule {}
```

2. And then can use the `ClsService` to access the store values.

cats.service.ts

JS TS

```typescript

@Injectable()
export class CatsService {
  constructor(
    // We can inject the provided ClsService instance,
    private readonly cls: ClsService,
    private readonly catsRepository: CatsRepository,
  ) {}

  getCatForUser() {
    // and use the "get" method to retrieve any stored value.
    const userId = this.cls.get('userId');
    return this.catsRepository.getForUser(userId);
  }
}
```

```typescript

@Injectable()
@Dependencies(AsyncLocalStorage, CatsRepository)
export class CatsService {
  constructor(cls, catsRepository) {
    // We can inject the provided ClsService instance,
    this.cls = cls
    this.catsRepository = catsRepository
  }

  getCatForUser() {
    // and use the "get" method to retrieve any stored value.
    const userId = this.cls.get('userId');
    return this.catsRepository.getForUser(userId);
  }
}
```

3. To get strong typing of the store values managed by the `ClsService` (and also get auto-suggestions of the string keys), we can use an optional type parameter `ClsService<MyClsStore>` when injecting it.

```ts

export interface MyClsStore extends ClsStore {
  userId: number;
}
```

> **hint** It it also possible to let the package automatically generate a Request ID and access it later with `cls.getId()`, or to get the whole Request object using `cls.get(CLS_REQ)`.

#### Testing[#](/recipes/async-local-storage#testing)

Since the `ClsService` is just another injectable provider, it can be entirely mocked out in unit tests.

However, in certain integration tests, we might still want to use the real `ClsService` implementation. In that case, we will need to wrap the context-aware piece of code with a call to `ClsService#run` or `ClsService#runWith`.

```ts

describe('CatsService', () => {
  let service: CatsService
  let cls: ClsService
  const mockCatsRepository = createMock<CatsRepository>()

  beforeEach(async () => {
    const module = await Test.createTestingModule({
      // Set up most of the testing module as we normally would.
      providers: [
        CatsService,
        {
          provide: CatsRepository
          useValue: mockCatsRepository
        }
      ],
      imports: [
        // Import the static version of ClsModule which only provides
        // the ClsService, but does not set up the store in any way.
        ClsModule
      ],
    }).compile()

    service = module.get(CatsService)

    // Also retrieve the ClsService for later use.
    cls = module.get(ClsService)
  })

  describe('getCatForUser', () => {
    it('retrieves cat based on user id', async () => {
      const expectedUserId = 42
      mocksCatsRepository.getForUser.mockImplementationOnce(
        (id) => ({ userId: id })
      )

      // Wrap the test call in the `runWith` method
      // in which we can pass hand-crafted store values.
      const cat = await cls.runWith(
        { userId: expectedUserId },
        () => service.getCatForUser()
      )

      expect(cat.userId).toEqual(expectedUserId)
    })
  })
})
```

#### More information[#](/recipes/async-local-storage#more-information)

Visit the [NestJS CLS GitHub Page](https://github.com/Papooch/nestjs-cls) for the full API documentation and more code examples.

----
url: https://docs.nestjs.com/v9/recipes/crud-generator
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [CRUD generator](https://docs.nestjs.com/v9/recipes/crud-generator#crud-generator)
* [Introduction](https://docs.nestjs.com/v9/recipes/crud-generator#introduction)
* [Generating a new resource](https://docs.nestjs.com/v9/recipes/crud-generator#generating-a-new-resource)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/recipes/crud-generator.md "Suggest Edits")

### CRUD generator

Throughout the life span of a project, when we build new features, we often need to add new resources to our application. These resources typically require multiple, repetitive operations that we have to repeat each time we define a new resource.

#### Introduction[#](/recipes/crud-generator#introduction)

Let's imagine a real-world scenario, where we need to expose CRUD endpoints for 2 entities, let's say **User** and **Product** entities. Following the best practices, for each entity we would have to perform several operations, as follows:

* Generate a module (`nest g mo`) to keep code organized and establish clear boundaries (grouping related components)
* Generate a controller (`nest g co`) to define CRUD routes (or queries/mutations for GraphQL applications)
* Generate a service (`nest g s`) to implement & isolate business logic
* Generate an entity class/interface to represent the resource data shape
* Generate Data Transfer Objects (or inputs for GraphQL applications) to define how the data will be sent over the network

That's a lot of steps!

To help speed up this repetitive process, [Nest CLI](/v9/cli/overview) provides a generator (schematic) that automatically generates all the boilerplate code to help us avoid doing all of this, and make the developer experience much simpler.

> **Note** The schematic supports generating **HTTP** controllers, **Microservice** controllers, **GraphQL** resolvers (both code first and schema first), and **WebSocket** Gateways.

#### Generating a new resource[#](/recipes/crud-generator#generating-a-new-resource)

To create a new resource, simply run the following command in the root directory of your project:

```shell

$ nest g resource
```

`nest g resource` command not only generates all the NestJS building blocks (module, service, controller classes) but also an entity class, DTO classes as well as the testing (`.spec`) files.

Below you can see the generated controller file (for REST API):

```typescript

@Controller('users')
export class UsersController {
  constructor(private readonly usersService: UsersService) {}

  @Post()
  create(@Body() createUserDto: CreateUserDto) {
    return this.usersService.create(createUserDto);
  }

  @Get()
  findAll() {
    return this.usersService.findAll();
  }

  @Get(':id')
  findOne(@Param('id') id: string) {
    return this.usersService.findOne(+id);
  }

  @Patch(':id')
  update(@Param('id') id: string, @Body() updateUserDto: UpdateUserDto) {
    return this.usersService.update(+id, updateUserDto);
  }

  @Delete(':id')
  remove(@Param('id') id: string) {
    return this.usersService.remove(+id);
  }
}
```

Also, it automatically creates placeholders for all the CRUD endpoints (routes for REST APIs, queries and mutations for GraphQL, message subscribes for both Microservices and WebSocket Gateways) - all without having to lift a finger.

> **Note** Generated service classes are **not** tied to any specific **ORM (or data source)**. This makes the generator generic enough to meet the needs of any project. By default, all methods will contain placeholders, allowing you to populate it with the data sources specific to your project.

Likewise, if you want to generate resolvers for a GraphQL application, simply select the `GraphQL (code first)` (or `GraphQL (schema first)`) as your transport layer.

In this case, NestJS will generate a resolver class instead of a REST API controller:

```shell

$ nest g resource users

> ? What transport layer do you use? GraphQL (code first)
> ? Would you like to generate CRUD entry points? Yes
> CREATE src/users/users.module.ts (224 bytes)
> CREATE src/users/users.resolver.spec.ts (525 bytes)
> CREATE src/users/users.resolver.ts (1109 bytes)
> CREATE src/users/users.service.spec.ts (453 bytes)
> CREATE src/users/users.service.ts (625 bytes)
> CREATE src/users/dto/create-user.input.ts (195 bytes)
> CREATE src/users/dto/update-user.input.ts (281 bytes)
> CREATE src/users/entities/user.entity.ts (187 bytes)
> UPDATE src/app.module.ts (312 bytes)
```

> **Hint** To avoid generating test files, you can pass the `--no-spec` flag, as follows: `nest g resource users --no-spec`

We can see below, that not only were all boilerplate mutations and queries created, but everything is all tied together. We're utilizing the `UsersService`, `User` Entity, and our DTO's.

```typescript

import { Resolver, Query, Mutation, Args, Int } from '@nestjs/graphql';
import { UsersService } from './users.service';
import { User } from './entities/user.entity';
import { CreateUserInput } from './dto/create-user.input';
import { UpdateUserInput } from './dto/update-user.input';

@Resolver(() => User)
export class UsersResolver {
  constructor(private readonly usersService: UsersService) {}

  @Mutation(() => User)
  createUser(@Args('createUserInput') createUserInput: CreateUserInput) {
    return this.usersService.create(createUserInput);
  }

  @Query(() => [User], { name: 'users' })
  findAll() {
    return this.usersService.findAll();
  }

  @Query(() => User, { name: 'user' })
  findOne(@Args('id', { type: () => Int }) id: number) {
    return this.usersService.findOne(id);
  }

  @Mutation(() => User)
  updateUser(@Args('updateUserInput') updateUserInput: UpdateUserInput) {
    return this.usersService.update(updateUserInput.id, updateUserInput);
  }

  @Mutation(() => User)
  removeUser(@Args('id', { type: () => Int }) id: number) {
    return this.usersService.remove(id);
  }
}
```

----
url: https://docs.nestjs.com/v7/graphql/plugins
----

* [Plugins](https://docs.nestjs.com/v7/graphql/plugins#plugins)
* [Custom plugins](https://docs.nestjs.com/v7/graphql/plugins#custom-plugins)
* [Using external plugins](https://docs.nestjs.com/v7/graphql/plugins#using-external-plugins)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/plugins.md "Suggest Edits")

### Plugins

Plugins enable you to extend Apollo Server's core functionality by performing custom operations in response to certain events. Currently, these events correspond to individual phases of the GraphQL request lifecycle, and to the startup of Apollo Server itself (read more [here](https://www.apollographql.com/docs/apollo-server/integrations/plugins/)). For example, a basic logging plugin might log the GraphQL query string associated with each request that's sent to Apollo Server.

#### Custom plugins[#](/graphql/plugins#custom-plugins)

To create a plugin, declare a class annotated with the `@Plugin` decorator exported from the `@nestjs/graphql` package. Also, for better code autocompletion, implement the `ApolloServerPlugin` interface from the `apollo-server-plugin-base` package.

```typescript

import { Plugin } from '@nestjs/graphql';
import {
  ApolloServerPlugin,
  GraphQLRequestListener,
} from 'apollo-server-plugin-base';

@Plugin()
export class LoggingPlugin implements ApolloServerPlugin {
  requestDidStart(): GraphQLRequestListener {
    console.log('Request started');
    return {
      willSendResponse() {
        console.log('Will send response');
      },
    };
  }
}
```

With this in place, we can register the `LoggingPlugin` as a provider.

```typescript

@Module({
  providers: [LoggingPlugin],
})
export class CommonModule {}
```

Nest will automatically instantiate a plugin and apply it to the Apollo Server.

#### Using external plugins[#](/graphql/plugins#using-external-plugins)

There are several plugins provided out-of-the-box. To use an existing plugin, simply import it and add it to the `plugins` array:

```typescript

GraphQLModule.forRoot({
  // ...
  plugins: [ApolloServerOperationRegistry({ /* options */})]
}),
```

> **Hint** The `ApolloServerOperationRegistry` plugin is exported from the `apollo-server-plugin-operation-registry` package.

----
url: https://docs.nestjs.com/v7/recipes/terminus
----

* [Healthchecks (Terminus)](https://docs.nestjs.com/v7/recipes/terminus#healthchecks-terminus)
* [Getting started](https://docs.nestjs.com/v7/recipes/terminus#getting-started)
* [Setting up a Healthcheck](https://docs.nestjs.com/v7/recipes/terminus#setting-up-a-healthcheck)
* [HTTP Healthcheck](https://docs.nestjs.com/v7/recipes/terminus#http-healthcheck)
* [TypeOrm health indicator](https://docs.nestjs.com/v7/recipes/terminus#typeorm-health-indicator)
* [Custom health indicator](https://docs.nestjs.com/v7/recipes/terminus#custom-health-indicator)
* [Examples](https://docs.nestjs.com/v7/recipes/terminus#examples)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/recipes/terminus.md "Suggest Edits")

### Healthchecks (Terminus)

The NestJS **Terminus** integration supports you with **readiness / liveness** health checks. Healthchecks are very important when it comes to complex backend setups. In a nutshell, a health check in the realm of web development usually consists of a special address, for example, `https://my-website.com/health/readiness`. A service, or a component of your infrastructure (e.g., Kubernetes) checks this address continuously. Depending on the HTTP status code returned from a `GET` request to this address the service will take action when it receives an "unhealthy" response. Since the definition of "healthy" or "unhealthy" varies with the type of service you provide, the NestJS **Terminus** integration supports you with a set of **health indicators**.

As an example, if your web server uses MongoDB to store its data, it would be crucial information whether MongoDB is still up and running. In that case, you can make use of the `MongooseHealthIndicator`. If configured correctly - more on that later - your health check address will return a healthy or unhealthy HTTP status code, depending on whether MongoDB is running.

#### Getting started[#](/recipes/terminus#getting-started)

To get started with `@nestjs/terminus` we need to install the required dependency.

```bash

$ npm install --save @nestjs/terminus
```

#### Setting up a Healthcheck[#](/recipes/terminus#setting-up-a-healthcheck)

A health check represents a summary of **health indicators**. A health indicator executes a check of a service, whether it is in a healthy or unhealthy state. A health check is positive if all the assigned health indicators are up and running. Because a lot of applications will need similar health indicators, [@nestjs/terminus](https://github.com/nestjs/terminus) provides a set of predefined indicators, such as:

To get started with our first health check, we need to import the `TerminusModule` into our `AppModule`.

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { TerminusModule } from '@nestjs/terminus';

@Module({
  imports: [TerminusModule]
})
export class AppModule { }
```

Our healthcheck(s) can be executed using a [controller](/v7/controllers), which can be easily setup using the [NestJS CLI](/v7/recipes/terminus/cli/overview).

```bash

$ nest generate controller health
```

> **Info** It is highly recommended to enable shutdown hooks in your application. The Terminus integration makes use of this lifecycle event if enabled. Read more about shutdown hooks [here](fundamentals/lifecycle-events#application-shutdown).

#### HTTP Healthcheck[#](/recipes/terminus#http-healthcheck)

Once we have installed `@nestjs/terminus`, imported our `TerminusModule` and created a new controller, we are ready to create a health check.

health.controller.ts

JS TS

```typescript

@Controller('health')
export class HealthController {
  constructor(
    private health: HealthCheckService,
    private http: HttpHealthIndicator,
  ) {}

  @Get()
  @HealthCheck()
  check() {
    return this.health.check([
      () => this.http.pingCheck('nestjs-docs', 'https://docs.nestjs.com'),
    ]);
  }
}
```

```typescript

@Controller('health')
@Dependencies(HealthCheckService, HttpHealthIndicator)
export class HealthController {
  constructor(
    private health,
    private http,
  ) { }

  @Get()
  @HealthCheck()
  healthCheck() {
    return this.health.check([
      async () => this.http.pingCheck('nestjs-docs', 'https://docs.nestjs.com'),
    ])
  }
}
```

Our health check will now send a *GET*-request to the `https://docs.nestjs.com` address. If we get a healthy response from that address, our route at `http://localhost:3000/health` will return the following object with a 200 status code.

```json

{
  "status": "ok",
  "info": {
    "nestjs-docs": {
      "status": "up"
    }
  },
  "error": {},
  "details": {
    "nestjs-docs": {
      "status": "up"
    }
  }
}
```

The interface of this response object can be accessed from the `@nestjs/terminus` package with the `HealthCheckResult` interface.

| `status`  | If any health indicator failed the status will be `'error'`. If the NestJS app is shutting down but still accepting HTTP requests, the health check will have the `'shutting_down'` status. | `'error' \| 'ok' \| 'shutting_down'` |
| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------ |
| `info`    | Object containing information of each health indicator which is of status `'up'`, or in other words "healthy".                                                                              | `object`                             |
| `error`   | Object containing information of each health indicator which is of status `'down'`, or in other words "unhealthy".                                                                          | `object`                             |
| `details` | Object containing all information of each health indicator                                                                                                                                  | `object`                             |

#### TypeOrm health indicator[#](/recipes/terminus#typeorm-health-indicator)

Terminus offers the capability to add database checks to your health check. In order to get started with this health indicator, you should check out the [Database chapter](/v7/techniques/sql) and make sure your database connection within your application is established.

> **Hint** Behind the scenes the `TypeOrmHealthIndicator` simply executes a `SELECT 1`-SQL command which is often used to verify whether the database still alive. In case you are using an Oracle database it uses `SELECT 1 FROM DUAL`.

health.controller.ts

JS TS

```typescript

@Controller('health')
export class HealthController {
  constructor(
    private health: HealthCheckService,
    private db: TypeOrmHealthIndicator,
  ) {}

  @Get()
  @HealthCheck()
  check() {
    return this.health.check([
      () => this.db.pingCheck('database'),
    ]);
  }
}
```

```typescript

@Controller('health')
@Dependencies(HealthCheckService, TypeOrmHealthIndicator)
export class HealthController {
  constructor(
    private health,
    private db,
  ) { }

  @Get()
  @HealthCheck()
  healthCheck() {
    return this.health.check([
      async () => this.db.pingCheck('database'),
    ])
  }
}
```

If your database is reachable, you should now see the following JSON-result when requesting `http://localhost:3000` with a `GET` request:

```json

{
  "status": "ok",
  "info": {
    "database": {
      "status": "up"
    }
  },
  "error": {},
  "details": {
    "database": {
      "status": "up"
    }
  }
}
```

In case your app uses [multiple databases](techniques/database#multiple-databases), you need to inject each connection into your `HealthController`. Then, you can simply pass the connection reference to the `TypeOrmHealthIndicator`.

health.controller.ts

JS TS

```typescript

@Controller('health')
export class HealthController {
  constructor(
    private health: HealthCheckService,
    private db: TypeOrmHealthIndicator,
    @InjectConnection('albumsConnection')
    private albumsConnection: Connection,
    @InjectConnection()
    private defaultConnection: Connection,
  ) {}

  @Get()
  @HealthCheck()
  check() {
    return this.health.check([
      () => this.db.pingCheck('albums-database', { connection: this.albumsConnection }),
      () => this.db.pingCheck('database', { connection: this.defaultConnection }),
    ]);
  }
}
```

#### Custom health indicator[#](/recipes/terminus#custom-health-indicator)

In some cases, the predefined health indicators provided by `@nestjs/terminus` do not cover all of your health check requirements. In that case, you can set up a custom health indicator according to your needs.

Let's get started by creating a service that will represent our custom indicator. To get a basic understanding of how an indicator is structured, we will create an example `DogHealthIndicator`. This service should have the state `'up'` if every `Dog` object has the type `'goodboy'`. If that condition is not satisfied then it should throw an error.

dog.health.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { HealthIndicator, HealthIndicatorResult, HealthCheckError } from '@nestjs/terminus';

export interface Dog {
  name: string;
  type: string;
}

@Injectable()
export class DogHealthIndicator extends HealthIndicator {
  private dogs: Dog[] = [
    { name: 'Fido', type: 'goodboy' },
    { name: 'Rex', type: 'badboy' },
  ];

  async isHealthy(key: string): Promise<HealthIndicatorResult> {
    const badboys = this.dogs.filter(dog => dog.type === 'badboy');
    const isHealthy = badboys.length === 0;
    const result = this.getStatus(key, isHealthy, { badboys: badboys.length });

    if (isHealthy) {
      return result;
    }
    throw new HealthCheckError('Dogcheck failed', result);
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';
import { HealthCheckError } from '@godaddy/terminus';

@Injectable()
export class DogHealthIndicator extends HealthIndicator {
  dogs = [
    { name: 'Fido', type: 'goodboy' },
    { name: 'Rex', type: 'badboy' },
  ];

  async isHealthy(key) {
    const badboys = this.dogs.filter(dog => dog.type === 'badboy');
    const isHealthy = badboys.length === 0;
    const result = this.getStatus(key, isHealthy, { badboys: badboys.length });

    if (isHealthy) {
      return result;
    }
    throw new HealthCheckError('Dogcheck failed', result);
  }
}
```

The next thing we need to do is register the health indicator as a provider.

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { TerminusModule } from '@nestjs/terminus';
import { DogHealthIndicator } from './dog.health';

@Module({
  controllers: [HealthController],
  imports: [TerminusModule],
  providers: [DogHealthIndicator]
})
export class AppModule { }
```

> **Hint** In a real-world application the `DogHealthIndicator` should be provided in a separate module, for example, `DogModule`, which then will be imported by the `AppModule`.

The last required step is to add the now available health indicator in the required health check endpoint. For that, we go back to our `HealthController` and add it to our `check` function.

health.controller.ts

JS TS

```typescript

import { HealthCheckService } from '@nestjs/terminus';
import { Injectable } from '@nestjs/common';
import { DogHealthIndicator } from './dog.health';

@Injectable()
export class HealthController {
  constructor(
    private health: HealthCheckService,
    private dogHealthIndicator: DogHealthIndicator
  ) {}

  @Get()
  @HealthCheck()
  healthCheck() {
    return this.health.check([
      async () => this.dogHealthIndicator.isHealthy('dog'),
    ])
  }
}
```

```typescript

import { HealthCheckService } from '@nestjs/terminus';
import { Injectable } from '@nestjs/common';
import { DogHealthIndicator } from './dog.health';

@Injectable()
@Dependencies(HealthCheckService, DogHealthIndicator)
export class HealthController {
  constructor(
    private health,
    private dogHealthIndicator
  ) {}

  @Get()
  @HealthCheck()
  healthCheck() {
    return this.health.check([
      async () => this.dogHealthIndicator.isHealthy('dog'),
    ])
  }
}
```

#### Examples[#](/recipes/terminus#examples)

Some working examples are available [here](https://github.com/nestjs/terminus/tree/master/sample).

----
url: https://docs.nestjs.com/faq/serverless
----

[Skip to content](#content)

On this page

* [Serverless](https://docs.nestjs.com/faq/serverless#serverless)
* [Cold start](https://docs.nestjs.com/faq/serverless#cold-start)
* [Benchmarks](https://docs.nestjs.com/faq/serverless#benchmarks)
* [Runtime optimizations](https://docs.nestjs.com/faq/serverless#runtime-optimizations)
* [Example integration](https://docs.nestjs.com/faq/serverless#example-integration)
* [Using standalone application feature](https://docs.nestjs.com/faq/serverless#using-standalone-application-feature)

### Serverless

Serverless computing is a cloud computing execution model in which the cloud provider allocates machine resources on demand, managing the servers on behalf of its customers. When an app is not in use, no computing resources are allocated to it. Pricing is based on the actual amount of resources the application consumes ([source](https://en.wikipedia.org/wiki/Serverless_computing)).

With a **serverless architecture**, you focus on the individual functions in your application code. Services such as AWS Lambda, Google Cloud Functions, and Microsoft Azure Functions manage the physical hardware, the virtual machine operating system, and the web server software.

> **Hint** This chapter doesn't cover the pros and cons of serverless functions, nor does it dive into the specifics of any cloud provider.

#### Cold start[#](/faq/serverless#cold-start)

A cold start is the first time your code runs in a while. Depending on your cloud provider, it may span several operations, from downloading the code and bootstrapping the runtime to running your code. This process adds **significant latency**, depending on several factors such as the language and the number of packages your application requires.

Some of these factors are beyond your control, but there's still a lot you can do on your side to keep the cold start as short as possible.

While Nest is a fully-fledged framework designed for complex enterprise applications, it is also **suitable for much "simpler" applications** (or scripts). For example, with the [standalone applications](/standalone-applications) feature, you can use Nest's DI system in simple workers, CRON jobs, CLIs, or serverless functions.

#### Benchmarks[#](/faq/serverless#benchmarks)

To better understand the cost of using Nest or other well-known libraries (like `express`) in serverless functions, let's compare how much time the Node.js runtime needs to run the following scripts:

```typescript

// #1 Express
import express from 'express';

async function bootstrap() {
  const app = express();
  app.get('/', (req, res) => res.send('Hello world!'));
  await new Promise<void>((resolve) => app.listen(3000, resolve));
}
await bootstrap();

// #2 Nest (with @nestjs/platform-express)
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module.js';

async function bootstrap() {
  const app = await NestFactory.create(AppModule, { logger: ['error'] });
  await app.listen(process.env.PORT ?? 3000);
}
await bootstrap();

// #3 Nest as a Standalone application (no HTTP server)
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module.js';
import { AppService } from './app.service.js';

async function bootstrap() {
  const app = await NestFactory.createApplicationContext(AppModule, {
    logger: ['error'],
  });
  console.log(app.get(AppService).getHello());
}
await bootstrap();

// #4 Raw Node.js script
async function bootstrap() {
  console.log('Hello world!');
}
await bootstrap();
```

For all these scripts, we used the `tsc` (TypeScript) compiler, so the code remains unbundled (`webpack` isn't used).

| Express                              | 0.0079s (7.9ms)   |
| ------------------------------------ | ----------------- |
| Nest with `@nestjs/platform-express` | 0.1974s (197.4ms) |
| Nest (standalone application)        | 0.1117s (111.7ms) |
| Raw Node.js script                   | 0.0071s (7.1ms)   |

> **Note** Machine: MacBook Pro Mid 2014, 2.5 GHz Quad-Core Intel Core i7, 16 GB 1600 MHz DDR3, SSD.

Now, let's repeat all benchmarks, this time using `webpack` to bundle the application into a single executable JavaScript file (if you have the [Nest CLI](/cli/overview) installed, run `nest build --webpack`). Instead of the default `webpack` configuration that the Nest CLI ships with, we'll bundle all dependencies (`node_modules`) together, as follows:

```javascript

module.exports = (options, webpack) => {
  const lazyImports = [
    '@nestjs/microservices/microservices-module',
    '@nestjs/websockets/socket-module',
  ];

  return {
    ...options,
    externals: [],
    plugins: [
      ...options.plugins,
      new webpack.IgnorePlugin({
        checkResource(resource) {
          if (lazyImports.includes(resource)) {
            try {
              require.resolve(resource);
            } catch (err) {
              return true;
            }
          }
          return false;
        },
      }),
    ],
  };
};
```

> **Hint** To make the Nest CLI use this configuration, create a `webpack.config.js` file in the root directory of your project.

With this configuration, we got the following results:

| Express                              | 0.0068s (6.8ms)  |
| ------------------------------------ | ---------------- |
| Nest with `@nestjs/platform-express` | 0.0815s (81.5ms) |
| Nest (standalone application)        | 0.0319s (31.9ms) |
| Raw Node.js script                   | 0.0066s (6.6ms)  |

> **Note** Machine: MacBook Pro Mid 2014, 2.5 GHz Quad-Core Intel Core i7, 16 GB 1600 MHz DDR3, SSD.

> **Hint** You can optimize it even further with additional code minification and optimization techniques (e.g., using `webpack` plugins).

The way you compile your code (and whether you bundle it) has a significant impact on the overall startup time. With `webpack`, you can get the bootstrap time of a standalone Nest application (a starter project with one module, controller, and service) down to \~32ms on average, and down to \~81.5ms for a regular HTTP, Express-based NestJS app.

For a more complex Nest application, for example, one with 10 resources generated with the `$ nest g resource` schematic (10 modules, 10 controllers, 10 services, 20 DTO classes, and 50 HTTP endpoints, plus `AppModule`), the overall startup on the same machine takes approximately 0.1298s (129.8ms). Running a monolithic application as a serverless function rarely makes sense anyway, so treat this benchmark as an example of how the bootstrap time may increase as your application grows.

#### Runtime optimizations[#](/faq/serverless#runtime-optimizations)

So far, we've covered compile-time optimizations. These are unrelated to the way you define providers and load Nest modules in your application, which plays an essential role as your application grows.

For example, imagine a database connection defined as an [asynchronous provider](/fundamentals/async-providers). Async providers are designed to delay the application start until one or more asynchronous tasks complete. If your serverless function needs 2s on average to connect to the database on bootstrap, your endpoint needs at least two extra seconds to send a response on a cold start, because it must wait until the connection is established.

In a **serverless environment**, where bootstrap time matters, you structure your providers somewhat differently. For example, if you use Redis for caching only in certain scenarios, you probably shouldn't define the Redis connection as an async provider: it would slow down bootstrap even for function invocations that don't need it.

You can also lazy load entire modules with the `LazyModuleLoader` class, as described in the [lazy-loading modules](/fundamentals/lazy-loading-modules) chapter. Caching is a good example here too. Imagine that your application has a `CacheModule` that connects to Redis and exports a `CacheService` for interacting with the Redis storage. If not every function invocation needs it, you can load it lazily, on demand. This way, all invocations that don't require caching get a faster startup time on a cold start.

```typescript

if (request.method === RequestMethod[RequestMethod.GET]) {
  const { CacheModule } = await import('./cache.module.js');
  const moduleRef = await this.lazyModuleLoader.load(() => CacheModule);

  const { CacheService } = await import('./cache.service.js');
  const cacheService = moduleRef.get(CacheService);

  return cacheService.get(ENDPOINT_KEY);
}
```

Another example is a webhook or worker that performs different operations depending on specific conditions (e.g., input arguments). In this case, you can add a condition inside your route handler that lazily loads the appropriate module for the specific function invocation, and load every other module lazily as well.

```typescript

if (workerType === WorkerType.A) {
  const { WorkerAModule } = await import('./worker-a.module.js');
  const moduleRef = await this.lazyModuleLoader.load(() => WorkerAModule);
  // ...
} else if (workerType === WorkerType.B) {
  const { WorkerBModule } = await import('./worker-b.module.js');
  const moduleRef = await this.lazyModuleLoader.load(() => WorkerBModule);
  // ...
}
```

#### Example integration[#](/faq/serverless#example-integration)

What your application's entry file (typically `main.ts`) should look like **depends on several factors**, so **there's no single template** that works for every scenario. For example, the initialization file required to spin up your serverless function varies by cloud provider (AWS, Azure, GCP, etc.). Also, your application's code looks different depending on whether you want to run a typical HTTP application with multiple routes/endpoints or provide a single route (or execute a specific portion of code). For example, for the endpoint-per-function approach, you could use `NestFactory.createApplicationContext()` instead of booting the HTTP server, setting up middleware, etc.

For illustration purposes, we'll integrate Nest (using `@nestjs/platform-express`, and therefore spinning up the whole, fully functional HTTP router) with the [Serverless](https://www.serverless.com/) framework (in this case, targeting AWS Lambda). As mentioned earlier, your code will differ depending on the cloud provider you choose, among many other factors.

First, install the required packages:

```bash

$ npm i @codegenie/serverless-express
$ npm i -D @types/aws-lambda serverless-offline
```

> **Hint** To speed up development cycles, we install the `serverless-offline` plugin, which emulates AWS Lambda and API Gateway locally.

Once the installation is complete, create the `serverless.yml` file to configure the Serverless framework:

```yaml

service: serverless-example

plugins:
  - serverless-offline

provider:
  name: aws
  runtime: nodejs22.x

functions:
  main:
    handler: dist/main.handler
    events:
      - http:
          method: ANY
          path: /
      - http:
          method: ANY
          path: '{proxy+}'
```

> **Hint** To learn more about the Serverless framework, visit the [official documentation](https://www.serverless.com/framework/docs/).

With this in place, open the `main.ts` file and update the bootstrap code with the required boilerplate:

```typescript

import { NestFactory } from '@nestjs/core';
import serverlessExpress from '@codegenie/serverless-express';
import type { Callback, Context, Handler } from 'aws-lambda';
import { AppModule } from './app.module.js';

let server: Handler;

async function bootstrap(): Promise<Handler> {
  const app = await NestFactory.create(AppModule);
  await app.init();

  const expressApp = app.getHttpAdapter().getInstance();
  return serverlessExpress({ app: expressApp });
}

export const handler: Handler = async (
  event: any,
  context: Context,
  callback: Callback,
) => {
  server = server ?? (await bootstrap());
  return server(event, context, callback);
};
```

> **Hint** To create multiple serverless functions that share common modules, we recommend using the [CLI monorepo mode](/cli/monorepo#monorepo-mode).

> **Warning** If you use the `@nestjs/swagger` package, serving the Swagger UI from a serverless function requires one extra step. Behind API Gateway, the request's `originalUrl` may lack the trailing slash Swagger UI expects, which causes an endless redirect loop. Register a middleware that restores it **before** calling `SwaggerModule.setup()`:
>
> ```typescript
>
> app.use((req, res, next) => {
>   if (req.originalUrl === '/swagger') {
>     req.originalUrl = '/swagger/';
>   }
>   next();
> });
> ```

Next, make sure the `esModuleInterop` option is enabled in your `tsconfig.json` file so that the `@codegenie/serverless-express` package loads properly (projects generated with `nest new` enable it by default).

```json

{
  "compilerOptions": {
    ...
    "esModuleInterop": true
  }
}
```

Now build the application (with `nest build` or `tsc`) and use the `serverless` CLI to start the Lambda function locally:

```bash

$ npm run build
$ npx serverless offline
```

Once the application is running, open your browser and navigate to `http://localhost:3000/dev/[ANY_ROUTE]`, where `[ANY_ROUTE]` is any endpoint registered in your application.

The sections above show that bundling your app with `webpack` can have a significant impact on the overall bootstrap time. To make it work with this example, the bundle must expose the exported `handler` function. Starting with `@nestjs/cli` v12.0.8, the default `webpack` configuration does this by setting `output.library.type` to `commonjs2`, as long as your `webpack.config.js` keeps `...options.output` when it overrides `output`. With older versions of the CLI, or with a configuration that doesn't extend `options.output`, add a few more settings to your `webpack.config.js` file. In particular, set the `output.libraryTarget` property to `commonjs2`.

```javascript

return {
  ...options,
  externals: [],
  output: {
    ...options.output,
    libraryTarget: 'commonjs2',
  },
  // ... the rest of the configuration
};
```

With this in place, run `$ nest build --webpack` to compile your function's code (and then `$ npx serverless offline` to test it).

We also recommend (but **don't require**, as it slows down the build) installing the `terser-webpack-plugin` package and overriding its configuration to keep class names intact when minifying your production build. Otherwise, `class-validator` may behave incorrectly in your application.

```javascript

const TerserPlugin = require('terser-webpack-plugin');

return {
  ...options,
  externals: [],
  optimization: {
    minimizer: [
      new TerserPlugin({
        terserOptions: {
          keep_classnames: true,
        },
      }),
    ],
  },
  output: {
    ...options.output,
    libraryTarget: 'commonjs2',
  },
  // ... the rest of the configuration
};
```

#### Using standalone application feature[#](/faq/serverless#using-standalone-application-feature)

Alternatively, if you want to keep your function lightweight and don't need any HTTP-related features (routing, but also guards, interceptors, pipes, etc.), use `NestFactory.createApplicationContext()` (as mentioned earlier) instead of running the entire HTTP server (and `express` under the hood):

main.ts

JS TS

```typescript

import { HttpStatus } from '@nestjs/common';
import { NestFactory } from '@nestjs/core';
import type { Callback, Context, Handler } from 'aws-lambda';
import { AppModule } from './app.module.js';
import { AppService } from './app.service.js';

export const handler: Handler = async (
  event: any,
  context: Context,
  callback: Callback,
) => {
  const appContext = await NestFactory.createApplicationContext(AppModule);
  const appService = appContext.get(AppService);

  return {
    body: appService.getHello(),
    statusCode: HttpStatus.OK,
  };
};
```

> **Hint**`NestFactory.createApplicationContext()` doesn't wrap controller methods with enhancers (guards, interceptors, etc.). If you need enhancers, use the `NestFactory.create()` method.

You could also pass the `event` object to a provider, such as an `EventsService`, that processes it and returns a corresponding value (depending on the input and your business logic).

```typescript

export const handler: Handler = async (
  event: any,
  context: Context,
  callback: Callback,
) => {
  const appContext = await NestFactory.createApplicationContext(AppModule);
  const eventsService = appContext.get(EventsService);
  return eventsService.process(event);
};
```

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/faq/serverless.md)

----
url: https://docs.nestjs.com/v8/microservices/basics
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Overview](https://docs.nestjs.com/v8/microservices/basics#overview)
* [Installation](https://docs.nestjs.com/v8/microservices/basics#installation)
* [Getting started](https://docs.nestjs.com/v8/microservices/basics#getting-started)
* [Patterns](https://docs.nestjs.com/v8/microservices/basics#patterns)
* [Request-response](https://docs.nestjs.com/v8/microservices/basics#request-response)
* [Asynchronous responses](https://docs.nestjs.com/v8/microservices/basics#asynchronous-responses)
* [Event-based](https://docs.nestjs.com/v8/microservices/basics#event-based)
* [Decorators](https://docs.nestjs.com/v8/microservices/basics#decorators)
* [Client](https://docs.nestjs.com/v8/microservices/basics#client)
* [Sending messages](https://docs.nestjs.com/v8/microservices/basics#sending-messages)
* [Publishing events](https://docs.nestjs.com/v8/microservices/basics#publishing-events)
* [Scopes](https://docs.nestjs.com/v8/microservices/basics#scopes)
* [Handling timeouts](https://docs.nestjs.com/v8/microservices/basics#handling-timeouts)

```bash

$ npm i --save @nestjs/microservices
```

#### Getting started[#](/microservices/basics#getting-started)

To instantiate a microservice, use the `createMicroservice()` method of the `NestFactory` class:

main.ts

JS TS

```typescript

import { NestFactory } from '@nestjs/core';
import { Transport, MicroserviceOptions } from '@nestjs/microservices';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.createMicroservice<MicroserviceOptions>(
    AppModule,
    {
      transport: Transport.TCP,
    },
  );
  await app.listen();
}
bootstrap();
```

```typescript

import { NestFactory } from '@nestjs/core';
import { Transport, MicroserviceOptions } from '@nestjs/microservices';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.createMicroservice(AppModule, {
    transport: Transport.TCP,
  });
  await app.listen();
}
bootstrap();
```

> **Hint** Microservices use the **TCP** transport layer by default.

The second argument of the `createMicroservice()` method is an `options` object. This object may consist of two members:

|             |                                                                            |
| ----------- | -------------------------------------------------------------------------- |
| `transport` | Specifies the transporter (for example, `Transport.NATS`)                  |
| `options`   | A transporter-specific options object that determines transporter behavior |

The `options` object is specific to the chosen transporter. The **TCP** transporter exposes the properties described below. For other transporters (e.g, Redis, MQTT, etc.), see the relevant chapter for a description of the available options.

|                 |                                                          |
| --------------- | -------------------------------------------------------- |
| `host`          | Connection hostname                                      |
| `port`          | Connection port                                          |
| `retryAttempts` | Number of times to retry message (default: `0`)          |
| `retryDelay`    | Delay between message retry attempts (ms) (default: `0`) |

```typescript

import { Controller } from '@nestjs/common';
import { MessagePattern } from '@nestjs/microservices';

@Controller()
export class MathController {
  @MessagePattern({ cmd: 'sum' })
  accumulate(data: number[]): number {
    return (data || []).reduce((a, b) => a + b);
  }
}
```

```typescript

import { Controller } from '@nestjs/common';
import { MessagePattern } from '@nestjs/microservices';

@Controller()
export class MathController {
  @MessagePattern({ cmd: 'sum' })
  accumulate(data) {
    return (data || []).reduce((a, b) => a + b);
  }
}
```

In the above code, the `accumulate()`**message handler** listens for messages that fulfill the `{ cmd: 'sum' }` message pattern. The message handler takes a single argument, the `data` passed from the client. In this case, the data is an array of numbers which are to be accumulated.

#### Asynchronous responses[#](/microservices/basics#asynchronous-responses)

Message handlers are able to respond either synchronously or **asynchronously**. Hence, `async` methods are supported.

JS TS

```typescript

@MessagePattern({ cmd: 'sum' })
async accumulate(data: number[]): Promise<number> {
  return (data || []).reduce((a, b) => a + b);
}
```

```typescript

@MessagePattern({ cmd: 'sum' })
async accumulate(data) {
  return (data || []).reduce((a, b) => a + b);
}
```

A message handler is also able to return an `Observable`, in which case the result values will be emitted until the stream is completed.

JS TS

```typescript

@MessagePattern({ cmd: 'sum' })
accumulate(data: number[]): Observable<number> {
  return from([1, 2, 3]);
}
```

```typescript

@MessagePattern({ cmd: 'sum' })
accumulate(data: number[]): Observable<number> {
  return from([1, 2, 3]);
}
```

In the example above, the message handler will respond **3 times** (with each item from the array).

#### Event-based[#](/microservices/basics#event-based)

While the request-response method is ideal for exchanging messages between services, it is less suitable when your message style is event-based - when you just want to publish **events** without waiting for a response. In that case, you do not want the overhead required by request-response for maintaining two channels.

Suppose you would like to simply notify another service that a certain condition has occurred in this part of the system. This is the ideal use case for the event-based message style.

To create an event handler, we use the `@EventPattern()` decorator, which is imported from the `@nestjs/microservices` package.

JS TS

```typescript

@EventPattern('user_created')
async handleUserCreated(data: Record<string, unknown>) {
  // business logic
}
```

```typescript

@EventPattern('user_created')
async handleUserCreated(data) {
  // business logic
}
```

> **Hint** You can register multiple event handlers for a **single** event pattern and all of them will be automatically triggered in parallel.

```typescript

@MessagePattern('time.us.*')
getDate(@Payload() data: number[], @Ctx() context: NatsContext) {
  console.log(`Subject: ${context.getSubject()}`); // e.g. "time.us.east"
  return new Date().toLocaleTimeString(...);
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('time.us.*')
getDate(data, context) {
  console.log(`Subject: ${context.getSubject()}`); // e.g. "time.us.east"
  return new Date().toLocaleTimeString(...);
}
```

> **Hint**`@Payload()`, `@Ctx()` and `NatsContext` are imported from `@nestjs/microservices`.

> **Hint** You can also pass in a property key to the `@Payload()` decorator to extract a specific property from the incoming payload object, for example, `@Payload('id')`.

#### Client[#](/microservices/basics#client)

A client Nest application can exchange messages or publish events to a Nest microservice using the `ClientProxy` class. This class defines several methods, such as `send()` (for request-response messaging) and `emit()` (for event-driven messaging) that let you communicate with a remote microservice. Obtain an instance of this class in one of the following ways.

One technique is to import the `ClientsModule`, which exposes the static `register()` method. This method takes an argument which is an array of objects representing microservice transporters. Each such object has a `name` property, an optional `transport` property (default is `Transport.TCP`), and an optional transporter-specific `options` property.

The `name` property serves as an **injection token** that can be used to inject an instance of a `ClientProxy` where needed. The value of the `name` property, as an injection token, can be an arbitrary string or JavaScript symbol, as described [here](https://docs.nestjs.com/fundamentals/custom-providers#non-class-based-provider-tokens).

The `options` property is an object with the same properties we saw in the `createMicroservice()` method earlier.

```typescript

@Module({
  imports: [
    ClientsModule.register([
      { name: 'MATH_SERVICE', transport: Transport.TCP },
    ]),
  ]
  ...
})
```

Once the module has been imported, we can inject an instance of the `ClientProxy` configured as specified via the `'MATH_SERVICE'` transporter options shown above, using the `@Inject()` decorator.

```typescript

constructor(
  @Inject('MATH_SERVICE') private client: ClientProxy,
) {}
```

> **Hint** The `ClientsModule` and `ClientProxy` classes are imported from the `@nestjs/microservices` package.

At times we may need to fetch the transporter configuration from another service (say a `ConfigService`), rather than hard-coding it in our client application. To do this, we can register a [custom provider](/v8/fundamentals/custom-providers) using the `ClientProxyFactory` class. This class has a static `create()` method, which accepts a transporter options object, and returns a customized `ClientProxy` instance.

```typescript

@Module({
  providers: [
    {
      provide: 'MATH_SERVICE',
      useFactory: (configService: ConfigService) => {
        const mathSvcOptions = configService.getMathSvcOptions();
        return ClientProxyFactory.create(mathSvcOptions);
      },
      inject: [ConfigService],
    }
  ]
  ...
})
```

> **Hint** The `ClientProxyFactory` is imported from the `@nestjs/microservices` package.

Another option is to use the `@Client()` property decorator.

```typescript

@Client({ transport: Transport.TCP })
client: ClientProxy;
```

> **Hint** The `@Client()` decorator is imported from the `@nestjs/microservices` package.

Using the `@Client()` decorator is not the preferred technique, as it is harder to test and harder to share a client instance.

The `ClientProxy` is **lazy**. It doesn't initiate a connection immediately. Instead, it will be established before the first microservice call, and then reused across each subsequent call. However, if you want to delay the application bootstrapping process until a connection is established, you can manually initiate a connection using the `ClientProxy` object's `connect()` method inside the `OnApplicationBootstrap` lifecycle hook.

JS TS

```typescript

async onApplicationBootstrap() {
  await this.client.connect();
}
```

If the connection cannot be created, the `connect()` method will reject with the corresponding error object.

#### Sending messages[#](/microservices/basics#sending-messages)

The `ClientProxy` exposes a `send()` method. This method is intended to call the microservice and returns an `Observable` with its response. Thus, we can subscribe to the emitted values easily.

JS TS

```typescript

accumulate(): Observable<number> {
  const pattern = { cmd: 'sum' };
  const payload = [1, 2, 3];
  return this.client.send<number>(pattern, payload);
}
```

```typescript

accumulate() {
  const pattern = { cmd: 'sum' };
  const payload = [1, 2, 3];
  return this.client.send(pattern, payload);
}
```

The `send()` method takes two arguments, `pattern` and `payload`. The `pattern` should match one defined in a `@MessagePattern()` decorator. The `payload` is a message that we want to transmit to the remote microservice. This method returns a **cold `Observable`**, which means that you have to explicitly subscribe to it before the message will be sent.

#### Publishing events[#](/microservices/basics#publishing-events)

To send an event, use the `ClientProxy` object's `emit()` method. This method publishes an event to the message broker.

JS TS

```typescript

async publish() {
  this.client.emit<number>('user_created', new UserCreatedEvent());
}
```

```typescript

async publish() {
  this.client.emit('user_created', new UserCreatedEvent());
}
```

The `emit()` method takes two arguments, `pattern` and `payload`. The `pattern`should match one defined in an `@EventPattern()` decorator. The `payload` is an event payload that we want to transmit to the remote microservice. This method returns a **hot `Observable`** (unlike the cold `Observable` returned by `send()`), which means that whether or not you explicitly subscribe to the observable, the proxy will immediately try to deliver the event.

## Hoodies, T-shirts, and accessories!

Support our future development by shopping in the official store!

[See more](https://nestjs.threadless.com/ "Shop | NestJS - A node.js framework built on top of TypeScript")

#### Scopes[#](/microservices/basics#scopes)

For people coming from different programming language backgrounds, it might be unexpected to learn that in Nest, almost everything is shared across incoming requests. We have a connection pool to the database, singleton services with global state, etc. Remember that Node.js doesn't follow the request/response Multi-Threaded Stateless Model in which every request is processed by a separate thread. Hence, using singleton instances is fully **safe** for our applications.

However, there are edge-cases when request-based lifetime of the handler may be the desired behavior, for instance per-request caching in GraphQL applications, request tracking or multi-tenancy. Learn how to control scopes [here](/v8/fundamentals/injection-scopes).

Request-scoped handlers and providers can inject `RequestContext` using the `@Inject()` decorator in combination with `CONTEXT` token:

```typescript

import { Injectable, Scope, Inject } from '@nestjs/common';
import { CONTEXT, RequestContext } from '@nestjs/microservices';

@Injectable({ scope: Scope.REQUEST })
export class CatsService {
  constructor(@Inject(CONTEXT) private ctx: RequestContext) {}
}
```

This provides access to the `RequestContext` object, which has two properties:

```typescript

export interface RequestContext<T = any> {
  pattern: string | Record<string, any>;
  data: T;
}
```

The `data` property is the message payload sent by the message producer. The `pattern` property is the pattern used to identify an appropriate handler to handle the incoming message.

#### Handling timeouts[#](/microservices/basics#handling-timeouts)

In distributed systems, sometimes microservices might be down or not available. To avoid infinitely long waiting, you can use Timeouts. A timeout is an incredibly useful pattern when communicating with other services. To apply timeouts to your microservice calls, you can use the [RxJS](https://rxjs.dev)`timeout` operator. If the microservice does not respond to the request within a certain time, an exception is thrown, which can be caught and handled appropriately.

To solve this problem you have to use [`rxjs`](https://github.com/ReactiveX/rxjs) package. Just use the `timeout` operator in the pipe:

JS TS

```typescript

this.client
      .send<TResult, TInput>(pattern, data)
      .pipe(timeout(5000));
```

```typescript

this.client
      .send(pattern, data)
      .pipe(timeout(5000));
```

> **Hint** The `timeout` operator is imported from the `rxjs/operators` package.

After 5 seconds, if the microservice isn't responding, it will throw an error.

----
url: https://docs.nestjs.com/v7/techniques/configuration
----

* [Configuration](https://docs.nestjs.com/v7/techniques/configuration#configuration)
* [Installation](https://docs.nestjs.com/v7/techniques/configuration#installation)
* [Getting started](https://docs.nestjs.com/v7/techniques/configuration#getting-started)
* [Custom env file path](https://docs.nestjs.com/v7/techniques/configuration#custom-env-file-path)
* [Disable env variables loading](https://docs.nestjs.com/v7/techniques/configuration#disable-env-variables-loading)
* [Use module globally](https://docs.nestjs.com/v7/techniques/configuration#use-module-globally)
* [Custom configuration files](https://docs.nestjs.com/v7/techniques/configuration#custom-configuration-files)
* [Using the ConfigService](https://docs.nestjs.com/v7/techniques/configuration#using-the-configservice)
* [Configuration namespaces](https://docs.nestjs.com/v7/techniques/configuration#configuration-namespaces)
* [Cache environment variables](https://docs.nestjs.com/v7/techniques/configuration#cache-environment-variables)
* [Partial registration](https://docs.nestjs.com/v7/techniques/configuration#partial-registration)
* [Schema validation](https://docs.nestjs.com/v7/techniques/configuration#schema-validation)
* [Custom validate function](https://docs.nestjs.com/v7/techniques/configuration#custom-validate-function)
* [Custom getter functions](https://docs.nestjs.com/v7/techniques/configuration#custom-getter-functions)
* [Expandable variables](https://docs.nestjs.com/v7/techniques/configuration#expandable-variables)
* [Using in the main.ts](https://docs.nestjs.com/v7/techniques/configuration#using-in-the-maints)

```bash

$ npm i --save @nestjs/config
```

> **Hint** The `@nestjs/config` package internally uses [dotenv](https://github.com/motdotla/dotenv).

#### Getting started[#](/techniques/configuration#getting-started)

Once the installation process is complete, we can import the `ConfigModule`. Typically, we'll import it into the root `AppModule` and control its behavior using the `.forRoot()` static method. During this step, environment variable key/value pairs are parsed and resolved. Later, we'll see several options for accessing the `ConfigService` class of the `ConfigModule` in our other feature modules.

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';

@Module({
  imports: [ConfigModule.forRoot()],
})
export class AppModule {}
```

The above code will load and parse a `.env` file from the default location (the project root directory), merge key/value pairs from the `.env` file with environment variables assigned to `process.env`, and store the result in a private structure that you can access through the `ConfigService`. The `forRoot()` method registers the `ConfigService` provider, which provides a `get()` method for reading these parsed/merged configuration variables. Since `@nestjs/config` relies on [dotenv](https://github.com/motdotla/dotenv), it uses that package's rules for resolving conflicts in environment variable names. When a key exists both in the runtime environment as an environment variable (e.g., via OS shell exports like `export DATABASE_USER=test`) and in a `.env` file, the runtime environment variable takes precedence.

A sample `.env` file looks something like this:

```json

DATABASE_USER=test
DATABASE_PASSWORD=test
```

#### Custom env file path[#](/techniques/configuration#custom-env-file-path)

By default, the package looks for a `.env` file in the root directory of the application. To specify another path for the `.env` file, set the `envFilePath` property of an (optional) options object you pass to `forRoot()`, as follows:

```typescript

ConfigModule.forRoot({
  envFilePath: '.development.env',
});
```

You can also specify multiple paths for `.env` files like this:

```typescript

ConfigModule.forRoot({
  envFilePath: ['.env.development.local', '.env.development'],
});
```

If a variable is found in multiple files, the first one takes precedence.

#### Disable env variables loading[#](/techniques/configuration#disable-env-variables-loading)

If you don't want to load the `.env` file, but instead would like to simply access environment variables from the runtime environment (as with OS shell exports like `export DATABASE_USER=test`), set the options object's `ignoreEnvFile` property to `true`, as follows:

```typescript

ConfigModule.forRoot({
  ignoreEnvFile: true,
});
```

#### Use module globally[#](/techniques/configuration#use-module-globally)

When you want to use `ConfigModule` in other modules, you'll need to import it (as is standard with any Nest module). Alternatively, declare it as a [global module](https://docs.nestjs.com/modules#global-modules) by setting the options object's `isGlobal` property to `true`, as shown below. In that case, you will not need to import `ConfigModule` in other modules once it's been loaded in the root module (e.g., `AppModule`).

```typescript

ConfigModule.forRoot({
  isGlobal: true,
});
```

#### Custom configuration files[#](/techniques/configuration#custom-configuration-files)

For more complex projects, you may utilize custom configuration files to return nested configuration objects. This allows you to group related configuration settings by function (e.g., database-related settings), and to store related settings in individual files to help manage them independently.

A custom configuration file exports a factory function that returns a configuration object. The configuration object can be any arbitrarily nested plain JavaScript object. The `process.env` object will contain the fully resolved environment variable key/value pairs (with `.env` file and externally defined variables resolved and merged as described [above](techniques/configuration#getting-started)). Since you control the returned configuration object, you can add any required logic to cast values to an appropriate type, set default values, etc. For example:

config/configuration.ts

JS TS

```typescript

export default () => ({
  port: parseInt(process.env.PORT, 10) || 3000,
  database: {
    host: process.env.DATABASE_HOST,
    port: parseInt(process.env.DATABASE_PORT, 10) || 5432
  }
});
```

We load this file using the `load` property of the options object we pass to the `ConfigModule.forRoot()` method:

```typescript

import configuration from './config/configuration';

@Module({
  imports: [
    ConfigModule.forRoot({
      load: [configuration],
    }),
  ],
})
export class AppModule {}
```

> **Notice** The value assigned to the `load` property is an array, allowing you to load multiple configuration files (e.g. `load: [databaseConfig, authConfig]`)

With custom configuration files, we can also manage custom files such as YAML files. Here is an example of a configuration using YAML format:

```yaml

http:
  host: 'localhost'
  port: 8080

db:
  postgres:
    url: 'localhost'
    port: 5432
    database: 'yaml-db'

  sqlite:
    database: 'sqlite.db'
```

To read and parse YAML files, we can leverage the `js-yaml` package.

```bash

$ npm i js-yaml
$ npm i -D @types/js-yaml
```

Once the package is installed, we use `yaml#load` function to load YAML file we just created above.

config/configuration.ts

JS TS

```typescript

import { readFileSync } from 'fs';
import * as yaml from 'js-yaml';
import { join } from 'path';

const YAML_CONFIG_FILENAME = 'config.yml';

export default () => {
  return yaml.load(
    fs.readFileSync(join(__dirname, YAML_CONFIG_FILENAME), 'utf8'),
  );
};
```

> **Note** Nest CLI does not automatically move your "assets" (non-TS files) to the `dist` folder during the build process. To make sure that your YAML files are copied, you have to specify this in the `compilerOptions#assets` object in the `nest-cli.json` file. As an example, if the `config` folder is at the same level as the `src` folder, add `compilerOptions#assets` with the value `"assets": [{"include": "../config/*.yaml", "outDir": "./dist/config"}]`. Read more [here](/cli/monorepo#assets).

```typescript

@Module({
  imports: [ConfigModule],
  // ...
})
```

Then we can inject it using standard constructor injection:

```typescript

constructor(private configService: ConfigService) {}
```

> **Hint** The `ConfigService` is imported from the `@nestjs/config` package.

And use it in our class:

```typescript

// get an environment variable
const dbUser = this.configService.get<string>('DATABASE_USER');

// get a custom configuration value
const dbHost = this.configService.get<string>('database.host');
```

As shown above, use the `configService.get()` method to get a simple environment variable by passing the variable name. You can do TypeScript type hinting by passing the type, as shown above (e.g., `get<string>(...)`). The `get()` method can also traverse a nested custom configuration object (created via a [Custom configuration file](techniques/configuration#custom-configuration-files)), as shown in the second example above.

You can also get the whole nested custom configuration object using an interface as the type hint:

```typescript

interface DatabaseConfig {
  host: string;
  port: number;
}

const dbConfig = this.configService.get<DatabaseConfig>('database');

// you can now use `dbConfig.port` and `dbConfig.host`
const port = dbConfig.port;
```

The `get()` method also takes an optional second argument defining a default value, which will be returned when the key doesn't exist, as shown below:

```typescript

// use "localhost" when "database.host" is not defined
const dbHost = this.configService.get<string>('database.host', 'localhost');
```

`ConfigService` has an optional generic (type argument) to help prevent accessing a config property that does not exist. Use it as shown below:

```typescript

interface EnvironmentVariables {
  PORT: number;
  TIMEOUT: string;
}

// somewhere in the code
constructor(private configService: ConfigService<EnvironmentVariables>) {
  // this is valid
  const port = this.configService.get<number>('PORT');

  // this is invalid as URL is not a property on the EnvironmentVariables interface
  const url = this.configService.get<string>('URL');
}
```

> **Notice** If you have nested properties in your config, like in the `database.host` example above, the interface must have a matching `'database.host': string;` property. Otherwise a TypeScript error will be thrown.

#### Configuration namespaces[#](/techniques/configuration#configuration-namespaces)

The `ConfigModule` allows you to define and load multiple custom configuration files, as shown in [Custom configuration files](techniques/configuration#custom-configuration-files) above. You can manage complex configuration object hierarchies with nested configuration objects as shown in that section. Alternatively, you can return a "namespaced" configuration object with the `registerAs()` function as follows:

config/database.config.ts

JS TS

```typescript

export default registerAs('database', () => ({
  host: process.env.DATABASE_HOST,
  port: process.env.DATABASE_PORT || 5432
}));
```

As with custom configuration files, inside your `registerAs()` factory function, the `process.env` object will contain the fully resolved environment variable key/value pairs (with `.env` file and externally defined variables resolved and merged as described [above](techniques/configuration#getting-started)).

> **Hint** The `registerAs` function is exported from the `@nestjs/config` package.

Load a namespaced configuration with the `load` property of the `forRoot()` method's options object, in the same way you load a custom configuration file:

```typescript

import databaseConfig from './config/database.config';

@Module({
  imports: [
    ConfigModule.forRoot({
      load: [databaseConfig],
    }),
  ],
})
export class AppModule {}
```

Now, to get the `host` value from the `database` namespace, use dot notation. Use `'database'` as the prefix to the property name, corresponding to the name of the namespace (passed as the first argument to the `registerAs()` function):

```typescript

const dbHost = this.configService.get<string>('database.host');
```

A reasonable alternative is to inject the `database` namespace directly. This allows us to benefit from strong typing:

```typescript

constructor(
  @Inject(databaseConfig.KEY)
  private dbConfig: ConfigType<typeof databaseConfig>,
) {}
```

> **Hint** The `ConfigType` is exported from the `@nestjs/config` package.

#### Cache environment variables[#](/techniques/configuration#cache-environment-variables)

As accessing `process.env` can be slow, you can set the `cache` property of the options object passed to `ConfigModule.forRoot()` to increase the performance of `ConfigService#get` method when it comes to variables stored in `process.env`.

```typescript

ConfigModule.forRoot({
  cache: true,
});
```

#### Partial registration[#](/techniques/configuration#partial-registration)

Thus far, we've processed configuration files in our root module (e.g., `AppModule`), with the `forRoot()` method. Perhaps you have a more complex project structure, with feature-specific configuration files located in multiple different directories. Rather than load all these files in the root module, the `@nestjs/config` package provides a feature called **partial registration**, which references only the configuration files associated with each feature module. Use the `forFeature()` static method within a feature module to perform this partial registration, as follows:

```typescript

import databaseConfig from './config/database.config';

@Module({
  imports: [ConfigModule.forFeature(databaseConfig)],
})
export class DatabaseModule {}
```

> **Warning** In some circumstances, you may need to access properties loaded via partial registration using the `onModuleInit()` hook, rather than in a constructor. This is because the `forFeature()` method is run during module initialization, and the order of module initialization is indeterminate. If you access values loaded this way by another module, in a constructor, the module that the configuration depends upon may not yet have initialized. The `onModuleInit()` method runs only after all modules it depends upon have been initialized, so this technique is safe.

#### Schema validation[#](/techniques/configuration#schema-validation)

It is standard practice to throw an exception during application startup if required environment variables haven't been provided or if they don't meet certain validation rules. The `@nestjs/config` package enables two different ways to do this:

* [Joi](https://github.com/sideway/joi) built-in validator. With Joi, you define an object schema and validate JavaScript objects against it.
* A custom `validate()` function which takes environment variables as an input.

To use Joi, we must install Joi package:

```bash

$ npm install --save joi
```

> **Notice** The latest version of `joi` requires you to be running Node v12 or later. For older versions of node, please install `v16.1.8`. This is mainly after the release of `v17.0.2` which causes errors during build time. For more information, please refer to [their 17.0.0 release notes](https://github.com/sideway/joi/issues/2262).

Now we can define a Joi validation schema and pass it via the `validationSchema` property of the `forRoot()` method's options object, as shown below:

app.module.ts

JS TS

```typescript

import * as Joi from 'joi';

@Module({
  imports: [
    ConfigModule.forRoot({
      validationSchema: Joi.object({
        NODE_ENV: Joi.string()
          .valid('development', 'production', 'test', 'provision')
          .default('development'),
        PORT: Joi.number().default(3000),
      }),
    }),
  ],
})
export class AppModule {}
```

By default, all schema keys are considered optional. Here, we set default values for `NODE_ENV` and `PORT` which will be used if we don't provide these variables in the environment (`.env` file or process environment). Alternatively, we can use the `required()` validation method to require that a value must be defined in the environment (`.env` file or process environment). In this case, the validation step will throw an exception if we don't provide the variable in the environment. See [Joi validation methods](https://joi.dev/api/?v=17.3.0#example) for more on how to construct validation schemas.

By default, unknown environment variables (environment variables whose keys are not present in the schema) are allowed and do not trigger a validation exception. By default, all validation errors are reported. You can alter these behaviors by passing an options object via the `validationOptions` key of the `forRoot()` options object. This options object can contain any of the standard validation options properties provided by [Joi validation options](https://joi.dev/api/?v=17.3.0#anyvalidatevalue-options). For example, to reverse the two settings above, pass options like this:

app.module.ts

JS TS

```typescript

import * as Joi from 'joi';

@Module({
  imports: [
    ConfigModule.forRoot({
      validationSchema: Joi.object({
        NODE_ENV: Joi.string()
          .valid('development', 'production', 'test', 'provision')
          .default('development'),
        PORT: Joi.number().default(3000),
      }),
      validationOptions: {
        allowUnknown: false,
        abortEarly: true,
      },
    }),
  ],
})
export class AppModule {}
```

```typescript

import { plainToClass } from 'class-transformer';
import { IsEnum, IsNumber, validateSync } from 'class-validator';

enum Environment {
  Development = "development",
  Production = "production",
  Test = "test",
  Provision = "provision",
}

class EnvironmentVariables {
  @IsEnum(Environment)
  NODE_ENV: Environment;

  @IsNumber()
  PORT: number;
}

export function validate(config: Record<string, unknown>) {
  const validatedConfig = plainToClass(
    EnvironmentVariables,
    config,
    { enableImplicitConversion: true },
  );
  const errors = validateSync(validatedConfig, { skipMissingProperties: false });

  if (errors.length > 0) {
    throw new Error(errors.toString());
  }
  return validatedConfig;
}
```

With this in place, use the `validate` function as a configuration option of the `ConfigModule`, as follows:

app.module.ts

JS TS

```typescript

import { validate } from './env.validation';

@Module({
  imports: [
    ConfigModule.forRoot({
      validate,
    }),
  ],
})
export class AppModule {}
```

## Hoodies, T-shirts, and accessories!

Support our future development by shopping in the official store!

[See more](https://nestjs.threadless.com/ "Shop | NestJS - A node.js framework built on top of TypeScript")

#### Custom getter functions[#](/techniques/configuration#custom-getter-functions)

`ConfigService` defines a generic `get()` method to retrieve a configuration value by key. We may also add `getter` functions to enable a little more natural coding style:

JS TS

```typescript

@Injectable()
export class ApiConfigService {
  constructor(private configService: ConfigService) {}

  get isAuthEnabled(): boolean {
    return this.configService.get('AUTH_ENABLED') === 'true';
  }
}
```

```typescript

@Dependencies(ConfigService)
@Injectable()
export class ApiConfigService {
  constructor(configService) {
    this.configService = configService;
  }

  get isAuthEnabled() {
    return this.configService.get('AUTH_ENABLED') === 'true';
  }
}
```

Now we can use the getter function as follows:

app.service.ts

JS TS

```typescript

@Injectable()
export class AppService {
  constructor(apiConfigService: ApiConfigService) {
    if (apiConfigService.isAuthEnabled) {
      // Authentication is enabled
    }
  }
}
```

```typescript

@Dependencies(ApiConfigService)
@Injectable()
export class AppService {
  constructor(apiConfigService) {
    if (apiConfigService.isAuthEnabled) {
      // Authentication is enabled
    }
  }
}
```

#### Expandable variables[#](/techniques/configuration#expandable-variables)

The `@nestjs/config` package supports environment variable expansion. With this technique, you can create nested environment variables, where one variable is referred to within the definition of another. For example:

```json

APP_URL=mywebsite.com
SUPPORT_EMAIL=support@${APP_URL}
```

With this construction, the variable `SUPPORT_EMAIL` resolves to `'support@mywebsite.com'`. Note the use of the `${...}` syntax to trigger resolving the value of the variable `APP_URL` inside the definition of `SUPPORT_EMAIL`.

> **Hint** For this feature, `@nestjs/config` package internally uses [dotenv-expand](https://github.com/motdotla/dotenv-expand).

Enable environment variable expansion using the `expandVariables` property in the options object passed to the `forRoot()` method of the `ConfigModule`, as shown below:

app.module.ts

JS TS

```typescript

@Module({
  imports: [
    ConfigModule.forRoot({
      // ...
      expandVariables: true,
    }),
  ],
})
export class AppModule {}
```

#### Using in the `main.ts`[#](/techniques/configuration#using-in-the-maints)

While our config is a stored in a service, it can still be used in the `main.ts` file. This way, you can use it to store variables such as the application port or the CORS host.

To access it, you must use the `app.get()` method, followed by the service reference:

```typescript

const configService = app.get(ConfigService);
```

You can then use it as usual, by calling the `get` method with the configuration key:

```typescript

const port = configService.get('PORT');
```

----
url: https://docs.nestjs.com/v4/fundamentals/async-components
----

### Async Components

Sometimes the application start has to be delayed until some **asynchronous tasks** will be finished, for example until the connection with the database will be established. That's why Nest provides a way to create **async components**.

To create an async component, we're using the `useFactory`. The factory must return `Promise` or just be marked as an `async` function.

TypeScript

```typescript

{
  provide: 'AsyncDbConnection',
  useFactory: async () => {
    const connection = await createConnection(options);
    return connection;
  },
},
```

> **Hint** Read more about custom components [here](/v4/fundamentals/dependency-injection).

These asynchronous components might be simply injected to other components by the token (in this case, by `AsyncDbConnection` token). Each component, which depends on the async components will be instantiated when the async component would be **already resolved**.

The above example is for demonstration purposes. If you're looking for more detailed one, [see here](/v4/recipes/sql-typeorm).

#### Sponsors

[](https://valor-software.com/)

Nest is an MIT-licensed open source project. It can grow thanks to the support by these awesome people. If you'd like to join them, please read more [here](https://opencollective.com/nest). Thanks!

[](https://opencollective.com/nest/backer/0/website)[](https://opencollective.com/nest/backer/1/website)[](https://opencollective.com/nest/backer/2/website)[](https://opencollective.com/nest/backer/3/website)[](https://opencollective.com/nest/backer/4/website)[](https://opencollective.com/nest/backer/5/website)[](https://opencollective.com/nest/backer/6/website)[](https://opencollective.com/nest/backer/7/website)[](https://opencollective.com/nest/backer/8/website)[](https://opencollective.com/nest/backer/9/website)[](https://opencollective.com/nest/backer/10/website)[](https://opencollective.com/nest/backer/11/website)[](https://opencollective.com/nest/backer/12/website)[](https://opencollective.com/nest/backer/13/website)[](https://opencollective.com/nest/backer/14/website)[](https://opencollective.com/nest/backer/15/website)[](https://opencollective.com/nest/backer/16/website)[](https://opencollective.com/nest/backer/17/website)[](https://opencollective.com/nest/backer/18/website)[](https://opencollective.com/nest/backer/19/website)[](https://opencollective.com/nest/backer/20/website)[](https://opencollective.com/nest/backer/21/website)[](https://opencollective.com/nest/backer/22/website)[](https://opencollective.com/nest/backer/23/website)[](https://opencollective.com/nest/backer/24/website)[](https://opencollective.com/nest/backer/25/website)[](https://opencollective.com/nest/backer/26/website)[](https://opencollective.com/nest/backer/27/website)[](https://opencollective.com/nest/backer/28/website)[](https://opencollective.com/nest/backer/29/website)

[Become a sponsor](https://opencollective.com/nest)

----
url: https://docs.nestjs.com/v4/faq/multiple-servers
----

### HTTPS & Multiple Simultaneous Servers

Since you can have a full control of the `express` instance lifecycle, it's not a big deal to create a few multiple simultaneous servers (e.g. both HTTP & HTTPS).

TypeScript

```typescript

const httpsOptions = {
  key: fs.readFileSync("./secrets/private-key.pem"),
  cert: fs.readFileSync("./secrets/public-certificate.pem")
};

const server = express();
const app = await NestFactory.create(ApplicationModule, server);
await app.init();

http.createServer(server).listen(3000);
https.createServer(httpsOptions, server).listen(443);
```

#### Sponsors

[](https://valor-software.com/)

Nest is an MIT-licensed open source project. It can grow thanks to the support by these awesome people. If you'd like to join them, please read more [here](https://opencollective.com/nest). Thanks!

[](https://opencollective.com/nest/backer/0/website)[](https://opencollective.com/nest/backer/1/website)[](https://opencollective.com/nest/backer/2/website)[](https://opencollective.com/nest/backer/3/website)[](https://opencollective.com/nest/backer/4/website)[](https://opencollective.com/nest/backer/5/website)[](https://opencollective.com/nest/backer/6/website)[](https://opencollective.com/nest/backer/7/website)[](https://opencollective.com/nest/backer/8/website)[](https://opencollective.com/nest/backer/9/website)[](https://opencollective.com/nest/backer/10/website)[](https://opencollective.com/nest/backer/11/website)[](https://opencollective.com/nest/backer/12/website)[](https://opencollective.com/nest/backer/13/website)[](https://opencollective.com/nest/backer/14/website)[](https://opencollective.com/nest/backer/15/website)[](https://opencollective.com/nest/backer/16/website)[](https://opencollective.com/nest/backer/17/website)[](https://opencollective.com/nest/backer/18/website)[](https://opencollective.com/nest/backer/19/website)[](https://opencollective.com/nest/backer/20/website)[](https://opencollective.com/nest/backer/21/website)[](https://opencollective.com/nest/backer/22/website)[](https://opencollective.com/nest/backer/23/website)[](https://opencollective.com/nest/backer/24/website)[](https://opencollective.com/nest/backer/25/website)[](https://opencollective.com/nest/backer/26/website)[](https://opencollective.com/nest/backer/27/website)[](https://opencollective.com/nest/backer/28/website)[](https://opencollective.com/nest/backer/29/website)

[Become a sponsor](https://opencollective.com/nest)

----
url: https://docs.nestjs.com/v11/microservices/guards
----

* [Guards](https://docs.nestjs.com/v11/microservices/guards#guards)
* [Binding guards](https://docs.nestjs.com/v11/microservices/guards#binding-guards)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/microservices/guards.md "Suggest Edits")

### Guards

There is no fundamental difference between microservices guards and [regular HTTP application guards](/v11/guards). The only difference is that instead of throwing `HttpException`, you should use `RpcException`.

> **Hint** The `RpcException` class is exposed from `@nestjs/microservices` package.

#### Binding guards[#](/microservices/guards#binding-guards)

The following example uses a method-scoped guard. Just as with HTTP based applications, you can also use controller-scoped guards (i.e., prefix the controller class with a `@UseGuards()` decorator).

JS TS

```typescript

@UseGuards(AuthGuard)
@MessagePattern({ cmd: 'sum' })
accumulate(data: number[]): number {
  return (data || []).reduce((a, b) => a + b);
}
```

```typescript

@UseGuards(AuthGuard)
@MessagePattern({ cmd: 'sum' })
accumulate(data) {
  return (data || []).reduce((a, b) => a + b);
}
```

----
url: https://docs.nestjs.com/application/mail
----

[Skip to content](#content)

On this page

* [Mail](https://docs.nestjs.com/application/mail#mail)
* [Installation](https://docs.nestjs.com/application/mail#installation)
* [Register the mail module](https://docs.nestjs.com/application/mail#register-the-mail-module)
* [Write the order confirmation mail](https://docs.nestjs.com/application/mail#write-the-order-confirmation-mail)
* [Attach the invoice and preview the mail](https://docs.nestjs.com/application/mail#attach-the-invoice-and-preview-the-mail)
* [Send after the order commits](https://docs.nestjs.com/application/mail#send-after-the-order-commits)
* [Send in production](https://docs.nestjs.com/application/mail#send-in-production)
* [Send it in the customer's language](https://docs.nestjs.com/application/mail#send-it-in-the-customers-language)
* [Use another template engine](https://docs.nestjs.com/application/mail#use-another-template-engine)
* [Write your own transport](https://docs.nestjs.com/application/mail#write-your-own-transport)
* [Try it](https://docs.nestjs.com/application/mail#try-it)
* [Testing](https://docs.nestjs.com/application/mail#testing)
* [Production checklist](https://docs.nestjs.com/application/mail#production-checklist)
* [Reference](https://docs.nestjs.com/application/mail#reference)

### Mail

When a customer places an order at an online store for cat food and supplies, they expect a confirmation email within a minute: the items, the total, a link to the order, and the invoice as a PDF. Sending that email well takes more than a call to an SMTP library:

* **The HTML must be safe.** A product name or a customer name ends up in the markup. Unescaped, a name like `<script>` or a stray `&` breaks the layout, or worse.
* **The mail must survive failures.** Mail servers greylist, rate-limit and go down. A send that fails inside the request either fails an order that already committed, or loses the email.
* **Tests must see what was sent.** A test for "the customer gets a confirmation with a link to the order" needs the rendered mail and its links, not a mocked method call.

`@nestjs/mail` covers these. Mail classes are injectable providers that render a subject and a body from typed data, so they can inject your other providers, such as a repository or a PDF renderer. The body comes from an HTML template file, rendered by a small built-in engine that escapes every value it inserts, or by Handlebars or any other engine you plug in. Transports deliver the result: SMTP, written on `node:net` and `node:tls`, and Resend, Postmark, SendGrid and Amazon SES over their HTTP APIs. Tests swap the transport for an in-memory one and read the mails it received. The package has no dependencies beyond Nest itself.

In this tutorial, you'll add order confirmation emails to the store's order API:

* Development writes every mail to an `.eml` file instead of sending it.
* The confirmation is a mail class that renders an HTML template, in a layout that every mail shares, with the invoice attached and the logo inline.
* A preview route shows the mail in a browser without sending it.
* Mail goes out after the order commits, through the outbox, with retries and dead letters.
* Production sends through SMTP or Resend, picked by an environment variable.

#### Installation[#](/application/mail#installation)

To get started, install the required dependency:

```bash

$ npm i --save @nestjs/mail
```

#### Register the mail module[#](/application/mail#register-the-mail-module)

Register `MailModule` in the root module, next to `DrizzleModule`. The mail tutorial needs the database for the customers and their orders, and for the outbox's tables, through which the mail is [sent after the order commits](/application/mail#send-after-the-order-commits). In development, `FileMailTransport` writes each mail to a file in `var/mail` instead of sending it, and `FileTemplateEngine` renders the mail bodies from HTML files in `mail/templates`. The feature modules it imports are built in the following sections:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { DrizzleModule } from '@nestjs/drizzle';
import { FileMailTransport, FileTemplateEngine, MailModule } from '@nestjs/mail';
import { drizzle } from 'drizzle-orm/node-postgres';
import { join } from 'node:path';
import * as schema from './database/schema.js';
import { NotificationsModule } from './notifications/notifications.module.js';
import { OrdersModule } from './orders/orders.module.js';

@Module({
  imports: [
    DrizzleModule.forRootAsync({
      // A pg pool on DATABASE_URL: the customers and orders, and the outbox's tables
      useFactory: () => ({ drizzle, connection: process.env.DATABASE_URL!, schema }),
    }),
    MailModule.forRoot({
      // Development: every mail becomes an .eml file in var/mail instead of leaving the machine
      transport: new FileMailTransport({ directory: 'var/mail' }),
      // Mail bodies are HTML files in mail/templates, wrapped in mail/templates/layout.html
      templates: new FileTemplateEngine({
        dir: join(import.meta.dirname, 'mail/templates'),
        layout: 'layout',
        // Development reads the files for every mail, so edits show up without a restart
        cache: process.env.NODE_ENV === 'production',
      }),
      from: 'Orders <orders@example.com>',
    }),
    OrdersModule,
    NotificationsModule,
  ],
})
export class AppModule {}
```

* `transport`: how mail leaves the application. Every transport extends the abstract `MailTransport` class, which is also its injection token, so tests replace it with `overrideProvider(MailTransport)`. `FileMailTransport` is for development: open the `.eml` files in any mail client to see exactly what would be sent. It writes to the local disk and reaches nobody, so [in production](/application/mail#send-in-production) the application switches to SMTP or Resend.
* `templates`: renders the mails that name a template. `FileTemplateEngine` reads `.html` files from `dir`, and wraps every mail in the `layout` template, `mail/templates/layout.html`. A relative `dir` is resolved against the working directory; built from `import.meta.dirname`, it points next to the compiled `app.module.js`, wherever the application is started. Compiled templates are cached. With `cache` off, as here outside production, every mail reads the files again, so an edited template shows up in the next mail without a restart.
* `from`: the default sender. A message can override it.

The TypeScript compiler doesn't copy HTML files to `dist`. Add the templates to the [assets](/cli/monorepo#assets) in `nest-cli.json`, so they land in `dist/mail/templates`, next to the compiled `app.module.js`:

```json

{
  "compilerOptions": {
    "assets": ["mail/templates/**/*"],
    "watchAssets": true
  }
}
```

With `watchAssets`, `nest start --watch` copies a template to `dist` whenever you save it.

> **Hint** The tutorial reads `process.env` directly, to stay short. In an application, load the environment through [`@nestjs/config`](/application/configuration) with a validation schema, so a missing `DATABASE_URL` or `SMTP_URL` stops the application at startup, and read the values from `ConfigService` in the factories.

`MailModule` is global and provides `Mailer`, which sends mail, and `MailEvents`, which reports what was sent and what failed. A missing `transport` or an invalid `from` stops the application at startup, with a message that names the option.

#### Write the order confirmation mail[#](/application/mail#write-the-order-confirmation-mail)

The mail's body is an HTML template. Values go between double braces, and a block such as `#each` repeats its part of the template for every item of a list:

mail/templates/order-confirmation.html

JS TS

```html

<p>Hi {{ customer.name }},</p>
<p>thank you for your order! We are packing it now.</p>
<table>
  <tr><th>Product</th><th>Qty</th><th>Price</th></tr>
  {{#each items}}
  <tr>
    <td>{{ name }}</td>
    <td>{{ quantity }}</td>
    <td>{{ price }}</td>
  </tr>
  {{/each}}
</table>
<p><strong>Total: {{ total }}</strong></p>
<p><a href="{{ orderUrl }}">View your order</a></p>
```

Every mail is wrapped in the layout. It places the rendered mail with triple braces around `body`, and includes the signature, a partial that lives in `mail/templates/partials/signature.html`:

mail/templates/layout.html

JS TS

```html

<!DOCTYPE html>
<html>
<body>
{{{ body }}}
{{> signature}}
</body>
</html>
```

mail/templates/partials/signature.html

JS TS

```html

<p>The customer care team</p>
```

A mail class implements `Mailable<TData>`. Its `render()` method gets the data and returns the subject, the template's name and its context, the values the template reads:

notifications/order-confirmation.mail.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import type { Mailable } from '@nestjs/mail';
import type { Customer } from '../customers/customers.repository.js';
import type { Order } from '../orders/order.js';

export interface OrderConfirmation {
  order: Order;
  customer: Customer;
}

const SHOP_URL = process.env.SHOP_URL ?? 'https://shop.example.com';

@Injectable()
export class OrderConfirmationMail implements Mailable<OrderConfirmation> {
  render({ order, customer }: OrderConfirmation) {
    const price = (cents: number) => `$${(cents / 100).toFixed(2)}`;
    return {
      subject: `Your order #${order.number}`,
      // mail/templates/order-confirmation.html, wrapped in the layout
      template: 'order-confirmation',
      // The values the template shows, ready to insert: prices formatted, the link built
      context: {
        customer,
        items: order.items.map((item) => ({
          name: item.name,
          quantity: item.quantity,
          price: price(item.price * item.quantity),
        })),
        total: price(order.total),
        orderUrl: `${SHOP_URL}/orders/${order.id}`,
      },
    };
  }
}
```

The template is logic-less. It has values, `#if`, `#unless` and `#each` blocks, partials and comments, but no helpers and no expressions: what needs code, such as formatting a price or building a link, happens in the mail class, in TypeScript, where it's typed and tested. The syntax is a subset of Handlebars (see [Template syntax](/application/mail#template-syntax)), so the templates move to [another engine](/application/mail#use-another-template-engine) as they are.

Double braces escape the value. A product named `Feather wand toy <limited edition>` becomes `Feather wand toy &lt;limited edition&gt;`, and the customer's name can't inject markup. Two rules make it hard to get wrong:

* Escaping protects element content and quoted attribute values, so those are the only places a double-braced value may go. A value inside a tag anywhere else is a compile error: `href=` followed directly by the value, or a value standing between attributes. Escaping can't protect either place (unquoted, a space in the value would start a new attribute). Quote attribute values, as the link above does.
* Triple braces insert a value as it is, for HTML you produced yourself. In this tutorial, only the layout's `body` needs them.

A missing value renders as nothing, as in Handlebars. Inside `#each`, `this` is the item, `@index`, `@first` and `@last` describe its position, and a name the item doesn't have is looked up in the template's context, so a row can show a value from outside the list. A template that doesn't compile fails the mail with a permanent `MailTemplateError`, which names the file and the position:

```text

order-confirmation.html:5:3: {{#each items}} is never closed (expected {{/each}})
```

There is no text template. The mailer derives the plain-text part from the HTML: paragraphs, table rows, and links as `View your order (https://shop.example.com/orders/…)`. Mail clients that don't show HTML, and spam filters, read that part. To write it yourself, add `order-confirmation.txt` next to the HTML: the engine renders it as the text part, with the same syntax, without escaping.

Register the class as a provider, like any other injectable:

notifications/notifications.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { OrderConfirmationMail } from './order-confirmation.mail.js';

@Module({
  providers: [OrderConfirmationMail],
})
export class NotificationsModule {}
```

Then send it when an order is placed. `mailer.send()` takes the mail class and the recipient, and the type of `data` comes from the class's `render()`:

orders/orders.service.ts

JS TS

```typescript

async placeOrder({ customerId, items }: PlaceOrderDto): Promise<Order> {
  const customer = await this.customersRepository.findById(customerId);
  if (!customer) {
    throw new BadRequestException(`Unknown customer "${customerId}"`);
  }
  if (!items?.length) {
    throw new BadRequestException('An order needs at least one item');
  }

  const order = await this.db.transaction((tx) => this.insertOrder(tx, customerId, items));

  // After the commit: never inside the transaction, which would stay open, holding its
  // connection and locks, for as long as the mail server takes to answer
  await this.mailer.send(OrderConfirmationMail, {
    to: { name: customer.name, address: customer.email },
    data: { order, customer },
  });
  return order;
}
```

The recipient is an object with a `name` and an `address`, so a name with a comma or quotes stays one display name. A string works too, as in `'Ada Lovelace <ada@example.com>'`, but a string must hold exactly one address: a comma-separated list throws, so a name typed by a user can never add a recipient. Lists of recipients are arrays.

Place an order and a file appears in `var/mail`. This works, but it sends the mail from the request, after the commit. [Send after the order commits](/application/mail#send-after-the-order-commits) explains why that isn't good enough, and fixes it.

**Mails written inline.** A mail small enough to write in TypeScript doesn't need a template file. `render()` returns `html` in place of `template` and `context`, built with the `html` tagged template:

notifications/order-confirmation.mail.ts

JS TS

```typescript

return {
  subject: `Your order #${order.number}`,
  html: html`
    <p>Hi ${customer.name},</p>
    <p>thank you for your order! We are packing it now.</p>
    <table>
      ${order.items.map(
        (item) => html`
          <tr>
            <td>${item.name}</td>
            <td>${item.quantity}</td>
            <td>${price(item.price * item.quantity)}</td>
          </tr>`,
      )}
    </table>
    // ...
};
```

`html` escapes every value you interpolate, by the same rules as a template: a value inside a tag must be in a quoted attribute value, or it throws. Nested `html` templates and arrays of them, like the table rows, are inserted as they are, and `unsafeHtml()` inserts HTML you produced yourself; the name is the warning. `mailer.send()` takes `html` too, for a message sent without a mail class.

#### Attach the invoice and preview the mail[#](/application/mail#attach-the-invoice-and-preview-the-mail)

The invoice is a PDF, rendered by a small provider. It writes the PDF by hand with a built-in font, to keep the example free of dependencies. A real application uses a PDF library or a rendering service here. The mail only needs the bytes:

notifications/invoice-pdf.ts

JS TS

```typescript

@Injectable()
export class InvoicePdf {
  render(order: Order, customer: Customer): Buffer {
    const money = (cents: number) => `$${(cents / 100).toFixed(2)}`;
    const lines = [
      `Invoice ${order.number}`,
      `Date: ${order.placedAt.slice(0, 10)}`,
      `Bill to: ${customer.name}`,
      '',
      ...order.items.map((item) => `${item.quantity} x ${item.name}  ${money(item.price * item.quantity)}`),
      '',
      `Total: ${money(order.total)}`,
    ];
    // ...
  }
}
```

`render()` returns attachments along with the template. The invoice is a regular attachment. The logo is an inline image: its `cid` makes it part of the HTML, which references it as `cid:logo@example.com`. The logo heads every mail, so the reference goes in the layout:

mail/templates/layout.html

JS TS

```html

<!DOCTYPE html>
<html>
<body>
<p><img src="cid:logo@example.com" alt="Logo" width="120" height="32"></p>
{{{ body }}}
{{> signature}}
</body>
</html>
```

The mail class attaches the logo and the invoice:

notifications/order-confirmation.mail.ts

JS TS

```typescript

const LOGO = join(import.meta.dirname, 'assets/logo.png');

@Injectable()
export class OrderConfirmationMail implements Mailable<OrderConfirmation> {
  constructor(private readonly invoicePdf: InvoicePdf) {}

  render({ order, customer }: OrderConfirmation) {
    // ...
    return {
      subject: `Your order #${order.number}`,
      // mail/templates/order-confirmation.html, wrapped in the layout
      template: 'order-confirmation',
      // ...
      attachments: [
        // Inline: the layout's <img> references it by its cid
        { cid: 'logo@example.com', path: LOGO },
        { filename: `invoice-${order.number}.pdf`, content: this.invoicePdf.render(order, customer) },
      ],
    };
  }
}
```

Every mail rendered in this layout attaches the logo the same way, or its header shows a broken image. The template gets one more line after the link, `<p>Your invoice is attached.</p>`.

An attachment's content is a `Buffer`, a string, or a stream, or it's read from a local `path` when the mail is sent. The content type comes from the file name, and a non-ASCII file name is encoded so that every mail client shows it. The mailer arranges the parts the way mail clients expect: the logo sits next to the HTML, so a client that shows the text version doesn't list it as an attachment.

> **Warning** Never build an attachment `path` from user input. The file at that path is attached, whatever it is. URLs are refused, not fetched.

While you work on the template, you don't want to place an order for every change. `mailer.render()` renders a mail class without sending it. A development-only route shows the result in the browser. With the template cache off, it shows an edited template on the next refresh:

notifications/mail-preview\.controller.ts

JS TS

```typescript

import { Controller, Get, Header } from '@nestjs/common';
import { Mailer } from '@nestjs/mail';
import { OrderConfirmationMail, type OrderConfirmation } from './order-confirmation.mail.js';

const SAMPLE: OrderConfirmation = {
  customer: {
    id: 'sample',
    name: 'Ada Lovelace',
    email: 'ada@example.com',
    // ...
  },
  order: {
    id: '00000000-0000-4000-8000-000000000000',
    number: 1001,
    customerId: 'sample',
    items: [
      { productId: 'salmon-kibble-2kg', name: 'Salmon kibble, 2 kg', quantity: 2, price: 2499 },
      { productId: 'feather-wand', name: 'Feather wand toy', quantity: 1, price: 799 },
    ],
    total: 5797,
    placedAt: '2026-09-22T10:00:00.000Z',
  },
};

@Controller('dev/mail')
export class MailPreviewController {
  constructor(private readonly mailer: Mailer) {}

  /** Renders the mail with sample data, without sending it: GET /dev/mail/order-confirmation */
  @Get('order-confirmation')
  @Header('content-type', 'text/html; charset=utf-8')
  async orderConfirmation() {
    const message = await this.mailer.render(OrderConfirmationMail, { data: SAMPLE });

    // Browsers don't resolve cid: references; inline the images as data: URLs instead
    let body = message.html ?? '';
    for (const { cid, contentType, content } of message.attachments) {
      if (cid) {
        body = body.replaceAll(`cid:${cid}`, `data:${contentType};base64,${content.toString('base64')}`);
      }
    }
    return body;
  }
}
```

`render()` returns the finished `MailMessage`: the subject, the HTML and the derived text, the attachments, and `toMime()` for the raw message. Recipients are optional here. `render()` also takes a message written inline, such as a subject, a `template` and its `context`, to preview a template without a mail class. Register the controller only outside production:

notifications/notifications.module.ts

JS TS

```typescript

@Module({
  // The preview route renders mail with sample data; production doesn't need it
  controllers: process.env.NODE_ENV === 'production' ? [] : [MailPreviewController],
  providers: [OrderConfirmationMail, InvoicePdf],
})
export class NotificationsModule {}
```

#### Send after the order commits[#](/application/mail#send-after-the-order-commits)

[Write the order confirmation mail](/application/mail#write-the-order-confirmation-mail) sends the mail from the request, after the order commits. Three things go wrong there:

* **A crash between the commit and the send loses the mail.** A deploy that restarts the process at the wrong moment leaves a paid order without a confirmation.
* **A mail server outage fails a request that already succeeded.** The order is saved, but the customer sees a 500 and may order again.
* **The customer waits for the mail server.** An SMTP exchange takes hundreds of milliseconds, and a slow server takes the request's time with it.

This is the dual-write problem from the [outbox tutorial](/reliability/outbox), and the outbox (`@nestjs/outbox`, installed and set up in that tutorial) fixes it. The order and an `order.placed` message commit in one transaction, and a relay hands the message to a handler that sends the mail. If the send fails, the relay retries it with backoff, and it moves messages that never succeed to the dead-letter table. The outbox keeps its messages in the application's PostgreSQL database, next to the orders, through its store, `PostgresOutboxStore` from `@nestjs/outbox/postgres`, on the database that [`@nestjs/drizzle`](/data/drizzle) registers. The store creates its tables, in a schema of their own, when the application starts; [Keep messages in your database](/reliability/outbox#keep-messages-in-your-database) in the outbox tutorial covers them, and how to apply their migrations in production.

This section shows the order transaction twice: first with Drizzle, which is the tutorial's path, and then, under "With TypeORM" at the end of the section, the same transaction for an application whose ORM is TypeORM. Take one of the two.

Register `OutboxModule`, and the store as a provider of the root module: a factory that injects the Drizzle database and the `OutboxStorage` registry, which the store registers itself with. Without it, the outbox would keep its messages in memory, and lose them on restart:

app.module.ts

JS TS

```typescript

@Module({
  imports: [
    // ...
    OutboxModule.forRootAsync({
      useFactory: () => ({
        relay: { enabled: process.env.OUTBOX_RELAY !== 'off' },
        // A mail server that is down for a while doesn't lose the confirmation
        retry: { attempts: 10, backoff: { delay: '10s', maxDelay: '10m' } },
      }),
    }),
    // ...
  ],
  providers: [
    {
      // Messages and inbox records in your database, in a schema of their own (nest_outbox)
      provide: PostgresOutboxStore,
      inject: [getDrizzleToken(), OutboxStorage],
      useFactory: (db: Database, outboxStorage: OutboxStorage) =>
        new PostgresOutboxStore({ executor: fromDrizzle(db) }, outboxStorage),
    },
  ],
})
export class AppModule {}
```

`OrdersService` adds the message instead of sending the mail, with Drizzle's `tx`, so the message commits or rolls back with the order:

orders/orders.service.ts

JS TS

```typescript

async placeOrder({ customerId, items }: PlaceOrderDto): Promise<Order> {
  if (!(await this.customersRepository.findById(customerId))) {
    throw new BadRequestException(`Unknown customer "${customerId}"`);
  }
  if (!items?.length) {
    throw new BadRequestException('An order needs at least one item');
  }

  const order = await this.db.transaction(async (tx) => {
    const order = await this.insertOrder(tx, customerId, items);
    // Same transaction: the confirmation mail is queued only if the order commits
    await this.outbox.add(tx, { topic: 'order.placed', payload: order });
    return order;
  });

  this.outbox.notify(); // send now instead of at the next poll
  return order;
}
```

The handler sends the mail:

notifications/order-mails.handler.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { MailError, Mailer } from '@nestjs/mail';
import { NonRetryableMessageError, OnOutboxMessage, type OutboxHandlerContext } from '@nestjs/outbox';
import { CustomersRepository } from '../customers/customers.repository.js';
import type { Order } from '../orders/order.js';
import { OrderConfirmationMail } from './order-confirmation.mail.js';

@Injectable()
export class OrderMailsHandler {
  constructor(
    private readonly mailer: Mailer,
    private readonly customersRepository: CustomersRepository,
  ) {}

  // Runs after the order committed. The inbox skips messages this consumer already handled.
  @OnOutboxMessage('order.placed', { consumer: 'order-confirmation-mail' })
  async sendConfirmation(order: Order, { message, signal }: OutboxHandlerContext) {
    const customer = await this.customersRepository.findById(order.customerId);
    if (!customer) {
      throw new NonRetryableMessageError(`Customer ${order.customerId} not found`);
    }

    try {
      await this.mailer.send(OrderConfirmationMail, {
        to: { name: customer.name, address: customer.email },
        data: { order, customer },
        // Over SMTP, a redelivery of this message keeps its Message-ID; Resend gets the
        // key as its Idempotency-Key and refuses the duplicate
        idempotencyKey: message.id,
        signal,
        // The outbox retries with its own backoff, and dead-letters what never succeeds
        retry: false,
      });
    } catch (error) {
      // A refused address or sender won't be accepted later: dead-letter it now
      if (error instanceof MailError && error.permanent) {
        throw new NonRetryableMessageError(error.message, { cause: error });
      }
      throw error;
    }
  }
}
```

Register the handler in `NotificationsModule`, which imports `CustomersModule` for the repository:

notifications/notifications.module.ts

JS TS

```typescript

@Module({
  imports: [CustomersModule],
  // The preview route renders mail with sample data; production doesn't need it
  controllers: process.env.NODE_ENV === 'production' ? [] : [MailPreviewController],
  providers: [OrderConfirmationMail, InvoicePdf, OrderMailsHandler],
})
export class NotificationsModule {}
```

Each option of the `send()` call has a job:

* **`idempotencyKey`.** The outbox delivers at least once: a relay that crashes after sending, before recording it, sends again. The key identifies the mail across those deliveries. The `Message-ID` header is derived from it, so over SMTP a duplicate carries the same id, which Gmail and other receivers use to drop it. `ResendTransport` sends the key as Resend's `Idempotency-Key`, and Resend refuses the duplicate for 24 hours. Postmark, SendGrid and SES assign their own `Message-ID` and have no idempotency keys, so with them a redelivery can reach the customer twice.
* **`signal`.** The relay aborts it when the handler outlives `publishTimeout`. The mailer stops the SMTP exchange or the HTTP request.
* **`retry: false`.** The mailer retries transient failures three times by default, with backoff. Here the outbox already retries, over minutes instead of seconds, so the mailer makes one attempt per delivery. Retries at both layers would multiply.

Every error the package throws extends `MailError`, and its `permanent` flag says whether sending the same message again can succeed. A 4xx SMTP reply (greylisting, a full mailbox), a 429 from an HTTP provider, a timeout or a dropped connection is transient: the handler rethrows it, and the outbox retries. A 5xx reply, such as `550 5.1.1 User unknown`, is permanent: the handler throws `NonRetryableMessageError`, and the outbox dead-letters the message at once instead of trying ten more times.

When SMTP refuses one of several recipients, the transaction is reset before the message is sent, so an error always means nobody received it, and the outbox's retry can't deliver twice. The one exception: the connection drops after the message was transmitted, before the server answers. The mailer can't know whether the server kept it, reports a transient error, and the retry sends it again, with the same `Message-ID`.

**With TypeORM.** The same order transaction for an application whose ORM is TypeORM. Drizzle stays the tutorial's path: take this code instead of the Drizzle code above, not next to it. The outbox keeps its messages through the same store, on TypeORM's data source, as the outbox tutorial's [Keep messages in your database](/reliability/outbox#keep-messages-in-your-database) shows. The example application keeps this version in `src/typeorm`, next to the tutorial's Drizzle code, with the customers, products and orders as entities.

`TypeOrmModule` takes the place of `DrizzleModule` in the root module, with the options the TypeORM CLI shares, and the store's factory injects its `DataSource`, through `fromTypeOrm()`:

typeorm/app.module.ts

JS TS

```typescript

@Module({
  imports: [
    TypeOrmModule.forRootAsync({
      // The entities and migrations the CLI uses; migrations run on deploy (`migration:run`)
      useFactory: () => ({ ...dataSourceOptions, url: process.env.DATABASE_URL }),
    }),
    // ...
    OutboxModule.forRootAsync({
      useFactory: () => ({
        relay: { enabled: process.env.OUTBOX_RELAY !== 'off' },
        // A mail server that is down for a while doesn't lose the confirmation
        retry: { attempts: 10, backoff: { delay: '10s', maxDelay: '10m' } },
      }),
    }),
    // ...
  ],
  providers: [
    {
      // Messages and inbox records in your database, in a schema of their own (nest_outbox)
      provide: PostgresOutboxStore,
      inject: [DataSource, OutboxStorage],
      useFactory: (dataSource: DataSource, outboxStorage: OutboxStorage) =>
        new PostgresOutboxStore({ executor: fromTypeOrm(dataSource) }, outboxStorage),
    },
  ],
})
export class AppModule {}
```

`OrdersService` opens its transaction with the data source, and passes the transaction's entity manager to `outbox.add()`, next to its own writes. The outbox's type parameter is TypeORM's `EntityManager`:

typeorm/orders.service.ts

JS TS

```typescript

@Injectable()
export class OrdersService {
  constructor(
    private readonly dataSource: DataSource,
    private readonly customersRepository: CustomersRepository,
    private readonly outbox: Outbox<EntityManager>,
  ) {}

  async placeOrder({ customerId, items }: PlaceOrderDto): Promise<Order> {
    // ... check the customer and the items, as in the Drizzle version

    const order = await this.dataSource.transaction(async (manager) => {
      const order = await this.insertOrder(manager, customerId, items);
      // The transaction's EntityManager: the confirmation mail is queued only if the order commits
      await this.outbox.add(manager, { topic: 'order.placed', payload: order });
      return order;
    });

    this.outbox.notify(); // send now instead of at the next poll
    return order;
  }

  private async insertOrder(manager: EntityManager, customerId: string, items: PlaceOrderDto['items']): Promise<Order> {
    const found = await manager.findBy(ProductEntity, { id: In(items.map((item) => item.productId)) });
    // ... price the lines and total them, as in the Drizzle version
    // The database numbers the order from its sequence: 1001, 1002, ...
    const { generatedMaps } = await manager.insert(OrderEntity, { id, customerId, items: lines, total, placedAt });
    const { number } = generatedMaps[0] as Pick<OrderEntity, 'number'>;
    return { id, number, customerId, items: lines, total, placedAt: placedAt.toISOString() };
  }
}
```

`OrderEntity` declares `number` as an identity column (`generated: 'identity'`), so `manager.insert()` returns the number the database assigned in `generatedMaps`. An entity can't state where the sequence starts, so the example's seed migration restarts it at 1001, next to the customers and products it inserts. The handler and `NotificationsModule` stay as they are; `CustomersRepository` reads the customer with TypeORM, like the rest of the application.

#### Send in production[#](/application/mail#send-in-production)

Development writes files, to a local disk that a container loses when it's replaced; production needs a real transport. Pick it from the environment, so the same build runs everywhere:

mail-transport.ts

JS TS

```typescript

import { FileMailTransport, ResendTransport, SmtpTransport, type MailTransport } from '@nestjs/mail';
import { readFileSync } from 'node:fs';

/**
 * The transport for this environment: `file` in development (the default), `smtp` or
 * `resend` in production. Missing settings fail at startup, naming the variable.
 */
export function mailTransport(env: NodeJS.ProcessEnv = process.env): MailTransport {
  switch (env.MAIL_TRANSPORT ?? 'file') {
    case 'file':
      return new FileMailTransport({ directory: env.MAIL_DIRECTORY ?? 'var/mail' });
    case 'smtp':
      return new SmtpTransport({
        url: required(env, 'SMTP_URL'), // smtp://user:password@smtp.example.com:587
        pool: true,
        // A private CA, e.g. for a relay inside the company network
        ...(env.SMTP_CA_FILE && { tls: { ca: readFileSync(env.SMTP_CA_FILE) } }),
      });
    case 'resend':
      return new ResendTransport({ apiKey: required(env, 'RESEND_API_KEY') });
    default:
      throw new Error(`MAIL_TRANSPORT must be "file", "smtp" or "resend" (got "${env.MAIL_TRANSPORT}")`);
  }
}

function required(env: NodeJS.ProcessEnv, name: string): string {
  const value = env[name];
  if (!value) {
    throw new Error(`${name} is required when MAIL_TRANSPORT is "${env.MAIL_TRANSPORT}"`);
  }
  return value;
}
```

Build the transport in `forRootAsync()`. The factory runs at startup, so a typo in `MAIL_TRANSPORT` or a missing `SMTP_URL` stops the application there instead of failing the first mail:

app.module.ts

JS TS

```typescript

MailModule.forRootAsync({
  // Runs at startup: a bad MAIL_TRANSPORT or a missing SMTP_URL stops the app there
  useFactory: () => ({
    transport: mailTransport(),
    templates: new FileTemplateEngine({
      dir: join(import.meta.dirname, 'mail/templates'),
      layout: 'layout',
      cache: process.env.NODE_ENV === 'production',
    }),
    from: process.env.MAIL_FROM ?? 'Orders <orders@example.com>',
  }),
}),
```

**SMTP.**`SmtpTransport` speaks SMTP itself, on `node:net` and `node:tls`:

* **Encryption.** On port 587 it upgrades with STARTTLS, and a server that doesn't offer STARTTLS is refused rather than sent to in plaintext. `startTls: 'opportunistic'`, the default for localhost, upgrades only when the server offers it, and `'never'` stays in plaintext, for a relay on a trusted network. On port 465 (`smtps://`) it uses TLS from the first byte. Certificates are verified against the host name; `tls.ca` adds a private CA. Credentials are never sent over an unencrypted connection, except to localhost.
* **Authentication.** It uses AUTH PLAIN or LOGIN, whichever the server offers, and `authMethod` forces one. For Gmail and Microsoft 365, pass an OAuth access token as `accessToken` in `auth` for XOAUTH2. OAuth access tokens expire, typically after an hour, so `accessToken` can also be a function that returns one, or a promise of one: it's called for every new connection, and can fetch a fresh token. `name` sets the name the transport introduces itself with in `EHLO`; the default is the machine's host name when it's fully qualified, else its IP address.
* **Pooling.**`pool: true` keeps up to five connections open and reuses them, instead of a TCP and TLS handshake per mail. An object sets the limits: `maxConnections` (default 5; further sends wait for a free connection), `maxMessages` (default 100, after which a connection is replaced) and `idleTimeout` (default `'30s'`, after which an idle connection is closed). Every connection says `QUIT` when the application shuts down.
* **Replies.** A 4xx reply is a transient `MailSmtpError`, a 5xx reply a permanent one. Both carry the reply `code`, the enhanced code (such as `5.1.1`) and the server's text.

To sign mail with DKIM when your SMTP server doesn't, add `dkim` with the domain (`domainName`), the selector (`keySelector`) and the private key (`privateKey`, PEM or a `KeyObject`). An RSA key signs with `rsa-sha256`, an Ed25519 key with `ed25519-sha256` (RFC 8463); not every receiver verifies Ed25519 signatures yet, and the transport signs with one key, so RSA is the safe choice unless you know your recipients' servers do. The signature covers From, Reply-To, To, Cc, Subject, Date, Message-ID and the MIME headers, plus the message's custom headers; `dkim.headers` replaces that list. From is always signed, and listed once more than it occurs in the message, so a second From added below the signature breaks it. HTTP providers sign with your verified domain themselves.

**HTTP providers.**`ResendTransport`, `PostmarkTransport`, `SendGridTransport` and `SesTransport` call the providers' APIs with `fetch`, and need no SDK. The `fetch` option replaces the global one, to go through a proxy or to stub the API in a test. `SesTransport` signs its requests with AWS Signature Version 4, and accepts the AWS SDK's credential providers, such as instance roles, as `credentials`. Of the four, only Resend supports idempotency keys. Resend and SendGrid need at least one `to` recipient: a mail with only `cc` or `bcc` fails with `MailMessageError` before the request.

**Internationalized addresses.** A domain with non-ASCII characters (`zoë@kočka.example`) is converted to its ASCII form (IDNA, `xn--...`) for every transport, so no server has to support it. A non-ASCII local part, before the `@`, can't be converted: over SMTP it needs the server's SMTPUTF8 extension. `SmtpTransport` uses SMTPUTF8 when the server offers it, and otherwise fails with a permanent `MailConnectionError` before sending anything: `The SMTP server ... doesn't support SMTPUTF8, which an address with non-ASCII characters needs`. The HTTP providers get the address as it is, and whether they accept it is up to the provider.

Use `app.enableShutdownHooks()` in `main.ts`, so a deploy lets the relay finish the mails it is sending, and closes the SMTP pool afterwards.

#### Send it in the customer's language[#](/application/mail#send-it-in-the-customers-language)

The store sells in English and Polish. Customers choose a language when they sign up, and the `customers` table stores it in a `locale` column: `en` or `pl`. The mailer hands the locale of each send to the template engine, which picks the template for it.

Translate the template: add `order-confirmation.pl.html` next to the English one.

mail/templates/order-confirmation.pl.html

JS TS

```html

<p>Cześć {{ customer.name }},</p>
<p>dziękujemy za zamówienie! Właśnie je pakujemy.</p>
<table>
  <tr><th>Produkt</th><th>Ilość</th><th>Cena</th></tr>
  {{#each items}}
  <tr>
    <td>{{ name }}</td>
    <td>{{ quantity }}</td>
    <td>{{ price }}</td>
  </tr>
  {{/each}}
</table>
<p><strong>Razem: {{ total }}</strong></p>
<p><a href="{{ orderUrl }}">Zobacz zamówienie</a></p>
<p>Fakturę znajdziesz w załączniku.</p>
```

For the locale `pl`, `FileTemplateEngine` renders `order-confirmation.pl.html`, and for any other locale, or none, `order-confirmation.html`. A regional locale tries itself first, then its language: for `pt-BR`, the engine looks for `order-confirmation.pt-BR.html`, then `order-confirmation.pt.html`. Partials and the layout are looked up the same way, so the layout stays shared, and the Polish signature is a partial of its own:

mail/templates/partials/signature.pl.html

JS TS

```html

<p>Zespół obsługi klienta</p>
```

A mail's copy is prose, so it's translated a file at a time: the translator sees the whole mail, and writes Polish sentences instead of filling in keys one by one. What the mail class computes still depends on the locale: the subject, the invoice's file name and the prices. They come from `@nestjs/i18n`, which the [internationalization chapter](/application/i18n) covers in depth. Add a catalog for the mail, one per language:

i18n/en/mail.json

JS TS

```json

{
  "orderConfirmation": {
    "subject": "Your order #{number}",
    "invoiceFile": "invoice-{number}.pdf"
  }
}
```

i18n/pl/mail.json

JS TS

```json

{
  "orderConfirmation": {
    "subject": "Twoje zamówienie #{number}",
    "invoiceFile": "faktura-{number}.pdf"
  }
}
```

Register the catalogs' shape, so keys are checked at compile time, and register `I18nModule` next to `MailModule`:

i18n/translations.ts

JS TS

```typescript

import type mail from './en/mail.json';

export interface Translations {
  mail: typeof mail;
}

declare module '@nestjs/i18n' {
  interface I18nTypes {
    translations: Translations;
  }
}
```

app.module.ts

JS TS

```typescript

@Module({
  imports: [
    // ...
    I18nModule.forRoot({
      defaultLocale: 'en',
      supportedLocales: ['en', 'pl'],
      loader: new JsonI18nLoader({ path: join(import.meta.dirname, 'i18n') }),
    }),
    MailModule.forRootAsync({
      // ...
    }),
    // ...
  ],
})
export class AppModule {}
```

Add the catalogs to the assets in `nest-cli.json` too (`i18n/**/*.json`), as the internationalization chapter shows.

The mail class is a provider, so it injects `I18nService` next to the invoice renderer. `render()` gets a second argument, the render context, whose `locale` is the one passed to `send()`, and the one the mailer hands to the template engine. Its `to` holds the parsed recipients, and is empty for a preview rendered without them:

notifications/order-confirmation.mail.ts

JS TS

```typescript

type Key = keyof Translations['mail']['orderConfirmation'];

const SHOP_URL = process.env.SHOP_URL ?? 'https://shop.example.com';
const LOGO = join(import.meta.dirname, 'assets/logo.png');

@Injectable()
export class OrderConfirmationMail implements Mailable<OrderConfirmation> {
  constructor(
    private readonly i18nService: I18nService,
    private readonly invoicePdf: InvoicePdf,
  ) {}

  render({ order, customer }: OrderConfirmation, { locale }: MailRenderContext) {
    // Mail is sent outside the customer's request, so the locale is always passed explicitly
    const t = (key: Key, args?: Record<string, unknown>) =>
      this.i18nService.t(`mail.orderConfirmation.${key}`, { locale, args });
    const price = (cents: number) =>
      this.i18nService.formatNumber(cents / 100, { locale, style: 'currency', currency: 'USD' });
    return {
      subject: t('subject', { number: order.number }),
      // order-confirmation.pl.html for Polish, else order-confirmation.html
      template: 'order-confirmation',
      // ...
      attachments: [
        // Inline: the layout's <img> references it by its cid
        { cid: 'logo@example.com', path: LOGO },
        { filename: t('invoiceFile', { number: order.number }), content: this.invoicePdf.render(order, customer) },
      ],
    };
  }
}
```

The context doesn't change: the same values fill either template. `Key` is `keyof Translations['mail']['orderConfirmation']`, so a misspelled key is a compile error. Prices are formatted for the locale: `$25.98` in English, `25,98 USD` in Polish. The invoice's file name comes from the catalog: `invoice-1001.pdf` or `faktura-1001.pdf`.

> **Warning** Pass the locale explicitly. `I18nService` falls back to the current request's locale, and mail is often sent outside the recipient's request: from an outbox handler, as here, or from a request made by someone else, such as an admin. That request's locale is the wrong one.

The outbox handler passes the customer's locale when sending:

notifications/order-mails.handler.ts

JS TS

```typescript

await this.mailer.send(OrderConfirmationMail, {
  to: { name: customer.name, address: customer.email },
  data: { order, customer },
  locale: customer.locale,
  // ...
});
```

A Polish subject or recipient name can't go into a mail header as it is: headers are ASCII. The mailer encodes non-ASCII header text as RFC 2047 encoded-words, such as `=?UTF-8?Q?Twoje_zam=C3=B3wienie_=231001?=`, and the body as quoted-printable, so every server carries the message unchanged and mail clients show `Twoje zamówienie #1001`.

The preview takes the language from the query string, so both versions can be checked in a browser:

notifications/mail-preview\.controller.ts

JS TS

```typescript

/** Renders the mail with sample data, without sending it: GET /dev/mail/order-confirmation?locale=pl */
@Get('order-confirmation')
@Header('content-type', 'text/html; charset=utf-8')
async orderConfirmation(@Query('locale') locale = 'en') {
  const message = await this.mailer.render(OrderConfirmationMail, { data: SAMPLE, locale });
  // ...
}
```

#### Use another template engine[#](/application/mail#use-another-template-engine)

`FileTemplateEngine` implements `MailTemplateEngine`, an abstract class with one method: `render()` takes the template's name, the context and the locale, and returns the HTML, or an object with `html` and `text`, or a promise of either. Extend it to render with Handlebars, EJS or anything else. An engine for Handlebars templates in `.hbs` files:

mail/handlebars-template.engine.ts

JS TS

```typescript

import { MailTemplateEngine, MailTemplateError, type MailTemplateRenderOptions } from '@nestjs/mail';
import Handlebars from 'handlebars';
import { readFile } from 'node:fs/promises';
import { join } from 'node:path';

const TEMPLATES = join(import.meta.dirname, 'templates');

/** Renders order-confirmation.pl.hbs, else order-confirmation.hbs, with Handlebars. */
export class HandlebarsTemplateEngine extends MailTemplateEngine {
  private readonly templates = new Map<string, ReturnType<typeof Handlebars.compile> | undefined>();

  async render(name: string, context: object, { locale }: MailTemplateRenderOptions) {
    // Only a language code goes into a file name, never whatever the locale holds
    const localized = locale && /^[a-z]{2}$/.test(locale) ? [`${name}.${locale}.hbs`] : [];
    for (const file of [...localized, `${name}.hbs`]) {
      const template = await this.load(file);
      if (template) {
        return template(context);
      }
    }
    throw new MailTemplateError(`No template "${name}" in ${TEMPLATES}`, { template: name });
  }

  private async load(file: string) {
    if (!this.templates.has(file)) {
      const source = await readFile(join(TEMPLATES, file), 'utf8').catch(() => undefined);
      // compat: plain paths fall back to outer contexts, as in FileTemplateEngine
      this.templates.set(file, source === undefined ? undefined : Handlebars.compile(source, { compat: true }));
    }
    return this.templates.get(file);
  }
}
```

Pass it as `templates` in place of `FileTemplateEngine`: an instance, or the class, which Nest instantiates, so it can inject configuration or other providers. As with the transport, a class goes at the top level of `forRootAsync()`, next to `useFactory`, and the factory returns instances.

The mailer sends the HTML as the engine returns it, so escaping is the engine's job: Handlebars escapes double-braced values, as `FileTemplateEngine` does. `compat: true` makes names inside `#each` fall back to the outer context, so the templates of this tutorial render under Handlebars as they are. Handlebars doesn't know about the `partials/` folder and the layout: register the partials with `Handlebars.registerPartial()`, and render the layout around the mail yourself. For [MJML](https://mjml.io), convert the rendered MJML with `mjml2html()` before returning the HTML. Throw `MailTemplateError` for a template that is missing or broken: it's permanent, so the outbox dead-letters the mail instead of retrying it.

#### Write your own transport[#](/application/mail#write-your-own-transport)

For a provider the package doesn't ship a transport for, extend `MailTransport`. Its `send()` gets the finished message and resolves once the provider has accepted it. A transport for Mailgun, whose `messages.mime` endpoint takes the message as MIME, the way `SesTransport` sends it to SES:

mail/mailgun.transport.ts

JS TS

```typescript

import {
  MailProviderError,
  MailTransport,
  type MailMessage,
  type MailTransportResult,
  type MailTransportSendOptions,
} from '@nestjs/mail';

export interface MailgunTransportOptions {
  domain: string;
  apiKey: string;
  /** `https://api.eu.mailgun.net` for a domain in the EU region. */
  baseUrl?: string;
}

/** Sends the finished MIME message through Mailgun's `messages.mime` endpoint. */
export class MailgunTransport extends MailTransport {
  readonly #apiKey: string;
  private readonly url: string;

  constructor({ domain, apiKey, baseUrl = 'https://api.mailgun.net' }: MailgunTransportOptions) {
    super();
    this.#apiKey = apiKey;
    this.url = `${baseUrl}/v3/${encodeURIComponent(domain)}/messages.mime`;
  }

  async send(message: MailMessage, { signal }: MailTransportSendOptions): Promise<MailTransportResult> {
    const form = new FormData();
    // The envelope names every recipient; the MIME message leaves Bcc out
    form.append('to', message.envelope.to.join(','));
    form.append('message', new Blob([new Uint8Array(message.toMime())]), 'message.eml');

    // An abort rejects with signal.reason; a network error is transient, so the mailer retries it
    const response = await fetch(this.url, {
      method: 'POST',
      headers: { authorization: `Basic ${Buffer.from(`api:${this.#apiKey}`).toString('base64')}` },
      body: form,
      signal: AbortSignal.any([signal, AbortSignal.timeout(30_000)]),
    });

    if (!response.ok) {
      const retryAfter = Number(response.headers.get('retry-after'));
      // Permanent for 4xx except 408, 409 and 429: those and 5xx are retried
      throw new MailProviderError({
        provider: 'mailgun',
        status: response.status,
        detail: await response.text(),
        ...(retryAfter > 0 && { retryAfterMs: retryAfter * 1_000 }),
      });
    }

    const { id } = (await response.json()) as { id?: string };
    return { accepted: message.envelope.to, providerMessageId: id };
  }
}
```

Pass an instance as `transport`, as with the built-in transports. `send(message, options)` gets:

* **`message`.** A `MailMessage`, validated and frozen: `from`, `to`, `cc`, `bcc`, `replyTo`, `subject`, `html`, `text`, `attachments`, `headers` and `messageId`. `envelope` holds the SMTP envelope, with every recipient once, Bcc included, and `toMime()` returns the message as MIME, without the Bcc header. It's the same object on every attempt.
* **`signal`.** Aborts when the caller cancels the send, such as the outbox relay when a handler outlives its timeout. Stop the request, and reject with `signal.reason`; the mailer doesn't retry an abort.
* **`idempotencyKey`.** The caller's key, the same on every attempt and every redelivery. Send it to a provider that deduplicates requests, as `ResendTransport` does; the `Message-ID` is already derived from it.
* **`attempt`.** 1 for the first attempt, 2 for the first retry.

It resolves to `accepted`, the envelope recipients the provider took (all of them when left out), `providerMessageId` and `response`, which the mailer's `send()` resolves to in turn.

What it throws decides whether the mailer retries. Throw a `MailError` whose `permanent` says whether sending the same message again can succeed: `MailProviderError` for an HTTP API's refusal, which is permanent for a 4xx status other than 408, 409 and 429 unless you pass `permanent` yourself, `MailConnectionError` and `MailTimeoutError` for a failed or slow request. Any other error counts as transient, unless it has `permanent: true` or a 4xx `status`, so a network error from `fetch` is retried. An error with `retryAfterMs` makes the mailer wait at least that long before the next attempt, up to `maxDelay`.

A transport that holds connections or a client implements `close()`, which runs on application shutdown, after the sends in flight have finished.

#### Try it[#](/application/mail#try-it)

Apply the migrations, which also add two customers and four products:

```bash

$ export DATABASE_URL=postgres://localhost:5432/store
$ npx drizzle-kit migrate
```

Start the application with the defaults: the file transport, and the relay running. Place an order for Ada:

```bash

$ curl -X POST localhost:3000/orders \
    -H 'Content-Type: application/json' \
    -d '{"customerId":"ada","items":[{"productId":"salmon-kibble-2kg","quantity":2},{"productId":"feather-wand","quantity":1}]}'
{"id":"fd2bfc1c-db5c-455c-8876-bf7331a1029c","number":1001,"customerId":"ada","items":[{"productId":"salmon-kibble-2kg","name":"Salmon kibble, 2 kg","quantity":2,"price":2499},{"productId":"feather-wand","name":"Feather wand toy","quantity":1,"price":799}],"total":5797,"placedAt":"2026-09-25T10:59:00.173Z"}
```

The response comes back before any mail is sent. A moment later, the relay's handler renders the mail and the file transport writes it:

```bash

[Nest] 37252  - 09/25/2026, 12:59:00 PM     LOG [FileMailTransport] "Your order #1001" to ada@example.com written to var/mail/2026-09-25T10-59-00-199Z--LtIZd5B_AiZek3-x8nOt88YfUYjgkZi-42ff80.eml
```

The file is the message exactly as SMTP would transmit it. Its headers and text part:

```bash

$ head -33 var/mail/*.eml
From: Orders <orders@example.com>
To: Ada Lovelace <ada@example.com>
Subject: Your order #1001
Date: Fri, 25 Sep 2026 10:59:00 +0000
Message-ID: <-LtIZd5B_AiZek3-x8nOt88YfUYjgkZi@example.com>
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="=_bTCd1MQ5LoxTNFNN0nLRwu8d"

--=_bTCd1MQ5LoxTNFNN0nLRwu8d
Content-Type: multipart/alternative; boundary="=_9HVDyVBGuLsAaijTpu4Y2_XU"

--=_9HVDyVBGuLsAaijTpu4Y2_XU
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: quoted-printable

Hi Ada Lovelace,

thank you for your order! We are packing it now.

Product Qty Price
Salmon kibble, 2 kg 2 $49.98
Feather wand toy 1 $7.99

Total: $57.97

View your order (https://shop.example.com/orders/fd2bfc1c-db5c-455c-8876-bf=
7331a1029c)

Your invoice is attached.

The customer care team
--=_9HVDyVBGuLsAaijTpu4Y2_XU
Content-Type: multipart/related; boundary="=_u7PgKDXrb-x3mIz35ZArIBAa"
```

A few things to notice:

* The `Message-ID` is derived from the outbox message's id, not random. A redelivery would carry the same one.
* The text part was derived from the HTML, with the link written out.
* The body is quoted-printable, which keeps every line short enough for any mail server: the `=` at the end of the link's first line joins it with the next.

The HTML, the logo and the invoice follow:

```bash

$ grep -E '^Content-(Type|Disposition|ID):' var/mail/*.eml | tail -5
Content-Type: image/png; name="logo.png"
Content-Disposition: inline; filename="logo.png"
Content-ID: <logo@example.com>
Content-Type: application/pdf; name="invoice-1001.pdf"
Content-Disposition: attachment; filename="invoice-1001.pdf"
```

Open the file in a mail client to see the rendered mail. To work on the template, open the preview in a browser instead. The response is the mail's HTML, the template in the layout, with the logo inlined as a `data:` URL (shortened here):

```bash

$ curl localhost:3000/dev/mail/order-confirmation
```

```html

<!DOCTYPE html>
<html>
<body>
<p><img src="data:image/png;base64,…" alt="Logo" width="120" height="32"></p>
<p>Hi Ada Lovelace,</p>
<p>thank you for your order! We are packing it now.</p>
<table>
  <tr><th>Product</th><th>Qty</th><th>Price</th></tr>
  <tr>
    <td>Salmon kibble, 2 kg</td>
    <td>2</td>
    <td>$49.98</td>
  </tr>
  <tr>
    <td>Feather wand toy</td>
    <td>1</td>
    <td>$7.99</td>
  </tr>
</table>
<p><strong>Total: $57.97</strong></p>
<p><a href="https://shop.example.com/orders/00000000-0000-4000-8000-000000000000">View your order</a></p>
<p>Your invoice is attached.</p>

<p>The customer care team</p>
</body>
</html>
```

Next, order a product that doesn't exist:

```bash

$ curl -X POST localhost:3000/orders \
    -H 'Content-Type: application/json' \
    -d '{"customerId":"ada","items":[{"productId":"salmon-kibble-2kg","quantity":1},{"productId":"catnip-mouse","quantity":1}]}'
{"message":"Unknown product \"catnip-mouse\"","error":"Bad Request","statusCode":400}
```

The transaction rolls back, the `order.placed` message with it, and no mail is written.

Finally, see [the customer's language](/application/mail#send-it-in-the-customers-language) at work. Place an order for Zofia, who chose Polish at sign-up:

```bash

$ curl -X POST localhost:3000/orders \
    -H 'Content-Type: application/json' \
    -d '{"customerId":"zofia","items":[{"productId":"feather-wand","quantity":1}]}'
{"id":"7fa5ce1f-9ef3-49b0-8de9-a2d98056c299","number":1002,"customerId":"zofia","items":[{"productId":"feather-wand","name":"Feather wand toy","quantity":1,"price":799}],"total":799,"placedAt":"2026-09-25T10:59:00.424Z"}
```

```bash

[Nest] 37252  - 09/25/2026, 12:59:00 PM     LOG [FileMailTransport] "Twoje zamówienie #1002" to zofia@example.com written to var/mail/2026-09-25T10-59-00-453Z-GnMdyKUxVa0FRBJ6wZ2k5snIWsdQmwC2-697a51.eml
```

The body comes from `order-confirmation.pl.html`. The Polish subject and Zofia's name reach the file as encoded-words, and her invoice is `faktura-1002.pdf`:

```bash

$ head -3 var/mail/2026-09-25T10-59-00-453Z-GnMdyKUxVa0FRBJ6wZ2k5snIWsdQmwC2-697a51.eml
From: Orders <orders@example.com>
To: =?UTF-8?Q?Zofia_W=C3=B3jcik?= <zofia@example.com>
Subject: =?UTF-8?Q?Twoje_zam=C3=B3wienie_=231002?=
```

#### Testing[#](/application/mail#testing)

Replace the transport with `InMemoryMailTransport`. It keeps every mail it receives, and has helpers that find one and read it:

test/order-confirmation.e2e-spec.ts

JS TS

```typescript

import { PGlite } from '@electric-sql/pglite';
import { getDrizzleToken } from '@nestjs/drizzle';
import { InMemoryMailTransport, MailSmtpError, MailTransport } from '@nestjs/mail';
import { OutboxDeadLetters, OutboxRelay } from '@nestjs/outbox';
import { Test, type TestingModule } from '@nestjs/testing';
import { drizzle } from 'drizzle-orm/pglite';
import { migrate } from 'drizzle-orm/pglite/migrator';
import { fileURLToPath } from 'node:url';
import { afterAll, beforeAll, beforeEach, describe, expect, it } from 'vitest';
import { AppModule } from '../src/app.module.js';
import * as schema from '../src/database/schema.js';
import { OrderConfirmationMail } from '../src/notifications/order-confirmation.mail.js';
import { OrdersService } from '../src/orders/orders.service.js';

describe('Order confirmation mail', () => {
  const client = new PGlite(); // PostgreSQL in-process
  const mailbox = new InMemoryMailTransport();
  let moduleRef: TestingModule;
  let orders: OrdersService;
  let relay: OutboxRelay;

  beforeAll(async () => {
    const db = drizzle(client, { schema });
    // Your migrations: the tables, and the seeded customers and products. The outbox's store
    // creates its own schema in init().
    await migrate(db, { migrationsFolder: fileURLToPath(new URL('../drizzle', import.meta.url)) });
    process.env.OUTBOX_RELAY = 'off'; // no poll loop: the test drives the relay
    moduleRef = await Test.createTestingModule({ imports: [AppModule] })
      .overrideProvider(getDrizzleToken())
      .useValue(db) // the outbox's store runs on it too
      .overrideProvider(MailTransport)
      .useValue(mailbox)
      .compile();
    await moduleRef.init();
    orders = moduleRef.get(OrdersService);
    relay = moduleRef.get(OutboxRelay);
  });

  afterAll(async () => {
    await moduleRef.close();
    await client.close();
  });

  beforeEach(() => mailbox.clear());

  it('confirms the order with the invoice and a link to it', async () => {
    const order = await orders.placeOrder({ customerId: 'ada', items: [{ productId: 'salmon-kibble-2kg', quantity: 1 }] });
    mailbox.assertNotSent(); // nothing until the relay publishes the committed order

    await relay.runOnce();

    const mail = mailbox.assertSent({ to: 'ada@example.com', mail: OrderConfirmationMail });
    expect(mail.subject).toBe(`Your order #${order.number}`);
    expect(mail.attachment(`invoice-${order.number}.pdf`).contentType).toBe('application/pdf');
    expect(mail.link('/orders/').pathname).toBe(`/orders/${order.id}`);
  });

  it('dead-letters a confirmation the mail server refuses', async () => {
    mailbox.failNext(new MailSmtpError('RCPT TO', { code: 550, text: 'User unknown' }));
    await orders.placeOrder({ customerId: 'ada', items: [{ productId: 'salmon-kibble-2kg', quantity: 1 }] });

    await relay.runOnce();

    mailbox.assertNotSent();
    const [deadLetter] = await moduleRef.get(OutboxDeadLetters).list();
    expect(deadLetter).toMatchObject({ topic: 'order.placed', reason: 'rejected' });
  });
});
```

* **Everything but the network is real.** The mail class renders its templates, with the catalogs and the invoice provider, the outbox and its inbox run, and the message is fully built, headers and attachments included. Only delivery is replaced.
* **The database is PostgreSQL, in-process.** PGlite (`@electric-sql/pglite`, a dev dependency) runs your real migrations, and the test overrides the database `DrizzleModule` registers (its token comes from `getDrizzleToken()`) with it, so the repositories and the outbox store use it. There's no server to start, and each test file gets a fresh database.
* **`assertSent()`** returns the most recent mail that matches, by recipient (`to` matches to, cc and bcc), `subject`, mail class or `template`, or a predicate. When nothing matches, it throws an error that lists what was sent. `assertNotSent()`, `filter()`, `find()` and `mails` cover the rest. The helpers throw plain errors, so they work with any test runner.
* **`link()`** returns the first link in the mail that contains a string or matches a regular expression, as a `URL`. For a password reset or a magic link, that is the whole test: send the mail, then call `mail.link('/reset-password').searchParams.get('token')` and follow the link. Entities are decoded, so the `&amp;` that escaping writes in a query string is `&` again.
* **`failNext()`** makes the next send throw, here a permanent SMTP error, to test the error path.
* **`raw`** is the message as MIME, and `mailer.render()` renders a mail class or a template on its own, for unit tests of a template.

#### Production checklist[#](/application/mail#production-checklist)

* Configure SPF, DKIM and DMARC for the sending domain. HTTP providers sign with DKIM once the domain is verified with them; with SMTP, sign with the `dkim` option or at the relay.
* Keep STARTTLS required, and certificate verification on. For a relay with a private CA, pass `tls.ca` instead of turning verification off.
* Keep credentials in the environment or a secret store. Transports hold them in private fields, and error messages never contain them.
* Send transactional mail after commit, through the outbox, with `retry: false` in the handler and the outbox's retry policy sized to how long your provider can be down.
* Pass `idempotencyKey` for every mail sent from a handler that can run twice.
* Turn permanent mail errors into dead letters, and alert on `dead-lettered` outbox events. A refused address usually means a typo at sign-up, or a mailbox that no longer exists.
* Watch `MailEvents`, or the `nestjs:mail:sent` and `nestjs:mail:failed` diagnostics channels, for delivery failures and slow sends.
* Send through `SmtpTransport` or an HTTP provider's transport in production. `FileMailTransport` writes to the local disk, which a container loses when it restarts or is replaced, and `LogMailTransport` only logs: both are for development, and `InMemoryMailTransport` is for tests. The module warns at startup when one of them runs with `NODE_ENV=production`.
* Keep the outbox's messages in the application's database, through `PostgresOutboxStore` or another registered store, so a queued mail commits with its order and survives a restart. Without a store, the outbox refuses to start with `NODE_ENV=production`, and so does the store while its migrations aren't applied: apply them on deploy, as [the outbox tutorial](/reliability/outbox#keep-messages-in-your-database) shows.
* Ship the templates to `dist` with the CLI's assets, and keep the template cache on in production, which is the default: `cache: false` rereads the files for every mail.
* Don't register development-only routes, such as the preview, in production.
* Use `app.enableShutdownHooks()`, so a deploy waits for the mails in flight and closes SMTP connections.

#### Reference[#](/application/mail#reference)

##### Module options[#](/application/mail#module-options)

`MailModule.forRoot()` takes these options, and a `forRootAsync()` factory returns them. With `useClass` or `useExisting` in place of `useFactory`, the class implements `MailOptionsFactory`, whose `createMailOptions()` returns them. `transport`, `templates`, `imports` and `isGlobal` also sit next to `useFactory`, `useClass` or `useExisting` in `forRootAsync()`. The resolved options are provided under the `MAIL_MODULE_OPTIONS` token.

| Option      | Type                                   | Default         | Description                                                                                                                                                                                                                    |
| ----------- | -------------------------------------- | --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `transport` | `MailTransport` instance or class      | none (required) | How mail leaves the application. A class is instantiated by Nest, so it can inject configuration. See [Send in production](/application/mail#send-in-production).                                                              |
| `templates` | `MailTemplateEngine` instance or class | none            | Renders mail that names a `template`: `FileTemplateEngine`, or [your own](/application/mail#use-another-template-engine). A class is instantiated by Nest. Without one, a mail with a template fails with `MailTemplateError`. |
| `from`      | address                                | none            | The default sender. A message without a sender fails with `MailMessageError`.                                                                                                                                                  |
| `replyTo`   | address or array                       | none            | The default Reply-To.                                                                                                                                                                                                          |
| `headers`   | `Record<string, string>`               | none            | Added to every message. A message's own headers win.                                                                                                                                                                           |
| `retry`     | number, `false` or retry options       | 3 attempts      | Attempts per send, with backoff from `1s` doubling to `30s`, full jitter. `false` makes one attempt. See [Send after the order commits](/application/mail#send-after-the-order-commits).                                       |
| `imports`   | modules                                | none            | Modules whose exports a transport or template engine class injects.                                                                                                                                                            |
| `isGlobal`  | `boolean`                              | `true`          | Registers `Mailer`, `MailEvents`, `MailTransport` and `MailTemplateEngine` globally.                                                                                                                                           |

The retry options are `attempts` (total, including the first), `backoff` (an object with `delay`, `factor`, `maxDelay` and `jitter`, or a function of the attempt) and `retryIf` (can only narrow which transient errors are retried). When an HTTP provider answers with a `Retry-After` header, typically with a 429 or a 503, the error keeps it as `retryAfterMs`, and the mailer waits at least that long before the next attempt, up to `maxDelay` (`30s` with a backoff function). The `signal` still ends the wait. SMTP replies have no `Retry-After`, and an outbox handler with `retry: false` leaves the wait to the outbox's backoff.

##### Template engine[#](/application/mail#template-engine)

`FileTemplateEngine` takes:

| Option   | Type      | Default         | Description                                                                                                                              |
| -------- | --------- | --------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| `dir`    | `string`  | none (required) | The directory of the templates, with partials in its `partials/` folder. A relative path is resolved against the working directory.      |
| `layout` | `string`  | none            | A template that wraps every mail's HTML, placing it with triple braces around `body`. A `.txt` version, if there is one, wraps the text. |
| `cache`  | `boolean` | `true`          | Keeps compiled templates, and which files exist, in memory. `false` reads the files for every mail, to see edits in development.         |

`template: 'order-confirmation'` with the locale `pt-BR` renders the first file that exists of `order-confirmation.pt-BR.html`, `order-confirmation.pt.html` and `order-confirmation.html`, and the first of the same names with `.txt` as the text part, if any. Template names are letters, digits, `-` and `_`, in folders separated by `/`. Other names, and locales that aren't language tags, fail with `MailTemplateError`, so neither can reach a file outside `dir`.

##### Template syntax[#](/application/mail#template-syntax)

The syntax is a subset of Handlebars:

| Syntax                                   | Renders                                                                                                                                                                                                       |
| ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `{{ customer.name }}`                    | The value, HTML-escaped. Paths use dots, and `items.0` is an array's first item. A missing value renders as nothing. In a `.txt` template, the value as it is.                                                |
| `{{{ body }}}`                           | The value as it is, for HTML you produced yourself. HTML built with the `html` tag is inserted as it is between double braces too.                                                                            |
| `{{#if paid}} … {{else}} … {{/if}}`      | The first part when the value is truthy, else the `else` part, which is optional. `false`, `0`, an empty string, an empty list and a missing value are falsy. `{{else if pending}}` chains another condition. |
| `{{#unless paid}} … {{/unless}}`         | The opposite of `#if`, with an optional `else` part.                                                                                                                                                          |
| `{{#each items}} … {{else}} … {{/each}}` | The first part once for every item of a list, or every value of an object; the `else` part for an empty or missing list.                                                                                      |
| `this, @index, @first, @last, @key`      | Inside `#each`: the item, its position from 0, whether it's the first or the last, and an object's key. A name the item doesn't have is looked up in the outer contexts.                                      |
| `../number, @root.shop`                  | The context outside the current `#each`, and the template's context.                                                                                                                                          |
| `{{> signature}}`                        | The partial `partials/signature.html` (`.txt` in a text template), in the mail's locale, with the context where it's included.                                                                                |
| `{{! note }}, {{!-- note --}}`           | Comments, left out of the output. The second form may contain double braces.                                                                                                                                  |
| `\{{`                                    | Literal double braces.                                                                                                                                                                                        |

There are no helpers and no expressions. Values are read from the context's own properties, never from a prototype, and functions aren't called. Anything else between double braces, a block that is never closed, and a double-braced value inside a tag but outside a quoted attribute value fail with `MailTemplateError`, which has the `file`, the `line` and the `column`.

##### Send options[#](/application/mail#send-options)

`mailer.send(MailClass, options)` and `mailer.send(message)` take:

| Option                    | Description                                                                                                                                                                                                                        |
| ------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `to`, `cc`, `bcc`         | One address or an array. An address is a string holding exactly one address, or an object with `name` and `address`. `bcc` goes only into the SMTP envelope.                                                                       |
| `data`                    | The mail class's data, typed from its `render()`.                                                                                                                                                                                  |
| `locale`                  | Passed to `render()` in the render context, and to the template engine, which picks the template for it. See [Send it in the customer's language](/application/mail#send-it-in-the-customers-language).                            |
| `from`, `replyTo`         | Override the module's defaults.                                                                                                                                                                                                    |
| `subject`, `html`, `text` | The content, for a message written inline. `text` is derived from `html` when omitted.                                                                                                                                             |
| `template`, `context`     | The template the body is rendered from, and the values it reads, in place of `html` and `text`. A mail class's `render()` returns them the same way.                                                                               |
| `attachments`             | Each has `filename`, `content` (a `Buffer`, string or stream) or a local `path`, and optionally `contentType` and `cid`. See [Attach the invoice and preview the mail](/application/mail#attach-the-invoice-and-preview-the-mail). |
| `headers`                 | Custom headers, such as `List-Unsubscribe`.                                                                                                                                                                                        |
| `retry`                   | Overrides the module's `retry` for this send.                                                                                                                                                                                      |
| `signal`                  | An `AbortSignal` that stops the send and any wait between attempts.                                                                                                                                                                |
| `idempotencyKey`          | Identifies the mail across redeliveries. The `Message-ID` is derived from it.                                                                                                                                                      |

`mailer.render(MailClass, options)` and `mailer.render(message)` take the same without the delivery options, and resolve to the `MailMessage`, which records its `template` and `locale`. `send()` resolves to `messageId`, `providerMessageId` (when the provider has one), `accepted` (the accepted envelope recipients), `response` (the final SMTP reply) and `attempts`.

##### Transports[#](/application/mail#transports)

| Transport               | Options                                                                                                                                                                                                                                                                                                                                    | Idempotency key                                      |
| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------- |
| `SmtpTransport`         | `url` or `host`, `port`, `secure`, `startTls` (`required`, `opportunistic` or `never`; `required` by default, `opportunistic` for localhost), `auth` (`user` with `pass` or `accessToken`), `authMethod` (`PLAIN`, `LOGIN` or `XOAUTH2`), `name`, `tls`, `pool`, `timeouts`, `dkim` (`domainName`, `keySelector`, `privateKey`, `headers`) | derived `Message-ID` only                            |
| `ResendTransport`       | `apiKey`, `baseUrl`, `timeout`, `fetch`                                                                                                                                                                                                                                                                                                    | `Idempotency-Key`, 24 hours                          |
| `PostmarkTransport`     | `serverToken`, `messageStream` (default `outbound`), `baseUrl`, `timeout`, `fetch`                                                                                                                                                                                                                                                         | none                                                 |
| `SendGridTransport`     | `apiKey`, `baseUrl`, `timeout`, `fetch`                                                                                                                                                                                                                                                                                                    | none                                                 |
| `SesTransport`          | `region`, `credentials`, `configurationSetName`, `endpoint`, `timeout`, `fetch`                                                                                                                                                                                                                                                            | none                                                 |
| `FileMailTransport`     | `directory`, `log`                                                                                                                                                                                                                                                                                                                         | development only                                     |
| `LogMailTransport`      | `body`, `logger`                                                                                                                                                                                                                                                                                                                           | development only                                     |
| `InMemoryMailTransport` | none                                                                                                                                                                                                                                                                                                                                       | tests only, see [Testing](/application/mail#testing) |

`InMemoryMailTransport.mails` lists every mail received, oldest first, as a `SentMail`, which `filter()`, `find()` and `assertSent()` return too. A `SentMail` has the message's `messageId`, `from`, `to`, `cc`, `bcc`, `subject`, `html`, `text`, `attachments`, `headers`, `mail` (the mail class), `template` and `locale`, plus `sentAt` (when the transport received it), `raw` (the MIME source), `links` (every link, from the HTML, then the ones only the text part has), `link()`, `attachment()` and `message`, the `MailMessage` itself. `clear()` forgets them all.

With `pool: true`, `SmtpTransport` keeps up to 5 connections, sends up to 100 messages per connection, and closes a connection after 30 seconds idle; an object with `maxConnections`, `maxMessages` and `idleTimeout` as `pool` changes those limits. Its default timeouts are `30s` to connect, `30s` for the greeting, `1m` per command and `5m` for the data. HTTP providers time out after `30s` per request.

##### Events[#](/application/mail#events)

`MailEvents.events$` emits one event per send, after its retries. Each event is also published on a `node:diagnostics_channel` channel.

| Event type | Channel              | When                                                                                                   | Payload                                                                                                  |
| ---------- | -------------------- | ------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------- |
| `sent`     | `nestjs:mail:sent`   | The transport accepted the message.                                                                    | `messageId`, `mail`, `recipients`, `subject`, `transport`, `attempts`, `durationMs`, `providerMessageId` |
| `failed`   | `nestjs:mail:failed` | The send failed after its retries, or its `signal` aborted before the first attempt (`attempts` is 0). | The same fields without `providerMessageId`, plus `error` and `permanent`                                |

A message that fails validation throws before any event.

##### Errors[#](/application/mail#errors)

Every error extends `MailError`, which has `permanent` (whether sending the same message again can't succeed) and `code` (the SMTP reply code or the provider's HTTP status). The mailer retries only errors that aren't permanent. See [Send after the order commits](/application/mail#send-after-the-order-commits).

| Error                         | When                                                                                                                                                                     | Permanent                                                                              |
| ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------- |
| `MailMessageError`            | The message is invalid, before anything is sent. `field` names the field, `status` is 400.                                                                               | Yes                                                                                    |
| `MailConnectionError`         | DNS, a refused or reset connection, TLS or a certificate. `cause` holds the socket error.                                                                                | No, except configuration problems such as a server without STARTTLS when it's required |
| `MailTimeoutError`            | A phase outlived its timeout. Has `phase` and `timeoutMs`.                                                                                                               | No                                                                                     |
| `MailSmtpError`               | An SMTP error reply. Has `code`, `enhancedCode`, `command` and `response`.                                                                                               | For 5xx replies                                                                        |
| `MailRecipientsRejectedError` | The server refused one or more recipients, and nothing was sent. `rejected` lists them. Extends `MailSmtpError`.                                                         | When any refusal is 5xx                                                                |
| `MailTemplateError`           | A template is missing or doesn't compile, or a mail names a template without a template engine. Has `template`, and `file`, `line` and `column` for a problem in a file. | Yes                                                                                    |
| `MailProviderError`           | An HTTP provider refused the request. Has `code` (the HTTP status), `provider`, `providerCode`, and `retryAfterMs` when the response had a valid `Retry-After`.          | For 4xx except 408, 409 and 429                                                        |

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/application/mail.md)

----
url: https://docs.nestjs.com/v10/graphql/resolvers
----

* [Resolvers](https://docs.nestjs.com/v10/graphql/resolvers#resolvers)
* [Code first](https://docs.nestjs.com/v10/graphql/resolvers#code-first)
* [Object types](https://docs.nestjs.com/v10/graphql/resolvers#object-types)
* [Code first resolver](https://docs.nestjs.com/v10/graphql/resolvers#code-first-resolver)
* [Query type names](https://docs.nestjs.com/v10/graphql/resolvers#query-type-names)
* [Query decorator options](https://docs.nestjs.com/v10/graphql/resolvers#query-decorator-options)
* [Args decorator options](https://docs.nestjs.com/v10/graphql/resolvers#args-decorator-options)
* [Dedicated arguments class](https://docs.nestjs.com/v10/graphql/resolvers#dedicated-arguments-class)
* [Class inheritance](https://docs.nestjs.com/v10/graphql/resolvers#class-inheritance)
* [Generics](https://docs.nestjs.com/v10/graphql/resolvers#generics)
* [Schema first](https://docs.nestjs.com/v10/graphql/resolvers#schema-first)
* [Schema first resolver](https://docs.nestjs.com/v10/graphql/resolvers#schema-first-resolver)
* [Generating types](https://docs.nestjs.com/v10/graphql/resolvers#generating-types)
* [GraphQL argument decorators](https://docs.nestjs.com/v10/graphql/resolvers#graphql-argument-decorators)
* [Module](https://docs.nestjs.com/v10/graphql/resolvers#module)

```graphql

type Author {
  id: Int!
  firstName: String
  lastName: String
  posts: [Post!]!
}
```

In this case, using the code first approach, we define schemas using TypeScript classes and using TypeScript decorators to annotate the fields of those classes. The equivalent of the above SDL in the code first approach is:

authors/models/author.model.ts

JS TS

```typescript

import { Field, Int, ObjectType } from '@nestjs/graphql';
import { Post } from './post';

@ObjectType()
export class Author {
  @Field(type => Int)
  id: number;

  @Field({ nullable: true })
  firstName?: string;

  @Field({ nullable: true })
  lastName?: string;

  @Field(type => [Post])
  posts: Post[];
}
```

> **Hint** TypeScript's metadata reflection system has several limitations which make it impossible, for instance, to determine what properties a class consists of or recognize whether a given property is optional or required. Because of these limitations, we must either explicitly use the `@Field()` decorator in our schema definition classes to provide metadata about each field's GraphQL type and optionality, or use a [CLI plugin](/v10/graphql/cli-plugin) to generate these for us.

The `Author` object type, like any class, is made of a collection of fields, with each field declaring a type. A field's type corresponds to a [GraphQL type](https://graphql.org/learn/schema/). A field's GraphQL type can be either another object type or a scalar type. A GraphQL scalar type is a primitive (like `ID`, `String`, `Boolean`, or `Int`) that resolves to a single value.

> **Hint** In addition to GraphQL's built-in scalar types, you can define custom scalar types (read [more](/v10/graphql/scalars)).

The above `Author` object type definition will cause Nest to **generate** the SDL we showed above:

```graphql

type Author {
  id: Int!
  firstName: String
  lastName: String
  posts: [Post!]!
}
```

```typescript

@Field({ description: `Book title`, deprecationReason: 'Not useful in v2 schema' })
title: string;
```

> **Hint** You can also add a description to, or deprecate, the whole object type: `@ObjectType({ description: 'Author model' })`.

When the field is an array, we must manually indicate the array type in the `Field()` decorator's type function, as shown below:

```typescript

@Field(type => [Post])
posts: Post[];
```

> **Hint** Using array bracket notation (`[ ]`), we can indicate the depth of the array. For example, using `[[Int]]` would represent an integer matrix.

To declare that an array's items (not the array itself) are nullable, set the `nullable` property to `'items'` as shown below:

```typescript

@Field(type => [Post], { nullable: 'items' })
posts: Post[];
```

> **Hint** If both the array and its items are nullable, set `nullable` to `'itemsAndList'` instead.

Now that the `Author` object type is created, let's define the `Post` object type.

posts/models/post.model.ts

JS TS

```typescript

import { Field, Int, ObjectType } from '@nestjs/graphql';

@ObjectType()
export class Post {
  @Field(type => Int)
  id: number;

  @Field()
  title: string;

  @Field(type => Int, { nullable: true })
  votes?: number;
}
```

The `Post` object type will result in generating the following part of the GraphQL schema in SDL:

```graphql

type Post {
  id: Int!
  title: String!
  votes: Int
}
```

#### Code first resolver[#](/graphql/resolvers#code-first-resolver)

At this point, we've defined the objects (type definitions) that can exist in our data graph, but clients don't yet have a way to interact with those objects. To address that, we need to create a resolver class. In the code first method, a resolver class both defines resolver functions **and** generates the **Query type**. This will be clear as we work through the example below:

authors/authors.resolver.ts

JS TS

```typescript

@Resolver(() => Author)
export class AuthorsResolver {
  constructor(
    private authorsService: AuthorsService,
    private postsService: PostsService,
  ) {}

  @Query(() => Author)
  async author(@Args('id', { type: () => Int }) id: number) {
    return this.authorsService.findOneById(id);
  }

  @ResolveField()
  async posts(@Parent() author: Author) {
    const { id } = author;
    return this.postsService.findAll({ authorId: id });
  }
}
```

> **Hint** All decorators (e.g., `@Resolver`, `@ResolveField`, `@Args`, etc.) are exported from the `@nestjs/graphql` package.

You can define multiple resolver classes. Nest will combine these at run time. See the [module](/graphql/resolvers#module) section below for more on code organization.

> **Note** The logic inside the `AuthorsService` and `PostsService` classes can be as simple or sophisticated as needed. The main point of this example is to show how to construct resolvers and how they can interact with other providers.

In the example above, we created the `AuthorsResolver` which defines one query resolver function and one field resolver function. To create a resolver, we create a class with resolver functions as methods, and annotate the class with the `@Resolver()` decorator.

In this example, we defined a query handler to get the author object based on the `id` sent in the request. To specify that the method is a query handler, use the `@Query()` decorator.

The argument passed to the `@Resolver()` decorator is optional, but comes into play when our graph becomes non-trivial. It's used to supply a parent object used by field resolver functions as they traverse down through an object graph.

In our example, since the class includes a **field resolver** function (for the `posts` property of the `Author` object type), we **must** supply the `@Resolver()` decorator with a value to indicate which class is the parent type (i.e., the corresponding `ObjectType` class name) for all field resolvers defined within this class. As should be clear from the example, when writing a field resolver function, it's necessary to access the parent object (the object the field being resolved is a member of). In this example, we populate an author's posts array with a field resolver that calls a service which takes the author's `id` as an argument. Hence the need to identify the parent object in the `@Resolver()` decorator. Note the corresponding use of the `@Parent()` method parameter decorator to then extract a reference to that parent object in the field resolver.

We can define multiple `@Query()` resolver functions (both within this class, and in any other resolver class), and they will be aggregated into a single **Query type** definition in the generated SDL along with the appropriate entries in the resolver map. This allows you to define queries close to the models and services that they use, and to keep them well organized in modules.

> **Hint** Nest CLI provides a generator (schematic) that automatically generates **all the boilerplate code** to help us avoid doing all of this, and make the developer experience much simpler. Read more about this feature [here](/v10/recipes/crud-generator).

#### Query type names[#](/graphql/resolvers#query-type-names)

In the above examples, the `@Query()` decorator generates a GraphQL schema query type name based on the method name. For example, consider the following construction from the example above:

```typescript

@Query(() => Author)
async author(@Args('id', { type: () => Int }) id: number) {
  return this.authorsService.findOneById(id);
}
```

This generates the following entry for the author query in our schema (the query type uses the same name as the method name):

```graphql

type Query {
  author(id: Int!): Author
}
```

> **Hint** Learn more about GraphQL queries [here](https://graphql.org/learn/queries/).

Conventionally, we prefer to decouple these names; for example, we prefer to use a name like `getAuthor()` for our query handler method, but still use `author` for our query type name. The same applies to our field resolvers. We can easily do this by passing the mapping names as arguments of the `@Query()` and `@ResolveField()` decorators, as shown below:

authors/authors.resolver.ts

JS TS

```typescript

@Resolver(() => Author)
export class AuthorsResolver {
  constructor(
    private authorsService: AuthorsService,
    private postsService: PostsService,
  ) {}

  @Query(() => Author, { name: 'author' })
  async getAuthor(@Args('id', { type: () => Int }) id: number) {
    return this.authorsService.findOneById(id);
  }

  @ResolveField('posts', () => [Post])
  async getPosts(@Parent() author: Author) {
    const { id } = author;
    return this.postsService.findAll({ authorId: id });
  }
}
```

The `getAuthor` handler method above will result in generating the following part of the GraphQL schema in SDL:

```graphql

type Query {
  author(id: Int!): Author
}
```

```typescript

@Args('id') id: string
```

In the `getAuthor()` case, the `number` type is used, which presents a challenge. The `number` TypeScript type doesn't give us enough information about the expected GraphQL representation (e.g., `Int` vs. `Float`). Thus we have to **explicitly** pass the type reference. We do that by passing a second argument to the `Args()` decorator, containing argument options, as shown below:

```typescript

@Query(() => Author, { name: 'author' })
async getAuthor(@Args('id', { type: () => Int }) id: number) {
  return this.authorsService.findOneById(id);
}
```

```typescript

getAuthor(
  @Args('firstName', { nullable: true }) firstName?: string,
  @Args('lastName', { defaultValue: '' }) lastName?: string,
) {}
```

#### Dedicated arguments class[#](/graphql/resolvers#dedicated-arguments-class)

With inline `@Args()` calls, code like the example above becomes bloated. Instead, you can create a dedicated `GetAuthorArgs` arguments class and access it in the handler method as follows:

```typescript

@Args() args: GetAuthorArgs
```

Create the `GetAuthorArgs` class using `@ArgsType()` as shown below:

authors/dto/get-author.args.ts

JS TS

```typescript

import { MinLength } from 'class-validator';
import { Field, ArgsType } from '@nestjs/graphql';

@ArgsType()
class GetAuthorArgs {
  @Field({ nullable: true })
  firstName?: string;

  @Field({ defaultValue: '' })
  @MinLength(3)
  lastName: string;
}
```

> **Hint** Again, due to TypeScript's metadata reflection system limitations, it's required to either use the `@Field` decorator to manually indicate type and optionality, or use a [CLI plugin](/v10/graphql/cli-plugin).

This will result in generating the following part of the GraphQL schema in SDL:

```graphql

type Query {
  author(firstName: String, lastName: String = ''): Author
}
```

> **Hint** Note that arguments classes like `GetAuthorArgs` play very well with the `ValidationPipe` (read [more](/v10/techniques/validation)).

#### Class inheritance[#](/graphql/resolvers#class-inheritance)

You can use standard TypeScript class inheritance to create base classes with generic utility type features (fields and field properties, validations, etc.) that can be extended. For example, you may have a set of pagination related arguments that always include the standard `offset` and `limit` fields, but also other index fields that are type-specific. You can set up a class hierarchy as shown below.

Base `@ArgsType()` class:

```typescript

@ArgsType()
class PaginationArgs {
  @Field(() => Int)
  offset: number = 0;

  @Field(() => Int)
  limit: number = 10;
}
```

Type specific sub-class of the base `@ArgsType()` class:

```typescript

@ArgsType()
class GetAuthorArgs extends PaginationArgs {
  @Field({ nullable: true })
  firstName?: string;

  @Field({ defaultValue: '' })
  @MinLength(3)
  lastName: string;
}
```

The same approach can be taken with `@ObjectType()` objects. Define generic properties on the base class:

```typescript

@ObjectType()
class Character {
  @Field(() => Int)
  id: number;

  @Field()
  name: string;
}
```

Add type-specific properties on sub-classes:

```typescript

@ObjectType()
class Warrior extends Character {
  @Field()
  level: number;
}
```

You can use inheritance with a resolver as well. You can ensure type safety by combining inheritance and TypeScript generics. For example, to create a base class with a generic `findAll` query, use a construction like this:

```typescript

function BaseResolver<T extends Type<unknown>>(classRef: T): any {
  @Resolver({ isAbstract: true })
  abstract class BaseResolverHost {
    @Query(() => [classRef], { name: `findAll${classRef.name}` })
    async findAll(): Promise<T[]> {
      return [];
    }
  }
  return BaseResolverHost;
}
```

Note the following:

* an explicit return type (`any` above) is required: otherwise TypeScript complains about the usage of a private class definition. Recommended: define an interface instead of using `any`.
* `Type` is imported from the `@nestjs/common` package
* The `isAbstract: true` property indicates that SDL (Schema Definition Language statements) shouldn't be generated for this class. Note, you can set this property for other types as well to suppress SDL generation.

Here's how you could generate a concrete sub-class of the `BaseResolver`:

```typescript

@Resolver(() => Recipe)
export class RecipesResolver extends BaseResolver(Recipe) {
  constructor(private recipesService: RecipesService) {
    super();
  }
}
```

This construct would generated the following SDL:

```graphql

type Query {
  findAllRecipe: [Recipe!]!
}
```

#### Generics[#](/graphql/resolvers#generics)

We saw one use of generics above. This powerful TypeScript feature can be used to create useful abstractions. For example, here's a sample cursor-based pagination implementation based on [this documentation](https://graphql.org/learn/pagination/#pagination-and-edges):

```typescript

import { Field, ObjectType, Int } from '@nestjs/graphql';
import { Type } from '@nestjs/common';

interface IEdgeType<T> {
  cursor: string;
  node: T;
}

export interface IPaginatedType<T> {
  edges: IEdgeType<T>[];
  nodes: T[];
  totalCount: number;
  hasNextPage: boolean;
}

export function Paginated<T>(classRef: Type<T>): Type<IPaginatedType<T>> {
  @ObjectType(`${classRef.name}Edge`)
  abstract class EdgeType {
    @Field(() => String)
    cursor: string;

    @Field(() => classRef)
    node: T;
  }

  @ObjectType({ isAbstract: true })
  abstract class PaginatedType implements IPaginatedType<T> {
    @Field(() => [EdgeType], { nullable: true })
    edges: EdgeType[];

    @Field(() => [classRef], { nullable: true })
    nodes: T[];

    @Field(() => Int)
    totalCount: number;

    @Field()
    hasNextPage: boolean;
  }
  return PaginatedType as Type<IPaginatedType<T>>;
}
```

With the above base class defined, we can now easily create specialized types that inherit this behavior. For example:

```typescript

@ObjectType()
class PaginatedAuthor extends Paginated(Author) {}
```

#### Schema first[#](/graphql/resolvers#schema-first)

As mentioned in the [previous](/v10/graphql/quick-start) chapter, in the schema first approach we start by manually defining schema types in SDL (read [more](https://graphql.org/learn/schema/#type-language)). Consider the following SDL type definitions.

> **Hint** For convenience in this chapter, we've aggregated all of the SDL in one location (e.g., one `.graphql` file, as shown below). In practice, you may find it appropriate to organize your code in a modular fashion. For example, it can be helpful to create individual SDL files with type definitions representing each domain entity, along with related services, resolver code, and the Nest module definition class, in a dedicated directory for that entity. Nest will aggregate all the individual schema type definitions at run time.

```graphql

type Author {
  id: Int!
  firstName: String
  lastName: String
  posts: [Post]
}

type Post {
  id: Int!
  title: String!
  votes: Int
}

type Query {
  author(id: Int!): Author
}
```

#### Schema first resolver[#](/graphql/resolvers#schema-first-resolver)

The schema above exposes a single query - `author(id: Int!): Author`.

> **Hint** Learn more about GraphQL queries [here](https://graphql.org/learn/queries/).

Let's now create an `AuthorsResolver` class that resolves author queries:

authors/authors.resolver.ts

JS TS

```typescript

@Resolver('Author')
export class AuthorsResolver {
  constructor(
    private authorsService: AuthorsService,
    private postsService: PostsService,
  ) {}

  @Query()
  async author(@Args('id') id: number) {
    return this.authorsService.findOneById(id);
  }

  @ResolveField()
  async posts(@Parent() author) {
    const { id } = author;
    return this.postsService.findAll({ authorId: id });
  }
}
```

> **Hint** All decorators (e.g., `@Resolver`, `@ResolveField`, `@Args`, etc.) are exported from the `@nestjs/graphql` package.

> **Note** The logic inside the `AuthorsService` and `PostsService` classes can be as simple or sophisticated as needed. The main point of this example is to show how to construct resolvers and how they can interact with other providers.

The `@Resolver()` decorator is required. It takes an optional string argument with the name of a class. This class name is required whenever the class includes `@ResolveField()` decorators to inform Nest that the decorated method is associated with a parent type (the `Author` type in our current example). Alternatively, instead of setting `@Resolver()` at the top of the class, this can be done for each method:

```typescript

@Resolver('Author')
@ResolveField()
async posts(@Parent() author) {
  const { id } = author;
  return this.postsService.findAll({ authorId: id });
}
```

In this case (`@Resolver()` decorator at the method level), if you have multiple `@ResolveField()` decorators inside a class, you must add `@Resolver()` to all of them. This is not considered the best practice (as it creates extra overhead).

> **Hint** Any class name argument passed to `@Resolver()`**does not** affect queries (`@Query()` decorator) or mutations (`@Mutation()` decorator).

> **Warning** Using the `@Resolver` decorator at the method level is not supported with the **code first** approach.

In the above examples, the `@Query()` and `@ResolveField()` decorators are associated with GraphQL schema types based on the method name. For example, consider the following construction from the example above:

```typescript

@Query()
async author(@Args('id') id: number) {
  return this.authorsService.findOneById(id);
}
```

This generates the following entry for the author query in our schema (the query type uses the same name as the method name):

```graphql

type Query {
  author(id: Int!): Author
}
```

Conventionally, we would prefer to decouple these, using names like `getAuthor()` or `getPosts()` for our resolver methods. We can easily do this by passing the mapping name as an argument to the decorator, as shown below:

authors/authors.resolver.ts

JS TS

```typescript

@Resolver('Author')
export class AuthorsResolver {
  constructor(
    private authorsService: AuthorsService,
    private postsService: PostsService,
  ) {}

  @Query('author')
  async getAuthor(@Args('id') id: number) {
    return this.authorsService.findOneById(id);
  }

  @ResolveField('posts')
  async getPosts(@Parent() author) {
    const { id } = author;
    return this.postsService.findAll({ authorId: id });
  }
}
```

> **Hint** Nest CLI provides a generator (schematic) that automatically generates **all the boilerplate code** to help us avoid doing all of this, and make the developer experience much simpler. Read more about this feature [here](/v10/recipes/crud-generator).

#### Generating types[#](/graphql/resolvers#generating-types)

Assuming that we use the schema first approach and have enabled the typings generation feature (with `outputAs: 'class'` as shown in the [previous](/v10/graphql/quick-start) chapter), once you run the application it will generate the following file (in the location you specified in the `GraphQLModule.forRoot()` method). For example, in `src/graphql.ts`:

graphql.ts

JS TS

```typescript

export (class Author {
  id: number;
  firstName?: string;
  lastName?: string;
  posts?: Post[];
})
export class Post {
  id: number;
  title: string;
  votes?: number;
}

export abstract class IQuery {
  abstract author(id: number): Author | Promise<Author>;
}
```

By generating classes (instead of the default technique of generating interfaces), you can use declarative validation **decorators** in combination with the schema first approach, which is an extremely useful technique (read [more](/v10/techniques/validation)). For example, you could add `class-validator` decorators to the generated `CreatePostInput` class as shown below to enforce minimum and maximum string lengths on the `title` field:

```typescript

import { MinLength, MaxLength } from 'class-validator';

export class CreatePostInput {
  @MinLength(3)
  @MaxLength(50)
  title: string;
}
```

> **Notice** To enable auto-validation of your inputs (and parameters), use `ValidationPipe`. Read more about validation [here](/v10/techniques/validation) and more specifically about pipes [here](/v10/pipes).

However, if you add decorators directly to the automatically generated file, they will be **overwritten** each time the file is generated. Instead, create a separate file and simply extend the generated class.

```typescript

import { MinLength, MaxLength } from 'class-validator';
import { Post } from '../../graphql.ts';

export class CreatePostInput extends Post {
  @MinLength(3)
  @MaxLength(50)
  title: string;
}
```

#### GraphQL argument decorators[#](/graphql/resolvers#graphql-argument-decorators)

We can access the standard GraphQL resolver arguments using dedicated decorators. Below is a comparison of the Nest decorators and the plain Apollo parameters they represent.

|                            |                              |
| -------------------------- | ---------------------------- |
| `@Root()` and `@Parent()`  | `root`/`parent`              |
| `@Context(param?: string)` | `context` / `context[param]` |
| `@Info(param?: string)`    | `info` / `info[param]`       |
| `@Args(param?: string)`    | `args` / `args[param]`       |

```typescript

@Module({
  imports: [PostsModule],
  providers: [AuthorsService, AuthorsResolver],
})
export class AuthorsModule {}
```

> **Hint** It is helpful to organize your code by your so-called **domain model** (similar to the way you would organize entry points in a REST API). In this approach, keep your models (`ObjectType` classes), resolvers and services together within a Nest module representing the domain model. Keep all of these components in a single folder per module. When you do this, and use the [Nest CLI](/v10/cli/overview) to generate each element, Nest will wire all of these parts together (locating files in appropriate folders, generating entries in `provider` and `imports` arrays, etc.) automatically for you.

----
url: https://docs.nestjs.com/v7/faq/global-prefix
----

* [Global prefix](https://docs.nestjs.com/v7/faq/global-prefix#global-prefix)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/faq/global-prefix.md "Suggest Edits")

### Global prefix

To set a prefix for **every route** registered in an HTTP application, use the `setGlobalPrefix()` method of the `INestApplication` instance.

```typescript

const app = await NestFactory.create(AppModule);
app.setGlobalPrefix('v1');
```

----
url: https://docs.nestjs.com/v7/websockets/adapter
----

* [Adapters](https://docs.nestjs.com/v7/websockets/adapter#adapters)
* [Extend socket.io](https://docs.nestjs.com/v7/websockets/adapter#extend-socketio)
* [Ws library](https://docs.nestjs.com/v7/websockets/adapter#ws-library)
* [Advanced (custom adapter)](https://docs.nestjs.com/v7/websockets/adapter#advanced-custom-adapter)
* [Example](https://docs.nestjs.com/v7/websockets/adapter#example)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/websockets/adapter.md "Suggest Edits")

### Adapters

The WebSockets module is platform-agnostic, hence, you can bring your own library (or even a native implementation) by making use of `WebSocketAdapter` interface. This interface forces to implement few methods described in the following table:

|                        |                                                                 |
| ---------------------- | --------------------------------------------------------------- |
| `create`               | Creates a socket instance based on passed arguments             |
| `bindClientConnect`    | Binds the client connection event                               |
| `bindClientDisconnect` | Binds the client disconnection event (optional\*)               |
| `bindMessageHandlers`  | Binds the incoming message to the corresponding message handler |
| `close`                | Terminates a server instance                                    |

#### Extend socket.io[#](/websockets/adapter#extend-socketio)

The [socket.io](https://github.com/socketio/socket.io) package is wrapped in an `IoAdapter` class. What if you would like to enhance the basic functionality of the adapter? For instance, your technical requirements require a capability to broadcast events across multiple load-balanced instances of your web service. For this, you can extend `IoAdapter` and override a single method which responsibility is to instantiate new socket.io servers. But first of all, let's install the required package.

```bash

$ npm i --save socket.io-redis
```

Once the package is installed, we can create a `RedisIoAdapter` class.

```typescript

import { IoAdapter } from '@nestjs/platform-socket.io';
import * as redisIoAdapter from 'socket.io-redis';

export class RedisIoAdapter extends IoAdapter {
  createIOServer(port: number, options?: any): any {
    const server = super.createIOServer(port, options);
    const redisAdapter = redisIoAdapter({ host: 'localhost', port: 6379 });
    
    server.adapter(redisAdapter);
    return server;
  }
}
```

Afterward, simply switch to your newly created Redis adapter.

```typescript

const app = await NestFactory.create(AppModule);
app.useWebSocketAdapter(new RedisIoAdapter(app));
```

#### Ws library[#](/websockets/adapter#ws-library)

Another available adapter is a `WsAdapter` which in turn acts like a proxy between the framework and integrate blazing fast and thoroughly tested [ws](https://github.com/websockets/ws) library. This adapter is fully compatible with native browser WebSockets and is far faster than socket.io package. Unluckily, it has significantly fewer functionalities available out-of-the-box. In some cases, you may just don't necessarily need them though.

In order to use `ws`, we firstly have to install the required package:

```bash

$ npm i --save @nestjs/platform-ws
```

Once the package is installed, we can switch an adapter:

```typescript

const app = await NestFactory.create(AppModule);
app.useWebSocketAdapter(new WsAdapter(app));
```

> **Hint** The `WsAdapter` is imported from `@nestjs/platform-ws`.

#### Advanced (custom adapter)[#](/websockets/adapter#advanced-custom-adapter)

For demonstration purposes, we are going to integrate the [ws](https://github.com/websockets/ws) library manually. As mentioned, the adapter for this library is already created and is exposed from the `@nestjs/platform-ws` package as a `WsAdapter` class. Here is how the simplified implementation could potentially look like:

ws-adapter.ts

JS TS

```typescript

import * as WebSocket from 'ws';
import { WebSocketAdapter, INestApplicationContext } from '@nestjs/common';
import { MessageMappingProperties } from '@nestjs/websockets';
import { Observable, fromEvent, EMPTY } from 'rxjs';
import { mergeMap, filter } from 'rxjs/operators';

export class WsAdapter implements WebSocketAdapter {
  constructor(private app: INestApplicationContext) {}

  create(port: number, options: any = {}): any {
    return new ws.Server({ port, ...options });
  }

  bindClientConnect(server, callback: Function) {
    server.on('connection', callback);
  }

  bindMessageHandlers(
    client: WebSocket,
    handlers: MessageMappingProperties[],
    process: (data: any) => Observable<any>,
  ) {
    fromEvent(client, 'message')
      .pipe(
        mergeMap(data => this.bindMessageHandler(data, handlers, process)),
        filter(result => result),
      )
      .subscribe(response => client.send(JSON.stringify(response)));
  }

  bindMessageHandler(
    buffer,
    handlers: MessageMappingProperties[],
    process: (data: any) => Observable<any>,
  ): Observable<any> {
    const message = JSON.parse(buffer.data);
    const messageHandler = handlers.find(
      handler => handler.message === message.event,
    );
    if (!messageHandler) {
      return EMPTY;
    }
    return process(messageHandler.callback(message.data));
  }

  close(server) {
    server.close();
  }
}
```

> **Hint** When you want to take advantage of [ws](https://github.com/websockets/ws) library, use built-in `WsAdapter` instead of creating your own one.

Then, we can set up a custom adapter using `useWebSocketAdapter()` method:

main.ts

JS TS

```typescript

const app = await NestFactory.create(AppModule);
app.useWebSocketAdapter(new WsAdapter(app));
```

#### Example[#](/websockets/adapter#example)

A working example that uses `WsAdapter` is available [here](https://github.com/nestjs/nest/tree/master/sample/16-gateways-ws).

----
url: https://docs.nestjs.com/v7/cli/usages
----

* [CLI command reference](https://docs.nestjs.com/v7/cli/usages#cli-command-reference)
* [nest new](https://docs.nestjs.com/v7/cli/usages#nest-new)
* [nest generate](https://docs.nestjs.com/v7/cli/usages#nest-generate)
* [nest build](https://docs.nestjs.com/v7/cli/usages#nest-build)
* [nest start](https://docs.nestjs.com/v7/cli/usages#nest-start)
* [nest add](https://docs.nestjs.com/v7/cli/usages#nest-add)
* [nest update](https://docs.nestjs.com/v7/cli/usages#nest-update)
* [nest info](https://docs.nestjs.com/v7/cli/usages#nest-info)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/cli/usages.md "Suggest Edits")

### CLI command reference

#### nest new[#](/cli/usages#nest-new)

Creates a new (standard mode) Nest project.

```bash

$ nest new <name> [options]
$ nest n <name> [options]
```

| Argument | Description                 |
| -------- | --------------------------- |
| `<name>` | The name of the new project |

##### Options

| Option                                | Description                                                                                                |
| ------------------------------------- | ---------------------------------------------------------------------------------------------------------- |
| `--dry-run`                           | Reports changes that would be made, but does not change the filesystem. Alias: `-d`                        |
| `--skip-git`                          | Skip git repository initialization. Alias: `-g`                                                            |
| `--skip-install`                      | Skip package installation. Alias: `-s`                                                                     |
| `--package-manager [package-manager]` | Specify package manager. Use `npm` or `yarn`. Package manager must be installed globally. Alias: `-p`      |
| `--language [language]`               | Specify programming language (`TS` or `JS`). Alias: `-l`                                                   |
| `--collection [collectionName]`       | Specify schematics collection. Use package name of installed npm package containing schematic. Alias: `-c` |

#### nest generate[#](/cli/usages#nest-generate)

Generates and/or modifies files based on a schematic

```bash

$ nest generate <schematic> <name> [options]
$ nest g <schematic> <name> [options]
```

##### Arguments

| Argument      | Description                                                                                              |
| ------------- | -------------------------------------------------------------------------------------------------------- |
| `<schematic>` | The `schematic` or `collection:schematic` to generate. See the table below for the available schematics. |
| `<name>`      | The name of the generated component.                                                                     |

##### Schematics

| Name          | Alias | Description                                                                                                     |
| ------------- | ----- | --------------------------------------------------------------------------------------------------------------- |
| `app`         |       | Generate a new application within a monorepo (converting to monorepo if it's a standard structure).             |
| `library`     | `lib` | Generate a new library within a monorepo (converting to monorepo if it's a standard structure).                 |
| `class`       | `cl`  | Generate a new class.                                                                                           |
| `controller`  | `co`  | Generate a controller declaration.                                                                              |
| `decorator`   | `d`   | Generate a custom decorator.                                                                                    |
| `filter`      | `f`   | Generate a filter declaration.                                                                                  |
| `gateway`     | `ga`  | Generate a gateway declaration.                                                                                 |
| `guard`       | `gu`  | Generate a guard declaration.                                                                                   |
| `interface`   |       | Generate an interface.                                                                                          |
| `interceptor` | `in`  | Generate an interceptor declaration.                                                                            |
| `middleware`  | `mi`  | Generate a middleware declaration.                                                                              |
| `module`      | `mo`  | Generate a module declaration.                                                                                  |
| `pipe`        | `pi`  | Generate a pipe declaration.                                                                                    |
| `provider`    | `pr`  | Generate a provider declaration.                                                                                |
| `resolver`    | `r`   | Generate a resolver declaration.                                                                                |
| `resource`    | `res` | Generate a new CRUD resource. See the [CRUD (resource) generator](/v7/recipes/crud-generator) for more details. |
| `service`     | `s`   | Generate a service declaration.                                                                                 |

##### Options

| Option                          | Description                                                                                                |
| ------------------------------- | ---------------------------------------------------------------------------------------------------------- |
| `--dry-run`                     | Reports changes that would be made, but does not change the filesystem. Alias: `-d`                        |
| `--project [project]`           | Project that element should be added to. Alias: `-p`                                                       |
| `--flat`                        | Do not generate a folder for the element.                                                                  |
| `--collection [collectionName]` | Specify schematics collection. Use package name of installed npm package containing schematic. Alias: `-c` |
| `--spec`                        | Enforce spec files generation (default)                                                                    |
| `--no-spec`                     | Disable spec files generation                                                                              |

#### nest build[#](/cli/usages#nest-build)

Compiles an application or workspace into an output folder.

```bash

$ nest build <name> [options]
```

##### Arguments

| Argument | Description                       |
| -------- | --------------------------------- |
| `<name>` | The name of the project to build. |

##### Options

| Option            | Description                                       |
| ----------------- | ------------------------------------------------- |
| `--path [path]`   | Path to `tsconfig` file. Alias `-p`               |
| `--config [path]` | Path to `nest-cli` configuration file. Alias `-c` |
| `--watch`         | Run in watch mode (live-reload) Alias `-w`        |
| `--webpack`       | Use webpack for compilation.                      |
| `--webpackPath`   | Path to webpack configuration.                    |
| `--tsc`           | Force use `tsc` for compilation.                  |

#### nest start[#](/cli/usages#nest-start)

Compiles and runs an application (or default project in a workspace).

```bash

$ nest start <name> [options]
```

##### Arguments

| Argument | Description                     |
| -------- | ------------------------------- |
| `<name>` | The name of the project to run. |

##### Options

| Option                  | Description                                                                                                          |
| ----------------------- | -------------------------------------------------------------------------------------------------------------------- |
| `--path [path]`         | Path to `tsconfig` file. Alias `-p`                                                                                  |
| `--config [path]`       | Path to `nest-cli` configuration file. Alias `-c`                                                                    |
| `--watch`               | Run in watch mode (live-reload) Alias `-w`                                                                           |
| `--preserveWatchOutput` | Keep outdated console output in watch mode instead of clearing the screen. (`tsc` watch mode only)                   |
| `--watchAssets`         | Run in watch mode (live-reload), watching non-TS files (assets). See [Assets](cli/monorepo#assets) for more details. |
| `--debug [hostport]`    | Run in debug mode (with --inspect flag) Alias `-d`                                                                   |
| `--webpack`             | Use webpack for compilation.                                                                                         |
| `--webpackPath`         | Path to webpack configuration.                                                                                       |
| `--tsc`                 | Force use `tsc` for compilation.                                                                                     |
| `--exec [binary]`       | Binary to run (default: `node`). Alias `-e`                                                                          |

#### nest add[#](/cli/usages#nest-add)

Imports a library that has been packaged as a **nest library**, running its install schematic.

```bash

$ nest add <name> [options]
```

##### Arguments

| Argument | Description                        |
| -------- | ---------------------------------- |
| `<name>` | The name of the library to import. |

#### nest update[#](/cli/usages#nest-update)

Updates `@nestjs` dependencies in the `package.json``"dependencies"` list to their `@latest` version.

##### Options

| Option    | Description                                                        |
| --------- | ------------------------------------------------------------------ |
| `--force` | Do **upgrade** instead of update Alias `-f`                        |
| `--tag`   | Update to tagged version (use `@latest`, `@<tag>`, etc) Alias `-t` |

#### nest info[#](/cli/usages#nest-info)

Displays information about installed nest packages and other helpful system info. For example:

```bash

 _   _             _      ___  _____  _____  _     _____
| \ | |           | |    |_  |/  ___|/  __ \| |   |_   _|
|  \| |  ___  ___ | |_     | |\ `--. | /  \/| |     | |
| . ` | / _ \/ __|| __|    | | `--. \| |    | |     | |
| |\  ||  __/\__ \| |_ /\__/ //\__/ /| \__/\| |_____| |_
\_| \_/ \___||___/ \__|\____/ \____/  \____/\_____/\___/

[System Information]
OS Version : macOS High Sierra
NodeJS Version : v8.9.0
YARN Version : 1.5.1
[Nest Information]
microservices version : 6.0.0
websockets version : 6.0.0
testing version : 6.0.0
common version : 6.0.0
core version : 6.0.0
```

----
url: https://docs.nestjs.com/v5/techniques/configuration
----

### Configuration

The applications used to run in different **environments**. Depending on an environment, various sets of configuration variables should be used. For example, that's very likely that local environment relays on specific database credentials, valid solely for local db instance. In order to solve this issue, we used to take advantage of `.env` files, that hold key-value pairs, where each key represents a particular value since this approach is very convenient.

But when we use a `process` global object, it's difficult to keep our tests clean since tested class may directly use it. Another way is to create an abstraction layer, a `ConfigModule` that exposes a `ConfigService` with loaded configuration variables.

#### Installation

Certain platforms automatically attach our environment variables to the `process.env` global. However, in the local environment, we have to manually take care of it. In order to parse our environment files, we'll use a [dotenv](https://github.com/motdotla/dotenv) package.

TypeScript

```typescript

$ npm i --save dotenv
```

#### Service

Firstly, let's create a `ConfigService` class.

JS TS

TypeScript

```typescript

import * as dotenv from 'dotenv';
import * as fs from 'fs';

export class ConfigService {
  private readonly envConfig: { [key: string]: string };

  constructor(filePath: string) {
    this.envConfig = dotenv.parse(fs.readFileSync(filePath))
  }

  get(key: string): string {
    return this.envConfig[key];
  }
}
```

TypeScript

```typescript

import * as dotenv from 'dotenv';
import * as fs from 'fs';

export class ConfigService {
  constructor(filePath) {
    this.envConfig = dotenv.parse(fs.readFileSync(filePath))
  }

  get(key) {
    return this.envConfig[key];
  }
}
```

This class takes a single argument, a `filePath`, which is a path to your `.env` file. The `get()` method is provided to enable access to a private `envConfig` object that holds each property defined inside an environment file.

The last step is to create a `ConfigModule`.

JS TS

TypeScript

```typescript

import { Module } from '@nestjs/common';
import { ConfigService } from './config.service';

@Module({
  providers: [
    {
      provide: ConfigService,
      useValue: new ConfigService(`${process.env.NODE_ENV}.env`),
    },
  ],
  exports: [ConfigService],
})
export class ConfigModule {}
```

The `ConfigModule` registers a `ConfigService` and exports it as well. Additionally, we passed a path to the `.env` file. This path will be different depending on actual execution environment. Now you can simply inject `ConfigService` anywhere, and pull out a particular value based on a passed key. Sample `.env` file could look like below:

development.env

TypeScript

```typescript

DATABASE_USER=test
DATABASE_PASSWORD=test
```

#### Using the ConfigService

To access **environment variables** from our `ConfigService` we need to inject it. Therefore we firstly need to import the module.

app.module.ts

TypeScript

```typescript

@Module({
  imports: [ConfigModule],
  ...
})
```

Afterward, you can inject it using an injection token. By default, the token is equal to the class name (in our example `ConfigService`).

app.service.ts

TypeScript

```typescript

@Injectable()
export class AppService {
  private isAuthEnabled: boolean;
  constructor(config: ConfigService) {
    // Please take note that this check is case sensitive!
    this.isAuthEnabled = config.get('IS_AUTH_ENABLED') === 'true' ? true : false;
  }
}
    
```

> Instead of importing `ConfigModule` repeatingly in all your modules, you can also declare `ConfigModule` as a global module.

#### Advanced configuration

We just implemented a basic `ConfigService`. However, this approach has a couple of disadvantages, which we'll address now:

* missing names & types for the environment variables (no IntelliSense)
* a lack of **validation** of the provided `.env` file
* the env file provides booleans as string (`'true'`), and thus have to cast them to a `boolean` every time

#### Validation

We'll start with the validation of the provided environment variables. You can throw an error if required environment variables haven't been provided or if they don't meet your predefined requirements. For this purpose, we are going to use the npm package [Joi](https://github.com/hapijs/joi). With Joi, you define an object schema and validate JavaScript objects against it.

Install Joi and it's types (for **TypeScript** users):

```bash

$ npm install --save joi
$ npm install --save-dev @types/joi
```

Once the packages are installed, we can move to our `ConfigService`.

config.service.ts

TypeScript

```typescript

import * as Joi from 'joi';
import * as fs from 'fs';

export interface EnvConfig {
  [key: string]: string;
}

export class ConfigService {
  private readonly envConfig: EnvConfig;

  constructor(filePath: string) {
    const config = dotenv.parse(fs.readFileSync(filePath));
    this.envConfig = this.validateInput(config);
  }

  /**
   * Ensures all needed variables are set, and returns the validated JavaScript object
   * including the applied default values.
   */
  private validateInput(envConfig: EnvConfig): EnvConfig {
    const envVarsSchema: Joi.ObjectSchema = Joi.object({
      NODE_ENV: Joi.string()
        .valid(['development', 'production', 'test', 'provision'])
        .default('development'),
      PORT: Joi.number().default(3000),
      API_AUTH_ENABLED: Joi.boolean().required(),
    });

    const { error, value: validatedEnvConfig } = Joi.validate(
      envConfig,
      envVarsSchema,
    );
    if (error) {
      throw new Error(`Config validation error: ${error.message}`);
    }
    return validatedEnvConfig;
  }
}
```

Since we set default values for `NODE_ENV` and `PORT` the validation will not fail if we don't provide these variables in the environment file. Nevertheless, we need to explicitly provide `API_AUTH_ENABLED`. The validation will also throw an error if we have variables in our .env file which aren't part of the schema. Additionally, Joi tries to convert the env strings into the right type.

#### Class properties

For each config property, we have to add a getter function.

config.service.ts

TypeScript

```typescript

get isApiAuthEnabled(): boolean {
  return Boolean(this.envConfig.API_AUTH_ENABLED);
}
```

#### Usage example

Now we can directly access the class properties.

app.service.ts

TypeScript

```typescript

@Injectable()
export class AppService {
  constructor(config: ConfigService) {
    if (config.isApiAuthEnabled) {
      // Authorization is enabled
    }
  }
}
    
```

* Configuration
* Installation
* Service
* Using the ConfigService
* Advanced configuration
* Validation
* Class properties
* Usage example

----
url: https://docs.nestjs.com/v11/techniques/streaming-files
----

* [Streaming files](https://docs.nestjs.com/v11/techniques/streaming-files#streaming-files)
* [Streamable File class](https://docs.nestjs.com/v11/techniques/streaming-files#streamable-file-class)
* [Cross-platform support](https://docs.nestjs.com/v11/techniques/streaming-files#cross-platform-support)
* [Example](https://docs.nestjs.com/v11/techniques/streaming-files#example)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/techniques/streaming-files.md "Suggest Edits")

### Streaming files

> **Note** This chapter shows how you can stream files from your **HTTP application**. The examples presented below do not apply to GraphQL or Microservice applications.

There may be times where you would like to send back a file from your REST API to the client. To do this with Nest, normally you'd do the following:

```ts

@Controller('file')
export class FileController {
  @Get()
  getFile(@Res() res: Response) {
    const file = createReadStream(join(process.cwd(), 'package.json'));
    file.pipe(res);
  }
}
```

But in doing so you end up losing access to your post-controller interceptor logic. To handle this, you can return a `StreamableFile` instance and under the hood, the framework will take care of piping the response.

#### Streamable File class[#](/techniques/streaming-files#streamable-file-class)

A `StreamableFile` is a class that holds onto the stream that is to be returned. To create a new `StreamableFile`, you can pass either a `Buffer` or a `Stream` to the `StreamableFile` constructor.

> **hint** The `StreamableFile` class can be imported from `@nestjs/common`.

#### Cross-platform support[#](/techniques/streaming-files#cross-platform-support)

Fastify, by default, can support sending files without needing to call `stream.pipe(res)`, so you don't need to use the `StreamableFile` class at all. However, Nest supports the use of `StreamableFile` in both platform types, so if you end up switching between Express and Fastify there's no need to worry about compatibility between the two engines.

#### Example[#](/techniques/streaming-files#example)

You can find a simple example of returning the `package.json` as a file instead of a JSON below, but the idea extends out naturally to images, documents, and any other file type.

```ts

import { Controller, Get, StreamableFile } from '@nestjs/common';
import { createReadStream } from 'node:fs';
import { join } from 'node:path';

@Controller('file')
export class FileController {
  @Get()
  getFile(): StreamableFile {
    const file = createReadStream(join(process.cwd(), 'package.json'));
    return new StreamableFile(file);
  }
}
```

The default content type (the value for `Content-Type` HTTP response header) is `application/octet-stream`. If you need to customize this value you can use the `type` option from `StreamableFile`, or use the `res.set` method or the [`@Header()`](/controllers#response-headers) decorator, like this:

```ts

import { Controller, Get, StreamableFile, Res } from '@nestjs/common';
import { createReadStream } from 'node:fs';
import { join } from 'node:path';
import type { Response } from 'express'; // Assuming that we are using the ExpressJS HTTP Adapter

@Controller('file')
export class FileController {
  @Get()
  getFile(): StreamableFile {
    const file = createReadStream(join(process.cwd(), 'package.json'));
    return new StreamableFile(file, {
      type: 'application/json',
      disposition: 'attachment; filename="package.json"',
      // If you want to define the Content-Length value to another value instead of file's length:
      // length: 123,
    });
  }

  // Or even:
  @Get()
  getFileChangingResponseObjDirectly(@Res({ passthrough: true }) res: Response): StreamableFile {
    const file = createReadStream(join(process.cwd(), 'package.json'));
    res.set({
      'Content-Type': 'application/json',
      'Content-Disposition': 'attachment; filename="package.json"',
    });
    return new StreamableFile(file);
  }

  // Or even:
  @Get()
  @Header('Content-Type', 'application/json')
  @Header('Content-Disposition', 'attachment; filename="package.json"')
  getFileUsingStaticValues(): StreamableFile {
    const file = createReadStream(join(process.cwd(), 'package.json'));
    return new StreamableFile(file);
  }  
}
```

----
url: https://docs.nestjs.com/v7/cli/libraries
----

* [Libraries](https://docs.nestjs.com/v7/cli/libraries#libraries)
* [Nest libraries](https://docs.nestjs.com/v7/cli/libraries#nest-libraries)
* [Creating libraries](https://docs.nestjs.com/v7/cli/libraries#creating-libraries)
* [Using libraries](https://docs.nestjs.com/v7/cli/libraries#using-libraries)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/cli/libraries.md "Suggest Edits")

### Libraries

Many applications need to solve the same general problems, or re-use a modular component in several different contexts. Nest has a few ways of addressing this, but each works at a different level to solve the problem in a way that helps meet different architectural and organizational objectives.

Nest [modules](/v7/modules) are useful for providing an execution context that enables sharing components within a single application. Modules can also be packaged with [npm](https://npmjs.com) to create a reusable library that can be installed in different projects. This can be an effective way to distribute configurable, re-usable libraries that can be used by different, loosely connected or unaffiliated organizations (e.g., by distributing/installing 3rd party libraries).

```bash

nest g library my-library
```

When you run the command, the `library` schematic prompts you for a prefix (AKA alias) for the library:

```bash

What prefix would you like to use for the library (default: @app)?
```

```javascript

...
{
    "my-library": {
      "type": "library",
      "root": "libs/my-library",
      "entryFile": "index",
      "sourceRoot": "libs/my-library/src",
      "compilerOptions": {
        "tsConfigPath": "libs/my-library/tsconfig.lib.json"
      }
}
...
```

There are two differences in `nest-cli.json` metadata between libraries and applications:

* the `"type"` property is set to `"library"` instead of `"application"`
* the `"entryFile"` property is set to `"index"` instead of `"main"`

These differences key the build process to handle libraries appropriately. For example, a library exports its functions through the `index.js` file.

As with application-type projects, libraries each have their own `tsconfig.lib.json` file that extends the root (monorepo-wide) `tsconfig.json` file. You can modify this file, if necessary, to provide library-specific compiler options.

You can build the library with the CLI command:

```bash

nest build my-library
```

#### Using libraries[#](/cli/libraries#using-libraries)

With the automatically generated configuration files in place, using libraries is straightforward. How would we import `MyLibraryService` from the `my-library` library into the `my-project` application?

First, note that using library modules is the same as using any other Nest module. What the monorepo does is manage paths in a way that importing libraries and generating builds is now transparent. To use `MyLibraryService`, we need to import its declaring module. We can modify `my-project/src/app.module.ts` as follows to import `MyLibraryModule`.

```typescript

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { MyLibraryModule } from '@app/my-library';

@Module({
  imports: [MyLibraryModule],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}
```

Notice above that we've used a path alias of `@app` in the ES module `import` line, which was the `prefix` we supplied with the `nest g library` command above. Under the covers, Nest handles this through tsconfig path mapping. When adding a library, Nest updates the global (monorepo) `tsconfig.json` file's `"paths"` key like this:

```javascript

"paths": {
    "@app/my-library": [
        "libs/my-library/src"
    ],
    "@app/my-library/*": [
        "libs/my-library/src/*"
    ]
}
```

So, in a nutshell, the combination of the monorepo and library features has made it easy and intuitive to include library modules into applications.

This same mechanism enables building and deploying applications that compose libraries. Once you've imported the `MyLibraryModule`, running `nest build` handles all the module resolution automatically and bundles the app along with any library dependencies, for deployment. The default compiler for a monorepo is **webpack**, so the resulting distribution file is a single file that bundles all of the transpiled JavaScript files into a single file. You can also switch to `tsc` as described [here](https://docs.nestjs.com/cli/monorepo#global-compiler-options).

----
url: https://docs.nestjs.com/v5/graphql/tooling
----

### Tooling

In the GraphQL world, a lot of articles complain how to handle stuff like an **authentication**, or **side-effects** of operations. Should we put it inside the business logic? Shall we use a higher-order function to enhance queries and mutations as well, for example, with an authorization logic? Or maybe use [schema directives](https://www.apollographql.com/docs/apollo-server/v2/features/directives.html). There is no single answer anyway.

Nest ecosystem is trying to help with this issue using existing features like [guards](/v5/guards) and [interceptors](/v5/interceptors). The idea behind them is to reduce redundancy and also, supply you with tooling that helps creating well-structured, readable, and consistent applications.

#### Overview

You can use either [guards](/v5/guards), [interceptors](/v5/interceptors), and [pipes](/v5/pipes) in the same fashion as in the simple REST application. Additionally, you are able to easily create your own decorators, by leveraging [custom decorators](/v5/custom-decorators) feature. They all act equivalently. Let's have a look at the following code:

TypeScript

```typescript

@Query('author')
@UseGuards(AuthGuard)
async getAuthor(@Args('id', ParseIntPipe) id: number) {
  return await this.authorsService.findOneById(id);
}
```

As you can see, GraphQL works pretty well with both guards and pipes. Thanks to that you can, for instance, move your authentication logic to the guard, or even reuse the same guard class as in the REST application. The interceptors works in the exact same way:

TypeScript

```typescript

@Mutation()
@UseInterceptors(EventsInterceptor)
async upvotePost(@Args('postId') postId: number) {
  return await this.postsService.upvoteById({ id: postId });
}
```

#### Execution context

However, the `ExecutionContext` received by both guards and interceptors is somewhat different. GraphQL resolvers have a separate set of arguments, respectively, `root`, `args`, `context`, and `info`. Hence, we need to transform given `ExecutionContext` to `GqlExecutionContext`, which is basically very simple.

TypeScript

```typescript

import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common';
import { GqlExecutionContext } from '@nestjs/graphql';

@Injectable()
export class AuthGuard implements CanActivate {
  canActivate(context: ExecutionContext): boolean {
    const ctx = GqlExecutionContext.create(context);
    return true;
  }
}
```

`GqlExecutionContext` exposes corresponding methods for each argument, like `getArgs()`, `getContext()`, and so on. Now we can effortlessly pick up every argument specific for currently processed request.

#### Custom decorators

As mentioned before, the [custom decorators](/v5/custom-decorators) feature works like a charm with GraphQL resolvers as well. Though, the factory function takes an array of arguments, instead of a `request` object.

TypeScript

```typescript

export const User = createParamDecorator(
  (data, [root, args, ctx, info]) => ctx.user,
);
```

And then:

TypeScript

```typescript

@Mutation()
async upvotePost(
  @User() user: UserEntity,
  @Args('postId') postId: number,
) {}
```

* Tooling
* Overview
* Execution context
* Custom decorators

----
url: https://docs.nestjs.com/
----

[Skip to content](#content)

On this page

* [Introduction](https://docs.nestjs.com/#introduction)
* [Philosophy](https://docs.nestjs.com/#philosophy)
* [Installation](https://docs.nestjs.com/#installation)
* [Alternatives](https://docs.nestjs.com/#alternatives)

[](https://srv.carbonads.net/ads/click/x/GTND4277CVSDE23NCWALYKQUF67D623NCAYDVZ3JCAAI6KQLF6YDCKJKC6BIE23YCWBIL537F67DP23EFTBI623MHEYI55QLCYAI6K3ECTNCYBZ52K)[Prove you can build it. Not just explain it. Earn a microcredential for free. ](https://srv.carbonads.net/ads/click/x/GTND4277CVSDE23NCWALYKQUF67D623NCAYDVZ3JCAAI6KQLF6YDCKJKC6BIE23YCWBIL537F67DP23EFTBI623MHEYI55QLCYAI6K3ECTNCYBZ52K)[ads via Carbon](http://carbonads.net/?utm_source=nestjscom\&utm_medium=ad_via_link\&utm_campaign=in_unit\&utm_term=carbon)

### Introduction

Nest (NestJS) is a framework for building efficient, scalable [Node.js](https://nodejs.org/) server-side applications. It uses progressive JavaScript, is built with and fully supports [TypeScript](https://www.typescriptlang.org/) (while still letting you write plain JavaScript), and combines elements of OOP (object-oriented programming), FP (functional programming), and FRP (functional reactive programming).

Under the hood, Nest uses robust HTTP server frameworks such as [Express](https://expressjs.com/) (the default), and can optionally be configured to use [Fastify](https://github.com/fastify/fastify) instead.

Nest provides a level of abstraction above these common Node.js frameworks (Express and Fastify), but also exposes their APIs directly to the developer. This gives you the freedom to use the myriad third-party modules available for the underlying platform.

#### Philosophy[#](/#philosophy)

In recent years, thanks to Node.js, JavaScript has become the "lingua franca" of the web for both frontend and backend applications. This has given rise to projects like [Angular](https://angular.dev/), [React](https://github.com/facebook/react), and [Vue](https://github.com/vuejs/core), which improve developer productivity and enable the creation of fast, testable, and extensible frontend applications. However, while plenty of excellent libraries, helpers, and tools exist for Node.js (and server-side JavaScript), none of them effectively solves the main problem of **architecture**.

Nest provides an out-of-the-box application architecture that lets developers and teams create highly testable, scalable, loosely coupled, and maintainable applications. The architecture is heavily inspired by Angular.

#### Installation[#](/#installation)

To get started, you can either scaffold the project with the [Nest CLI](/cli/overview) or [clone a starter project](/#alternatives). Both produce the same outcome.

To scaffold the project with the Nest CLI, run the following commands. They create a new project directory and populate it with the initial core Nest files and supporting modules, giving your project a conventional base structure. We recommend the **Nest CLI** for first-time users, and the [First steps](/first-steps) chapter continues with this approach.

```bash

$ npm i -g @nestjs/cli
$ nest new project-name
```

#### Alternatives[#](/#alternatives)

Alternatively, you can install the TypeScript starter project with **Git**:

```bash

$ git clone https://github.com/nestjs/typescript-starter.git project
$ cd project
$ npm install
$ npm run start
```

> **Hint** To clone the repository without its Git history, use [degit](https://github.com/Rich-Harris/degit).

Open your browser and navigate to [`http://localhost:3000/`](http://localhost:3000/).

To install the JavaScript flavor of the starter project, use `javascript-starter.git` in the command sequence above.

You can also start a new project from scratch by installing the core and supporting packages yourself. In that case, you need to set up the project boilerplate files on your own. At a minimum, you need these dependencies: `@nestjs/core`, `@nestjs/common`, `rxjs`, and `reflect-metadata`. For a walkthrough of creating a complete project this way, see [5 steps to create a bare minimum NestJS app from scratch](https://dev.to/micalevisk/5-steps-to-create-a-bare-minimum-nestjs-app-from-scratch-5c3b).

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/introduction.md)

----
url: https://docs.nestjs.com/v10/graphql/directives
----

* [Directives](https://docs.nestjs.com/v10/graphql/directives#directives)
* [Custom directives](https://docs.nestjs.com/v10/graphql/directives#custom-directives)
* [Code first](https://docs.nestjs.com/v10/graphql/directives#code-first)
* [Schema first](https://docs.nestjs.com/v10/graphql/directives#schema-first)

```typescript

import { getDirective, MapperKind, mapSchema } from '@graphql-tools/utils';
import { defaultFieldResolver, GraphQLSchema } from 'graphql';

export function upperDirectiveTransformer(
  schema: GraphQLSchema,
  directiveName: string,
) {
  return mapSchema(schema, {
    [MapperKind.OBJECT_FIELD]: (fieldConfig) => {
      const upperDirective = getDirective(
        schema,
        fieldConfig,
        directiveName,
      )?.[0];

      if (upperDirective) {
        const { resolve = defaultFieldResolver } = fieldConfig;

        // Replace the original resolver with a function that *first* calls
        // the original resolver, then converts its result to upper case
        fieldConfig.resolve = async function (source, args, context, info) {
          const result = await resolve(source, args, context, info);
          if (typeof result === 'string') {
            return result.toUpperCase();
          }
          return result;
        };
        return fieldConfig;
      }
    },
  });
}
```

Now, apply the `upperDirectiveTransformer` transformation function in the `GraphQLModule#forRoot` method using the `transformSchema` function:

```typescript

GraphQLModule.forRoot({
  // ...
  transformSchema: (schema) => upperDirectiveTransformer(schema, 'upper'),
});
```

Once registered, the `@upper` directive can be used in our schema. However, the way you apply the directive will vary depending on the approach you use (code first or schema first).

#### Code first[#](/graphql/directives#code-first)

In the code first approach, use the `@Directive()` decorator to apply the directive.

```typescript

@Directive('@upper')
@Field()
title: string;
```

> **Hint** The `@Directive()` decorator is exported from the `@nestjs/graphql` package.

Directives can be applied on fields, field resolvers, input and object types, as well as queries, mutations, and subscriptions. Here's an example of the directive applied on the query handler level:

```typescript

@Directive('@deprecated(reason: "This query will be removed in the next version")')
@Query(() => Author, { name: 'author' })
async getAuthor(@Args({ name: 'id', type: () => Int }) id: number) {
  return this.authorsService.findOneById(id);
}
```

> **Warning** Directives applied through the `@Directive()` decorator will not be reflected in the generated schema definition file.

Lastly, make sure to declare directives in the `GraphQLModule`, as follows:

```typescript

GraphQLModule.forRoot({
  // ...,
  transformSchema: schema => upperDirectiveTransformer(schema, 'upper'),
  buildSchemaOptions: {
    directives: [
      new GraphQLDirective({
        name: 'upper',
        locations: [DirectiveLocation.FIELD_DEFINITION],
      }),
    ],
  },
}),
```

> **Hint** Both `GraphQLDirective` and `DirectiveLocation` are exported from the `graphql` package.

#### Schema first[#](/graphql/directives#schema-first)

In the schema first approach, apply directives directly in SDL.

```graphql

directive @upper on FIELD_DEFINITION

type Post {
  id: Int!
  title: String! @upper
  votes: Int
}
```

----
url: https://docs.nestjs.com/v9/cli/usages
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [CLI command reference](https://docs.nestjs.com/v9/cli/usages#cli-command-reference)
* [nest new](https://docs.nestjs.com/v9/cli/usages#nest-new)
* [nest generate](https://docs.nestjs.com/v9/cli/usages#nest-generate)
* [nest build](https://docs.nestjs.com/v9/cli/usages#nest-build)
* [nest start](https://docs.nestjs.com/v9/cli/usages#nest-start)
* [nest add](https://docs.nestjs.com/v9/cli/usages#nest-add)
* [nest info](https://docs.nestjs.com/v9/cli/usages#nest-info)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/cli/usages.md "Suggest Edits")

### CLI command reference

#### nest new[#](/cli/usages#nest-new)

Creates a new (standard mode) Nest project.

```bash

$ nest new <name> [options]
$ nest n <name> [options]
```

| Argument | Description                 |
| -------- | --------------------------- |
| `<name>` | The name of the new project |

##### Options

| Option                                | Description                                                                                                                                                                                          |
| ------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--dry-run`                           | Reports changes that would be made, but does not change the filesystem. Alias: `-d`                                                                                                                  |
| `--skip-git`                          | Skip git repository initialization. Alias: `-g`                                                                                                                                                      |
| `--skip-install`                      | Skip package installation. Alias: `-s`                                                                                                                                                               |
| `--package-manager [package-manager]` | Specify package manager. Use `npm`, `yarn`, or `pnpm`. Package manager must be installed globally. Alias: `-p`                                                                                       |
| `--language [language]`               | Specify programming language (`TS` or `JS`). Alias: `-l`                                                                                                                                             |
| `--collection [collectionName]`       | Specify schematics collection. Use package name of installed npm package containing schematic. Alias: `-c`                                                                                           |
| `--strict`                            | Start the project with the following TypeScript compiler flags enabled: `strictNullChecks`, `noImplicitAny`, `strictBindCallApply`, `forceConsistentCasingInFileNames`, `noFallthroughCasesInSwitch` |

#### nest generate[#](/cli/usages#nest-generate)

Generates and/or modifies files based on a schematic

```bash

$ nest generate <schematic> <name> [options]
$ nest g <schematic> <name> [options]
```

##### Arguments

| Argument      | Description                                                                                              |
| ------------- | -------------------------------------------------------------------------------------------------------- |
| `<schematic>` | The `schematic` or `collection:schematic` to generate. See the table below for the available schematics. |
| `<name>`      | The name of the generated component.                                                                     |

##### Schematics

| Name          | Alias | Description                                                                                                     |
| ------------- | ----- | --------------------------------------------------------------------------------------------------------------- |
| `app`         |       | Generate a new application within a monorepo (converting to monorepo if it's a standard structure).             |
| `library`     | `lib` | Generate a new library within a monorepo (converting to monorepo if it's a standard structure).                 |
| `class`       | `cl`  | Generate a new class.                                                                                           |
| `controller`  | `co`  | Generate a controller declaration.                                                                              |
| `decorator`   | `d`   | Generate a custom decorator.                                                                                    |
| `filter`      | `f`   | Generate a filter declaration.                                                                                  |
| `gateway`     | `ga`  | Generate a gateway declaration.                                                                                 |
| `guard`       | `gu`  | Generate a guard declaration.                                                                                   |
| `interface`   | `itf` | Generate an interface.                                                                                          |
| `interceptor` | `itc` | Generate an interceptor declaration.                                                                            |
| `middleware`  | `mi`  | Generate a middleware declaration.                                                                              |
| `module`      | `mo`  | Generate a module declaration.                                                                                  |
| `pipe`        | `pi`  | Generate a pipe declaration.                                                                                    |
| `provider`    | `pr`  | Generate a provider declaration.                                                                                |
| `resolver`    | `r`   | Generate a resolver declaration.                                                                                |
| `resource`    | `res` | Generate a new CRUD resource. See the [CRUD (resource) generator](/v9/recipes/crud-generator) for more details. |
| `service`     | `s`   | Generate a service declaration.                                                                                 |

##### Options

| Option                          | Description                                                                                                |
| ------------------------------- | ---------------------------------------------------------------------------------------------------------- |
| `--dry-run`                     | Reports changes that would be made, but does not change the filesystem. Alias: `-d`                        |
| `--project [project]`           | Project that element should be added to. Alias: `-p`                                                       |
| `--flat`                        | Do not generate a folder for the element.                                                                  |
| `--collection [collectionName]` | Specify schematics collection. Use package name of installed npm package containing schematic. Alias: `-c` |
| `--spec`                        | Enforce spec files generation (default)                                                                    |
| `--no-spec`                     | Disable spec files generation                                                                              |

#### nest build[#](/cli/usages#nest-build)

Compiles an application or workspace into an output folder.

Also, the `build` command is responsible for:

* mapping paths (if using path aliases) via `tsconfig-paths`
* annotating DTOs with OpenAPI decorators (if `@nestjs/swagger` CLI plugin is enabled)
* annotating DTOs with GraphQL decorators (if `@nestjs/graphql` CLI plugin is enabled)

```bash

$ nest build <name> [options]
```

##### Arguments

| Argument | Description                       |
| -------- | --------------------------------- |
| `<name>` | The name of the project to build. |

##### Options

| Option            | Description                                                                                                                      |
| ----------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| `--path [path]`   | Path to `tsconfig` file. Alias `-p`                                                                                              |
| `--config [path]` | Path to `nest-cli` configuration file. Alias `-c`                                                                                |
| `--watch`         | Run in watch mode (live-reload). If you're using `tsc` for compilation, you can type `rs` to restart the application. Alias `-w` |
| `--webpack`       | Use webpack for compilation.                                                                                                     |
| `--webpackPath`   | Path to webpack configuration.                                                                                                   |
| `--tsc`           | Force use `tsc` for compilation.                                                                                                 |

#### nest start[#](/cli/usages#nest-start)

Compiles and runs an application (or default project in a workspace).

```bash

$ nest start <name> [options]
```

##### Arguments

| Argument | Description                     |
| -------- | ------------------------------- |
| `<name>` | The name of the project to run. |

##### Options

| Option                  | Description                                                                                                          |
| ----------------------- | -------------------------------------------------------------------------------------------------------------------- |
| `--path [path]`         | Path to `tsconfig` file. Alias `-p`                                                                                  |
| `--config [path]`       | Path to `nest-cli` configuration file. Alias `-c`                                                                    |
| `--watch`               | Run in watch mode (live-reload) Alias `-w`                                                                           |
| `--preserveWatchOutput` | Keep outdated console output in watch mode instead of clearing the screen. (`tsc` watch mode only)                   |
| `--watchAssets`         | Run in watch mode (live-reload), watching non-TS files (assets). See [Assets](cli/monorepo#assets) for more details. |
| `--debug [hostport]`    | Run in debug mode (with --inspect flag) Alias `-d`                                                                   |
| `--webpack`             | Use webpack for compilation.                                                                                         |
| `--webpackPath`         | Path to webpack configuration.                                                                                       |
| `--tsc`                 | Force use `tsc` for compilation.                                                                                     |
| `--exec [binary]`       | Binary to run (default: `node`). Alias `-e`                                                                          |

#### nest add[#](/cli/usages#nest-add)

Imports a library that has been packaged as a **nest library**, running its install schematic.

```bash

$ nest add <name> [options]
```

##### Arguments

| Argument | Description                        |
| -------- | ---------------------------------- |
| `<name>` | The name of the library to import. |

#### nest info[#](/cli/usages#nest-info)

Displays information about installed nest packages and other helpful system info. For example:

```bash

$ nest info
```

```bash

 _   _             _      ___  _____  _____  _     _____
| \ | |           | |    |_  |/  ___|/  __ \| |   |_   _|
|  \| |  ___  ___ | |_     | |\ `--. | /  \/| |     | |
| . ` | / _ \/ __|| __|    | | `--. \| |    | |     | |
| |\  ||  __/\__ \| |_ /\__/ //\__/ /| \__/\| |_____| |_
\_| \_/ \___||___/ \__|\____/ \____/  \____/\_____/\___/

[System Information]
OS Version : macOS High Sierra
NodeJS Version : v8.9.0
YARN Version : 1.5.1
[Nest Information]
microservices version : 6.0.0
websockets version : 6.0.0
testing version : 6.0.0
common version : 6.0.0
core version : 6.0.0
```

----
url: https://docs.nestjs.com/v7/graphql/subscriptions
----

* [Subscriptions](https://docs.nestjs.com/v7/graphql/subscriptions#subscriptions)
* [Enable subscriptions](https://docs.nestjs.com/v7/graphql/subscriptions#enable-subscriptions)
* [Code first](https://docs.nestjs.com/v7/graphql/subscriptions#code-first)
* [Publishing](https://docs.nestjs.com/v7/graphql/subscriptions#publishing)
* [Filtering subscriptions](https://docs.nestjs.com/v7/graphql/subscriptions#filtering-subscriptions)
* [Mutating subscription payloads](https://docs.nestjs.com/v7/graphql/subscriptions#mutating-subscription-payloads)
* [Schema first](https://docs.nestjs.com/v7/graphql/subscriptions#schema-first)
* [PubSub](https://docs.nestjs.com/v7/graphql/subscriptions#pubsub)
* [Customize subscriptions server](https://docs.nestjs.com/v7/graphql/subscriptions#customize-subscriptions-server)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/subscriptions.md "Suggest Edits")

### Subscriptions

In addition to fetching data using queries and modifying data using mutations, the GraphQL spec supports a third operation type, called `subscription`. GraphQL subscriptions are a way to push data from the server to the clients that choose to listen to real time messages from the server. Subscriptions are similar to queries in that they specify a set of fields to be delivered to the client, but instead of immediately returning a single answer, a channel is opened and a result is sent to the client every time a particular event happens on the server.

A common use case for subscriptions is notifying the client side about particular events, for example the creation of a new object, updated fields and so on (read more [here](https://www.apollographql.com/docs/react/data/subscriptions)).

#### Enable subscriptions[#](/graphql/subscriptions#enable-subscriptions)

To enable subscriptions, set the `installSubscriptionHandlers` property to `true`.

```typescript

GraphQLModule.forRoot({
  installSubscriptionHandlers: true,
}),
```

#### Code first[#](/graphql/subscriptions#code-first)

To create a subscription using the code first approach, we use the `@Subscription()` decorator and the `PubSub` class from the `graphql-subscriptions` package, which provides a simple **publish/subscribe API**.

The following subscription handler takes care of **subscribing** to an event by calling `PubSub#asyncIterator`. This method takes a single argument, the `triggerName`, which corresponds to an event topic name.

```typescript

const pubSub = new PubSub();

@Resolver(of => Author)
export class AuthorResolver {
  // ...
  @Subscription(returns => Comment)
  commentAdded() {
    return pubSub.asyncIterator('commentAdded');
  }
}
```

> **Hint** All decorators are exported from the `@nestjs/graphql` package, while the `PubSub` class is exported from the `graphql-subscriptions` package.

> **Note**`PubSub` is a class that exposes a simple `publish` and `subscribe API`. Read more about it [here](https://www.apollographql.com/docs/graphql-subscriptions/setup.html). Note that the Apollo docs warn that the default implementation is not suitable for production (read more [here](https://github.com/apollographql/graphql-subscriptions#getting-started-with-your-first-subscription)). Production apps should use a `PubSub` implementation backed by an external store (read more [here](https://github.com/apollographql/graphql-subscriptions#pubsub-implementations)).

This will result in generating the following part of the GraphQL schema in SDL:

```graphql

type Subscription {
  commentAdded(): Comment!
}
```

Note that subscriptions, by definition, return an object with a single top level property whose key is the name of the subscription. This name is either inherited from the name of the subscription handler method (i.e., `commentAdded` above), or is provided explicitly by passing an option with the key `name` as the second argument to the `@Subscription()` decorator, as shown below.

```typescript

  @Subscription(returns => Comment, {
    name: 'commentAdded',
  })
  addCommentHandler() {
    return pubSub.asyncIterator('commentAdded');
  }
```

This construct produces the same SDL as the previous code sample, but allows us to decouple the method name from the subscription.

#### Publishing[#](/graphql/subscriptions#publishing)

Now, to publish the event, we use the `PubSub#publish` method. This is often used within a mutation to trigger a client-side update when a part of the object graph has changed. For example:

posts/posts.resolver.ts

JS TS

```typescript

@Mutation(returns => Post)
async addComment(
  @Args('postId', { type: () => Int }) postId: number,
  @Args('comment', { type: () => Comment }) comment: CommentInput,
) {
  const newComment = this.commentsService.addComment({ id: postId, comment });
  pubSub.publish('commentAdded', { commentAdded: newComment });
  return newComment;
}
```

The `PubSub#publish` method takes a `triggerName` (again, think of this as an event topic name) as the first parameter, and an event payload as the second parameter. As mentioned, the subscription, by definition, returns a value and that value has a shape. Look again at the generated SDL for our `commentAdded` subscription:

```graphql

type Subscription {
  commentAdded(): Comment!
}
```

This tells us that the subscription must return an object with a top-level property name of `commentAdded` that has a value which is a `Comment` object. The important point to note is that the shape of the event payload emitted by the `PubSub#publish` method must correspond to the shape of the value expected to return from the subscription. So, in our example above, the `pubSub.publish('commentAdded', { commentAdded: newComment })` statement publishes a `commentAdded` event with the appropriately shaped payload. If these shapes don't match, your subscription will fail during the GraphQL validation phase.

#### Filtering subscriptions[#](/graphql/subscriptions#filtering-subscriptions)

To filter out specific events, set the `filter` property to a filter function. This function acts similar to the function passed to an array `filter`. It takes two arguments: `payload` containing the event payload (as sent by the event publisher), and `variables` taking any arguments passed in during the subscription request. It returns a boolean determining whether this event should be published to client listeners.

```typescript

@Subscription(returns => Comment, {
  filter: (payload, variables) =>
    payload.commentAdded.title === variables.title,
})
commentAdded(@Args('title') title: string) {
  return pubSub.asyncIterator('commentAdded');
}
```

#### Mutating subscription payloads[#](/graphql/subscriptions#mutating-subscription-payloads)

To mutate the published event payload, set the `resolve` property to a function. The function receives the event payload (as sent by the event publisher) and returns the appropriate value.

```typescript

@Subscription(returns => Comment, {
  resolve: value => value,
})
commentAdded() {
  return pubSub.asyncIterator('commentAdded');
}
```

> **Note** If you use the `resolve` option, you should return the unwrapped payload (e.g., with our example, return a `newComment` object directly, not a `{ commentAdded: newComment }` object).

If you need to access injected providers (e.g., use an external service to validate the data), use the following construction.

```typescript

@Subscription(returns => Comment, {
  resolve(this: AuthorResolver, value) {
    // "this" refers to an instance of "AuthorResolver"
    return value;
  }
})
commentAdded() {
  return pubSub.asyncIterator('commentAdded');
}
```

The same construction works with filters:

```typescript

@Subscription(returns => Comment, {
  filter(this: AuthorResolver, payload, variables) {
    // "this" refers to an instance of "AuthorResolver"
    return payload.commentAdded.title === variables.title;
  }
})
commentAdded() {
  return pubSub.asyncIterator('commentAdded');
}
```

#### Schema first[#](/graphql/subscriptions#schema-first)

To create an equivalent subscription in Nest, we'll make use of the `@Subscription()` decorator.

```typescript

const pubSub = new PubSub();

@Resolver('Author')
export class AuthorResolver {
  // ...
  @Subscription()
  commentAdded() {
    return pubSub.asyncIterator('commentAdded');
  }
}
```

To filter out specific events based on context and arguments, set the `filter` property.

```typescript

@Subscription('commentAdded', {
  filter: (payload, variables) =>
    payload.commentAdded.title === variables.title,
})
commentAdded() {
  return pubSub.asyncIterator('commentAdded');
}
```

To mutate the published payload, we can use a `resolve` function.

```typescript

@Subscription('commentAdded', {
  resolve: value => value,
})
commentAdded() {
  return pubSub.asyncIterator('commentAdded');
}
```

If you need to access injected providers (e.g., use an external service to validate the data), use the following construction:

```typescript

@Subscription('commentAdded', {
  resolve(this: AuthorResolver, value) {
    // "this" refers to an instance of "AuthorResolver"
    return value;
  }
})
commentAdded() {
  return pubSub.asyncIterator('commentAdded');
}
```

The same construction works with filters:

```typescript

@Subscription('commentAdded', {
  filter(this: AuthorResolver, payload, variables) {
    // "this" refers to an instance of "AuthorResolver"
    return payload.commentAdded.title === variables.title;
  }
})
commentAdded() {
  return pubSub.asyncIterator('commentAdded');
}
```

The last step is to update the type definitions file.

```graphql

type Author {
  id: Int!
  firstName: String
  lastName: String
  posts: [Post]
}

type Post {
  id: Int!
  title: String
  votes: Int
}

type Query {
  author(id: Int!): Author
}

type Comment {
  id: String
  content: String
}

type Subscription {
  commentAdded(title: String!): Comment
}
```

With this, we've created a single `commentAdded(title: String!): Comment` subscription. You can find a full sample implementation [here](https://github.com/nestjs/nest/blob/master/sample/12-graphql-schema-first).

#### PubSub[#](/graphql/subscriptions#pubsub)

We instantiated a local `PubSub` instance above. The preferred approach is to define `PubSub` as a [provider](/v7/fundamentals/custom-providers) and inject it through the constructor (using the `@Inject()` decorator). This allows us to re-use the instance across the whole application. For example, define a provider as follows, then inject `'PUB_SUB'` where needed.

```typescript

{
  provide: 'PUB_SUB',
  useValue: new PubSub(),
}
```

#### Customize subscriptions server[#](/graphql/subscriptions#customize-subscriptions-server)

To customize the subscriptions server (e.g., change the listener port), use the `subscriptions` options property (read [more](https://www.apollographql.com/docs/apollo-server/v2/api/apollo-server.html#constructor-options-lt-ApolloServer-gt)).

```typescript

GraphQLModule.forRoot({
  installSubscriptionHandlers: true,
  subscriptions: {
    keepAlive: 5000,
  }
}),
```

----
url: https://docs.nestjs.com/v7/cli/monorepo
----

* [Workspaces](https://docs.nestjs.com/v7/cli/monorepo#workspaces)
* [Standard mode](https://docs.nestjs.com/v7/cli/monorepo#standard-mode)
* [Monorepo mode](https://docs.nestjs.com/v7/cli/monorepo#monorepo-mode)
* [Workspace projects](https://docs.nestjs.com/v7/cli/monorepo#workspace-projects)
* [Applications](https://docs.nestjs.com/v7/cli/monorepo#applications)
* [Libraries](https://docs.nestjs.com/v7/cli/monorepo#libraries)
* [CLI properties](https://docs.nestjs.com/v7/cli/monorepo#cli-properties)
* [Global compiler options](https://docs.nestjs.com/v7/cli/monorepo#global-compiler-options)
* [Global generate options](https://docs.nestjs.com/v7/cli/monorepo#global-generate-options)
* [Project-specific generate options](https://docs.nestjs.com/v7/cli/monorepo#project-specific-generate-options)
* [Specified compiler](https://docs.nestjs.com/v7/cli/monorepo#specified-compiler)
* [Webpack options](https://docs.nestjs.com/v7/cli/monorepo#webpack-options)
* [Assets](https://docs.nestjs.com/v7/cli/monorepo#assets)
* [Project properties](https://docs.nestjs.com/v7/cli/monorepo#project-properties)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/cli/workspaces.md "Suggest Edits")

```bash

nest new my-project
```

```bash

cd my-project
nest generate app my-app
```

> **Warning** The conversion of a standard mode structure to monorepo only works for projects that have followed the canonical Nest project structure. Specifically, during conversion, the schematic attempts to relocate the `src` and `test` folders in a project folder beneath the `apps` folder in the root. If a project does not use this structure, the conversion will fail or produce unreliable results.

#### Workspace projects[#](/cli/monorepo#workspace-projects)

A monorepo uses the concept of a workspace to manage its member entities. Workspaces are composed of **projects**. A project may be either:

* an **application**: a full Nest application including a `main.ts` file to bootstrap the application. Aside from compile and build considerations, an application-type project within a workspace is functionally identical to an application within a *standard mode* structure.
* a **library**: a library is a way of packaging a general purpose set of features (modules, providers, controllers, etc.) that can be used within other projects. A library cannot run on its own, and has no `main.ts` file. Read more about libraries [here](/v7/cli/libraries).

All workspaces have a **default project** (which should be an application-type project). This is defined by the top-level `"root"` property in the `nest-cli.json` file, which points at the root of the default project (see [CLI properties](/cli/monorepo#cli-properties) below for more details). Usually, this is the **standard mode** application you started with, and later converted to a monorepo using `nest generate app`. When you follow these steps, this property is populated automatically.

Default projects are used by `nest` commands like `nest build` and `nest start` when a project name is not supplied.

For example, in the above monorepo structure, running

```bash

$ nest start
```

will start up the `my-project` app. To start `my-app`, we'd use:

```bash

$ nest start my-app
```

#### Applications[#](/cli/monorepo#applications)

Application-type projects, or what we might informally refer to as just "applications", are complete Nest applications that you can run and deploy. You generate an application-type project with `nest generate app`.

This command automatically generates a project skeleton, including the standard `src` and `test` folders from the [typescript starter](https://github.com/nestjs/typescript-starter). Unlike standard mode, an application project in a monorepo does not have any of the package dependency (`package.json`) or other project configuration artifacts like `.prettierrc` and `tslint.json`. Instead, the monorepo-wide dependencies and config files are used.

However, the schematic does generate a project-specific `tsconfig.app.json` file in the root folder of the project. This config file automatically sets appropriate build options, including setting the compilation output folder properly. The file extends the top-level (monorepo) `tsconfig.json` file, so you can manage global settings monorepo-wide, but override them if needed at the project level.

#### Libraries[#](/cli/monorepo#libraries)

As mentioned, library-type projects, or simply "libraries", are packages of Nest components that need to be composed into applications in order to run. You generate a library-type project with `nest generate library`. Deciding what belongs in a library is an architectural design decision. We discuss libraries in depth in the [libraries](/v7/cli/libraries) chapter.

#### CLI properties[#](/cli/monorepo#cli-properties)

Nest keeps the metadata needed to organize, build and deploy both standard and monorepo structured projects in the `nest-cli.json` file. Nest automatically adds to and updates this file as you add projects, so you usually do not have to think about it or edit its contents. However, there are some settings you may want to change manually, so it's helpful to have an overview understanding of the file.

After running the steps above to create a monorepo, our `nest-cli.json` file looks like this:

```javascript

{
  "collection": "@nestjs/schematics",
  "sourceRoot": "apps/my-project/src",
  "monorepo": true,
  "root": "apps/my-project",
  "compilerOptions": {
    "webpack": true,
    "tsConfigPath": "apps/my-project/tsconfig.app.json"
  },
  "projects": {
    "my-project": {
      "type": "application",
      "root": "apps/my-project",
      "entryFile": "main",
      "sourceRoot": "apps/my-project/src",
      "compilerOptions": {
        "tsConfigPath": "apps/my-project/tsconfig.app.json"
      }
    },
    "my-app": {
      "type": "application",
      "root": "apps/my-app",
      "entryFile": "main",
      "sourceRoot": "apps/my-app/src",
      "compilerOptions": {
        "tsConfigPath": "apps/my-app/tsconfig.app.json"
      }
    }
  }
}
```

| Property Name       | Property Value Type | Description                                                                                                                                                                                                                           |
| ------------------- | ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `webpack`           | boolean             | If `true`, use [webpack compiler](https://webpack.js.org/). If `false` or not present, use `tsc`. In monorepo mode, the default is `true` (use webpack), in standard mode, the default is `false` (use `tsc`). See below for details. |
| `tsConfigPath`      | string              | (**monorepo only**) Points at the file containing the `tsconfig.json` settings that will be used when `nest build` or `nest start` is called without a `project` option (e.g., when the default project is built or started).         |
| `webpackConfigPath` | string              | Points at a webpack options file. If not specified, Nest looks for the file `webpack.config.js`. See below for more details.                                                                                                          |
| `deleteOutDir`      | boolean             | If `true`, whenever the compiler is invoked, it will first remove the compilation output directory (as configured in `tsconfig.json`, where the default is `./dist`).                                                                 |
| `assets`            | array               | Enables automatically distributing non-TypeScript assets whenever a compilation step begins (asset distribution does **not** happen on incremental compiles in `--watch` mode). See below for details.                                |
| `watchAssets`       | boolean             | If `true`, run in watch-mode, watching **all** non-TypeScript assets. (For more fine-grained control of the assets to watch, see [Assets](cli/monorepo#assets) section below).                                                        |

#### Global generate options[#](/cli/monorepo#global-generate-options)

These properties specify the default generate options to be used by the `nest generate` command.

| Property Name | Property Value Type | Description                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| ------------- | ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `spec`        | boolean *or* object | If the value is boolean, a value of `true` enables `spec` generation by default and a value of `false` disables it. A flag passed on the CLI command line overrides this setting, as does a project-specific `generateOptions` setting (more below). If the value is an object, each key represents a schematic name, and the boolean value determines whether the default spec generation is enabled / disabled for that specific schematic. |

The following example uses a boolean value to specify that spec file generation should be disabled by default for all projects:

```javascript

{
  "generateOptions": {
    "spec": false
  },
  ...
}
```

In the following example, `spec` file generation is disabled only for `service` schematics (e.g., `nest generate service...`):

```javascript

{
  "generateOptions": {
    "spec": {
      "service": false
    }
  },
  ...
}
```

> **Warning** When specifying the `spec` as an object, the key for the generation schematic does not currently support automatic alias handling. This means that specifying a key as for example `service: false` and trying to generate a service via the alias `s`, the spec would still be generated. To make sure both the normal schematic name and the alias work as intended, specify both the normal command name as well as the alias, as seen below.
>
> ```javascript
>
> {
>   "generateOptions": {
>     "spec": {
>       "service": false,
>       "s": false
>     }
>   },
>   ...
> }
> ```

#### Project-specific generate options[#](/cli/monorepo#project-specific-generate-options)

In addition to providing global generate options, you may also specify project-specific generate options. The project specific generate options follow the exact same format as the global generate options, but are specified directly on each project.

Project-specific generate options override global generate options.

```javascript

{
  "projects": {
    "cats-project": {
      "generateOptions": {
        "spec": {
          "service": false
        }
      },
      ...
    }
  },
  ...
}
```

> **Warning** The order of precedence for generate options is as follows. Options specified on the CLI command line take precedence over project-specific options. Project-specific options override global options.

#### Specified compiler[#](/cli/monorepo#specified-compiler)

The reason for the different default compilers is that for larger projects (e.g., more typical in a monorepo) webpack can have significant advantages in build times and in producing a single file bundling all project components together. If you wish to generate individual files, set `"webpack"` to `false`, which will cause the build process to use `tsc`.

#### Webpack options[#](/cli/monorepo#webpack-options)

The webpack options file can contain standard [webpack configuration options](https://webpack.js.org/configuration/). For example, to tell webpack to bundle `node_modules` (which are excluded by default), add the following to `webpack.config.js`:

```javascript

module.exports = {
  externals: [],
};
```

Since the webpack config file is a JavaScript file, you can even expose a function that takes default options and returns a modified object:

```javascript

module.exports = function(options) {
  return {
    ...options,
    externals: [],
  };
};
```

#### Assets[#](/cli/monorepo#assets)

TypeScript compilation automatically distributes compiler output (`.js` and `.d.ts` files) to the specified output directory. It can also be convenient to distribute non-TypeScript files, such as `.graphql` files, `images`, `.html` files and other assets. This allows you to treat `nest build` (and any initial compilation step) as a lightweight **development build** step, where you may be editing non-TypeScript files and iteratively compiling and testing.

The value of the `assets` key should be an array of elements specifying the files to be distributed. The elements can be simple strings with `glob`-like file specs, for example:

```typescript

"assets": ["**/*.graphql"],
"watchAssets": true,
```

For finer control, the elements can be objects with the following keys:

* `"include"`: `glob`-like file specifications for the assets to be distributed
* `"exclude"`: `glob`-like file specifications for assets to be **excluded** from the `include` list
* `"outDir"`: a string specifying the path (relative to the root folder) where the assets should be distributed. Defaults to the same output directory configured for compiler output.
* `"watchAssets"`: boolean; if `true`, run in watch mode watching specified assets

For example:

```typescript

"assets": [
  { "include": "**/*.graphql", "exclude": "**/omitted.graphql", "watchAssets": true },
]
```

> **Warning** Setting `watchAssets` in a top-level `compilerOptions` property overrides any `watchAssets` settings within the `assets` property.

#### Project properties[#](/cli/monorepo#project-properties)

This element exists only for monorepo-mode structures. You generally should not edit these properties, as they are used by Nest to locate projects and their configuration options within the monorepo.

----
url: https://docs.nestjs.com/v5/interceptors
----

### Interceptors

An interceptor is a class annotated with the `@Injectable()` decorator. The interceptor should implement the `NestInterceptor` interface.

Interceptors have a set of useful capabilities which are inspired by the **Aspect-Oriented Programming** (AOP) technique. They make possible to:

* bind **extra logic** before / after method execution
* **transform** the result returned from a function
* **transform** the exception thrown from a function
* extend the basic function behaviour
* completely **override** a function depending on the chosen conditions (e.g. caching purposes)

#### Basics

Each interceptor has the `intercept()` method that takes 2 arguments. The first one is the `ExecutionContext` instance (exactly the same object as for [guards](/v5/guards)). The `ExecutionContext` inherits from `ArgumentsHost` (first mention [here](/v5/exception-filters)). The `ArgumentsHost` is a wrapper around arguments that have been passed to the **original** handler, and it contains different arguments array under the hood based on the type of the application.

TypeScript

```typescript

export interface ArgumentsHost {
  getArgs<T extends Array<any> = any[]>(): T;
  getArgByIndex<T = any>(index: number): T;
  switchToRpc(): RpcArgumentsHost;
  switchToHttp(): HttpArgumentsHost;
  switchToWs(): WsArgumentsHost;
}
```

The `ArgumentsHost` supplies us with a set of useful methods that helps to pick correct arguments from the underlying array. In other words, `ArgumentsHost` is nothing else than just an **array of arguments**. For example, when the guard is used within HTTP application context, `ArgumentsHost` will contain `[request, response]` array inside. However, when current context is a web sockets application, this array will be equal to `[client, data]`. This design decision enables you to access any argument that would be eventually passed to the corresponding handler.

The `ExecutionContext` offers a little bit more. It extends `ArgumentsHost`, but also, provides more details about current execution process.

TypeScript

```typescript

export interface ExecutionContext extends ArgumentsHost {
  getClass<T = any>(): Type<T>;
  getHandler(): Function;
}
```

The `getHandler()` returns a reference to the currently processed handler, while `getClass()` returns a type of the `Controller` class which this particular handler belongs to. Using other words, if the user points to `create()` method that is defined and registered within `CatsController`, the `getHandler()` will return a reference to the `create()` method and `getClass()` in this case, will simply return a `CatsController`**type** (not instance).

The second argument is a `call$`, an `Observable` stream. If you don't return this stream, the main handler won't be evaluated at all. What does it mean? Basically, the `call$` is a stream that **defers the final handler execution**. Let's say, someone made a POST `/cats` request. This request points to `create()` handler defined inside the `CatsController`. If an interceptor which does not return a `call$` stream is called along the way, the `create()` method won't be evaluated. Only when `call$` stream is returned, the final method will be triggered. Why? Because Nest **subscribes** to the returned stream and uses values that this stream produces to create either a single response or multiple responses for the end-user. Moreover, as mentioned a while ago, `call$` is an `Observable`, meaning, it supplies us with a set of very powerful operators that helps with, for example, response manipulation.

#### Aspect interception

The first use case is to use the interceptor to add extra logic either before or after the function execution. It's useful when we're gonna **log interaction** with the application, e.g. storing user calls, asynchronously dispatching events or calculating the timestamp. As an example, let's create a simple `LoggingInterceptor`.

logging.interceptor.ts

JS TS

TypeScript

```typescript

import { Injectable, NestInterceptor, ExecutionContext } from '@nestjs/common';
import { Observable } from 'rxjs';
import { tap } from 'rxjs/operators';

@Injectable()
export class LoggingInterceptor implements NestInterceptor {
  intercept(
    context: ExecutionContext,
    call$: Observable<any>,
  ): Observable<any> {
    console.log('Before...');

    const now = Date.now();
    return call$.pipe(
      tap(() => console.log(`After... ${Date.now() - now}ms`)),
    );
  }
}
```

TypeScript

```typescript

import { Injectable } from '@nestjs/common';
import { Observable } from 'rxjs';
import { tap } from 'rxjs/operators';

@Injectable()
export class LoggingInterceptor {
  intercept(context, call$) {
    console.log('Before...');

    const now = Date.now();
    return call$.pipe(
      tap(() => console.log(`After... ${Date.now() - now}ms`)),
    );
  }
}
```

> **Hint** The `NestInterceptor<T, R>` is a generic interface in which `T` indicates a type of the processed `Observable<T>` (behind the stream), while `R` the return type of the value wrapped into returned `Observable<R>`.

> **Notice** Interceptors act the same as controllers, providers, guards, and so on, meaning, they can **inject dependencies&#x20;**&#x74;hrough the `constructor`.

Since `call$` is a [RxJS](https://github.com/reactivex/rxjs)`Observable`, we have a lot of various operators which we can use to manipulate the stream. In the example above, We used the `tap()` operator that invokes the function upon graceful or exceptional termination of the observable sequence.

In order to set up the interceptor, we use the `@UseInterceptors()` decorator imported from the `@nestjs/common` package. Same as [guards](/v5/guards), interceptors can be controller-scoped, method-scoped, and global-scoped as well.

cats.controller.ts

JS TS

TypeScript

```typescript

@UseInterceptors(LoggingInterceptor)
export class CatsController {}
```

> **Hint** The `@UseInterceptors()` decorator is imported from the `@nestjs/common` package.

Thanks to that, each route handler defined in `CatsController` will use `LoggingInterceptor`. When someone calls the GET `/cats` endpoint, you'll see a following output in your console window:

TypeScript

```typescript

Before...
After... 1ms
```

Note that we passed the `LoggingInterceptor` type instead of an instance, leaving framework the instantiation responsibility and enabling dependency injection. Another available way is to pass the immediately created instance:

cats.controller.ts

JS TS

TypeScript

```typescript

@UseInterceptors(new LoggingInterceptor())
export class CatsController {}
```

As mentioned before, the construction above attaches the interceptor to every handler declared by this controller. If we decide to restrict only one of them, we just need to set up the interceptor at **method level**. In order to bind the global interceptor, we use the `useGlobalInterceptors()` method of the Nest application instance:

TypeScript

```typescript

const app = await NestFactory.create(ApplicationModule);
app.useGlobalInterceptors(new LoggingInterceptor());
```

The global interceptors are used across the whole application, for every controller and every route handler. In terms of dependency injection, global interceptors registered from the outside of any module (as in the previous example above) cannot inject dependencies since they don't belong to any module. In order to solve this issue, you can set up a guard **directly from any module** using following construction:

app.module.ts

JS TS

TypeScript

```typescript

import { Module } from '@nestjs/common';
import { APP_INTERCEPTOR } from '@nestjs/core';

@Module({
  providers: [
    {
      provide: APP_INTERCEPTOR,
      useClass: LoggingInterceptor,
    },
  ],
})
export class ApplicationModule {}
```

> **Hint** The alternative option is to use an [execution context](/v5/execution-context) feature. Also, `useClass` is not the only way of dealing with custom providers registration. Learn more [here](/v5/fundamentals/dependency-injection).

#### Response mapping

We already know that `call$` is an `Observable`. This object contains the value **returned** from the route handler, and thus we can easily mutate it using the `map()` operator.

> **Warning** The response mapping feature doesn't work with the library-specific response strategy (using the `@Res()` object directly is forbidden).

Let's create the `TransformInterceptor` that will take each response and modify it by assigning to the `data` property of the newly created object.

transform.interceptor.ts

JS TS

TypeScript

```typescript

import { Injectable, NestInterceptor, ExecutionContext } from '@nestjs/common';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';

export interface Response<T> {
  data: T;
}

@Injectable()
export class TransformInterceptor<T>
  implements NestInterceptor<T, Response<T>> {
  intercept(
    context: ExecutionContext,
    call$: Observable<T>,
  ): Observable<Response<T>> {
    return call$.pipe(map(data => ({ data })));
  }
}
```

TypeScript

```typescript

import { Injectable } from '@nestjs/common';
import { map } from 'rxjs/operators';

@Injectable()
export class TransformInterceptor {
  intercept(context, call$) {
    return call$.pipe(map(data => ({ data })));
  }
}
```

> **Hint** Nest interceptors work like a charm with asynchronous `intercept()` methods, meaning, you can effortlessly switch your method to `async` if necessary.

Afterward, when someone calls the GET `/cats` endpoint, the request would look like below (we assumed that route handler returns an empty array `[]`):

TypeScript

```typescript

{
    "data": []
}
```

The interceptors have a huge potential when it comes to creating reusable solutions used in whole applications. For example, let's imagine that we need to transform each occurred `null` value to empty string `''`. We can do it using one line of code and bind interceptor as a global one. Thanks to that, it'll be automatically reused by each registered handler.

JS TS

TypeScript

```typescript

import { Injectable, NestInterceptor, ExecutionContext } from '@nestjs/common';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';

@Injectable()
export class ExcludeNullInterceptor implements NestInterceptor {
  intercept(
    context: ExecutionContext,
    call$: Observable<any>,
  ): Observable<any> {
    return call$.pipe(map(value => value === null ? '' : value ));
  }
}
```

TypeScript

```typescript

import { Injectable } from '@nestjs/common';
import { map } from 'rxjs/operators';

@Injectable()
export class ExcludeNullInterceptor {
  intercept(context, call$) {
    return call$.pipe(map(value => value === null ? '' : value ));
  }
}
```

#### Exception mapping

Another interesting use-case is to take advantage of the `catchError()` operator to override thrown exceptions:

errors.interceptor.ts

JS TS

TypeScript

```typescript

import {
  Injectable,
  NestInterceptor,
  ExecutionContext,
  HttpStatus,
} from '@nestjs/common';
import { HttpException } from '@nestjs/common';
import { Observable, throwError } from 'rxjs';
import { catchError } from 'rxjs/operators';

@Injectable()
export class ErrorsInterceptor implements NestInterceptor {
  intercept(
    context: ExecutionContext,
    call$: Observable<any>,
  ): Observable<any> {
    return call$.pipe(
      catchError(err =>
        throwError(new HttpException('Message', HttpStatus.BAD_GATEWAY)),
      ),
    );
  }
}
```

TypeScript

```typescript

import { Injectable, HttpStatus } from '@nestjs/common';
import { HttpException } from '@nestjs/common';
import { throwError } from 'rxjs';
import { catchError } from 'rxjs/operators';

@Injectable()
export class ErrorsInterceptor {
  intercept(context, call$) {
    return call$.pipe(
      catchError(err =>
        throwError(new HttpException('Message', HttpStatus.BAD_GATEWAY)),
      ),
    );
  }
}
```

#### Stream overriding

There're several reasons why sometimes we might want to completely prevent calling the handler and return a different value instead (e.g. from cache due to performance issues). An excellent example is a **cache interceptor** that would store the cached responses with some TTL. Unfortunately, this feature needs a bit more code and due to simplification, we'll provide only a basic example that should briefly explain the main concept.

cache.interceptor.ts

JS TS

TypeScript

```typescript

import { Injectable, NestInterceptor, ExecutionContext } from '@nestjs/common';
import { Observable } from 'rxjs';
import { of } from 'rxjs/observable/of';

@Injectable()
export class CacheInterceptor implements NestInterceptor {
  intercept(
    context: ExecutionContext,
    call$: Observable<any>,
  ): Observable<any> {
    const isCached = true;
    if (isCached) {
      return of([]);
    }
    return call$;
  }
}
```

TypeScript

```typescript

import { Injectable } from '@nestjs/common';
import { of } from 'rxjs/observable/of';

@Injectable()
export class CacheInterceptor {
  intercept(context, call$) {
    const isCached = true;
    if (isCached) {
      return of([]);
    }
    return call$;
  }
}
```

Here's a `CacheInterceptor` with a hardcoded `isCached` variable and the hardcoded response `[]` as well. We returned a new stream here, created through the `of` operator, therefore the route handler **won't be called** at all. When someone calls endpoint that makes use of `CacheInterceptor`, the response (a hardcoded, empty array) will be returned immedietely. In order to create a generic solution, you can take advantage of `Reflector` and create a custom decorator. The `Reflector` is well described in the [guards](/v5/guards) chapter.

The possibility of returning the stream gives us many possibilities. Let's think about another common use-case. Imagine you would like to handle **timeouts**. When your endpoint doesn't return anything after a period of time, we want to respond with an error response.

timeout.interceptor.ts

JS TS

TypeScript

```typescript

import { Injectable, NestInterceptor, ExecutionContext } from '@nestjs/common';
import { Observable } from 'rxjs';
import { timeout } from 'rxjs/operators';

@Injectable()
export class TimeoutInterceptor implements NestInterceptor {
  intercept(
    context: ExecutionContext,
    call$: Observable<any>,
  ): Observable<any> {
    return call$.pipe(timeout(5000))
  }
}
```

TypeScript

```typescript

import { Injectable } from '@nestjs/common';
import { timeout } from 'rxjs/operators';

@Injectable()
export class TimeoutInterceptor {
  intercept(context, call$) {
    return call$.pipe(timeout(5000))
  }
}
```

After 5 seconds the request processing will be canceled.

* Interceptors
* Basics
* Aspect interception
* Response mapping
* Exception mapping
* Stream overriding

----
url: https://docs.nestjs.com/observability/sdk
----

[Skip to content](#content)

On this page

* [SDK](https://docs.nestjs.com/observability/sdk#sdk)
* [Installation](https://docs.nestjs.com/observability/sdk#installation)
* [Quick start](https://docs.nestjs.com/observability/sdk#quick-start)
* [Configuring the module](https://docs.nestjs.com/observability/sdk#configuring-the-module)
* [Automatic instrumentation](https://docs.nestjs.com/observability/sdk#automatic-instrumentation)
* [Errors and failed requests](https://docs.nestjs.com/observability/sdk#errors-and-failed-requests)
* [Logs and trace correlation](https://docs.nestjs.com/observability/sdk#logs-and-trace-correlation)
* [Shaping what is recorded](https://docs.nestjs.com/observability/sdk#shaping-what-is-recorded)
* [Full configuration reference](https://docs.nestjs.com/observability/sdk#full-configuration-reference)
* [Where to go next](https://docs.nestjs.com/observability/sdk#where-to-go-next)

### SDK

The `@nestjs/observe` SDK is what gets your application's requests, jobs, errors, logs, and traces into your [NestJS Observe](https://www.observe.nestjs.com/ "NestJS Observe") dashboard. It hooks into Nest's own request lifecycle - controllers, interceptors, resolvers, queue consumers - rather than bolting a generic Node.js agent onto the process, so most of what shows up in the dashboard needs no manual span wiring.

> **Hint** Not sure it is worth the setup yet? The [live demo](https://www.observe-demo.nestjs.com/dashboard "NestJS Observe live demo") shows what this instrumentation produces - traces, waterfalls, errors and jobs from a busy service - without installing anything.

#### Installation[#](/observability/sdk#installation)

There are two ways to set up the SDK: one command that does it for you, or the same steps by hand.

**With one command.** Run the following in your project's directory:

```bash

$ npx @nestjs/observe link
```

The command prints an eight-letter code. Type it at [observe.nestjs.com/link](https://www.observe.nestjs.com/link "Link a project to NestJS Observe"), signing up first if you don't have an account, and approve. The command then writes the project's key pair into `.env` as `OBSERVE_APP_KEY` and `OBSERVE_APP_SECRET`, git-ignores `.env`, and adds `--env-file .env` to every script that runs `nest start` (`start`, `start:dev`, and `start:debug` in a `nest new` project).

If the application doesn't use the SDK yet, the command also installs `@nestjs/observe` with your package manager and makes the three edits from the [Quick start](/observability/sdk#quick-start) below for you. It tells you so before you approve. See [Linking from the terminal](/observability/sdk#linking-from-the-terminal) for exactly what it changes.

> **Warning** The SDK requires `@nestjs/core` v11.1.4 or later (it relies on the `instrument` application option introduced in that release), and `@nestjs/graphql` v13.4.4 or later if your application uses GraphQL. Earlier versions lack the hooks the SDK needs.

**By hand.** Install the SDK:

```bash

$ npm i @nestjs/observe
```

Then make the three edits from the [Quick start](/observability/sdk#quick-start) below, generate an API key on your project's **API Keys** page (see [First project](/observability/overview#first-project)), and set the key pair as `OBSERVE_APP_KEY` and `OBSERVE_APP_SECRET`. This is also the way to go wherever the command leaves the wiring to you.

#### Quick start[#](/observability/sdk#quick-start)

The integration takes three steps. First, call `createObserveModule()` once, typically in `app.module.ts` or another root-level file. It returns a matched pair - a Nest module and an `instrument` hook - bound to the same configuration:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { createObserveModule } from '@nestjs/observe';
import { AppController } from './app.controller.js';
import { AppService } from './app.service.js';

export const { ObserveModule, ObserveInstrument } = createObserveModule();

@Module({
  imports: [
    ObserveModule.forRoot({
      appKey: process.env.OBSERVE_APP_KEY!,
      appSecret: process.env.OBSERVE_APP_SECRET!,
      serviceId: 'cats-app',
    }),
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}
```

Second, import `ObserveModule.forRoot()` into your root module with at least a `serviceId` (shown above). Third, pass `ObserveInstrument` to `NestFactory.create()` so the SDK attaches to the application before it starts handling traffic:

main.ts

JS TS

```typescript

import { NestFactory } from '@nestjs/core';
import { AppModule, ObserveInstrument } from './app.module.js';

async function bootstrap() {
  const app = await NestFactory.create(AppModule, {
    instrument: ObserveInstrument,
  });
  await app.listen(process.env.PORT ?? 3000);
}
await bootstrap();
```

> **Fastify** With `FastifyAdapter` (or any explicit adapter), the adapter takes the second argument, so the application options - and therefore `instrument` - move to the **third**:
>
> ```typescript
>
> const app = await NestFactory.create<NestFastifyApplication>(
>   AppModule,
>   new FastifyAdapter(),
>   { instrument: ObserveInstrument },
> );
> ```
>
> Passing the options object as the second argument alongside an adapter silently drops them, and the SDK never attaches.

That completes the integration. Once the application receives traffic, requests, errors, and traces appear in your project's dashboard within moments, with no exporter to configure and no schema to design. The same `instrument` option is accepted by `NestFactory.createMicroservice()` and `NestFactory.createApplicationContext()`, so workers and standalone applications are instrumented the same way.

> **Hint**`createObserveModule()` itself takes an options object that controls how trace ids are generated, how error source context is captured, and which providers are instrumented - see [Trace correlation](/observability/sdk#trace-correlation) and [Error source context](/observability/sdk#error-source-context) below. Everything else is configured through `ObserveModule.forRoot()`.

#### Configuring the module[#](/observability/sdk#configuring-the-module)

Beyond the credentials in the quick start, these options decide how the SDK identifies your application, where it sends what it records, and how much it tells you about itself.

##### Authenticating and identifying the application[#](/observability/sdk#authenticating-and-identifying-the-application)

```typescript

ObserveModule.forRoot({
  appKey: process.env.OBSERVE_APP_KEY!,
  appSecret: process.env.OBSERVE_APP_SECRET!,
  serviceId: 'cats-app',
  serviceVersion: process.env.GIT_SHA,
});
```

| Option           | Type     | Default  | Description                                                                                                                                                                                                             |
| ---------------- | -------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `appKey`         | `string` | required | Written into `.env` as `OBSERVE_APP_KEY` by `npx @nestjs/observe link`, or generated from your project's **API Keys** page - see [First project](/observability/overview#first-project). Keep it out of source control. |
| `appSecret`      | `string` | required | Issued alongside `appKey`, the same way, and written as `OBSERVE_APP_SECRET`. Keep it out of source control.                                                                                                            |
| `serviceId`      | `string` | required | Identifies this application in your dashboard. If you run multiple instances of the same service, use a value unique per instance (hostname, container id) to tell them apart in the Profiler.                          |
| `serviceVersion` | `string` | -        | Identifies the deployment - a semantic version, a commit hash, or any other identifier. Every request and job records the version that served it, which is what powers the **Releases** view.                           |

`serviceVersion` is optional but strongly recommended. It lets the dashboard compare each version of an application against the one before it (error rate, latency, and throughput side by side), so a regression introduced by a deploy is visible immediately rather than buried in a week-long chart.

##### Linking from the terminal[#](/observability/sdk#linking-from-the-terminal)

`npx @nestjs/observe link` puts a key pair on a developer's machine without copying a secret out of the browser, and sets the SDK up in an application that doesn't use it yet. Run it in the project's directory (the one with `package.json`), or point it there with `--cwd <dir>`:

1. It prints an eight-letter code, such as `BCDF-GHJK`, and opens [observe.nestjs.com/link](https://www.observe.nestjs.com/link "Link a project to NestJS Observe") in your browser. With `--no-browser`, in CI, or without a terminal, it only prints the address. The code expires after 15 minutes. If the application doesn't use the SDK yet, the command also says, below the code, that it will install and wire it once you approve.
2. Type the code on that page. If you don't have an account yet, you sign up first; if you're signed out, you sign in. Either way, you come back to the code afterwards.
3. Check the request: the page shows the hostname of the machine and the package name the command sent. Then choose where the key goes. The page proposes your newest project, and in it the application named after your package, or a new application if there isn't one yet. You can change both, including to a new project.
4. Approve. The dashboard issues a new API key for that application, and the command writes it into the project.

In every project, the command changes up to three files:

* **`.env`** receives `OBSERVE_APP_KEY` and `OBSERVE_APP_SECRET`, single-quoted, replacing an earlier pair and leaving every other line as it was. A new `.env` is created readable only by you. The quotes are deliberate: a key or secret can contain `$` and `&`, which `dotenv-expand` (or `ConfigModule` with `expandVariables`) would rewrite, and at which a shell sourcing the file would stop.
* **`.gitignore`** gets a `.env` entry, unless the file is already ignored (as it is in a project generated by `nest new`).
* **`package.json`**: every script whose command begins with `nest start` gets `--env-file .env`: `start`, `start:dev`, and `start:debug` in a project generated by `nest new`, and a monorepo's per-application scripts as well. Scripts that already pass an env file are left alone, and so is `start:prod` (`node dist/main`). A `start` or `start:dev` script that starts the application some other way is left alone too, but the command names it, so you can load `.env` there yourself (for example, with `node --env-file=.env`).

In an application that doesn't use the SDK yet (no source file imports `@nestjs/observe`), the command also sets the SDK up, the way `nest new` does:

* **The SDK** is installed at the command's own version (`@nestjs/observe@^0.3.16` from 0.3.16). The command uses the package manager that the project's lockfile belongs to (pnpm, Yarn, Bun, or npm), looking up to the repository's root, so that a package in a workspace finds the root's lockfile. Without a lockfile, it uses the one named by the `packageManager` field in `package.json`, and npm otherwise. An `@nestjs/observe` that is already installed but older than the command is upgraded the same way. In that case, run `npx @nestjs/observe@latest link`, because plain `npx` runs the version installed in the project.
* **The root module**, the one `main.ts` passes to `NestFactory.create()` (found by following its import), gets the `createObserveModule()` call, and `ObserveModule.forRoot()` as the first entry of its `imports`. The options read the key pair from `OBSERVE_APP_KEY` and `OBSERVE_APP_SECRET`, and set `serviceId` to the name of the application you approved, lower-cased, with spaces turned into dashes and any other punctuation dropped (`Cats API` becomes `cats-api`).
* **`main.ts`** passes `instrument: ObserveInstrument` to `NestFactory.create()`, inside its options object, or as a new options argument if there is none.

The edits follow each file's quotes, semicolons, and indentation, and either both files change or neither does. The command lists them, so you can review them with `git diff`.

In some projects, the command leaves the wiring to you and prints why; the [Quick start](/observability/sdk#quick-start) shows the edits to make. It does so in a workspace with several applications (the key belongs to one of them), in a JavaScript project, and wherever it can't edit the code safely, for example when `main.ts` imports the root module through a path alias rather than a relative path, when `imports` isn't a plain array, or when an `instrument` option is already passed. If the installation fails, the command prints the install command for you to run yourself, and leaves the wiring to you as well.

Before it asks for a code, the command turns away a project that it would have to install the SDK in but that has no `@nestjs/core`, or runs a NestJS version older than 11.

Nothing is written until the key arrives, so a denied, expired, or interrupted link leaves the project unchanged.

> **Warning** Approve only a code you started yourself, and only when it matches your terminal. The code is typed rather than carried in a URL so that nobody can send you a link that approves a key for them.

The key appears on the project's **API Keys** page like any other, named `CLI` followed by the time it was issued, and expires after a year; run the command again for a new one. `.env` stays on the machine that ran the command, so each teammate (or each additional machine) runs `npx @nestjs/observe link` as well and gets a key of its own for the same application.

##### Reading the key pair from the environment[#](/observability/sdk#reading-the-key-pair-from-the-environment)

When `appKey` or `appSecret` is unset or empty, or still holds the placeholder that `nest new` generates (`'YOUR_APP_KEY'` and `'YOUR_APP_SECRET'`), `ObserveModule` reads `OBSERVE_APP_KEY` or `OBSERVE_APP_SECRET` from the environment instead. This is what lets a project generated with Observe report once it's linked, without any change to `AppModule`. A value you pass yourself always wins, and the same fallback applies to the options that `forRootAsync()` resolves.

The variables are read when the options are resolved (for `forRoot()`, when the `AppModule` file is imported), so they must already be in `process.env` at that point. The `--env-file` flag loads them before any module runs.

In production, set `OBSERVE_APP_KEY` and `OBSERVE_APP_SECRET` in the environment (your platform's secrets or environment settings) rather than shipping `.env`. A project generated by `nest new` runs `node dist/main` for `start:prod`, which doesn't load `.env` anyway, and `nest start` skips an `--env-file` that doesn't exist, so a fresh clone or a CI run without `.env` still starts. Give production a key of its own from the project's **API Keys** page, so revoking a development key never stops it from reporting.

> **Hint** The `link` command and the environment fallback require `@nestjs/observe` 0.3.15 or later. Installing and wiring the SDK into an application that doesn't use it yet requires 0.3.16 or later.

##### Asynchronous configuration[#](/observability/sdk#asynchronous-configuration)

When the credentials come from a configuration provider rather than directly from `process.env`, use `forRootAsync()`. It accepts the same `useFactory`/`inject`, `useClass`, and `useExisting` shapes as every other Nest dynamic module (a class implements `ObserveOptionsFactory` with a `createObserveOptions()` method), plus `extraProviders` and `global`:

app.module.ts

JS TS

```typescript

ObserveModule.forRootAsync({
  imports: [ConfigModule],
  inject: [ConfigService],
  useFactory: (config: ConfigService) => ({
    appKey: config.getOrThrow('OBSERVE_APP_KEY'),
    appSecret: config.getOrThrow('OBSERVE_APP_SECRET'),
    serviceId: config.get('SERVICE_ID', 'cats-app'),
    serviceVersion: config.get('GIT_SHA'),
  }),
});
```

##### Collector endpoint[#](/observability/sdk#collector-endpoint)

```typescript

ObserveModule.forRoot({
  // ...
  endpoint: 'https://observe-api.nestjs.com',
});
```

`endpoint` (default `'https://observe-api.nestjs.com'`) is the base URL of the collector. Telemetry and profiles share it, so the two can never point at different places. To override it without touching the config, set the `OBSERVE_ENDPOINT` environment variable. NestJS Observe is a hosted service and `observe-api.nestjs.com` is the only collector it runs; change the endpoint when your traffic has to leave through a forwarding proxy, or to point a test environment at a stub that accepts the batches.

##### Debugging the SDK itself[#](/observability/sdk#debugging-the-sdk-itself)

```typescript

ObserveModule.forRoot({
  // ...
  debug: true,
});
```

`debug` (default `false`) logs additional diagnostic information from the SDK to the console. Use it while getting instrumentation working, and turn it off in production.

#### Automatic instrumentation[#](/observability/sdk#automatic-instrumentation)

Everything in this section is recorded without any code of your own; installing the SDK is enough. The options only narrow it or switch it off.

##### Database queries and outbound HTTP[#](/observability/sdk#database-queries-and-outbound-http)

Since `@nestjs/observe` 0.3.0, database queries and outbound requests appear as spans with no configuration, nested under the method that made them. A slow repository call shows *which* statement it was waiting on.

Databases are instrumented at the driver rather than the ORM: `pg`, `mysql2` and `mongodb` are detected if your application already depends on them, which covers TypeORM, MikroORM, Drizzle, Mongoose, Knex, Sequelize, and Prisma's driver adapters without naming any of them. ORMs that ship their own nested copy of a driver (MikroORM and Mongoose do, whenever versions disagree) are handled too. The driver's own housekeeping (connection handshakes, authentication, pings) is not recorded. A query span is labeled with its verb and table (`SELECT users`) and carries the statement with **every literal removed** - strings, numbers, `IN (...)` lists, and comments are replaced before the span leaves the process, and bound parameters are never read at all. Repeated queries under one parent fold into a single node with a count, so an N+1 reads as `SELECT order_items ×47` rather than 47 rows.

Outbound HTTP is read from Node's own diagnostics channels, so `fetch`, `undici`, and everything built on `node:http` (axios, got, most SDKs) are covered with nothing patched. The span is labeled `GET api.example.com` and carries the URL with sensitive query parameters masked. The SDK also sends the current trace id as `x-request-id`, which makes [HTTP-to-HTTP tracing](/observability/distributed-tracing#http-to-http) automatic.

```typescript

ObserveModule.forRoot({
  // ...
  outgoing: {
    database: true,
    http: {
      ignore: (url) => url.startsWith('https://internal-metrics.'),
      // Only forward the trace id to your own services
      propagateTraceId: (url) => url.includes('.svc.cluster.local'),
    },
  },
});
```

Set `outgoing: false` to switch all of it off, or `database: false` / `http: false` individually.

> **Hint** These spans are **not billed**. They are detail about a method span you already sent, so they don't count toward your Observability Events or your rate cap. A request that runs ten queries costs the same as before.

##### WebSocket gateways[#](/observability/sdk#websocket-gateways)

Messages handled by `@SubscribeMessage()` are reported as requests with the `ws` protocol and an operation id of `GatewayClass:pattern`, on any platform adapter. The `ws` option block takes the same `ignore`, `tags`, `setAttributes`, and `getUserId` hooks as the other transports; each receives `{ gateway, pattern, client, data }`. Connections and disconnections are not operations and are not reported.

##### Queues[#](/observability/sdk#queues)

`@nestjs/bullmq` and the original `@nestjs/bull` are both instrumented: every processor run is reported as a job, with its queue wait, attempt number, and outcome. A job added from inside a traced operation inherits that operation's trace id - see [Distributed tracing](/observability/distributed-tracing#queue-jobs-bullmq-and-bull).

##### Runtime metrics and profiling[#](/observability/sdk#runtime-metrics-and-profiling)

```typescript

ObserveModule.forRoot({
  // ...
  runtimeMetrics: true,
  runtimeMetricsInterval: 60000,
});
```

`runtimeMetrics` (default `true`) samples memory, CPU, garbage collection, and event loop latency on an interval (`runtimeMetricsInterval`, default `60000` ms) and feeds the **Profiler**. The same samples double as the application's heartbeat: a **Telemetry silence** alert fires when they stop arriving, which gives you lightweight uptime monitoring without an external probe.

#### Errors and failed requests[#](/observability/sdk#errors-and-failed-requests)

An error that escapes a controller, resolver, or job is captured automatically. These options decide what comes with it: the source code around the failing frame, and the headers and body of the request that failed.

##### Error source context[#](/observability/sdk#error-source-context)

Errors that propagate out of a controller, resolver, job, or span are captured automatically. When `sourceContext` is enabled (the default), the SDK also reads the source lines around each in-app stack frame of a captured error and attaches them. This lets the dashboard show the failing code alongside the stack trace, even for a production failure on a build you don't have checked out.

app.module.ts

JS TS

```typescript

export const { ObserveModule, ObserveInstrument } = createObserveModule({
  sourceContext: {
    linesOfContext: 5,
    maxFrames: 5,
    sourceMaps: false,
  },
});
```

This is an option of `createObserveModule()`, not `forRoot()`. Set `sourceContext: false` to disable it, or pass an object to tune the defaults:

| Option           | Type      | Default | Description                                                                                                                                                                                                                                                                                                                                                                       |
| ---------------- | --------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `linesOfContext` | `number`  | `5`     | Lines read on either side of the frame's line.                                                                                                                                                                                                                                                                                                                                    |
| `maxFrames`      | `number`  | `5`     | How many in-app frames, counted from the top of the stack, get source attached. Bounds the payload on deep stacks.                                                                                                                                                                                                                                                                |
| `sourceMaps`     | `boolean` | `false` | Resolves compiled frames back through source maps before reading source. Only needed if the process runs compiled output *without* Node's own source map support (`--enable-source-maps` or `process.setSourceMapsEnabled(true)`); with that on, frames already carry original positions and this is redundant. Costs a map parse per compiled file on first touch, cached after. |

> **Warning** Enabling this ships fragments of your application's source code (usually a few lines around the error) to your dashboard, where they are stored alongside the error. Frames inside `node_modules` and Node internals are never read, only application source. Turn it off if shipping any source is not acceptable for your codebase.

##### Capturing failed and slow requests[#](/observability/sdk#capturing-failed-and-slow-requests)

When an HTTP request **fails**, the SDK records a small, fixed allow-list of its headers alongside it - `user-agent`, `content-type`, `content-length`, `accept`, `host`, `origin` and `referer`. None of these authenticate or identify the caller. If you set `slowerThanMs`, requests that ran at least that long are captured the same way, failed or not. An ordinary request records nothing. Request bodies are **off** by default; turn them on explicitly if you want them:

```typescript

ObserveModule.forRoot({
  // ...
  http: {
    capture: {
      headers: ['user-agent', 'x-tenant-id'],
      body: { maxBytes: 4096 }, // default 2048, at most 16384
      slowerThanMs: 2000,
    },
  },
});
```

Everything captured passes through [`redaction`](/observability/sdk#logs) before it leaves the process: sensitive keys (`password`, `token`, `authorization`, ...) are masked by name inside the body, and naming a sensitive header records `[REDACTED]` instead of its value. `capture: false` records nothing. The capture is shown on the request's detail page as a **Request** card.

#### Logs and trace correlation[#](/observability/sdk#logs-and-trace-correlation)

Every execution gets a trace id. These options decide how your log lines relate to it: forwarded to the dashboard, or only stamped with the id so your own log stack can link to the trace.

##### Logs[#](/observability/sdk#logs)

```typescript

ObserveModule.forRoot({
  // ...
  forwardLogs: true,
  redaction: {
    enabled: true,
    keys: ['internalToken'],
    patterns: [/acct_[a-z0-9]{16}/gi],
  },
});
```

`forwardLogs` (default `false`) sends your application's log lines (anything written through Nest's `Logger`) to the dashboard, correlated to the trace that was active when each line was written. On an execution page, every line is placed on the trace's clock next to the span that was in flight when it was written. Log forwarding is available on Pro and above.

Forwarding logs moves them onto infrastructure you don't control, so redaction is on by default. The same redaction also scrubs the message and stack of every captured error and any captured request data, whether or not `forwardLogs` is on:

| `redaction` field    | Type       | Default        | Description                                                                                                                                                                                                                                                              |
| -------------------- | ---------- | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `enabled`            | `boolean`  | `true`         | Whether anything is scrubbed at all.                                                                                                                                                                                                                                     |
| `useDefaultPatterns` | `boolean`  | `true`         | Applies the built-in patterns: bearer tokens, JWTs, AWS key ids, PEM private keys, `key=value` secrets, and Luhn-valid card numbers. Disable only if you're replacing them wholesale with your own `patterns`; there's no supported case for forwarding logs unredacted. |
| `patterns`           | `RegExp[]` | -              | Extra patterns to mask, for secrets shaped in a way only your codebase knows (internal token prefixes, customer identifiers). Always applied as if global, so a match is never limited to the first occurrence in a line.                                                |
| `keys`               | `string[]` | -              | Extra keys whose values are masked outright (in log attributes, captured headers and bodies, and URL query strings), on top of the built-in list. Compared case-insensitively and ignoring `-`/`_`, so `apiKey`, `api_key`, and `API-KEY` are one entry.                 |
| `replacement`        | `string`   | `'[REDACTED]'` | Text substituted for anything matched.                                                                                                                                                                                                                                   |

> **Hint** Even with `forwardLogs` off, the SDK augments `ConsoleLogger` so every line written inside a traced execution carries its trace id (`attachTraceIdToLogs`, see [Trace correlation](/observability/sdk#trace-correlation)). That lets you correlate your own log aggregator with traces in the dashboard without shipping the log content anywhere.

##### Trace correlation[#](/observability/sdk#trace-correlation)

These are also options of `createObserveModule()`. They shape how requests get a trace id and how that id shows up in your own logs:

app.module.ts

JS TS

```typescript

import { randomUUID } from 'node:crypto';

export const { ObserveModule, ObserveInstrument } = createObserveModule({
  traceIdKey: 'traceId',
  traceIdGenerator: (req: any) => req.headers['x-request-id'] ?? randomUUID(),
  attachTraceIdToLogs: true,
});
```

| Option                | Type                       | Default                                                                                                    | Description                                                                                                                                                                                                                                                                                                                                                        |
| --------------------- | -------------------------- | ---------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `traceIdKey`          | `string`                   | `'traceId'`                                                                                                | The key used to store the trace id in the request context, for later retrieval through `TracerService`.                                                                                                                                                                                                                                                            |
| `traceIdGenerator`    | `(req: unknown) => string` | Adopts a well-formed `x-request-id` (HTTP header, or TCP/Redis packet metadata) if present, else a UUID v7 | Generates the trace id per request. Called with the request object for HTTP; for other protocols it receives the transport context.                                                                                                                                                                                                                                |
| `attachTraceIdToLogs` | `boolean`                  | `true`                                                                                                     | Augments `ConsoleLogger` to include the trace id in log messages, so logs can be correlated with traces even without `forwardLogs`. In the default text format the id ends the line, after the message (` Trace ID: <id>`); with [JSON logging](/application/logger#json-logging) it is a `traceId` field. Lines written outside a traced execution are unchanged. |

Because the default generator adopts an incoming `x-request-id`, a chain of HTTP services already shares one trace with no extra configuration. The same applies to the TCP and Redis microservice transports on `@nestjs/microservices` 12.0.4 or later. Propagating across gRPC, the other microservice transports, and GraphQL takes a few lines - see [Distributed tracing](/observability/distributed-tracing).

#### Shaping what is recorded[#](/observability/sdk#shaping-what-is-recorded)

These options enrich what the SDK records (who a request was for, what it concerned) and keep out what you don't need.

##### Associating users with telemetry[#](/observability/sdk#associating-users-with-telemetry)

`getUserId` reads the incoming request and returns whatever identifier your system uses for a person: a user id, an account id, or a tenant-scoped id. Set it once and the **Users** view populates automatically:

```typescript

ObserveModule.forRoot({
  // ...
  http: {
    getUserId: (req) => req.user?.id ?? 'anonymous',
  },
});
```

The same option exists on `rpc` (receiving the transport id and the `BaseRpcContext`), `grpc` (receiving the call object), `graphql` (receiving the GraphQL context, for operations with no enclosing HTTP request), and `ws` (receiving the gateway message), each reading the transport's own context instead of an HTTP request. Reporting a user identifier is optional: traffic without one still shows up everywhere except the per-user views. The dashboard treats the identifier as an opaque string and never tries to resolve it into a name or an email, so prefer an opaque internal id over anything personally identifying.

##### Tags and custom attributes[#](/observability/sdk#tags-and-custom-attributes)

`http`, `rpc`, `grpc`, `graphql`, and `jobs` each accept the same two options for attaching your own data to every request they cover:

| Option          | Applies                                                       | Description                                                                         |
| --------------- | ------------------------------------------------------------- | ----------------------------------------------------------------------------------- |
| `tags`          | The same static `Record<string, string>` to every request     | For constants that don't vary per call, e.g., `project`, `env`, `region`.           |
| `setAttributes` | A function of the request/call/job, returning key-value pairs | For anything that varies per call, e.g., a feature flag, a tenant id, a queue name. |

```typescript

ObserveModule.forRoot({
  // ...
  http: {
    tags: { project: 'cats-app', env: process.env.NODE_ENV ?? 'development' },
    setAttributes: (req) => ({
      'user-agent': req.headers['user-agent'],
      'client-ip': req.ip,
    }),
  },
  jobs: {
    setAttributes: (job) => ({ queueName: job.queueName, jobName: job.name }),
  },
});
```

Both appear as tags on the resulting request, job, or span, and are searchable and visible on its detail page. The function receives whatever the transport has: the request for `http`, the transport id and `BaseRpcContext` for `rpc`, the call object for `grpc`, the resolve info and GraphQL context for `graphql`, and `{ queueName, name, id }` for `jobs`. To tag a single span from inside your code rather than every request, use `TracerService` (see [Manual instrumentation](/observability/manual-instrumentation)).

> **Hint** A GraphQL server is usually an HTTP endpoint, so its requests are already subject to the `http` options: `http.ignore` drops a request before the GraphQL layer sees it, and `http.getUserId` supplies the user for queries over HTTP. The `graphql` block tunes what happens *inside* a request that was let through, per operation rather than per resolver, and `graphql.getUserId` is only consulted for operations that aren't already inside an HTTP trace, such as subscriptions over a WebSocket.

##### Ignoring noisy operations[#](/observability/sdk#ignoring-noisy-operations)

Every inbound transport block (`http`, `rpc`, `grpc`, `graphql`, and `ws`) has an `ignore` option that skips instrumentation entirely for matching calls, such as a health check endpoint, an internal probe, or anything else not worth a trace:

```typescript

ObserveModule.forRoot({
  // ...
  http: {
    ignore: ['/health', { method: 'GET', path: /^\/internal\// }],
  },
  rpc: {
    ignore: (transportId, ctx) =>
      ctx instanceof TcpContext && ctx.getPattern() === 'ping',
  },
  grpc: {
    ignore: (call) => call.path.endsWith('/Health/Check'),
  },
  graphql: {
    ignore: (info) => info.fieldName === 'healthcheck',
  },
});
```

`http.ignore` accepts an array of paths, `{ method, path }` pairs (`path` can be a string or a `RegExp`), and plain `RegExp`s or a single predicate function over the request. `rpc.ignore`, `grpc.ignore`, and `graphql.ignore` are predicates over the transport's own context (the `@nestjs/microservices` transport id and `BaseRpcContext`, the gRPC call object, and the GraphQL resolve info respectively). Matching a GraphQL field name skips the whole operation that field leads, not only that field: an operation is measured end to end, so it is either traced or not.

`ignore` stops telemetry from being generated at all. The dashboard's spend-control drop filters are a different tool: they discard already-generated events at ingestion to reduce billed volume. Use `ignore` when you don't want a trace to exist, and drop filters when you want to tune cost on data the SDK is already producing.

`http` additionally takes `queryParamsObfuscateRegex`, a `RegExp` that masks sensitive query string values before they're sent. It is applied on top of the built-in redaction, which always masks well-known sensitive parameters (`token`, `password`, `code`, `signature`, and so on).

##### Trace sampling and batching[#](/observability/sdk#trace-sampling-and-batching)

```typescript

ObserveModule.forRoot({
  // ...
  tracesSampleRate: 0.25,
  maxTracesPerBatch: 1000,
  flushInterval: 5000,
});
```

| Option              | Type                                                                                            | Default | Description                                                                                               |
| ------------------- | ----------------------------------------------------------------------------------------------- | ------- | --------------------------------------------------------------------------------------------------------- |
| `tracesSampleRate`  | `number \| ((protocol: 'http' \| 'rpc' \| 'grpc' \| 'graphql' \| 'ws', attributes) => boolean)` | `1.0`   | Fraction of traces sent, or a predicate for per-trace decisions. `1.0` sends everything; `0.1` sends 10%. |
| `maxTracesPerBatch` | `number`                                                                                        | `1000`  | Caps how many traces go out per batch, to bound volume on high-traffic applications.                      |
| `flushInterval`     | `number` (ms)                                                                                   | `5000`  | How often the SDK batches and sends collected traces.                                                     |

Telemetry is buffered in the process and shipped on the flush interval rather than inline with each request. Sampling here decides what the SDK *produces*. The dashboard's per-project spend controls (span sampling, rate caps, drop filters) act on what it has already sent, and you can change them without a redeploy.

#### Full configuration reference[#](/observability/sdk#full-configuration-reference)

All options at a glance. Options listed under `createObserveModule()` must be set there; everything else goes to `forRoot()`/`forRootAsync()`.

| Where                   | Option                                     | Purpose                                                                    |
| ----------------------- | ------------------------------------------ | -------------------------------------------------------------------------- |
| `createObserveModule()` | `sourceContext`                            | Attach source lines to error stack frames                                  |
| `createObserveModule()` | `traceIdKey`                               | Context key the trace id is stored under                                   |
| `createObserveModule()` | `traceIdGenerator`                         | How each request obtains its trace id                                      |
| `createObserveModule()` | `attachTraceIdToLogs`                      | Add the trace id to `ConsoleLogger` output                                 |
| `createObserveModule()` | `skipInstrumentation`                      | Predicate that excludes provider instances from instrumentation            |
| `forRoot()`             | `appKey`, `appSecret`                      | Project API key pair (or `OBSERVE_APP_KEY`, `OBSERVE_APP_SECRET`)          |
| `forRoot()`             | `endpoint`                                 | Collector base URL (or `OBSERVE_ENDPOINT`)                                 |
| `forRoot()`             | `serviceId`, `serviceVersion`              | Application and release identity                                           |
| `forRoot()`             | `http`, `rpc`, `grpc`, `graphql`           | Per-transport `tags`, `setAttributes`, `getUserId`, `ignore`               |
| `forRoot()`             | `jobs`                                     | `tags` and `setAttributes` for queue and scheduled jobs                    |
| `forRoot()`             | `http.queryParamsObfuscateRegex`           | Mask sensitive query string values                                         |
| `forRoot()`             | `http.capture`                             | Headers (and optionally body) recorded for failed and slow requests        |
| `forRoot()`             | `outgoing`                                 | Database query and outbound HTTP spans                                     |
| `forRoot()`             | `ws`                                       | WebSocket gateway `tags`, `setAttributes`, `getUserId`, `ignore`           |
| `forRoot()`             | `runtimeMetrics`, `runtimeMetricsInterval` | Profiler samples and heartbeat                                             |
| `forRoot()`             | `forwardLogs`, `redaction`                 | Logs streaming and scrubbing                                               |
| `forRoot()`             | `tracesSampleRate`                         | Fraction (or predicate) of traces to send                                  |
| `forRoot()`             | `maxTracesPerBatch`, `flushInterval`       | Batching                                                                   |
| `forRoot()`             | `spanCollapse`                             | Collapse repeated sibling spans (default threshold `20`, keep slowest `3`) |
| `forRoot()`             | `debug`                                    | SDK diagnostics                                                            |

#### Where to go next[#](/observability/sdk#where-to-go-next)

* [Manual instrumentation](/observability/manual-instrumentation) - add your own spans, capture handled errors, attach request-scoped attributes, and report custom metrics.
* [Distributed tracing](/observability/distributed-tracing) - keep one trace across HTTP, gRPC, microservice transports, and GraphQL.
* [Dashboard](/observability/dashboard) - what shows up once the SDK is running, and how the views relate to each other.

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/observability/sdk.md)

----
url: https://docs.nestjs.com/v9/controllers
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Controllers](https://docs.nestjs.com/v9/controllers#controllers)
* [Routing](https://docs.nestjs.com/v9/controllers#routing)
* [Request object](https://docs.nestjs.com/v9/controllers#request-object)
* [Resources](https://docs.nestjs.com/v9/controllers#resources)
* [Route wildcards](https://docs.nestjs.com/v9/controllers#route-wildcards)
* [Status code](https://docs.nestjs.com/v9/controllers#status-code)
* [Headers](https://docs.nestjs.com/v9/controllers#headers)
* [Redirection](https://docs.nestjs.com/v9/controllers#redirection)
* [Route parameters](https://docs.nestjs.com/v9/controllers#route-parameters)
* [Sub-Domain Routing](https://docs.nestjs.com/v9/controllers#sub-domain-routing)
* [Scopes](https://docs.nestjs.com/v9/controllers#scopes)
* [Asynchronicity](https://docs.nestjs.com/v9/controllers#asynchronicity)
* [Request payloads](https://docs.nestjs.com/v9/controllers#request-payloads)
* [Handling errors](https://docs.nestjs.com/v9/controllers#handling-errors)
* [Full resource sample](https://docs.nestjs.com/v9/controllers#full-resource-sample)
* [Getting up and running](https://docs.nestjs.com/v9/controllers#getting-up-and-running)
* [Library-specific approach](https://docs.nestjs.com/v9/controllers#library-specific-approach)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/controllers.md "Suggest Edits")

### Controllers

Controllers are responsible for handling incoming **requests** and returning **responses** to the client.

A controller's purpose is to receive specific requests for the application. The **routing** mechanism controls which controller receives which requests. Frequently, each controller has more than one route, and different routes can perform different actions.

In order to create a basic controller, we use classes and **decorators**. Decorators associate classes with required metadata and enable Nest to create a routing map (tie requests to the corresponding controllers).

> **Hint** For quickly creating a CRUD controller with the [validation](https://docs.nestjs.com/techniques/validation) built-in, you may use the CLI's [CRUD generator](https://docs.nestjs.com/recipes/crud-generator#crud-generator): `nest g resource [name]`.

#### Routing[#](/controllers#routing)

In the following example we'll use the `@Controller()` decorator, which is **required** to define a basic controller. We'll specify an optional route path prefix of `cats`. Using a path prefix in a `@Controller()` decorator allows us to easily group a set of related routes, and minimize repetitive code. For example, we may choose to group a set of routes that manage interactions with a cat entity under the route `/cats`. In that case, we could specify the path prefix `cats` in the `@Controller()` decorator so that we don't have to repeat that portion of the path for each route in the file.

cats.controller.ts

JS TS

```typescript

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

@Controller('cats')
export class CatsController {
  @Get()
  findAll(): string {
    return 'This action returns all cats';
  }
}
```

```typescript

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

@Controller('cats')
export class CatsController {
  @Get()
  findAll() {
    return 'This action returns all cats';
  }
}
```

> **Hint** To create a controller using the CLI, simply execute the `$ nest g controller [name]` command.

The `@Get()` HTTP request method decorator before the `findAll()` method tells Nest to create a handler for a specific endpoint for HTTP requests. The endpoint corresponds to the HTTP request method (GET in this case) and the route path. What is the route path? The route path for a handler is determined by concatenating the (optional) prefix declared for the controller, and any path specified in the method's decorator. Since we've declared a prefix for every route ( `cats`), and haven't added any path information in the decorator, Nest will map `GET /cats` requests to this handler. As mentioned, the path includes both the optional controller path prefix **and** any path string declared in the request method decorator. For example, a path prefix of `cats` combined with the decorator `@Get('breed')` would produce a route mapping for requests like `GET /cats/breed`.

In our example above, when a GET request is made to this endpoint, Nest routes the request to our user-defined `findAll()` method. Note that the method name we choose here is completely arbitrary. We obviously must declare a method to bind the route to, but Nest doesn't attach any significance to the method name chosen.

This method will return a 200 status code and the associated response, which in this case is just a string. Why does that happen? To explain, we'll first introduce the concept that Nest employs two **different** options for manipulating responses:

|                        |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Standard (recommended) | Using this built-in method, when a request handler returns a JavaScript object or array, it will **automatically** be serialized to JSON. When it returns a JavaScript primitive type (e.g., `string`, `number`, `boolean`), however, Nest will send just the value without attempting to serialize it. This makes response handling simple: just return the value, and Nest takes care of the rest. Furthermore, the response's **status code** is always 200 by default, except for POST requests which use 201. We can easily change this behavior by adding the `@HttpCode(...)` decorator at a handler-level (see [Status codes](controllers#status-code)). |
| Library-specific       | We can use the library-specific (e.g., Express) [response object](https://expressjs.com/en/api.html#res), which can be injected using the `@Res()` decorator in the method handler signature (e.g., `findAll(@Res() response)`). With this approach, you have the ability to use the native response handling methods exposed by that object. For example, with Express, you can construct responses using code like `response.status(200).send()`.                                                                                                                                                                                                              |

> **Warning** Nest detects when the handler is using either `@Res()` or `@Next()`, indicating you have chosen the library-specific option. If both approaches are used at the same time, the Standard approach is **automatically disabled** for this single route and will no longer work as expected. To use both approaches at the same time (for example, by injecting the response object to only set cookies/headers but still leave the rest to the framework), you must set the `passthrough` option to `true` in the `@Res({ passthrough: true })` decorator.

```typescript

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

@Controller('cats')
export class CatsController {
  @Get()
  findAll(@Req() request: Request): string {
    return 'This action returns all cats';
  }
}
```

```typescript

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

@Controller('cats')
export class CatsController {
  @Get()
  @Bind(Req())
  findAll(request) {
    return 'This action returns all cats';
  }
}
```

> **Hint** In order to take advantage of `express` typings (as in the `request: Request` parameter example above), install `@types/express` package.

The request object represents the HTTP request and has properties for the request query string, parameters, HTTP headers, and body (read more [here](https://expressjs.com/en/api.html#req)). In most cases, it's not necessary to grab these properties manually. We can use dedicated decorators instead, such as `@Body()` or `@Query()`, which are available out of the box. Below is a list of the provided decorators and the plain platform-specific objects they represent.

|                           |                                     |
| ------------------------- | ----------------------------------- |
| `@Request(), @Req()`      | `req`                               |
| `@Response(), @Res()`\*   | `res`                               |
| `@Next()`                 | `next`                              |
| `@Session()`              | `req.session`                       |
| `@Param(key?: string)`    | `req.params` / `req.params[key]`    |
| `@Body(key?: string)`     | `req.body` / `req.body[key]`        |
| `@Query(key?: string)`    | `req.query` / `req.query[key]`      |
| `@Headers(name?: string)` | `req.headers` / `req.headers[name]` |
| `@Ip()`                   | `req.ip`                            |
| `@HostParam()`            | `req.hosts`                         |

\* For compatibility with typings across underlying HTTP platforms (e.g., Express and Fastify), Nest provides `@Res()` and `@Response()` decorators. `@Res()` is simply an alias for `@Response()`. Both directly expose the underlying native platform `response` object interface. When using them, you should also import the typings for the underlying library (e.g., `@types/express`) to take full advantage. Note that when you inject either `@Res()` or `@Response()` in a method handler, you put Nest into **Library-specific mode** for that handler, and you become responsible for managing the response. When doing so, you must issue some kind of response by making a call on the `response` object (e.g., `res.json(...)` or `res.send(...)`), or the HTTP server will hang.

> **Hint** To learn how to create your own custom decorators, visit [this](/v9/custom-decorators) chapter.

#### Resources[#](/controllers#resources)

Earlier, we defined an endpoint to fetch the cats resource (**GET** route). We'll typically also want to provide an endpoint that creates new records. For this, let's create the **POST** handler:

cats.controller.ts

JS TS

```typescript

import { Controller, Get, Post } from '@nestjs/common';

@Controller('cats')
export class CatsController {
  @Post()
  create(): string {
    return 'This action adds a new cat';
  }

  @Get()
  findAll(): string {
    return 'This action returns all cats';
  }
}
```

```typescript

import { Controller, Get, Post } from '@nestjs/common';

@Controller('cats')
export class CatsController {
  @Post()
  create() {
    return 'This action adds a new cat';
  }

  @Get()
  findAll() {
    return 'This action returns all cats';
  }
}
```

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.

#### Route wildcards[#](/controllers#route-wildcards)

Pattern based routes are supported as well. For instance, the asterisk is used as a wildcard, and will match any combination of characters.

```typescript

@Get('ab*cd')
findAll() {
  return 'This route uses a wildcard';
}
```

The `'ab*cd'` route path will match `abcd`, `ab_cd`, `abecd`, and so on. The characters `?`, `+`, `*`, and `()` may be used in a route path, and are subsets of their regular expression counterparts. The hyphen ( `-`) and the dot (`.`) are interpreted literally by string-based paths.

#### Status code[#](/controllers#status-code)

As mentioned, the response **status code** is always **200** by default, except for POST requests which are **201**. We can easily change this behavior by adding the `@HttpCode(...)` decorator at a handler level.

```typescript

@Post()
@HttpCode(204)
create() {
  return 'This action adds a new cat';
}
```

> **Hint** Import `HttpCode` from the `@nestjs/common` package.

Often, your status code isn't static but depends on various factors. In that case, you can use a library-specific **response** (inject using `@Res()`) object (or, in case of an error, throw an exception).

#### Headers[#](/controllers#headers)

To specify a custom response header, you can either use a `@Header()` decorator or a library-specific response object (and call `res.header()` directly).

```typescript

@Post()
@Header('Cache-Control', 'none')
create() {
  return 'This action adds a new cat';
}
```

> **Hint** Import `Header` from the `@nestjs/common` package.

#### Redirection[#](/controllers#redirection)

To redirect a response to a specific URL, you can either use a `@Redirect()` decorator or a library-specific response object (and call `res.redirect()` directly).

`@Redirect()` takes two arguments, `url` and `statusCode`, both are optional. The default value of `statusCode` is `302` (`Found`) if omitted.

```typescript

@Get()
@Redirect('https://nestjs.com', 301)
```

Sometimes you may want to determine the HTTP status code or the redirect URL dynamically. Do this by returning an object from the route handler method with the shape:

```json

{
  "url": string,
  "statusCode": number
}
```

Returned values will override any arguments passed to the `@Redirect()` decorator. For example:

```typescript

@Get('docs')
@Redirect('https://docs.nestjs.com', 302)
getDocs(@Query('version') version) {
  if (version && version === '5') {
    return { url: 'https://docs.nestjs.com/v5/' };
  }
}
```

#### Route parameters[#](/controllers#route-parameters)

Routes with static paths won't work when you need to accept **dynamic data** as part of the request (e.g., `GET /cats/1` to get cat with id `1`). In order to define routes with parameters, we can add route parameter **tokens** in the path of the route to capture the dynamic value at that position in the request URL. The route parameter token in the `@Get()` decorator example below demonstrates this usage. Route parameters declared in this way can be accessed using the `@Param()` decorator, which should be added to the method signature.

> **Hint** Routes with parameters should be declared after any static paths. This prevents the parameterized paths from intercepting traffic destined for the static paths.

JS TS

```typescript

@Get(':id')
findOne(@Param() params: any): string {
  console.log(params.id);
  return `This action returns a #${params.id} cat`;
}
```

```typescript

@Get(':id')
@Bind(Param())
findOne(params) {
  console.log(params.id);
  return `This action returns a #${params.id} cat`;
}
```

`@Param()` is used to decorate a method parameter (`params` in the example above), and makes the **route** parameters available as properties of that decorated method parameter inside the body of the method. As seen in the code above, we can access the `id` parameter by referencing `params.id`. You can also pass in a particular parameter token to the decorator, and then reference the route parameter directly by name in the method body.

> **Hint** Import `Param` from the `@nestjs/common` package.

JS TS

```typescript

@Get(':id')
findOne(@Param('id') id: string): string {
  return `This action returns a #${id} cat`;
}
```

```typescript

@Get(':id')
@Bind(Param('id'))
findOne(id) {
  return `This action returns a #${id} cat`;
}
```

#### Sub-Domain Routing[#](/controllers#sub-domain-routing)

The `@Controller` decorator can take a `host` option to require that the HTTP host of the incoming requests matches some specific value.

```typescript

@Controller({ host: 'admin.example.com' })
export class AdminController {
  @Get()
  index(): string {
    return 'Admin page';
  }
}
```

> **Warning** Since **Fastify** lacks support for nested routers, when using sub-domain routing, the (default) Express adapter should be used instead.

Similar to a route `path`, the `hosts` option can use tokens to capture the dynamic value at that position in the host name. The host parameter token in the `@Controller()` decorator example below demonstrates this usage. Host parameters declared in this way can be accessed using the `@HostParam()` decorator, which should be added to the method signature.

```typescript

@Controller({ host: ':account.example.com' })
export class AccountController {
  @Get()
  getInfo(@HostParam('account') account: string) {
    return account;
  }
}
```

#### Scopes[#](/controllers#scopes)

For people coming from different programming language backgrounds, it might be unexpected to learn that in Nest, almost everything is shared across incoming requests. We have a connection pool to the database, singleton services with global state, etc. Remember that Node.js doesn't follow the request/response Multi-Threaded Stateless Model in which every request is processed by a separate thread. Hence, using singleton instances is fully **safe** for our applications.

However, there are edge-cases when request-based lifetime of the controller may be the desired behavior, for instance per-request caching in GraphQL applications, request tracking or multi-tenancy. Learn how to control scopes [here](/v9/fundamentals/injection-scopes).

#### Asynchronicity[#](/controllers#asynchronicity)

We love modern JavaScript and we know that data extraction is mostly **asynchronous**. That's why Nest supports and works well with `async` functions.

> **Hint** Learn more about `async / await` feature [here](https://kamilmysliwiec.com/typescript-2-1-introduction-async-await)

Every async function has to return a `Promise`. This means that you can return a deferred value that Nest will be able to resolve by itself. Let's see an example of this:

cats.controller.ts

JS TS

```typescript

@Get()
async findAll(): Promise<any[]> {
  return [];
}
```

```typescript

@Get()
async findAll() {
  return [];
}
```

The above code is fully valid. Furthermore, Nest route handlers are even more powerful by being able to return RxJS [observable streams](http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html). Nest will automatically subscribe to the source underneath and take the last emitted value (once the stream is completed).

cats.controller.ts

JS TS

```typescript

@Get()
findAll(): Observable<any[]> {
  return of([]);
}
```

```typescript

@Get()
findAll() {
  return of([]);
}
```

```typescript

export class CreateCatDto {
  name: string;
  age: number;
  breed: string;
}
```

It has only three basic properties. Thereafter we can use the newly created DTO inside the `CatsController`:

cats.controller.ts

JS TS

```typescript

@Post()
async create(@Body() createCatDto: CreateCatDto) {
  return 'This action adds a new cat';
}
```

```typescript

@Post()
@Bind(Body())
async create(createCatDto) {
  return 'This action adds a new cat';
}
```

> **Hint** Our `ValidationPipe` can filter out properties that should not be received by the method handler. In this case, we can whitelist the acceptable properties, and any property not included in the whitelist is automatically stripped from the resulting object. In the `CreateCatDto` example, our whitelist is the `name`, `age`, and `breed` properties. Learn more [here](https://docs.nestjs.com/techniques/validation#stripping-properties).

#### Handling errors[#](/controllers#handling-errors)

There's a separate chapter about handling errors (i.e., working with exceptions) [here](/v9/exception-filters).

#### Full resource sample[#](/controllers#full-resource-sample)

Below is an example that makes use of several of the available decorators to create a basic controller. This controller exposes a couple of methods to access and manipulate internal data.

cats.controller.ts

JS TS

```typescript

import { Controller, Get, Query, Post, Body, Put, Param, Delete } from '@nestjs/common';
import { CreateCatDto, UpdateCatDto, ListAllEntities } from './dto';

@Controller('cats')
export class CatsController {
  @Post()
  create(@Body() createCatDto: CreateCatDto) {
    return 'This action adds a new cat';
  }

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

  @Get(':id')
  findOne(@Param('id') id: string) {
    return `This action returns a #${id} cat`;
  }

  @Put(':id')
  update(@Param('id') id: string, @Body() updateCatDto: UpdateCatDto) {
    return `This action updates a #${id} cat`;
  }

  @Delete(':id')
  remove(@Param('id') id: string) {
    return `This action removes a #${id} cat`;
  }
}
```

```typescript

import { Controller, Get, Query, Post, Body, Put, Param, Delete, Bind } from '@nestjs/common';

@Controller('cats')
export class CatsController {
  @Post()
  @Bind(Body())
  create(createCatDto) {
    return 'This action adds a new cat';
  }

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

  @Get(':id')
  @Bind(Param('id'))
  findOne(id) {
    return `This action returns a #${id} cat`;
  }

  @Put(':id')
  @Bind(Param('id'), Body())
  update(id, updateCatDto) {
    return `This action updates a #${id} cat`;
  }

  @Delete(':id')
  @Bind(Param('id'))
  remove(id) {
    return `This action removes a #${id} cat`;
  }
}
```

> **Hint** Nest CLI provides a generator (schematic) that automatically generates **all the boilerplate code** to help us avoid doing all of this, and make the developer experience much simpler. Read more about this feature [here](/v9/recipes/crud-generator).

#### Getting up and running[#](/controllers#getting-up-and-running)

With the above controller fully defined, Nest still doesn't know that `CatsController` exists and as a result won't create an instance of this class.

Controllers always belong to a module, which is why we include the `controllers` array within the `@Module()` decorator. Since we haven't yet defined any other modules except the root `AppModule`, we'll use that to introduce the `CatsController`:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { CatsController } from './cats/cats.controller';

@Module({
  controllers: [CatsController],
})
export class AppModule {}
```

```typescript

import { Controller, Get, Post, Res, HttpStatus } from '@nestjs/common';
import { Response } from 'express';

@Controller('cats')
export class CatsController {
  @Post()
  create(@Res() res: Response) {
    res.status(HttpStatus.CREATED).send();
  }

  @Get()
  findAll(@Res() res: Response) {
     res.status(HttpStatus.OK).json([]);
  }
}
```

```typescript

import { Controller, Get, Post, Bind, Res, Body, HttpStatus } from '@nestjs/common';

@Controller('cats')
export class CatsController {
  @Post()
  @Bind(Res(), Body())
  create(res, createCatDto) {
    res.status(HttpStatus.CREATED).send();
  }

  @Get()
  @Bind(Res())
  findAll(res) {
     res.status(HttpStatus.OK).json([]);
  }
}
```

Though this approach works, and does in fact allow for more flexibility in some ways by providing full control of the response object (headers manipulation, library-specific features, and so on), it should be used with care. In general, the approach is much less clear and does have some disadvantages. The main disadvantage is that your code becomes platform-dependent (as underlying libraries may have different APIs on the response object), and harder to test (you'll have to mock the response object, etc.).

Also, in the example above, you lose compatibility with Nest features that depend on Nest standard response handling, such as Interceptors and `@HttpCode()` / `@Header()` decorators. To fix this, you can set the `passthrough` option to `true`, as follows:

JS TS

```typescript

@Get()
findAll(@Res({ passthrough: true }) res: Response) {
  res.status(HttpStatus.OK);
  return [];
}
```

```typescript

@Get()
@Bind(Res({ passthrough: true }))
findAll(res) {
  res.status(HttpStatus.OK);
  return [];
}
```

Now you can interact with the native response object (for example, set cookies or headers depending on certain conditions), but leave the rest to the framework.

----
url: https://docs.nestjs.com/v8/recipes/documentation
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Documentation](https://docs.nestjs.com/v8/recipes/documentation#documentation)
* [Setup](https://docs.nestjs.com/v8/recipes/documentation#setup)
* [Generation](https://docs.nestjs.com/v8/recipes/documentation#generation)
* [Contribute](https://docs.nestjs.com/v8/recipes/documentation#contribute)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/recipes/documentation.md "Suggest Edits")

### Documentation

**Compodoc** is a documentation tool for Angular applications. Since Nest and Angular share similar project and code structures, **Compodoc** works with Nest applications as well.

#### Setup[#](/recipes/documentation#setup)

Setting up Compodoc inside an existing Nest project is very simple. Start by adding the dev-dependency with the following command in your OS terminal:

```bash

$ npm i -D @compodoc/compodoc
```

#### Generation[#](/recipes/documentation#generation)

Generate project documentation using the following command (npm 6 is required for `npx` support). See [the official documentation](https://compodoc.app/guides/usage.html) for more options.

```bash

$ npx @compodoc/compodoc -p tsconfig.json -s
```

Open your browser and navigate to <http://localhost:8080>. You should see an initial Nest CLI project:

#### Contribute[#](/recipes/documentation#contribute)

You can participate and contribute to the Compodoc project [here](https://github.com/compodoc/compodoc).

----
url: https://docs.nestjs.com/v7/techniques/file-upload
----

* [File upload](https://docs.nestjs.com/v7/techniques/file-upload#file-upload)
* [Basic example](https://docs.nestjs.com/v7/techniques/file-upload#basic-example)
* [Array of files](https://docs.nestjs.com/v7/techniques/file-upload#array-of-files)
* [Multiple files](https://docs.nestjs.com/v7/techniques/file-upload#multiple-files)
* [Any files](https://docs.nestjs.com/v7/techniques/file-upload#any-files)
* [Default options](https://docs.nestjs.com/v7/techniques/file-upload#default-options)
* [Async configuration](https://docs.nestjs.com/v7/techniques/file-upload#async-configuration)
* [Example](https://docs.nestjs.com/v7/techniques/file-upload#example)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/techniques/file-upload.md "Suggest Edits")

### File upload

To handle file uploading, Nest provides a built-in module based on the [multer](https://github.com/expressjs/multer) middleware package for Express. Multer handles data posted in the `multipart/form-data` format, which is primarily used for uploading files via an HTTP `POST` request. This module is fully configurable and you can adjust its behavior to your application requirements.

> **Warning** Multer cannot process data which is not in the supported multipart format (`multipart/form-data`). Also, note that this package is not compatible with the `FastifyAdapter`.

For better type safety, let's install Multer typings package:

```shell

$ npm i -D @types/multer
```

With this package installed, we can now use the `Express.Multer.File` type (you can import this type as follows: `import { Express } from 'express'`).

#### Basic example[#](/techniques/file-upload#basic-example)

To upload a single file, simply tie the `FileInterceptor()` interceptor to the route handler and extract `file` from the `request` using the `@UploadedFile()` decorator.

JS TS

```typescript

@Post('upload')
@UseInterceptors(FileInterceptor('file'))
uploadFile(@UploadedFile() file: Express.Multer.File) {
  console.log(file);
}
```

```typescript

@Post('upload')
@UseInterceptors(FileInterceptor('file'))
@Bind(UploadedFile())
uploadFile(file) {
  console.log(file);
}
```

> **Hint** The `FileInterceptor()` decorator is exported from the `@nestjs/platform-express` package. The `@UploadedFile()` decorator is exported from `@nestjs/common`.

The `FileInterceptor()` decorator takes two arguments:

* `fieldName`: string that supplies the name of the field from the HTML form that holds a file
* `options`: optional object of type `MulterOptions`. This is the same object used by the multer constructor (more details [here](https://github.com/expressjs/multer#multeropts)).

> **Warning**`FileInterceptor()` may not be compatible with third party cloud providers like Google Firebase or others.

```typescript

@Post('upload')
@UseInterceptors(FilesInterceptor('files'))
uploadFile(@UploadedFiles() files: Express.Multer.File) {
  console.log(files);
}
```

```typescript

@Post('upload')
@UseInterceptors(FilesInterceptor('files'))
@Bind(UploadedFiles())
uploadFile(files) {
  console.log(files);
}
```

> **Hint** The `FilesInterceptor()` decorator is exported from the `@nestjs/platform-express` package. The `@UploadedFiles()` decorator is exported from `@nestjs/common`.

#### Multiple files[#](/techniques/file-upload#multiple-files)

To upload multiple fields (all with different field name keys), use the `FileFieldsInterceptor()` decorator. This decorator takes two arguments:

* `uploadedFields`: an array of objects, where each object specifies a required `name` property with a string value specifying a field name, as described above, and an optional `maxCount` property, as described above
* `options`: optional `MulterOptions` object, as described above

When using `FileFieldsInterceptor()`, extract files from the `request` with the `@UploadedFiles()` decorator.

JS TS

```typescript

@Post('upload')
@UseInterceptors(FileFieldsInterceptor([
  { name: 'avatar', maxCount: 1 },
  { name: 'background', maxCount: 1 },
]))
uploadFile(@UploadedFiles() files) {
  console.log(files);
}
```

```typescript

@Post('upload')
@Bind(UploadedFiles())
@UseInterceptors(FileFieldsInterceptor([
  { name: 'avatar', maxCount: 1 },
  { name: 'background', maxCount: 1 },
]))
uploadFile(files) {
  console.log(files);
}
```

#### Any files[#](/techniques/file-upload#any-files)

To upload all fields with arbitrary field name keys, use the `AnyFilesInterceptor()` decorator. This decorator can accept an optional `options` object as described above.

When using `AnyFilesInterceptor()`, extract files from the `request` with the `@UploadedFiles()` decorator.

JS TS

```typescript

@Post('upload')
@UseInterceptors(AnyFilesInterceptor())
uploadFile(@UploadedFiles() files: Express.Multer.File) {
  console.log(files);
}
```

```typescript

@Post('upload')
@Bind(UploadedFiles())
@UseInterceptors(AnyFilesInterceptor())
uploadFile(files) {
  console.log(files);
}
```

#### Default options[#](/techniques/file-upload#default-options)

You can specify multer options in the file interceptors as described above. To set default options, you can call the static `register()` method when you import the `MulterModule`, passing in supported options. You can use all options listed [here](https://github.com/expressjs/multer#multeropts).

```typescript

MulterModule.register({
  dest: './upload',
});
```

> **Hint** The `MulterModule` class is exported from the `@nestjs/platform-express` package.

#### Async configuration[#](/techniques/file-upload#async-configuration)

When you need to set `MulterModule` options asynchronously instead of statically, use the `registerAsync()` method. As with most dynamic modules, Nest provides several techniques to deal with async configuration.

One technique is to use a factory function:

```typescript

MulterModule.registerAsync({
  useFactory: () => ({
    dest: './upload',
  }),
});
```

Like other [factory providers](https://docs.nestjs.com/fundamentals/custom-providers#factory-providers-usefactory), our factory function can be `async` and can inject dependencies through `inject`.

```typescript

MulterModule.registerAsync({
  imports: [ConfigModule],
  useFactory: async (configService: ConfigService) => ({
    dest: configService.getString('MULTER_DEST'),
  }),
  inject: [ConfigService],
});
```

Alternatively, you can configure the `MulterModule` using a class instead of a factory, as shown below:

```typescript

MulterModule.registerAsync({
  useClass: MulterConfigService,
});
```

The construction above instantiates `MulterConfigService` inside `MulterModule`, using it to create the required options object. Note that in this example, the `MulterConfigService` has to implement the `MulterOptionsFactory` interface, as shown below. The `MulterModule` will call the `createMulterOptions()` method on the instantiated object of the supplied class.

```typescript

@Injectable()
class MulterConfigService implements MulterOptionsFactory {
  createMulterOptions(): MulterModuleOptions {
    return {
      dest: './upload',
    };
  }
}
```

If you want to reuse an existing options provider instead of creating a private copy inside the `MulterModule`, use the `useExisting` syntax.

```typescript

MulterModule.registerAsync({
  imports: [ConfigModule],
  useExisting: ConfigService,
});
```

#### Example[#](/techniques/file-upload#example)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/29-file-upload).

----
url: https://docs.nestjs.com/v7/security/cors
----

* [CORS](https://docs.nestjs.com/v7/security/cors#cors)
* [Getting started](https://docs.nestjs.com/v7/security/cors#getting-started)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/security/cors.md "Suggest Edits")

### CORS

Cross-origin resource sharing (CORS) is a mechanism that allows resources to be requested from another domain. Under the hood, Nest makes use of the Express [cors](https://github.com/expressjs/cors) package. This package provides various options that you can customize based on your requirements.

#### Getting started[#](/security/cors#getting-started)

To enable CORS, call the `enableCors()` method on the Nest application object.

```typescript

const app = await NestFactory.create(AppModule);
app.enableCors();
await app.listen(3000);
```

The `enableCors()` method takes an optional configuration object argument. The available properties of this object are described in the official [CORS](https://github.com/expressjs/cors#configuration-options) documentation. Another way is to pass a [callback function](https://github.com/expressjs/cors#configuring-cors-asynchronously) that lets you define the configuration object asynchronously based on the request (on the fly).

Alternatively, enable CORS via the `create()` method's options object. Set the `cors` property to `true` to enable CORS with default settings. Or, pass a [CORS configuration object](https://github.com/expressjs/cors#configuration-options) or [callback function](https://github.com/expressjs/cors#configuring-cors-asynchronously) as the `cors` property value to customize its behavior.

```typescript

const app = await NestFactory.create(AppModule, { cors: true });
await app.listen(3000);
```

Above method only applies to REST endpoints.

To enable CORS in GraphQL, set `cors` property to `true` or pass [CORS configuration object](https://github.com/expressjs/cors#configuration-options) or a [callback function](https://github.com/expressjs/cors#configuring-cors-asynchronously) as the `cors` property value when you import GraphQL module.

> **Warning**`CorsOptionsDelegate` solution is not working with the `apollo-server-fastify` package yet.

```typescript

GraphQLModule.forRoot({
  cors: {
    origin: 'http://localhost:3000',
    credentials: true,
  },
}),
```

----
url: https://docs.nestjs.com/microservices/guards
----

[Skip to content](#content)

On this page

* [Guards](https://docs.nestjs.com/microservices/guards#guards)
* [Binding guards](https://docs.nestjs.com/microservices/guards#binding-guards)

### Guards

Microservice guards work the same way as [regular HTTP application guards](/guards). The only difference is that they should throw `RpcException` instead of `HttpException`. When a guard returns `false`, Nest throws an `RpcException` with the `Forbidden resource` message.

> **Hint** The `RpcException` class is exposed from the `@nestjs/microservices` package.

#### Binding guards[#](/microservices/guards#binding-guards)

The following example uses a method-scoped guard. As with HTTP-based applications, you can also use controller-scoped guards (i.e., prefix the controller class with a `@UseGuards()` decorator).

JS TS

```typescript

@UseGuards(AuthGuard)
@MessagePattern({ cmd: 'sum' })
accumulate(data: number[]): number {
  return (data || []).reduce((a, b) => a + b);
}
```

```typescript

@UseGuards(AuthGuard)
@MessagePattern({ cmd: 'sum' })
accumulate(data) {
  return (data || []).reduce((a, b) => a + b);
}
```

> **Hint** Global guards registered on the main HTTP application don't apply to microservices connected to a [hybrid application](/faq/hybrid-application) unless you set the `inheritAppConfig` option. See [sharing configuration](/faq/hybrid-application#sharing-configuration).

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/microservices/guards.md)

----
url: https://docs.nestjs.com/v10/graphql/other-features
----

* [Other features](https://docs.nestjs.com/v10/graphql/other-features#other-features)
* [Overview](https://docs.nestjs.com/v10/graphql/other-features#overview)
* [Execution context](https://docs.nestjs.com/v10/graphql/other-features#execution-context)
* [Exception filters](https://docs.nestjs.com/v10/graphql/other-features#exception-filters)
* [Custom decorators](https://docs.nestjs.com/v10/graphql/other-features#custom-decorators)
* [Execute enhancers at the field resolver level](https://docs.nestjs.com/v10/graphql/other-features#execute-enhancers-at-the-field-resolver-level)
* [Creating a custom driver](https://docs.nestjs.com/v10/graphql/other-features#creating-a-custom-driver)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/guards-interceptors.md "Suggest Edits")

### Other features

In the GraphQL world, there is a lot of debate about handling issues like **authentication**, or **side-effects** of operations. Should we handle things inside the business logic? Should we use a higher-order function to enhance queries and mutations with authorization logic? Or should we use [schema directives](https://www.apollographql.com/docs/apollo-server/schema/directives/)? There is no single one-size-fits-all answer to these questions.

Nest helps address these issues with its cross-platform features like [guards](/v10/guards) and [interceptors](/v10/interceptors). The philosophy is to reduce redundancy and provide tooling that helps create well-structured, readable, and consistent applications.

#### Overview[#](/graphql/other-features#overview)

You can use standard [guards](/v10/guards), [interceptors](/v10/interceptors), [filters](/v10/exception-filters) and [pipes](/v10/pipes) in the same fashion with GraphQL as with any RESTful application. Additionally, you can easily create your own decorators by leveraging the [custom decorators](/v10/custom-decorators) feature. Let's take a look at a sample GraphQL query handler.

```typescript

@Query('author')
@UseGuards(AuthGuard)
async getAuthor(@Args('id', ParseIntPipe) id: number) {
  return this.authorsService.findOneById(id);
}
```

As you can see, GraphQL works with both guards and pipes in the same way as HTTP REST handlers. Because of this, you can move your authentication logic to a guard; you can even reuse the same guard class across both a REST and GraphQL API interface. Similarly, interceptors work across both types of applications in the same way:

```typescript

@Mutation()
@UseInterceptors(EventsInterceptor)
async upvotePost(@Args('postId') postId: number) {
  return this.postsService.upvoteById({ id: postId });
}
```

#### Execution context[#](/graphql/other-features#execution-context)

Since GraphQL receives a different type of data in the incoming request, the [execution context](https://docs.nestjs.com/fundamentals/execution-context) received by both guards and interceptors is somewhat different with GraphQL vs. REST. GraphQL resolvers have a distinct set of arguments: `root`, `args`, `context`, and `info`. Thus guards and interceptors must transform the generic `ExecutionContext` to a `GqlExecutionContext`. This is straightforward:

```typescript

import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common';
import { GqlExecutionContext } from '@nestjs/graphql';

@Injectable()
export class AuthGuard implements CanActivate {
  canActivate(context: ExecutionContext): boolean {
    const ctx = GqlExecutionContext.create(context);
    return true;
  }
}
```

The GraphQL context object returned by `GqlExecutionContext.create()` exposes a **get** method for each GraphQL resolver argument (e.g., `getArgs()`, `getContext()`, etc). Once transformed, we can easily pick out any GraphQL argument for the current request.

#### Exception filters[#](/graphql/other-features#exception-filters)

Nest standard [exception filters](/v10/exception-filters) are compatible with GraphQL applications as well. As with `ExecutionContext`, GraphQL apps should transform the `ArgumentsHost` object to a `GqlArgumentsHost` object.

```typescript

@Catch(HttpException)
export class HttpExceptionFilter implements GqlExceptionFilter {
  catch(exception: HttpException, host: ArgumentsHost) {
    const gqlHost = GqlArgumentsHost.create(host);
    return exception;
  }
}
```

> **Hint** Both `GqlExceptionFilter` and `GqlArgumentsHost` are imported from the `@nestjs/graphql` package.

Note that unlike the REST case, you don't use the native `response` object to generate a response.

#### Custom decorators[#](/graphql/other-features#custom-decorators)

As mentioned, the [custom decorators](/v10/custom-decorators) feature works as expected with GraphQL resolvers.

```typescript

export const User = createParamDecorator(
  (data: unknown, ctx: ExecutionContext) =>
    GqlExecutionContext.create(ctx).getContext().user,
);
```

Use the `@User()` custom decorator as follows:

```typescript

@Mutation()
async upvotePost(
  @User() user: UserEntity,
  @Args('postId') postId: number,
) {}
```

> **Hint** In the above example, we have assumed that the `user` object is assigned to the context of your GraphQL application.

#### Execute enhancers at the field resolver level[#](/graphql/other-features#execute-enhancers-at-the-field-resolver-level)

In the GraphQL context, Nest does not run **enhancers** (the generic name for interceptors, guards and filters) at the field level [see this issue](https://github.com/nestjs/graphql/issues/320#issuecomment-511193229): they only run for the top level `@Query()`/`@Mutation()` method. You can tell Nest to execute interceptors, guards or filters for methods annotated with `@ResolveField()` by setting the `fieldResolverEnhancers` option in `GqlModuleOptions`. Pass it a list of `'interceptors'`, `'guards'`, and/or `'filters'` as appropriate:

```typescript

GraphQLModule.forRoot({
  fieldResolverEnhancers: ['interceptors']
}),
```

> **Warning** Enabling enhancers for field resolvers can cause performance issues when you are returning lots of records and your field resolver is executed thousands of times. For this reason, when you enable `fieldResolverEnhancers`, we advise you to skip execution of enhancers that are not strictly necessary for your field resolvers. You can do this using the following helper function:

```typescript

export function isResolvingGraphQLField(context: ExecutionContext): boolean {
  if (context.getType<GqlContextType>() === 'graphql') {
    const gqlContext = GqlExecutionContext.create(context);
    const info = gqlContext.getInfo();
    const parentType = info.parentType.name;
    return parentType !== 'Query' && parentType !== 'Mutation';
  }
  return false;
}
```

#### Creating a custom driver[#](/graphql/other-features#creating-a-custom-driver)

Nest provides two official drivers out-of-the-box: `@nestjs/apollo` and `@nestjs/mercurius`, as well as an API allowing developers to build new **custom drivers**. With a custom driver, you can integrate any GraphQL library or extend the existing integration, adding extra features on top.

For example, to integrate the `express-graphql` package, you could create the following driver class:

```typescript

import { AbstractGraphQLDriver, GqlModuleOptions } from '@nestjs/graphql';
import { graphqlHTTP } from 'express-graphql';

class ExpressGraphQLDriver extends AbstractGraphQLDriver {
  async start(options: GqlModuleOptions<any>): Promise<void> {
    options = await this.graphQlFactory.mergeWithSchema(options);

    const { httpAdapter } = this.httpAdapterHost;
    httpAdapter.use(
      '/graphql',
      graphqlHTTP({
        schema: options.schema,
        graphiql: true,
      }),
    );
  }

  async stop() {}
}
```

And then use it as follows:

```typescript

GraphQLModule.forRoot({
  driver: ExpressGraphQLDriver,
});
```

----
url: https://docs.nestjs.com/http/versioning
----

[Skip to content](#content)

On this page

* [Versioning](https://docs.nestjs.com/http/versioning#versioning)
* [URI Versioning Type](https://docs.nestjs.com/http/versioning#uri-versioning-type)
* [Header Versioning Type](https://docs.nestjs.com/http/versioning#header-versioning-type)
* [Media Type Versioning Type](https://docs.nestjs.com/http/versioning#media-type-versioning-type)
* [Custom Versioning Type](https://docs.nestjs.com/http/versioning#custom-versioning-type)
* [Usage](https://docs.nestjs.com/http/versioning#usage)
* [Controller versions](https://docs.nestjs.com/http/versioning#controller-versions)
* [Route versions](https://docs.nestjs.com/http/versioning#route-versions)
* [Multiple versions](https://docs.nestjs.com/http/versioning#multiple-versions)
* [Version "Neutral"](https://docs.nestjs.com/http/versioning#version-neutral)
* [Global default version](https://docs.nestjs.com/http/versioning#global-default-version)
* [Middleware versioning](https://docs.nestjs.com/http/versioning#middleware-versioning)

### Versioning

> **Hint** This chapter applies only to HTTP-based applications.

Versioning lets you run **different versions** of your controllers or individual routes within the same application. Applications change frequently, and you often need to introduce breaking changes while still supporting the previous version of the application.

Nest supports four types of versioning:

|                                                                       |                                                                                                                   |
| --------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- |
| [`URI Versioning`](http/versioning#uri-versioning-type)               | The version is passed within the URI of the request (default)                                                     |
| [`Header Versioning`](http/versioning#header-versioning-type)         | A custom request header specifies the version                                                                     |
| [`Media Type Versioning`](http/versioning#media-type-versioning-type) | The `Accept` header of the request specifies the version                                                          |
| [`Custom Versioning`](http/versioning#custom-versioning-type)         | Any aspect of the request may specify the version(s). You provide a custom function that extracts the version(s). |

#### URI Versioning Type[#](/http/versioning#uri-versioning-type)

URI Versioning uses the version passed within the URI of the request, such as `https://example.com/v1/route` and `https://example.com/v2/route`.

> **Notice** With URI Versioning, the version is automatically added to the URI after the [global path prefix](faq/global-prefix) (if one exists) and before any controller or route paths.

To enable URI Versioning for your application, do the following:

main.ts

JS TS

```typescript

const app = await NestFactory.create(AppModule);
// or "app.enableVersioning()"
app.enableVersioning({
  type: VersioningType.URI,
});
await app.listen(process.env.PORT ?? 3000);
```

> **Notice** By default, the version in the URI is automatically prefixed with `v`. To change the prefix, set the `prefix` key to your desired value, or set it to `false` to disable it.

> **Hint** The `VersioningType` enum is available to use for the `type` property and is imported from the `@nestjs/common` package.

#### Header Versioning Type[#](/http/versioning#header-versioning-type)

Header Versioning uses a custom, user-specified request header whose value specifies the version to use for the request.

To enable **Header Versioning** for your application, do the following:

main.ts

JS TS

```typescript

const app = await NestFactory.create(AppModule);
app.enableVersioning({
  type: VersioningType.HEADER,
  header: 'Custom-Header',
});
await app.listen(process.env.PORT ?? 3000);
```

The `header` property is the name of the header that contains the version of the request.

> **Hint** The `VersioningType` enum is available to use for the `type` property and is imported from the `@nestjs/common` package.

#### Media Type Versioning Type[#](/http/versioning#media-type-versioning-type)

Media Type Versioning uses the `Accept` header of the request to specify the version.

Within the `Accept` header, the version is separated from the media type with a semicolon (`;`), followed by a key-value pair that represents the version to use for the request, such as `Accept: application/json;v=2`. The key is treated as a prefix for the version, so the `key` property must include both the key and the separator.

To enable **Media Type Versioning** for your application, do the following:

main.ts

JS TS

```typescript

const app = await NestFactory.create(AppModule);
app.enableVersioning({
  type: VersioningType.MEDIA_TYPE,
  key: 'v=',
});
await app.listen(process.env.PORT ?? 3000);
```

The `key` property is the key and separator of the key-value pair that contains the version. For `Accept: application/json;v=2`, set the `key` property to `v=`.

> **Hint** The `VersioningType` enum is available to use for the `type` property and is imported from the `@nestjs/common` package.

#### Custom Versioning Type[#](/http/versioning#custom-versioning-type)

Custom Versioning uses any aspect of the request to specify the version (or versions). Nest analyzes the incoming request with an `extractor` function that returns a string or an array of strings.

If the requester provides multiple versions, the extractor function can return an array of strings sorted from the highest version to the lowest. Versions are matched to routes in order from highest to lowest.

If the `extractor` returns an empty string or array, no routes are matched and a 404 is returned.

For example, if an incoming request specifies that it supports versions `1`, `2`, and `3`, the `extractor`**must** return `['3', '2', '1']`. This ensures that the highest possible route version is selected first.

If versions `['3', '2', '1']` are extracted, but routes exist only for versions `2` and `1`, the route that matches version `2` is selected (version `3` is ignored).

> **Notice** With the Express adapter, make your `extractor` return a single version (a string, or an array with one element). Selecting the highest matching version from a multi-element array **does not reliably work** in Express due to design limitations of the adapter. If you need that behavior, use the Fastify adapter, which supports both single-version and highest-matching-version selection.

To enable **Custom Versioning** for your application, create an `extractor` function and pass it to `enableVersioning()`:

main.ts

JS TS

```typescript

// Example extractor that pulls out a list of versions from a custom header and turns it into a sorted array.
// This example uses Fastify, but Express requests can be processed in a similar way.
const extractor = (request: FastifyRequest): string | string[] =>
  [request.headers['custom-versioning-field'] ?? '']
     .flatMap(v => v.split(','))
     .filter(v => !!v)
     .sort()
     .reverse()

const app = await NestFactory.create(AppModule);
app.enableVersioning({
  type: VersioningType.CUSTOM,
  extractor,
});
await app.listen(process.env.PORT ?? 3000);
```

#### Usage[#](/http/versioning#usage)

Versioning lets you version controllers and individual routes, and also lets certain resources opt out of versioning. Usage is the same regardless of the versioning type your application uses.

> **Notice** If versioning is enabled for the application but a controller or route does not specify a version (and no [global default version](/http/versioning#global-default-version) is set), any request to that controller or route receives a `404` response status. Similarly, a request containing a version that has no corresponding controller or route also receives a `404` response status.

#### Controller versions[#](/http/versioning#controller-versions)

A version can be applied to a controller, setting the version for all routes within that controller.

To add a version to a controller, do the following:

cats.controller.ts

JS TS

```typescript

@Controller({
  version: '1',
})
export class CatsControllerV1 {
  @Get('cats')
  findAll(): string {
    return 'This action returns all cats for version 1';
  }
}
```

```typescript

@Controller({
  version: '1',
})
export class CatsControllerV1 {
  @Get('cats')
  findAll() {
    return 'This action returns all cats for version 1';
  }
}
```

#### Route versions[#](/http/versioning#route-versions)

A version can be applied to an individual route. This version overrides any other version that would affect the route, such as the controller version.

To add a version to an individual route, do the following:

cats.controller.ts

JS TS

```typescript

import { Controller, Get, Version } from '@nestjs/common';

@Controller()
export class CatsController {
  @Version('1')
  @Get('cats')
  findAllV1(): string {
    return 'This action returns all cats for version 1';
  }

  @Version('2')
  @Get('cats')
  findAllV2(): string {
    return 'This action returns all cats for version 2';
  }
}
```

```typescript

import { Controller, Get, Version } from '@nestjs/common';

@Controller()
export class CatsController {
  @Version('1')
  @Get('cats')
  findAllV1() {
    return 'This action returns all cats for version 1';
  }

  @Version('2')
  @Get('cats')
  findAllV2() {
    return 'This action returns all cats for version 2';
  }
}
```

#### Multiple versions[#](/http/versioning#multiple-versions)

Multiple versions can be applied to a controller or route. To use multiple versions, set the version to an array:

cats.controller.ts

JS TS

```typescript

@Controller({
  version: ['1', '2'],
})
export class CatsController {
  @Get('cats')
  findAll(): string {
    return 'This action returns all cats for version 1 or 2';
  }
}
```

```typescript

@Controller({
  version: ['1', '2'],
})
export class CatsController {
  @Get('cats')
  findAll() {
    return 'This action returns all cats for version 1 or 2';
  }
}
```

#### Version "Neutral"[#](/http/versioning#version-neutral)

Some controllers or routes behave the same regardless of the version. To accommodate this, set the version to the `VERSION_NEUTRAL` symbol.

An incoming request is mapped to a `VERSION_NEUTRAL` controller or route regardless of the version specified, including when the request contains no version at all.

> **Notice** With URI Versioning, a `VERSION_NEUTRAL` resource does not have the version in its URI.

To add a version-neutral controller or route, do the following:

cats.controller.ts

JS TS

```typescript

import { Controller, Get, VERSION_NEUTRAL } from '@nestjs/common';

@Controller({
  version: VERSION_NEUTRAL,
})
export class CatsController {
  @Get('cats')
  findAll(): string {
    return 'This action returns all cats regardless of version';
  }
}
```

```typescript

import { Controller, Get, VERSION_NEUTRAL } from '@nestjs/common';

@Controller({
  version: VERSION_NEUTRAL,
})
export class CatsController {
  @Get('cats')
  findAll() {
    return 'This action returns all cats regardless of version';
  }
}
```

#### Global default version[#](/http/versioning#global-default-version)

If you don't want to provide a version for each controller or individual route, or you want a specific version to act as the default for every controller or route that doesn't specify one, set the `defaultVersion` as follows:

main.ts

JS TS

```typescript

app.enableVersioning({
  // ...
  defaultVersion: '1',
  // or: defaultVersion: ['1', '2'],
  // or: defaultVersion: VERSION_NEUTRAL,
});
```

#### Middleware versioning[#](/http/versioning#middleware-versioning)

[Middleware](/middleware) can also use versioning metadata to target a specific route version. To do so, set the `version` property in the route object passed to the `MiddlewareConsumer.forRoutes()` method:

app.module.ts

JS TS

```typescript

import { Module, NestModule, MiddlewareConsumer, RequestMethod } from '@nestjs/common';
import { LoggerMiddleware } from './common/middleware/logger.middleware.js';
import { CatsModule } from './cats/cats.module.js';
import { CatsController } from './cats/cats.controller.js';

@Module({
  imports: [CatsModule],
})
export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer
      .apply(LoggerMiddleware)
      .forRoutes({ path: 'cats', method: RequestMethod.GET, version: '2' });
  }
}
```

With the code above, the `LoggerMiddleware` is applied only to version `'2'` of the `/cats` endpoint.

> **Note** Middleware works with any versioning type described in this chapter: `URI`, `Header`, `Media Type`, or `Custom`.

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/http/versioning.md)

----
url: https://docs.nestjs.com/faq/hybrid-application
----

[Skip to content](#content)

On this page

* [Hybrid application](https://docs.nestjs.com/faq/hybrid-application#hybrid-application)
* [Sharing configuration](https://docs.nestjs.com/faq/hybrid-application#sharing-configuration)

### Hybrid application

A hybrid application listens for requests from two or more different sources. It can combine an HTTP server with a microservice listener, or combine several different microservice listeners. The `createMicroservice()` method doesn't support multiple servers, so in this case you create and start each microservice manually. To do this, connect `INestMicroservice` instances to the `INestApplication` instance with the `connectMicroservice()` method.

```typescript

const app = await NestFactory.create(AppModule);
const microservice = app.connectMicroservice<MicroserviceOptions>({
  transport: Transport.TCP,
});

await app.startAllMicroservices();
await app.listen(3001);
```

> **Hint** The `app.listen(port)` method starts an HTTP server on the specified port. If your application doesn't handle HTTP requests, use the `app.init()` method instead.

> **Notice** The order of these calls matters. With `await app.startAllMicroservices()` first (as above), the microservices begin consuming messages **before** the application's lifecycle hooks (such as `onModuleInit` and `onApplicationBootstrap`) have completed. Call `app.listen()` (or `app.init()`) before `startAllMicroservices()` if your handlers must not receive messages until every module has fully initialized.

To connect multiple microservice instances, call `connectMicroservice()` once for each microservice:

```typescript

const app = await NestFactory.create(AppModule);
// microservice #1
const microserviceTcp = app.connectMicroservice<MicroserviceOptions>({
  transport: Transport.TCP,
  options: {
    port: 3002,
  },
});
// microservice #2
const microserviceRedis = app.connectMicroservice<MicroserviceOptions>({
  transport: Transport.REDIS,
  options: {
    host: 'localhost',
    port: 6379,
  },
});

await app.startAllMicroservices();
await app.listen(3001);
```

In a hybrid application with multiple microservices, you can bind `@MessagePattern()` to a single transport strategy (for example, NATS) by passing a second argument that identifies the transport. For the built-in strategies, this is a value of the `Transport` enum; for a [custom transporter](/microservices/custom-transport), it is the `transportId` symbol of its server class.

JS TS

```typescript

@MessagePattern('time.us.*', Transport.NATS)
getDate(@Payload() data: number[], @Ctx() context: NatsContext) {
  console.log(`Subject: ${context.getSubject()}`); // e.g. "time.us.east"
  return new Date().toLocaleTimeString(...);
}
@MessagePattern({ cmd: 'time.us' }, Transport.TCP)
getTCPDate(@Payload() data: number[]) {
  return new Date().toLocaleTimeString(...);
}
@MessagePattern('topic.time.us', XYZServer.Transport) // XYZServer is a custom transporter
getXYZDate(@Payload() data: number[]) {
  return new Date().toLocaleTimeString(...);
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('time.us.*', Transport.NATS)
getDate(data, context) {
  console.log(`Subject: ${context.getSubject()}`); // e.g. "time.us.east"
  return new Date().toLocaleTimeString(...);
}
@Bind(Payload(), Ctx())
@MessagePattern({ cmd: 'time.us' }, Transport.TCP)
getTCPDate(data, context) {
  return new Date().toLocaleTimeString(...);
}

@Bind(Payload())
@MessagePattern('topic.time.us', XYZServer.Transport)
getXYZDate(data) {
  return new Date().toLocaleTimeString(...);
}
```

> **Hint**`@Payload()`, `@Ctx()`, `Transport` and `NatsContext` are imported from `@nestjs/microservices`. `XYZServer.Transport` here stands for the `transportId` symbol exposed by the custom transporter.

#### Sharing configuration[#](/faq/hybrid-application#sharing-configuration)

By default, connected microservices don't inherit the global pipes, interceptors, guards, and filters configured for the main (HTTP-based) application. This applies both to enhancers registered with the `useGlobal*()` methods and to those registered as providers with the `APP_PIPE`, `APP_INTERCEPTOR`, `APP_GUARD`, and `APP_FILTER` tokens. To inherit this configuration, set the `inheritAppConfig` property in the options object passed as the second argument of `connectMicroservice()`:

```typescript

const microservice = app.connectMicroservice<MicroserviceOptions>(
  {
    transport: Transport.TCP,
  },
  { inheritAppConfig: true },
);
```

> **Hint** A connected microservice registers its message handlers as soon as `connectMicroservice()` is called. When you use `inheritAppConfig`, call `app.useGlobalPipes()`, `app.useGlobalGuards()`, and the other `useGlobal*()` methods **before**`connectMicroservice()`, otherwise the enhancers they register won't apply to the microservice's handlers.

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/faq/hybrid-application.md)

----
url: https://docs.nestjs.com/v11/microservices/grpc
----

* [gRPC](https://docs.nestjs.com/v11/microservices/grpc#grpc)
* [Installation](https://docs.nestjs.com/v11/microservices/grpc#installation)
* [Overview](https://docs.nestjs.com/v11/microservices/grpc#overview)
* [Options](https://docs.nestjs.com/v11/microservices/grpc#options)
* [Sample gRPC service](https://docs.nestjs.com/v11/microservices/grpc#sample-grpc-service)
* [Client](https://docs.nestjs.com/v11/microservices/grpc#client)
* [Example](https://docs.nestjs.com/v11/microservices/grpc#example)
* [gRPC Reflection](https://docs.nestjs.com/v11/microservices/grpc#grpc-reflection)
* [gRPC Streaming](https://docs.nestjs.com/v11/microservices/grpc#grpc-streaming)
* [Streaming sample](https://docs.nestjs.com/v11/microservices/grpc#streaming-sample)
* [Subject strategy](https://docs.nestjs.com/v11/microservices/grpc#subject-strategy)
* [Call stream handler](https://docs.nestjs.com/v11/microservices/grpc#call-stream-handler)
* [Health checks](https://docs.nestjs.com/v11/microservices/grpc#health-checks)
* [gRPC Metadata](https://docs.nestjs.com/v11/microservices/grpc#grpc-metadata)

```bash

$ npm i --save @grpc/grpc-js @grpc/proto-loader
```

#### Overview[#](/microservices/grpc#overview)

Like other Nest microservices transport layer implementations, you select the gRPC transporter mechanism using the `transport` property of the options object passed to the `createMicroservice()` method. In the following example, we'll set up a hero service. The `options` property provides metadata about that service; its properties are described [below](microservices/grpc#options).

main.ts

JS TS

```typescript

const app = await NestFactory.createMicroservice<MicroserviceOptions>(AppModule, {
  transport: Transport.GRPC,
  options: {
    package: 'hero',
    protoPath: join(__dirname, 'hero/hero.proto'),
  },
});
```

```typescript

const app = await NestFactory.createMicroservice(AppModule, {
  transport: Transport.GRPC,
  options: {
    package: 'hero',
    protoPath: join(__dirname, 'hero/hero.proto'),
  },
});
```

> **Hint** The `join()` function is imported from the `path` package; the `Transport` enum is imported from the `@nestjs/microservices` package.

In the `nest-cli.json` file, we add the `assets` property that allows us to distribute non-TypeScript files, and `watchAssets` - to turn on watching all non-TypeScript assets. In our case, we want `.proto` files to be automatically copied to the `dist` folder.

```json

{
  "compilerOptions": {
    "assets": ["**/*.proto"],
    "watchAssets": true
  }
}
```

#### Options[#](/microservices/grpc#options)

The **gRPC** transporter options object exposes the properties described below.

|               |                                                                                                                                                                                                                                            |
| ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `package`     | Protobuf package name (matches `package` setting from `.proto` file). Required                                                                                                                                                             |
| `protoPath`   | Absolute (or relative to the root dir) path to the `.proto` file. Required                                                                                                                                                                 |
| `url`         | Connection url. String in the format `ip address/dns name:port` (for example, `'0.0.0.0:50051'` for a Docker server) defining the address/port on which the transporter establishes a connection. Optional. Defaults to `'localhost:5000'` |
| `protoLoader` | NPM package name for the utility to load `.proto` files. Optional. Defaults to `'@grpc/proto-loader'`                                                                                                                                      |
| `loader`      | `@grpc/proto-loader` options. These provide detailed control over the behavior of `.proto` files. Optional. See [here](https://github.com/grpc/grpc-node/blob/master/packages/proto-loader/README.md) for more details                     |
| `credentials` | Server credentials. Optional. [Read more here](https://grpc.io/grpc/node/grpc.ServerCredentials.html)                                                                                                                                      |

#### Sample gRPC service[#](/microservices/grpc#sample-grpc-service)

Let's define our sample gRPC service called `HeroesService`. In the above `options` object, the`protoPath` property sets a path to the `.proto` definitions file `hero.proto`. The `hero.proto` file is structured using [protocol buffers](https://developers.google.com/protocol-buffers). Here's what it looks like:

```typescript

// hero/hero.proto
syntax = "proto3";

package hero;

service HeroesService {
  rpc FindOne (HeroById) returns (Hero) {}
}

message HeroById {
  int32 id = 1;
}

message Hero {
  int32 id = 1;
  string name = 2;
}
```

Our `HeroesService` exposes a `FindOne()` method. This method expects an input argument of type `HeroById` and returns a `Hero` message (protocol buffers use `message` elements to define both parameter types and return types).

Next, we need to implement the service. To define a handler that fulfills this definition, we use the `@GrpcMethod()` decorator in a controller, as shown below. This decorator provides the metadata needed to declare a method as a gRPC service method.

> **Hint** The `@MessagePattern()` decorator ([read more](microservices/basics#request-response)) introduced in previous microservices chapters is not used with gRPC-based microservices. The `@GrpcMethod()` decorator effectively takes its place for gRPC-based microservices.

heroes.controller.ts

JS TS

```typescript

@Controller()
export class HeroesController {
  @GrpcMethod('HeroesService', 'FindOne')
  findOne(data: HeroById, metadata: Metadata, call: ServerUnaryCall<any, any>): Hero {
    const items = [
      { id: 1, name: 'John' },
      { id: 2, name: 'Doe' },
    ];
    return items.find(({ id }) => id === data.id);
  }
}
```

```typescript

@Controller()
export class HeroesController {
  @GrpcMethod('HeroesService', 'FindOne')
  findOne(data, metadata, call) {
    const items = [
      { id: 1, name: 'John' },
      { id: 2, name: 'Doe' },
    ];
    return items.find(({ id }) => id === data.id);
  }
}
```

> **Hint** The `@GrpcMethod()` decorator is imported from the `@nestjs/microservices` package, while `Metadata` and `ServerUnaryCall` from the `grpc` package.

The decorator shown above takes two arguments. The first is the service name (e.g., `'HeroesService'`), corresponding to the `HeroesService` service definition in `hero.proto`. The second (the string `'FindOne'`) corresponds to the `FindOne()` rpc method defined within `HeroesService` in the `hero.proto` file.

The `findOne()` handler method takes three arguments, the `data` passed from the caller, `metadata` that stores gRPC request metadata and `call` to obtain the `GrpcCall` object properties such as `sendMetadata` for send metadata to client.

Both `@GrpcMethod()` decorator arguments are optional. If called without the second argument (e.g., `'FindOne'`), Nest will automatically associate the `.proto` file rpc method with the handler based on converting the handler name to upper camel case (e.g., the `findOne` handler is associated with the `FindOne` rpc call definition). This is shown below.

heroes.controller.ts

JS TS

```typescript

@Controller()
export class HeroesController {
  @GrpcMethod('HeroesService')
  findOne(data: HeroById, metadata: Metadata, call: ServerUnaryCall<any, any>): Hero {
    const items = [
      { id: 1, name: 'John' },
      { id: 2, name: 'Doe' },
    ];
    return items.find(({ id }) => id === data.id);
  }
}
```

```typescript

@Controller()
export class HeroesController {
  @GrpcMethod('HeroesService')
  findOne(data, metadata, call) {
    const items = [
      { id: 1, name: 'John' },
      { id: 2, name: 'Doe' },
    ];
    return items.find(({ id }) => id === data.id);
  }
}
```

You can also omit the first `@GrpcMethod()` argument. In this case, Nest automatically associates the handler with the service definition from the proto definitions file based on the **class** name where the handler is defined. For example, in the following code, class `HeroesService` associates its handler methods with the `HeroesService` service definition in the `hero.proto` file based on the matching of the name `'HeroesService'`.

heroes.controller.ts

JS TS

```typescript

@Controller()
export class HeroesService {
  @GrpcMethod()
  findOne(data: HeroById, metadata: Metadata, call: ServerUnaryCall<any, any>): Hero {
    const items = [
      { id: 1, name: 'John' },
      { id: 2, name: 'Doe' },
    ];
    return items.find(({ id }) => id === data.id);
  }
}
```

```typescript

@Controller()
export class HeroesService {
  @GrpcMethod()
  findOne(data, metadata, call) {
    const items = [
      { id: 1, name: 'John' },
      { id: 2, name: 'Doe' },
    ];
    return items.find(({ id }) => id === data.id);
  }
}
```

#### Client[#](/microservices/grpc#client)

Nest applications can act as gRPC clients, consuming services defined in `.proto` files. You access remote services through a `ClientGrpc` object. You can obtain a `ClientGrpc` object in several ways.

The preferred technique is to import the `ClientsModule`. Use the `register()` method to bind a package of services defined in a `.proto` file to an injection token, and to configure the service. The `name` property is the injection token. For gRPC services, use `transport: Transport.GRPC`. The `options` property is an object with the same properties described [above](microservices/grpc#options).

```typescript

imports: [
  ClientsModule.register([
    {
      name: 'HERO_PACKAGE',
      transport: Transport.GRPC,
      options: {
        package: 'hero',
        protoPath: join(__dirname, 'hero/hero.proto'),
      },
    },
  ]),
];
```

> **Hint** The `register()` method takes an array of objects. Register multiple packages by providing a comma separated list of registration objects.

Once registered, we can inject the configured `ClientGrpc` object with `@Inject()`. Then we use the `ClientGrpc` object's `getService()` method to retrieve the service instance, as shown below.

```typescript

@Injectable()
export class AppService implements OnModuleInit {
  private heroesService: HeroesService;

  constructor(@Inject('HERO_PACKAGE') private client: ClientGrpc) {}

  onModuleInit() {
    this.heroesService = this.client.getService<HeroesService>('HeroesService');
  }

  getHero(): Observable<string> {
    return this.heroesService.findOne({ id: 1 });
  }
}
```

> **Warning** gRPC Client will not send fields that contain underscore `_` in their names unless the `keepCase` options is set to `true` in the proto loader configuration (`options.loader.keepcase` in the microservice transporter configuration).

Notice that there is a small difference compared to the technique used in other microservice transport methods. Instead of the `ClientProxy` class, we use the `ClientGrpc` class, which provides the `getService()` method. The `getService()` generic method takes a service name as an argument and returns its instance (if available).

Alternatively, you can use the `@Client()` decorator to instantiate a `ClientGrpc` object, as follows:

```typescript

@Injectable()
export class AppService implements OnModuleInit {
  @Client({
    transport: Transport.GRPC,
    options: {
      package: 'hero',
      protoPath: join(__dirname, 'hero/hero.proto'),
    },
  })
  client: ClientGrpc;

  private heroesService: HeroesService;

  onModuleInit() {
    this.heroesService = this.client.getService<HeroesService>('HeroesService');
  }

  getHero(): Observable<string> {
    return this.heroesService.findOne({ id: 1 });
  }
}
```

Finally, for more complex scenarios, we can inject a dynamically configured client using the `ClientProxyFactory` class as described [here](/microservices/basics#client).

In either case, we end up with a reference to our `HeroesService` proxy object, which exposes the same set of methods that are defined inside the `.proto` file. Now, when we access this proxy object (i.e., `heroesService`), the gRPC system automatically serializes requests, forwards them to the remote system, returns a response, and deserializes the response. Because gRPC shields us from these network communication details, `heroesService` looks and acts like a local provider.

Note, all service methods are **lower camel cased** (in order to follow the natural convention of the language). So, for example, while our `.proto` file `HeroesService` definition contains the `FindOne()` function, the `heroesService` instance will provide the `findOne()` method.

```typescript

interface HeroesService {
  findOne(data: { id: number }): Observable<any>;
}
```

A message handler is also able to return an `Observable`, in which case the result values will be emitted until the stream is completed.

heroes.controller.ts

JS TS

```typescript

@Get()
call(): Observable<any> {
  return this.heroesService.findOne({ id: 1 });
}
```

```typescript

@Get()
call() {
  return this.heroesService.findOne({ id: 1 });
}
```

To send gRPC metadata (along with the request), you can pass a second argument, as follows:

```typescript

call(): Observable<any> {
  const metadata = new Metadata();
  metadata.add('Set-Cookie', 'yummy_cookie=choco');

  return this.heroesService.findOne({ id: 1 }, metadata);
}
```

> **Hint** The `Metadata` class is imported from the `grpc` package.

Please note that this would require updating the `HeroesService` interface that we've defined a few steps earlier.

#### Example[#](/microservices/grpc#example)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/04-grpc).

#### gRPC Reflection[#](/microservices/grpc#grpc-reflection)

The [gRPC Server Reflection Specification](https://grpc.io/docs/guides/reflection/#overview) is a standard which allows gRPC clients to request details about the API that the server exposes, akin to exposing an OpenAPI document for a REST API. This can make working with developer debugging tools such as grpc-ui or postman significantly easier.

To add gRPC reflection support to your server, first install the required implementation package:

```bash

$ npm i --save @grpc/reflection
```

Then it can be hooked into the gRPC server using the `onLoadPackageDefinition` hook in your gRPC server options, as follows:

main.ts

JS TS

```typescript

import { ReflectionService } from '@grpc/reflection';

const app = await NestFactory.createMicroservice<MicroserviceOptions>(AppModule, {
  options: {
    onLoadPackageDefinition: (pkg, server) => {
      new ReflectionService(pkg).addToServer(server);
    },
  },
});
```

Now your server will respond to messages requesting API details using the reflection specification.

#### gRPC Streaming[#](/microservices/grpc#grpc-streaming)

gRPC on its own supports long-term live connections, conventionally known as `streams`. Streams are useful for cases such as Chatting, Observations or Chunk-data transfers. Find more details in the official documentation [here](https://grpc.io/docs/guides/concepts/).

Nest supports GRPC stream handlers in two possible ways:

* RxJS `Subject` + `Observable` handler: can be useful to write responses right inside of a Controller method or to be passed down to `Subject`/`Observable` consumer
* Pure GRPC call stream handler: can be useful to be passed to some executor which will handle the rest of dispatch for the Node standard `Duplex` stream handler.

Let's define a new sample gRPC service called `HelloService`. The `hello.proto` file is structured using [protocol buffers](https://developers.google.com/protocol-buffers). Here's what it looks like:

```typescript

// hello/hello.proto
syntax = "proto3";

package hello;

service HelloService {
  rpc BidiHello(stream HelloRequest) returns (stream HelloResponse);
  rpc LotsOfGreetings(stream HelloRequest) returns (HelloResponse);
}

message HelloRequest {
  string greeting = 1;
}

message HelloResponse {
  string reply = 1;
}
```

> **Hint** The `LotsOfGreetings` method can be simply implemented with the `@GrpcMethod` decorator (as in the examples above) since the returned stream can emit multiple values.

Based on this `.proto` file, let's define the `HelloService` interface:

```typescript

interface HelloService {
  bidiHello(upstream: Observable<HelloRequest>): Observable<HelloResponse>;
  lotsOfGreetings(
    upstream: Observable<HelloRequest>,
  ): Observable<HelloResponse>;
}

interface HelloRequest {
  greeting: string;
}

interface HelloResponse {
  reply: string;
}
```

> **Hint** The proto interface can be automatically generated by the [ts-proto](https://github.com/stephenh/ts-proto) package, learn more [here](https://github.com/stephenh/ts-proto/blob/main/NESTJS.markdown).

#### Subject strategy[#](/microservices/grpc#subject-strategy)

The `@GrpcStreamMethod()` decorator provides the function parameter as an RxJS `Observable`. Thus, we can receive and process multiple messages.

```typescript

@GrpcStreamMethod()
bidiHello(messages: Observable<any>, metadata: Metadata, call: ServerDuplexStream<any, any>): Observable<any> {
  const subject = new Subject();

  const onNext = message => {
    console.log(message);
    subject.next({
      reply: 'Hello, world!'
    });
  };
  const onComplete = () => subject.complete();
  messages.subscribe({
    next: onNext,
    complete: onComplete,
  });


  return subject.asObservable();
}
```

> **Warning** For supporting full-duplex interaction with the `@GrpcStreamMethod()` decorator, the controller method must return an RxJS `Observable`.

> **Hint** The `Metadata` and `ServerUnaryCall` classes/interfaces are imported from the `grpc` package.

According to the service definition (in the `.proto` file), the `BidiHello` method should stream requests to the service. To send multiple asynchronous messages to the stream from a client, we leverage an RxJS `ReplaySubject` class.

```typescript

const helloService = this.client.getService<HelloService>('HelloService');
const helloRequest$ = new ReplaySubject<HelloRequest>();

helloRequest$.next({ greeting: 'Hello (1)!' });
helloRequest$.next({ greeting: 'Hello (2)!' });
helloRequest$.complete();

return helloService.bidiHello(helloRequest$);
```

In the example above, we wrote two messages to the stream (`next()` calls) and notified the service that we've completed sending the data (`complete()` call).

#### Call stream handler[#](/microservices/grpc#call-stream-handler)

When the method return value is defined as `stream`, the `@GrpcStreamCall()` decorator provides the function parameter as `grpc.ServerDuplexStream`, which supports standard methods like `.on('data', callback)`, `.write(message)` or `.cancel()`. Full documentation on available methods can be found [here](https://grpc.github.io/grpc/node/grpc-ClientDuplexStream.html).

Alternatively, when the method return value is not a `stream`, the `@GrpcStreamCall()` decorator provides two function parameters, respectively `grpc.ServerReadableStream` (read more [here](https://grpc.github.io/grpc/node/grpc-ServerReadableStream.html)) and `callback`.

Let's start with implementing the `BidiHello` which should support a full-duplex interaction.

```typescript

@GrpcStreamCall()
bidiHello(requestStream: any) {
  requestStream.on('data', message => {
    console.log(message);
    requestStream.write({
      reply: 'Hello, world!'
    });
  });
}
```

> **Hint** This decorator does not require any specific return parameter to be provided. It is expected that the stream will be handled similar to any other standard stream type.

In the example above, we used the `write()` method to write objects to the response stream. The callback passed into the `.on()` method as a second parameter will be called every time our service receives a new chunk of data.

Let's implement the `LotsOfGreetings` method.

```typescript

@GrpcStreamCall()
lotsOfGreetings(requestStream: any, callback: (err: unknown, value: HelloResponse) => void) {
  requestStream.on('data', message => {
    console.log(message);
  });
  requestStream.on('end', () => callback(null, { reply: 'Hello, world!' }));
}
```

Here we used the `callback` function to send the response once processing of the `requestStream` has been completed.

#### Health checks[#](/microservices/grpc#health-checks)

When running a gRPC application in an orchestrator such a Kubernetes, you may need to know if it is running and in a healthy state. The [gRPC Health Check specification](https://grpc.io/docs/guides/health-checking/) is a standard that allow gRPC clients to expose their health status to allow the orchestrator to act accordingly.

To add gRPC health check support, first install the [grpc-node](https://github.com/grpc/grpc-node/tree/master/packages/grpc-health-check) package:

```bash

$ npm i --save grpc-health-check
```

Then it can be hooked into the gRPC service using the `onLoadPackageDefinition` hook in your gRPC server options, as follows. Note that the `protoPath` needs to have both the health check and the hero package.

main.ts

JS TS

```typescript

import { HealthImplementation, protoPath as healthCheckProtoPath } from 'grpc-health-check';

const app = await NestFactory.createMicroservice<MicroserviceOptions>(AppModule, {
  options: {
    protoPath: [
      healthCheckProtoPath,
      protoPath: join(__dirname, 'hero/hero.proto'),
    ],
    onLoadPackageDefinition: (pkg, server) => {
      const healthImpl = new HealthImplementation({
        '': 'UNKNOWN',
      });

      healthImpl.addToServer(server);
      healthImpl.setStatus('', 'SERVING');
    },
  },
});
```

> **Hint** The [gRPC health probe](https://github.com/grpc-ecosystem/grpc-health-probe) is a useful CLI to test gRPC health checks in a containerized environment.

#### gRPC Metadata[#](/microservices/grpc#grpc-metadata)

Metadata is information about a particular RPC call in the form of a list of key-value pairs, where the keys are strings and the values are typically strings but can be binary data. Metadata is opaque to gRPC itself - it lets the client provide information associated with the call to the server and vice versa. Metadata may include authentication tokens, request identifiers and tags for monitoring purposes, and data information such as the number of records in a data set.

To read the metadata in `@GrpcMethod()` handler, use the second argument (metadata), which is of type `Metadata` (imported from the `grpc` package).

To send back metadata from the handler, use the `ServerUnaryCall#sendMetadata()` method (third handler argument).

heroes.controller.ts

JS TS

```typescript

@Controller()
export class HeroesService {
  @GrpcMethod()
  findOne(data: HeroById, metadata: Metadata, call: ServerUnaryCall<any, any>): Hero {
    const serverMetadata = new Metadata();
    const items = [
      { id: 1, name: 'John' },
      { id: 2, name: 'Doe' },
    ];

    serverMetadata.add('Set-Cookie', 'yummy_cookie=choco');
    call.sendMetadata(serverMetadata);

    return items.find(({ id }) => id === data.id);
  }
}
```

```typescript

@Controller()
export class HeroesService {
  @GrpcMethod()
  findOne(data, metadata, call) {
    const serverMetadata = new Metadata();
    const items = [
      { id: 1, name: 'John' },
      { id: 2, name: 'Doe' },
    ];

    serverMetadata.add('Set-Cookie', 'yummy_cookie=choco');
    call.sendMetadata(serverMetadata);

    return items.find(({ id }) => id === data.id);
  }
}
```

Likewise, to read the metadata in handlers annotated with the `@GrpcStreamMethod()` handler ([subject strategy](microservices/grpc#subject-strategy)), use the second argument (metadata), which is of type `Metadata` (imported from the `grpc` package).

To send back metadata from the handler, use the `ServerDuplexStream#sendMetadata()` method (third handler argument).

To read metadata from within the [call stream handlers](microservices/grpc#call-stream-handler) (handlers annotated with `@GrpcStreamCall()` decorator), listen to the `metadata` event on the `requestStream` reference, as follows:

```typescript

requestStream.on('metadata', (metadata: Metadata) => {
  const meta = metadata.get('X-Meta');
});
```

----
url: https://docs.nestjs.com/v9/graphql/plugins
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Plugins](https://docs.nestjs.com/v9/graphql/plugins#plugins)
* [Custom plugins](https://docs.nestjs.com/v9/graphql/plugins#custom-plugins)
* [Using external plugins](https://docs.nestjs.com/v9/graphql/plugins#using-external-plugins)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/plugins.md "Suggest Edits")

### Plugins

> **Warning** This chapter applies only to the `@nestjs/apollo` driver.

Plugins enable you to extend Apollo Server's core functionality by performing custom operations in response to certain events. Currently, these events correspond to individual phases of the GraphQL request lifecycle, and to the startup of Apollo Server itself (read more [here](https://www.apollographql.com/docs/apollo-server/integrations/plugins/)). For example, a basic logging plugin might log the GraphQL query string associated with each request that's sent to Apollo Server.

#### Custom plugins[#](/graphql/plugins#custom-plugins)

To create a plugin, declare a class annotated with the `@Plugin` decorator exported from the `@nestjs/apollo` package. Also, for better code autocompletion, implement the `ApolloServerPlugin` interface from the `@apollo/server` package.

```typescript

import { ApolloServerPlugin, GraphQLRequestListener } from '@apollo/server';
import { Plugin } from '@nestjs/apollo';

@Plugin()
export class LoggingPlugin implements ApolloServerPlugin {
  async requestDidStart(): Promise<GraphQLRequestListener<any>> {
    console.log('Request started');
    return {
      async willSendResponse() {
        console.log('Will send response');
      },
    };
  }
}
```

With this in place, we can register the `LoggingPlugin` as a provider.

```typescript

@Module({
  providers: [LoggingPlugin],
})
export class CommonModule {}
```

Nest will automatically instantiate a plugin and apply it to the Apollo Server.

#### Using external plugins[#](/graphql/plugins#using-external-plugins)

There are several plugins provided out-of-the-box. To use an existing plugin, simply import it and add it to the `plugins` array:

```typescript

GraphQLModule.forRoot({
  // ...
  plugins: [ApolloServerOperationRegistry({ /* options */})]
}),
```

> **Hint** The `ApolloServerOperationRegistry` plugin is exported from the `@apollo/server-plugin-operation-registry` package.

----
url: https://docs.nestjs.com/v9/techniques/task-scheduling
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Task Scheduling](https://docs.nestjs.com/v9/techniques/task-scheduling#task-scheduling)
* [Installation](https://docs.nestjs.com/v9/techniques/task-scheduling#installation)
* [Declarative cron jobs](https://docs.nestjs.com/v9/techniques/task-scheduling#declarative-cron-jobs)
* [Declarative intervals](https://docs.nestjs.com/v9/techniques/task-scheduling#declarative-intervals)
* [Declarative timeouts](https://docs.nestjs.com/v9/techniques/task-scheduling#declarative-timeouts)
* [Dynamic schedule module API](https://docs.nestjs.com/v9/techniques/task-scheduling#dynamic-schedule-module-api)
* [Dynamic cron jobs](https://docs.nestjs.com/v9/techniques/task-scheduling#dynamic-cron-jobs)
* [Dynamic intervals](https://docs.nestjs.com/v9/techniques/task-scheduling#dynamic-intervals)
* [Dynamic timeouts](https://docs.nestjs.com/v9/techniques/task-scheduling#dynamic-timeouts)
* [Example](https://docs.nestjs.com/v9/techniques/task-scheduling#example)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/techniques/task-scheduling.md "Suggest Edits")

### Task Scheduling

Task scheduling allows you to schedule arbitrary code (methods/functions) to execute at a fixed date/time, at recurring intervals, or once after a specified interval. In the Linux world, this is often handled by packages like [cron](https://en.wikipedia.org/wiki/Cron) at the OS level. For Node.js apps, there are several packages that emulate cron-like functionality. Nest provides the `@nestjs/schedule` package, which integrates with the popular Node.js [cron](https://github.com/kelektiv/node-cron) package. We'll cover this package in the current chapter.

#### Installation[#](/techniques/task-scheduling#installation)

To begin using it, we first install the required dependencies.

```bash

$ npm install --save @nestjs/schedule
$ npm install --save-dev @types/cron
```

To activate job scheduling, import the `ScheduleModule` into the root `AppModule` and run the `forRoot()` static method as shown below:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { ScheduleModule } from '@nestjs/schedule';

@Module({
  imports: [
    ScheduleModule.forRoot()
  ],
})
export class AppModule {}
```

The `.forRoot()` call initializes the scheduler and registers any declarative [cron jobs](techniques/task-scheduling#declarative-cron-jobs), [timeouts](techniques/task-scheduling#declarative-timeouts) and [intervals](techniques/task-scheduling#declarative-intervals) that exist within your app. Registration occurs when the `onApplicationBootstrap` lifecycle hook occurs, ensuring that all modules have loaded and declared any scheduled jobs.

#### Declarative cron jobs[#](/techniques/task-scheduling#declarative-cron-jobs)

A cron job schedules an arbitrary function (method call) to run automatically. Cron jobs can run:

* Once, at a specified date/time.
* On a recurring basis; recurring jobs can run at a specified instant within a specified interval (for example, once per hour, once per week, once every 5 minutes)

Declare a cron job with the `@Cron()` decorator preceding the method definition containing the code to be executed, as follows:

```typescript

import { Injectable, Logger } from '@nestjs/common';
import { Cron } from '@nestjs/schedule';

@Injectable()
export class TasksService {
  private readonly logger = new Logger(TasksService.name);

  @Cron('45 * * * * *')
  handleCron() {
    this.logger.debug('Called when the current second is 45');
  }
}
```

In this example, the `handleCron()` method will be called each time the current second is `45`. In other words, the method will be run once per minute, at the 45 second mark.

The `@Cron()` decorator supports all standard [cron patterns](http://crontab.org/):

* Asterisk (e.g. `*`)
* Ranges (e.g. `1-3,5`)
* Steps (e.g. `*/2`)

In the example above, we passed `45 * * * * *` to the decorator. The following key shows how each position in the cron pattern string is interpreted:

```javascript

* * * * * *
| | | | | |
| | | | | day of week
| | | | months
| | | day of month
| | hours
| minutes
seconds (optional)
```

Some sample cron patterns are:

|                     |                                             |
| ------------------- | ------------------------------------------- |
| `* * * * * *`       | every second                                |
| `45 * * * * *`      | every minute, on the 45th second            |
| `0 10 * * * *`      | every hour, at the start of the 10th minute |
| `0 */30 9-17 * * *` | every 30 minutes between 9am and 5pm        |
| `0 30 11 * * 1-5`   | Monday to Friday at 11:30am                 |

The `@nestjs/schedule` package provides a convenience enum with commonly used cron patterns. You can use this enum as follows:

```typescript

import { Injectable, Logger } from '@nestjs/common';
import { Cron, CronExpression } from '@nestjs/schedule';

@Injectable()
export class TasksService {
  private readonly logger = new Logger(TasksService.name);

  @Cron(CronExpression.EVERY_30_SECONDS)
  handleCron() {
    this.logger.debug('Called every 30 seconds');
  }
}
```

In this example, the `handleCron()` method will be called every `30` seconds.

Alternatively, you can supply a JavaScript `Date` object to the `@Cron()` decorator. Doing so causes the job to execute exactly once, at the specified date.

> **Hint** Use JavaScript date arithmetic to schedule jobs relative to the current date. For example, `@Cron(new Date(Date.now() + 10 * 1000))` to schedule a job to run 10 seconds after the app starts.

Also, you can supply additional options as the second parameter to the `@Cron()` decorator.

|             |                                                                                                                                                                                                                                                        |
| ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `name`      | Useful to access and control a cron job after it's been declared.                                                                                                                                                                                      |
| `timeZone`  | Specify the timezone for the execution. This will modify the actual time relative to your timezone. If the timezone is invalid, an error is thrown. You can check all timezones available at [Moment Timezone](http://momentjs.com/timezone/) website. |
| `utcOffset` | This allows you to specify the offset of your timezone rather than using the `timeZone` param.                                                                                                                                                         |
| `disabled`  | This indicates whether the job will be executed at all.                                                                                                                                                                                                |

```typescript

import { Injectable } from '@nestjs/common';
import { Cron, CronExpression } from '@nestjs/schedule';

@Injectable()
export class NotificationService {
  @Cron('* * 0 * * *', {
    name: 'notifications',
    timeZone: 'Europe/Paris',
  })
  triggerNotifications() {}
}
```

You can access and control a cron job after it's been declared, or dynamically create a cron job (where its cron pattern is defined at runtime) with the [Dynamic API](/techniques/task-scheduling#dynamic-schedule-module-api). To access a declarative cron job via the API, you must associate the job with a name by passing the `name` property in an optional options object as the second argument of the decorator.

#### Declarative intervals[#](/techniques/task-scheduling#declarative-intervals)

To declare that a method should run at a (recurring) specified interval, prefix the method definition with the `@Interval()` decorator. Pass the interval value, as a number in milliseconds, to the decorator as shown below:

```typescript

@Interval(10000)
handleInterval() {
  this.logger.debug('Called every 10 seconds');
}
```

> **Hint** This mechanism uses the JavaScript `setInterval()` function under the hood. You can also utilize a cron job to schedule recurring jobs.

If you want to control your declarative interval from outside the declaring class via the [Dynamic API](/techniques/task-scheduling#dynamic-schedule-module-api), associate the interval with a name using the following construction:

```typescript

@Interval('notifications', 2500)
handleInterval() {}
```

```typescript

@Timeout(5000)
handleTimeout() {
  this.logger.debug('Called once after 5 seconds');
}
```

> **Hint** This mechanism uses the JavaScript `setTimeout()` function under the hood.

If you want to control your declarative timeout from outside the declaring class via the [Dynamic API](/techniques/task-scheduling#dynamic-schedule-module-api), associate the timeout with a name using the following construction:

```typescript

@Timeout('notifications', 2500)
handleTimeout() {}
```

The [Dynamic API](techniques/task-scheduling#dynamic-timeouts) also enables **creating** dynamic timeouts, where the timeout's properties are defined at runtime, and **listing and deleting** them.

#### Dynamic schedule module API[#](/techniques/task-scheduling#dynamic-schedule-module-api)

The `@nestjs/schedule` module provides a dynamic API that enables managing declarative [cron jobs](techniques/task-scheduling#declarative-cron-jobs), [timeouts](techniques/task-scheduling#declarative-timeouts) and [intervals](techniques/task-scheduling#declarative-intervals). The API also enables creating and managing **dynamic** cron jobs, timeouts and intervals, where the properties are defined at runtime.

#### Dynamic cron jobs[#](/techniques/task-scheduling#dynamic-cron-jobs)

Obtain a reference to a `CronJob` instance by name from anywhere in your code using the `SchedulerRegistry` API. First, inject `SchedulerRegistry` using standard constructor injection:

```typescript

constructor(private schedulerRegistry: SchedulerRegistry) {}
```

> **Hint** Import the `SchedulerRegistry` from the `@nestjs/schedule` package.

Then use it in a class as follows. Assume a cron job was created with the following declaration:

```typescript

@Cron('* * 8 * * *', {
  name: 'notifications',
})
triggerNotifications() {}
```

Access this job using the following:

```typescript

const job = this.schedulerRegistry.getCronJob('notifications');

job.stop();
console.log(job.lastDate());
```

The `getCronJob()` method returns the named cron job. The returned `CronJob` object has the following methods:

* `stop()` - stops a job that is scheduled to run.
* `start()` - restarts a job that has been stopped.
* `setTime(time: CronTime)` - stops a job, sets a new time for it, and then starts it
* `lastDate()` - returns a string representation of the last date a job executed
* `nextDates(count: number)` - returns an array (size `count`) of `moment` objects representing upcoming job execution dates.

> **Hint** Use `toDate()` on `moment` objects to render them in human readable form.

**Create** a new cron job dynamically using the `SchedulerRegistry.addCronJob()` method, as follows:

```typescript

addCronJob(name: string, seconds: string) {
  const job = new CronJob(`${seconds} * * * * *`, () => {
    this.logger.warn(`time (${seconds}) for job ${name} to run!`);
  });

  this.schedulerRegistry.addCronJob(name, job);
  job.start();

  this.logger.warn(
    `job ${name} added for each minute at ${seconds} seconds!`,
  );
}
```

In this code, we use the `CronJob` object from the `cron` package to create the cron job. The `CronJob` constructor takes a cron pattern (just like the `@Cron()`[decorator](techniques/task-scheduling#declarative-cron-jobs)) as its first argument, and a callback to be executed when the cron timer fires as its second argument. The `SchedulerRegistry.addCronJob()` method takes two arguments: a name for the `CronJob`, and the `CronJob` object itself.

> **Warning** Remember to inject the `SchedulerRegistry` before accessing it. Import `CronJob` from the `cron` package.

**Delete** a named cron job using the `SchedulerRegistry.deleteCronJob()` method, as follows:

```typescript

deleteCron(name: string) {
  this.schedulerRegistry.deleteCronJob(name);
  this.logger.warn(`job ${name} deleted!`);
}
```

**List** all cron jobs using the `SchedulerRegistry.getCronJobs()` method as follows:

```typescript

getCrons() {
  const jobs = this.schedulerRegistry.getCronJobs();
  jobs.forEach((value, key, map) => {
    let next;
    try {
      next = value.nextDates().toDate();
    } catch (e) {
      next = 'error: next fire date is in the past!';
    }
    this.logger.log(`job: ${key} -> next: ${next}`);
  });
}
```

The `getCronJobs()` method returns a `map`. In this code, we iterate over the map and attempt to access the `nextDates()` method of each `CronJob`. In the `CronJob` API, if a job has already fired and has no future firing dates, it throws an exception.

#### Dynamic intervals[#](/techniques/task-scheduling#dynamic-intervals)

Obtain a reference to an interval with the `SchedulerRegistry.getInterval()` method. As above, inject `SchedulerRegistry` using standard constructor injection:

```typescript

constructor(private schedulerRegistry: SchedulerRegistry) {}
```

And use it as follows:

```typescript

const interval = this.schedulerRegistry.getInterval('notifications');
clearInterval(interval);
```

**Create** a new interval dynamically using the `SchedulerRegistry.addInterval()` method, as follows:

```typescript

addInterval(name: string, milliseconds: number) {
  const callback = () => {
    this.logger.warn(`Interval ${name} executing at time (${milliseconds})!`);
  };

  const interval = setInterval(callback, milliseconds);
  this.schedulerRegistry.addInterval(name, interval);
}
```

In this code, we create a standard JavaScript interval, then pass it to the `ScheduleRegistry.addInterval()` method. That method takes two arguments: a name for the interval, and the interval itself.

**Delete** a named interval using the `SchedulerRegistry.deleteInterval()` method, as follows:

```typescript

deleteInterval(name: string) {
  this.schedulerRegistry.deleteInterval(name);
  this.logger.warn(`Interval ${name} deleted!`);
}
```

**List** all intervals using the `SchedulerRegistry.getIntervals()` method as follows:

```typescript

getIntervals() {
  const intervals = this.schedulerRegistry.getIntervals();
  intervals.forEach(key => this.logger.log(`Interval: ${key}`));
}
```

#### Dynamic timeouts[#](/techniques/task-scheduling#dynamic-timeouts)

Obtain a reference to a timeout with the `SchedulerRegistry.getTimeout()` method. As above, inject `SchedulerRegistry` using standard constructor injection:

```typescript

constructor(private schedulerRegistry: SchedulerRegistry) {}
```

And use it as follows:

```typescript

const timeout = this.schedulerRegistry.getTimeout('notifications');
clearTimeout(timeout);
```

**Create** a new timeout dynamically using the `SchedulerRegistry.addTimeout()` method, as follows:

```typescript

addTimeout(name: string, milliseconds: number) {
  const callback = () => {
    this.logger.warn(`Timeout ${name} executing after (${milliseconds})!`);
  };

  const timeout = setTimeout(callback, milliseconds);
  this.schedulerRegistry.addTimeout(name, timeout);
}
```

In this code, we create a standard JavaScript timeout, then pass it to the `ScheduleRegistry.addTimeout()` method. That method takes two arguments: a name for the timeout, and the timeout itself.

**Delete** a named timeout using the `SchedulerRegistry.deleteTimeout()` method, as follows:

```typescript

deleteTimeout(name: string) {
  this.schedulerRegistry.deleteTimeout(name);
  this.logger.warn(`Timeout ${name} deleted!`);
}
```

**List** all timeouts using the `SchedulerRegistry.getTimeouts()` method as follows:

```typescript

getTimeouts() {
  const timeouts = this.schedulerRegistry.getTimeouts();
  timeouts.forEach(key => this.logger.log(`Timeout: ${key}`));
}
```

#### Example[#](/techniques/task-scheduling#example)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/27-scheduling).

----
url: https://docs.nestjs.com/v8/websockets/pipes
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Pipes](https://docs.nestjs.com/v8/websockets/pipes#pipes)
* [Binding pipes](https://docs.nestjs.com/v8/websockets/pipes#binding-pipes)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/websockets/pipes.md "Suggest Edits")

### Pipes

There is no fundamental difference between [regular pipes](/v8/pipes) and web sockets pipes. The only difference is that instead of throwing `HttpException`, you should use `WsException`. In addition, all pipes will be only applied to the `data` parameter (because validating or transforming `client` instance is useless).

> **Hint** The `WsException` class is exposed from `@nestjs/websockets` package.

#### Binding pipes[#](/websockets/pipes#binding-pipes)

The following example uses a manually instantiated method-scoped pipe. Just as with HTTP based applications, you can also use gateway-scoped pipes (i.e., prefix the gateway class with a `@UsePipes()` decorator).

JS TS

```typescript

@UsePipes(new ValidationPipe())
@SubscribeMessage('events')
handleEvent(client: Client, data: unknown): WsResponse<unknown> {
  const event = 'events';
  return { event, data };
}
```

```typescript

@UsePipes(new ValidationPipe())
@SubscribeMessage('events')
handleEvent(client, data) {
  const event = 'events';
  return { event, data };
}
```

----
url: https://docs.nestjs.com/data/sequelize
----

[Skip to content](#content)

On this page

* [Sequelize](https://docs.nestjs.com/data/sequelize#sequelize)
* [Models](https://docs.nestjs.com/data/sequelize#models)
* [Relations](https://docs.nestjs.com/data/sequelize#relations)
* [Auto-load models](https://docs.nestjs.com/data/sequelize#auto-load-models)
* [Sequelize Transactions](https://docs.nestjs.com/data/sequelize#sequelize-transactions)
* [Migrations](https://docs.nestjs.com/data/sequelize#migrations)
* [Multiple databases](https://docs.nestjs.com/data/sequelize#multiple-databases)
* [Testing](https://docs.nestjs.com/data/sequelize#testing)
* [Async configuration](https://docs.nestjs.com/data/sequelize#async-configuration)
* [Example](https://docs.nestjs.com/data/sequelize#example)

### Sequelize

The `@nestjs/sequelize` package integrates the [Sequelize](https://sequelize.org/) ORM with Nest. It also uses the [sequelize-typescript](https://github.com/RobinBuschmann/sequelize-typescript) package, which provides decorators to define models declaratively.

To begin using it, we first install the required dependencies. In this chapter, we'll demonstrate using the popular [MySQL](https://www.mysql.com/) Relational DBMS, but Sequelize provides support for many relational databases, such as PostgreSQL, MySQL, Microsoft SQL Server, SQLite, and MariaDB. The procedure we walk through in this chapter will be the same for any database supported by Sequelize. You'll simply need to install the associated client API libraries for your selected database.

```bash

$ npm install --save @nestjs/sequelize sequelize sequelize-typescript mysql2
$ npm install --save-dev @types/sequelize
```

Once the installation process is complete, we can import the `SequelizeModule` into the root `AppModule`.

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { SequelizeModule } from '@nestjs/sequelize';

@Module({
  imports: [
    SequelizeModule.forRoot({
      dialect: 'mysql',
      host: 'localhost',
      port: 3306,
      username: 'root',
      password: 'root',
      database: 'test',
      models: [],
    }),
  ],
})
export class AppModule {}
```

The `forRoot()` method supports all the configuration properties exposed by the Sequelize constructor ([read more](https://sequelize.org/docs/v6/getting-started/#connecting-to-a-database)). In addition, there are several extra configuration properties described below.

|                       |                                                                                         |
| --------------------- | --------------------------------------------------------------------------------------- |
| `retryAttempts`       | Number of attempts to connect to the database (default: `10`)                           |
| `retryDelay`          | Delay between connection retry attempts (ms) (default: `3000`)                          |
| `autoLoadModels`      | If `true`, models will be loaded automatically (default: `false`)                       |
| `keepConnectionAlive` | If `true`, connection will not be closed on the application shutdown (default: `false`) |
| `synchronize`         | If `true`, automatically loaded models will be synchronized (default: `true`)           |

Once this is done, the `Sequelize` object will be available to inject across the entire project (without needing to import any modules), for example:

app.service.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { Sequelize } from 'sequelize-typescript';

@Injectable()
export class AppService {
  constructor(private sequelize: Sequelize) {}
}
```

```typescript

import { Injectable } from '@nestjs/common';
import { Sequelize } from 'sequelize-typescript';

@Dependencies(Sequelize)
@Injectable()
export class AppService {
  constructor(sequelize) {
    this.sequelize = sequelize;
  }
}
```

#### Models[#](/data/sequelize#models)

Sequelize implements the Active Record pattern. With this pattern, you use model classes directly to interact with the database. To continue the example, we need at least one model. Let's define the `User` model.

user.model.ts

JS TS

```typescript

import { Column, Model, Table } from 'sequelize-typescript';

@Table
export class User extends Model {
  @Column
  firstName: string;

  @Column
  lastName: string;

  @Column({ defaultValue: true })
  isActive: boolean;
}
```

> **Hint** Learn more about the available decorators [here](https://github.com/RobinBuschmann/sequelize-typescript#column).

The `User` model file sits in the `users` directory. This directory contains all files related to the `UsersModule`. You can decide where to keep your model files, however, we recommend creating them near their **domain**, in the corresponding module directory.

To begin using the `User` model, we need to let Sequelize know about it by inserting it into the `models` array in the module `forRoot()` method options:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { SequelizeModule } from '@nestjs/sequelize';
import { User } from './users/user.model.js';

@Module({
  imports: [
    SequelizeModule.forRoot({
      dialect: 'mysql',
      host: 'localhost',
      port: 3306,
      username: 'root',
      password: 'root',
      database: 'test',
      models: [User],
    }),
  ],
})
export class AppModule {}
```

Next, let's look at the `UsersModule`:

users.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { SequelizeModule } from '@nestjs/sequelize';
import { User } from './user.model.js';
import { UsersController } from './users.controller.js';
import { UsersService } from './users.service.js';

@Module({
  imports: [SequelizeModule.forFeature([User])],
  providers: [UsersService],
  controllers: [UsersController],
})
export class UsersModule {}
```

This module uses the `forFeature()` method to define which models are registered in the current scope. With that in place, we can inject the `UserModel` into the `UsersService` using the `@InjectModel()` decorator:

users.service.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { InjectModel } from '@nestjs/sequelize';
import { User } from './user.model.js';

@Injectable()
export class UsersService {
  constructor(
    @InjectModel(User)
    private userModel: typeof User,
  ) {}

  async findAll(): Promise<User[]> {
    return this.userModel.findAll();
  }

  findOne(id: string): Promise<User> {
    return this.userModel.findOne({
      where: {
        id,
      },
    });
  }

  async remove(id: string): Promise<void> {
    const user = await this.findOne(id);
    await user.destroy();
  }
}
```

```typescript

import { Injectable, Dependencies } from '@nestjs/common';
import { getModelToken } from '@nestjs/sequelize';
import { User } from './user.model.js';

@Injectable()
@Dependencies(getModelToken(User))
export class UsersService {
  constructor(usersRepository) {
    this.usersRepository = usersRepository;
  }

  async findAll() {
    return this.userModel.findAll();
  }

  findOne(id) {
    return this.userModel.findOne({
      where: {
        id,
      },
    });
  }

  async remove(id) {
    const user = await this.findOne(id);
    await user.destroy();
  }
}
```

> **Notice** Don't forget to import the `UsersModule` into the root `AppModule`.

If you want to use the model outside of the module which imports `SequelizeModule.forFeature`, you'll need to re-export the providers generated by it. You can do this by exporting the whole module, like this:

users.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { SequelizeModule } from '@nestjs/sequelize';
import { User } from './user.entity.js';

@Module({
  imports: [SequelizeModule.forFeature([User])],
  exports: [SequelizeModule]
})
export class UsersModule {}
```

Now if we import `UsersModule` in `UserHttpModule`, we can use `@InjectModel(User)` in the providers of the latter module.

users-http.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { UsersModule } from './users.module.js';
import { UsersService } from './users.service.js';
import { UsersController } from './users.controller.js';

@Module({
  imports: [UsersModule],
  providers: [UsersService],
  controllers: [UsersController]
})
export class UserHttpModule {}
```

#### Relations[#](/data/sequelize#relations)

Relations are associations established between two or more tables. Relations are based on common fields from each table, often involving primary and foreign keys.

There are three types of relations:

|                             |                                                                                                                                                             |
| --------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `One-to-one`                | Every row in the primary table has one and only one associated row in the foreign table                                                                     |
| `One-to-many / Many-to-one` | Every row in the primary table has one or more related rows in the foreign table                                                                            |
| `Many-to-many`              | Every row in the primary table has many related rows in the foreign table, and every record in the foreign table has many related rows in the primary table |

To define relations in models, use the corresponding **decorators**. For example, to define that each `User` can have multiple photos, use the `@HasMany()` decorator.

user.model.ts

JS TS

```typescript

import { Column, Model, Table, HasMany } from 'sequelize-typescript';
import { Photo } from '../photos/photo.model.js';

@Table
export class User extends Model {
  @Column
  firstName: string;

  @Column
  lastName: string;

  @Column({ defaultValue: true })
  isActive: boolean;

  @HasMany(() => Photo)
  photos: Photo[];
}
```

> **Hint** To learn more about associations in Sequelize, read [this](https://github.com/RobinBuschmann/sequelize-typescript#model-association) chapter.

#### Auto-load models[#](/data/sequelize#auto-load-models)

Manually adding models to the `models` array of the connection options can be tedious. In addition, referencing models from the root module breaks application domain boundaries and causes leaking implementation details to other parts of the application. To solve this issue, automatically load models by setting both `autoLoadModels` and `synchronize` properties of the configuration object (passed into the `forRoot()` method) to `true`, as shown below:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { SequelizeModule } from '@nestjs/sequelize';

@Module({
  imports: [
    SequelizeModule.forRoot({
      ...
      autoLoadModels: true,
      synchronize: true,
    }),
  ],
})
export class AppModule {}
```

With that option specified, every model registered through the `forFeature()` method will be automatically added to the `models` array of the configuration object.

> **Warning** Note that models that aren't registered through the `forFeature()` method, but are only referenced from the model (via an association), won't be included.

#### Sequelize Transactions[#](/data/sequelize#sequelize-transactions)

A database transaction symbolizes a unit of work performed within a database management system against a database, and treated in a coherent and reliable way independent of other transactions. A transaction generally represents any change in a database ([learn more](https://en.wikipedia.org/wiki/Database_transaction)).

There are many different strategies to handle [Sequelize transactions](https://sequelize.org/docs/v6/other-topics/transactions/). Below is a sample implementation of a managed transaction (auto-callback).

First, we need to inject the `Sequelize` object into a class in the normal way:

```typescript

@Injectable()
export class UsersService {
  constructor(private sequelize: Sequelize) {}
}
```

> **Hint** The `Sequelize` class is imported from the `sequelize-typescript` package.

Now, we can use this object to create a transaction.

```typescript

async createMany() {
  try {
    await this.sequelize.transaction(async t => {
      const transactionHost = { transaction: t };

      await this.userModel.create(
          { firstName: 'Abraham', lastName: 'Lincoln' },
          transactionHost,
      );
      await this.userModel.create(
          { firstName: 'John', lastName: 'Boothe' },
          transactionHost,
      );
    });
  } catch (err) {
    // Transaction has been rolled back
    // err is whatever rejected the promise chain returned to the transaction callback
  }
}
```

> **Hint** Note that the `Sequelize` instance is used only to start the transaction. However, to test this class would require mocking the entire `Sequelize` object (which exposes several methods). Thus, we recommend using a helper factory class (e.g., `TransactionRunner`) and defining an interface with a limited set of methods required to maintain transactions. This technique makes mocking these methods pretty straightforward.

#### Migrations[#](/data/sequelize#migrations)

[Migrations](https://sequelize.org/docs/v6/other-topics/migrations/) provide a way to incrementally update the database schema to keep it in sync with the application's data model while preserving existing data in the database. To generate, run, and revert migrations, Sequelize provides a dedicated [CLI](https://sequelize.org/docs/v6/other-topics/migrations/#installing-the-cli).

Migration classes are separate from the Nest application source code. Their lifecycle is maintained by the Sequelize CLI. Therefore, you are not able to leverage dependency injection and other Nest specific features with migrations. To learn more about migrations, follow the guide in the [Sequelize documentation](https://sequelize.org/docs/v6/other-topics/migrations/#installing-the-cli).

## Learn the right way!

* 80+ chapters
* 5+ hours of videos
* Official certificate
* Deep-dive sessions

[Explore official courses](https://courses.nestjs.com "Courses | NestJS - A node.js framework built on top of TypeScript")

#### Multiple databases[#](/data/sequelize#multiple-databases)

Some projects require multiple database connections. This can also be achieved with this module. To work with multiple connections, first create the connections. In this case, connection naming becomes **mandatory**.

Suppose you have an `Album` entity stored in its own database.

```typescript

const defaultOptions = {
  dialect: 'postgres',
  port: 5432,
  username: 'user',
  password: 'password',
  database: 'db',
  synchronize: true,
};

@Module({
  imports: [
    SequelizeModule.forRoot({
      ...defaultOptions,
      host: 'user_db_host',
      models: [User],
    }),
    SequelizeModule.forRoot({
      ...defaultOptions,
      name: 'albumsConnection',
      host: 'album_db_host',
      models: [Album],
    }),
  ],
})
export class AppModule {}
```

> **Notice** If you don't set the `name` for a connection, its name is set to `default`. Please note that you shouldn't have multiple connections without a name, or with the same name, otherwise they will get overridden.

At this point, you have `User` and `Album` models registered with their own connection. With this setup, you have to tell the `SequelizeModule.forFeature()` method and the `@InjectModel()` decorator which connection should be used. If you do not pass any connection name, the `default` connection is used.

```typescript

@Module({
  imports: [
    SequelizeModule.forFeature([User]),
    SequelizeModule.forFeature([Album], 'albumsConnection'),
  ],
})
export class AppModule {}
```

You can also inject the `Sequelize` instance for a given connection:

```typescript

@Injectable()
export class AlbumsService {
  constructor(
    @InjectConnection('albumsConnection')
    private sequelize: Sequelize,
  ) {}
}
```

It's also possible to inject any `Sequelize` instance to the providers:

```typescript

@Module({
  providers: [
    {
      provide: AlbumsService,
      useFactory: (albumsSequelize: Sequelize) => {
        return new AlbumsService(albumsSequelize);
      },
      inject: [getDataSourceToken('albumsConnection')],
    },
  ],
})
export class AlbumsModule {}
```

#### Testing[#](/data/sequelize#testing)

When it comes to unit testing an application, we usually want to avoid making a database connection, keeping our test suites independent and their execution process as fast as possible. But our classes might depend on models that are pulled from the connection instance. How do we handle that? The solution is to create mock models. In order to achieve that, we set up [custom providers](/fundamentals/custom-providers). Each registered model is automatically represented by a `<ModelName>Model` token, where `ModelName` is the name of your model class.

The `@nestjs/sequelize` package exposes the `getModelToken()` function which returns a prepared token based on a given model.

```typescript

@Module({
  providers: [
    UsersService,
    {
      provide: getModelToken(User),
      useValue: mockModel,
    },
  ],
})
export class UsersModule {}
```

Now a substitute `mockModel` will be used as the `UserModel`. Whenever any class asks for `UserModel` using an `@InjectModel()` decorator, Nest will use the registered `mockModel` object.

#### Async configuration[#](/data/sequelize#async-configuration)

You may want to pass your `SequelizeModule` options asynchronously instead of statically. In this case, use the `forRootAsync()` method, which provides several ways to deal with async configuration.

One approach is to use a factory function:

```typescript

SequelizeModule.forRootAsync({
  useFactory: () => ({
    dialect: 'mysql',
    host: 'localhost',
    port: 3306,
    username: 'root',
    password: 'root',
    database: 'test',
    models: [],
  }),
});
```

Our factory behaves like any other [asynchronous provider](https://docs.nestjs.com/fundamentals/async-providers) (e.g., it can be `async` and it's able to inject dependencies through `inject`).

```typescript

SequelizeModule.forRootAsync({
  imports: [ConfigModule],
  useFactory: (configService: ConfigService) => ({
    dialect: 'mysql',
    host: configService.get('HOST'),
    port: +configService.get('PORT'),
    username: configService.get('USERNAME'),
    password: configService.get('PASSWORD'),
    database: configService.get('DATABASE'),
    models: [],
  }),
  inject: [ConfigService],
});
```

Alternatively, you can use the `useClass` syntax:

```typescript

SequelizeModule.forRootAsync({
  useClass: SequelizeConfigService,
});
```

The construction above will instantiate `SequelizeConfigService` inside `SequelizeModule` and use it to provide an options object by calling `createSequelizeOptions()`. Note that this means that the `SequelizeConfigService` has to implement the `SequelizeOptionsFactory` interface, as shown below:

```typescript

@Injectable()
class SequelizeConfigService implements SequelizeOptionsFactory {
  createSequelizeOptions(): SequelizeModuleOptions {
    return {
      dialect: 'mysql',
      host: 'localhost',
      port: 3306,
      username: 'root',
      password: 'root',
      database: 'test',
      models: [],
    };
  }
}
```

In order to prevent the creation of `SequelizeConfigService` inside `SequelizeModule` and use a provider imported from a different module, you can use the `useExisting` syntax.

```typescript

SequelizeModule.forRootAsync({
  imports: [ConfigModule],
  useExisting: ConfigService,
});
```

This construction works the same as `useClass` with one critical difference - `SequelizeModule` will lookup imported modules to reuse an existing `ConfigService` instead of instantiating a new one.

#### Example[#](/data/sequelize#example)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/07-sequelize).

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/data/sequelize.md)

----
url: https://docs.nestjs.com/v11/graphql/interfaces
----

* [Interfaces](https://docs.nestjs.com/v11/graphql/interfaces#interfaces)
* [Code first](https://docs.nestjs.com/v11/graphql/interfaces#code-first)
* [Interface resolvers](https://docs.nestjs.com/v11/graphql/interfaces#interface-resolvers)
* [Schema first](https://docs.nestjs.com/v11/graphql/interfaces#schema-first)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/interfaces.md "Suggest Edits")

### Interfaces

Like many type systems, GraphQL supports interfaces. An **Interface** is an abstract type that includes a certain set of fields that a type must include to implement the interface (read more [here](https://graphql.org/learn/schema/#interfaces)).

#### Code first[#](/graphql/interfaces#code-first)

When using the code first approach, you define a GraphQL interface by creating an abstract class annotated with the `@InterfaceType()` decorator exported from the `@nestjs/graphql`.

```typescript

import { Field, ID, InterfaceType } from '@nestjs/graphql';

@InterfaceType()
export abstract class Character {
  @Field(() => ID)
  id: string;

  @Field()
  name: string;
}
```

> **Warning** TypeScript interfaces cannot be used to define GraphQL interfaces.

This will result in generating the following part of the GraphQL schema in SDL:

```graphql

interface Character {
  id: ID!
  name: String!
}
```

Now, to implement the `Character` interface, use the `implements` key:

```typescript

@ObjectType({
  implements: () => [Character],
})
export class Human implements Character {
  id: string;
  name: string;
}
```

> **Hint** The `@ObjectType()` decorator is exported from the `@nestjs/graphql` package.

The default `resolveType()` function generated by the library extracts the type based on the value returned from the resolver method. This means that you must return class instances (you cannot return literal JavaScript objects).

To provide a customized `resolveType()` function, pass the `resolveType` property to the options object passed into the `@InterfaceType()` decorator, as follows:

```typescript

@InterfaceType({
  resolveType(book) {
    if (book.colors) {
      return ColoringBook;
    }
    return TextBook;
  },
})
export abstract class Book {
  @Field(() => ID)
  id: string;

  @Field()
  title: string;
}
```

#### Interface resolvers[#](/graphql/interfaces#interface-resolvers)

So far, using interfaces, you could only share field definitions with your objects. If you also want to share the actual field resolvers implementation, you can create a dedicated interface resolver, as follows:

```typescript

import { Resolver, ResolveField, Parent, Info } from '@nestjs/graphql';

@Resolver((type) => Character) // Reminder: Character is an interface
export class CharacterInterfaceResolver {
  @ResolveField(() => [Character])
  friends(
    @Parent() character, // Resolved object that implements Character
    @Info() { parentType }, // Type of the object that implements Character
    @Args('search', { type: () => String }) searchTerm: string,
  ) {
    // Get character's friends
    return [];
  }
}
```

Now the `friends` field resolver is auto-registered for all object types that implement the `Character` interface.

> **Warning** This requires the `inheritResolversFromInterfaces` property set to be true in the `GraphQLModule` configuration.

#### Schema first[#](/graphql/interfaces#schema-first)

To define an interface in the schema first approach, simply create a GraphQL interface with SDL.

```graphql

interface Character {
  id: ID!
  name: String!
}
```

Then, you can use the typings generation feature (as shown in the [quick start](/v11/graphql/quick-start) chapter) to generate corresponding TypeScript definitions:

```typescript

export interface Character {
  id: string;
  name: string;
}
```

Interfaces require an extra `__resolveType` field in the resolver map to determine which type the interface should resolve to. Let's create a `CharactersResolver` class and define the `__resolveType` method:

```typescript

@Resolver('Character')
export class CharactersResolver {
  @ResolveField()
  __resolveType(value) {
    if ('age' in value) {
      return Person;
    }
    return null;
  }
}
```

> **Hint** All decorators are exported from the `@nestjs/graphql` package.

----
url: https://docs.nestjs.com/v8/fundamentals/lazy-loading-modules
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Lazy-loading modules](https://docs.nestjs.com/v8/fundamentals/lazy-loading-modules#lazy-loading-modules)
* [Getting started](https://docs.nestjs.com/v8/fundamentals/lazy-loading-modules#getting-started)
* [Lazy-loading controllers, gateways, and resolvers](https://docs.nestjs.com/v8/fundamentals/lazy-loading-modules#lazy-loading-controllers-gateways-and-resolvers)
* [Common use-cases](https://docs.nestjs.com/v8/fundamentals/lazy-loading-modules#common-use-cases)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/fundamentals/lazy-loading-modules.md "Suggest Edits")

### Lazy-loading modules

By default, modules are eagerly loaded, which means that as soon as the application loads, so do all the modules, whether or not they are immediately necessary. While this is fine for most applications, it may become a bottleneck for apps/workers running in the **serverless environment**, where the startup latency ("cold start") is crucial.

Lazy loading can help decrease bootstrap time by loading only modules required by the specific serverless function invocation. In addition, you could also load other modules asynchronously once the serverless function is "warm" to speed-up the bootstrap time for subsequent calls even further (deferred modules registration).

> **Hint** If you're familiar with the **Angular** framework, you might have seen the "lazy-loading modules" term before. Be aware that this technique is **functionally different** in Nest and so think about this as an entirely different feature that shares similar naming conventions.

> **Warning** Do note that [lifecycle hooks methods](https://docs.nestjs.com/fundamentals/lifecycle-events) are not invoked in lazy loaded modules and services.

#### Getting started[#](/fundamentals/lazy-loading-modules#getting-started)

To load modules on-demand, Nest provides the `LazyModuleLoader` class that can be injected into a class in the normal way:

cats.service.ts

JS TS

```typescript

@Injectable()
export class CatsService {
  constructor(private lazyModuleLoader: LazyModuleLoader) {}
}
```

```typescript

@Injectable()
@Dependencies(LazyModuleLoader)
export class CatsService {
  constructor(lazyModuleLoader) {
    this.lazyModuleLoader = lazyModuleLoader;
  }
}
```

> **Hint** The `LazyModuleLoader` class is imported from the `@nestjs/core` package.

Alternatively, you can obtain a reference to the `LazyModuleLoader` provider from within your application bootstrap file (`main.ts`), as follows:

```typescript

// "app" represents a Nest application instance
const lazyModuleLoader = app.get(LazyModuleLoader);
```

With this in place, you can now load any module using the following construction:

```typescript

const { LazyModule } = await import('./lazy.module');
const moduleRef = await this.lazyModuleLoader.load(() => LazyModule);
```

> **Hint** "Lazy-loaded" modules are **cached** upon the first `LazyModuleLoader#load` method invocation. That means, each consecutive attempt to load `LazyModule` will be **very fast** and will return a cached instance, instead of loading the module again.
>
> ```bash
>
> Load "LazyModule" attempt: 1
> time: 2.379ms
> Load "LazyModule" attempt: 2
> time: 0.294ms
> Load "LazyModule" attempt: 3
> time: 0.303ms
> ```
>
> Also, "lazy-loaded" modules share the same modules graph as those eagerly loaded on the application bootstrap as well as any other lazy modules registered later in your app.

Where `lazy.module.ts` is a TypeScript file that exports a **regular Nest module** (no extra changes are required).

The `LazyModuleLoader#load` method returns the [module reference](/v8/fundamentals/module-ref) (of `LazyModule`) that lets you navigate the internal list of providers and obtain a reference to any provider using its injection token as a lookup key.

For example, let's say we have a `LazyModule` with the following definition:

```typescript

@Module({
  providers: [LazyService],
  exports: [LazyService],
})
export class LazyModule {}
```

> **Hint** Lazy-loaded modules cannot be registered as **global modules** as it simply makes no sense (since they are registered lazily, on-demand when all the statically registered modules have been already instantiated). Likewise, registered **global enhancers** (guards/interceptors/etc.) **will not work** properly either.

With this, we could obtain a reference to the `LazyService` provider, as follows:

```typescript

const { LazyModule } = await import('./lazy.module');
const moduleRef = await this.lazyModuleLoader.load(() => LazyModule);

const { LazyService } = await import('./lazy.service');
const lazyService = moduleRef.get(LazyService);
```

> **Warning** If you use **Webpack**, make sure to update your `tsconfig.json` file - setting `compilerOptions.module` to `"esnext"` and adding `compilerOptions.moduleResolution` property with `"node"` as a value:
>
> ```json
>
> {
>   "compilerOptions": {
>     "module": "esnext",
>     "moduleResolution": "node",
>     ...
>   }
> }
> ```
>
> With these options set up, you'll be able to leverage the [code splitting](https://webpack.js.org/guides/code-splitting/) feature.

#### Lazy-loading controllers, gateways, and resolvers[#](/fundamentals/lazy-loading-modules#lazy-loading-controllers-gateways-and-resolvers)

Since controllers (or resolvers in GraphQL applications) in Nest represent sets of routes/paths/topics (or queries/mutations), you **cannot lazy load them** using the `LazyModuleLoader` class.

> **Warning** Controllers, [resolvers](/v8/graphql/resolvers), and [gateways](/v8/websockets/gateways) registered inside lazy-loaded modules will not behave as expected. Similarly, you cannot register middleware functions (by implementing the `MiddlewareConsumer` interface) on-demand.

For example, let's say you're building a REST API (HTTP application) with a Fastify driver under the hood (using the `@nestjs/platform-fastify` package). Fastify does not let you register routes after the application is ready/successfully listening to messages. That means even if we analyzed route mappings registered in the module's controllers, all lazy-loaded routes wouldn't be accessible since there is no way to register them at runtime.

Likewise, some transport strategies we provide as part of the `@nestjs/microservices` package (including Kafka, gRPC, or RabbitMQ) require to subscribe/listen to specific topics/channels before the connection is established. Once your application starts listening to messages, the framework would not be able to subscribe/listen to new topics.

Lastly, the `@nestjs/graphql` package with the code first approach enabled automatically generates the GraphQL schema on-the-fly based on the metadata. That means, it requires all classes to be loaded beforehand. Otherwise, it would not be doable to create the appropriate, valid schema.

#### Common use-cases[#](/fundamentals/lazy-loading-modules#common-use-cases)

Most commonly, you will see lazy loaded modules in situations when your worker/cron job/lambda & serverless function/webhook must trigger different services (different logic) based on the input arguments (route path/date/query parameters, etc.). On the other hand, lazy-loading modules may not make too much sense for monolithic applications, where the startup time is rather irrelevant.

----
url: https://docs.nestjs.com/v8/techniques/cookies
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Cookies](https://docs.nestjs.com/v8/techniques/cookies#cookies)
* [Use with Express (default)](https://docs.nestjs.com/v8/techniques/cookies#use-with-express-default)
* [Use with Fastify](https://docs.nestjs.com/v8/techniques/cookies#use-with-fastify)
* [Creating a custom decorator (cross-platform)](https://docs.nestjs.com/v8/techniques/cookies#creating-a-custom-decorator-cross-platform)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/techniques/cookies.md "Suggest Edits")

### Cookies

An **HTTP cookie** is a small piece of data stored by the user's browser. Cookies were designed to be a reliable mechanism for websites to remember stateful information. When the user visits the website again, the cookie is automatically sent with the request.

#### Use with Express (default)[#](/techniques/cookies#use-with-express-default)

First install the [required package](https://github.com/expressjs/cookie-parser) (and its types for TypeScript users):

```shell

$ npm i cookie-parser
$ npm i -D @types/cookie-parser
```

Once the installation is complete, apply the `cookie-parser` middleware as global middleware (for example, in your `main.ts` file).

```typescript

import * as cookieParser from 'cookie-parser';
// somewhere in your initialization file
app.use(cookieParser());
```

You can pass several options to the `cookieParser` middleware:

* `secret` a string or array used for signing cookies. This is optional and if not specified, will not parse signed cookies. If a string is provided, this is used as the secret. If an array is provided, an attempt will be made to unsign the cookie with each secret in order.
* `options` an object that is passed to `cookie.parse` as the second option. See [cookie](https://www.npmjs.org/package/cookie) for more information.

The middleware will parse the `Cookie` header on the request and expose the cookie data as the property `req.cookies` and, if a secret was provided, as the property `req.signedCookies`. These properties are name value pairs of the cookie name to cookie value.

When secret is provided, this module will unsign and validate any signed cookie values and move those name value pairs from req.cookies into `req.signedCookies`. A signed cookie is a cookie that has a value prefixed with `s:`. Signed cookies that fail signature validation will have the value `false` instead of the tampered value.

With this in place, you can now read cookies from within the route handlers, as follows:

```typescript

@Get()
findAll(@Req() request: Request) {
  console.log(request.cookies); // or "request.cookies['cookieKey']"
  // or console.log(request.signedCookies);
}
```

> **Hint** The `@Req()` decorator is imported from the `@nestjs/common`, while `Request` from the `express` package.

To attach a cookie to an outgoing response, use the `Response#cookie()` method:

```typescript

@Get()
findAll(@Res({ passthrough: true }) response: Response) {
  response.cookie('key', 'value')
}
```

> **Warning** If you want to leave the response handling logic to the framework, remember to set the `passthrough` option to `true`, as shown above. Read more [here](/controllers#appendix-library-specific-approach).

> **Hint** The `@Res()` decorator is imported from the `@nestjs/common`, while `Response` from the `express` package.

#### Use with Fastify[#](/techniques/cookies#use-with-fastify)

First install the required package:

```shell

$ npm i fastify-cookie
```

Once the installation is complete, register the `fastify-cookie` plugin:

```typescript

import fastifyCookie from 'fastify-cookie';

// somewhere in your initialization file
const app = await NestFactory.create<NestFastifyApplication>(
  AppModule,
  new FastifyAdapter(),
);
await app.register(fastifyCookie, {
  secret: 'my-secret', // for cookies signature
});
```

With this in place, you can now read cookies from within the route handlers, as follows:

```typescript

@Get()
findAll(@Req() request: FastifyRequest) {
  console.log(request.cookies); // or "request.cookies['cookieKey']"
}
```

> **Hint** The `@Req()` decorator is imported from the `@nestjs/common`, while `FastifyRequest` from the `fastify` package.

To attach a cookie to an outgoing response, use the `FastifyReply#setCookie()` method:

```typescript

@Get()
findAll(@Res({ passthrough: true }) response: FastifyReply) {
  response.setCookie('key', 'value')
}
```

To read more about `FastifyReply#setCookie()` method, check out this [page](https://github.com/fastify/fastify-cookie#sending).

> **Warning** If you want to leave the response handling logic to the framework, remember to set the `passthrough` option to `true`, as shown above. Read more [here](/controllers#appendix-library-specific-approach).

> **Hint** The `@Res()` decorator is imported from the `@nestjs/common`, while `FastifyReply` from the `fastify` package.

#### Creating a custom decorator (cross-platform)[#](/techniques/cookies#creating-a-custom-decorator-cross-platform)

To provide a convenient, declarative way of accessing incoming cookies, we can create a [custom decorator](/v8/custom-decorators).

```typescript

import { createParamDecorator, ExecutionContext } from '@nestjs/common';

export const Cookies = createParamDecorator(
  (data: string, ctx: ExecutionContext) => {
    const request = ctx.switchToHttp().getRequest();
    return data ? request.cookies?.[data] : request.cookies;
  },
);
```

The `@Cookies()` decorator will extract all cookies, or a named cookie from the `req.cookies` object and populate the decorated parameter with that value.

With this in place, we can now use the decorator in a route handler signature, as follows:

```typescript

@Get()
findAll(@Cookies('name') name: string) {}
```

----
url: https://docs.nestjs.com/openapi/mapped-types
----

[Skip to content](#content)

On this page

* [Mapped types](https://docs.nestjs.com/openapi/mapped-types#mapped-types)
* [Partial](https://docs.nestjs.com/openapi/mapped-types#partial)
* [Pick](https://docs.nestjs.com/openapi/mapped-types#pick)
* [Omit](https://docs.nestjs.com/openapi/mapped-types#omit)
* [Intersection](https://docs.nestjs.com/openapi/mapped-types#intersection)
* [Composition](https://docs.nestjs.com/openapi/mapped-types#composition)

### Mapped types

As you build out features like **CRUD** (Create/Read/Update/Delete), it's often useful to construct variants of a base entity type. Nest provides several utility functions that perform type transformations to make this task more convenient.

#### Partial[#](/openapi/mapped-types#partial)

When building input validation types (also called DTOs), it's often useful to build **create** and **update** variations on the same type. For example, the **create** variant may require all fields, while the **update** variant may make all fields optional.

Nest provides the `PartialType()` utility function to make this task easier and minimize boilerplate.

The `PartialType()` function returns a type (class) with all the properties of the input type set to optional. For example, suppose you have a **create** type as follows:

```typescript

import { ApiProperty } from '@nestjs/swagger';

export class CreateCatDto {
  @ApiProperty()
  name: string;

  @ApiProperty()
  age: number;

  @ApiProperty()
  breed: string;
}
```

By default, all of these fields are required. To create a type with the same fields, but with each one optional, use `PartialType()` and pass the class reference (`CreateCatDto`) as an argument:

```typescript

export class UpdateCatDto extends PartialType(CreateCatDto) {}
```

> **Hint** The `PartialType()` function is imported from the `@nestjs/swagger` package.

#### Pick[#](/openapi/mapped-types#pick)

The `PickType()` function constructs a new type (class) by picking a set of properties from an input type. For example, suppose you start with a type like:

```typescript

import { ApiProperty } from '@nestjs/swagger';

export class CreateCatDto {
  @ApiProperty()
  name: string;

  @ApiProperty()
  age: number;

  @ApiProperty()
  breed: string;
}
```

You can pick a set of properties from this class using the `PickType()` utility function:

```typescript

export class UpdateCatAgeDto extends PickType(CreateCatDto, ['age'] as const) {}
```

> **Hint** The `PickType()` function is imported from the `@nestjs/swagger` package.

#### Omit[#](/openapi/mapped-types#omit)

The `OmitType()` function constructs a type by picking all properties from an input type and then removing a particular set of keys. For example, suppose you start with a type like:

```typescript

import { ApiProperty } from '@nestjs/swagger';

export class CreateCatDto {
  @ApiProperty()
  name: string;

  @ApiProperty()
  age: number;

  @ApiProperty()
  breed: string;
}
```

You can generate a derived type that has every property **except**`name`, as shown below. In this construct, the second argument to `OmitType()` is an array of property names.

```typescript

export class UpdateCatDto extends OmitType(CreateCatDto, ['name'] as const) {}
```

> **Hint** The `OmitType()` function is imported from the `@nestjs/swagger` package.

#### Intersection[#](/openapi/mapped-types#intersection)

The `IntersectionType()` function combines two or more types into one new type (class). For example, suppose you start with two types like:

```typescript

import { ApiProperty } from '@nestjs/swagger';

export class CreateCatDto {
  @ApiProperty()
  name: string;

  @ApiProperty()
  breed: string;
}

export class AdditionalCatInfo {
  @ApiProperty()
  color: string;
}
```

You can generate a new type that combines all properties of both types:

```typescript

export class UpdateCatDto extends IntersectionType(
  CreateCatDto,
  AdditionalCatInfo,
) {}
```

> **Hint** The `IntersectionType()` function is imported from the `@nestjs/swagger` package.

#### Composition[#](/openapi/mapped-types#composition)

The type mapping utility functions are composable. For example, the following produces a type (class) that has all of the properties of the `CreateCatDto` type except for `name`, with those properties set to optional:

```typescript

export class UpdateCatDto extends PartialType(
  OmitType(CreateCatDto, ['name'] as const),
) {}
```

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/openapi/mapped-types.md)

----
url: https://docs.nestjs.com/v11/openapi/cli-plugin
----

* [CLI Plugin](https://docs.nestjs.com/v11/openapi/cli-plugin#cli-plugin)
* [Overview](https://docs.nestjs.com/v11/openapi/cli-plugin#overview)
* [Comments introspection](https://docs.nestjs.com/v11/openapi/cli-plugin#comments-introspection)
* [Using the CLI plugin](https://docs.nestjs.com/v11/openapi/cli-plugin#using-the-cli-plugin)
* [SWC builder](https://docs.nestjs.com/v11/openapi/cli-plugin#swc-builder)
* [Integration with ts-jest (e2e tests)](https://docs.nestjs.com/v11/openapi/cli-plugin#integration-with-ts-jest-e2e-tests)
* [Troubleshooting jest (e2e tests)](https://docs.nestjs.com/v11/openapi/cli-plugin#troubleshooting-jest-e2e-tests)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/openapi/cli-plugin.md "Suggest Edits")

### CLI Plugin

[TypeScript](https://www.typescriptlang.org/docs/handbook/decorators.html)'s metadata reflection system has several limitations which make it impossible to, for instance, determine what properties a class consists of or recognize whether a given property is optional or required. However, some of these constraints can be addressed at compilation time. Nest provides a plugin that enhances the TypeScript compilation process to reduce the amount of boilerplate code required.

> **Hint** This plugin is **opt-in**. If you prefer, you can declare all decorators manually, or only specific decorators where you need them.

```typescript

export class CreateUserDto {
  @ApiProperty()
  email: string;

  @ApiProperty()
  password: string;

  @ApiProperty({ enum: RoleEnum, default: [], isArray: true })
  roles: RoleEnum[] = [];

  @ApiProperty({ required: false, default: true })
  isEnabled?: boolean = true;
}
```

While not a significant issue with medium-sized projects, it becomes verbose & hard to maintain once you have a large set of classes.

By [enabling the Swagger plugin](/openapi/cli-plugin#using-the-cli-plugin), the above class definition can be declared simply:

```typescript

export class CreateUserDto {
  email: string;
  password: string;
  roles: RoleEnum[] = [];
  isEnabled?: boolean = true;
}
```

> **Note** The Swagger plugin will derive the @ApiProperty() annotations from the TypeScript types and class-validator decorators. This helps in clearly describing your API for the generated Swagger UI documentation. However, the validation at runtime would still be handled by class-validator decorators. So, it is required to continue using validators like `IsEmail()`, `IsNumber()`, etc.

Hence, if you intend to rely on automatic annotations for generating documentations and still wish for runtime validations, then the class-validator decorators are still necessary.

> **Hint** When using [mapped types utilities](https://docs.nestjs.com/openapi/mapped-types) (like `PartialType`) in DTOs import them from `@nestjs/swagger` instead of `@nestjs/mapped-types` for the plugin to pick up the schema.

The plugin adds appropriate decorators on the fly based on the **Abstract Syntax Tree**. Thus you won't have to struggle with `@ApiProperty` decorators scattered throughout the code.

> **Hint** The plugin will automatically generate any missing swagger properties, but if you need to override them, you simply set them explicitly via `@ApiProperty()`.

#### Comments introspection[#](/openapi/cli-plugin#comments-introspection)

With the comments introspection feature enabled, CLI plugin will generate descriptions and example values for properties based on comments.

For example, given an example `roles` property:

```typescript

/**
 * A list of user's roles
 * @example ['admin']
 */
@ApiProperty({
  description: `A list of user's roles`,
  example: ['admin'],
})
roles: RoleEnum[] = [];
```

You must duplicate both description and example values. With `introspectComments` enabled, the CLI plugin can extract these comments and automatically provide descriptions (and examples, if defined) for properties. Now, the above property can be declared simply as follows:

```typescript

/**
 * A list of user's roles
 * @example ['admin']
 */
roles: RoleEnum[] = [];
```

There are `dtoKeyOfComment` and `controllerKeyOfComment` plugin options available for customizing how the plugin assigns values to the `ApiProperty` and `ApiOperation` decorators, respectively. See the example below:

```typescript

export class SomeController {
  /**
   * Create some resource
   */
  @Post()
  create() {}
}
```

This is equivalent to the following instruction:

```typescript

@ApiOperation({ summary: "Create some resource" })
```

> **Hint** For models, the same logic applies but is used with the `ApiProperty` decorator instead.

For controllers, you can provide not only a summary but also a description (remarks), tags (such as` @deprecated`), and response examples, like this:

```ts

/**
 * Create a new cat
 *
 * @remarks This operation allows you to create a new cat.
 *
 * @deprecated
 * @throws {500} Something went wrong.
 * @throws {400} Bad Request.
 */
@Post()
async create(): Promise<Cat> {}
```

#### Using the CLI plugin[#](/openapi/cli-plugin#using-the-cli-plugin)

To enable the plugin, open `nest-cli.json` (if you use [Nest CLI](/v11/cli/overview)) and add the following `plugins` configuration:

```javascript

{
  "collection": "@nestjs/schematics",
  "sourceRoot": "src",
  "compilerOptions": {
    "plugins": ["@nestjs/swagger"]
  }
}
```

You can use the `options` property to customize the behavior of the plugin.

```javascript

{
  "collection": "@nestjs/schematics",
  "sourceRoot": "src",
  "compilerOptions": {
    "plugins": [
      {
        "name": "@nestjs/swagger",
        "options": {
          "classValidatorShim": false,
          "introspectComments": true,
          "skipAutoHttpCode": true
        }
      }
    ]
  }
}
```

The `options` property has to fulfill the following interface:

```typescript

export interface PluginOptions {
  dtoFileNameSuffix?: string[];
  controllerFileNameSuffix?: string[];
  classValidatorShim?: boolean;
  dtoKeyOfComment?: string;
  controllerKeyOfComment?: string;
  introspectComments?: boolean;
  skipAutoHttpCode?: boolean;
  esmCompatible?: boolean;
}
```

| Option                     | Default                     | Description                                                                                                                             |
| -------------------------- | --------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| `dtoFileNameSuffix`        | `['.dto.ts', '.entity.ts']` | DTO (Data Transfer Object) files suffix                                                                                                 |
| `controllerFileNameSuffix` | `.controller.ts`            | Controller files suffix                                                                                                                 |
| `classValidatorShim`       | `true`                      | If set to true, the module will reuse `class-validator` validation decorators (e.g. `@Max(10)` will add `max: 10` to schema definition) |
| `dtoKeyOfComment`          | `'description'`             | The property key to set the comment text to on `ApiProperty`.                                                                           |
| `controllerKeyOfComment`   | `'summary'`                 | The property key to set the comment text to on `ApiOperation`.                                                                          |
| `introspectComments`       | `false`                     | If set to true, plugin will generate descriptions and example values for properties based on comments                                   |
| `skipAutoHttpCode`         | `false`                     | Disables the automatic addition of `@HttpCode()` in controllers                                                                         |
| `esmCompatible`            | `false`                     | If set to true, resolves syntax errors encountered when using ESM (`{ "type": "module" }`).                                             |

Make sure to delete the `/dist` folder and rebuild your application whenever plugin options are updated. If you don't use the CLI but instead have a custom `webpack` configuration, you can use this plugin in combination with `ts-loader`:

```javascript

getCustomTransformers: (program: any) => ({
  before: [require('@nestjs/swagger/plugin').before({}, program)]
}),
```

#### SWC builder[#](/openapi/cli-plugin#swc-builder)

For standard setups (non-monorepo), to use CLI Plugins with the SWC builder, you need to enable type checking, as described [here](/recipes/swc#type-checking).

```bash

$ nest start -b swc --type-check
```

For monorepo setups, follow the instructions [here](/recipes/swc#monorepo-and-cli-plugins).

```bash

$ npx ts-node src/generate-metadata.ts
# OR npx ts-node apps/{YOUR_APP}/src/generate-metadata.ts
```

Now, the serialized metadata file must be loaded by the `SwaggerModule#loadPluginMetadata` method, as shown below:

```typescript

import metadata from './metadata'; // <-- file auto-generated by the "PluginMetadataGenerator"

await SwaggerModule.loadPluginMetadata(metadata); // <-- here
const document = SwaggerModule.createDocument(app, config);
```

#### Integration with `ts-jest` (e2e tests)[#](/openapi/cli-plugin#integration-with-ts-jest-e2e-tests)

To run e2e tests, `ts-jest` compiles your source code files on the fly, in memory. This means, it doesn't use Nest CLI compiler and does not apply any plugins or perform AST transformations.

To enable the plugin, create the following file in your e2e tests directory:

```javascript

const transformer = require('@nestjs/swagger/plugin');

module.exports.name = 'nestjs-swagger-transformer';
// you should change the version number anytime you change the configuration below - otherwise, jest will not detect changes
module.exports.version = 1;

module.exports.factory = (cs) => {
  return transformer.before(
    {
      // @nestjs/swagger/plugin options (can be empty)
    },
    cs.program, // "cs.tsCompiler.program" for older versions of Jest (<= v27)
  );
};
```

With this in place, import AST transformer within your `jest` configuration file. By default (in the starter application), e2e tests configuration file is located under the `test` folder and is named `jest-e2e.json`.

If you use `jest@<29`, then use the snippet below.

```json

{
  ... // other configuration
  "globals": {
    "ts-jest": {
      "astTransformers": {
        "before": ["<path to the file created above>"]
      }
    }
  }
}
```

If you use `jest@^29`, then use the snippet below, as the previous approach got deprecated.

```json

{
  ... // other configuration
  "transform": {
    "^.+\\.(t|j)s$": [
      "ts-jest",
      {
        "astTransformers": {
          "before": ["<path to the file created above>"]
        }
      }
    ]
  }
}
```

#### Troubleshooting `jest` (e2e tests)[#](/openapi/cli-plugin#troubleshooting-jest-e2e-tests)

In case `jest` does not seem to pick up your configuration changes, it's possible that Jest has already **cached** the build result. To apply the new configuration, you need to clear Jest's cache directory.

To clear the cache directory, run the following command in your NestJS project folder:

```bash

$ npx jest --clearCache
```

In case the automatic cache clearance fails, you can still manually remove the cache folder with the following commands:

```bash

# Find jest cache directory (usually /tmp/jest_rs)
# by running the following command in your NestJS project root
$ npx jest --showConfig | grep cache
# ex result:
#   "cache": true,
#   "cacheDirectory": "/tmp/jest_rs"

# Remove or empty the Jest cache directory
$ rm -rf  <cacheDirectory value>
# ex:
# rm -rf /tmp/jest_rs
```

----
url: https://docs.nestjs.com/v6/techniques/database
----

* [Database](https://docs.nestjs.com/v6/techniques/database#database)
* [TypeORM Integration](https://docs.nestjs.com/v6/techniques/database#typeorm-integration)
* [Repository pattern](https://docs.nestjs.com/v6/techniques/database#repository-pattern)
* [Relations](https://docs.nestjs.com/v6/techniques/database#relations)
* [Auto-load entities](https://docs.nestjs.com/v6/techniques/database#auto-load-entities)
* [Transactions](https://docs.nestjs.com/v6/techniques/database#transactions)
* [Subscribers](https://docs.nestjs.com/v6/techniques/database#subscribers)
* [Migrations](https://docs.nestjs.com/v6/techniques/database#migrations)
* [Multiple databases](https://docs.nestjs.com/v6/techniques/database#multiple-databases)
* [Testing](https://docs.nestjs.com/v6/techniques/database#testing)
* [Custom repository](https://docs.nestjs.com/v6/techniques/database#custom-repository)
* [Async configuration](https://docs.nestjs.com/v6/techniques/database#async-configuration)
* [Example](https://docs.nestjs.com/v6/techniques/database#example)
* [Sequelize Integration](https://docs.nestjs.com/v6/techniques/database#sequelize-integration)
* [Models](https://docs.nestjs.com/v6/techniques/database#models)
* [Relations](https://docs.nestjs.com/v6/techniques/database#relations-1)
* [Auto-load models](https://docs.nestjs.com/v6/techniques/database#auto-load-models)
* [Transactions](https://docs.nestjs.com/v6/techniques/database#transactions-1)
* [Migrations](https://docs.nestjs.com/v6/techniques/database#migrations-1)
* [Multiple databases](https://docs.nestjs.com/v6/techniques/database#multiple-databases-1)
* [Testing](https://docs.nestjs.com/v6/techniques/database#testing-1)
* [Async configuration](https://docs.nestjs.com/v6/techniques/database#async-configuration-1)
* [Example](https://docs.nestjs.com/v6/techniques/database#example-1)

[](https://srv.carbonads.net/ads/click/x/GTND4277CVSIC2JEFTBLYKQUF67D62Q7CTSI4Z3JCAAI623WC6YDVK3KCYYIVK3UCY7IL2JUF67IK5QMF6BILZ3JCAAI627ECVADTK3K2JWNABY)[Run Kubernetes, Proxmox or databases on AMD EPYC 4005 servers, ready in minutes. Configure yours today. ](https://srv.carbonads.net/ads/click/x/GTND4277CVSIC2JEFTBLYKQUF67D62Q7CTSI4Z3JCAAI623WC6YDVK3KCYYIVK3UCY7IL2JUF67IK5QMF6BILZ3JCAAI627ECVADTK3K2JWNABY)[ads via Carbon](http://carbonads.net/?utm_source=nestjscom\&utm_medium=ad_via_link\&utm_campaign=in_unit\&utm_term=carbon)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/techniques/sql.md "Suggest Edits")

### Database

Nest is database agnostic, allowing you to easily integrate with any SQL or NoSQL database. You have a number of options available to you, depending on your preferences. At the most general level, connecting Nest to a database is simply a matter of loading an appropriate Node.js driver for the database, just as you would with [Express](https://expressjs.com/en/guide/database-integration.html) or Fastify.

You can also directly use any general purpose Node.js database integration **library** or ORM, such as [Sequelize](https://sequelize.org/) (navigate to the [Sequelize integration](/techniques/database#sequelize-integration) section), [Knex.js](http://knexjs.org/) ([tutorial](https://dev.to/nestjs/build-a-nestjs-module-for-knex-js-or-other-resource-based-libraries-in-5-minutes-12an)) and [TypeORM](https://github.com/typeorm/typeorm), to operate at a higher level of abstraction.

For convenience, Nest provides tight integration with TypeORM and Sequelize out-of-the-box with the `@nestjs/typeorm` and `@nestjs/sequelize` packages respectively, which we'll cover in the current chapter, and Mongoose with `@nestjs/mongoose`, which is covered in [this chapter](/v6/techniques/mongodb). These integrations provide additional NestJS-specific features, such as model/repository injection, testability, and asynchronous configuration to make accessing your chosen database even easier.

### TypeORM Integration

For integrating with SQL and NoSQL databases, Nest provides the `@nestjs/typeorm` package. Nest uses [TypeORM](https://github.com/typeorm/typeorm) because it's the most mature Object Relational Mapper (ORM) available for TypeScript. Since it's written in TypeScript, it integrates well with the Nest framework.

To begin using it, we first install the required dependencies. In this chapter, we'll demonstrate using the popular [MySQL](https://www.mysql.com/) Relational DBMS, but TypeORM provides support for many relational databases, such as PostgreSQL, Oracle, Microsoft SQL Server, SQLite, and even NoSQL databases like MongoDB. The procedure we walk through in this chapter will be the same for any database supported by TypeORM. You'll simply need to install the associated client API libraries for your selected database.

```bash

$ npm install --save @nestjs/typeorm typeorm mysql
```

Once the installation process is complete, we can import the `TypeOrmModule` into the root `AppModule`.

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';

@Module({
  imports: [
    TypeOrmModule.forRoot({
      type: 'mysql',
      host: 'localhost',
      port: 3306,
      username: 'root',
      password: 'root',
      database: 'test',
      entities: [],
      synchronize: true,
    }),
  ],
})
export class AppModule {}
```

The `forRoot()` method supports all the configuration properties exposed by the `createConnection()` function from the [TypeORM](https://typeorm.io/#/connection-options) package. In addition, there are several extra configuration properties described below.

|                       |                                                                                     |
| --------------------- | ----------------------------------------------------------------------------------- |
| `retryAttempts`       | Number of attempts to connect to the database (default: `10`)                       |
| `retryDelay`          | Delay between connection retry attempts (ms) (default: `3000`)                      |
| `autoLoadEntities`    | If `true`, entities will be loaded automatically (default: `false`)                 |
| `keepConnectionAlive` | If `true`, connection will not be closed on application shutdown (default: `false`) |

> **Hint** Learn more about the connection options [here](https://typeorm.io/#/connection-options).

Alternatively, rather than passing a configuration object to `forRoot()`, we can create an `ormconfig.json` file in the project root directory.

```json

{
  "type": "mysql",
  "host": "localhost",
  "port": 3306,
  "username": "root",
  "password": "root",
  "database": "test",
  "entities": ["dist/**/*.entity{.ts,.js}"],
  "synchronize": true
}
```

Then, we can call `forRoot()` without any options:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';

@Module({
  imports: [TypeOrmModule.forRoot()],
})
export class AppModule {}
```

> **Warning** Static glob paths (e.g., `dist/**/*.entity{ .ts,.js}`) won't work properly with [webpack](https://webpack.js.org/).

> **Warning** Note that the `ormconfig.json` file is loaded by the `typeorm` library. Thus, any of the extra properties described above (which are supported internally by way of the `forRoot()` method - for example, `autoLoadEntities` and `retryDelay`) won't be applied.

Once this is done, the TypeORM `Connection` and `EntityManager` objects will be available to inject across the entire project (without needing to import any modules), for example:

app.module.ts

JS TS

```typescript

import { Connection } from 'typeorm';

@Module({
  imports: [TypeOrmModule.forRoot(), UsersModule],
})
export class AppModule {
  constructor(private readonly connection: Connection) {}
}
```

```typescript

import { Connection } from 'typeorm';

@Dependencies(Connection)
@Module({
  imports: [TypeOrmModule.forRoot(), UsersModule],
})
export class AppModule {
  constructor(connection) {
    this.connection = connection;
  }
}
```

#### Repository pattern[#](/techniques/database#repository-pattern)

[TypeORM](https://github.com/typeorm/typeorm) supports the **repository design pattern**, so each entity has its own repository. These repositories can be obtained from the database connection.

To continue the example, we need at least one entity. Let's define the `User` entity.

user.entity.ts

JS TS

```typescript

import { Entity, Column, PrimaryGeneratedColumn } from 'typeorm';

@Entity()
export class User {
  @PrimaryGeneratedColumn()
  id: number;

  @Column()
  firstName: string;

  @Column()
  lastName: string;

  @Column({ default: true })
  isActive: boolean;
}
```

> **Hint** Learn more about entities in the [TypeORM documentation](https://typeorm.io/#/entities).

The `User` entity file sits in the `users` directory. This directory contains all files related to the `UsersModule`. You can decide where to keep your model files, however, we recommend creating them near their **domain**, in the corresponding module directory.

To begin using the `User` entity, we need to let TypeORM know about it by inserting it into the `entities` array in the module `forRoot()` method options (unless you use a static glob path):

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { User } from './users/user.entity';

@Module({
  imports: [
    TypeOrmModule.forRoot({
      type: 'mysql',
      host: 'localhost',
      port: 3306,
      username: 'root',
      password: 'root',
      database: 'test',
      entities: [User],
      synchronize: true,
    }),
  ],
})
export class AppModule {}
```

Next, let's look at the `UsersModule`:

users.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { UsersService } from './users.service';
import { UsersController } from './users.controller';
import { User } from './user.entity';

@Module({
  imports: [TypeOrmModule.forFeature([User])],
  providers: [UsersService],
  controllers: [UsersController],
})
export class UsersModule {}
```

This module uses the `forFeature()` method to define which repositories are registered in the current scope. With that in place, we can inject the `UsersRepository` into the `UsersService` using the `@InjectRepository()` decorator:

users.service.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { User } from './user.entity';

@Injectable()
export class UsersService {
  constructor(
    @InjectRepository(User)
    private readonly usersRepository: Repository<User>,
  ) {}

  findAll(): Promise<User[]> {
    return this.usersRepository.find();
  }

  findOne(id: string): Promise<User> {
    return this.usersRepository.findOne(id);
  }

  async remove(id: string): Promise<void> {
    await this.usersRepository.delete(id);
  }
}
```

```typescript

import { Injectable, Dependencies } from '@nestjs/common';
import { getRepositoryToken } from '@nestjs/typeorm';
import { User } from './user.entity';

@Injectable()
@Dependencies(getRepositoryToken(User))
export class UserService {
  constructor(usersRepository) {
    this.usersRepository = usersRepository;
  }

  findAll() {
    return this.usersRepository.find();
  }

  findOne(id) {
    return this.usersRepository.findOne(id);
  }

  async remove(id) {
    await this.usersRepository.delete(id);
  }
}
```

> **Notice** Don't forget to import the `UsersModule` into the root `AppModule`.

If you want to use the repository outside of the module which imports `TypeOrmModule.forFeature`, you'll need to re-export the providers generated by it. You can do this by exporting the whole module, like this:

users.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { User } from './user.entity';

@Module({
  imports: [TypeOrmModule.forFeature([User])],
  exports: [TypeOrmModule]
})
export class UsersModule {}
```

Now if we import `UsersModule` in `UserHttpModule`, we can use `@InjectRepository(User)` in the providers of the latter module.

users-http.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { UsersModule } from './user.module';
import { UserService } from './user.service';
import { UserController } from './user.controller';

@Module({
  imports: [UsersModule],
  providers: [UserService],
  controllers: [UserController]
})
export class UserHttpModule {}
```

### Relations

Relations are associations established between two or more tables. Relations are based on common fields from each table, often involving primary and foreign keys.

There are three types of relations:

|                             |                                                                                                                                                                                                                                 |
| --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `One-to-one`                | Every row in the primary table has one and only one associated row in the foreign table. Use the `@OneToOne()` decorator to define this type of relation.                                                                       |
| `One-to-many / Many-to-one` | Every row in the primary table has one or more related rows in the foreign table. Use the `@OneToMany()` and `@ManyToOne()` decorators to define this type of relation.                                                         |
| `Many-to-many`              | Every row in the primary table has many related rows in the foreign table, and every record in the foreign table has many related rows in the primary table. Use the `@ManyToMany()` decorator to define this type of relation. |

To define relations in entities, use the corresponding **decorators**. For example, to define that each `User` can have multiple photos, use the `@OneToMany()` decorator.

user.entity.ts

JS TS

```typescript

import { Entity, Column, PrimaryGeneratedColumn, OneToMany } from 'typeorm';
import { Photo } from '../photos/photo.entity';

@Entity()
export class User {
  @PrimaryGeneratedColumn()
  id: number;

  @Column()
  firstName: string;

  @Column()
  lastName: string;

  @Column({ default: true })
  isActive: boolean;

  @OneToMany(type => Photo, photo => photo.user)
  photos: Photo[];
}
```

> **Hint** To learn more about relations in TypeORM, visit the [TypeORM documentation](https://typeorm.io/#/relations).

#### Auto-load entities[#](/techniques/database#auto-load-entities)

Manually adding entities to the `entities` array of the connection options can be tedious. In addition, referencing entities from the root module breaks application domain boundaries and causes leaking implementation details to other parts of the application. To solve this issue, static glob paths can be used (e.g., `dist/**/*.entity{ .ts,.js}`).

Note, however, that glob paths are not supported by webpack, so if you are building your application within a monorepo, you won't be able to use them. To address this issue, an alternative solution is provided. To automatically load entities, set the `autoLoadEntities` property of the configuration object (passed into the `forRoot()` method) to `true`, as shown below:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';

@Module({
  imports: [
    TypeOrmModule.forRoot({
      ...
      autoLoadEntities: true,
    }),
  ],
})
export class AppModule {}
```

With that option specified, every entity registered through the `forFeature()` method will be automatically added to the `entities` array of the configuration object.

> **Warning** Note that entities that aren't registered through the `forFeature()` method, but are only referenced from the entity (via a relationship), won't be included by way of the `autoLoadEntities` setting.

#### Transactions[#](/techniques/database#transactions)

A database transaction symbolizes a unit of work performed within a database management system against a database, and treated in a coherent and reliable way independent of other transactions. A transaction generally represents any change in a database ([learn more](https://en.wikipedia.org/wiki/Database_transaction)).

There are many different strategies to handle [TypeORM transactions](https://typeorm.io/#/transactions). We recommend using the `QueryRunner` class because it gives full control over the transaction.

First, we need to inject the `Connection` object into a class in the normal way:

```typescript

@Injectable()
export class UsersService {
  constructor(private readonly connection: Connection) {}
}
```

> **Hint** The `Connection` class is imported from the `typeorm` package.

Now, we can use this object to create a transaction.

```typescript

async createMany(users: User[]) {
  const queryRunner = this.connection.createQueryRunner();

  await queryRunner.connect();
  await queryRunner.startTransaction();
  try {
    await queryRunner.manager.save(users[0]);
    await queryRunner.manager.save(users[1]);

    await queryRunner.commitTransaction();
  } catch (err) {
    // since we have errors lets rollback the changes we made
    await queryRunner.rollbackTransaction();
  } finally {
    // you need to release a queryRunner which was manually instantiated
    await queryRunner.release();
  }
}
```

> **Hint** Note that the `connection` is used only to create the `QueryRunner`. However, to test this class would require mocking the entire `Connection` object (which exposes several methods). Thus, we recommend using a helper factory class (e.g., `QueryRunnerFactory`) and defining an interface with a limited set of methods required to maintain transactions. This technique makes mocking these methods pretty straightforward.

Alternatively, you can use the callback-style approach with the `transaction` method of the `Connection` object ([read more](https://typeorm.io/#/transactions/creating-and-using-transactions)).

```typescript

async createMany(users: User[]) {
  await this.connection.transaction(async manager => {
    await manager.save(users[0]);
    await manager.save(users[1]);
  });
}
```

Using decorators to control the transaction (`@Transaction()` and `@TransactionManager()`) is not recommended.

## Hoodies, T-shirts, and accessories!

Support our future development by shopping in the official store!

[See more](https://nestjs.threadless.com/ "Shop | NestJS - A node.js framework built on top of TypeScript")

#### Subscribers[#](/techniques/database#subscribers)

With TypeORM [subscribers](https://typeorm.io/#/listeners-and-subscribers/what-is-a-subscriber), you can listen to specific entity events.

```typescript

import {
  Connection,
  EntitySubscriberInterface,
  EventSubscriber,
  InsertEvent,
} from 'typeorm';
import { User } from './user.entity';

@EventSubscriber()
export class UserSubscriber implements EntitySubscriberInterface<User> {
  constructor(connection: Connection) {
    connection.subscribers.push(this);
  }

  listenTo() {
    return User;
  }

  beforeInsert(event: InsertEvent<User>) {
    console.log(`BEFORE USER INSERTED: `, event.entity);
  }
}
```

> **Warning** Event subscribers can not be [request-scoped](/v6/fundamentals/injection-scopes).

Now, add the `UserSubscriber` class to the `providers` array:

```typescript

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { User } from './user.entity';
import { UsersController } from './users.controller';
import { UsersService } from './users.service';
import { UserSubscriber } from './user.subscriber';

@Module({
  imports: [TypeOrmModule.forFeature([User])],
  providers: [UsersService, UserSubscriber],
  controllers: [UsersController],
})
export class UsersModule {}
```

> **Hint** Learn more about entity subscribers [here](https://typeorm.io/#/listeners-and-subscribers/what-is-a-subscriber).

#### Migrations[#](/techniques/database#migrations)

[Migrations](https://typeorm.io/#/migrations) provide a way to incrementally update the database schema to keep it in sync with the application's data model while preserving existing data in the database. To generate, run, and revert migrations, TypeORM provides a dedicated [CLI](https://typeorm.io/#/migrations/creating-a-new-migration).

Migration classes are separate from the Nest application source code. Their lifecycle is maintained by the TypeORM CLI. Therefore, you are not able to leverage dependency injection and other Nest specific features with migrations. To learn more about migrations, follow the guide in the [TypeORM documentation](https://typeorm.io/#/migrations/creating-a-new-migration).

#### Multiple databases[#](/techniques/database#multiple-databases)

Some projects require multiple database connections. This can also be achieved with this module. To work with multiple connections, first create the connections. In this case, connection naming becomes **mandatory**.

Suppose you have an `Album` entity stored in its own database.

```typescript

const defaultOptions = {
  type: 'postgres',
  port: 5432,
  username: 'user',
  password: 'password',
  database: 'db',
  synchronize: true,
};

@Module({
  imports: [
    TypeOrmModule.forRoot({
      ...defaultOptions,
      host: 'user_db_host',
      entities: [User],
    }),
    TypeOrmModule.forRoot({
      ...defaultOptions,
      name: 'albumsConnection',
      host: 'album_db_host',
      entities: [Album],
    }),
  ],
})
export class AppModule {}
```

> **Notice** If you don't set the `name` for a connection, its name is set to `default`. Please note that you shouldn't have multiple connections without a name, or with the same name, otherwise they will get overridden.

At this point, you have `User` and `Album` entities registered with their own connection. With this setup, you have to tell the `TypeOrmModule.forFeature()` method and the `@InjectRepository()` decorator which connection should be used. If you do not pass any connection name, the `default` connection is used.

```typescript

@Module({
  imports: [
    TypeOrmModule.forFeature([User]),
    TypeOrmModule.forFeature([Album], 'albumsConnection'),
  ],
})
export class AppModule {}
```

You can also inject the `Connection` or `EntityManager` for a given connection:

```typescript

@Injectable()
export class AlbumsService {
  constructor(
    @InjectConnection('albumsConnection')
    private readonly connection: Connection,
    @InjectEntityManager('albumsConnection')
    private readonly entityManager: EntityManager,
  ) {}
}
```

#### Testing[#](/techniques/database#testing)

When it comes to unit testing an application, we usually want to avoid making a database connection, keeping our test suites independent and their execution process as fast as possible. But our classes might depend on repositories that are pulled from the connection instance. How do we handle that? The solution is to create mock repositories. In order to achieve that, we set up [custom providers](/v6/fundamentals/custom-providers). Each registered repository is automatically represented by an `<EntityName>Repository` token, where `EntityName` is the name of your entity class.

The `@nestjs/typeorm` package exposes the `getRepositoryToken()` function which returns a prepared token based on a given entity.

```typescript

@Module({
  providers: [
    UserService,
    {
      provide: getRepositoryToken(User),
      useValue: mockRepository,
    },
  ],
})
export class UsersModule {}
```

Now a substitute `mockRepository` will be used as the `UserRepository`. Whenever any class asks for `UserRepository` using an `@InjectRepository()` decorator, Nest will use the registered `mockRepository` object.

#### Custom repository[#](/techniques/database#custom-repository)

TypeORM provides a feature called **custom repositories**. Custom repositories allow you to extend a base repository class, and enrich it with several special methods. To learn more about this feature, visit [this page](http://typeorm.io/#/custom-repository).

In order to create your custom repository, use the `@EntityRepository()` decorator and extend the `Repository` class.

```typescript

@EntityRepository(Author)
export class AuthorRepository extends Repository<Author> {}
```

> **Hint** Both `@EntityRepository()` and `Repository` are imported from the `typeorm` package.

Once the class is created, the next step is to delegate instantiation responsibility to Nest. For this, we have to pass the`AuthorRepository` class to the `TypeOrm.forFeature()` method.

```typescript

@Module({
  imports: [TypeOrmModule.forFeature([AuthorRepository])],
  controller: [AuthorController],
  providers: [AuthorService],
})
export class AuthorModule {}
```

Afterward, simply inject the repository using the following construction:

```typescript

@Injectable()
export class AuthorService {
  constructor(private readonly authorRepository: AuthorRepository) {}
}
```

#### Async configuration[#](/techniques/database#async-configuration)

You may want to pass your repository module options asynchronously instead of statically. In this case, use the `forRootAsync()` method, which provides several ways to deal with async configuration.

One approach is to use a factory function:

```typescript

TypeOrmModule.forRootAsync({
  useFactory: () => ({
    type: 'mysql',
    host: 'localhost',
    port: 3306,
    username: 'root',
    password: 'root',
    database: 'test',
    entities: [__dirname + '/**/*.entity{.ts,.js}'],
    synchronize: true,
  }),
});
```

Our factory behaves like any other [asynchronous provider](https://docs.nestjs.com/fundamentals/async-providers) (e.g., it can be `async` and it's able to inject dependencies through `inject`).

```typescript

TypeOrmModule.forRootAsync({
  imports: [ConfigModule],
  useFactory: (configService: ConfigService) => ({
    type: 'mysql',
    host: configService.get<string>('HOST'),
    port: configService.get<string>('PORT'),
    username: configService.get<string>('USERNAME'),
    password: configService.get<string>('PASSWORD'),
    database: configService.get<string>('DATABASE'),
    entities: [__dirname + '/**/*.entity{.ts,.js}'],
    synchronize: true,
  }),
  inject: [ConfigService],
});
```

Alternatively, you can use the `useClass` syntax:

```typescript

TypeOrmModule.forRootAsync({
  useClass: TypeOrmConfigService,
});
```

The construction above will instantiate `TypeOrmConfigService` inside `TypeOrmModule` and use it to provide an options object by calling `createTypeOrmOptions()`. Note that this means that the `TypeOrmConfigService` has to implement the `TypeOrmOptionsFactory` interface, as shown below:

```typescript

@Injectable()
class TypeOrmConfigService implements TypeOrmOptionsFactory {
  createTypeOrmOptions(): TypeOrmModuleOptions {
    return {
      type: 'mysql',
      host: 'localhost',
      port: 3306,
      username: 'root',
      password: 'root',
      database: 'test',
      entities: [__dirname + '/**/*.entity{.ts,.js}'],
      synchronize: true,
    };
  }
}
```

In order to prevent the creation of `TypeOrmConfigService` inside `TypeOrmModule` and use a provider imported from a different module, you can use the `useExisting` syntax.

```typescript

TypeOrmModule.forRootAsync({
  imports: [ConfigModule],
  useExisting: ConfigService,
});
```

This construction works the same as `useClass` with one critical difference - `TypeOrmModule` will lookup imported modules to reuse an existing `ConfigService` instead of instantiating a new one.

```bash

$ npm install --save @nestjs/sequelize sequelize sequelize-typescript mysql2
$ npm install --save-dev @types/sequelize
```

Once the installation process is complete, we can import the `SequelizeModule` into the root `AppModule`.

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { SequelizeModule } from '@nestjs/sequelize';

@Module({
  imports: [
    SequelizeModule.forRoot({
      dialect: 'mysql',
      host: 'localhost',
      port: 3306,
      username: 'root',
      password: 'root',
      database: 'test',
      models: [],
    }),
  ],
})
export class AppModule {}
```

The `forRoot()` method supports all the configuration properties exposed by the Sequelize constuctor ([read more](https://sequelize.org/v5/manual/getting-started.html#setting-up-a-connection)). In addition, there are several extra configuration properties described below.

|                       |                                                                                         |
| --------------------- | --------------------------------------------------------------------------------------- |
| `retryAttempts`       | Number of attempts to connect to the database (default: `10`)                           |
| `retryDelay`          | Delay between connection retry attempts (ms) (default: `3000`)                          |
| `autoLoadModels`      | If `true`, models will be loaded automatically (default: `false`)                       |
| `keepConnectionAlive` | If `true`, connection will not be closed on the application shutdown (default: `false`) |
| `synchronize`         | If `true`, automatically loaded models will be synchronized (default: `false`)          |

Once this is done, the `Sequelize` object will be available to inject across the entire project (without needing to import any modules), for example:

app.module.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { Sequelize } from 'sequelize-typescript';

@Injectable()
export class AppService {
  constructor(private readonly sequelize: Sequelize) {}
}
```

```typescript

import { Injectable } from '@nestjs/common';
import { Sequelize } from 'sequelize-typescript';

@Dependencies(Sequelize)
@Injectable()
export class AppService {
  constructor(sequelize) {
    this.sequelize = sequelize;
  }
}
```

#### Models[#](/techniques/database#models)

Sequelize implements the Active Record pattern. With this pattern, you use model classes directly to interact with the database. To continue the example, we need at least one model. Let's define the `User` model.

user.model.ts

JS TS

```typescript

import { Column, Model, Table } from 'sequelize-typescript';

@Table
export class User extends Model<User> {
  @Column
  firstName: string;

  @Column
  lastName: string;

  @Column({ defaultValue: true })
  isActive: boolean;
}
```

> **Hint** Learn more about the available decorators [here](https://github.com/RobinBuschmann/sequelize-typescript#column).

The `User` model file sits in the `users` directory. This directory contains all files related to the `UsersModule`. You can decide where to keep your model files, however, we recommend creating them near their **domain**, in the corresponding module directory.

To begin using the `User` model, we need to let Sequelize know about it by inserting it into the `models` array in the module `forRoot()` method options:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { SequelizeModule } from '@nestjs/sequelize';
import { User } from './users/user.model';

@Module({
  imports: [
    SequelizeModule.forRoot({
      dialect: 'mysql',
      host: 'localhost',
      port: 3306,
      username: 'root',
      password: 'root',
      database: 'test',
      models: [User],
    }),
  ],
})
export class AppModule {}
```

Next, let's look at the `UsersModule`:

users.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { SequelizeModule } from '@nestjs/sequelize';
import { User } from './user.model';
import { UsersController } from './users.controller';
import { UsersService } from './users.service';

@Module({
  imports: [SequelizeModule.forFeature([User])],
  providers: [UsersService],
  controllers: [UsersController],
})
export class UsersModule {}
```

This module uses the `forFeature()` method to define which models are registered in the current scope. With that in place, we can inject the `UserModel` into the `UsersService` using the `@InjectModel()` decorator:

users.service.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { InjectModel } from '@nestjs/sequelize';
import { User } from './user.model';

@Injectable()
export class UsersService {
  constructor(
    @InjectModel(User)
    private readonly userModel: typeof User,
  ) {}

  async findAll(): Promise<User[]> {
    return this.userModel.findAll();
  }

  findOne(id: string): Promise<User> {
    return this.userModel.findOne({
      where: {
        id,
      },
    });
  }

  async remove(id: string): Promise<void> {
    const user = await this.findOne(id);
    await user.destroy();
  }
}
```

```typescript

import { Injectable, Dependencies } from '@nestjs/common';
import { getModelToken } from '@nestjs/sequelize';
import { User } from './user.model';

@Injectable()
@Dependencies(getModelToken(User))
export class UserService {
  constructor(usersRepository) {
    this.usersRepository = usersRepository;
  }

  async findAll() {
    return this.userModel.findAll();
  }

  findOne(id) {
    return this.userModel.findOne({
      where: {
        id,
      },
    });
  }

  async remove(id) {
    const user = await this.findOne(id);
    await user.destroy();
  }
}
```

> **Notice** Don't forget to import the `UsersModule` into the root `AppModule`.

If you want to use the repository outside of the module which imports `SequelizeModule.forFeature`, you'll need to re-export the providers generated by it. You can do this by exporting the whole module, like this:

users.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { SequelizeModule } from '@nestjs/sequelize';
import { User } from './user.entity';

@Module({
  imports: [SequelizeModule.forFeature([User])],
  exports: [SequelizeModule]
})
export class UsersModule {}
```

Now if we import `UsersModule` in `UserHttpModule`, we can use `@InjectModel(User)` in the providers of the latter module.

users-http.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { UsersModule } from './user.module';
import { UserService } from './user.service';
import { UserController } from './user.controller';

@Module({
  imports: [UsersModule],
  providers: [UserService],
  controllers: [UserController]
})
export class UserHttpModule {}
```

### Relations

Relations are associations established between two or more tables. Relations are based on common fields from each table, often involving primary and foreign keys.

There are three types of relations:

|                             |                                                                                                                                                             |
| --------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `One-to-one`                | Every row in the primary table has one and only one associated row in the foreign table                                                                     |
| `One-to-many / Many-to-one` | Every row in the primary table has one or more related rows in the foreign table                                                                            |
| `Many-to-many`              | Every row in the primary table has many related rows in the foreign table, and every record in the foreign table has many related rows in the primary table |

To define relations in entities, use the corresponding **decorators**. For example, to define that each `User` can have multiple photos, use the `@HasMany()` decorator.

user.entity.ts

JS TS

```typescript

import { Column, Model, Table, HasMany } from 'sequelize-typescript';
import { Photo } from '../photos/photo.model';

@Table
export class User extends Model<User> {
  @Column
  firstName: string;

  @Column
  lastName: string;

  @Column({ defaultValue: true })
  isActive: boolean;

  @HasMany(() => Photo)
  photos: Photo[];
}
```

> **Hint** To learn more about associations in Sequelize, read [this](https://github.com/RobinBuschmann/sequelize-typescript#model-association) chapter.

#### Auto-load models[#](/techniques/database#auto-load-models)

Manually adding models to the `models` array of the connection options can be tedious. In addition, referencing models from the root module breaks application domain boundaries and causes leaking implementation details to other parts of the application. To solve this issue, automatically load models by setting both `autoLoadModels` and `synchronize` properties of the configuration object (passed into the `forRoot()` method) to `true`, as shown below:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { SequelizeModule } from '@nestjs/sequelize';

@Module({
  imports: [
    SequelizeModule.forRoot({
      ...
      autoLoadModels: true,
      synchronize: true,
    }),
  ],
})
export class AppModule {}
```

With that option specified, every model registered through the `forFeature()` method will be automatically added to the `models` array of the configuration object.

> **Warning** Note that models that aren't registered through the `forFeature()` method, but are only referenced from the model (via an association), won't be included.

#### Transactions[#](/techniques/database#transactions-1)

A database transaction symbolizes a unit of work performed within a database management system against a database, and treated in a coherent and reliable way independent of other transactions. A transaction generally represents any change in a database ([learn more](https://en.wikipedia.org/wiki/Database_transaction)).

There are many different strategies to handle [Sequelize transactions](https://sequelize.org/v5/manual/transactions.html). Below is a sample implementation of a managed transaction (auto-callback).

First, we need to inject the `Sequelize` object into a class in the normal way:

```typescript

@Injectable()
export class UsersService {
  constructor(private readonly sequelize: Sequelize) {}
}
```

> **Hint** The `Sequelize` class is imported from the `sequelize-typescript` package.

Now, we can use this object to create a transaction.

```typescript

async createMany() {
  try {
    await this.sequelize.transaction(async t => {
      const transactionHost = { transaction: t };

      await this.userModel.create(
          { firstName: 'Abraham', lastName: 'Lincoln' },
          transactionHost,
      );
      await this.userModel.create(
          { firstName: 'John', lastName: 'Boothe' },
          transactionHost,
      );
    });
  } catch (err) {
    // Transaction has been rolled back
    // err is whatever rejected the promise chain returned to the transaction callback
  }
}
```

> **Hint** Note that the `Sequelize` instance is used only to start the transaction. However, to test this class would require mocking the entire `Sequelize` object (which exposes several methods). Thus, we recommend using a helper factory class (e.g., `TransactionRunner`) and defining an interface with a limited set of methods required to maintain transactions. This technique makes mocking these methods pretty straightforward.

#### Migrations[#](/techniques/database#migrations-1)

[Migrations](https://sequelize.org/v5/manual/migrations.html) provide a way to incrementally update the database schema to keep it in sync with the application's data model while preserving existing data in the database. To generate, run, and revert migrations, Sequelize provides a dedicated [CLI](https://sequelize.org/v5/manual/migrations.html#the-cli).

Migration classes are separate from the Nest application source code. Their lifecycle is maintained by the Sequelize CLI. Therefore, you are not able to leverage dependency injection and other Nest specific features with migrations. To learn more about migrations, follow the guide in the [Sequelize documentation](https://sequelize.org/v5/manual/migrations.html#the-cli).

## Learn the right way!

* 60+ chapters
* 4+ hours of videos
* Official certificate
* Deep-dive sessions

[Explore official courses](https://courses.nestjs.com "Courses | NestJS - A node.js framework built on top of TypeScript")

#### Multiple databases[#](/techniques/database#multiple-databases-1)

Some projects require multiple database connections. This can also be achieved with this module. To work with multiple connections, first create the connections. In this case, connection naming becomes **mandatory**.

Suppose you have an `Album` entity stored in its own database.

```typescript

const defaultOptions = {
  dialect: 'postgres',
  port: 5432,
  username: 'user',
  password: 'password',
  database: 'db',
  synchronize: true,
};

@Module({
  imports: [
    SequelizeModule.forRoot({
      ...defaultOptions,
      host: 'user_db_host',
      models: [User],
    }),
    SequelizeModule.forRoot({
      ...defaultOptions,
      name: 'albumsConnection',
      host: 'album_db_host',
      models: [Album],
    }),
  ],
})
export class AppModule {}
```

> **Notice** If you don't set the `name` for a connection, its name is set to `default`. Please note that you shouldn't have multiple connections without a name, or with the same name, otherwise they will get overridden.

At this point, you have `User` and `Album` models registered with their own connection. With this setup, you have to tell the `SequelizeModule.forFeature()` method and the `@InjectModel()` decorator which connection should be used. If you do not pass any connection name, the `default` connection is used.

```typescript

@Module({
  imports: [
    SequelizeModule.forFeature([User]),
    SequelizeModule.forFeature([Album], 'albumsConnection'),
  ],
})
export class AppModule {}
```

You can also inject the `Sequelize` instance for a given connection:

```typescript

@Injectable()
export class AlbumsService {
  constructor(
    @InjectConnection('albumsConnection')
    private readonly sequelize: Sequelize,
  ) {}
}
```

#### Testing[#](/techniques/database#testing-1)

When it comes to unit testing an application, we usually want to avoid making a database connection, keeping our test suites independent and their execution process as fast as possible. But our classes might depend on models that are pulled from the connection instance. How do we handle that? The solution is to create mock models. In order to achieve that, we set up [custom providers](/v6/fundamentals/custom-providers). Each registered model is automatically represented by a `<ModelName>Model` token, where `ModelName` is the name of your model class.

The `@nestjs/sequelize` package exposes the `getModelToken()` function which returns a prepared token based on a given model.

```typescript

@Module({
  providers: [
    UserService,
    {
      provide: getModelToken(User),
      useValue: mockModel,
    },
  ],
})
export class UsersModule {}
```

Now a substitute `mockModel` will be used as the `UserModel`. Whenever any class asks for `UserModel` using an `@InjectModel()` decorator, Nest will use the registered `mockModel` object.

#### Async configuration[#](/techniques/database#async-configuration-1)

You may want to pass your `SequelizeModule` options asynchronously instead of statically. In this case, use the `forRootAsync()` method, which provides several ways to deal with async configuration.

One approach is to use a factory function:

```typescript

SequelizeModule.forRootAsync({
  useFactory: () => ({
    dialect: 'mysql',
    host: 'localhost',
    port: 3306,
    username: 'root',
    password: 'root',
    database: 'test',
    models: [],
  }),
});
```

Our factory behaves like any other [asynchronous provider](https://docs.nestjs.com/fundamentals/async-providers) (e.g., it can be `async` and it's able to inject dependencies through `inject`).

```typescript

SequelizeModule.forRootAsync({
  imports: [ConfigModule],
  useFactory: (configService: ConfigService) => ({
    dialect: 'mysql',
    host: configService.get<string>('HOST'),
    port: configService.get<string>('PORT'),
    username: configService.get<string>('USERNAME'),
    password: configService.get<string>('PASSWORD'),
    database: configService.get<string>('DATABASE'),
    models: [],
  }),
  inject: [ConfigService],
});
```

Alternatively, you can use the `useClass` syntax:

```typescript

SequelizeModule.forRootAsync({
  useClass: SequelizeConfigService,
});
```

The construction above will instantiate `SequelizeConfigService` inside `SequelizeModule` and use it to provide an options object by calling `createSequelizeOptions()`. Note that this means that the `SequelizeConfigService` has to implement the `SequelizeOptionsFactory` interface, as shown below:

```typescript

@Injectable()
class SequelizeConfigService implements SequelizeOptionsFactory {
  createSequelizeOptions(): SequelizeModuleOptions {
    return {
      dialect: 'mysql',
      host: 'localhost',
      port: 3306,
      username: 'root',
      password: 'root',
      database: 'test',
      models: [],
    };
  }
}
```

In order to prevent the creation of `SequelizeConfigService` inside `SequelizeModule` and use a provider imported from a different module, you can use the `useExisting` syntax.

```typescript

SequelizeModule.forRootAsync({
  imports: [ConfigModule],
  useExisting: ConfigService,
});
```

This construction works the same as `useClass` with one critical difference - `SequelizeModule` will lookup imported modules to reuse an existing `ConfigService` instead of instantiating a new one.

#### Example[#](/techniques/database#example-1)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/07-sequelize).

----
url: https://docs.nestjs.com/v4/modules
----

### Modules

A module is a class with a `@Module()` decorator. The `@Module()` decorator provides metadata, which **Nest** uses to organize the application structure.

Every Nest application has at least one module, the **root module**. The root module is the place where Nest is starting to arrange the application tree. In fact, the root module could be the only module in your application, especially when the app is small. For large applications however, it doesn't make sense. In most cases, you'll have several modules, each with a closely related set of **capabilities**.

The `@Module()` decorator takes a single object whose properties describe the module:

|               |                                                                                                              |
| ------------- | ------------------------------------------------------------------------------------------------------------ |
| `components`  | the components that will be instantiated by the Nest injector and may be shared at least across this module. |
| `controllers` | the set of controllers which have to be created                                                              |
| `imports`     | the list of imported modules that export the components which are required in this module                    |
| `exports`     | the subset of `components` that are provided by this module and should be available in the other modules     |

The module **encapsulates** components by default. It means that it isn't possible to inject components which aren't directly part of the current module, or they're not exported from the imported modules.

#### CatsModule

The `CatsController` and `CatsService` belong to the same application domain. They should be moved to a feature module, being the `CatsModule`.

cats/cats.module.ts

JavaScript TypeScript

TypeScript

```typescript

import { Module } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

@Module({
    controllers: [CatsController],
    components: [CatsService],
})
export class CatsModule {}
```

I have created the `cats.module.ts` file and moved everything related to this module into the `cats` directory. The last thing we need to do is import this module into our root module (`ApplicationModule`).

app.module.ts

JavaScript TypeScript

TypeScript

```typescript

import { Module } from '@nestjs/common';
import { CatsModule } from './cats/cats.module';

@Module({
    imports: [CatsModule],
})
export class ApplicationModule {}
```

That's it! Now Nest knows that besides `ApplicationModule`, it's essential to register the `CatsModule` too. That's how our directory structure looks right now:

### Shared Module

In Nest, modules **are singletons** by default, thus you can share the **same instance** of the component between 2..\* modules without any effort.

> **Notice** In the previous versions of the Nest (< 4), modules weren't singletons, we had to use `@Shared()` decorator which is now **deprecated**.

Every module is a **Shared Module** in fact. Once created it can be reused by each module. Let's imagine that we want to share the `CatsService` instance between a few modules. We need to put the `CatsService` into `exports` array as shown below:

cats.module.ts

JavaScript TypeScript

TypeScript

```typescript

import { Module } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

@Module({
    controllers: [CatsController],
    components: [CatsService],
    exports: [CatsService]
})
export class CatsModule {}
```

Now each module which would import the `CatsModule` (we need to put `CatsModule` into the `imports` array) has access to the `CatsService` and will share the same instance with all of the modules which are importing this module too.

> **Notice** You should never export the controllers!

#### Modules re-exporting

The modules can export their components. Moreover, they can re-export modules imported by themselves.

TypeScript

```typescript

@Module({
  imports: [CommonModule],
  exports: [CommonModule],
})
export class CoreModule {}
```

#### Dependency Injection

It's natural that a module can **inject** components, which belong to it (e.g. for configuration purposes):

cats.module.ts

JavaScript TypeScript

TypeScript

```typescript

import { Module } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

@Module({
    controllers: [CatsController],
    components: [CatsService],
})
export class CatsModule {
  constructor(private readonly catsService: CatsService) {}
}
```

TypeScript

```typescript

import { Module, Dependencies } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

@Module({
    controllers: [CatsController],
    components: [CatsService],
})
@Dependencies(CatsService)
export class CatsModule {
  constructor(catsService) {
    this.catsService = catsService;
  }
}
```

However, module classes can't be injected by the components, because it creates a [circular dependency](/fundamentals/circular-dependency).

#### Global modules

If you have to import the same set of modules everywhere, it can be annoying. In [Angular](https://angular.io), the `providers` are registered in the global scope. Once defined, they're available everywhere. On the other hand, Nest encapsulates components inside the module scope. You can't use the module components elsewhere without importing it. But sometimes, you may just want to provide a set of things which should be available always - out-of-the-box, for example: helpers, database connection, whatever. That's why you're able to make the module a **global** one.

TypeScript

```typescript

import { Module, Global } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

@Global()
@Module({
    controllers: [CatsController],
    components: [CatsService],
    exports: [CatsService]
})
export class CatsModule {}
```

The `@Global()` decorator makes the module global-scoped. Global modules should be registered **only once**, in best case by the root or core module. Afterwards, the `CatsService` component will be ubiquitous, although `CatsModule` won't be imported.

> **Hint** Making everything global is not a good solution. Global modules are here to reduce the amount of necessary boilerplate. The `imports` array is still the best way to make the module API transparent.

#### Dynamic modules

The Nest module system comes with a feature called **dynamic modules**. It enables you to create customizable modules without any effort. Let's have a look at the `DatabaseModule`:

TypeScript

```typescript

import { Module, DynamicModule } from '@nestjs/common';
import { createDatabaseProviders } from './database.providers';
import { Connection } from './connection.component';

@Module({
  components: [Connection],
})
export class DatabaseModule {
  static forRoot(entities = [], options?): DynamicModule {
    const providers = createDatabaseProviders(options, entities);
    return {
      module: DatabaseModule,
      components: providers,
      exports: providers,
    };
  }
}
```

It defines the `Connection` component by default, but additionally - depending on the passed `options` and `entities` - it creates a collection of the providers, for example repository components. In fact, the dynamic module **extends** the module metadata. This substantial feature is useful when you need to register components dynamically. Then you may import the `DatabaseModule` in the following manner:

TypeScript

```typescript

import { Module } from '@nestjs/common';
import { DatabaseModule } from './database/database.module';
import { User } from './users/entities/user.entity';

@Module({
  imports: [
    DatabaseModule.forRoot([User]),
  ],
})
export class ApplicationModule {}
```

#### Sponsors

[](https://valor-software.com/)

Nest is an MIT-licensed open source project. It can grow thanks to the support by these awesome people. If you'd like to join them, please read more [here](https://opencollective.com/nest). Thanks!

[](https://opencollective.com/nest/backer/0/website)[](https://opencollective.com/nest/backer/1/website)[](https://opencollective.com/nest/backer/2/website)[](https://opencollective.com/nest/backer/3/website)[](https://opencollective.com/nest/backer/4/website)[](https://opencollective.com/nest/backer/5/website)[](https://opencollective.com/nest/backer/6/website)[](https://opencollective.com/nest/backer/7/website)[](https://opencollective.com/nest/backer/8/website)[](https://opencollective.com/nest/backer/9/website)[](https://opencollective.com/nest/backer/10/website)[](https://opencollective.com/nest/backer/11/website)[](https://opencollective.com/nest/backer/12/website)[](https://opencollective.com/nest/backer/13/website)[](https://opencollective.com/nest/backer/14/website)[](https://opencollective.com/nest/backer/15/website)[](https://opencollective.com/nest/backer/16/website)[](https://opencollective.com/nest/backer/17/website)[](https://opencollective.com/nest/backer/18/website)[](https://opencollective.com/nest/backer/19/website)[](https://opencollective.com/nest/backer/20/website)[](https://opencollective.com/nest/backer/21/website)[](https://opencollective.com/nest/backer/22/website)[](https://opencollective.com/nest/backer/23/website)[](https://opencollective.com/nest/backer/24/website)[](https://opencollective.com/nest/backer/25/website)[](https://opencollective.com/nest/backer/26/website)[](https://opencollective.com/nest/backer/27/website)[](https://opencollective.com/nest/backer/28/website)[](https://opencollective.com/nest/backer/29/website)

[Become a sponsor](https://opencollective.com/nest)

----
url: https://docs.nestjs.com/v9/techniques/streaming-files
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Streaming files](https://docs.nestjs.com/v9/techniques/streaming-files#streaming-files)
* [Streamable File class](https://docs.nestjs.com/v9/techniques/streaming-files#streamable-file-class)
* [Cross-platform support](https://docs.nestjs.com/v9/techniques/streaming-files#cross-platform-support)
* [Example](https://docs.nestjs.com/v9/techniques/streaming-files#example)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/techniques/streaming-files.md "Suggest Edits")

### Streaming files

> **Note** This chapter shows how you can stream files from your **HTTP application**. The examples presented below do not apply to GraphQL or Microservice applications.

There may be times where you would like to send back a file from your REST API to the client. To do this with Nest, normally you'd do the following:

```ts

@Controller('file')
export class FileController {
  @Get()
  getFile(@Res() res: Response) {
    const file = createReadStream(join(process.cwd(), 'package.json'));
    file.pipe(res);
  }
}
```

But in doing so you end up losing access to your post-controller interceptor logic. To handle this, you can return a `StreamableFile` instance and under the hood, the framework will take care of piping the response.

#### Streamable File class[#](/techniques/streaming-files#streamable-file-class)

A `StreamableFile` is a class that holds onto the stream that is to be returned. To create a new `StreamableFile`, you can pass either a `Buffer` or a `Stream` to the `StreamableFile` constructor.

> **hint** The `StreamableFile` class can be imported from `@nestjs/common`.

#### Cross-platform support[#](/techniques/streaming-files#cross-platform-support)

Fastify, by default, can support sending files without needing to call `stream.pipe(res)`, so you don't need to use the `StreamableFile` class at all. However, Nest supports the use of `StreamableFile` in both platform types, so if you end up switching between Express and Fastify there's no need to worry about compatibility between the two engines.

#### Example[#](/techniques/streaming-files#example)

You can find a simple example of returning the `package.json` as a file instead of a JSON below, but the idea extends out naturally to images, documents, and any other file type.

```ts

import { Controller, Get, StreamableFile } from '@nestjs/common';
import { createReadStream } from 'fs';
import { join } from 'path';

@Controller('file')
export class FileController {
  @Get()
  getFile(): StreamableFile {
    const file = createReadStream(join(process.cwd(), 'package.json'));
    return new StreamableFile(file);
  }
}
```

The default content type is `application/octet-stream`, if you need to customize the response you can use the `res.set` method or the [`@Header()`](/controllers#headers) decorator, like this:

```ts

import { Controller, Get, StreamableFile, Res } from '@nestjs/common';
import { createReadStream } from 'fs';
import { join } from 'path';
import type { Response } from 'express';

@Controller('file')
export class FileController {
  @Get()
  getFile(@Res({ passthrough: true }) res: Response): StreamableFile {
    const file = createReadStream(join(process.cwd(), 'package.json'));
    res.set({
      'Content-Type': 'application/json',
      'Content-Disposition': 'attachment; filename="package.json"',
    });
    return new StreamableFile(file);
  }

  // Or even:
  @Get()
  @Header('Content-Type', 'application/json')
  @Header('Content-Disposition', 'attachment; filename="package.json"')
  getStaticFile(): StreamableFile {
    const file = createReadStream(join(process.cwd(), 'package.json'));
    return new StreamableFile(file);
  }  
}
```

----
url: https://docs.nestjs.com/v9/faq/http-adapter
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [HTTP adapter](https://docs.nestjs.com/v9/faq/http-adapter#http-adapter)
* [Outside application context strategy](https://docs.nestjs.com/v9/faq/http-adapter#outside-application-context-strategy)
* [In-context strategy](https://docs.nestjs.com/v9/faq/http-adapter#in-context-strategy)

```typescript

const app = await NestFactory.create(AppModule);
const httpAdapter = app.getHttpAdapter();
```

#### In-context strategy[#](/faq/http-adapter#in-context-strategy)

To get a reference to the `HttpAdapterHost` from within the application context, inject it using the same technique as any other existing provider (e.g., using constructor injection).

JS TS

```typescript

export class CatsService {
  constructor(private adapterHost: HttpAdapterHost) {}
}
```

```typescript

@Dependencies(HttpAdapterHost)
export class CatsService {
  constructor(adapterHost) {
    this.adapterHost = adapterHost;
  }
}
```

> **Hint** The `HttpAdapterHost` is imported from the `@nestjs/core` package.

The `HttpAdapterHost` is **not** an actual `HttpAdapter`. To get the actual `HttpAdapter` instance, simply access the `httpAdapter` property.

```typescript

const adapterHost = app.get(HttpAdapterHost);
const httpAdapter = adapterHost.httpAdapter;
```

The `httpAdapter` is the actual instance of the HTTP adapter used by the underlying framework. It is an instance of either `ExpressAdapter` or `FastifyAdapter` (both classes extend `AbstractHttpAdapter`).

The adapter object exposes several useful methods to interact with the HTTP server. However, if you want to access the library instance (e.g., the Express instance) directly, call the `getInstance()` method.

```typescript

const instance = httpAdapter.getInstance();
```

----
url: https://docs.nestjs.com/v6/recipes/documentation
----

* [Documentation](https://docs.nestjs.com/v6/recipes/documentation#documentation)
* [Setup](https://docs.nestjs.com/v6/recipes/documentation#setup)
* [Generation](https://docs.nestjs.com/v6/recipes/documentation#generation)
* [Contribute](https://docs.nestjs.com/v6/recipes/documentation#contribute)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/recipes/documentation.md "Suggest Edits")

### Documentation

**Compodoc** is a documentation tool for Angular applications. Since Nest and Angular share similar project and code structures, **Compodoc** works with Nest applications as well.

#### Setup[#](/recipes/documentation#setup)

Setting up Compodoc inside an existing Nest project is very simple. Start by adding the dev-dependency with the following command in your OS terminal:

```bash

$ npm i -D @compodoc/compodoc
```

#### Generation[#](/recipes/documentation#generation)

Generate project documentation using the following command (npm 6 is required for `npx` support). See [the official documentation](https://compodoc.app/guides/usage.html) for more options.

```bash

$ npx compodoc -p tsconfig.json -s
```

Open your browser and navigate to <http://localhost:8080>. You should see an initial Nest CLI project:

#### Contribute[#](/recipes/documentation#contribute)

You can participate and contribute to the Compodoc project [here](https://github.com/compodoc/compodoc).

----
url: https://docs.nestjs.com/v5/graphql/subscriptions
----

### Subscriptions

Subscription is just another GraphQL operation type like Query and Mutation. It allows creating real-time subscriptions over a bidirectional transport layer, mainly over websockets. Read more about the subscriptions [here](https://www.apollographql.com/docs/graphql-subscriptions). Below is a `commentAdded` subscription example, copied and pasted directly from the official [Apollo](https://www.apollographql.com/docs/graphql-subscriptions/subscriptions-to-schema.html) documentation:

TypeScript

```typescript

Subscription: {
  commentAdded: {
    subscribe: () => pubSub.asyncIterator('commentAdded')
  }
}
```

> **Notice** The `pubsub` is an instance of `PubSub` class. Read more about it [here](https://www.apollographql.com/docs/graphql-subscriptions/setup.html).

In order to create an equivalent subscription in Nest, we'll make use of the `@Subscription()` decorator. Let's extend our `AuthorResolver` used in the [resolvers](/v5/graphql/resolvers-map) section.

TypeScript

```typescript

const pubSub = new PubSub();

@Resolver('Author')
export class AuthorResolver {
  constructor(
    private readonly authorsService: AuthorsService,
    private readonly postsService: PostsService,
  ) {}

  @Query('author')
  async getAuthor(@Args('id') id: number) {
    return await this.authorsService.findOneById(id);
  }

  @ResolveProperty('posts')
  async getPosts(@Parent() author) {
    const { id } = author;
    return await this.postsService.findAll({ authorId: id });
  }

  @Subscription()
  commentAdded() {
    return {
      subscribe: () => pubSub.asyncIterator('commentAdded'),
    };
  }
}
```

We have used a local `PubSub` instance here. Instead, we should define `PubSub` as a **provider**, inject it through the constructor (using `@Inject()` decorator), and reuse it across the whole application. You can read more about Nest custom providers [here](/v5/fundamentals/custom-providers).

#### Module

In order to enable subscriptions, we have to set `installSubscriptionHandlers` property to `true`.

Java

```java

GraphQLModule.forRoot({
  typePaths: ['./**/*.graphql'],
  installSubscriptionHandlers: true,
})
```

To customize the subscriptions server (e.g. change port), you can use `subscriptions` property (read [more](https://www.apollographql.com/docs/apollo-server/v2/api/apollo-server.html#constructor-options-lt-ApolloServer-gt)).

#### Type definitions

The last step is to update type definitions file.

Java

```java

type Author {
  id: Int!
  firstName: String
  lastName: String
  posts: [Post]
}

type Post {
  id: Int!
  title: String
  votes: Int
}

type Query {
  author(id: Int!): Author
}

type Comment {
  id: String
  content: String
}

type Subscription {
  commentAdded(repoFullName: String!): Comment
}
```

Well done. We created a single `commentAdded(repoFullName: String!): Comment` subscription. You can find a full sample implementation [here](https://github.com/nestjs/nest/blob/master/sample/12-graphql-apollo).

* Subscriptions
* Module

----
url: https://docs.nestjs.com/v11/support
----

* [Support](https://docs.nestjs.com/v11/support#support)
* [How can you help?](https://docs.nestjs.com/v11/support#how-can-you-help)

----
url: https://docs.nestjs.com/v8/openapi/security
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Security](https://docs.nestjs.com/v8/openapi/security#security)
* [Basic authentication](https://docs.nestjs.com/v8/openapi/security#basic-authentication)
* [Bearer authentication](https://docs.nestjs.com/v8/openapi/security#bearer-authentication)
* [OAuth2 authentication](https://docs.nestjs.com/v8/openapi/security#oauth2-authentication)
* [Cookie authentication](https://docs.nestjs.com/v8/openapi/security#cookie-authentication)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/openapi/security.md "Suggest Edits")

### Security

To define which security mechanisms should be used for a specific operation, use the `@ApiSecurity()` decorator.

```typescript

@ApiSecurity('basic')
@Controller('cats')
export class CatsController {}
```

Before you run your application, remember to add the security definition to your base document using `DocumentBuilder`:

```typescript

const options = new DocumentBuilder().addSecurity('basic', {
  type: 'http',
  scheme: 'basic',
});
```

Some of the most popular authentication techniques are built-in (e.g., `basic` and `bearer`) and therefore you don't have to define security mechanisms manually as shown above.

#### Basic authentication

To enable basic authentication, use `@ApiBasicAuth()`.

```typescript

@ApiBasicAuth()
@Controller('cats')
export class CatsController {}
```

Before you run your application, remember to add the security definition to your base document using `DocumentBuilder`:

```typescript

const options = new DocumentBuilder().addBasicAuth();
```

#### Bearer authentication

To enable bearer authentication, use `@ApiBearerAuth()`.

```typescript

@ApiBearerAuth()
@Controller('cats')
export class CatsController {}
```

Before you run your application, remember to add the security definition to your base document using `DocumentBuilder`:

```typescript

const options = new DocumentBuilder().addBearerAuth();
```

#### OAuth2 authentication

To enable OAuth2, use `@ApiOAuth2()`.

```typescript

@ApiOAuth2(['pets:write'])
@Controller('cats')
export class CatsController {}
```

Before you run your application, remember to add the security definition to your base document using `DocumentBuilder`:

```typescript

const options = new DocumentBuilder().addOAuth2();
```

#### Cookie authentication

To enable cookie authentication, use `@ApiCookieAuth()`.

```typescript

@ApiCookieAuth()
@Controller('cats')
export class CatsController {}
```

Before you run your application, remember to add the security definition to your base document using `DocumentBuilder`:

```typescript

const options = new DocumentBuilder().addCookieAuth('optional-session-id');
```

----
url: https://docs.nestjs.com/v7/graphql/complexity
----

* [Complexity](https://docs.nestjs.com/v7/graphql/complexity#complexity)
* [Installation](https://docs.nestjs.com/v7/graphql/complexity#installation)
* [Getting started](https://docs.nestjs.com/v7/graphql/complexity#getting-started)
* [Field-level complexity](https://docs.nestjs.com/v7/graphql/complexity#field-level-complexity)
* [Query/Mutation-level complexity](https://docs.nestjs.com/v7/graphql/complexity#querymutation-level-complexity)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/complexity.md "Suggest Edits")

### Complexity

> **Warning** This chapter applies only to the code first approach.

Query complexity allows you to define how complex certain fields are, and to restrict queries with a **maximum complexity**. The idea is to define how complex each field is by using a simple number. A common default is to give each field a complexity of `1`. In addition, the complexity calculation of a GraphQL query can be customized with so-called complexity estimators. A complexity estimator is a simple function that calculates the complexity for a field. You can add any number of complexity estimators to the rule, which are then executed one after another. The first estimator that returns a numeric complexity value determines the complexity for that field.

The `@nestjs/graphql` package integrates very well with tools like [graphql-query-complexity](https://github.com/slicknode/graphql-query-complexity) that provides a cost analysis-based solution. With this library, you can reject queries to your GraphQL server that are deemed too costly to execute.

#### Installation[#](/graphql/complexity#installation)

To begin using it, we first install the required dependency.

```bash

$ npm install --save graphql-query-complexity
```

#### Getting started[#](/graphql/complexity#getting-started)

Once the installation process is complete, we can define the `ComplexityPlugin` class:

```typescript

import { GraphQLSchemaHost, Plugin } from '@nestjs/graphql';
import {
  ApolloServerPlugin,
  GraphQLRequestListener,
} from 'apollo-server-plugin-base';
import { GraphQLError } from 'graphql';
import {
  fieldExtensionsEstimator,
  getComplexity,
  simpleEstimator,
} from 'graphql-query-complexity';

@Plugin()
export class ComplexityPlugin implements ApolloServerPlugin {
  constructor(private gqlSchemaHost: GraphQLSchemaHost) {}

  requestDidStart(): GraphQLRequestListener {
    const { schema } = this.gqlSchemaHost;

    return {
      didResolveOperation({ request, document }) {
        const complexity = getComplexity({
          schema,
          operationName: request.operationName,
          query: document,
          variables: request.variables,
          estimators: [
            fieldExtensionsEstimator(),
            simpleEstimator({ defaultComplexity: 1 }),
          ],
        });
        if (complexity >= 20) {
          throw new GraphQLError(
            `Query is too complex: ${complexity}. Maximum allowed complexity: 20`,
          );
        }
        console.log('Query Complexity:', complexity);
      },
    };
  }
}
```

For demonstration purposes, we specified the maximum allowed complexity as `20`. In the example above, we used 2 estimators, the `simpleEstimator` and the `fieldExtensionsEstimator`.

* `simpleEstimator`: the simple estimator returns a fixed complexity for each field
* `fieldExtensionsEstimator`: the field extensions estimator extracts the complexity value for each field of your schema

> **Hint** Remember to add this class to the providers array in any module.

#### Field-level complexity[#](/graphql/complexity#field-level-complexity)

With this plugin in place, we can now define the complexity for any field by specifying the `complexity` property in the options object passed into the `@Field()` decorator, as follows:

```typescript

@Field({ complexity: 3 })
title: string;
```

Alternatively, you can define the estimator function:

```typescript

@Field({ complexity: (options: ComplexityEstimatorArgs) => ... })
title: string;
```

#### Query/Mutation-level complexity[#](/graphql/complexity#querymutation-level-complexity)

In addition, `@Query()` and `@Mutation()` decorators may have a `complexity` property specified like so:

```typescript

@Query({ complexity: (options: ComplexityEstimatorArgs) => options.args.count * options.childComplexity })
items(@Args('count') count: number) {
  return this.itemsService.getItems({ count });
}
```

----
url: https://docs.nestjs.com/recipes/cqrs
----

[Skip to content](#content)

On this page

* [CQRS](https://docs.nestjs.com/recipes/cqrs#cqrs)
* [Installation](https://docs.nestjs.com/recipes/cqrs#installation)
* [Commands](https://docs.nestjs.com/recipes/cqrs#commands)
* [Queries](https://docs.nestjs.com/recipes/cqrs#queries)
* [Events](https://docs.nestjs.com/recipes/cqrs#events)
* [Flexible Aggregate Roots](https://docs.nestjs.com/recipes/cqrs#flexible-aggregate-roots)
* [Manual event publishing](https://docs.nestjs.com/recipes/cqrs#manual-event-publishing)
* [Sagas](https://docs.nestjs.com/recipes/cqrs#sagas)
* [Durable sagas](https://docs.nestjs.com/recipes/cqrs#durable-sagas)
* [Unhandled exceptions](https://docs.nestjs.com/recipes/cqrs#unhandled-exceptions)
* [Subscribing to all events](https://docs.nestjs.com/recipes/cqrs#subscribing-to-all-events)
* [Request-scoping](https://docs.nestjs.com/recipes/cqrs#request-scoping)
* [Example](https://docs.nestjs.com/recipes/cqrs#example)

### CQRS

The flow of simple [CRUD](https://en.wikipedia.org/wiki/Create,_read,_update_and_delete) (Create, Read, Update and Delete) applications can be described as follows:

1. The controllers layer handles HTTP requests and delegates tasks to the services layer.
2. The services layer is where most of the business logic lives.
3. Services use repositories or DAOs to change and persist entities.
4. Entities act as containers for values, with setters and getters.

While this pattern is usually sufficient for small and medium-sized applications, it may not be the best choice for larger, more complex ones. In such cases, the **CQRS** (Command and Query Responsibility Segregation) model may be more appropriate and scalable, depending on the application's requirements. Benefits of this model include:

* **Separation of concerns**. Read and write operations are handled by separate models.
* **Scalability**. Read and write operations can be scaled independently.
* **Flexibility**. Reads and writes can use different data stores.
* **Performance**. Each data store can be optimized for its workload (reads or writes).

To support this model, Nest provides a lightweight [CQRS module](https://github.com/nestjs/cqrs). This chapter describes how to use it.

#### Installation[#](/recipes/cqrs#installation)

First, install the required package:

```bash

$ npm install --save @nestjs/cqrs
```

Once the installation is complete, open the root module of your application (usually `AppModule`) and import `CqrsModule.forRoot()`:

```typescript

import { Module } from '@nestjs/common';
import { CqrsModule } from '@nestjs/cqrs';

@Module({
  imports: [CqrsModule.forRoot()],
})
export class AppModule {}
```

`forRoot()` accepts an optional configuration object. To provide the options asynchronously (e.g., from a configuration service), use `CqrsModule.forRootAsync()` instead. The following options are available:

| Attribute                     | Description                                                                                                                   | Default                           |
| ----------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | --------------------------------- |
| `commandPublisher`            | The publisher responsible for dispatching commands to the system.                                                             | `DefaultCommandPubSub`            |
| `eventPublisher`              | The publisher used to publish events, allowing them to be broadcasted or processed.                                           | `DefaultPubSub`                   |
| `queryPublisher`              | The publisher used for publishing queries, which can trigger data retrieval operations.                                       | `DefaultQueryPubSub`              |
| `unhandledExceptionPublisher` | The publisher used to publish unhandled exceptions to the `UnhandledExceptionBus`.                                            | `DefaultUnhandledExceptionPubSub` |
| `eventIdProvider`             | Service that retrieves unique event IDs from event instances.                                                                 | `DefaultEventIdProvider`          |
| `rethrowUnhandled`            | Whether exceptions thrown by event handlers and sagas are rethrown instead of being published to the `UnhandledExceptionBus`. | `false`                           |

#### Commands[#](/recipes/cqrs#commands)

Commands change the application state. They should be task-based rather than data-centric. When a command is dispatched, it is handled by a corresponding **command handler**, which is responsible for updating the application state.

heroes-game.service.ts

JS TS

```typescript

@Injectable()
export class HeroesGameService {
  constructor(private commandBus: CommandBus) {}

  async killDragon(heroId: string, killDragonDto: KillDragonDto) {
    return this.commandBus.execute(
      new KillDragonCommand(heroId, killDragonDto.dragonId)
    );
  }
}
```

```typescript

@Injectable()
@Dependencies(CommandBus)
export class HeroesGameService {
  constructor(commandBus) {
    this.commandBus = commandBus;
  }

  async killDragon(heroId, killDragonDto) {
    return this.commandBus.execute(
      new KillDragonCommand(heroId, killDragonDto.dragonId)
    );
  }
}
```

The code above instantiates the `KillDragonCommand` class and passes it to the `execute()` method of the `CommandBus`. Here is the command class:

kill-dragon.command.ts

JS TS

```typescript

export class KillDragonCommand extends Command<{
  actionId: string // This type represents the command execution result
}> {
  constructor(
    public readonly heroId: string,
    public readonly dragonId: string,
  ) {
    super();
  }
}
```

```typescript

export class KillDragonCommand extends Command {
  constructor(heroId, dragonId) {
    super();
    this.heroId = heroId;
    this.dragonId = dragonId;
  }
}
```

The `KillDragonCommand` class extends the `Command` class, a utility class exported from the `@nestjs/cqrs` package that lets you define the command's return type. In this case, the return type is an object with an `actionId` property. Whenever the `KillDragonCommand` command is dispatched, the return type of the `CommandBus#execute()` method is inferred as `Promise<{ actionId: string }>`. This is useful when the command handler returns data to the caller.

> **Hint** Extending the `Command` class is optional. You only need it to define the command's return type.

The `CommandBus` represents a **stream** of commands. It dispatches commands to the appropriate handlers. The `execute()` method returns a promise that resolves to the value returned by the handler.

Let's create a handler for the `KillDragonCommand` command.

kill-dragon.handler.ts

JS TS

```typescript

@CommandHandler(KillDragonCommand)
export class KillDragonHandler implements ICommandHandler<KillDragonCommand> {
  constructor(private repository: HeroesRepository) {}

  async execute(command: KillDragonCommand) {
    const { heroId, dragonId } = command;
    const hero = this.repository.findOneById(+heroId);

    hero.killEnemy(dragonId);
    await this.repository.persist(hero);

    // "ICommandHandler<KillDragonCommand>" forces you to return a value that matches the command's return type
    return {
      actionId: crypto.randomUUID(), // This value will be returned to the caller
    }
  }
}
```

```typescript

@CommandHandler(KillDragonCommand)
@Dependencies(HeroesRepository)
export class KillDragonHandler {
  constructor(repository) {
    this.repository = repository;
  }

  async execute(command) {
    const { heroId, dragonId } = command;
    const hero = this.repository.findOneById(+heroId);

    hero.killEnemy(dragonId);
    await this.repository.persist(hero);

    // "ICommandHandler<KillDragonCommand>" forces you to return a value that matches the command's return type
    return {
      actionId: crypto.randomUUID(), // This value will be returned to the caller
    }
  }
}
```

This handler retrieves the `Hero` entity from the repository, calls its `killEnemy()` method, and then persists the changes. The `KillDragonHandler` class implements the `ICommandHandler` interface, which requires an `execute()` method. The `execute()` method receives the command object as an argument.

`ICommandHandler<KillDragonCommand>` requires `execute()` to return a value that matches the command's return type (here, an object with an `actionId` property). This only applies to commands that extend the `Command` class. For other commands, the return type isn't constrained.

Finally, register the `KillDragonHandler` as a provider in a module:

```typescript

providers: [KillDragonHandler];
```

#### Queries[#](/recipes/cqrs#queries)

Queries retrieve data from the application state. They should be data-centric rather than task-based. When a query is dispatched, it is handled by a corresponding **query handler**, which is responsible for retrieving the data.

The `QueryBus` follows the same pattern as the `CommandBus`. Query handlers implement the `IQueryHandler` interface and are annotated with the `@QueryHandler()` decorator. Start with the query class:

```typescript

export class GetHeroQuery extends Query<Hero> {
  constructor(public readonly heroId: string) {
    super();
  }
}
```

Like the `Command` class, the `Query` class is a utility class exported from the `@nestjs/cqrs` package that lets you define the query's return type. In this case, the return type is a `Hero` object. Whenever the `GetHeroQuery` query is dispatched, the return type of the `QueryBus#execute()` method is inferred as `Promise<Hero>`.

To retrieve the hero, create a query handler:

get-hero.handler.ts

JS TS

```typescript

@QueryHandler(GetHeroQuery)
export class GetHeroHandler implements IQueryHandler<GetHeroQuery> {
  constructor(private repository: HeroesRepository) {}

  async execute(query: GetHeroQuery) {
    return this.repository.findOneById(query.heroId);
  }
}
```

```typescript

@QueryHandler(GetHeroQuery)
@Dependencies(HeroesRepository)
export class GetHeroHandler {
  constructor(repository) {
    this.repository = repository;
  }

  async execute(query) {
    return this.repository.findOneById(query.heroId);
  }
}
```

The `GetHeroHandler` class implements the `IQueryHandler` interface, which requires an `execute()` method. The `execute()` method receives the query object as an argument and must return data that matches the query's return type (in this case, a `Hero` object).

Finally, register the `GetHeroHandler` as a provider in a module:

```typescript

providers: [GetHeroHandler];
```

To dispatch the query, use the `QueryBus`:

```typescript

const hero = await this.queryBus.execute(new GetHeroQuery(heroId)); // "hero" will be auto-inferred as "Hero" type
```

#### Events[#](/recipes/cqrs#events)

Events notify other parts of the application about changes in the application state. They are dispatched by **models** or directly through the `EventBus`. When an event is dispatched, it is handled by the corresponding **event handlers**, which can, for example, update the read model.

For demonstration purposes, let's create an event class:

hero-killed-dragon.event.ts

JS TS

```typescript

export class HeroKilledDragonEvent {
  constructor(
    public readonly heroId: string,
    public readonly dragonId: string,
  ) {}
}
```

```typescript

export class HeroKilledDragonEvent {
  constructor(heroId, dragonId) {
    this.heroId = heroId;
    this.dragonId = dragonId;
  }
}
```

While you can dispatch events directly with the `EventBus.publish()` method, you can also dispatch them from the model. Let's update the `Hero` model to dispatch the `HeroKilledDragonEvent` event when the `killEnemy()` method is called.

hero.model.ts

JS TS

```typescript

export class Hero extends AggregateRoot {
  constructor(private id: string) {
    super();
  }

  killEnemy(enemyId: string) {
    // Business logic
    this.apply(new HeroKilledDragonEvent(this.id, enemyId));
  }
}
```

```typescript

export class Hero extends AggregateRoot {
  constructor(id) {
    super();
    this.id = id;
  }

  killEnemy(enemyId) {
    // Business logic
    this.apply(new HeroKilledDragonEvent(this.id, enemyId));
  }
}
```

The `apply()` method dispatches events. It accepts an event object as an argument. However, the model isn't aware of the `EventBus`, so you need to connect the two. The `EventPublisher` class does that:

kill-dragon.handler.ts

JS TS

```typescript

@CommandHandler(KillDragonCommand)
export class KillDragonHandler implements ICommandHandler<KillDragonCommand> {
  constructor(
    private repository: HeroesRepository,
    private publisher: EventPublisher,
  ) {}

  async execute(command: KillDragonCommand) {
    const { heroId, dragonId } = command;
    const hero = this.publisher.mergeObjectContext(
      await this.repository.findOneById(+heroId),
    );
    hero.killEnemy(dragonId);
    hero.commit();

    return {
      actionId: crypto.randomUUID(),
    };
  }
}
```

```typescript

@CommandHandler(KillDragonCommand)
@Dependencies(HeroesRepository, EventPublisher)
export class KillDragonHandler {
  constructor(repository, publisher) {
    this.repository = repository;
    this.publisher = publisher;
  }

  async execute(command) {
    const { heroId, dragonId } = command;
    const hero = this.publisher.mergeObjectContext(
      await this.repository.findOneById(+heroId),
    );
    hero.killEnemy(dragonId);
    hero.commit();

    return {
      actionId: crypto.randomUUID(),
    };
  }
}
```

The `EventPublisher#mergeObjectContext` method merges the event publisher into the provided object. This object must implement the `IAggregateRoot` interface (or extend the `AggregateRoot` class). Once merged, the object can publish events to the event stream.

Events applied with `apply()` are queued until you call the model's `commit()` method, which dispatches all outstanding events. To dispatch events as soon as they are applied, set the `autoCommit` property to `true`:

```typescript

export class Hero extends AggregateRoot {
  constructor(private id: string) {
    super();
    this.autoCommit = true;
  }
}
```

To merge the event publisher into a class rather than into an existing object, use the `EventPublisher#mergeClassContext` method:

```typescript

const HeroModel = this.publisher.mergeClassContext(Hero);
const hero = new HeroModel('id'); // <-- HeroModel is a class
```

Every instance of the `HeroModel` class can now publish events without calling the `mergeObjectContext()` method.

As of `@nestjs/cqrs` 12.1, a model's `commit()`, `publish()` and `publishAll()` return what the event bus returns, which is whatever the event publisher returns. The default in-memory publisher returns nothing, as it doesn't wait for the event handlers. With an asynchronous publisher, such as one that writes to a message broker, `await hero.commit()` waits for it and throws when it fails.

All three also accept a dispatcher context, which the event publisher receives in place of the model. A command handler can pass its transaction this way, for a publisher that writes through it:

```typescript

await hero.commit({ transaction: tx });
```

`commit()` clears the model's events as soon as it hands them to the event bus, without waiting for the publisher, so calling it again never publishes the same events twice. If an awaited `commit()` fails, roll back and run the command again with a freshly loaded model.

#### Flexible Aggregate Roots[#](/recipes/cqrs#flexible-aggregate-roots)

The `AggregateRoot` class is a base class that you can extend to add event-driven capabilities to your domain models. However, this approach requires domain entities to extend `AggregateRoot` directly, which can be a limitation if your application already has an established entity inheritance hierarchy (e.g., a base `Entity` class or domain-specific base classes such as `Monster` or `Vehicle`).

For more flexibility, the `@nestjs/cqrs` package supports three approaches to implementing aggregate roots:

**Approach 1: Traditional (Class Inheritance)**

This is the standard approach shown in the previous examples. It works well for simple scenarios and greenfield projects.

```typescript

export class Hero extends AggregateRoot {
  constructor(private id: string) {
    super();
  }

  killEnemy(enemyId: string) {
    this.apply(new HeroKilledDragonEvent(this.id, enemyId));
  }
}
```

**Approach 2: Mixin (For existing hierarchies)**

If you already have a base class and can't extend `AggregateRoot` directly, use the `WithAggregateRoot<EventBase, TBase>()` mixin function. It applies aggregate root behavior to any existing base class.

dragon.model.ts

JS TS

```typescript

abstract class Monster {
  constructor(protected readonly id: string) {}
  abstract roar(): void;
}

export class Dragon extends WithAggregateRoot(Monster) {
  roar(): void {
    console.log('Roarrrr!');
  }

  die(): void {
    this.roar();
    this.apply(new DragonDiedEvent(this.id)); // Provided by the mixin
  }
}
```

```typescript

class Monster {
  constructor(id) {
    this.id = id;
  }
}

export class Dragon extends WithAggregateRoot(Monster) {
  roar() {
    console.log('Roarrrr!');
  }

  die() {
    this.roar();
    this.apply(new DragonDiedEvent(this.id));
  }
}
```

**Approach 3: Custom Implementation**

For maximum control, or to keep your domain layer completely framework-agnostic, implement the `IAggregateRoot` interface directly:

```typescript

export class CustomEntity implements IAggregateRoot {
  autoCommit = false;
  private events: IEvent[] = [];

  getUncommittedEvents() {
    return this.events;
  }

  publish(event: IEvent, dispatcherContext?: unknown) {
    // custom logic
  }

  publishAll(events: IEvent[], dispatcherContext?: unknown) {
    // custom logic
  }

  commit(dispatcherContext?: unknown) {
    // custom logic, such as:
    // return this.publishAll(this.events.splice(0), dispatcherContext);
  }

  uncommit() {
    // custom logic
  }

  apply(event: IEvent) {
    this.events.push(event);
  }

  loadFromHistory(history: IEvent[]) {
    // custom logic
  }
}
```

All three approaches work with `EventPublisher`, which accepts any object that implements the `IAggregateRoot` interface. As of `@nestjs/cqrs` 12.1, `mergeObjectContext()` and `mergeClassContext()` give the model `publish()` and `publishAll()` methods that pass a dispatcher context on to the event bus and return its result. A custom `commit()` supports the dispatcher context by passing it on to `publishAll()`. The parameters are optional: an implementation without them, whose methods return nothing, still satisfies the interface.

#### Manual event publishing[#](/recipes/cqrs#manual-event-publishing)

To publish an event without going through a model, call the `EventBus#publish()` method directly:

```typescript

this.eventBus.publish(new HeroKilledDragonEvent(heroId, dragonId));
```

> **Hint** The `EventBus` is an injectable class.

Each event can have multiple **event handlers**.

hero-killed-dragon.handler.ts

JS TS

```typescript

@EventsHandler(HeroKilledDragonEvent)
export class HeroKilledDragonHandler implements IEventHandler<HeroKilledDragonEvent> {
  constructor(private repository: HeroesRepository) {}

  handle(event: HeroKilledDragonEvent) {
    // Business logic
  }
}
```

> **Hint** Event handlers run outside the traditional HTTP request context:
>
> * Errors thrown in command handlers can still be caught by the built-in [exception filters](/exception-filters).
> * Errors thrown in event handlers can't be caught by exception filters, so you have to handle them yourself: with a `try/catch` block, with a [saga](/recipes/cqrs#sagas) that triggers a compensating event, or with another approach of your choice.
> * The value returned by a command handler can still be sent back to the client in the HTTP response.
> * Event handlers can't send HTTP responses. To send information to the client, use [WebSockets](/websockets/gateways), [server-sent events](/http/server-sent-events), or another mechanism.

As with commands and queries, register the `HeroKilledDragonHandler` as a provider in a module:

```typescript

providers: [HeroKilledDragonHandler];
```

#### Sagas[#](/recipes/cqrs#sagas)

A saga is a long-running process that listens to events and may trigger new commands. Sagas are typically used to manage complex workflows. For example, when a user signs up, a saga may listen to the `UserRegisteredEvent` and send the user a welcome email.

A single saga may listen for 1..\* events. With the [RxJS](https://github.com/ReactiveX/rxjs) library, you can filter, map, fork, and merge event streams to build sophisticated workflows. Each saga returns an `Observable` that emits command instances. Each emitted command is then dispatched **asynchronously** by the `CommandBus`.

> **Hint** Sagas run in memory. For processes that must survive restarts, see [Durable sagas](/recipes/cqrs#durable-sagas).

Let's create a saga that listens to the `HeroKilledDragonEvent` and dispatches the `DropAncientItemCommand` command.

heroes-game.saga.ts

JS TS

```typescript

@Injectable()
export class HeroesGameSagas {
  @Saga()
  dragonKilled = (events$: Observable<any>): Observable<ICommand> => {
    return events$.pipe(
      ofType(HeroKilledDragonEvent),
      map((event) => new DropAncientItemCommand(event.heroId, fakeItemID)),
    );
  }
}
```

```typescript

@Injectable()
export class HeroesGameSagas {
  @Saga()
  dragonKilled = (events$) => {
    return events$.pipe(
      ofType(HeroKilledDragonEvent),
      map((event) => new DropAncientItemCommand(event.heroId, fakeItemID)),
    );
  }
}
```

> **Hint** The `ofType` operator and the `@Saga()` decorator are exported from the `@nestjs/cqrs` package.

The `@Saga()` decorator marks the property as a saga. The `events$` argument is an `Observable` stream of all events. The `ofType` operator filters the stream by the specified event type, and the `map` operator maps each event to a new command instance.

In this example, each `HeroKilledDragonEvent` is mapped to a `DropAncientItemCommand` command, which the `CommandBus` then dispatches automatically.

As with query, command, and event handlers, register the `HeroesGameSagas` as a provider in a module:

```typescript

providers: [HeroesGameSagas];
```

#### Durable sagas[#](/recipes/cqrs#durable-sagas)

Sagas and event handlers run in memory. If the process stops between an event and the command a saga dispatches, the command is never dispatched. A saga that combines several events, such as one that waits for the payment after an order and gives up after an hour, loses the events it has seen on a restart. An event published just before the transaction behind it rolls back still reaches them.

When a process must survive restarts and deploys, let the events start and signal a [durable workflow](/reliability/workflows) instead. The `@nestjs/workflows/cqrs` entry point maps events to workflows, so your code keeps executing commands and publishing events:

```bash

$ npm i --save @nestjs/workflows
```

app.module.ts

JS TS

```typescript

import { CqrsModule } from '@nestjs/cqrs';
import { WorkflowsModule } from '@nestjs/workflows';
import { WorkflowsCqrsModule } from '@nestjs/workflows/cqrs';

@Module({
  imports: [CqrsModule.forRoot(), WorkflowsModule.forRoot(), WorkflowsCqrsModule],
  providers: [PlaceOrderHandler, OrderFulfilmentWorkflow],
})
export class AppModule {}
```

Until you register a store, `WorkflowsModule` keeps the workflows in memory. On PostgreSQL or MySQL, register the package's `PostgresWorkflowStore` or `MySqlWorkflowStore` as a provider, on the database client you already use, as [Keep workflows in your database](/reliability/workflows#keep-workflows-in-your-database) shows: the workflows then live in your database, and their starts and signals can join your transactions.

`@StartOn()` starts the workflow when an event is published, and `@SignalOn()` wakes the instance that waits for another one:

order-fulfilment.workflow\.ts

JS TS

```typescript

@Workflow('order-fulfilment')
@StartOn(OrderPlacedEvent, {
  id: (event) => `order-${event.order.id}`,
  input: (event) => event.order,
})
@SignalOn(OrderDeliveredEvent, {
  signal: shipmentDelivered,
  key: (event) => event.delivery.reference,
})
export class OrderFulfilmentWorkflow implements WorkflowRunner<Order, FulfilmentResult> {
  constructor(private readonly commandBus: CommandBus) {}

  async run(ctx: WorkflowContext, order: Order): Promise<FulfilmentResult> {
    const charge = await ctx.step('charge-payment', ({ idempotencyKey }) =>
      this.commandBus.execute(new ChargePaymentCommand(order, idempotencyKey)),
    );

    const delivery = await ctx.waitForSignal('await-delivery', shipmentDelivered, {
      key: order.id,
      timeout: '3d',
    });
    // ...
  }
}
```

The command handler passes its transaction as the second argument of `publish()`, CQRS's dispatcher context. The workflow is then created in that transaction, so it exists if and only if the order was saved:

place-order.handler.ts

JS TS

```typescript

return this.db.transaction(async (tx) => {
  await tx.insert(orders).values(order);
  await this.eventBus.publish(new OrderPlacedEvent(order), { transaction: tx });
  return order;
});
```

An aggregate's events go the same way. As of `@nestjs/cqrs` 12.1, pass the transaction to the aggregate's `commit()` in the same callback, and await it: it resolves once the workflows are started and signalled.

```typescript

await order.commit({ transaction: tx });
```

The workflow's state lives in your database, so it outlives restarts and deploys. A completed step never runs again, and a step the process died in runs again with the same idempotency key, which the command hands to the payment provider. A repeated event finds the instance the first one started. Your event handlers and sagas still receive every event, after the workflows. See [Durable workflows with CQRS](/reliability/workflows#with-cqrs) for the guarantees of each way of publishing, and aggregates.

#### Unhandled exceptions[#](/recipes/cqrs#unhandled-exceptions)

Event handlers are executed asynchronously, so they must always handle exceptions properly to prevent the application from entering an inconsistent state. If an exception isn't handled, the `EventBus` logs it, creates an `UnhandledExceptionInfo` object, and pushes it to the `UnhandledExceptionBus` stream. The same applies to exceptions thrown by sagas and by command handlers executing commands that sagas dispatched. The `UnhandledExceptionBus` is an `Observable` that you can subscribe to in order to process unhandled exceptions. If the `rethrowUnhandled` option is set to `true`, these exceptions are rethrown instead of being published to the `UnhandledExceptionBus`.

```typescript

private destroy$ = new Subject<void>();

constructor(private unhandledExceptionsBus: UnhandledExceptionBus) {
  this.unhandledExceptionsBus
    .pipe(takeUntil(this.destroy$))
    .subscribe((exceptionInfo) => {
      // Handle exception here
      // e.g. send it to external service, terminate process, or publish a new event
    });
}

onModuleDestroy() {
  this.destroy$.next();
  this.destroy$.complete();
}
```

To handle only specific exception types, use the `UnhandledExceptionBus.ofType()` operator, which filters exceptions with `instanceof`:

```typescript

this.unhandledExceptionsBus
  .pipe(
    takeUntil(this.destroy$),
    UnhandledExceptionBus.ofType(TransactionNotAllowedException),
  )
  .subscribe((exceptionInfo) => {
    // Handle exception here
  });
```

Here, only exceptions that are instances of `TransactionNotAllowedException` reach the subscriber.

The `UnhandledExceptionInfo` object contains the following properties:

```typescript

export interface UnhandledExceptionInfo<
  Cause = IEvent | ICommand,
  Exception = any,
> {
  /**
   * The exception that was thrown.
   */
  exception: Exception;
  /**
   * The cause of the exception (event or command reference).
   */
  cause: Cause;
}
```

#### Subscribing to all events[#](/recipes/cqrs#subscribing-to-all-events)

`CommandBus`, `QueryBus`, and `EventBus` are all **Observables**. This means you can subscribe to the entire stream and, for example, process all events: log them to the console or save them to an event store.

```typescript

private destroy$ = new Subject<void>();

constructor(private eventBus: EventBus) {
  this.eventBus
    .pipe(takeUntil(this.destroy$))
    .subscribe((event) => {
      // Save events to database
    });
}

onModuleDestroy() {
  this.destroy$.next();
  this.destroy$.complete();
}
```

#### Request-scoping[#](/recipes/cqrs#request-scoping)

If you're coming from other programming languages, you may be surprised that in Nest, most things are shared across incoming requests: a connection pool to the database, singleton services with global state, and more. Node.js doesn't follow the request/response multi-threaded stateless model, in which each request is processed by a separate thread. As a result, using singleton instances is **safe** for your applications.

However, there are edge cases where a request-based lifetime for a handler is desirable, such as per-request caching in GraphQL applications, request tracking, or multi-tenancy. See the [injection scopes](/fundamentals/injection-scopes) chapter to learn how to control scopes.

Using request-scoped providers alongside CQRS can be complex because the `CommandBus`, `QueryBus`, and `EventBus` are singletons. The `@nestjs/cqrs` package handles this by automatically creating a new instance of a request-scoped handler for each processed command, query, or event.

To make a handler request-scoped, either:

1. Depend on a request-scoped provider.
2. Explicitly set its scope to `REQUEST` in the `@CommandHandler()`, `@QueryHandler()`, or `@EventsHandler()` decorator, as shown:

```typescript

@CommandHandler(KillDragonCommand, {
  scope: Scope.REQUEST,
})
export class KillDragonHandler {
  // Implementation here
}
```

To inject the request payload into a request-scoped provider, use the `@Inject(REQUEST)` decorator (`REQUEST` is exported from `@nestjs/core`). In CQRS, however, the request payload depends on the context: it could be an HTTP request, a scheduled job, or any other operation that triggers a command.

The payload must be an instance of `AsyncContext` (exported from `@nestjs/cqrs`) or of a class that extends it. It acts as the request context and holds data that is accessible throughout the request lifecycle.

```typescript

import { AsyncContext } from '@nestjs/cqrs';

export class MyRequest extends AsyncContext {
  constructor(public readonly user: User) {
    super();
  }
}
```

When executing a command, pass the custom request context as the second argument to the `CommandBus#execute()` method:

```typescript

const myRequest = new MyRequest(user);
await this.commandBus.execute(
  new KillDragonCommand(heroId, killDragonDto.dragonId),
  myRequest,
);
```

This makes the `MyRequest` instance available as the `REQUEST` provider to the corresponding handler:

```typescript

@CommandHandler(KillDragonCommand, {
  scope: Scope.REQUEST,
})
export class KillDragonHandler {
  constructor(
    @Inject(REQUEST) private request: MyRequest, // Inject the request context
  ) {}

  // Handler implementation here
}
```

Queries work the same way:

```typescript

const myRequest = new MyRequest(user);
const hero = await this.queryBus.execute(new GetHeroQuery(heroId), myRequest);
```

And in the query handler:

```typescript

@QueryHandler(GetHeroQuery, {
  scope: Scope.REQUEST,
})
export class GetHeroHandler {
  constructor(
    @Inject(REQUEST) private request: MyRequest, // Inject the request context
  ) {}

  // Handler implementation here
}
```

For events, you can pass the request context to `EventBus#publish()`, but this is less common. Instead, use `EventPublisher` to merge the request context into a model:

```typescript

const hero = this.publisher.mergeObjectContext(
  await this.repository.findOneById(+heroId),
  this.request, // Inject the request context here
);
```

Request-scoped event handlers that handle these events have access to the request context.

Sagas are always singletons because they manage long-running processes (registering a saga in a non-singleton provider throws an exception). However, you can retrieve the request context from event objects:

```typescript

@Saga()
dragonKilled = (events$: Observable<any>): Observable<ICommand> => {
  return events$.pipe(
    ofType(HeroKilledDragonEvent),
    map((event) => {
      const request = AsyncContext.of(event); // Retrieve the request context
      const command = new DropAncientItemCommand(event.heroId, fakeItemID);

      AsyncContext.merge(request, command); // Merge the request context into the command
      return command;
    }),
  );
}
```

Alternatively, call the `request.attachTo(command)` method to attach the request context to the command.

#### Example[#](/recipes/cqrs#example)

A working example is available in the [nest-cqrs-example repository](https://github.com/kamilmysliwiec/nest-cqrs-example).

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/recipes/cqrs.md)

----
url: https://docs.nestjs.com/v9/faq/global-prefix
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Global prefix](https://docs.nestjs.com/v9/faq/global-prefix#global-prefix)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/faq/global-prefix.md "Suggest Edits")

### Global prefix

To set a prefix for **every route** registered in an HTTP application, use the `setGlobalPrefix()` method of the `INestApplication` instance.

```typescript

const app = await NestFactory.create(AppModule);
app.setGlobalPrefix('v1');
```

You can exclude routes from the global prefix using the following construction:

```typescript

app.setGlobalPrefix('v1', {
  exclude: [{ path: 'health', method: RequestMethod.GET }],
});
```

Alternatively, you can specify route as a string (it will apply to every request method):

```typescript

app.setGlobalPrefix('v1', { exclude: ['cats'] });
```

> **Hint** The `path` property supports wildcard parameters using the [path-to-regexp](https://github.com/pillarjs/path-to-regexp#parameters) package. Note: this does not accept wildcard asterisks `*`. Instead, you must use parameters (e.g., `(.*)`, `:splat*`).

----
url: https://docs.nestjs.com/v4/microservices/pipes
----

### Pipes

There's no difference between microservices **pipes** and the [regular pipes](/v4/pipes). The only thing you should be aware of is that instead of throwing `HttpException`, you should use the `RpcException`.

> **Hint** The `RpcException` class is available within the `@nestjs/microservices` package.

#### Sponsors

[](https://valor-software.com/)

Nest is an MIT-licensed open source project. It can grow thanks to the support by these awesome people. If you'd like to join them, please read more [here](https://opencollective.com/nest). Thanks!

[](https://opencollective.com/nest/backer/0/website)[](https://opencollective.com/nest/backer/1/website)[](https://opencollective.com/nest/backer/2/website)[](https://opencollective.com/nest/backer/3/website)[](https://opencollective.com/nest/backer/4/website)[](https://opencollective.com/nest/backer/5/website)[](https://opencollective.com/nest/backer/6/website)[](https://opencollective.com/nest/backer/7/website)[](https://opencollective.com/nest/backer/8/website)[](https://opencollective.com/nest/backer/9/website)[](https://opencollective.com/nest/backer/10/website)[](https://opencollective.com/nest/backer/11/website)[](https://opencollective.com/nest/backer/12/website)[](https://opencollective.com/nest/backer/13/website)[](https://opencollective.com/nest/backer/14/website)[](https://opencollective.com/nest/backer/15/website)[](https://opencollective.com/nest/backer/16/website)[](https://opencollective.com/nest/backer/17/website)[](https://opencollective.com/nest/backer/18/website)[](https://opencollective.com/nest/backer/19/website)[](https://opencollective.com/nest/backer/20/website)[](https://opencollective.com/nest/backer/21/website)[](https://opencollective.com/nest/backer/22/website)[](https://opencollective.com/nest/backer/23/website)[](https://opencollective.com/nest/backer/24/website)[](https://opencollective.com/nest/backer/25/website)[](https://opencollective.com/nest/backer/26/website)[](https://opencollective.com/nest/backer/27/website)[](https://opencollective.com/nest/backer/28/website)[](https://opencollective.com/nest/backer/29/website)

[Become a sponsor](https://opencollective.com/nest)

----
url: https://docs.nestjs.com/v11/exception-filters
----

* [Exception filters](https://docs.nestjs.com/v11/exception-filters#exception-filters)
* [Throwing standard exceptions](https://docs.nestjs.com/v11/exception-filters#throwing-standard-exceptions)
* [Exceptions logging](https://docs.nestjs.com/v11/exception-filters#exceptions-logging)
* [Custom exceptions](https://docs.nestjs.com/v11/exception-filters#custom-exceptions)
* [Built-in HTTP exceptions](https://docs.nestjs.com/v11/exception-filters#built-in-http-exceptions)
* [Exception filters](https://docs.nestjs.com/v11/exception-filters#exception-filters-1)
* [Arguments host](https://docs.nestjs.com/v11/exception-filters#arguments-host)
* [Binding filters](https://docs.nestjs.com/v11/exception-filters#binding-filters)
* [Catch everything](https://docs.nestjs.com/v11/exception-filters#catch-everything)
* [Inheritance](https://docs.nestjs.com/v11/exception-filters#inheritance)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/exception-filters.md "Suggest Edits")

### Exception filters

Nest comes with a built-in **exceptions layer** which is responsible for processing all unhandled exceptions across an application. When an exception is not handled by your application code, it is caught by this layer, which then automatically sends an appropriate user-friendly response.

Out of the box, this action is performed by a built-in **global exception filter**, which handles exceptions of type `HttpException` (and subclasses of it). When an exception is **unrecognized** (is neither `HttpException` nor a class that inherits from `HttpException`), the built-in exception filter generates the following default JSON response:

```json

{
  "statusCode": 500,
  "message": "Internal server error"
}
```

> **Hint** The global exception filter partially supports the `http-errors` library. Basically, any thrown exception containing the `statusCode` and `message` properties will be properly populated and sent back as a response (instead of the default `InternalServerErrorException` for unrecognized exceptions).

#### Throwing standard exceptions[#](/exception-filters#throwing-standard-exceptions)

Nest provides a built-in `HttpException` class, exposed from the `@nestjs/common` package. For typical HTTP REST/GraphQL API based applications, it's best practice to send standard HTTP response objects when certain error conditions occur.

For example, in the `CatsController`, we have a `findAll()` method (a `GET` route handler). Let's assume that this route handler throws an exception for some reason. To demonstrate this, we'll hard-code it as follows:

cats.controller.ts

JS TS

```typescript

@Get()
async findAll() {
  throw new HttpException('Forbidden', HttpStatus.FORBIDDEN);
}
```

> **Hint** We used the `HttpStatus` here. This is a helper enum imported from the `@nestjs/common` package.

When the client calls this endpoint, the response looks like this:

```json

{
  "statusCode": 403,
  "message": "Forbidden"
}
```

```typescript

@Get()
async findAll() {
  try {
    await this.service.findAll()
  } catch (error) {
    throw new HttpException({
      status: HttpStatus.FORBIDDEN,
      error: 'This is a custom message',
    }, HttpStatus.FORBIDDEN, {
      cause: error
    });
  }
}
```

Using the above, this is how the response would look:

```json

{
  "status": 403,
  "error": "This is a custom message"
}
```

#### Exceptions logging[#](/exception-filters#exceptions-logging)

By default, the exception filter does not log built-in exceptions like `HttpException` (and any exceptions that inherit from it). When these exceptions are thrown, they won't appear in the console, as they are treated as part of the normal application flow. The same behavior applies to other built-in exceptions such as `WsException` and `RpcException`.

These exceptions all inherit from the base `IntrinsicException` class, which is exported from the `@nestjs/common` package. This class helps differentiate between exceptions that are part of normal application operation and those that are not.

If you want to log these exceptions, you can create a custom exception filter. We'll explain how to do this in the next section.

#### Custom exceptions[#](/exception-filters#custom-exceptions)

In many cases, you will not need to write custom exceptions, and can use the built-in Nest HTTP exception, as described in the next section. If you do need to create customized exceptions, it's good practice to create your own **exceptions hierarchy**, where your custom exceptions inherit from the base `HttpException` class. With this approach, Nest will recognize your exceptions, and automatically take care of the error responses. Let's implement such a custom exception:

forbidden.exception.ts

JS TS

```typescript

export class ForbiddenException extends HttpException {
  constructor() {
    super('Forbidden', HttpStatus.FORBIDDEN);
  }
}
```

Since `ForbiddenException` extends the base `HttpException`, it will work seamlessly with the built-in exception handler, and therefore we can use it inside the `findAll()` method.

cats.controller.ts

JS TS

```typescript

@Get()
async findAll() {
  throw new ForbiddenException();
}
```

```typescript

throw new BadRequestException('Something bad happened', {
  cause: new Error(),
  description: 'Some error description',
});
```

Using the above, this is how the response would look:

```json

{
  "message": "Something bad happened",
  "error": "Some error description",
  "statusCode": 400
}
```

#### Exception filters[#](/exception-filters#exception-filters-1)

While the base (built-in) exception filter can automatically handle many cases for you, you may want **full control** over the exceptions layer. For example, you may want to add logging or use a different JSON schema based on some dynamic factors. **Exception filters** are designed for exactly this purpose. They let you control the exact flow of control and the content of the response sent back to the client.

Let's create an exception filter that is responsible for catching exceptions which are an instance of the `HttpException` class, and implementing custom response logic for them. To do this, we'll need to access the underlying platform `Request` and `Response` objects. We'll access the `Request` object so we can pull out the original `url` and include that in the logging information. We'll use the `Response` object to take direct control of the response that is sent, using the `response.json()` method.

http-exception.filter.ts

JS TS

```typescript

import { ExceptionFilter, Catch, ArgumentsHost, HttpException } from '@nestjs/common';
import { Request, Response } from 'express';

@Catch(HttpException)
export class HttpExceptionFilter implements ExceptionFilter {
  catch(exception: HttpException, host: ArgumentsHost) {
    const ctx = host.switchToHttp();
    const response = ctx.getResponse<Response>();
    const request = ctx.getRequest<Request>();
    const status = exception.getStatus();

    response
      .status(status)
      .json({
        statusCode: status,
        timestamp: new Date().toISOString(),
        path: request.url,
      });
  }
}
```

```typescript

import { Catch, HttpException } from '@nestjs/common';

@Catch(HttpException)
export class HttpExceptionFilter {
  catch(exception, host) {
    const ctx = host.switchToHttp();
    const response = ctx.getResponse();
    const request = ctx.getRequest();
    const status = exception.getStatus();

    response
      .status(status)
      .json({
        statusCode: status,
        timestamp: new Date().toISOString(),
        path: request.url,
      });
  }
}
```

> **Hint** All exception filters should implement the generic `ExceptionFilter<T>` interface. This requires you to provide the `catch(exception: T, host: ArgumentsHost)` method with its indicated signature. `T` indicates the type of the exception.

> **Warning** If you are using `@nestjs/platform-fastify` you can use `response.send()` instead of `response.json()`. Don't forget to import the correct types from `fastify`.

The `@Catch(HttpException)` decorator binds the required metadata to the exception filter, telling Nest that this particular filter is looking for exceptions of type `HttpException` and nothing else. The `@Catch()` decorator may take a single parameter, or a comma-separated list. This lets you set up the filter for several types of exceptions at once.

#### Arguments host[#](/exception-filters#arguments-host)

Let's look at the parameters of the `catch()` method. The `exception` parameter is the exception object currently being processed. The `host` parameter is an `ArgumentsHost` object. `ArgumentsHost` is a powerful utility object that we'll examine further in the [execution context chapter](/v11/fundamentals/execution-context)\*. In this code sample, we use it to obtain a reference to the `Request` and `Response` objects that are being passed to the original request handler (in the controller where the exception originates). In this code sample, we've used some helper methods on `ArgumentsHost` to get the desired `Request` and `Response` objects. Learn more about `ArgumentsHost`[here](/v11/fundamentals/execution-context).

```typescript

@Post()
@UseFilters(new HttpExceptionFilter())
async create(@Body() createCatDto: CreateCatDto) {
  throw new ForbiddenException();
}
```

```typescript

@Post()
@UseFilters(new HttpExceptionFilter())
@Bind(Body())
async create(createCatDto) {
  throw new ForbiddenException();
}
```

> **Hint** The `@UseFilters()` decorator is imported from the `@nestjs/common` package.

We have used the `@UseFilters()` decorator here. Similar to the `@Catch()` decorator, it can take a single filter instance, or a comma-separated list of filter instances. Here, we created the instance of `HttpExceptionFilter` in place. Alternatively, you may pass the class (instead of an instance), leaving responsibility for instantiation to the framework, and enabling **dependency injection**.

cats.controller.ts

JS TS

```typescript

@Post()
@UseFilters(HttpExceptionFilter)
async create(@Body() createCatDto: CreateCatDto) {
  throw new ForbiddenException();
}
```

```typescript

@Post()
@UseFilters(HttpExceptionFilter)
@Bind(Body())
async create(createCatDto) {
  throw new ForbiddenException();
}
```

> **Hint** Prefer applying filters by using classes instead of instances when possible. It reduces **memory usage** since Nest can easily reuse instances of the same class across your entire module.

In the example above, the `HttpExceptionFilter` is applied only to the single `create()` route handler, making it method-scoped. Exception filters can be scoped at different levels: method-scoped of the controller/resolver/gateway, controller-scoped, or global-scoped. For example, to set up a filter as controller-scoped, you would do the following:

cats.controller.ts

JS TS

```typescript

@Controller()
@UseFilters(new HttpExceptionFilter())
export class CatsController {}
```

This construction sets up the `HttpExceptionFilter` for every route handler defined inside the `CatsController`.

To create a global-scoped filter, you would do the following:

main.ts

JS TS

```typescript

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.useGlobalFilters(new HttpExceptionFilter());
  await app.listen(process.env.PORT ?? 3000);
}
bootstrap();
```

> **Warning** The `useGlobalFilters()` method does not set up filters for gateways or hybrid applications.

Global-scoped filters are used across the whole application, for every controller and every route handler. In terms of dependency injection, global filters registered from outside of any module (with `useGlobalFilters()` as in the example above) cannot inject dependencies since this is done outside the context of any module. In order to solve this issue, you can register a global-scoped filter **directly from any module** using the following construction:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { APP_FILTER } from '@nestjs/core';

@Module({
  providers: [
    {
      provide: APP_FILTER,
      useClass: HttpExceptionFilter,
    },
  ],
})
export class AppModule {}
```

> **Hint** When using this approach to perform dependency injection for the filter, note that regardless of the module where this construction is employed, the filter is, in fact, global. Where should this be done? Choose the module where the filter (`HttpExceptionFilter` in the example above) is defined. Also, `useClass` is not the only way of dealing with custom provider registration. Learn more [here](/v11/fundamentals/custom-providers).

You can add as many filters with this technique as needed; simply add each to the providers array.

#### Catch everything[#](/exception-filters#catch-everything)

In order to catch **every** unhandled exception (regardless of the exception type), leave the `@Catch()` decorator's parameter list empty, e.g., `@Catch()`.

In the example below we have a code that is platform-agnostic because it uses the [HTTP adapter](./faq/http-adapter) to deliver the response, and doesn't use any of the platform-specific objects (`Request` and `Response`) directly:

```typescript

import {
  ExceptionFilter,
  Catch,
  ArgumentsHost,
  HttpException,
  HttpStatus,
} from '@nestjs/common';
import { HttpAdapterHost } from '@nestjs/core';

@Catch()
export class CatchEverythingFilter implements ExceptionFilter {
  constructor(private readonly httpAdapterHost: HttpAdapterHost) {}

  catch(exception: unknown, host: ArgumentsHost): void {
    // In certain situations `httpAdapter` might not be available in the
    // constructor method, thus we should resolve it here.
    const { httpAdapter } = this.httpAdapterHost;

    const ctx = host.switchToHttp();

    const httpStatus =
      exception instanceof HttpException
        ? exception.getStatus()
        : HttpStatus.INTERNAL_SERVER_ERROR;

    const responseBody = {
      statusCode: httpStatus,
      timestamp: new Date().toISOString(),
      path: httpAdapter.getRequestUrl(ctx.getRequest()),
    };

    httpAdapter.reply(ctx.getResponse(), responseBody, httpStatus);
  }
}
```

> **Warning** When combining an exception filter that catches everything with a filter that is bound to a specific type, the "Catch anything" filter should be declared first to allow the specific filter to correctly handle the bound type.

#### Inheritance[#](/exception-filters#inheritance)

Typically, you'll create fully customized exception filters crafted to fulfill your application requirements. However, there might be use-cases when you would like to simply extend the built-in default **global exception filter**, and override the behavior based on certain factors.

In order to delegate exception processing to the base filter, you need to extend `BaseExceptionFilter` and call the inherited `catch()` method.

all-exceptions.filter.ts

JS TS

```typescript

import { Catch, ArgumentsHost } from '@nestjs/common';
import { BaseExceptionFilter } from '@nestjs/core';

@Catch()
export class AllExceptionsFilter extends BaseExceptionFilter {
  catch(exception: unknown, host: ArgumentsHost) {
    super.catch(exception, host);
  }
}
```

```typescript

import { Catch } from '@nestjs/common';
import { BaseExceptionFilter } from '@nestjs/core';

@Catch()
export class AllExceptionsFilter extends BaseExceptionFilter {
  catch(exception, host) {
    super.catch(exception, host);
  }
}
```

> **Warning** Method-scoped and Controller-scoped filters that extend the `BaseExceptionFilter` should not be instantiated with `new`. Instead, let the framework instantiate them automatically.

Global filters **can** extend the base filter. This can be done in either of two ways.

The first method is to inject the `HttpAdapter` reference when instantiating the custom global filter:

```typescript

async function bootstrap() {
  const app = await NestFactory.create(AppModule);

  const { httpAdapter } = app.get(HttpAdapterHost);
  app.useGlobalFilters(new AllExceptionsFilter(httpAdapter));

  await app.listen(process.env.PORT ?? 3000);
}
bootstrap();
```

The second method is to use the `APP_FILTER` token [as shown here](exception-filters#binding-filters).

----
url: https://docs.nestjs.com/microservices/mqtt
----

[Skip to content](#content)

On this page

* [MQTT](https://docs.nestjs.com/microservices/mqtt#mqtt)
* [Installation](https://docs.nestjs.com/microservices/mqtt#installation)
* [Overview](https://docs.nestjs.com/microservices/mqtt#overview)
* [Options](https://docs.nestjs.com/microservices/mqtt#options)
* [Client](https://docs.nestjs.com/microservices/mqtt#client)
* [Context](https://docs.nestjs.com/microservices/mqtt#context)
* [Wildcards](https://docs.nestjs.com/microservices/mqtt#wildcards)
* [Quality of Service (QoS)](https://docs.nestjs.com/microservices/mqtt#quality-of-service-qos)
* [Per-pattern QoS](https://docs.nestjs.com/microservices/mqtt#per-pattern-qos)
* [Record builders](https://docs.nestjs.com/microservices/mqtt#record-builders)
* [Instance status updates](https://docs.nestjs.com/microservices/mqtt#instance-status-updates)
* [Listening to MQTT events](https://docs.nestjs.com/microservices/mqtt#listening-to-mqtt-events)
* [Underlying driver access](https://docs.nestjs.com/microservices/mqtt#underlying-driver-access)

### MQTT

[MQTT](https://mqtt.org/) (Message Queuing Telemetry Transport) is an open source, lightweight messaging protocol optimized for low latency. It provides a scalable and cost-efficient way to connect devices using a **publish/subscribe** model. A communication system built on MQTT consists of the publishing server, a broker, and one or more clients. The protocol is designed for constrained devices and for low-bandwidth, high-latency, or unreliable networks.

#### Installation[#](/microservices/mqtt#installation)

To start building MQTT-based microservices, first install the required package:

```bash

$ npm i --save mqtt
```

#### Overview[#](/microservices/mqtt#overview)

To use the MQTT transporter, pass the following options object to the `createMicroservice()` method:

main.ts

JS TS

```typescript

const app = await NestFactory.createMicroservice<MicroserviceOptions>(AppModule, {
  transport: Transport.MQTT,
  options: {
    url: 'mqtt://localhost:1883',
  },
});
```

```typescript

const app = await NestFactory.createMicroservice(AppModule, {
  transport: Transport.MQTT,
  options: {
    url: 'mqtt://localhost:1883',
  },
});
```

> **Hint** The `Transport` enum is imported from the `@nestjs/microservices` package.

#### Options[#](/microservices/mqtt#options)

The `options` object is specific to the chosen transporter. The **MQTT** transporter exposes the [MQTT.js client options](https://github.com/mqttjs/MQTT.js/#mqttclientstreambuilder-options), as well as the `url`, `subscribeOptions` (see [Quality of Service](/microservices/mqtt#quality-of-service-qos)), and `userProperties` (see [record builders](/microservices/mqtt#record-builders)) properties. On the server, the `maxConnectionAttempts` property limits the number of attempts to establish the initial connection (default: `-1`, i.e., unlimited). The limit doesn't apply to reconnections after the server has connected.

#### Client[#](/microservices/mqtt#client)

As with other microservice transporters, you have [several options](/microservices/basics#client-producer-class) for creating an MQTT `ClientProxy` instance.

One way to create an instance is to use the `ClientsModule`. Import it and use its `register()` method to pass an options object with the same properties shown above for the `createMicroservice()` method, plus a `name` property to use as the injection token. Read more about the `ClientsModule` in the [client section of the overview](/microservices/basics#client-producer-class).

```typescript

@Module({
  imports: [
    ClientsModule.register([
      {
        name: 'MATH_SERVICE',
        transport: Transport.MQTT,
        options: {
          url: 'mqtt://localhost:1883',
        }
      },
    ]),
  ]
  ...
})
```

You can also create a client with `ClientProxyFactory` or the `@Client()` decorator. Both are described in the [client section of the overview](/microservices/basics#client-producer-class).

#### Context[#](/microservices/mqtt#context)

In more complex scenarios, you may need additional information about the incoming request. With the MQTT transporter, you can access the `MqttContext` object.

JS TS

```typescript

@MessagePattern('notifications')
getNotifications(@Payload() data: number[], @Ctx() context: MqttContext) {
  console.log(`Topic: ${context.getTopic()}`);
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('notifications')
getNotifications(data, context) {
  console.log(`Topic: ${context.getTopic()}`);
}
```

> **Hint**`@Payload()`, `@Ctx()` and `MqttContext` are imported from the `@nestjs/microservices` package.

To access the original MQTT [packet](https://github.com/mqttjs/mqtt-packet), use the `getPacket()` method of the `MqttContext` object:

JS TS

```typescript

@MessagePattern('notifications')
getNotifications(@Payload() data: number[], @Ctx() context: MqttContext) {
  console.log(context.getPacket());
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('notifications')
getNotifications(data, context) {
  console.log(context.getPacket());
}
```

#### Wildcards[#](/microservices/mqtt#wildcards)

A subscription can target an explicit topic, or it can include wildcards. Two wildcards are available: `+` matches a single topic level, and `#` matches multiple topic levels.

JS TS

```typescript

@MessagePattern('sensors/+/temperature/+')
getTemperature(@Ctx() context: MqttContext) {
  console.log(`Topic: ${context.getTopic()}`);
}
```

```typescript

@Bind(Ctx())
@MessagePattern('sensors/+/temperature/+')
getTemperature(context) {
  console.log(`Topic: ${context.getTopic()}`);
}
```

#### Quality of Service (QoS)[#](/microservices/mqtt#quality-of-service-qos)

By default, subscriptions created with the `@MessagePattern()` and `@EventPattern()` decorators use QoS 0. If you need a higher QoS, set it globally with the `subscribeOptions` block when establishing the connection:

main.ts

JS TS

```typescript

const app = await NestFactory.createMicroservice<MicroserviceOptions>(AppModule, {
  transport: Transport.MQTT,
  options: {
    url: 'mqtt://localhost:1883',
    subscribeOptions: {
      qos: 2
    },
  },
});
```

```typescript

const app = await NestFactory.createMicroservice(AppModule, {
  transport: Transport.MQTT,
  options: {
    url: 'mqtt://localhost:1883',
    subscribeOptions: {
      qos: 2
    },
  },
});
```

#### Per-pattern QoS[#](/microservices/mqtt#per-pattern-qos)

You can override the subscription QoS for an individual pattern by passing a `qos` property in the extras object, the second argument of the `@MessagePattern()` or `@EventPattern()` decorator. Patterns without their own `qos` use the global `subscribeOptions.qos` value.

JS TS

```typescript

@EventPattern('critical-events', { qos: 2 })
handleCriticalEvent(@Payload() data: any) {
  // This subscription uses QoS 2
}

@EventPattern('metrics', { qos: 0 })
handleMetrics(@Payload() data: any) {
  // This subscription uses QoS 0
}
```

```typescript

@Bind(Payload())
@EventPattern('critical-events', { qos: 2 })
handleCriticalEvent(data) {
  // This subscription uses QoS 2
}

@Bind(Payload())
@EventPattern('metrics', { qos: 0 })
handleMetrics(data) {
  // This subscription uses QoS 0
}
```

#### Record builders[#](/microservices/mqtt#record-builders)

To configure message options (adjust the QoS level, set the Retain or DUP flags, or add properties to the payload), use the `MqttRecordBuilder` class. For example, the following record sets QoS to `1` with the `setQoS()` method and adds a user property with the `setProperties()` method:

```typescript

const userProperties = { 'x-version': '1.0.0' };
const record = new MqttRecordBuilder(':cat:')
  .setProperties({ userProperties })
  .setQoS(1)
  .build();
client.send('replace-emoji', record).subscribe(...);
```

> **Hint** The `MqttRecordBuilder` class is exported from the `@nestjs/microservices` package.

On the server side, you can read these options through the `MqttContext`:

JS TS

```typescript

@MessagePattern('replace-emoji')
replaceEmoji(@Payload() data: string, @Ctx() context: MqttContext): string {
  const { properties: { userProperties } } = context.getPacket();
  return userProperties['x-version'] === '1.0.0' ? '🐱' : '🐈';
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('replace-emoji')
replaceEmoji(data, context) {
  const { properties: { userProperties } } = context.getPacket();
  return userProperties['x-version'] === '1.0.0' ? '🐱' : '🐈';
}
```

To configure user properties for all requests sent by a client, pass them as options to the `ClientProxyFactory`:

```typescript

import { Module } from '@nestjs/common';
import { ClientProxyFactory, Transport } from '@nestjs/microservices';

@Module({
  providers: [
    {
      provide: 'API_v1',
      useFactory: () =>
        ClientProxyFactory.create({
          transport: Transport.MQTT,
          options: {
            url: 'mqtt://localhost:1883',
            userProperties: { 'x-version': '1.0.0' },
          },
        }),
    },
  ],
})
export class ApiModule {}
```

Starting with NestJS v12.1.3, a message handler can also return a record. Nest sends the record data as the reply and applies the record options (for example, the QoS level and the properties) to the reply message:

```typescript

@MessagePattern('replace-emoji')
replaceEmoji() {
  return new MqttRecordBuilder(':cat:')
    .setProperties({ userProperties: { 'x-version': '1.0.0' } })
    .setQoS(1)
    .build();
}
```

#### Instance status updates[#](/microservices/mqtt#instance-status-updates)

To get real-time updates on the connection and the state of the underlying driver instance, subscribe to the `status` stream. This stream provides status updates specific to the chosen driver. For the MQTT driver, the `status` stream emits `connected`, `disconnected`, `reconnecting`, and `closed` events.

```typescript

this.client.status.subscribe((status: MqttStatus) => {
  console.log(status);
});
```

> **Hint** The `MqttStatus` type is imported from the `@nestjs/microservices` package.

Similarly, you can subscribe to the server's `status` stream to receive notifications about the server's status.

```typescript

const server = app.connectMicroservice<MicroserviceOptions>(...);
server.status.subscribe((status: MqttStatus) => {
  console.log(status);
});
```

#### Listening to MQTT events[#](/microservices/mqtt#listening-to-mqtt-events)

In some cases, you might want to listen to internal events emitted by the microservice. For example, you could listen for the `error` event to trigger additional operations when an error occurs. To do this, use the `on()` method, as shown below:

```typescript

this.client.on('error', (err) => {
  console.error(err);
});
```

Similarly, you can listen to the server's internal events:

```typescript

server.on<MqttEvents>('error', (err) => {
  console.error(err);
});
```

> **Hint** The `MqttEvents` type is imported from the `@nestjs/microservices` package.

Starting with NestJS v12.1.2, listeners registered with the client's `on()` method stay registered until you call `close()`, so they are also attached to the new MQTT client created on the next `send()` or `emit()` call after the previous one closed without reconnecting (for example, when `reconnectPeriod` is `0`). Registrations are not deduplicated, so register each listener once rather than again from its callback or after each reconnect.

#### Underlying driver access[#](/microservices/mqtt#underlying-driver-access)

For more advanced use cases, you may need to access the underlying driver instance, for example, to close the connection manually or to use driver-specific methods. In most cases, however, you **shouldn't need** to access the driver directly.

To do so, use the `unwrap()` method, which returns the underlying driver instance. The generic type parameter specifies the type of driver instance you expect.

```typescript

const mqttClient = this.client.unwrap<import('mqtt').MqttClient>();
```

Similarly, you can access the server's underlying driver instance:

```typescript

const mqttClient = server.unwrap<import('mqtt').MqttClient>();
```

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/microservices/mqtt.md)

----
url: https://docs.nestjs.com/support
----

[Skip to content](#content)

On this page

* [Support](https://docs.nestjs.com/support#support)
* [How can you help?](https://docs.nestjs.com/support#how-can-you-help)

### Support

Nest is an MIT-licensed open source project whose ongoing development is made possible by the support of the community. The framework is the result of a long road of sleepless nights, work **after hours**, and busy weekends.

#### How can you help?[#](/support#how-can-you-help)

Nest isn't backed by a large company that continuously pays for the hours spent on its development. I rely entirely on the **goodness** ❤️ of the community. I would love to make the framework even better and stay fully focused on delivering solutions that make coding enjoyable. To make that possible, I run a few support platforms:

* become a backer or sponsor on [OpenCollective](https://opencollective.com/nest)
* send a one-time donation via [PayPal](https://paypal.me/kamilmysliwiec)
* or reach me directly at <mail@kamilmysliwiec.com>

If you love Nest, or your business uses it, consider sponsoring its development to ensure that the project your product relies on is **actively maintained** and improved. Your support also helps me create more content for the whole Nest community, such as educational blog posts and videos.

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/support.md)

----
url: https://docs.nestjs.com/v7/microservices/pipes
----

* [Pipes](https://docs.nestjs.com/v7/microservices/pipes#pipes)
* [Binding pipes](https://docs.nestjs.com/v7/microservices/pipes#binding-pipes)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/microservices/pipes.md "Suggest Edits")

### Pipes

There is no fundamental difference between [regular pipes](/v7/pipes) and microservices pipes. The only difference is that instead of throwing `HttpException`, you should use `RpcException`.

> **Hint** The `RpcException` class is exposed from `@nestjs/microservices` package.

#### Binding pipes[#](/microservices/pipes#binding-pipes)

The following example uses a manually instantiated method-scoped pipe. Just as with HTTP based applications, you can also use controller-scoped pipes (i.e., prefix the controller class with a `@UsePipes()` decorator).

JS TS

```typescript

@UsePipes(new ValidationPipe())
@MessagePattern({ cmd: 'sum' })
accumulate(data: number[]): number {
  return (data || []).reduce((a, b) => a + b);
}
```

```typescript

@UsePipes(new ValidationPipe())
@MessagePattern({ cmd: 'sum' })
accumulate(data) {
  return (data || []).reduce((a, b) => a + b);
}
```

----
url: https://docs.nestjs.com/v8/websockets/gateways
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Gateways](https://docs.nestjs.com/v8/websockets/gateways#gateways)
* [Installation](https://docs.nestjs.com/v8/websockets/gateways#installation)
* [Overview](https://docs.nestjs.com/v8/websockets/gateways#overview)
* [Multiple responses](https://docs.nestjs.com/v8/websockets/gateways#multiple-responses)
* [Asynchronous responses](https://docs.nestjs.com/v8/websockets/gateways#asynchronous-responses)
* [Lifecycle hooks](https://docs.nestjs.com/v8/websockets/gateways#lifecycle-hooks)
* [Server](https://docs.nestjs.com/v8/websockets/gateways#server)
* [Example](https://docs.nestjs.com/v8/websockets/gateways#example)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/websockets/gateways.md "Suggest Edits")

### Gateways

Most of the concepts discussed elsewhere in this documentation, such as dependency injection, decorators, exception filters, pipes, guards and interceptors, apply equally to gateways. Wherever possible, Nest abstracts implementation details so that the same components can run across HTTP-based platforms, WebSockets, and Microservices. This section covers the aspects of Nest that are specific to WebSockets.

In Nest, a gateway is simply a class annotated with `@WebSocketGateway()` decorator. Technically, gateways are platform-agnostic which makes them compatible with any WebSockets library once an adapter is created. There are two WS platforms supported out-of-the-box: [socket.io](https://github.com/socketio/socket.io) and [ws](https://github.com/websockets/ws). You can choose the one that best suits your needs. Also, you can build your own adapter by following this [guide](/v8/websockets/adapter).

> **Hint** Gateways can be treated as [providers](/v8/providers); this means they can inject dependencies through the class constructor. Also, gateways can be injected by other classes (providers and controllers) as well.

#### Installation[#](/websockets/gateways#installation)

To start building WebSockets-based applications, first install the required package:

JS TS

```typescript

$ npm i --save @nestjs/websockets @nestjs/platform-socket.io
```

```typescript

$ npm i --save @nestjs/websockets @nestjs/platform-socket.io
```

#### Overview[#](/websockets/gateways#overview)

In general, each gateway is listening on the same port as the **HTTP server**, unless your app is not a web application, or you have changed the port manually. This default behavior can be modified by passing an argument to the `@WebSocketGateway(80)` decorator where `80` is a chosen port number. You can also set a [namespace](https://socket.io/docs/v4/namespaces/) used by the gateway using the following construction:

```typescript

@WebSocketGateway(80, { namespace: 'events' })
```

> **Warning** Gateways are not instantiated until they are referenced in the providers array of an existing module.

You can pass any supported [option](https://socket.io/docs/v4/server-options/) to the socket constructor with the second argument to the `@WebSocketGateway()` decorator, as shown below:

```typescript

@WebSocketGateway(81, { transports: ['websocket'] })
```

The gateway is now listening, but we have not yet subscribed to any incoming messages. Let's create a handler that will subscribe to the `events` messages and respond to the user with the exact same data.

events.gateway.ts

JS TS

```typescript

@SubscribeMessage('events')
handleEvent(@MessageBody() data: string): string {
  return data;
}
```

```typescript

@Bind(MessageBody())
@SubscribeMessage('events')
handleEvent(data) {
  return data;
}
```

> **Hint**`@SubscribeMessage()` and `@MessageBody()` decorators are imported from `@nestjs/websockets` package.

Once the gateway is created, we can register it in our module.

events.module.ts

JS TS

```typescript

@Module({
  providers: [EventsGateway]
})
export class EventsModule {}
```

You can also pass in a property key to the decorator to extract it from the incoming message body:

events.gateway.ts

JS TS

```typescript

@SubscribeMessage('events')
handleEvent(@MessageBody('id') id: number): number {
  // id === messageBody.id
  return id;
}
```

```typescript

@Bind(MessageBody('id'))
@SubscribeMessage('events')
handleEvent(id) {
  // id === messageBody.id
  return id;
}
```

If you would prefer not to use decorators, the following code is functionally equivalent:

events.gateway.ts

JS TS

```typescript

@SubscribeMessage('events')
handleEvent(client: Socket, data: string): string {
  return data;
}
```

```typescript

@SubscribeMessage('events')
handleEvent(client, data) {
  return data;
}
```

In the example above, the `handleEvent()` function takes two arguments. The first one is a platform-specific [socket instance](https://socket.io/docs/v4/server-api/#socket), while the second one is the data received from the client. This approach is not recommended though, because it requires mocking the `socket` instance in each unit test.

Once the `events` message is received, the handler sends an acknowledgment with the same data that was sent over the network. In addition, it's possible to emit messages using a library-specific approach, for example, by making use of `client.emit()` method. In order to access a connected socket instance, use `@ConnectedSocket()` decorator.

events.gateway.ts

JS TS

```typescript

@SubscribeMessage('events')
handleEvent(
  @MessageBody() data: string,
  @ConnectedSocket() client: Socket,
): string {
  return data;
}
```

```typescript

@Bind(MessageBody(), ConnectedSocket())
@SubscribeMessage('events')
handleEvent(data, client) {
  return data;
}
```

> **Hint**`@ConnectedSocket()` decorator is imported from `@nestjs/websockets` package.

However, in this case, you won't be able to leverage interceptors. If you don't want to respond to the user, you can simply skip the `return` statement (or explicitly return a "falsy" value, e.g. `undefined`).

Now when a client emits the message as follows:

```typescript

socket.emit('events', { name: 'Nest' });
```

The `handleEvent()` method will be executed. In order to listen for messages emitted from within the above handler, the client has to attach a corresponding acknowledgment listener:

```typescript

socket.emit('events', { name: 'Nest' }, (data) => console.log(data));
```

#### Multiple responses[#](/websockets/gateways#multiple-responses)

The acknowledgment is dispatched only once. Furthermore, it is not supported by native WebSockets implementation. To solve this limitation, you may return an object which consists of two properties. The `event` which is a name of the emitted event and the `data` that has to be forwarded to the client.

events.gateway.ts

JS TS

```typescript

@SubscribeMessage('events')
handleEvent(@MessageBody() data: unknown): WsResponse<unknown> {
  const event = 'events';
  return { event, data };
}
```

```typescript

@Bind(MessageBody())
@SubscribeMessage('events')
handleEvent(data) {
  const event = 'events';
  return { event, data };
}
```

> **Hint** The `WsResponse` interface is imported from `@nestjs/websockets` package.

> **Warning** You should return a class instance that implements `WsResponse` if your `data` field relies on `ClassSerializerInterceptor`, as it ignores plain JavaScript object responses.

In order to listen for the incoming response(s), the client has to apply another event listener.

```typescript

socket.on('events', (data) => console.log(data));
```

#### Asynchronous responses[#](/websockets/gateways#asynchronous-responses)

Message handlers are able to respond either synchronously or **asynchronously**. Hence, `async` methods are supported. A message handler is also able to return an `Observable`, in which case the result values will be emitted until the stream is completed.

events.gateway.ts

JS TS

```typescript

@SubscribeMessage('events')
onEvent(@MessageBody() data: unknown): Observable<WsResponse<number>> {
  const event = 'events';
  const response = [1, 2, 3];

  return from(response).pipe(
    map(data => ({ event, data })),
  );
}
```

```typescript

@Bind(MessageBody())
@SubscribeMessage('events')
onEvent(data) {
  const event = 'events';
  const response = [1, 2, 3];

  return from(response).pipe(
    map(data => ({ event, data })),
  );
}
```

In the example above, the message handler will respond **3 times** (with each item from the array).

#### Lifecycle hooks[#](/websockets/gateways#lifecycle-hooks)

There are 3 useful lifecycle hooks available. All of them have corresponding interfaces and are described in the following table:

|                       |                                                                                                                                         |
| --------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| `OnGatewayInit`       | Forces to implement the `afterInit()` method. Takes library-specific server instance as an argument (and spreads the rest if required). |
| `OnGatewayConnection` | Forces to implement the `handleConnection()` method. Takes library-specific client socket instance as an argument.                      |
| `OnGatewayDisconnect` | Forces to implement the `handleDisconnect()` method. Takes library-specific client socket instance as an argument.                      |

> **Hint** Each lifecycle interface is exposed from `@nestjs/websockets` package.

#### Server[#](/websockets/gateways#server)

Occasionally, you may want to have a direct access to the native, **platform-specific** server instance. The reference to this object is passed as an argument to the `afterInit()` method (`OnGatewayInit` interface). Another option is to use the `@WebSocketServer()` decorator.

```typescript

@WebSocketServer()
server: Server;
```

> **Notice** The `@WebSocketServer()` decorator is imported from the `@nestjs/websockets` package.

----
url: https://docs.nestjs.com/v7/fundamentals/platform-agnosticism
----

* [Platform agnosticism](https://docs.nestjs.com/v7/fundamentals/platform-agnosticism#platform-agnosticism)
* [Build once, use everywhere](https://docs.nestjs.com/v7/fundamentals/platform-agnosticism#build-once-use-everywhere)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/fundamentals/platform-agnosticism.md "Suggest Edits")

### Platform agnosticism

Nest is a platform-agnostic framework. This means you can develop **reusable logical parts** that can be used across different types of applications. For example, most components can be re-used without change across different underlying HTTP server frameworks (e.g., Express and Fastify), and even across different *types* of applications (e.g., HTTP server frameworks, Microservices with different transport layers, and Web Sockets).

#### Build once, use everywhere[#](/fundamentals/platform-agnosticism#build-once-use-everywhere)

The **Overview** section of the documentation primarily shows coding techniques using HTTP server frameworks (e.g., apps providing a REST API or providing an MVC-style server-side rendered app). However, all those building blocks can be used on top of different transport layers ([microservices](/v7/microservices/basics) or [websockets](/v7/websockets/gateways)).

Furthermore, Nest comes with a dedicated [GraphQL](/v7/graphql/quick-start) module. You can use GraphQL as your API layer interchangeably with providing a REST API.

In addition, the [application context](/v7/application-context) feature helps to create any kind of Node.js application - including things like CRON jobs and CLI apps - on top of Nest.

Nest aspires to be a full-fledged platform for Node.js apps that brings a higher-level of modularity and reusability to your applications. Build once, use everywhere!

----
url: https://docs.nestjs.com/v11/graphql/quick-start
----

* [Installation](https://docs.nestjs.com/v11/graphql/quick-start#installation)
* [Overview](https://docs.nestjs.com/v11/graphql/quick-start#overview)
* [Getting started with GraphQL & TypeScript](https://docs.nestjs.com/v11/graphql/quick-start#getting-started-with-graphql--typescript)
* [GraphQL playground](https://docs.nestjs.com/v11/graphql/quick-start#graphql-playground)
* [Code first](https://docs.nestjs.com/v11/graphql/quick-start#code-first)
* [Example](https://docs.nestjs.com/v11/graphql/quick-start#example)
* [Schema first](https://docs.nestjs.com/v11/graphql/quick-start#schema-first)
* [Apollo Sandbox](https://docs.nestjs.com/v11/graphql/quick-start#apollo-sandbox)
* [Example](https://docs.nestjs.com/v11/graphql/quick-start#example-1)
* [Accessing generated schema](https://docs.nestjs.com/v11/graphql/quick-start#accessing-generated-schema)
* [Async configuration](https://docs.nestjs.com/v11/graphql/quick-start#async-configuration)
* [Mercurius integration](https://docs.nestjs.com/v11/graphql/quick-start#mercurius-integration)
* [Multiple endpoints](https://docs.nestjs.com/v11/graphql/quick-start#multiple-endpoints)
* [Third-party integrations](https://docs.nestjs.com/v11/graphql/quick-start#third-party-integrations)
* [Example](https://docs.nestjs.com/v11/graphql/quick-start#example-2)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/quick-start.md "Suggest Edits")

## Harnessing the power of TypeScript & GraphQL

[GraphQL](https://graphql.org/) is a powerful query language for APIs and a runtime for fulfilling those queries with your existing data. It's an elegant approach that solves many problems typically found with REST APIs. For background, we suggest reading this [comparison](https://www.apollographql.com/blog/graphql-vs-rest) between GraphQL and REST. GraphQL combined with [TypeScript](https://www.typescriptlang.org/) helps you develop better type safety with your GraphQL queries, giving you end-to-end typing.

In this chapter, we assume a basic understanding of GraphQL, and focus on how to work with the built-in `@nestjs/graphql` module. The `GraphQLModule` can be configured to use [Apollo](https://www.apollographql.com/) server (with the `@nestjs/apollo` driver) and [Mercurius](https://github.com/mercurius-js/mercurius) (with the `@nestjs/mercurius`). We provide official integrations for these proven GraphQL packages to provide a simple way to use GraphQL with Nest (see more integrations [here](https://docs.nestjs.com/graphql/quick-start#third-party-integrations)).

You can also build your own dedicated driver (read more on that [here](/graphql/other-features#creating-a-custom-driver)).

#### Installation[#](/graphql/quick-start#installation)

Start by installing the required packages:

```bash

# For Express and Apollo (default)
$ npm i @nestjs/graphql @nestjs/apollo @apollo/server @as-integrations/express5 graphql

# For Fastify and Apollo
# npm i @nestjs/graphql @nestjs/apollo @apollo/server @as-integrations/fastify graphql

# For Fastify and Mercurius
# npm i @nestjs/graphql @nestjs/mercurius graphql mercurius
```

> **Warning**`@nestjs/graphql@>=9` and `@nestjs/apollo^10` packages are compatible with **Apollo v3** (check out Apollo Server 3 [migration guide](https://www.apollographql.com/docs/apollo-server/migration/) for more details), while `@nestjs/graphql@^8` only supports **Apollo v2** (e.g., `apollo-server-express@2.x.x` package).

#### Overview[#](/graphql/quick-start#overview)

Nest offers two ways of building GraphQL applications, the **code first** and the **schema first** methods. You should choose the one that works best for you. Most of the chapters in this GraphQL section are divided into two main parts: one you should follow if you adopt **code first**, and the other to be used if you adopt **schema first**.

In the **code first** approach, you use decorators and TypeScript classes to generate the corresponding GraphQL schema. This approach is useful if you prefer to work exclusively with TypeScript and avoid context switching between language syntaxes.

In the **schema first** approach, the source of truth is GraphQL SDL (Schema Definition Language) files. SDL is a language-agnostic way to share schema files between different platforms. Nest automatically generates your TypeScript definitions (using either classes or interfaces) based on the GraphQL schemas to reduce the need to write redundant boilerplate code.

> **Hint** In the following chapters, we'll be integrating the `@nestjs/apollo` package. If you want to use `mercurius` package instead, navigate to [this section](/graphql/quick-start#mercurius-integration).

Once the packages are installed, we can import the `GraphQLModule` and configure it with the `forRoot()` static method.

JS TS

```typescript

import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';
import { ApolloDriver, ApolloDriverConfig } from '@nestjs/apollo';

@Module({
  imports: [
    GraphQLModule.forRoot<ApolloDriverConfig>({
      driver: ApolloDriver,
    }),
  ],
})
export class AppModule {}
```

> **Hint** For `mercurius` integration, you should be using the `MercuriusDriver` and `MercuriusDriverConfig` instead. Both are exported from the `@nestjs/mercurius` package.

The `forRoot()` method takes an options object as an argument. These options are passed through to the underlying driver instance (read more about available settings here: [Apollo](https://www.apollographql.com/docs/apollo-server/api/apollo-server) and [Mercurius](https://github.com/mercurius-js/mercurius/blob/master/docs/api/options.md#plugin-options)). For example, if you want to disable the `playground` and turn off `debug` mode (for Apollo), pass the following options:

JS TS

```typescript

import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';
import { ApolloDriver, ApolloDriverConfig } from '@nestjs/apollo';

@Module({
  imports: [
    GraphQLModule.forRoot<ApolloDriverConfig>({
      driver: ApolloDriver,
      playground: false,
    }),
  ],
})
export class AppModule {}
```

In this case, these options will be forwarded to the `ApolloServer` constructor.

#### GraphQL playground[#](/graphql/quick-start#graphql-playground)

The playground is a graphical, interactive, in-browser GraphQL IDE, available by default on the same URL as the GraphQL server itself. To access the playground, you need a basic GraphQL server configured and running. To see it now, you can install and build the [working example here](https://github.com/nestjs/nest/tree/master/sample/23-graphql-code-first). Alternatively, if you're following along with these code samples, once you've completed the steps in the [Resolvers chapter](/v11/graphql/resolvers-map), you can access the playground.

With that in place, and with your application running in the background, you can then open your web browser and navigate to `http://localhost:3000/graphql` (host and port may vary depending on your configuration). You will then see the GraphQL playground, as shown below.

> **Note**`@nestjs/mercurius` integration does not ship with the built-in GraphQL Playground integration. Instead, you can use [GraphiQL](https://github.com/graphql/graphiql) (set `graphiql: true`).

> **Warning** Update (04/14/2025): The default Apollo playground has been deprecated and will be removed in the next major release. Instead, you can use [GraphiQL](https://github.com/graphql/graphiql), just set `graphiql: true` in the `GraphQLModule` configuration, as shown below:
>
> ```typescript
>
> GraphQLModule.forRoot<ApolloDriverConfig>({
>   driver: ApolloDriver,
>   graphiql: true,
> }),
> ```
>
> If your application uses [subscriptions](/v11/graphql/subscriptions), be sure to use `graphql-ws`, as `subscriptions-transport-ws` isn't supported by GraphiQL.

#### Code first[#](/graphql/quick-start#code-first)

In the **code first** approach, you use decorators and TypeScript classes to generate the corresponding GraphQL schema.

To use the code first approach, start by adding the `autoSchemaFile` property to the options object:

```typescript

GraphQLModule.forRoot<ApolloDriverConfig>({
  driver: ApolloDriver,
  autoSchemaFile: join(process.cwd(), 'src/schema.gql'),
}),
```

The `autoSchemaFile` property value is the path where your automatically generated schema will be created. Alternatively, the schema can be generated on-the-fly in memory. To enable this, set the `autoSchemaFile` property to `true`:

```typescript

GraphQLModule.forRoot<ApolloDriverConfig>({
  driver: ApolloDriver,
  autoSchemaFile: true,
}),
```

By default, the types in the generated schema will be in the order they are defined in the included modules. To sort the schema lexicographically, set the `sortSchema` property to `true`:

```typescript

GraphQLModule.forRoot<ApolloDriverConfig>({
  driver: ApolloDriver,
  autoSchemaFile: join(process.cwd(), 'src/schema.gql'),
  sortSchema: true,
}),
```

#### Example[#](/graphql/quick-start#example)

A fully working code first sample is available [here](https://github.com/nestjs/nest/tree/master/sample/23-graphql-code-first).

#### Schema first[#](/graphql/quick-start#schema-first)

To use the schema first approach, start by adding a `typePaths` property to the options object. The `typePaths` property indicates where the `GraphQLModule` should look for GraphQL SDL schema definition files you'll be writing. These files will be combined in memory; this allows you to split your schemas into several files and locate them near their resolvers.

```typescript

GraphQLModule.forRoot<ApolloDriverConfig>({
  driver: ApolloDriver,
  typePaths: ['./**/*.graphql'],
}),
```

You will typically also need to have TypeScript definitions (classes and interfaces) that correspond to the GraphQL SDL types. Creating the corresponding TypeScript definitions by hand is redundant and tedious. It leaves us without a single source of truth -- each change made within SDL forces us to adjust TypeScript definitions as well. To address this, the `@nestjs/graphql` package can **automatically generate** TypeScript definitions from the abstract syntax tree ([AST](https://en.wikipedia.org/wiki/Abstract_syntax_tree)). To enable this feature, add the `definitions` options property when configuring the `GraphQLModule`.

```typescript

GraphQLModule.forRoot<ApolloDriverConfig>({
  driver: ApolloDriver,
  typePaths: ['./**/*.graphql'],
  definitions: {
    path: join(process.cwd(), 'src/graphql.ts'),
  },
}),
```

The path property of the `definitions` object indicates where to save generated TypeScript output. By default, all generated TypeScript types are created as interfaces. To generate classes instead, specify the `outputAs` property with a value of `'class'`.

```typescript

GraphQLModule.forRoot<ApolloDriverConfig>({
  driver: ApolloDriver,
  typePaths: ['./**/*.graphql'],
  definitions: {
    path: join(process.cwd(), 'src/graphql.ts'),
    outputAs: 'class',
  },
}),
```

The above approach dynamically generates TypeScript definitions each time the application starts. Alternatively, it may be preferable to build a simple script to generate these on demand. For example, assume we create the following script as `generate-typings.ts`:

```typescript

import { GraphQLDefinitionsFactory } from '@nestjs/graphql';
import { join } from 'node:path';

const definitionsFactory = new GraphQLDefinitionsFactory();
definitionsFactory.generate({
  typePaths: ['./src/**/*.graphql'],
  path: join(process.cwd(), 'src/graphql.ts'),
  outputAs: 'class',
});
```

Now you can run this script on demand:

```bash

$ ts-node generate-typings
```

> **Hint** You can compile the script beforehand (e.g., with `tsc`) and use `node` to execute it.

To enable watch mode for the script (to automatically generate typings whenever any `.graphql` file changes), pass the `watch` option to the `generate()` method.

```typescript

definitionsFactory.generate({
  typePaths: ['./src/**/*.graphql'],
  path: join(process.cwd(), 'src/graphql.ts'),
  outputAs: 'class',
  watch: true,
});
```

To automatically generate the additional `__typename` field for every object type, enable the `emitTypenameField` option:

```typescript

definitionsFactory.generate({
  // ...
  emitTypenameField: true,
});
```

To generate resolvers (queries, mutations, subscriptions) as plain fields without arguments, enable the `skipResolverArgs` option:

```typescript

definitionsFactory.generate({
  // ...
  skipResolverArgs: true,
});
```

To generate enums as TypeScript union types instead of regular TypeScript enums, set the `enumsAsTypes` option to `true`:

```typescript

definitionsFactory.generate({
  // ...
  enumsAsTypes: true,
});
```

#### Apollo Sandbox[#](/graphql/quick-start#apollo-sandbox)

To use [Apollo Sandbox](https://www.apollographql.com/blog/announcement/platform/apollo-sandbox-an-open-graphql-ide-for-local-development/) instead of the `graphql-playground` as a GraphQL IDE for local development, use the following configuration:

```typescript

import { ApolloDriver, ApolloDriverConfig } from '@nestjs/apollo';
import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';
import { ApolloServerPluginLandingPageLocalDefault } from '@apollo/server/plugin/landingPage/default';

@Module({
  imports: [
    GraphQLModule.forRoot<ApolloDriverConfig>({
      driver: ApolloDriver,
      playground: false,
      plugins: [ApolloServerPluginLandingPageLocalDefault()],
    }),
  ],
})
export class AppModule {}
```

#### Example[#](/graphql/quick-start#example-1)

A fully working schema first sample is available [here](https://github.com/nestjs/nest/tree/master/sample/12-graphql-schema-first).

#### Accessing generated schema[#](/graphql/quick-start#accessing-generated-schema)

In some circumstances (for example end-to-end tests), you may want to get a reference to the generated schema object. In end-to-end tests, you can then run queries using the `graphql` object without using any HTTP listeners.

You can access the generated schema (in either the code first or schema first approach), using the `GraphQLSchemaHost` class:

```typescript

const { schema } = app.get(GraphQLSchemaHost);
```

> **Hint** You must call the `GraphQLSchemaHost#schema` getter after the application has been initialized (after the `onModuleInit` hook has been triggered by either the `app.listen()` or `app.init()` method).

#### Async configuration[#](/graphql/quick-start#async-configuration)

When you need to pass module options asynchronously instead of statically, use the `forRootAsync()` method. As with most dynamic modules, Nest provides several techniques to deal with async configuration.

One technique is to use a factory function:

```typescript

 GraphQLModule.forRootAsync<ApolloDriverConfig>({
  driver: ApolloDriver,
  useFactory: () => ({
    typePaths: ['./**/*.graphql'],
  }),
}),
```

Like other factory providers, our factory function can be [async](https://docs.nestjs.com/fundamentals/custom-providers#factory-providers-usefactory) and can inject dependencies through `inject`.

```typescript

GraphQLModule.forRootAsync<ApolloDriverConfig>({
  driver: ApolloDriver,
  imports: [ConfigModule],
  useFactory: async (configService: ConfigService) => ({
    typePaths: configService.get<string>('GRAPHQL_TYPE_PATHS'),
  }),
  inject: [ConfigService],
}),
```

Alternatively, you can configure the `GraphQLModule` using a class instead of a factory, as shown below:

```typescript

GraphQLModule.forRootAsync<ApolloDriverConfig>({
  driver: ApolloDriver,
  useClass: GqlConfigService,
}),
```

The construction above instantiates `GqlConfigService` inside `GraphQLModule`, using it to create options object. Note that in this example, the `GqlConfigService` has to implement the `GqlOptionsFactory` interface, as shown below. The `GraphQLModule` will call the `createGqlOptions()` method on the instantiated object of the supplied class.

```typescript

@Injectable()
class GqlConfigService implements GqlOptionsFactory {
  createGqlOptions(): ApolloDriverConfig {
    return {
      typePaths: ['./**/*.graphql'],
    };
  }
}
```

If you want to reuse an existing options provider instead of creating a private copy inside the `GraphQLModule`, use the `useExisting` syntax.

```typescript

GraphQLModule.forRootAsync<ApolloDriverConfig>({
  imports: [ConfigModule],
  useExisting: ConfigService,
}),
```

#### Mercurius integration[#](/graphql/quick-start#mercurius-integration)

Instead of using Apollo, Fastify users (read more [here](/v11/techniques/performance)) can alternatively use the `@nestjs/mercurius` driver.

JS TS

```typescript

import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';
import { MercuriusDriver, MercuriusDriverConfig } from '@nestjs/mercurius';

@Module({
  imports: [
    GraphQLModule.forRoot<MercuriusDriverConfig>({
      driver: MercuriusDriver,
      graphiql: true,
    }),
  ],
})
export class AppModule {}
```

> **Hint** Once the application is running, open your browser and navigate to `http://localhost:3000/graphiql`. You should see the [GraphQL IDE](https://github.com/graphql/graphiql).

The `forRoot()` method takes an options object as an argument. These options are passed through to the underlying driver instance. Read more about available settings [here](https://github.com/mercurius-js/mercurius/blob/master/docs/api/options.md#plugin-options).

#### Multiple endpoints[#](/graphql/quick-start#multiple-endpoints)

Another useful feature of the `@nestjs/graphql` module is the ability to serve multiple endpoints at once. This lets you decide which modules should be included in which endpoint. By default, `GraphQL` searches for resolvers throughout the whole app. To limit this scan to only a subset of modules, use the `include` property.

```typescript

GraphQLModule.forRoot({
  include: [CatsModule],
}),
```

> **Warning** If you use the `@apollo/server` with `@as-integrations/fastify` package with multiple GraphQL endpoints in a single application, make sure to enable the `disableHealthCheck` setting in the `GraphQLModule` configuration.

#### Third-party integrations[#](/graphql/quick-start#third-party-integrations)

* [GraphQL Yoga](https://github.com/dotansimha/graphql-yoga)

#### Example[#](/graphql/quick-start#example-2)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/33-graphql-mercurius).

----
url: https://docs.nestjs.com/v9/techniques/logger
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Logger](https://docs.nestjs.com/v9/techniques/logger#logger)
* [Basic customization](https://docs.nestjs.com/v9/techniques/logger#basic-customization)
* [Custom implementation](https://docs.nestjs.com/v9/techniques/logger#custom-implementation)
* [Extend built-in logger](https://docs.nestjs.com/v9/techniques/logger#extend-built-in-logger)
* [Dependency injection](https://docs.nestjs.com/v9/techniques/logger#dependency-injection)
* [Using the logger for application logging](https://docs.nestjs.com/v9/techniques/logger#using-the-logger-for-application-logging)
* [Injecting a custom logger](https://docs.nestjs.com/v9/techniques/logger#injecting-a-custom-logger)
* [Use external logger](https://docs.nestjs.com/v9/techniques/logger#use-external-logger)

```typescript

const app = await NestFactory.create(AppModule, {
  logger: false,
});
await app.listen(3000);
```

To enable specific logging levels, set the `logger` property to an array of strings specifying the log levels to display, as follows:

```typescript

const app = await NestFactory.create(AppModule, {
  logger: ['error', 'warn'],
});
await app.listen(3000);
```

Values in the array can be any combination of `'log'`, `'error'`, `'warn'`, `'debug'`, and `'verbose'`.

> **Hint** To disable color in the default logger's messages, set the `NO_COLOR` environment variable to some non-empty string.

#### Custom implementation[#](/techniques/logger#custom-implementation)

You can provide a custom logger implementation to be used by Nest for system logging by setting the value of the `logger` property to an object that fulfills the `LoggerService` interface. For example, you can tell Nest to use the built-in global JavaScript `console` object (which implements the `LoggerService` interface), as follows:

```typescript

const app = await NestFactory.create(AppModule, {
  logger: console,
});
await app.listen(3000);
```

Implementing your own custom logger is straightforward. Simply implement each of the methods of the `LoggerService` interface as shown below.

```typescript

import { LoggerService } from '@nestjs/common';

export class MyLogger implements LoggerService {
  /**
   * Write a 'log' level log.
   */
  log(message: any, ...optionalParams: any[]) {}

  /**
   * Write an 'error' level log.
   */
  error(message: any, ...optionalParams: any[]) {}

  /**
   * Write a 'warn' level log.
   */
  warn(message: any, ...optionalParams: any[]) {}

  /**
   * Write a 'debug' level log.
   */
  debug?(message: any, ...optionalParams: any[]) {}

  /**
   * Write a 'verbose' level log.
   */
  verbose?(message: any, ...optionalParams: any[]) {}
}
```

You can then supply an instance of `MyLogger` via the `logger` property of the Nest application options object.

```typescript

const app = await NestFactory.create(AppModule, {
  logger: new MyLogger(),
});
await app.listen(3000);
```

This technique, while simple, doesn't utilize dependency injection for the `MyLogger` class. This can pose some challenges, particularly for testing, and limit the reusability of `MyLogger`. For a better solution, see the [Dependency Injection](techniques/logger#dependency-injection) section below.

#### Extend built-in logger[#](/techniques/logger#extend-built-in-logger)

Rather than writing a logger from scratch, you may be able to meet your needs by extending the built-in `ConsoleLogger` class and overriding selected behavior of the default implementation.

```typescript

import { ConsoleLogger } from '@nestjs/common';

export class MyLogger extends ConsoleLogger {
  error(message: any, stack?: string, context?: string) {
    // add your tailored logic here
    super.error(...arguments);
  }
}
```

```typescript

import { Module } from '@nestjs/common';
import { MyLogger } from './my-logger.service';

@Module({
  providers: [MyLogger],
  exports: [MyLogger],
})
export class LoggerModule {}
```

With this construct, you are now providing your custom logger for use by any other module. Because your `MyLogger` class is part of a module, it can use dependency injection (for example, to inject a `ConfigService`). There's one more technique needed to provide this custom logger for use by Nest for system logging (e.g., for bootstrapping and error handling).

Because application instantiation (`NestFactory.create()`) happens outside the context of any module, it doesn't participate in the normal Dependency Injection phase of initialization. So we must ensure that at least one application module imports the `LoggerModule` to trigger Nest to instantiate a singleton instance of our `MyLogger` class.

We can then instruct Nest to use the same singleton instance of `MyLogger` with the following construction:

```typescript

const app = await NestFactory.create(AppModule, {
  bufferLogs: true,
});
app.useLogger(app.get(MyLogger));
await app.listen(3000);
```

> **Note** In the example above, we set the `bufferLogs` to `true` to make sure all logs will be buffered until a custom logger is attached (`MyLogger` in this case) and the application initialisation process either completes or fails. If the initialisation process fails, Nest will fallback to the original `ConsoleLogger` to print out any reported error messages. Also, you can set the `autoFlushLogs` to `false` (default `true`) to manually flush logs (using the `Logger#flush()` method).

Here we use the `get()` method on the `NestApplication` instance to retrieve the singleton instance of the `MyLogger` object. This technique is essentially a way to "inject" an instance of a logger for use by Nest. The `app.get()` call retrieves the singleton instance of `MyLogger`, and depends on that instance being first injected in another module, as described above.

You can also inject this `MyLogger` provider in your feature classes, thus ensuring consistent logging behavior across both Nest system logging and application logging. See [Using the logger for application logging](techniques/logger#using-the-logger-for-application-logging) and [Injecting a custom logger](techniques/logger#injecting-a-custom-logger) below for more information.

#### Using the logger for application logging[#](/techniques/logger#using-the-logger-for-application-logging)

We can combine several of the techniques above to provide consistent behavior and formatting across both Nest system logging and our own application event/message logging.

A good practice is to instantiate `Logger` class from `@nestjs/common` in each of our services. We can supply our service name as the `context` argument in the `Logger` constructor, like so:

```typescript

import { Logger, Injectable } from '@nestjs/common';

@Injectable()
class MyService {
  private readonly logger = new Logger(MyService.name);

  doSomething() {
    this.logger.log('Doing something...');
  }
}
```

In the default logger implementation, `context` is printed in the square brackets, like `NestFactory` in the example below:

```bash

[Nest] 19096   - 12/08/2019, 7:12:59 AM   [NestFactory] Starting Nest application...
```

If we supply a custom logger via `app.useLogger()`, it will actually be used by Nest internally. That means that our code remains implementation agnostic, while we can easily substitute the default logger for our custom one by calling `app.useLogger()`.

That way if we follow the steps from the previous section and call `app.useLogger(app.get(MyLogger))`, the following calls to `this.logger.log()` from `MyService` would result in calls to method `log` from `MyLogger` instance.

This should be suitable for most cases. But if you need more customization (like adding and calling custom methods), move to the next section.

#### Injecting a custom logger[#](/techniques/logger#injecting-a-custom-logger)

To start, extend the built-in logger with code like the following. We supply the `scope` option as configuration metadata for the `ConsoleLogger` class, specifying a [transient](/v9/fundamentals/injection-scopes) scope, to ensure that we'll have a unique instance of the `MyLogger` in each feature module. In this example, we do not extend the individual `ConsoleLogger` methods (like `log()`, `warn()`, etc.), though you may choose to do so.

```typescript

import { Injectable, Scope, ConsoleLogger } from '@nestjs/common';

@Injectable({ scope: Scope.TRANSIENT })
export class MyLogger extends ConsoleLogger {
  customLog() {
    this.log('Please feed the cat!');
  }
}
```

Next, create a `LoggerModule` with a construction like this:

```typescript

import { Module } from '@nestjs/common';
import { MyLogger } from './my-logger.service';

@Module({
  providers: [MyLogger],
  exports: [MyLogger],
})
export class LoggerModule {}
```

Next, import the `LoggerModule` into your feature module. Since we extended default `Logger` we have the convenience of using `setContext` method. So we can start using the context-aware custom logger, like this:

```typescript

import { Injectable } from '@nestjs/common';
import { MyLogger } from './my-logger.service';

@Injectable()
export class CatsService {
  private readonly cats: Cat[] = [];

  constructor(private myLogger: MyLogger) {
    // Due to transient scope, CatsService has its own unique instance of MyLogger,
    // so setting context here will not affect other instances in other services
    this.myLogger.setContext('CatsService');
  }

  findAll(): Cat[] {
    // You can call all the default methods
    this.myLogger.warn('About to return cats!');
    // And your custom methods
    this.myLogger.customLog();
    return this.cats;
  }
}
```

Finally, instruct Nest to use an instance of the custom logger in your `main.ts` file as shown below. Of course in this example, we haven't actually customized the logger behavior (by extending the `Logger` methods like `log()`, `warn()`, etc.), so this step isn't actually needed. But it **would** be needed if you added custom logic to those methods and wanted Nest to use the same implementation.

```typescript

const app = await NestFactory.create(AppModule, {
  bufferLogs: true,
});
app.useLogger(new MyLogger());
await app.listen(3000);
```

> **Hint** Alternatively, instead of setting `bufferLogs` to `true`, you could temporarily disable the logger with `logger: false` instruction. Be mindful that if you supply `logger: false` to `NestFactory.create`, nothing will be logged until you call `useLogger`, so you may miss some important initialization errors. If you don't mind that some of your initial messages will be logged with the default logger, you can just omit the `logger: false` option.

#### Use external logger[#](/techniques/logger#use-external-logger)

Production applications often have specific logging requirements, including advanced filtering, formatting and centralized logging. Nest's built-in logger is used for monitoring Nest system behavior, and can also be useful for basic formatted text logging in your feature modules while in development, but production applications often take advantage of dedicated logging modules like [Winston](https://github.com/winstonjs/winston). As with any standard Node.js application, you can take full advantage of such modules in Nest.

----
url: https://docs.nestjs.com/v8/openapi/cli-plugin
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [CLI Plugin](https://docs.nestjs.com/v8/openapi/cli-plugin#cli-plugin)
* [Overview](https://docs.nestjs.com/v8/openapi/cli-plugin#overview)
* [Comments introspection](https://docs.nestjs.com/v8/openapi/cli-plugin#comments-introspection)
* [Using the CLI plugin](https://docs.nestjs.com/v8/openapi/cli-plugin#using-the-cli-plugin)
* [Integration with ts-jest (e2e tests)](https://docs.nestjs.com/v8/openapi/cli-plugin#integration-with-ts-jest-e2e-tests)
* [Troubleshooting jest (e2e tests)](https://docs.nestjs.com/v8/openapi/cli-plugin#troubleshooting-jest-e2e-tests)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/openapi/cli-plugin.md "Suggest Edits")

### CLI Plugin

TypeScript's metadata reflection system has several limitations which make it impossible to, for instance, determine what properties a class consists of or recognize whether a given property is optional or required. However, some of these constraints can be addressed at compilation time. Nest provides a plugin that enhances the TypeScript compilation process to reduce the amount of boilerplate code required.

> **Hint** This plugin is **opt-in**. If you prefer, you can declare all decorators manually, or only specific decorators where you need them.

```typescript

export class CreateUserDto {
  @ApiProperty()
  email: string;

  @ApiProperty()
  password: string;

  @ApiProperty({ enum: RoleEnum, default: [], isArray: true })
  roles: RoleEnum[] = [];

  @ApiProperty({ required: false, default: true })
  isEnabled?: boolean = true;
}
```

While not a significant issue with medium-sized projects, it becomes verbose & hard to maintain once you have a large set of classes.

By [enabling the Swagger plugin](/openapi/cli-plugin#using-the-cli-plugin), the above class definition can be declared simply:

```typescript

export class CreateUserDto {
  email: string;
  password: string;
  roles: RoleEnum[] = [];
  isEnabled?: boolean = true;
}
```

The plugin adds appropriate decorators on the fly based on the **Abstract Syntax Tree**. Thus you won't have to struggle with `@ApiProperty` decorators scattered throughout the code.

> **Hint** The plugin will automatically generate any missing swagger properties, but if you need to override them, you simply set them explicitly via `@ApiProperty()`.

#### Comments introspection[#](/openapi/cli-plugin#comments-introspection)

With the comments introspection feature enabled, CLI plugin will generate descriptions and example values for properties based on comments.

For example, given an example `roles` property:

```typescript

/**
 * A list of user's roles
 * @example ['admin']
 */
@ApiProperty({
  description: `A list of user's roles`,
  example: ['admin'],
})
roles: RoleEnum[] = [];
```

You must duplicate both description and example values. With `introspectComments` enabled, the CLI plugin can extract these comments and automatically provide descriptions (and examples, if defined) for properties. Now, the above property can be declared simply as follows:

```typescript

/**
 * A list of user's roles
 * @example ['admin']
 */
roles: RoleEnum[] = [];
```

There are `dtoKeyOfComment` and `controllerKeyOfComment` plugin options that you can use to customize how the plugin will set the value for `ApiProperty` and `ApiOperation` decorators respectively. Take a look at the following example:

```typescript

export class SomeController {
  /**
   * Create some resource
   */
  @Post()
  create() {}
}
```

By default, these options are set to `"description"`. This means the plugin will assign `"Create some resource"` to `description` key on the `ApiOperation` operator. Like so:

```ts

@ApiOperation({ description: "Create some resource" })
```

> **Hint** For models, the same logic applies but to `ApiProperty` decorator instead.

#### Using the CLI plugin[#](/openapi/cli-plugin#using-the-cli-plugin)

To enable the plugin, open `nest-cli.json` (if you use [Nest CLI](/v8/cli/overview)) and add the following `plugins` configuration:

```javascript

{
  "collection": "@nestjs/schematics",
  "sourceRoot": "src",
  "compilerOptions": {
    "plugins": ["@nestjs/swagger"]
  }
}
```

You can use the `options` property to customize the behavior of the plugin.

```javascript

"plugins": [
  {
    "name": "@nestjs/swagger",
    "options": {
      "classValidatorShim": false,
      "introspectComments": true
    }
  }
]
```

The `options` property has to fulfill the following interface:

```typescript

export interface PluginOptions {
  dtoFileNameSuffix?: string[];
  controllerFileNameSuffix?: string[];
  classValidatorShim?: boolean;
  dtoKeyOfComment?: string;
  controllerKeyOfComment?: string;
  introspectComments?: boolean;
}
```

| Option                     | Default                     | Description                                                                                                                             |
| -------------------------- | --------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| `dtoFileNameSuffix`        | `['.dto.ts', '.entity.ts']` | DTO (Data Transfer Object) files suffix                                                                                                 |
| `controllerFileNameSuffix` | `.controller.ts`            | Controller files suffix                                                                                                                 |
| `classValidatorShim`       | `true`                      | If set to true, the module will reuse `class-validator` validation decorators (e.g. `@Max(10)` will add `max: 10` to schema definition) |
| `dtoKeyOfComment`          | `'description'`             | The property key to set the comment text to on `ApiProperty`.                                                                           |
| `controllerKeyOfComment`   | `'description'`             | The property key to set the comment text to on `ApiOperation`.                                                                          |
| `introspectComments`       | `false`                     | If set to true, plugin will generate descriptions and example values for properties based on comments                                   |

If you don't use the CLI but instead have a custom `webpack` configuration, you can use this plugin in combination with `ts-loader`:

```javascript

getCustomTransformers: (program: any) => ({
  before: [require('@nestjs/swagger/plugin').before({}, program)]
}),
```

#### Integration with `ts-jest` (e2e tests)[#](/openapi/cli-plugin#integration-with-ts-jest-e2e-tests)

To run e2e tests, `ts-jest` compiles your source code files on the fly, in memory. This means, it doesn't use Nest CLI compiler and does not apply any plugins or perform AST transformations.

To enable the plugin, create the following file in your e2e tests directory:

```javascript

const transformer = require('@nestjs/swagger/plugin');

module.exports.name = 'nestjs-swagger-transformer';
// you should change the version number anytime you change the configuration below - otherwise, jest will not detect changes
module.exports.version = 1;

module.exports.factory = (cs) => {
  return transformer.before(
    {
      // @nestjs/swagger/plugin options (can be empty)
    },
    cs.program, // "cs.tsCompiler.program" for older versions of Jest (<= v27)
  );
};
```

With this in place, import AST transformer within your `jest` configuration file. By default (in the starter application), e2e tests configuration file is located under the `test` folder and is named `jest-e2e.json`.

```json

{
  ... // other configuration
  "globals": {
    "ts-jest": {
      "astTransformers": {
        "before": ["<path to the file created above>"],
      }
    }
  }
}
```

#### Troubleshooting `jest` (e2e tests)[#](/openapi/cli-plugin#troubleshooting-jest-e2e-tests)

In case `jest` does not seem to pick up your configuration changes, it's possible that Jest has already **cached** the build result. To apply the new configuration, you need to clear Jest's cache directory.

To clear the cache directory, run the following command in your NestJS project folder:

```bash

$ npx jest --clearCache
```

In case the automatic cache clearance fails, you can still manually remove the cache folder with the following commands:

```bash

# Find jest cache directory (usually /tmp/jest_rs)
# by running the following command in your NestJS project root
$ npx jest --showConfig | grep cache
# ex result:
#   "cache": true,
#   "cacheDirectory": "/tmp/jest_rs"

# Remove or empty the Jest cache directory
$ rm -rf  <cacheDirectory value>
# ex:
# rm -rf /tmp/jest_rs
```

----
url: https://docs.nestjs.com/v8/recipes/crud-generator
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [CRUD generator](https://docs.nestjs.com/v8/recipes/crud-generator#crud-generator)
* [Introduction](https://docs.nestjs.com/v8/recipes/crud-generator#introduction)
* [Generating a new resource](https://docs.nestjs.com/v8/recipes/crud-generator#generating-a-new-resource)

To help speed up this repetitive process, [Nest CLI](/v8/cli/overview) provides a generator (schematic) that automatically generates all the boilerplate code to help us avoid doing all of this, and make the developer experience much simpler.

> **Note** The schematic supports generating **HTTP** controllers, **Microservice** controllers, **GraphQL** resolvers (both code first and schema first), and **WebSocket** Gateways.

#### Generating a new resource[#](/recipes/crud-generator#generating-a-new-resource)

To create a new resource, simply run the following command in the root directory of your project:

```shell

$ nest g resource
```

`nest g resource` command not only generates all the NestJS building blocks (module, service, controller classes) but also an entity class, DTO classes as well as the testing (`.spec`) files.

Below you can see the generated controller file (for REST API):

```typescript

@Controller('users')
export class UsersController {
  constructor(private readonly usersService: UsersService) {}

  @Post()
  create(@Body() createUserDto: CreateUserDto) {
    return this.usersService.create(createUserDto);
  }

  @Get()
  findAll() {
    return this.usersService.findAll();
  }

  @Get(':id')
  findOne(@Param('id') id: string) {
    return this.usersService.findOne(+id);
  }

  @Patch(':id')
  update(@Param('id') id: string, @Body() updateUserDto: UpdateUserDto) {
    return this.usersService.update(+id, updateUserDto);
  }

  @Delete(':id')
  remove(@Param('id') id: string) {
    return this.usersService.remove(+id);
  }
}
```

Also, it automatically creates placeholders for all the CRUD endpoints (routes for REST APIs, queries and mutations for GraphQL, message subscribes for both Microservices and WebSocket Gateways) - all without having to lift a finger.

> **Note** Generated service classes are **not** tied to any specific **ORM (or data source)**. This makes the generator generic enough to meet the needs of any project. By default, all methods will contain placeholders, allowing you to populate it with the data sources specific to your project.

Likewise, if you want to generate resolvers for a GraphQL application, simply select the `GraphQL (code first)` (or `GraphQL (schema first)`) as your transport layer.

In this case, NestJS will generate a resolver class instead of a REST API controller:

```shell

$ nest g resource users

> ? What transport layer do you use? GraphQL (code first)
> ? Would you like to generate CRUD entry points? Yes
> CREATE src/users/users.module.ts (224 bytes)
> CREATE src/users/users.resolver.spec.ts (525 bytes)
> CREATE src/users/users.resolver.ts (1109 bytes)
> CREATE src/users/users.service.spec.ts (453 bytes)
> CREATE src/users/users.service.ts (625 bytes)
> CREATE src/users/dto/create-user.input.ts (195 bytes)
> CREATE src/users/dto/update-user.input.ts (281 bytes)
> CREATE src/users/entities/user.entity.ts (187 bytes)
> UPDATE src/app.module.ts (312 bytes)
```

> **Hint** To avoid generating test files, you can pass the `--no-spec` flag, as follows: `nest g resource users --no-spec`

We can see below, that not only were all boilerplate mutations and queries created, but everything is all tied together. We're utilizing the `UsersService`, `User` Entity, and our DTO's.

```typescript

import { Resolver, Query, Mutation, Args, Int } from '@nestjs/graphql';
import { UsersService } from './users.service';
import { User } from './entities/user.entity';
import { CreateUserInput } from './dto/create-user.input';
import { UpdateUserInput } from './dto/update-user.input';

@Resolver(() => User)
export class UsersResolver {
  constructor(private readonly usersService: UsersService) {}

  @Mutation(() => User)
  createUser(@Args('createUserInput') createUserInput: CreateUserInput) {
    return this.usersService.create(createUserInput);
  }

  @Query(() => [User], { name: 'users' })
  findAll() {
    return this.usersService.findAll();
  }

  @Query(() => User, { name: 'user' })
  findOne(@Args('id', { type: () => Int }) id: number) {
    return this.usersService.findOne(id);
  }

  @Mutation(() => User)
  updateUser(@Args('updateUserInput') updateUserInput: UpdateUserInput) {
    return this.usersService.update(updateUserInput.id, updateUserInput);
  }

  @Mutation(() => User)
  removeUser(@Args('id', { type: () => Int }) id: number) {
    return this.usersService.remove(id);
  }
}
```

----
url: https://docs.nestjs.com/v8/graphql/generating-sdl
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Generating SDL](https://docs.nestjs.com/v8/graphql/generating-sdl#generating-sdl)
* [Usage](https://docs.nestjs.com/v8/graphql/generating-sdl#usage)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/schema-generator.md "Suggest Edits")

### Generating SDL

> **Warning** This chapter applies only to the code first approach.

To manually generate a GraphQL SDL schema (i.e., without running an application, connecting to the database, hooking up resolvers, etc.), use the `GraphQLSchemaBuilderModule`.

```typescript

async function generateSchema() {
  const app = await NestFactory.create(GraphQLSchemaBuilderModule);
  await app.init();

  const gqlSchemaFactory = app.get(GraphQLSchemaFactory);
  const schema = await gqlSchemaFactory.create([RecipesResolver]);
  console.log(printSchema(schema));
}
```

> **Hint** The `GraphQLSchemaBuilderModule` and `GraphQLSchemaFactory` are imported from the `@nestjs/graphql` package. The `printSchema` function is imported from the `graphql` package.

#### Usage[#](/graphql/generating-sdl#usage)

The `gqlSchemaFactory.create()` method takes an array of resolver class references. For example:

```typescript

const schema = await gqlSchemaFactory.create([
  RecipesResolver,
  AuthorsResolver,
  PostsResolvers,
]);
```

It also takes a second optional argument with an array of scalar classes:

```typescript

const schema = await gqlSchemaFactory.create(
  [RecipesResolver, AuthorsResolver, PostsResolvers],
  [DurationScalar, DateScalar],
);
```

Lastly, you can pass an options object:

```typescript

const schema = await gqlSchemaFactory.create([RecipesResolver], {
  skipCheck: true,
  orphanedTypes: [],
});
```

* `skipCheck`: ignore schema validation; boolean, defaults to `false`
* `orphanedTypes`: list of classes that are not explicitly referenced (not part of the object graph) to be generated. Normally, if a class is declared but isn't otherwise referenced in the graph, it's omitted. The property value is an array of class references.

----
url: https://docs.nestjs.com/v5/discover/companies
----

### Who is using Nest?

We are proudly helping various companies building their products at scale. If you are using Nest and would you like to be listed here, see this [thread](https://github.com/nestjs/nest/issues/1006). We are willing to put your logo here!

#### Companies

According to our knowledge, all the following companies have built awesome projects on top of our framework:

[](https://valor-software.com/)[](http://xtremis.com/)[](https://neoteric.eu/)[](https://swingdev.io/)[](https://adidas.com)[](https://gojob.com/)[](https://trellis.org/)[](https://scal.io)[](https://rewe-digital.com/)[](https://genuinebee.com/)[](http://architectnow.net)

|                                     |
| ----------------------------------- |
| <https://gorrion.io/>               |
| <http://balticdatascience.com/>     |
| <https://prohabits.com/>            |
| <https://komed-health.com/>         |
| <https://kerberus.com.co/>          |
| <https://notadd.com/>               |
| <http://jsdaddy.io/>                |
| <https://yumpingo.com/>             |
| <https://analytics-importer.cz/>    |
| <https://dayzim.com/>               |
| <https://wizkids.co.uk/>            |
| <https://pilvia.com/>               |
| <https://wi-q.com/>                 |
| <http://agrofel.com.br>             |
| <https://societegenerale.com/>      |
| <https://trashpanda.hulan.nl/>      |
| <https://bytedance.com/>            |
| <https://votercircle.com>           |
| <https://erento.com>                |
| <https://ideas.manticore-labs.com/> |
| <https://smartexlab.com/>           |
| <https://automama.ru/>              |
| <https://iflix.com/>                |

and a lot more but we don't have enough time to update above list. Feel free to create a [pull request](https://github.com/nestjs/docs.nestjs.com/pulls) though!

* Who is using Nest?
* Companies

----
url: https://docs.nestjs.com/v11/microservices/nats
----

* [NATS](https://docs.nestjs.com/v11/microservices/nats#nats)
* [Installation](https://docs.nestjs.com/v11/microservices/nats#installation)
* [Overview](https://docs.nestjs.com/v11/microservices/nats#overview)
* [Options](https://docs.nestjs.com/v11/microservices/nats#options)
* [Client](https://docs.nestjs.com/v11/microservices/nats#client)
* [Request-response](https://docs.nestjs.com/v11/microservices/nats#request-response)
* [Event-based](https://docs.nestjs.com/v11/microservices/nats#event-based)
* [Queue groups](https://docs.nestjs.com/v11/microservices/nats#queue-groups)
* [Context](https://docs.nestjs.com/v11/microservices/nats#context)
* [Wildcards](https://docs.nestjs.com/v11/microservices/nats#wildcards)
* [Record builders](https://docs.nestjs.com/v11/microservices/nats#record-builders)
* [Instance status updates](https://docs.nestjs.com/v11/microservices/nats#instance-status-updates)
* [Listening to Nats events](https://docs.nestjs.com/v11/microservices/nats#listening-to-nats-events)
* [Underlying driver access](https://docs.nestjs.com/v11/microservices/nats#underlying-driver-access)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/microservices/nats.md "Suggest Edits")

### NATS

[NATS](https://nats.io) is a simple, secure and high performance open source messaging system for cloud native applications, IoT messaging, and microservices architectures. The NATS server is written in the Go programming language, but client libraries to interact with the server are available for dozens of major programming languages. NATS supports both **At Most Once** and **At Least Once** delivery. It can run anywhere, from large servers and cloud instances, through edge gateways and even Internet of Things devices.

#### Installation[#](/microservices/nats#installation)

To start building NATS-based microservices, first install the required package:

```bash

$ npm i --save nats
```

#### Overview[#](/microservices/nats#overview)

To use the NATS transporter, pass the following options object to the `createMicroservice()` method:

main.ts

JS TS

```typescript

const app = await NestFactory.createMicroservice<MicroserviceOptions>(AppModule, {
  transport: Transport.NATS,
  options: {
    servers: ['nats://localhost:4222'],
  },
});
```

```typescript

const app = await NestFactory.createMicroservice(AppModule, {
  transport: Transport.NATS,
  options: {
    servers: ['nats://localhost:4222'],
  },
});
```

> **Hint** The `Transport` enum is imported from the `@nestjs/microservices` package.

#### Options[#](/microservices/nats#options)

The `options` object is specific to the chosen transporter. The **NATS** transporter exposes the properties described [here](https://github.com/nats-io/node-nats#connection-options) as well as the following properties:

|                    |                                                                                                                                                                                            |
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `queue`            | Queue that your server should subscribe to (leave `undefined` to ignore this setting). Read more about NATS queue groups [below](https://docs.nestjs.com/microservices/nats#queue-groups). |
| `gracefulShutdown` | Enables graceful shutdown. When enabled, the server first unsubscribes from all channels before closing the connection. Default is `false`.                                                |
| `gracePeriod`      | Time in milliseconds to wait for the server after unsubscribing from all channels. Default is `10000` ms.                                                                                  |

#### Client[#](/microservices/nats#client)

Like other microservice transporters, you have [several options](https://docs.nestjs.com/microservices/basics#client) for creating a NATS `ClientProxy` instance.

One method for creating an instance is to use the `ClientsModule`. To create a client instance with the `ClientsModule`, import it and use the `register()` method to pass an options object with the same properties shown above in the `createMicroservice()` method, as well as a `name` property to be used as the injection token. Read more about `ClientsModule`[here](https://docs.nestjs.com/microservices/basics#client).

```typescript

@Module({
  imports: [
    ClientsModule.register([
      {
        name: 'MATH_SERVICE',
        transport: Transport.NATS,
        options: {
          servers: ['nats://localhost:4222'],
        }
      },
    ]),
  ]
  ...
})
```

```typescript

const app = await NestFactory.createMicroservice<MicroserviceOptions>(AppModule, {
  transport: Transport.NATS,
  options: {
    servers: ['nats://localhost:4222'],
    queue: 'cats_queue',
  },
});
```

#### Context[#](/microservices/nats#context)

In more complex scenarios, you may need to access additional information about the incoming request. When using the NATS transporter, you can access the `NatsContext` object.

JS TS

```typescript

@MessagePattern('notifications')
getNotifications(@Payload() data: number[], @Ctx() context: NatsContext) {
  console.log(`Subject: ${context.getSubject()}`);
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('notifications')
getNotifications(data, context) {
  console.log(`Subject: ${context.getSubject()}`);
}
```

> **Hint**`@Payload()`, `@Ctx()` and `NatsContext` are imported from the `@nestjs/microservices` package.

#### Wildcards[#](/microservices/nats#wildcards)

A subscription may be to an explicit subject, or it may include wildcards.

JS TS

```typescript

@MessagePattern('time.us.*')
getDate(@Payload() data: number[], @Ctx() context: NatsContext) {
  console.log(`Subject: ${context.getSubject()}`); // e.g. "time.us.east"
  return new Date().toLocaleTimeString(...);
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('time.us.*')
getDate(data, context) {
  console.log(`Subject: ${context.getSubject()}`); // e.g. "time.us.east"
  return new Date().toLocaleTimeString(...);
}
```

#### Record builders[#](/microservices/nats#record-builders)

To configure message options, you can use the `NatsRecordBuilder` class (note: this is doable for event-based flows as well). For example, to add `x-version` header, use the `setHeaders` method, as follows:

```typescript

import * as nats from 'nats';

// somewhere in your code
const headers = nats.headers();
headers.set('x-version', '1.0.0');

const record = new NatsRecordBuilder(':cat:').setHeaders(headers).build();
this.client.send('replace-emoji', record).subscribe(...);
```

> **Hint**`NatsRecordBuilder` class is exported from the `@nestjs/microservices` package.

And you can read these headers on the server-side as well, by accessing the `NatsContext`, as follows:

JS TS

```typescript

@MessagePattern('replace-emoji')
replaceEmoji(@Payload() data: string, @Ctx() context: NatsContext): string {
  const headers = context.getHeaders();
  return headers['x-version'] === '1.0.0' ? '🐱' : '🐈';
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('replace-emoji')
replaceEmoji(data, context) {
  const headers = context.getHeaders();
  return headers['x-version'] === '1.0.0' ? '🐱' : '🐈';
}
```

In some cases you might want to configure headers for multiple requests, you can pass these as options to the `ClientProxyFactory`:

```typescript

import { Module } from '@nestjs/common';
import { ClientProxyFactory, Transport } from '@nestjs/microservices';

@Module({
  providers: [
    {
      provide: 'API_v1',
      useFactory: () =>
        ClientProxyFactory.create({
          transport: Transport.NATS,
          options: {
            servers: ['nats://localhost:4222'],
            headers: { 'x-version': '1.0.0' },
          },
        }),
    },
  ],
})
export class ApiModule {}
```

#### Instance status updates[#](/microservices/nats#instance-status-updates)

To get real-time updates on the connection and the state of the underlying driver instance, you can subscribe to the `status` stream. This stream provides status updates specific to the chosen driver. For the NATS driver, the `status` stream emits `connected`, `disconnected`, and `reconnecting` events.

```typescript

this.client.status.subscribe((status: NatsStatus) => {
  console.log(status);
});
```

> **Hint** The `NatsStatus` type is imported from the `@nestjs/microservices` package.

Similarly, you can subscribe to the server's `status` stream to receive notifications about the server's status.

```typescript

const server = app.connectMicroservice<MicroserviceOptions>(...);
server.status.subscribe((status: NatsStatus) => {
  console.log(status);
});
```

#### Listening to Nats events[#](/microservices/nats#listening-to-nats-events)

In some cases, you might want to listen to internal events emitted by the microservice. For example, you could listen for the `error` event to trigger additional operations when an error occurs. To do this, use the `on()` method, as shown below:

```typescript

this.client.on('error', (err) => {
  console.error(err);
});
```

Similarly, you can listen to the server's internal events:

```typescript

server.on<NatsEvents>('error', (err) => {
  console.error(err);
});
```

> **Hint** The `NatsEvents` type is imported from the `@nestjs/microservices` package.

#### Underlying driver access[#](/microservices/nats#underlying-driver-access)

For more advanced use cases, you may need to access the underlying driver instance. This can be useful for scenarios like manually closing the connection or using driver-specific methods. However, keep in mind that for most cases, you **shouldn't need** to access the driver directly.

To do so, you can use the `unwrap()` method, which returns the underlying driver instance. The generic type parameter should specify the type of driver instance you expect.

```typescript

const natsConnection = this.client.unwrap<import('nats').NatsConnection>();
```

Similarly, you can access the server's underlying driver instance:

```typescript

const natsConnection = server.unwrap<import('nats').NatsConnection>();
```

----
url: https://docs.nestjs.com/v8/cli/usages
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [CLI command reference](https://docs.nestjs.com/v8/cli/usages#cli-command-reference)
* [nest new](https://docs.nestjs.com/v8/cli/usages#nest-new)
* [nest generate](https://docs.nestjs.com/v8/cli/usages#nest-generate)
* [nest build](https://docs.nestjs.com/v8/cli/usages#nest-build)
* [nest start](https://docs.nestjs.com/v8/cli/usages#nest-start)
* [nest add](https://docs.nestjs.com/v8/cli/usages#nest-add)
* [nest update](https://docs.nestjs.com/v8/cli/usages#nest-update)
* [nest info](https://docs.nestjs.com/v8/cli/usages#nest-info)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/cli/usages.md "Suggest Edits")

### CLI command reference

#### nest new[#](/cli/usages#nest-new)

Creates a new (standard mode) Nest project.

```bash

$ nest new <name> [options]
$ nest n <name> [options]
```

| Argument | Description                 |
| -------- | --------------------------- |
| `<name>` | The name of the new project |

##### Options

| Option                                | Description                                                                                                    |
| ------------------------------------- | -------------------------------------------------------------------------------------------------------------- |
| `--dry-run`                           | Reports changes that would be made, but does not change the filesystem. Alias: `-d`                            |
| `--skip-git`                          | Skip git repository initialization. Alias: `-g`                                                                |
| `--skip-install`                      | Skip package installation. Alias: `-s`                                                                         |
| `--package-manager [package-manager]` | Specify package manager. Use `npm`, `yarn`, or `pnpm`. Package manager must be installed globally. Alias: `-p` |
| `--language [language]`               | Specify programming language (`TS` or `JS`). Alias: `-l`                                                       |
| `--collection [collectionName]`       | Specify schematics collection. Use package name of installed npm package containing schematic. Alias: `-c`     |

#### nest generate[#](/cli/usages#nest-generate)

Generates and/or modifies files based on a schematic

```bash

$ nest generate <schematic> <name> [options]
$ nest g <schematic> <name> [options]
```

##### Arguments

| Argument      | Description                                                                                              |
| ------------- | -------------------------------------------------------------------------------------------------------- |
| `<schematic>` | The `schematic` or `collection:schematic` to generate. See the table below for the available schematics. |
| `<name>`      | The name of the generated component.                                                                     |

##### Schematics

| Name          | Alias | Description                                                                                                     |
| ------------- | ----- | --------------------------------------------------------------------------------------------------------------- |
| `app`         |       | Generate a new application within a monorepo (converting to monorepo if it's a standard structure).             |
| `library`     | `lib` | Generate a new library within a monorepo (converting to monorepo if it's a standard structure).                 |
| `class`       | `cl`  | Generate a new class.                                                                                           |
| `controller`  | `co`  | Generate a controller declaration.                                                                              |
| `decorator`   | `d`   | Generate a custom decorator.                                                                                    |
| `filter`      | `f`   | Generate a filter declaration.                                                                                  |
| `gateway`     | `ga`  | Generate a gateway declaration.                                                                                 |
| `guard`       | `gu`  | Generate a guard declaration.                                                                                   |
| `interface`   |       | Generate an interface.                                                                                          |
| `interceptor` | `in`  | Generate an interceptor declaration.                                                                            |
| `middleware`  | `mi`  | Generate a middleware declaration.                                                                              |
| `module`      | `mo`  | Generate a module declaration.                                                                                  |
| `pipe`        | `pi`  | Generate a pipe declaration.                                                                                    |
| `provider`    | `pr`  | Generate a provider declaration.                                                                                |
| `resolver`    | `r`   | Generate a resolver declaration.                                                                                |
| `resource`    | `res` | Generate a new CRUD resource. See the [CRUD (resource) generator](/v8/recipes/crud-generator) for more details. |
| `service`     | `s`   | Generate a service declaration.                                                                                 |

##### Options

| Option                          | Description                                                                                                |
| ------------------------------- | ---------------------------------------------------------------------------------------------------------- |
| `--dry-run`                     | Reports changes that would be made, but does not change the filesystem. Alias: `-d`                        |
| `--project [project]`           | Project that element should be added to. Alias: `-p`                                                       |
| `--flat`                        | Do not generate a folder for the element.                                                                  |
| `--collection [collectionName]` | Specify schematics collection. Use package name of installed npm package containing schematic. Alias: `-c` |
| `--spec`                        | Enforce spec files generation (default)                                                                    |
| `--no-spec`                     | Disable spec files generation                                                                              |

#### nest build[#](/cli/usages#nest-build)

Compiles an application or workspace into an output folder.

```bash

$ nest build <name> [options]
```

##### Arguments

| Argument | Description                       |
| -------- | --------------------------------- |
| `<name>` | The name of the project to build. |

##### Options

| Option            | Description                                       |
| ----------------- | ------------------------------------------------- |
| `--path [path]`   | Path to `tsconfig` file. Alias `-p`               |
| `--config [path]` | Path to `nest-cli` configuration file. Alias `-c` |
| `--watch`         | Run in watch mode (live-reload) Alias `-w`        |
| `--webpack`       | Use webpack for compilation.                      |
| `--webpackPath`   | Path to webpack configuration.                    |
| `--tsc`           | Force use `tsc` for compilation.                  |

#### nest start[#](/cli/usages#nest-start)

Compiles and runs an application (or default project in a workspace).

```bash

$ nest start <name> [options]
```

##### Arguments

| Argument | Description                     |
| -------- | ------------------------------- |
| `<name>` | The name of the project to run. |

##### Options

| Option                  | Description                                                                                                          |
| ----------------------- | -------------------------------------------------------------------------------------------------------------------- |
| `--path [path]`         | Path to `tsconfig` file. Alias `-p`                                                                                  |
| `--config [path]`       | Path to `nest-cli` configuration file. Alias `-c`                                                                    |
| `--watch`               | Run in watch mode (live-reload) Alias `-w`                                                                           |
| `--preserveWatchOutput` | Keep outdated console output in watch mode instead of clearing the screen. (`tsc` watch mode only)                   |
| `--watchAssets`         | Run in watch mode (live-reload), watching non-TS files (assets). See [Assets](cli/monorepo#assets) for more details. |
| `--debug [hostport]`    | Run in debug mode (with --inspect flag) Alias `-d`                                                                   |
| `--webpack`             | Use webpack for compilation.                                                                                         |
| `--webpackPath`         | Path to webpack configuration.                                                                                       |
| `--tsc`                 | Force use `tsc` for compilation.                                                                                     |
| `--exec [binary]`       | Binary to run (default: `node`). Alias `-e`                                                                          |

#### nest add[#](/cli/usages#nest-add)

Imports a library that has been packaged as a **nest library**, running its install schematic.

```bash

$ nest add <name> [options]
```

##### Arguments

| Argument | Description                        |
| -------- | ---------------------------------- |
| `<name>` | The name of the library to import. |

#### nest update[#](/cli/usages#nest-update)

Updates `@nestjs` dependencies in the `package.json``"dependencies"` list to their `@latest` version.

##### Options

| Option    | Description                                                        |
| --------- | ------------------------------------------------------------------ |
| `--force` | Do **upgrade** instead of update Alias `-f`                        |
| `--tag`   | Update to tagged version (use `@latest`, `@<tag>`, etc) Alias `-t` |

#### nest info[#](/cli/usages#nest-info)

Displays information about installed nest packages and other helpful system info. For example:

```bash

$ nest info
```

```bash

 _   _             _      ___  _____  _____  _     _____
| \ | |           | |    |_  |/  ___|/  __ \| |   |_   _|
|  \| |  ___  ___ | |_     | |\ `--. | /  \/| |     | |
| . ` | / _ \/ __|| __|    | | `--. \| |    | |     | |
| |\  ||  __/\__ \| |_ /\__/ //\__/ /| \__/\| |_____| |_
\_| \_/ \___||___/ \__|\____/ \____/  \____/\_____/\___/

[System Information]
OS Version : macOS High Sierra
NodeJS Version : v8.9.0
YARN Version : 1.5.1
[Nest Information]
microservices version : 6.0.0
websockets version : 6.0.0
testing version : 6.0.0
common version : 6.0.0
core version : 6.0.0
```

----
url: https://docs.nestjs.com/v7/openapi/types-and-parameters
----

* [Types and parameters](https://docs.nestjs.com/v7/openapi/types-and-parameters#types-and-parameters)
* [Arrays](https://docs.nestjs.com/v7/openapi/types-and-parameters#arrays)
* [Circular dependencies](https://docs.nestjs.com/v7/openapi/types-and-parameters#circular-dependencies)
* [Generics and interfaces](https://docs.nestjs.com/v7/openapi/types-and-parameters#generics-and-interfaces)
* [Enums](https://docs.nestjs.com/v7/openapi/types-and-parameters#enums)
* [Enums schema](https://docs.nestjs.com/v7/openapi/types-and-parameters#enums-schema)
* [Raw definitions](https://docs.nestjs.com/v7/openapi/types-and-parameters#raw-definitions)
* [Extra models](https://docs.nestjs.com/v7/openapi/types-and-parameters#extra-models)
* [oneOf, anyOf, allOf](https://docs.nestjs.com/v7/openapi/types-and-parameters#oneof-anyof-allof)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/openapi/types-and-parameters.md "Suggest Edits")

### 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:

```typescript

@Post()
async create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

> **Hint** To explicitly set the body definition use the `@ApiBody()` decorator (imported from the `@nestjs/swagger` package).

Based on the `CreateCatDto`, the following model definition Swagger UI will be created:

As you can see, the definition is empty although the class has a few declared properties. In order to make the class properties visible to the `SwaggerModule`, we have to either annotate them with the `@ApiProperty()` decorator or use the CLI plugin (read more in the **Plugin** section) which will do it automatically:

```typescript

import { ApiProperty } from '@nestjs/swagger';

export class CreateCatDto {
  @ApiProperty()
  name: string;

  @ApiProperty()
  age: number;

  @ApiProperty()
  breed: string;
}
```

> **Hint** Instead of manually annotating each property, consider using the Swagger plugin (see [Plugin](/v7/openapi/cli-plugin) section) which will automatically provide this for you.

Let's open the browser and verify the generated `CreateCatDto` model:

In addition, the `@ApiProperty()` decorator allows setting various [Schema Object](https://swagger.io/specification/#schemaObject) properties:

```typescript

@ApiProperty({
  description: 'The age of a cat',
  minimum: 1,
  default: 1,
})
age: number;
```

> **Hint** Instead of explicitly typing the `@ApiProperty({ required: false })` you can use the `@ApiPropertyOptional()` short-hand decorator.

In order to explicitly set the type of the property, use the `type` key:

```typescript

@ApiProperty({
  type: Number,
})
age: number;
```

#### Arrays[#](/openapi/types-and-parameters#arrays)

When the property is an array, we must manually indicate the array type as shown below:

```typescript

@ApiProperty({ type: [String] })
names: string[];
```

> **Hint** Consider using the Swagger plugin (see [Plugin](/v7/openapi/cli-plugin) section) which will automatically detect arrays.

```typescript

@ApiProperty({ type: () => Node })
node: Node;
```

> **Hint** Consider using the Swagger plugin (see [Plugin](/v7/openapi/cli-plugin) section) which will automatically detect circular dependencies.

#### Generics and interfaces[#](/openapi/types-and-parameters#generics-and-interfaces)

Since TypeScript does not store metadata about generics or interfaces, when you use them in your DTOs, `SwaggerModule` may not be able to properly generate model definitions at runtime. For instance, the following code won't be correctly inspected by the Swagger module:

```typescript

createBulk(@Body() usersDto: CreateUserDto[])
```

In order to overcome this limitation, you can set the type explicitly:

```typescript

@ApiBody({ type: [CreateUserDto] })
createBulk(@Body() usersDto: CreateUserDto[])
```

#### Enums[#](/openapi/types-and-parameters#enums)

To identify an `enum`, we must manually set the `enum` property on the `@ApiProperty` with an array of values.

```typescript

@ApiProperty({ enum: ['Admin', 'Moderator', 'User']})
role: UserRole;
```

Alternatively, define an actual TypeScript enum as follows:

```typescript

export enum UserRole {
  Admin = 'Admin',
  Moderator = 'Moderator',
  User = 'User',
}
```

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

```typescript

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

With `isArray` set to **true**, the `enum` can be selected as a **multi-select**:

#### Enums schema[#](/openapi/types-and-parameters#enums-schema)

By default, the `enum` property will add a raw definition of [Enum](https://swagger.io/docs/specification/data-models/enums/) on the `parameter`.

```yaml

- breed:
    type: 'string'
    enum:
      - Persian
      - Tabby
      - Siamese
```

The above specification works fine for most cases. However, if you are utilizing a tool that takes the specification as **input** and generates **client-side** code, you might run into a problem with the generated code containing duplicated `enums`. Consider the following code snippet:

```typescript

// generated client-side code
export class CatDetail {
  breed: CatDetailEnum;
}

export class CatInformation {
  breed: CatInformationEnum;
}

export enum CatDetailEnum {
  Persian = 'Persian',
  Tabby = 'Tabby',
  Siamese = 'Siamese',
}

export enum CatInformationEnum {
  Persian = 'Persian',
  Tabby = 'Tabby',
  Siamese = 'Siamese',
}
```

> **Hint** The above snippet is generated using a tool called [NSwag](https://github.com/RicoSuter/NSwag).

You can see that now you have two `enums` that are exactly the same. To address this issue, you can pass an `enumName` along with the `enum` property in your decorator.

```typescript

export class CatDetail {
  @ApiProperty({ enum: CatBreed, enumName: 'CatBreed' })
  breed: CatBreed;
}
```

The `enumName` property enables `@nestjs/swagger` to turn `CatBreed` into its own `schema` which in turns makes `CatBreed` enum reusable. The specification will look like the following:

```yaml

CatDetail:
  type: 'object'
  properties:
    ...
    - breed:
        schema:
          $ref: '#/components/schemas/CatBreed'
CatBreed:
  type: string
  enum:
    - Persian
    - Tabby
    - Siamese
```

> **Hint** Any **decorator** that takes `enum` as a property will also take `enumName`.

#### Raw definitions[#](/openapi/types-and-parameters#raw-definitions)

In some specific scenarios (e.g., deeply nested arrays, matrices), you may want to describe your type by hand.

```typescript

@ApiProperty({
  type: 'array',
  items: {
    type: 'array',
    items: {
      type: 'number',
    },
  },
})
coords: number[][];
```

Likewise, in order to define your input/output content manually in controller classes, use the `schema` property:

```typescript

@ApiBody({
  schema: {
    type: 'array',
    items: {
      type: 'array',
      items: {
        type: 'number',
      },
    },
  },
})
async create(@Body() coords: number[][]) {}
```

#### Extra models[#](/openapi/types-and-parameters#extra-models)

To define additional models that are not directly referenced in your controllers but should be inspected by the Swagger module, use the `@ApiExtraModels()` decorator:

```typescript

@ApiExtraModels(ExtraModel)
export class CreateCatDto {}
```

> **Hint** You only need to use `@ApiExtraModels()` once for a specific model class.

Alternatively, you can pass an options object with the `extraModels` property specified to the `SwaggerModule#createDocument()` method, as follows:

```typescript

const document = SwaggerModule.createDocument(app, options, {
  extraModels: [ExtraModel],
});
```

To get a reference (`$ref`) to your model, use the `getSchemaPath(ExtraModel)` function:

```typescript

'application/vnd.api+json': {
   schema: { $ref: getSchemaPath(ExtraModel) },
},
```

#### oneOf, anyOf, allOf[#](/openapi/types-and-parameters#oneof-anyof-allof)

To combine schemas, you can use the `oneOf`, `anyOf` or `allOf` keywords ([read more](https://swagger.io/docs/specification/data-models/oneof-anyof-allof-not/)).

```typescript

@ApiProperty({
  oneOf: [
    { $ref: getSchemaPath(Cat) },
    { $ref: getSchemaPath(Dog) },
  ],
})
pet: Cat | Dog;
```

If you want to define a polymorphic array (i.e., an array whose members span multiple schemas), you should use a raw definition (see above) to define your type by hand.

```typescript

type Pet = Cat | Dog;

@ApiProperty({
  type: 'array',
  items: {
    oneOf: [
      { $ref: getSchemaPath(Cat) },
      { $ref: getSchemaPath(Dog) },
    ],
  },
})
pets: Pet[];
```

> **Hint** The `getSchemaPath()` function is imported from `@nestjs/swagger`.

Both `Cat` and `Dog` must be defined as extra models using the `@ApiExtraModels()` decorator (at the class-level).

----
url: https://docs.nestjs.com/v8/security/encryption-and-hashing
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Encryption and Hashing](https://docs.nestjs.com/v8/security/encryption-and-hashing#encryption-and-hashing)
* [Encryption](https://docs.nestjs.com/v8/security/encryption-and-hashing#encryption)
* [Hashing](https://docs.nestjs.com/v8/security/encryption-and-hashing#hashing)

```typescript

import { createCipheriv, randomBytes, scrypt } from 'crypto';
import { promisify } from 'util';

const iv = randomBytes(16);
const password = 'Password used to generate key';

// The key length is dependent on the algorithm.
// In this case for aes256, it is 32 bytes.
const key = (await promisify(scrypt)(password, 'salt', 32)) as Buffer;
const cipher = createCipheriv('aes-256-ctr', key, iv);

const textToEncrypt = 'Nest';
const encryptedText = Buffer.concat([
  cipher.update(textToEncrypt),
  cipher.final(),
]);
```

Now to decrypt `encryptedText` value:

```typescript

import { createDecipheriv } from 'crypto';

const decipher = createDecipheriv('aes-256-ctr', key, iv);
const decryptedText = Buffer.concat([
  decipher.update(encryptedText),
  decipher.final(),
]);
```

#### Hashing[#](/security/encryption-and-hashing#hashing)

For hashing, we recommend using either the [bcrypt](https://www.npmjs.com/package/bcrypt) or [argon2](https://www.npmjs.com/package/argon2) packages. Nest itself does not provide any additional wrappers on top of these modules to avoid introducing unnecessary abstractions (making the learning curve short).

As an example, let's use `bcrypt` to hash a random password.

First install required packages:

```shell

$ npm i bcrypt
$ npm i -D @types/bcrypt
```

Once the installation is complete, you can use the `hash` function, as follows:

```typescript

import * as bcrypt from 'bcrypt';

const saltOrRounds = 10;
const password = 'random_password';
const hash = await bcrypt.hash(password, saltOrRounds);
```

To generate a salt, use the `genSalt` function:

```typescript

const salt = await bcrypt.genSalt();
```

To compare/check a password, use the `compare` function:

```typescript

const isMatch = await bcrypt.compare(password, hash);
```

You can read more about available functions [here](https://www.npmjs.com/package/bcrypt).

----
url: https://docs.nestjs.com/v4/techniques/authentication
----

### Authentication (Passport)

[Passport](https://github.com/jaredhanson/passport) is the most popular authentication library, probably well-known by almost every node.js developer in the world, and successively used in many production applications. It's really simple to integrate this tool with **Nest** framework. For demonstration purposes, I'll set up the [passport-jwt](https://github.com/themikenicholson/passport-jwt) strategy.

To start the adventure with this library we have to install all of the required dependencies:

TypeScript

```typescript

$ npm install --save passport passport-jwt jsonwebtoken
```

Firstly, we're gonna create the `AuthService`. This class will contain 2 methods, **(1)** to create a token using fake user, and **(2)** to validate the signed user from the decoded JWT (hardcoded `true`).

auth.service.ts

JavaScript TypeScript

TypeScript

```typescript

import * as jwt from 'jsonwebtoken';
import { Component } from '@nestjs/common';

@Component()
export class AuthService {
  async createToken() {
    const expiresIn = 60 * 60, secretOrKey = 'secret';
    const user = { email: 'thisis@example.com' };
    const token = jwt.sign(user, secretOrKey, { expiresIn });
    return {
      expires_in: expiresIn,
      access_token: token,
    };
  }

  async validateUser(signedUser): Promise<boolean> {
    // put some validation logic here
    // for example query user by id / email / username
    return true;
  }
}
```

TypeScript

```typescript

import * as jwt from 'jsonwebtoken';
import { Component } from '@nestjs/common';

@Component()
export class AuthService {
  async createToken() {
    const expiresIn = 60 * 60, secretOrKey = 'secret';
    const user = { email: 'thisis@example.com' };
    const token = jwt.sign(user, secretOrKey, { expiresIn });
    return {
      expires_in: expiresIn,
      access_token: token,
    };
  }

  async validateUser(signedUser) {
    // put some validation logic here
    // for example query user by id / email / username
    return true;
  }
}
```

> **Hint** In a best-case scenario the `jwt` object and token configuration (secret key and expiration time) should be provided as a [custom components](/v4/fundamentals/dependency-injection) and injected through constructor.

Passport uses the concept of strategies to authenticate requests. In this chapter, we're gonna extend the strategy provided by the [passport-jwt](https://github.com/themikenicholson/passport-jwt) package, the `JwtStrategy`:

jwt.strategy.ts

JavaScript TypeScript

TypeScript

```typescript

import * as passport from 'passport';
import { ExtractJwt, Strategy } from 'passport-jwt';
import { Component, Inject } from '@nestjs/common';
import { AuthService } from '../auth.service';

@Component()
export class JwtStrategy extends Strategy {
  constructor(private readonly authService: AuthService) {
    super(
      {
        jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
        passReqToCallback: true,
        secretOrKey: 'secret',
      },
      async (req, payload, next) => await this.verify(req, payload, next)
    );
    passport.use(this);
  }

  public async verify(req, payload, done) {
    const isValid = await this.authService.validateUser(payload);
    if (!isValid) {
      return done('Unauthorized', false);
    }
    done(null, payload);
  }
}
```

TypeScript

```typescript

import * as passport from 'passport';
import { ExtractJwt, Strategy } from 'passport-jwt';
import { Component, Dependencies } from '@nestjs/common';
import { AuthService } from '../auth.service';

@Component()
@Dependencies(AuthService)
export class JwtStrategy extends Strategy {
  constructor(authService) {
    super(
      {
        jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
        passReqToCallback: true,
        secretOrKey: 'secret',
      },
      async (req, payload, next) => await this.verify(req, payload, next)
    );
    this.authService = authService;
    passport.use(this);
  }

  async verify(req, payload, done) {
    const isValid = await this.authService.validateUser(payload);
    if (!isValid) {
      return done('Unauthorized', false);
    }
    done(null, payload);
  }
}
```

The `JwtStrategy` uses `AuthService` to validate the payload (signed user). When the payload is valid, the request may be handled by the route handler. Otherwise, the user would receive `401 Unauthorized` response.

The last step is to create an `AuthModule`:

auth.module.ts

JavaScript TypeScript

TypeScript

```typescript

import * as passport from 'passport';
import {
  Module,
  NestModule,
  MiddlewaresConsumer,
  RequestMethod,
} from '@nestjs/common';
import { AuthService } from './auth.service';
import { JwtStrategy } from './passport/jwt.strategy';
import { AuthController } from './auth.controller';

@Module({
  components: [AuthService, JwtStrategy],
  controllers: [AuthController],
})
export class AuthModule implements NestModule {
  public configure(consumer: MiddlewaresConsumer) {
    consumer
      .apply(passport.authenticate('jwt', { session: false }))
      .forRoutes({ path: '/auth/authorized', method: RequestMethod.ALL });
  }
}
```

TypeScript

```typescript

import * as passport from 'passport';
import { Module, RequestMethod } from '@nestjs/common';
import { AuthService } from './auth.service';
import { JwtStrategy } from './passport/jwt.strategy';
import { AuthController } from './auth.controller';

@Module({
  components: [AuthService, JwtStrategy],
  controllers: [AuthController],
})
export class AuthModule {
  public configure(consumer) {
    consumer
      .apply(passport.authenticate('jwt', { session: false }))
      .forRoutes({ path: '/auth/authorized', method: RequestMethod.ALL });
  }
}
```

The trick's to provide a `JwtStrategy` as a component, and set up the strategy immediately after instance creation (inside the `constructor`). Also, we're binding the [functional middleware](/v4/middlewares) to the single `/auth/authorized` route (just for testing purposes). It's everything.

The full source code's available [here](https://github.com/nestjs/nest/tree/master/examples/08-passport).

#### Sponsors

[](https://valor-software.com/)

Nest is an MIT-licensed open source project. It can grow thanks to the support by these awesome people. If you'd like to join them, please read more [here](https://opencollective.com/nest). Thanks!

[](https://opencollective.com/nest/backer/0/website)[](https://opencollective.com/nest/backer/1/website)[](https://opencollective.com/nest/backer/2/website)[](https://opencollective.com/nest/backer/3/website)[](https://opencollective.com/nest/backer/4/website)[](https://opencollective.com/nest/backer/5/website)[](https://opencollective.com/nest/backer/6/website)[](https://opencollective.com/nest/backer/7/website)[](https://opencollective.com/nest/backer/8/website)[](https://opencollective.com/nest/backer/9/website)[](https://opencollective.com/nest/backer/10/website)[](https://opencollective.com/nest/backer/11/website)[](https://opencollective.com/nest/backer/12/website)[](https://opencollective.com/nest/backer/13/website)[](https://opencollective.com/nest/backer/14/website)[](https://opencollective.com/nest/backer/15/website)[](https://opencollective.com/nest/backer/16/website)[](https://opencollective.com/nest/backer/17/website)[](https://opencollective.com/nest/backer/18/website)[](https://opencollective.com/nest/backer/19/website)[](https://opencollective.com/nest/backer/20/website)[](https://opencollective.com/nest/backer/21/website)[](https://opencollective.com/nest/backer/22/website)[](https://opencollective.com/nest/backer/23/website)[](https://opencollective.com/nest/backer/24/website)[](https://opencollective.com/nest/backer/25/website)[](https://opencollective.com/nest/backer/26/website)[](https://opencollective.com/nest/backer/27/website)[](https://opencollective.com/nest/backer/28/website)[](https://opencollective.com/nest/backer/29/website)

[Become a sponsor](https://opencollective.com/nest)

----
url: https://docs.nestjs.com/v9/providers
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Providers](https://docs.nestjs.com/v9/providers#providers)
* [Services](https://docs.nestjs.com/v9/providers#services)
* [Dependency injection](https://docs.nestjs.com/v9/providers#dependency-injection)
* [Scopes](https://docs.nestjs.com/v9/providers#scopes)
* [Custom providers](https://docs.nestjs.com/v9/providers#custom-providers)
* [Optional providers](https://docs.nestjs.com/v9/providers#optional-providers)
* [Property-based injection](https://docs.nestjs.com/v9/providers#property-based-injection)
* [Provider registration](https://docs.nestjs.com/v9/providers#provider-registration)
* [Manual instantiation](https://docs.nestjs.com/v9/providers#manual-instantiation)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/components.md "Suggest Edits")

### Providers

Providers are a fundamental concept in Nest. Many of the basic Nest classes may be treated as a provider – services, repositories, factories, helpers, and so on. The main idea of a provider is that it can be **injected** as a dependency; this means objects can create various relationships with each other, and the function of "wiring up" instances of objects can largely be delegated to the Nest runtime system.

In the previous chapter, we built a simple `CatsController`. Controllers should handle HTTP requests and delegate more complex tasks to **providers**. Providers are plain JavaScript classes that are declared as `providers` in a [module](/v9/modules).

> **Hint** Since Nest enables the possibility to design and organize dependencies in a more OO way, we strongly recommend following the [SOLID](https://en.wikipedia.org/wiki/SOLID) principles.

#### Services[#](/providers#services)

Let's start by creating a simple `CatsService`. This service will be responsible for data storage and retrieval, and is designed to be used by the `CatsController`, so it's a good candidate to be defined as a provider.

cats.service.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { Cat } from './interfaces/cat.interface';

@Injectable()
export class CatsService {
  private readonly cats: Cat[] = [];

  create(cat: Cat) {
    this.cats.push(cat);
  }

  findAll(): Cat[] {
    return this.cats;
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';

@Injectable()
export class CatsService {
  constructor() {
    this.cats = [];
  }

  create(cat) {
    this.cats.push(cat);
  }

  findAll() {
    return this.cats;
  }
}
```

> **Hint** To create a service using the CLI, simply execute the `$ nest g service cats` command.

Our `CatsService` is a basic class with one property and two methods. The only new feature is that it uses the `@Injectable()` decorator. The `@Injectable()` decorator attaches metadata, which declares that `CatsService` is a class that can be managed by the Nest [IoC](https://en.wikipedia.org/wiki/Inversion_of_control) container. By the way, this example also uses a `Cat` interface, which probably looks something like this:

interfaces/cat.interface.ts

JS TS

```typescript

export interface Cat {
  name: string;
  age: number;
  breed: string;
}
```

Now that we have a service class to retrieve cats, let's use it inside the `CatsController`:

cats.controller.ts

JS TS

```typescript

import { Controller, Get, Post, Body } from '@nestjs/common';
import { CreateCatDto } from './dto/create-cat.dto';
import { CatsService } from './cats.service';
import { Cat } from './interfaces/cat.interface';

@Controller('cats')
export class CatsController {
  constructor(private catsService: CatsService) {}

  @Post()
  async create(@Body() createCatDto: CreateCatDto) {
    this.catsService.create(createCatDto);
  }

  @Get()
  async findAll(): Promise<Cat[]> {
    return this.catsService.findAll();
  }
}
```

```typescript

import { Controller, Get, Post, Body, Bind, Dependencies } from '@nestjs/common';
import { CatsService } from './cats.service';

@Controller('cats')
@Dependencies(CatsService)
export class CatsController {
  constructor(catsService) {
    this.catsService = catsService;
  }

  @Post()
  @Bind(Body())
  async create(createCatDto) {
    this.catsService.create(createCatDto);
  }

  @Get()
  async findAll() {
    return this.catsService.findAll();
  }
}
```

The `CatsService` is **injected** through the class constructor. Notice the use of the `private` syntax. This shorthand allows us to both declare and initialize the `catsService` member immediately in the same location.

#### Dependency injection[#](/providers#dependency-injection)

Nest is built around the strong design pattern commonly known as **Dependency injection**. We recommend reading a great article about this concept in the official [Angular](https://angular.io/guide/dependency-injection) documentation.

In Nest, thanks to TypeScript capabilities, it's extremely easy to manage dependencies because they are resolved just by type. In the example below, Nest will resolve the `catsService` by creating and returning an instance of `CatsService` (or, in the normal case of a singleton, returning the existing instance if it has already been requested elsewhere). This dependency is resolved and passed to your controller's constructor (or assigned to the indicated property):

```typescript

constructor(private catsService: CatsService) {}
```

#### Scopes[#](/providers#scopes)

Providers normally have a lifetime ("scope") synchronized with the application lifecycle. When the application is bootstrapped, every dependency must be resolved, and therefore every provider has to be instantiated. Similarly, when the application shuts down, each provider will be destroyed. However, there are ways to make your provider lifetime **request-scoped** as well. You can read more about these techniques [here](/v9/fundamentals/injection-scopes).

Nest has a built-in inversion of control ("IoC") container that resolves relationships between providers. This feature underlies the dependency injection feature described above, but is in fact far more powerful than what we've described so far. There are several ways to define a provider: you can use plain values, classes, and either asynchronous or synchronous factories. More examples are provided [here](/v9/fundamentals/dependency-injection).

#### Optional providers[#](/providers#optional-providers)

Occasionally, you might have dependencies which do not necessarily have to be resolved. For instance, your class may depend on a **configuration object**, but if none is passed, the default values should be used. In such a case, the dependency becomes optional, because lack of the configuration provider wouldn't lead to errors.

To indicate a provider is optional, use the `@Optional()` decorator in the constructor's signature.

```typescript

import { Injectable, Optional, Inject } from '@nestjs/common';

@Injectable()
export class HttpService<T> {
  constructor(@Optional() @Inject('HTTP_OPTIONS') private httpClient: T) {}
}
```

Note that in the example above we are using a custom provider, which is the reason we include the `HTTP_OPTIONS` custom **token**. Previous examples showed constructor-based injection indicating a dependency through a class in the constructor. Read more about custom providers and their associated tokens [here](/v9/fundamentals/custom-providers).

#### Property-based injection[#](/providers#property-based-injection)

The technique we've used so far is called constructor-based injection, as providers are injected via the constructor method. In some very specific cases, **property-based injection** might be useful. For instance, if your top-level class depends on either one or multiple providers, passing them all the way up by calling `super()` in sub-classes from the constructor can be very tedious. In order to avoid this, you can use the `@Inject()` decorator at the property level.

```typescript

import { Injectable, Inject } from '@nestjs/common';

@Injectable()
export class HttpService<T> {
  @Inject('HTTP_OPTIONS')
  private readonly httpClient: T;
}
```

> **Warning** If your class doesn't extend another provider, you should always prefer using **constructor-based** injection.

#### Provider registration[#](/providers#provider-registration)

Now that we have defined a provider (`CatsService`), and we have a consumer of that service (`CatsController`), we need to register the service with Nest so that it can perform the injection. We do this by editing our module file (`app.module.ts`) and adding the service to the `providers` array of the `@Module()` decorator.

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { CatsController } from './cats/cats.controller';
import { CatsService } from './cats/cats.service';

@Module({
  controllers: [CatsController],
  providers: [CatsService],
})
export class AppModule {}
```

----
url: https://docs.nestjs.com/v9/graphql/interfaces
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Interfaces](https://docs.nestjs.com/v9/graphql/interfaces#interfaces)
* [Code first](https://docs.nestjs.com/v9/graphql/interfaces#code-first)
* [Interface resolvers](https://docs.nestjs.com/v9/graphql/interfaces#interface-resolvers)
* [Schema first](https://docs.nestjs.com/v9/graphql/interfaces#schema-first)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/interfaces.md "Suggest Edits")

### Interfaces

Like many type systems, GraphQL supports interfaces. An **Interface** is an abstract type that includes a certain set of fields that a type must include to implement the interface (read more [here](https://graphql.org/learn/schema/#interfaces)).

#### Code first

When using the code first approach, you define a GraphQL interface by creating an abstract class annotated with the `@InterfaceType()` decorator exported from the `@nestjs/graphql`.

```typescript

import { Field, ID, InterfaceType } from '@nestjs/graphql';

@InterfaceType()
export abstract class Character {
  @Field((type) => ID)
  id: string;

  @Field()
  name: string;
}
```

> **Warning** TypeScript interfaces cannot be used to define GraphQL interfaces.

This will result in generating the following part of the GraphQL schema in SDL:

```graphql

interface Character {
  id: ID!
  name: String!
}
```

Now, to implement the `Character` interface, use the `implements` key:

```typescript

@ObjectType({
  implements: () => [Character],
})
export class Human implements Character {
  id: string;
  name: string;
}
```

> **Hint** The `@ObjectType()` decorator is exported from the `@nestjs/graphql` package.

The default `resolveType()` function generated by the library extracts the type based on the value returned from the resolver method. This means that you must return class instances (you cannot return literal JavaScript objects).

To provide a customized `resolveType()` function, pass the `resolveType` property to the options object passed into the `@InterfaceType()` decorator, as follows:

```typescript

@InterfaceType({
  resolveType(book) {
    if (book.colors) {
      return ColoringBook;
    }
    return TextBook;
  },
})
export abstract class Book {
  @Field((type) => ID)
  id: string;

  @Field()
  title: string;
}
```

#### Interface resolvers

So far, using interfaces, you could only share field definitions with your objects. If you also want to share the actual field resolvers implementation, you can create a dedicated interface resolver, as follows:

```typescript

import { Resolver, ResolveField, Parent, Info } from '@nestjs/graphql';

@Resolver(type => Character) // Reminder: Character is an interface
export class CharacterInterfaceResolver {
  @ResolveField(() => [Character])
  friends(
    @Parent() character, // Resolved object that implements Character
    @Info() { parentType }, // Type of the object that implements Character
    @Args('search', { type: () => String }) searchTerm: string,
  ) {
    // Get character's friends
    return [];
  }
}
```

Now the `friends` field resolver is auto-registered for all object types that implement the `Character` interface.

#### Schema first

To define an interface in the schema first approach, simply create a GraphQL interface with SDL.

```graphql

interface Character {
  id: ID!
  name: String!
}
```

Then, you can use the typings generation feature (as shown in the [quick start]() chapter) to generate corresponding TypeScript definitions:

```typescript

export interface Character {
  id: string;
  name: string;
}
```

Interfaces require an extra `__resolveType` field in the resolver map to determine which type the interface should resolve to. Let's create a `CharactersResolver` class and define the `__resolveType` method:

```typescript

@Resolver('Character')
export class CharactersResolver {
  @ResolveField()
  __resolveType(value) {
    if ('age' in value) {
      return Person;
    }
    return null;
  }
}
```

> **Hint** All decorators are exported from the `@nestjs/graphql` package.

----
url: https://docs.nestjs.com/v7/graphql/mutations
----

* [Mutations](https://docs.nestjs.com/v7/graphql/mutations#mutations)
* [Code first](https://docs.nestjs.com/v7/graphql/mutations#code-first)
* [Schema first](https://docs.nestjs.com/v7/graphql/mutations#schema-first)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/mutations.md "Suggest Edits")

### Mutations

Most discussions of GraphQL focus on data fetching, but any complete data platform needs a way to modify server-side data as well. In REST, any request could end up causing side-effects on the server, but best practice suggests we should not modify data in GET requests. GraphQL is similar - technically any query could be implemented to cause a data write. However, like REST, it's recommended to observe the convention that any operations that cause writes should be sent explicitly via a mutation (read more [here](https://graphql.org/learn/queries/#mutations)).

The official [Apollo](https://www.apollographql.com/docs/graphql-tools/generate-schema.html) documentation uses an `upvotePost()` mutation example. This mutation implements a method to increase a post's `votes` property value. To create an equivalent mutation in Nest, we'll make use of the `@Mutation()` decorator.

#### Code first[#](/graphql/mutations#code-first)

Let's add another method to the `AuthorResolver` used in the previous section (see [resolvers](/v7/graphql/resolvers)).

```typescript

@Mutation(returns => Post)
async upvotePost(@Args({ name: 'postId', type: () => Int }) postId: number) {
  return this.postsService.upvoteById({ id: postId });
}
```

> **Hint** All decorators (e.g., `@Resolver`, `@ResolveField`, `@Args`, etc.) are exported from the `@nestjs/graphql` package.

This will result in generating the following part of the GraphQL schema in SDL:

```graphql

type Mutation {
  upvotePost(postId: Int!): Post
}
```

The `upvotePost()` method takes `postId` (`Int`) as an argument and returns an updated `Post` entity. For the reasons explained in the [resolvers](/v7/graphql/resolvers) section, we have to explicitly set the expected type.

If the mutation needs to take an object as an argument, we can create an **input type**. The input type is a special kind of object type that can be passed in as an argument (read more [here](https://graphql.org/learn/schema/#input-types)). To declare an input type, use the `@InputType()` decorator.

```typescript

import { InputType, Field } from '@nestjs/graphql';

@InputType()
export class UpvotePostInput {
  @Field()
  postId: number;
}
```

> **Hint** The `@InputType()` decorator takes an options object as an argument, so you can, for example, specify the input type's description. Note that, due to TypeScript's metadata reflection system limitations, you must either use the `@Field` decorator to manually indicate a type, or use a [CLI plugin](/v7/graphql/cli-plugin).

We can then use this type in the resolver class:

```typescript

@Mutation(returns => Post)
async upvotePost(
  @Args('upvotePostData') upvotePostData: UpvotePostInput,
) {}
```

#### Schema first[#](/graphql/mutations#schema-first)

Let's extend our `AuthorResolver` used in the previous section (see [resolvers](/v7/graphql/resolvers)).

```typescript

@Mutation()
async upvotePost(@Args('postId') postId: number) {
  return this.postsService.upvoteById({ id: postId });
}
```

Note that we assumed above that the business logic has been moved to the `PostsService` (querying the post and incrementing its `votes` property). The logic inside the `PostsService` class can be as simple or sophisticated as needed. The main point of this example is to show how resolvers can interact with other providers.

The last step is to add our mutation to the existing types definition.

```graphql

type Author {
  id: Int!
  firstName: String
  lastName: String
  posts: [Post]
}

type Post {
  id: Int!
  title: String
  votes: Int
}

type Query {
  author(id: Int!): Author
}

type Mutation {
  upvotePost(postId: Int!): Post
}
```

The `upvotePost(postId: Int!): Post` mutation is now available to be called as part of our application's GraphQL API.

----
url: https://docs.nestjs.com/security/cors
----

[Skip to content](#content)

On this page

* [CORS](https://docs.nestjs.com/security/cors#cors)
* [Getting started](https://docs.nestjs.com/security/cors#getting-started)
* [Default allowed methods](https://docs.nestjs.com/security/cors#default-allowed-methods)

### CORS

Cross-origin resource sharing (CORS) is a mechanism that allows resources to be requested from another domain. Under the hood, Nest uses the Express [cors](https://github.com/expressjs/cors) package or the Fastify [@fastify/cors](https://github.com/fastify/fastify-cors) package, depending on the underlying platform. These packages provide various options that you can customize to your requirements.

#### Getting started[#](/security/cors#getting-started)

To enable CORS, call the `enableCors()` method on the Nest application object.

```typescript

const app = await NestFactory.create(AppModule);
app.enableCors();
await app.listen(process.env.PORT ?? 3000);
```

The `enableCors()` method takes an optional configuration object. Its available properties are described in the official [CORS configuration options](https://github.com/expressjs/cors#configuration-options) documentation. Alternatively, pass a [callback function](https://github.com/expressjs/cors#customizing-cors-settings-dynamically-per-request) that computes the configuration object for each request.

You can also enable CORS through the options object of the `create()` method. Set the `cors` property to `true` to enable CORS with default settings, or pass a [CORS configuration object](https://github.com/expressjs/cors#configuration-options) or [callback function](https://github.com/expressjs/cors#customizing-cors-settings-dynamically-per-request) as the `cors` property value to customize its behavior.

```typescript

const app = await NestFactory.create(AppModule, { cors: true });
await app.listen(process.env.PORT ?? 3000);
```

#### Default allowed methods[#](/security/cors#default-allowed-methods)

The two packages do not share the same defaults, so `enableCors()` with no options does not advertise the same `Access-Control-Allow-Methods` on both platforms. The Express [cors](https://github.com/expressjs/cors) package answers `GET,HEAD,PUT,PATCH,POST,DELETE`, while [@fastify/cors](https://github.com/fastify/fastify-cors) answers only the [CORS-safelisted methods](https://fetch.spec.whatwg.org/#methods): `GET,HEAD,POST`.

> **Warning** On Fastify, a cross-origin `PUT`, `PATCH`, or `DELETE` is rejected at the preflight stage unless you list the method yourself. The same application code works on Express.

Both packages read the same `methods` option, so define it explicitly whenever your API is called from another origin with a method outside the safelist. It is accepted by `enableCors()` and by the `cors` property of the `create()` options object alike.

```typescript

app.enableCors({
  methods: ['GET', 'HEAD', 'PUT', 'PATCH', 'POST', 'DELETE'],
});
```

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/security/cors.md)

----
url: https://docs.nestjs.com/v11/observability/manual-instrumentation
----

* [Manual instrumentation](https://docs.nestjs.com/v11/observability/manual-instrumentation#manual-instrumentation)
* [Creating spans](https://docs.nestjs.com/v11/observability/manual-instrumentation#creating-spans)
* [Capturing handled errors](https://docs.nestjs.com/v11/observability/manual-instrumentation#capturing-handled-errors)
* [Request-scoped attributes](https://docs.nestjs.com/v11/observability/manual-instrumentation#request-scoped-attributes)
* [Custom metrics](https://docs.nestjs.com/v11/observability/manual-instrumentation#custom-metrics)
* [API summary](https://docs.nestjs.com/v11/observability/manual-instrumentation#api-summary)
* [Where to go next](https://docs.nestjs.com/v11/observability/manual-instrumentation#where-to-go-next)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/observability/manual-instrumentation.md "Suggest Edits")

### Manual instrumentation

Most of the SDK is automatic instrumentation - you configure it once and it decides what to record. `TracerService` is the manual half: inject it anywhere in your application to add spans inside an already-traced request, attach context to that request, capture errors you handled yourself, and report your own metrics.

cats.service.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { TracerService } from '@nestjs/observe';

@Injectable()
export class CatsService {
  constructor(private readonly tracerService: TracerService) {}
}
```

`TracerService` is exported by `ObserveModule`, so it's injectable in any module that imports it. Every method reads the trace from the ambient async context, which means calling one outside of a request, job, or other instrumented operation throws - there is no trace to attach to. That's deliberate: silently dropping a span is harder to notice than an error. (The exception is [custom metrics](#custom-metrics), which aren't tied to a trace.)

#### Creating spans[#](/observability/manual-instrumentation#creating-spans)

`createSpan(name, callback)` runs the callback inside a new span nested under whatever is currently active, and returns whatever the callback returns. The span's duration is the callback's duration, so `await` anything you want measured:

cats.service.ts

JS TS

```typescript

async findOne(id: string, activeUser: ActiveUserData) {
  return this.tracerService.createSpan('cats.findOne', async (span) => {
    span.addTags({ userId: activeUser.sub, catId: id });
    return this.catsRepository.findOne(id);
  });
}
```

Spans nest by call stack - a `createSpan()` inside another `createSpan()` callback becomes its child, which is what produces the waterfall on the trace detail page. The callback may be synchronous or asynchronous. Auto-instrumented spans (controller methods, providers, database calls) and your custom spans slot into the same tree, so a hand-named span appears exactly where it ran relative to everything else.

The `span` argument is a `TraceSpanDelegate`, whose `addTags(tags)` (or `setTag(key, value)` for a single entry) attaches key-value pairs to that span alone. They're searchable and shown on the span in the trace view, the same as the `tags`/`setAttributes` options described in [SDK → Tags and custom attributes](/observability/sdk#tags-and-custom-attributes) - the difference is scope: those cover every request, this covers one span.

`activeSpan()` returns the `TraceSpanDelegate` for the currently active span without creating a new one, for when you want to tag the enclosing span from code that didn't create it:

```typescript

const span = await this.tracerService.activeSpan();
span.addTags({ cacheHit: 'false' });
```

It throws if no span is active for the current trace.

> **Hint** Span names are what the **Spans** analytics view aggregates on, across every route that calls them. Pick names that describe the work (`orders.recalculate`, `cache.lookup`) rather than the caller, so "is this slow everywhere, or only from this one endpoint?" is a question the dashboard can answer.

#### Capturing handled errors[#](/observability/manual-instrumentation#capturing-handled-errors)

Errors that propagate out of a controller, job, or span are recorded automatically. `captureError()` is for the ones that don't - anything you caught and handled but still want visible in the dashboard:

```typescript

try {
  await this.billing.sync(accountId);
} catch (error) {
  await this.tracerService.captureError(error, {
    accountId,
    retryable: 'true',
  });
}
```

The error is attached to the current trace, with the optional tags recorded alongside it, and gets the same source-context treatment as any other captured error if [`sourceContext`](/observability/sdk#error-source-context) is enabled.

#### Request-scoped attributes[#](/observability/manual-instrumentation#request-scoped-attributes)

`setAttribute(key, value)` and `getAttribute(key)` read and write the trace's own context store - values that live for the duration of the request and are readable from anywhere downstream, without threading them through every function signature:

```typescript

this.tracerService.setAttribute('tenantId', tenant.id);
// ...later, in a different service on the same request
const tenantId = this.tracerService.getAttribute('tenantId');
```

`getAttribute()` returns `undefined` for a key that was never set. Both throw when called outside a traced context.

This store is the same one the trace id lives in, so `getAttribute(traceIdKey)` retrieves the current trace id - useful for correlating with an external system, or [propagating it to another service](). `currentTraceId()` is a shorthand for that lookup with one deliberate difference: it returns `null` outside a traced context instead of throwing, because reading the trace id to forward it downstream is exactly the kind of call that may legitimately happen when there is no trace yet.

To type the store, pass its shape as `TracerService`'s first type argument; keys and values are then checked against it, including nested paths:

```typescript

interface RequestStore {
  tenantId: string;
  flags: { betaCheckout: boolean };
}

@Injectable()
export class CheckoutService {
  constructor(private readonly tracerService: TracerService<RequestStore>) {}

  enableBeta() {
    this.tracerService.setAttribute('flags.betaCheckout', true);
  }
}
```

> **Hint**`ObserveModule` also exports the `AsyncLocalStorage` instance the trace context lives in. `setAttribute()`/`getAttribute()` are the supported way to reach it; inject the store directly only if you need something they don't expose. If you already use the pattern described in the [Async local storage]() recipe, this store can replace your hand-rolled one.

#### Custom metrics[#](/observability/manual-instrumentation#custom-metrics)

Three metric types are available, each created (or retrieved, if the name already exists) by name. They report into the **Custom** section of the dashboard and can be alerted on like any built-in metric.

Unlike the methods above, metrics aren't tied to a trace, so they can be reported from anywhere - including startup and shutdown code, `onModuleInit()` hooks, and cron jobs.

| Method    | For                                                                        | Reporting method |
| --------- | -------------------------------------------------------------------------- | ---------------- |
| `counter` | Values that only go up - requests served, orders placed, retries attempted | `increment()`    |
| `gauge`   | Values that go up and down - queue depth, active connections, cache ratio  | `increment()`    |
| `summary` | Distributions you want quantiles over - latency, payload size              | `observe(value)` |

cats.service.ts

JS TS

```typescript

this.tracerService
  .counter('cats.lookups', { description: 'Number of cat lookups' })
  .increment();

this.tracerService
  .gauge('cats.active.sessions', {
    kind: 'ratio',
    initialValue: 0,
    description: 'Number of active sessions',
  })
  .increment();

const latency = this.tracerService.summary('cats.lookup.duration', {
  description: 'Duration of cat lookups in milliseconds',
});
const startedAt = performance.now();
try {
  return await this.catsRepository.findOne(id);
} finally {
  // Observed in a finally so a failed lookup still lands in the distribution -
  // dropping the slow failures is how a latency summary ends up flattering itself.
  latency.observe(performance.now() - startedAt);
}
```

Calling `counter('orders.placed')` twice returns the same instance, so there's no need to hold a reference in a field - though doing so is cheaper on a hot path. Passing attributes on a later call updates the existing metric's description and labels in place.

| Attribute      | Applies to              | Description                                                                                                                           |
| -------------- | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| `description`  | counter, gauge, summary | Shown alongside the metric in the dashboard. Worth setting - a bare metric name rarely survives contact with a future reader.         |
| `labels`       | counter, gauge, summary | Dimensions the metric is broken down by, so the chart can be split rather than showing one aggregate line.                            |
| `initialValue` | counter, gauge          | Starting value. Only applied while the metric is still at `0`, so a restart-time declaration doesn't clobber a value already counted. |
| `kind`         | gauge                   | `'ratio'` (default) for values that stand alone per report, or `'additive'` for values that sum across reporting instances.           |
| `sampleSize`   | summary                 | How many observations per label are retained to compute quantiles from, which bounds the summary's memory under load.                 |

A metric that has been declared but never reported reads as "unknown" rather than `0` in the dashboard. That's a real state, not missing data: "we have never heard from this metric" and "this metric is currently zero" are different facts, and showing the second when you mean the first hides a broken deploy.

#### API summary[#](/observability/manual-instrumentation#api-summary)

| Method                       | Needs a trace | Description                                                |
| ---------------------------- | :-----------: | ---------------------------------------------------------- |
| `createSpan(name, callback)` |       ✓       | Run `callback` inside a new child span; returns its result |
| `activeSpan()`               |       ✓       | The `TraceSpanDelegate` of the span currently in flight    |
| `captureError(error, tags?)` |       ✓       | Record a handled error on the current trace                |
| `setAttribute(key, value)`   |       ✓       | Write to the request-scoped context store                  |
| `getAttribute(key)`          |       ✓       | Read from the request-scoped context store                 |
| `currentTraceId()`           |       ✗       | The active trace id, or `null` outside a trace             |
| `counter(name, attributes?)` |       ✗       | Get or create a monotonically increasing metric            |
| `gauge(name, attributes?)`   |       ✗       | Get or create a metric that can go up and down             |
| `summary(name, attributes?)` |       ✗       | Get or create a distribution metric with quantiles         |

#### Where to go next[#](/observability/manual-instrumentation#where-to-go-next)

* [Distributed tracing]() - use `currentTraceId()` to keep one trace across service boundaries.
* [Dashboard]() - where spans, captured errors, and custom metrics show up.

----
url: https://docs.nestjs.com/v11/microservices/rabbitmq
----

* [RabbitMQ](https://docs.nestjs.com/v11/microservices/rabbitmq#rabbitmq)
* [Installation](https://docs.nestjs.com/v11/microservices/rabbitmq#installation)
* [Overview](https://docs.nestjs.com/v11/microservices/rabbitmq#overview)
* [Options](https://docs.nestjs.com/v11/microservices/rabbitmq#options)
* [Client](https://docs.nestjs.com/v11/microservices/rabbitmq#client)
* [Context](https://docs.nestjs.com/v11/microservices/rabbitmq#context)
* [Message acknowledgement](https://docs.nestjs.com/v11/microservices/rabbitmq#message-acknowledgement)
* [Record builders](https://docs.nestjs.com/v11/microservices/rabbitmq#record-builders)
* [Instance status updates](https://docs.nestjs.com/v11/microservices/rabbitmq#instance-status-updates)
* [Listening to RabbitMQ events](https://docs.nestjs.com/v11/microservices/rabbitmq#listening-to-rabbitmq-events)
* [Underlying driver access](https://docs.nestjs.com/v11/microservices/rabbitmq#underlying-driver-access)
* [Wildcards](https://docs.nestjs.com/v11/microservices/rabbitmq#wildcards)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/microservices/rabbitmq.md "Suggest Edits")

### RabbitMQ

[RabbitMQ](https://www.rabbitmq.com/) is an open-source and lightweight message broker which supports multiple messaging protocols. It can be deployed in distributed and federated configurations to meet high-scale, high-availability requirements. In addition, it's the most widely deployed message broker, used worldwide at small startups and large enterprises.

#### Installation[#](/microservices/rabbitmq#installation)

To start building RabbitMQ-based microservices, first install the required packages:

```bash

$ npm i --save amqplib amqp-connection-manager
```

#### Overview[#](/microservices/rabbitmq#overview)

To use the RabbitMQ transporter, pass the following options object to the `createMicroservice()` method:

main.ts

JS TS

```typescript

const app = await NestFactory.createMicroservice<MicroserviceOptions>(AppModule, {
  transport: Transport.RMQ,
  options: {
    urls: ['amqp://localhost:5672'],
    queue: 'cats_queue',
    queueOptions: {
      durable: false
    },
  },
});
```

```typescript

const app = await NestFactory.createMicroservice(AppModule, {
  transport: Transport.RMQ,
  options: {
    urls: ['amqp://localhost:5672'],
    queue: 'cats_queue',
    queueOptions: {
      durable: false
    },
  },
});
```

> **Hint** The `Transport` enum is imported from the `@nestjs/microservices` package.

#### Options[#](/microservices/rabbitmq#options)

The `options` property is specific to the chosen transporter. The **RabbitMQ** transporter exposes the properties described below.

|                         |                                                                                                                                                                                                                                                                                                                                                                  |
| ----------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `urls`                  | An array of connection URLs to try in order                                                                                                                                                                                                                                                                                                                      |
| `queue`                 | Queue name which your server will listen to                                                                                                                                                                                                                                                                                                                      |
| `prefetchCount`         | Sets the prefetch count for the channel                                                                                                                                                                                                                                                                                                                          |
| `isGlobalPrefetchCount` | Enables per channel prefetching                                                                                                                                                                                                                                                                                                                                  |
| `noAck`                 | If `false`, manual acknowledgment mode enabled                                                                                                                                                                                                                                                                                                                   |
| `consumerTag`           | A name which the server will use to distinguish message deliveries for the consumer; mustn’t be already in use on the channel. It’s usually easier to omit this, in which case the server will create a random name and supply it in the reply. Consumer Tag Identifier (read more [here](https://amqp-node.github.io/amqplib/channel_api.html#channel_consume)) |
| `queueOptions`          | Additional queue options (read more [here](https://amqp-node.github.io/amqplib/channel_api.html#channel_assertQueue))                                                                                                                                                                                                                                            |
| `socketOptions`         | Additional socket options (read more [here](https://amqp-node.github.io/amqplib/channel_api.html#connect))                                                                                                                                                                                                                                                       |
| `headers`               | Headers to be sent along with every message                                                                                                                                                                                                                                                                                                                      |
| `replyQueue`            | Reply queue for the producer. Default is `amq.rabbitmq.reply-to`                                                                                                                                                                                                                                                                                                 |
| `persistent`            | If truthy, the message will survive broker restarts provided it’s in a queue that also survives restarts                                                                                                                                                                                                                                                         |
| `noAssert`              | When false, a queue will not be asserted before consuming                                                                                                                                                                                                                                                                                                        |
| `wildcards`             | Set to true only if you want to use Topic Exchange for routing messages to queues. Enabling this will allow you to use wildcards (\*, #) as message and event patterns                                                                                                                                                                                           |
| `exchange`              | Name for the exchange. Defaults to the queue name when "wildcards" is set to true                                                                                                                                                                                                                                                                                |
| `exchangeType`          | Type of the exchange. Default is `topic`. Valid values are `direct`, `fanout`, `topic`, and `headers`                                                                                                                                                                                                                                                            |
| `routingKey`            | Additional routing key for the topic exchange                                                                                                                                                                                                                                                                                                                    |
| `maxConnectionAttempts` | Maximum number of connection attempts. Applies only to the consumer configuration. -1 === infinite                                                                                                                                                                                                                                                               |

#### Client[#](/microservices/rabbitmq#client)

Like other microservice transporters, you have [several options](https://docs.nestjs.com/microservices/basics#client) for creating a RabbitMQ `ClientProxy` instance.

One method for creating an instance is to use the `ClientsModule`. To create a client instance with the `ClientsModule`, import it and use the `register()` method to pass an options object with the same properties shown above in the `createMicroservice()` method, as well as a `name` property to be used as the injection token. Read more about `ClientsModule`[here](https://docs.nestjs.com/microservices/basics#client).

```typescript

@Module({
  imports: [
    ClientsModule.register([
      {
        name: 'MATH_SERVICE',
        transport: Transport.RMQ,
        options: {
          urls: ['amqp://localhost:5672'],
          queue: 'cats_queue',
          queueOptions: {
            durable: false
          },
        },
      },
    ]),
  ]
  ...
})
```

Other options to create a client (either `ClientProxyFactory` or `@Client()`) can be used as well. You can read about them [here](https://docs.nestjs.com/microservices/basics#client).

#### Context[#](/microservices/rabbitmq#context)

In more complex scenarios, you may need to access additional information about the incoming request. When using the RabbitMQ transporter, you can access the `RmqContext` object.

JS TS

```typescript

@MessagePattern('notifications')
getNotifications(@Payload() data: number[], @Ctx() context: RmqContext) {
  console.log(`Pattern: ${context.getPattern()}`);
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('notifications')
getNotifications(data, context) {
  console.log(`Pattern: ${context.getPattern()}`);
}
```

> **Hint**`@Payload()`, `@Ctx()` and `RmqContext` are imported from the `@nestjs/microservices` package.

To access the original RabbitMQ message (with the `properties`, `fields`, and `content`), use the `getMessage()` method of the `RmqContext` object, as follows:

JS TS

```typescript

@MessagePattern('notifications')
getNotifications(@Payload() data: number[], @Ctx() context: RmqContext) {
  console.log(context.getMessage());
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('notifications')
getNotifications(data, context) {
  console.log(context.getMessage());
}
```

To retrieve a reference to the RabbitMQ [channel](https://www.rabbitmq.com/channels.html), use the `getChannelRef` method of the `RmqContext` object, as follows:

JS TS

```typescript

@MessagePattern('notifications')
getNotifications(@Payload() data: number[], @Ctx() context: RmqContext) {
  console.log(context.getChannelRef());
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('notifications')
getNotifications(data, context) {
  console.log(context.getChannelRef());
}
```

#### Message acknowledgement[#](/microservices/rabbitmq#message-acknowledgement)

To make sure a message is never lost, RabbitMQ supports [message acknowledgements](https://www.rabbitmq.com/confirms.html). An acknowledgement is sent back by the consumer to tell RabbitMQ that a particular message has been received, processed and that RabbitMQ is free to delete it. If a consumer dies (its channel is closed, connection is closed, or TCP connection is lost) without sending an ack, RabbitMQ will understand that a message wasn't processed fully and will re-queue it.

To enable manual acknowledgment mode, set the `noAck` property to `false`:

```typescript

options: {
  urls: ['amqp://localhost:5672'],
  queue: 'cats_queue',
  noAck: false,
  queueOptions: {
    durable: false
  },
},
```

When manual consumer acknowledgements are turned on, we must send a proper acknowledgement from the worker to signal that we are done with a task.

JS TS

```typescript

@MessagePattern('notifications')
getNotifications(@Payload() data: number[], @Ctx() context: RmqContext) {
  const channel = context.getChannelRef();
  const originalMsg = context.getMessage();

  channel.ack(originalMsg);
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('notifications')
getNotifications(data, context) {
  const channel = context.getChannelRef();
  const originalMsg = context.getMessage();

  channel.ack(originalMsg);
}
```

#### Record builders[#](/microservices/rabbitmq#record-builders)

To configure message options, you can use the `RmqRecordBuilder` class (note: this is doable for event-based flows as well). For example, to set `headers` and `priority` properties, use the `setOptions` method, as follows:

```typescript

const message = ':cat:';
const record = new RmqRecordBuilder(message)
  .setOptions({
    headers: {
      ['x-version']: '1.0.0',
    },
    priority: 3,
  })
  .build();

this.client.send('replace-emoji', record).subscribe(...);
```

> **Hint**`RmqRecordBuilder` class is exported from the `@nestjs/microservices` package.

And you can read these values on the server-side as well, by accessing the `RmqContext`, as follows:

JS TS

```typescript

@MessagePattern('replace-emoji')
replaceEmoji(@Payload() data: string, @Ctx() context: RmqContext): string {
  const { properties: { headers } } = context.getMessage();
  return headers['x-version'] === '1.0.0' ? '🐱' : '🐈';
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('replace-emoji')
replaceEmoji(data, context) {
  const { properties: { headers } } = context.getMessage();
  return headers['x-version'] === '1.0.0' ? '🐱' : '🐈';
}
```

#### Instance status updates[#](/microservices/rabbitmq#instance-status-updates)

To get real-time updates on the connection and the state of the underlying driver instance, you can subscribe to the `status` stream. This stream provides status updates specific to the chosen driver. For the RMQ driver, the `status` stream emits `connected` and `disconnected` events.

```typescript

this.client.status.subscribe((status: RmqStatus) => {
  console.log(status);
});
```

> **Hint** The `RmqStatus` type is imported from the `@nestjs/microservices` package.

Similarly, you can subscribe to the server's `status` stream to receive notifications about the server's status.

```typescript

const server = app.connectMicroservice<MicroserviceOptions>(...);
server.status.subscribe((status: RmqStatus) => {
  console.log(status);
});
```

#### Listening to RabbitMQ events[#](/microservices/rabbitmq#listening-to-rabbitmq-events)

In some cases, you might want to listen to internal events emitted by the microservice. For example, you could listen for the `error` event to trigger additional operations when an error occurs. To do this, use the `on()` method, as shown below:

```typescript

this.client.on('error', (err) => {
  console.error(err);
});
```

Similarly, you can listen to the server's internal events:

```typescript

server.on<RmqEvents>('error', (err) => {
  console.error(err);
});
```

> **Hint** The `RmqEvents` type is imported from the `@nestjs/microservices` package.

#### Underlying driver access[#](/microservices/rabbitmq#underlying-driver-access)

For more advanced use cases, you may need to access the underlying driver instance. This can be useful for scenarios like manually closing the connection or using driver-specific methods. However, keep in mind that for most cases, you **shouldn't need** to access the driver directly.

To do so, you can use the `unwrap()` method, which returns the underlying driver instance. The generic type parameter should specify the type of driver instance you expect.

```typescript

const managerRef =
  this.client.unwrap<import('amqp-connection-manager').AmqpConnectionManager>();
```

Similarly, you can access the server's underlying driver instance:

```typescript

const managerRef =
  server.unwrap<import('amqp-connection-manager').AmqpConnectionManager>();
```

#### Wildcards[#](/microservices/rabbitmq#wildcards)

RabbitMQ supports the use of wildcards in routing keys to allow for flexible message routing. The `#` wildcard matches zero or more words, while the `*` wildcard matches exactly one word.

For example, the routing key `cats.#` matches `cats`, `cats.meow`, and `cats.meow.purr`. The routing key `cats.*` matches `cats.meow` but not `cats.meow.purr`.

To enable wildcard support in your RabbitMQ microservice, set the `wildcards` configuration option to `true` in the options object:

```typescript

const app = await NestFactory.createMicroservice<MicroserviceOptions>(
  AppModule,
  {
    transport: Transport.RMQ,
    options: {
      urls: ['amqp://localhost:5672'],
      queue: 'cats_queue',
      wildcards: true,
    },
  },
);
```

With this configuration, you can use wildcards in your routing keys when subscribing to events/messages. For example, to listen for messages with the routing key `cats.#`, you can use the following code:

```typescript

@MessagePattern('cats.#')
getCats(@Payload() data: { message: string }, @Ctx() context: RmqContext) {
  console.log(`Received message with routing key: ${context.getPattern()}`);

  return {
    message: 'Hello from the cats service!',
  }
}
```

To send a message with a specific routing key, you can use the `send()` method of the `ClientProxy` instance:

```typescript

this.client.send('cats.meow', { message: 'Meow!' }).subscribe((response) => {
  console.log(response);
});
```

----
url: https://docs.nestjs.com/v6/websockets/exception-filters
----

* [Exception filters](https://docs.nestjs.com/v6/websockets/exception-filters#exception-filters)
* [Filters](https://docs.nestjs.com/v6/websockets/exception-filters#filters)
* [Inheritance](https://docs.nestjs.com/v6/websockets/exception-filters#inheritance)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/websockets/exception-filters.md "Suggest Edits")

### Exception filters

The only difference between the HTTP [exception filter](/v6/exception-filters) layer and the corresponding web sockets layer is that instead of throwing `HttpException`, you should instead use `WsException`.

```typescript

throw new WsException('Invalid credentials.');
```

> **Hint** The `WsException` class is imported from the `@nestjs/websockets` package.

With the sample above, Nest will handle the thrown exception and emit the `exception` message with the following structure:

```typescript

{
  status: 'error',
  message: 'Invalid credentials.'
}
```

#### Filters[#](/websockets/exception-filters#filters)

Web sockets exception filters behave equivalently to HTTP exception filters. The following example uses a manually instantiated method-scoped filter. Just as with HTTP based applications, you can also use gateway-scoped filters (i.e., prefix the gateway class with a `@UseFilters()` decorator).

```typescript

@UseFilters(new WsExceptionFilter())
@SubscribeMessage('events')
onEvent(client, data: any): WsResponse<any> {
  const event = 'events';
  return { event, data };
}
```

#### Inheritance[#](/websockets/exception-filters#inheritance)

Typically, you'll create fully customized exception filters crafted to fulfill your application requirements. However, there might be use-cases when you would like to simply extend the **core exception filter**, and override the behavior based on certain factors.

In order to delegate exception processing to the base filter, you need to extend `BaseWsExceptionFilter` and call the inherited `catch()` method.

JS TS

```typescript

import { Catch, ArgumentsHost } from '@nestjs/common';
import { BaseWsExceptionFilter } from '@nestjs/websockets';

@Catch()
export class AllExceptionsFilter extends BaseWsExceptionFilter {
  catch(exception: unknown, host: ArgumentsHost) {
    super.catch(exception, host);
  }
}
```

```typescript

import { Catch } from '@nestjs/common';
import { BaseWsExceptionFilter } from '@nestjs/websockets';

@Catch()
export class AllExceptionsFilter extends BaseWsExceptionFilter {
  catch(exception, host) {
    super.catch(exception, host);
  }
}
```

The above implementation is just a shell demonstrating the approach. Your implementation of the extended exception filter would include your tailored **business logic** (e.g., handling various conditions).

----
url: https://docs.nestjs.com/v6/faq/multiple-servers
----

* [HTTPS](https://docs.nestjs.com/v6/faq/multiple-servers#https)
* [Multiple simultaneous servers](https://docs.nestjs.com/v6/faq/multiple-servers#multiple-simultaneous-servers)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/faq/multiple-servers.md "Suggest Edits")

### HTTPS

To create an application that uses the HTTPS protocol, set the `httpsOptions` property in the options object passed to the `create()` method of the `NestFactory` class:

```typescript

const httpsOptions = {
  key: fs.readFileSync('./secrets/private-key.pem'),
  cert: fs.readFileSync('./secrets/public-certificate.pem'),
};
const app = await NestFactory.create(ApplicationModule, {
  httpsOptions,
});
await app.listen(3000);
```

If you use the `FastifyAdapter`, create the application as follows:

```typescript

const app = await NestFactory.create<NestFastifyApplication>(
  ApplicationModule,
  new FastifyAdapter({ https: httpsOptions }),
);
```

#### Multiple simultaneous servers[#](/faq/multiple-servers#multiple-simultaneous-servers)

The following recipe shows how to instantiate a Nest application that listens on multiple ports (for example, on a non-HTTPS port and an HTTPS port) simultaneously.

```typescript

const httpsOptions = {
  key: fs.readFileSync('./secrets/private-key.pem'),
  cert: fs.readFileSync('./secrets/public-certificate.pem'),
};

const server = express();
const app = await NestFactory.create(
  ApplicationModule,
  new ExpressAdapter(server),
);
await app.init();

http.createServer(server).listen(3000);
https.createServer(httpsOptions, server).listen(443);
```

> **Hint** The `ExpressAdapter` is imported from the `@nestjs/platform-express` package. The `http` and `https` packages are native Node.js packages.

> **Warning** This recipe does not work with [GraphQL Subscriptions](/v6/graphql/subscriptions).

----
url: https://docs.nestjs.com/v8/support
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Support](https://docs.nestjs.com/v8/support#support)
* [How can you help?](https://docs.nestjs.com/v8/support#how-can-you-help)

----
url: https://docs.nestjs.com/v9/openapi/migration-guide
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Migration guide](https://docs.nestjs.com/v9/openapi/migration-guide#migration-guide)
* [Breaking changes](https://docs.nestjs.com/v9/openapi/migration-guide#breaking-changes)
* [New methods](https://docs.nestjs.com/v9/openapi/migration-guide#new-methods)

----
url: https://docs.nestjs.com/v8/microservices/mqtt
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [MQTT](https://docs.nestjs.com/v8/microservices/mqtt#mqtt)
* [Installation](https://docs.nestjs.com/v8/microservices/mqtt#installation)
* [Overview](https://docs.nestjs.com/v8/microservices/mqtt#overview)
* [Options](https://docs.nestjs.com/v8/microservices/mqtt#options)
* [Client](https://docs.nestjs.com/v8/microservices/mqtt#client)
* [Context](https://docs.nestjs.com/v8/microservices/mqtt#context)
* [Wildcards](https://docs.nestjs.com/v8/microservices/mqtt#wildcards)
* [Record builders](https://docs.nestjs.com/v8/microservices/mqtt#record-builders)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/microservices/mqtt.md "Suggest Edits")

### MQTT

[MQTT](https://mqtt.org/) (Message Queuing Telemetry Transport) is an open source, lightweight messaging protocol, optimized for low latency. This protocol provides a scalable and cost-efficient way to connect devices using a **publish/subscribe** model. A communication system built on MQTT consists of the publishing server, a broker and one or more clients. It is designed for constrained devices and low-bandwidth, high-latency or unreliable networks.

#### Installation[#](/microservices/mqtt#installation)

To start building MQTT-based microservices, first install the required package:

```bash

$ npm i --save mqtt
```

#### Overview[#](/microservices/mqtt#overview)

To use the MQTT transporter, pass the following options object to the `createMicroservice()` method:

main.ts

JS TS

```typescript

const app = await NestFactory.createMicroservice<MicroserviceOptions>(AppModule, {
  transport: Transport.MQTT,
  options: {
    url: 'mqtt://localhost:1883',
  },
});
```

```typescript

const app = await NestFactory.createMicroservice(AppModule, {
  transport: Transport.MQTT,
  options: {
    url: 'mqtt://localhost:1883',
  },
});
```

> **Hint** The `Transport` enum is imported from the `@nestjs/microservices` package.

#### Options[#](/microservices/mqtt#options)

The `options` object is specific to the chosen transporter. The **MQTT** transporter exposes the properties described [here](https://github.com/mqttjs/MQTT.js/#mqttclientstreambuilder-options).

#### Client[#](/microservices/mqtt#client)

Like other microservice transporters, you have [several options](https://docs.nestjs.com/microservices/basics#client) for creating a MQTT `ClientProxy` instance.

One method for creating an instance is to use use the `ClientsModule`. To create a client instance with the `ClientsModule`, import it and use the `register()` method to pass an options object with the same properties shown above in the `createMicroservice()` method, as well as a `name` property to be used as the injection token. Read more about `ClientsModule`[here](https://docs.nestjs.com/microservices/basics#client).

```typescript

@Module({
  imports: [
    ClientsModule.register([
      {
        name: 'MATH_SERVICE',
        transport: Transport.MQTT,
        options: {
          url: 'mqtt://localhost:1883',
        }
      },
    ]),
  ]
  ...
})
```

Other options to create a client (either `ClientProxyFactory` or `@Client()`) can be used as well. You can read about them [here](https://docs.nestjs.com/microservices/basics#client).

#### Context[#](/microservices/mqtt#context)

In more sophisticated scenarios, you may want to access more information about the incoming request. When using the MQTT transporter, you can access the `MqttContext` object.

JS TS

```typescript

@MessagePattern('notifications')
getNotifications(@Payload() data: number[], @Ctx() context: MqttContext) {
  console.log(`Topic: ${context.getTopic()}`);
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('notifications')
getNotifications(data, context) {
  console.log(`Topic: ${context.getTopic()}`);
}
```

> **Hint**`@Payload()`, `@Ctx()` and `MqttContext` are imported from the `@nestjs/microservices` package.

To access the original mqtt [packet](https://github.com/mqttjs/mqtt-packet), use the `getPacket()` method of the `MqttContext` object, as follows:

JS TS

```typescript

@MessagePattern('notifications')
getNotifications(@Payload() data: number[], @Ctx() context: MqttContext) {
  console.log(context.getPacket());
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('notifications')
getNotifications(data, context) {
  console.log(context.getPacket());
}
```

#### Wildcards[#](/microservices/mqtt#wildcards)

A subscription may be to an explicit topic, or it may include wildcards. Two wildcards are available, `+` and `#`. `+` is a single-level wildcard, while `#` is a multi-level wildcard which covers many topic levels.

JS TS

```typescript

@MessagePattern('sensors/+/temperature/+')
getTemperature(@Ctx() context: MqttContext) {
  console.log(`Topic: ${context.getTopic()}`);
}
```

```typescript

@Bind(Ctx())
@MessagePattern('sensors/+/temperature/+')
getTemperature(context) {
  console.log(`Topic: ${context.getTopic()}`);
}
```

#### Record builders[#](/microservices/mqtt#record-builders)

To configure message options (adjust the QoS level, set the Retain or DUP flags, or add additional properties to the payload), you can use the `MqttRecordBuilder` class. For example, to set `QoS` to `2` use the `setQoS` method, as follows:

```typescript

const userProperties = { 'x-version': '1.0.0' };
const record = new MqttRecordBuilder(':cat:')
  .setProperties({ userProperties })
  .setQoS(1)
  .build();
client.send('replace-emoji', record).subscribe(...);
```

> **Hint**`MqttRecordBuilder` class is exported from the `@nestjs/microservices` package.

And you can read these options on the server-side as well, by accessing the `MqttContext`.

JS TS

```typescript

@MessagePattern('replace-emoji')
replaceEmoji(@Payload() data: string, @Ctx() context: MqttContext): string {
  const { properties: { userProperties } } = context.getPacket();
  return userProperties['x-version'] === '1.0.0' ? '🐱' : '🐈';
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('replace-emoji')
replaceEmoji(data, context) {
  const { properties: { userProperties } } = context.getPacket();
  return userProperties['x-version'] === '1.0.0' ? '🐱' : '🐈';
}
```

In some cases you might want to configure user properties for multiple requests, you can pass these options to the `ClientProxyFactory`.

```typescript

import { Module } from '@nestjs/common';
import { ClientProxyFactory, Transport } from '@nestjs/microservices';

@Module({
  providers: [
    {
      provide: 'API_v1',
      useFactory: () =>
        ClientProxyFactory.create({
          transport: Transport.MQTT,
          options: {
            url: 'mqtt://localhost:1833',
            userProperties: { 'x-version': '1.0.0' },
          },
        }),
    },
  ],
})
export class ApiModule {}
```

----
url: https://docs.nestjs.com/v7/recipes/cqrs
----

* [CQRS](https://docs.nestjs.com/v7/recipes/cqrs#cqrs)
* [Installation](https://docs.nestjs.com/v7/recipes/cqrs#installation)
* [Commands](https://docs.nestjs.com/v7/recipes/cqrs#commands)
* [Events](https://docs.nestjs.com/v7/recipes/cqrs#events)
* [Sagas](https://docs.nestjs.com/v7/recipes/cqrs#sagas)
* [Queries](https://docs.nestjs.com/v7/recipes/cqrs#queries)
* [Setup](https://docs.nestjs.com/v7/recipes/cqrs#setup)
* [Summary](https://docs.nestjs.com/v7/recipes/cqrs#summary)
* [Example](https://docs.nestjs.com/v7/recipes/cqrs#example)

```bash

$ npm install --save @nestjs/cqrs
```

#### Commands[#](/recipes/cqrs#commands)

In this model, each action is called a **Command**. When a command is dispatched, the application reacts to it. Commands can be dispatched from the services layer, or directly from controllers/gateways. Commands are consumed by **Command Handlers**.

heroes-game.service.ts

JS TS

```typescript

@Injectable()
export class HeroesGameService {
  constructor(private commandBus: CommandBus) {}

  async killDragon(heroId: string, killDragonDto: KillDragonDto) {
    return this.commandBus.execute(
      new KillDragonCommand(heroId, killDragonDto.dragonId)
    );
  }
}
```

```typescript

@Injectable()
@Dependencies(CommandBus)
export class HeroesGameService {
  constructor(commandBus) {
    this.commandBus = commandBus;
  }

  async killDragon(heroId, killDragonDto) {
    return this.commandBus.execute(
      new KillDragonCommand(heroId, killDragonDto.dragonId)
    );
  }
}
```

Here's a sample service that dispatches `KillDragonCommand`. Let's see how the command looks:

kill-dragon.command.ts

JS TS

```typescript

export class KillDragonCommand {
  constructor(
    public readonly heroId: string,
    public readonly dragonId: string,
  ) {}
}
```

```typescript

export class KillDragonCommand {
  constructor(heroId, dragonId) {
    this.heroId = heroId;
    this.dragonId = dragonId;
  }
}
```

The `CommandBus` is a **stream** of commands. It delegates commands to the equivalent handlers. Each command must have a corresponding **Command Handler**:

kill-dragon.handler.ts

JS TS

```typescript

@CommandHandler(KillDragonCommand)
export class KillDragonHandler implements ICommandHandler<KillDragonCommand> {
  constructor(private repository: HeroRepository) {}

  async execute(command: KillDragonCommand) {
    const { heroId, dragonId } = command;
    const hero = this.repository.findOneById(+heroId);

    hero.killEnemy(dragonId);
    await this.repository.persist(hero);
  }
}
```

```typescript

@CommandHandler(KillDragonCommand)
@Dependencies(HeroRepository)
export class KillDragonHandler {
  constructor(repository) {
    this.repository = repository;
  }

  async execute(command) {
    const { heroId, dragonId } = command;
    const hero = this.repository.findOneById(+heroId);

    hero.killEnemy(dragonId);
    await this.repository.persist(hero);
  }
}
```

With this approach, every application state change is driven by the occurrence of a **Command**. The logic is encapsulated in handlers. With this approach, we can simply add behavior like logging or persisting commands in the database (e.g., for diagnostics purposes).

#### Events[#](/recipes/cqrs#events)

Command handlers neatly encapsulate logic. While beneficial, the application structure is still not flexible enough, not **reactive**. To remedy this, we also introduce **events**.

hero-killed-dragon.event.ts

JS TS

```typescript

export class HeroKilledDragonEvent {
  constructor(
    public readonly heroId: string,
    public readonly dragonId: string,
  ) {}
}
```

```typescript

export class HeroKilledDragonEvent {
  constructor(heroId, dragonId) {
    this.heroId = heroId;
    this.dragonId = dragonId;
  }
}
```

Events are asynchronous. They are dispatched either by **models** or directly using `EventBus`. In order to dispatch events, models have to extend the `AggregateRoot` class.

hero.model.ts

JS TS

```typescript

export class Hero extends AggregateRoot {
  constructor(private id: string) {
    super();
  }

  killEnemy(enemyId: string) {
    // logic
    this.apply(new HeroKilledDragonEvent(this.id, enemyId));
  }
}
```

```typescript

export class Hero extends AggregateRoot {
  constructor(id) {
    super();
    this.id = id;
  }

  killEnemy(enemyId) {
    // logic
    this.apply(new HeroKilledDragonEvent(this.id, enemyId));
  }
}
```

The `apply()` method does not dispatch events yet because there's no relationship between the model and the `EventPublisher` class. How do we associate the model and the publisher? By using a publisher `mergeObjectContext()` method inside our command handler.

kill-dragon.handler.ts

JS TS

```typescript

@CommandHandler(KillDragonCommand)
export class KillDragonHandler implements ICommandHandler<KillDragonCommand> {
  constructor(
    private repository: HeroRepository,
    private publisher: EventPublisher,
  ) {}

  async execute(command: KillDragonCommand) {
    const { heroId, dragonId } = command;
    const hero = this.publisher.mergeObjectContext(
      await this.repository.findOneById(+heroId),
    );
    hero.killEnemy(dragonId);
    hero.commit();
  }
}
```

```typescript

@CommandHandler(KillDragonCommand)
@Dependencies(HeroRepository, EventPublisher)
export class KillDragonHandler {
  constructor(repository, publisher) {
    this.repository = repository;
    this.publisher = publisher;
  }

  async execute(command) {
    const { heroId, dragonId } = command;
    const hero = this.publisher.mergeObjectContext(
      await this.repository.findOneById(+heroId),
    );
    hero.killEnemy(dragonId);
    hero.commit();
  }
}
```

Now everything works as expected. Notice that we need to `commit()` events since they're not being dispatched immediately. Obviously, an object doesn't have to exist up front. We can easily merge type context as well:

```typescript

const HeroModel = this.publisher.mergeClassContext(Hero);
new HeroModel('id');
```

Now the model has the ability to publish events. Additionally, we can emit events manually using `EventBus`:

```typescript

this.eventBus.publish(new HeroKilledDragonEvent());
```

> **Hint** The `EventBus` is an injectable class.

Each event can have multiple **Event Handlers**.

hero-killed-dragon.handler.ts

JS TS

```typescript

@EventsHandler(HeroKilledDragonEvent)
export class HeroKilledDragonHandler implements IEventHandler<HeroKilledDragonEvent> {
  constructor(private repository: HeroRepository) {}

  handle(event: HeroKilledDragonEvent) {
    // logic
  }
}
```

Now we can move the **write logic** into the event handlers.

#### Sagas[#](/recipes/cqrs#sagas)

This type of **Event-Driven Architecture** improves application **reactiveness and scalability**. Now, when we have events, we can simply react to them in various ways. **Sagas** are the final building block from an architectural point of view.

Sagas are an extremely powerful feature. A single saga may listen for 1..\* events. Using the [RxJS](https://github.com/ReactiveX/rxjs) library, it can combine, merge, filter or apply other `RxJS` operators on the event stream. Each saga returns an Observable which contains a command. This command is dispatched **asynchronously**.

heroes-game.saga.ts

JS TS

```typescript

@Injectable()
export class HeroesGameSagas {
  @Saga()
  dragonKilled = (events$: Observable<any>): Observable<ICommand> => {
    return events$.pipe(
      ofType(HeroKilledDragonEvent),
      map((event) => new DropAncientItemCommand(event.heroId, fakeItemID)),
    );
  }
}
```

```typescript

@Injectable()
export class HeroesGameSagas {
  @Saga()
  dragonKilled = (events$) => {
    return events$.pipe(
      ofType(HeroKilledDragonEvent),
      map((event) => new DropAncientItemCommand(event.heroId, fakeItemID)),
    );
  }
}
```

> **Hint** The `ofType` operator is exported from the `@nestjs/cqrs` package.

```typescript

export const CommandHandlers = [KillDragonHandler, DropAncientItemHandler];
export const EventHandlers =  [HeroKilledDragonHandler, HeroFoundItemHandler];

@Module({
  imports: [CqrsModule],
  controllers: [HeroesGameController],
  providers: [
    HeroesGameService,
    HeroesGameSagas,
    ...CommandHandlers,
    ...EventHandlers,
    HeroRepository,
  ]
})
export class HeroesGameModule {}
```

#### Summary[#](/recipes/cqrs#summary)

`CommandBus`, `QueryBus` and `EventBus` are **Observables**. This means that you can easily subscribe to the whole stream and enrich your application with **Event Sourcing**.

#### Example[#](/recipes/cqrs#example)

A working example is available [here](https://github.com/kamilmysliwiec/nest-cqrs-example).

----
url: https://docs.nestjs.com/v5/techniques/security
----

### Security

In this chapter you will learn some techniques that will allow you to increase the security of your applications.

#### Helmet

[Helmet](https://github.com/helmetjs/helmet) can help protect your app from some well-known web vulnerabilities by setting HTTP headers appropriately. Generally, Helmet is just a collection of 12 smaller middleware functions that set security-related HTTP headers (read [more](https://github.com/helmetjs/helmet#how-it-works)). Firstly, install the required package:

```bash

$ npm i --save helmet
```

Once the installation is completed, apply it as a global middleware.

TypeScript

```typescript

import * as helmet from 'helmet';
// somewhere in your initialization file
app.use(helmet());
```

#### CORS

Cross-origin resource sharing (CORS) is a mechanism that allows resources to be requested from another domain. Under the hood, Nest makes use of [cors](https://github.com/expressjs/cors) package, that provides a bunch of options that you may customize based on your requirements. In order to enable CORS, you have to call `enableCors()` method.

TypeScript

```typescript

const app = await NestFactory.create(ApplicationModule);
app.enableCors();
await app.listen(3000);
```

Also, you can pass a configuration object as a parameter of this function. The available properties are exhaustively described in the official [cors](https://github.com/expressjs/cors) repository. A different way is to use a Nest options object:

TypeScript

```typescript

const app = await NestFactory.create(ApplicationModule, { cors: true });
await app.listen(3000);
```

Instead of passing a boolean value, you can use a cors configuration object as well (read [more](https://github.com/expressjs/cors#configuration-options)).

#### CSRF

Cross-site request forgery (known as CSRF or XSRF) is a type of malicious exploit of a website where **unauthorized** commands are transmitted from a user that the web application trusts. To mitigate this kind of attacks you can use the [csurf](https://github.com/expressjs/csurf) package. Firstly, install the required package:

```bash

$ npm i --save csurf
```

Once the installation is completed, apply it as a global middleware.

TypeScript

```typescript

import * as csurf from 'csurf';
// somewhere in your initialization file
app.use(csurf());
```

#### Rate limiting

To protect your applications from brute-force attacks, you have to implement some kind of rate-limiting. Luckily, there is a bunch of various middleware available on the NPM already. One of them is [express-rate-limit](https://github.com/nfriedly/express-rate-limit).

```bash

$ npm i --save express-rate-limit
```

Once the installation is completed, apply it as a global middleware.

TypeScript

```typescript


import * as rateLimit from 'express-rate-limit';
// somewhere in your initialization file
app.use(rateLimit({
  windowMs: 15 * 60 * 1000, // 15 minutes
  max: 100 // limit each IP to 100 requests per windowMs
}));
```

> **Hint** If you work wtih `FastifyAdapter`, consider using [fastify-rate-limit](https://github.com/fastify/fastify-rate-limit) instead.

* Security
* Helmet
* CORS
* CSRF
* Rate limiting

----
url: https://docs.nestjs.com/v10/interceptors
----

* [Interceptors](https://docs.nestjs.com/v10/interceptors#interceptors)
* [Basics](https://docs.nestjs.com/v10/interceptors#basics)
* [Execution context](https://docs.nestjs.com/v10/interceptors#execution-context)
* [Call handler](https://docs.nestjs.com/v10/interceptors#call-handler)
* [Aspect interception](https://docs.nestjs.com/v10/interceptors#aspect-interception)
* [Binding interceptors](https://docs.nestjs.com/v10/interceptors#binding-interceptors)
* [Response mapping](https://docs.nestjs.com/v10/interceptors#response-mapping)
* [Exception mapping](https://docs.nestjs.com/v10/interceptors#exception-mapping)
* [Stream overriding](https://docs.nestjs.com/v10/interceptors#stream-overriding)
* [More operators](https://docs.nestjs.com/v10/interceptors#more-operators)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/interceptors.md "Suggest Edits")

### Interceptors

An interceptor is a class annotated with the `@Injectable()` decorator and implements the `NestInterceptor` interface.

Each interceptor implements the `intercept()` method, which takes two arguments. The first one is the `ExecutionContext` instance (exactly the same object as for [guards](/v10/guards)). The `ExecutionContext` inherits from `ArgumentsHost`. We saw `ArgumentsHost` before in the exception filters chapter. There, we saw that it's a wrapper around arguments that have been passed to the original handler, and contains different arguments arrays based on the type of the application. You can refer back to the [exception filters](https://docs.nestjs.com/exception-filters#arguments-host) for more on this topic.

#### Execution context[#](/interceptors#execution-context)

By extending `ArgumentsHost`, `ExecutionContext` also adds several new helper methods that provide additional details about the current execution process. These details can be helpful in building more generic interceptors that can work across a broad set of controllers, methods, and execution contexts. Learn more about `ExecutionContext`[here](/v10/fundamentals/execution-context).

#### Call handler[#](/interceptors#call-handler)

The second argument is a `CallHandler`. The `CallHandler` interface implements the `handle()` method, which you can use to invoke the route handler method at some point in your interceptor. If you don't call the `handle()` method in your implementation of the `intercept()` method, the route handler method won't be executed at all.

This approach means that the `intercept()` method effectively **wraps** the request/response stream. As a result, you may implement custom logic **both before and after** the execution of the final route handler. It's clear that you can write code in your `intercept()` method that executes **before** calling `handle()`, but how do you affect what happens afterward? Because the `handle()` method returns an `Observable`, we can use powerful [RxJS](https://github.com/ReactiveX/rxjs) operators to further manipulate the response. Using Aspect Oriented Programming terminology, the invocation of the route handler (i.e., calling `handle()`) is called a [Pointcut](https://en.wikipedia.org/wiki/Pointcut), indicating that it's the point at which our additional logic is inserted.

Consider, for example, an incoming `POST /cats` request. This request is destined for the `create()` handler defined inside the `CatsController`. If an interceptor which does not call the `handle()` method is called anywhere along the way, the `create()` method won't be executed. Once `handle()` is called (and its `Observable` has been returned), the `create()` handler will be triggered. And once the response stream is received via the `Observable`, additional operations can be performed on the stream, and a final result returned to the caller.

## Explore your graph with NestJS Devtools

* **Graph visualizer
* **Routes navigator
* **Interactive playground
* **CI/CD integration

[Sign up](https://devtools.nestjs.com "Devtools | NestJS - A node.js framework built on top of TypeScript")

#### Aspect interception[#](/interceptors#aspect-interception)

The first use case we'll look at is to use an interceptor to log user interaction (e.g., storing user calls, asynchronously dispatching events or calculating a timestamp). We show a simple `LoggingInterceptor` below:

logging.interceptor.ts

JS TS

```typescript

import { Injectable, NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
import { Observable } from 'rxjs';
import { tap } from 'rxjs/operators';

@Injectable()
export class LoggingInterceptor implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    console.log('Before...');

    const now = Date.now();
    return next
      .handle()
      .pipe(
        tap(() => console.log(`After... ${Date.now() - now}ms`)),
      );
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';
import { Observable } from 'rxjs';
import { tap } from 'rxjs/operators';

@Injectable()
export class LoggingInterceptor {
  intercept(context, next) {
    console.log('Before...');

    const now = Date.now();
    return next
      .handle()
      .pipe(
        tap(() => console.log(`After... ${Date.now() - now}ms`)),
      );
  }
}
```

> **Hint** The `NestInterceptor<T, R>` is a generic interface in which `T` indicates the type of an `Observable<T>` (supporting the response stream), and `R` is the type of the value wrapped by `Observable<R>`.

> **Notice** Interceptors, like controllers, providers, guards, and so on, can **inject dependencies** through their `constructor`.

Since `handle()` returns an RxJS `Observable`, we have a wide choice of operators we can use to manipulate the stream. In the example above, we used the `tap()` operator, which invokes our anonymous logging function upon graceful or exceptional termination of the observable stream, but doesn't otherwise interfere with the response cycle.

#### Binding interceptors[#](/interceptors#binding-interceptors)

In order to set up the interceptor, we use the `@UseInterceptors()` decorator imported from the `@nestjs/common` package. Like [pipes](/v10/pipes) and [guards](/v10/guards), interceptors can be controller-scoped, method-scoped, or global-scoped.

cats.controller.ts

JS TS

```typescript

@UseInterceptors(LoggingInterceptor)
export class CatsController {}
```

> **Hint** The `@UseInterceptors()` decorator is imported from the `@nestjs/common` package.

Using the above construction, each route handler defined in `CatsController` will use `LoggingInterceptor`. When someone calls the `GET /cats` endpoint, you'll see the following output in your standard output:

```typescript

Before...
After... 1ms
```

Note that we passed the `LoggingInterceptor` class (instead of an instance), leaving responsibility for instantiation to the framework and enabling dependency injection. As with pipes, guards, and exception filters, we can also pass an in-place instance:

cats.controller.ts

JS TS

```typescript

@UseInterceptors(new LoggingInterceptor())
export class CatsController {}
```

As mentioned, the construction above attaches the interceptor to every handler declared by this controller. If we want to restrict the interceptor's scope to a single method, we simply apply the decorator at the **method level**.

In order to set up a global interceptor, we use the `useGlobalInterceptors()` method of the Nest application instance:

```typescript

const app = await NestFactory.create(AppModule);
app.useGlobalInterceptors(new LoggingInterceptor());
```

Global interceptors are used across the whole application, for every controller and every route handler. In terms of dependency injection, global interceptors registered from outside of any module (with `useGlobalInterceptors()`, as in the example above) cannot inject dependencies since this is done outside the context of any module. In order to solve this issue, you can set up an interceptor **directly from any module** using the following construction:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { APP_INTERCEPTOR } from '@nestjs/core';

@Module({
  providers: [
    {
      provide: APP_INTERCEPTOR,
      useClass: LoggingInterceptor,
    },
  ],
})
export class AppModule {}
```

> **Hint** When using this approach to perform dependency injection for the interceptor, note that regardless of the module where this construction is employed, the interceptor is, in fact, global. Where should this be done? Choose the module where the interceptor (`LoggingInterceptor` in the example above) is defined. Also, `useClass` is not the only way of dealing with custom provider registration. Learn more [here](/v10/fundamentals/custom-providers).

#### Response mapping[#](/interceptors#response-mapping)

We already know that `handle()` returns an `Observable`. The stream contains the value **returned** from the route handler, and thus we can easily mutate it using RxJS's `map()` operator.

> **Warning** The response mapping feature doesn't work with the library-specific response strategy (using the `@Res()` object directly is forbidden).

Let's create the `TransformInterceptor`, which will modify each response in a trivial way to demonstrate the process. It will use RxJS's `map()` operator to assign the response object to the `data` property of a newly created object, returning the new object to the client.

transform.interceptor.ts

JS TS

```typescript

import { Injectable, NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';

export interface Response<T> {
  data: T;
}

@Injectable()
export class TransformInterceptor<T> implements NestInterceptor<T, Response<T>> {
  intercept(context: ExecutionContext, next: CallHandler): Observable<Response<T>> {
    return next.handle().pipe(map(data => ({ data })));
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';
import { map } from 'rxjs/operators';

@Injectable()
export class TransformInterceptor {
  intercept(context, next) {
    return next.handle().pipe(map(data => ({ data })));
  }
}
```

> **Hint** Nest interceptors work with both synchronous and asynchronous `intercept()` methods. You can simply switch the method to `async` if necessary.

With the above construction, when someone calls the `GET /cats` endpoint, the response would look like the following (assuming that route handler returns an empty array `[]`):

```json

{
  "data": []
}
```

Interceptors have great value in creating re-usable solutions to requirements that occur across an entire application. For example, imagine we need to transform each occurrence of a `null` value to an empty string `''`. We can do it using one line of code and bind the interceptor globally so that it will automatically be used by each registered handler.

JS TS

```typescript

import { Injectable, NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';

@Injectable()
export class ExcludeNullInterceptor implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    return next
      .handle()
      .pipe(map(value => value === null ? '' : value ));
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';
import { map } from 'rxjs/operators';

@Injectable()
export class ExcludeNullInterceptor {
  intercept(context, next) {
    return next
      .handle()
      .pipe(map(value => value === null ? '' : value ));
  }
}
```

#### Exception mapping[#](/interceptors#exception-mapping)

Another interesting use-case is to take advantage of RxJS's `catchError()` operator to override thrown exceptions:

errors.interceptor.ts

JS TS

```typescript

import {
  Injectable,
  NestInterceptor,
  ExecutionContext,
  BadGatewayException,
  CallHandler,
} from '@nestjs/common';
import { Observable, throwError } from 'rxjs';
import { catchError } from 'rxjs/operators';

@Injectable()
export class ErrorsInterceptor implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    return next
      .handle()
      .pipe(
        catchError(err => throwError(() => new BadGatewayException())),
      );
  }
}
```

```typescript

import { Injectable, BadGatewayException } from '@nestjs/common';
import { throwError } from 'rxjs';
import { catchError } from 'rxjs/operators';

@Injectable()
export class ErrorsInterceptor {
  intercept(context, next) {
    return next
      .handle()
      .pipe(
        catchError(err => throwError(() => new BadGatewayException())),
      );
  }
}
```

#### Stream overriding[#](/interceptors#stream-overriding)

There are several reasons why we may sometimes want to completely prevent calling the handler and return a different value instead. An obvious example is to implement a cache to improve response time. Let's take a look at a simple **cache interceptor** that returns its response from a cache. In a realistic example, we'd want to consider other factors like TTL, cache invalidation, cache size, etc., but that's beyond the scope of this discussion. Here we'll provide a basic example that demonstrates the main concept.

cache.interceptor.ts

JS TS

```typescript

import { Injectable, NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
import { Observable, of } from 'rxjs';

@Injectable()
export class CacheInterceptor implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    const isCached = true;
    if (isCached) {
      return of([]);
    }
    return next.handle();
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';
import { of } from 'rxjs';

@Injectable()
export class CacheInterceptor {
  intercept(context, next) {
    const isCached = true;
    if (isCached) {
      return of([]);
    }
    return next.handle();
  }
}
```

Our `CacheInterceptor` has a hardcoded `isCached` variable and a hardcoded response `[]` as well. The key point to note is that we return a new stream here, created by the RxJS `of()` operator, therefore the route handler **won't be called** at all. When someone calls an endpoint that makes use of `CacheInterceptor`, the response (a hardcoded, empty array) will be returned immediately. In order to create a generic solution, you can take advantage of `Reflector` and create a custom decorator. The `Reflector` is well described in the [guards](/v10/guards) chapter.

#### More operators[#](/interceptors#more-operators)

The possibility of manipulating the stream using RxJS operators gives us many capabilities. Let's consider another common use case. Imagine you would like to handle **timeouts** on route requests. When your endpoint doesn't return anything after a period of time, you want to terminate with an error response. The following construction enables this:

timeout.interceptor.ts

JS TS

```typescript

import { Injectable, NestInterceptor, ExecutionContext, CallHandler, RequestTimeoutException } from '@nestjs/common';
import { Observable, throwError, TimeoutError } from 'rxjs';
import { catchError, timeout } from 'rxjs/operators';

@Injectable()
export class TimeoutInterceptor implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    return next.handle().pipe(
      timeout(5000),
      catchError(err => {
        if (err instanceof TimeoutError) {
          return throwError(() => new RequestTimeoutException());
        }
        return throwError(() => err);
      }),
    );
  };
};
```

```typescript

import { Injectable, RequestTimeoutException } from '@nestjs/common';
import { Observable, throwError, TimeoutError } from 'rxjs';
import { catchError, timeout } from 'rxjs/operators';

@Injectable()
export class TimeoutInterceptor {
  intercept(context, next) {
    return next.handle().pipe(
      timeout(5000),
      catchError(err => {
        if (err instanceof TimeoutError) {
          return throwError(() => new RequestTimeoutException());
        }
        return throwError(() => err);
      }),
    );
  };
};
```

After 5 seconds, request processing will be canceled. You can also add custom logic before throwing `RequestTimeoutException` (e.g. release resources).

----
url: https://docs.nestjs.com/faq/keep-alive-connections
----

[Skip to content](#content)

On this page

* [Keep alive connections](https://docs.nestjs.com/faq/keep-alive-connections#keep-alive-connections)
* [Usage](https://docs.nestjs.com/faq/keep-alive-connections#usage)

### Keep alive connections

By default, the NestJS HTTP adapters wait until responses have finished before closing the application. Sometimes this behavior is unwanted or unexpected: some requests use `Connection: Keep-Alive` headers and keep their connections open for a long time.

If you want your application to always exit without waiting for these connections to end, enable the `forceCloseConnections` option when creating your NestJS application.

> **Hint** Most users don't need this option. The typical symptom that you do is an application that doesn't exit when you expect it to, usually with `app.enableShutdownHooks()` enabled, and most often during development when running with `--watch`.

#### Usage[#](/faq/keep-alive-connections#usage)

In your `main.ts` file, enable the option when creating your NestJS application:

```typescript

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module.js';

async function bootstrap() {
  const app = await NestFactory.create(AppModule, {
    forceCloseConnections: true,
  });
  await app.listen(process.env.PORT ?? 3000);
}

await bootstrap();
```

> **Note** Both the Express and the Fastify adapter implement the `forceCloseConnections` application option. With Fastify, this requires NestJS v12.1 or later. In earlier versions, pass Fastify's own `forceCloseConnections` server option to the `FastifyAdapter` constructor instead.

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/faq/keep-alive-connections.md)

----
url: https://docs.nestjs.com/v8/graphql/mapped-types
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Mapped types](https://docs.nestjs.com/v8/graphql/mapped-types#mapped-types)
* [Partial](https://docs.nestjs.com/v8/graphql/mapped-types#partial)
* [Pick](https://docs.nestjs.com/v8/graphql/mapped-types#pick)
* [Omit](https://docs.nestjs.com/v8/graphql/mapped-types#omit)
* [Intersection](https://docs.nestjs.com/v8/graphql/mapped-types#intersection)
* [Composition](https://docs.nestjs.com/v8/graphql/mapped-types#composition)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/mapped-types.md "Suggest Edits")

### Mapped types

> **Warning** This chapter applies only to the code first approach.

As you build out features like CRUD (Create/Read/Update/Delete) it's often useful to construct variants on a base entity type. Nest provides several utility functions that perform type transformations to make this task more convenient.

#### Partial[#](/graphql/mapped-types#partial)

When building input validation types (also called Data Transfer Objects or DTOs), it's often useful to build **create** and **update** variations on the same type. For example, the **create** variant may require all fields, while the **update** variant may make all fields optional.

Nest provides the `PartialType()` utility function to make this task easier and minimize boilerplate.

The `PartialType()` function returns a type (class) with all the properties of the input type set to optional. For example, suppose we have a **create** type as follows:

```typescript

@InputType()
class CreateUserInput {
  @Field()
  email: string;

  @Field()
  password: string;

  @Field()
  firstName: string;
}
```

By default, all of these fields are required. To create a type with the same fields, but with each one optional, use `PartialType()` passing the class reference (`CreateUserInput`) as an argument:

```typescript

@InputType()
export class UpdateUserInput extends PartialType(CreateUserInput) {}
```

> **Hint** The `PartialType()` function is imported from the `@nestjs/graphql` package.

The `PartialType()` function takes an optional second argument that is a reference to a decorator factory. This argument can be used to change the decorator function applied to the resulting (child) class. If not specified, the child class effectively uses the same decorator as the **parent** class (the class referenced in the first argument). In the example above, we are extending `CreateUserInput` which is annotated with the `@InputType()` decorator. Since we want `UpdateUserInput` to also be treated as if it were decorated with `@InputType()`, we didn't need to pass `InputType` as the second argument. If the parent and child types are different, (e.g., the parent is decorated with `@ObjectType`), we would pass `InputType` as the second argument. For example:

```typescript

@InputType()
export class UpdateUserInput extends PartialType(User, InputType) {}
```

#### Pick[#](/graphql/mapped-types#pick)

The `PickType()` function constructs a new type (class) by picking a set of properties from an input type. For example, suppose we start with a type like:

```typescript

@InputType()
class CreateUserInput {
  @Field()
  email: string;

  @Field()
  password: string;

  @Field()
  firstName: string;
}
```

We can pick a set of properties from this class using the `PickType()` utility function:

```typescript

@InputType()
export class UpdateEmailInput extends PickType(CreateUserInput, [
  'email',
] as const) {}
```

> **Hint** The `PickType()` function is imported from the `@nestjs/graphql` package.

#### Omit[#](/graphql/mapped-types#omit)

The `OmitType()` function constructs a type by picking all properties from an input type and then removing a particular set of keys. For example, suppose we start with a type like:

```typescript

@InputType()
class CreateUserInput {
  @Field()
  email: string;

  @Field()
  password: string;

  @Field()
  firstName: string;
}
```

We can generate a derived type that has every property **except**`email` as shown below. In this construct, the second argument to `OmitType` is an array of property names.

```typescript

@InputType()
export class UpdateUserInput extends OmitType(CreateUserInput, [
  'email',
] as const) {}
```

> **Hint** The `OmitType()` function is imported from the `@nestjs/graphql` package.

#### Intersection[#](/graphql/mapped-types#intersection)

The `IntersectionType()` function combines two types into one new type (class). For example, suppose we start with two types like:

```typescript

@InputType()
class CreateUserInput {
  @Field()
  email: string;

  @Field()
  password: string;
}

@ObjectType()
export class AdditionalUserInfo {
  @Field()
  firstName: string;

  @Field()
  lastName: string;
}
```

We can generate a new type that combines all properties in both types.

```typescript

@InputType()
export class UpdateUserInput extends IntersectionType(
  CreateUserInput,
  AdditionalUserInfo,
) {}
```

> **Hint** The `IntersectionType()` function is imported from the `@nestjs/graphql` package.

#### Composition[#](/graphql/mapped-types#composition)

The type mapping utility functions are composable. For example, the following will produce a type (class) that has all of the properties of the `CreateUserInput` type except for `email`, and those properties will be set to optional:

```typescript

@InputType()
export class UpdateUserInput extends PartialType(
  OmitType(CreateUserInput, ['email'] as const),
) {}
```

----
url: https://docs.nestjs.com/v6/application-context
----

* [Standalone applications](https://docs.nestjs.com/v6/standalone-applications#standalone-applications)
* [Getting started](https://docs.nestjs.com/v6/standalone-applications#getting-started)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/application-context.md "Suggest Edits")

### Standalone applications

There are several ways of mounting a Nest application. You can create a web app, a microservice or just a bare Nest **standalone application** (without any network listeners). The Nest standalone application is a wrapper around the Nest **IoC container**, which holds all instantiated classes. We can obtain a reference to any existing instance from within any imported module directly using the standalone application object. Thus, you can take advantage of the Nest framework anywhere, including, for example, scripted **CRON** jobs. You can even build a **CLI** on top of it.

#### Getting started[#](/standalone-applications#getting-started)

To create a Nest standalone application, use the following construction:

JS TS

```typescript

async function bootstrap() {
  const app = await NestFactory.createApplicationContext(ApplicationModule);
  // application logic...
}
bootstrap();
```

The standalone application object allows you to obtain a reference to any instance registered within the Nest application. Let's imagine that we have a `TasksService` in the `TasksModule`. This class provides a set of methods that we want to call from within a CRON job.

JS TS

```typescript

const app = await NestFactory.create(ApplicationModule);
const tasksService = app.get(TasksService);
```

To access the `TasksService` instance we the use `get()` method. The `get()` method acts like a **query** that searches for an instance in each registered module. Alternatively, for strict context checking, pass an options object with the `strict: true` property. With this option in effect, you have to navigate through specific modules to obtain a particular instance from the selected context.

JS TS

```typescript

const app = await NestFactory.create(AppModule);
const tasksService = app.select(TasksModule).get(TasksService, { strict: true });
```

Following is a summary of the methods available for retrieving instance references from the standalone application object.

|            |                                                                                                                                                   |
| ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| `get()`    | Retrieves an instance of a controller or provider (including guards, filters, and so on) available in the application context.                    |
| `select()` | Navigates through the modules graph to pull out a specific instance from the selected module (used together with strict mode as described above). |

> **Hint** In non-strict mode, the root module is selected by default. To select any other module, you need to navigate the modules graph manually, step by step.

If you want the node application to close after the script finishes (e.g., for a script running CRON jobs), add `await app.close()` to the end of your `bootstrap` function:

JS TS

```typescript

async function bootstrap() {
  const app = await NestFactory.createApplicationContext(ApplicationModule);
  // application logic...
  await app.close();
}
bootstrap();
```

----
url: https://docs.nestjs.com/v5
----

### Introduction

Nest is a framework for building efficient, scalable [Node.js](http://nodejs.org) server-side applications. It uses progressive JavaScript, is built with [TypeScript](http://www.typescriptlang.org) (preserves compatibility with pure JavaScript) and combines elements of OOP (Object Oriented Programming), FP (Functional Programming), and FRP (Functional Reactive Programming).

Under the hood, Nest makes use of [Express](https://expressjs.com/), but also provides compatibility with a wide range of other libraries (e.g. [Fastify](https://github.com/fastify/fastify)). This allows for easy use of the myriad third-party plugins which are available.

### Philosophy

In recent years, thanks to Node.js, JavaScript has become the “lingua franca” of the web for both front and backend applications. This has given rise to awesome projects like [Angular](https://angular.io/), [React](https://github.com/facebook/react) and [Vue](https://github.com/vuejs/vue) which improve developer productivity and enable the construction of fast, testable, and extensible frontend applications. However, while plenty of superb libraries, helpers, and tools exist for Node (and server-side JavaScript), none of them effectively solve the main problem - **architecture**.

Nest provides an out-of-the-box application architecture which allows for effortless creation of highly testable, scalable, loosely coupled, and easily maintainable applications.

### Installation

To get started, scaffold the base project with the [Nest CLI](/v5/cli/overview):

```bash

$ npm i -g @nestjs/cli
$ nest new project-name
```

Install the starter project with **Git**:

JS TS

```bash

$ git clone https://github.com/nestjs/typescript-starter.git project
$ cd project
$ npm install
$ npm run start
```

```bash

$ git clone https://github.com/nestjs/javascript-starter.git project
$ cd project
$ npm install
$ npm run start
```

Or start a new project from scratch with **npm** (or **yarn**):

```bash

$ npm i --save @nestjs/core @nestjs/common rxjs reflect-metadata
```

### Stay in touch

* Author - [Kamil Myśliwiec](https://kamilmysliwiec.com "Kamil Mysliwiec Blog | Full-Stack Software Engineer")
* Website - [https://nestjs.com](https://nestjs.com "NestJS - A node.js framework built on top of TypeScript")
* Twitter - [@nestframework](https://twitter.com/nestframework)

- Introduction
- Philosophy
- Installation
- Stay in touch

----
url: https://docs.nestjs.com/security/csrf
----

[Skip to content](#content)

On this page

* [CSRF Protection](https://docs.nestjs.com/security/csrf#csrf-protection)
* [How it works](https://docs.nestjs.com/security/csrf#how-it-works)
* [Getting started](https://docs.nestjs.com/security/csrf#getting-started)
* [Rejected requests](https://docs.nestjs.com/security/csrf#rejected-requests)
* [Options](https://docs.nestjs.com/security/csrf#options)
* [Trusted origins](https://docs.nestjs.com/security/csrf#trusted-origins)
* [Excluding routes](https://docs.nestjs.com/security/csrf#excluding-routes)
* [Limitations](https://docs.nestjs.com/security/csrf#limitations)
* [When you need a token-based approach](https://docs.nestjs.com/security/csrf#when-you-need-a-token-based-approach)
* [Token-based protection](https://docs.nestjs.com/security/csrf#token-based-protection)

### CSRF Protection

Cross-site request forgery (CSRF or XSRF) is an attack in which a malicious site makes a user's browser send unwanted, state-changing requests to your application. Because the browser attaches the user's cookies to those requests, the application treats them as if the user had sent them on purpose.

Starting with NestJS v12.1, Nest has built-in CSRF protection. It works the same way on Express and Fastify, and needs no extra package, cookie, session, or change to your client code.

#### How it works[#](/security/csrf#how-it-works)

Modern browsers tell the server where each request comes from. They send a [`Sec-Fetch-Site`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Sec-Fetch-Site) header (part of Fetch Metadata), which is `same-origin` when one of your own pages made the request, and `same-site` or `cross-site` when another site did. They also send an `Origin` header with cross-origin requests. The built-in protection rejects state-changing requests that the browser reports as cross-origin, following the algorithm of Go 1.25's [`CrossOriginProtection`](https://pkg.go.dev/net/http#CrossOriginProtection).

In detail, each request is checked as follows:

1. `GET`, `HEAD` and `OPTIONS` requests are always allowed.
2. If the request has a `Sec-Fetch-Site` header, the values `same-origin` and `none` (a navigation the user started, such as opening a bookmark) are allowed. Any other value, including `same-site`, is rejected.
3. If the request has neither a `Sec-Fetch-Site` nor an `Origin` header, it is allowed, because it does not come from a browser.
4. Otherwise, the host of the `Origin` header must match the request's `Host` header (`:authority` on HTTP/2). The comparison is case-insensitive and ignores the default port of the scheme, so `https://example.com` matches `example.com:443`. The `X-Forwarded-Host` header is ignored.

A request that would be rejected is still allowed when it matches an [excluded route](/security/csrf#excluding-routes), or when its `Origin` is one of the [trusted origins](/security/csrf#trusted-origins).

#### Getting started[#](/security/csrf#getting-started)

To enable the protection, call the `enableCsrfProtection()` method on the Nest application object:

```typescript

// main.ts
const app = await NestFactory.create(AppModule);
app.enableCsrfProtection();
await app.listen(process.env.PORT ?? 3000);
```

The check runs for every request, including requests to routes that do not exist, before Nest middleware, body parsing, guards, interceptors and route handlers. The following rules apply:

* Call `enableCsrfProtection()` before `app.init()` or `app.listen()`. Calling it afterwards, or calling it twice, throws an error.
* Options are validated when you call the method, so a bad configuration fails at startup. For example, a misspelled option throws `Invalid CSRF protection options: unknown option "trustedOrigin" (expected "trustedOrigins", "exclude").`
* The check is registered as a framework-level middleware (Express) or `onRequest` hook (Fastify) at the point where you call the method. Middleware registered with `app.use()` before that call runs first, so call `enableCsrfProtection()` right after `NestFactory.create()`.
* `app.useSecurityHeaders()` (see [Security headers](/security/helmet)) shares the same request hook. You can call the two methods in any order: the headers are always written before the CSRF check runs, so rejected requests carry them too.
* `setGlobalPrefix()` and `enableVersioning()` can be called before or after `enableCsrfProtection()`, because exclusions are resolved when the application initializes.

#### Rejected requests[#](/security/csrf#rejected-requests)

A rejected request becomes a `ForbiddenException`, which goes through your global [exception filters](/exception-filters) like any other exception. Without a custom filter, the client receives a `403` response like this:

```json

{
  "message": "Cross-origin request detected from Sec-Fetch-Site header",
  "error": "Forbidden",
  "statusCode": 403
}
```

When the request has no `Sec-Fetch-Site` header and its `Origin` does not match `Host`, the message is `Cross-origin request detected, and/or browser is out of date: Sec-Fetch-Site is missing, and Origin does not match Host`.

Since the check runs before routing, controller-scoped filters, guards and interceptors don't run for rejected requests.

#### Options[#](/security/csrf#options)

The `enableCsrfProtection()` method takes an optional options object:

```typescript

app.enableCsrfProtection({
  trustedOrigins: ['https://admin.example.com'],
  exclude: [{ path: 'webhooks/stripe', method: RequestMethod.POST }],
});
```

| Option           | Type                                                     | Description                                                                                 |
| ---------------- | -------------------------------------------------------- | ------------------------------------------------------------------------------------------- |
| `trustedOrigins` | `string[]`                                               | Origins that may send cross-origin, state-changing requests. Defaults to none.              |
| `exclude`        | an array of paths and `RouteInfo` objects, or a function | Requests that skip the check. Consulted only for requests that would otherwise be rejected. |

Any other option is rejected when the method is called.

#### Trusted origins[#](/security/csrf#trusted-origins)

A frontend served from another origin, such as an admin panel on a sibling subdomain, sends cross-origin requests. The browser reports them as `same-site` or `cross-site`, so they are rejected unless you list the frontend's origin in `trustedOrigins`:

```typescript

app.enableCsrfProtection({
  trustedOrigins: ['https://admin.example.com', 'http://localhost:4200'],
});
```

Each entry must be a serialized origin in the form `scheme://host[:port]`:

* A path (even a trailing `/`), query string, fragment, credentials and wildcards are not allowed. List every origin separately.
* Entries are normalized the way browsers serialize the `Origin` header: lower-case, without the default port. `https://Example.com:443` becomes `https://example.com`.
* A request is exempt when its `Origin` header equals one of the entries exactly.

An invalid entry throws at startup, for example `Invalid trusted origin "https://example.com/": expected "scheme://host[:port]", without a path, query string or fragment.`

> **Warning** Origins allowed by [CORS](/security/cors) are not trusted automatically. If a cross-origin frontend sends state-changing requests with credentials, list its origin in `trustedOrigins` too.

#### Excluding routes[#](/security/csrf#excluding-routes)

Server-to-server requests usually carry neither `Sec-Fetch-Site` nor `Origin`, so they pass the check without any configuration. Exclude a route when it must accept requests with a foreign origin, for example from a webhook sender that sets an `Origin` header, or from an identity provider that sends the user back to your application with a cross-site form `POST` (SAML, or OAuth's `form_post` response mode).

Exclusions are declared like the ones of `MiddlewareConsumer.exclude()` (see [Middleware](/middleware)): as a path, which matches every request method, or as a `RouteInfo` object with a `path`, a `method`, and an optional `version`. Paths are declared without the global prefix:

```typescript

// main.ts
import { RequestMethod } from '@nestjs/common';

app.setGlobalPrefix('api');
app.enableCsrfProtection({
  exclude: [
    // POST /api/webhooks/stripe
    { path: 'webhooks/stripe', method: RequestMethod.POST },
    // POST /api/auth/saml/callback
    { path: 'auth/saml/callback', method: RequestMethod.POST },
  ],
});
```

Exclusions are resolved when the application initializes:

* The [global prefix](/faq/global-prefix) is added, unless the route is excluded from it.
* With [URI versioning](/http/versioning), the version segment of the `version` property is added. The default version is not applied, so set `version` on the exclusion of a versioned route.
* Route parameters and wildcards work as in route paths, for example `webhooks/:provider` or `webhooks/*path`.

Unlike `MiddlewareConsumer.exclude()`, the match is exact, because a lenient match could let a request reach a route that is not excluded:

* Matching is case-sensitive, and a trailing slash does not match. The query string is ignored.
* Non-canonical request paths never match: paths that contain `//`, `.` or `..` segments, `;`, `#`, `\`, or a percent-encoded `.`, `/` or `\`. Such requests go through the check like any other, so the protection fails closed.
* On Fastify, exclusions are matched against the URL before `rewriteUrl` runs, as with `MiddlewareConsumer.exclude()`.

If your Fastify application enables the `ignoreTrailingSlash` or `caseSensitive: false` router options, variants of an excluded path still reach the route but are not excluded, so they are rejected. If clients need such variants, list them explicitly. Because a trailing slash is stripped from an exclusion path, use an optional group to match it:

```typescript

app.enableCsrfProtection({
  exclude: [
    // matches /webhooks/stripe and /webhooks/stripe/
    { path: 'webhooks/stripe{/}', method: RequestMethod.POST },
    // a variant accepted with caseSensitive: false
    { path: 'webhooks/Stripe', method: RequestMethod.POST },
  ],
});
```

Instead of a list, `exclude` also accepts a predicate that receives the platform request object (an Express `Request` or a `FastifyRequest`) and returns `true` to skip the check. It is called only for requests that would otherwise be rejected.

> **Warning** A predicate receives the raw request, so none of the matching rules above apply to it. For example, a predicate that tests whether `request.url` starts with `/public/` also skips the check for `/public/../account`, which a router or proxy may resolve to `/account`. Prefer a list of routes where you can.

#### Limitations[#](/security/csrf#limitations)

* The protection is not a token scheme. It relies on the browser's `Sec-Fetch-Site` header, which browsers only send to secure origins (HTTPS or `localhost`), or on the `Origin` header.
* `GET`, `HEAD` and `OPTIONS` requests are never checked, so handlers for these methods must not change state.
* The `Origin`/`Host` fallback does not know the scheme. For browsers that don't send `Sec-Fetch-Site`, a request from `http://example.com` to `https://example.com` is allowed (fails open), as in Go. [HSTS](/security/helmet#default-headers), which `app.useSecurityHeaders()` sends by default, mitigates this.
* `X-Forwarded-Host` is ignored. Behind a proxy that rewrites the `Host` header, browsers that don't send `Sec-Fetch-Site` hit the fallback and receive a `403`. Configure the proxy to preserve `Host`, or add your public origin to `trustedOrigins`.
* A `403` response does not carry CORS headers when CORS is registered after the protection, which is the case with the `cors` option of `NestFactory.create()`.
* Middleware registered with `app.use()` before `enableCsrfProtection()` runs before the check, and requests that such middleware answers are not checked.
* WebSocket upgrade requests are not checked. If your [gateways](/websockets/gateways) authenticate connections with cookies, validate the handshake's `Origin` header yourself.

#### When you need a token-based approach[#](/security/csrf#when-you-need-a-token-based-approach)

CSRF abuses the credentials that a browser attaches to requests automatically, so non-browser clients, such as mobile apps, CLI tools and other servers, don't need CSRF protection. Their requests carry neither `Sec-Fetch-Site` nor `Origin`, and are allowed.

Every evergreen browser has sent `Sec-Fetch-Site` since 2023. Very old browsers that send neither header look like non-browser clients, so their requests are allowed too. If you must protect users of such browsers, add a token-based scheme, as described below.

#### Token-based protection[#](/security/csrf#token-based-protection)

Token-based schemes store a secret in a cookie or session, and require the client to send a matching token with each state-changing request. They need changes to your client code and a package that depends on the underlying platform.

##### Express[#](/security/csrf#express)

Install the [csrf-csrf](https://github.com/Psifi-Solutions/csrf-csrf) package:

```bash

$ npm i csrf-csrf
```

Then register its middleware as global middleware. The `doubleCsrf()` function requires the `getSecret` and `getSessionIdentifier` options; the other options have defaults:

```typescript

// main.ts
import { doubleCsrf } from 'csrf-csrf';

const { doubleCsrfProtection } = doubleCsrf(doubleCsrfOptions);
app.use(doubleCsrfProtection);
```

> **Warning** As noted in the [csrf-csrf documentation](https://github.com/Psifi-Solutions/csrf-csrf?tab=readme-ov-file#getting-started), this middleware requires session middleware or `cookie-parser` to be initialized beforehand. `doubleCsrf()` also returns a function that generates the tokens your routes hand to clients. Please refer to the documentation for further details.

##### Fastify[#](/security/csrf#fastify)

Install the [@fastify/csrf-protection](https://github.com/fastify/csrf-protection) package:

```bash

$ npm i @fastify/csrf-protection
```

Then register it as a Fastify plugin:

```typescript

// main.ts
import fastifyCsrf from '@fastify/csrf-protection';

// after registering a storage plugin
await app.register(fastifyCsrf);
```

> **Warning** As explained in the [@fastify/csrf-protection documentation](https://github.com/fastify/csrf-protection#usage), this plugin requires a storage plugin (`@fastify/cookie`, `@fastify/session`, or `@fastify/secure-session`) to be registered first.

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/security/csrf.md)

----
url: https://docs.nestjs.com/v11/techniques/http-module
----

* [HTTP module](https://docs.nestjs.com/v11/techniques/http-module#http-module)
* [Installation](https://docs.nestjs.com/v11/techniques/http-module#installation)
* [Getting started](https://docs.nestjs.com/v11/techniques/http-module#getting-started)
* [Configuration](https://docs.nestjs.com/v11/techniques/http-module#configuration)
* [Async configuration](https://docs.nestjs.com/v11/techniques/http-module#async-configuration)
* [Using Axios directly](https://docs.nestjs.com/v11/techniques/http-module#using-axios-directly)
* [Full example](https://docs.nestjs.com/v11/techniques/http-module#full-example)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/techniques/http-module.md "Suggest Edits")

### HTTP module

[Axios](https://github.com/axios/axios) is a richly featured HTTP client package that is widely used. Nest wraps Axios and exposes it via the built-in `HttpModule`. The `HttpModule` exports the `HttpService` class, which exposes Axios-based methods to perform HTTP requests. The library also transforms the resulting HTTP responses into `Observables`.

> **Hint** You can also use any general purpose Node.js HTTP client library directly, including [got](https://github.com/sindresorhus/got) or [undici](https://github.com/nodejs/undici).

#### Installation[#](/techniques/http-module#installation)

To begin using it, we first install required dependencies.

```bash

$ npm i --save @nestjs/axios axios
```

#### Getting started[#](/techniques/http-module#getting-started)

Once the installation process is complete, to use the `HttpService`, first import `HttpModule`.

```typescript

@Module({
  imports: [HttpModule],
  providers: [CatsService],
})
export class CatsModule {}
```

Next, inject `HttpService` using normal constructor injection.

> **Hint**`HttpModule` and `HttpService` are imported from `@nestjs/axios` package.

JS TS

```typescript

@Injectable()
export class CatsService {
  constructor(private readonly httpService: HttpService) {}

  findAll(): Observable<AxiosResponse<Cat[]>> {
    return this.httpService.get('http://localhost:3000/cats');
  }
}
```

```typescript

@Injectable()
@Dependencies(HttpService)
export class CatsService {
  constructor(httpService) {
    this.httpService = httpService;
  }

  findAll() {
    return this.httpService.get('http://localhost:3000/cats');
  }
}
```

> **Hint**`AxiosResponse` is an interface exported from the `axios` package (`$ npm i axios`).

All `HttpService` methods return an `AxiosResponse` wrapped in an `Observable` object.

#### Configuration[#](/techniques/http-module#configuration)

[Axios](https://github.com/axios/axios) can be configured with a variety of options to customize the behavior of the `HttpService`. Read more about them [here](https://github.com/axios/axios#request-config). To configure the underlying Axios instance, pass an optional options object to the `register()` method of `HttpModule` when importing it. This options object will be passed directly to the underlying Axios constructor.

```typescript

@Module({
  imports: [
    HttpModule.register({
      timeout: 5000,
      maxRedirects: 5,
    }),
  ],
  providers: [CatsService],
})
export class CatsModule {}
```

#### Async configuration[#](/techniques/http-module#async-configuration)

When you need to pass module options asynchronously instead of statically, use the `registerAsync()` method. As with most dynamic modules, Nest provides several techniques to deal with async configuration.

One technique is to use a factory function:

```typescript

HttpModule.registerAsync({
  useFactory: () => ({
    timeout: 5000,
    maxRedirects: 5,
  }),
});
```

Like other factory providers, our factory function can be [async](https://docs.nestjs.com/fundamentals/custom-providers#factory-providers-usefactory) and can inject dependencies through `inject`.

```typescript

HttpModule.registerAsync({
  imports: [ConfigModule],
  useFactory: async (configService: ConfigService) => ({
    timeout: configService.get('HTTP_TIMEOUT'),
    maxRedirects: configService.get('HTTP_MAX_REDIRECTS'),
  }),
  inject: [ConfigService],
});
```

Alternatively, you can configure the `HttpModule` using a class instead of a factory, as shown below.

```typescript

HttpModule.registerAsync({
  useClass: HttpConfigService,
});
```

The construction above instantiates `HttpConfigService` inside `HttpModule`, using it to create an options object. Note that in this example, the `HttpConfigService` has to implement `HttpModuleOptionsFactory` interface as shown below. The `HttpModule` will call the `createHttpOptions()` method on the instantiated object of the supplied class.

```typescript

@Injectable()
class HttpConfigService implements HttpModuleOptionsFactory {
  createHttpOptions(): HttpModuleOptions {
    return {
      timeout: 5000,
      maxRedirects: 5,
    };
  }
}
```

If you want to reuse an existing options provider instead of creating a private copy inside the `HttpModule`, use the `useExisting` syntax.

```typescript

HttpModule.registerAsync({
  imports: [ConfigModule],
  useExisting: HttpConfigService,
});
```

You can also pass so-called `extraProviders` to the `registerAsync()` method. These providers will be merged with the module providers.

```typescript

HttpModule.registerAsync({
  imports: [ConfigModule],
  useClass: HttpConfigService,
  extraProviders: [MyAdditionalProvider],
});
```

This is useful when you want to provide additional dependencies to the factory function or the class constructor.

#### Using Axios directly[#](/techniques/http-module#using-axios-directly)

If you think that `HttpModule.register`'s options are not enough for you, or if you just want to access the underlying Axios instance created by `@nestjs/axios`, you can access it via `HttpService#axiosRef` as follows:

```typescript

@Injectable()
export class CatsService {
  constructor(private readonly httpService: HttpService) {}

  findAll(): Promise<AxiosResponse<Cat[]>> {
    return this.httpService.axiosRef.get('http://localhost:3000/cats');
    //                      ^ AxiosInstance interface
  }
}
```

#### Full example[#](/techniques/http-module#full-example)

Since the return value of the `HttpService` methods is an Observable, we can use `rxjs` - `firstValueFrom` or `lastValueFrom` to retrieve the data of the request in the form of a promise.

```typescript

import { catchError, firstValueFrom } from 'rxjs';

@Injectable()
export class CatsService {
  private readonly logger = new Logger(CatsService.name);
  constructor(private readonly httpService: HttpService) {}

  async findAll(): Promise<Cat[]> {
    const { data } = await firstValueFrom(
      this.httpService.get<Cat[]>('http://localhost:3000/cats').pipe(
        catchError((error: AxiosError) => {
          this.logger.error(error.response.data);
          throw 'An error happened!';
        }),
      ),
    );
    return data;
  }
}
```

> **Hint** Visit RxJS's documentation on [`firstValueFrom`](https://rxjs.dev/api/index/function/firstValueFrom) and [`lastValueFrom`](https://rxjs.dev/api/index/function/lastValueFrom) for differences between them.

----
url: https://docs.nestjs.com/application/task-scheduling
----

[Skip to content](#content)

On this page

* [Task scheduling](https://docs.nestjs.com/application/task-scheduling#task-scheduling)
* [Installation](https://docs.nestjs.com/application/task-scheduling#installation)
* [Declarative cron jobs](https://docs.nestjs.com/application/task-scheduling#declarative-cron-jobs)
* [Declarative intervals](https://docs.nestjs.com/application/task-scheduling#declarative-intervals)
* [Declarative timeouts](https://docs.nestjs.com/application/task-scheduling#declarative-timeouts)
* [Dynamic schedule module API](https://docs.nestjs.com/application/task-scheduling#dynamic-schedule-module-api)
* [Dynamic cron jobs](https://docs.nestjs.com/application/task-scheduling#dynamic-cron-jobs)
* [Dynamic intervals](https://docs.nestjs.com/application/task-scheduling#dynamic-intervals)
* [Dynamic timeouts](https://docs.nestjs.com/application/task-scheduling#dynamic-timeouts)
* [Running on several instances](https://docs.nestjs.com/application/task-scheduling#running-on-several-instances)
* [Knowing a cron job actually ran](https://docs.nestjs.com/application/task-scheduling#knowing-a-cron-job-actually-ran)
* [Example](https://docs.nestjs.com/application/task-scheduling#example)

[](https://srv.carbonads.net/ads/click/x/GTND4277CVSD5KJUCAYLYKQUF67D62QUF6BIKZ3JCAAI623WC67IT27KC6YDE2QICWBD653ECW7DPK7LCWSDPK3WHEYI55QLCAYD653ECTNCYBZ52K)[Build, govern, and optimize agents with Gemini Enterprise Agent Platform. Try it for free. ](https://srv.carbonads.net/ads/click/x/GTND4277CVSD5KJUCAYLYKQUF67D62QUF6BIKZ3JCAAI623WC67IT27KC6YDE2QICWBD653ECW7DPK7LCWSDPK3WHEYI55QLCAYD653ECTNCYBZ52K)[ads via Carbon](http://carbonads.net/?utm_source=nestjscom\&utm_medium=ad_via_link\&utm_campaign=in_unit\&utm_term=carbon)

### Task scheduling

Task scheduling lets you run arbitrary code (methods or functions) at a fixed date and time, at recurring intervals, or once after a specified delay. In the Linux world, this is often handled at the OS level by tools like [cron](https://en.wikipedia.org/wiki/Cron). For Node.js apps, several packages emulate cron-like functionality. Nest provides the `@nestjs/schedule` package, which integrates with the popular Node.js [cron](https://github.com/kelektiv/node-cron) package. This chapter covers the `@nestjs/schedule` package.

#### Installation[#](/application/task-scheduling#installation)

To begin using it, install the required dependencies.

```bash

$ npm install --save @nestjs/schedule
```

To activate job scheduling, import the `ScheduleModule` into the root `AppModule` and call the `forRoot()` static method, as shown below:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { ScheduleModule } from '@nestjs/schedule';

@Module({
  imports: [
    ScheduleModule.forRoot()
  ],
})
export class AppModule {}
```

The `forRoot()` call initializes the scheduler and registers any declarative [cron jobs](application/task-scheduling#declarative-cron-jobs), [timeouts](application/task-scheduling#declarative-timeouts), and [intervals](application/task-scheduling#declarative-intervals) that exist within your app. The scheduled jobs start in the `onApplicationBootstrap` lifecycle hook, which ensures that all modules have loaded and declared their scheduled jobs.

> **Warning** Call `forRoot()` in one module only. Each additional import registers every `@Cron()`, `@Interval()` and `@Timeout()` handler in your app again, so importing it in three modules makes each job run three times.

#### Declarative cron jobs[#](/application/task-scheduling#declarative-cron-jobs)

A cron job schedules an arbitrary function (method call) to run automatically. Cron jobs can run:

* Once, at a specified date and time.
* On a recurring basis. Recurring jobs can run at a specified instant within a specified interval (e.g., once per hour, once per week, once every 5 minutes).

Declare a cron job by applying the `@Cron()` decorator to the method that contains the code to execute, as follows:

```typescript

import { Injectable, Logger } from '@nestjs/common';
import { Cron } from '@nestjs/schedule';

@Injectable()
export class TasksService {
  private readonly logger = new Logger(TasksService.name);

  @Cron('45 * * * * *')
  handleCron() {
    this.logger.debug('Called when the current second is 45');
  }
}
```

In this example, the `handleCron()` method is called each time the current second is `45`. In other words, the method runs once per minute, at the 45-second mark.

The `@Cron()` decorator supports the following standard [cron patterns](http://crontab.org/):

* Asterisks (e.g., `*`)
* Ranges and lists (e.g., `1-3,5`)
* Steps (e.g., `*/2`)

In the example above, we passed `45 * * * * *` to the decorator. The following key shows how each position in the cron pattern string is interpreted:

```javascript

* * * * * *
| | | | | |
| | | | | day of week
| | | | months
| | | day of month
| | hours
| minutes
seconds (optional)
```

Some sample cron patterns are:

|                     |                                             |
| ------------------- | ------------------------------------------- |
| `* * * * * *`       | every second                                |
| `45 * * * * *`      | every minute, on the 45th second            |
| `0 10 * * * *`      | every hour, at the start of the 10th minute |
| `0 */30 9-17 * * *` | every 30 minutes between 9am and 5pm        |
| `0 30 11 * * 1-5`   | Monday to Friday at 11:30am                 |

The `@nestjs/schedule` package provides the `CronExpression` enum with commonly used cron patterns. You can use this enum as follows:

```typescript

import { Injectable, Logger } from '@nestjs/common';
import { Cron, CronExpression } from '@nestjs/schedule';

@Injectable()
export class TasksService {
  private readonly logger = new Logger(TasksService.name);

  @Cron(CronExpression.EVERY_30_SECONDS)
  handleCron() {
    this.logger.debug('Called every 30 seconds');
  }
}
```

In this example, the `handleCron()` method is called every `30` seconds. Every method annotated with `@Cron()` is automatically wrapped in a `try-catch` block, so if an exception occurs, it's logged to the console.

Alternatively, you can supply a JavaScript `Date` object to the `@Cron()` decorator. This causes the job to execute exactly once, at the specified date.

> **Hint** Use JavaScript date arithmetic to schedule jobs relative to the current date. For example, `@Cron(new Date(Date.now() + 10 * 1000))` schedules a job to run 10 seconds after the app starts.

You can also supply additional options as the second parameter to the `@Cron()` decorator.

|                     |                                                                                                                                                                                                                                                               |
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `name`              | Lets you access and control a cron job after it's been declared.                                                                                                                                                                                              |
| `timeZone`          | Specifies the time zone for the execution. This modifies the actual time relative to your time zone. If the time zone is invalid, an error is thrown. You can check all available time zones on the [Moment Timezone](http://momentjs.com/timezone/) website. |
| `utcOffset`         | Specifies the offset of your time zone instead of using the `timeZone` option. Don't combine it with `timeZone`.                                                                                                                                              |
| `waitForCompletion` | If `true`, no additional instances of the cron job run until the current `onTick` callback completes. Any new scheduled executions that occur while the current cron job is running are skipped entirely.                                                     |
| `disabled`          | If `true`, the job is not executed at all (defaults to `false`).                                                                                                                                                                                              |

```typescript

import { Injectable } from '@nestjs/common';
import { Cron, CronExpression } from '@nestjs/schedule';

@Injectable()
export class NotificationService {
  @Cron('* * 0 * * *', {
    name: 'notifications',
    timeZone: 'Europe/Paris',
  })
  triggerNotifications() {}
}
```

With the [dynamic API](/application/task-scheduling#dynamic-schedule-module-api), you can access and control a cron job after it's been declared, or create a cron job dynamically (with its cron pattern defined at runtime). To access a declarative cron job via the API, you must associate the job with a name by passing the `name` property in the options object (the decorator's optional second argument).

#### Declarative intervals[#](/application/task-scheduling#declarative-intervals)

To declare that a method should run at a specified (recurring) interval, prefix the method definition with the `@Interval()` decorator. Pass the interval value to the decorator as a number in milliseconds, as shown below:

```typescript

@Interval(10000)
handleInterval() {
  this.logger.debug('Called every 10 seconds');
}
```

> **Hint** This mechanism uses the JavaScript `setInterval()` function under the hood. You can also use a cron job to schedule recurring jobs.

To control your declarative interval from outside the declaring class via the [dynamic API](/application/task-scheduling#dynamic-schedule-module-api), associate the interval with a name using the following construction:

```typescript

@Interval('notifications', 2500)
handleInterval() {}
```

Every method annotated with `@Interval()` is automatically wrapped in a `try-catch` block, so if an exception occurs, it's logged to the console.

The [dynamic API](application/task-scheduling#dynamic-intervals) also enables **creating** dynamic intervals, where the interval's properties are defined at runtime, and **listing and deleting** them.

## Official enterprise support

* Providing technical guidance
* Performing in-depth code reviews
* Mentoring team members
* Advising best practices

[Explore more](https://enterprise.nestjs.com "Enterprise | NestJS - A progressive Node.js framework")

#### Declarative timeouts[#](/application/task-scheduling#declarative-timeouts)

To declare that a method should run once after a specified timeout, prefix the method definition with the `@Timeout()` decorator. Pass the time offset from application startup (in milliseconds) to the decorator, as shown below:

```typescript

@Timeout(5000)
handleTimeout() {
  this.logger.debug('Called once after 5 seconds');
}
```

> **Hint** This mechanism uses the JavaScript `setTimeout()` function under the hood.

Every method annotated with `@Timeout()` is automatically wrapped in a `try-catch` block, so if an exception occurs, it's logged to the console.

To control your declarative timeout from outside the declaring class via the [dynamic API](/application/task-scheduling#dynamic-schedule-module-api), associate the timeout with a name using the following construction:

```typescript

@Timeout('notifications', 2500)
handleTimeout() {}
```

The [dynamic API](application/task-scheduling#dynamic-timeouts) also enables **creating** dynamic timeouts, where the timeout's properties are defined at runtime, and **listing and deleting** them.

#### Dynamic schedule module API[#](/application/task-scheduling#dynamic-schedule-module-api)

The `@nestjs/schedule` module provides a dynamic API for managing declarative [cron jobs](application/task-scheduling#declarative-cron-jobs), [timeouts](application/task-scheduling#declarative-timeouts), and [intervals](application/task-scheduling#declarative-intervals). The API also lets you create and manage **dynamic** cron jobs, timeouts, and intervals, whose properties are defined at runtime.

#### Dynamic cron jobs[#](/application/task-scheduling#dynamic-cron-jobs)

Obtain a reference to a `CronJob` instance by name from anywhere in your code using the `SchedulerRegistry` API. First, inject `SchedulerRegistry` using standard constructor injection:

```typescript

constructor(private schedulerRegistry: SchedulerRegistry) {}
```

> **Hint** Import the `SchedulerRegistry` from the `@nestjs/schedule` package.

Then use it in a class. Assume a cron job was created with the following declaration:

```typescript

@Cron('* * 8 * * *', {
  name: 'notifications',
})
triggerNotifications() {}
```

Access this job using the following:

```typescript

const job = this.schedulerRegistry.getCronJob('notifications');

job.stop();
console.log(job.lastDate());
```

The `getCronJob()` method returns the named cron job. The returned `CronJob` object has the following methods:

* `stop()` - stops a job that is scheduled to run.
* `start()` - restarts a job that has been stopped.
* `setTime(time: CronTime)` - stops a job, sets a new time for it, and then starts it.
* `lastDate()` - returns a JavaScript `Date` representing the last execution of the job, or `null` if it hasn't run yet.
* `nextDate()` - returns a `DateTime` representation of the date when the next execution of the job is scheduled.
* `nextDates(count: number)` - returns an array (of size `count`) of `DateTime` representations for the next set of dates that will trigger job execution. `count` defaults to 0, which returns an empty array.

> **Hint** Call `toJSDate()` on a `DateTime` object (a [Luxon](https://moment.github.io/luxon/) type) to convert it to the equivalent JavaScript `Date`.

**Create** a new cron job dynamically using the `SchedulerRegistry#addCronJob` method, as follows:

```typescript

addCronJob(name: string, seconds: string) {
  const job = new CronJob(`${seconds} * * * * *`, () => {
    this.logger.warn(`time (${seconds}) for job ${name} to run!`);
  });

  this.schedulerRegistry.addCronJob(name, job);
  job.start();

  this.logger.warn(
    `job ${name} added for each minute at ${seconds} seconds!`,
  );
}
```

This code uses the `CronJob` class from the `cron` package to create the cron job. The `CronJob` constructor takes a cron pattern (like the `@Cron()`[decorator](application/task-scheduling#declarative-cron-jobs)) as its first argument, and a callback to execute when the cron timer fires as its second argument. The `SchedulerRegistry#addCronJob` method takes two arguments: a name for the `CronJob`, and the `CronJob` object itself.

> **Warning** Remember to inject the `SchedulerRegistry` before accessing it. Import `CronJob` from the `cron` package.

**Delete** a named cron job using the `SchedulerRegistry#deleteCronJob` method, as follows:

```typescript

deleteCron(name: string) {
  this.schedulerRegistry.deleteCronJob(name);
  this.logger.warn(`job ${name} deleted!`);
}
```

**List** all cron jobs using the `SchedulerRegistry#getCronJobs` method, as follows:

```typescript

getCrons() {
  const jobs = this.schedulerRegistry.getCronJobs();
  jobs.forEach((value, key, map) => {
    let next;
    try {
      next = value.nextDate().toJSDate();
    } catch (e) {
      next = 'error: next fire date is in the past!';
    }
    this.logger.log(`job: ${key} -> next: ${next}`);
  });
}
```

The `getCronJobs()` method returns a `Map`. This code iterates over the map and calls the `nextDate()` method of each `CronJob`. In the `CronJob` API, `nextDate()` throws an exception if a job has already fired and has no future firing date.

#### Dynamic intervals[#](/application/task-scheduling#dynamic-intervals)

Obtain a reference to an interval with the `SchedulerRegistry#getInterval` method. As above, inject `SchedulerRegistry` using standard constructor injection:

```typescript

constructor(private schedulerRegistry: SchedulerRegistry) {}
```

Then use it as follows:

```typescript

const interval = this.schedulerRegistry.getInterval('notifications');
clearInterval(interval);
```

**Create** a new interval dynamically using the `SchedulerRegistry#addInterval` method, as follows:

```typescript

addInterval(name: string, milliseconds: number) {
  const callback = () => {
    this.logger.warn(`Interval ${name} executing at time (${milliseconds})!`);
  };

  const interval = setInterval(callback, milliseconds);
  this.schedulerRegistry.addInterval(name, interval);
}
```

This code creates a standard JavaScript interval, then passes it to the `SchedulerRegistry#addInterval` method. That method takes two arguments: a name for the interval, and the interval itself.

**Delete** a named interval using the `SchedulerRegistry#deleteInterval` method, as follows:

```typescript

deleteInterval(name: string) {
  this.schedulerRegistry.deleteInterval(name);
  this.logger.warn(`Interval ${name} deleted!`);
}
```

**List** the names of all intervals using the `SchedulerRegistry#getIntervals` method, as follows:

```typescript

getIntervals() {
  const intervals = this.schedulerRegistry.getIntervals();
  intervals.forEach(key => this.logger.log(`Interval: ${key}`));
}
```

#### Dynamic timeouts[#](/application/task-scheduling#dynamic-timeouts)

Obtain a reference to a timeout with the `SchedulerRegistry#getTimeout` method. As above, inject `SchedulerRegistry` using standard constructor injection:

```typescript

constructor(private readonly schedulerRegistry: SchedulerRegistry) {}
```

Then use it as follows:

```typescript

const timeout = this.schedulerRegistry.getTimeout('notifications');
clearTimeout(timeout);
```

**Create** a new timeout dynamically using the `SchedulerRegistry#addTimeout` method, as follows:

```typescript

addTimeout(name: string, milliseconds: number) {
  const callback = () => {
    this.logger.warn(`Timeout ${name} executing after (${milliseconds})!`);
  };

  const timeout = setTimeout(callback, milliseconds);
  this.schedulerRegistry.addTimeout(name, timeout);
}
```

This code creates a standard JavaScript timeout, then passes it to the `SchedulerRegistry#addTimeout` method. That method takes two arguments: a name for the timeout, and the timeout itself.

**Delete** a named timeout using the `SchedulerRegistry#deleteTimeout` method, as follows:

```typescript

deleteTimeout(name: string) {
  this.schedulerRegistry.deleteTimeout(name);
  this.logger.warn(`Timeout ${name} deleted!`);
}
```

**List** the names of all timeouts using the `SchedulerRegistry#getTimeouts` method, as follows:

```typescript

getTimeouts() {
  const timeouts = this.schedulerRegistry.getTimeouts();
  timeouts.forEach(key => this.logger.log(`Timeout: ${key}`));
}
```

#### Running on several instances[#](/application/task-scheduling#running-on-several-instances)

The scheduler runs every job in every process of your application. With three instances behind a load balancer, a job scheduled with `@Cron('0 2 * * *')` runs three times a night: three invoice exports, three batches of reminder emails.

To run a job on one instance per tick, add `@OnOneInstance()` from [`@nestjs/locks`](/reliability/locks) next to its `@Cron()`, `@Interval()` or `@Timeout()` decorator:

```typescript

import { Injectable } from '@nestjs/common';
import { OnOneInstance } from '@nestjs/locks';
import { Cron } from '@nestjs/schedule';

@Injectable()
export class InvoicesJob {
  @Cron('0 2 * * *')
  @OnOneInstance({ key: 'invoices:nightly-export' })
  async exportInvoices() {
    // ...
  }
}
```

The instances coordinate through a lock store they share, such as your PostgreSQL database or Redis. The first instance to fire the job takes a lease on it and keeps renewing it while it's up, and the other instances skip their ticks instead of queuing them. If the owner stops, another instance takes the job over at its next tick. A job that can take longer than its interval also gets `@WithoutOverlapping()`, which skips a tick while the previous run is still going. [Distributed locks](/reliability/locks) shows how to register the module and the store.

#### Knowing a cron job actually ran[#](/application/task-scheduling#knowing-a-cron-job-actually-ran)

A scheduled job that throws is a problem you will hear about. A scheduled job that silently *stops being scheduled* (the process crashed, the container was descheduled, a deploy shipped a `@Cron()` expression with a typo) is a problem nobody hears about until the report it generates is missing.

This is the failure mode cron monitoring exists for, and [NestJS Observe](https://www.observe.nestjs.com/ "NestJS Observe") covers it without a third-party ping service or a heartbeat URL for the job to call on its way out. Scheduled runs are reported as **jobs**, alongside queue consumers, each with its duration, outcome, and failure reason. A **job silence** alert rule fires when a named job hasn't reported within a tolerance you set, anywhere from 2 minutes to 7 days: *"alert me if `daily-invoices` has not reported in the last 26 hours"*.

Two details make this practical rather than noisy. A scope that has never reported anything doesn't fire, so you can add the rule before the job ships without being paged for something that isn't integrated yet. And rules carry a recurring mute schedule, so a job that legitimately doesn't run at weekends doesn't wake anyone on Saturday.

A handler that needs to report its own progress can inject `TracerService` and record spans or custom metrics from inside the run. Metrics in particular aren't tied to a trace, so they can be reported from cron jobs and lifecycle hooks alike. See [Manual instrumentation](/observability/manual-instrumentation) for that, and the [Observability](/observability/overview) chapter for setup.

#### Example[#](/application/task-scheduling#example)

A working example is available in the [27-scheduling sample](https://github.com/nestjs/nest/tree/master/sample/27-scheduling).

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/application/task-scheduling.md)

----
url: https://docs.nestjs.com/v10/security/rate-limiting
----

* [Rate Limiting](https://docs.nestjs.com/v10/security/rate-limiting#rate-limiting)
* [Multiple Throttler Definitions](https://docs.nestjs.com/v10/security/rate-limiting#multiple-throttler-definitions)
* [Customization](https://docs.nestjs.com/v10/security/rate-limiting#customization)
* [Proxies](https://docs.nestjs.com/v10/security/rate-limiting#proxies)
* [Websockets](https://docs.nestjs.com/v10/security/rate-limiting#websockets)
* [GraphQL](https://docs.nestjs.com/v10/security/rate-limiting#graphql)
* [Configuration](https://docs.nestjs.com/v10/security/rate-limiting#configuration)
* [Async Configuration](https://docs.nestjs.com/v10/security/rate-limiting#async-configuration)
* [Storages](https://docs.nestjs.com/v10/security/rate-limiting#storages)
* [Time Helpers](https://docs.nestjs.com/v10/security/rate-limiting#time-helpers)
* [Migration Guide](https://docs.nestjs.com/v10/security/rate-limiting#migration-guide)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/security/rate-limiting.md "Suggest Edits")

### Rate Limiting

A common technique to protect applications from brute-force attacks is **rate-limiting**. To get started, you'll need to install the `@nestjs/throttler` package.

```bash

$ npm i --save @nestjs/throttler
```

Once the installation is complete, the `ThrottlerModule` can be configured as any other Nest package with `forRoot` or `forRootAsync` methods.

app.module.ts

JS TS

```typescript

@Module({
  imports: [
    ThrottlerModule.forRoot([{
      ttl: 60000,
      limit: 10,
    }]),
  ],
})
export class AppModule {}
```

The above will set the global options for the `ttl`, the time to live in milliseconds, and the `limit`, the maximum number of requests within the ttl, for the routes of your application that are guarded.

Once the module has been imported, you can then choose how you would like to bind the `ThrottlerGuard`. Any kind of binding as mentioned in the [guards](https://docs.nestjs.com/guards) section is fine. If you wanted to bind the guard globally, for example, you could do so by adding this provider to any module:

```typescript

{
  provide: APP_GUARD,
  useClass: ThrottlerGuard
}
```

#### Multiple Throttler Definitions[#](/security/rate-limiting#multiple-throttler-definitions)

There may come upon times where you want to set up multiple throttling definitions, like no more than 3 calls in a second, 20 calls in 10 seconds, and 100 calls in a minute. To do so, you can set up your definitions in the array with named options, that can later be referenced in the `@SkipThrottle()` and `@Throttle()` decorators to change the options again.

app.module.ts

JS TS

```typescript

@Module({
  imports: [
    ThrottlerModule.forRoot([
      {
        name: 'short',
        ttl: 1000,
        limit: 3,
      },
      {
        name: 'medium',
        ttl: 10000,
        limit: 20
      },
      {
        name: 'long',
        ttl: 60000,
        limit: 100
      }
    ]),
  ],
})
export class AppModule {}
```

#### Customization[#](/security/rate-limiting#customization)

There may be a time where you want to bind the guard to a controller or globally, but want to disable rate limiting for one or more of your endpoints. For that, you can use the `@SkipThrottle()` decorator, to negate the throttler for an entire class or a single route. The `@SkipThrottle()` decorator can also take in an object of string keys with boolean values for if there is a case where you want to exclude *most* of a controller, but not every route, and configure it per throttler set if you have more than one. If you do not pass an object, the default is to use `{ default: true }`

```typescript

@SkipThrottle()
@Controller('users')
export class UsersController {}
```

This `@SkipThrottle()` decorator can be used to skip a route or a class or to negate the skipping of a route in a class that is skipped.

```typescript

@SkipThrottle()
@Controller('users')
export class UsersController {
  // Rate limiting is applied to this route.
  @SkipThrottle({ default: false })
  dontSkip() {
    return 'List users work with Rate limiting.';
  }
  // This route will skip rate limiting.
  doSkip() {
    return 'List users work without Rate limiting.';
  }
}
```

There is also the `@Throttle()` decorator which can be used to override the `limit` and `ttl` set in the global module, to give tighter or looser security options. This decorator can be used on a class or a function as well. With version 5 and onwards, the decorator takes in an object with the string relating to the name of the throttler set, and an object with the limit and ttl keys and integer values, similar to the options passed to the root module. If you do not have a name set in your original options, use the string `default` You have to configure it like this:

```typescript

// Override default configuration for Rate limiting and duration.
@Throttle({ default: { limit: 3, ttl: 60000 } })
@Get()
findAll() {
  return "List users works with custom rate limiting.";
}
```

#### Proxies[#](/security/rate-limiting#proxies)

If your application is running behind a proxy server, it’s essential to configure the HTTP adapter to trust the proxy. You can refer to the specific HTTP adapter options for [Express](http://expressjs.com/en/guide/behind-proxies.html) and [Fastify](https://www.fastify.io/docs/latest/Reference/Server/#trustproxy) to enable the `trust proxy` setting.

Here's an example that demonstrates how to enable `trust proxy` for the Express adapter:

main.ts.ts

JS TS

```typescript

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { NestExpressApplication } from '@nestjs/platform-express';

async function bootstrap() {
  const app = await NestFactory.create<NestExpressApplication>(AppModule);
  app.set('trust proxy', 'loopback'); // Trust requests from the loopback address
  await app.listen(3000);
}

bootstrap();
```

```typescript

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { NestExpressApplication } from '@nestjs/platform-express';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.set('trust proxy', 'loopback'); // Trust requests from the loopback address
  await app.listen(3000);
}

bootstrap();
```

Enabling `trust proxy` allows you to retrieve the original IP address from the `X-Forwarded-For` header. You can also customize the behavior of your application by overriding the `getTracker()` method to extract the IP address from this header instead of relying on `req.ip`. The following example demonstrates how to achieve this for both Express and Fastify:

throttler-behind-proxy.guard.ts

JS TS

```typescript

import { ThrottlerGuard } from '@nestjs/throttler';
import { Injectable } from '@nestjs/common';

@Injectable()
export class ThrottlerBehindProxyGuard extends ThrottlerGuard {
  protected async getTracker(req: Record<string, any>): Promise<string> {
    return req.ips.length ? req.ips[0] : req.ip; // individualize IP extraction to meet your own needs
  }
}
```

> **Hint** You can find the API of the `req` Request object for express [here](https://expressjs.com/en/api.html#req.ips) and for fastify [here](https://www.fastify.io/docs/latest/Reference/Request/).

#### Websockets[#](/security/rate-limiting#websockets)

This module can work with websockets, but it requires some class extension. You can extend the `ThrottlerGuard` and override the `handleRequest` method like so:

```typescript

@Injectable()
export class WsThrottlerGuard extends ThrottlerGuard {
  async handleRequest(requestProps: ThrottlerRequest): Promise<boolean> {
    const {
      context,
      limit,
      ttl,
      throttler,
      blockDuration,
      getTracker,
      generateKey,
    } = requestProps;

    const client = context.switchToWs().getClient();
    const tracker = client._socket.remoteAddress;
    const key = generateKey(context, tracker, throttler.name);
    const { totalHits, timeToExpire, isBlocked, timeToBlockExpire } =
      await this.storageService.increment(
        key,
        ttl,
        limit,
        blockDuration,
        throttler.name,
      );

    const getThrottlerSuffix = (name: string) =>
      name === 'default' ? '' : `-${name}`;

    // Throw an error when the user reached their limit.
    if (isBlocked) {
      await this.throwThrottlingException(context, {
        limit,
        ttl,
        key,
        tracker,
        totalHits,
        timeToExpire,
        isBlocked,
        timeToBlockExpire,
      });
    }

    return true;
  }
}
```

> **Hint** If you are using ws, it is necessary to replace the `_socket` with `conn`

There's a few things to keep in mind when working with WebSockets:

* Guard cannot be registered with the `APP_GUARD` or `app.useGlobalGuards()`
* When a limit is reached, Nest will emit an `exception` event, so make sure there is a listener ready for this

> **Hint** If you are using the `@nestjs/platform-ws` package you can use `client._socket.remoteAddress` instead.

#### GraphQL[#](/security/rate-limiting#graphql)

The `ThrottlerGuard` can also be used to work with GraphQL requests. Again, the guard can be extended, but this time the `getRequestResponse` method will be overridden

```typescript

@Injectable()
export class GqlThrottlerGuard extends ThrottlerGuard {
  getRequestResponse(context: ExecutionContext) {
    const gqlCtx = GqlExecutionContext.create(context);
    const ctx = gqlCtx.getContext();
    return { req: ctx.req, res: ctx.res };
  }
}
```

#### Configuration[#](/security/rate-limiting#configuration)

The following options are valid for the object passed to the array of the `ThrottlerModule`'s options:

|                    |                                                                                                                                                                 |
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `name`             | the name for internal tracking of which throttler set is being used. Defaults to \`default\` if not passed                                                      |
| `ttl`              | the number of milliseconds that each request will last in storage                                                                                               |
| `limit`            | the maximum number of requests within the TTL limit                                                                                                             |
| `blockDuration`    | the number of milliseconds that request will be blocked for that time                                                                                           |
| `ignoreUserAgents` | an array of regular expressions of user-agents to ignore when it comes to throttling requests                                                                   |
| `skipIf`           | a function that takes in the `ExecutionContext` and returns a `boolean` to short circuit the throttler logic. Like `@SkipThrottler()`, but based on the request |

If you need to set up storage instead, or want to use some of the above options in a more global sense, applying to each throttler set, you can pass the options above via the `throttlers` option key and use the below table

|                    |                                                                                                                                                                                                                                                                           |
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `storage`          | a custom storage service for where the throttling should be kept track. [See here.](/security/rate-limiting#storages)                                                                                                                                                     |
| `ignoreUserAgents` | an array of regular expressions of user-agents to ignore when it comes to throttling requests                                                                                                                                                                             |
| `skipIf`           | a function that takes in the `ExecutionContext` and returns a `boolean` to short circuit the throttler logic. Like `@SkipThrottler()`, but based on the request                                                                                                           |
| `throttlers`       | an array of throttler sets, defined using the table above                                                                                                                                                                                                                 |
| `errorMessage`     | a `string` OR a function that takes in the `ExecutionContext` and the `ThrottlerLimitDetail` and returns a `string` which overrides the default throttler error message                                                                                                   |
| `getTracker`       | a function that takes in the `Request` and returns a `string` to override the default logic of the `getTracker` method                                                                                                                                                    |
| `generateKey`      | a function that takes in the `ExecutionContext`, the tacker `string` and the throttler name as a `string` and returns a `string` to override the final key which will be used to store the rate limit value. This overrides the default logic of the `generateKey` method |

#### Async Configuration[#](/security/rate-limiting#async-configuration)

You may want to get your rate-limiting configuration asynchronously instead of synchronously. You can use the `forRootAsync()` method, which allows for dependency injection and `async` methods.

One approach would be to use a factory function:

```typescript

@Module({
  imports: [
    ThrottlerModule.forRootAsync({
      imports: [ConfigModule],
      inject: [ConfigService],
      useFactory: (config: ConfigService) => [
        {
          ttl: config.get('THROTTLE_TTL'),
          limit: config.get('THROTTLE_LIMIT'),
        },
      ],
    }),
  ],
})
export class AppModule {}
```

You can also use the `useClass` syntax:

```typescript

@Module({
  imports: [
    ThrottlerModule.forRootAsync({
      imports: [ConfigModule],
      useClass: ThrottlerConfigService,
    }),
  ],
})
export class AppModule {}
```

This is doable, as long as `ThrottlerConfigService` implements the interface `ThrottlerOptionsFactory`.

#### Storages[#](/security/rate-limiting#storages)

The built in storage is an in memory cache that keeps track of the requests made until they have passed the TTL set by the global options. You can drop in your own storage option to the `storage` option of the `ThrottlerModule` so long as the class implements the `ThrottlerStorage` interface.

For distributed servers you could use the community storage provider for [Redis](https://github.com/jmcdo29/nest-lab/tree/main/packages/throttler-storage-redis) to have a single source of truth.

> **Note**`ThrottlerStorage` can be imported from `@nestjs/throttler`.

#### Time Helpers[#](/security/rate-limiting#time-helpers)

There are a couple of helper methods to make the timings more readable if you prefer to use them over the direct definition. `@nestjs/throttler` exports five different helpers, `seconds`, `minutes`, `hours`, `days`, and `weeks`. To use them, simply call `seconds(5)` or any of the other helpers, and the correct number of milliseconds will be returned.

#### Migration Guide[#](/security/rate-limiting#migration-guide)

For most people, wrapping your options in an array will be enough.

If you are using a custom storage, you should wrap your `ttl` and `limit` in an array and assign it to the `throttlers` property of the options object.

Any `@ThrottleSkip()` should now take in an object with `string: boolean` props. The strings are the names of the throttlers. If you do not have a name, pass the string `'default'`, as this is what will be used under the hood otherwise.

Any `@Throttle()` decorators should also now take in an object with string keys, relating to the names of the throttler contexts (again, `'default'` if no name) and values of objects that have `limit` and `ttl` keys.

> **Important** The `ttl` is now in **milliseconds**. If you want to keep your ttl in seconds for readability, use the `seconds` helper from this package. It just multiplies the ttl by 1000 to make it in milliseconds.

For more info, see the [Changelog](https://github.com/nestjs/throttler/blob/master/CHANGELOG.md#500)

----
url: https://docs.nestjs.com/v9/microservices/mqtt
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [MQTT](https://docs.nestjs.com/v9/microservices/mqtt#mqtt)
* [Installation](https://docs.nestjs.com/v9/microservices/mqtt#installation)
* [Overview](https://docs.nestjs.com/v9/microservices/mqtt#overview)
* [Options](https://docs.nestjs.com/v9/microservices/mqtt#options)
* [Client](https://docs.nestjs.com/v9/microservices/mqtt#client)
* [Context](https://docs.nestjs.com/v9/microservices/mqtt#context)
* [Wildcards](https://docs.nestjs.com/v9/microservices/mqtt#wildcards)
* [Record builders](https://docs.nestjs.com/v9/microservices/mqtt#record-builders)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/microservices/mqtt.md "Suggest Edits")

### MQTT

[MQTT](https://mqtt.org/) (Message Queuing Telemetry Transport) is an open source, lightweight messaging protocol, optimized for low latency. This protocol provides a scalable and cost-efficient way to connect devices using a **publish/subscribe** model. A communication system built on MQTT consists of the publishing server, a broker and one or more clients. It is designed for constrained devices and low-bandwidth, high-latency or unreliable networks.

#### Installation[#](/microservices/mqtt#installation)

To start building MQTT-based microservices, first install the required package:

```bash

$ npm i --save mqtt
```

#### Overview[#](/microservices/mqtt#overview)

To use the MQTT transporter, pass the following options object to the `createMicroservice()` method:

main.ts

JS TS

```typescript

const app = await NestFactory.createMicroservice<MicroserviceOptions>(AppModule, {
  transport: Transport.MQTT,
  options: {
    url: 'mqtt://localhost:1883',
  },
});
```

```typescript

const app = await NestFactory.createMicroservice(AppModule, {
  transport: Transport.MQTT,
  options: {
    url: 'mqtt://localhost:1883',
  },
});
```

> **Hint** The `Transport` enum is imported from the `@nestjs/microservices` package.

#### Options[#](/microservices/mqtt#options)

The `options` object is specific to the chosen transporter. The **MQTT** transporter exposes the properties described [here](https://github.com/mqttjs/MQTT.js/#mqttclientstreambuilder-options).

#### Client[#](/microservices/mqtt#client)

Like other microservice transporters, you have [several options](https://docs.nestjs.com/microservices/basics#client) for creating a MQTT `ClientProxy` instance.

One method for creating an instance is to use use the `ClientsModule`. To create a client instance with the `ClientsModule`, import it and use the `register()` method to pass an options object with the same properties shown above in the `createMicroservice()` method, as well as a `name` property to be used as the injection token. Read more about `ClientsModule`[here](https://docs.nestjs.com/microservices/basics#client).

```typescript

@Module({
  imports: [
    ClientsModule.register([
      {
        name: 'MATH_SERVICE',
        transport: Transport.MQTT,
        options: {
          url: 'mqtt://localhost:1883',
        }
      },
    ]),
  ]
  ...
})
```

Other options to create a client (either `ClientProxyFactory` or `@Client()`) can be used as well. You can read about them [here](https://docs.nestjs.com/microservices/basics#client).

#### Context[#](/microservices/mqtt#context)

In more sophisticated scenarios, you may want to access more information about the incoming request. When using the MQTT transporter, you can access the `MqttContext` object.

JS TS

```typescript

@MessagePattern('notifications')
getNotifications(@Payload() data: number[], @Ctx() context: MqttContext) {
  console.log(`Topic: ${context.getTopic()}`);
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('notifications')
getNotifications(data, context) {
  console.log(`Topic: ${context.getTopic()}`);
}
```

> **Hint**`@Payload()`, `@Ctx()` and `MqttContext` are imported from the `@nestjs/microservices` package.

To access the original mqtt [packet](https://github.com/mqttjs/mqtt-packet), use the `getPacket()` method of the `MqttContext` object, as follows:

JS TS

```typescript

@MessagePattern('notifications')
getNotifications(@Payload() data: number[], @Ctx() context: MqttContext) {
  console.log(context.getPacket());
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('notifications')
getNotifications(data, context) {
  console.log(context.getPacket());
}
```

#### Wildcards[#](/microservices/mqtt#wildcards)

A subscription may be to an explicit topic, or it may include wildcards. Two wildcards are available, `+` and `#`. `+` is a single-level wildcard, while `#` is a multi-level wildcard which covers many topic levels.

JS TS

```typescript

@MessagePattern('sensors/+/temperature/+')
getTemperature(@Ctx() context: MqttContext) {
  console.log(`Topic: ${context.getTopic()}`);
}
```

```typescript

@Bind(Ctx())
@MessagePattern('sensors/+/temperature/+')
getTemperature(context) {
  console.log(`Topic: ${context.getTopic()}`);
}
```

#### Record builders[#](/microservices/mqtt#record-builders)

To configure message options (adjust the QoS level, set the Retain or DUP flags, or add additional properties to the payload), you can use the `MqttRecordBuilder` class. For example, to set `QoS` to `2` use the `setQoS` method, as follows:

```typescript

const userProperties = { 'x-version': '1.0.0' };
const record = new MqttRecordBuilder(':cat:')
  .setProperties({ userProperties })
  .setQoS(1)
  .build();
client.send('replace-emoji', record).subscribe(...);
```

> **Hint**`MqttRecordBuilder` class is exported from the `@nestjs/microservices` package.

And you can read these options on the server-side as well, by accessing the `MqttContext`.

JS TS

```typescript

@MessagePattern('replace-emoji')
replaceEmoji(@Payload() data: string, @Ctx() context: MqttContext): string {
  const { properties: { userProperties } } = context.getPacket();
  return userProperties['x-version'] === '1.0.0' ? '🐱' : '🐈';
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('replace-emoji')
replaceEmoji(data, context) {
  const { properties: { userProperties } } = context.getPacket();
  return userProperties['x-version'] === '1.0.0' ? '🐱' : '🐈';
}
```

In some cases you might want to configure user properties for multiple requests, you can pass these options to the `ClientProxyFactory`.

```typescript

import { Module } from '@nestjs/common';
import { ClientProxyFactory, Transport } from '@nestjs/microservices';

@Module({
  providers: [
    {
      provide: 'API_v1',
      useFactory: () =>
        ClientProxyFactory.create({
          transport: Transport.MQTT,
          options: {
            url: 'mqtt://localhost:1833',
            userProperties: { 'x-version': '1.0.0' },
          },
        }),
    },
  ],
})
export class ApiModule {}
```

----
url: https://docs.nestjs.com/v10/graphql/cli-plugin
----

* [CLI Plugin](https://docs.nestjs.com/v10/graphql/cli-plugin#cli-plugin)
* [Overview](https://docs.nestjs.com/v10/graphql/cli-plugin#overview)
* [Comments introspection](https://docs.nestjs.com/v10/graphql/cli-plugin#comments-introspection)
* [Using the CLI plugin](https://docs.nestjs.com/v10/graphql/cli-plugin#using-the-cli-plugin)
* [SWC builder](https://docs.nestjs.com/v10/graphql/cli-plugin#swc-builder)
* [Integration with ts-jest (e2e tests)](https://docs.nestjs.com/v10/graphql/cli-plugin#integration-with-ts-jest-e2e-tests)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/cli-plugin.md "Suggest Edits")

### CLI Plugin

> **Warning** This chapter applies only to the code first approach.

TypeScript's metadata reflection system has several limitations which make it impossible to, for instance, determine what properties a class consists of or recognize whether a given property is optional or required. However, some of these constraints can be addressed at compilation time. Nest provides a plugin that enhances the TypeScript compilation process to reduce the amount of boilerplate code required.

> **Hint** This plugin is **opt-in**. If you prefer, you can declare all decorators manually, or only specific decorators where you need them.

```typescript

@ObjectType()
export class Author {
  @Field(type => ID)
  id: number;

  @Field({ nullable: true })
  firstName?: string;

  @Field({ nullable: true })
  lastName?: string;

  @Field(type => [Post])
  posts: Post[];
}
```

While not a significant issue with medium-sized projects, it becomes verbose & hard to maintain once you have a large set of classes.

By enabling the GraphQL plugin, the above class definition can be declared simply:

authors/models/author.model.ts

JS TS

```typescript

@ObjectType()
export class Author {
  @Field(type => ID)
  id: number;
  firstName?: string;
  lastName?: string;
  posts: Post[];
}
```

The plugin adds appropriate decorators on-the-fly based on the **Abstract Syntax Tree**. Thus, you won't have to struggle with `@Field` decorators scattered throughout the code.

> **Hint** The plugin will automatically generate any missing GraphQL properties, but if you need to override them, simply set them explicitly via `@Field()`.

#### Comments introspection[#](/graphql/cli-plugin#comments-introspection)

With the comments introspection feature enabled, CLI plugin will generate descriptions for fields based on comments.

For example, given an example `roles` property:

```typescript

/**
 * A list of user's roles
 */
@Field(() => [String], {
  description: `A list of user's roles`
})
roles: string[];
```

You must duplicate description values. With `introspectComments` enabled, the CLI plugin can extract these comments and automatically provide descriptions for properties. Now, the above field can be declared simply as follows:

```typescript

/**
 * A list of user's roles
 */
roles: string[];
```

#### Using the CLI plugin[#](/graphql/cli-plugin#using-the-cli-plugin)

To enable the plugin, open `nest-cli.json` (if you use [Nest CLI](/v10/cli/overview)) and add the following `plugins` configuration:

```javascript

{
  "collection": "@nestjs/schematics",
  "sourceRoot": "src",
  "compilerOptions": {
    "plugins": ["@nestjs/graphql"]
  }
}
```

You can use the `options` property to customize the behavior of the plugin.

```javascript

"plugins": [
  {
    "name": "@nestjs/graphql",
    "options": {
      "typeFileNameSuffix": [".input.ts", ".args.ts"],
      "introspectComments": true
    }
  }
]
```

The `options` property has to fulfill the following interface:

```typescript

export interface PluginOptions {
  typeFileNameSuffix?: string[];
  introspectComments?: boolean;
}
```

| Option               | Default                                                | Description                                                                        |
| -------------------- | ------------------------------------------------------ | ---------------------------------------------------------------------------------- |
| `typeFileNameSuffix` | `['.input.ts', '.args.ts', '.entity.ts', '.model.ts']` | GraphQL types files suffix                                                         |
| `introspectComments` | `false`                                                | If set to true, plugin will generate descriptions for properties based on comments |

If you don't use the CLI but instead have a custom `webpack` configuration, you can use this plugin in combination with `ts-loader`:

```javascript

getCustomTransformers: (program: any) => ({
  before: [require('@nestjs/graphql/plugin').before({}, program)]
}),
```

#### SWC builder[#](/graphql/cli-plugin#swc-builder)

For standard setups (non-monorepo), to use CLI Plugins with the SWC builder, you need to enable type checking, as described [here](/recipes/swc#type-checking).

```bash

$ nest start -b swc --type-check
```

For monorepo setups, follow the instructions [here](/recipes/swc#monorepo-and-cli-plugins).

```bash

$ npx ts-node src/generate-metadata.ts
# OR npx ts-node apps/{YOUR_APP}/src/generate-metadata.ts
```

Now, the serialized metadata file must be loaded by the `GraphQLModule` method, as shown below:

```typescript

import metadata from './metadata'; // <-- file auto-generated by the "PluginMetadataGenerator"

GraphQLModule.forRoot<...>({
  ..., // other options
  metadata,
}),
```

#### Integration with `ts-jest` (e2e tests)[#](/graphql/cli-plugin#integration-with-ts-jest-e2e-tests)

When running e2e tests with this plugin enabled, you may run into issues with compiling schema. For example, one of the most common errors is:

```json

Object type <name> must define one or more fields.
```

This happens because `jest` configuration does not import `@nestjs/graphql/plugin` plugin anywhere.

To fix this, create the following file in your e2e tests directory:

```javascript

const transformer = require('@nestjs/graphql/plugin');

module.exports.name = 'nestjs-graphql-transformer';
// you should change the version number anytime you change the configuration below - otherwise, jest will not detect changes
module.exports.version = 1;

module.exports.factory = (cs) => {
  return transformer.before(
    {
      // @nestjs/graphql/plugin options (can be empty)
    },
    cs.program, // "cs.tsCompiler.program" for older versions of Jest (<= v27)
  );
};
```

With this in place, import AST transformer within your `jest` configuration file. By default (in the starter application), e2e tests configuration file is located under the `test` folder and is named `jest-e2e.json`.

```json

{
  ... // other configuration
  "globals": {
    "ts-jest": {
      "astTransformers": {
        "before": ["<path to the file created above>"]
      }
    }
  }
}
```

If you use `jest@^29`, then use the snippet below, as the previous approach got deprecated.

```json

{
  ... // other configuration
  "transform": {
    "^.+\\.(t|j)s$": [
      "ts-jest",
      {
        "astTransformers": {
          "before": ["<path to the file created above>"]
        }
      }
    ]
  }
}
```

----
url: https://docs.nestjs.com/v7/fundamentals/dynamic-modules
----

* [Dynamic modules](https://docs.nestjs.com/v7/fundamentals/dynamic-modules#dynamic-modules)
* [Introduction](https://docs.nestjs.com/v7/fundamentals/dynamic-modules#introduction)
* [Dynamic module use case](https://docs.nestjs.com/v7/fundamentals/dynamic-modules#dynamic-module-use-case)
* [Config module example](https://docs.nestjs.com/v7/fundamentals/dynamic-modules#config-module-example)
* [Module configuration](https://docs.nestjs.com/v7/fundamentals/dynamic-modules#module-configuration)
* [Example](https://docs.nestjs.com/v7/fundamentals/dynamic-modules#example)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/fundamentals/dynamic-modules.md "Suggest Edits")

### Dynamic modules

The [Modules chapter](/v7/modules) covers the basics of Nest modules, and includes a brief introduction to [dynamic modules](https://docs.nestjs.com/modules#dynamic-modules). This chapter expands on the subject of dynamic modules. Upon completion, you should have a good grasp of what they are and how and when to use them.

#### Introduction[#](/fundamentals/dynamic-modules#introduction)

Most application code examples in the **Overview** section of the documentation make use of regular, or static, modules. Modules define groups of components like [providers](/v7/providers) and [controllers](/v7/controllers) that fit together as a modular part of an overall application. They provide an execution context, or scope, for these components. For example, providers defined in a module are visible to other members of the module without the need to export them. When a provider needs to be visible outside of a module, it is first exported from its host module, and then imported into its consuming module.

Let's walk through a familiar example.

First, we'll define a `UsersModule` to provide and export a `UsersService`. `UsersModule` is the **host** module for `UsersService`.

```typescript

import { Module } from '@nestjs/common';
import { UsersService } from './users.service';

@Module({
  providers: [UsersService],
  exports: [UsersService],
})
export class UsersModule {}
```

Next, we'll define an `AuthModule`, which imports `UsersModule`, making `UsersModule`'s exported providers available inside `AuthModule`:

```typescript

import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { UsersModule } from '../users/users.module';

@Module({
  imports: [UsersModule],
  providers: [AuthService],
  exports: [AuthService],
})
export class AuthModule {}
```

These constructs allow us to inject `UsersService` in, for example, the `AuthService` that is hosted in `AuthModule`:

```typescript

import { Injectable } from '@nestjs/common';
import { UsersService } from '../users/users.service';

@Injectable()
export class AuthService {
  constructor(private usersService: UsersService) {}
  /*
    Implementation that makes use of this.usersService
  */
}
```

```typescript

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { ConfigModule } from './config/config.module';

@Module({
  imports: [ConfigModule],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}
```

Let's consider what a *dynamic module* import, where we're passing in a configuration object, might look like. Compare the difference in the `imports` array between these two examples:

```typescript

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { ConfigModule } from './config/config.module';

@Module({
  imports: [ConfigModule.register({ folder: './config' })],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}
```

Let's see what's happening in the dynamic example above. What are the moving parts?

1. `ConfigModule` is a normal class, so we can infer that it must have a **static method** called `register()`. We know it's static because we're calling it on the `ConfigModule` class, not on an **instance** of the class. Note: this method, which we will create soon, can have any arbitrary name, but by convention we should call it either `forRoot()` or `register()`.
2. The `register()` method is defined by us, so we can accept any input arguments we like. In this case, we're going to accept a simple `options` object with suitable properties, which is the typical case.
3. We can infer that the `register()` method must return something like a `module` since its return value appears in the familiar `imports` list, which we've seen so far includes a list of modules.

In fact, what our `register()` method will return is a `DynamicModule`. A dynamic module is nothing more than a module created at run-time, with the same exact properties as a static module, plus one additional property called `module`. Let's quickly review a sample static module declaration, paying close attention to the module options passed in to the decorator:

```typescript

@Module({
  imports: [DogsService],
  controllers: [CatsController],
  providers: [CatsService],
  exports: [CatsService]
})
```

Dynamic modules must return an object with the exact same interface, plus one additional property called `module`. The `module` property serves as the name of the module, and should be the same as the class name of the module, as shown in the example below.

> **Hint** For a dynamic module, all properties of the module options object are optional **except**`module`.

What about the static `register()` method? We can now see that its job is to return an object that has the `DynamicModule` interface. When we call it, we are effectively providing a module to the `imports` list, similar to the way we would do so in the static case by listing a module class name. In other words, the dynamic module API simply returns a module, but rather than fix the properties in the `@Modules` decorator, we specify them programmatically.

There are still a couple of details to cover to help make the picture complete:

1. We can now state that the `@Module()` decorator's `imports` property can take not only a module class name (e.g., `imports: [UsersModule]`), but also a function **returning** a dynamic module (e.g., `imports: [ConfigModule.register(...)]`).
2. A dynamic module can itself import other modules. We won't do so in this example, but if the dynamic module depends on providers from other modules, you would import them using the optional `imports` property. Again, this is exactly analogous to the way you'd declare metadata for a static module using the `@Module()` decorator.

Armed with this understanding, we can now look at what our dynamic `ConfigModule` declaration must look like. Let's take a crack at it.

```typescript

import { DynamicModule, Module } from '@nestjs/common';
import { ConfigService } from './config.service';

@Module({})
export class ConfigModule {
  static register(): DynamicModule {
    return {
      module: ConfigModule,
      providers: [ConfigService],
      exports: [ConfigService],
    };
  }
}
```

It should now be clear how the pieces tie together. Calling `ConfigModule.register(...)` returns a `DynamicModule` object with properties which are essentially the same as those that, until now, we've provided as metadata via the `@Module()` decorator.

> **Hint** Import `DynamicModule` from `@nestjs/common`.

Our dynamic module isn't very interesting yet, however, as we haven't introduced any capability to **configure** it as we said we would like to do. Let's address that next.

### Module configuration

The obvious solution for customizing the behavior of the `ConfigModule` is to pass it an `options` object in the static `register()` method, as we guessed above. Let's look once again at our consuming module's `imports` property:

```typescript

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { ConfigModule } from './config/config.module';

@Module({
  imports: [ConfigModule.register({ folder: './config' })],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}
```

That nicely handles passing an `options` object to our dynamic module. How do we then use that `options` object in the `ConfigModule`? Let's consider that for a minute. We know that our `ConfigModule` is basically a host for providing and exporting an injectable service - the `ConfigService` - for use by other providers. It's actually our `ConfigService` that needs to read the `options` object to customize its behavior. Let's assume for the moment that we know how to somehow get the `options` from the `register()` method into the `ConfigService`. With that assumption, we can make a few changes to the service to customize its behavior based on the properties from the `options` object. (**Note**: for the time being, since we *haven't* actually determined how to pass it in, we'll just hard-code `options`. We'll fix this in a minute).

```typescript

import { Injectable } from '@nestjs/common';
import * as dotenv from 'dotenv';
import * as fs from 'fs';
import { EnvConfig } from './interfaces';

@Injectable()
export class ConfigService {
  private readonly envConfig: EnvConfig;

  constructor() {
    const options = { folder: './config' };

    const filePath = `${process.env.NODE_ENV || 'development'}.env`;
    const envFile = path.resolve(__dirname, '../../', options.folder, filePath);
    this.envConfig = dotenv.parse(fs.readFileSync(envFile));
  }

  get(key: string): string {
    return this.envConfig[key];
  }
}
```

Now our `ConfigService` knows how to find the `.env` file in the folder we've specified in `options`.

Our remaining task is to somehow inject the `options` object from the `register()` step into our `ConfigService`. And of course, we'll use *dependency injection* to do it. This is a key point, so make sure you understand it. Our `ConfigModule` is providing `ConfigService`. `ConfigService` in turn depends on the `options` object that is only supplied at run-time. So, at run-time, we'll need to first bind the `options` object to the Nest IoC container, and then have Nest inject it into our `ConfigService`. Remember from the **Custom providers** chapter that providers can [include any value](https://docs.nestjs.com/fundamentals/custom-providers#non-service-based-providers) not just services, so we're fine using dependency injection to handle a simple `options` object.

Let's tackle binding the options object to the IoC container first. We do this in our static `register()` method. Remember that we are dynamically constructing a module, and one of the properties of a module is its list of providers. So what we need to do is define our options object as a provider. This will make it injectable into the `ConfigService`, which we'll take advantage of in the next step. In the code below, pay attention to the `providers` array:

```typescript

import { DynamicModule, Module } from '@nestjs/common';
import { ConfigService } from './config.service';

@Module({})
export class ConfigModule {
  static register(options): DynamicModule {
    return {
      module: ConfigModule,
      providers: [
        {
          provide: 'CONFIG_OPTIONS',
          useValue: options,
        },
        ConfigService,
      ],
      exports: [ConfigService],
    };
  }
}
```

Now we can complete the process by injecting the `'CONFIG_OPTIONS'` provider into the `ConfigService`. Recall that when we define a provider using a non-class token we need to use the `@Inject()` decorator [as described here](https://docs.nestjs.com/fundamentals/custom-providers#non-class-based-provider-tokens).

```typescript

import * as dotenv from 'dotenv';
import * as fs from 'fs';
import { Injectable, Inject } from '@nestjs/common';
import { EnvConfig } from './interfaces';

@Injectable()
export class ConfigService {
  private readonly envConfig: EnvConfig;

  constructor(@Inject('CONFIG_OPTIONS') private options) {
    const filePath = `${process.env.NODE_ENV || 'development'}.env`;
    const envFile = path.resolve(__dirname, '../../', options.folder, filePath);
    this.envConfig = dotenv.parse(fs.readFileSync(envFile));
  }

  get(key: string): string {
    return this.envConfig[key];
  }
}
```

One final note: for simplicity we used a string-based injection token (`'CONFIG_OPTIONS'`) above, but best practice is to define it as a constant (or `Symbol`) in a separate file, and import that file. For example:

```typescript

export const CONFIG_OPTIONS = 'CONFIG_OPTIONS';
```

### Example

A full example of the code in this chapter can be found [here](https://github.com/nestjs/nest/tree/master/sample/25-dynamic-modules).

----
url: https://docs.nestjs.com/v7/recipes/sql-sequelize
----

* [SQL (Sequelize)](https://docs.nestjs.com/v7/recipes/sql-sequelize#sql-sequelize)
* [Getting started](https://docs.nestjs.com/v7/recipes/sql-sequelize#getting-started)
* [Model injection](https://docs.nestjs.com/v7/recipes/sql-sequelize#model-injection)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/recipes/sql-sequelize.md "Suggest Edits")

### SQL (Sequelize)

##### This chapter applies only to TypeScript

> **Warning** In this article, you'll learn how to create a `DatabaseModule` based on the **Sequelize** package from scratch using custom components. As a consequence, this technique contains a lot of overhead that you can avoid by using the dedicated, out-of-the-box `@nestjs/sequelize` package. To learn more, see [here](/techniques/database#sequelize-integration).

[Sequelize](https://github.com/sequelize/sequelize) is a popular Object Relational Mapper (ORM) written in a vanilla JavaScript, but there is a [sequelize-typescript](https://github.com/RobinBuschmann/sequelize-typescript) TypeScript wrapper which provides a set of decorators and other extras for the base sequelize.

#### Getting started[#](/recipes/sql-sequelize#getting-started)

To start the adventure with this library we have to install the following dependencies:

```bash

$ npm install --save sequelize sequelize-typescript mysql2
$ npm install --save-dev @types/sequelize
```

The first step we need to do is create a **Sequelize** instance with an options object passed into the constructor. Also, we need to add all models (the alternative is to use `modelPaths` property) and `sync()` our database tables.

database.providers.ts

JS TS

```typescript

import { Sequelize } from 'sequelize-typescript';
import { Cat } from '../cats/cat.entity';

export const databaseProviders = [
  {
    provide: 'SEQUELIZE',
    useFactory: async () => {
      const sequelize = new Sequelize({
        dialect: 'mysql',
        host: 'localhost',
        port: 3306,
        username: 'root',
        password: 'password',
        database: 'nest',
      });
      sequelize.addModels([Cat]);
      await sequelize.sync();
      return sequelize;
    },
  },
];
```

> **Hint** Following best practices, we declared the custom provider in the separated file which has a `*.providers.ts` suffix.

Then, we need to export these providers to make them **accessible** for the rest part of the application.

```typescript

import { Module } from '@nestjs/common';
import { databaseProviders } from './database.providers';

@Module({
  providers: [...databaseProviders],
  exports: [...databaseProviders],
})
export class DatabaseModule {}
```

Now we can inject the `Sequelize` object using `@Inject()` decorator. Each class that would depend on the `Sequelize` async provider will wait until a `Promise` is resolved.

#### Model injection[#](/recipes/sql-sequelize#model-injection)

In [Sequelize](https://github.com/sequelize/sequelize) the **Model** defines a table in the database. Instances of this class represent a database row. Firstly, we need at least one entity:

cat.entity.ts

JS TS

```typescript

import { Table, Column, Model } from 'sequelize-typescript';

@Table
export class Cat extends Model<Cat> {
  @Column
  name: string;

  @Column
  age: number;

  @Column
  breed: string;
}
```

The `Cat` entity belongs to the `cats` directory. This directory represents the `CatsModule`. Now it's time to create a **Repository** provider:

cats.providers.ts

JS TS

```typescript

import { Cat } from './cat.entity';

export const catsProviders = [
  {
    provide: 'CATS_REPOSITORY',
    useValue: Cat,
  },
];
```

> **Warning** In the real-world applications you should avoid **magic strings**. Both `CATS_REPOSITORY` and `SEQUELIZE` should be kept in the separated `constants.ts` file.

In Sequelize, we use static methods to manipulate the data, and thus we created an **alias** here.

Now we can inject the `CATS_REPOSITORY` to the `CatsService` using the `@Inject()` decorator:

cats.service.ts

JS TS

```typescript

import { Injectable, Inject } from '@nestjs/common';
import { CreateCatDto } from './dto/create-cat.dto';
import { Cat } from './cat.entity';

@Injectable()
export class CatsService {
  constructor(
    @Inject('CATS_REPOSITORY') private catsRepository: typeof Cat) {}

  async findAll(): Promise<Cat[]> {
    return this.catsRepository.findAll<Cat>();
  }
}
```

The database connection is **asynchronous**, but Nest makes this process completely invisible for the end-user. The `CATS_REPOSITORY` provider is waiting for the db connection, and the `CatsService` is delayed until repository is ready to use. The entire application can start when each class is instantiated.

Here is a final `CatsModule`:

cats.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';
import { catsProviders } from './cats.providers';
import { DatabaseModule } from '../database/database.module';

@Module({
  imports: [DatabaseModule],
  controllers: [CatsController],
  providers: [
    CatsService,
    ...catsProviders,
  ],
})
export class CatsModule {}
```

> **Hint** Do not forget to import the `CatsModule` into the root `ApplicationModule`.

----
url: https://docs.nestjs.com/v10/faq/raw-body
----

* [Raw body](https://docs.nestjs.com/v10/faq/raw-body#raw-body)
* [Use with Express](https://docs.nestjs.com/v10/faq/raw-body#use-with-express)
* [Registering a different parser](https://docs.nestjs.com/v10/faq/raw-body#registering-a-different-parser)
* [Body parser size limit](https://docs.nestjs.com/v10/faq/raw-body#body-parser-size-limit)
* [Use with Fastify](https://docs.nestjs.com/v10/faq/raw-body#use-with-fastify)
* [Registering a different parser](https://docs.nestjs.com/v10/faq/raw-body#registering-a-different-parser-1)
* [Body parser size limit](https://docs.nestjs.com/v10/faq/raw-body#body-parser-size-limit-1)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/faq/raw-body.md "Suggest Edits")

### Raw body

One of the most common use-case for having access to the raw request body is performing webhook signature verifications. Usually to perform webhook signature validations the unserialized request body is required to calculate an HMAC hash.

> **Warning** This feature can be used only if the built-in global body parser middleware is enabled, ie., you must not pass `bodyParser: false` when creating the app.

#### Use with Express[#](/faq/raw-body#use-with-express)

First enable the option when creating your Nest Express application:

```typescript

import { NestFactory } from '@nestjs/core';
import type { NestExpressApplication } from '@nestjs/platform-express';
import { AppModule } from './app.module';

// in the "bootstrap" function
const app = await NestFactory.create<NestExpressApplication>(AppModule, {
  rawBody: true,
});
await app.listen(process.env.PORT ?? 3000);
```

To access the raw request body in a controller, a convenience interface `RawBodyRequest` is provided to expose a `rawBody` field on the request: use the interface `RawBodyRequest` type:

```typescript

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

@Controller('cats')
class CatsController {
  @Post()
  create(@Req() req: RawBodyRequest<Request>) {
    const raw = req.rawBody; // returns a `Buffer`.
  }
}
```

#### Registering a different parser[#](/faq/raw-body#registering-a-different-parser)

By default, only `json` and `urlencoded` parsers are registered. If you want to register a different parser on the fly, you will need to do so explicitly.

For example, to register a `text` parser, you can use the following code:

```typescript

app.useBodyParser('text');
```

> **Warning** Ensure that you are providing the correct application type to the `NestFactory.create` call. For Express applications, the correct type is `NestExpressApplication`. Otherwise the `.useBodyParser` method will not be found.

#### Body parser size limit[#](/faq/raw-body#body-parser-size-limit)

If your application needs to parse a body larger than the default `100kb` of Express, use the following:

```typescript

app.useBodyParser('json', { limit: '10mb' });
```

The `.useBodyParser` method will respect the `rawBody` option that is passed in the application options.

#### Use with Fastify[#](/faq/raw-body#use-with-fastify)

First enable the option when creating your Nest Fastify application:

```typescript

import { NestFactory } from '@nestjs/core';
import {
  FastifyAdapter,
  NestFastifyApplication,
} from '@nestjs/platform-fastify';
import { AppModule } from './app.module';

// in the "bootstrap" function
const app = await NestFactory.create<NestFastifyApplication>(
  AppModule,
  new FastifyAdapter(),
  {
    rawBody: true,
  },
);
await app.listen(process.env.PORT ?? 3000);
```

To access the raw request body in a controller, a convenience interface `RawBodyRequest` is provided to expose a `rawBody` field on the request: use the interface `RawBodyRequest` type:

```typescript

import { Controller, Post, RawBodyRequest, Req } from '@nestjs/common';
import { FastifyRequest } from 'fastify';

@Controller('cats')
class CatsController {
  @Post()
  create(@Req() req: RawBodyRequest<FastifyRequest>) {
    const raw = req.rawBody; // returns a `Buffer`.
  }
}
```

#### Registering a different parser[#](/faq/raw-body#registering-a-different-parser-1)

By default, only `application/json` and `application/x-www-form-urlencoded` parsers are registered. If you want to register a different parser on the fly, you will need to do so explicitly.

For example, to register a `text/plain` parser, you can use the following code:

```typescript

app.useBodyParser('text/plain');
```

> **Warning** Ensure that you are providing the correct application type to the `NestFactory.create` call. For Fastify applications, the correct type is `NestFastifyApplication`. Otherwise the `.useBodyParser` method will not be found.

#### Body parser size limit[#](/faq/raw-body#body-parser-size-limit-1)

If your application needs to parse a body larger than the default 1MiB of Fastify, use the following:

```typescript

const bodyLimit = 10_485_760; // 10MiB
app.useBodyParser('application/json', { bodyLimit });
```

The `.useBodyParser` method will respect the `rawBody` option that is passed in the application options.

----
url: https://docs.nestjs.com/v7/techniques/server-sent-events
----

* [Server-Sent Events](https://docs.nestjs.com/v7/techniques/server-sent-events#server-sent-events)
* [Usage](https://docs.nestjs.com/v7/techniques/server-sent-events#usage)
* [Example](https://docs.nestjs.com/v7/techniques/server-sent-events#example)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/techniques/server-sent-events.md "Suggest Edits")

### Server-Sent Events

Server-Sent Events (SSE) is a server push technology enabling a client to receive automatic updates from a server via HTTP connection. Each notification is sent as a block of text terminated by a pair of newlines (learn more [here](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events)).

#### Usage[#](/techniques/server-sent-events#usage)

To enable Server-Sent events on a route (route registered within a **controller class**), annotate the method handler with the `@Sse()` decorator.

```typescript

@Sse('sse')
sse(): Observable<MessageEvent> {
  return interval(1000).pipe(map((_) => ({ data: { hello: 'world' } })));
}
```

> **Hint** The `@Sse()` decorator is imported from the `@nestjs/common`, while `Observable`, `interval`, `and map` are imported from the `rxjs` package.

> **Warning** Server-Sent Events routes must return an `Observable` stream.

In the example above, we defined a route named `sse` that will allow us to propagate real-time updates. These events can be listened to using the [EventSource API](https://developer.mozilla.org/en-US/docs/Web/API/EventSource).

The `sse` method returns an `Observable` that emits multiple `MessageEvent` (in this example, it emits a new `MessageEvent` every second). The `MessageEvent` object should respect the following interface to match the specification:

```typescript

export interface MessageEvent {
  data: string | object;
  id?: string;
  type?: string;
  retry?: number;
}
```

With this in place, we can now create an instance of the `EventSource` class in our client-side application, passing the `/sse` route (which matches the endpoint we have passed into the `@Sse()` decorator above) as a constructor argument.

`EventSource` instance opens a persistent connection to an HTTP server, which sends events in `text/event-stream` format. The connection remains open until closed by calling `EventSource.close()`.

Once the connection is opened, incoming messages from the server are delivered to your code in the form of events. If there is an event field in the incoming message, the triggered event is the same as the event field value. If no event field is present, then a generic `message` event is fired ([source](https://developer.mozilla.org/en-US/docs/Web/API/EventSource)).

```javascript

const eventSource = new EventSource('/sse');
eventSource.onmessage = ({ data }) => {
  console.log('New message', JSON.parse(data));
};
```

#### Example[#](/techniques/server-sent-events#example)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/28-sse).

----
url: https://docs.nestjs.com/v5/microservices/grpc
----

### gRPC

The [gRPC](https://github.com/grpc/grpc-node) is a high-performance, open-source universal RPC framework.

#### Installation

Before we start, we have to install required package:

```bash

$ npm i --save grpc @grpc/proto-loader
```

#### Transporter

In order to switch to **gRPC** transporter, we need to modify an options object passed to the `createMicroservice()` method.

main.ts

JS TS

TypeScript

```typescript

const app = await NestFactory.createMicroservice(ApplicationModule, {
  transport: Transport.GRPC,
  options: {
    package: 'hero',
    protoPath: join(__dirname, 'hero/hero.proto'),
  },
});
```

> **Hint** The `join()` function is imported from `path` package.

#### Options

There are a bunch of available options that determine a transporter behavior.

|               |                                                                                                                                             |
| ------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
| `url`         | Connection url                                                                                                                              |
| `protoPath`   | Absolute (or relative to the root dir) path to the `.proto` file                                                                            |
| `loader`      | `@grpc/proto-loader` options. They are well-described [here](https://github.com/grpc/grpc-node/tree/master/packages/grpc-protobufjs#usage). |
| `package`     | Protobuf package name                                                                                                                       |
| `credentials` | Server credentials ([read more](https://grpc.io/grpc/node/grpc.ServerCredentials.html))                                                     |

#### Overview

In general, a `package` property sets a [protobuf](https://developers.google.com/protocol-buffers/docs/proto) package name, while `protoPath` is a path to the `.proto` definitions file. The `hero.proto` file is structured using protocol buffer language.

hero.proto

TypeScript

```typescript

syntax = "proto3";

package hero;

service HeroService {
  rpc FindOne (HeroById) returns (Hero) {}
}

message HeroById {
  int32 id = 1;
}

message Hero {
  int32 id = 1;
  string name = 2;
}
```

In the above example, we defined a `HeroService` that exposes a `FindOne()` gRPC handler which expects `HeroById` as an input and returns a `Hero` message. In order to define a handler that fulfills this protobuf definition, we have to use a `@GrpcMethod()` decorator. The previously known `@MessagePattern()` is no longer useful.

hero.controller.ts

JS TS

TypeScript

```typescript

@GrpcMethod('HeroService', 'FindOne')
findOne(data: HeroById, metadata: any): Hero {
  const items = [
    { id: 1, name: 'John' },
    { id: 2, name: 'Doe' },
  ];
  return items.find(({ id }) => id === data.id);
}
```

TypeScript

```typescript

@GrpcMethod('HeroService', 'FindOne')
findOne(data, metadata) {
  const items = [
    { id: 1, name: 'John' },
    { id: 2, name: 'Doe' },
  ];
  return items.find(({ id }) => id === data.id);
}
```

> **Hint** The `@GrpcMethod()` decorator is imported from `@nestjs/microservices` package.

The `HeroService` is a service's name, while `FindOne` points to a `FindOne()` gRPC handler. The corresponding `findOne()` method takes two arguments, the `data` passed from the caller and `metadata` that stores gRPC request's metadata.

Furthermore, the `FindOne` is actually redundant here. If you don't pass a second argument to the `@GrpcMethod()`, Nest will automatically use the method name with the capitalized first letter, for example, `findOne` -> `FindOne`.

hero.controller.ts

JS TS

TypeScript

```typescript

@GrpcMethod('HeroService')
findOne(data: HeroById, metadata: any): Hero {
  const items = [
    { id: 1, name: 'John' },
    { id: 2, name: 'Doe' },
  ];
  return items.find(({ id }) => id === data.id);
}
```

TypeScript

```typescript

@GrpcMethod('HeroService')
findOne(data, metadata) {
  const items = [
    { id: 1, name: 'John' },
    { id: 2, name: 'Doe' },
  ];
  return items.find(({ id }) => id === data.id);
}
```

Likewise, you might not pass any argument. In this case, Nest would use a class name.

hero.controller.ts

JS TS

TypeScript

```typescript

@Controller()
export class HeroService {
  @GrpcMethod()
  findOne(data: HeroById, metadata: any): Hero {
    const items = [
      { id: 1, name: 'John' },
      { id: 2, name: 'Doe' },
    ];
    return items.find(({ id }) => id === data.id);
  }
}
```

TypeScript

```typescript

@Controller()
export class HeroService {
  @GrpcMethod()
  findOne(data, metadata) {
    const items = [
      { id: 1, name: 'John' },
      { id: 2, name: 'Doe' },
    ];
    return items.find(({ id }) => id === data.id);
  }
}
```

#### Client

In order to create a client instance, we need to make use of `@Client()` decorator.

hero.controller.ts

JS TS

TypeScript

```typescript

@Client({
  transport: Transport.GRPC,
  options: {
    package: 'hero',
    protoPath: join(__dirname, 'hero/hero.proto'),
  },
})
private readonly client: ClientGrpc;
```

TypeScript

```typescript

@Client({
  transport: Transport.GRPC,
  options: {
    package: 'hero',
    protoPath: join(__dirname, 'hero/hero.proto'),
  },
})
client;
```

There is a small difference compared to the previous examples. Instead of the `ClientProxy` class, we use the `ClientGrpc` that provides a `getService()` method. The `getService()` generic method takes service's name as an argument and returns its instance if available.

hero.controller.ts

JS TS

TypeScript

```typescript

onModuleInit() {
  this.heroService = this.client.getService<HeroService>('HeroService');
}
```

TypeScript

```typescript

onModuleInit() {
  this.heroService = this.client.getService('HeroService');
}
```

The `heroService` object exposes the same set of methods that have been defined inside `.proto` file. Note, all of them are **lowercased** (in order to follow the natural convention). Basically, our gRPC `HeroService` definition contains `FindOne()` function. It means that `heroService` instance will provide the `findOne()` method.

TypeScript

```typescript

interface HeroService {
  findOne(data: { id: number }): Observable<any>;
}
```

All service's methods return `Observable`. Since Nest supports [RxJS](https://github.com/reactivex/rxjs) streams and works pretty well with them, we can return them within HTTP handler as well.

hero.controller.ts

JS TS

TypeScript

```typescript

@Get()
call(): Observable<any> {
  return this.heroService.findOne({ id: 1 });
}
```

TypeScript

```typescript

@Get()
call() {
  return this.heroService.findOne({ id: 1 });
}
```

A full working example is available [here](https://github.com/nestjs/nest/tree/master/sample/04-grpc).

* gRPC
* Installation
* Transporter
* Options
* Overview

----
url: https://docs.nestjs.com/recipes/repl
----

[Skip to content](#content)

On this page

* [Read-Eval-Print-Loop (REPL)](https://docs.nestjs.com/recipes/repl#read-eval-print-loop-repl)
* [Usage](https://docs.nestjs.com/recipes/repl#usage)
* [Native functions](https://docs.nestjs.com/recipes/repl#native-functions)
* [Watch mode](https://docs.nestjs.com/recipes/repl#watch-mode)

### Read-Eval-Print-Loop (REPL)

A REPL is an interactive environment that takes single user inputs, executes them, and returns the result to the user. The REPL feature lets you inspect your dependency graph and call methods on your providers (and controllers) directly from your terminal.

#### Usage[#](/recipes/repl#usage)

To run your NestJS application in REPL mode, create a new `repl.ts` file (alongside the existing `main.ts` file) and add the following code:

repl.ts

JS TS

```typescript

import { repl } from '@nestjs/core';
import { AppModule } from './app.module.js';

async function bootstrap() {
  await repl(AppModule);
}
await bootstrap();
```

```typescript

import { repl } from '@nestjs/core';
import { AppModule } from './app.module.js';

async function bootstrap() {
  await repl(AppModule);
}
await bootstrap();
```

Then start the REPL from your terminal with the following command:

```bash

$ npm run start -- --entryFile repl
```

> **Hint** The `repl()` function returns a promise that resolves to a [Node.js REPL server](https://nodejs.org/api/repl.html) object. You can pass [Node.js REPL options](https://nodejs.org/api/repl.html#replstartoptions) as its second argument.

Once it's running, you should see the following messages in your console:

```bash

LOG [NestFactory] Starting Nest application...
LOG [InstanceLoader] AppModule dependencies initialized
LOG REPL initialized
```

You can now interact with your dependency graph. For instance, you can retrieve the `AppService` instance (this example uses the starter project) and call its `getHello()` method:

```typescript

> get(AppService).getHello()
'Hello World!'
```

You can execute any JavaScript code from your terminal. For example, you can assign the `AppController` instance to a local variable and use `await` to call an asynchronous method:

```typescript

> appController = get(AppController)
AppController { appService: AppService {} }
> await appController.getHello()
'Hello World!'
```

To display all public methods available on a given provider or controller, use the `methods()` function, as follows:

```typescript

> methods(AppController)

Methods:
 ◻ getHello
```

To print all registered modules as a list, together with their controllers and providers, use `debug()`:

```typescript

> debug()

AppModule:
 - controllers:
  ◻ AppController
 - providers:
  ◻ AppService
```

Here's a quick demo:

The following section describes the built-in native functions in more detail.

#### Native functions[#](/recipes/repl#native-functions)

The built-in NestJS REPL comes with a few native functions that are globally available when you start the REPL. Call `help()` to list them.

If you don't remember the signature (i.e., the expected parameters and return type) of a function, use `<function_name>.help`. For instance:

```text

> $.help
Retrieves an instance of either injectable or controller, otherwise, throws exception.
Interface: $(token: InjectionToken) => any
```

> **Hint** These function interfaces are written in [TypeScript function type expression syntax](https://www.typescriptlang.org/docs/handbook/2/functions.html#function-type-expressions).

| Function     | Description                                                                                                                                                             | Signature                                                             |
| ------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------- |
| `debug`      | Prints all registered modules as a list, together with their controllers and providers. Pass a module (e.g., `debug(MyModule)`) to print only that module's components. | `debug(moduleCls?: ClassRef \| string) => void`                       |
| `get` or `$` | Retrieves an instance of a provider or controller; throws an exception if it can't be found.                                                                            | `get(token: InjectionToken) => any`                                   |
| `help`       | Displays all available REPL native functions.                                                                                                                           | `help() => void`                                                      |
| `methods`    | Displays all public methods available on a given provider or controller.                                                                                                | `methods(token: ClassRef \| string) => void`                          |
| `resolve`    | Resolves a transient or request-scoped instance of a provider or controller; throws an exception if it can't be found.                                                  | `resolve(token: InjectionToken, contextId: any) => Promise<any>`      |
| `select`     | Navigates through the modules tree, for example, to pull out a specific instance from the selected module.                                                              | `select(token: DynamicModule \| ClassRef) => INestApplicationContext` |

#### Watch mode[#](/recipes/repl#watch-mode)

During development, it's useful to run the REPL in watch mode so that code changes are reflected automatically:

```bash

$ npm run start -- --watch --entryFile repl
```

The downside is that the REPL's command history is discarded after each reload. To preserve it, modify your `bootstrap()` function as follows:

```typescript

async function bootstrap() {
  const replServer = await repl(AppModule);
  replServer.setupHistory(".nestjs_repl_history", (err) => {
    if (err) {
      console.error(err);
    }
  });
}
```

The history is now preserved between runs and reloads.

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/recipes/repl.md)

----
url: https://docs.nestjs.com/v9/websockets/exception-filters
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Exception filters](https://docs.nestjs.com/v9/websockets/exception-filters#exception-filters)
* [Filters](https://docs.nestjs.com/v9/websockets/exception-filters#filters)
* [Inheritance](https://docs.nestjs.com/v9/websockets/exception-filters#inheritance)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/websockets/exception-filters.md "Suggest Edits")

### Exception filters

The only difference between the HTTP [exception filter](/v9/exception-filters) layer and the corresponding web sockets layer is that instead of throwing `HttpException`, you should use `WsException`.

```typescript

throw new WsException('Invalid credentials.');
```

> **Hint** The `WsException` class is imported from the `@nestjs/websockets` package.

With the sample above, Nest will handle the thrown exception and emit the `exception` message with the following structure:

```typescript

{
  status: 'error',
  message: 'Invalid credentials.'
}
```

#### Filters[#](/websockets/exception-filters#filters)

Web sockets exception filters behave equivalently to HTTP exception filters. The following example uses a manually instantiated method-scoped filter. Just as with HTTP based applications, you can also use gateway-scoped filters (i.e., prefix the gateway class with a `@UseFilters()` decorator).

```typescript

@UseFilters(new WsExceptionFilter())
@SubscribeMessage('events')
onEvent(client, data: any): WsResponse<any> {
  const event = 'events';
  return { event, data };
}
```

#### Inheritance[#](/websockets/exception-filters#inheritance)

Typically, you'll create fully customized exception filters crafted to fulfill your application requirements. However, there might be use-cases when you would like to simply extend the **core exception filter**, and override the behavior based on certain factors.

In order to delegate exception processing to the base filter, you need to extend `BaseWsExceptionFilter` and call the inherited `catch()` method.

JS TS

```typescript

import { Catch, ArgumentsHost } from '@nestjs/common';
import { BaseWsExceptionFilter } from '@nestjs/websockets';

@Catch()
export class AllExceptionsFilter extends BaseWsExceptionFilter {
  catch(exception: unknown, host: ArgumentsHost) {
    super.catch(exception, host);
  }
}
```

```typescript

import { Catch } from '@nestjs/common';
import { BaseWsExceptionFilter } from '@nestjs/websockets';

@Catch()
export class AllExceptionsFilter extends BaseWsExceptionFilter {
  catch(exception, host) {
    super.catch(exception, host);
  }
}
```

----
url: https://docs.nestjs.com/v9/recipes/hot-reload
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Hot Reload](https://docs.nestjs.com/v9/recipes/hot-reload#hot-reload)
* [With CLI](https://docs.nestjs.com/v9/recipes/hot-reload#with-cli)
* [Installation](https://docs.nestjs.com/v9/recipes/hot-reload#installation)
* [Configuration](https://docs.nestjs.com/v9/recipes/hot-reload#configuration)
* [Hot-Module Replacement](https://docs.nestjs.com/v9/recipes/hot-reload#hot-module-replacement)
* [Without CLI](https://docs.nestjs.com/v9/recipes/hot-reload#without-cli)
* [Installation](https://docs.nestjs.com/v9/recipes/hot-reload#installation-1)
* [Configuration](https://docs.nestjs.com/v9/recipes/hot-reload#configuration-1)
* [Hot-Module Replacement](https://docs.nestjs.com/v9/recipes/hot-reload#hot-module-replacement-1)
* [Example](https://docs.nestjs.com/v9/recipes/hot-reload#example)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/recipes/hot-reload.md "Suggest Edits")

### Hot Reload

The highest impact on your application's bootstrapping process is **TypeScript compilation**. Fortunately, with [webpack](https://github.com/webpack/webpack) HMR (Hot-Module Replacement), we don't need to recompile the entire project each time a change occurs. This significantly decreases the amount of time necessary to instantiate your application, and makes iterative development a lot easier.

> **Warning** Note that `webpack` won't automatically copy your assets (e.g. `graphql` files) to the `dist` folder. Similarly, `webpack` is not compatible with glob static paths (e.g., the `entities` property in `TypeOrmModule`).

### With CLI

If you are using the [Nest CLI](https://docs.nestjs.com/cli/overview), the configuration process is pretty straightforward. The CLI wraps `webpack`, which allows use of the `HotModuleReplacementPlugin`.

#### Installation[#](/recipes/hot-reload#installation)

First install the required packages:

```bash

$ npm i --save-dev webpack-node-externals run-script-webpack-plugin webpack
```

> **Hint** If you use **Yarn Berry** (not classic Yarn), install the `webpack-pnp-externals` package instead of the `webpack-node-externals`.

#### Configuration[#](/recipes/hot-reload#configuration)

Once the installation is complete, create a `webpack-hmr.config.js` file in the root directory of your application.

```typescript

const nodeExternals = require('webpack-node-externals');
const { RunScriptWebpackPlugin } = require('run-script-webpack-plugin');

module.exports = function (options, webpack) {
  return {
    ...options,
    entry: ['webpack/hot/poll?100', options.entry],
    externals: [
      nodeExternals({
        allowlist: ['webpack/hot/poll?100'],
      }),
    ],
    plugins: [
      ...options.plugins,
      new webpack.HotModuleReplacementPlugin(),
      new webpack.WatchIgnorePlugin({
        paths: [/\.js$/, /\.d\.ts$/],
      }),
      new RunScriptWebpackPlugin({ name: options.output.filename, autoRestart: false }),
    ],
  };
};
```

> **Hint** With **Yarn Berry** (not classic Yarn), instead of using the `nodeExternals` in the `externals` configuration property, use the `WebpackPnpExternals` from `webpack-pnp-externals` package: `WebpackPnpExternals({ exclude: ['webpack/hot/poll?100'] })`.

This function takes the original object containing the default webpack configuration as a first argument, and the reference to the underlying `webpack` package used by the Nest CLI as the second one. Also, it returns a modified webpack configuration with the `HotModuleReplacementPlugin`, `WatchIgnorePlugin`, and `RunScriptWebpackPlugin` plugins.

#### Hot-Module Replacement[#](/recipes/hot-reload#hot-module-replacement)

To enable **HMR**, open the application entry file (`main.ts`) and add the following webpack-related instructions:

```typescript

declare const module: any;

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  await app.listen(3000);

  if (module.hot) {
    module.hot.accept();
    module.hot.dispose(() => app.close());
  }
}
bootstrap();
```

To simplify the execution process, add a script to your `package.json` file.

```json

"start:dev": "nest build --webpack --webpackPath webpack-hmr.config.js --watch"
```

Now simply open your command line and run the following command:

```bash

$ npm run start:dev
```

### Without CLI

If you are not using the [Nest CLI](https://docs.nestjs.com/cli/overview), the configuration will be slightly more complex (will require more manual steps).

#### Installation[#](/recipes/hot-reload#installation-1)

First install the required packages:

```bash

$ npm i --save-dev webpack webpack-cli webpack-node-externals ts-loader run-script-webpack-plugin
```

> **Hint** If you use **Yarn Berry** (not classic Yarn), install the `webpack-pnp-externals` package instead of the `webpack-node-externals`.

#### Configuration[#](/recipes/hot-reload#configuration-1)

Once the installation is complete, create a `webpack.config.js` file in the root directory of your application.

```typescript

const webpack = require('webpack');
const path = require('path');
const nodeExternals = require('webpack-node-externals');
const { RunScriptWebpackPlugin } = require('run-script-webpack-plugin');

module.exports = {
  entry: ['webpack/hot/poll?100', './src/main.ts'],
  target: 'node',
  externals: [
    nodeExternals({
      allowlist: ['webpack/hot/poll?100'],
    }),
  ],
  module: {
    rules: [
      {
        test: /.tsx?$/,
        use: 'ts-loader',
        exclude: /node_modules/,
      },
    ],
  },
  mode: 'development',
  resolve: {
    extensions: ['.tsx', '.ts', '.js'],
  },
  plugins: [
    new webpack.HotModuleReplacementPlugin(),
    new RunScriptWebpackPlugin({ name: 'server.js', autoRestart: false }),
  ],
  output: {
    path: path.join(__dirname, 'dist'),
    filename: 'server.js',
  },
};
```

> **Hint** With **Yarn Berry** (not classic Yarn), instead of using the `nodeExternals` in the `externals` configuration property, use the `WebpackPnpExternals` from `webpack-pnp-externals` package: `WebpackPnpExternals({ exclude: ['webpack/hot/poll?100'] })`.

This configuration tells webpack a few essential things about your application: location of the entry file, which directory should be used to hold **compiled** files, and what kind of loader we want to use to compile source files. Generally, you should be able to use this file as-is, even if you don't fully understand all of the options.

#### Hot-Module Replacement[#](/recipes/hot-reload#hot-module-replacement-1)

To enable **HMR**, open the application entry file (`main.ts`) and add the following webpack-related instructions:

```typescript

declare const module: any;

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  await app.listen(3000);

  if (module.hot) {
    module.hot.accept();
    module.hot.dispose(() => app.close());
  }
}
bootstrap();
```

To simplify the execution process, add a script to your `package.json` file.

```json

"start:dev": "webpack --config webpack.config.js --watch"
```

Now simply open your command line and run the following command:

```bash

$ npm run start:dev
```

#### Example[#](/recipes/hot-reload#example)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/08-webpack).

----
url: https://docs.nestjs.com/v11/interceptors
----

* [Interceptors](https://docs.nestjs.com/v11/interceptors#interceptors)
* [Basics](https://docs.nestjs.com/v11/interceptors#basics)
* [Execution context](https://docs.nestjs.com/v11/interceptors#execution-context)
* [Call handler](https://docs.nestjs.com/v11/interceptors#call-handler)
* [Aspect interception](https://docs.nestjs.com/v11/interceptors#aspect-interception)
* [Binding interceptors](https://docs.nestjs.com/v11/interceptors#binding-interceptors)
* [Response mapping](https://docs.nestjs.com/v11/interceptors#response-mapping)
* [Exception mapping](https://docs.nestjs.com/v11/interceptors#exception-mapping)
* [Stream overriding](https://docs.nestjs.com/v11/interceptors#stream-overriding)
* [More operators](https://docs.nestjs.com/v11/interceptors#more-operators)

Each interceptor implements the `intercept()` method, which takes two arguments. The first one is the `ExecutionContext` instance (exactly the same object as for [guards](/v11/guards)). The `ExecutionContext` inherits from `ArgumentsHost`. We saw `ArgumentsHost` before in the exception filters chapter. There, we saw that it's a wrapper around arguments that have been passed to the original handler, and contains different arguments arrays based on the type of the application. You can refer back to the [exception filters](https://docs.nestjs.com/exception-filters#arguments-host) for more on this topic.

#### Execution context[#](/interceptors#execution-context)

By extending `ArgumentsHost`, `ExecutionContext` also adds several new helper methods that provide additional details about the current execution process. These details can be helpful in building more generic interceptors that can work across a broad set of controllers, methods, and execution contexts. Learn more about `ExecutionContext`[here](/v11/fundamentals/execution-context).

```typescript

import { Injectable, NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
import { Observable } from 'rxjs';
import { tap } from 'rxjs/operators';

@Injectable()
export class LoggingInterceptor implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    console.log('Before...');

    const now = Date.now();
    return next
      .handle()
      .pipe(
        tap(() => console.log(`After... ${Date.now() - now}ms`)),
      );
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';
import { Observable } from 'rxjs';
import { tap } from 'rxjs/operators';

@Injectable()
export class LoggingInterceptor {
  intercept(context, next) {
    console.log('Before...');

    const now = Date.now();
    return next
      .handle()
      .pipe(
        tap(() => console.log(`After... ${Date.now() - now}ms`)),
      );
  }
}
```

> **Hint** The `NestInterceptor<T, R>` is a generic interface in which `T` indicates the type of an `Observable<T>` (supporting the response stream), and `R` is the type of the value wrapped by `Observable<R>`.

> **Notice** Interceptors, like controllers, providers, guards, and so on, can **inject dependencies** through their `constructor`.

Since `handle()` returns an RxJS `Observable`, we have a wide choice of operators we can use to manipulate the stream. In the example above, we used the `tap()` operator, which invokes our anonymous logging function upon graceful or exceptional termination of the observable stream, but doesn't otherwise interfere with the response cycle.

#### Binding interceptors[#](/interceptors#binding-interceptors)

In order to set up the interceptor, we use the `@UseInterceptors()` decorator imported from the `@nestjs/common` package. Like [pipes](/v11/pipes) and [guards](/v11/guards), interceptors can be controller-scoped, method-scoped, or global-scoped.

cats.controller.ts

JS TS

```typescript

@UseInterceptors(LoggingInterceptor)
export class CatsController {}
```

> **Hint** The `@UseInterceptors()` decorator is imported from the `@nestjs/common` package.

Using the above construction, each route handler defined in `CatsController` will use `LoggingInterceptor`. When someone calls the `GET /cats` endpoint, you'll see the following output in your standard output:

```typescript

Before...
After... 1ms
```

Note that we passed the `LoggingInterceptor` class (instead of an instance), leaving responsibility for instantiation to the framework and enabling dependency injection. As with pipes, guards, and exception filters, we can also pass an in-place instance:

cats.controller.ts

JS TS

```typescript

@UseInterceptors(new LoggingInterceptor())
export class CatsController {}
```

As mentioned, the construction above attaches the interceptor to every handler declared by this controller. If we want to restrict the interceptor's scope to a single method, we simply apply the decorator at the **method level**.

In order to set up a global interceptor, we use the `useGlobalInterceptors()` method of the Nest application instance:

```typescript

const app = await NestFactory.create(AppModule);
app.useGlobalInterceptors(new LoggingInterceptor());
```

Global interceptors are used across the whole application, for every controller and every route handler. In terms of dependency injection, global interceptors registered from outside of any module (with `useGlobalInterceptors()`, as in the example above) cannot inject dependencies since this is done outside the context of any module. In order to solve this issue, you can set up an interceptor **directly from any module** using the following construction:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { APP_INTERCEPTOR } from '@nestjs/core';

@Module({
  providers: [
    {
      provide: APP_INTERCEPTOR,
      useClass: LoggingInterceptor,
    },
  ],
})
export class AppModule {}
```

> **Hint** When using this approach to perform dependency injection for the interceptor, note that regardless of the module where this construction is employed, the interceptor is, in fact, global. Where should this be done? Choose the module where the interceptor (`LoggingInterceptor` in the example above) is defined. Also, `useClass` is not the only way of dealing with custom provider registration. Learn more [here](/v11/fundamentals/custom-providers).

#### Response mapping[#](/interceptors#response-mapping)

We already know that `handle()` returns an `Observable`. The stream contains the value **returned** from the route handler, and thus we can easily mutate it using RxJS's `map()` operator.

> **Warning** The response mapping feature doesn't work with the library-specific response strategy (using the `@Res()` object directly is forbidden).

Let's create the `TransformInterceptor`, which will modify each response in a trivial way to demonstrate the process. It will use RxJS's `map()` operator to assign the response object to the `data` property of a newly created object, returning the new object to the client.

transform.interceptor.ts

JS TS

```typescript

import { Injectable, NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';

export interface Response<T> {
  data: T;
}

@Injectable()
export class TransformInterceptor<T> implements NestInterceptor<T, Response<T>> {
  intercept(context: ExecutionContext, next: CallHandler): Observable<Response<T>> {
    return next.handle().pipe(map(data => ({ data })));
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';
import { map } from 'rxjs/operators';

@Injectable()
export class TransformInterceptor {
  intercept(context, next) {
    return next.handle().pipe(map(data => ({ data })));
  }
}
```

> **Hint** Nest interceptors work with both synchronous and asynchronous `intercept()` methods. You can simply switch the method to `async` if necessary.

With the above construction, when someone calls the `GET /cats` endpoint, the response would look like the following (assuming that route handler returns an empty array `[]`):

```json

{
  "data": []
}
```

Interceptors have great value in creating re-usable solutions to requirements that occur across an entire application. For example, imagine we need to transform each occurrence of a `null` value to an empty string `''`. We can do it using one line of code and bind the interceptor globally so that it will automatically be used by each registered handler.

JS TS

```typescript

import { Injectable, NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';

@Injectable()
export class ExcludeNullInterceptor implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    return next
      .handle()
      .pipe(map(value => value === null ? '' : value ));
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';
import { map } from 'rxjs/operators';

@Injectable()
export class ExcludeNullInterceptor {
  intercept(context, next) {
    return next
      .handle()
      .pipe(map(value => value === null ? '' : value ));
  }
}
```

#### Exception mapping[#](/interceptors#exception-mapping)

Another interesting use-case is to take advantage of RxJS's `catchError()` operator to override thrown exceptions:

errors.interceptor.ts

JS TS

```typescript

import {
  Injectable,
  NestInterceptor,
  ExecutionContext,
  BadGatewayException,
  CallHandler,
} from '@nestjs/common';
import { Observable, throwError } from 'rxjs';
import { catchError } from 'rxjs/operators';

@Injectable()
export class ErrorsInterceptor implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    return next
      .handle()
      .pipe(
        catchError(err => throwError(() => new BadGatewayException())),
      );
  }
}
```

```typescript

import { Injectable, BadGatewayException } from '@nestjs/common';
import { throwError } from 'rxjs';
import { catchError } from 'rxjs/operators';

@Injectable()
export class ErrorsInterceptor {
  intercept(context, next) {
    return next
      .handle()
      .pipe(
        catchError(err => throwError(() => new BadGatewayException())),
      );
  }
}
```

#### Stream overriding[#](/interceptors#stream-overriding)

There are several reasons why we may sometimes want to completely prevent calling the handler and return a different value instead. An obvious example is to implement a cache to improve response time. Let's take a look at a simple **cache interceptor** that returns its response from a cache. In a realistic example, we'd want to consider other factors like TTL, cache invalidation, cache size, etc., but that's beyond the scope of this discussion. Here we'll provide a basic example that demonstrates the main concept.

cache.interceptor.ts

JS TS

```typescript

import { Injectable, NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
import { Observable, of } from 'rxjs';

@Injectable()
export class CacheInterceptor implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    const isCached = true;
    if (isCached) {
      return of([]);
    }
    return next.handle();
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';
import { of } from 'rxjs';

@Injectable()
export class CacheInterceptor {
  intercept(context, next) {
    const isCached = true;
    if (isCached) {
      return of([]);
    }
    return next.handle();
  }
}
```

Our `CacheInterceptor` has a hardcoded `isCached` variable and a hardcoded response `[]` as well. The key point to note is that we return a new stream here, created by the RxJS `of()` operator, therefore the route handler **won't be called** at all. When someone calls an endpoint that makes use of `CacheInterceptor`, the response (a hardcoded, empty array) will be returned immediately. In order to create a generic solution, you can take advantage of `Reflector` and create a custom decorator. The `Reflector` is well described in the [guards](/v11/guards) chapter.

#### More operators[#](/interceptors#more-operators)

The possibility of manipulating the stream using RxJS operators gives us many capabilities. Let's consider another common use case. Imagine you would like to handle **timeouts** on route requests. When your endpoint doesn't return anything after a period of time, you want to terminate with an error response. The following construction enables this:

timeout.interceptor.ts

JS TS

```typescript

import { Injectable, NestInterceptor, ExecutionContext, CallHandler, RequestTimeoutException } from '@nestjs/common';
import { Observable, throwError, TimeoutError } from 'rxjs';
import { catchError, timeout } from 'rxjs/operators';

@Injectable()
export class TimeoutInterceptor implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    return next.handle().pipe(
      timeout(5000),
      catchError(err => {
        if (err instanceof TimeoutError) {
          return throwError(() => new RequestTimeoutException());
        }
        return throwError(() => err);
      }),
    );
  };
};
```

```typescript

import { Injectable, RequestTimeoutException } from '@nestjs/common';
import { Observable, throwError, TimeoutError } from 'rxjs';
import { catchError, timeout } from 'rxjs/operators';

@Injectable()
export class TimeoutInterceptor {
  intercept(context, next) {
    return next.handle().pipe(
      timeout(5000),
      catchError(err => {
        if (err instanceof TimeoutError) {
          return throwError(() => new RequestTimeoutException());
        }
        return throwError(() => err);
      }),
    );
  };
};
```

After 5 seconds, request processing will be canceled. You can also add custom logic before throwing `RequestTimeoutException` (e.g. release resources).

----
url: https://docs.nestjs.com/v5/graphql/mutations
----

### Mutations

In GraphQL, in order to modify the server-side data, we use mutations (read more [here](http://graphql.org/learn/queries/#mutations))a. The official [Apollo](https://www.apollographql.com/docs/graphql-tools/generate-schema.html) documentation shares an `upvotePost()` mutation example. This mutation allows to increase a post `votes` property value. In order to create an equivalent mutation in Nest, we'll make use of the `@Mutation()` decorator. Let's extend our `AuthorResolver` used in the previous section (see [resolvers](/v5/graphql/resolvers-map)).

TypeScript

```typescript

@Resolver('Author')
export class AuthorResolver {
  constructor(
    private readonly authorsService: AuthorsService,
    private readonly postsService: PostsService,
  ) {}

  @Query('author')
  async getAuthor(@Args('id') id: number) {
    return await this.authorsService.findOneById(id);
  }

  @Mutation()
  async upvotePost(@Args('postId') postId: number) {
    return await this.postsService.upvoteById({ id: postId });
  }

  @ResolveProperty('posts')
  async getPosts(@Parent() { id }) {
    return await this.postsService.findAll({ authorId: id });
  }
}
```

Notice that we've assumed that the business logic has been moved to the `PostsService` (respectively querying post and incrementing `votes` property).

#### Type definitions

The last step is to add our mutation to the existing types definition.

Java

```java

type Author {
  id: Int!
  firstName: String
  lastName: String
  posts: [Post]
}

type Post {
  id: Int!
  title: String
  votes: Int
}

type Query {
  author(id: Int!): Author
}

type Mutation {
  upvotePost(postId: Int!): Post
}
```

The `upvotePost(postId: Int!): Post` mutation should be available now.

* Mutations

----
url: https://docs.nestjs.com/v8/graphql/subscriptions
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Subscriptions](https://docs.nestjs.com/v8/graphql/subscriptions#subscriptions)
* [Enable subscriptions with Apollo driver](https://docs.nestjs.com/v8/graphql/subscriptions#enable-subscriptions-with-apollo-driver)
* [Code first](https://docs.nestjs.com/v8/graphql/subscriptions#code-first)
* [Publishing](https://docs.nestjs.com/v8/graphql/subscriptions#publishing)
* [Filtering subscriptions](https://docs.nestjs.com/v8/graphql/subscriptions#filtering-subscriptions)
* [Mutating subscription payloads](https://docs.nestjs.com/v8/graphql/subscriptions#mutating-subscription-payloads)
* [Schema first](https://docs.nestjs.com/v8/graphql/subscriptions#schema-first)
* [PubSub](https://docs.nestjs.com/v8/graphql/subscriptions#pubsub)
* [Customize subscriptions server](https://docs.nestjs.com/v8/graphql/subscriptions#customize-subscriptions-server)
* [Authentication over WebSockets](https://docs.nestjs.com/v8/graphql/subscriptions#authentication-over-websockets)
* [Enable subscriptions with Mercurius driver](https://docs.nestjs.com/v8/graphql/subscriptions#enable-subscriptions-with-mercurius-driver)
* [Code first](https://docs.nestjs.com/v8/graphql/subscriptions#code-first-1)
* [Publishing](https://docs.nestjs.com/v8/graphql/subscriptions#publishing-1)
* [Filtering subscriptions](https://docs.nestjs.com/v8/graphql/subscriptions#filtering-subscriptions-1)
* [Schema first](https://docs.nestjs.com/v8/graphql/subscriptions#schema-first-1)
* [PubSub](https://docs.nestjs.com/v8/graphql/subscriptions#pubsub-1)
* [Authentication over WebSockets](https://docs.nestjs.com/v8/graphql/subscriptions#authentication-over-websockets-1)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/subscriptions.md "Suggest Edits")

### Subscriptions

In addition to fetching data using queries and modifying data using mutations, the GraphQL spec supports a third operation type, called `subscription`. GraphQL subscriptions are a way to push data from the server to the clients that choose to listen to real time messages from the server. Subscriptions are similar to queries in that they specify a set of fields to be delivered to the client, but instead of immediately returning a single answer, a channel is opened and a result is sent to the client every time a particular event happens on the server.

A common use case for subscriptions is notifying the client side about particular events, for example the creation of a new object, updated fields and so on (read more [here](https://www.apollographql.com/docs/react/data/subscriptions)).

#### Enable subscriptions with Apollo driver[#](/graphql/subscriptions#enable-subscriptions-with-apollo-driver)

To enable subscriptions, set the `installSubscriptionHandlers` property to `true`.

```typescript

GraphQLModule.forRoot<ApolloDriverConfig>({
  driver: ApolloDriver,
  installSubscriptionHandlers: true,
}),
```

> **Warning** The `installSubscriptionHandlers` configuration option has been removed from the latest version of Apollo server and will be soon deprecated in this package as well. By default, `installSubscriptionHandlers` will fallback to use the `subscriptions-transport-ws` ([read more](https://github.com/apollographql/subscriptions-transport-ws)) but we strongly recommend using the `graphql-ws`([read more](https://github.com/enisdenjo/graphql-ws)) library instead.

To switch to use the `graphql-ws` package instead, use the following configuration:

```typescript

GraphQLModule.forRoot<ApolloDriverConfig>({
  driver: ApolloDriver,
  subscriptions: {
    'graphql-ws': true
  },
}),
```

> **Hint** You can also use both packages (`subscriptions-transport-ws` and `graphql-ws`) at the same time, for example, for backward compatibility.

#### Code first[#](/graphql/subscriptions#code-first)

To create a subscription using the code first approach, we use the `@Subscription()` decorator (exported from the `@nestjs/graphql` package) and the `PubSub` class from the `graphql-subscriptions` package, which provides a simple **publish/subscribe API**.

The following subscription handler takes care of **subscribing** to an event by calling `PubSub#asyncIterator`. This method takes a single argument, the `triggerName`, which corresponds to an event topic name.

```typescript

const pubSub = new PubSub();

@Resolver((of) => Author)
export class AuthorResolver {
  // ...
  @Subscription((returns) => Comment)
  commentAdded() {
    return pubSub.asyncIterator('commentAdded');
  }
}
```

> **Hint** All decorators are exported from the `@nestjs/graphql` package, while the `PubSub` class is exported from the `graphql-subscriptions` package.

> **Note**`PubSub` is a class that exposes a simple `publish` and `subscribe API`. Read more about it [here](https://www.apollographql.com/docs/graphql-subscriptions/setup.html). Note that the Apollo docs warn that the default implementation is not suitable for production (read more [here](https://github.com/apollographql/graphql-subscriptions#getting-started-with-your-first-subscription)). Production apps should use a `PubSub` implementation backed by an external store (read more [here](https://github.com/apollographql/graphql-subscriptions#pubsub-implementations)).

This will result in generating the following part of the GraphQL schema in SDL:

```graphql

type Subscription {
  commentAdded(): Comment!
}
```

Note that subscriptions, by definition, return an object with a single top level property whose key is the name of the subscription. This name is either inherited from the name of the subscription handler method (i.e., `commentAdded` above), or is provided explicitly by passing an option with the key `name` as the second argument to the `@Subscription()` decorator, as shown below.

```typescript

@Subscription(returns => Comment, {
  name: 'commentAdded',
})
subscribeToCommentAdded() {
  return pubSub.asyncIterator('commentAdded');
}
```

This construct produces the same SDL as the previous code sample, but allows us to decouple the method name from the subscription.

#### Publishing[#](/graphql/subscriptions#publishing)

Now, to publish the event, we use the `PubSub#publish` method. This is often used within a mutation to trigger a client-side update when a part of the object graph has changed. For example:

posts/posts.resolver.ts

JS TS

```typescript

@Mutation(returns => Post)
async addComment(
  @Args('postId', { type: () => Int }) postId: number,
  @Args('comment', { type: () => Comment }) comment: CommentInput,
) {
  const newComment = this.commentsService.addComment({ id: postId, comment });
  pubSub.publish('commentAdded', { commentAdded: newComment });
  return newComment;
}
```

The `PubSub#publish` method takes a `triggerName` (again, think of this as an event topic name) as the first parameter, and an event payload as the second parameter. As mentioned, the subscription, by definition, returns a value and that value has a shape. Look again at the generated SDL for our `commentAdded` subscription:

```graphql

type Subscription {
  commentAdded(): Comment!
}
```

This tells us that the subscription must return an object with a top-level property name of `commentAdded` that has a value which is a `Comment` object. The important point to note is that the shape of the event payload emitted by the `PubSub#publish` method must correspond to the shape of the value expected to return from the subscription. So, in our example above, the `pubSub.publish('commentAdded', { commentAdded: newComment })` statement publishes a `commentAdded` event with the appropriately shaped payload. If these shapes don't match, your subscription will fail during the GraphQL validation phase.

#### Filtering subscriptions[#](/graphql/subscriptions#filtering-subscriptions)

To filter out specific events, set the `filter` property to a filter function. This function acts similar to the function passed to an array `filter`. It takes two arguments: `payload` containing the event payload (as sent by the event publisher), and `variables` taking any arguments passed in during the subscription request. It returns a boolean determining whether this event should be published to client listeners.

```typescript

@Subscription(returns => Comment, {
  filter: (payload, variables) =>
    payload.commentAdded.title === variables.title,
})
commentAdded(@Args('title') title: string) {
  return pubSub.asyncIterator('commentAdded');
}
```

#### Mutating subscription payloads[#](/graphql/subscriptions#mutating-subscription-payloads)

To mutate the published event payload, set the `resolve` property to a function. The function receives the event payload (as sent by the event publisher) and returns the appropriate value.

```typescript

@Subscription(returns => Comment, {
  resolve: value => value,
})
commentAdded() {
  return pubSub.asyncIterator('commentAdded');
}
```

> **Note** If you use the `resolve` option, you should return the unwrapped payload (e.g., with our example, return a `newComment` object directly, not a `{ commentAdded: newComment }` object).

If you need to access injected providers (e.g., use an external service to validate the data), use the following construction.

```typescript

@Subscription(returns => Comment, {
  resolve(this: AuthorResolver, value) {
    // "this" refers to an instance of "AuthorResolver"
    return value;
  }
})
commentAdded() {
  return pubSub.asyncIterator('commentAdded');
}
```

The same construction works with filters:

```typescript

@Subscription(returns => Comment, {
  filter(this: AuthorResolver, payload, variables) {
    // "this" refers to an instance of "AuthorResolver"
    return payload.commentAdded.title === variables.title;
  }
})
commentAdded() {
  return pubSub.asyncIterator('commentAdded');
}
```

#### Schema first[#](/graphql/subscriptions#schema-first)

To create an equivalent subscription in Nest, we'll make use of the `@Subscription()` decorator.

```typescript

const pubSub = new PubSub();

@Resolver('Author')
export class AuthorResolver {
  // ...
  @Subscription()
  commentAdded() {
    return pubSub.asyncIterator('commentAdded');
  }
}
```

To filter out specific events based on context and arguments, set the `filter` property.

```typescript

@Subscription('commentAdded', {
  filter: (payload, variables) =>
    payload.commentAdded.title === variables.title,
})
commentAdded() {
  return pubSub.asyncIterator('commentAdded');
}
```

To mutate the published payload, we can use a `resolve` function.

```typescript

@Subscription('commentAdded', {
  resolve: value => value,
})
commentAdded() {
  return pubSub.asyncIterator('commentAdded');
}
```

If you need to access injected providers (e.g., use an external service to validate the data), use the following construction:

```typescript

@Subscription('commentAdded', {
  resolve(this: AuthorResolver, value) {
    // "this" refers to an instance of "AuthorResolver"
    return value;
  }
})
commentAdded() {
  return pubSub.asyncIterator('commentAdded');
}
```

The same construction works with filters:

```typescript

@Subscription('commentAdded', {
  filter(this: AuthorResolver, payload, variables) {
    // "this" refers to an instance of "AuthorResolver"
    return payload.commentAdded.title === variables.title;
  }
})
commentAdded() {
  return pubSub.asyncIterator('commentAdded');
}
```

The last step is to update the type definitions file.

```graphql

type Author {
  id: Int!
  firstName: String
  lastName: String
  posts: [Post]
}

type Post {
  id: Int!
  title: String
  votes: Int
}

type Query {
  author(id: Int!): Author
}

type Comment {
  id: String
  content: String
}

type Subscription {
  commentAdded(title: String!): Comment
}
```

With this, we've created a single `commentAdded(title: String!): Comment` subscription. You can find a full sample implementation [here](https://github.com/nestjs/nest/blob/master/sample/12-graphql-schema-first).

#### PubSub[#](/graphql/subscriptions#pubsub)

We instantiated a local `PubSub` instance above. The preferred approach is to define `PubSub` as a [provider](/v8/fundamentals/custom-providers) and inject it through the constructor (using the `@Inject()` decorator). This allows us to re-use the instance across the whole application. For example, define a provider as follows, then inject `'PUB_SUB'` where needed.

```typescript

{
  provide: 'PUB_SUB',
  useValue: new PubSub(),
}
```

#### Customize subscriptions server[#](/graphql/subscriptions#customize-subscriptions-server)

To customize the subscriptions server (e.g., change the path), use the `subscriptions` options property.

```typescript

GraphQLModule.forRoot<ApolloDriverConfig>({
  driver: ApolloDriver,
  subscriptions: {
    'subscriptions-transport-ws': {
      path: '/graphql'
    },
  }
}),
```

If you're using the `graphql-ws` package for subscriptions, replace the `subscriptions-transport-ws` key with `graphql-ws`, as follows:

```typescript

GraphQLModule.forRoot<ApolloDriverConfig>({
  driver: ApolloDriver,
  subscriptions: {
    'graphql-ws': {
      path: '/graphql'
    },
  }
}),
```

#### Authentication over WebSockets[#](/graphql/subscriptions#authentication-over-websockets)

Checking whether the user is authenticated can be done inside the `onConnect` callback function that you can specify in the `subscriptions` options.

The `onConnect` will receive as a first argument the `connectionParams` passed to the `SubscriptionClient` (read [more](https://www.apollographql.com/docs/react/data/subscriptions/#5-authenticate-over-websocket-optional)).

```typescript

GraphQLModule.forRoot<ApolloDriverConfig>({
  driver: ApolloDriver,
  subscriptions: {
    'subscriptions-transport-ws': {
      onConnect: (connectionParams) => {
        const authToken = connectionParams.authToken;
        if (!isValid(authToken)) {
          throw new Error('Token is not valid');
        }
        // extract user information from token
        const user = parseToken(authToken);
        // return user info to add them to the context later
        return { user };
      },
    }
  },
  context: ({ connection }) => {
    // connection.context will be equal to what was returned by the "onConnect" callback
  },
}),
```

The `authToken` in this example is only sent once by the client, when the connection is first established. All subscriptions made with this connection will have the same `authToken`, and thus the same user info.

> **Note** There is a bug in `subscriptions-transport-ws` that allows connections to skip the `onConnect` phase (read [more](https://github.com/apollographql/subscriptions-transport-ws/issues/349)). You should not assume that `onConnect` was called when the user starts a subscription, and always check that the `context` is populated.

If you're using the `graphql-ws` package, the signature of the `onConnect` callback will be slightly different:

```typescript

GraphQLModule.forRoot<ApolloDriverConfig>({
  driver: ApolloDriver,
  subscriptions: {
    'graphql-ws': {
      onConnect: (context: Context<any>) => {
        const { connectionParams, extra } = context;
        // user validation will remain the same as in the example above
        // when using with graphql-ws, additional context value should be stored in the extra field
        extra.user = { user: {} };
      },
    },
  },
  context: ({ extra }) => {
    // you can now access your additional context value through the extra field
  },
});
```

#### Enable subscriptions with Mercurius driver[#](/graphql/subscriptions#enable-subscriptions-with-mercurius-driver)

To enable subscriptions, set the `subscription` property to `true`.

```typescript

GraphQLModule.forRoot<MercuriusDriverConfig>({
  driver: MercuriusDriver,
  subscription: true,
}),
```

> **Hint** You can also pass the options object to set up a custom emitter, validate incoming connections, etc. Read more [here](https://github.com/mercurius-js/mercurius/blob/master/docs/api/options.md#plugin-options) (see `subscription`).

#### Code first[#](/graphql/subscriptions#code-first-1)

To create a subscription using the code first approach, we use the `@Subscription()` decorator (exported from the `@nestjs/graphql` package) and the `PubSub` class from the `mercurius` package, which provides a simple **publish/subscribe API**.

The following subscription handler takes care of **subscribing** to an event by calling `PubSub#asyncIterator`. This method takes a single argument, the `triggerName`, which corresponds to an event topic name.

```typescript

@Resolver((of) => Author)
export class AuthorResolver {
  // ...
  @Subscription((returns) => Comment)
  commentAdded(@Context('pubsub') pubSub: PubSub) {
    return pubSub.subscribe('commentAdded');
  }
}
```

> **Hint** All decorators used in the example above are exported from the `@nestjs/graphql` package, while the `PubSub` class is exported from the `mercurius` package.

> **Note**`PubSub` is a class that exposes a simple `publish` and `subscribe` API. Check out [this section](https://github.com/mercurius-js/mercurius/blob/master/docs/subscriptions.md#subscriptions-with-custom-pubsub) on how to register a custom `PubSub` class.

This will result in generating the following part of the GraphQL schema in SDL:

```graphql

type Subscription {
  commentAdded(): Comment!
}
```

Note that subscriptions, by definition, return an object with a single top level property whose key is the name of the subscription. This name is either inherited from the name of the subscription handler method (i.e., `commentAdded` above), or is provided explicitly by passing an option with the key `name` as the second argument to the `@Subscription()` decorator, as shown below.

```typescript

@Subscription(returns => Comment, {
  name: 'commentAdded',
})
subscribeToCommentAdded(@Context('pubsub') pubSub: PubSub) {
  return pubSub.subscribe('commentAdded');
}
```

This construct produces the same SDL as the previous code sample, but allows us to decouple the method name from the subscription.

#### Publishing[#](/graphql/subscriptions#publishing-1)

Now, to publish the event, we use the `PubSub#publish` method. This is often used within a mutation to trigger a client-side update when a part of the object graph has changed. For example:

posts/posts.resolver.ts

JS TS

```typescript

@Mutation(returns => Post)
async addComment(
  @Args('postId', { type: () => Int }) postId: number,
  @Args('comment', { type: () => Comment }) comment: CommentInput,
  @Context('pubsub') pubSub: PubSub,
) {
  const newComment = this.commentsService.addComment({ id: postId, comment });
  await pubSub.publish({
    topic: 'commentAdded',
    payload: {
      commentAdded: newComment
    }
  });
  return newComment;
}
```

As mentioned, the subscription, by definition, returns a value and that value has a shape. Look again at the generated SDL for our `commentAdded` subscription:

```graphql

type Subscription {
  commentAdded(): Comment!
}
```

This tells us that the subscription must return an object with a top-level property name of `commentAdded` that has a value which is a `Comment` object. The important point to note is that the shape of the event payload emitted by the `PubSub#publish` method must correspond to the shape of the value expected to return from the subscription. So, in our example above, the `pubSub.publish({ topic: 'commentAdded', payload: { commentAdded: newComment } })` statement publishes a `commentAdded` event with the appropriately shaped payload. If these shapes don't match, your subscription will fail during the GraphQL validation phase.

#### Filtering subscriptions[#](/graphql/subscriptions#filtering-subscriptions-1)

To filter out specific events, set the `filter` property to a filter function. This function acts similar to the function passed to an array `filter`. It takes two arguments: `payload` containing the event payload (as sent by the event publisher), and `variables` taking any arguments passed in during the subscription request. It returns a boolean determining whether this event should be published to client listeners.

```typescript

@Subscription(returns => Comment, {
  filter: (payload, variables) =>
    payload.commentAdded.title === variables.title,
})
commentAdded(@Args('title') title: string, @Context('pubsub') pubSub: PubSub) {
  return pubSub.subscribe('commentAdded');
}
```

If you need to access injected providers (e.g., use an external service to validate the data), use the following construction.

```typescript

@Subscription(returns => Comment, {
  filter(this: AuthorResolver, payload, variables) {
    // "this" refers to an instance of "AuthorResolver"
    return payload.commentAdded.title === variables.title;
  }
})
commentAdded(@Args('title') title: string, @Context('pubsub') pubSub: PubSub) {
  return pubSub.subscribe('commentAdded');
}
```

#### Schema first[#](/graphql/subscriptions#schema-first-1)

To create an equivalent subscription in Nest, we'll make use of the `@Subscription()` decorator.

```typescript

const pubSub = new PubSub();

@Resolver('Author')
export class AuthorResolver {
  // ...
  @Subscription()
  commentAdded(@Context('pubsub') pubSub: PubSub) {
    return pubSub.subscribe('commentAdded');
  }
}
```

To filter out specific events based on context and arguments, set the `filter` property.

```typescript

@Subscription('commentAdded', {
  filter: (payload, variables) =>
    payload.commentAdded.title === variables.title,
})
commentAdded(@Context('pubsub') pubSub: PubSub) {
  return pubSub.subscribe('commentAdded');
}
```

If you need to access injected providers (e.g., use an external service to validate the data), use the following construction:

```typescript

@Subscription('commentAdded', {
  filter(this: AuthorResolver, payload, variables) {
    // "this" refers to an instance of "AuthorResolver"
    return payload.commentAdded.title === variables.title;
  }
})
commentAdded(@Context('pubsub') pubSub: PubSub) {
  return pubSub.subscribe('commentAdded');
}
```

The last step is to update the type definitions file.

```graphql

type Author {
  id: Int!
  firstName: String
  lastName: String
  posts: [Post]
}

type Post {
  id: Int!
  title: String
  votes: Int
}

type Query {
  author(id: Int!): Author
}

type Comment {
  id: String
  content: String
}

type Subscription {
  commentAdded(title: String!): Comment
}
```

With this, we've created a single `commentAdded(title: String!): Comment` subscription.

#### PubSub[#](/graphql/subscriptions#pubsub-1)

In the examples above, we used the default `PubSub` emitter ([mqemitter](https://github.com/mcollina/mqemitter)) The preferred approach (for production) is to use `mqemitter-redis`. Alternatively, a custom `PubSub` implementation can be provided (read more [here](https://github.com/mercurius-js/mercurius/blob/master/docs/subscriptions.md))

```typescript

GraphQLModule.forRoot<MercuriusDriverConfig>({
  driver: MercuriusDriver,
  subscription: {
    emitter: require('mqemitter-redis')({
      port: 6579,
      host: '127.0.0.1',
    }),
  },
});
```

#### Authentication over WebSockets[#](/graphql/subscriptions#authentication-over-websockets-1)

Checking whether the user is authenticated can be done inside the `verifyClient` callback function that you can specify in the `subscription` options.

The `verifyClient` will receive the `info` object as a first argument which you can use to retrive the request's headers.

```typescript

GraphQLModule.forRoot<MercuriusDriverConfig>({
  driver: MercuriusDriver,
  subscription: {
    verifyClient: (info, next) => {
      const authorization = info.req.headers?.authorization as string;
      if (!authorization?.startsWith('Bearer ')) {
        return next(false);
      }
      next(true);
    },
  }
}),
```

----
url: https://docs.nestjs.com/v10/openapi/introduction
----

* [Introduction](https://docs.nestjs.com/v10/openapi/introduction#introduction)
* [Installation](https://docs.nestjs.com/v10/openapi/introduction#installation)
* [Bootstrap](https://docs.nestjs.com/v10/openapi/introduction#bootstrap)
* [Document options](https://docs.nestjs.com/v10/openapi/introduction#document-options)
* [Setup options](https://docs.nestjs.com/v10/openapi/introduction#setup-options)
* [Example](https://docs.nestjs.com/v10/openapi/introduction#example)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/openapi/introduction.md "Suggest Edits")

### Introduction

The [OpenAPI](https://swagger.io/specification/) specification is a language-agnostic definition format used to describe RESTful APIs. Nest provides a dedicated [module](https://github.com/nestjs/swagger) which allows generating such a specification by leveraging decorators.

#### Installation[#](/openapi/introduction#installation)

To begin using it, we first install the required dependency.

```bash

$ npm install --save @nestjs/swagger
```

#### Bootstrap[#](/openapi/introduction#bootstrap)

Once the installation process is complete, open the `main.ts` file and initialize Swagger using the `SwaggerModule` class:

main.ts

JS TS

```typescript

import { NestFactory } from '@nestjs/core';
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);

  const config = new DocumentBuilder()
    .setTitle('Cats example')
    .setDescription('The cats API description')
    .setVersion('1.0')
    .addTag('cats')
    .build();
  const documentFactory = () => SwaggerModule.createDocument(app, config);
  SwaggerModule.setup('api', app, documentFactory);

  await app.listen(process.env.PORT ?? 3000);
}
bootstrap();
```

> **Hint** The factory method `SwaggerModule#createDocument()` is used specifically to generate the Swagger document when you request it. This approach helps save some initialization time, and the resulting document is a serializable object that conforms to the [OpenAPI Document](https://swagger.io/specification/#openapi-document) specification. Instead of serving the document over HTTP, you can also save it as a JSON or YAML file and use it in various ways.

```bash

$ npm run start
```

While the application is running, open your browser and navigate to `http://localhost:3000/api`. You should see the Swagger UI.

As you can see, the `SwaggerModule` automatically reflects all of your endpoints.

> **Hint** To generate and download a Swagger JSON file, navigate to `http://localhost:3000/api-json` (assuming that your Swagger documentation is available under `http://localhost:3000/api`). It is also possible to expose it on a route of your choice using only the setup method from `@nestjs/swagger`, like this:
>
> ```typescript
>
> SwaggerModule.setup('swagger', app, document, {
>   jsonDocumentUrl: 'swagger/json',
> });
> ```
>
> Which would expose it at `http://localhost:3000/swagger/json`

> **Warning** When using `fastify` and `helmet`, there may be a problem with [CSP](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP), to solve this collision, configure the CSP as shown below:
>
> ```typescript
>
> app.register(helmet, {
>   contentSecurityPolicy: {
>     directives: {
>       defaultSrc: [`'self'`],
>       styleSrc: [`'self'`, `'unsafe-inline'`],
>       imgSrc: [`'self'`, 'data:', 'validator.swagger.io'],
>       scriptSrc: [`'self'`, `https: 'unsafe-inline'`],
>     },
>   },
> });
>
> // If you are not going to use CSP at all, you can use this:
> app.register(helmet, {
>   contentSecurityPolicy: false,
> });
> ```

#### Document options[#](/openapi/introduction#document-options)

When creating a document, it is possible to provide some extra options to fine tune the library's behavior. These options should be of type `SwaggerDocumentOptions`, which can be the following:

```typescript

export interface SwaggerDocumentOptions {
  /**
   * List of modules to include in the specification
   */
  include?: Function[];

  /**
   * Additional, extra models that should be inspected and included in the specification
   */
  extraModels?: Function[];

  /**
   * If `true`, swagger will ignore the global prefix set through `setGlobalPrefix()` method
   */
  ignoreGlobalPrefix?: boolean;

  /**
   * If `true`, swagger will also load routes from the modules imported by `include` modules
   */
  deepScanRoutes?: boolean;

  /**
   * Custom operationIdFactory that will be used to generate the `operationId`
   * based on the `controllerKey`, `methodKey`, and version.
   * @default () => controllerKey_methodKey_version
   */
  operationIdFactory?: OperationIdFactory;

  /**
   * Custom linkNameFactory that will be used to generate the name of links
   * in the `links` field of responses
   *
   * @see [Link objects](https://swagger.io/docs/specification/links/)
   *
   * @default () => `${controllerKey}_${methodKey}_from_${fieldKey}`
   */
  linkNameFactory?: (
    controllerKey: string,
    methodKey: string,
    fieldKey: string
  ) => string;

  /*
   * Generate tags automatically based on the controller name.
   * If `false`, you must use the `@ApiTags()` decorator to define tags.
   * Otherwise, the controller name without the suffix `Controller` will be used.
   * @default true
   */
  autoTagControllers?: boolean;
}
```

For example, if you want to make sure that the library generates operation names like `createUser` instead of `UserController_createUser`, you can set the following:

```typescript

const options: SwaggerDocumentOptions =  {
  operationIdFactory: (
    controllerKey: string,
    methodKey: string
  ) => methodKey
};
const documentFactory = () => SwaggerModule.createDocument(app, config, options);
```

#### Setup options[#](/openapi/introduction#setup-options)

You can configure Swagger UI by passing the options object which fulfills the `SwaggerCustomOptions` interface as a fourth argument of the `SwaggerModule#setup` method.

```typescript

export interface SwaggerCustomOptions {
  /**
   * If `true`, Swagger resources paths will be prefixed by the global prefix set through `setGlobalPrefix()`.
   * Default: `false`.
   * @see https://docs.nestjs.com/faq/global-prefix
   */
  useGlobalPrefix?: boolean;

  /**
   * If `false`, only API definitions (JSON and YAML) will be served (on `/{path}-json` and `/{path}-yaml`).
   * This is particularly useful if you are already hosting a Swagger UI somewhere else and just want to serve API definitions.
   * Default: `true`.
   */
  swaggerUiEnabled?: boolean;

  /**
   * Url point the API definition to load in Swagger UI.
   */
  swaggerUrl?: string;

  /**
   * Path of the JSON API definition to serve.
   * Default: `<path>-json`.
   */
  jsonDocumentUrl?: string;

  /**
   * Path of the YAML API definition to serve.
   * Default: `<path>-yaml`.
   */
  yamlDocumentUrl?: string;

  /**
   * Hook allowing to alter the OpenAPI document before being served.
   * It's called after the document is generated and before it is served as JSON & YAML.
   */
  patchDocumentOnRequest?: <TRequest = any, TResponse = any>(
    req: TRequest,
    res: TResponse,
    document: OpenAPIObject
  ) => OpenAPIObject;

  /**
   * If `true`, the selector of OpenAPI definitions is displayed in the Swagger UI interface.
   * Default: `false`.
   */
  explorer?: boolean;

  /**
   * Additional Swagger UI options
   */
  swaggerOptions?: SwaggerUiOptions;

  /**
   * Custom CSS styles to inject in Swagger UI page.
   */
  customCss?: string;

  /**
   * URL(s) of a custom CSS stylesheet to load in Swagger UI page.
   */
  customCssUrl?: string | string[];

  /**
   * URL(s) of custom JavaScript files to load in Swagger UI page.
   */
  customJs?: string | string[];

  /**
   * Custom JavaScript scripts to load in Swagger UI page.
   */
  customJsStr?: string | string[];

  /**
   * Custom favicon for Swagger UI page.
   */
  customfavIcon?: string;

  /**
   * Custom title for Swagger UI page.
   */
  customSiteTitle?: string;

  /**
   * File system path (ex: ./node_modules/swagger-ui-dist) containing static Swagger UI assets.
   */
  customSwaggerUiPath?: string;

  /**
   * @deprecated This property has no effect.
   */
  validatorUrl?: string;

  /**
   * @deprecated This property has no effect.
   */
  url?: string;

  /**
   * @deprecated This property has no effect.
   */
  urls?: Record<'url' | 'name', string>[];

}
```

#### Example[#](/openapi/introduction#example)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/11-swagger).

----
url: https://docs.nestjs.com/v8/cli/overview
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Overview](https://docs.nestjs.com/v8/cli/overview#overview)
* [Installation](https://docs.nestjs.com/v8/cli/overview#installation)
* [Basic workflow](https://docs.nestjs.com/v8/cli/overview#basic-workflow)
* [Project structure](https://docs.nestjs.com/v8/cli/overview#project-structure)
* [CLI command syntax](https://docs.nestjs.com/v8/cli/overview#cli-command-syntax)
* [Command overview](https://docs.nestjs.com/v8/cli/overview#command-overview)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/cli/overview.md "Suggest Edits")

### Overview

The [Nest CLI](https://github.com/nestjs/nest-cli) is a command-line interface tool that helps you to initialize, develop, and maintain your Nest applications. It assists in multiple ways, including scaffolding the project, serving it in development mode, and building and bundling the application for production distribution. It embodies best-practice architectural patterns to encourage well-structured apps.

#### Installation[#](/cli/overview#installation)

**Note**: In this guide we describe using [npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm) to install packages, including the Nest CLI. Other package managers may be used at your discretion. With npm, you have several options available for managing how your OS command line resolves the location of the `nest` CLI binary file. Here, we describe installing the `nest` binary globally using the `-g` option. This provides a measure of convenience, and is the approach we assume throughout the documentation. Note that installing **any**`npm` package globally leaves the responsibility of ensuring they're running the correct version up to the user. It also means that if you have different projects, each will run the **same** version of the CLI. A reasonable alternative is to use the [npx](https://github.com/npm/npx) program (or similar features with other package managers) to ensure that you run a **managed version** of the Nest CLI. We recommend you consult the [npx documentation](https://github.com/npm/npx) and/or your DevOps support staff for more information.

Install the CLI globally using the `npm install -g` command (see the **Note** above for details about global installs).

```bash

$ npm install -g @nestjs/cli
```

#### Basic workflow[#](/cli/overview#basic-workflow)

Once installed, you can invoke CLI commands directly from your OS command line through the `nest` executable. See the available `nest` commands by entering the following:

```bash

$ nest --help
```

Get help on an individual command using the following construct. Substitute any command, like `new`, `add`, etc., where you see `generate` in the example below to get detailed help on that command:

```bash

$ nest generate --help
```

To create, build and run a new basic Nest project in development mode, go to the folder that should be the parent of your new project, and run the following commands:

```bash

$ nest new my-nest-project
$ cd my-nest-project
$ npm run start:dev
```

In your browser, open <http://localhost:3000> to see the new application running. The app will automatically recompile and reload when you change any of the source files.

#### Project structure[#](/cli/overview#project-structure)

When you run `nest new`, Nest generates a boilerplate application structure by creating a new folder and populating an initial set of files. You can continue working in this default structure, adding new components, as described throughout this documentation. We refer to the project structure generated by `nest new` as **standard mode**. Nest also supports an alternate structure for managing multiple projects and libraries called **monorepo mode**.

Aside from a few specific considerations around how the **build** process works (essentially, monorepo mode simplifies build complexities that can sometimes arise from monorepo-style project structures), and built-in [library](/v8/cli/libraries) support, the rest of the Nest features, and this documentation, apply equally to both standard and monorepo mode project structures. In fact, you can easily switch from standard mode to monorepo mode at any time in the future, so you can safely defer this decision while you're still learning about Nest.

You can use either mode to manage multiple projects. Here's a quick summary of the differences:

| Feature                                               | Standard Mode                                                      | Monorepo Mode                                              |
| ----------------------------------------------------- | ------------------------------------------------------------------ | ---------------------------------------------------------- |
| Multiple projects                                     | Separate file system structure                                     | Single file system structure                               |
| `node_modules` & `package.json`                       | Separate instances                                                 | Shared across monorepo                                     |
| Default compiler                                      | `tsc`                                                              | webpack                                                    |
| Compiler settings                                     | Specified separately                                               | Monorepo defaults that can be overridden per project       |
| Config files like `.eslintrc.js`, `.prettierrc`, etc. | Specified separately                                               | Shared across monorepo                                     |
| `nest build` and `nest start` commands                | Target defaults automatically to the (only) project in the context | Target defaults to the **default project** in the monorepo |
| Libraries                                             | Managed manually, usually via npm packaging                        | Built-in support, including path management and bundling   |

Read the sections on [Workspaces](/v8/cli/monorepo) and [Libraries](/v8/cli/libraries) for more detailed information to help you decide which mode is most suitable for you.

```bash

nest commandOrAlias requiredArg [optionalArg] [options]
```

For example:

```bash

$ nest new my-nest-project --dry-run
```

Here, `new` is the *commandOrAlias*. The `new` command has an alias of `n`. `my-nest-project` is the *requiredArg*. If a *requiredArg* is not supplied on the command line, `nest` will prompt for it. Also, `--dry-run` has an equivalent short-hand form `-d`. With this in mind, the following command is the equivalent of the above:

```bash

$ nest n my-nest-project -d
```

Most commands, and some options, have aliases. Try running `nest new --help` to see these options and aliases, and to confirm your understanding of the above constructs.

#### Command overview[#](/cli/overview#command-overview)

Run `nest <command> --help` for any of the following commands to see command-specific options.

See [usage](/v8/cli/usages) for detailed descriptions for each command.

| Command    | Alias | Description                                                                                          |
| ---------- | ----- | ---------------------------------------------------------------------------------------------------- |
| `new`      | `n`   | Scaffolds a new *standard mode* application with all boilerplate files needed to run.                |
| `generate` | `g`   | Generates and/or modifies files based on a schematic.                                                |
| `build`    |       | Compiles an application or workspace into an output folder.                                          |
| `start`    |       | Compiles and runs an application (or default project in a workspace).                                |
| `add`      |       | Imports a library that has been packaged as a **nest library**, running its install schematic.       |
| `update`   | `u`   | Update `@nestjs` dependencies in the `package.json``"dependencies"` list to their `@latest` version. |
| `info`     | `i`   | Displays information about installed nest packages and other helpful system info.                    |

----
url: https://docs.nestjs.com/microservices/custom-transport
----

[Skip to content](#content)

On this page

* [Custom transporters](https://docs.nestjs.com/microservices/custom-transport#custom-transporters)
* [Creating a strategy](https://docs.nestjs.com/microservices/custom-transport#creating-a-strategy)
* [Reporting event handler errors](https://docs.nestjs.com/microservices/custom-transport#reporting-event-handler-errors)
* [Client proxy](https://docs.nestjs.com/microservices/custom-transport#client-proxy)
* [Message serialization](https://docs.nestjs.com/microservices/custom-transport#message-serialization)

### Custom transporters

Nest provides a variety of **transporters** out of the box, as well as an API for building custom transport strategies. Transporters let you connect components over a network using a pluggable communications layer and a simple application-level message protocol (see the [full article](https://dev.to/nestjs/integrate-nestjs-with-external-services-using-microservice-transporters-part-1-p3)).

> **Hint** Building a microservice with Nest doesn't necessarily mean you must use the `@nestjs/microservices` package. For example, if you want to communicate with external services (e.g., other microservices written in different languages), you may not need all the features provided by the `@nestjs/microservices` library. If you don't need the decorators that let you define subscribers declaratively (`@EventPattern` or `@MessagePattern`), running a [standalone application](/application-context) and managing connections and channel subscriptions manually is enough for most use cases, and gives you more flexibility.

With a custom transporter, you can integrate any messaging system or protocol (including Google Cloud Pub/Sub, Amazon Kinesis, and others), or extend an existing one with extra features (for example, [QoS](https://github.com/mqttjs/MQTT.js/blob/master/README.md#qos) for MQTT).

> **Hint** To better understand how Nest microservices work and how you can extend the capabilities of existing transporters, we recommend reading the [NestJS Microservices in Action](https://dev.to/johnbiundo/series/4724) and [Advanced NestJS Microservices](https://dev.to/nestjs/part-1-introduction-and-setup-1a2l) article series.

#### Creating a strategy[#](/microservices/custom-transport#creating-a-strategy)

First, let's define a class representing our custom transporter:

```typescript

import { CustomTransportStrategy, Server } from '@nestjs/microservices';

class GoogleCloudPubSubServer
  extends Server
  implements CustomTransportStrategy
{
  /**
   * Triggered when you run "app.listen()".
   */
  listen(callback: () => void) {
    callback();
  }

  /**
   * Triggered on application shutdown.
   */
  close() {}

  /**
   * You can ignore this method if you don't want transporter users
   * to be able to register event listeners. Most custom implementations
   * will not need this.
   */
  on(event: string, callback: Function) {
    throw new Error('Method not implemented.');
  }

  /**
   * You can ignore this method if you don't want transporter users
   * to be able to retrieve the underlying native server. Most custom implementations
   * will not need this.
   */
  unwrap<T = never>(): T {
    throw new Error('Method not implemented.');
  }
}
```

> **Warning** This chapter doesn't implement a fully-featured Google Cloud Pub/Sub server, as that would require diving into transporter-specific technical details.

In the example above, we declared the `GoogleCloudPubSubServer` class and provided the `listen()` and `close()` methods enforced by the `CustomTransportStrategy` interface. Our class also extends the `Server` class from the `@nestjs/microservices` package, which provides several useful methods, such as the ones the Nest runtime uses to register message handlers. Alternatively, to extend the capabilities of an existing transport strategy, you can extend the corresponding server class, for example, `ServerRedis`. By convention, we added the `"Server"` suffix to the class name, because the class is responsible for subscribing to messages and events (and responding to them, if necessary).

With this in place, we can use our custom strategy instead of a built-in transporter:

```typescript

const app = await NestFactory.createMicroservice<MicroserviceOptions>(
  AppModule,
  {
    strategy: new GoogleCloudPubSubServer(),
  },
);
```

Instead of passing the usual transporter options object with the `transport` and `options` properties, we pass a single property, `strategy`, whose value is an instance of our custom transporter class.

Back to the `GoogleCloudPubSubServer` class. In a real-world application, the `listen()` method would establish a connection to the message broker or external service and register subscribers or listen to specific channels (and the `close()` teardown method would remove the subscriptions and close the connection). Since this requires a good understanding of how Nest microservices communicate with each other, we recommend reading the [Advanced NestJS Microservices article series](https://dev.to/nestjs/part-1-introduction-and-setup-1a2l). This chapter instead focuses on the capabilities the `Server` class provides and how you can use them to build custom strategies.

For example, let's say that the following message handler is defined somewhere in our application:

```typescript

@MessagePattern('echo')
echo(@Payload() data: object) {
  return data;
}
```

The Nest runtime registers this message handler automatically. With the `Server` class, you can see which message patterns have been registered, and access and execute the methods assigned to them. To test this out, let's add a `console.log` call inside the `listen()` method, before the `callback` function is called:

```typescript

listen(callback: () => void) {
  console.log(this.messageHandlers);
  callback();
}
```

After your application restarts, you'll see the following log in your terminal:

```text

Map(1) {
  'echo' => [AsyncFunction (anonymous)] { isEventHandler: false, extras: {} }
}
```

> **Hint** With the `@EventPattern` decorator, you would see the same output, but with the `isEventHandler` property set to `true`.

The `messageHandlers` property is a `Map` of all message (and event) handlers, keyed by pattern. You can use a key (for example, `"echo"`) to get a reference to the message handler:

```typescript

async listen(callback: () => void) {
  const echoHandler = this.messageHandlers.get('echo');
  console.log(await echoHandler('Hello world!'));
  callback();
}
```

When we execute `echoHandler` with an arbitrary string as the argument (`"Hello world!"` here), we should see it in the console:

```text

Hello world!
```

This means that our handler method was executed correctly.

When you use a `CustomTransportStrategy` with [interceptors](/interceptors), the handlers are wrapped in RxJS streams. This means you need to subscribe to them to execute the streams' underlying logic (e.g., to continue into the controller logic after an interceptor has run).

For example:

```typescript

async listen(callback: () => void) {
  const echoHandler = this.messageHandlers.get('echo');
  const streamOrResult = await echoHandler('Hello World');
  if (isObservable(streamOrResult)) {
    streamOrResult.subscribe();
  }
  callback();
}
```

#### Reporting event handler errors[#](/microservices/custom-transport#reporting-event-handler-errors)

An event handler has no response stream, so an error thrown inside one has nowhere to go. Nest logs it instead, but only after your exception filters run. If one of your filters matches the exception, that filter is the only report.

Some transporters await the event stream themselves and hand the failure to their client library, which reports it. `ServerKafka` does this: `kafkajs` logs the rejection, so a second report from Nest would duplicate it. Set `propagatesEventHandlerErrors` to `true` in that case:

```typescript

class GoogleCloudPubSubServer
  extends Server
  implements CustomTransportStrategy
{
  /**
   * The client library reports an event handler failure, so Nest must not
   * log it a second time.
   */
  public override readonly propagatesEventHandlerErrors = true;
}
```

The default is `false`, which suits a transporter that uses the inherited `handleEvent`. Nothing subscribes to the event stream there, so Nest is the only thing that can report the failure.

#### Client proxy[#](/microservices/custom-transport#client-proxy)

As mentioned in the first section, you don't necessarily need the `@nestjs/microservices` package to create microservices. However, if you use it and need to integrate a custom strategy, you also need to provide a "client" class.

> **Hint** Implementing a fully-featured client class compatible with all `@nestjs/microservices` features (e.g., streaming) requires a good understanding of the communication techniques the framework uses. To learn more, see the [basic client component article](https://dev.to/nestjs/part-4-basic-client-component-16f9).

To communicate with an external service and publish messages (or emit events), you can either use a library-specific SDK package or implement a custom client class that extends `ClientProxy`:

```typescript

import { ClientProxy, ReadPacket, WritePacket } from '@nestjs/microservices';

class GoogleCloudPubSubClient extends ClientProxy {
  async connect(): Promise<any> {}
  async close() {}
  async dispatchEvent(packet: ReadPacket<any>): Promise<any> {}
  publish(
    packet: ReadPacket<any>,
    callback: (packet: WritePacket<any>) => void,
  ): () => void {}
  unwrap<T = never>(): T {
    throw new Error('Method not implemented.');
  }
}
```

> **Warning** This chapter doesn't implement a fully-featured Google Cloud Pub/Sub client, as that would require diving into transporter-specific technical details.

The `ClientProxy` class requires you to implement methods for establishing and closing the connection, and for publishing messages (`publish()`) and events (`dispatchEvent()`). If you don't need to support the request-response communication style, you can leave the `publish()` method empty. Likewise, if you don't need to support event-based communication, leave the `dispatchEvent()` method empty.

To observe which of these methods run, and when, let's add several `console.log` calls:

```typescript

class GoogleCloudPubSubClient extends ClientProxy {
  async connect(): Promise<any> {
    console.log('connect');
  }

  async close() {
    console.log('close');
  }

  async dispatchEvent(packet: ReadPacket<any>): Promise<any> {
    return console.log('event to dispatch: ', packet);
  }

  publish(
    packet: ReadPacket<any>,
    callback: (packet: WritePacket<any>) => void,
  ): () => void {
    console.log('message:', packet);

    // In a real-world application, the "callback" function should be executed
    // with the payload sent back from the responder. Here, we simulate a response
    // (after a 5-second delay) by passing back the same "data" we originally sent.
    //
    // The "isDisposed" flag on the WritePacket signals that no further data is
    // expected. If it's omitted or false, the data is emitted to the Observable.
    setTimeout(() => callback({ 
      response: packet.data,
      isDisposed: true,
    }), 5000);

    return () => console.log('teardown');
  }

  unwrap<T = never>(): T {
    throw new Error('Method not implemented.');
  }
}
```

With this in place, let's create an instance of the `GoogleCloudPubSubClient` class and call the `send()` method (which you might have seen in earlier chapters), subscribing to the returned observable stream:

```typescript

const googlePubSubClient = new GoogleCloudPubSubClient();
googlePubSubClient
  .send('pattern', 'Hello world!')
  .subscribe((response) => console.log(response));
```

You should see the following output in your terminal:

```typescript

connect
message: { pattern: 'pattern', data: 'Hello world!' }
Hello world! // <-- after 5 seconds
```

To test whether the teardown function (which our `publish()` method returns) runs, let's apply the `timeout` operator to the stream, set to 2 seconds so that it throws before our `setTimeout` calls the `callback` function:

```typescript

const googlePubSubClient = new GoogleCloudPubSubClient();
googlePubSubClient
  .send('pattern', 'Hello world!')
  .pipe(timeout(2000))
  .subscribe({
    next: (response) => console.log(response),
    error: (error) => console.error(error.message),
  });
```

> **Hint** The `timeout` operator is imported from the `rxjs/operators` package.

With the `timeout` operator applied, your terminal output should look as follows:

```typescript

connect
message: { pattern: 'pattern', data: 'Hello world!' }
teardown // <-- teardown
Timeout has occurred
```

To dispatch an event (instead of sending a message), use the `emit()` method:

```typescript

googlePubSubClient.emit('event', 'Hello world!');
```

You should see the following in the console:

```typescript

connect
event to dispatch:  { pattern: 'event', data: 'Hello world!' }
```

#### Message serialization[#](/microservices/custom-transport#message-serialization)

To add custom logic around the serialization of responses on the client side, use a custom class that extends the `ClientProxy` class or one of its child classes. To modify successful responses, override the `serializeResponse()` method; to modify any errors that go through this client, override the `serializeError()` method. To use this custom class, pass the class itself to the `ClientsModule.register()` method using the `customClass` property. Below is an example of a custom `ClientProxy` that serializes each error into an `RpcException`.

error-handling.proxy.ts

JS TS

```typescript

import { ClientTCP, RpcException } from '@nestjs/microservices';

class ErrorHandlingProxy extends ClientTCP {
  serializeError(err: Error) {
    return new RpcException(err);
  }
}
```

Then use it in the `ClientsModule`:

app.module.ts

JS TS

```typescript

@Module({
  imports: [
    ClientsModule.register([{
      name: 'CustomProxy',
      customClass: ErrorHandlingProxy,
    }]),
  ]
})
export class AppModule {}
```

> **Hint** You pass the class itself to `customClass`, not an instance of the class. Nest creates the instance for you and passes any options given in the `options` property to the new `ClientProxy`.

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/microservices/custom-transport.md)

----
url: https://docs.nestjs.com/v11/observability/overview
----

* [Overview](https://docs.nestjs.com/v11/observability/overview#overview)
* [What makes it different](https://docs.nestjs.com/v11/observability/overview#what-makes-it-different)
* [What it offers](https://docs.nestjs.com/v11/observability/overview#what-it-offers)
* [How it is organized](https://docs.nestjs.com/v11/observability/overview#how-it-is-organized)
* [Subscribing](https://docs.nestjs.com/v11/observability/overview#subscribing)
* [First project](https://docs.nestjs.com/v11/observability/overview#first-project)
* [Where to go next](https://docs.nestjs.com/v11/observability/overview#where-to-go-next)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/observability/overview.md "Suggest Edits")

### Overview

[NestJS Observe](https://www.observe.nestjs.com/ "NestJS Observe") is the official, auto-instrumented observability platform for NestJS applications. Install the SDK, add an API key, and your application starts streaming requests, background jobs, errors, logs, and traces to your dashboard - no manual span wiring, no collector to run, no schema to design, no dashboards to build by hand.

> **Hint** This chapter covers how to instrument a NestJS application with the `@nestjs/observe` SDK and what that instrumentation gives you. If you are looking for the dashboard itself, head over to [observe.nestjs.com](https://www.observe.nestjs.com/ "NestJS Observe").

#### What makes it different[#](/observability/overview#what-makes-it-different)

Generic Node.js APM agents attach to the HTTP server and the database driver and leave everything in between as a black box. NestJS Observe is built around Nest's own request lifecycle - controllers, guards, interceptors, pipes, resolvers, queue consumers - so the telemetry is expressed in the vocabulary you wrote the code in: `OrdersService.recalculate`, not `POST /orders`. That is also why it can show time spent per NestJS **class and method**, not only per route, and why a trace waterfall from an unmodified application already reads like a call graph.

The SDK attaches to the framework through the `instrument` application option of `NestFactory.create()` (available since `@nestjs/core` v11.1.4), so it sees every controller, provider, resolver, and queue consumer as Nest wires them - no process-wide patching, and nothing to import before the rest of your code.

#### What it offers[#](/observability/overview#what-it-offers)

Once the SDK is running, every plan - including the free tier - gives you:

* **Request monitoring** for HTTP, GraphQL, gRPC, and `@nestjs/microservices` transports: throughput, latency (average and p95), failure rate per operation, and a detail page for every single execution.
* **Distributed tracing** with a waterfall of every span a request ran, self-time ranking to find where the time actually went, and correlation across services once a trace id is propagated (see [Distributed tracing]()).

Paid plans add **logs streaming** (correlated to traces, with redaction on by default), **alerting** (thresholds, anomaly detection, absence detection, Slack/webhook/email channels), **issues**, team management, and - on the higher tiers - **SSO**, **SLOs** with error budgets and burn-rate alerts, and a read-only **MCP server** so an MCP-compatible agent can query your telemetry directly (see [MCP server]()).

Usage is metered in **Observability Events (OEs)** - one per request, background job run, error, log entry, or trace span your applications report. These compound rather than collapse: a request that ran three database spans, wrote two log lines, and raised one error is seven events. Your plan sets a monthly allowance of included events, a retention window, and which features are unlocked:

| Plan       | Included events / month | Retention  | Logs & alerts | SSO & SLOs |
| ---------- | ----------------------: | ---------- | ------------- | ---------- |
| Free       |                    300k | 3 days     | ✗             | ✗          |
| Pro        |                     25M | 30 days    | ✓             | ✗          |
| Scale      |                    200M | 90 days    | ✓             | ✓          |
| Enterprise |              Negotiated | Negotiated | ✓             | ✓          |

Free has a hard monthly limit - once it is reached, ingestion is rejected until the next period. Pro and Scale allow overage instead of a hard stop, billed per additional million events, so a busy month doesn't mean lost telemetry. Annual billing is discounted against the monthly price. For current prices, seat counts, and overage rates, see the [pricing page](https://www.observe.nestjs.com/ "NestJS Observe").

To upgrade, open **Billing → Manage subscription** for the team that owns your projects. From the same area, the **Usage** page tracks your Observability Events against the allowance, broken down by project, and lets you set **quota notifications** (up to five thresholds, e.g. 50%, 80%, 100%) to get an email the moment usage crosses one.

> **Hint** Ingestion volume is controllable without a redeploy through per-project **spend controls**: trace-coherent span sampling, a per-minute rate cap, and drop filters for known-noisy traffic like `/health*`. Errors are never sampled or dropped by these controls. You can also stop telemetry from being generated at all on the SDK side - see [Ignoring noisy operations](/observability/sdk#ignoring-noisy-operations).

#### First project[#](/observability/overview#first-project)

1. **Create a project** and give it a name.
2. **Add an application** to it. An application needs nothing beyond a name - the routes it serves, the jobs it processes, and the metrics it reports are all discovered from the telemetry the SDK sends.
3. **Generate an API key** from the project's **API Keys** page. Each key has a name (one for local development, one for CI, one for production) and an optional expiration date. The key pair (`appKey` and `appSecret`) is shown once, at creation, so copy it into your secrets store right away. Keys are scoped to a project: every application whose telemetry should land in that project uses the same key.
4. **Instrument your application** by following the [SDK]() chapter. Telemetry starts appearing within moments of your application receiving traffic.

> **Warning** Treat `appKey` and `appSecret` like any other credential: read them from environment variables or a secrets manager, never commit them to source control. Revoke a key from the same page at any time - any application still using it will stop being able to send telemetry.

#### Where to go next[#](/observability/overview#where-to-go-next)

* [SDK]() - installation, the three-line quick start, and every configuration option.
* [Manual instrumentation]() - custom spans, handled errors, request-scoped attributes, and custom metrics.
* [Distributed tracing]() - propagating a trace id across HTTP, gRPC, microservice transports, and GraphQL.
* [Dashboard]() - what each view shows once telemetry is flowing, and how alerts, SLOs, and issues build on it.
* [MCP server]() - querying your telemetry from Claude Code, Cursor, VS Code, or your own agent.

----
url: https://docs.nestjs.com/http/performance
----

[Skip to content](#content)

On this page

* [Performance (Fastify)](https://docs.nestjs.com/http/performance#performance-fastify)
* [Installation](https://docs.nestjs.com/http/performance#installation)
* [Adapter](https://docs.nestjs.com/http/performance#adapter)
* [Platform specific packages](https://docs.nestjs.com/http/performance#platform-specific-packages)
* [Redirect response](https://docs.nestjs.com/http/performance#redirect-response)
* [Fastify options](https://docs.nestjs.com/http/performance#fastify-options)
* [Middleware](https://docs.nestjs.com/http/performance#middleware)
* [Route Config](https://docs.nestjs.com/http/performance#route-config)
* [Route Constraints](https://docs.nestjs.com/http/performance#route-constraints)
* [Example](https://docs.nestjs.com/http/performance#example)

### Performance (Fastify)

By default, Nest uses the [Express](https://expressjs.com/) framework. Nest is also compatible with other libraries, such as [Fastify](https://github.com/fastify/fastify). It achieves this framework independence through a framework adapter, whose primary job is to proxy middleware and handlers to the appropriate library-specific implementations.

> **Hint** A framework adapter can only be implemented for a library that provides request/response pipeline processing similar to Express.

[Fastify](https://github.com/fastify/fastify) is a good alternative framework for Nest because it solves design issues in a similar way to Express. However, Fastify is significantly **faster** than Express, achieving nearly twice the benchmark results. Nest still uses Express as the default HTTP provider because Express is widely used, well known, and has an enormous set of compatible middleware, which is available to Nest users out of the box.

Because Nest is framework independent, you can migrate between the two. Fastify can be a better choice when raw speed is a priority. To use Fastify, choose the built-in `FastifyAdapter`, as shown in this chapter.

#### Installation[#](/http/performance#installation)

First, install the required package:

```bash

$ npm i --save @nestjs/platform-fastify
```

#### Adapter[#](/http/performance#adapter)

Once the Fastify platform is installed, you can use the `FastifyAdapter`.

main.ts

JS TS

```typescript

import { NestFactory } from '@nestjs/core';
import {
  FastifyAdapter,
  NestFastifyApplication,
} from '@nestjs/platform-fastify';
import { AppModule } from './app.module.js';

async function bootstrap() {
  const app = await NestFactory.create<NestFastifyApplication>(
    AppModule,
    new FastifyAdapter()
  );
  await app.listen(process.env.PORT ?? 3000);
}
await bootstrap();
```

By default, Fastify listens only on the `localhost` interface (see the [Fastify getting started guide](https://fastify.dev/docs/latest/Guides/Getting-Started/#your-first-server)). To accept connections on other hosts, specify `'0.0.0.0'` in the `listen()` call:

```typescript

async function bootstrap() {
  const app = await NestFactory.create<NestFastifyApplication>(
    AppModule,
    new FastifyAdapter(),
  );
  await app.listen(3000, '0.0.0.0');
}
```

#### Platform specific packages[#](/http/performance#platform-specific-packages)

When you use the `FastifyAdapter`, Nest uses Fastify as the **HTTP provider**. This means that recipes that rely on Express may not work. Use Fastify-equivalent packages instead.

#### Redirect response[#](/http/performance#redirect-response)

Fastify handles redirect responses slightly differently than Express. To redirect with Fastify, set the status code with `status()`, then call `redirect()` with the URL:

```typescript

@Get()
index(@Res() res) {
  res.status(302).redirect('/login');
}
```

#### Fastify options[#](/http/performance#fastify-options)

You can pass options to the Fastify instance through the `FastifyAdapter` constructor. For example:

```typescript

new FastifyAdapter({ logger: true });
```

#### Middleware[#](/http/performance#middleware)

Middleware functions receive the raw `req` and `res` objects instead of Fastify's wrappers. This is how the `@fastify/middie` package, which Nest uses under the hood, works. See the [Fastify middleware documentation](https://fastify.dev/docs/latest/Reference/Middleware/) for more information.

logger.middleware.ts

JS TS

```typescript

import { Injectable, NestMiddleware } from '@nestjs/common';
import { FastifyRequest, FastifyReply } from 'fastify';

@Injectable()
export class LoggerMiddleware implements NestMiddleware {
  use(req: FastifyRequest['raw'], res: FastifyReply['raw'], next: () => void) {
    console.log('Request...');
    next();
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';

@Injectable()
export class LoggerMiddleware {
  use(req, res, next) {
    console.log('Request...');
    next();
  }
}
```

#### Route Config[#](/http/performance#route-config)

Use the `@RouteConfig()` decorator to apply Fastify's [route config](https://fastify.dev/docs/latest/Reference/Routes/#config) feature.

```typescript

@RouteConfig({ output: 'hello world' })
@Get()
index(@Req() req) {
  return req.routeConfig.output;
}
```

#### Route Constraints[#](/http/performance#route-constraints)

Use the `@RouteConstraints()` decorator to apply Fastify's [route constraints](https://fastify.dev/docs/latest/Reference/Routes/#constraints) feature.

```typescript

@RouteConstraints({ version: '1.2.x' })
newFeature() {
  return 'This works only for version >= 1.2.x';
}
```

> **Hint**`@RouteConfig()` and `@RouteConstraints()` are imported from `@nestjs/platform-fastify`.

#### Example[#](/http/performance#example)

A working example is available in the [nestjs/nest repository](https://github.com/nestjs/nest/tree/master/sample/10-fastify).

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/http/performance.md)

----
url: https://docs.nestjs.com/v8/fundamentals/circular-dependency
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Circular dependency](https://docs.nestjs.com/v8/fundamentals/circular-dependency#circular-dependency)
* [Forward reference](https://docs.nestjs.com/v8/fundamentals/circular-dependency#forward-reference)
* [ModuleRef class alternative](https://docs.nestjs.com/v8/fundamentals/circular-dependency#moduleref-class-alternative)
* [Module forward reference](https://docs.nestjs.com/v8/fundamentals/circular-dependency#module-forward-reference)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/fundamentals/circular-dependency.md "Suggest Edits")

### Circular dependency

A circular dependency occurs when two classes depend on each other. For example, class A needs class B, and class B also needs class A. Circular dependencies can arise in Nest between modules and between providers.

While circular dependencies should be avoided where possible, you can't always do so. In such cases, Nest enables resolving circular dependencies between providers in two ways. In this chapter, we describe using **forward referencing** as one technique, and using the **ModuleRef** class to retrieve a provider instance from the DI container as another.

We also describe resolving circular dependencies between modules.

> **Warning** A circular dependency might also be caused when using "barrel files"/index.ts files to group imports. Barrel files should be omitted when it comes to module/provider classes. For example, barrel files should not be used when importing files within the same directory as the barrel file, i.e. `cats/cats.controller` should not import `cats` to import the `cats/cats.service` file. For more details please also see [this github issue](https://github.com/nestjs/nest/issues/1181#issuecomment-430197191).

#### Forward reference[#](/fundamentals/circular-dependency#forward-reference)

A **forward reference** allows Nest to reference classes which aren't yet defined using the `forwardRef()` utility function. For example, if `CatsService` and `CommonService` depend on each other, both sides of the relationship can use `@Inject()` and the `forwardRef()` utility to resolve the circular dependency. Otherwise Nest won't instantiate them because all of the essential metadata won't be available. Here's an example:

cats.service.ts

JS TS

```typescript

@Injectable()
export class CatsService {
  constructor(
    @Inject(forwardRef(() => CommonService))
    private commonService: CommonService,
  ) {}
}
```

```typescript

@Injectable()
@Dependencies(forwardRef(() => CommonService))
export class CatsService {
  constructor(commonService) {
    this.commonService = commonService;
  }
}
```

> **Hint** The `forwardRef()` function is imported from the `@nestjs/common` package.

That covers one side of the relationship. Now let's do the same with `CommonService`:

common.service.ts

JS TS

```typescript

@Injectable()
export class CommonService {
  constructor(
    @Inject(forwardRef(() => CatsService))
    private catsService: CatsService,
  ) {}
}
```

```typescript

@Injectable()
@Dependencies(forwardRef(() => CatsService))
export class CommonService {
  constructor(catsService) {
    this.catsService = catsService;
  }
}
```

> **Warning** The order of instantiation is indeterminate. Make sure your code does not depend on which constructor is called first. Having circular dependencies depend on providers with `Scope.REQUEST` can lead to undefined dependencies. More information available [here](https://github.com/nestjs/nest/issues/5778)

#### ModuleRef class alternative[#](/fundamentals/circular-dependency#moduleref-class-alternative)

An alternative to using `forwardRef()` is to refactor your code and use the `ModuleRef` class to retrieve a provider on one side of the (otherwise) circular relationship. Learn more about the `ModuleRef` utility class [here](/v8/fundamentals/module-ref).

#### Module forward reference[#](/fundamentals/circular-dependency#module-forward-reference)

In order to resolve circular dependencies between modules, use the same `forwardRef()` utility function on both sides of the modules association. For example:

common.module.ts

JS TS

```typescript

@Module({
  imports: [forwardRef(() => CatsModule)],
})
export class CommonModule {}
```

----
url: https://docs.nestjs.com/v10/recipes/router-module
----

* [Router module](https://docs.nestjs.com/v10/recipes/router-module#router-module)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/recipes/router-module.md "Suggest Edits")

### Router module

> **Hint** This chapter is only relevant to HTTP-based applications.

In an HTTP application (for example, REST API), the route path for a handler is determined by concatenating the (optional) prefix declared for the controller (inside the `@Controller` decorator), and any path specified in the method's decorator (e.g, `@Get('users')`). You can learn more about that in [this section](/controllers#routing). Additionally, you can define a [global prefix](/v10/faq/global-prefix) for all routes registered in your application, or enable [versioning](/v10/techniques/versioning).

Also, there are edge-cases when defining a prefix at a module-level (and so for all controllers registered inside that module) may come in handy. For example, imagine a REST application that exposes several different endpoints being used by a specific portion of your application called "Dashboard". In such a case, instead of repeating the `/dashboard` prefix within each controller, you could use a utility `RouterModule` module, as follows:

```typescript

@Module({
  imports: [
    DashboardModule,
    RouterModule.register([
      {
        path: 'dashboard',
        module: DashboardModule,
      },
    ]),
  ],
})
export class AppModule {}
```

> **Hint** The `RouterModule` class is exported from the `@nestjs/core` package.

In addition, you can define hierarchical structures. This means each module can have `children` modules. The children modules will inherit their parent's prefix. In the following example, we'll register the `AdminModule` as a parent module of `DashboardModule` and `MetricsModule`.

```typescript

@Module({
  imports: [
    AdminModule,
    DashboardModule,
    MetricsModule,
    RouterModule.register([
      {
        path: 'admin',
        module: AdminModule,
        children: [
          {
            path: 'dashboard',
            module: DashboardModule,
          },
          {
            path: 'metrics',
            module: MetricsModule,
          },
        ],
      },
    ])
  ],
});
```

> **Hint** This feature should be used very carefully, as overusing it can make code difficult to maintain over time.

In the example above, any controller registered inside the `DashboardModule` will have an extra `/admin/dashboard` prefix (as the module concatenates paths from top to bottom - recursively - parent to children). Likewise, each controller defined inside the `MetricsModule` will have an additional module-level prefix `/admin/metrics`.

----
url: https://docs.nestjs.com/v9/security/csrf
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [CSRF Protection](https://docs.nestjs.com/v9/security/csrf#csrf-protection)
* [Use with Express (default)](https://docs.nestjs.com/v9/security/csrf#use-with-express-default)
* [Use with Fastify](https://docs.nestjs.com/v9/security/csrf#use-with-fastify)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/security/csrf.md "Suggest Edits")

### CSRF Protection

Cross-site request forgery (also known as CSRF or XSRF) is a type of malicious exploit of a website where **unauthorized** commands are transmitted from a user that the web application trusts. To mitigate this kind of attack you can use the [csurf](https://github.com/expressjs/csurf) package.

#### Use with Express (default)[#](/security/csrf#use-with-express-default)

Start by installing the required package:

```bash

$ npm i --save csurf
```

> **Warning** This package is deprecated, refer to [`csurf` docs](https://github.com/expressjs/csurf#csurf) for more information.

> **Warning** As explained in the [`csurf` docs](https://github.com/expressjs/csurf#csurf), this middleware requires either session middleware or `cookie-parser` to be initialized first. Please see that documentation for further instructions.

Once the installation is complete, apply the `csurf` middleware as global middleware.

```typescript

import * as csurf from 'csurf';
// ...
// somewhere in your initialization file
app.use(csurf());
```

#### Use with Fastify[#](/security/csrf#use-with-fastify)

Start by installing the required package:

```bash

$ npm i --save @fastify/csrf-protection
```

Once the installation is complete, register the `@fastify/csrf-protection` plugin, as follows:

```typescript

import fastifyCsrf from '@fastify/csrf-protection';
// ...
// somewhere in your initialization file after registering some storage plugin
await app.register(fastifyCsrf);
```

> **Warning** As explained in the `@fastify/csrf-protection` docs [here](https://github.com/fastify/csrf-protection#usage), this plugin requires a storage plugin to be initialized first. Please, see that documentation for further instructions.

----
url: https://docs.nestjs.com/v8/cli/monorepo
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Workspaces](https://docs.nestjs.com/v8/cli/monorepo#workspaces)
* [Standard mode](https://docs.nestjs.com/v8/cli/monorepo#standard-mode)
* [Monorepo mode](https://docs.nestjs.com/v8/cli/monorepo#monorepo-mode)
* [Workspace projects](https://docs.nestjs.com/v8/cli/monorepo#workspace-projects)
* [Applications](https://docs.nestjs.com/v8/cli/monorepo#applications)
* [Libraries](https://docs.nestjs.com/v8/cli/monorepo#libraries)
* [CLI properties](https://docs.nestjs.com/v8/cli/monorepo#cli-properties)
* [Global compiler options](https://docs.nestjs.com/v8/cli/monorepo#global-compiler-options)
* [Global generate options](https://docs.nestjs.com/v8/cli/monorepo#global-generate-options)
* [Project-specific generate options](https://docs.nestjs.com/v8/cli/monorepo#project-specific-generate-options)
* [Specified compiler](https://docs.nestjs.com/v8/cli/monorepo#specified-compiler)
* [Webpack options](https://docs.nestjs.com/v8/cli/monorepo#webpack-options)
* [Assets](https://docs.nestjs.com/v8/cli/monorepo#assets)
* [Project properties](https://docs.nestjs.com/v8/cli/monorepo#project-properties)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/cli/workspaces.md "Suggest Edits")

### Workspaces

Nest has two modes for organizing code:

* **standard mode**: useful for building individual project-focused applications that have their own dependencies and settings, and don't need to optimize for sharing modules, or optimizing complex builds. This is the default mode.
* **monorepo mode**: this mode treats code artifacts as part of a lightweight **monorepo**, and may be more appropriate for teams of developers and/or multi-project environments. It automates parts of the build process to make it easy to create and compose modular components, promotes code re-use, makes integration testing easier, makes it easy to share project-wide artifacts like `eslint` rules and other configuration policies, and is easier to use than alternatives like github submodules. Monorepo mode employs the concept of a **workspace**, represented in the `nest-cli.json` file, to coordinate the relationship between the components of the monorepo.

It's important to note that virtually all of Nest's features are independent of your code organization mode. The **only** affect of this choice is how your projects are composed and how build artifacts are generated. All other functionality, from the CLI to core modules to add-on modules work the same in either mode.

```bash

nest new my-project
```

```bash

cd my-project
nest generate app my-app
```

> **Warning** The conversion of a standard mode structure to monorepo only works for projects that have followed the canonical Nest project structure. Specifically, during conversion, the schematic attempts to relocate the `src` and `test` folders in a project folder beneath the `apps` folder in the root. If a project does not use this structure, the conversion will fail or produce unreliable results.

#### Workspace projects[#](/cli/monorepo#workspace-projects)

A monorepo uses the concept of a workspace to manage its member entities. Workspaces are composed of **projects**. A project may be either:

* an **application**: a full Nest application including a `main.ts` file to bootstrap the application. Aside from compile and build considerations, an application-type project within a workspace is functionally identical to an application within a *standard mode* structure.
* a **library**: a library is a way of packaging a general purpose set of features (modules, providers, controllers, etc.) that can be used within other projects. A library cannot run on its own, and has no `main.ts` file. Read more about libraries [here](/v8/cli/libraries).

All workspaces have a **default project** (which should be an application-type project). This is defined by the top-level `"root"` property in the `nest-cli.json` file, which points at the root of the default project (see [CLI properties](/cli/monorepo#cli-properties) below for more details). Usually, this is the **standard mode** application you started with, and later converted to a monorepo using `nest generate app`. When you follow these steps, this property is populated automatically.

Default projects are used by `nest` commands like `nest build` and `nest start` when a project name is not supplied.

For example, in the above monorepo structure, running

```bash

$ nest start
```

will start up the `my-project` app. To start `my-app`, we'd use:

```bash

$ nest start my-app
```

#### Applications[#](/cli/monorepo#applications)

Application-type projects, or what we might informally refer to as just "applications", are complete Nest applications that you can run and deploy. You generate an application-type project with `nest generate app`.

This command automatically generates a project skeleton, including the standard `src` and `test` folders from the [typescript starter](https://github.com/nestjs/typescript-starter). Unlike standard mode, an application project in a monorepo does not have any of the package dependency (`package.json`) or other project configuration artifacts like `.prettierrc` and `.eslintrc.js`. Instead, the monorepo-wide dependencies and config files are used.

However, the schematic does generate a project-specific `tsconfig.app.json` file in the root folder of the project. This config file automatically sets appropriate build options, including setting the compilation output folder properly. The file extends the top-level (monorepo) `tsconfig.json` file, so you can manage global settings monorepo-wide, but override them if needed at the project level.

#### Libraries[#](/cli/monorepo#libraries)

As mentioned, library-type projects, or simply "libraries", are packages of Nest components that need to be composed into applications in order to run. You generate a library-type project with `nest generate library`. Deciding what belongs in a library is an architectural design decision. We discuss libraries in depth in the [libraries](/v8/cli/libraries) chapter.

#### CLI properties[#](/cli/monorepo#cli-properties)

Nest keeps the metadata needed to organize, build and deploy both standard and monorepo structured projects in the `nest-cli.json` file. Nest automatically adds to and updates this file as you add projects, so you usually do not have to think about it or edit its contents. However, there are some settings you may want to change manually, so it's helpful to have an overview understanding of the file.

After running the steps above to create a monorepo, our `nest-cli.json` file looks like this:

```javascript

{
  "collection": "@nestjs/schematics",
  "sourceRoot": "apps/my-project/src",
  "monorepo": true,
  "root": "apps/my-project",
  "compilerOptions": {
    "webpack": true,
    "tsConfigPath": "apps/my-project/tsconfig.app.json"
  },
  "projects": {
    "my-project": {
      "type": "application",
      "root": "apps/my-project",
      "entryFile": "main",
      "sourceRoot": "apps/my-project/src",
      "compilerOptions": {
        "tsConfigPath": "apps/my-project/tsconfig.app.json"
      }
    },
    "my-app": {
      "type": "application",
      "root": "apps/my-app",
      "entryFile": "main",
      "sourceRoot": "apps/my-app/src",
      "compilerOptions": {
        "tsConfigPath": "apps/my-app/tsconfig.app.json"
      }
    }
  }
}
```

| Property Name       | Property Value Type | Description                                                                                                                                                                                                                           |
| ------------------- | ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `webpack`           | boolean             | If `true`, use [webpack compiler](https://webpack.js.org/). If `false` or not present, use `tsc`. In monorepo mode, the default is `true` (use webpack), in standard mode, the default is `false` (use `tsc`). See below for details. |
| `tsConfigPath`      | string              | (**monorepo only**) Points at the file containing the `tsconfig.json` settings that will be used when `nest build` or `nest start` is called without a `project` option (e.g., when the default project is built or started).         |
| `webpackConfigPath` | string              | Points at a webpack options file. If not specified, Nest looks for the file `webpack.config.js`. See below for more details.                                                                                                          |
| `deleteOutDir`      | boolean             | If `true`, whenever the compiler is invoked, it will first remove the compilation output directory (as configured in `tsconfig.json`, where the default is `./dist`).                                                                 |
| `assets`            | array               | Enables automatically distributing non-TypeScript assets whenever a compilation step begins (asset distribution does **not** happen on incremental compiles in `--watch` mode). See below for details.                                |
| `watchAssets`       | boolean             | If `true`, run in watch-mode, watching **all** non-TypeScript assets. (For more fine-grained control of the assets to watch, see [Assets](cli/monorepo#assets) section below).                                                        |

#### Global generate options[#](/cli/monorepo#global-generate-options)

These properties specify the default generate options to be used by the `nest generate` command.

| Property Name | Property Value Type | Description                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| ------------- | ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `spec`        | boolean *or* object | If the value is boolean, a value of `true` enables `spec` generation by default and a value of `false` disables it. A flag passed on the CLI command line overrides this setting, as does a project-specific `generateOptions` setting (more below). If the value is an object, each key represents a schematic name, and the boolean value determines whether the default spec generation is enabled / disabled for that specific schematic. |

The following example uses a boolean value to specify that spec file generation should be disabled by default for all projects:

```javascript

{
  "generateOptions": {
    "spec": false
  },
  ...
}
```

In the following example, `spec` file generation is disabled only for `service` schematics (e.g., `nest generate service...`):

```javascript

{
  "generateOptions": {
    "spec": {
      "service": false
    }
  },
  ...
}
```

> **Warning** When specifying the `spec` as an object, the key for the generation schematic does not currently support automatic alias handling. This means that specifying a key as for example `service: false` and trying to generate a service via the alias `s`, the spec would still be generated. To make sure both the normal schematic name and the alias work as intended, specify both the normal command name as well as the alias, as seen below.
>
> ```javascript
>
> {
>   "generateOptions": {
>     "spec": {
>       "service": false,
>       "s": false
>     }
>   },
>   ...
> }
> ```

#### Project-specific generate options[#](/cli/monorepo#project-specific-generate-options)

In addition to providing global generate options, you may also specify project-specific generate options. The project specific generate options follow the exact same format as the global generate options, but are specified directly on each project.

Project-specific generate options override global generate options.

```javascript

{
  "projects": {
    "cats-project": {
      "generateOptions": {
        "spec": {
          "service": false
        }
      },
      ...
    }
  },
  ...
}
```

> **Warning** The order of precedence for generate options is as follows. Options specified on the CLI command line take precedence over project-specific options. Project-specific options override global options.

#### Specified compiler[#](/cli/monorepo#specified-compiler)

The reason for the different default compilers is that for larger projects (e.g., more typical in a monorepo) webpack can have significant advantages in build times and in producing a single file bundling all project components together. If you wish to generate individual files, set `"webpack"` to `false`, which will cause the build process to use `tsc`.

#### Webpack options[#](/cli/monorepo#webpack-options)

The webpack options file can contain standard [webpack configuration options](https://webpack.js.org/configuration/). For example, to tell webpack to bundle `node_modules` (which are excluded by default), add the following to `webpack.config.js`:

```javascript

module.exports = {
  externals: [],
};
```

Since the webpack config file is a JavaScript file, you can even expose a function that takes default options and returns a modified object:

```javascript

module.exports = function (options) {
  return {
    ...options,
    externals: [],
  };
};
```

#### Assets[#](/cli/monorepo#assets)

TypeScript compilation automatically distributes compiler output (`.js` and `.d.ts` files) to the specified output directory. It can also be convenient to distribute non-TypeScript files, such as `.graphql` files, `images`, `.html` files and other assets. This allows you to treat `nest build` (and any initial compilation step) as a lightweight **development build** step, where you may be editing non-TypeScript files and iteratively compiling and testing. The assets should be located in the `src` folder otherwise they will not be copied.

The value of the `assets` key should be an array of elements specifying the files to be distributed. The elements can be simple strings with `glob`-like file specs, for example:

```typescript

"assets": ["**/*.graphql"],
"watchAssets": true,
```

For finer control, the elements can be objects with the following keys:

* `"include"`: `glob`-like file specifications for the assets to be distributed
* `"exclude"`: `glob`-like file specifications for assets to be **excluded** from the `include` list
* `"outDir"`: a string specifying the path (relative to the root folder) where the assets should be distributed. Defaults to the same output directory configured for compiler output.
* `"watchAssets"`: boolean; if `true`, run in watch mode watching specified assets

For example:

```typescript

"assets": [
  { "include": "**/*.graphql", "exclude": "**/omitted.graphql", "watchAssets": true },
]
```

> **Warning** Setting `watchAssets` in a top-level `compilerOptions` property overrides any `watchAssets` settings within the `assets` property.

#### Project properties[#](/cli/monorepo#project-properties)

This element exists only for monorepo-mode structures. You generally should not edit these properties, as they are used by Nest to locate projects and their configuration options within the monorepo.

----
url: https://docs.nestjs.com/v6/controllers
----

* [Controllers](https://docs.nestjs.com/v6/controllers#controllers)
* [Routing](https://docs.nestjs.com/v6/controllers#routing)
* [Request object](https://docs.nestjs.com/v6/controllers#request-object)
* [Resources](https://docs.nestjs.com/v6/controllers#resources)
* [Route wildcards](https://docs.nestjs.com/v6/controllers#route-wildcards)
* [Status code](https://docs.nestjs.com/v6/controllers#status-code)
* [Headers](https://docs.nestjs.com/v6/controllers#headers)
* [Redirection](https://docs.nestjs.com/v6/controllers#redirection)
* [Route parameters](https://docs.nestjs.com/v6/controllers#route-parameters)
* [Sub-Domain Routing](https://docs.nestjs.com/v6/controllers#sub-domain-routing)
* [Scopes](https://docs.nestjs.com/v6/controllers#scopes)
* [Asynchronicity](https://docs.nestjs.com/v6/controllers#asynchronicity)
* [Request payloads](https://docs.nestjs.com/v6/controllers#request-payloads)
* [Handling errors](https://docs.nestjs.com/v6/controllers#handling-errors)
* [Full resource sample](https://docs.nestjs.com/v6/controllers#full-resource-sample)
* [Getting up and running](https://docs.nestjs.com/v6/controllers#getting-up-and-running)
* [Appendix: Library-specific approach](https://docs.nestjs.com/v6/controllers#appendix-library-specific-approach)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/controllers.md "Suggest Edits")

### Controllers

Controllers are responsible for handling incoming **requests** and returning **responses** to the client.

A controller's purpose is to receive specific requests for the application. The **routing** mechanism controls which controller receives which requests. Frequently, each controller has more than one route, and different routes can perform different actions.

In order to create a basic controller, we use classes and **decorators**. Decorators associate classes with required metadata and enable Nest to create a routing map (tie requests to the corresponding controllers).

#### Routing[#](/controllers#routing)

In the following example we'll use the `@Controller()` decorator, which is **required** to define a basic controller. We'll specify an optional route path prefix of `cats`. Using a path prefix in a `@Controller()` decorator allows us to easily group a set of related routes, and minimize repetitive code. For example, we may choose to group a set of routes that manage interactions with a customer entity under the route `/customers`. In that case, we could specify the path prefix `customers` in the `@Controller()` decorator so that we don't have to repeat that portion of the path for each route in the file.

cats.controller.ts

JS TS

```typescript

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

@Controller('cats')
export class CatsController {
  @Get()
  findAll(): string {
    return 'This action returns all cats';
  }
}
```

```typescript

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

@Controller('cats')
export class CatsController {
  @Get()
  findAll() {
    return 'This action returns all cats';
  }
}
```

> **Hint** To create a controller using the CLI, simply execute the `$ nest g controller cats` command.

The `@Get()` HTTP request method decorator before the `findAll()` method tells Nest to create a handler for a specific endpoint for HTTP requests. The endpoint corresponds to the HTTP request method (GET in this case) and the route path. What is the route path? The route path for a handler is determined by concatenating the (optional) prefix declared for the controller, and any path specified in the request decorator. Since we've declared a prefix for every route ( `cats`), and haven't added any path information in the decorator, Nest will map `GET /cats` requests to this handler. As mentioned, the path includes both the optional controller path prefix **and** any path string declared in the request method decorator. For example, a path prefix of `customers` combined with the decorator `@Get('profile')` would produce a route mapping for requests like `GET /customers/profile`.

In our example above, when a GET request is made to this endpoint, Nest routes the request to our user-defined `findAll()` method. Note that the method name we choose here is completely arbitrary. We obviously must declare a method to bind the route to, but Nest doesn't attach any significance to the method name chosen.

This method will return a 200 status code and the associated response, which in this case is just a string. Why does that happen? To explain, we'll first introduce the concept that Nest employs two **different** options for manipulating responses:

|                        |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Standard (recommended) | Using this built-in method, when a request handler returns a JavaScript object or array, it will **automatically** be serialized to JSON. When it returns a JavaScript primitive type (e.g., `string`, `number`, `boolean`), however, Nest will send just the value without attempting to serialize it. This makes response handling simple: just return the value, and Nest takes care of the rest. Furthermore, the response's **status code** is always 200 by default, except for POST requests which use 201. We can easily change this behavior by adding the `@HttpCode(...)` decorator at a handler-level (see [Status codes](controllers#status-code)). |
| Library-specific       | We can use the library-specific (e.g., Express) [response object](http://expressjs.com/en/api.html#res), which can be injected using the `@Res()` decorator in the method handler signature (e.g., `findAll(@Res() response)`). With this approach, you have the ability (and the responsibility), to use the native response handling methods exposed by that object. For example, with Express, you can construct responses using code like `response.status(200).send()`                                                                                                                                                                                      |

> **Warning** You cannot use both approaches at the same time. Nest detects when the handler is using either `@Res()` or `@Next()`, indicating you have chosen the library-specific option. If both approaches are used at the same time, the Standard approach is **automatically disabled** for this single route and will no longer work as expected.

Handlers often need access to the client **request** details. Nest provides access to the [request object](http://expressjs.com/en/api.html#req) of the underlying platform (Express by default). We can access the request object by instructing Nest to inject it by adding the `@Req()` decorator to the handler's signature.

cats.controller.ts

JS TS

```typescript

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

@Controller('cats')
export class CatsController {
  @Get()
  findAll(@Req() request: Request): string {
    return 'This action returns all cats';
  }
}
```

```typescript

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

@Controller('cats')
export class CatsController {
  @Get()
  @Bind(Req())
  findAll(request) {
    return 'This action returns all cats';
  }
}
```

> **Hint** In order to take advantage of `express` typings (as in the `request: Request` parameter example above), install `@types/express` package.

The request object represents the HTTP request and has properties for the request query string, parameters, HTTP headers, and body (read more [here](http://expressjs.com/en/api.html#req)). In most cases, it's not necessary to grab these properties manually. We can use dedicated decorators instead, such as `@Body()` or `@Query()`, which are available out of the box. Below is a list of the provided decorators and the plain platform-specific objects they represent.

|                           |                                     |
| ------------------------- | ----------------------------------- |
| `@Request()`              | `req`                               |
| `@Response(), @Res()`\*   | `res`                               |
| `@Next()`                 | `next`                              |
| `@Session()`              | `req.session`                       |
| `@Param(key?: string)`    | `req.params` / `req.params[key]`    |
| `@Body(key?: string)`     | `req.body` / `req.body[key]`        |
| `@Query(key?: string)`    | `req.query` / `req.query[key]`      |
| `@Headers(name?: string)` | `req.headers` / `req.headers[name]` |
| `@Ip()`                   | `req.ip`                            |

\* For compatibility with typings across underlying HTTP platforms (e.g., Express and Fastify), Nest provides `@Res()` and `@Response()` decorators. `@Res()` is simply an alias for `@Response()`. Both directly expose the underlying native platform `response` object interface. When using them, you should also import the typings for the underlying library (e.g., `@types/express`) to take full advantage. Note that when you inject either `@Res()` or `@Response()` in a method handler, you put Nest into **Library-specific mode** for that handler, and you become responsible for managing the response. When doing so, you must issue some kind of response by making a call on the `response` object (e.g., `res.json(...)` or `res.send(...)`), or the HTTP server will hang.

> **Hint** To learn how to create your own custom decorators, visit [this](/v6/custom-decorators) chapter.

#### Resources[#](/controllers#resources)

Earlier, we defined an endpoint to fetch the cats resource (**GET** route). We'll typically also want to provide an endpoint that creates new records. For this, let's create the **POST** handler:

cats.controller.ts

JS TS

```typescript

import { Controller, Get, Post } from '@nestjs/common';

@Controller('cats')
export class CatsController {
  @Post()
  create(): string {
    return 'This action adds a new cat';
  }

  @Get()
  findAll(): string {
    return 'This action returns all cats';
  }
}
```

```typescript

import { Controller, Get, Post } from '@nestjs/common';

@Controller('cats')
export class CatsController {
  @Post()
  create() {
    return 'This action adds a new cat';
  }

  @Get()
  findAll() {
    return 'This action returns all cats';
  }
}
```

It's that simple. Nest provides the rest of the standard HTTP request endpoint decorators in the same fashion - `@Put()`, `@Delete()`, `@Patch()`, `@Options()`, `@Head()`, and `@All()`. Each represents its respective HTTP request method.

#### Route wildcards[#](/controllers#route-wildcards)

Pattern based routes are supported as well. For instance, the asterisk is used as a wildcard, and will match any combination of characters.

```typescript

@Get('ab*cd')
findAll() {
  return 'This route uses a wildcard';
}
```

The `'ab*cd'` route path will match `abcd`, `ab_cd`, `abecd`, and so on. The characters `?`, `+`, `*`, and `()` may be used in a route path, and are subsets of their regular expression counterparts. The hyphen ( `-`) and the dot (`.`) are interpreted literally by string-based paths.

#### Status code[#](/controllers#status-code)

As mentioned, the response **status code** is always **200** by default, except for POST requests which are **201**. We can easily change this behavior by adding the `@HttpCode(...)` decorator at a handler level.

```typescript

@Post()
@HttpCode(204)
create() {
  return 'This action adds a new cat';
}
```

> **Hint** Import `HttpCode` from the `@nestjs/common` package.

Often, your status code isn't static but depends on various factors. In that case, you can use a library-specific **response** (inject using `@Res()`) object (or, in case of an error, throw an exception).

#### Headers[#](/controllers#headers)

To specify a custom response header, you can either use a `@Header()` decorator or a library-specific response object (and call `res.header()` directly).

```typescript

@Post()
@Header('Cache-Control', 'none')
create() {
  return 'This action adds a new cat';
}
```

> **Hint** Import `Header` from the `@nestjs/common` package.

#### Redirection[#](/controllers#redirection)

To redirect a response to a specific URL, you can either use a `@Redirect()` decorator or a library-specific response object (and call `res.redirect()` directly).

`@Redirect()` takes a required `url` argument, and an optional `statusCode` argument. The `statusCode` defaults to `302` (`Found`) if omitted.

```typescript

@Get()
@Redirect('https://nestjs.com', 301)
```

Sometimes you may want to determine the HTTP status code or the redirect URL dynamically. Do this by returning an object from the route handler method with the shape:

```json

{
  "url": string,
  "statusCode": number
}
```

Returned values will override any arguments passed to the `@Redirect()` decorator. For example:

```typescript

@Get('docs')
@Redirect('https://docs.nestjs.com', 302)
getDocs(@Query('version') version) {
  if (version && version === '5') {
    return { url: 'https://docs.nestjs.com/v5/' };
  }
}
```

#### Route parameters[#](/controllers#route-parameters)

Routes with static paths won't work when you need to accept **dynamic data** as part of the request (e.g., `GET /cats/1` to get cat with id `1`). In order to define routes with parameters, we can add route parameter **tokens** in the path of the route to capture the dynamic value at that position in the request URL. The route parameter token in the `@Get()` decorator example below demonstrates this usage. Route parameters declared in this way can be accessed using the `@Param()` decorator, which should be added to the method signature.

JS TS

```typescript

@Get(':id')
findOne(@Param() params): string {
  console.log(params.id);
  return `This action returns a #${params.id} cat`;
}
```

```typescript

@Get(':id')
@Bind(Param())
findOne(params) {
  console.log(params.id);
  return `This action returns a #${params.id} cat`;
}
```

`@Param()` is used to decorate a method parameter (`params` in the example above), and makes the **route** parameters available as properties of that decorated method parameter inside the body of the method. As seen in the code above, we can access the `id` parameter by referencing `params.id`. You can also pass in a particular parameter token to the decorator, and then reference the route parameter directly by name in the method body.

> **Hint** Import `Param` from the `@nestjs/common` package.

JS TS

```typescript

@Get(':id')
findOne(@Param('id') id): string {
  return `This action returns a #${id} cat`;
}
```

```typescript

@Get(':id')
@Bind(Param('id'))
findOne(id) {
  return `This action returns a #${id} cat`;
}
```

#### Sub-Domain Routing[#](/controllers#sub-domain-routing)

The `@Controller` decorator can take a `host` option to require that the HTTP host of the incoming requests matches some specific value.

```typescript

@Controller({ host: 'admin.example.com' })
export class AdminController {
  @Get()
  index(): string {
    return 'Admin page';
  }
}
```

> **Warning** Since **Fastify** lacks support for nested routers, when using sub-domain routing, the (default) Express adapter should be used instead.

Similar to a route `path`, the `hosts` option can use tokens to capture the dynamic value at that position in the host name. The host parameter token in the `@Controller()` decorator example below demonstrates this usage. Host parameters declared in this way can be accessed using the `@HostParam()` decorator, which should be added to the method signature.

```typescript

@Controller({ host: ':account.example.com' })
export class AccountController {
  @Get()
  getInfo(@HostParam('account') account: string) {
    return account;
  }
}
```

#### Scopes[#](/controllers#scopes)

For people coming from different programming language backgrounds, it might be unexpected to learn that in Nest, almost everything is shared across incoming requests. We have a connection pool to the database, singleton services with global state, etc. Remember that Node.js doesn't follow the request/response Multi-Threaded Stateless Model in which every request is processed by a separate thread. Hence, using singleton instances is fully **safe** for our applications.

However, there are edge-cases when request-based lifetime of the controller may be the desired behavior, for instance per-request caching in GraphQL applications, request tracking or multi-tenancy. Learn how to control scopes [here](/v6/fundamentals/injection-scopes).

#### Asynchronicity[#](/controllers#asynchronicity)

We love modern JavaScript and we know that data extraction is mostly **asynchronous**. That's why Nest supports and works well with `async` functions.

> **Hint** Learn more about `async / await` feature [here](https://kamilmysliwiec.com/typescript-2-1-introduction-async-await)

Every async function has to return a `Promise`. This means that you can return a deferred value that Nest will be able to resolve by itself. Let's see an example of this:

cats.controller.ts

JS TS

```typescript

@Get()
async findAll(): Promise<any[]> {
  return [];
}
```

```typescript

@Get()
async findAll() {
  return [];
}
```

The above code is fully valid. Furthermore, Nest route handlers are even more powerful by being able to return RxJS [observable streams](http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html). Nest will automatically subscribe to the source underneath and take the last emitted value (once the stream is completed).

cats.controller.ts

JS TS

```typescript

@Get()
findAll(): Observable<any[]> {
  return of([]);
}
```

```typescript

@Get()
findAll() {
  return of([]);
}
```

```typescript

export class CreateCatDto {
  name: string;
  age: number;
  breed: string;
}
```

It has only three basic properties. Thereafter we can use the newly created DTO inside the `CatsController`:

cats.controller.ts

JS TS

```typescript

@Post()
async create(@Body() createCatDto: CreateCatDto) {
  return 'This action adds a new cat';
}
```

```typescript

@Post()
@Bind(Body())
async create(createCatDto) {
  return 'This action adds a new cat';
}
```

#### Handling errors[#](/controllers#handling-errors)

There's a separate chapter about handling errors (i.e., working with exceptions) [here](/v6/exception-filters).

#### Full resource sample[#](/controllers#full-resource-sample)

Below is an example that makes use of several of the available decorators to create a basic controller. This controller exposes a couple of methods to access and manipulate internal data.

cats.controller.ts

JS TS

```typescript

import { Controller, Get, Query, Post, Body, Put, Param, Delete } from '@nestjs/common';
import { CreateCatDto, UpdateCatDto, ListAllEntities } from './dto';

@Controller('cats')
export class CatsController {
  @Post()
  create(@Body() createCatDto: CreateCatDto) {
    return 'This action adds a new cat';
  }

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

  @Get(':id')
  findOne(@Param('id') id: string) {
    return `This action returns a #${id} cat`;
  }

  @Put(':id')
  update(@Param('id') id: string, @Body() updateCatDto: UpdateCatDto) {
    return `This action updates a #${id} cat`;
  }

  @Delete(':id')
  remove(@Param('id') id: string) {
    return `This action removes a #${id} cat`;
  }
}
```

```typescript

import { Controller, Get, Query, Post, Body, Put, Param, Delete } from '@nestjs/common';

@Controller('cats')
export class CatsController {
  @Post()
  @Bind(Body())
  create(@Body() createCatDto) {
    return 'This action adds a new cat';
  }

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

  @Get(':id')
  @Bind(Param('id'))
  findOne(@Param('id') id) {
    return `This action returns a #${id} cat`;
  }

  @Put(':id')
  @Bind(Param('id'), Body())
  update(@Param('id') id, @Body() updateCatDto) {
    return `This action updates a #${id} cat`;
  }

  @Delete(':id')
  @Bind(Param('id'))
  remove(@Param('id') id) {
    return `This action removes a #${id} cat`;
  }
}
```

#### Getting up and running[#](/controllers#getting-up-and-running)

With the above controller fully defined, Nest still doesn't know that `CatsController` exists and as a result won't create an instance of this class.

Controllers always belong to a module, which is why we include the `controllers` array within the `@Module()` decorator. Since we haven't yet defined any other modules except the root `AppModule`, we'll use that to introduce the `CatsController`:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { CatsController } from './cats/cats.controller';

@Module({
  controllers: [CatsController],
})
export class AppModule {}
```

We attached the metadata to the module class using the `@Module()` decorator, and Nest can now easily reflect which controllers have to be mounted.

## Hoodies, T-shirts, and accessories!

Support our future development by shopping in the official store!

[See more](https://nestjs.threadless.com/ "Shop | NestJS - A node.js framework built on top of TypeScript")

#### Appendix: Library-specific approach[#](/controllers#appendix-library-specific-approach)

So far we've discussed the Nest standard way of manipulating responses. The second way of manipulating the response is to use a library-specific [response object](http://expressjs.com/en/api.html#res). In order to inject a particular response object, we need to use the `@Res()` decorator. To show the differences, let's rewrite the `CatsController` to the following:

JS TS

```typescript

import { Controller, Get, Post, Res, HttpStatus } from '@nestjs/common';
import { Response } from 'express';

@Controller('cats')
export class CatsController {
  @Post()
  create(@Res() res: Response) {
    res.status(HttpStatus.CREATED).send();
  }

  @Get()
  findAll(@Res() res: Response) {
     res.status(HttpStatus.OK).json([]);
  }
}
```

```typescript

import { Controller, Get, Post, Bind, Res, Body, HttpStatus } from '@nestjs/common';

@Controller('cats')
export class CatsController {
  @Post()
  @Bind(Res(), Body())
  create(res, createCatDto) {
    res.status(HttpStatus.CREATED).send();
  }

  @Get()
  @Bind(Res())
  findAll(res) {
     res.status(HttpStatus.OK).json([]);
  }
}
```

Though this approach works, and does in fact allow for more flexibility in some ways by providing full control of the response object (headers manipulation, library-specific features, and so on), it should be used with care. In general, the approach is much less clear and does have some disadvantages. The main disadvantages are that you lose compatibility with Nest features that depend on Nest standard response handling, such as Interceptors and the `@HttpCode()` decorator. Also, your code can become platform-dependent (as underlying libraries may have different APIs on the response object), and harder to test (you'll have to mock the response object, etc.).

As a result, the Nest standard approach should always be preferred when possible.

----
url: https://docs.nestjs.com/v4/graphql/quick-start
----

### Quick Start

GraphQL is a new way of thinking about the APIs. Here's a great [comparison](https://dev-blog.apollodata.com/graphql-vs-rest-5d425123e34b) between GraphQL and REST. In this set of articles, I'm not gonna explain what the GraphQL is, but rather show how to work with the dedicated `@nestjs/graphql` module.

The `GraphQLModule` is nothing more than a wrapper around the [Apollo](https://www.apollographql.com/) server. We don't reinvent the wheel but provide a ready to use a module instead, that brings a clean way to play with the GraphQL and Nest together.

#### Installation

Firstly, we need to install the required packages:

TypeScript

```typescript

$ npm i --save @nestjs/graphql apollo-server-express graphql-tools graphql
```

#### Apollo Middleware

Once the packages are installed, we can apply the GraphQL middleware provided by the `apollo-server-express` package:

app.module.ts

JavaScript TypeScript

TypeScript

```typescript

import {
  Module,
  MiddlewaresConsumer,
  NestModule,
  RequestMethod,
} from '@nestjs/common';
import { graphqlExpress } from 'apollo-server-express';
import { GraphQLModule } from '@nestjs/graphql';

@Module({
  imports: [GraphQLModule],
})
export class ApplicationModule implements NestModule {
  configure(consumer: MiddlewaresConsumer) {
    consumer
      .apply(graphqlExpress(req => ({ schema: {}, rootValue: req })))
      .forRoutes({ path: '/graphql', method: RequestMethod.ALL });
  }
}
```

TypeScript

```typescript

import { Module, RequestMethod } from '@nestjs/common';
import { graphqlExpress } from 'apollo-server-express';
import { GraphQLModule } from '@nestjs/graphql';

@Module({
  imports: [GraphQLModule],
})
export class ApplicationModule {
  configure(consumer) {
    consumer
      .apply(graphqlExpress(req => ({ schema: {}, rootValue: req })))
      .forRoutes({ path: '/graphql', method: RequestMethod.ALL });
  }
}
```

That's all. We passed an empty object as a GraphQL `schema` and `req` (request object) as a `rootValue` for now. Additionally, there're a few other available `graphqlExpress` options and you can read about them [here](https://www.apollographql.com/docs/apollo-server/setup.html#graphqlOptions).

#### Schema

To create a schema, we are using `GraphQLFactory` which is a part of the `@nestjs/graphql` package. This component provides a `createSchema()` method that accepts the same object as a `makeExecutableSchema()` function, well-described [here](https://www.apollographql.com/docs/graphql-tools/generate-schema.html#makeExecutableSchema).

The schema options object demand at least `resolvers` and the `typeDefs` property. You can pass type definitions manually, or use a utility `mergeTypesByPaths()` method of the `GraphQLFactory`. Let's have a look on the following example:

app.module.ts

JavaScript TypeScript

TypeScript

```typescript

import {
  Module,
  MiddlewaresConsumer,
  NestModule,
  RequestMethod,
} from '@nestjs/common';
import { graphqlExpress } from 'apollo-server-express';
import { GraphQLModule, GraphQLFactory } from '@nestjs/graphql';

@Module({
  imports: [GraphQLModule],
})
export class ApplicationModule implements NestModule {
  constructor(private readonly graphQLFactory: GraphQLFactory) {}

  configure(consumer: MiddlewaresConsumer) {
    const typeDefs = this.graphQLFactory.mergeTypesByPaths('./**/*.graphql');
    const schema = this.graphQLFactory.createSchema({ typeDefs });

    consumer
      .apply(graphqlExpress(req => ({ schema, rootValue: req })))
      .forRoutes({ path: '/graphql', method: RequestMethod.ALL });
  }
}
```

TypeScript

```typescript

import { Module,  RequestMethod } from '@nestjs/common';
import { graphqlExpress } from 'apollo-server-express';
import { GraphQLModule, GraphQLFactory } from '@nestjs/graphql';

@Dependencies(GraphQLFactory)
@Module({
  imports: [GraphQLModule],
})
export class ApplicationModule {
  constructor(graphQLFactory) {
    this.graphQLFactory = graphQLFactory;
  }

  configure(consumer) {
    const typeDefs = this.graphQLFactory.mergeTypesByPaths('./**/*.graphql');
    const schema = this.graphQLFactory.createSchema({ typeDefs });

    consumer
      .apply(graphqlExpress(req => ({ schema, rootValue: req })))
      .forRoutes({ path: '/graphql', method: RequestMethod.ALL });
  }
}
```

> **Hint** Learn more about GraphQL schema [here](http://graphql.org/learn/schema/).

In this case, the `GraphQLFactory` will go through each directory, and merge files that have a `.graphql` extension. Afterwards, we can create a schema using these particular type definitions. The `resolvers` will be reflected **automatically**.

[Here](https://www.apollographql.com/docs/graphql-tools/resolvers.html) you can read more about what the **resolvers map** actually is.

#### Sponsors

[](https://valor-software.com/)

Nest is an MIT-licensed open source project. It can grow thanks to the support by these awesome people. If you'd like to join them, please read more [here](https://opencollective.com/nest). Thanks!

[](https://opencollective.com/nest/backer/0/website)[](https://opencollective.com/nest/backer/1/website)[](https://opencollective.com/nest/backer/2/website)[](https://opencollective.com/nest/backer/3/website)[](https://opencollective.com/nest/backer/4/website)[](https://opencollective.com/nest/backer/5/website)[](https://opencollective.com/nest/backer/6/website)[](https://opencollective.com/nest/backer/7/website)[](https://opencollective.com/nest/backer/8/website)[](https://opencollective.com/nest/backer/9/website)[](https://opencollective.com/nest/backer/10/website)[](https://opencollective.com/nest/backer/11/website)[](https://opencollective.com/nest/backer/12/website)[](https://opencollective.com/nest/backer/13/website)[](https://opencollective.com/nest/backer/14/website)[](https://opencollective.com/nest/backer/15/website)[](https://opencollective.com/nest/backer/16/website)[](https://opencollective.com/nest/backer/17/website)[](https://opencollective.com/nest/backer/18/website)[](https://opencollective.com/nest/backer/19/website)[](https://opencollective.com/nest/backer/20/website)[](https://opencollective.com/nest/backer/21/website)[](https://opencollective.com/nest/backer/22/website)[](https://opencollective.com/nest/backer/23/website)[](https://opencollective.com/nest/backer/24/website)[](https://opencollective.com/nest/backer/25/website)[](https://opencollective.com/nest/backer/26/website)[](https://opencollective.com/nest/backer/27/website)[](https://opencollective.com/nest/backer/28/website)[](https://opencollective.com/nest/backer/29/website)

[Become a sponsor](https://opencollective.com/nest)

----
url: https://docs.nestjs.com/security/rate-limiting
----

[Skip to content](#content)

On this page

* [Rate Limiting](https://docs.nestjs.com/security/rate-limiting#rate-limiting)
* [Multiple Throttler Definitions](https://docs.nestjs.com/security/rate-limiting#multiple-throttler-definitions)
* [Customization](https://docs.nestjs.com/security/rate-limiting#customization)
* [Proxies](https://docs.nestjs.com/security/rate-limiting#proxies)
* [WebSockets](https://docs.nestjs.com/security/rate-limiting#websockets)
* [GraphQL](https://docs.nestjs.com/security/rate-limiting#graphql)
* [Configuration](https://docs.nestjs.com/security/rate-limiting#configuration)
* [Async Configuration](https://docs.nestjs.com/security/rate-limiting#async-configuration)
* [Storages](https://docs.nestjs.com/security/rate-limiting#storages)
* [Time Helpers](https://docs.nestjs.com/security/rate-limiting#time-helpers)
* [Migration Guide](https://docs.nestjs.com/security/rate-limiting#migration-guide)

### Rate Limiting

A common technique to protect applications from brute-force attacks is **rate limiting**. To get started, install the `@nestjs/throttler` package.

```bash

$ npm i --save @nestjs/throttler
```

Once the installation is complete, configure the `ThrottlerModule` like any other Nest package, with the `forRoot()` or `forRootAsync()` method.

app.module.ts

JS TS

```typescript

@Module({
  imports: [
    ThrottlerModule.forRoot({
      throttlers: [
        {
          ttl: 60000,
          limit: 10,
        },
      ],
    }),
  ],
})
export class AppModule {}
```

This sets the global options for the guarded routes of your application: `ttl`, the time to live in milliseconds, and `limit`, the maximum number of requests within the `ttl`.

Once the module has been imported, choose how to bind the `ThrottlerGuard`. Any kind of binding described in the [guards](/guards#binding-guards) chapter works. For example, to bind the guard globally, add this provider to any module:

```typescript

{
  provide: APP_GUARD,
  useClass: ThrottlerGuard
}
```

#### Multiple Throttler Definitions[#](/security/rate-limiting#multiple-throttler-definitions)

Sometimes you want multiple throttling definitions, such as no more than 3 calls per second, 20 calls per 10 seconds, and 100 calls per minute. To do so, define them in the array with named options. You can reference these names later in the `@SkipThrottle()` and `@Throttle()` decorators to change the options per route or controller.

app.module.ts

JS TS

```typescript

@Module({
  imports: [
    ThrottlerModule.forRoot([
      {
        name: 'short',
        ttl: 1000,
        limit: 3,
      },
      {
        name: 'medium',
        ttl: 10000,
        limit: 20
      },
      {
        name: 'long',
        ttl: 60000,
        limit: 100
      }
    ]),
  ],
})
export class AppModule {}
```

#### Customization[#](/security/rate-limiting#customization)

You may want to bind the guard to a controller or globally, but disable rate limiting for one or more endpoints. For that, use the `@SkipThrottle()` decorator to disable the throttler for an entire class or a single route. The `@SkipThrottle()` decorator also accepts an object with string keys (throttler names) and boolean values. This is useful when you want to exclude *most* of a controller, but not every route, and to configure skipping per throttler set if you have more than one. If you don't pass an object, the default is `{ default: true }`.

```typescript

@SkipThrottle()
@Controller('users')
export class UsersController {}
```

The `@SkipThrottle()` decorator can skip a route or a class, or negate the skipping of a route within a skipped class.

```typescript

@SkipThrottle()
@Controller('users')
export class UsersController {
  // Rate limiting is applied to this route.
  @SkipThrottle({ default: false })
  dontSkip() {
    return 'List users work with Rate limiting.';
  }
  // This route will skip rate limiting.
  doSkip() {
    return 'List users work without Rate limiting.';
  }
}
```

The `@Throttle()` decorator overrides the `limit` and `ttl` set in the root module, to give tighter or looser security options. You can apply it to a class or a method. Since version 5, the decorator takes an object whose keys are throttler set names and whose values are objects with `limit` and `ttl` keys (and, optionally, `blockDuration`), similar to the options passed to the root module. If you didn't set a name in the root options, use the key `default`:

```typescript

// Override default configuration for Rate limiting and duration.
@Throttle({ default: { limit: 3, ttl: 60000 } })
@Get()
findAll() {
  return "List users works with custom rate limiting.";
}
```

#### Proxies[#](/security/rate-limiting#proxies)

If your application runs behind a proxy server, configure the HTTP adapter to trust the proxy. See the `trust proxy` options of [Express](http://expressjs.com/en/guide/behind-proxies.html) and [Fastify](https://www.fastify.io/docs/latest/Reference/Server/#trustproxy).

The following example enables `trust proxy` for the Express adapter:

main.ts

JS TS

```typescript

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module.js';
import { NestExpressApplication } from '@nestjs/platform-express';

async function bootstrap() {
  const app = await NestFactory.create<NestExpressApplication>(AppModule);
  app.set('trust proxy', 'loopback'); // Trust requests from the loopback address
  await app.listen(3000);
}

await bootstrap();
```

```typescript

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module.js';
import { NestExpressApplication } from '@nestjs/platform-express';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.set('trust proxy', 'loopback'); // Trust requests from the loopback address
  await app.listen(3000);
}

await bootstrap();
```

For the Fastify adapter, pass the `trustProxy` option instead:

main.ts

JS TS

```typescript

const app = await NestFactory.create<NestFastifyApplication>(
  AppModule,
  new FastifyAdapter({ trustProxy: 'loopback' }), // Trust requests from the loopback address
);
```

```typescript

const app = await NestFactory.create(
  AppModule,
  new FastifyAdapter({ trustProxy: 'loopback' }), // Trust requests from the loopback address
);
```

> **Warning** In Fastify v5.12.1 and later, which `@nestjs/platform-fastify` v12 installs, a number passed as `trustProxy` (a hop count such as `1`) makes Fastify trust no proxy at all. `request.ip` is then the proxy's address, and the throttler counts every client behind the proxy as one. Pass the address or range of your proxy instead, as in the example above.

Enabling `trust proxy` lets you retrieve the original IP address from the `X-Forwarded-For` header. You can also override the `getTracker()` method to extract the IP address from this header instead of relying on `req.ip`. The following example is for Express:

throttler-behind-proxy.guard.ts

JS TS

```typescript

import { ThrottlerGuard } from '@nestjs/throttler';
import { Injectable } from '@nestjs/common';

@Injectable()
export class ThrottlerBehindProxyGuard extends ThrottlerGuard {
  protected async getTracker(req: Record<string, any>): Promise<string> {
    return req.ips.length ? req.ips[0] : req.ip; // individualize IP extraction to meet your own needs
  }
}
```

> **Hint** On Fastify, `request.ips` is ordered from the closest address to the furthest, so its first entry is the proxy's address, and this guard would count every client behind the proxy as one. Keep the default tracker there, which uses `request.ip`. See the request object API for [Express](https://expressjs.com/en/api.html#req.ips) and [Fastify](https://www.fastify.io/docs/latest/Reference/Request/).

#### WebSockets[#](/security/rate-limiting#websockets)

This module works with WebSockets, but it requires extending the `ThrottlerGuard` class and overriding its `handleRequest()` method, as follows:

```typescript

@Injectable()
export class WsThrottlerGuard extends ThrottlerGuard {
  async handleRequest(requestProps: ThrottlerRequest): Promise<boolean> {
    const { context, limit, ttl, throttler, blockDuration, generateKey } =
      requestProps;

    const client = context.switchToWs().getClient();
    const tracker = client._socket.remoteAddress;
    const key = generateKey(context, tracker, throttler.name);
    const { totalHits, timeToExpire, isBlocked, timeToBlockExpire } =
      await this.storageService.increment(
        key,
        ttl,
        limit,
        blockDuration,
        throttler.name,
      );

    // Throw an error when the user reached their limit.
    if (isBlocked) {
      await this.throwThrottlingException(context, {
        limit,
        ttl,
        key,
        tracker,
        totalHits,
        timeToExpire,
        isBlocked,
        timeToBlockExpire,
      });
    }

    return true;
  }
}
```

> **Hint** The example above reads the client address from `client._socket`, which works with the `@nestjs/platform-ws` package. If you use `@nestjs/platform-socket.io`, replace `client._socket` with `client.conn`.

Keep the following in mind when working with WebSockets:

* Don't register this guard with `APP_GUARD` or `app.useGlobalGuards()`. Global guards also run for HTTP routes, and this guard handles only WebSocket contexts.
* When a limit is reached, Nest emits an `exception` event, so make sure a listener is ready for it.

> **Hint** When you configure [multiple throttler definitions](/security/rate-limiting#multiple-throttler-definitions), `handleRequest()` runs once for each throttler set. Pass `throttler.name` from the `ThrottlerRequest` when generating the storage key and when calling `storageService.increment()`, as shown above, so that each named throttler tracks its own limit.

#### GraphQL[#](/security/rate-limiting#graphql)

The `ThrottlerGuard` also works with GraphQL requests. Again, extend the guard, but this time override the `getRequestResponse()` method:

```typescript

@Injectable()
export class GqlThrottlerGuard extends ThrottlerGuard {
  getRequestResponse(context: ExecutionContext) {
    const gqlCtx = GqlExecutionContext.create(context);
    const ctx = gqlCtx.getContext();
    return { req: ctx.req, res: ctx.res };
  }
}
```

#### Configuration[#](/security/rate-limiting#configuration)

The following options are valid for each object in the array passed to the `ThrottlerModule`:

|                    |                                                                                                                                                                                                                               |
| ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `name`             | the name used internally to track which throttler set is in use. Defaults to `default` if not passed. For named throttlers, the name is also appended to the rate limit response headers (e.g., `X-RateLimit-Remaining-long`) |
| `ttl`              | the number of milliseconds that each request is kept in storage                                                                                                                                                               |
| `limit`            | the maximum number of requests within the TTL                                                                                                                                                                                 |
| `blockDuration`    | the number of milliseconds for which requests are blocked once the limit is reached. Defaults to the `ttl` value                                                                                                              |
| `ignoreUserAgents` | an array of regular expressions matching user agents to ignore when throttling requests                                                                                                                                       |
| `skipIf`           | a function that takes the `ExecutionContext` and returns a `boolean` to short-circuit the throttler logic. Like `@SkipThrottle()`, but based on the request                                                                   |
| `getTracker`       | a function that overrides the default tracker logic for this throttler set (see the table below)                                                                                                                              |
| `generateKey`      | a function that overrides the default key generation logic for this throttler set (see the table below)                                                                                                                       |
| `setHeaders`       | whether to add the rate limit headers to the response. Defaults to `true`                                                                                                                                                     |

To set up a custom storage, or to apply some of the above options globally to every throttler set, pass an options object instead of an array. Define the throttler sets in its `throttlers` property, and use the options in the following table:

|                    |                                                                                                                                                                                                                                                      |
| ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `storage`          | a custom storage service that keeps track of the throttling. See [Storages](/security/rate-limiting#storages)                                                                                                                                        |
| `ignoreUserAgents` | an array of regular expressions matching user agents to ignore when throttling requests                                                                                                                                                              |
| `skipIf`           | a function that takes the `ExecutionContext` and returns a `boolean` to short-circuit the throttler logic. Like `@SkipThrottle()`, but based on the request                                                                                          |
| `throttlers`       | an array of throttler sets, defined using the table above                                                                                                                                                                                            |
| `errorMessage`     | a `string`, or a function that takes the `ExecutionContext` and the `ThrottlerLimitDetail` and returns a `string`, which overrides the default throttler error message                                                                               |
| `getTracker`       | a function that takes the request and the `ExecutionContext` and returns a `string` (or a `Promise` of one), overriding the default logic of the `getTracker()` method                                                                               |
| `generateKey`      | a function that takes the `ExecutionContext`, the tracker `string`, and the throttler name as a `string`, and returns the `string` used as the storage key for the rate limit value. This overrides the default logic of the `generateKey()` method  |
| `setHeaders`       | whether to add the rate limit headers to the response. Defaults to `true`                                                                                                                                                                            |
| `ipv6SubnetPrefix` | the prefix length used to group IPv6 addresses into a single tracker, so that a client cannot evade the limit by rotating through the addresses of its subnet. Applies only to the built-in tracker (not to a custom `getTracker`). Defaults to `64` |

#### Async Configuration[#](/security/rate-limiting#async-configuration)

You may want to load your rate limiting configuration asynchronously. Use the `forRootAsync()` method, which supports dependency injection and `async` methods.

One approach is to use a factory function:

```typescript

@Module({
  imports: [
    ThrottlerModule.forRootAsync({
      imports: [ConfigModule],
      inject: [ConfigService],
      useFactory: (config: ConfigService) => [
        {
          ttl: config.get('THROTTLE_TTL'),
          limit: config.get('THROTTLE_LIMIT'),
        },
      ],
    }),
  ],
})
export class AppModule {}
```

You can also use the `useClass` syntax:

```typescript

@Module({
  imports: [
    ThrottlerModule.forRootAsync({
      imports: [ConfigModule],
      useClass: ThrottlerConfigService,
    }),
  ],
})
export class AppModule {}
```

This works as long as `ThrottlerConfigService` implements the `ThrottlerOptionsFactory` interface.

#### Storages[#](/security/rate-limiting#storages)

The built-in storage is an in-memory cache that keeps track of requests until their TTL has passed. You can pass your own storage to the `storage` option of the `ThrottlerModule`, as long as the class implements the `ThrottlerStorage` interface.

For distributed servers, you can use the community storage provider for [Redis](https://github.com/jmcdo29/nest-lab/tree/main/packages/throttler-storage-redis) to have a single source of truth.

> **Note**`ThrottlerStorage` can be imported from `@nestjs/throttler`.

#### Time Helpers[#](/security/rate-limiting#time-helpers)

`@nestjs/throttler` exports five helper functions that make timings more readable than raw millisecond values: `seconds`, `minutes`, `hours`, `days`, and `weeks`. Each returns the equivalent number of milliseconds. For example, `seconds(5)` returns `5000`.

#### Migration Guide[#](/security/rate-limiting#migration-guide)

When migrating to version 5 or later, wrapping your options in an array is enough for most applications.

If you use a custom storage, wrap your `ttl` and `limit` in an array and assign it to the `throttlers` property of the options object.

The `@SkipThrottle()` decorator now takes an optional object with string keys (the throttler names) and boolean values, which defaults to `{ default: true }`.

The `@Throttle()` decorator now takes an object with string keys, the names of the throttler sets (again, `'default'` if no name is set), and values that are objects with `limit` and `ttl` keys.

> **Warning** The `ttl` is now in **milliseconds**. To keep your `ttl` in seconds for readability, use the `seconds` helper from this package, which multiplies the value by 1000.

For more information, see the [5.0 changelog entry](https://github.com/nestjs/throttler/blob/master/CHANGELOG.md#501).

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/security/rate-limiting.md)

----
url: https://docs.nestjs.com/techniques/streaming-files
----

[](https://srv.carbonads.net/ads/click/x/GTND4277CVSD5KJUCAYLYKQUF67D62Q7CW7DTZ3JCAAI623WCTBIP2QKC6SIC2JWCTAI6277FTYDVKQ7CT7DPKJJHEYI55QLCAYD653ECTNCYBZ52K)[Afraid of a surprise AWS bill? Not on the new Free Plan. Start for free. ](https://srv.carbonads.net/ads/click/x/GTND4277CVSD5KJUCAYLYKQUF67D62Q7CW7DTZ3JCAAI623WCTBIP2QKC6SIC2JWCTAI6277FTYDVKQ7CT7DPKJJHEYI55QLCAYD653ECTNCYBZ52K)[ads via Carbon](http://carbonads.net/?utm_source=nestjscom\&utm_medium=ad_via_link\&utm_campaign=in_unit\&utm_term=carbon)

### File upload and streaming

This chapter covers files in both directions: receiving files that clients upload, and [streaming files](/http/file-upload#streaming-files) back to clients.

To handle file uploads, Nest provides a built-in module based on the [multer](https://github.com/expressjs/multer) middleware package for Express. Multer handles data posted in the `multipart/form-data` format, which is primarily used to upload files with an HTTP `POST` request. The module is fully configurable, so you can adjust its behavior to your application's requirements.

> **Warning** Multer cannot process data that is not in the `multipart/form-data` format.

> **Hint** If your application runs on the `FastifyAdapter`, the same interceptors are available from the `@nestjs/platform-fastify` package, backed by [@fastify/multipart](https://github.com/fastify/fastify-multipart) instead of Multer, and the decorators and pipes described in this chapter work unchanged. Only the import path changes - see the [Fastify](/http/file-upload#fastify) section below.

For type safety, install the Multer type definitions:

```shell

$ npm i -D @types/multer
```

With this package installed, you can use the `Express.Multer.File` type (import the `Express` namespace with `import { Express } from 'express'`).

#### Basic example[#](/http/file-upload#basic-example)

To upload a single file, bind the `FileInterceptor()` interceptor to the route handler and extract the file from the request with the `@UploadedFile()` decorator.

JS TS

```typescript

@Post('upload')
@UseInterceptors(FileInterceptor('file'))
uploadFile(@UploadedFile() file: Express.Multer.File) {
  console.log(file);
}
```

```typescript

@Post('upload')
@UseInterceptors(FileInterceptor('file'))
@Bind(UploadedFile())
uploadFile(file) {
  console.log(file);
}
```

> **Hint** The `FileInterceptor()` decorator is exported from the `@nestjs/platform-express` package. The `@UploadedFile()` decorator is exported from `@nestjs/common`.

The `FileInterceptor()` decorator takes two arguments:

* `fieldName`: the name of the HTML form field that holds the file
* `options`: an optional object of type `MulterOptions`. This is the same object the Multer constructor accepts (see the [Multer options](https://github.com/expressjs/multer#multeropts)).

> **Warning**`FileInterceptor()` may not be compatible with third party cloud providers like Google Firebase or others.

#### File validation[#](/http/file-upload#file-validation)

You will often want to validate incoming file metadata, such as the file size or MIME type. To do so, create a [pipe](/pipes) and bind it to the parameter decorated with `@UploadedFile()`. The following example implements a basic file size validation pipe:

```typescript

import { PipeTransform, Injectable, ArgumentMetadata } from '@nestjs/common';

@Injectable()
export class FileSizeValidationPipe implements PipeTransform {
  transform(value: any, metadata: ArgumentMetadata) {
    // "value" is an object containing the file's attributes and metadata
    const oneKb = 1000;
    return value.size < oneKb;
  }
}
```

Use it together with the `FileInterceptor` as follows:

```typescript

@Post('file')
@UseInterceptors(FileInterceptor('file'))
uploadFileAndValidate(@UploadedFile(
  new FileSizeValidationPipe(),
  // other pipes can be added here
) file: Express.Multer.File, ) {
  return file;
}
```

For common cases, Nest provides a built-in pipe, `ParseFilePipe`, which also standardizes how new file validations are added:

```typescript

@Post('file')
uploadFileAndPassValidation(
  @Body() body: SampleDto,
  @UploadedFile(
    new ParseFilePipe({
      validators: [
        // ... Set of file validator instances here
      ]
    })
  )
  file: Express.Multer.File,
) {
  return {
    body,
    file: file.buffer.toString(),
  };
}
```

`ParseFilePipe` requires an array of file validators to execute. The validator interface is described below. The pipe also accepts two **optional** options:

|                       |                                                                                                   |
| --------------------- | ------------------------------------------------------------------------------------------------- |
| `errorHttpStatusCode` | The HTTP status code to be thrown in case **any** validator fails. Default is `400` (BAD REQUEST) |
| `exceptionFactory`    | A factory which receives the error message and returns an error.                                  |

Validators used by this pipe are either built-in implementations or your own subclasses of the abstract `FileValidator` class:

```typescript

export abstract class FileValidator<TValidationOptions = Record<string, any>> {
  constructor(protected readonly validationOptions: TValidationOptions) {}

  /**
   * Indicates if this file should be considered valid, according to the options passed in the constructor.
   * @param file the file from the request object
   */
  abstract isValid(file?: any): boolean | Promise<boolean>;

  /**
   * Builds an error message in case the validation fails.
   * @param file the file from the request object
   */
  abstract buildErrorMessage(file: any): string;
}
```

> **Hint** The `isValid()` method can be asynchronous. For type safety, type the `file` parameter as `Express.Multer.File` when you use Express (the default HTTP adapter).

A `FileValidator` receives the file object and validates it according to the options passed to its constructor. Nest provides two built-in implementations:

* `MaxFileSizeValidator` checks that the file's size is less than the provided value, in bytes.
* `FileTypeValidator` checks that the file's MIME type matches the given string or regular expression. By default, it determines the MIME type from the file content's [magic number](https://www.ibm.com/support/pages/what-magic-number).

The following snippet uses both validators with `ParseFilePipe`:

```typescript

@UploadedFile(
  new ParseFilePipe({
    validators: [
      new MaxFileSizeValidator({ maxSize: 1000 }),
      new FileTypeValidator({ fileType: 'image/jpeg' }),
    ],
  }),
)
file: Express.Multer.File,
```

> **Hint** If the list of validators grows long, define the array in a separate file and import it as a named constant, such as `fileValidators`.

Alternatively, compose the validators with the `ParseFilePipeBuilder` class. The builder instantiates each validator for you, so you pass only their options:

```typescript

@UploadedFile(
  new ParseFilePipeBuilder()
    .addFileTypeValidator({
      fileType: 'jpeg',
    })
    .addMaxSizeValidator({
      maxSize: 1000
    })
    .build({
      errorHttpStatusCode: HttpStatus.UNPROCESSABLE_ENTITY
    }),
)
file: Express.Multer.File,
```

> **Hint** A file is required by default. To make it optional, pass `fileIsRequired: false` in the options of the `build()` method (next to `errorHttpStatusCode`).

```typescript

@Post('upload')
@UseInterceptors(FilesInterceptor('files'))
uploadFile(@UploadedFiles() files: Array<Express.Multer.File>) {
  console.log(files);
}
```

```typescript

@Post('upload')
@UseInterceptors(FilesInterceptor('files'))
@Bind(UploadedFiles())
uploadFile(files) {
  console.log(files);
}
```

> **Hint** The `FilesInterceptor()` decorator is exported from the `@nestjs/platform-express` package. The `@UploadedFiles()` decorator is exported from `@nestjs/common`.

#### Validating an array of files[#](/http/file-upload#validating-an-array-of-files)

To validate an array of uploaded files, pass a pipe built with `ParseFilePipeBuilder` to the `@UploadedFiles()` decorator. The registered validators run against each file in the array.

JS TS

```typescript

@Post('upload')
@UseInterceptors(FilesInterceptor('files', 5))
uploadFiles(
  @UploadedFiles(
    new ParseFilePipeBuilder()
      .addFileTypeValidator({
        fileType: /^image\/(jpeg|png|gif)$/,
      })
      .addMaxSizeValidator({ maxSize: 5242880 })
      .build({
        errorHttpStatusCode: HttpStatus.UNPROCESSABLE_ENTITY,
      }),
  )
  files: Array<Express.Multer.File>,
) {
  console.log(files);
}
```

#### Multiple files[#](/http/file-upload#multiple-files)

To upload multiple files under different field names, use the `FileFieldsInterceptor()` decorator. It takes two arguments:

* `uploadedFields`: an array of objects, each with a required `name` property (the field name) and an optional `maxCount` property
* `options`: an optional `MulterOptions` object, as described above

When using `FileFieldsInterceptor()`, extract files from the `request` with the `@UploadedFiles()` decorator.

JS TS

```typescript

@Post('upload')
@UseInterceptors(FileFieldsInterceptor([
  { name: 'avatar', maxCount: 1 },
  { name: 'background', maxCount: 1 },
]))
uploadFile(@UploadedFiles() files: { avatar?: Express.Multer.File[], background?: Express.Multer.File[] }) {
  console.log(files);
}
```

```typescript

@Post('upload')
@Bind(UploadedFiles())
@UseInterceptors(FileFieldsInterceptor([
  { name: 'avatar', maxCount: 1 },
  { name: 'background', maxCount: 1 },
]))
uploadFile(files) {
  console.log(files);
}
```

#### Any files[#](/http/file-upload#any-files)

To accept files under any field names, use the `AnyFilesInterceptor()` decorator. It accepts an optional `options` object, as described above.

When using `AnyFilesInterceptor()`, extract files from the `request` with the `@UploadedFiles()` decorator.

JS TS

```typescript

@Post('upload')
@UseInterceptors(AnyFilesInterceptor())
uploadFile(@UploadedFiles() files: Array<Express.Multer.File>) {
  console.log(files);
}
```

```typescript

@Post('upload')
@Bind(UploadedFiles())
@UseInterceptors(AnyFilesInterceptor())
uploadFile(files) {
  console.log(files);
}
```

#### No files[#](/http/file-upload#no-files)

To accept `multipart/form-data` without allowing file uploads, use the `NoFilesInterceptor`. It sets the multipart fields as properties of the request body. A request that contains files is rejected with a `BadRequestException`.

```typescript

@Post('upload')
@UseInterceptors(NoFilesInterceptor())
handleMultiPartData(@Body() body) {
  console.log(body)
}
```

#### Default options[#](/http/file-upload#default-options)

You can pass Multer options to each file interceptor, as described above. To set default options instead, call the static `register()` method when you import the `MulterModule`. It accepts all [Multer options](https://github.com/expressjs/multer#multeropts).

```typescript

MulterModule.register({
  dest: './upload',
});
```

> **Hint** The `MulterModule` class is exported from the `@nestjs/platform-express` package.

Options passed to a file interceptor take precedence over these defaults. Starting with NestJS v12.0.4, the two `limits` objects are merged key by key, so a route that sets only `limits.fileSize` keeps a default such as `limits.files`. If one of them is a function, the interceptor's `limits` replaces the default one entirely.

#### Async configuration[#](/http/file-upload#async-configuration)

To set `MulterModule` options asynchronously instead of statically, use the `registerAsync()` method. As with most dynamic modules, it supports several techniques for async configuration.

One technique is to use a factory function:

```typescript

MulterModule.registerAsync({
  useFactory: () => ({
    dest: './upload',
  }),
});
```

Like other [factory providers](/fundamentals/custom-providers#factory-providers-usefactory), the factory function can be `async` and can inject dependencies through `inject`.

```typescript

MulterModule.registerAsync({
  imports: [ConfigModule],
  useFactory: async (configService: ConfigService) => ({
    dest: configService.get<string>('MULTER_DEST'),
  }),
  inject: [ConfigService],
});
```

Alternatively, you can configure the `MulterModule` using a class instead of a factory, as shown below:

```typescript

MulterModule.registerAsync({
  useClass: MulterConfigService,
});
```

The construction above instantiates `MulterConfigService` inside `MulterModule` and calls its `createMulterOptions()` method to obtain the options object. For this to work, `MulterConfigService` must implement the `MulterOptionsFactory` interface:

```typescript

@Injectable()
class MulterConfigService implements MulterOptionsFactory {
  createMulterOptions(): MulterModuleOptions {
    return {
      dest: './upload',
    };
  }
}
```

If you want to reuse an existing options provider instead of creating a private copy inside the `MulterModule`, use the `useExisting` syntax.

```typescript

MulterModule.registerAsync({
  imports: [ConfigModule],
  useExisting: ConfigService,
});
```

You can also pass `extraProviders` to the `registerAsync()` method. These providers are merged with the module's providers.

```typescript

MulterModule.registerAsync({
  imports: [ConfigModule],
  useClass: ConfigService,
  extraProviders: [MyAdditionalProvider],
});
```

This is useful when the factory function or the class constructor needs additional dependencies.

#### Memory usage and storage[#](/http/file-upload#memory-usage-and-storage)

By default, Multer uses its in-memory storage engine (`memoryStorage()`): every uploaded file is read completely into memory and exposed as a `Buffer` on `file.buffer` before your route handler runs. This is convenient for small files (avatars or CSV imports), but each in-flight upload occupies as much memory as its size, so large files or many concurrent uploads can quickly exhaust the memory of your process.

> **Warning** Multer does not limit the size of uploaded files by default. When you keep files in memory, always set `limits.fileSize`.

##### File size limit[#](/http/file-upload#file-size-limit)

Use the `limits` option to reject files that are too large. When a limit is exceeded, Nest responds with a `413 File too large` error (for `fileSize`) or `400 Bad Request` (for other limits, such as `files`) and the route handler is not called.

```typescript

@Post('upload')
@UseInterceptors(
  FileInterceptor('file', {
    limits: { fileSize: 5 * 1024 * 1024 }, // 5 MB
  }),
)
uploadFile(@UploadedFile() file: Express.Multer.File) {
  console.log(file.size);
}
```

> **Hint** Unlike `MaxFileSizeValidator`, which runs after the whole file has been received, `limits.fileSize` makes Multer stop storing the file and reject the request as soon as the limit is reached, so oversized files never fully reach memory or disk. See the [Multer limits](https://github.com/expressjs/multer#limits) for the full list of options.

##### Field name limits[#](/http/file-upload#field-name-limits)

Field names such as `user[address][city]` or `tags[2]` build nested objects and arrays in the request body. Two limits bound them: `fieldNestingDepth`, the number of nesting levels (`a[b][c]` has 2), and `fieldArrayIndexLimit`, the highest array index (`tags[2]` uses index 2). A request that exceeds either one is rejected with a `400 Bad Request` response. Starting with NestJS v12.1.4, they default to 32 and 1000 respectively (Multer leaves them unlimited), so that a single request cannot build an arbitrarily deep body or a huge array. Set a limit to `Infinity` to lift it.

##### Disk storage[#](/http/file-upload#disk-storage)

To keep memory usage constant regardless of file size, write uploads to disk with the `diskStorage()` engine. Multer then streams each file to disk as it arrives, and the file object exposes `destination`, `filename` and `path` instead of `buffer`.

```typescript

import { extname } from 'node:path';
import { randomUUID } from 'node:crypto';
import { diskStorage } from 'multer';

@Post('upload')
@UseInterceptors(
  FileInterceptor('file', {
    storage: diskStorage({
      destination: './uploads',
      filename: (req, file, cb) => {
        cb(null, `${randomUUID()}${extname(file.originalname)}`);
      },
    }),
    limits: { fileSize: 1024 * 1024 * 1024 }, // 1 GB
  }),
)
uploadFile(@UploadedFile() file: Express.Multer.File) {
  console.log(file.path);
}
```

> **Hint** The `diskStorage()` and `memoryStorage()` functions are exported from the `multer` package. As a shorthand, pass `dest: './uploads'` to store files on disk under random names. If you pass a `destination` function instead of a string, you are responsible for creating the directory.

To apply the same storage and limits to every file interceptor in a module, set them as [default options](/http/file-upload#default-options) or with [async configuration](/http/file-upload#async-configuration).

Files stored on disk are not removed automatically once your route handler has run. Delete them (for example with `unlink()` from `fs/promises`) once you have processed them, including when processing fails. Starting with NestJS v12.1.4, if a pipe rejects the request (for example, because `ParseFilePipe` validation fails), the route handler does not run, and the stored files are removed once the error response has been sent.

##### Sending files to external storage[#](/http/file-upload#sending-files-to-external-storage)

To store uploads in S3, Cloudflare R2 or another external store without buffering them in memory or writing a temporary file, use a storage engine that streams each file to its destination as it arrives. The [`@nestjs/storage`](/application/file-storage) package provides one, `uploadToDisk()`, which you pass as the `storage` option of `FileInterceptor()`. See [Upload product photos](/application/file-storage#upload-product-photos). Any other Multer [storage engine](https://github.com/expressjs/multer/blob/main/StorageEngine.md) works the same way.

> **Hint** On the `FastifyAdapter`, you can also receive the file as a stream inside the route handler with `FileStreamInterceptor()`. See [Streaming uploads](/http/file-upload#streaming-uploads).

#### Fastify[#](/http/file-upload#fastify)

Starting with NestJS v12.1, applications running on the `FastifyAdapter` (see [Performance (Fastify)](/http/performance)) can handle file uploads with the same API, backed by the [@fastify/multipart](https://github.com/fastify/fastify-multipart) plugin instead of Multer. The interceptors described in this chapter take the same arguments and options, populate the request in the same way, and fail with the same error responses, while `@UploadedFile()`, `@UploadedFiles()`, `ParseFilePipe`, `ParseFilePipeBuilder` and the built-in file validators work unchanged.

First, install the plugin:

```bash

$ npm i @fastify/multipart
```

There is no need to register it: the `FastifyAdapter` registers the plugin automatically as soon as your application uses one of the upload interceptors (in applications that don't, it is not registered at all). If the package is not installed, the application fails to start with an error naming it.

Next, import the interceptors from `@nestjs/platform-fastify/multipart` instead of `@nestjs/platform-express`. The rest of the controller stays the same, except that files are typed as `UploadedMultipartFile`:

```typescript

import {
  Controller,
  FileTypeValidator,
  MaxFileSizeValidator,
  ParseFilePipe,
  Post,
  UploadedFile,
  UseInterceptors,
} from '@nestjs/common';
import {
  FileInterceptor,
  UploadedMultipartFile,
} from '@nestjs/platform-fastify/multipart';

@Controller('files')
export class FilesController {
  @Post('upload')
  @UseInterceptors(FileInterceptor('file'))
  uploadFile(
    @UploadedFile(
      new ParseFilePipe({
        validators: [
          new MaxFileSizeValidator({ maxSize: 1000 }),
          new FileTypeValidator({ fileType: 'image/png' }),
        ],
      }),
    )
    file: UploadedMultipartFile,
  ) {
    console.log(file);
  }
}
```

> **Hint** Everything exported from `@nestjs/platform-fastify/multipart` is also re-exported from the `@nestjs/platform-fastify` package root. The interceptors only work with the `FastifyAdapter`: with the `ExpressAdapter`, the application fails to start, so keep importing them from `@nestjs/platform-express` there.

The table below maps the Express API to its Fastify counterpart:

| `@nestjs/platform-express`                                                                                            | `@nestjs/platform-fastify/multipart`                                                     |
| --------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- |
| `FileInterceptor()`, `FilesInterceptor()`, `FileFieldsInterceptor()`, `AnyFilesInterceptor()`, `NoFilesInterceptor()` | Same names, arguments and options                                                        |
| `MulterOptions`                                                                                                       | `MultipartOptions`                                                                       |
| `MulterModule`, `MulterOptionsFactory`, `createMulterOptions()`                                                       | `MultipartModule`, `MultipartOptionsFactory`, `createMultipartOptions()`                 |
| `Express.Multer.File`                                                                                                 | `UploadedMultipartFile`                                                                  |
| `memoryStorage()` and `diskStorage()` from the `multer` package                                                       | `memoryStorage()` and `diskStorage()`                                                    |
| -                                                                                                                     | `FileStreamInterceptor()` (see [Streaming uploads](/http/file-upload#streaming-uploads)) |

The interceptor options are the ones Multer accepts: `dest`, `storage`, `limits` (an object, or a function that receives the request and returns one), `fileFilter`, `preservePath` and `defParamCharset`. Uploaded files are exposed as `req.file` or `req.files` and text fields as `req.body`, exactly as with Multer. `UploadedMultipartFile` has the same shape as `Express.Multer.File`, so you don't need the `@types/multer` package.

`MultipartModule` sets default options for the upload interceptors of the module that imports it, just like `MulterModule`. Its `registerAsync()` method accepts `useFactory` (with `imports` and `inject`), `useClass` and `useExisting`.

```typescript

MultipartModule.register({
  dest: './upload',
});
```

##### Storage[#](/http/file-upload#storage)

As with Multer, files are kept in memory (in `file.buffer`) unless you set the `dest` or `storage` option. `dest` writes each file to the given folder under a random name, and the `diskStorage()` function lets you choose the folder and the file name. Disk storage sets `destination`, `filename` and `path` on the file instead of `buffer`.

```typescript

import {
  diskStorage,
  FileInterceptor,
  UploadedMultipartFile,
} from '@nestjs/platform-fastify/multipart';

@Post('upload')
@UseInterceptors(
  FileInterceptor('file', {
    storage: diskStorage({
      destination: './uploads',
      filename: (req, file, callback) =>
        callback(null, `${Date.now()}-${file.originalname}`),
    }),
  }),
)
uploadFile(@UploadedFile() file: UploadedMultipartFile) {
  console.log(file.path);
}
```

Storage engines follow Multer's storage engine contract (`_handleFile()` and `_removeFile()`), so Multer's own `multer.diskStorage()` and third-party Multer storage engines can be passed as `storage` unchanged.

##### Limits[#](/http/file-upload#limits)

`@fastify/multipart` applies stricter defaults than Multer. Unless configured otherwise, the maximum file size (`fileSize`) is the Fastify `bodyLimit` (1 MiB by default) and the maximum number of parts (`parts`) is 1000, whereas Multer limits neither. Larger files are rejected with a `413 File too large` response. You can raise these limits:

* for a single route, with the `limits` option of the interceptor
* for a module, with `MultipartModule.register()` or `registerAsync()`
* for the whole application, with the `multipart` option of the `FastifyAdapter`, which passes options to the plugin itself:

```typescript

const app = await NestFactory.create<NestFastifyApplication>(
  AppModule,
  new FastifyAdapter({
    multipart: { limits: { fileSize: 10 * 1024 * 1024 } },
  }),
);
```

```typescript

import multipart from '@fastify/multipart';

const app = await NestFactory.create<NestFastifyApplication>(
  AppModule,
  new FastifyAdapter(),
);
await app.register(multipart, { limits: { fileSize: 10 * 1024 * 1024 } });
```

> **Warning** Registering `@fastify/multipart` directly on the Fastify instance (`app.getHttpAdapter().getInstance().register(multipart)`), or passing a dynamic `import()` of it to `app.register()`, only works before `app.init()` (which `app.listen()` calls for you). After that, the adapter has already registered the plugin for your upload interceptors, and Fastify fails with an `FST_ERR_DEC_ALREADY_PRESENT` error. Use `app.register(multipart)` or the `multipart` option instead, or set the option to `false` to manage the plugin yourself.

##### Streaming uploads[#](/http/file-upload#streaming-uploads)

The interceptors described so far store every file (in memory or on disk) before the route handler runs. To process a file as it arrives instead, for example to pipe a large upload to its final destination, use `FileStreamInterceptor()`, which is available on Fastify only. It takes the name of the field that holds the file and an optional options object (the same as for the other interceptors, except `dest` and `storage`), and hands the route handler a file with a `stream` property in place of `buffer`:

```typescript

import { randomUUID } from 'node:crypto';
import { createWriteStream } from 'node:fs';
import { join } from 'node:path';
import { pipeline } from 'node:stream/promises';
import {
  FileStreamInterceptor,
  MultipartFileStream,
} from '@nestjs/platform-fastify/multipart';

@Post('upload')
@UseInterceptors(
  FileStreamInterceptor('file', { limits: { fileSize: 1024 * 1024 * 1024 } }),
)
async uploadFile(@UploadedFile() file: MultipartFileStream, @Body() body) {
  const path = join('uploads', randomUUID());
  await pipeline(file.stream, createWriteStream(path));
  return { originalname: file.originalname, path, body };
}
```

```typescript

@Controller('file')
export class FileController {
  @Get()
  getFile(@Res() res: Response) {
    const file = createReadStream(join(process.cwd(), 'package.json'));
    file.pipe(res);
  }
}
```

With this approach, the handler takes over the response, so post-controller [interceptor](/interceptors) logic no longer runs. Instead, return a `StreamableFile` instance, and Nest pipes it into the response for you.

> **Note** Streaming files applies to **HTTP applications**. The examples below do not apply to GraphQL or microservice applications.

##### Streamable file class[#](/http/file-upload#streamable-file-class)

A `StreamableFile` holds the content to be sent. Its constructor accepts either a `Readable` stream or a `Uint8Array` (including a `Buffer`). The following example returns the `package.json` file instead of a JSON response. The same approach works for images, documents, and any other file type:

```typescript

import { Controller, Get, StreamableFile } from '@nestjs/common';
import { createReadStream } from 'node:fs';
import { join } from 'node:path';

@Controller('file')
export class FileController {
  @Get()
  getFile(): StreamableFile {
    const file = createReadStream(join(process.cwd(), 'package.json'));
    return new StreamableFile(file);
  }
}
```

> **Hint** The `StreamableFile` class is exported from the `@nestjs/common` package.

Neither the `ClassSerializerInterceptor` nor the `StandardSchemaSerializerInterceptor`[serializes](/application/serialization)`StreamableFile` responses.

##### Response headers[#](/http/file-upload#response-headers)

By default, the `Content-Type` response header is `application/octet-stream`. To change it, and to set the `Content-Disposition` and `Content-Length` headers, pass the `type`, `disposition`, and `length` options to the `StreamableFile` constructor:

```typescript

@Get()
getFile(): StreamableFile {
  const file = createReadStream(join(process.cwd(), 'package.json'));
  return new StreamableFile(file, {
    type: 'application/json',
    disposition: 'attachment; filename="package.json"',
  });
}
```

When the content is a `Uint8Array`, `length` defaults to its size. For streams, set `length` yourself if you know the size in advance.

Headers with static values can also be set with the [`@Header()`](/controllers#response-headers) decorator:

```typescript

@Get()
@Header('Content-Type', 'application/json')
@Header('Content-Disposition', 'attachment; filename="package.json"')
getFile(): StreamableFile {
  const file = createReadStream(join(process.cwd(), 'package.json'));
  return new StreamableFile(file);
}
```

To compute headers at runtime, inject the response object with `passthrough` enabled, so that Nest still sends the returned `StreamableFile`:

```typescript

import type { Response } from 'express';

@Get()
getFile(@Res({ passthrough: true }) res: Response): StreamableFile {
  const file = createReadStream(join(process.cwd(), 'package.json'));
  res.set({
    'Content-Type': 'application/json',
    'Content-Disposition': 'attachment; filename="package.json"',
  });
  return new StreamableFile(file);
}
```

##### Stream errors[#](/http/file-upload#stream-errors)

With the Express adapter, if the stream emits an error before any data has been sent, the client receives a `400 Bad Request` response, and the error is logged. Starting with NestJS v12.1.4, the response body no longer contains the error message, which may include the path of the file. If data has already been sent, the response is ended. To customize this behavior, pass a handler to the `setErrorHandler()` method:

```typescript

@Get()
getReport(): StreamableFile {
  const file = createReadStream(join(process.cwd(), 'report.pdf'));
  return new StreamableFile(file).setErrorHandler((err, res) => {
    if (res.headersSent) {
      res.end();
      return;
    }
    res.statusCode = 404;
    res.send('Report not found');
  });
}
```

The `setErrorLogger()` method replaces the function that logs errors: those the default error handler answers, and those the response stream emits while the file is being written to it.

> **Note** The error handler and the error logger apply to the Express adapter. With the Fastify adapter, a stream error is handled by the [exceptions layer](/exception-filters), so by default the client receives a `500 Internal Server Error` response.

----
url: https://docs.nestjs.com/v9/cli/scripts
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Nest CLI and scripts](https://docs.nestjs.com/v9/cli/scripts#nest-cli-and-scripts)
* [The nest binary](https://docs.nestjs.com/v9/cli/scripts#the-nest-binary)
* [Build](https://docs.nestjs.com/v9/cli/scripts#build)
* [Execution](https://docs.nestjs.com/v9/cli/scripts#execution)
* [Generation](https://docs.nestjs.com/v9/cli/scripts#generation)
* [Package scripts](https://docs.nestjs.com/v9/cli/scripts#package-scripts)
* [Backward compatibility](https://docs.nestjs.com/v9/cli/scripts#backward-compatibility)
* [Migration](https://docs.nestjs.com/v9/cli/scripts#migration)

#### The nest binary[#](/cli/scripts#the-nest-binary)

The `nest` command is an OS level binary (i.e., runs from the OS command line). This command actually encompasses 3 distinct areas, described below. We recommend that you run the build (`nest build`) and execution (`nest start`) sub-commands via the `package.json` scripts provided automatically when a project is scaffolded (see [typescript starter](https://github.com/nestjs/typescript-starter) if you wish to start by cloning a repo, instead of running `nest new`).

#### Build[#](/cli/scripts#build)

`nest build` is a wrapper on top of the standard `tsc` compiler (for [standard projects](https://docs.nestjs.com/cli/overview#project-structure)) or the webpack bundler using the `ts-loader` (for [monorepos](https://docs.nestjs.com/cli/overview#project-structure)). It does not add any other compilation features or steps except for handling `tsconfig-paths` out of the box. The reason it exists is that most developers, especially when starting out with Nest, do not need to adjust compiler options (e.g., `tsconfig.json` file) which can sometimes be tricky.

See the [nest build](https://docs.nestjs.com/cli/usages#nest-build) documentation for more details.

#### Execution[#](/cli/scripts#execution)

`nest start` simply ensures the project has been built (same as `nest build`), then invokes the `node` command in a portable, easy way to execute the compiled application. As with builds, you are free to customize this process as needed, either using the `nest start` command and its options, or completely replacing it. The entire process is a standard TypeScript application build and execute pipeline, and you are free to manage the process as such.

See the [nest start](https://docs.nestjs.com/cli/usages#nest-start) documentation for more details.

#### Generation[#](/cli/scripts#generation)

The `nest generate` commands, as the name implies, generate new Nest projects, or components within them.

#### Package scripts[#](/cli/scripts#package-scripts)

Running the `nest` commands at the OS command level requires that the `nest` binary be installed globally. This is a standard feature of npm, and outside of Nest's direct control. One consequence of this is that the globally installed `nest` binary is **not** managed as a project dependency in `package.json`. For example, two different developers can be running two different versions of the `nest` binary. The standard solution for this is to use package scripts so that you can treat the tools used in the build and execute steps as development dependencies.

When you run `nest new`, or clone the [typescript starter](https://github.com/nestjs/typescript-starter), Nest populates the new project's `package.json` scripts with commands like `build` and `start`. It also installs the underlying compiler tools (such as `typescript`) as **dev dependencies**.

You run the build and execute scripts with commands like:

```bash

$ npm run build
```

and

```bash

$ npm run start
```

```bash

$ npm install -g @nestjs/cli
$ cd  /some/project/root/folder
$ npm install -D @nestjs/cli
```

You can then replace the `scripts` defined in `package.json` with the following ones:

```typescript

"build": "nest build",
"start": "nest start",
"start:dev": "nest start --watch",
"start:debug": "nest start --debug --watch",
```

----
url: https://docs.nestjs.com/v10/recipes/passport
----

* [Passport (authentication)](https://docs.nestjs.com/v10/recipes/passport#passport-authentication)
* [Authentication requirements](https://docs.nestjs.com/v10/recipes/passport#authentication-requirements)
* [Implementing Passport strategies](https://docs.nestjs.com/v10/recipes/passport#implementing-passport-strategies)
* [Implementing Passport local](https://docs.nestjs.com/v10/recipes/passport#implementing-passport-local)
* [Built-in Passport Guards](https://docs.nestjs.com/v10/recipes/passport#built-in-passport-guards)
* [Login route](https://docs.nestjs.com/v10/recipes/passport#login-route)
* [Logout route](https://docs.nestjs.com/v10/recipes/passport#logout-route)
* [JWT functionality](https://docs.nestjs.com/v10/recipes/passport#jwt-functionality)
* [Implementing Passport JWT](https://docs.nestjs.com/v10/recipes/passport#implementing-passport-jwt)
* [Implement protected route and JWT strategy guards](https://docs.nestjs.com/v10/recipes/passport#implement-protected-route-and-jwt-strategy-guards)
* [Extending guards](https://docs.nestjs.com/v10/recipes/passport#extending-guards)
* [Enable authentication globally](https://docs.nestjs.com/v10/recipes/passport#enable-authentication-globally)
* [Request-scoped strategies](https://docs.nestjs.com/v10/recipes/passport#request-scoped-strategies)
* [Customize Passport](https://docs.nestjs.com/v10/recipes/passport#customize-passport)
* [Named strategies](https://docs.nestjs.com/v10/recipes/passport#named-strategies)
* [GraphQL](https://docs.nestjs.com/v10/recipes/passport#graphql)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/recipes/passport.md "Suggest Edits")

### Passport (authentication)

[Passport](https://github.com/jaredhanson/passport) is the most popular node.js authentication library, well-known by the community and successfully used in many production applications. It's straightforward to integrate this library with a **Nest** application using the `@nestjs/passport` module. At a high level, Passport executes a series of steps to:

* Authenticate a user by verifying their "credentials" (such as username/password, JSON Web Token ([JWT](https://jwt.io/)), or identity token from an Identity Provider)
* Manage authenticated state (by issuing a portable token, such as a JWT, or creating an [Express session](https://github.com/expressjs/session))
* Attach information about the authenticated user to the `Request` object for further use in route handlers

Passport has a rich ecosystem of [strategies](http://www.passportjs.org/) that implement various authentication mechanisms. While simple in concept, the set of Passport strategies you can choose from is large and presents a lot of variety. Passport abstracts these varied steps into a standard pattern, and the `@nestjs/passport` module wraps and standardizes this pattern into familiar Nest constructs.

In this chapter, we'll implement a complete end-to-end authentication solution for a RESTful API server using these powerful and flexible modules. You can use the concepts described here to implement any Passport strategy to customize your authentication scheme. You can follow the steps in this chapter to build this complete example.

#### Authentication requirements[#](/recipes/passport#authentication-requirements)

Let's flesh out our requirements. For this use case, clients will start by authenticating with a username and password. Once authenticated, the server will issue a JWT that can be sent as a [bearer token in an authorization header](https://tools.ietf.org/html/rfc6750) on subsequent requests to prove authentication. We'll also create a protected route that is accessible only to requests that contain a valid JWT.

We'll start with the first requirement: authenticating a user. We'll then extend that by issuing a JWT. Finally, we'll create a protected route that checks for a valid JWT on the request.

First we need to install the required packages. Passport provides a strategy called [passport-local](https://github.com/jaredhanson/passport-local) that implements a username/password authentication mechanism, which suits our needs for this portion of our use case.

```bash

$ npm install --save @nestjs/passport passport passport-local
$ npm install --save-dev @types/passport-local
```

> **Notice** For **any** Passport strategy you choose, you'll always need the `@nestjs/passport` and `passport` packages. Then, you'll need to install the strategy-specific package (e.g., `passport-jwt` or `passport-local`) that implements the particular authentication strategy you are building. In addition, you can also install the type definitions for any Passport strategy, as shown above with `@types/passport-local`, which provides assistance while writing TypeScript code.

```bash

$ nest g module auth
$ nest g service auth
```

As we implement the `AuthService`, we'll find it useful to encapsulate user operations in a `UsersService`, so let's generate that module and service now:

```bash

$ nest g module users
$ nest g service users
```

Replace the default contents of these generated files as shown below. For our sample app, the `UsersService` simply maintains a hard-coded in-memory list of users, and a find method to retrieve one by username. In a real app, this is where you'd build your user model and persistence layer, using your library of choice (e.g., TypeORM, Sequelize, Mongoose, etc.).

users/users.service.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';

// This should be a real class/interface representing a user entity
export type User = any;

@Injectable()
export class UsersService {
  private readonly users = [
    {
      userId: 1,
      username: 'john',
      password: 'changeme',
    },
    {
      userId: 2,
      username: 'maria',
      password: 'guess',
    },
  ];

  async findOne(username: string): Promise<User | undefined> {
    return this.users.find(user => user.username === username);
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';

@Injectable()
export class UsersService {
  constructor() {
    this.users = [
      {
        userId: 1,
        username: 'john',
        password: 'changeme',
      },
      {
        userId: 2,
        username: 'maria',
        password: 'guess',
      },
    ];
  }

  async findOne(username) {
    return this.users.find(user => user.username === username);
  }
}
```

In the `UsersModule`, the only change needed is to add the `UsersService` to the exports array of the `@Module` decorator so that it is visible outside this module (we'll soon use it in our `AuthService`).

users/users.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { UsersService } from './users.service';

@Module({
  providers: [UsersService],
  exports: [UsersService],
})
export class UsersModule {}
```

```typescript

import { Module } from '@nestjs/common';
import { UsersService } from './users.service';

@Module({
  providers: [UsersService],
  exports: [UsersService],
})
export class UsersModule {}
```

Our `AuthService` has the job of retrieving a user and verifying the password. We create a `validateUser()` method for this purpose. In the code below, we use a convenient ES6 spread operator to strip the password property from the user object before returning it. We'll be calling into the `validateUser()` method from our Passport local strategy in a moment.

auth/auth.service.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { UsersService } from '../users/users.service';

@Injectable()
export class AuthService {
  constructor(private usersService: UsersService) {}

  async validateUser(username: string, pass: string): Promise<any> {
    const user = await this.usersService.findOne(username);
    if (user && user.password === pass) {
      const { password, ...result } = user;
      return result;
    }
    return null;
  }
}
```

```typescript

import { Injectable, Dependencies } from '@nestjs/common';
import { UsersService } from '../users/users.service';

@Injectable()
@Dependencies(UsersService)
export class AuthService {
  constructor(usersService) {
    this.usersService = usersService;
  }

  async validateUser(username, pass) {
    const user = await this.usersService.findOne(username);
    if (user && user.password === pass) {
      const { password, ...result } = user;
      return result;
    }
    return null;
  }
}
```

> **Warning** Of course in a real application, you wouldn't store a password in plain text. You'd instead use a library like [bcrypt](https://github.com/kelektiv/node.bcrypt.js#readme), with a salted one-way hash algorithm. With that approach, you'd only store hashed passwords, and then compare the stored password to a hashed version of the **incoming** password, thus never storing or exposing user passwords in plain text. To keep our sample app simple, we violate that absolute mandate and use plain text. **Don't do this in your real app!**

Now, we update our `AuthModule` to import the `UsersModule`.

auth/auth.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { UsersModule } from '../users/users.module';

@Module({
  imports: [UsersModule],
  providers: [AuthService],
})
export class AuthModule {}
```

```typescript

import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { UsersModule } from '../users/users.module';

@Module({
  imports: [UsersModule],
  providers: [AuthService],
})
export class AuthModule {}
```

#### Implementing Passport local[#](/recipes/passport#implementing-passport-local)

Now we can implement our Passport **local authentication strategy**. Create a file called `local.strategy.ts` in the `auth` folder, and add the following code:

auth/local.strategy.ts

JS TS

```typescript

import { Strategy } from 'passport-local';
import { PassportStrategy } from '@nestjs/passport';
import { Injectable, UnauthorizedException } from '@nestjs/common';
import { AuthService } from './auth.service';

@Injectable()
export class LocalStrategy extends PassportStrategy(Strategy) {
  constructor(private authService: AuthService) {
    super();
  }

  async validate(username: string, password: string): Promise<any> {
    const user = await this.authService.validateUser(username, password);
    if (!user) {
      throw new UnauthorizedException();
    }
    return user;
  }
}
```

```typescript

import { Strategy } from 'passport-local';
import { PassportStrategy } from '@nestjs/passport';
import { Injectable, UnauthorizedException, Dependencies } from '@nestjs/common';
import { AuthService } from './auth.service';

@Injectable()
@Dependencies(AuthService)
export class LocalStrategy extends PassportStrategy(Strategy) {
  constructor(authService) {
    super();
    this.authService = authService;
  }

  async validate(username, password) {
    const user = await this.authService.validateUser(username, password);
    if (!user) {
      throw new UnauthorizedException();
    }
    return user;
  }
}
```

We've followed the recipe described earlier for all Passport strategies. In our use case with passport-local, there are no configuration options, so our constructor simply calls `super()`, without an options object.

> **Hint** We can pass an options object in the call to `super()` to customize the behavior of the passport strategy. In this example, the passport-local strategy by default expects properties called `username` and `password` in the request body. Pass an options object to specify different property names, for example: `super({ usernameField: 'email' })`. See the [Passport documentation](http://www.passportjs.org/docs/configure/) for more information.

We've also implemented the `validate()` method. For each strategy, Passport will call the verify function (implemented with the `validate()` method in `@nestjs/passport`) using an appropriate strategy-specific set of parameters. For the local-strategy, Passport expects a `validate()` method with the following signature: `validate(username: string, password:string): any`.

Most of the validation work is done in our `AuthService` (with the help of our `UsersService`), so this method is quite straightforward. The `validate()` method for **any** Passport strategy will follow a similar pattern, varying only in the details of how credentials are represented. If a user is found and the credentials are valid, the user is returned so Passport can complete its tasks (e.g., creating the `user` property on the `Request` object), and the request handling pipeline can continue. If it's not found, we throw an exception and let our [exceptions layer](exception-filters) handle it.

Typically, the only significant difference in the `validate()` method for each strategy is **how** you determine if a user exists and is valid. For example, in a JWT strategy, depending on requirements, we may evaluate whether the `userId` carried in the decoded token matches a record in our user database, or matches a list of revoked tokens. Hence, this pattern of sub-classing and implementing strategy-specific validation is consistent, elegant and extensible.

We need to configure our `AuthModule` to use the Passport features we just defined. Update `auth.module.ts` to look like this:

auth/auth.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { UsersModule } from '../users/users.module';
import { PassportModule } from '@nestjs/passport';
import { LocalStrategy } from './local.strategy';

@Module({
  imports: [UsersModule, PassportModule],
  providers: [AuthService, LocalStrategy],
})
export class AuthModule {}
```

```typescript

import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { UsersModule } from '../users/users.module';
import { PassportModule } from '@nestjs/passport';
import { LocalStrategy } from './local.strategy';

@Module({
  imports: [UsersModule, PassportModule],
  providers: [AuthService, LocalStrategy],
})
export class AuthModule {}
```

#### Built-in Passport Guards[#](/recipes/passport#built-in-passport-guards)

* **19 chapters
* **Authn & Authz
* **Official certificate
* **Deep-dive sessions

[Purchase the Authentication course](https://courses.nestjs.com/#authentication "Courses | NestJS - A node.js framework built on top of TypeScript")

#### Login route[#](/recipes/passport#login-route)

With the strategy in place, we can now implement a bare-bones `/auth/login` route, and apply the built-in Guard to initiate the passport-local flow.

Open the `app.controller.ts` file and replace its contents with the following:

app.controller.ts

JS TS

```typescript

import { Controller, Request, Post, UseGuards } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';

@Controller()
export class AppController {
  @UseGuards(AuthGuard('local'))
  @Post('auth/login')
  async login(@Request() req) {
    return req.user;
  }
}
```

```typescript

import { Controller, Bind, Request, Post, UseGuards } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';

@Controller()
export class AppController {
  @UseGuards(AuthGuard('local'))
  @Post('auth/login')
  @Bind(Request())
  async login(req) {
    return req.user;
  }
}
```

With `@UseGuards(AuthGuard('local'))` we are using an `AuthGuard` that `@nestjs/passport`**automatically provisioned** for us when we extended the passport-local strategy. Let's break that down. Our Passport local strategy has a default name of `'local'`. We reference that name in the `@UseGuards()` decorator to associate it with code supplied by the `passport-local` package. This is used to disambiguate which strategy to invoke in case we have multiple Passport strategies in our app (each of which may provision a strategy-specific `AuthGuard`). While we only have one such strategy so far, we'll shortly add a second, so this is needed for disambiguation.

In order to test our route we'll have our `/auth/login` route simply return the user for now. This also lets us demonstrate another Passport feature: Passport automatically creates a `user` object, based on the value we return from the `validate()` method, and assigns it to the `Request` object as `req.user`. Later, we'll replace this with code to create and return a JWT instead.

Since these are API routes, we'll test them using the commonly available [cURL](https://curl.haxx.se/) library. You can test with any of the `user` objects hard-coded in the `UsersService`.

```bash

$ # POST to /auth/login
$ curl -X POST http://localhost:3000/auth/login -d '{"username": "john", "password": "changeme"}' -H "Content-Type: application/json"
$ # result -> {"userId":1,"username":"john"}
```

While this works, passing the strategy name directly to the `AuthGuard()` introduces magic strings in the codebase. Instead, we recommend creating your own class, as shown below:

auth/local-auth.guard.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';

@Injectable()
export class LocalAuthGuard extends AuthGuard('local') {}
```

Now, we can update the `/auth/login` route handler and use the `LocalAuthGuard` instead:

```typescript

@UseGuards(LocalAuthGuard)
@Post('auth/login')
async login(@Request() req) {
  return req.user;
}
```

#### Logout route[#](/recipes/passport#logout-route)

To log out, we can create an additional route that invokes `res.logout()` to clear the user's session. This is a typical approach used in session-based authentication, but it does not apply to JWTs.

```typescript

@UseGuards(LocalAuthGuard)
@Post('auth/logout')
async logout(@Request() req) {
  return req.logout();
}
```

#### JWT functionality[#](/recipes/passport#jwt-functionality)

We're ready to move on to the JWT portion of our auth system. Let's review and refine our requirements:

* Allow users to authenticate with username/password, returning a JWT for use in subsequent calls to protected API endpoints. We're well on our way to meeting this requirement. To complete it, we'll need to write the code that issues a JWT.
* Create API routes which are protected based on the presence of a valid JWT as a bearer token

We'll need to install a couple more packages to support our JWT requirements:

```bash

$ npm install --save @nestjs/jwt passport-jwt
$ npm install --save-dev @types/passport-jwt
```

```typescript

import { Injectable } from '@nestjs/common';
import { UsersService } from '../users/users.service';
import { JwtService } from '@nestjs/jwt';

@Injectable()
export class AuthService {
  constructor(
    private usersService: UsersService,
    private jwtService: JwtService
  ) {}

  async validateUser(username: string, pass: string): Promise<any> {
    const user = await this.usersService.findOne(username);
    if (user && user.password === pass) {
      const { password, ...result } = user;
      return result;
    }
    return null;
  }

  async login(user: any) {
    const payload = { username: user.username, sub: user.userId };
    return {
      access_token: this.jwtService.sign(payload),
    };
  }
}
```

```typescript

import { Injectable, Dependencies } from '@nestjs/common';
import { UsersService } from '../users/users.service';
import { JwtService } from '@nestjs/jwt';

@Dependencies(UsersService, JwtService)
@Injectable()
export class AuthService {
  constructor(usersService, jwtService) {
    this.usersService = usersService;
    this.jwtService = jwtService;
  }

  async validateUser(username, pass) {
    const user = await this.usersService.findOne(username);
    if (user && user.password === pass) {
      const { password, ...result } = user;
      return result;
    }
    return null;
  }

  async login(user) {
    const payload = { username: user.username, sub: user.userId };
    return {
      access_token: this.jwtService.sign(payload),
    };
  }
}
```

We're using the `@nestjs/jwt` library, which supplies a `sign()` function to generate our JWT from a subset of the `user` object properties, which we then return as a simple object with a single `access_token` property. Note: we choose a property name of `sub` to hold our `userId` value to be consistent with JWT standards. Don't forget to inject the JwtService provider into the `AuthService`.

We now need to update the `AuthModule` to import the new dependencies and configure the `JwtModule`.

First, create `constants.ts` in the `auth` folder, and add the following code:

auth/constants.ts

JS TS

```typescript

export const jwtConstants = {
  secret: 'DO NOT USE THIS VALUE. INSTEAD, CREATE A COMPLEX SECRET AND KEEP IT SAFE OUTSIDE OF THE SOURCE CODE.',
};
```

```typescript

export const jwtConstants = {
  secret: 'DO NOT USE THIS VALUE. INSTEAD, CREATE A COMPLEX SECRET AND KEEP IT SAFE OUTSIDE OF THE SOURCE CODE.',
};
```

We'll use this to share our key between the JWT signing and verifying steps.

> **Warning****Do not expose this key publicly**. We have done so here to make it clear what the code is doing, but in a production system **you must protect this key** using appropriate measures such as a secrets vault, environment variable, or configuration service.

Now, open `auth.module.ts` in the `auth` folder and update it to look like this:

auth/auth.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { LocalStrategy } from './local.strategy';
import { UsersModule } from '../users/users.module';
import { PassportModule } from '@nestjs/passport';
import { JwtModule } from '@nestjs/jwt';
import { jwtConstants } from './constants';

@Module({
  imports: [
    UsersModule,
    PassportModule,
    JwtModule.register({
      secret: jwtConstants.secret,
      signOptions: { expiresIn: '60s' },
    }),
  ],
  providers: [AuthService, LocalStrategy],
  exports: [AuthService],
})
export class AuthModule {}
```

```typescript

import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { LocalStrategy } from './local.strategy';
import { UsersModule } from '../users/users.module';
import { PassportModule } from '@nestjs/passport';
import { JwtModule } from '@nestjs/jwt';
import { jwtConstants } from './constants';

@Module({
  imports: [
    UsersModule,
    PassportModule,
    JwtModule.register({
      secret: jwtConstants.secret,
      signOptions: { expiresIn: '60s' },
    }),
  ],
  providers: [AuthService, LocalStrategy],
  exports: [AuthService],
})
export class AuthModule {}
```

We configure the `JwtModule` using `register()`, passing in a configuration object. See [here](https://github.com/nestjs/jwt/blob/master/README.md) for more on the Nest `JwtModule` and [here](https://github.com/auth0/node-jsonwebtoken#usage) for more details on the available configuration options.

Now we can update the `/auth/login` route to return a JWT.

app.controller.ts

JS TS

```typescript

import { Controller, Request, Post, UseGuards } from '@nestjs/common';
import { LocalAuthGuard } from './auth/local-auth.guard';
import { AuthService } from './auth/auth.service';

@Controller()
export class AppController {
  constructor(private authService: AuthService) {}

  @UseGuards(LocalAuthGuard)
  @Post('auth/login')
  async login(@Request() req) {
    return this.authService.login(req.user);
  }
}
```

```typescript

import { Controller, Bind, Request, Post, UseGuards } from '@nestjs/common';
import { LocalAuthGuard } from './auth/local-auth.guard';
import { AuthService } from './auth/auth.service';

@Controller()
export class AppController {
  constructor(private authService: AuthService) {}

  @UseGuards(LocalAuthGuard)
  @Post('auth/login')
  @Bind(Request())
  async login(req) {
    return this.authService.login(req.user);
  }
}
```

Let's go ahead and test our routes using cURL again. You can test with any of the `user` objects hard-coded in the `UsersService`.

```bash

$ # POST to /auth/login
$ curl -X POST http://localhost:3000/auth/login -d '{"username": "john", "password": "changeme"}' -H "Content-Type: application/json"
$ # result -> {"access_token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."}
$ # Note: above JWT truncated
```

#### Implementing Passport JWT[#](/recipes/passport#implementing-passport-jwt)

We can now address our final requirement: protecting endpoints by requiring a valid JWT be present on the request. Passport can help us here too. It provides the [passport-jwt](https://github.com/mikenicholson/passport-jwt) strategy for securing RESTful endpoints with JSON Web Tokens. Start by creating a file called `jwt.strategy.ts` in the `auth` folder, and add the following code:

auth/jwt.strategy.ts

JS TS

```typescript

import { ExtractJwt, Strategy } from 'passport-jwt';
import { PassportStrategy } from '@nestjs/passport';
import { Injectable } from '@nestjs/common';
import { jwtConstants } from './constants';

@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
  constructor() {
    super({
      jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
      ignoreExpiration: false,
      secretOrKey: jwtConstants.secret,
    });
  }

  async validate(payload: any) {
    return { userId: payload.sub, username: payload.username };
  }
}
```

```typescript

import { ExtractJwt, Strategy } from 'passport-jwt';
import { PassportStrategy } from '@nestjs/passport';
import { Injectable } from '@nestjs/common';
import { jwtConstants } from './constants';

@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
  constructor() {
    super({
      jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
      ignoreExpiration: false,
      secretOrKey: jwtConstants.secret,
    });
  }

  async validate(payload) {
    return { userId: payload.sub, username: payload.username };
  }
}
```

```typescript

import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { LocalStrategy } from './local.strategy';
import { JwtStrategy } from './jwt.strategy';
import { UsersModule } from '../users/users.module';
import { PassportModule } from '@nestjs/passport';
import { JwtModule } from '@nestjs/jwt';
import { jwtConstants } from './constants';

@Module({
  imports: [
    UsersModule,
    PassportModule,
    JwtModule.register({
      secret: jwtConstants.secret,
      signOptions: { expiresIn: '60s' },
    }),
  ],
  providers: [AuthService, LocalStrategy, JwtStrategy],
  exports: [AuthService],
})
export class AuthModule {}
```

```typescript

import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { LocalStrategy } from './local.strategy';
import { JwtStrategy } from './jwt.strategy';
import { UsersModule } from '../users/users.module';
import { PassportModule } from '@nestjs/passport';
import { JwtModule } from '@nestjs/jwt';
import { jwtConstants } from './constants';

@Module({
  imports: [
    UsersModule,
    PassportModule,
    JwtModule.register({
      secret: jwtConstants.secret,
      signOptions: { expiresIn: '60s' },
    }),
  ],
  providers: [AuthService, LocalStrategy, JwtStrategy],
  exports: [AuthService],
})
export class AuthModule {}
```

By importing the same secret used when we signed the JWT, we ensure that the **verify** phase performed by Passport, and the **sign** phase performed in our AuthService, use a common secret.

Finally, we define the `JwtAuthGuard` class which extends the built-in `AuthGuard`:

auth/jwt-auth.guard.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';

@Injectable()
export class JwtAuthGuard extends AuthGuard('jwt') {}
```

#### Implement protected route and JWT strategy guards[#](/recipes/passport#implement-protected-route-and-jwt-strategy-guards)

We can now implement our protected route and its associated Guard.

Open the `app.controller.ts` file and update it as shown below:

app.controller.ts

JS TS

```typescript

import { Controller, Get, Request, Post, UseGuards } from '@nestjs/common';
import { JwtAuthGuard } from './auth/jwt-auth.guard';
import { LocalAuthGuard } from './auth/local-auth.guard';
import { AuthService } from './auth/auth.service';

@Controller()
export class AppController {
  constructor(private authService: AuthService) {}

  @UseGuards(LocalAuthGuard)
  @Post('auth/login')
  async login(@Request() req) {
    return this.authService.login(req.user);
  }

  @UseGuards(JwtAuthGuard)
  @Get('profile')
  getProfile(@Request() req) {
    return req.user;
  }
}
```

```typescript

import { Controller, Dependencies, Bind, Get, Request, Post, UseGuards } from '@nestjs/common';
import { JwtAuthGuard } from './auth/jwt-auth.guard';
import { LocalAuthGuard } from './auth/local-auth.guard';
import { AuthService } from './auth/auth.service';

@Dependencies(AuthService)
@Controller()
export class AppController {
  constructor(authService) {
    this.authService = authService;
  }

  @UseGuards(LocalAuthGuard)
  @Post('auth/login')
  @Bind(Request())
  async login(req) {
    return this.authService.login(req.user);
  }

  @UseGuards(JwtAuthGuard)
  @Get('profile')
  @Bind(Request())
  getProfile(req) {
    return req.user;
  }
}
```

Once again, we're applying the `AuthGuard` that the `@nestjs/passport` module has automatically provisioned for us when we configured the passport-jwt module. This Guard is referenced by its default name, `jwt`. When our `GET /profile` route is hit, the Guard will automatically invoke our passport-jwt custom configured strategy, validate the JWT, and assign the `user` property to the `Request` object.

Ensure the app is running, and test the routes using `cURL`.

```bash

$ # GET /profile
$ curl http://localhost:3000/profile
$ # result -> {"statusCode":401,"message":"Unauthorized"}

$ # POST /auth/login
$ curl -X POST http://localhost:3000/auth/login -d '{"username": "john", "password": "changeme"}' -H "Content-Type: application/json"
$ # result -> {"access_token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2Vybm... }

$ # GET /profile using access_token returned from previous step as bearer code
$ curl http://localhost:3000/profile -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2Vybm..."
$ # result -> {"userId":1,"username":"john"}
```

Note that in the `AuthModule`, we configured the JWT to have an expiration of `60 seconds`. This is probably too short an expiration, and dealing with the details of token expiration and refresh is beyond the scope of this article. However, we chose that to demonstrate an important quality of JWTs and the passport-jwt strategy. If you wait 60 seconds after authenticating before attempting a `GET /profile` request, you'll receive a `401 Unauthorized` response. This is because Passport automatically checks the JWT for its expiration time, saving you the trouble of doing so in your application.

We've now completed our JWT authentication implementation. JavaScript clients (such as Angular/React/Vue), and other JavaScript apps, can now authenticate and communicate securely with our API Server.

#### Extending guards[#](/recipes/passport#extending-guards)

In most cases, using a provided `AuthGuard` class is sufficient. However, there might be use-cases when you would like to simply extend the default error handling or authentication logic. For this, you can extend the built-in class and override methods within a sub-class.

```typescript

import {
  ExecutionContext,
  Injectable,
  UnauthorizedException,
} from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';

@Injectable()
export class JwtAuthGuard extends AuthGuard('jwt') {
  canActivate(context: ExecutionContext) {
    // Add your custom authentication logic here
    // for example, call super.logIn(request) to establish a session.
    return super.canActivate(context);
  }

  handleRequest(err, user, info) {
    // You can throw an exception based on either "info" or "err" arguments
    if (err || !user) {
      throw err || new UnauthorizedException();
    }
    return user;
  }
}
```

In addition to extending the default error handling and authentication logic, we can allow authentication to go through a chain of strategies. The first strategy to succeed, redirect, or error will halt the chain. Authentication failures will proceed through each strategy in series, ultimately failing if all strategies fail.

```typescript

export class JwtAuthGuard extends AuthGuard(['strategy_jwt_1', 'strategy_jwt_2', '...']) { ... }
```

#### Enable authentication globally[#](/recipes/passport#enable-authentication-globally)

If the vast majority of your endpoints should be protected by default, you can register the authentication guard as a [global guard](/guards#binding-guards) and instead of using `@UseGuards()` decorator on top of each controller, you could simply flag which routes should be public.

First, register the `JwtAuthGuard` as a global guard using the following construction (in any module):

```typescript

providers: [
  {
    provide: APP_GUARD,
    useClass: JwtAuthGuard,
  },
],
```

With this in place, Nest will automatically bind `JwtAuthGuard` to all endpoints.

Now we must provide a mechanism for declaring routes as public. For this, we can create a custom decorator using the `SetMetadata` decorator factory function.

```typescript

import { SetMetadata } from '@nestjs/common';

export const IS_PUBLIC_KEY = 'isPublic';
export const Public = () => SetMetadata(IS_PUBLIC_KEY, true);
```

In the file above, we exported two constants. One being our metadata key named `IS_PUBLIC_KEY`, and the other being our new decorator itself that we’re going to call `Public` (you can alternatively name it `SkipAuth` or `AllowAnon`, whatever fits your project).

Now that we have a custom `@Public()` decorator, we can use it to decorate any method, as follows:

```typescript

@Public()
@Get()
findAll() {
  return [];
}
```

Lastly, we need the `JwtAuthGuard` to return `true` when the `"isPublic"` metadata is found. For this, we'll use the `Reflector` class (read more [here](/guards#putting-it-all-together)).

```typescript

@Injectable()
export class JwtAuthGuard extends AuthGuard('jwt') {
  constructor(private reflector: Reflector) {
    super();
  }

  canActivate(context: ExecutionContext) {
    const isPublic = this.reflector.getAllAndOverride<boolean>(IS_PUBLIC_KEY, [
      context.getHandler(),
      context.getClass(),
    ]);
    if (isPublic) {
      return true;
    }
    return super.canActivate(context);
  }
}
```

#### Request-scoped strategies[#](/recipes/passport#request-scoped-strategies)

The passport API is based on registering strategies to the global instance of the library. Therefore strategies are not designed to have request-dependent options or to be dynamically instantiated per request (read more about the [request-scoped](/v10/fundamentals/injection-scopes) providers). When you configure your strategy to be request-scoped, Nest will never instantiate it since it's not tied to any specific route. There is no physical way to determine which "request-scoped" strategies should be executed per request.

However, there are ways to dynamically resolve request-scoped providers within the strategy. For this, we leverage the [module reference](/v10/fundamentals/module-ref) feature.

First, open the `local.strategy.ts` file and inject the `ModuleRef` in the normal way:

```typescript

constructor(private moduleRef: ModuleRef) {
  super({
    passReqToCallback: true,
  });
}
```

> **Hint** The `ModuleRef` class is imported from the `@nestjs/core` package.

Be sure to set the `passReqToCallback` configuration property to `true`, as shown above.

In the next step, the request instance will be used to obtain the current context identifier, instead of generating a new one (read more about request context [here](/fundamentals/module-ref#getting-current-sub-tree)).

Now, inside the `validate()` method of the `LocalStrategy` class, use the `getByRequest()` method of the `ContextIdFactory` class to create a context id based on the request object, and pass this to the `resolve()` call:

```typescript

async validate(
  request: Request,
  username: string,
  password: string,
) {
  const contextId = ContextIdFactory.getByRequest(request);
  // "AuthService" is a request-scoped provider
  const authService = await this.moduleRef.resolve(AuthService, contextId);
  ...
}
```

In the example above, the `resolve()` method will asynchronously return the request-scoped instance of the `AuthService` provider (we assumed that `AuthService` is marked as a request-scoped provider).

#### Customize Passport[#](/recipes/passport#customize-passport)

Any standard Passport customization options can be passed the same way, using the `register()` method. The available options depend on the strategy being implemented. For example:

```typescript

PassportModule.register({ session: true });
```

You can also pass strategies an options object in their constructors to configure them. For the local strategy you can pass e.g.:

```typescript

constructor(private authService: AuthService) {
  super({
    usernameField: 'email',
    passwordField: 'password',
  });
}
```

Take a look at the official [Passport Website](http://www.passportjs.org/docs/oauth/) for property names.

#### Named strategies[#](/recipes/passport#named-strategies)

When implementing a strategy, you can provide a name for it by passing a second argument to the `PassportStrategy` function. If you don't do this, each strategy will have a default name (e.g., 'jwt' for jwt-strategy):

```typescript

export class JwtStrategy extends PassportStrategy(Strategy, 'myjwt')
```

Then, you refer to this via a decorator like `@UseGuards(AuthGuard('myjwt'))`.

#### GraphQL[#](/recipes/passport#graphql)

In order to use an AuthGuard with [GraphQL](https://docs.nestjs.com/graphql/quick-start), extend the built-in `AuthGuard` class and override the `getRequest()` method.

```typescript

@Injectable()
export class GqlAuthGuard extends AuthGuard('jwt') {
  getRequest(context: ExecutionContext) {
    const ctx = GqlExecutionContext.create(context);
    return ctx.getContext().req;
  }
}
```

To get the current authenticated user in your graphql resolver, you can define a `@CurrentUser()` decorator:

```typescript

import { createParamDecorator, ExecutionContext } from '@nestjs/common';
import { GqlExecutionContext } from '@nestjs/graphql';

export const CurrentUser = createParamDecorator(
  (data: unknown, context: ExecutionContext) => {
    const ctx = GqlExecutionContext.create(context);
    return ctx.getContext().req.user;
  },
);
```

To use above decorator in your resolver, be sure to include it as a parameter of your query or mutation:

```typescript

@Query(() => User)
@UseGuards(GqlAuthGuard)
whoAmI(@CurrentUser() user: User) {
  return this.usersService.findById(user.id);
}
```

For the passport-local strategy, you'll also need to add the GraphQL context's arguments to the request body so Passport can access them for validation. Otherwise, you'll get an Unauthorized error.

```typescript

@Injectable()
export class GqlLocalAuthGuard extends AuthGuard('local') {
  getRequest(context: ExecutionContext) {
    const gqlExecutionContext = GqlExecutionContext.create(context);
    const gqlContext = gqlExecutionContext.getContext();
    const gqlArgs = gqlExecutionContext.getArgs();

    gqlContext.req.body = { ...gqlContext.req.body, ...gqlArgs };
    return gqlContext.req;
  }
}
```

----
url: https://docs.nestjs.com/v9/websockets/guards
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Guards](https://docs.nestjs.com/v9/websockets/guards#guards)
* [Binding guards](https://docs.nestjs.com/v9/websockets/guards#binding-guards)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/websockets/guards.md "Suggest Edits")

### Guards

There is no fundamental difference between web sockets guards and [regular HTTP application guards](/v9/guards). The only difference is that instead of throwing `HttpException`, you should use `WsException`.

> **Hint** The `WsException` class is exposed from `@nestjs/websockets` package.

#### Binding guards[#](/websockets/guards#binding-guards)

The following example uses a method-scoped guard. Just as with HTTP based applications, you can also use gateway-scoped guards (i.e., prefix the gateway class with a `@UseGuards()` decorator).

JS TS

```typescript

@UseGuards(AuthGuard)
@SubscribeMessage('events')
handleEvent(client: Client, data: unknown): WsResponse<unknown> {
  const event = 'events';
  return { event, data };
}
```

```typescript

@UseGuards(AuthGuard)
@SubscribeMessage('events')
handleEvent(client, data) {
  const event = 'events';
  return { event, data };
}
```

----
url: https://docs.nestjs.com/v7/recipes/crud-generator
----

* [CRUD generator](https://docs.nestjs.com/v7/recipes/crud-generator#crud-generator)
* [Introduction](https://docs.nestjs.com/v7/recipes/crud-generator#introduction)
* [Generating a new resource](https://docs.nestjs.com/v7/recipes/crud-generator#generating-a-new-resource)

To help speed up this repetitive process, [Nest CLI](/v7/cli/overview) provides a generator (schematic) that automatically generates all the boilerplate code to help us avoid doing all of this, and make the developer experience much simpler.

> **Note** The schematic supports generating **HTTP** controllers, **Microservice** controllers, **GraphQL** resolvers (both code first and schema first), and **WebSocket** Gateways.

#### Generating a new resource[#](/recipes/crud-generator#generating-a-new-resource)

To create a new resource, simply run the following command in the root directory of your project:

```shell

$ nest g resource
```

`nest g resource` command not only generates all the NestJS building blocks (module, service, controller classes) but also an entity class, DTO classes as well as the testing (`.spec`) files.

Below you can see the generated controller file (for REST API):

```typescript

@Controller('users')
export class UsersController {
  constructor(private readonly usersService: UsersService) {}

  @Post()
  create(@Body() createUserDto: CreateUserDto) {
    return this.usersService.create(createUserDto);
  }

  @Get()
  findAll() {
    return this.usersService.findAll();
  }

  @Get(':id')
  findOne(@Param('id') id: string) {
    return this.usersService.findOne(+id);
  }

  @Put(':id')
  update(@Param('id') id: string, @Body() updateUserDto: UpdateUserDto) {
    return this.usersService.update(+id, updateUserDto);
  }

  @Delete(':id')
  remove(@Param('id') id: string) {
    return this.usersService.remove(+id);
  }
}
```

Also, it automatically creates placeholders for all the CRUD endpoints (routes for REST APIs, queries and mutations for GraphQL, message subscribes for both Microservices and WebSocket Gateways) - all without having to lift a finger.

> **Note** Generated service classes are **not** tied to any specific **ORM (or data source)**. This makes the generator generic enough to meet the needs of any project. By default, all methods will contain placeholders, allowing you to populate it with the data sources specific to your project.

Likewise, if you want to generate resolvers for a GraphQL application, simply select the `GraphQL (code first)` (or `GraphQL (schema first)`) as your transport layer.

In this case, NestJS will generate a resolver class instead of a REST API controller:

```shell

$ nest g resource users

> ? What transport layer do you use? GraphQL (code first)
> ? Would you like to generate CRUD entry points? Yes
> CREATE src/users/users.module.ts (224 bytes)
> CREATE src/users/users.resolver.spec.ts (525 bytes)
> CREATE src/users/users.resolver.ts (1109 bytes)
> CREATE src/users/users.service.spec.ts (453 bytes)
> CREATE src/users/users.service.ts (625 bytes)
> CREATE src/users/dto/create-user.input.ts (195 bytes)
> CREATE src/users/dto/update-user.input.ts (281 bytes)
> CREATE src/users/entities/user.entity.ts (187 bytes)
> UPDATE src/app.module.ts (312 bytes)
```

> **Hint** To avoid generating test files, you can pass the `--no-spec` flag, as follows: `nest g resource users --no-spec`

We can see below, that not only were all boilerplate mutations and queries created, but everything is all tied together. We're utilizing the `UsersService`, `User` Entity, and our DTO's.

```typescript

import { Resolver, Query, Mutation, Args, Int } from '@nestjs/graphql';
import { UsersService } from './users.service';
import { User } from './entities/user.entity';
import { CreateUserInput } from './dto/create-user.input';
import { UpdateUserInput } from './dto/update-user.input';

@Resolver(() => User)
export class UsersResolver {
  constructor(private readonly usersService: UsersService) {}

  @Mutation(() => User)
  createUser(@Args('createUserInput') createUserInput: CreateUserInput) {
    return this.usersService.create(createUserInput);
  }

  @Query(() => [User], { name: 'users' })
  findAll() {
    return this.usersService.findAll();
  }

  @Query(() => User, { name: 'user' })
  findOne(@Args('id', { type: () => Int }) id: number) {
    return this.usersService.findOne(id);
  }

  @Mutation(() => User)
  updateUser(@Args('updateUserInput') updateUserInput: UpdateUserInput) {
    return this.usersService.update(updateUserInput.id, updateUserInput);
  }

  @Mutation(() => User)
  removeUser(@Args('id', { type: () => Int }) id: number) {
    return this.usersService.remove(id);
  }
}
```

----
url: https://docs.nestjs.com/v10/graphql/interfaces
----

* [Interfaces](https://docs.nestjs.com/v10/graphql/interfaces#interfaces)
* [Code first](https://docs.nestjs.com/v10/graphql/interfaces#code-first)
* [Interface resolvers](https://docs.nestjs.com/v10/graphql/interfaces#interface-resolvers)
* [Schema first](https://docs.nestjs.com/v10/graphql/interfaces#schema-first)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/interfaces.md "Suggest Edits")

### Interfaces

Like many type systems, GraphQL supports interfaces. An **Interface** is an abstract type that includes a certain set of fields that a type must include to implement the interface (read more [here](https://graphql.org/learn/schema/#interfaces)).

#### Code first[#](/graphql/interfaces#code-first)

When using the code first approach, you define a GraphQL interface by creating an abstract class annotated with the `@InterfaceType()` decorator exported from the `@nestjs/graphql`.

```typescript

import { Field, ID, InterfaceType } from '@nestjs/graphql';

@InterfaceType()
export abstract class Character {
  @Field(() => ID)
  id: string;

  @Field()
  name: string;
}
```

> **Warning** TypeScript interfaces cannot be used to define GraphQL interfaces.

This will result in generating the following part of the GraphQL schema in SDL:

```graphql

interface Character {
  id: ID!
  name: String!
}
```

Now, to implement the `Character` interface, use the `implements` key:

```typescript

@ObjectType({
  implements: () => [Character],
})
export class Human implements Character {
  id: string;
  name: string;
}
```

> **Hint** The `@ObjectType()` decorator is exported from the `@nestjs/graphql` package.

The default `resolveType()` function generated by the library extracts the type based on the value returned from the resolver method. This means that you must return class instances (you cannot return literal JavaScript objects).

To provide a customized `resolveType()` function, pass the `resolveType` property to the options object passed into the `@InterfaceType()` decorator, as follows:

```typescript

@InterfaceType({
  resolveType(book) {
    if (book.colors) {
      return ColoringBook;
    }
    return TextBook;
  },
})
export abstract class Book {
  @Field(() => ID)
  id: string;

  @Field()
  title: string;
}
```

#### Interface resolvers[#](/graphql/interfaces#interface-resolvers)

So far, using interfaces, you could only share field definitions with your objects. If you also want to share the actual field resolvers implementation, you can create a dedicated interface resolver, as follows:

```typescript

import { Resolver, ResolveField, Parent, Info } from '@nestjs/graphql';

@Resolver((type) => Character) // Reminder: Character is an interface
export class CharacterInterfaceResolver {
  @ResolveField(() => [Character])
  friends(
    @Parent() character, // Resolved object that implements Character
    @Info() { parentType }, // Type of the object that implements Character
    @Args('search', { type: () => String }) searchTerm: string,
  ) {
    // Get character's friends
    return [];
  }
}
```

Now the `friends` field resolver is auto-registered for all object types that implement the `Character` interface.

> **Warning** This requires the `inheritResolversFromInterfaces` property set to be true in the `GraphQLModule` configuration.

#### Schema first[#](/graphql/interfaces#schema-first)

To define an interface in the schema first approach, simply create a GraphQL interface with SDL.

```graphql

interface Character {
  id: ID!
  name: String!
}
```

Then, you can use the typings generation feature (as shown in the [quick start](/v10/graphql/quick-start) chapter) to generate corresponding TypeScript definitions:

```typescript

export interface Character {
  id: string;
  name: string;
}
```

Interfaces require an extra `__resolveType` field in the resolver map to determine which type the interface should resolve to. Let's create a `CharactersResolver` class and define the `__resolveType` method:

```typescript

@Resolver('Character')
export class CharactersResolver {
  @ResolveField()
  __resolveType(value) {
    if ('age' in value) {
      return Person;
    }
    return null;
  }
}
```

> **Hint** All decorators are exported from the `@nestjs/graphql` package.

----
url: https://docs.nestjs.com/v10/microservices/redis
----

* [Redis](https://docs.nestjs.com/v10/microservices/redis#redis)
* [Installation](https://docs.nestjs.com/v10/microservices/redis#installation)
* [Overview](https://docs.nestjs.com/v10/microservices/redis#overview)
* [Options](https://docs.nestjs.com/v10/microservices/redis#options)
* [Client](https://docs.nestjs.com/v10/microservices/redis#client)
* [Context](https://docs.nestjs.com/v10/microservices/redis#context)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/microservices/redis.md "Suggest Edits")

### Redis

The [Redis](https://redis.io/) transporter implements the publish/subscribe messaging paradigm and leverages the [Pub/Sub](https://redis.io/topics/pubsub) feature of Redis. Published messages are categorized in channels, without knowing what subscribers (if any) will eventually receive the message. Each microservice can subscribe to any number of channels. In addition, more than one channel can be subscribed to at a time. Messages exchanged through channels are **fire-and-forget**, which means that if a message is published and there are no subscribers interested in it, the message is removed and cannot be recovered. Thus, you don't have a guarantee that either messages or events will be handled by at least one service. A single message can be subscribed to (and received) by multiple subscribers.

#### Installation[#](/microservices/redis#installation)

To start building Redis-based microservices, first install the required package:

```bash

$ npm i --save ioredis
```

#### Overview[#](/microservices/redis#overview)

To use the Redis transporter, pass the following options object to the `createMicroservice()` method:

main.ts

JS TS

```typescript

const app = await NestFactory.createMicroservice<MicroserviceOptions>(AppModule, {
  transport: Transport.REDIS,
  options: {
    host: 'localhost',
    port: 6379,
  },
});
```

```typescript

const app = await NestFactory.createMicroservice(AppModule, {
  transport: Transport.REDIS,
  options: {
    host: 'localhost',
    port: 6379,
  },
});
```

> **Hint** The `Transport` enum is imported from the `@nestjs/microservices` package.

#### Options[#](/microservices/redis#options)

The `options` property is specific to the chosen transporter. The **Redis** transporter exposes the properties described below.

|                 |                                                                                                                                 |
| --------------- | ------------------------------------------------------------------------------------------------------------------------------- |
| `host`          | Connection url                                                                                                                  |
| `port`          | Connection port                                                                                                                 |
| `retryAttempts` | Number of times to retry message (default: `0`)                                                                                 |
| `retryDelay`    | Delay between message retry attempts (ms) (default: `0`)                                                                        |
| `wildcards`     | Enables Redis wildcard subscriptions, instructing transporter to use `psubscribe`/`pmessage` under the hood. (default: `false`) |

All the properties supported by the official [ioredis](https://redis.github.io/ioredis/index.html#RedisOptions) client are also supported by this transporter.

#### Client[#](/microservices/redis#client)

Like other microservice transporters, you have [several options](https://docs.nestjs.com/microservices/basics#client) for creating a Redis `ClientProxy` instance.

One method for creating an instance is to use the `ClientsModule`. To create a client instance with the `ClientsModule`, import it and use the `register()` method to pass an options object with the same properties shown above in the `createMicroservice()` method, as well as a `name` property to be used as the injection token. Read more about `ClientsModule`[here](https://docs.nestjs.com/microservices/basics#client).

```typescript

@Module({
  imports: [
    ClientsModule.register([
      {
        name: 'MATH_SERVICE',
        transport: Transport.REDIS,
        options: {
          host: 'localhost',
          port: 6379,
        }
      },
    ]),
  ]
  ...
})
```

Other options to create a client (either `ClientProxyFactory` or `@Client()`) can be used as well. You can read about them [here](https://docs.nestjs.com/microservices/basics#client).

#### Context[#](/microservices/redis#context)

In more sophisticated scenarios, you may want to access more information about the incoming request. When using the Redis transporter, you can access the `RedisContext` object.

JS TS

```typescript

@MessagePattern('notifications')
getNotifications(@Payload() data: number[], @Ctx() context: RedisContext) {
  console.log(`Channel: ${context.getChannel()}`);
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('notifications')
getNotifications(data, context) {
  console.log(`Channel: ${context.getChannel()}`);
}
```

> **Hint**`@Payload()`, `@Ctx()` and `RedisContext` are imported from the `@nestjs/microservices` package.

----
url: https://docs.nestjs.com/v6/techniques/logger
----

* [Logger](https://docs.nestjs.com/v6/techniques/logger#logger)
* [Basic customization](https://docs.nestjs.com/v6/techniques/logger#basic-customization)
* [Custom implementation](https://docs.nestjs.com/v6/techniques/logger#custom-implementation)
* [Extend built-in logger](https://docs.nestjs.com/v6/techniques/logger#extend-built-in-logger)
* [Dependency injection](https://docs.nestjs.com/v6/techniques/logger#dependency-injection)
* [Using the logger for application logging](https://docs.nestjs.com/v6/techniques/logger#using-the-logger-for-application-logging)
* [Use external logger](https://docs.nestjs.com/v6/techniques/logger#use-external-logger)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/techniques/logger.md "Suggest Edits")

### Logger

Nest comes with a built-in text-based logger which is used during application bootstrapping and several other circumstances such as displaying caught exceptions (i.e., system logging). This functionality is provided via the `Logger` class in the `@nestjs/common` package. You can fully control the behavior of the logging system, including any of the following:

* disable logging entirely
* specify the log level of detail (e.g., display errors, warnings, debug information, etc.)
* completely override the default logger
* customize the default logger by extending it
* make use of dependency injection to simplify composing and testing your application

You can also make use of the built-in logger, or create your own custom implementation, to log your own application-level events and messages.

For more advanced logging functionality, you can make use of any Node.js logging package, such as [Winston](https://github.com/winstonjs/winston), to implement a completely custom, production grade logging system.

#### Basic customization[#](/techniques/logger#basic-customization)

To disable logging, set the `logger` property to `false` in the (optional) Nest application options object passed as the second argument to the `NestFactory.create()` method.

```typescript

const app = await NestFactory.create(ApplicationModule, {
  logger: false,
});
await app.listen(3000);
```

To enable specific logging levels, set the `logger` property to an array of strings specifying the log levels to display, as follows:

```typescript

const app = await NestFactory.create(ApplicationModule, {
  logger: ['error', 'warn'],
});
await app.listen(3000);
```

Values in the array can be any combination of `'log'`, `'error'`, `'warn'`, `'debug'`, and `'verbose'`.

#### Custom implementation[#](/techniques/logger#custom-implementation)

You can provide a custom logger implementation to be used by Nest for system logging by setting the value of the `logger` property to an object that fulfills the `LoggerService` interface. For example, you can tell Nest to use the built-in global JavaScript `console` object (which implements the `LoggerService` interface), as follows:

```typescript

const app = await NestFactory.create(ApplicationModule, {
  logger: console,
});
await app.listen(3000);
```

Implementing your own custom logger is straightforward. Simply implement each of the methods of the `LoggerService` interface as shown below.

```typescript

import { LoggerService } from '@nestjs/common';

export class MyLogger implements LoggerService {
  log(message: string) {
    /* your implementation */
  }
  error(message: string, trace: string) {
    /* your implementation */
  }
  warn(message: string) {
    /* your implementation */
  }
  debug(message: string) {
    /* your implementation */
  }
  verbose(message: string) {
    /* your implementation */
  }
}
```

You can then supply an instance of `MyLogger` via the `logger` property of the Nest application options object.

```typescript

const app = await NestFactory.create(ApplicationModule, {
  logger: new MyLogger(),
});
await app.listen(3000);
```

This technique, while simple, doesn't utilize dependency injection for the `MyLogger` class. This can pose some challenges, particularly for testing, and limit the reusability of `MyLogger`. For a better solution, see the [Dependency Injection](techniques/logger#dependency-injection) section below.

#### Extend built-in logger[#](/techniques/logger#extend-built-in-logger)

Rather than writing a logger from scratch, you may be able to meet your needs by extending the built-in `Logger` class and overriding selected behavior of the default implementation.

```typescript

import { Logger } from '@nestjs/common';

export class MyLogger extends Logger {
  error(message: string, trace: string) {
    // add your tailored logic here
    super.error(message, trace);
  }
}
```

You can use such an extended logger in your feature modules as described in the [Using the logger for application logging](techniques/logger#using-the-logger-for-application-logging) section below.

You can tell Nest to use your extended logger for system logging by passing an instance of it via the `logger` property of the application options object (as shown in the [Custom implementation](techniques/logger#custom-logger-implementation) section above), or by using the technique shown in the [Dependency Injection](techniques/logger#dependency-injection) section below. If you do so, you should take care to call `super`, as shown in the sample code above, to delegate the specific log method call to the parent (built-in) class so that Nest can rely on the built-in features it expects.

## Learn the right way!

* **60+ chapters
* **4+ hours of videos
* **Official certificate
* **Deep-dive sessions

[Explore official courses](https://courses.nestjs.com "Courses | NestJS - A node.js framework built on top of TypeScript")

#### Dependency injection[#](/techniques/logger#dependency-injection)

For more advanced logging functionality, you'll want to take advantage of dependency injection. For example, you may want to inject a `ConfigService` into your logger to customize it, and in turn inject your custom logger into other controllers and/or providers. To enable dependency injection for your custom logger, create a class that implements `LoggerService` and register that class as a provider in some module. For example, you can

1. Define a `MyLogger` class that either extends the built-in `Logger` or completely overrides it, as shown in previous sections.
2. Create a `LoggerModule` as shown below, and provide `MyLogger` from that module.

```typescript

import { Module } from '@nestjs/common';
import { MyLogger } from './my-logger.service';

@Module({
  providers: [MyLogger],
  exports: [MyLogger],
})
export class LoggerModule {}
```

With this construct, you are now providing your custom logger for use by any other module. Because your `MyLogger` class is part of a module, it can use dependency injection (for example, to inject a `ConfigService`). There's one more technique needed to provide this custom logger for use by Nest for system logging (e.g., for bootstrapping and error handling).

Because application instantiation (`NestFactory.create()`) happens outside the context of any module, it doesn't participate in the normal Dependency Injection phase of initialization. So we must ensure that at least one application module imports the `LoggerModule` to trigger Nest to instantiate a singleton instance of our `MyLogger` class. We can then instruct Nest to use the same singleton instance of `MyLogger` with the following construction:

```typescript

const app = await NestFactory.create(ApplicationModule, {
  logger: false,
});
app.useLogger(app.get(MyLogger));
await app.listen(3000);
```

Here we use the `get()` method on the `NestApplication` instance to retrieve the singleton instance of the `MyLogger` object. This technique is essentially a way to "inject" an instance of a logger for use by Nest. The `app.get()` call retrieves the singleton instance of `MyLogger`, and depends on that instance being first injected in another module, as described above.

You can also inject this `MyLogger` provider in your feature classes, thus ensuring consistent logging behavior across both Nest system logging and application logging. See [Using the logger for application logging](techniques/logger#using-the-logger-for-application-logging) below for more information.

#### Using the logger for application logging[#](/techniques/logger#using-the-logger-for-application-logging)

We can combine several of the techniques above to provide consistent behavior and formatting across both Nest system logging and our own application event/message logging. In this section, we'll achieve this with the following steps:

1. We extend the built-in logger and customize the `context` portion of the log message (e.g., the phrase `NestFactory` in square brackets in the log line shown below).

```bash

[Nest] 19096   - 12/08/2019, 7:12:59 AM   [NestFactory] Starting Nest application...
```

2. We inject a [transient](/v6/fundamentals/injection-scopes) instance of the `Logger` into our feature modules so that each one has its own custom context.
3. We supply this extended logger for Nest to use for system logging.

To start, extend the built-in logger with code like the following. We supply the `scope` option as configuration metadata for the `Logger` class, specifying a [transient](/v6/fundamentals/injection-scopes) scope, to ensure that we'll have a unique instance of the `Logger` in each feature module. In this example, we do not extend the individual `Logger` methods (like `log()`, `warn()`, etc.), though you may choose to do so.

```typescript

import { Injectable, Scope, Logger } from '@nestjs/common';

@Injectable({ scope: Scope.TRANSIENT })
export class MyLogger extends Logger {}
```

Next, create a `LoggerModule` with a construction like this:

```typescript

import { Module } from '@nestjs/common';
import { MyLogger } from './my-logger.service';

@Module({
  providers: [MyLogger],
  exports: [MyLogger],
})
export class LoggerModule {}
```

Next, import the `LoggerModule` into your feature module. Then set the logger context, and start using the context-aware custom logger, like this:

```typescript

import { Injectable } from '@nestjs/common';
import { MyLogger } from './my-logger.service';

@Injectable()
export class CatsService {
  private readonly cats: Cat[] = [];

  constructor(private readonly myLogger: MyLogger) {
    this.myLogger.setContext('CatsService');
  }

  findAll(): Cat[] {
    this.myLogger.warn('About to return cats!');
    return this.cats;
  }
}
```

Finally, instruct Nest to use an instance of the custom logger in your `main.ts` file as shown below. Of course in this example, we haven't actually customized the logger behavior (by extending the `Logger` methods like `log()`, `warn()`, etc.), so this step isn't actually needed. But it **would** be needed if you added custom logic to those methods and wanted Nest to use the same implementation.

```typescript

const app = await NestFactory.create(ApplicationModule, {
  logger: false,
});
app.useLogger(new MyLogger());
await app.listen(3000);
```

#### Use external logger[#](/techniques/logger#use-external-logger)

Production applications often have specific logging requirements, including advanced filtering, formatting and centralized logging. Nest's built-in logger is used for monitoring Nest system behavior, and can also be useful for basic formatted text logging in your feature modules while in development, but production applications often take advantage of dedicated logging modules like [Winston](https://github.com/winstonjs/winston). As with any standard Node.js application, you can take full advantage of such modules in Nest.

----
url: https://docs.nestjs.com/microservices/interceptors
----

[Skip to content](#content)

On this page

* [Interceptors](https://docs.nestjs.com/microservices/interceptors#interceptors)

[](https://srv.carbonads.net/ads/click/x/GTND4277CVSD5KJUCAYLYKQUF67D62QUF6BIKZ3JCAAI623WC6YIV2QKF6SDV2Q7F6AIKK7JCY7IL23EF6BIL23KC6SILKJUCT7DEK3EHJNCLSIZ)[NVIDIA L4 GPUs. 5-second cold starts. Scale to zero when idle. ](https://srv.carbonads.net/ads/click/x/GTND4277CVSD5KJUCAYLYKQUF67D62QUF6BIKZ3JCAAI623WC6YIV2QKF6SDV2Q7F6AIKK7JCY7IL23EF6BIL23KC6SILKJUCT7DEK3EHJNCLSIZ)[ads via Carbon](http://carbonads.net/?utm_source=nestjscom\&utm_medium=ad_via_link\&utm_campaign=in_unit\&utm_term=carbon)

### Interceptors

Microservice interceptors work the same way as [regular interceptors](/interceptors). The following example uses a manually instantiated method-scoped interceptor. As with HTTP-based applications, you can also use controller-scoped interceptors (i.e., prefix the controller class with a `@UseInterceptors()` decorator).

JS TS

```typescript

@UseInterceptors(new TransformInterceptor())
@MessagePattern({ cmd: 'sum' })
accumulate(data: number[]): number {
  return (data || []).reduce((a, b) => a + b);
}
```

```typescript

@UseInterceptors(new TransformInterceptor())
@MessagePattern({ cmd: 'sum' })
accumulate(data) {
  return (data || []).reduce((a, b) => a + b);
}
```

> **Hint** Global interceptors registered on the main HTTP application don't apply to microservices connected to a [hybrid application](/faq/hybrid-application) unless you set the `inheritAppConfig` option. See [sharing configuration](/faq/hybrid-application#sharing-configuration).

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/microservices/interceptors.md)

----
url: https://docs.nestjs.com/v8/pipes
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Pipes](https://docs.nestjs.com/v8/pipes#pipes)
* [Built-in pipes](https://docs.nestjs.com/v8/pipes#built-in-pipes)
* [Binding pipes](https://docs.nestjs.com/v8/pipes#binding-pipes)
* [Custom pipes](https://docs.nestjs.com/v8/pipes#custom-pipes)
* [Schema based validation](https://docs.nestjs.com/v8/pipes#schema-based-validation)
* [Object schema validation](https://docs.nestjs.com/v8/pipes#object-schema-validation)
* [Binding validation pipes](https://docs.nestjs.com/v8/pipes#binding-validation-pipes)
* [Class validator](https://docs.nestjs.com/v8/pipes#class-validator)
* [Global scoped pipes](https://docs.nestjs.com/v8/pipes#global-scoped-pipes)
* [The built-in ValidationPipe](https://docs.nestjs.com/v8/pipes#the-built-in-validationpipe)
* [Transformation use case](https://docs.nestjs.com/v8/pipes#transformation-use-case)
* [Providing defaults](https://docs.nestjs.com/v8/pipes#providing-defaults)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/pipes.md "Suggest Edits")

### Pipes

A pipe is a class annotated with the `@Injectable()` decorator, which implements the `PipeTransform` interface.

Pipes have two typical use cases:

* **transformation**: transform input data to the desired form (e.g., from string to integer)
* **validation**: evaluate input data and if valid, simply pass it through unchanged; otherwise, throw an exception when the data is incorrect

In both cases, pipes operate on the `arguments` being processed by a [controller route handler](controllers#route-parameters). Nest interposes a pipe just before a method is invoked, and the pipe receives the arguments destined for the method and operates on them. Any transformation or validation operation takes place at that time, after which the route handler is invoked with any (potentially) transformed arguments.

Nest comes with a number of built-in pipes that you can use out-of-the-box. You can also build your own custom pipes. In this chapter, we'll introduce the built-in pipes and show how to bind them to route handlers. We'll then examine several custom-built pipes to show how you can build one from scratch.

> **Hint** Pipes run inside the exceptions zone. This means that when a Pipe throws an exception it is handled by the exceptions layer (global exceptions filter and any [exceptions filters](/v8/exception-filters) that are applied to the current context). Given the above, it should be clear that when an exception is thrown in a Pipe, no controller method is subsequently executed. This gives you a best-practice technique for validating data coming into the application from external sources at the system boundary.

#### Built-in pipes[#](/pipes#built-in-pipes)

Nest comes with eight pipes available out-of-the-box:

* `ValidationPipe`
* `ParseIntPipe`
* `ParseFloatPipe`
* `ParseBoolPipe`
* `ParseArrayPipe`
* `ParseUUIDPipe`
* `ParseEnumPipe`
* `DefaultValuePipe`

They're exported from the `@nestjs/common` package.

Let's take a quick look at using `ParseIntPipe`. This is an example of the **transformation** use case, where the pipe ensures that a method handler parameter is converted to a JavaScript integer (or throws an exception if the conversion fails). Later in this chapter, we'll show a simple custom implementation for a `ParseIntPipe`. The example techniques below also apply to the other built-in transformation pipes (`ParseBoolPipe`, `ParseFloatPipe`, `ParseEnumPipe`, `ParseArrayPipe` and `ParseUUIDPipe`, which we'll refer to as the `Parse*` pipes in this chapter).

#### Binding pipes[#](/pipes#binding-pipes)

To use a pipe, we need to bind an instance of the pipe class to the appropriate context. In our `ParseIntPipe` example, we want to associate the pipe with a particular route handler method, and make sure it runs before the method is called. We do so with the following construct, which we'll refer to as binding the pipe at the method parameter level:

```typescript

@Get(':id')
async findOne(@Param('id', ParseIntPipe) id: number) {
  return this.catsService.findOne(id);
}
```

This ensures that one of the following two conditions is true: either the parameter we receive in the `findOne()` method is a number (as expected in our call to `this.catsService.findOne()`), or an exception is thrown before the route handler is called.

For example, assume the route is called like:

```bash

GET localhost:3000/abc
```

Nest will throw an exception like this:

```json

{
  "statusCode": 400,
  "message": "Validation failed (numeric string is expected)",
  "error": "Bad Request"
}
```

The exception will prevent the body of the `findOne()` method from executing.

In the example above, we pass a class (`ParseIntPipe`), not an instance, leaving responsibility for instantiation to the framework and enabling dependency injection. As with pipes and guards, we can instead pass an in-place instance. Passing an in-place instance is useful if we want to customize the built-in pipe's behavior by passing options:

```typescript

@Get(':id')
async findOne(
  @Param('id', new ParseIntPipe({ errorHttpStatusCode: HttpStatus.NOT_ACCEPTABLE }))
  id: number,
) {
  return this.catsService.findOne(id);
}
```

Binding the other transformation pipes (all of the **Parse\*** pipes) works similarly. These pipes all work in the context of validating route parameters, query string parameters and request body values.

For example with a query string parameter:

```typescript

@Get()
async findOne(@Query('id', ParseIntPipe) id: number) {
  return this.catsService.findOne(id);
}
```

Here's an example of using the `ParseUUIDPipe` to parse a string parameter and validate if it is a UUID.

JS TS

```typescript

@Get(':uuid')
async findOne(@Param('uuid', new ParseUUIDPipe()) uuid: string) {
  return this.catsService.findOne(uuid);
}
```

```typescript

@Get(':uuid')
@Bind(Param('uuid', new ParseUUIDPipe()))
async findOne(uuid) {
  return this.catsService.findOne(uuid);
}
```

> **Hint** When using `ParseUUIDPipe()` you are parsing UUID in version 3, 4 or 5, if you only require a specific version of UUID you can pass a version in the pipe options.

Above we've seen examples of binding the various `Parse*` family of built-in pipes. Binding validation pipes is a little bit different; we'll discuss that in the following section.

> **Hint** Also, see [Validation techniques](/v8/techniques/validation) for extensive examples of validation pipes.

#### Custom pipes[#](/pipes#custom-pipes)

As mentioned, you can build your own custom pipes. While Nest provides a robust built-in `ParseIntPipe` and `ValidationPipe`, let's build simple custom versions of each from scratch to see how custom pipes are constructed.

We start with a simple `ValidationPipe`. Initially, we'll have it simply take an input value and immediately return the same value, behaving like an identity function.

validation.pipe.ts

JS TS

```typescript

import { PipeTransform, Injectable, ArgumentMetadata } from '@nestjs/common';

@Injectable()
export class ValidationPipe implements PipeTransform {
  transform(value: any, metadata: ArgumentMetadata) {
    return value;
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';

@Injectable()
export class ValidationPipe {
  transform(value, metadata) {
    return value;
  }
}
```

> **Hint**`PipeTransform<T, R>` is a generic interface that must be implemented by any pipe. The generic interface uses `T` to indicate the type of the input `value`, and `R` to indicate the return type of the `transform()` method.

Every pipe must implement the `transform()` method to fulfill the `PipeTransform` interface contract. This method has two parameters:

* `value`
* `metadata`

The `value` parameter is the currently processed method argument (before it is received by the route handling method), and `metadata` is the currently processed method argument's metadata. The metadata object has these properties:

```typescript

export interface ArgumentMetadata {
  type: 'body' | 'query' | 'param' | 'custom';
  metatype?: Type<unknown>;
  data?: string;
}
```

These properties describe the currently processed argument.

|            |                                                                                                                                                                                                      |
| ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `type`     | Indicates whether the argument is a body `@Body()`, query `@Query()`, param `@Param()`, or a custom parameter (read more [here](/v8/custom-decorators)).                                             |
| `metatype` | Provides the metatype of the argument, for example, `String`. Note: the value is `undefined` if you either omit a type declaration in the route handler method signature, or use vanilla JavaScript. |
| `data`     | The string passed to the decorator, for example `@Body('string')`. It's `undefined` if you leave the decorator parenthesis empty.                                                                    |

> **Warning** TypeScript interfaces disappear during transpilation. Thus, if a method parameter's type is declared as an interface instead of a class, the `metatype` value will be `Object`.

#### Schema based validation[#](/pipes#schema-based-validation)

Let's make our validation pipe a little more useful. Take a closer look at the `create()` method of the `CatsController`, where we probably would like to ensure that the post body object is valid before attempting to run our service method.

JS TS

```typescript

@Post()
async create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

```typescript

@Post()
async create(@Body() createCatDto) {
  this.catsService.create(createCatDto);
}
```

Let's focus in on the `createCatDto` body parameter. Its type is `CreateCatDto`:

create-cat.dto.ts

JS TS

```typescript

export class CreateCatDto {
  name: string;
  age: number;
  breed: string;
}
```

```bash

$ npm install --save joi
$ npm install --save-dev @types/joi
```

In the code sample below, we create a simple class that takes a schema as a `constructor` argument. We then apply the `schema.validate()` method, which validates our incoming argument against the provided schema.

As noted earlier, a **validation pipe** either returns the value unchanged, or throws an exception.

In the next section, you'll see how we supply the appropriate schema for a given controller method using the `@UsePipes()` decorator. Doing so makes our validation pipe re-usable across contexts, just as we set out to do.

JS TS

```typescript

import { PipeTransform, Injectable, ArgumentMetadata, BadRequestException } from '@nestjs/common';
import { ObjectSchema } from 'joi';

@Injectable()
export class JoiValidationPipe implements PipeTransform {
  constructor(private schema: ObjectSchema) {}

  transform(value: any, metadata: ArgumentMetadata) {
    const { error } = this.schema.validate(value);
    if (error) {
      throw new BadRequestException('Validation failed');
    }
    return value;
  }
}
```

```typescript

import { Injectable, BadRequestException } from '@nestjs/common';

@Injectable()
export class JoiValidationPipe {
  constructor(schema) {
    this.schema = schema;
  }

  transform(value, metadata) {
    const { error } = this.schema.validate(value);
    if (error) {
      throw new BadRequestException('Validation failed');
    }
    return value;
  }
}
```

```typescript

@Post()
@UsePipes(new JoiValidationPipe(createCatSchema))
async create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

```typescript

@Post()
@Bind(Body())
@UsePipes(new JoiValidationPipe(createCatSchema))
async create(createCatDto) {
  this.catsService.create(createCatDto);
}
```

> **Hint** The `@UsePipes()` decorator is imported from the `@nestjs/common` package.

#### Class validator[#](/pipes#class-validator)

> **Warning** The techniques in this section require TypeScript, and are not available if your app is written using vanilla JavaScript.

Let's look at an alternate implementation for our validation technique.

Nest works well with the [class-validator](https://github.com/typestack/class-validator) library. This powerful library allows you to use decorator-based validation. Decorator-based validation is extremely powerful, especially when combined with Nest's **Pipe** capabilities since we have access to the `metatype` of the processed property. Before we start, we need to install the required packages:

```bash

$ npm i --save class-validator class-transformer
```

Once these are installed, we can add a few decorators to the `CreateCatDto` class. Here we see a significant advantage of this technique: the `CreateCatDto` class remains the single source of truth for our Post body object (rather than having to create a separate validation class).

create-cat.dto.ts

JS TS

```typescript

import { IsString, IsInt } from 'class-validator';

export class CreateCatDto {
  @IsString()
  name: string;

  @IsInt()
  age: number;

  @IsString()
  breed: string;
}
```

> **Hint** Read more about the class-validator decorators [here](https://github.com/typestack/class-validator#usage).

Now we can create a `ValidationPipe` class that uses these annotations.

validation.pipe.ts

JS TS

```typescript

import { PipeTransform, Injectable, ArgumentMetadata, BadRequestException } from '@nestjs/common';
import { validate } from 'class-validator';
import { plainToClass } from 'class-transformer';

@Injectable()
export class ValidationPipe implements PipeTransform<any> {
  async transform(value: any, { metatype }: ArgumentMetadata) {
    if (!metatype || !this.toValidate(metatype)) {
      return value;
    }
    const object = plainToClass(metatype, value);
    const errors = await validate(object);
    if (errors.length > 0) {
      throw new BadRequestException('Validation failed');
    }
    return value;
  }

  private toValidate(metatype: Function): boolean {
    const types: Function[] = [String, Boolean, Number, Array, Object];
    return !types.includes(metatype);
  }
}
```

> **Notice** Above, we have used the [class-transformer](https://github.com/typestack/class-transformer) library. It's made by the same author as the **class-validator** library, and as a result, they play very well together.

```typescript

@Post()
async create(
  @Body(new ValidationPipe()) createCatDto: CreateCatDto,
) {
  this.catsService.create(createCatDto);
}
```

Parameter-scoped pipes are useful when the validation logic concerns only one specified parameter.

#### Global scoped pipes[#](/pipes#global-scoped-pipes)

Since the `ValidationPipe` was created to be as generic as possible, we can realize it's full utility by setting it up as a **global-scoped** pipe so that it is applied to every route handler across the entire application.

main.ts

JS TS

```typescript

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.useGlobalPipes(new ValidationPipe());
  await app.listen(3000);
}
bootstrap();
```

> **Notice** In the case of [hybrid apps](faq/hybrid-application) the `useGlobalPipes()` method doesn't set up pipes for gateways and micro services. For "standard" (non-hybrid) microservice apps, `useGlobalPipes()` does mount pipes globally.

Global pipes are used across the whole application, for every controller and every route handler.

Note that in terms of dependency injection, global pipes registered from outside of any module (with `useGlobalPipes()` as in the example above) cannot inject dependencies since the binding has been done outside the context of any module. In order to solve this issue, you can set up a global pipe **directly from any module** using the following construction:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { APP_PIPE } from '@nestjs/core';

@Module({
  providers: [
    {
      provide: APP_PIPE,
      useClass: ValidationPipe,
    },
  ],
})
export class AppModule {}
```

> **Hint** When using this approach to perform dependency injection for the pipe, note that regardless of the module where this construction is employed, the pipe is, in fact, global. Where should this be done? Choose the module where the pipe (`ValidationPipe` in the example above) is defined. Also, `useClass` is not the only way of dealing with custom provider registration. Learn more [here](/v8/fundamentals/custom-providers).

#### The built-in ValidationPipe[#](/pipes#the-built-in-validationpipe)

As a reminder, you don't have to build a generic validation pipe on your own since the `ValidationPipe` is provided by Nest out-of-the-box. The built-in `ValidationPipe` offers more options than the sample we built in this chapter, which has been kept basic for the sake of illustrating the mechanics of a custom-built pipe. You can find full details, along with lots of examples [here](/v8/techniques/validation).

#### Transformation use case[#](/pipes#transformation-use-case)

Validation isn't the only use case for custom pipes. At the beginning of this chapter, we mentioned that a pipe can also **transform** the input data to the desired format. This is possible because the value returned from the `transform` function completely overrides the previous value of the argument.

When is this useful? Consider that sometimes the data passed from the client needs to undergo some change - for example converting a string to an integer - before it can be properly handled by the route handler method. Furthermore, some required data fields may be missing, and we would like to apply default values. **Transformation pipes** can perform these functions by interposing a processing function between the client request and the request handler.

Here's a simple `ParseIntPipe` which is responsible for parsing a string into an integer value. (As noted above, Nest has a built-in `ParseIntPipe` that is more sophisticated; we include this as a simple example of a custom transformation pipe).

parse-int.pipe.ts

JS TS

```typescript

import { PipeTransform, Injectable, ArgumentMetadata, BadRequestException } from '@nestjs/common';

@Injectable()
export class ParseIntPipe implements PipeTransform<string, number> {
  transform(value: string, metadata: ArgumentMetadata): number {
    const val = parseInt(value, 10);
    if (isNaN(val)) {
      throw new BadRequestException('Validation failed');
    }
    return val;
  }
}
```

```typescript

import { Injectable, BadRequestException } from '@nestjs/common';

@Injectable()
export class ParseIntPipe {
  transform(value, metadata) {
    const val = parseInt(value, 10);
    if (isNaN(val)) {
      throw new BadRequestException('Validation failed');
    }
    return val;
  }
}
```

We can then bind this pipe to the selected param as shown below:

JS TS

```typescript

@Get(':id')
async findOne(@Param('id', new ParseIntPipe()) id) {
  return this.catsService.findOne(id);
}
```

```typescript

@Get(':id')
@Bind(Param('id', new ParseIntPipe()))
async findOne(id) {
  return this.catsService.findOne(id);
}
```

Another useful transformation case would be to select an **existing user** entity from the database using an id supplied in the request:

JS TS

```typescript

@Get(':id')
findOne(@Param('id', UserByIdPipe) userEntity: UserEntity) {
  return userEntity;
}
```

```typescript

@Get(':id')
@Bind(Param('id', UserByIdPipe))
findOne(userEntity) {
  return userEntity;
}
```

We leave the implementation of this pipe to the reader, but note that like all other transformation pipes, it receives an input value (an `id`) and returns an output value (a `UserEntity` object). This can make your code more declarative and [DRY](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself) by abstracting boilerplate code out of your handler and into a common pipe.

#### Providing defaults[#](/pipes#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:

JS TS

```typescript

@Get()
async findAll(
  @Query('activeOnly', new DefaultValuePipe(false), ParseBoolPipe) activeOnly: boolean,
  @Query('page', new DefaultValuePipe(0), ParseIntPipe) page: number,
) {
  return this.catsService.findAll({ activeOnly, page });
}
```

----
url: https://docs.nestjs.com/v8/graphql/scalars
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Scalars](https://docs.nestjs.com/v8/graphql/scalars#scalars)
* [Code first](https://docs.nestjs.com/v8/graphql/scalars#code-first)
* [Override a default scalar](https://docs.nestjs.com/v8/graphql/scalars#override-a-default-scalar)
* [Import a custom scalar](https://docs.nestjs.com/v8/graphql/scalars#import-a-custom-scalar)
* [Create a custom scalar](https://docs.nestjs.com/v8/graphql/scalars#create-a-custom-scalar)
* [Schema first](https://docs.nestjs.com/v8/graphql/scalars#schema-first)

```typescript

GraphQLModule.forRoot({
  buildSchemaOptions: {
    dateScalarMode: 'timestamp',
  }
}),
```

Likewise, the `GraphQLFloat` is used by default to represent the `number` type. To use the `GraphQLInt` instead, set the `numberScalarMode` of the `buildSchemaOptions` object to `'integer'` as follows:

```typescript

GraphQLModule.forRoot({
  buildSchemaOptions: {
    numberScalarMode: 'integer',
  }
}),
```

In addition, you can create custom scalars.

#### Override a default scalar[#](/graphql/scalars#override-a-default-scalar)

To create a custom implementation for the `Date` scalar, simply create a new class.

```typescript

import { Scalar, CustomScalar } from '@nestjs/graphql';
import { Kind, ValueNode } from 'graphql';

@Scalar('Date', (type) => Date)
export class DateScalar implements CustomScalar<number, Date> {
  description = 'Date custom scalar type';

  parseValue(value: number): Date {
    return new Date(value); // value from the client
  }

  serialize(value: Date): number {
    return value.getTime(); // value sent to the client
  }

  parseLiteral(ast: ValueNode): Date {
    if (ast.kind === Kind.INT) {
      return new Date(ast.value);
    }
    return null;
  }
}
```

With this in place, register `DateScalar` as a provider.

```typescript

@Module({
  providers: [DateScalar],
})
export class CommonModule {}
```

Now we can use the `Date` type in our classes.

```typescript

@Field()
creationDate: Date;
```

#### Import a custom scalar[#](/graphql/scalars#import-a-custom-scalar)

To use a custom scalar, import and register it as a resolver. We’ll use the `graphql-type-json` package for demonstration purposes. This npm package defines a `JSON` GraphQL scalar type.

Start by installing the package:

```bash

$ npm i --save graphql-type-json
```

Once the package is installed, we pass a custom resolver to the `forRoot()` method:

```typescript

import GraphQLJSON from 'graphql-type-json';

@Module({
  imports: [
    GraphQLModule.forRoot({
      resolvers: { JSON: GraphQLJSON },
    }),
  ],
})
export class AppModule {}
```

Now we can use the `JSON` type in our classes.

```typescript

@Field((type) => GraphQLJSON)
info: JSON;
```

For a suite of useful scalars, take a look at the [graphql-scalars](https://www.npmjs.com/package/graphql-scalars) package.

#### Create a custom scalar[#](/graphql/scalars#create-a-custom-scalar)

To define a custom scalar, create a new `GraphQLScalarType` instance. We'll create a custom `UUID` scalar.

```typescript

const regex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;

function validate(uuid: unknown): string | never {
  if (typeof uuid !== "string" || !regex.test(uuid)) {
    throw new Error("invalid uuid");
  }
  return uuid;
}

export const CustomUuidScalar = new GraphQLScalarType({
  name: 'UUID',
  description: 'A simple UUID parser',
  serialize: (value) => validate(value),
  parseValue: (value) => validate(value),
  parseLiteral: (ast) => validate(ast.value)
})
```

We pass a custom resolver to the `forRoot()` method:

```typescript

@Module({
  imports: [
    GraphQLModule.forRoot({
      resolvers: { UUID: CustomUuidScalar },
    }),
  ],
})
export class AppModule {}
```

Now we can use the `UUID` type in our classes.

```typescript

@Field((type) => CustomUuidScalar)
uuid: string;
```

#### Schema first[#](/graphql/scalars#schema-first)

To define a custom scalar (read more about scalars [here](https://www.apollographql.com/docs/graphql-tools/scalars.html)), create a type definition and a dedicated resolver. Here (as in the official documentation), we’ll use the `graphql-type-json` package for demonstration purposes. This npm package defines a `JSON` GraphQL scalar type.

Start by installing the package:

```bash

$ npm i --save graphql-type-json
```

Once the package is installed, we pass a custom resolver to the `forRoot()` method:

```typescript

import GraphQLJSON from 'graphql-type-json';

@Module({
  imports: [
    GraphQLModule.forRoot({
      typePaths: ['./**/*.graphql'],
      resolvers: { JSON: GraphQLJSON },
    }),
  ],
})
export class AppModule {}
```

Now we can use the `JSON` scalar in our type definitions:

```graphql

scalar JSON

type Foo {
  field: JSON
}
```

Another method to define a scalar type is to create a simple class. Assume we want to enhance our schema with the `Date` type.

```typescript

import { Scalar, CustomScalar } from '@nestjs/graphql';
import { Kind, ValueNode } from 'graphql';

@Scalar('Date')
export class DateScalar implements CustomScalar<number, Date> {
  description = 'Date custom scalar type';

  parseValue(value: number): Date {
    return new Date(value); // value from the client
  }

  serialize(value: Date): number {
    return value.getTime(); // value sent to the client
  }

  parseLiteral(ast: ValueNode): Date {
    if (ast.kind === Kind.INT) {
      return new Date(ast.value);
    }
    return null;
  }
}
```

With this in place, register `DateScalar` as a provider.

```typescript

@Module({
  providers: [DateScalar],
})
export class CommonModule {}
```

Now we can use the `Date` scalar in type definitions.

```graphql

scalar Date
```

By default, the generated TypeScript definition for all scalars is `any` - which isn't particularly typesafe. But, you can configure how Nest generates typings for your custom scalars when you specify how to generate types:

```typescript

import { GraphQLDefinitionsFactory } from '@nestjs/graphql';
import { join } from 'path';

const definitionsFactory = new GraphQLDefinitionsFactory();

definitionsFactory.generate({
  typePaths: ['./src/**/*.graphql'],
  path: join(process.cwd(), 'src/graphql.ts'),
  outputAs: 'class',
  defaultScalarType: 'unknown',
  customScalarTypeMapping: {
    DateTime: 'Date',
    BigNumber: '_BigNumber',
  },
  additionalHeader: "import _BigNumber from 'bignumber.js'",
});
```

> **Hint** Alternatively, you can use a type reference instead, for example: `DateTime: Date`. In this case, `GraphQLDefinitionsFactory` will extract the name property of the specified type (`Date.name`) to generate TS definitions. Note: adding an import statement for non-built-in types (custom types) is required.

Now, given the following GraphQL custom scalar types:

```graphql

scalar DateTime
scalar BigNumber
scalar Payload
```

We will now see the following generated TypeScript definitions in `src/graphql.ts`:

```typescript

import _BigNumber from 'bignumber.js';

export type DateTime = Date;
export type BigNumber = _BigNumber;
export type Payload = unknown;
```

Here, we've used the `customScalarTypeMapping` property to supply a map of the types we wish to declare for our custom scalars. We've also provided an `additionalHeader` property so that we can add any imports required for these type definitions. Lastly, we've added a `defaultScalarType` of `'unknown'`, so that any custom scalars not specified in `customScalarTypeMapping` will be aliased to `unknown` instead of `any` (which [TypeScript recommends](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-0.html#new-unknown-top-type) using since 3.0 for added type safety).

> **Hint** Note that we've imported `_BigNumber` from `bignumber.js`; this is to avoid [circular type references](https://github.com/Microsoft/TypeScript/issues/12525#issuecomment-263166239).

----
url: https://docs.nestjs.com/v11/recipes/terminus
----

* [Healthchecks (Terminus)](https://docs.nestjs.com/v11/recipes/terminus#healthchecks-terminus)
* [Getting started](https://docs.nestjs.com/v11/recipes/terminus#getting-started)
* [Setting up a Healthcheck](https://docs.nestjs.com/v11/recipes/terminus#setting-up-a-healthcheck)
* [HTTP Healthcheck](https://docs.nestjs.com/v11/recipes/terminus#http-healthcheck)
* [TypeOrm health indicator](https://docs.nestjs.com/v11/recipes/terminus#typeorm-health-indicator)
* [Disk health indicator](https://docs.nestjs.com/v11/recipes/terminus#disk-health-indicator)
* [Memory health indicator](https://docs.nestjs.com/v11/recipes/terminus#memory-health-indicator)
* [Custom health indicator](https://docs.nestjs.com/v11/recipes/terminus#custom-health-indicator)
* [Logging](https://docs.nestjs.com/v11/recipes/terminus#logging)
* [Graceful shutdown timeout](https://docs.nestjs.com/v11/recipes/terminus#graceful-shutdown-timeout)
* [More examples](https://docs.nestjs.com/v11/recipes/terminus#more-examples)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/recipes/terminus.md "Suggest Edits")

### Healthchecks (Terminus)

Terminus integration provides you with **readiness/liveness** health checks. Healthchecks are crucial when it comes to complex backend setups. In a nutshell, a health check in the realm of web development usually consists of a special address, for example, `https://my-website.com/health/readiness`. A service or a component of your infrastructure (e.g., [Kubernetes](https://kubernetes.io/) checks this address continuously). Depending on the HTTP status code returned from a `GET` request to this address the service will take action when it receives an "unhealthy" response. Since the definition of "healthy" or "unhealthy" varies with the type of service you provide, the **Terminus** integration supports you with a set of **health indicators**.

As an example, if your web server uses MongoDB to store its data, it would be vital information whether MongoDB is still up and running. In that case, you can make use of the `MongooseHealthIndicator`. If configured correctly - more on that later - your health check address will return a healthy or unhealthy HTTP status code, depending on whether MongoDB is running.

#### Getting started[#](/recipes/terminus#getting-started)

To get started with `@nestjs/terminus` we need to install the required dependency.

```bash

$ npm install --save @nestjs/terminus
```

> **Hint** To create the module using the [Nest CLI](/v11/recipes/terminus/cli/overview), simply execute the `$ nest g module health` command.

health.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { TerminusModule } from '@nestjs/terminus';

@Module({
  imports: [TerminusModule]
})
export class HealthModule {}
```

Our healthcheck(s) can be executed using a [controller](/v11/controllers), which can be easily set up using the [Nest CLI](/v11/recipes/terminus/cli/overview).

```bash

$ nest g controller health
```

> **Info** It is highly recommended to enable shutdown hooks in your application. Terminus integration makes use of this lifecycle event if enabled. Read more about shutdown hooks [here](fundamentals/lifecycle-events#application-shutdown).

#### HTTP Healthcheck[#](/recipes/terminus#http-healthcheck)

Once we have installed `@nestjs/terminus`, imported our `TerminusModule` and created a new controller, we are ready to create a health check.

The `HTTPHealthIndicator` requires the `@nestjs/axios` package so make sure to have it installed:

```bash

$ npm i --save @nestjs/axios axios
```

Now we can setup our `HealthController`:

health.controller.ts

JS TS

```typescript

import { Controller, Get } from '@nestjs/common';
import { HealthCheckService, HttpHealthIndicator, HealthCheck } from '@nestjs/terminus';

@Controller('health')
export class HealthController {
  constructor(
    private health: HealthCheckService,
    private http: HttpHealthIndicator,
  ) {}

  @Get()
  @HealthCheck()
  check() {
    return this.health.check([
      () => this.http.pingCheck('nestjs-docs', 'https://docs.nestjs.com'),
    ]);
  }
}
```

```typescript

import { Controller, Dependencies, Get } from '@nestjs/common';
import { HealthCheckService, HttpHealthIndicator, HealthCheck } from '@nestjs/terminus';

@Controller('health')
@Dependencies(HealthCheckService, HttpHealthIndicator)
export class HealthController {
  constructor(
    private health,
    private http,
  ) { }

  @Get()
  @HealthCheck()
  healthCheck() {
    return this.health.check([
      () => this.http.pingCheck('nestjs-docs', 'https://docs.nestjs.com'),
    ])
  }
}
```

health.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { TerminusModule } from '@nestjs/terminus';
import { HttpModule } from '@nestjs/axios';
import { HealthController } from './health.controller';

@Module({
  imports: [TerminusModule, HttpModule],
  controllers: [HealthController],
})
export class HealthModule {}
```

```typescript

import { Module } from '@nestjs/common';
import { TerminusModule } from '@nestjs/terminus';
import { HttpModule } from '@nestjs/axios';
import { HealthController } from './health.controller';

@Module({
  imports: [TerminusModule, HttpModule],
  controllers: [HealthController],
})
export class HealthModule {}
```

Our health check will now send a *GET*-request to the `https://docs.nestjs.com` address. If we get a healthy response from that address, our route at `http://localhost:3000/health` will return the following object with a 200 status code.

```json

{
  "status": "ok",
  "info": {
    "nestjs-docs": {
      "status": "up"
    }
  },
  "error": {},
  "details": {
    "nestjs-docs": {
      "status": "up"
    }
  }
}
```

The interface of this response object can be accessed from the `@nestjs/terminus` package with the `HealthCheckResult` interface.

| `status`  | If any health indicator failed the status will be `'error'`. If the NestJS app is shutting down but still accepting HTTP requests, the health check will have the `'shutting_down'` status. | `'error' \| 'ok' \| 'shutting_down'` |
| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------ |
| `info`    | Object containing information of each health indicator which is of status `'up'`, or in other words "healthy".                                                                              | `object`                             |
| `error`   | Object containing information of each health indicator which is of status `'down'`, or in other words "unhealthy".                                                                          | `object`                             |
| `details` | Object containing all information of each health indicator                                                                                                                                  | `object`                             |

##### Check for specific HTTP response codes

In certain cases, you might want to check for specific criteria and validate the response. As an example, let's assume `https://my-external-service.com` returns a response code `204`. With `HttpHealthIndicator.responseCheck` you can check for that response code specifically and determine all other codes as unhealthy.

In case any other response code other than `204` gets returned, the following example would be unhealthy. The third parameter requires you to provide a function (sync or async) which returns a boolean whether the response is considered healthy (`true`) or unhealthy (`false`).

health.controller.ts

JS TS

```typescript

// Within the `HealthController`-class

@Get()
@HealthCheck()
check() {
  return this.health.check([
    () =>
      this.http.responseCheck(
        'my-external-service',
        'https://my-external-service.com',
        (res) => res.status === 204,
      ),
  ]);
}
```

#### TypeOrm health indicator[#](/recipes/terminus#typeorm-health-indicator)

Terminus offers the capability to add database checks to your health check. In order to get started with this health indicator, you should check out the [Database chapter](/v11/techniques/sql) and make sure your database connection within your application is established.

> **Hint** Behind the scenes the `TypeOrmHealthIndicator` simply executes a `SELECT 1`-SQL command which is often used to verify whether the database still alive. In case you are using an Oracle database it uses `SELECT 1 FROM DUAL`.

health.controller.ts

JS TS

```typescript

@Controller('health')
export class HealthController {
  constructor(
    private health: HealthCheckService,
    private db: TypeOrmHealthIndicator,
  ) {}

  @Get()
  @HealthCheck()
  check() {
    return this.health.check([
      () => this.db.pingCheck('database'),
    ]);
  }
}
```

```typescript

@Controller('health')
@Dependencies(HealthCheckService, TypeOrmHealthIndicator)
export class HealthController {
  constructor(
    private health,
    private db,
  ) { }

  @Get()
  @HealthCheck()
  healthCheck() {
    return this.health.check([
      () => this.db.pingCheck('database'),
    ])
  }
}
```

If your database is reachable, you should now see the following JSON-result when requesting `http://localhost:3000/health` with a `GET` request:

```json

{
  "status": "ok",
  "info": {
    "database": {
      "status": "up"
    }
  },
  "error": {},
  "details": {
    "database": {
      "status": "up"
    }
  }
}
```

In case your app uses [multiple databases](techniques/database#multiple-databases), you need to inject each connection into your `HealthController`. Then, you can simply pass the connection reference to the `TypeOrmHealthIndicator`.

health.controller.ts

JS TS

```typescript

@Controller('health')
export class HealthController {
  constructor(
    private health: HealthCheckService,
    private db: TypeOrmHealthIndicator,
    @InjectConnection('albumsConnection')
    private albumsConnection: Connection,
    @InjectConnection()
    private defaultConnection: Connection,
  ) {}

  @Get()
  @HealthCheck()
  check() {
    return this.health.check([
      () => this.db.pingCheck('albums-database', { connection: this.albumsConnection }),
      () => this.db.pingCheck('database', { connection: this.defaultConnection }),
    ]);
  }
}
```

#### Disk health indicator[#](/recipes/terminus#disk-health-indicator)

With the `DiskHealthIndicator` we can check how much storage is in use. To get started, make sure to inject the `DiskHealthIndicator` into your `HealthController`. The following example checks the storage used of the path `/` (or on Windows you can use `C:\\`). If that exceeds more than 50% of the total storage space it would response with an unhealthy Health Check.

health.controller.ts

JS TS

```typescript

@Controller('health')
export class HealthController {
  constructor(
    private readonly health: HealthCheckService,
    private readonly disk: DiskHealthIndicator,
  ) {}

  @Get()
  @HealthCheck()
  check() {
    return this.health.check([
      () => this.disk.checkStorage('storage', { path: '/', thresholdPercent: 0.5 }),
    ]);
  }
}
```

```typescript

@Controller('health')
@Dependencies(HealthCheckService, DiskHealthIndicator)
export class HealthController {
  constructor(health, disk) {}

  @Get()
  @HealthCheck()
  healthCheck() {
    return this.health.check([
      () => this.disk.checkStorage('storage', { path: '/', thresholdPercent: 0.5 }),
    ])
  }
}
```

With the `DiskHealthIndicator.checkStorage` function you also have the possibility to check for a fixed amount of space. The following example would be unhealthy in case the path `/my-app/` would exceed 250GB.

health.controller.ts

JS TS

```typescript

// Within the `HealthController`-class

@Get()
@HealthCheck()
check() {
  return this.health.check([
    () => this.disk.checkStorage('storage', {  path: '/', threshold: 250 * 1024 * 1024 * 1024, })
  ]);
}
```

#### Memory health indicator[#](/recipes/terminus#memory-health-indicator)

To make sure your process does not exceed a certain memory limit the `MemoryHealthIndicator` can be used. The following example can be used to check the heap of your process.

> **Hint** Heap is the portion of memory where dynamically allocated memory resides (i.e. memory allocated via malloc). Memory allocated from the heap will remain allocated until one of the following occurs:
>
> * The memory is *free*'d
> * The program terminates

health.controller.ts

JS TS

```typescript

@Controller('health')
export class HealthController {
  constructor(
    private health: HealthCheckService,
    private memory: MemoryHealthIndicator,
  ) {}

  @Get()
  @HealthCheck()
  check() {
    return this.health.check([
      () => this.memory.checkHeap('memory_heap', 150 * 1024 * 1024),
    ]);
  }
}
```

```typescript

@Controller('health')
@Dependencies(HealthCheckService, MemoryHealthIndicator)
export class HealthController {
  constructor(health, memory) {}

  @Get()
  @HealthCheck()
  healthCheck() {
    return this.health.check([
      () => this.memory.checkHeap('memory_heap', 150 * 1024 * 1024),
    ])
  }
}
```

It is also possible to verify the memory RSS of your process with `MemoryHealthIndicator.checkRSS`. This example would return an unhealthy response code in case your process does have more than 150MB allocated.

> **Hint** RSS is the Resident Set Size and is used to show how much memory is allocated to that process and is in RAM. It does not include memory that is swapped out. It does include memory from shared libraries as long as the pages from those libraries are actually in memory. It does include all stack and heap memory.

health.controller.ts

JS TS

```typescript

// Within the `HealthController`-class

@Get()
@HealthCheck()
check() {
  return this.health.check([
    () => this.memory.checkRSS('memory_rss', 150 * 1024 * 1024),
  ]);
}
```

#### Custom health indicator[#](/recipes/terminus#custom-health-indicator)

In some cases, the predefined health indicators provided by `@nestjs/terminus` do not cover all of your health check requirements. In that case, you can set up a custom health indicator according to your needs.

Let's get started by creating a service that will represent our custom indicator. To get a basic understanding of how an indicator is structured, we will create an example `DogHealthIndicator`. This service should have the state `'up'` if every `Dog` object has the type `'goodboy'`. If that condition is not satisfied then it should throw an error.

dog.health.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { HealthIndicatorService } from '@nestjs/terminus';

export interface Dog {
  name: string;
  type: string;
}

@Injectable()
export class DogHealthIndicator {
  constructor(
    private readonly healthIndicatorService: HealthIndicatorService
  ) {}

  private dogs: Dog[] = [
    { name: 'Fido', type: 'goodboy' },
    { name: 'Rex', type: 'badboy' },
  ];

  async isHealthy(key: string){
    const indicator = this.healthIndicatorService.check(key);
    const badboys = this.dogs.filter(dog => dog.type === 'badboy');
    const isHealthy = badboys.length === 0;

    if (!isHealthy) {
      return indicator.down({ badboys: badboys.length });
    }

    return indicator.up();
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';
import { HealthIndicatorService } from '@nestjs/terminus';

@Injectable()
@Dependencies(HealthIndicatorService)
export class DogHealthIndicator {
  constructor(healthIndicatorService) {
    this.healthIndicatorService = healthIndicatorService;
  }

  private dogs = [
    { name: 'Fido', type: 'goodboy' },
    { name: 'Rex', type: 'badboy' },
  ];

  async isHealthy(key){
    const indicator = this.healthIndicatorService.check(key);
    const badboys = this.dogs.filter(dog => dog.type === 'badboy');
    const isHealthy = badboys.length === 0;

    if (!isHealthy) {
      return indicator.down({ badboys: badboys.length });
    }

    return indicator.up();
  }
}
```

The next thing we need to do is register the health indicator as a provider.

health.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { TerminusModule } from '@nestjs/terminus';
import { DogHealthIndicator } from './dog.health';

@Module({
  controllers: [HealthController],
  imports: [TerminusModule],
  providers: [DogHealthIndicator]
})
export class HealthModule { }
```

> **Hint** In a real-world application the `DogHealthIndicator` should be provided in a separate module, for example, `DogModule`, which then will be imported by the `HealthModule`.

The last required step is to add the now available health indicator in the required health check endpoint. For that, we go back to our `HealthController` and add it to our `check` function.

health.controller.ts

JS TS

```typescript

import { HealthCheckService, HealthCheck } from '@nestjs/terminus';
import { Injectable, Dependencies, Get } from '@nestjs/common';
import { DogHealthIndicator } from './dog.health';

@Injectable()
export class HealthController {
  constructor(
    private health: HealthCheckService,
    private dogHealthIndicator: DogHealthIndicator
  ) {}

  @Get()
  @HealthCheck()
  healthCheck() {
    return this.health.check([
      () => this.dogHealthIndicator.isHealthy('dog'),
    ])
  }
}
```

```typescript

import { HealthCheckService, HealthCheck } from '@nestjs/terminus';
import { Injectable, Get } from '@nestjs/common';
import { DogHealthIndicator } from './dog.health';

@Injectable()
@Dependencies(HealthCheckService, DogHealthIndicator)
export class HealthController {
  constructor(
    health,
    dogHealthIndicator
  ) {
    this.health = health;
    this.dogHealthIndicator = dogHealthIndicator;
  }

  @Get()
  @HealthCheck()
  healthCheck() {
    return this.health.check([
      () => this.dogHealthIndicator.isHealthy('dog'),
    ])
  }
}
```

#### Logging[#](/recipes/terminus#logging)

Terminus only logs error messages, for instance when a Healthcheck has failed. With the `TerminusModule.forRoot()` method you have more control over how errors are being logged as well as completely take over the logging itself.

In this section, we are going to walk you through how you create a custom logger `TerminusLogger`. This logger extends the built-in logger. Therefore you can pick and choose which part of the logger you would like to overwrite

> **Info** If you want to learn more about custom loggers in NestJS, [read more here](/techniques/logger#injecting-a-custom-logger).

terminus-logger.service.ts

JS TS

```typescript

import { Injectable, Scope, ConsoleLogger } from '@nestjs/common';

@Injectable({ scope: Scope.TRANSIENT })
export class TerminusLogger extends ConsoleLogger {
  error(message: any, stack?: string, context?: string): void;
  error(message: any, ...optionalParams: any[]): void;
  error(
    message: unknown,
    stack?: unknown,
    context?: unknown,
    ...rest: unknown[]
  ): void {
    // Overwrite here how error messages should be logged
  }
}
```

Once you have created your custom logger, all you need to do is simply pass it into the `TerminusModule.forRoot()` as such.

health.module.ts

JS TS

```typescript

@Module({
imports: [
  TerminusModule.forRoot({
    logger: TerminusLogger,
  }),
],
})
export class HealthModule {}
```

To completely suppress any log messages coming from Terminus, including error messages, configure Terminus as such.

health.module.ts

JS TS

```typescript

@Module({
imports: [
  TerminusModule.forRoot({
    logger: false,
  }),
],
})
export class HealthModule {}
```

Terminus allows you to configure how Healthcheck errors should be displayed in your logs.

| Error Log Style  | Description                                                                                                                        | Example |
| :--------------- | :--------------------------------------------------------------------------------------------------------------------------------- | :------ |
| `json` (default) | Prints a summary of the health check result in case of an error as JSON object                                                     |         |
| `pretty`         | Prints a summary of the health check result in case of an error within formatted boxes and highlights successful/erroneous results |         |

You can change the log style using the `errorLogStyle` configuration option as in the following snippet.

health.module.ts

JS TS

```typescript

@Module({
  imports: [
    TerminusModule.forRoot({
      errorLogStyle: 'pretty',
    }),
  ]
})
export class HealthModule {}
```

#### Graceful shutdown timeout[#](/recipes/terminus#graceful-shutdown-timeout)

If your application requires postponing its shutdown process, Terminus can handle it for you. This setting can prove particularly beneficial when working with an orchestrator such as Kubernetes. By setting a delay slightly longer than the readiness check interval, you can achieve zero downtime when shutting down containers.

health.module.ts

JS TS

```typescript

@Module({
  imports: [
    TerminusModule.forRoot({
      gracefulShutdownTimeoutMs: 1000,
    }),
  ]
})
export class HealthModule {}
```

#### More examples[#](/recipes/terminus#more-examples)

More working examples are available [here](https://github.com/nestjs/terminus/tree/master/sample).

----
url: https://docs.nestjs.com/v10/devtools/overview
----

* [Overview](https://docs.nestjs.com/v10/devtools/overview#overview)
* [Investigating the "Cannot resolve dependency" error](https://docs.nestjs.com/v10/devtools/overview#investigating-the-cannot-resolve-dependency-error)
* [Routes explorer](https://docs.nestjs.com/v10/devtools/overview#routes-explorer)
* [Sandbox](https://docs.nestjs.com/v10/devtools/overview#sandbox)
* [Bootstrap performance analyzer](https://docs.nestjs.com/v10/devtools/overview#bootstrap-performance-analyzer)
* [Audit](https://docs.nestjs.com/v10/devtools/overview#audit)
* [Preview static files](https://docs.nestjs.com/v10/devtools/overview#preview-static-files)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/devtools/overview.md "Suggest Edits")

### Overview

> **Hint** This chapter covers the Nest Devtools integration with the Nest framework. If you are looking for the Devtools application, please visit the [Devtools](https://devtools.nestjs.com) website.

To start debugging your local application, open up the `main.ts` file and make sure to set the `snapshot` attribute to `true` in the application options object, as follows:

```typescript

async function bootstrap() {
  const app = await NestFactory.create(AppModule, {
    snapshot: true,
  });
  await app.listen(process.env.PORT ?? 3000);
}
```

This will instruct the framework to collect necessary metadata that will let Nest Devtools visualize your application's graph.

Next up, let's install the required dependency:

```bash

$ npm i @nestjs/devtools-integration
```

> **Warning** If you're using `@nestjs/graphql` package in your application, make sure to install the latest version (`npm i @nestjs/graphql@11`).

With this dependency in place, let's open up the `app.module.ts` file and import the `DevtoolsModule` that we just installed:

```typescript

@Module({
  imports: [
    DevtoolsModule.register({
      http: process.env.NODE_ENV !== 'production',
    }),
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}
```

> **Warning** The reason we are checking the `NODE_ENV` environment variable here is that you should never use this module in production!

Once the `DevtoolsModule` is imported and your application is up and running (`npm run start:dev`), you should be able to navigate to [Devtools](https://devtools.nestjs.com) URL and see the instrospected graph.

> **Hint** As you can see on the screenshot above, every module connects to the `InternalCoreModule`. `InternalCoreModule` is a global module that is always imported into the root module. Since it's registered as a global node, Nest automatically creates edges between all of the modules and the `InternalCoreModule` node. Now, if you want to hide global modules from the graph, you can use the "**Hide global modules**" checkbox (in the sidebar).

So as we can see, `DevtoolsModule` makes your application expose an additional HTTP server (on port 8000) that the Devtools application will use to introspect your app.

Just to double-check that everything works as expected, change the graph view to "Classes". You should see the following screen:

To focus on a specific node, click on the rectangle and the graph will show a popup window with the **"Focus"** button. You can also use the search bar (located in the sidebar) to find a specific node.

> **Hint** If you click on the **Inspect** button, application will take you to the `/debug` page with that specific node selected.

> **Hint** To export a graph as an image, click on the **Export as PNG** button in the right corner of the graph.

Using the form controls located in the sidebar (on the left), you can control edges proximity to, for example, visualize a specific application sub-tree:

This can be particularly useful when you have **new developers** on your team and you want to show them how your application is structured. You can also use this feature to visualize a specific module (e.g. `TasksModule`) and all of its dependencies, which can come in handy when you're breaking down a large application into smaller modules (for example, individual micro-services).

You can watch this video to see the **Graph Explorer** feature in action:

#### Investigating the "Cannot resolve dependency" error[#](/devtools/overview#investigating-the-cannot-resolve-dependency-error)

> **Note** This feature is supported for `@nestjs/core` >= `v9.3.10`.

Probably the most common error message you might have seen is about Nest not being able to resolve dependencies of a provider. Using Nest Devtools, you can effortlessly identify the issue and learn how to resolve it.

First, open up the `main.ts` file and update the `bootstrap()` call, as follows:

```typescript

bootstrap().catch((err) => {
  fs.writeFileSync('graph.json', PartialGraphHost.toString() ?? '');
  process.exit(1);
});
```

Also, make sure to set the `abortOnError` to `false`:

```typescript

const app = await NestFactory.create(AppModule, {
  snapshot: true,
  abortOnError: false, // <--- THIS
});
```

> **Hint** This page shows not only HTTP routes, but also all of the other entrypoints (e.g. WebSockets, gRPC, GraphQL resolvers etc.).

> **Hint** To pretty display an array of objects, use the `console.table()` (or just `table()`) function.

You can watch this video to see the **Interactive Playground** feature in action:

#### Bootstrap performance analyzer[#](/devtools/overview#bootstrap-performance-analyzer)

To see a list of all class nodes (controllers, providers, enhancers, etc.) and their corresponding instantiation times, navigate to the **Bootstrap performance** page:

This page is particularly useful when you want to identify the slowest parts of your application's bootstrap process (e.g. when you want to optimize the application's startup time which is crucial for, for example, serverless environments).

#### Audit[#](/devtools/overview#audit)

To see the auto-generated audit - errors/warnings/hints that the application came up with while analyzing your serialized graph, navigate to the **Audit** page:

> **Hint** The screenshot above doesn't show all of the available audit rules.

This page comes in handy when you want to identify potential issues in your application.

#### Preview static files[#](/devtools/overview#preview-static-files)

To save a serialized graph to a file, use the following code:

```typescript

await app.listen(process.env.PORT ?? 3000); // OR await app.init()
fs.writeFileSync('./graph.json', app.get(SerializedGraph).toString());
```

> **Hint**`SerializedGraph` is exported from the `@nestjs/core` package.

Then you can drag and drop/upload this file:

This is helpful when you want to share your graph with someone else (e.g., co-worker), or when you want to analyze it offline.

----
url: https://docs.nestjs.com/v4/graphql/mutations
----

### Mutations

In GraphQL, to modify the server-side data, we're using mutations. Read more about them [here](http://graphql.org/learn/queries/#mutations).

The official [Apollo](https://www.apollographql.com/docs/graphql-tools/generate-schema.html) documentation shares an `upvotePost()` mutation example. This mutation allows to increase a post `votes` property value.

JavaScript TypeScript

TypeScript

```typescript

Mutation: {
  upvotePost: (_, { postId }) => {
    const post = find(posts, { id: postId });
    if (!post) {
      throw new Error(`Couldn't find post with id ${postId}`);
    }
    post.votes += 1;
    return post;
  },
}
```

In order to create an equivalent mutation in Nest-way, we'll make use of the `@Mutation()` decorator. Let's extend our `AuthorResolver` used in the previous section ([resolvers map](/v4/graphql/resolvers-map)).

JavaScript TypeScript

TypeScript

```typescript

import { Query, Mutation, Resolver, ResolveProperty } from '@nestjs/graphql';
import { find, filter } from 'lodash';

// example data
const authors = [
  { id: 1, firstName: 'Tom', lastName: 'Coleman' },
  { id: 2, firstName: 'Sashko', lastName: 'Stubailo' },
  { id: 3, firstName: 'Mikhail', lastName: 'Novikov' },
];
const posts = [
  { id: 1, authorId: 1, title: 'Introduction to GraphQL', votes: 2 },
  { id: 2, authorId: 2, title: 'Welcome to Meteor', votes: 3 },
  { id: 3, authorId: 2, title: 'Advanced GraphQL', votes: 1 },
  { id: 4, authorId: 3, title: 'Launchpad is Cool', votes: 7 },
];

@Resolver('Author')
export class AuthorResolver {
  @Query('author')
  getAuthor(obj, args, context, info) {
    return find(authors, { id: args.id });
  }

  @Mutation()
  upvotePost(_, { postId }) {
    const post = find(posts, { id: postId });
    if (!post) {
      throw new Error(`Couldn't find post with id ${postId}`);
    }
    post.votes += 1;
    return post;
  }

  @ResolveProperty('posts')
  getPosts(author) {
    return filter(posts, { authorId: author.id });
  }
}
```

#### Refactor

Once again (same as in [resolvers map](/v4/graphql/resolvers-map) chapter) we're gonna do a small refactor to take advantages of the Nest architecture, to turn it into a **real-world** example.

JavaScript TypeScript

TypeScript

```typescript

@Resolver('Author')
export class AuthorResolver {
  constructor(
    private readonly authorsService: AuthorsService,
    private readonly postsService: PostsService,
  ) {}

  @Query('author')
  async getAuthor(obj, args, context, info) {
    const { id } = args;
    return await this.authorsService.findOneById(id);
  }

  @Mutation()
  async upvotePost(_, { postId }) {
    return await this.postsService.upvoteById({ id: postId });
  }

  @ResolveProperty('posts')
  async getPosts(author) {
    const { id } = author;
    return await this.postsService.findAll({ authorId: id });
  }
}
```

TypeScript

```typescript

@Resolver('Author')
@Dependencies(AuthorsService, PostsService)
export class AuthorResolver {
  constructor(authorsService, postsService) {
    this.authorsService = authorsService;
    this.postsService = postsService;
  }

  @Query('author')
  async getAuthor(obj, args, context, info) {
    const { id } = args;
    return await this.authorsService.findOneById(id);
  }

  @Mutation()
  async upvotePost(_, { postId }) {
    return await this.postsService.upvoteById({ id: postId });
  }

  @ResolveProperty('posts')
  async getPosts(author) {
    const { id } = author;
    return await this.postsService.findAll({ authorId: id });
  }
}
```

That's all. The business logic was moved to the `PostsService`.

#### Type definitions

The last step is to add our mutation to the existing type definitions.

author-types.graphql

Java

```java

type Author {
  id: Int!
  firstName: String
  lastName: String
  posts: [Post]
}

type Post {
  id: Int!
  title: String
  votes: Int
}

type Query {
  author(id: Int!): Author
}

type Mutation {
  upvotePost(postId: Int!): Post
}
```

The `upvotePost(postId: Int!): Post` mutation is here now!

#### Sponsors

[](https://valor-software.com/)

Nest is an MIT-licensed open source project. It can grow thanks to the support by these awesome people. If you'd like to join them, please read more [here](https://opencollective.com/nest). Thanks!

[](https://opencollective.com/nest/backer/0/website)[](https://opencollective.com/nest/backer/1/website)[](https://opencollective.com/nest/backer/2/website)[](https://opencollective.com/nest/backer/3/website)[](https://opencollective.com/nest/backer/4/website)[](https://opencollective.com/nest/backer/5/website)[](https://opencollective.com/nest/backer/6/website)[](https://opencollective.com/nest/backer/7/website)[](https://opencollective.com/nest/backer/8/website)[](https://opencollective.com/nest/backer/9/website)[](https://opencollective.com/nest/backer/10/website)[](https://opencollective.com/nest/backer/11/website)[](https://opencollective.com/nest/backer/12/website)[](https://opencollective.com/nest/backer/13/website)[](https://opencollective.com/nest/backer/14/website)[](https://opencollective.com/nest/backer/15/website)[](https://opencollective.com/nest/backer/16/website)[](https://opencollective.com/nest/backer/17/website)[](https://opencollective.com/nest/backer/18/website)[](https://opencollective.com/nest/backer/19/website)[](https://opencollective.com/nest/backer/20/website)[](https://opencollective.com/nest/backer/21/website)[](https://opencollective.com/nest/backer/22/website)[](https://opencollective.com/nest/backer/23/website)[](https://opencollective.com/nest/backer/24/website)[](https://opencollective.com/nest/backer/25/website)[](https://opencollective.com/nest/backer/26/website)[](https://opencollective.com/nest/backer/27/website)[](https://opencollective.com/nest/backer/28/website)[](https://opencollective.com/nest/backer/29/website)

[Become a sponsor](https://opencollective.com/nest)

----
url: https://docs.nestjs.com/graphql/directives
----

[Skip to content](#content)

On this page

* [Directives](https://docs.nestjs.com/graphql/directives#directives)
* [Custom directives](https://docs.nestjs.com/graphql/directives#custom-directives)
* [Code first](https://docs.nestjs.com/graphql/directives#code-first)
* [Schema first](https://docs.nestjs.com/graphql/directives#schema-first)

### Directives

A directive can be attached to a field or fragment inclusion, and can affect execution of the query in any way the server desires (see [directives](https://graphql.org/learn/queries/#directives) in the GraphQL documentation). The GraphQL specification provides several default directives:

* `@include(if: Boolean)`: include this field in the result only if the argument is `true`
* `@skip(if: Boolean)`: skip this field if the argument is `true`
* `@deprecated(reason: String)`: mark the field as deprecated, with a message

A directive is an identifier preceded by an `@` character, optionally followed by a list of named arguments. Directives can appear after almost any element in the GraphQL query and schema languages.

#### Custom directives[#](/graphql/directives#custom-directives)

To define what happens when Apollo or Mercurius encounters your directive, create a transformer function. This function uses the `mapSchema` function to iterate through locations in your schema (field definitions, type definitions, etc.) and apply the corresponding transformations.

```typescript

import { getDirective, MapperKind, mapSchema } from '@graphql-tools/utils';
import { defaultFieldResolver, GraphQLSchema } from 'graphql';

export function upperDirectiveTransformer(
  schema: GraphQLSchema,
  directiveName: string,
) {
  return mapSchema(schema, {
    [MapperKind.OBJECT_FIELD]: (fieldConfig) => {
      const upperDirective = getDirective(
        schema,
        fieldConfig,
        directiveName,
      )?.[0];

      if (upperDirective) {
        const { resolve = defaultFieldResolver } = fieldConfig;

        // Replace the original resolver with a function that *first* calls
        // the original resolver, then converts its result to upper case
        fieldConfig.resolve = async function (source, args, context, info) {
          const result = await resolve(source, args, context, info);
          if (typeof result === 'string') {
            return result.toUpperCase();
          }
          return result;
        };
        return fieldConfig;
      }
    },
  });
}
```

Next, apply the `upperDirectiveTransformer` function in the `GraphQLModule#forRoot()` method using the `transformSchema` option:

```typescript

GraphQLModule.forRoot({
  // ...
  transformSchema: (schema) => upperDirectiveTransformer(schema, 'upper'),
});
```

Once registered, the `@upper` directive can be used in your schema. How you apply the directive depends on the approach you use (code first or schema first).

#### Code first[#](/graphql/directives#code-first)

In the code first approach, use the `@Directive()` decorator to apply the directive:

```typescript

@Directive('@upper')
@Field()
title: string;
```

> **Hint** The `@Directive()` decorator is exported from the `@nestjs/graphql` package.

Directives can be applied to fields, field resolvers, input and object types, as well as queries, mutations, and subscriptions. The following example applies a directive at the query handler level:

```typescript

@Directive('@deprecated(reason: "This query will be removed in the next version")')
@Query(() => Author, { name: 'author' })
async getAuthor(@Args({ name: 'id', type: () => Int }) id: number) {
  return this.authorsService.findOneById(id);
}
```

> **Warning** Directives applied through the `@Directive()` decorator are not reflected in the generated schema definition file.

Lastly, declare the directives in the `GraphQLModule` configuration:

```typescript

GraphQLModule.forRoot({
  // ...,
  transformSchema: schema => upperDirectiveTransformer(schema, 'upper'),
  buildSchemaOptions: {
    directives: [
      new GraphQLDirective({
        name: 'upper',
        locations: [DirectiveLocation.FIELD_DEFINITION],
      }),
    ],
  },
}),
```

> **Hint** Both `GraphQLDirective` and `DirectiveLocation` are exported from the `graphql` package.

#### Schema first[#](/graphql/directives#schema-first)

In the schema first approach, apply directives directly in SDL:

```graphql

directive @upper on FIELD_DEFINITION

type Post {
  id: Int!
  title: String! @upper
  votes: Int
}
```

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/directives.md)

----
url: https://docs.nestjs.com/v10/techniques/compression
----

* [Compression](https://docs.nestjs.com/v10/techniques/compression#compression)
* [Use with Express (default)](https://docs.nestjs.com/v10/techniques/compression#use-with-express-default)
* [Use with Fastify](https://docs.nestjs.com/v10/techniques/compression#use-with-fastify)

```bash

$ npm i --save compression
```

Once the installation is complete, apply the compression middleware as global middleware.

```typescript

import * as compression from 'compression';
// somewhere in your initialization file
app.use(compression());
```

#### Use with Fastify[#](/techniques/compression#use-with-fastify)

If using the `FastifyAdapter`, you'll want to use [fastify-compress](https://github.com/fastify/fastify-compress):

```bash

$ npm i --save @fastify/compress
```

Once the installation is complete, apply the `@fastify/compress` middleware as global middleware.

```typescript

import compression from '@fastify/compress';
// somewhere in your initialization file
await app.register(compression);
```

By default, `@fastify/compress` will use Brotli compression (on Node >= 11.7.0) when browsers indicate support for the encoding. While Brotli can be quite efficient in terms of compression ratio, it can also be quite slow. By default, Brotli sets a maximum compression quality of 11, although it can be adjusted to reduce compression time in lieu of compression quality by adjusting the `BROTLI_PARAM_QUALITY` between 0 min and 11 max. This will require fine tuning to optimize space/time performance. An example with quality 4:

```typescript

import { constants } from 'zlib';
// somewhere in your initialization file
await app.register(compression, { brotliOptions: { params: { [constants.BROTLI_PARAM_QUALITY]: 4 } } });
```

To simplify, you may want to tell `fastify-compress` to only use deflate and gzip to compress responses; you'll end up with potentially larger responses but they'll be delivered much more quickly.

To specify encodings, provide a second argument to `app.register`:

```typescript

await app.register(compression, { encodings: ['gzip', 'deflate'] });
```

The above tells `fastify-compress` to only use gzip and deflate encodings, preferring gzip if the client supports both.

----
url: https://docs.nestjs.com/v8/fundamentals/injection-scopes
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Injection scopes](https://docs.nestjs.com/v8/fundamentals/injection-scopes#injection-scopes)
* [Provider scope](https://docs.nestjs.com/v8/fundamentals/injection-scopes#provider-scope)
* [Usage](https://docs.nestjs.com/v8/fundamentals/injection-scopes#usage)
* [Controller scope](https://docs.nestjs.com/v8/fundamentals/injection-scopes#controller-scope)
* [Scope hierarchy](https://docs.nestjs.com/v8/fundamentals/injection-scopes#scope-hierarchy)
* [Request provider](https://docs.nestjs.com/v8/fundamentals/injection-scopes#request-provider)
* [Inquirer provider](https://docs.nestjs.com/v8/fundamentals/injection-scopes#inquirer-provider)
* [Performance](https://docs.nestjs.com/v8/fundamentals/injection-scopes#performance)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/fundamentals/provider-scopes.md "Suggest Edits")

### Injection scopes

For people coming from different programming language backgrounds, it might be unexpected to learn that in Nest, almost everything is shared across incoming requests. We have a connection pool to the database, singleton services with global state, etc. Remember that Node.js doesn't follow the request/response Multi-Threaded Stateless Model in which every request is processed by a separate thread. Hence, using singleton instances is fully **safe** for our applications.

However, there are edge-cases when request-based lifetime may be the desired behavior, for instance per-request caching in GraphQL applications, request tracking, and multi-tenancy. Injection scopes provide a mechanism to obtain the desired provider lifetime behavior.

#### Provider scope[#](/fundamentals/injection-scopes#provider-scope)

A provider can have any of the following scopes:

|             |                                                                                                                                                                                                                                                                            |
| ----------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `DEFAULT`   | A single instance of the provider is shared across the entire application. The instance lifetime is tied directly to the application lifecycle. Once the application has bootstrapped, all singleton providers have been instantiated. Singleton scope is used by default. |
| `REQUEST`   | A new instance of the provider is created exclusively for each incoming **request**. The instance is garbage-collected after the request has completed processing.                                                                                                         |
| `TRANSIENT` | Transient providers are not shared across consumers. Each consumer that injects a transient provider will receive a new, dedicated instance.                                                                                                                               |

> **Hint** Using singleton scope is **recommended** for most use cases. Sharing providers across consumers and across requests means that an instance can be cached and its initialization occurs only once, during application startup.

#### Usage[#](/fundamentals/injection-scopes#usage)

Specify injection scope by passing the `scope` property to the `@Injectable()` decorator options object:

```typescript

import { Injectable, Scope } from '@nestjs/common';

@Injectable({ scope: Scope.REQUEST })
export class CatsService {}
```

Similarly, for [custom providers](/v8/fundamentals/custom-providers), set the `scope` property in the long-hand form for a provider registration:

```typescript

{
  provide: 'CACHE_MANAGER',
  useClass: CacheManager,
  scope: Scope.TRANSIENT,
}
```

> **Hint** Import the `Scope` enum from `@nestjs/common`

Singleton scope is used by default, and need not be declared. If you do want to declare a provider as singleton scoped, use the `Scope.DEFAULT` value for the `scope` property.

> **Notice** Websocket Gateways should not use request-scoped providers because they must act as singletons. Each gateway encapsulates a real socket and cannot be instantiated multiple times. The limitation also applies to some other providers, like [*Passport strategies*](../security/authentication#request-scoped-strategies) or *Cron controllers*.

#### Controller scope[#](/fundamentals/injection-scopes#controller-scope)

Controllers can also have scope, which applies to all request method handlers declared in that controller. Like provider scope, the scope of a controller declares its lifetime. For a request-scoped controller, a new instance is created for each inbound request, and garbage-collected when the request has completed processing.

Declare controller scope with the `scope` property of the `ControllerOptions` object:

```typescript

@Controller({
  path: 'cats',
  scope: Scope.REQUEST,
})
export class CatsController {}
```

```typescript

import { Injectable, Scope, Inject } from '@nestjs/common';
import { REQUEST } from '@nestjs/core';
import { Request } from 'express';

@Injectable({ scope: Scope.REQUEST })
export class CatsService {
  constructor(@Inject(REQUEST) private request: Request) {}
}
```

Because of underlying platform/protocol differences, you access the inbound request slightly differently for Microservice or GraphQL applications. In [GraphQL](/v8/graphql/quick-start) applications, you inject `CONTEXT` instead of `REQUEST`:

```typescript

import { Injectable, Scope, Inject } from '@nestjs/common';
import { CONTEXT } from '@nestjs/graphql';

@Injectable({ scope: Scope.REQUEST })
export class CatsService {
  constructor(@Inject(CONTEXT) private context) {}
}
```

You then configure your `context` value (in the `GraphQLModule`) to contain `request` as its property.

#### Inquirer provider[#](/fundamentals/injection-scopes#inquirer-provider)

If you want get the class where a provider was constructed, for instance in logging or metrics providers, you can inject the `INQUIRER` token.

```typescript

import { Inject, Injectable, Scope } from '@nestjs/common';
import { INQUIRER } from '@nestjs/core';

@Injectable({ scope: Scope.TRANSIENT })
export class HelloService {
  constructor(@Inject(INQUIRER) private parentClass: object) {}

  sayHello(message: string) {
    console.log(`${this.parentClass?.constructor?.name}: ${message}`);
  }
}
```

And then use it as follows:

```typescript

import { Injectable } from '@nestjs/common';
import { HelloService } from './hello.service';

@Injectable()
export class AppService {
  constructor(private helloService: HelloService) {}

  getRoot(): string {
    this.helloService.sayHello('My name is getRoot');

    return 'Hello world!';
  }
}
```

In the example above when `AppService#getRoot` is called, `"AppService: My name is getRoot"` will be logged to the console.

#### Performance[#](/fundamentals/injection-scopes#performance)

Using request-scoped providers will have an impact on application performance. While Nest tries to cache as much metadata as possible, it will still have to create an instance of your class on each request. Hence, it will slow down your average response time and overall benchmarking result. Unless a provider must be request-scoped, it is strongly recommended that you use the default singleton scope.

----
url: https://docs.nestjs.com/v11/middleware
----

* [Middleware](https://docs.nestjs.com/v11/middleware#middleware)
* [Dependency injection](https://docs.nestjs.com/v11/middleware#dependency-injection)
* [Applying middleware](https://docs.nestjs.com/v11/middleware#applying-middleware)
* [Route wildcards](https://docs.nestjs.com/v11/middleware#route-wildcards)
* [Middleware consumer](https://docs.nestjs.com/v11/middleware#middleware-consumer)
* [Excluding routes](https://docs.nestjs.com/v11/middleware#excluding-routes)
* [Functional middleware](https://docs.nestjs.com/v11/middleware#functional-middleware)
* [Multiple middleware](https://docs.nestjs.com/v11/middleware#multiple-middleware)
* [Global middleware](https://docs.nestjs.com/v11/middleware#global-middleware)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/middlewares.md "Suggest Edits")

### Middleware

Middleware is a function which is called **before** the route handler. Middleware functions have access to the [request](https://expressjs.com/en/4x/api.html#req) and [response](https://expressjs.com/en/4x/api.html#res) objects, and the `next()` middleware function in the application’s request-response cycle. The **next** middleware function is commonly denoted by a variable named `next`.

Nest middleware are, by default, equivalent to [express](https://expressjs.com/en/guide/using-middleware.html) middleware. The following description from the official express documentation describes the capabilities of middleware:

> Middleware functions can perform the following tasks:
>
> * execute any code.
> * make changes to the request and the response objects.
> * end the request-response cycle.
> * call the next middleware function in the stack.
> * if the current middleware function does not end the request-response cycle, it must call `next()` to pass control to the next middleware function. Otherwise, the request will be left hanging.

You implement custom Nest middleware in either a function, or in a class with an `@Injectable()` decorator. The class should implement the `NestMiddleware` interface, while the function does not have any special requirements. Let's start by implementing a simple middleware feature using the class method.

> **Warning**`Express` and `fastify` handle middleware differently and provide different method signatures, read more [here](/techniques/performance#middleware).

logger.middleware.ts

JS TS

```typescript

import { Injectable, NestMiddleware } from '@nestjs/common';
import { Request, Response, NextFunction } from 'express';

@Injectable()
export class LoggerMiddleware implements NestMiddleware {
  use(req: Request, res: Response, next: NextFunction) {
    console.log('Request...');
    next();
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';

@Injectable()
export class LoggerMiddleware {
  use(req, res, next) {
    console.log('Request...');
    next();
  }
}
```

#### Dependency injection[#](/middleware#dependency-injection)

Nest middleware fully supports Dependency Injection. Just as with providers and controllers, they are able to **inject dependencies** that are available within the same module. As usual, this is done through the `constructor`.

#### Applying middleware[#](/middleware#applying-middleware)

There is no place for middleware in the `@Module()` decorator. Instead, we set them up using the `configure()` method of the module class. Modules that include middleware have to implement the `NestModule` interface. Let's set up the `LoggerMiddleware` at the `AppModule` level.

app.module.ts

JS TS

```typescript

import { Module, NestModule, MiddlewareConsumer } from '@nestjs/common';
import { LoggerMiddleware } from './common/middleware/logger.middleware';
import { CatsModule } from './cats/cats.module';

@Module({
  imports: [CatsModule],
})
export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer
      .apply(LoggerMiddleware)
      .forRoutes('cats');
  }
}
```

```typescript

import { Module } from '@nestjs/common';
import { LoggerMiddleware } from './common/middleware/logger.middleware';
import { CatsModule } from './cats/cats.module';

@Module({
  imports: [CatsModule],
})
export class AppModule {
  configure(consumer) {
    consumer
      .apply(LoggerMiddleware)
      .forRoutes('cats');
  }
}
```

In the above example we have set up the `LoggerMiddleware` for the `/cats` route handlers that were previously defined inside the `CatsController`. We may also further restrict a middleware to a particular request method by passing an object containing the route `path` and request `method` to the `forRoutes()` method when configuring the middleware. In the example below, notice that we import the `RequestMethod` enum to reference the desired request method type.

app.module.ts

JS TS

```typescript

import { Module, NestModule, RequestMethod, MiddlewareConsumer } from '@nestjs/common';
import { LoggerMiddleware } from './common/middleware/logger.middleware';
import { CatsModule } from './cats/cats.module';

@Module({
  imports: [CatsModule],
})
export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer
      .apply(LoggerMiddleware)
      .forRoutes({ path: 'cats', method: RequestMethod.GET });
  }
}
```

```typescript

import { Module, RequestMethod } from '@nestjs/common';
import { LoggerMiddleware } from './common/middleware/logger.middleware';
import { CatsModule } from './cats/cats.module';

@Module({
  imports: [CatsModule],
})
export class AppModule {
  configure(consumer) {
    consumer
      .apply(LoggerMiddleware)
      .forRoutes({ path: 'cats', method: RequestMethod.GET });
  }
}
```

> **Hint** The `configure()` method can be made asynchronous using `async/await` (e.g., you can `await` completion of an asynchronous operation inside the `configure()` method body).

> **Warning** When using the `express` adapter, the NestJS app will register `json` and `urlencoded` from the package `body-parser` by default. This means if you want to customize that middleware via the `MiddlewareConsumer`, you need to turn off the global middleware by setting the `bodyParser` flag to `false` when creating the application with `NestFactory.create()`.

#### Route wildcards[#](/middleware#route-wildcards)

Pattern-based routes are also supported in NestJS middleware. For example, the named wildcard (`*splat`) can be used as a wildcard to match any combination of characters in a route. In the following example, the middleware will be executed for any route that starts with `abcd/`, regardless of the number of characters that follow.

```typescript

forRoutes({
  path: 'abcd/*splat',
  method: RequestMethod.ALL,
});
```

> **Hint**`splat` is simply the name of the wildcard parameter and has no special meaning. You can name it anything you like, for example, `*wildcard`.

The `'abcd/*'` route path will match `abcd/1`, `abcd/123`, `abcd/abc`, and so on. The hyphen ( `-`) and the dot (`.`) are interpreted literally by string-based paths. However, `abcd/` with no additional characters will not match the route. For this, you need to wrap the wildcard in braces to make it optional:

```typescript

forRoutes({
  path: 'abcd/{*splat}',
  method: RequestMethod.ALL,
});
```

#### Middleware consumer[#](/middleware#middleware-consumer)

The `MiddlewareConsumer` is a helper class. It provides several built-in methods to manage middleware. All of them can be simply **chained** in the [fluent style](https://en.wikipedia.org/wiki/Fluent_interface). The `forRoutes()` method can take a single string, multiple strings, a `RouteInfo` object, a controller class and even multiple controller classes. In most cases you'll probably just pass a list of **controllers** separated by commas. Below is an example with a single controller:

app.module.ts

JS TS

```typescript

import { Module, NestModule, MiddlewareConsumer } from '@nestjs/common';
import { LoggerMiddleware } from './common/middleware/logger.middleware';
import { CatsModule } from './cats/cats.module';
import { CatsController } from './cats/cats.controller';

@Module({
  imports: [CatsModule],
})
export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer
      .apply(LoggerMiddleware)
      .forRoutes(CatsController);
  }
}
```

```typescript

import { Module } from '@nestjs/common';
import { LoggerMiddleware } from './common/middleware/logger.middleware';
import { CatsModule } from './cats/cats.module';
import { CatsController } from './cats/cats.controller';

@Module({
  imports: [CatsModule],
})
export class AppModule {
  configure(consumer) {
    consumer
      .apply(LoggerMiddleware)
      .forRoutes(CatsController);
  }
}
```

> **Hint** The `apply()` method may either take a single middleware, or multiple arguments to specify [multiple middlewares](/middleware#multiple-middleware).

#### Excluding routes[#](/middleware#excluding-routes)

At times, we may want to **exclude** certain routes from having middleware applied. This can be easily achieved using the `exclude()` method. The `exclude()` method accepts a single string, multiple strings, or a `RouteInfo` object to identify the routes to be excluded.

Here's an example of how to use it:

```typescript

consumer
  .apply(LoggerMiddleware)
  .exclude(
    { path: 'cats', method: RequestMethod.GET },
    { path: 'cats', method: RequestMethod.POST },
    'cats/{*splat}',
  )
  .forRoutes(CatsController);
```

> **Hint** The `exclude()` method supports wildcard parameters using the [path-to-regexp](https://github.com/pillarjs/path-to-regexp#parameters) package.

With the example above, `LoggerMiddleware` will be bound to all routes defined inside `CatsController`**except** the three passed to the `exclude()` method.

This approach provides flexibility in applying or excluding middleware based on specific routes or route patterns.

#### Functional middleware[#](/middleware#functional-middleware)

The `LoggerMiddleware` class we've been using is quite simple. It has no members, no additional methods, and no dependencies. Why can't we just define it in a simple function instead of a class? In fact, we can. This type of middleware is called **functional middleware**. Let's transform the logger middleware from class-based into functional middleware to illustrate the difference:

logger.middleware.ts

JS TS

```typescript

import { Request, Response, NextFunction } from 'express';

export function logger(req: Request, res: Response, next: NextFunction) {
  console.log(`Request...`);
  next();
};
```

```typescript

export function logger(req, res, next) {
  console.log(`Request...`);
  next();
};
```

And use it within the `AppModule`:

app.module.ts

JS TS

```typescript

consumer
  .apply(logger)
  .forRoutes(CatsController);
```

> **Hint** Consider using the simpler **functional middleware** alternative any time your middleware doesn't need any dependencies.

#### Multiple middleware[#](/middleware#multiple-middleware)

As mentioned above, in order to bind multiple middleware that are executed sequentially, simply provide a comma separated list inside the `apply()` method:

```typescript

consumer.apply(cors(), helmet(), logger).forRoutes(CatsController);
```

#### Global middleware[#](/middleware#global-middleware)

If we want to bind middleware to every registered route at once, we can use the `use()` method that is supplied by the `INestApplication` instance:

main.ts

JS TS

```typescript

const app = await NestFactory.create(AppModule);
app.use(logger);
await app.listen(process.env.PORT ?? 3000);
```

> **Hint** Accessing the DI container in a global middleware is not possible. You can use a [functional middleware](middleware#functional-middleware) instead when using `app.use()`. Alternatively, you can use a class middleware and consume it with `.forRoutes('*')` within the `AppModule` (or any other module).

----
url: https://docs.nestjs.com/v11/fundamentals/dynamic-modules
----

* [Dynamic modules](https://docs.nestjs.com/v11/fundamentals/dynamic-modules#dynamic-modules)
* [Introduction](https://docs.nestjs.com/v11/fundamentals/dynamic-modules#introduction)
* [Dynamic module use case](https://docs.nestjs.com/v11/fundamentals/dynamic-modules#dynamic-module-use-case)
* [Config module example](https://docs.nestjs.com/v11/fundamentals/dynamic-modules#config-module-example)
* [Module configuration](https://docs.nestjs.com/v11/fundamentals/dynamic-modules#module-configuration)
* [Example](https://docs.nestjs.com/v11/fundamentals/dynamic-modules#example)
* [Community guidelines](https://docs.nestjs.com/v11/fundamentals/dynamic-modules#community-guidelines)
* [Configurable module builder](https://docs.nestjs.com/v11/fundamentals/dynamic-modules#configurable-module-builder)
* [Custom method key](https://docs.nestjs.com/v11/fundamentals/dynamic-modules#custom-method-key)
* [Custom options factory class](https://docs.nestjs.com/v11/fundamentals/dynamic-modules#custom-options-factory-class)
* [Extra options](https://docs.nestjs.com/v11/fundamentals/dynamic-modules#extra-options)
* [Extending auto-generated methods](https://docs.nestjs.com/v11/fundamentals/dynamic-modules#extending-auto-generated-methods)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/fundamentals/dynamic-modules.md "Suggest Edits")

### Dynamic modules

The [Modules chapter](/v11/modules) covers the basics of Nest modules, and includes a brief introduction to [dynamic modules](https://docs.nestjs.com/modules#dynamic-modules). This chapter expands on the subject of dynamic modules. Upon completion, you should have a good grasp of what they are and how and when to use them.

#### Introduction[#](/fundamentals/dynamic-modules#introduction)

Most application code examples in the **Overview** section of the documentation make use of regular, or static, modules. Modules define groups of components like [providers](/v11/providers) and [controllers](/v11/controllers) that fit together as a modular part of an overall application. They provide an execution context, or scope, for these components. For example, providers defined in a module are visible to other members of the module without the need to export them. When a provider needs to be visible outside of a module, it is first exported from its host module, and then imported into its consuming module.

Let's walk through a familiar example.

First, we'll define a `UsersModule` to provide and export a `UsersService`. `UsersModule` is the **host** module for `UsersService`.

```typescript

import { Module } from '@nestjs/common';
import { UsersService } from './users.service';

@Module({
  providers: [UsersService],
  exports: [UsersService],
})
export class UsersModule {}
```

Next, we'll define an `AuthModule`, which imports `UsersModule`, making `UsersModule`'s exported providers available inside `AuthModule`:

```typescript

import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { UsersModule } from '../users/users.module';

@Module({
  imports: [UsersModule],
  providers: [AuthService],
  exports: [AuthService],
})
export class AuthModule {}
```

These constructs allow us to inject `UsersService` in, for example, the `AuthService` that is hosted in `AuthModule`:

```typescript

import { Injectable } from '@nestjs/common';
import { UsersService } from '../users/users.service';

@Injectable()
export class AuthService {
  constructor(private usersService: UsersService) {}
  /*
    Implementation that makes use of this.usersService
  */
}
```

```typescript

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { ConfigModule } from './config/config.module';

@Module({
  imports: [ConfigModule],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}
```

Let's consider what a *dynamic module* import, where we're passing in a configuration object, might look like. Compare the difference in the `imports` array between these two examples:

```typescript

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { ConfigModule } from './config/config.module';

@Module({
  imports: [ConfigModule.register({ folder: './config' })],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}
```

Let's see what's happening in the dynamic example above. What are the moving parts?

1. `ConfigModule` is a normal class, so we can infer that it must have a **static method** called `register()`. We know it's static because we're calling it on the `ConfigModule` class, not on an **instance** of the class. Note: this method, which we will create soon, can have any arbitrary name, but by convention we should call it either `forRoot()` or `register()`.
2. The `register()` method is defined by us, so we can accept any input arguments we like. In this case, we're going to accept a simple `options` object with suitable properties, which is the typical case.
3. We can infer that the `register()` method must return something like a `module` since its return value appears in the familiar `imports` list, which we've seen so far includes a list of modules.

In fact, what our `register()` method will return is a `DynamicModule`. A dynamic module is nothing more than a module created at run-time, with the same exact properties as a static module, plus one additional property called `module`. Let's quickly review a sample static module declaration, paying close attention to the module options passed in to the decorator:

```typescript

@Module({
  imports: [DogsModule],
  controllers: [CatsController],
  providers: [CatsService],
  exports: [CatsService]
})
```

Dynamic modules must return an object with the exact same interface, plus one additional property called `module`. The `module` property serves as the name of the module, and should be the same as the class name of the module, as shown in the example below.

> **Hint** For a dynamic module, all properties of the module options object are optional **except**`module`.

What about the static `register()` method? We can now see that its job is to return an object that has the `DynamicModule` interface. When we call it, we are effectively providing a module to the `imports` list, similar to the way we would do so in the static case by listing a module class name. In other words, the dynamic module API simply returns a module, but rather than fix the properties in the `@Module` decorator, we specify them programmatically.

There are still a couple of details to cover to help make the picture complete:

1. We can now state that the `@Module()` decorator's `imports` property can take not only a module class name (e.g., `imports: [UsersModule]`), but also a function **returning** a dynamic module (e.g., `imports: [ConfigModule.register(...)]`).
2. A dynamic module can itself import other modules. We won't do so in this example, but if the dynamic module depends on providers from other modules, you would import them using the optional `imports` property. Again, this is exactly analogous to the way you'd declare metadata for a static module using the `@Module()` decorator.

Armed with this understanding, we can now look at what our dynamic `ConfigModule` declaration must look like. Let's take a crack at it.

```typescript

import { DynamicModule, Module } from '@nestjs/common';
import { ConfigService } from './config.service';

@Module({})
export class ConfigModule {
  static register(): DynamicModule {
    return {
      module: ConfigModule,
      providers: [ConfigService],
      exports: [ConfigService],
    };
  }
}
```

It should now be clear how the pieces tie together. Calling `ConfigModule.register(...)` returns a `DynamicModule` object with properties which are essentially the same as those that, until now, we've provided as metadata via the `@Module()` decorator.

> **Hint** Import `DynamicModule` from `@nestjs/common`.

Our dynamic module isn't very interesting yet, however, as we haven't introduced any capability to **configure** it as we said we would like to do. Let's address that next.

#### Module configuration[#](/fundamentals/dynamic-modules#module-configuration)

The obvious solution for customizing the behavior of the `ConfigModule` is to pass it an `options` object in the static `register()` method, as we guessed above. Let's look once again at our consuming module's `imports` property:

```typescript

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { ConfigModule } from './config/config.module';

@Module({
  imports: [ConfigModule.register({ folder: './config' })],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}
```

That nicely handles passing an `options` object to our dynamic module. How do we then use that `options` object in the `ConfigModule`? Let's consider that for a minute. We know that our `ConfigModule` is basically a host for providing and exporting an injectable service - the `ConfigService` - for use by other providers. It's actually our `ConfigService` that needs to read the `options` object to customize its behavior. Let's assume for the moment that we know how to somehow get the `options` from the `register()` method into the `ConfigService`. With that assumption, we can make a few changes to the service to customize its behavior based on the properties from the `options` object. (**Note**: for the time being, since we *haven't* actually determined how to pass it in, we'll just hard-code `options`. We'll fix this in a minute).

```typescript

import { Injectable } from '@nestjs/common';
import * as fs from 'node:fs';
import * as path from 'node:path';
import * as dotenv from 'dotenv';
import { EnvConfig } from './interfaces';

@Injectable()
export class ConfigService {
  private readonly envConfig: EnvConfig;

  constructor() {
    const options = { folder: './config' };

    const filePath = `${process.env.NODE_ENV || 'development'}.env`;
    const envFile = path.resolve(__dirname, '../../', options.folder, filePath);
    this.envConfig = dotenv.parse(fs.readFileSync(envFile));
  }

  get(key: string): string {
    return this.envConfig[key];
  }
}
```

Now our `ConfigService` knows how to find the `.env` file in the folder we've specified in `options`.

Our remaining task is to somehow inject the `options` object from the `register()` step into our `ConfigService`. And of course, we'll use *dependency injection* to do it. This is a key point, so make sure you understand it. Our `ConfigModule` is providing `ConfigService`. `ConfigService` in turn depends on the `options` object that is only supplied at run-time. So, at run-time, we'll need to first bind the `options` object to the Nest IoC container, and then have Nest inject it into our `ConfigService`. Remember from the **Custom providers** chapter that providers can [include any value](https://docs.nestjs.com/fundamentals/custom-providers#non-service-based-providers) not just services, so we're fine using dependency injection to handle a simple `options` object.

Let's tackle binding the options object to the IoC container first. We do this in our static `register()` method. Remember that we are dynamically constructing a module, and one of the properties of a module is its list of providers. So what we need to do is define our options object as a provider. This will make it injectable into the `ConfigService`, which we'll take advantage of in the next step. In the code below, pay attention to the `providers` array:

```typescript

import { DynamicModule, Module } from '@nestjs/common';
import { ConfigService } from './config.service';

@Module({})
export class ConfigModule {
  static register(options: Record<string, any>): DynamicModule {
    return {
      module: ConfigModule,
      providers: [
        {
          provide: 'CONFIG_OPTIONS',
          useValue: options,
        },
        ConfigService,
      ],
      exports: [ConfigService],
    };
  }
}
```

Now we can complete the process by injecting the `'CONFIG_OPTIONS'` provider into the `ConfigService`. Recall that when we define a provider using a non-class token we need to use the `@Inject()` decorator [as described here](https://docs.nestjs.com/fundamentals/custom-providers#non-class-based-provider-tokens).

```typescript

import * as fs from 'node:fs';
import * as path from 'node:path';
import * as dotenv from 'dotenv';
import { Injectable, Inject } from '@nestjs/common';
import { EnvConfig } from './interfaces';

@Injectable()
export class ConfigService {
  private readonly envConfig: EnvConfig;

  constructor(@Inject('CONFIG_OPTIONS') private options: Record<string, any>) {
    const filePath = `${process.env.NODE_ENV || 'development'}.env`;
    const envFile = path.resolve(__dirname, '../../', options.folder, filePath);
    this.envConfig = dotenv.parse(fs.readFileSync(envFile));
  }

  get(key: string): string {
    return this.envConfig[key];
  }
}
```

One final note: for simplicity we used a string-based injection token (`'CONFIG_OPTIONS'`) above, but best practice is to define it as a constant (or `Symbol`) in a separate file, and import that file. For example:

```typescript

export const CONFIG_OPTIONS = 'CONFIG_OPTIONS';
```

```typescript

export interface ConfigModuleOptions {
  folder: string;
}
```

With this in place, create a new dedicated file (alongside the existing `config.module.ts` file) and name it `config.module-definition.ts`. In this file, let's utilize the `ConfigurableModuleBuilder` to construct `ConfigModule` definition.

config.module-definition.ts

JS TS

```typescript

import { ConfigurableModuleBuilder } from '@nestjs/common';
import { ConfigModuleOptions } from './interfaces/config-module-options.interface';

export const { ConfigurableModuleClass, MODULE_OPTIONS_TOKEN } =
  new ConfigurableModuleBuilder<ConfigModuleOptions>().build();
```

```typescript

import { ConfigurableModuleBuilder } from '@nestjs/common';

export const { ConfigurableModuleClass, MODULE_OPTIONS_TOKEN } =
  new ConfigurableModuleBuilder().build();
```

Now let's open up the `config.module.ts` file and modify its implementation to leverage the auto-generated `ConfigurableModuleClass`:

```typescript

import { Module } from '@nestjs/common';
import { ConfigService } from './config.service';
import { ConfigurableModuleClass } from './config.module-definition';

@Module({
  providers: [ConfigService],
  exports: [ConfigService],
})
export class ConfigModule extends ConfigurableModuleClass {}
```

Extending the `ConfigurableModuleClass` means that `ConfigModule` provides now not only the `register` method (as previously with the custom implementation), but also the `registerAsync` method which allows consumers asynchronously configure that module, for example, by supplying async factories:

```typescript

@Module({
  imports: [
    ConfigModule.register({ folder: './config' }),
    // or alternatively:
    // ConfigModule.registerAsync({
    //   useFactory: () => {
    //     return {
    //       folder: './config',
    //     }
    //   },
    //   inject: [...any extra dependencies...]
    // }),
  ],
})
export class AppModule {}
```

The `registerAsync` method takes the following object as an argument:

```typescript

{
  /**
   * Injection token resolving to a class that will be instantiated as a provider.
   * The class must implement the corresponding interface.
   */
  useClass?: Type<
    ConfigurableModuleOptionsFactory<ModuleOptions, FactoryClassMethodKey>
  >;
  /**
   * Function returning options (or a Promise resolving to options) to configure the
   * module.
   */
  useFactory?: (...args: any[]) => Promise<ModuleOptions> | ModuleOptions;
  /**
   * Dependencies that a Factory may inject.
   */
  inject?: FactoryProvider['inject'];
  /**
   * Injection token resolving to an existing provider. The provider must implement
   * the corresponding interface.
   */
  useExisting?: Type<
    ConfigurableModuleOptionsFactory<ModuleOptions, FactoryClassMethodKey>
  >;
}
```

Let's go through the above properties one by one:

* `useFactory` - a function that returns the configuration object. It can be either synchronous or asynchronous. To inject dependencies into the factory function, use the `inject` property. We used this variant in the example above.
* `inject` - an array of dependencies that will be injected into the factory function. The order of the dependencies must match the order of the parameters in the factory function.
* `useClass` - a class that will be instantiated as a provider. The class must implement the corresponding interface. Typically, this is a class that provides a `create()` method that returns the configuration object. Read more about this in the [Custom method key](/fundamentals/dynamic-modules#custom-method-key) section below.
* `useExisting` - a variant of `useClass` that allows you to use an existing provider instead of instructing Nest to create a new instance of the class. This is useful when you want to use a provider that is already registered in the module. Keep in mind that the class must implement the same interface as the one used in `useClass` (and so it must provide the `create()` method, unless you override the default method name, see [Custom method key](/fundamentals/dynamic-modules#custom-method-key) section below).

Always choose one of the above options (`useFactory`, `useClass`, or `useExisting`), as they are mutually exclusive.

Lastly, let's update the `ConfigService` class to inject the generated module options' provider instead of the `'CONFIG_OPTIONS'` that we used so far.

```typescript

@Injectable()
export class ConfigService {
  constructor(@Inject(MODULE_OPTIONS_TOKEN) private options: ConfigModuleOptions) { ... }
}
```

#### Custom method key[#](/fundamentals/dynamic-modules#custom-method-key)

`ConfigurableModuleClass` by default provides the `register` and its counterpart `registerAsync` methods. To use a different method name, use the `ConfigurableModuleBuilder#setClassMethodName` method, as follows:

config.module-definition.ts

JS TS

```typescript

export const { ConfigurableModuleClass, MODULE_OPTIONS_TOKEN } =
  new ConfigurableModuleBuilder<ConfigModuleOptions>().setClassMethodName('forRoot').build();
```

```typescript

export const { ConfigurableModuleClass, MODULE_OPTIONS_TOKEN } =
  new ConfigurableModuleBuilder().setClassMethodName('forRoot').build();
```

This construction will instruct `ConfigurableModuleBuilder` to generate a class that exposes `forRoot` and `forRootAsync` instead. Example:

```typescript

@Module({
  imports: [
    ConfigModule.forRoot({ folder: './config' }), // <-- note the use of "forRoot" instead of "register"
    // or alternatively:
    // ConfigModule.forRootAsync({
    //   useFactory: () => {
    //     return {
    //       folder: './config',
    //     }
    //   },
    //   inject: [...any extra dependencies...]
    // }),
  ],
})
export class AppModule {}
```

#### Custom options factory class[#](/fundamentals/dynamic-modules#custom-options-factory-class)

Since the `registerAsync` method (or `forRootAsync` or any other name, depending on the configuration) lets consumer pass a provider definition that resolves to the module configuration, a library consumer could potentially supply a class to be used to construct the configuration object.

```typescript

@Module({
  imports: [
    ConfigModule.registerAsync({
      useClass: ConfigModuleOptionsFactory,
    }),
  ],
})
export class AppModule {}
```

This class, by default, must provide the `create()` method that returns a module configuration object. However, if your library follows a different naming convention, you can change that behavior and instruct `ConfigurableModuleBuilder` to expect a different method, for example, `createConfigOptions`, using the `ConfigurableModuleBuilder#setFactoryMethodName` method:

config.module-definition.ts

JS TS

```typescript

export const { ConfigurableModuleClass, MODULE_OPTIONS_TOKEN } =
  new ConfigurableModuleBuilder<ConfigModuleOptions>().setFactoryMethodName('createConfigOptions').build();
```

```typescript

export const { ConfigurableModuleClass, MODULE_OPTIONS_TOKEN } =
  new ConfigurableModuleBuilder().setFactoryMethodName('createConfigOptions').build();
```

Now, `ConfigModuleOptionsFactory` class must expose the `createConfigOptions` method (instead of `create`):

```typescript

@Module({
  imports: [
    ConfigModule.registerAsync({
      useClass: ConfigModuleOptionsFactory, // <-- this class must provide the "createConfigOptions" method
    }),
  ],
})
export class AppModule {}
```

#### Extra options[#](/fundamentals/dynamic-modules#extra-options)

There are edge-cases when your module may need to take extra options that determine how it is supposed to behave (a nice example of such an option is the `isGlobal` flag - or just `global`) that at the same time, shouldn't be included in the `MODULE_OPTIONS_TOKEN` provider (as they are irrelevant to services/providers registered within that module, for example, `ConfigService` does not need to know whether its host module is registered as a global module).

In such cases, the `ConfigurableModuleBuilder#setExtras` method can be used. See the following example:

```typescript

export const { ConfigurableModuleClass, MODULE_OPTIONS_TOKEN } =
  new ConfigurableModuleBuilder<ConfigModuleOptions>()
    .setExtras(
      {
        isGlobal: true,
      },
      (definition, extras) => ({
        ...definition,
        global: extras.isGlobal,
      }),
    )
    .build();
```

In the example above, the first argument passed into the `setExtras` method is an object containing default values for the "extra" properties. The second argument is a function that takes an auto-generated module definitions (with `provider`, `exports`, etc.) and `extras` object which represents extra properties (either specified by the consumer or defaults). The returned value of this function is a modified module definition. In this specific example, we're taking the `extras.isGlobal` property and assigning it to the `global` property of the module definition (which in turn determines whether a module is global or not, read more [here](/modules#dynamic-modules)).

Now when consuming this module, the additional `isGlobal` flag can be passed in, as follows:

```typescript

@Module({
  imports: [
    ConfigModule.register({
      isGlobal: true,
      folder: './config',
    }),
  ],
})
export class AppModule {}
```

However, since `isGlobal` is declared as an "extra" property, it won't be available in the `MODULE_OPTIONS_TOKEN` provider:

```typescript

@Injectable()
export class ConfigService {
  constructor(
    @Inject(MODULE_OPTIONS_TOKEN) private options: ConfigModuleOptions,
  ) {
    // "options" object will not have the "isGlobal" property
    // ...
  }
}
```

#### Extending auto-generated methods[#](/fundamentals/dynamic-modules#extending-auto-generated-methods)

The auto-generated static methods (`register`, `registerAsync`, etc.) can be extended if needed, as follows:

```typescript

import { Module } from '@nestjs/common';
import { ConfigService } from './config.service';
import {
  ConfigurableModuleClass,
  ASYNC_OPTIONS_TYPE,
  OPTIONS_TYPE,
} from './config.module-definition';

@Module({
  providers: [ConfigService],
  exports: [ConfigService],
})
export class ConfigModule extends ConfigurableModuleClass {
  static register(options: typeof OPTIONS_TYPE): DynamicModule {
    return {
      // your custom logic here
      ...super.register(options),
    };
  }

  static registerAsync(options: typeof ASYNC_OPTIONS_TYPE): DynamicModule {
    return {
      // your custom logic here
      ...super.registerAsync(options),
    };
  }
}
```

Note the use of `OPTIONS_TYPE` and `ASYNC_OPTIONS_TYPE` types that must be exported from the module definition file:

```typescript

export const {
  ConfigurableModuleClass,
  MODULE_OPTIONS_TOKEN,
  OPTIONS_TYPE,
  ASYNC_OPTIONS_TYPE,
} = new ConfigurableModuleBuilder<ConfigModuleOptions>().build();
```

----
url: https://docs.nestjs.com/v11/microservices/kafka
----

* [Kafka](https://docs.nestjs.com/v11/microservices/kafka#kafka)
* [Installation](https://docs.nestjs.com/v11/microservices/kafka#installation)
* [Overview](https://docs.nestjs.com/v11/microservices/kafka#overview)
* [Options](https://docs.nestjs.com/v11/microservices/kafka#options)
* [Client](https://docs.nestjs.com/v11/microservices/kafka#client)
* [Message pattern](https://docs.nestjs.com/v11/microservices/kafka#message-pattern)
* [Message response subscription](https://docs.nestjs.com/v11/microservices/kafka#message-response-subscription)
* [Incoming](https://docs.nestjs.com/v11/microservices/kafka#incoming)
* [Outgoing](https://docs.nestjs.com/v11/microservices/kafka#outgoing)
* [Event-based](https://docs.nestjs.com/v11/microservices/kafka#event-based)
* [Context](https://docs.nestjs.com/v11/microservices/kafka#context)
* [Naming conventions](https://docs.nestjs.com/v11/microservices/kafka#naming-conventions)
* [Retriable exceptions](https://docs.nestjs.com/v11/microservices/kafka#retriable-exceptions)
* [Custom exception handling](https://docs.nestjs.com/v11/microservices/kafka#custom-exception-handling)
* [Commit offsets](https://docs.nestjs.com/v11/microservices/kafka#commit-offsets)
* [Instance status updates](https://docs.nestjs.com/v11/microservices/kafka#instance-status-updates)
* [Underlying producer and consumer](https://docs.nestjs.com/v11/microservices/kafka#underlying-producer-and-consumer)

```bash

$ npm i --save kafkajs
```

#### Overview[#](/microservices/kafka#overview)

Like other Nest microservice transport layer implementations, you select the Kafka transporter mechanism using the `transport` property of the options object passed to the `createMicroservice()` method, along with an optional `options` property, as shown below:

main.ts

JS TS

```typescript

const app = await NestFactory.createMicroservice<MicroserviceOptions>(AppModule, {
  transport: Transport.KAFKA,
  options: {
    client: {
      brokers: ['localhost:9092'],
    }
  }
});
```

```typescript

const app = await NestFactory.createMicroservice(AppModule, {
  transport: Transport.KAFKA,
  options: {
    client: {
      brokers: ['localhost:9092'],
    }
  }
});
```

> **Hint** The `Transport` enum is imported from the `@nestjs/microservices` package.

#### Options[#](/microservices/kafka#options)

The `options` property is specific to the chosen transporter. The **Kafka** transporter exposes the properties described below.

|                    |                                                                                                                 |
| ------------------ | --------------------------------------------------------------------------------------------------------------- |
| `client`           | Client configuration options (read more [here](https://kafka.js.org/docs/configuration))                        |
| `consumer`         | Consumer configuration options (read more [here](https://kafka.js.org/docs/consuming#a-name-options-a-options)) |
| `run`              | Run configuration options (read more [here](https://kafka.js.org/docs/consuming))                               |
| `subscribe`        | Subscribe configuration options (read more [here](https://kafka.js.org/docs/consuming#frombeginning))           |
| `producer`         | Producer configuration options (read more [here](https://kafka.js.org/docs/producing#options))                  |
| `send`             | Send configuration options (read more [here](https://kafka.js.org/docs/producing#options))                      |
| `producerOnlyMode` | Feature flag to skip consumer group registration and only act as a producer (`boolean`)                         |
| `postfixId`        | Change suffix of clientId value (`string`)                                                                      |

#### Client[#](/microservices/kafka#client)

There is a small difference in Kafka compared to other microservice transporters. Instead of the `ClientProxy` class, we use the `ClientKafkaProxy` class.

Like other microservice transporters, you have [several options](https://docs.nestjs.com/microservices/basics#client) for creating a `ClientKafkaProxy` instance.

One method for creating an instance is to use the `ClientsModule`. To create a client instance with the `ClientsModule`, import it and use the `register()` method to pass an options object with the same properties shown above in the `createMicroservice()` method, as well as a `name` property to be used as the injection token. Read more about `ClientsModule`[here](https://docs.nestjs.com/microservices/basics#client).

```typescript

@Module({
  imports: [
    ClientsModule.register([
      {
        name: 'HERO_SERVICE',
        transport: Transport.KAFKA,
        options: {
          client: {
            clientId: 'hero',
            brokers: ['localhost:9092'],
          },
          consumer: {
            groupId: 'hero-consumer'
          }
        }
      },
    ]),
  ]
  ...
})
```

Other options to create a client (either `ClientProxyFactory` or `@Client()`) can be used as well. You can read about them [here](https://docs.nestjs.com/microservices/basics#client).

Use the `@Client()` decorator as follows:

```typescript

@Client({
  transport: Transport.KAFKA,
  options: {
    client: {
      clientId: 'hero',
      brokers: ['localhost:9092'],
    },
    consumer: {
      groupId: 'hero-consumer'
    }
  }
})
client: ClientKafkaProxy;
```

#### Message pattern[#](/microservices/kafka#message-pattern)

The Kafka microservice message pattern utilizes two topics for the request and reply channels. The `ClientKafkaProxy.send()` method sends messages with a [return address](https://www.enterpriseintegrationpatterns.com/patterns/messaging/ReturnAddress.html) by associating a [correlation id](https://www.enterpriseintegrationpatterns.com/patterns/messaging/CorrelationIdentifier.html), reply topic, and reply partition with the request message. This requires the `ClientKafkaProxy` instance to be subscribed to the reply topic and assigned to at least one partition before sending a message.

Subsequently, you need to have at least one reply topic partition for every Nest application running. For example, if you are running 4 Nest applications but the reply topic only has 3 partitions, then 1 of the Nest applications will error out when trying to send a message.

When new `ClientKafkaProxy` instances are launched they join the consumer group and subscribe to their respective topics. This process triggers a rebalance of topic partitions assigned to consumers of the consumer group.

Normally, topic partitions are assigned using the round robin partitioner, which assigns topic partitions to a collection of consumers sorted by consumer names which are randomly set on application launch. However, when a new consumer joins the consumer group, the new consumer can be positioned anywhere within the collection of consumers. This creates a condition where pre-existing consumers can be assigned different partitions when the pre-existing consumer is positioned after the new consumer. As a result, the consumers that are assigned different partitions will lose response messages of requests sent before the rebalance.

To prevent the `ClientKafkaProxy` consumers from losing response messages, a Nest-specific built-in custom partitioner is utilized. This custom partitioner assigns partitions to a collection of consumers sorted by high-resolution timestamps (`process.hrtime()`) that are set on application launch.

#### Message response subscription[#](/microservices/kafka#message-response-subscription)

> **Note** This section is only relevant if you use [request-response](/microservices/basics#request-response) message style (with the `@MessagePattern` decorator and the `ClientKafkaProxy.send` method). Subscribing to the response topic is not necessary for the [event-based](/microservices/basics#event-based) communication (`@EventPattern` decorator and `ClientKafkaProxy.emit` method).

The `ClientKafkaProxy` class provides the `subscribeToResponseOf()` method. The `subscribeToResponseOf()` method takes a request's topic name as an argument and adds the derived reply topic name to a collection of reply topics. This method is required when implementing the message pattern.

heroes.controller.ts

JS TS

```typescript

onModuleInit() {
  this.client.subscribeToResponseOf('hero.kill.dragon');
}
```

If the `ClientKafkaProxy` instance is created asynchronously, the `subscribeToResponseOf()` method must be called before calling the `connect()` method.

heroes.controller.ts

JS TS

```typescript

async onModuleInit() {
  this.client.subscribeToResponseOf('hero.kill.dragon');
  await this.client.connect();
}
```

#### Incoming[#](/microservices/kafka#incoming)

Nest receives incoming Kafka messages as an object with `key`, `value`, and `headers` properties that have values of type `Buffer`. Nest then parses these values by transforming the buffers into strings. If the string is "object like", Nest attempts to parse the string as `JSON`. The `value` is then passed to its associated handler.

#### Outgoing[#](/microservices/kafka#outgoing)

Nest sends outgoing Kafka messages after a serialization process when publishing events or sending messages. This occurs on arguments passed to the `ClientKafkaProxy``emit()` and `send()` methods or on values returned from a `@MessagePattern` method. This serialization "stringifies" objects that are not strings or buffers by using `JSON.stringify()` or the `toString()` prototype method.

heroes.controller.ts

JS TS

```typescript

@Controller()
export class HeroesController {
  @MessagePattern('hero.kill.dragon')
  killDragon(@Payload() message: KillDragonMessage): any {
    const dragonId = message.dragonId;
    const items = [
      { id: 1, name: 'Mythical Sword' },
      { id: 2, name: 'Key to Dungeon' },
    ];
    return items;
  }
}
```

> **Hint**`@Payload()` is imported from the `@nestjs/microservices` package.

Outgoing messages can also be keyed by passing an object with the `key` and `value` properties. Keying messages is important for meeting the [co-partitioning requirement](https://docs.confluent.io/current/ksql/docs/developer-guide/partition-data.html#co-partitioning-requirements).

heroes.controller.ts

JS TS

```typescript

@Controller()
export class HeroesController {
  @MessagePattern('hero.kill.dragon')
  killDragon(@Payload() message: KillDragonMessage): any {
    const realm = 'Nest';
    const heroId = message.heroId;
    const dragonId = message.dragonId;

    const items = [
      { id: 1, name: 'Mythical Sword' },
      { id: 2, name: 'Key to Dungeon' },
    ];

    return {
      headers: {
        realm
      },
      key: heroId,
      value: items
    }
  }
}
```

Additionally, messages passed in this format can also contain custom headers set in the `headers` hash property. Header hash property values must be either of type `string` or type `Buffer`.

heroes.controller.ts

JS TS

```typescript

@Controller()
export class HeroesController {
  @MessagePattern('hero.kill.dragon')
  killDragon(@Payload() message: KillDragonMessage): any {
    const realm = 'Nest';
    const heroId = message.heroId;
    const dragonId = message.dragonId;

    const items = [
      { id: 1, name: 'Mythical Sword' },
      { id: 2, name: 'Key to Dungeon' },
    ];

    return {
      headers: {
        kafka_nestRealm: realm
      },
      key: heroId,
      value: items
    }
  }
}
```

#### Event-based[#](/microservices/kafka#event-based)

While the request-response method is ideal for exchanging messages between services, it is less suitable when your message style is event-based (which in turn is ideal for Kafka) - when you just want to publish events **without waiting for a response**. In that case, you do not want the overhead required by request-response for maintaining two topics.

Check out these two sections to learn more about this: [Overview: Event-based](/microservices/basics#event-based) and [Overview: Publishing events](/microservices/basics#publishing-events).

#### Context[#](/microservices/kafka#context)

In more complex scenarios, you may need to access additional information about the incoming request. When using the Kafka transporter, you can access the `KafkaContext` object.

JS TS

```typescript

@MessagePattern('hero.kill.dragon')
killDragon(@Payload() message: KillDragonMessage, @Ctx() context: KafkaContext) {
  console.log(`Topic: ${context.getTopic()}`);
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('hero.kill.dragon')
killDragon(message, context) {
  console.log(`Topic: ${context.getTopic()}`);
}
```

> **Hint**`@Payload()`, `@Ctx()` and `KafkaContext` are imported from the `@nestjs/microservices` package.

To access the original Kafka `IncomingMessage` object, use the `getMessage()` method of the `KafkaContext` object, as follows:

JS TS

```typescript

@MessagePattern('hero.kill.dragon')
killDragon(@Payload() message: KillDragonMessage, @Ctx() context: KafkaContext) {
  const originalMessage = context.getMessage();
  const partition = context.getPartition();
  const { headers, timestamp } = originalMessage;
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('hero.kill.dragon')
killDragon(message, context) {
  const originalMessage = context.getMessage();
  const partition = context.getPartition();
  const { headers, timestamp } = originalMessage;
}
```

Where the `IncomingMessage` fulfills the following interface:

```typescript

interface IncomingMessage {
  topic: string;
  partition: number;
  timestamp: string;
  size: number;
  attributes: number;
  offset: string;
  key: any;
  value: any;
  headers: Record<string, any>;
}
```

If your handler involves a slow processing time for each received message you should consider using the `heartbeat` callback. To retrieve the `heartbeat` function, use the `getHeartbeat()` method of the `KafkaContext`, as follows:

JS TS

```typescript

@MessagePattern('hero.kill.dragon')
async killDragon(@Payload() message: KillDragonMessage, @Ctx() context: KafkaContext) {
  const heartbeat = context.getHeartbeat();

  // Do some slow processing
  await doWorkPart1();

  // Send heartbeat to not exceed the sessionTimeout
  await heartbeat();

  // Do some slow processing again
  await doWorkPart2();
}
```

#### Naming conventions[#](/microservices/kafka#naming-conventions)

The Kafka microservice components append a description of their respective role onto the `client.clientId` and `consumer.groupId` options to prevent collisions between Nest microservice client and server components. By default the `ClientKafkaProxy` components append `-client` and the `ServerKafka` components append `-server` to both of these options. Note how the provided values below are transformed in that way (as shown in the comments).

main.ts

JS TS

```typescript

const app = await NestFactory.createMicroservice<MicroserviceOptions>(AppModule, {
  transport: Transport.KAFKA,
  options: {
    client: {
      clientId: 'hero', // hero-server
      brokers: ['localhost:9092'],
    },
    consumer: {
      groupId: 'hero-consumer' // hero-consumer-server
    },
  }
});
```

And for the client:

heroes.controller.ts

JS TS

```typescript

@Client({
  transport: Transport.KAFKA,
  options: {
    client: {
      clientId: 'hero', // hero-client
      brokers: ['localhost:9092'],
    },
    consumer: {
      groupId: 'hero-consumer' // hero-consumer-client
    }
  }
})
client: ClientKafkaProxy;
```

> **Hint** Kafka client and consumer naming conventions can be customized by extending `ClientKafkaProxy` and `KafkaServer` in your own custom provider and overriding the constructor.

Since the Kafka microservice message pattern utilizes two topics for the request and reply channels, a reply pattern should be derived from the request topic. By default, the name of the reply topic is the composite of the request topic name with `.reply` appended.

heroes.controller.ts

JS TS

```typescript

onModuleInit() {
  this.client.subscribeToResponseOf('hero.get'); // hero.get.reply
}
```

> **Hint** Kafka reply topic naming conventions can be customized by extending `ClientKafkaProxy` in your own custom provider and overriding the `getResponsePatternName` method.

#### Retriable exceptions[#](/microservices/kafka#retriable-exceptions)

Similar to other transporters, all unhandled exceptions are automatically wrapped into an `RpcException` and converted to a "user-friendly" format. However, there are edge-cases when you might want to bypass this mechanism and let exceptions be consumed by the `kafkajs` driver instead. Throwing an exception when processing a message instructs `kafkajs` to **retry** it (redeliver it) which means that even though the message (or event) handler was triggered, the offset won't be committed to Kafka.

> **Warning** For event handlers (event-based communication), all unhandled exceptions are considered **retriable exceptions** by default.

For this, you can use a dedicated class called `KafkaRetriableException`, as follows:

```typescript

throw new KafkaRetriableException('...');
```

> **Hint**`KafkaRetriableException` class is exported from the `@nestjs/microservices` package.

### Custom exception handling

Along with the default error handling mechanisms, you can create a custom Exception Filter for Kafka events to manage retry logic. For instance, the example below demonstrates how to skip a problematic event after a configurable number of retries:

```typescript

import { Catch, ArgumentsHost, Logger } from '@nestjs/common';
import { BaseExceptionFilter } from '@nestjs/core';
import { KafkaContext } from '@nestjs/microservices';
import { Producer } from 'kafkajs';

@Catch()
export class KafkaMaxRetryExceptionFilter extends BaseExceptionFilter {
  private readonly logger = new Logger(KafkaMaxRetryExceptionFilter.name);

  constructor(
    private readonly producer: Producer,
    private readonly maxRetries: number,
    // Optional custom function executed when max retries are exceeded
    private readonly skipHandler?: (message: any) => Promise<void>,
  ) {
    super();
  }

  async catch(exception: unknown, host: ArgumentsHost) {
    const kafkaContext = host.switchToRpc().getContext<KafkaContext>();
    const message = kafkaContext.getMessage();
    const currentRetryCount = this.getRetryCountFromContext(kafkaContext);

    if (currentRetryCount >= this.maxRetries) {
      this.logger.warn(
        `Max retries (${
          this.maxRetries
        }) exceeded for message: ${JSON.stringify(message)}`,
      );

      if (this.skipHandler) {
        try {
          await this.skipHandler(message);
        } catch (err) {
          this.logger.error('Error in skipHandler:', err);
        }
      }

      try {
        await this.commitOffset(kafkaContext);
      } catch (commitError) {
        this.logger.error('Failed to commit offset:', commitError);
      }
      return; // Stop propagating the exception
    }

    // Republish the message to the same topic with incremented retry count
    try {
      await this.republishWithRetry(kafkaContext, currentRetryCount + 1);
      await this.commitOffset(kafkaContext);
    } catch (republishError) {
      this.logger.error('Failed to republish message for retry:', republishError);
      // Fall back to default exception handling
      super.catch(exception, host);
    }
  }

  private getRetryCountFromContext(context: KafkaContext): number {
    const headers = context.getMessage().headers || {};
    const retryHeader = headers['retry-count'];
    if (!retryHeader) {
      return 0;
    }
    // Header values are Buffers, so convert to string first
    const value = Buffer.isBuffer(retryHeader)
      ? retryHeader.toString()
      : String(retryHeader);
    return parseInt(value, 10) || 0;
  }

  private async republishWithRetry(
    context: KafkaContext,
    retryCount: number,
  ): Promise<void> {
    const topic = context.getTopic();
    const message = context.getMessage();

    await this.producer.send({
      topic,
      messages: [
        {
          key: message.key,
          value: message.value,
          headers: {
            ...message.headers,
            'retry-count': retryCount.toString(),
          },
        },
      ],
    });
  }

  private async commitOffset(context: KafkaContext): Promise<void> {
    const consumer = context.getConsumer();
    if (!consumer) {
      throw new Error('Consumer instance is not available from KafkaContext.');
    }

    const topic = context.getTopic();
    const partition = context.getPartition();
    const message = context.getMessage();
    const offset = message.offset;

    if (!topic || partition === undefined || offset === undefined) {
      throw new Error(
        'Incomplete Kafka message context for committing offset.',
      );
    }

    await consumer.commitOffsets([
      {
        topic,
        partition,
        // When committing an offset, commit the next number (i.e., current offset + 1)
        offset: (Number(offset) + 1).toString(),
      },
    ]);
  }
}
```

This filter offers a way to retry processing a Kafka event up to a configurable number of times. When an exception occurs, it republishes the message to the same topic with an incremented `retry-count` header, then commits the current offset. Once the maximum retries are reached, it triggers a custom `skipHandler` (if provided) and commits the offset, effectively skipping the problematic event. This allows subsequent events to be processed without interruption.

You can integrate this filter by registering it globally or at the controller level. Note that you need to provide a Kafka producer instance:

kafka-retry.filter.ts

JS TS

```typescript

import { Inject, Injectable } from '@nestjs/common';
import { Producer } from 'kafkajs';

@Injectable()
export class AppKafkaRetryFilter extends KafkaMaxRetryExceptionFilter {
  constructor(@Inject('KAFKA_PRODUCER') producer: Producer) {
    super(producer, 5); // maxRetries = 5
  }
}
```

```typescript

import { Inject, Injectable } from '@nestjs/common';

@Injectable()
export class AppKafkaRetryFilter extends KafkaMaxRetryExceptionFilter {
  constructor(@Inject('KAFKA_PRODUCER') producer) {
    super(producer, 5); // maxRetries = 5
  }
}
```

my-event.handler.ts

JS TS

```typescript

@Controller()
@UseFilters(AppKafkaRetryFilter)
export class MyEventHandler {
  @EventPattern('your-topic')
  async handleEvent(@Payload() data: any, @Ctx() context: KafkaContext) {
    // Your event processing logic...
  }
}
```

```typescript

@Controller()
@UseFilters(AppKafkaRetryFilter)
export class MyEventHandler {
  @Bind(Payload(), Ctx())
  @EventPattern('your-topic')
  async handleEvent(data, context) {
    // Your event processing logic...
  }
}
```

Make sure to provide the Kafka producer in your module:

app.module.ts

JS TS

```typescript

import { Kafka } from 'kafkajs';

@Module({
  providers: [
    AppKafkaRetryFilter,
    {
      provide: 'KAFKA_PRODUCER',
      useFactory: async () => {
        const kafka = new Kafka({ brokers: ['localhost:9092'] });
        const producer = kafka.producer();
        await producer.connect();
        return producer;
      },
    },
  ],
})
export class AppModule {}
```

#### Commit offsets[#](/microservices/kafka#commit-offsets)

Committing offsets is essential when working with Kafka. Per default, messages will be automatically committed after a specific time. For more information visit [KafkaJS docs](https://kafka.js.org/docs/consuming#autocommit). `KafkaContext` offers a way to access the active consumer for manually committing offsets. The consumer is the KafkaJS consumer and works as the [native KafkaJS implementation](https://kafka.js.org/docs/consuming#manual-committing).

JS TS

```typescript

@EventPattern('user.created')
async handleUserCreated(@Payload() data: IncomingMessage, @Ctx() context: KafkaContext) {
  // business logic

  const { offset } = context.getMessage();
  const partition = context.getPartition();
  const topic = context.getTopic();
  const consumer = context.getConsumer();
  await consumer.commitOffsets([{ topic, partition, offset }])
}
```

```typescript

@Bind(Payload(), Ctx())
@EventPattern('user.created')
async handleUserCreated(data, context) {
  // business logic

  const { offset } = context.getMessage();
  const partition = context.getPartition();
  const topic = context.getTopic();
  const consumer = context.getConsumer();
  await consumer.commitOffsets([{ topic, partition, offset }])
}
```

To disable auto-committing of messages set `autoCommit: false` in the `run` configuration, as follows:

main.ts

JS TS

```typescript

const app = await NestFactory.createMicroservice<MicroserviceOptions>(AppModule, {
  transport: Transport.KAFKA,
  options: {
    client: {
      brokers: ['localhost:9092'],
    },
    run: {
      autoCommit: false
    }
  }
});
```

```typescript

const app = await NestFactory.createMicroservice(AppModule, {
  transport: Transport.KAFKA,
  options: {
    client: {
      brokers: ['localhost:9092'],
    },
    run: {
      autoCommit: false
    }
  }
});
```

#### Instance status updates[#](/microservices/kafka#instance-status-updates)

To get real-time updates on the connection and the state of the underlying driver instance, you can subscribe to the `status` stream. This stream provides status updates specific to the chosen driver. For the Kafka driver, the `status` stream emits `connected`, `disconnected`, `rebalancing`, `crashed`, and `stopped` events.

```typescript

this.client.status.subscribe((status: KafkaStatus) => {
  console.log(status);
});
```

> **Hint** The `KafkaStatus` type is imported from the `@nestjs/microservices` package.

Similarly, you can subscribe to the server's `status` stream to receive notifications about the server's status.

```typescript

const server = app.connectMicroservice<MicroserviceOptions>(...);
server.status.subscribe((status: KafkaStatus) => {
  console.log(status);
});
```

#### Underlying producer and consumer[#](/microservices/kafka#underlying-producer-and-consumer)

For more advanced use cases, you may need to access the underlying producer and consumer instances. This can be useful for scenarios like manually closing the connection or using driver-specific methods. However, keep in mind that for most cases, you **shouldn't need** to access the driver directly.

To do so, you can use `producer` and `consumer` getters exposed by the `ClientKafkaProxy` instance.

```typescript

const producer = this.client.producer;
const consumer = this.client.consumer;
```

----
url: https://docs.nestjs.com/v10/devtools/ci-cd-integration
----

* [CI/CD integration](https://docs.nestjs.com/v10/devtools/ci-cd-integration#cicd-integration)
* [Publishing graphs](https://docs.nestjs.com/v10/devtools/ci-cd-integration#publishing-graphs)
* [Reports](https://docs.nestjs.com/v10/devtools/ci-cd-integration#reports)
* [Build preview](https://docs.nestjs.com/v10/devtools/ci-cd-integration#build-preview)
* [Integrations: GitHub Actions](https://docs.nestjs.com/v10/devtools/ci-cd-integration#integrations-github-actions)
* [Integrations: Gitlab Pipelines](https://docs.nestjs.com/v10/devtools/ci-cd-integration#integrations-gitlab-pipelines)
* [Other CI/CD tools](https://docs.nestjs.com/v10/devtools/ci-cd-integration#other-cicd-tools)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/devtools/ci-cd.md "Suggest Edits")

### CI/CD integration

> **Hint** This chapter covers the Nest Devtools integration with the Nest framework. If you are looking for the Devtools application, please visit the [Devtools](https://devtools.nestjs.com) website.

CI/CD integration is available for users with the **[Enterprise](/v10/settings)** plan.

You can watch this video to learn why & how CI/CD integration can help you:

#### Publishing graphs[#](/devtools/ci-cd-integration#publishing-graphs)

Let's first configure the application bootstrap file (`main.ts`) to use the `GraphPublisher` class (exported from the `@nestjs/devtools-integration` - see previous chapter for more details), as follows:

```typescript

async function bootstrap() {
  const shouldPublishGraph = process.env.PUBLISH_GRAPH === "true";

  const app = await NestFactory.create(AppModule, {
    snapshot: true,
    preview: shouldPublishGraph,
  });

  if (shouldPublishGraph) {
    await app.init();

    const publishOptions = { ... } // NOTE: this options object will vary depending on the CI/CD provider you're using
    const graphPublisher = new GraphPublisher(app);
    await graphPublisher.publish(publishOptions);

    await app.close();
  } else {
    await app.listen(process.env.PORT ?? 3000);
  }
}
```

```yaml

name: Devtools

on:
  push:
    branches:
      - master
  pull_request:
    branches:
      - '*'

jobs:
  publish:
    if: github.actor!= 'dependabot[bot]'
    name: Publish graph
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: '16'
          cache: 'npm'
      - name: Install dependencies
        run: npm ci
      - name: Setup Environment (PR)
        if: ${{ github.event_name == 'pull_request' }}
        shell: bash
        run: |
          echo "COMMIT_SHA=${{ github.event.pull_request.head.sha }}" >>\${GITHUB_ENV}
      - name: Setup Environment (Push)
        if: ${{ github.event_name == 'push' }}
        shell: bash
        run: |
          echo "COMMIT_SHA=\${GITHUB_SHA}" >> \${GITHUB_ENV}
      - name: Publish
        run: PUBLISH_GRAPH=true npm run start
        env:
          DEVTOOLS_API_KEY: CHANGE_THIS_TO_YOUR_API_KEY
          REPOSITORY_NAME: ${{ github.event.repository.name }}
          BRANCH_NAME: ${{ github.head_ref || github.ref_name }}
          TARGET_SHA: ${{ github.event.pull_request.base.sha }}
```

Ideally, `DEVTOOLS_API_KEY` environment variable should be retrieved from GitHub Secrets, read more [here](https://docs.github.com/en/actions/security-guides/encrypted-secrets#creating-encrypted-secrets-for-a-repository) .

This workflow will run per each pull request that's targeting the `master` branch OR in case there's a direct commit to the `master` branch. Feel free to align this configuration to whatever your project needs. What's essential here is that we provide necessary environment variables for our `GraphPublisher` class (to run).

However, there's one variable that needs to be updated before we can start using this workflow - `DEVTOOLS_API_KEY`. We can generate an API key dedicated for our project on this [page](https://devtools.nestjs.com/settings/manage-api-keys).

Lastly, let's navigate to the `main.ts` file again and update the `publishOptions` object we previously left empty.

```typescript

const publishOptions = {
  apiKey: process.env.DEVTOOLS_API_KEY,
  repository: process.env.REPOSITORY_NAME,
  owner: process.env.GITHUB_REPOSITORY_OWNER,
  sha: process.env.COMMIT_SHA,
  target: process.env.TARGET_SHA,
  trigger: process.env.GITHUB_BASE_REF ? 'pull' : 'push',
  branch: process.env.BRANCH_NAME,
};
```

For the best developer experience, make sure to integrate the **GitHub application** for your project by clicking on the "Integrate GitHub app" button (see screenshot below). Note - this isn't required.

With this integration, you'll be able to see the status of the preview/report generation process right in your pull request:

#### Integrations: Gitlab Pipelines[#](/devtools/ci-cd-integration#integrations-gitlab-pipelines)

First let's start from creating a new Gitlab CI configuration file in the root directory of our project and call it, for example, `.gitlab-ci.yml`. Inside this file, let's use the following definition:

```typescript

const publishOptions = {
  apiKey: process.env.DEVTOOLS_API_KEY,
  repository: process.env.REPOSITORY_NAME,
  owner: process.env.GITHUB_REPOSITORY_OWNER,
  sha: process.env.COMMIT_SHA,
  target: process.env.TARGET_SHA,
  trigger: process.env.GITHUB_BASE_REF ? 'pull' : 'push',
  branch: process.env.BRANCH_NAME,
};
```

> **Hint** Ideally, `DEVTOOLS_API_KEY` environment variable should be retrieved from secrets.

This workflow will run per each pull request that's targeting the `master` branch OR in case there's a direct commit to the `master` branch. Feel free to align this configuration to whatever your project needs. What's essential here is that we provide necessary environment variables for our `GraphPublisher` class (to run).

However, there's one variable (in this workflow definition) that needs to be updated before we can start using this workflow - `DEVTOOLS_API_KEY`. We can generate an API key dedicated for our project on this **page** .

Lastly, let's navigate to the `main.ts` file again and update the `publishOptions` object we previously left empty.

```yaml

image: node:16

stages:
  - build

cache:
  key:
    files:
      - package-lock.json
  paths:
    - node_modules/

workflow:
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
      when: always
    - if: $CI_COMMIT_BRANCH == "master" && $CI_PIPELINE_SOURCE == "push"
      when: always
    - when: never

install_dependencies:
  stage: build
  script:
    - npm ci

publish_graph:
  stage: build
  needs:
    - install_dependencies
  script: npm run start
  variables:
    PUBLISH_GRAPH: 'true'
    DEVTOOLS_API_KEY: 'CHANGE_THIS_TO_YOUR_API_KEY'
```

#### Other CI/CD tools[#](/devtools/ci-cd-integration#other-cicd-tools)

Nest Devtools CI/CD integration can be used with any CI/CD tool of your choice (e.g., [Bitbucket Pipelines](https://bitbucket.org/product/features/pipelines) , [CircleCI](https://circleci.com/), etc) so don't feel limited to providers we described here.

Look at the following `publishOptions` object configuration to understand what information is required to publish the graph for a given commit/build/PR.

```typescript

const publishOptions = {
  apiKey: process.env.DEVTOOLS_API_KEY,
  repository: process.env.CI_PROJECT_NAME,
  owner: process.env.CI_PROJECT_ROOT_NAMESPACE,
  sha: process.env.CI_COMMIT_SHA,
  target: process.env.CI_MERGE_REQUEST_DIFF_BASE_SHA,
  trigger: process.env.CI_MERGE_REQUEST_DIFF_BASE_SHA ? 'pull' : 'push',
  branch: process.env.CI_COMMIT_BRANCH ?? process.env.CI_MERGE_REQUEST_SOURCE_BRANCH_NAME,
};
```

Most of this information is provided through CI/CD built-in environment variables (see [CircleCI built-in environment list](https://circleci.com/docs/variables/#built-in-environment-variables) and [Bitbucket variables](https://support.atlassian.com/bitbucket-cloud/docs/variables-and-secrets/) ).

When it comes to the pipeline configuration for publishing graphs, we recommend using the following triggers:

* `push` event - only if the current branch represents a deployment environment, for example `master`, `main`, `staging`, `production`, etc.
* `pull request` event - always, or when the **target branch** represents a deployment environment (see above)

----
url: https://docs.nestjs.com/v8/custom-decorators
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Custom route decorators](https://docs.nestjs.com/v8/custom-decorators#custom-route-decorators)
* [Param decorators](https://docs.nestjs.com/v8/custom-decorators#param-decorators)
* [Passing data](https://docs.nestjs.com/v8/custom-decorators#passing-data)
* [Working with pipes](https://docs.nestjs.com/v8/custom-decorators#working-with-pipes)
* [Decorator composition](https://docs.nestjs.com/v8/custom-decorators#decorator-composition)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/custom-decorators.md "Suggest Edits")

### Custom route decorators

Nest is built around a language feature called **decorators**. Decorators are a well-known concept in a lot of commonly used programming languages, but in the JavaScript world, they're still relatively new. In order to better understand how decorators work, we recommend reading [this article](https://medium.com/google-developers/exploring-es7-decorators-76ecb65fb841). Here's a simple definition:

> An ES2016 decorator is an expression which returns a function and can take a target, name and property descriptor as arguments. You apply it by prefixing the decorator with an `@` character and placing this at the very top of what you are trying to decorate. Decorators can be defined for either a class, a method or a property.

#### Param decorators[#](/custom-decorators#param-decorators)

Nest provides a set of useful **param decorators** that you can use together with the HTTP route handlers. Below is a list of the provided decorators and the plain Express (or Fastify) objects they represent

|                            |                                      |
| -------------------------- | ------------------------------------ |
| `@Request(), @Req()`       | `req`                                |
| `@Response(), @Res()`      | `res`                                |
| `@Next()`                  | `next`                               |
| `@Session()`               | `req.session`                        |
| `@Param(param?: string)`   | `req.params` / `req.params[param]`   |
| `@Body(param?: string)`    | `req.body` / `req.body[param]`       |
| `@Query(param?: string)`   | `req.query` / `req.query[param]`     |
| `@Headers(param?: string)` | `req.headers` / `req.headers[param]` |
| `@Ip()`                    | `req.ip`                             |
| `@HostParam()`             | `req.hosts`                          |

Additionally, you can create your own **custom decorators**. Why is this useful?

In the node.js world, it's common practice to attach properties to the **request** object. Then you manually extract them in each route handler, using code like the following:

```typescript

const user = req.user;
```

In order to make your code more readable and transparent, you can create a `@User()` decorator and reuse it across all of your controllers.

user.decorator.ts

JS TS

```typescript

import { createParamDecorator, ExecutionContext } from '@nestjs/common';

export const User = createParamDecorator(
  (data: unknown, ctx: ExecutionContext) => {
    const request = ctx.switchToHttp().getRequest();
    return request.user;
  },
);
```

Then, you can simply use it wherever it fits your requirements.

JS TS

```typescript

@Get()
async findOne(@User() user: UserEntity) {
  console.log(user);
}
```

```typescript

@Get()
@Bind(User())
async findOne(user) {
  console.log(user);
}
```

#### Passing data[#](/custom-decorators#passing-data)

When the behavior of your decorator depends on some conditions, you can use the `data` parameter to pass an argument to the decorator's factory function. One use case for this is a custom decorator that extracts properties from the request object by key. Let's assume, for example, that our [authentication layer](techniques/authentication#implementing-passport-strategies) validates requests and attaches a user entity to the request object. The user entity for an authenticated request might look like:

```json

{
  "id": 101,
  "firstName": "Alan",
  "lastName": "Turing",
  "email": "alan@email.com",
  "roles": ["admin"]
}
```

Let's define a decorator that takes a property name as key, and returns the associated value if it exists (or undefined if it doesn't exist, or if the `user` object has not been created).

user.decorator.ts

JS TS

```typescript

import { createParamDecorator, ExecutionContext } from '@nestjs/common';

export const User = createParamDecorator(
  (data: string, ctx: ExecutionContext) => {
    const request = ctx.switchToHttp().getRequest();
    const user = request.user;

    return data ? user?.[data] : user;
  },
);
```

```typescript

import { createParamDecorator } from '@nestjs/common';

export const User = createParamDecorator((data, ctx) => {
  const request = ctx.switchToHttp().getRequest();
  const user = request.user;

  return data ? user && user[data] : user;
});
```

Here's how you could then access a particular property via the `@User()` decorator in the controller:

JS TS

```typescript

@Get()
async findOne(@User('firstName') firstName: string) {
  console.log(`Hello ${firstName}`);
}
```

```typescript

@Get()
@Bind(User('firstName'))
async findOne(firstName) {
  console.log(`Hello ${firstName}`);
}
```

You can use this same decorator with different keys to access different properties. If the `user` object is deep or complex, this can make for easier and more readable request handler implementations.

> **Hint** For TypeScript users, note that `createParamDecorator<T>()` is a generic. This means you can explicitly enforce type safety, for example `createParamDecorator<string>((data, ctx) => ...)`. Alternatively, specify a parameter type in the factory function, for example `createParamDecorator((data: string, ctx) => ...)`. If you omit both, the type for `data` will be `any`.

#### Working with pipes[#](/custom-decorators#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:

JS TS

```typescript

@Get()
async findOne(
  @User(new ValidationPipe({ validateCustomDecorators: true }))
  user: UserEntity,
) {
  console.log(user);
}
```

```typescript

@Get()
@Bind(User(new ValidationPipe({ validateCustomDecorators: true })))
async findOne(user) {
  console.log(user);
}
```

> **Hint** Note that `validateCustomDecorators` option must be set to true. `ValidationPipe` does not validate arguments annotated with the custom decorators by default.

#### Decorator composition[#](/custom-decorators#decorator-composition)

Nest provides a helper method to compose multiple decorators. For example, suppose you want to combine all decorators related to authentication into a single decorator. This could be done with the following construction:

auth.decorator.ts

JS TS

```typescript

import { applyDecorators } from '@nestjs/common';

export function Auth(...roles: Role[]) {
  return applyDecorators(
    SetMetadata('roles', roles),
    UseGuards(AuthGuard, RolesGuard),
    ApiBearerAuth(),
    ApiUnauthorizedResponse({ description: 'Unauthorized' }),
  );
}
```

```typescript

import { applyDecorators } from '@nestjs/common';

export function Auth(...roles) {
  return applyDecorators(
    SetMetadata('roles', roles),
    UseGuards(AuthGuard, RolesGuard),
    ApiBearerAuth(),
    ApiUnauthorizedResponse({ description: 'Unauthorized' }),
  );
}
```

You can then use this custom `@Auth()` decorator as follows:

```typescript

@Get('users')
@Auth('admin')
findAllUsers() {}
```

This has the effect of applying all four decorators with a single declaration.

> **Warning** The `@ApiHideProperty()` decorator from the `@nestjs/swagger` package is not composable and won't work properly with the `applyDecorators` function.

----
url: https://docs.nestjs.com/v6/microservices/pipes
----

* [Pipes](https://docs.nestjs.com/v6/microservices/pipes#pipes)
* [Binding pipes](https://docs.nestjs.com/v6/microservices/pipes#binding-pipes)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/microservices/pipes.md "Suggest Edits")

### Pipes

There is no fundamental difference between [regular pipes](/v6/pipes) and microservices pipes. The only difference is that instead of throwing `HttpException`, you should use `RpcException`.

> **Hint** The `RpcException` class is exposed from `@nestjs/microservices` package.

#### Binding pipes[#](/microservices/pipes#binding-pipes)

The following example uses a manually instantiated method-scoped pipe. Just as with HTTP based applications, you can also use controller-scoped pipes (i.e., prefix the controller class with a `@UsePipes()` decorator).

JS TS

```typescript

@UsePipes(new ValidationPipe())
@MessagePattern({ cmd: 'sum' })
accumulate(data: number[]): number {
  return (data || []).reduce((a, b) => a + b);
}
```

```typescript

@UsePipes(new ValidationPipe())
@MessagePattern({ cmd: 'sum' })
accumulate(data) {
  return (data || []).reduce((a, b) => a + b);
}
```

----
url: https://docs.nestjs.com/middleware
----

[Skip to content](#content)

On this page

* [Middleware](https://docs.nestjs.com/middleware#middleware)
* [Dependency injection](https://docs.nestjs.com/middleware#dependency-injection)
* [Applying middleware](https://docs.nestjs.com/middleware#applying-middleware)
* [Route wildcards](https://docs.nestjs.com/middleware#route-wildcards)
* [Middleware consumer](https://docs.nestjs.com/middleware#middleware-consumer)
* [Excluding routes](https://docs.nestjs.com/middleware#excluding-routes)
* [Functional middleware](https://docs.nestjs.com/middleware#functional-middleware)
* [Multiple middleware](https://docs.nestjs.com/middleware#multiple-middleware)
* [Global middleware](https://docs.nestjs.com/middleware#global-middleware)
* [Error handling](https://docs.nestjs.com/middleware#error-handling)

### Middleware

Middleware is a function that is called **before** the route handler. Middleware functions have access to the [request](https://expressjs.com/en/4x/api.html#req) and [response](https://expressjs.com/en/4x/api.html#res) objects, and to the `next()` middleware function in the application's request-response cycle. The **next** middleware function is commonly denoted by a variable named `next`.

By default, Nest middleware is equivalent to [Express](https://expressjs.com/en/guide/using-middleware.html) middleware. The official Express documentation describes the capabilities of middleware as follows:

> Middleware functions can perform the following tasks:
>
> * execute any code.
> * make changes to the request and the response objects.
> * end the request-response cycle.
> * call the next middleware function in the stack.
> * if the current middleware function does not end the request-response cycle, it must call `next()` to pass control to the next middleware function. Otherwise, the request will be left hanging.

You implement custom Nest middleware either as a function or as a class with the `@Injectable()` decorator. A class should implement the `NestMiddleware` interface, while a function has no special requirements. Let's start by implementing a simple middleware class.

> **Warning** Express and Fastify handle middleware differently and provide different method signatures. See the [Performance (Fastify)](/http/performance#middleware) chapter for details.

logger.middleware.ts

JS TS

```typescript

import { Injectable, NestMiddleware } from '@nestjs/common';
import { Request, Response, NextFunction } from 'express';

@Injectable()
export class LoggerMiddleware implements NestMiddleware {
  use(req: Request, res: Response, next: NextFunction) {
    console.log('Request...');
    next();
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';

@Injectable()
export class LoggerMiddleware {
  use(req, res, next) {
    console.log('Request...');
    next();
  }
}
```

#### Dependency injection[#](/middleware#dependency-injection)

Nest middleware fully supports dependency injection. Like providers and controllers, middleware classes can **inject dependencies** that are available within the same module. As usual, dependencies are injected through the `constructor`.

#### Applying middleware[#](/middleware#applying-middleware)

Middleware is not registered in the `@Module()` decorator. Instead, you set it up in the `configure()` method of the module class. Modules that include middleware must implement the `NestModule` interface. Let's set up the `LoggerMiddleware` at the `AppModule` level.

app.module.ts

JS TS

```typescript

import { Module, NestModule, MiddlewareConsumer } from '@nestjs/common';
import { LoggerMiddleware } from './common/middleware/logger.middleware.js';
import { CatsModule } from './cats/cats.module.js';

@Module({
  imports: [CatsModule],
})
export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer
      .apply(LoggerMiddleware)
      .forRoutes('cats');
  }
}
```

```typescript

import { Module } from '@nestjs/common';
import { LoggerMiddleware } from './common/middleware/logger.middleware.js';
import { CatsModule } from './cats/cats.module.js';

@Module({
  imports: [CatsModule],
})
export class AppModule {
  configure(consumer) {
    consumer
      .apply(LoggerMiddleware)
      .forRoutes('cats');
  }
}
```

In the example above, the `LoggerMiddleware` is applied to the `/cats` route handlers defined in the `CatsController`. To restrict middleware to a particular request method, pass an object containing the route `path` and the request `method` to the `forRoutes()` method. The example below imports the `RequestMethod` enum to reference the desired request method.

app.module.ts

JS TS

```typescript

import { Module, NestModule, RequestMethod, MiddlewareConsumer } from '@nestjs/common';
import { LoggerMiddleware } from './common/middleware/logger.middleware.js';
import { CatsModule } from './cats/cats.module.js';

@Module({
  imports: [CatsModule],
})
export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer
      .apply(LoggerMiddleware)
      .forRoutes({ path: 'cats', method: RequestMethod.GET });
  }
}
```

```typescript

import { Module, RequestMethod } from '@nestjs/common';
import { LoggerMiddleware } from './common/middleware/logger.middleware.js';
import { CatsModule } from './cats/cats.module.js';

@Module({
  imports: [CatsModule],
})
export class AppModule {
  configure(consumer) {
    consumer
      .apply(LoggerMiddleware)
      .forRoutes({ path: 'cats', method: RequestMethod.GET });
  }
}
```

> **Hint** The `configure()` method can be asynchronous. Declare it with `async` to `await` the completion of an asynchronous operation inside the method body.

> **Warning** With the Express adapter, Nest registers the `json` and `urlencoded` body parsers (`express.json()` and `express.urlencoded()`) by default. To customize these parsers through the `MiddlewareConsumer`, disable the defaults by setting the `bodyParser` option to `false` when creating the application with `NestFactory.create()`.

#### Route wildcards[#](/middleware#route-wildcards)

Middleware also supports pattern-based routes. For example, the named wildcard (`*splat`) matches any combination of characters in a route. In the following example, the middleware runs for any route that starts with `abcd/`, regardless of how many characters follow.

```typescript

forRoutes({
  path: 'abcd/*splat',
  method: RequestMethod.ALL,
});
```

> **Hint**`splat` is only the name of the wildcard parameter and has no special meaning. You can use any name, e.g., `*wildcard`.

The `'abcd/*splat'` route path matches `abcd/1`, `abcd/123`, `abcd/abc`, and so on. String-based paths interpret the hyphen (`-`) and the dot (`.`) literally. However, `abcd/` with no additional characters does not match. To match it as well, wrap the wildcard in braces to make it optional:

```typescript

forRoutes({
  path: 'abcd/{*splat}',
  method: RequestMethod.ALL,
});
```

#### Middleware consumer[#](/middleware#middleware-consumer)

The `MiddlewareConsumer` is a helper class that provides several built-in methods to manage middleware. All of them can be **chained** in the [fluent style](https://en.wikipedia.org/wiki/Fluent_interface). The `forRoutes()` method accepts a single string, multiple strings, a `RouteInfo` object, a controller class, or multiple controller classes. In most cases, you'll pass a comma-separated list of **controllers**. Below is an example with a single controller:

app.module.ts

JS TS

```typescript

import { Module, NestModule, MiddlewareConsumer } from '@nestjs/common';
import { LoggerMiddleware } from './common/middleware/logger.middleware.js';
import { CatsModule } from './cats/cats.module.js';
import { CatsController } from './cats/cats.controller.js';

@Module({
  imports: [CatsModule],
})
export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer
      .apply(LoggerMiddleware)
      .forRoutes(CatsController);
  }
}
```

```typescript

import { Module } from '@nestjs/common';
import { LoggerMiddleware } from './common/middleware/logger.middleware.js';
import { CatsModule } from './cats/cats.module.js';
import { CatsController } from './cats/cats.controller.js';

@Module({
  imports: [CatsModule],
})
export class AppModule {
  configure(consumer) {
    consumer
      .apply(LoggerMiddleware)
      .forRoutes(CatsController);
  }
}
```

> **Hint** The `apply()` method accepts either a single middleware or multiple arguments to specify [multiple middleware](/middleware#multiple-middleware).

#### Excluding routes[#](/middleware#excluding-routes)

To **exclude** certain routes from having middleware applied, use the `exclude()` method. It accepts a single string, multiple strings, or a `RouteInfo` object that identifies the routes to exclude:

```typescript

consumer
  .apply(LoggerMiddleware)
  .exclude(
    { path: 'cats', method: RequestMethod.GET },
    { path: 'cats', method: RequestMethod.POST },
    'cats/{*splat}',
  )
  .forRoutes(CatsController);
```

With the example above, `LoggerMiddleware` is bound to all routes defined inside `CatsController`**except** those matching the three entries passed to the `exclude()` method.

> **Hint** The `exclude()` method supports wildcard parameters using the [path-to-regexp](https://github.com/pillarjs/path-to-regexp#parameters) package.

#### Functional middleware[#](/middleware#functional-middleware)

The `LoggerMiddleware` class we've been using is minimal: it has no members, no additional methods, and no dependencies. Middleware like this can be defined as a plain function instead of a class. This type of middleware is called **functional middleware**. Let's convert the logger middleware from a class into a function to illustrate the difference:

logger.middleware.ts

JS TS

```typescript

import { Request, Response, NextFunction } from 'express';

export function logger(req: Request, res: Response, next: NextFunction) {
  console.log('Request...');
  next();
}
```

```typescript

export function logger(req, res, next) {
  console.log('Request...');
  next();
}
```

Then use it within the `AppModule`:

app.module.ts

JS TS

```typescript

consumer
  .apply(logger)
  .forRoutes(CatsController);
```

> **Hint** Consider using **functional middleware** whenever your middleware doesn't need any dependencies.

#### Multiple middleware[#](/middleware#multiple-middleware)

To bind multiple middleware that execute sequentially, pass a comma-separated list to the `apply()` method:

```typescript

consumer.apply(cors(), helmet(), logger).forRoutes(CatsController);
```

#### Global middleware[#](/middleware#global-middleware)

To bind middleware to every registered route at once, use the `use()` method of the `INestApplication` instance:

main.ts

JS TS

```typescript

const app = await NestFactory.create(AppModule);
app.use(logger);
await app.listen(process.env.PORT ?? 3000);
```

> **Hint** Global middleware registered with `app.use()` cannot access the DI container, so use [functional middleware](middleware#functional-middleware) there. Alternatively, use a class middleware and bind it with `.forRoutes('*')` within the `AppModule` (or any other module).

#### Error handling[#](/middleware#error-handling)

When middleware throws an exception, Nest's [exceptions layer](/exception-filters) catches it and sends an appropriate response, just as it does for exceptions thrown from a route handler. The recommended approach is to throw an `HttpException` (or a built-in subclass such as `UnauthorizedException`):

auth.middleware.ts

JS TS

```typescript

import {
  Injectable,
  NestMiddleware,
  UnauthorizedException,
} from '@nestjs/common';
import { Request, Response, NextFunction } from 'express';

@Injectable()
export class AuthMiddleware implements NestMiddleware {
  use(req: Request, res: Response, next: NextFunction) {
    if (!req.headers.authorization) {
      throw new UnauthorizedException();
    }
    next();
  }
}
```

```typescript

import { Injectable, UnauthorizedException } from '@nestjs/common';

@Injectable()
export class AuthMiddleware {
  use(req, res, next) {
    if (!req.headers.authorization) {
      throw new UnauthorizedException();
    }
    next();
  }
}
```

If the middleware is asynchronous, declare `use()` as `async` (or return a `Promise`) so that a rejected promise is forwarded to the exceptions layer:

auth.middleware.ts

JS TS

```typescript

@Injectable()
export class AuthMiddleware implements NestMiddleware {
  constructor(private readonly authService: AuthService) {}

  async use(req: Request, res: Response, next: NextFunction) {
    const user = await this.authService.verify(req.headers.authorization);
    if (!user) {
      throw new UnauthorizedException();
    }
    req['user'] = user;
    next();
  }
}
```

You can also pass the error to `next()`. This is useful when wrapping existing Express-style middleware that reports failures through the callback:

```typescript

use(req: Request, res: Response, next: NextFunction) {
  if (!req.headers.authorization) {
    return next(new UnauthorizedException());
  }
  next();
}
```

> **Warning** Because middleware runs before a route handler is selected, only **global** exception filters (registered with `app.useGlobalFilters()` or the `APP_FILTER` token) catch exceptions thrown from middleware. Method-scoped and controller-scoped filters are not invoked, and binding filters to a middleware class with `@UseFilters()` is not supported.

> **Hint** Middleware registered with `app.use()` is handled by the underlying HTTP platform (Express or Fastify), not by Nest's `MiddlewareModule`. Prefer throwing errors (or calling `next(err)`) from middleware bound with the `MiddlewareConsumer`, so that the exceptions layer can process them.

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/middlewares.md)

----
url: https://docs.nestjs.com/v11/providers
----

* [Providers](https://docs.nestjs.com/v11/providers#providers)
* [Services](https://docs.nestjs.com/v11/providers#services)
* [Dependency injection](https://docs.nestjs.com/v11/providers#dependency-injection)
* [Scopes](https://docs.nestjs.com/v11/providers#scopes)
* [Custom providers](https://docs.nestjs.com/v11/providers#custom-providers)
* [Optional providers](https://docs.nestjs.com/v11/providers#optional-providers)
* [Property-based injection](https://docs.nestjs.com/v11/providers#property-based-injection)
* [Provider registration](https://docs.nestjs.com/v11/providers#provider-registration)
* [Manual instantiation](https://docs.nestjs.com/v11/providers#manual-instantiation)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/components.md "Suggest Edits")

### Providers

Providers are a core concept in Nest. Many of the basic Nest classes, such as services, repositories, factories, and helpers, can be treated as providers. The key idea behind a provider is that it can be **injected** as a dependency, allowing objects to form various relationships with each other. The responsibility of "wiring up" these objects is largely handled by the Nest runtime system.

In the previous chapter, we created a simple `CatsController`. Controllers should handle HTTP requests and delegate more complex tasks to **providers**. Providers are plain JavaScript classes declared as `providers` in a NestJS module. For more details, refer to the "Modules" chapter.

> **Hint** Since Nest enables you to design and organize dependencies in an object-oriented manner, we strongly recommend following the [SOLID principles](https://en.wikipedia.org/wiki/SOLID).

#### Services[#](/providers#services)

Let's begin by creating a simple `CatsService`. This service will handle data storage and retrieval, and it will be used by the `CatsController`. Because of its role in managing the application's logic, it’s an ideal candidate to be defined as a provider.

cats.service.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { Cat } from './interfaces/cat.interface';

@Injectable()
export class CatsService {
  private readonly cats: Cat[] = [];

  create(cat: Cat) {
    this.cats.push(cat);
  }

  findAll(): Cat[] {
    return this.cats;
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';

@Injectable()
export class CatsService {
  constructor() {
    this.cats = [];
  }

  create(cat) {
    this.cats.push(cat);
  }

  findAll() {
    return this.cats;
  }
}
```

> **Hint** To create a service using the CLI, simply execute the `$ nest g service cats` command.

Our `CatsService` is a basic class with one property and two methods. The key addition here is the `@Injectable()` decorator. This decorator attaches metadata to the class, signaling that `CatsService` is a class that can be managed by the Nest [IoC](https://en.wikipedia.org/wiki/Inversion_of_control) container.

Additionally, this example makes use of a `Cat` interface, which likely looks something like this:

interfaces/cat.interface.ts

JS TS

```typescript

export interface Cat {
  name: string;
  age: number;
  breed: string;
}
```

Now that we have a service class to retrieve cats, let's use it inside the `CatsController`:

cats.controller.ts

JS TS

```typescript

import { Controller, Get, Post, Body } from '@nestjs/common';
import { CreateCatDto } from './dto/create-cat.dto';
import { CatsService } from './cats.service';
import { Cat } from './interfaces/cat.interface';

@Controller('cats')
export class CatsController {
  constructor(private catsService: CatsService) {}

  @Post()
  async create(@Body() createCatDto: CreateCatDto) {
    this.catsService.create(createCatDto);
  }

  @Get()
  async findAll(): Promise<Cat[]> {
    return this.catsService.findAll();
  }
}
```

```typescript

import { Controller, Get, Post, Body, Bind, Dependencies } from '@nestjs/common';
import { CatsService } from './cats.service';

@Controller('cats')
@Dependencies(CatsService)
export class CatsController {
  constructor(catsService) {
    this.catsService = catsService;
  }

  @Post()
  @Bind(Body())
  async create(createCatDto) {
    this.catsService.create(createCatDto);
  }

  @Get()
  async findAll() {
    return this.catsService.findAll();
  }
}
```

The `CatsService` is **injected** through the class constructor. Notice the use of the `private` keyword. This shorthand allows us to both declare and initialize the `catsService` member in the same line, streamlining the process.

#### Dependency injection[#](/providers#dependency-injection)

Nest is built around the powerful design pattern known as **Dependency Injection**. We highly recommend reading a great article about this concept in the official [Angular documentation](https://angular.dev/guide/di).

In Nest, thanks to TypeScript's capabilities, managing dependencies is straightforward because they are resolved based on their type. In the example below, Nest will resolve the `catsService` by creating and returning an instance of `CatsService` (or, in the case of a singleton, returning the existing instance if it has already been requested elsewhere). This dependency is then injected into your controller's constructor (or assigned to the specified property):

```typescript

constructor(private catsService: CatsService) {}
```

#### Scopes[#](/providers#scopes)

Providers typically have a lifetime ("scope") that aligns with the application lifecycle. When the application is bootstrapped, each dependency must be resolved, meaning every provider gets instantiated. Similarly, when the application shuts down, all providers are destroyed. However, it’s also possible to make a provider **request-scoped**, meaning its lifetime is tied to a specific request rather than the application's lifecycle. You can learn more about these techniques in the [Injection Scopes](/v11/fundamentals/injection-scopes) chapter.

Nest comes with a built-in inversion of control ("IoC") container that manages the relationships between providers. This feature is the foundation of dependency injection, but it’s actually much more powerful than we've covered so far. There are several ways to define a provider: you can use plain values, classes, and both asynchronous or synchronous factories. For more examples of defining providers, check out the [Dependency Injection](/v11/fundamentals/dependency-injection) chapter.

#### Optional providers[#](/providers#optional-providers)

Occasionally, you may have dependencies that don't always need to be resolved. For example, your class might depend on a **configuration object**, but if none is provided, default values should be used. In such cases, the dependency is considered optional, and the absence of the configuration provider should not result in an error.

To mark a provider as optional, use the `@Optional()` decorator in the constructor's signature.

```typescript

import { Injectable, Optional, Inject } from '@nestjs/common';

@Injectable()
export class HttpService<T> {
  constructor(@Optional() @Inject('HTTP_OPTIONS') private httpClient: T) {}
}
```

In the example above, we're using a custom provider, which is why we include the `HTTP_OPTIONS` custom **token**. Previous examples demonstrated constructor-based injection, where a dependency is indicated through a class in the constructor. For more details on custom providers and how their associated tokens work, check out the [Custom Providers](/v11/fundamentals/custom-providers) chapter.

#### Property-based injection[#](/providers#property-based-injection)

The technique we've used so far is called constructor-based injection, where providers are injected through the constructor method. In certain specific cases, **property-based injection** can be useful. For example, if your top-level class depends on one or more providers, passing them all the way up through `super()` in sub-classes can become cumbersome. To avoid this, you can use the `@Inject()` decorator directly at the property level.

```typescript

import { Injectable, Inject } from '@nestjs/common';

@Injectable()
export class HttpService<T> {
  @Inject('HTTP_OPTIONS')
  private readonly httpClient: T;
}
```

> **Warning** If your class doesn't extend another class, it's generally better to use **constructor-based** injection. The constructor clearly specifies which dependencies are required, offering better visibility and making the code easier to understand compared to class properties annotated with `@Inject`.

#### Provider registration[#](/providers#provider-registration)

Now that we've defined a provider (`CatsService`) and a consumer (`CatsController`), we need to register the service with Nest so that it can handle the injection. This is done by editing the module file (`app.module.ts`) and adding the service to the `providers` array in the `@Module()` decorator.

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { CatsController } from './cats/cats.controller';
import { CatsService } from './cats/cats.service';

@Module({
  controllers: [CatsController],
  providers: [CatsService],
})
export class AppModule {}
```

Nest will now be able to resolve the dependencies of the `CatsController` class.

At this point, our directory structure should look like this:

So far, we've covered how Nest automatically handles most of the details of resolving dependencies. However, in some cases, you might need to step outside of the built-in Dependency Injection system and manually retrieve or instantiate providers. Two such techniques are briefly discussed below.

* To retrieve existing instances or instantiate providers dynamically, you can use the [Module reference](https://docs.nestjs.com/fundamentals/module-ref).
* To get providers within the `bootstrap()` function (e.g., for standalone applications or to use a configuration service during bootstrapping), check out [Standalone applications](https://docs.nestjs.com/standalone-applications).

----
url: https://docs.nestjs.com/v8/faq/serverless
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Serverless](https://docs.nestjs.com/v8/faq/serverless#serverless)
* [Cold start](https://docs.nestjs.com/v8/faq/serverless#cold-start)
* [Benchmarks](https://docs.nestjs.com/v8/faq/serverless#benchmarks)
* [Runtime optimizations](https://docs.nestjs.com/v8/faq/serverless#runtime-optimizations)
* [Example integration](https://docs.nestjs.com/v8/faq/serverless#example-integration)
* [Using standalone application feature](https://docs.nestjs.com/v8/faq/serverless#using-standalone-application-feature)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/faq/serverless.md "Suggest Edits")

### Serverless

Serverless computing is a cloud computing execution model in which the cloud provider allocates machine resources on-demand, taking care of the servers on behalf of their customers. When an app is not in use, there are no computing resources allocated to the app. Pricing is based on the actual amount of resources consumed by an application ([source](https://en.wikipedia.org/wiki/Serverless_computing)).

With a **serverless architecture**, you focus purely on the individual functions in your application code. Services such as AWS Lambda, Google Cloud Functions, and Microsoft Azure Functions take care of all the physical hardware, virtual machine operating system, and web server software management.

> **Hint** This chapter does not cover the pros and cons of serverless functions nor dives into the specifics of any cloud providers.

#### Cold start[#](/faq/serverless#cold-start)

A cold start is the first time your code has been executed in a while. Depending on a cloud provider you use, it may span several different operations, from downloading the code and bootstrapping the runtime to eventually running your code. This process adds **significant latency** depending on several factors, the language, the number of packages your application require, etc.

The cold start is important and although there are things which are beyond our control, there's still a lot of things we can do on our side to make it as short as possible.

While you can think of Nest as a fully-fledged framework designed to be used in complex, enterprise applications, it is also **suitable for much "simpler" applications** (or scripts). For example, with the use of [Standalone applications](/v8/standalone-applications) feature, you can take advantage of Nest's DI system in simple workers, CRON jobs, CLIs, or serverless functions.

#### Benchmarks[#](/faq/serverless#benchmarks)

To better understand what's the cost of using Nest or other, well-known libraries (like `express`) in the context of serverless functions, let's compare how much time Node runtime needs to run the following scripts:

```typescript

// #1 Express
import * as express from 'express';

async function bootstrap() {
  const app = express();
  app.get('/', (req, res) => res.send('Hello world!'));
  await new Promise<void>((resolve) => app.listen(3000, resolve));
}
bootstrap();

// #2 Nest (with @nestjs/platform-express)
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule, { logger: ['error'] });
  await app.listen(3000);
}
bootstrap();

// #3 Nest as a Standalone application (no HTTP server)
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { AppService } from './app.service';

async function bootstrap() {
  const app = await NestFactory.createApplicationContext(AppModule, {
    logger: ['error'],
  });
  console.log(app.get(AppService).getHello());
}
bootstrap();

// #4 Raw Node.js script
async function bootstrap() {
  console.log('Hello world!');
}
bootstrap();
```

For all these scripts, we used the `tsc` (TypeScript) compiler and so the code remains unbundled (`webpack` isn't used).

| Express                              | 0.0079s (7.9ms)   |
| ------------------------------------ | ----------------- |
| Nest with `@nestjs/platform-express` | 0.1974s (197.4ms) |
| Nest (standalone application)        | 0.1117s (111.7ms) |
| Raw Node.js script                   | 0.0071s (7.1ms)   |

> **Note** Machine: MacBook Pro Mid 2014, 2.5 GHz Quad-Core Intel Core i7, 16 GB 1600 MHz DDR3, SSD.

Now, let's repeat all benchmarks but this time, using `webpack` (if you have [Nest CLI](/v8/cli/overview) installed, you can run `nest build --webpack`) to bundle our application into a single executable JavaScript file. However, instead of using the default `webpack` configuration that Nest CLI ships with, we'll make sure to bundle all dependencies (`node_modules`) together, as follows:

```javascript

module.exports = (options, webpack) => {
  const lazyImports = [
    '@nestjs/microservices/microservices-module',
    '@nestjs/websockets/socket-module',
  ];

  return {
    ...options,
    externals: [],
    plugins: [
      ...options.plugins,
      new webpack.IgnorePlugin({
        checkResource(resource) {
          if (lazyImports.includes(resource)) {
            try {
              require.resolve(resource);
            } catch (err) {
              return true;
            }
          }
          return false;
        },
      }),
    ],
  };
};
```

> **Hint** To instruct Nest CLI to use this configuration, create a new `webpack.config.js` file in the root directory of your project.

With this configuration, we received the following results:

| Express                              | 0.0068s (6.8ms)  |
| ------------------------------------ | ---------------- |
| Nest with `@nestjs/platform-express` | 0.0815s (81.5ms) |
| Nest (standalone application)        | 0.0319s (31.9ms) |
| Raw Node.js script                   | 0.0066s (6.6ms)  |

> **Note** Machine: MacBook Pro Mid 2014, 2.5 GHz Quad-Core Intel Core i7, 16 GB 1600 MHz DDR3, SSD.

> **Hint** You could optimize it even further by applying additional code minification & optimization techniques (using `webpack` plugins, etc.).

As you can see, the way you compile (and whether you bundle your code) is crucial and has a significant impact on the overall startup time. With `webpack`, you can get the bootstrap time of a standalone Nest application (starter project with one module, controller, and service) down to \~32ms on average, and down to \~81.5ms for a regular HTTP, express-based NestJS app.

For more complicated Nest applications, for example, with 10 resources (generated through `$ nest g resource` schematic = 10 modules, 10 controllers, 10 services, 20 DTO classes, 50 HTTP endpoints + `AppModule`), the overall startup on MacBook Pro Mid 2014, 2.5 GHz Quad-Core Intel Core i7, 16 GB 1600 MHz DDR3, SSD is approximately 0.1298s (129.8ms). Running a monolithic application as a serverless function typically doesn't make too much sense anyway, so think of this benchmark more as an example of how the bootstrap time may potentially increase as your application grows.

#### Runtime optimizations[#](/faq/serverless#runtime-optimizations)

Thus far we covered compile-time optimizations. These are unrelated to the way you define providers and load Nest modules in your application, and that plays an essential role as your application gets bigger.

For example, imagine having a database connection defined as an [asynchronous provider](/v8/fundamentals/async-providers). Async providers are designed to delay the application start until one or more asynchronous tasks are completed. That means, if your serverless function on average requires 2s to connect to the database (on bootstrap), your endpoint will need at least two extra seconds (because it must wait till the connection is established) to send a response back (when it's a cold start and your application wasn't running already).

As you can see, the way you structure your providers is somewhat different in a **serverless environment** where bootstrap time is important. Another good example is if you use Redis for caching, but only in certain scenarios. Perhaps, in this case, you should not define a Redis connection as an async provider, as it would slow down the bootstrap time, even if it's not required for this specific function invocation.

Also, sometimes you could lazy-load entire modules, using the `LazyModuleLoader` class, as described in [this chapter](/v8/fundamentals/lazy-loading-modules). Caching is a great example here too. Imagine that your application has, let's say, `CacheModule` which internally connects to Redis and also, exports the `CacheService` to interact with the Redis storage. If you don't need it for all potential function invocations, you can just load it on-demand, lazily. This way you'll get a faster startup time (when a cold start occurs) for all invocations that don't require caching.

```typescript

if (request.method === RequestMethod[RequestMethod.GET]) {
  const { CacheModule } = await import('./cache.module');
  const moduleRef = await this.lazyModuleLoader.load(() => CacheModule);

  const { CacheService } = await import('./cache.service');
  const cacheService = moduleRef.get(CacheService);

  return cacheService.get(ENDPOINT_KEY);
}
```

Another great example is a webhook or worker, which depending on some specific conditions (e.g., input arguments), may perform different operations. In such a case, you could specify a condition inside your route handler that lazily loads an appropriate module for the specific function invocation, and just load every other module lazily.

```typescript

if (workerType === WorkerType.A) {
  const { WorkerAModule } = await import('./worker-a.module');
  const moduleRef = await this.lazyModuleLoader.load(() => WorkerAModule);
  // ...
} else if (workerType === WorkerType.B) {
  const { WorkerBModule } = await import('./worker-b.module');
  const moduleRef = await this.lazyModuleLoader.load(() => WorkerBModule);
  // ...
}
```

#### Example integration[#](/faq/serverless#example-integration)

The way your application's entry file (typically `main.ts` file) is supposed to look like **depends on several factors** and so **there's no single template** that just works for every scenario. For example, the initialization file required to spin up your serverless function varies by cloud providers (AWS, Azure, GCP, etc.). Also, depending on whether you want to run a typical HTTP application with multiple routes/endpoints or just provide a single route (or execute a specific portion of code), your application's code will look different (for example, for the endpoint-per-function approach you could use the `NestFactory.createApplicationContext` instead of booting the HTTP server, setting up middleware, etc.).

Just for illustration purposes, we'll integrate Nest (using `@nestjs/platform-express` and so spinning up the whole, fully functional HTTP router) with the [Serverless](https://www.serverless.com/) framework (in this case, targetting AWS Lambda). As we've mentioned earlier, your code will differ depending on the cloud provider you choose, and many other factors.

First, let's install the required packages:

```bash

$ npm i @vendia/serverless-express aws-lambda
$ npm i -D @types/aws-lambda serverless-offline
```

> **Hint** To speed up development cycles, we install the `serverless-offline` plugin which emulates AWS λ and API Gateway.

Once the installation process is complete, let's create the `serverless.yml` file to configure the Serverless framework:

```yaml

service: serverless-example

plugins:
  - serverless-offline

provider:
  name: aws
  runtime: nodejs14.x

functions:
  main:
    handler: dist/main.handler
    events:
      - http:
          method: ANY
          path: /
      - http:
          method: ANY
          path: '{proxy+}'
```

> **Hint** To learn more about the Serverless framework, visit the [official documentation](https://www.serverless.com/framework/docs/).

With this place, we can now navigate to the `main.ts` file and update our bootstrap code with the required boilerplate:

```typescript

import { NestFactory } from '@nestjs/core';
import serverlessExpress from '@vendia/serverless-express';
import { Callback, Context, Handler } from 'aws-lambda';
import { AppModule } from './app.module';

let server: Handler;

async function bootstrap(): Promise<Handler> {
  const app = await NestFactory.create(AppModule);
  await app.init();

  const expressApp = app.getHttpAdapter().getInstance();
  return serverlessExpress({ app: expressApp });
}

export const handler: Handler = async (
  event: any,
  context: Context,
  callback: Callback,
) => {
  server = server ?? (await bootstrap());
  return server(event, context, callback);
};
```

> **Hint** For creating multiple serverless functions and sharing common modules between them, we recommend using the [CLI Monorepo mode](/cli/monorepo#monorepo-mode).

> **Warning** If you use `@nestjs/swagger` package, there are a few additional steps required to make it work properly in the context of serverless function. Check out this [article](https://javascript.plainenglish.io/serverless-nestjs-document-your-api-with-swagger-and-aws-api-gateway-64a53962e8a2) for more information.

Next, open up the `tsconfig.json` file and make sure to enable the `esModuleInterop` option to make the `@vendia/serverless-express` package load properly.

```json

{
  "compilerOptions": {
    ...
    "esModuleInterop": true
  }
}
```

Now we can build our application (with `nest build` or `tsc`) and use the `serverless` CLI to start our lambda function locally:

```bash

$ npm run build
$ npx serverless offline
```

Once the application is running, open your browser and navigate to `http://localhost:3000/dev/[ANY_ROUTE]` (where `[ANY_ROUTE]` is any endpoint registered in your application).

In the sections above, we've shown that using `webpack` and bundling your app can have significant impact on the overall bootstrap time. However, to make it work with our example, there are a few additional configurations you must add in your `webpack.config.js` file. Generally, to make sure our `handler` function will be picked up, we must change the `output.libraryTarget` property to `commonjs2`.

```javascript

return {
  ...options,
  externals: [],
  output: {
    ...options.output,
    libraryTarget: 'commonjs2',
  },
  // ... the rest of the configuration
};
```

With this in place, you can now use `$ nest build --webpack` to compile your function's code (and then `$ npx serverless offline` to test it).

It's also recommended (but **not required** as it will slow down your build process) to install the `terser-webpack-plugin` package and override its configuration to keep classnames intact when minifying your production build. Not doing so can result in incorrect behavior when using `class-validator` within your application.

```javascript

const TerserPlugin = require('terser-webpack-plugin');

return {
  ...options,
  externals: [],
  optimization: {
    minimizer: [
      new TerserPlugin({
        terserOptions: {
          keep_classnames: true,
        },
      }),
    ],
  },
  output: {
    ...options.output,
    libraryTarget: 'commonjs2',
  },
  // ... the rest of the configuration
};
```

#### Using standalone application feature[#](/faq/serverless#using-standalone-application-feature)

Alternatively, if you want to keep your function very lightweight and you don't need any HTTP-related features (routing, but also guards, interceptors, pipes, etc.), you can just use `NestFactory.createApplicationContext` (as mentioned earlier) instead of running the entire HTTP server (and `express` under the hood), as follows:

main.ts

JS TS

```typescript

import { HttpStatus } from '@nestjs/common';
import { NestFactory } from '@nestjs/core';
import { Callback, Context, Handler } from 'aws-lambda';
import { AppModule } from './app.module';
import { AppService } from './app.service';

export const handler: Handler = async (
  event: any,
  context: Context,
  callback: Callback,
) => {
  const appContext = await NestFactory.createApplicationContext(AppModule);
  const appService = appContext.get(AppService);

  return {
    body: appService.getHello(),
    statusCode: HttpStatus.OK,
  };
};
```

> **Hint** Be aware that `NestFactory.createApplicationContext` does not wrap controller methods with enhancers (guard, interceptors, etc.). For this, you must use the `NestFactory.create` method.

You could also pass the `event` object down to, let's say, `EventsService` provider that could process it and return a corresponding value (depending on the input value and your business logic).

```typescript

export const handler: Handler = async (
  event: any,
  context: Context,
  callback: Callback,
) => {
  const appContext = await NestFactory.createApplicationContext(AppModule);
  const eventsService = appContext.get(EventsService);
  return eventsService.process(event);
};
```

----
url: https://docs.nestjs.com/v8/techniques/task-scheduling
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Task Scheduling](https://docs.nestjs.com/v8/techniques/task-scheduling#task-scheduling)
* [Installation](https://docs.nestjs.com/v8/techniques/task-scheduling#installation)
* [Declarative cron jobs](https://docs.nestjs.com/v8/techniques/task-scheduling#declarative-cron-jobs)
* [Declarative intervals](https://docs.nestjs.com/v8/techniques/task-scheduling#declarative-intervals)
* [Declarative timeouts](https://docs.nestjs.com/v8/techniques/task-scheduling#declarative-timeouts)
* [Dynamic schedule module API](https://docs.nestjs.com/v8/techniques/task-scheduling#dynamic-schedule-module-api)
* [Dynamic cron jobs](https://docs.nestjs.com/v8/techniques/task-scheduling#dynamic-cron-jobs)
* [Dynamic intervals](https://docs.nestjs.com/v8/techniques/task-scheduling#dynamic-intervals)
* [Dynamic timeouts](https://docs.nestjs.com/v8/techniques/task-scheduling#dynamic-timeouts)
* [Example](https://docs.nestjs.com/v8/techniques/task-scheduling#example)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/techniques/task-scheduling.md "Suggest Edits")

### Task Scheduling

Task scheduling allows you to schedule arbitrary code (methods/functions) to execute at a fixed date/time, at recurring intervals, or once after a specified interval. In the Linux world, this is often handled by packages like [cron](https://en.wikipedia.org/wiki/Cron) at the OS level. For Node.js apps, there are several packages that emulate cron-like functionality. Nest provides the `@nestjs/schedule` package, which integrates with the popular Node.js [node-cron](https://github.com/kelektiv/node-cron) package. We'll cover this package in the current chapter.

#### Installation[#](/techniques/task-scheduling#installation)

To begin using it, we first install the required dependencies.

```bash

$ npm install --save @nestjs/schedule
$ npm install --save-dev @types/cron
```

To activate job scheduling, import the `ScheduleModule` into the root `AppModule` and run the `forRoot()` static method as shown below:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { ScheduleModule } from '@nestjs/schedule';

@Module({
  imports: [
    ScheduleModule.forRoot()
  ],
})
export class AppModule {}
```

The `.forRoot()` call initializes the scheduler and registers any declarative [cron jobs](techniques/task-scheduling#declarative-cron-jobs), [timeouts](techniques/task-scheduling#declarative-timeouts) and [intervals](techniques/task-scheduling#declarative-intervals) that exist within your app. Registration occurs when the `onApplicationBootstrap` lifecycle hook occurs, ensuring that all modules have loaded and declared any scheduled jobs.

#### Declarative cron jobs[#](/techniques/task-scheduling#declarative-cron-jobs)

A cron job schedules an arbitrary function (method call) to run automatically. Cron jobs can run:

* Once, at a specified date/time.
* On a recurring basis; recurring jobs can run at a specified instant within a specified interval (for example, once per hour, once per week, once every 5 minutes)

Declare a cron job with the `@Cron()` decorator preceding the method definition containing the code to be executed, as follows:

```typescript

import { Injectable, Logger } from '@nestjs/common';
import { Cron } from '@nestjs/schedule';

@Injectable()
export class TasksService {
  private readonly logger = new Logger(TasksService.name);

  @Cron('45 * * * * *')
  handleCron() {
    this.logger.debug('Called when the current second is 45');
  }
}
```

In this example, the `handleCron()` method will be called each time the current second is `45`. In other words, the method will be run once per minute, at the 45 second mark.

The `@Cron()` decorator supports all standard [cron patterns](http://crontab.org/):

* Asterisk (e.g. `*`)
* Ranges (e.g. `1-3,5`)
* Steps (e.g. `*/2`)

In the example above, we passed `45 * * * * *` to the decorator. The following key shows how each position in the cron pattern string is interpreted:

```javascript

* * * * * *
| | | | | |
| | | | | day of week
| | | | months
| | | day of month
| | hours
| minutes
seconds (optional)
```

Some sample cron patterns are:

|                     |                                             |
| ------------------- | ------------------------------------------- |
| `* * * * * *`       | every second                                |
| `45 * * * * *`      | every minute, on the 45th second            |
| `0 10 * * * *`      | every hour, at the start of the 10th minute |
| `0 */30 9-17 * * *` | every 30 minutes between 9am and 5pm        |
| `0 30 11 * * 1-5`   | Monday to Friday at 11:30am                 |

The `@nestjs/schedule` package provides a convenience enum with commonly used cron patterns. You can use this enum as follows:

```typescript

import { Injectable, Logger } from '@nestjs/common';
import { Cron, CronExpression } from '@nestjs/schedule';

@Injectable()
export class TasksService {
  private readonly logger = new Logger(TasksService.name);

  @Cron(CronExpression.EVERY_30_SECONDS)
  handleCron() {
    this.logger.debug('Called every 30 seconds');
  }
}
```

In this example, the `handleCron()` method will be called every `30` seconds.

Alternatively, you can supply a JavaScript `Date` object to the `@Cron()` decorator. Doing so causes the job to execute exactly once, at the specified date.

> **Hint** Use JavaScript date arithmetic to schedule jobs relative to the current date. For example, `@Cron(new Date(Date.now() + 10 * 1000))` to schedule a job to run 10 seconds after the app starts.

Also, you can supply additional options as the second parameter to the `@Cron()` decorator.

|             |                                                                                                                                                                                                                                                        |
| ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `name`      | Useful to access and control a cron job after it's been declared.                                                                                                                                                                                      |
| `timeZone`  | Specify the timezone for the execution. This will modify the actual time relative to your timezone. If the timezone is invalid, an error is thrown. You can check all timezones available at [Moment Timezone](http://momentjs.com/timezone/) website. |
| `utcOffset` | This allows you to specify the offset of your timezone rather than using the `timeZone` param.                                                                                                                                                         |

```typescript

import { Injectable } from '@nestjs/common';
import { Cron, CronExpression } from '@nestjs/schedule';

@Injectable()
export class NotificationService {
  @Cron('* * 0 * * *', {
    name: 'notifications',
    timeZone: 'Europe/Paris',
  })
  triggerNotifications() {}
}
```

You can access and control a cron job after it's been declared, or dynamically create a cron job (where its cron pattern is defined at runtime) with the [Dynamic API](/techniques/task-scheduling#dynamic-schedule-module-api). To access a declarative cron job via the API, you must associate the job with a name by passing the `name` property in an optional options object as the second argument of the decorator.

#### Declarative intervals[#](/techniques/task-scheduling#declarative-intervals)

To declare that a method should run at a (recurring) specified interval, prefix the method definition with the `@Interval()` decorator. Pass the interval value, as a number in milliseconds, to the decorator as shown below:

```typescript

@Interval(10000)
handleInterval() {
  this.logger.debug('Called every 10 seconds');
}
```

> **Hint** This mechanism uses the JavaScript `setInterval()` function under the hood. You can also utilize a cron job to schedule recurring jobs.

If you want to control your declarative interval from outside the declaring class via the [Dynamic API](/techniques/task-scheduling#dynamic-schedule-module-api), associate the interval with a name using the following construction:

```typescript

@Interval('notifications', 2500)
handleInterval() {}
```

```typescript

@Timeout(5000)
handleTimeout() {
  this.logger.debug('Called once after 5 seconds');
}
```

> **Hint** This mechanism uses the JavaScript `setTimeout()` function under the hood.

If you want to control your declarative timeout from outside the declaring class via the [Dynamic API](/techniques/task-scheduling#dynamic-schedule-module-api), associate the timeout with a name using the following construction:

```typescript

@Timeout('notifications', 2500)
handleTimeout() {}
```

The [Dynamic API](techniques/task-scheduling#dynamic-timeouts) also enables **creating** dynamic timeouts, where the timeout's properties are defined at runtime, and **listing and deleting** them.

#### Dynamic schedule module API[#](/techniques/task-scheduling#dynamic-schedule-module-api)

The `@nestjs/schedule` module provides a dynamic API that enables managing declarative [cron jobs](techniques/task-scheduling#declarative-cron-jobs), [timeouts](techniques/task-scheduling#declarative-timeouts) and [intervals](techniques/task-scheduling#declarative-intervals). The API also enables creating and managing **dynamic** cron jobs, timeouts and intervals, where the properties are defined at runtime.

#### Dynamic cron jobs[#](/techniques/task-scheduling#dynamic-cron-jobs)

Obtain a reference to a `CronJob` instance by name from anywhere in your code using the `SchedulerRegistry` API. First, inject `SchedulerRegistry` using standard constructor injection:

```typescript

constructor(private schedulerRegistry: SchedulerRegistry) {}
```

> **Hint** Import the `SchedulerRegistry` from the `@nestjs/schedule` package.

Then use it in a class as follows. Assume a cron job was created with the following declaration:

```typescript

@Cron('* * 8 * * *', {
  name: 'notifications',
})
triggerNotifications() {}
```

Access this job using the following:

```typescript

const job = this.schedulerRegistry.getCronJob('notifications');

job.stop();
console.log(job.lastDate());
```

The `getCronJob()` method returns the named cron job. The returned `CronJob` object has the following methods:

* `stop()` - stops a job that is scheduled to run.
* `start()` - restarts a job that has been stopped.
* `setTime(time: CronTime)` - stops a job, sets a new time for it, and then starts it
* `lastDate()` - returns a string representation of the last date a job executed
* `nextDates(count: number)` - returns an array (size `count`) of `moment` objects representing upcoming job execution dates.

> **Hint** Use `toDate()` on `moment` objects to render them in human readable form.

**Create** a new cron job dynamically using the `SchedulerRegistry.addCronJob()` method, as follows:

```typescript

addCronJob(name: string, seconds: string) {
  const job = new CronJob(`${seconds} * * * * *`, () => {
    this.logger.warn(`time (${seconds}) for job ${name} to run!`);
  });

  this.schedulerRegistry.addCronJob(name, job);
  job.start();

  this.logger.warn(
    `job ${name} added for each minute at ${seconds} seconds!`,
  );
}
```

In this code, we use the `CronJob` object from the `cron` package to create the cron job. The `CronJob` constructor takes a cron pattern (just like the `@Cron()`[decorator](techniques/task-scheduling#declarative-cron-jobs)) as its first argument, and a callback to be executed when the cron timer fires as its second argument. The `SchedulerRegistry.addCronJob()` method takes two arguments: a name for the `CronJob`, and the `CronJob` object itself.

> **Warning** Remember to inject the `SchedulerRegistry` before accessing it. Import `CronJob` from the `cron` package.

**Delete** a named cron job using the `SchedulerRegistry.deleteCronJob()` method, as follows:

```typescript

deleteCron(name: string) {
  this.schedulerRegistry.deleteCronJob(name);
  this.logger.warn(`job ${name} deleted!`);
}
```

**List** all cron jobs using the `SchedulerRegistry.getCronJobs()` method as follows:

```typescript

getCrons() {
  const jobs = this.schedulerRegistry.getCronJobs();
  jobs.forEach((value, key, map) => {
    let next;
    try {
      next = value.nextDates().toDate();
    } catch (e) {
      next = 'error: next fire date is in the past!';
    }
    this.logger.log(`job: ${key} -> next: ${next}`);
  });
}
```

The `getCronJobs()` method returns a `map`. In this code, we iterate over the map and attempt to access the `nextDates()` method of each `CronJob`. In the `CronJob` API, if a job has already fired and has no future firing dates, it throws an exception.

#### Dynamic intervals[#](/techniques/task-scheduling#dynamic-intervals)

Obtain a reference to an interval with the `SchedulerRegistry.getInterval()` method. As above, inject `SchedulerRegistry` using standard constructor injection:

```typescript

constructor(private schedulerRegistry: SchedulerRegistry) {}
```

And use it as follows:

```typescript

const interval = this.schedulerRegistry.getInterval('notifications');
clearInterval(interval);
```

**Create** a new interval dynamically using the `SchedulerRegistry.addInterval()` method, as follows:

```typescript

addInterval(name: string, milliseconds: number) {
  const callback = () => {
    this.logger.warn(`Interval ${name} executing at time (${milliseconds})!`);
  };

  const interval = setInterval(callback, milliseconds);
  this.schedulerRegistry.addInterval(name, interval);
}
```

In this code, we create a standard JavaScript interval, then pass it to the `ScheduleRegistry.addInterval()` method. That method takes two arguments: a name for the interval, and the interval itself.

**Delete** a named interval using the `SchedulerRegistry.deleteInterval()` method, as follows:

```typescript

deleteInterval(name: string) {
  this.schedulerRegistry.deleteInterval(name);
  this.logger.warn(`Interval ${name} deleted!`);
}
```

**List** all intervals using the `SchedulerRegistry.getIntervals()` method as follows:

```typescript

getIntervals() {
  const intervals = this.schedulerRegistry.getIntervals();
  intervals.forEach(key => this.logger.log(`Interval: ${key}`));
}
```

#### Dynamic timeouts[#](/techniques/task-scheduling#dynamic-timeouts)

Obtain a reference to a timeout with the `SchedulerRegistry.getTimeout()` method. As above, inject `SchedulerRegistry` using standard constructor injection:

```typescript

constructor(private schedulerRegistry: SchedulerRegistry) {}
```

And use it as follows:

```typescript

const timeout = this.schedulerRegistry.getTimeout('notifications');
clearTimeout(timeout);
```

**Create** a new timeout dynamically using the `SchedulerRegistry.addTimeout()` method, as follows:

```typescript

addTimeout(name: string, milliseconds: number) {
  const callback = () => {
    this.logger.warn(`Timeout ${name} executing after (${milliseconds})!`);
  };

  const timeout = setTimeout(callback, milliseconds);
  this.schedulerRegistry.addTimeout(name, timeout);
}
```

In this code, we create a standard JavaScript timeout, then pass it to the `ScheduleRegistry.addTimeout()` method. That method takes two arguments: a name for the timeout, and the timeout itself.

**Delete** a named timeout using the `SchedulerRegistry.deleteTimeout()` method, as follows:

```typescript

deleteTimeout(name: string) {
  this.schedulerRegistry.deleteTimeout(name);
  this.logger.warn(`Timeout ${name} deleted!`);
}
```

**List** all timeouts using the `SchedulerRegistry.getTimeouts()` method as follows:

```typescript

getTimeouts() {
  const timeouts = this.schedulerRegistry.getTimeouts();
  timeouts.forEach(key => this.logger.log(`Timeout: ${key}`));
}
```

#### Example[#](/techniques/task-scheduling#example)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/27-scheduling).

----
url: https://docs.nestjs.com/observability/opentelemetry
----

[Skip to content](#content)

On this page

* [OpenTelemetry](https://docs.nestjs.com/observability/opentelemetry#opentelemetry)
* [Why we recommend NestJS Observe](https://docs.nestjs.com/observability/opentelemetry#why-we-recommend-nestjs-observe)
* [Zero-code setup](https://docs.nestjs.com/observability/opentelemetry#zero-code-setup)
* [Configuring the SDK in code](https://docs.nestjs.com/observability/opentelemetry#configuring-the-sdk-in-code)
* [What gets recorded for Nest](https://docs.nestjs.com/observability/opentelemetry#what-gets-recorded-for-nest)
* [Adding your own spans](https://docs.nestjs.com/observability/opentelemetry#adding-your-own-spans)

### OpenTelemetry

[OpenTelemetry](https://opentelemetry.io/ "OpenTelemetry") is the vendor-neutral standard for traces, metrics, and logs. You instrument an application once, send the data to any compatible backend - Jaeger, Grafana Tempo, or one of the many vendors that accept the OpenTelemetry protocol (OTLP) - and change backends later without touching application code.

For a NestJS backend, we recommend [NestJS Observe](/observability/overview) instead. This page explains why, and when OpenTelemetry is still the better choice. If OpenTelemetry is what you need, the [setup](/observability/opentelemetry#zero-code-setup) follows below.

#### Why we recommend NestJS Observe[#](/observability/opentelemetry#why-we-recommend-nestjs-observe)

OpenTelemetry instruments a Node.js application from the outside: it patches the HTTP server, the router, and the database driver as they load. It has no way to see the structure Nest builds in between, so a trace reads in the vocabulary of libraries. A slow `POST /orders` in an OpenTelemetry backend looks roughly like this on NestJS 11 (on NestJS 12, the two Nest spans are missing too):

```bash

POST /orders                          1,812 ms
  OrdersController.create             1,806 ms
    create                            1,806 ms
      pg.query SELECT customers          11 ms
      POST api.stripe.com             1,747 ms
```

NestJS Observe instruments the framework from the inside. Nest hands it every provider it creates, through the `instrument` option of `NestFactory.create()`, so every method call on a controller, service, repository, guard, interceptor, or pipe becomes a span named the way you named it. The same request in Observe:

```bash

POST /orders                          1,812 ms
  AuthGuard.canActivate                   3 ms
  OrdersController.create             1,806 ms   self 1 ms
    OrdersService.create              1,805 ms   self 6 ms
      CustomersService.findById          12 ms
        SELECT customers                 11 ms
      PricingService.quote               38 ms
      PaymentsService.charge          1,749 ms
        POST api.stripe.com           1,747 ms
```

Nobody wrote a span for `PricingService.quote`, and nobody had to guess in advance that it might matter. Because the tree is complete, Observe can compute the time each method spent on its own (self time) instead of leaving it to guesswork. With OpenTelemetry, getting the same tree means adding a span by hand to every method you care about - code that has to be written, kept up to date, and only ever covers what someone already suspected (see [Adding your own spans](/observability/opentelemetry#adding-your-own-spans)).

The difference continues past the request:

* **Nothing to run.** An OpenTelemetry pipeline is an SDK, an exporter, usually a collector, and a backend to store, query, and alert on the data. Observe is one command, `npx @nestjs/observe link`, which installs the SDK, wires it into your application, and writes the API key into `.env`. There is no collector and no backend to operate.
* **Nest's building blocks, recorded as what they are.** Queue consumers, `@Cron()` handlers, GraphQL resolvers, microservice handlers, and WebSocket gateways are each recorded as their own kind of operation, and a BullMQ or Bull job shares a trace with the request that enqueued it.
* **Kept in step with the framework.** Observe is built and maintained by the Nest team, alongside Nest itself. OpenTelemetry's Nest instrumentation, by contrast, doesn't support NestJS 12 yet (see [What gets recorded for Nest](/observability/opentelemetry#what-gets-recorded-for-nest)).
* **More than traces.** Error monitoring with source context, queue wait times and retries, a per-class breakdown of where time goes, runtime profiling, and releases come with the same SDK, on every plan, free tier included.

Observe is narrower than OpenTelemetry on purpose, and the trade-offs are real:

* It's NestJS on Node.js only. A service written in another language in the same request path doesn't appear in the trace, and services are correlated through the `x-request-id` header (see [Distributed tracing](/observability/distributed-tracing)), not the W3C `traceparent` header that OpenTelemetry propagates.
* It's a hosted service, and it doesn't export or ingest OTLP today. Its traces can't be sent to an OpenTelemetry backend, and spans from an OpenTelemetry SDK don't appear in Observe.
* Its library coverage is narrower. Redis and Kafka client calls, for example, aren't recorded as spans.

So choose OpenTelemetry when vendor neutrality, keeping telemetry on your own infrastructure, or one trace across services written in several languages is a hard requirement. For everything else on a NestJS backend - and especially if you have no tracing today because nobody had the week to build a pipeline - start with [NestJS Observe](/observability/overview).

The two can be installed in the same application, but both hook the database drivers, so try the combination in a staging environment first. They don't share a trace. For a longer discussion of this trade-off, see [NestJS and OpenTelemetry: why we instrument the framework instead](https://dev.to/nestjs/nestjs-and-opentelemetry-why-we-instrument-the-framework-instead-50i6).

#### Zero-code setup[#](/observability/opentelemetry#zero-code-setup)

> **Hint** Much of OpenTelemetry's Node.js documentation assumes the compiled application runs as CommonJS. Applications generated by `nest new` on Nest 12 are ES modules, which need an extra loader flag. Both variants are shown below.

The quickest way to get traces out of a Nest application is OpenTelemetry's zero-code instrumentation. Install the API and the auto-instrumentations bundle:

```bash

$ npm i --save @opentelemetry/api @opentelemetry/auto-instrumentations-node
```

The instrumentation has to be loaded before Nest and the libraries it patches, so it goes on the `node` command line rather than into `main.ts`. For a CommonJS build:

```bash

$ OTEL_SERVICE_NAME=orders-api \
  OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318 \
  node --require @opentelemetry/auto-instrumentations-node/register dist/main.js
```

For an ES module build, OpenTelemetry's loader hook is required as well:

```bash

$ OTEL_SERVICE_NAME=orders-api \
  OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318 \
  node --experimental-loader=@opentelemetry/instrumentation/hook.mjs \
  --import @opentelemetry/auto-instrumentations-node/register dist/main.js
```

If your platform starts the process for you and you can't change the command, put the same flags in the `NODE_OPTIONS` environment variable.

Spans are sent over OTLP to the endpoint you configure. To look at them locally, Jaeger runs in a single container and accepts OTLP on port 4318:

```bash

$ docker run --rm -p 16686:16686 -p 4318:4318 jaegertracing/jaeger
```

Open `http://localhost:16686`, send a request to your application, and the trace appears under the service name you set.

#### Configuring the SDK in code[#](/observability/opentelemetry#configuring-the-sdk-in-code)

To choose the exporter, sampler, or instrumentations yourself, start the SDK from a file of your own instead of the `register` entry point:

```bash

$ npm i --save @opentelemetry/api @opentelemetry/sdk-node @opentelemetry/auto-instrumentations-node @opentelemetry/exporter-trace-otlp-http
```

instrumentation.ts

JS TS

```typescript

import { NodeSDK } from '@opentelemetry/sdk-node';
import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node';
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';

export const otelSdk = new NodeSDK({
  serviceName: 'orders-api',
  traceExporter: new OTLPTraceExporter(),
  instrumentations: [getNodeAutoInstrumentations()],
});

otelSdk.start();
```

`OTLPTraceExporter` reads its endpoint from `OTEL_EXPORTER_OTLP_ENDPOINT` and defaults to `http://localhost:4318`. Load the file before anything else, the same way as the zero-code entry point:

```bash

# CommonJS
$ node --require ./dist/instrumentation.js dist/main.js

# ES modules
$ node --experimental-loader=@opentelemetry/instrumentation/hook.mjs \
  --import ./dist/instrumentation.js dist/main.js
```

In a CommonJS build you can instead import the file on the very first line of `main.ts`, before `@nestjs/core` and your `AppModule`. In an ES module build that isn't enough, because the loader hook has to be registered on the command line.

The SDK exports spans in batches. To send the last batch when the application stops, call `otelSdk.shutdown()` once Nest has finished shutting down, for example from an `onApplicationShutdown()` hook with [shutdown hooks](/fundamentals/lifecycle-events#application-shutdown) enabled.

#### What gets recorded for Nest[#](/observability/opentelemetry#what-gets-recorded-for-nest)

The auto-instrumentations bundle records incoming and outgoing HTTP requests (including `fetch`), Express, and the common database drivers such as `pg`, `mysql2`, `mongodb`, and Mongoose. ORMs built on those drivers, such as TypeORM, MikroORM, and Drizzle, show up through the queries they run.

Nest itself is covered by `@opentelemetry/instrumentation-nestjs-core`, which is part of the bundle. It emits three kinds of span:

| Span name                       | Type              | What it covers                                 |
| ------------------------------- | ----------------- | ---------------------------------------------- |
| `Create Nest App`               | `app_creation`    | The `NestFactory.create()` call at startup     |
| `<ControllerName>.<memberName>` | `request_context` | The whole request, from Nest's point of view   |
| `<memberName>`                  | `handler`         | The controller method that handled the request |

> **Warning** At the time of writing, `@opentelemetry/instrumentation-nestjs-core` supports `@nestjs/core` versions below 12. On NestJS 12 the three spans above aren't recorded, and a trace contains the HTTP and database spans only. Check the package's supported versions for the release you install.

The spans stop at the controller. The providers it calls - services, repositories, and the guards, interceptors, and pipes around it - are not traced automatically, so the time spent in your own code shows up as one undivided span. On the Fastify adapter, route-level spans come from `@fastify/otel`, maintained by the Fastify team, which isn't part of the auto-instrumentations bundle.

#### Adding your own spans[#](/observability/opentelemetry#adding-your-own-spans)

To see inside your providers, create spans with the OpenTelemetry API. `startActiveSpan()` makes the new span the parent of everything that runs inside the callback, including database and HTTP spans:

pricing.service.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { SpanStatusCode, trace } from '@opentelemetry/api';

const tracer = trace.getTracer('orders-api');

@Injectable()
export class PricingService {
  async quote(cart: Cart) {
    return tracer.startActiveSpan('PricingService.quote', async (span) => {
      try {
        span.setAttribute('cart.items', cart.items.length);
        return await this.calculate(cart);
      } catch (error) {
        span.recordException(error as Error);
        span.setStatus({ code: SpanStatusCode.ERROR });
        throw error;
      } finally {
        span.end();
      }
    });
  }
}
```

Every span you start must be ended, including when the work fails, which is what the `finally` block is for. The API package is safe to import even when no SDK is running: without one, the calls do nothing.

This is the work NestJS Observe does for you: with its SDK installed, every provider method is already a span, and the manual API is only needed for code that isn't a provider method.

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/observability/opentelemetry.md)

----
url: https://docs.nestjs.com/application/i18n
----

[Skip to content](#content)

On this page

* [Internationalization](https://docs.nestjs.com/application/i18n#internationalization)
* [Installation](https://docs.nestjs.com/application/i18n#installation)
* [Add catalogs and register the module](https://docs.nestjs.com/application/i18n#add-catalogs-and-register-the-module)
* [Translate order confirmations](https://docs.nestjs.com/application/i18n#translate-order-confirmations)
* [Localize exceptions](https://docs.nestjs.com/application/i18n#localize-exceptions)
* [Localize validation messages](https://docs.nestjs.com/application/i18n#localize-validation-messages)
* [Localize GraphQL fields](https://docs.nestjs.com/application/i18n#localize-graphql-fields)
* [Format prices and dates](https://docs.nestjs.com/application/i18n#format-prices-and-dates)
* [Use the customer's saved language](https://docs.nestjs.com/application/i18n#use-the-customers-saved-language)
* [Microservices and WebSocket gateways](https://docs.nestjs.com/application/i18n#microservices-and-websocket-gateways)
* [Handle missing keys and reload catalogs](https://docs.nestjs.com/application/i18n#handle-missing-keys-and-reload-catalogs)
* [Use ICU message syntax](https://docs.nestjs.com/application/i18n#use-icu-message-syntax)
* [Try it](https://docs.nestjs.com/application/i18n#try-it)
* [Testing](https://docs.nestjs.com/application/i18n#testing)
* [Production checklist](https://docs.nestjs.com/application/i18n#production-checklist)
* [Reference](https://docs.nestjs.com/application/i18n#reference)

### Internationalization

An online store for cat food and supplies sells to customers in the United States, Poland and Germany, and its order API should answer each of them in their own language. In this tutorial, you'll translate order confirmations (with correct Polish plurals), error messages, validation messages (from `class-validator`, or from Zod) and GraphQL fields. You'll also format prices and dates for each locale.

The package resolves the locale once per request and keeps it in an `AsyncLocalStorage` store. Services, exceptions, pipes and GraphQL field resolvers translate without access to the request object, and every provider stays a singleton. It works the same on Express and Fastify, and for microservices and WebSocket gateways too.

#### Installation[#](/application/i18n#installation)

This tutorial extends the store's order API, which serves customers in English, Polish, and German. Orders are plain objects kept in memory. The example seeds order #1001: two bags of salmon kibble and three packs of clumping litter, $97.95 in total. It was placed on September 14, 2026 and has shipped since.

Install the package:

```bash

$ npm i --save @nestjs/i18n
```

The first section derives a type from a JSON file, so enable `resolveJsonModule` in your `tsconfig.json`.

#### Add catalogs and register the module[#](/application/i18n#add-catalogs-and-register-the-module)

Translations live in JSON files, one directory per locale. Each file becomes a namespace named after the file, so the `notFound` message in `orders.json` has the key `orders.notFound`.

```text

src
├── i18n
│   ├── de
│   │   ├── orders.json
│   │   └── validation.json
│   ├── en
│   │   ├── orders.json
│   │   └── validation.json
│   ├── pl
│   │   ├── orders.json
│   │   └── validation.json
│   └── translations.ts
├── orders
└── app.module.ts
```

Here's the English catalog for orders. Words in curly braces are placeholders, filled from the arguments you pass when translating. `items` is a plural message, which [Translate order confirmations](/application/i18n#translate-order-confirmations) explains.

src/i18n/en/orders.json

JS TS

```json

{
  "items": {
    "one": "{count} item",
    "other": "{count} items"
  },
  "confirmed": "Thank you! Order #{id} is confirmed: {items}.",
  "notFound": "Order #{id} was not found.",
  "invalidId": "The order number must be a whole number.",
  "unknownProduct": "Product {id} is not in our catalog.",
  "tooManyItems": {
    "one": "{path} must not exceed {count} item per product",
    "other": "{path} must not exceed {count} items per product"
  },
  "unsupportedCountry": "We only ship to the United States, Poland and Germany.",
  "status": {
    "pending": "Awaiting payment",
    "paid": "Paid",
    "shipped": "Shipped"
  }
}
```

The TypeScript compiler doesn't copy JSON files to `dist`. Add them to the [assets](/cli/monorepo#assets) in `nest-cli.json`:

```json

{
  "compilerOptions": {
    "assets": ["i18n/**/*.json"],
    "watchAssets": true
  }
}
```

Now register `I18nModule` in the root module:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import {
  AcceptLanguageLocaleResolver,
  HeaderLocaleResolver,
  I18nModule,
  JsonI18nLoader,
  QueryLocaleResolver,
} from '@nestjs/i18n';
import { join } from 'node:path';
import { OrdersModule } from './orders/orders.module.js';

@Module({
  imports: [
    I18nModule.forRoot({
      defaultLocale: 'en',
      supportedLocales: ['en', 'pl', 'de'],
      fallbacks: { 'de-AT': 'de' },
      loader: new JsonI18nLoader({
        path: join(import.meta.dirname, 'i18n'),
      }),
      resolvers: [
        new QueryLocaleResolver('lang'),
        new HeaderLocaleResolver('x-lang'),
        new AcceptLanguageLocaleResolver(),
      ],
    }),
    OrdersModule,
  ],
})
export class AppModule {}
```

The module is global, and it mounts a middleware on every route that resolves the locale before guards, interceptors, pipes and handlers run. Resolution works like this:

* **Resolvers run in order.** Each returns one or more candidates, and the first candidate that matches a supported locale wins. Here, `?lang=pl` beats an `x-lang` header, which beats `Accept-Language`.
* **`Accept-Language` is parsed properly.** Languages are ordered by their `q` values, and unsupported ones are skipped, so `fr-CH, fr;q=0.9, de;q=0.8` resolves to `de`.
* **Regions match their base language.**`pl-PL` resolves to `pl`. Nothing to configure.
* **`fallbacks` keeps a region as a locale of its own.**`de-AT` resolves to `de-AT`, and its messages come from `de`. The locale matters when [formatting prices and dates](/application/i18n#format-prices-and-dates): Austrian customers get Austrian number formatting. A region that isn't listed, such as `de-CH`, resolves to plain `de`.
* **Nothing matches, or there's no request at all** (a cron job, a queue consumer): the `defaultLocale` is used.

`CookieLocaleResolver` reads a cookie instead, `lang` by default, for a site that remembers the language a visitor picked. [Use the customer's saved language](/application/i18n#use-the-customers-saved-language) adds a resolver of your own.

Every response says which locale it was written in. The middleware sets `Content-Language` to the resolved locale and adds the headers the resolvers read to `Vary`, here `Vary: x-lang, Accept-Language`, so caches keep one copy per language. Set `responseHeaders: false` to turn this off.

`supportedLocales` is optional and defaults to the directories the loader finds. Pinning it means a stray directory never becomes a locale.

Finally, give your keys a type. The English catalog is the source of truth, and a type-only import reads its shape at compile time without loading the file. The `declare module` block registers that shape with the package:

i18n/translations.ts

JS TS

```typescript

import type orders from './en/orders.json';
import type validation from './en/validation.json';

export interface Translations {
  orders: typeof orders;
  validation: typeof validation;
}

declare module '@nestjs/i18n' {
  interface I18nTypes {
    translations: Translations;
  }
}
```

From now on, `I18nService` and the helper functions you'll use to localize exceptions and validation messages, `t()`, `i18nValidationMessage()` and `i18nIssueMessage()`, accept only keys that exist in the English catalog. A typo such as `orders.notFund` fails to compile, and so does `orders.status`, because it's a namespace and not a message. A provider that translates from catalogs of another shape, such as a library's, injects `I18nService<OtherTranslations>`, which checks keys against `OtherTranslations` instead.

#### Translate order confirmations[#](/application/i18n#translate-order-confirmations)

When a customer places an order, the API confirms it with a message that includes the number of items. Inject `I18nService` into `OrdersService` and call `t()`:

orders/orders.service.ts

JS TS

```typescript

@Injectable()
export class OrdersService {
  // ...
  constructor(private readonly i18nService: I18nService) {}

  create(userId: number, dto: CreateOrderDto) {
    const order: Order = {
      id: this.nextId++,
      userId,
      items: dto.items,
      total: this.priceOf(dto.items),
      status: 'pending',
      createdAt: new Date(),
    };
    this.orders.push(order);

    return {
      id: order.id,
      message: this.i18nService.t('orders.confirmed', {
        args: { id: order.id, items: this.describeItems(order) },
      }),
    };
  }

  describeItems(order: Order): string {
    const count = order.items.reduce((sum, item) => sum + item.quantity, 0);
    return this.i18nService.t('orders.items', { args: { count } });
  }
  // ...
}
```

You don't pass a locale to `t()`. It reads the one resolved for the current request, even though `OrdersService` is a singleton that never sees the request. Set the `locale` option only to override it, for example when a background job emails a customer in the language saved on their profile. The option is matched the way a request locale is: `pl-PL` becomes `pl`, and a locale you don't support becomes the default locale, so an outdated profile value can't break the job.

The controller has nothing locale-specific in it:

orders/orders.controller.ts

JS TS

```typescript

@Controller('orders')
export class OrdersController {
  constructor(private readonly ordersService: OrdersService) {}

  @Post()
  create(@Body() dto: CreateOrderDto) {
    // The Authentication tutorial replaces the fixed customer with the signed-in user.
    return this.ordersService.create(1, dto);
  }
}
```

English and German have two plural forms. Polish has four, and which one a number takes depends on its last digits. A plural message is an object keyed by plural category:

src/i18n/pl/orders.json

JS TS

```json

{
  "items": {
    "one": "{count} produkt",
    "few": "{count} produkty",
    "many": "{count} produktów",
    "other": "{count} produktu"
  },
  "confirmed": "Dziękujemy! Zamówienie #{id} zostało przyjęte: {items}.",
  "notFound": "Nie znaleziono zamówienia #{id}.",
  "invalidId": "Numer zamówienia musi być liczbą całkowitą.",
  "unknownProduct": "Produktu {id} nie ma w naszym katalogu.",
  "tooManyItems": {
    "one": "{path}: można zamówić najwyżej {count} sztukę jednego produktu",
    "few": "{path}: można zamówić najwyżej {count} sztuki jednego produktu",
    "many": "{path}: można zamówić najwyżej {count} sztuk jednego produktu",
    "other": "{path}: można zamówić najwyżej {count} sztuki jednego produktu"
  },
  "unsupportedCountry": "Wysyłamy tylko do Stanów Zjednoczonych, Polski i Niemiec.",
  "status": {
    "pending": "Oczekuje na płatność",
    "paid": "Opłacone",
    "shipped": "Wysłane"
  }
}
```

When the arguments include a numeric `count`, the service picks the form with `Intl.PluralRules` for the message's locale. If a category is missing, `other` is used. The German file mirrors the English one, with `one` and `other` forms only.

| Items | English  | Polish      | German      |
| ----- | -------- | ----------- | ----------- |
| 1     | 1 item   | 1 produkt   | 1 Produkt   |
| 2     | 2 items  | 2 produkty  | 2 Produkte  |
| 5     | 5 items  | 5 produktów | 5 Produkte  |
| 22    | 22 items | 22 produkty | 22 Produkte |

The confirmation is composed from two messages: the plural phrase is translated first and then inserted into the sentence. Placeholders can't nest, so this is how you combine them.

A placeholder's name is made of letters, digits and underscores. A placeholder you pass no argument for stays in the text as written, and so does any other text in braces. To write a brace next to a name, double it: `{{id}}` prints `{id}`. For select, ordinals and exact matches, [use ICU message syntax](/application/i18n#use-icu-message-syntax).

> **Hint** Only the `count` argument selects a plural form, so name it `count` in every plural message you translate with `t()`. Thanks to the registered catalog type, `t()` doesn't compile without it for plural messages. Validation messages get a `count` automatically, as [Localize validation messages](/application/i18n#localize-validation-messages) shows.

#### Localize exceptions[#](/application/i18n#localize-exceptions)

A missing order should produce a 404 in the customer's language. Translate the message when you throw:

orders/orders.service.ts

JS TS

```typescript

findOne(id: number): Order {
  const order = this.orders.find((order) => order.id === id);
  if (!order) {
    throw new NotFoundException(this.i18nService.t('orders.notFound', { args: { id } }));
  }
  return order;
}
```

The exception carries the finished text, so there is nothing to configure: Nest's default exception filter, your own filters and GraphQL error formatting all receive the translated message. `GET /orders/999` with `x-lang: pl` returns:

```json

{
  "message": "Nie znaleziono zamówienia #999.",
  "error": "Not Found",
  "statusCode": 404
}
```

Code that has no `I18nService` at hand can use the `t()` function instead. It translates for the current request in the same way. Built-in pipes such as `ParseIntPipe` produce English messages, so give the pipe that parses order IDs an exception factory:

orders/orders.controller.ts

JS TS

```typescript

const orderIdPipe = new ParseIntPipe({
  exceptionFactory: () => new BadRequestException(t('orders.invalidId')),
});

@Controller('orders')
export class OrdersController {
  constructor(private readonly ordersService: OrdersService) {}
  // ...

  @Get(':id')
  findOne(@Param('id', orderIdPipe) id: number) {
    return this.ordersService.getSummary(id);
  }
}
```

The pipe is created once, outside dependency injection, and still answers each request in its own language. You'll write `getSummary()` in [Format prices and dates](/application/i18n#format-prices-and-dates).

If your API shapes errors with its own [exception filter](/exception-filters#binding-filters), for example as RFC 9457 problem details, the filter reads the translated message like any other:

common/problem-details.filter.ts

JS TS

```typescript

import {
  Catch,
  NotFoundException,
  type ArgumentsHost,
  type ExceptionFilter,
} from '@nestjs/common';
import { HttpAdapterHost } from '@nestjs/core';

@Catch(NotFoundException)
export class ProblemDetailsFilter implements ExceptionFilter {
  constructor(private readonly httpAdapterHost: HttpAdapterHost) {}

  catch(exception: NotFoundException, host: ArgumentsHost) {
    const { httpAdapter } = this.httpAdapterHost;
    const response = host.switchToHttp().getResponse();
    httpAdapter.setHeader(response, 'Content-Type', 'application/problem+json');
    httpAdapter.reply(
      response,
      { type: 'about:blank', title: 'Not Found', status: 404, detail: exception.message },
      404,
    );
  }
}
```

With the filter registered, the same request returns:

```json

{
  "type": "about:blank",
  "title": "Not Found",
  "status": 404,
  "detail": "Nie znaleziono zamówienia #999."
}
```

#### Localize validation messages[#](/application/i18n#localize-validation-messages)

This step assumes your application validates request bodies with `class-validator`; if it validates with Zod or another Standard Schema library, read on to [With Zod](/application/i18n#with-zod). `I18nValidationPipe` is a drop-in replacement for Nest's [`ValidationPipe`](/application/validation#using-the-built-in-validationpipe): it accepts the same options and only translates the messages. Bind it where `ValidationPipe` was, here as an `APP_PIPE` provider of `AppModule`:

app.module.ts

JS TS

```typescript

providers: [
  {
    provide: APP_PIPE,
    useValue: new I18nValidationPipe({ whitelist: true, transform: true }),
  },
],
```

Start with the DTO for new orders. It uses `class-validator` decorators without any messages:

orders/dto/create-order.dto.ts

JS TS

```typescript

import { i18nValidationMessage } from '@nestjs/i18n';
import { Type } from 'class-transformer';
import { ArrayNotEmpty, IsInt, IsString, Max, Min, ValidateNested } from 'class-validator';

export class OrderItemDto {
  @IsString()
  productId: string;

  @IsInt()
  @Min(1)
  @Max(10, { message: i18nValidationMessage('orders.tooManyItems') })
  quantity: number;
}

export class CreateOrderDto {
  @ArrayNotEmpty()
  @ValidateNested({ each: true })
  @Type(() => OrderItemDto)
  items: OrderItemDto[];
}
```

A constraint without a `message` is looked up in the `validation` namespace by constraint name: `@IsInt()` reads `validation.isInt`, and `@Min()` reads `validation.min`. `i18nValidationMessage()` points a single constraint at a key of your choice, here a store-specific message for the item limit. Messages you write as plain strings are left alone. A message can use these placeholders:

* `property`: the field name, such as `quantity`.
* `path`: the dotted path from the DTO, such as `items.1.quantity`. For a top-level field, it's the same as `property`.
* `value`: the rejected value, when it's a string, number or boolean.
* `constraint1`, `constraint2` and so on: the decorator's arguments. A list, such as the values `@IsIn()` accepts, reads `US, PL, DE`.
* `count`: the first numeric argument, so a plural message agrees with it. `@Max(10)` selects the form for 10.

The item limit is a plural message (see the Polish catalog in [Translate order confirmations](/application/i18n#translate-order-confirmations)), so `@Max(10)` reads "10 sztuk" in Polish. Here is the Polish `validation` catalog for the constraints this tutorial uses. `minLength` is a plural message too, so `@MinLength(2)` reads "2 znaki" and `@MinLength(5)` "5 znaków":

src/i18n/pl/validation.json

JS TS

```json

{
  "isInt": "{path} musi być liczbą całkowitą",
  "isString": "{path} musi być tekstem",
  "min": "{path} musi wynosić co najmniej {constraint1}",
  "arrayNotEmpty": "{path} musi zawierać co najmniej jeden element",
  "minLength": {
    "one": "{path} musi mieć co najmniej {count} znak",
    "few": "{path} musi mieć co najmniej {count} znaki",
    "many": "{path} musi mieć co najmniej {count} znaków",
    "other": "{path} musi mieć co najmniej {count} znaku"
  },
  "matches": "{path} ma nieprawidłowy format"
}
```

A constraint that has no translation keeps the `class-validator` message, so you can translate the constraints you use one at a time.

For nested objects, Nest's `ValidationPipe` puts the parent path in front of each message. `I18nValidationPipe` leaves translated messages as they are, so each message decides for itself: `path` gives `items.1.quantity`, and `property` gives just `quantity`. Messages without a translation keep the prefix.

Customers set a shipping address on an order. Its DTO relies on the `minLength` and `matches` entries of the catalog, and names a store-specific message for the country:

orders/dto/shipping-address.dto.ts

JS TS

```typescript

import { i18nValidationMessage } from '@nestjs/i18n';
import { IsIn, Matches, MinLength } from 'class-validator';

export class ShippingAddressDto {
  @MinLength(2)
  recipient: string;

  @MinLength(2)
  city: string;

  @Matches(/^[0-9-]{5,6}$/)
  postalCode: string;

  @IsIn(['US', 'PL', 'DE'], { message: i18nValidationMessage('orders.unsupportedCountry') })
  country: 'US' | 'PL' | 'DE';
}
```

orders/orders.controller.ts

JS TS

```typescript

@Put(':id/shipping-address')
updateShippingAddress(
  @Param('id', orderIdPipe) id: number,
  @Body() address: ShippingAddressDto,
) {
  return this.ordersService.updateShippingAddress(id, address);
}
```

A German customer who sends a one-letter recipient, a four-digit postal code and `AT` as the country gets three translated messages back. The [Try it](/application/i18n#try-it) section shows the response.

##### With Zod[#](/application/i18n#with-zod)

If your application validates with Zod, Valibot, ArkType or another [Standard Schema](https://standardschema.dev/) library, bind `I18nStandardSchemaValidationPipe` instead of `I18nValidationPipe`. It's the drop-in replacement for Nest's [`StandardSchemaValidationPipe`](/application/validation#schema-based-validation), and an application binds one of the two pipes, not both:

app.module.ts

JS TS

```typescript

providers: [{ provide: APP_PIPE, useValue: new I18nStandardSchemaValidationPipe() }],
```

Here are the same inputs as Zod schemas. Library messages are plain strings, so `i18nIssueMessage()` encodes a translation key in the message itself, which works with any Standard Schema library:

orders/orders.schemas.ts

JS TS

```typescript

import { i18nIssueMessage } from '@nestjs/i18n';
import { z } from 'zod';

export const orderItemSchema = z.object({
  productId: z.string(),
  quantity: z.number().int().min(1).max(10, i18nIssueMessage('orders.tooManyItems')),
});

export const createOrderSchema = z.object({
  items: z.array(orderItemSchema).nonempty(),
});
export type CreateOrderDto = z.infer<typeof createOrderSchema>;

export const shippingAddressSchema = z.object({
  recipient: z.string().min(2),
  city: z.string().min(2),
  postalCode: z.string().regex(/^[0-9-]{5,6}$/),
  country: z.enum(['US', 'PL', 'DE'], i18nIssueMessage('orders.unsupportedCountry')),
});
export type ShippingAddress = z.infer<typeof shippingAddressSchema>;
```

The body parameters declare their schema instead of a class:

orders/orders.controller.ts

JS TS

```typescript

import {
  createOrderSchema,
  shippingAddressSchema,
  type CreateOrderDto,
  type ShippingAddress,
} from './orders.schemas.js';
// ...
@Post()
create(@Body({ schema: createOrderSchema }) dto: CreateOrderDto) {
  // ...
}

@Put(':id/shipping-address')
updateShippingAddress(
  @Param('id', orderIdPipe) id: number,
  @Body({ schema: shippingAddressSchema }) address: ShippingAddress,
) {
  return this.ordersService.updateShippingAddress(id, address);
}
```

An issue without an explicit key is looked up by the code the library assigns, from the most specific key to the least:

* **Format first.** A failed regex reads `validation.invalid_format.regex`.
* **Then the origin.** Zod reports `too_small` for short strings, small numbers and short arrays alike, and says which in `origin`. A short string reads `validation.too_small.string`, so the catalog can talk about characters without getting numbers wrong.
* **Then the code alone**, such as `validation.too_small`.

Valibot's issue `type` works the same way. Messages can use the `property` and `path` placeholders as above, the library's own text as `message`, and the issue's parameters, such as `minimum` or `expected`. `count` holds the numeric `minimum` or `maximum`, so "2 znaki" and "5 znaków" both come out right, and so does `orders.tooManyItems` for `.max(10)`. Here is the Polish catalog again, with the issue-code entries in front of the constraint names:

src/i18n/pl/validation.json

JS TS

```json

{
  "invalid_type": "{path} musi być typu {expected}",
  "too_small": {
    "string": {
      "one": "{path} musi mieć co najmniej {count} znak",
      "few": "{path} musi mieć co najmniej {count} znaki",
      "many": "{path} musi mieć co najmniej {count} znaków",
      "other": "{path} musi mieć co najmniej {count} znaku"
    },
    "number": "{path} musi wynosić co najmniej {minimum}",
    "array": "{path} musi zawierać co najmniej jeden element"
  },
  "invalid_format": {
    "regex": "{path} ma nieprawidłowy format"
  },
  "isInt": "{path} musi być liczbą całkowitą",
  "isString": "{path} musi być tekstem",
  "min": "{path} musi wynosić co najmniej {constraint1}",
  "arrayNotEmpty": "{path} musi zawierać co najmniej jeden element",
  "minLength": {
    "one": "{path} musi mieć co najmniej {count} znak",
    "few": "{path} musi mieć co najmniej {count} znaki",
    "many": "{path} musi mieć co najmniej {count} znaków",
    "other": "{path} musi mieć co najmniej {count} znaku"
  },
  "matches": "{path} ma nieprawidłowy format"
}
```

With these entries, the invalid shipping address from the [Try it](/application/i18n#try-it) section gets the same three German messages as with the class, and the invalid order reads:

```json

{
  "message": [
    "items.0.quantity musi wynosić co najmniej 1",
    "items.1.productId musi być typu string",
    "items.1.quantity: można zamówić najwyżej 10 sztuk jednego produktu"
  ],
  "error": "Bad Request",
  "statusCode": 400
}
```

Issues without a translation keep Nest's usual format, the path followed by the library's message.

#### Localize GraphQL fields[#](/application/i18n#localize-graphql-fields)

This step applies to an application that serves GraphQL with `@nestjs/graphql`. The mobile app reads orders over GraphQL, through the Apollo driver and a [code first](/graphql/quick-start#code-first) schema registered in `AppModule`:

app.module.ts

JS TS

```typescript

GraphQLModule.forRoot<ApolloDriverConfig>({
  driver: ApolloDriver,
  autoSchemaFile: true,
}),
```

The object type exposes raw order data:

orders/order.model.ts

JS TS

```typescript

import { Field, Float, Int, ObjectType } from '@nestjs/graphql';

@ObjectType('Order')
export class OrderModel {
  @Field(() => Int)
  id: number;

  @Field()
  status: string;

  @Field(() => Float)
  total: number;
}
```

Localized fields are computed by field resolvers, with the same `I18nService` the REST controller uses:

orders/orders.resolver.ts

JS TS

```typescript

import { Args, Int, Parent, Query, ResolveField, Resolver } from '@nestjs/graphql';
import { I18nService } from '@nestjs/i18n';
import type { Order } from './order.entity.js';
import { OrderModel } from './order.model.js';
import { OrdersService } from './orders.service.js';

@Resolver(() => OrderModel)
export class OrdersResolver {
  constructor(
    private readonly ordersService: OrdersService,
    private readonly i18nService: I18nService,
  ) {}

  @Query(() => OrderModel)
  order(@Args('id', { type: () => Int }) id: number) {
    return this.ordersService.findOne(id);
  }

  @ResolveField(() => String)
  statusLabel(@Parent() order: Order) {
    return this.i18nService.t(`orders.status.${order.status}`);
  }

  @ResolveField(() => String)
  items(@Parent() order: Order) {
    return this.ordersService.describeItems(order);
  }
}
```

The `statusLabel` key is a template literal built from the `OrderStatus` union, so the compiler still checks that every status has a label.

On Express, Apollo is mounted after Nest's middleware, so the locale middleware from [Add catalogs and register the module](/application/i18n#add-catalogs-and-register-the-module) wraps every GraphQL operation. `?lang`, `x-lang` and `Accept-Language` work exactly as they do for REST, in resolvers, field resolvers and guards. The `NotFoundException` thrown by `findOne()` reaches the client translated, in `errors[0].message`.

> **Warning** The locale middleware doesn't wrap subscriptions, which run over WebSockets, or a GraphQL driver that is mounted outside it. That includes the common case of a [global prefix](/faq/global-prefix): Nest mounts the middleware under the prefix, while Apollo stays at `/graphql`, so set `useGlobalPrefix: true` on `GraphQLModule` when you use one. Where the middleware doesn't run, the package falls back to a global interceptor, which reads the locale from the request on the GraphQL context (for a subscription, the WebSocket handshake) and runs after guards. Field resolvers, including those of subscription events, are only covered if you set `fieldResolverEnhancers: ['interceptors']`, guards don't see the locale, and responses carry no `Content-Language`.

#### Format prices and dates[#](/application/i18n#format-prices-and-dates)

The order summary shows the status, the number of items, the total and the order date, formatted the way each customer expects:

orders/orders.service.ts

JS TS

```typescript

getSummary(id: number) {
  const order = this.findOne(id);
  return {
    id: order.id,
    status: this.i18nService.t(`orders.status.${order.status}`),
    items: this.describeItems(order),
    total: this.i18nService.formatNumber(order.total, { style: 'currency', currency: 'USD' }),
    placedAt: this.i18nService.formatDate(order.createdAt, {
      dateStyle: 'long',
      timeZone: 'UTC',
    }),
  };
}
```

`formatNumber()` and `formatDate()` wrap `Intl.NumberFormat` and `Intl.DateTimeFormat` with the request's locale. They take the usual `Intl` options, plus a `locale` option that overrides the current locale, as in `t()`. For order #1001:

| Locale  | `total`   | `placedAt`         |
| ------- | --------- | ------------------ |
| `en`    | $97.95    | September 14, 2026 |
| `pl`    | 97,95 USD | 14 września 2026   |
| `de`    | 97,95 $   | 14. September 2026 |
| `de-AT` | $ 97,95   | 14. September 2026 |

`de-AT` gets Austrian formatting because the module registration listed it in `fallbacks`. Its messages still come from the German catalog.

Two things the locale doesn't decide:

* **Currency.** The locale controls how an amount is written, not what it's worth. The store charges in US dollars, so every customer sees USD. Take the currency from the order or the store, never from the locale.
* **Time zone.** Without `timeZone`, dates are formatted in the server's time zone, which can shift the day. Pass the customer's time zone if you store one, or format in UTC as here.

#### Use the customer's saved language[#](/application/i18n#use-the-customers-saved-language)

Customers pick a language when they sign up, and the customer record keeps it in a `locale` field, like the `customers` table of the [mail chapter](/application/mail#send-it-in-the-customers-language). Here, `CustomersService` keeps customers in memory, as `OrdersService` keeps orders. For a signed-in customer, that choice should beat `Accept-Language`, which is only their browser's default. The guard of [`@nestjs/authentication`](/security/authentication), like a Passport guard, puts the signed-in user on `request.user`.

Resolvers run in the locale middleware, before guards, when nobody is signed in yet. A resolver that sets `afterGuards` runs after guards instead, and receives the `executionContext` of the call:

customers/customer-locale.resolver.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { LocaleResolver, type LocaleResolverInput } from '@nestjs/i18n';
import { CustomersService } from './customers.service.js';

@Injectable()
export class CustomerLocaleResolver extends LocaleResolver {
  // After guards, the authentication guard has put the signed-in user on the request
  readonly afterGuards = true;

  constructor(private readonly customersService: CustomersService) {
    super();
  }

  resolve({ executionContext }: LocaleResolverInput) {
    const request = executionContext?.switchToHttp().getRequest<{ user?: { id: number } }>();
    const user = request?.user;
    return user ? this.customersService.findOne(user.id)?.locale : undefined;
  }
}
```

Nest instantiates a resolver class, so it can inject providers. Put it into `resolvers` at the rank it should have, and import the module that provides what it injects:

app.module.ts

JS TS

```typescript

I18nModule.forRoot({
  // ...
  resolvers: [
    new QueryLocaleResolver('lang'),
    new HeaderLocaleResolver('x-lang'),
    CustomerLocaleResolver,
    new AcceptLanguageLocaleResolver(),
  ],
  imports: [CustomersModule],
  // ...
}),
```

The order of the resolvers still decides:

* **`?lang` and `x-lang` win.** They're a choice made for this request, by a language switcher link or an app setting. When one of them matches, the customer resolver doesn't run.
* **The saved language beats `Accept-Language`.** Zofia saved Polish, so she reads Polish in any browser. Lukas saved `de-AT`, which is matched like any candidate, so he gets Austrian formatting.
* **Anonymous customers, and customers without a supported saved language,** get what the resolvers below it find, here from `Accept-Language`.

Guards see the locale that the resolvers before guards found, and so does the response to an error a guard throws, such as a 401. The handler, and everything after it, sees the customer's. The resolver runs once per request, also for a GraphQL operation with several root fields. Over GraphQL, the request is at `GqlExecutionContext.create(executionContext).getContext().req`.

> **Hint** A response to a signed-in customer now depends on who asks. Such responses are usually private anyway, but if a shared cache stores them, list the header that identifies the customer, such as `Authorization`, in the resolver's `varyHeaders`, and the middleware adds it to `Vary`.

When customers change their language, answer them in the new one right away. `I18nContext.setLocale()` changes the locale for the rest of the request, `Content-Language` included:

customers/customers.controller.ts

JS TS

```typescript

@Controller('customers')
export class CustomersController {
  constructor(
    private readonly customersService: CustomersService,
    private readonly i18nContext: I18nContext,
    private readonly i18nService: I18nService,
  ) {}

  @Put('me/locale')
  updateLocale(@Req() request: { user: { id: number } }, @Body('locale') locale: string) {
    const supported = this.i18nContext.setLocale(locale);
    if (!supported) {
      throw new BadRequestException(this.i18nService.t('customers.unsupportedLocale'));
    }

    this.customersService.updateLocale(request.user.id, supported);
    return { locale: supported, message: this.i18nService.t('customers.localeUpdated') };
  }
}
```

`setLocale()` matches the locale the way resolution does and returns the match: `de-DE` becomes `de`. For a language the store doesn't write in, it returns `undefined` and leaves the locale as it was, so the error is in the language the customer is reading. The two messages live in a new `customers` catalog in each language, registered with `customers: typeof customers` in `Translations`:

src/i18n/de/customers.json

JS TS

```json

{
  "localeUpdated": "Erledigt! Ab jetzt schreiben wir Ihnen auf Deutsch.",
  "unsupportedLocale": "Wir schreiben nur auf Englisch, Polnisch und Deutsch."
}
```

#### Microservices and WebSocket gateways[#](/application/i18n#microservices-and-websocket-gateways)

Message handlers and WebSocket gateways don't pass through the HTTP middleware. There, the module resolves the locale in a global interceptor, with the same resolvers, so services, exceptions and the `t()` function work as they do for HTTP requests.

A message has no headers or query string, but resolvers receive the `executionContext`, so a resolver can read the locale a producer puts into the message itself. Add it to the `resolvers` of the microservice's `I18nModule`:

common/message-locale.resolver.ts

JS TS

```typescript

import { LocaleResolver, type LocaleResolverInput } from '@nestjs/i18n';

export class MessageLocaleResolver extends LocaleResolver {
  resolve({ executionContext }: LocaleResolverInput) {
    if (executionContext?.getType() !== 'rpc') {
      return undefined;
    }
    return executionContext.switchToRpc().getData<{ locale?: string }>()?.locale;
  }
}
```

A resolver can read a message's transport metadata the same way, such as the headers of a NATS or Kafka message, from `executionContext.switchToRpc().getContext()`.

For a gateway, the built-in resolvers read the headers and query string of the connection's upgrade request. Socket.IO keeps that request as the handshake, and the resolvers find it there. The `ws` library, behind `WsAdapter` from `@nestjs/platform-ws`, keeps nothing, so store the request on `client.request` when a client connects (`WsAuthenticator` of `@nestjs/authentication` does the same):

orders/order-updates.gateway.ts

JS TS

```typescript

@WebSocketGateway({ path: '/orders/updates' })
export class OrderUpdatesGateway implements OnGatewayConnection {
  constructor(private readonly ordersService: OrdersService) {}

  handleConnection(client: WebSocket & { request?: IncomingMessage }, request: IncomingMessage) {
    // The ws library keeps no reference to the upgrade request, whose headers and query the resolvers read
    client.request = request;
  }

  @SubscribeMessage('orders.summary')
  summary(@MessageBody() id: number) {
    return { event: 'orders.summary', data: this.ordersService.getSummary(id) };
  }
}
```

A client that connects to `/orders/updates?lang=de` reads German summaries. Interceptors run after guards, so on these paths guards see the default locale, and an error a guard throws is in the default locale. Pipes and handlers see the resolved one, and resolvers with `afterGuards` need nothing extra: every resolver already runs after guards here.

#### Handle missing keys and reload catalogs[#](/application/i18n#handle-missing-keys-and-reload-catalogs)

A missing translation should break the build in development and CI, and degrade quietly in production. Here's the final `AppModule`:

app.module.ts

JS TS

```typescript

import { ApolloDriver, type ApolloDriverConfig } from '@nestjs/apollo';
import { Module } from '@nestjs/common';
import { APP_PIPE } from '@nestjs/core';
import { GraphQLModule } from '@nestjs/graphql';
import {
  AcceptLanguageLocaleResolver,
  HeaderLocaleResolver,
  I18nModule,
  I18nValidationPipe,
  JsonI18nLoader,
  QueryLocaleResolver,
} from '@nestjs/i18n';
import { join } from 'node:path';
import { CustomerLocaleResolver } from './customers/customer-locale.resolver.js';
import { CustomersModule } from './customers/customers.module.js';
import { OrdersModule } from './orders/orders.module.js';

const env = process.env.NODE_ENV ?? 'development';

@Module({
  imports: [
    I18nModule.forRoot({
      defaultLocale: 'en',
      supportedLocales: ['en', 'pl', 'de'],
      fallbacks: { 'de-AT': 'de' },
      loader: new JsonI18nLoader({
        path: join(import.meta.dirname, 'i18n'),
        watch: env === 'development',
      }),
      resolvers: [
        new QueryLocaleResolver('lang'),
        new HeaderLocaleResolver('x-lang'),
        CustomerLocaleResolver,
        new AcceptLanguageLocaleResolver(),
      ],
      imports: [CustomersModule],
      missingKey: env === 'production' ? 'fallback' : 'throw',
    }),
    GraphQLModule.forRoot<ApolloDriverConfig>({
      driver: ApolloDriver,
      autoSchemaFile: true,
    }),
    CustomersModule,
    OrdersModule,
  ],
  providers: [
    {
      provide: APP_PIPE,
      useValue: new I18nValidationPipe({ whitelist: true, transform: true }),
    },
  ],
})
export class AppModule {}
```

The `missingKey` option decides what happens when a key isn't found for the requested locale:

* **`'throw'` outside production.**`t()` and `translate()` throw an `I18nMissingKeyError`, and the request fails with a 500. A Polish message that exists only in English fails too, because this policy never falls back to the default locale. Vitest sets `NODE_ENV` to `test`, so your test suite runs with this policy.
* **`'fallback'` in production.** A missing Polish message is taken from the default locale, English, and a warning names the key and the locale, once per pair. A key that exists nowhere returns the key itself and logs a warning, once per key.

The `de-AT` to `de` fallback and region-to-base matching apply under every policy. Validation messages looked up by constraint name or issue code never throw either: a constraint or issue without a translation keeps the library's message. Keys you name with `i18nValidationMessage()` or `i18nIssueMessage()` follow the policy, like `t()`. The other policies are `'key'`, `'empty'` and a function that receives the key and the locale.

> **Hint** Fallback works per key. When messages are composed as in [Translate order confirmations](/application/i18n#translate-order-confirmations), a Polish customer can receive an English sentence around a Polish plural. The warning tells you it happened; the catalog test in [Testing](/application/i18n#testing) keeps it from shipping.

With `watch: true`, the JSON loader watches the catalog directory and reloads it when a file changes, so translators can edit messages without restarting the app. Enable it in development only:

* **Reloads are atomic.** The whole catalog is re-read and swapped in one step, so a request never sees a mix of old and new messages.
* **Broken files are ignored.** If a file fails to parse, the previous catalog stays in use, and the error is logged with the file path. The next valid save is picked up.
* **Watching stops on shutdown.** The watcher closes when the application closes. Call `app.enableShutdownHooks()` in `main.ts` to close it on termination signals as well.

With `watchAssets` enabled in `nest-cli.json`, the CLI copies edited catalogs to `dist`, where the loader reads them.

##### Options from configuration[#](/application/i18n#options-from-configuration)

The tutorial reads `process.env` directly, to stay short. In an application, load the environment through [`@nestjs/config`](/application/configuration) with a validation schema, and register the module with `forRootAsync()`. Its factory receives the injected `ConfigService` and returns the options:

app.module.ts

JS TS

```typescript

I18nModule.forRootAsync({
  inject: [ConfigService],
  useFactory: (configService: ConfigService) => {
    const env = configService.get<string>('NODE_ENV', 'development');
    return {
      defaultLocale: 'en',
      supportedLocales: ['en', 'pl', 'de'],
      fallbacks: { 'de-AT': 'de' },
      loader: new JsonI18nLoader({
        path: join(import.meta.dirname, 'i18n'),
        watch: env === 'development',
      }),
      missingKey: env === 'production' ? 'fallback' : 'throw',
    };
  },
  // The list has a class, which Nest instantiates, so it stays next to useFactory
  resolvers: [
    new QueryLocaleResolver('lang'),
    new HeaderLocaleResolver('x-lang'),
    CustomerLocaleResolver,
    new AcceptLanguageLocaleResolver(),
  ],
  imports: [CustomersModule],
}),
```

The factory can return loader, resolver and formatter instances, but not classes: Nest instantiates classes while it builds the module, before any factory runs. So `resolvers`, which lists `CustomerLocaleResolver`, stays at the top level with `imports`. A factory that returns a class, or an option set in both places, fails at startup with a message that names the option.

To keep the options in a class of their own, pass it as `useClass`. It implements `I18nOptionsFactory`, and Nest calls its `createI18nOptions()` method:

i18n/i18n-config.service.ts

JS TS

```typescript

@Injectable()
export class I18nConfigService implements I18nOptionsFactory {
  constructor(private readonly configService: ConfigService) {}

  createI18nOptions(): I18nModuleOptions {
    const env = this.configService.get<string>('NODE_ENV', 'development');
    return {
      defaultLocale: 'en',
      // ...
    };
  }
}
```

app.module.ts

JS TS

```typescript

I18nModule.forRootAsync({
  useClass: I18nConfigService,
  resolvers: [
    // ...
  ],
  imports: [CustomersModule],
}),
```

The options the module ends up with are injectable with the `I18N_MODULE_OPTIONS` token, for a provider of your own that depends on them.

##### A custom loader[#](/application/i18n#a-custom-loader)

Translators often work in a translation platform, which exports every catalog as one JSON document. A loader extends `I18nLoader`: `load()` returns the catalogs keyed by locale, and the optional `watch()` passes new ones to a callback, for hot reload. This one fetches the export at startup, and again every five minutes:

i18n/remote-i18n.loader.ts

JS TS

```typescript

import { Logger } from '@nestjs/common';
import { I18nLoader, type I18nCatalogs } from '@nestjs/i18n';

/** Catalogs a translation platform exports as one JSON document, fetched again every `interval` ms. */
export class RemoteI18nLoader extends I18nLoader {
  private readonly logger = new Logger(RemoteI18nLoader.name);

  constructor(
    private readonly url: string,
    private readonly interval = 5 * 60_000,
  ) {
    super();
  }

  async load(): Promise<I18nCatalogs> {
    const response = await fetch(this.url, { signal: AbortSignal.timeout(10_000) });
    if (!response.ok) {
      throw new Error(`GET ${this.url} answered ${response.status}`);
    }
    return (await response.json()) as I18nCatalogs;
  }

  watch(onChange: (catalogs: I18nCatalogs) => void): () => void {
    const timer = setInterval(() => {
      this.load().then(onChange, (err: Error) =>
        this.logger.warn(`Keeping the current catalogs: ${err.message}`),
      );
    }, this.interval);
    // Polling alone doesn't keep the process alive
    timer.unref();
    return () => clearInterval(timer);
  }
}
```

Pass an instance as `loader`. A failed fetch at startup fails the bootstrap, and a failed poll keeps the catalogs in use. The module calls `watch()` when it initializes, and the function `watch()` returns when it shuts down. New catalogs are checked like the first ones, and a set that doesn't fit, such as one without a catalog for the default locale, is logged and ignored. To read catalogs from your database, pass a loader class instead, which Nest instantiates with the repository it injects, and list the repository's module in `imports`.

#### Use ICU message syntax[#](/application/i18n#use-icu-message-syntax)

The built-in syntax has placeholders, and plural forms as catalog objects. Translation platforms such as Crowdin and Lokalise often export catalogs in ICU MessageFormat instead, which also has exact matches such as `=0`, `select` (for a message that depends on a value, such as a pet's species), and `selectordinal` (1st, 2nd, 3rd). Here is the Polish `items` message in ICU:

```json

{
  "items": "{count, plural, one {# produkt} few {# produkty} many {# produktów} other {# produktu}}"
}
```

The `formatter` option plugs in another syntax. A formatter extends `I18nMessageFormatter` and implements `format()`, which receives the message, the arguments and the locale. This one hands the message to the [`intl-messageformat`](https://formatjs.github.io/docs/intl-messageformat/) library, which your application installs:

i18n/icu-message.formatter.ts

JS TS

```typescript

import { I18nMessageFormatter } from '@nestjs/i18n';
import { IntlMessageFormat } from 'intl-messageformat';

export class IcuMessageFormatter extends I18nMessageFormatter {
  // Parsing a message costs far more than formatting it, and the catalogs hold a fixed set
  private readonly compiled = new Map<string, IntlMessageFormat>();

  format(message: string, args: Record<string, unknown>, locale: string): string {
    const key = `${locale}\u0000${message}`;
    let compiled = this.compiled.get(key);
    if (!compiled) {
      compiled = new IntlMessageFormat(message, locale, undefined, { ignoreTag: true });
      this.compiled.set(key, compiled);
    }
    return String(compiled.format<unknown>(args));
  }
}
```

`ignoreTag` keeps `<` and `>` as text, where the library would otherwise read rich-text tags. Pass an instance, or a class that Nest instantiates, as `formatter`:

app.module.ts

JS TS

```typescript

I18nModule.forRoot({
  // ...
  formatter: new IcuMessageFormatter(),
}),
```

With the formatter in place:

* **The tutorial's catalogs work unchanged.** A placeholder is a simple ICU argument, and plural objects still work: the module picks the form, and the formatter formats it. Polish `items` reads "5 produktów" as a plural object and as the ICU message above.
* **The locale is the request's.** A message that `de-AT` reads from the German catalog is formatted for `de-AT`, so a number argument with a currency style reads `$ 97,95`. A message that fell back to the default locale is formatted for the default locale, whose grammar it's written in.
* **Keys stay checked, plural counts don't.** The compiler requires a numeric `count` for a plural object, but an ICU plural is a string to it, so pass its argument yourself.

#### Try it[#](/application/i18n#try-it)

Start the application and place an order with Polish in `Accept-Language`:

```bash

$ curl -X POST http://localhost:3000/orders \
    -H 'Content-Type: application/json' \
    -H 'Accept-Language: pl-PL,pl;q=0.9,en;q=0.8' \
    -d '{"items":[{"productId":"salmon-kibble-2kg","quantity":2},{"productId":"sisal-scratching-post","quantity":3}]}'
{"id":1002,"message":"Dziękujemy! Zamówienie #1002 zostało przyjęte: 5 produktów."}
```

The `lang` query parameter wins over any header:

```bash

$ curl -X POST 'http://localhost:3000/orders?lang=de' \
    -H 'Content-Type: application/json' \
    -d '{"items":[{"productId":"feather-wand","quantity":1}]}'
{"id":1003,"message":"Vielen Dank! Bestellung #1003 ist bestätigt: 1 Produkt."}
```

Read the summary of order #1001 as an Austrian customer:

```bash

$ curl http://localhost:3000/orders/1001 -H 'Accept-Language: de-AT'
```

```json

{
  "id": 1001,
  "status": "Versandt",
  "items": "5 Produkte",
  "total": "$ 97,95",
  "placedAt": "14. September 2026"
}
```

Ask for an order that doesn't exist, with the `x-lang` header:

```bash

$ curl http://localhost:3000/orders/999 -H 'x-lang: pl'
```

```json

{
  "message": "Nie znaleziono zamówienia #999.",
  "error": "Not Found",
  "statusCode": 404
}
```

Send an invalid order:

```bash

$ curl -X POST 'http://localhost:3000/orders?lang=pl' \
    -H 'Content-Type: application/json' \
    -d '{"items":[{"productId":"salmon-kibble-2kg","quantity":0},{"productId":42,"quantity":12}]}'
```

```json

{
  "message": [
    "items.0.quantity musi wynosić co najmniej 1",
    "items.1.productId musi być tekstem",
    "items.1.quantity: można zamówić najwyżej 10 sztuk jednego produktu"
  ],
  "error": "Bad Request",
  "statusCode": 400
}
```

Send an invalid shipping address:

```bash

$ curl -X PUT http://localhost:3000/orders/1001/shipping-address \
    -H 'Content-Type: application/json' \
    -H 'Accept-Language: de' \
    -d '{"recipient":"A","city":"Wien","postalCode":"1010","country":"AT"}'
```

```json

{
  "message": [
    "recipient muss mindestens 2 Zeichen lang sein",
    "postalCode hat ein ungültiges Format",
    "Wir liefern nur in die USA, nach Polen und nach Deutschland."
  ],
  "error": "Bad Request",
  "statusCode": 400
}
```

Finally, query the order over GraphQL:

```bash

$ curl -X POST 'http://localhost:3000/graphql?lang=pl' \
    -H 'Content-Type: application/json' \
    -d '{"query":"{ order(id: 1001) { id status statusLabel items } }"}'
```

```json

{
  "data": {
    "order": {
      "id": 1001,
      "status": "shipped",
      "statusLabel": "Wysłane",
      "items": "5 produktów"
    }
  }
}
```

> **Hint**`Intl` separates the amount and the currency with a no-break space (U+00A0) in `97,95 USD`, `97,95 $` and `$ 97,95`. The responses above show a regular space. Keep that in mind when you compare formatted strings in tests.

#### Testing[#](/application/i18n#testing)

An [end-to-end test](/fundamentals/testing#end-to-end-testing) sets the language the same way a client does:

test/orders.e2e.spec.ts

JS TS

```typescript

import type { INestApplication } from '@nestjs/common';
import { Test } from '@nestjs/testing';
import request from 'supertest';
import { AppModule } from '../src/app.module.js';

describe('Orders (e2e)', () => {
  let app: INestApplication;

  beforeAll(async () => {
    const moduleRef = await Test.createTestingModule({
      imports: [AppModule],
    }).compile();
    app = moduleRef.createNestApplication();
    await app.listen(0, '127.0.0.1');
  });

  afterAll(() => app.close());

  it('confirms an order in the language of the request', async () => {
    const res = await request(app.getHttpServer())
      .post('/orders')
      .set('Accept-Language', 'pl-PL,pl;q=0.9')
      .send({ items: [{ productId: 'salmon-kibble-2kg', quantity: 5 }] })
      .expect(201);

    expect(res.body.message).toBe(
      'Dziękujemy! Zamówienie #1002 zostało przyjęte: 5 produktów.',
    );
  });

  it('localizes errors', async () => {
    const res = await request(app.getHttpServer())
      .get('/orders/999?lang=de')
      .expect(404);

    expect(res.body.message).toBe('Bestellung #999 wurde nicht gefunden.');
  });
});
```

Outside a request, `I18nService` uses the default locale. To test a service in another language without HTTP, run the call inside `I18nContext.run()`, which makes the locale current as a request would:

test/orders.service.spec.ts

JS TS

```typescript

import { I18nContext } from '@nestjs/i18n';
import { Test } from '@nestjs/testing';
import { AppModule } from '../src/app.module.js';
import { OrdersService } from '../src/orders/orders.service.js';

describe('OrdersService', () => {
  let ordersService: OrdersService;
  let i18nContext: I18nContext;

  beforeAll(async () => {
    const moduleRef = await Test.createTestingModule({
      imports: [AppModule],
    }).compile();
    ordersService = moduleRef.get(OrdersService);
    i18nContext = moduleRef.get(I18nContext);
  });

  it.each([
    [1, '1 produkt'],
    [2, '2 produkty'],
    [5, '5 produktów'],
    [22, '22 produkty'],
  ])('describes %i item(s) in Polish', (quantity, expected) => {
    const order = {
      ...ordersService.findOne(1001),
      items: [{ productId: 'salmon-kibble-2kg', quantity }],
    };
    expect(i18nContext.run('pl', () => ordersService.describeItems(order))).toBe(expected);
  });

  it('falls back to the default locale outside a request', () => {
    const order = ordersService.findOne(1001);
    expect(ordersService.describeItems(order)).toBe('5 items');
  });
});
```

To run the application with other catalogs, for example with a translation removed to test the missing-key policy, replace the loader on the testing module: `overrideProvider(I18nLoader).useValue(new InMemoryI18nLoader(catalogs))`.

The `'throw'` policy catches missing keys on the paths your tests exercise. A catalog test catches the rest: every locale must have the same keys and placeholders as English, and every plural message must have the forms its language needs. `Intl.PluralRules` knows which forms those are:

test/catalogs.spec.ts

JS TS

```typescript

import { JsonI18nLoader, type I18nCatalog } from '@nestjs/i18n';
import { join } from 'node:path';

type Message = string | Record<string, string>;

/** Flattens a catalog to [key, message] pairs; plural forms count as one message. */
function messages(tree: I18nCatalog, prefix = ''): [string, Message][] {
  return Object.entries(tree).flatMap(([name, value]): [string, Message][] =>
    typeof value === 'string' || 'other' in value
      ? [[prefix + name, value as Message]]
      : messages(value, `${prefix}${name}.`),
  );
}

const placeholders = (message: Message) =>
  [...new Set(JSON.stringify(message).match(/\{\w+\}/g))].sort();

const loader = new JsonI18nLoader({ path: join(import.meta.dirname, '../src/i18n') });
const catalogs = await loader.load();
const english = new Map(messages(catalogs.en));

describe.each(Object.keys(catalogs))('the %s catalog', (lang) => {
  const translated = new Map(messages(catalogs[lang]));

  it('has the same keys and placeholders as the English one', () => {
    expect([...translated.keys()].sort()).toEqual([...english.keys()].sort());
    for (const [key, message] of translated) {
      expect(placeholders(message), key).toEqual(placeholders(english.get(key)!));
    }
  });

  it('has every plural form the language needs', () => {
    const forms = new Intl.PluralRules(lang).resolvedOptions().pluralCategories;
    for (const [key, message] of translated) {
      if (typeof message === 'object') {
        expect(Object.keys(message), key).toEqual(expect.arrayContaining(forms));
      }
    }
  });
});
```

Delete the `many` form from the Polish `items` message, and the second test fails with the list of forms Polish needs.

#### Production checklist[#](/application/i18n#production-checklist)

* **Ship the catalogs.** Check that `dist/i18n` exists after `nest build`. The loader reads the directory at startup, and a missing directory fails the bootstrap.
* **Use `'fallback'` in production and `'throw'` everywhere else**, and run the catalog test in CI. Watch production logs for fallback warnings.
* **Turn off `watch` in production.** Hot reload is a development tool.
* **Pin `supportedLocales`.** Otherwise every directory under `i18n` becomes a locale, including one that appears while the app is running with `watch` enabled.
* **Add formatting regions to `fallbacks`.** A region resolves to its base language unless it's listed, and then it's formatted like the base language too.
* **Set the locale outside requests.** Cron jobs, queue consumers and outgoing emails have no request, so `I18nService` falls back to the default locale there, and the `t()` function returns the key. Save each customer's preferred locale, and run the work inside `I18nContext.run()`.
* **Mind caches.** Responses to the same URL differ by `Accept-Language` and `x-lang`. The middleware lists both in `Vary`; check that your cache or CDN honors it. The `lang` query parameter is part of the URL, so it needs nothing extra.
* **Keep GraphQL under the global prefix.** With `setGlobalPrefix()`, the locale middleware only covers routes under the prefix. Give `GraphQLModule``useGlobalPrefix: true`, or guards on resolvers stop seeing the locale (see [Localize GraphQL fields](/application/i18n#localize-graphql-fields)).
* **Escape messages that end up in HTML.** Arguments such as a customer's name are inserted as they are. That's right for JSON responses, but an HTML email must escape the message like any other text.
* **Keep numbers and dates in the locale's hands, and currency and time zone out of them.** See [Format prices and dates](/application/i18n#format-prices-and-dates).

#### Reference[#](/application/i18n#reference)

##### Module options[#](/application/i18n#module-options)

`I18nModule.forRoot()` takes these options. `forRootAsync()` takes the same values from its factory (`useFactory` with `inject`, or a `useClass` or `useExisting` class that implements `I18nOptionsFactory`), while `imports`, `isGlobal` and loader, resolver or formatter classes stay at the top level. See [Options from configuration](/application/i18n#options-from-configuration). The resolved options are injectable with the `I18N_MODULE_OPTIONS` token.

| Option             | Default                                | Description                                                                                                                                                                                                                            |
| ------------------ | -------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `loader`           | required                               | Where catalogs come from: an `I18nLoader` instance such as `JsonI18nLoader`, or a loader class Nest instantiates. See [Add catalogs and register the module](/application/i18n#add-catalogs-and-register-the-module).                  |
| `resolvers`        | `[new AcceptLanguageLocaleResolver()]` | Locale resolvers, tried in order: instances, or classes Nest instantiates.                                                                                                                                                             |
| `formatter`        | the built-in syntax                    | An `I18nMessageFormatter` instance, or a class Nest instantiates, that turns messages into text. See [Use ICU message syntax](/application/i18n#use-icu-message-syntax).                                                               |
| `defaultLocale`    | `'en'`                                 | Used when no resolver finds a supported locale, and outside requests.                                                                                                                                                                  |
| `supportedLocales` | the loaded locales                     | The locales a request can get, as BCP 47 tags.                                                                                                                                                                                         |
| `fallbacks`        | none                                   | An object that maps a locale to the one its messages come from, such as `'de-AT': 'de'`. Keys count as supported locales.                                                                                                              |
| `missingKey`       | `'fallback'`                           | What a missing key returns: `'fallback'`, `'key'`, `'empty'`, `'throw'`, or a function that receives the key and the locale. See [Handle missing keys and reload catalogs](/application/i18n#handle-missing-keys-and-reload-catalogs). |
| `logMissingKeys`   | `'once'`                               | Warn about missing keys and default-locale fallbacks `'once'` per key, `'always'`, or `'never'`.                                                                                                                                       |
| `responseHeaders`  | `true`                                 | Set `Content-Language` and `Vary` on HTTP responses.                                                                                                                                                                                   |
| `imports`          | none                                   | Modules whose exported providers loader, resolver and formatter classes inject.                                                                                                                                                        |
| `isGlobal`         | `true`                                 | Register the module globally.                                                                                                                                                                                                          |

`JsonI18nLoader` takes `path`, the directory with one subdirectory per locale, and `watch` (default `false`), which reloads catalogs when a file changes. `InMemoryI18nLoader` takes the catalogs as an object keyed by locale.

##### Locale resolvers[#](/application/i18n#locale-resolvers)

| Resolver                       | Reads                                    | Default name |
| ------------------------------ | ---------------------------------------- | ------------ |
| `QueryLocaleResolver`          | a query parameter                        | `lang`       |
| `HeaderLocaleResolver`         | a request header                         | `x-lang`     |
| `AcceptLanguageLocaleResolver` | `Accept-Language`, ordered by `q` values | none         |
| `CookieLocaleResolver`         | a cookie in the `Cookie` header          | `lang`       |

A custom resolver extends `LocaleResolver` and implements `resolve()`, which receives the request `headers` and `query`, and returns a candidate, a list of candidates, or nothing. It lists the headers it reads in `varyHeaders`. With `afterGuards` set, it runs after guards, keeping its rank, and receives the `executionContext`, as every resolver does for microservices, WebSocket gateways and GraphQL subscriptions. See [Use the customer's saved language](/application/i18n#use-the-customers-saved-language).

##### Translation API[#](/application/i18n#translation-api)

* `I18nService.t(key, options)`: translates for the current locale. `options` takes `args`, the placeholder values (a numeric `count` selects the plural form), and `locale`, an explicit locale. See [Translate order confirmations](/application/i18n#translate-order-confirmations). `I18nService<OtherTranslations>` checks keys against another catalog shape.
* `I18nService.translate(key, options)`: the same with an unchecked key, for keys built at runtime.
* `I18nService.exists(key, locale)`: whether a key has a message.
* `I18nService.formatNumber(value, options)` and `formatDate(value, options)`: `Intl` formatting in the current locale, with the usual `Intl` options plus `locale`. See [Format prices and dates](/application/i18n#format-prices-and-dates).
* `I18nService.matchLocale(candidate)`: maps a locale, such as one saved on a profile, to a supported one, or `undefined`.
* `I18nService.defaultLocale` and `supportedLocales`: the configured locales, for a language picker.
* `I18nContext.locale` and `I18nContext.run(locale, fn)`: read the current locale, or make one current for code outside a request.
* `I18nContext.setLocale(locale)`: changes the locale for the rest of the request and returns the matched locale, or `undefined` for an unsupported one, which changes nothing. It throws outside a request, and on microservices, WebSocket gateways and GraphQL subscriptions in guards, which run before the locale is resolved.
* `@CurrentLocale()`: the current locale as a handler parameter.
* `t(key, options)`: `I18nService.t()` for code without dependency injection. Outside a request, it returns the key. See [Localize exceptions](/application/i18n#localize-exceptions).

##### Validation[#](/application/i18n#validation)

| Export                                           | Description                                                                                                                                                                                |
| ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `I18nValidationPipe`                             | Takes the `ValidationPipe` options, plus `namespace` (default `'validation'`) for constraint messages. See [Localize validation messages](/application/i18n#localize-validation-messages). |
| `I18nStandardSchemaValidationPipe`               | Takes the `StandardSchemaValidationPipe` options, plus `namespace` and `issueKeys`, a function that returns extra candidate keys for an issue. See [With Zod](/application/i18n#with-zod). |
| `i18nValidationMessage(key, args)`               | Points a `class-validator` constraint at a key.                                                                                                                                            |
| `i18nIssueMessage(key, args)`                    | Points a Standard Schema issue at a key.                                                                                                                                                   |
| `translateValidationErrors(errors, options)`     | Translates `class-validator` errors, for pipes of your own.                                                                                                                                |
| `translateStandardSchemaIssues(issues, options)` | Translates Standard Schema issues, for pipes of your own.                                                                                                                                  |

##### Errors[#](/application/i18n#errors)

| Error                 | When                                                                                                                                        |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
| `I18nMissingKeyError` | A key is missing under `missingKey: 'throw'`. It carries `key` and `locale`, and isn't an `HttpException`, so the request fails with a 500. |

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/application/i18n.md)

----
url: https://docs.nestjs.com/v10/microservices/grpc
----

* [gRPC](https://docs.nestjs.com/v10/microservices/grpc#grpc)
* [Installation](https://docs.nestjs.com/v10/microservices/grpc#installation)
* [Overview](https://docs.nestjs.com/v10/microservices/grpc#overview)
* [Options](https://docs.nestjs.com/v10/microservices/grpc#options)
* [Sample gRPC service](https://docs.nestjs.com/v10/microservices/grpc#sample-grpc-service)
* [Client](https://docs.nestjs.com/v10/microservices/grpc#client)
* [Example](https://docs.nestjs.com/v10/microservices/grpc#example)
* [gRPC Reflection](https://docs.nestjs.com/v10/microservices/grpc#grpc-reflection)
* [gRPC Streaming](https://docs.nestjs.com/v10/microservices/grpc#grpc-streaming)
* [Streaming sample](https://docs.nestjs.com/v10/microservices/grpc#streaming-sample)
* [Subject strategy](https://docs.nestjs.com/v10/microservices/grpc#subject-strategy)
* [Call stream handler](https://docs.nestjs.com/v10/microservices/grpc#call-stream-handler)
* [gRPC Metadata](https://docs.nestjs.com/v10/microservices/grpc#grpc-metadata)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/microservices/grpc.md "Suggest Edits")

### gRPC

[gRPC](https://github.com/grpc/grpc-node) is a modern, open source, high performance RPC framework that can run in any environment. It can efficiently connect services in and across data centers with pluggable support for load balancing, tracing, health checking and authentication.

Like many RPC systems, gRPC is based on the concept of defining a service in terms of functions (methods) that can be called remotely. For each method, you define the parameters and return types. Services, parameters, and return types are defined in `.proto` files using Google's open source language-neutral [protocol buffers](https://protobuf.dev) mechanism.

With the gRPC transporter, Nest uses `.proto` files to dynamically bind clients and servers to make it easy to implement remote procedure calls, automatically serializing and deserializing structured data.

#### Installation[#](/microservices/grpc#installation)

To start building gRPC-based microservices, first install the required packages:

```bash

$ npm i --save @grpc/grpc-js @grpc/proto-loader
```

#### Overview[#](/microservices/grpc#overview)

Like other Nest microservices transport layer implementations, you select the gRPC transporter mechanism using the `transport` property of the options object passed to the `createMicroservice()` method. In the following example, we'll set up a hero service. The `options` property provides metadata about that service; its properties are described [below](microservices/grpc#options).

main.ts

JS TS

```typescript

const app = await NestFactory.createMicroservice<MicroserviceOptions>(AppModule, {
  transport: Transport.GRPC,
  options: {
    package: 'hero',
    protoPath: join(__dirname, 'hero/hero.proto'),
  },
});
```

```typescript

const app = await NestFactory.createMicroservice(AppModule, {
  transport: Transport.GRPC,
  options: {
    package: 'hero',
    protoPath: join(__dirname, 'hero/hero.proto'),
  },
});
```

> **Hint** The `join()` function is imported from the `path` package; the `Transport` enum is imported from the `@nestjs/microservices` package.

In the `nest-cli.json` file, we add the `assets` property that allows us to distribute non-TypeScript files, and `watchAssets` - to turn on watching all non-TypeScript assets. In our case, we want `.proto` files to be automatically copied to the `dist` folder.

```json

{
  "compilerOptions": {
    "assets": ["**/*.proto"],
    "watchAssets": true
  }
}
```

#### Options[#](/microservices/grpc#options)

The **gRPC** transporter options object exposes the properties described below.

|               |                                                                                                                                                                                                                                            |
| ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `package`     | Protobuf package name (matches `package` setting from `.proto` file). Required                                                                                                                                                             |
| `protoPath`   | Absolute (or relative to the root dir) path to the `.proto` file. Required                                                                                                                                                                 |
| `url`         | Connection url. String in the format `ip address/dns name:port` (for example, `'0.0.0.0:50051'` for a Docker server) defining the address/port on which the transporter establishes a connection. Optional. Defaults to `'localhost:5000'` |
| `protoLoader` | NPM package name for the utility to load `.proto` files. Optional. Defaults to `'@grpc/proto-loader'`                                                                                                                                      |
| `loader`      | `@grpc/proto-loader` options. These provide detailed control over the behavior of `.proto` files. Optional. See [here](https://github.com/grpc/grpc-node/blob/master/packages/proto-loader/README.md) for more details                     |
| `credentials` | Server credentials. Optional. [Read more here](https://grpc.io/grpc/node/grpc.ServerCredentials.html)                                                                                                                                      |

#### Sample gRPC service[#](/microservices/grpc#sample-grpc-service)

Let's define our sample gRPC service called `HeroesService`. In the above `options` object, the`protoPath` property sets a path to the `.proto` definitions file `hero.proto`. The `hero.proto` file is structured using [protocol buffers](https://developers.google.com/protocol-buffers). Here's what it looks like:

```typescript

// hero/hero.proto
syntax = "proto3";

package hero;

service HeroesService {
  rpc FindOne (HeroById) returns (Hero) {}
}

message HeroById {
  int32 id = 1;
}

message Hero {
  int32 id = 1;
  string name = 2;
}
```

Our `HeroesService` exposes a `FindOne()` method. This method expects an input argument of type `HeroById` and returns a `Hero` message (protocol buffers use `message` elements to define both parameter types and return types).

Next, we need to implement the service. To define a handler that fulfills this definition, we use the `@GrpcMethod()` decorator in a controller, as shown below. This decorator provides the metadata needed to declare a method as a gRPC service method.

> **Hint** The `@MessagePattern()` decorator ([read more](microservices/basics#request-response)) introduced in previous microservices chapters is not used with gRPC-based microservices. The `@GrpcMethod()` decorator effectively takes its place for gRPC-based microservices.

heroes.controller.ts

JS TS

```typescript

@Controller()
export class HeroesController {
  @GrpcMethod('HeroesService', 'FindOne')
  findOne(data: HeroById, metadata: Metadata, call: ServerUnaryCall<any, any>): Hero {
    const items = [
      { id: 1, name: 'John' },
      { id: 2, name: 'Doe' },
    ];
    return items.find(({ id }) => id === data.id);
  }
}
```

```typescript

@Controller()
export class HeroesController {
  @GrpcMethod('HeroesService', 'FindOne')
  findOne(data, metadata, call) {
    const items = [
      { id: 1, name: 'John' },
      { id: 2, name: 'Doe' },
    ];
    return items.find(({ id }) => id === data.id);
  }
}
```

> **Hint** The `@GrpcMethod()` decorator is imported from the `@nestjs/microservices` package, while `Metadata` and `ServerUnaryCall` from the `grpc` package.

The decorator shown above takes two arguments. The first is the service name (e.g., `'HeroesService'`), corresponding to the `HeroesService` service definition in `hero.proto`. The second (the string `'FindOne'`) corresponds to the `FindOne()` rpc method defined within `HeroesService` in the `hero.proto` file.

The `findOne()` handler method takes three arguments, the `data` passed from the caller, `metadata` that stores gRPC request metadata and `call` to obtain the `GrpcCall` object properties such as `sendMetadata` for send metadata to client.

Both `@GrpcMethod()` decorator arguments are optional. If called without the second argument (e.g., `'FindOne'`), Nest will automatically associate the `.proto` file rpc method with the handler based on converting the handler name to upper camel case (e.g., the `findOne` handler is associated with the `FindOne` rpc call definition). This is shown below.

heroes.controller.ts

JS TS

```typescript

@Controller()
export class HeroesController {
  @GrpcMethod('HeroesService')
  findOne(data: HeroById, metadata: Metadata, call: ServerUnaryCall<any, any>): Hero {
    const items = [
      { id: 1, name: 'John' },
      { id: 2, name: 'Doe' },
    ];
    return items.find(({ id }) => id === data.id);
  }
}
```

```typescript

@Controller()
export class HeroesController {
  @GrpcMethod('HeroesService')
  findOne(data, metadata, call) {
    const items = [
      { id: 1, name: 'John' },
      { id: 2, name: 'Doe' },
    ];
    return items.find(({ id }) => id === data.id);
  }
}
```

You can also omit the first `@GrpcMethod()` argument. In this case, Nest automatically associates the handler with the service definition from the proto definitions file based on the **class** name where the handler is defined. For example, in the following code, class `HeroesService` associates its handler methods with the `HeroesService` service definition in the `hero.proto` file based on the matching of the name `'HeroesService'`.

heroes.controller.ts

JS TS

```typescript

@Controller()
export class HeroesService {
  @GrpcMethod()
  findOne(data: HeroById, metadata: Metadata, call: ServerUnaryCall<any, any>): Hero {
    const items = [
      { id: 1, name: 'John' },
      { id: 2, name: 'Doe' },
    ];
    return items.find(({ id }) => id === data.id);
  }
}
```

```typescript

@Controller()
export class HeroesService {
  @GrpcMethod()
  findOne(data, metadata, call) {
    const items = [
      { id: 1, name: 'John' },
      { id: 2, name: 'Doe' },
    ];
    return items.find(({ id }) => id === data.id);
  }
}
```

#### Client[#](/microservices/grpc#client)

Nest applications can act as gRPC clients, consuming services defined in `.proto` files. You access remote services through a `ClientGrpc` object. You can obtain a `ClientGrpc` object in several ways.

The preferred technique is to import the `ClientsModule`. Use the `register()` method to bind a package of services defined in a `.proto` file to an injection token, and to configure the service. The `name` property is the injection token. For gRPC services, use `transport: Transport.GRPC`. The `options` property is an object with the same properties described [above](microservices/grpc#options).

```typescript

imports: [
  ClientsModule.register([
    {
      name: 'HERO_PACKAGE',
      transport: Transport.GRPC,
      options: {
        package: 'hero',
        protoPath: join(__dirname, 'hero/hero.proto'),
      },
    },
  ]),
];
```

> **Hint** The `register()` method takes an array of objects. Register multiple packages by providing a comma separated list of registration objects.

Once registered, we can inject the configured `ClientGrpc` object with `@Inject()`. Then we use the `ClientGrpc` object's `getService()` method to retrieve the service instance, as shown below.

```typescript

@Injectable()
export class AppService implements OnModuleInit {
  private heroesService: HeroesService;

  constructor(@Inject('HERO_PACKAGE') private client: ClientGrpc) {}

  onModuleInit() {
    this.heroesService = this.client.getService<HeroesService>('HeroesService');
  }

  getHero(): Observable<string> {
    return this.heroesService.findOne({ id: 1 });
  }
}
```

> **Warning** gRPC Client will not send fields that contain underscore `_` in their names unless the `keepCase` options is set to `true` in the proto loader configuration (`options.loader.keepcase` in the microservice transporter configuration).

Notice that there is a small difference compared to the technique used in other microservice transport methods. Instead of the `ClientProxy` class, we use the `ClientGrpc` class, which provides the `getService()` method. The `getService()` generic method takes a service name as an argument and returns its instance (if available).

Alternatively, you can use the `@Client()` decorator to instantiate a `ClientGrpc` object, as follows:

```typescript

@Injectable()
export class AppService implements OnModuleInit {
  @Client({
    transport: Transport.GRPC,
    options: {
      package: 'hero',
      protoPath: join(__dirname, 'hero/hero.proto'),
    },
  })
  client: ClientGrpc;

  private heroesService: HeroesService;

  onModuleInit() {
    this.heroesService = this.client.getService<HeroesService>('HeroesService');
  }

  getHero(): Observable<string> {
    return this.heroesService.findOne({ id: 1 });
  }
}
```

Finally, for more complex scenarios, we can inject a dynamically configured client using the `ClientProxyFactory` class as described [here](/microservices/basics#client).

In either case, we end up with a reference to our `HeroesService` proxy object, which exposes the same set of methods that are defined inside the `.proto` file. Now, when we access this proxy object (i.e., `heroesService`), the gRPC system automatically serializes requests, forwards them to the remote system, returns a response, and deserializes the response. Because gRPC shields us from these network communication details, `heroesService` looks and acts like a local provider.

Note, all service methods are **lower camel cased** (in order to follow the natural convention of the language). So, for example, while our `.proto` file `HeroesService` definition contains the `FindOne()` function, the `heroesService` instance will provide the `findOne()` method.

```typescript

interface HeroesService {
  findOne(data: { id: number }): Observable<any>;
}
```

A message handler is also able to return an `Observable`, in which case the result values will be emitted until the stream is completed.

heroes.controller.ts

JS TS

```typescript

@Get()
call(): Observable<any> {
  return this.heroesService.findOne({ id: 1 });
}
```

```typescript

@Get()
call() {
  return this.heroesService.findOne({ id: 1 });
}
```

To send gRPC metadata (along with the request), you can pass a second argument, as follows:

```typescript

call(): Observable<any> {
  const metadata = new Metadata();
  metadata.add('Set-Cookie', 'yummy_cookie=choco');

  return this.heroesService.findOne({ id: 1 }, metadata);
}
```

> **Hint** The `Metadata` class is imported from the `grpc` package.

Please note that this would require updating the `HeroesService` interface that we've defined a few steps earlier.

#### Example[#](/microservices/grpc#example)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/04-grpc).

#### gRPC Reflection[#](/microservices/grpc#grpc-reflection)

The [gRPC Server Reflection Specification](https://grpc.io/docs/guides/reflection/#overview) is a standard which allows gRPC clients to request details about the API that the server exposes, akin to exposing an OpenAPI document for a REST API. This can make working with developer debugging tools such as grpc-ui or postman significantly easier.

To add gRPC reflection support to your server, first install the required implementation package:

```bash

$ npm i --save @grpc/reflection
```

Then it can be hooked into the gRPC server using the `onLoadPackageDefinition` hook in your gRPC server options, as follows:

main.ts

JS TS

```typescript

import { ReflectionService } from '@grpc/reflection';

const app = await NestFactory.createMicroservice<MicroserviceOptions>(AppModule, {
  options: {
    onLoadPackageDefinition: (pkg, server) => {
      new ReflectionService(pkg).addToServer(server);
    },
  },
});
```

Now your server will respond to messages requesting API details using the reflection specification.

```typescript

// hello/hello.proto
syntax = "proto3";

package hello;

service HelloService {
  rpc BidiHello(stream HelloRequest) returns (stream HelloResponse);
  rpc LotsOfGreetings(stream HelloRequest) returns (HelloResponse);
}

message HelloRequest {
  string greeting = 1;
}

message HelloResponse {
  string reply = 1;
}
```

> **Hint** The `LotsOfGreetings` method can be simply implemented with the `@GrpcMethod` decorator (as in the examples above) since the returned stream can emit multiple values.

Based on this `.proto` file, let's define the `HelloService` interface:

```typescript

interface HelloService {
  bidiHello(upstream: Observable<HelloRequest>): Observable<HelloResponse>;
  lotsOfGreetings(
    upstream: Observable<HelloRequest>,
  ): Observable<HelloResponse>;
}

interface HelloRequest {
  greeting: string;
}

interface HelloResponse {
  reply: string;
}
```

> **Hint** The proto interface can be automatically generated by the [ts-proto](https://github.com/stephenh/ts-proto) package, learn more [here](https://github.com/stephenh/ts-proto/blob/main/NESTJS.markdown).

#### Subject strategy[#](/microservices/grpc#subject-strategy)

The `@GrpcStreamMethod()` decorator provides the function parameter as an RxJS `Observable`. Thus, we can receive and process multiple messages.

```typescript

@GrpcStreamMethod()
bidiHello(messages: Observable<any>, metadata: Metadata, call: ServerDuplexStream<any, any>): Observable<any> {
  const subject = new Subject();

  const onNext = message => {
    console.log(message);
    subject.next({
      reply: 'Hello, world!'
    });
  };
  const onComplete = () => subject.complete();
  messages.subscribe({
    next: onNext,
    complete: onComplete,
  });


  return subject.asObservable();
}
```

> **Warning** For supporting full-duplex interaction with the `@GrpcStreamMethod()` decorator, the controller method must return an RxJS `Observable`.

> **Hint** The `Metadata` and `ServerUnaryCall` classes/interfaces are imported from the `grpc` package.

According to the service definition (in the `.proto` file), the `BidiHello` method should stream requests to the service. To send multiple asynchronous messages to the stream from a client, we leverage an RxJS `ReplaySubject` class.

```typescript

const helloService = this.client.getService<HelloService>('HelloService');
const helloRequest$ = new ReplaySubject<HelloRequest>();

helloRequest$.next({ greeting: 'Hello (1)!' });
helloRequest$.next({ greeting: 'Hello (2)!' });
helloRequest$.complete();

return helloService.bidiHello(helloRequest$);
```

In the example above, we wrote two messages to the stream (`next()` calls) and notified the service that we've completed sending the data (`complete()` call).

#### Call stream handler[#](/microservices/grpc#call-stream-handler)

When the method return value is defined as `stream`, the `@GrpcStreamCall()` decorator provides the function parameter as `grpc.ServerDuplexStream`, which supports standard methods like `.on('data', callback)`, `.write(message)` or `.cancel()`. Full documentation on available methods can be found [here](https://grpc.github.io/grpc/node/grpc-ClientDuplexStream.html).

Alternatively, when the method return value is not a `stream`, the `@GrpcStreamCall()` decorator provides two function parameters, respectively `grpc.ServerReadableStream` (read more [here](https://grpc.github.io/grpc/node/grpc-ServerReadableStream.html)) and `callback`.

Let's start with implementing the `BidiHello` which should support a full-duplex interaction.

```typescript

@GrpcStreamCall()
bidiHello(requestStream: any) {
  requestStream.on('data', message => {
    console.log(message);
    requestStream.write({
      reply: 'Hello, world!'
    });
  });
}
```

> **Hint** This decorator does not require any specific return parameter to be provided. It is expected that the stream will be handled similar to any other standard stream type.

In the example above, we used the `write()` method to write objects to the response stream. The callback passed into the `.on()` method as a second parameter will be called every time our service receives a new chunk of data.

Let's implement the `LotsOfGreetings` method.

```typescript

@GrpcStreamCall()
lotsOfGreetings(requestStream: any, callback: (err: unknown, value: HelloResponse) => void) {
  requestStream.on('data', message => {
    console.log(message);
  });
  requestStream.on('end', () => callback(null, { reply: 'Hello, world!' }));
}
```

```typescript

@Controller()
export class HeroesService {
  @GrpcMethod()
  findOne(data: HeroById, metadata: Metadata, call: ServerUnaryCall<any, any>): Hero {
    const serverMetadata = new Metadata();
    const items = [
      { id: 1, name: 'John' },
      { id: 2, name: 'Doe' },
    ];

    serverMetadata.add('Set-Cookie', 'yummy_cookie=choco');
    call.sendMetadata(serverMetadata);

    return items.find(({ id }) => id === data.id);
  }
}
```

```typescript

@Controller()
export class HeroesService {
  @GrpcMethod()
  findOne(data, metadata, call) {
    const serverMetadata = new Metadata();
    const items = [
      { id: 1, name: 'John' },
      { id: 2, name: 'Doe' },
    ];

    serverMetadata.add('Set-Cookie', 'yummy_cookie=choco');
    call.sendMetadata(serverMetadata);

    return items.find(({ id }) => id === data.id);
  }
}
```

Likewise, to read the metadata in handlers annotated with the `@GrpcStreamMethod()` handler ([subject strategy](microservices/grpc#subject-strategy)), use the second argument (metadata), which is of type `Metadata` (imported from the `grpc` package).

To send back metadata from the handler, use the `ServerDuplexStream#sendMetadata()` method (third handler argument).

To read metadata from within the [call stream handlers](microservices/grpc#call-stream-handler) (handlers annotated with `@GrpcStreamCall()` decorator), listen to the `metadata` event on the `requestStream` reference, as follows:

```typescript

requestStream.on('metadata', (metadata: Metadata) => {
  const meta = metadata.get('X-Meta');
});
```

----
url: https://docs.nestjs.com/v8/recipes/router-module
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Router module](https://docs.nestjs.com/v8/recipes/router-module#router-module)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/recipes/router-module.md "Suggest Edits")

### Router module

> **Hint** This chapter is only relevant to HTTP-based applications.

In an HTTP application (for example, REST API), the route path for a handler is determined by concatenating the (optional) prefix declared for the controller (inside the `@Controller` decorator), and any path specified in the method's decorator (e.g, `@Get('users')`). You can learn more about that in [this section](/controllers#routing). Additionally, you can define a [global prefix](/v8/faq/global-prefix) for all routes registered in your application, or enable [versioning](/v8/techniques/versioning).

Also, there are edge-cases when defining a prefix at a module-level (and so for all controllers registered inside that module) may come in handy. For example, imagine a REST application that exposes several different endpoints being used by a specific portion of your application called "Dashboard". In such a case, instead of repeating the `/dashboard` prefix within each controller, you could use a utility `RouterModule` module, as follows:

```typescript

@Module({
  imports: [
    DashboardModule,
    RouterModule.register([
      {
        path: 'dashboard',
        module: DashboardModule,
      },
    ]),
  ],
})
export class AppModule {}
```

> **Hint** The `RouterModule` class is exported from the `@nestjs/core` package.

In addition, you can define hierarchical structures. This means each module can have `children` modules. The children modules will inherit their parent's prefix. In the following example, we'll register the `AdminModule` as a parent module of `DashboardModule` and `MetricsModule`.

```typescript

RouterModule.register([
  {
    path: 'admin',
    module: AdminModule,
    children: [
      {
        path: 'dashboard',
        module: DashboardModule,
      },
      {
        path: 'metrics',
        module: MetricsModule,
      },
    ],
  },
]);
```

> **Hint** This feature should be used very carefully, as overusing it can make code difficult to maintain over time.

In the example above, any controller registered inside the `DashboardModule` will have an extra `/admin/dashboard` prefix (as the module concatenates paths from top to bottom - recursively - parent to children). Likewise, each controller defined inside the `MetricsModule` will have an additional module-level prefix `/admin/metrics`.

----
url: https://docs.nestjs.com/application/configuration
----

[Skip to content](#content)

On this page

* [Configuration](https://docs.nestjs.com/application/configuration#configuration)
* [Installation](https://docs.nestjs.com/application/configuration#installation)
* [Getting started](https://docs.nestjs.com/application/configuration#getting-started)
* [Custom env file path](https://docs.nestjs.com/application/configuration#custom-env-file-path)
* [Disable env variables loading](https://docs.nestjs.com/application/configuration#disable-env-variables-loading)
* [Use module globally](https://docs.nestjs.com/application/configuration#use-module-globally)
* [Custom configuration files](https://docs.nestjs.com/application/configuration#custom-configuration-files)
* [Using the ConfigService](https://docs.nestjs.com/application/configuration#using-the-configservice)
* [Configuration namespaces](https://docs.nestjs.com/application/configuration#configuration-namespaces)
* [Namespaced configurations in modules](https://docs.nestjs.com/application/configuration#namespaced-configurations-in-modules)
* [Cache environment variables](https://docs.nestjs.com/application/configuration#cache-environment-variables)
* [Partial registration](https://docs.nestjs.com/application/configuration#partial-registration)
* [Schema validation](https://docs.nestjs.com/application/configuration#schema-validation)
* [Custom validate function](https://docs.nestjs.com/application/configuration#custom-validate-function)
* [Custom getter functions](https://docs.nestjs.com/application/configuration#custom-getter-functions)
* [Environment variables loaded hook](https://docs.nestjs.com/application/configuration#environment-variables-loaded-hook)
* [Conditional module configuration](https://docs.nestjs.com/application/configuration#conditional-module-configuration)
* [Expandable variables](https://docs.nestjs.com/application/configuration#expandable-variables)
* [Using in the main.ts](https://docs.nestjs.com/application/configuration#using-in-the-maints)

[](https://srv.carbonads.net/ads/click/x/GTND4277CVSD5KJUCAYLYKQUF67D62Q7CW7DTZ3JCAAI6KQJCASI4KQKC6YDLKQJC6BDKKJYCABIVK7LCWSD4K7IHEYI55QLCAYD653ECTNCYBZ52K)[Architectural guidance, code that runs. Free, for all levels. Start building ](https://srv.carbonads.net/ads/click/x/GTND4277CVSD5KJUCAYLYKQUF67D62Q7CW7DTZ3JCAAI6KQJCASI4KQKC6YDLKQJC6BDKKJYCABIVK7LCWSD4K7IHEYI55QLCAYD653ECTNCYBZ52K)[ads via Carbon](http://carbonads.net/?utm_source=nestjscom\&utm_medium=ad_via_link\&utm_campaign=in_unit\&utm_term=carbon)

### Configuration

Applications often run in different **environments**, and each environment needs its own configuration settings. For example, the local environment typically relies on database credentials that are valid only for the local database instance, while the production environment uses a separate set of credentials. Since configuration variables change between environments, best practice is to [store configuration variables](https://12factor.net/config) in the environment.

Externally defined environment variables are visible inside Node.js through the `process.env` global. You could handle multiple environments by setting the environment variables separately in each one. This quickly gets unwieldy, especially in development and testing environments, where these values need to be easy to mock or change.

In Node.js applications, it's common to represent each environment with a `.env` file that holds key-value pairs. Running an app in a different environment is then a matter of swapping in the correct `.env` file.

A good way to apply this technique in Nest is to create a `ConfigModule` that exposes a `ConfigService`, which loads the appropriate `.env` file. You can write such a module yourself, but for convenience, Nest provides the `@nestjs/config` package. This chapter covers that package.

#### Installation[#](/application/configuration#installation)

To get started, install the required dependency:

```bash

$ npm i --save @nestjs/config
```

> **Hint** The `@nestjs/config` package internally uses [dotenv](https://github.com/motdotla/dotenv).

> **Note**`@nestjs/config` requires TypeScript 4.1 or later.

#### Getting started[#](/application/configuration#getting-started)

Once the installation is complete, import the `ConfigModule`. Typically, you import it into the root `AppModule` and control its behavior with the `.forRoot()` static method. During this step, environment variable key/value pairs are parsed and resolved. Later, you'll see several options for accessing the `ConfigService` class of the `ConfigModule` in other feature modules.

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';

@Module({
  imports: [ConfigModule.forRoot()],
})
export class AppModule {}
```

This code loads and parses a `.env` file from the default location (the directory the process is started from, typically the project root), merges the key/value pairs from the `.env` file with the environment variables assigned to `process.env`, and stores the result in a private structure that you can access through the `ConfigService`. The `forRoot()` method registers the `ConfigService` provider, which provides a `get()` method for reading these parsed and merged configuration variables. Since `@nestjs/config` relies on [dotenv](https://github.com/motdotla/dotenv), it uses that package's rules for resolving conflicts in environment variable names. When a key exists both in the runtime environment (e.g., set through a shell export like `export DATABASE_USER=test`) and in a `.env` file, the runtime environment variable takes precedence. To let values from the `.env` file win instead, set the `override` option to `true`.

A sample `.env` file looks like this:

```json

DATABASE_USER=test
DATABASE_PASSWORD=test
```

If you need some environment variables to be available before the `ConfigModule` is loaded and the Nest application is bootstrapped (for example, to pass the microservice configuration to the `NestFactory#createMicroservice()` method), use the `--env-file` option of the Nest CLI. It specifies the path to a `.env` file to load before the application starts. The CLI passes the file to the Node.js `--env-file` flag; see the [Node.js documentation](https://nodejs.org/dist/v20.18.1/docs/api/cli.html#--env-fileconfig) for details.

```bash

$ nest start --env-file .env
```

#### Custom env file path[#](/application/configuration#custom-env-file-path)

By default, the package looks for a `.env` file in the current working directory (typically the root directory of the application). To specify another path for the `.env` file, set the `envFilePath` property of the optional options object you pass to `forRoot()`, as follows:

```typescript

ConfigModule.forRoot({
  envFilePath: '.development.env',
});
```

You can also specify multiple paths for `.env` files:

```typescript

ConfigModule.forRoot({
  envFilePath: ['.env.development.local', '.env.development'],
});
```

If a variable is found in multiple files, the first one takes precedence.

#### Disable env variables loading[#](/application/configuration#disable-env-variables-loading)

If you don't want to load the `.env` file and only want to access environment variables from the runtime environment (e.g., set through shell exports like `export DATABASE_USER=test`), set the `ignoreEnvFile` property of the options object to `true`:

```typescript

ConfigModule.forRoot({
  ignoreEnvFile: true,
});
```

#### Use module globally[#](/application/configuration#use-module-globally)

To use `ConfigModule` in other modules, you need to import it (as with any Nest module). Alternatively, declare it as a [global module](/modules#global-modules) by setting the `isGlobal` property of the options object to `true`, as shown below. In that case, once `ConfigModule` is loaded in the root module (e.g., `AppModule`), you don't need to import it in other modules.

```typescript

ConfigModule.forRoot({
  isGlobal: true,
});
```

#### Custom configuration files[#](/application/configuration#custom-configuration-files)

For more complex projects, you can use custom configuration files that return nested configuration objects. This lets you group related configuration settings by function (e.g., database-related settings) and store them in individual files, so you can manage them independently.

A custom configuration file exports a factory function that returns a configuration object. The configuration object can be any arbitrarily nested plain JavaScript object. Inside the factory, the `process.env` object contains the fully resolved environment variable key/value pairs (with the `.env` file and externally defined variables resolved and merged as described in [Getting started](/application/configuration#getting-started)). Since you control the returned configuration object, you can add any logic you need to cast values to the appropriate type, set default values, and so on. For example:

config/configuration.ts

JS TS

```typescript

export default () => ({
  port: parseInt(process.env.PORT ?? '', 10) || 3000,
  database: {
    host: process.env.DATABASE_HOST,
    port: parseInt(process.env.DATABASE_PORT ?? '', 10) || 5432
  }
});
```

Load this file with the `load` property of the options object you pass to the `ConfigModule.forRoot()` method:

```typescript

import configuration from './config/configuration.js';

@Module({
  imports: [
    ConfigModule.forRoot({
      load: [configuration],
    }),
  ],
})
export class AppModule {}
```

> **Hint** The value assigned to the `load` property is an array, so you can load multiple configuration files (e.g., `load: [databaseConfig, authConfig]`).

Custom configuration files also let you load configuration from other formats, such as YAML. Here is an example of a configuration in YAML format:

```yaml

http:
  host: 'localhost'
  port: 8080

db:
  postgres:
    url: 'localhost'
    port: 5432
    database: 'yaml-db'

  sqlite:
    database: 'sqlite.db'
```

To read and parse YAML files, you can use the `js-yaml` package:

```bash

$ npm i js-yaml
$ npm i -D @types/js-yaml
```

Once the package is installed, use the `yaml#load` function to load the YAML file created above:

config/configuration.ts

JS TS

```typescript

import { readFileSync } from 'node:fs';
import { join } from 'node:path';
import yaml from 'js-yaml';

const YAML_CONFIG_FILENAME = 'config.yaml';

export default () => {
  return yaml.load(
    readFileSync(join(import.meta.dirname, YAML_CONFIG_FILENAME), 'utf8'),
  ) as Record<string, any>;
};
```

> **Note** The Nest CLI doesn't automatically copy your "assets" (non-TS files) to the `dist` folder during the build process. To make sure that your YAML files are copied, specify them in the `compilerOptions#assets` object in the `nest-cli.json` file. As an example, if the `config` folder is at the same level as the `src` folder, add `compilerOptions#assets` with the value `"assets": [{"include": "../config/*.yaml", "outDir": "./dist/config"}]`. See [Assets](/cli/monorepo#assets) for details.

Configuration files aren't validated automatically, even if you use the `validationSchema` option of the `ConfigModule` (it only applies to environment variables). If you need validation or want to apply transformations, handle them in the factory function, where you have full control over the configuration object.

For example, to ensure that the port is within a certain range, add a validation step to the factory function:

config/configuration.ts

JS TS

```typescript

export default () => {
  const config = yaml.load(
    readFileSync(join(import.meta.dirname, YAML_CONFIG_FILENAME), 'utf8'),
  ) as Record<string, any>;

  if (config.http.port < 1024 || config.http.port > 49151) {
    throw new Error('HTTP port must be between 1024 and 49151');
  }

  return config;
};
```

Now, if the port is outside the specified range, the application throws an error during startup.

## Debug production with NestJS Observe

* Every request traced
* Errors with source code
* Logs in context
* Zero config, free plan

[Start for free](https://observe.nestjs.com "Observe | NestJS - A progressive Node.js framework")

#### Using the `ConfigService`[#](/application/configuration#using-the-configservice)

To access configuration values, first inject `ConfigService`. As with any provider, you need to import its containing module, the `ConfigModule`, into the module that uses it (unless you set the `isGlobal` property of the options object passed to `ConfigModule.forRoot()` to `true`). Import it into a feature module as shown below:

feature.module.ts

JS TS

```typescript

@Module({
  imports: [ConfigModule],
  // ...
})
```

Then inject it through the constructor:

```typescript

constructor(private configService: ConfigService) {}
```

> **Hint** Import `ConfigService` from the `@nestjs/config` package.

Then use it in your class:

```typescript

// get an environment variable
const dbUser = this.configService.get<string>('DATABASE_USER');

// get a custom configuration value
const dbHost = this.configService.get<string>('database.host');
```

As shown above, use the `configService.get()` method to get a simple environment variable by passing the variable name. You can pass a type argument as a TypeScript type hint (e.g., `get<string>(...)`). The `get()` method can also traverse a nested custom configuration object (created with a [custom configuration file](/application/configuration#custom-configuration-files)), as shown in the second example.

You can also get the whole nested custom configuration object using an interface as the type hint:

```typescript

interface DatabaseConfig {
  host: string;
  port: number;
}

const dbConfig = this.configService.get<DatabaseConfig>('database');

// you can now use `dbConfig.port` and `dbConfig.host`
const port = dbConfig.port;
```

The `get()` method also takes an optional second argument that defines a default value, returned when the key doesn't exist:

```typescript

// use "localhost" when "database.host" is not defined
const dbHost = this.configService.get<string>('database.host', 'localhost');
```

If a value is required, use the `getOrThrow()` method instead. It accepts the same arguments as `get()`, but throws an error if the resolved value is `undefined`, and its return type excludes `undefined`:

```typescript

// throws if "DATABASE_USER" is not defined
const dbUser = this.configService.getOrThrow<string>('DATABASE_USER');
```

`ConfigService` has two optional generics (type arguments). The first one helps prevent accessing a configuration property that doesn't exist:

```typescript

interface EnvironmentVariables {
  PORT: number;
  TIMEOUT: string;
}

// somewhere in the code
constructor(private configService: ConfigService<EnvironmentVariables>) {
  const port = this.configService.get('PORT', { infer: true });

  // TypeScript Error: this is invalid as the URL property is not defined in EnvironmentVariables
  const url = this.configService.get('URL', { infer: true });
}
```

With the `infer` property set to `true`, the `ConfigService#get` method infers the property type from the interface. For example, `port` is typed as `number`, since `PORT` has a `number` type in the `EnvironmentVariables` interface (with the `strictNullChecks` compiler option enabled, the type is `number | undefined`).

With the `infer` feature, you can also infer the type of a nested custom configuration object's property, even when using dot notation:

```typescript

constructor(private configService: ConfigService<{ database: { host: string } }>) {
  const dbHost = this.configService.get('database.host', { infer: true })!;
  // typeof dbHost === "string"                                          |
  //                                                                     +--> non-null assertion operator
}
```

The second generic relies on the first one. It acts as a type assertion that removes the `undefined` type that the `ConfigService` methods can return when `strictNullChecks` is enabled. For instance:

```typescript

// ...
constructor(private configService: ConfigService<{ PORT: number }, true>) {
  //                                                               ^^^^
  const port = this.configService.get('PORT', { infer: true });
  //    ^^^ The type of port is 'number', so you don't need TS type assertions
}
```

> **Hint** To make the `ConfigService#get` method ignore `process.env` variables and retrieve values only from custom configuration files (and from validated environment variables, if you use validation), set the `skipProcessEnv` option to `true` in the options object passed to `ConfigModule.forRoot()`.

#### Configuration namespaces[#](/application/configuration#configuration-namespaces)

The `ConfigModule` lets you define and load multiple custom configuration files, as shown in [Custom configuration files](/application/configuration#custom-configuration-files) above. You can manage complex configuration hierarchies with nested configuration objects, as shown in that section. Alternatively, you can return a "namespaced" configuration object with the `registerAs()` function, as follows:

config/database.config.ts

JS TS

```typescript

export default registerAs('database', () => ({
  host: process.env.DATABASE_HOST,
  port: process.env.DATABASE_PORT || 5432
}));
```

As with custom configuration files, inside your `registerAs()` factory function, the `process.env` object contains the fully resolved environment variable key/value pairs (with the `.env` file and externally defined variables resolved and merged as described in [Getting started](/application/configuration#getting-started)).

> **Hint** The `registerAs()` function is exported from the `@nestjs/config` package.

Load a namespaced configuration with the `load` property of the `forRoot()` method's options object, in the same way you load a custom configuration file:

```typescript

import databaseConfig from './config/database.config.js';

@Module({
  imports: [
    ConfigModule.forRoot({
      load: [databaseConfig],
    }),
  ],
})
export class AppModule {}
```

To get the `host` value from the `database` namespace, use dot notation. Use `'database'` as the prefix of the property name. It corresponds to the name of the namespace (passed as the first argument to the `registerAs()` function):

```typescript

const dbHost = this.configService.get<string>('database.host');
```

Alternatively, you can inject the `database` namespace directly, which gives you strong typing:

```typescript

constructor(
  @Inject(databaseConfig.KEY)
  private dbConfig: ConfigType<typeof databaseConfig>,
) {}
```

> **Hint** The `ConfigType` type is exported from the `@nestjs/config` package.

#### Namespaced configurations in modules[#](/application/configuration#namespaced-configurations-in-modules)

To use a namespaced configuration as the configuration object of another module in your application, use the `.asProvider()` method of the configuration object. This method converts your namespaced configuration into a provider definition that you can pass to the `forRootAsync()` method (or equivalent) of the module you want to configure:

```typescript

import databaseConfig from './config/database.config.js';

@Module({
  imports: [
    TypeOrmModule.forRootAsync(databaseConfig.asProvider()),
  ],
})
```

To understand how the `.asProvider()` method works, look at its return value:

```typescript

// Return value of the .asProvider() method
{
  imports: [ConfigModule.forFeature(databaseConfig)],
  useFactory: (configuration: ConfigType<typeof databaseConfig>) => configuration,
  inject: [databaseConfig.KEY]
}
```

This structure lets you plug namespaced configurations into other modules without writing repetitive boilerplate code, which keeps your application organized and modular.

#### Cache environment variables[#](/application/configuration#cache-environment-variables)

Accessing `process.env` can be slow. To improve the performance of the `ConfigService#get` method for variables stored in `process.env`, set the `cache` property of the options object passed to `ConfigModule.forRoot()`:

```typescript

ConfigModule.forRoot({
  cache: true,
});
```

#### Partial registration[#](/application/configuration#partial-registration)

So far, we've processed configuration files in the root module (e.g., `AppModule`) with the `forRoot()` method. In a more complex project structure, you may have feature-specific configuration files located in several different directories. Rather than loading all these files in the root module, you can use a feature of the `@nestjs/config` package called **partial registration**, which references only the configuration files associated with each feature module. Use the `forFeature()` static method within a feature module to perform partial registration, as follows:

```typescript

import databaseConfig from './config/database.config.js';

@Module({
  imports: [ConfigModule.forFeature(databaseConfig)],
})
export class DatabaseModule {}
```

> **Warning** In some circumstances, you may need to access properties loaded through partial registration in the `onModuleInit()` hook rather than in a constructor. This is because the `forFeature()` method runs during module initialization, and the order of module initialization is indeterminate. If you access values loaded this way by another module in a constructor, the module that the configuration depends on may not have initialized yet. The `onModuleInit()` method runs only after all the modules it depends on have been initialized, so this technique is safe.

#### Schema validation[#](/application/configuration#schema-validation)

It's standard practice to throw an exception during application startup if required environment variables haven't been provided or don't meet certain validation rules. The `@nestjs/config` package supports two ways to do this:

* A [Standard Schema](https://standardschema.dev/)-compatible schema passed through the `validationSchema` option. Any library that implements the specification works, such as [Zod](https://zod.dev/), [Valibot](https://valibot.dev/), and [ArkType](https://arktype.io/).
* A custom `validate()` function that takes the environment variables as input.

Install the validation library of your choice. This example uses Zod:

```bash

$ npm install --save zod
```

Now define a validation schema and pass it through the `validationSchema` property of the options object passed to `forRoot()`, as shown below:

app.module.ts

JS TS

```typescript

import { z } from 'zod';

@Module({
  imports: [
    ConfigModule.forRoot({
      validationSchema: z.object({
        NODE_ENV: z
          .enum(['development', 'production', 'test', 'provision'])
          .default('development'),
        PORT: z.coerce.number().default(3000),
      }),
    }),
  ],
})
export class AppModule {}
```

This schema sets default values for `NODE_ENV` and `PORT`, which are used if you don't provide these variables in the environment (`.env` file or process environment). To require a variable instead, leave it without a default. The validation step then throws an exception during bootstrap if the variable is missing.

Environment variables always arrive as strings, which is why `PORT` uses `z.coerce.number()`. `ConfigService` serves the values returned by the schema, so coercions and transformations declared in the schema apply to the configuration your application reads. Variables that the schema doesn't declare remain available through `ConfigService` as well.

By default, unknown environment variables (the many unrelated entries that `process.env` always carries, such as `PATH` and `HOME`) don't trigger a validation exception, and every failing variable is reported rather than only the first. Each validation error is formatted as `PATH: message`, and the errors are joined by newlines.

You can forward library-specific options through the `validationOptions` key. Because the option is typed against the Standard Schema specification, library-specific settings go under `libraryOptions`:

app.module.ts

JS TS

```typescript

import { z } from 'zod';

@Module({
  imports: [
    ConfigModule.forRoot({
      validationSchema: z.object({
        NODE_ENV: z
          .enum(['development', 'production', 'test', 'provision'])
          .default('development'),
        PORT: z.coerce.number().default(3000),
      }),
      validationOptions: {
        libraryOptions: {
          // options specific to your validation library
        },
      },
    }),
  ],
})
export class AppModule {}
```

> **Hint** Joi is still supported, but it requires **Joi v18 or later**, which implements the Standard Schema specification. Pass `Joi.object({ ... })` to `validationSchema` as before, and put Joi settings such as `allowUnknown` and `abortEarly` under `validationOptions.libraryOptions`. For Joi schemas, `@nestjs/config` keeps its historical defaults of `allowUnknown: true` and `abortEarly: false`, and merges the options you pass on top of them. For new projects, we recommend a modern Standard Schema library such as Zod instead.

> **Hint** To disable validation of predefined environment variables, set the `validatePredefined` property to `false` in the options object passed to `forRoot()`. Predefined environment variables are process variables (`process.env` variables) that were set before the module was imported. For example, if you start your application with `PORT=3000 node main.js`, then `PORT` is a predefined environment variable.

#### Custom validate function[#](/application/configuration#custom-validate-function)

Alternatively, you can specify a **synchronous**`validate` function. It takes an object containing the environment variables (from the `.env` file and the process) and returns an object containing the validated environment variables, so you can convert or modify them if needed. If the function throws an error, the application doesn't bootstrap.

This example uses the `class-transformer` and `class-validator` packages. First, define:

* a class with validation constraints,
* a validate function that makes use of the `plainToInstance` and `validateSync` functions.

env.validation.ts

JS TS

```typescript

import { plainToInstance } from 'class-transformer';
import { IsEnum, IsNumber, Max, Min, validateSync } from 'class-validator';

enum Environment {
  Development = "development",
  Production = "production",
  Test = "test",
  Provision = "provision",
}

class EnvironmentVariables {
  @IsEnum(Environment)
  NODE_ENV: Environment;

  @IsNumber()
  @Min(0)
  @Max(65535)
  PORT: number;
}

export function validate(config: Record<string, unknown>) {
  const validatedConfig = plainToInstance(
    EnvironmentVariables,
    config,
    { enableImplicitConversion: true },
  );
  const errors = validateSync(validatedConfig, { skipMissingProperties: false });

  if (errors.length > 0) {
    throw new Error(errors.toString());
  }
  return validatedConfig;
}
```

With this in place, pass the `validate` function as a configuration option of the `ConfigModule`:

app.module.ts

JS TS

```typescript

import { validate } from './env.validation.js';

@Module({
  imports: [
    ConfigModule.forRoot({
      validate,
    }),
  ],
})
export class AppModule {}
```

#### Custom getter functions[#](/application/configuration#custom-getter-functions)

`ConfigService` defines a generic `get()` method that retrieves a configuration value by key. You can also add getter functions for a more natural coding style:

api-config.service.ts

JS TS

```typescript

@Injectable()
export class ApiConfigService {
  constructor(private configService: ConfigService) {}

  get isAuthEnabled(): boolean {
    return this.configService.get('AUTH_ENABLED') === 'true';
  }
}
```

```typescript

@Dependencies(ConfigService)
@Injectable()
export class ApiConfigService {
  constructor(configService) {
    this.configService = configService;
  }

  get isAuthEnabled() {
    return this.configService.get('AUTH_ENABLED') === 'true';
  }
}
```

> **Hint** This example assumes that `AUTH_ENABLED` is a string. If your validation schema converts it to a boolean, `get()` returns the converted value, so return `this.configService.get<boolean>('AUTH_ENABLED')` directly instead of comparing it with `'true'`.

Now you can use the getter function as follows:

app.service.ts

JS TS

```typescript

@Injectable()
export class AppService {
  constructor(apiConfigService: ApiConfigService) {
    if (apiConfigService.isAuthEnabled) {
      // Authentication is enabled
    }
  }
}
```

```typescript

@Dependencies(ApiConfigService)
@Injectable()
export class AppService {
  constructor(apiConfigService) {
    if (apiConfigService.isAuthEnabled) {
      // Authentication is enabled
    }
  }
}
```

#### Environment variables loaded hook[#](/application/configuration#environment-variables-loaded-hook)

If a module configuration depends on environment variables loaded from the `.env` file, use the `ConfigModule.envVariablesLoaded` hook to ensure that the file has been loaded before you read the `process.env` object:

```typescript

export async function getStorageModule() {
  await ConfigModule.envVariablesLoaded;
  return process.env.STORAGE === 'S3' ? S3StorageModule : DefaultStorageModule;
}
```

This construction guarantees that all configuration variables are loaded once the `ConfigModule.envVariablesLoaded` promise resolves.

#### Conditional module configuration[#](/application/configuration#conditional-module-configuration)

Sometimes you may want to load a module conditionally and specify the condition in an environment variable. The `@nestjs/config` package provides a `ConditionalModule` for this purpose.

```typescript

@Module({
  imports: [
    ConfigModule.forRoot(),
    ConditionalModule.registerWhen(FooModule, 'USE_FOO'),
  ],
})
export class AppModule {}
```

This module loads the `FooModule` unless the `USE_FOO` environment variable is set to `false` (case-insensitive). If the variable isn't defined, `FooModule` is loaded. You can also pass a custom condition: a function that receives the `process.env` reference and returns a boolean:

```typescript

@Module({
  imports: [
    ConfigModule.forRoot(),
    ConditionalModule.registerWhen(
      FooBarModule,
      (env: NodeJS.ProcessEnv) => !!env['foo'] && !!env['bar'],
    ),
  ],
})
export class AppModule {}
```

When you use the `ConditionalModule`, make sure the `ConfigModule` is also loaded in the application, so that the `ConfigModule.envVariablesLoaded` hook resolves. If the hook doesn't resolve within 5 seconds (or within the timeout, in milliseconds, set through the `timeout` property of the third `options` argument of the `registerWhen()` method), the `ConditionalModule` throws an error and Nest aborts starting the application.

#### Expandable variables[#](/application/configuration#expandable-variables)

The `@nestjs/config` package supports environment variable expansion. With this technique, you can create nested environment variables, where one variable is referenced within the definition of another. For example:

```json

APP_URL=mywebsite.com
SUPPORT_EMAIL=support@${APP_URL}
```

With this construction, the variable `SUPPORT_EMAIL` resolves to `'support@mywebsite.com'`. The `${...}` syntax triggers resolving the value of the variable `APP_URL` inside the definition of `SUPPORT_EMAIL`.

> **Hint** For this feature, the `@nestjs/config` package internally uses [dotenv-expand](https://github.com/motdotla/dotenv-expand).

Enable environment variable expansion with the `expandVariables` property of the options object passed to `ConfigModule.forRoot()`, as shown below. Instead of `true`, you can also pass an object with options for `dotenv-expand`.

app.module.ts

JS TS

```typescript

@Module({
  imports: [
    ConfigModule.forRoot({
      // ...
      expandVariables: true,
    }),
  ],
})
export class AppModule {}
```

#### Using in the `main.ts`[#](/application/configuration#using-in-the-maints)

Although the configuration is stored in a service, you can still use it in the `main.ts` file, for example, to read variables such as the application port or the CORS host.

To access it, use the `app.get()` method with the service class:

```typescript

const configService = app.get(ConfigService);
```

You can then use it as usual, by calling the `get()` method with the configuration key:

```typescript

const port = configService.get('PORT');
```

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/application/configuration.md)

----
url: https://docs.nestjs.com/v11/microservices/pipes
----

* [Pipes](https://docs.nestjs.com/v11/microservices/pipes#pipes)
* [Binding pipes](https://docs.nestjs.com/v11/microservices/pipes#binding-pipes)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/microservices/pipes.md "Suggest Edits")

### Pipes

There is no fundamental difference between [regular pipes](/v11/pipes) and microservices pipes. The only difference is that instead of throwing `HttpException`, you should use `RpcException`.

> **Hint** The `RpcException` class is exposed from `@nestjs/microservices` package.

#### Binding pipes[#](/microservices/pipes#binding-pipes)

The following example uses a manually instantiated method-scoped pipe. Just as with HTTP based applications, you can also use controller-scoped pipes (i.e., prefix the controller class with a `@UsePipes()` decorator).

JS TS

```typescript

@UsePipes(new ValidationPipe({ exceptionFactory: (errors) => new RpcException(errors) }))
@MessagePattern({ cmd: 'sum' })
accumulate(data: number[]): number {
  return (data || []).reduce((a, b) => a + b);
}
```

```typescript

@UsePipes(new ValidationPipe({ exceptionFactory: (errors) => new RpcException(errors) }))
@MessagePattern({ cmd: 'sum' })
accumulate(data) {
  return (data || []).reduce((a, b) => a + b);
}
```

----
url: https://docs.nestjs.com/v9/modules
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Modules](https://docs.nestjs.com/v9/modules#modules)
* [Feature modules](https://docs.nestjs.com/v9/modules#feature-modules)
* [Shared modules](https://docs.nestjs.com/v9/modules#shared-modules)
* [Module re-exporting](https://docs.nestjs.com/v9/modules#module-re-exporting)
* [Dependency injection](https://docs.nestjs.com/v9/modules#dependency-injection)
* [Global modules](https://docs.nestjs.com/v9/modules#global-modules)
* [Dynamic modules](https://docs.nestjs.com/v9/modules#dynamic-modules)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/modules.md "Suggest Edits")

### Modules

A module is a class annotated with a `@Module()` decorator. The `@Module()` decorator provides metadata that **Nest** makes use of to organize the application structure.

Each application has at least one module, a **root module**. The root module is the starting point Nest uses to build the **application graph** - the internal data structure Nest uses to resolve module and provider relationships and dependencies. While very small applications may theoretically have just the root module, this is not the typical case. We want to emphasize that modules are **strongly** recommended as an effective way to organize your components. Thus, for most applications, the resulting architecture will employ multiple modules, each encapsulating a closely related set of **capabilities**.

The `@Module()` decorator takes a single object whose properties describe the module:

| `providers`   | the providers that will be instantiated by the Nest injector and that may be shared at least across this module                                                                                          |
| ------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `controllers` | the set of controllers defined in this module which have to be instantiated                                                                                                                              |
| `imports`     | the list of imported modules that export the providers which are required in this module                                                                                                                 |
| `exports`     | the subset of `providers` that are provided by this module and should be available in other modules which import this module. You can use either the provider itself or just its token (`provide` value) |

The module **encapsulates** providers by default. This means that it's impossible to inject providers that are neither directly part of the current module nor exported from the imported modules. Thus, you may consider the exported providers from a module as the module's public interface, or API.

#### Feature modules[#](/modules#feature-modules)

The `CatsController` and `CatsService` belong to the same application domain. As they are closely related, it makes sense to move them into a feature module. A feature module simply organizes code relevant for a specific feature, keeping code organized and establishing clear boundaries. This helps us manage complexity and develop with [SOLID](https://en.wikipedia.org/wiki/SOLID) principles, especially as the size of the application and/or team grow.

To demonstrate this, we'll create the `CatsModule`.

cats/cats.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

@Module({
  controllers: [CatsController],
  providers: [CatsService],
})
export class CatsModule {}
```

> **Hint** To create a module using the CLI, simply execute the `$ nest g module cats` command.

Above, we defined the `CatsModule` in the `cats.module.ts` file, and moved everything related to this module into the `cats` directory. The last thing we need to do is import this module into the root module (the `AppModule`, defined in the `app.module.ts` file).

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { CatsModule } from './cats/cats.module';

@Module({
  imports: [CatsModule],
})
export class AppModule {}
```

```typescript

import { Module } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

@Module({
  controllers: [CatsController],
  providers: [CatsService],
  exports: [CatsService]
})
export class CatsModule {}
```

Now any module that imports the `CatsModule` has access to the `CatsService` and will share the same instance with all other modules that import it as well.

```typescript

@Module({
  imports: [CommonModule],
  exports: [CommonModule],
})
export class CoreModule {}
```

#### Dependency injection[#](/modules#dependency-injection)

A module class can **inject** providers as well (e.g., for configuration purposes):

cats.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

@Module({
  controllers: [CatsController],
  providers: [CatsService],
})
export class CatsModule {
  constructor(private catsService: CatsService) {}
}
```

```typescript

import { Module, Dependencies } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

@Module({
  controllers: [CatsController],
  providers: [CatsService],
})
@Dependencies(CatsService)
export class CatsModule {
  constructor(catsService) {
    this.catsService = catsService;
  }
}
```

However, module classes themselves cannot be injected as providers due to [circular dependency](/v9/fundamentals/circular-dependency) .

#### Global modules[#](/modules#global-modules)

If you have to import the same set of modules everywhere, it can get tedious. Unlike in Nest, [Angular](https://angular.io)`providers` are registered in the global scope. Once defined, they're available everywhere. Nest, however, encapsulates providers inside the module scope. You aren't able to use a module's providers elsewhere without first importing the encapsulating module.

When you want to provide a set of providers which should be available everywhere out-of-the-box (e.g., helpers, database connections, etc.), make the module **global** with the `@Global()` decorator.

```typescript

import { Module, Global } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

@Global()
@Module({
  controllers: [CatsController],
  providers: [CatsService],
  exports: [CatsService],
})
export class CatsModule {}
```

The `@Global()` decorator makes the module global-scoped. Global modules should be registered **only once**, generally by the root or core module. In the above example, the `CatsService` provider will be ubiquitous, and modules that wish to inject the service will not need to import the `CatsModule` in their imports array.

> **Hint** Making everything global is not a good design decision. Global modules are available to reduce the amount of necessary boilerplate. The `imports` array is generally the preferred way to make the module's API available to consumers.

#### Dynamic modules[#](/modules#dynamic-modules)

The Nest module system includes a powerful feature called **dynamic modules**. This feature enables you to easily create customizable modules that can register and configure providers dynamically. Dynamic modules are covered extensively [here](/v9/fundamentals/dynamic-modules). In this chapter, we'll give a brief overview to complete the introduction to modules.

Following is an example of a dynamic module definition for a `DatabaseModule`:

JS TS

```typescript

import { Module, DynamicModule } from '@nestjs/common';
import { createDatabaseProviders } from './database.providers';
import { Connection } from './connection.provider';

@Module({
  providers: [Connection],
})
export class DatabaseModule {
  static forRoot(entities = [], options?): DynamicModule {
    const providers = createDatabaseProviders(options, entities);
    return {
      module: DatabaseModule,
      providers: providers,
      exports: providers,
    };
  }
}
```

```typescript

import { Module } from '@nestjs/common';
import { createDatabaseProviders } from './database.providers';
import { Connection } from './connection.provider';

@Module({
  providers: [Connection],
})
export class DatabaseModule {
  static forRoot(entities = [], options) {
    const providers = createDatabaseProviders(options, entities);
    return {
      module: DatabaseModule,
      providers: providers,
      exports: providers,
    };
  }
}
```

> **Hint** The `forRoot()` method may return a dynamic module either synchronously or asynchronously (i.e., via a `Promise`).

This module defines the `Connection` provider by default (in the `@Module()` decorator metadata), but additionally - depending on the `entities` and `options` objects passed into the `forRoot()` method - exposes a collection of providers, for example, repositories. Note that the properties returned by the dynamic module **extend** (rather than override) the base module metadata defined in the `@Module()` decorator. That's how both the statically declared `Connection` provider **and** the dynamically generated repository providers are exported from the module.

If you want to register a dynamic module in the global scope, set the `global` property to `true`.

```typescript

{
  global: true,
  module: DatabaseModule,
  providers: providers,
  exports: providers,
}
```

> **Warning** As mentioned above, making everything global **is not a good design decision**.

The `DatabaseModule` can be imported and configured in the following manner:

```typescript

import { Module } from '@nestjs/common';
import { DatabaseModule } from './database/database.module';
import { User } from './users/entities/user.entity';

@Module({
  imports: [DatabaseModule.forRoot([User])],
})
export class AppModule {}
```

If you want to in turn re-export a dynamic module, you can omit the `forRoot()` method call in the exports array:

```typescript

import { Module } from '@nestjs/common';
import { DatabaseModule } from './database/database.module';
import { User } from './users/entities/user.entity';

@Module({
  imports: [DatabaseModule.forRoot([User])],
  exports: [DatabaseModule],
})
export class AppModule {}
```

The [Dynamic modules](/v9/fundamentals/dynamic-modules) chapter covers this topic in greater detail, and includes a [working example](https://github.com/nestjs/nest/tree/master/sample/25-dynamic-modules).

> **Hint** Learn how to build highly customizable dynamic modules with the use of `ConfigurableModuleBuilder` here in [this chapter](/fundamentals/dynamic-modules#configurable-module-builder).

----
url: https://docs.nestjs.com/v7/recipes/hot-reload
----

* [Hot Reload](https://docs.nestjs.com/v7/recipes/hot-reload#hot-reload)
* [With CLI](https://docs.nestjs.com/v7/recipes/hot-reload#with-cli)
* [Installation](https://docs.nestjs.com/v7/recipes/hot-reload#installation)
* [Configuration](https://docs.nestjs.com/v7/recipes/hot-reload#configuration)
* [Hot-Module Replacement](https://docs.nestjs.com/v7/recipes/hot-reload#hot-module-replacement)
* [Without CLI](https://docs.nestjs.com/v7/recipes/hot-reload#without-cli)
* [Installation](https://docs.nestjs.com/v7/recipes/hot-reload#installation-1)
* [Configuration](https://docs.nestjs.com/v7/recipes/hot-reload#configuration-1)
* [Hot-Module Replacement](https://docs.nestjs.com/v7/recipes/hot-reload#hot-module-replacement-1)
* [Example](https://docs.nestjs.com/v7/recipes/hot-reload#example)
* [TypeORM](https://docs.nestjs.com/v7/recipes/hot-reload#typeorm)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/recipes/hot-reload.md "Suggest Edits")

### Hot Reload

The highest impact on your application's bootstrapping process is **TypeScript compilation**. Fortunately, with [webpack](https://github.com/webpack/webpack) HMR (Hot-Module Replacement), we don't need to recompile the entire project each time a change occurs. This significantly decreases the amount of time necessary to instantiate your application, and makes iterative development a lot easier.

> **Warning** Note that `webpack` won't automatically copy your assets (e.g. `graphql` files) to the `dist` folder. Similarly, `webpack` is not compatible with glob static paths (e.g., the `entities` property in `TypeOrmModule`).

### With CLI

If you are using the [Nest CLI](https://docs.nestjs.com/cli/overview), the configuration process is pretty straightforward. The CLI wraps `webpack`, which allows use of the `HotModuleReplacementPlugin`.

#### Installation[#](/recipes/hot-reload#installation)

First install the required packages:

```bash

$ npm i --save-dev webpack-node-externals run-script-webpack-plugin webpack
```

> **Hint** If you use **Yarn Berry** (not classic Yarn), install the `webpack-pnp-externals` package instead of the `webpack-node-externals`.

#### Configuration[#](/recipes/hot-reload#configuration)

Once the installation is complete, create a `webpack-hmr.config.js` file in the root directory of your application.

```typescript

const nodeExternals = require('webpack-node-externals');
const { RunScriptWebpackPlugin } = require('run-script-webpack-plugin');

module.exports = function (options, webpack) {
  return {
    ...options,
    entry: ['webpack/hot/poll?100', options.entry],
    watch: true,
    externals: [
      nodeExternals({
        allowlist: ['webpack/hot/poll?100'],
      }),
    ],
    plugins: [
      ...options.plugins,
      new webpack.HotModuleReplacementPlugin(),
      new webpack.WatchIgnorePlugin({
        paths: [/\.js$/, /\.d\.ts$/],
      }),
      new RunScriptWebpackPlugin({ name: options.output.filename }),
    ],
  };
};
```

> **Hint** With **Yarn Berry** (not classic Yarn), instead of using the `nodeExternals` in the `externals` configuration property, use the `WebpackPnpExternals` from `webpack-pnp-externals` package: `WebpackPnpExternals({ exclude: ['webpack/hot/poll?100'] })`.

This function takes the original object containing the default webpack configuration as a first argument, and the reference to the underlying `webpack` package used by the Nest CLI as the second one. Also, it returns a modified webpack configuration with the `HotModuleReplacementPlugin`, `WatchIgnorePlugin`, and `RunScriptWebpackPlugin` plugins.

#### Hot-Module Replacement[#](/recipes/hot-reload#hot-module-replacement)

To enable **HMR**, open the application entry file (`main.ts`) and add the following webpack-related instructions:

```typescript

declare const module: any;

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  await app.listen(3000);

  if (module.hot) {
    module.hot.accept();
    module.hot.dispose(() => app.close());
  }
}
bootstrap();
```

To simplify the execution process, add a script to your `package.json` file.

```json

"start:dev": "nest build --webpack --webpackPath webpack-hmr.config.js"
```

Now simply open your command line and run the following command:

```bash

$ npm run start:dev
```

### Without CLI

If you are not using the [Nest CLI](https://docs.nestjs.com/cli/overview), the configuration will be slightly more complex (will require more manual steps).

#### Installation[#](/recipes/hot-reload#installation-1)

First install the required packages:

```bash

$ npm i --save-dev webpack webpack-cli webpack-node-externals ts-loader run-script-webpack-plugin
```

> **Hint** If you use **Yarn Berry** (not classic Yarn), install the `webpack-pnp-externals` package instead of the `webpack-node-externals`.

#### Configuration[#](/recipes/hot-reload#configuration-1)

Once the installation is complete, create a `webpack.config.js` file in the root directory of your application.

##### With NPM or Yarn classic

```typescript

const webpack = require('webpack');
const path = require('path');
const nodeExternals = require('webpack-node-externals');
const { RunScriptWebpackPlugin } = require('run-script-webpack-plugin');

module.exports = {
  entry: ['webpack/hot/poll?100', './src/main.ts'],
  watch: true,
  target: 'node',
  externals: [
    nodeExternals({
      allowlist: ['webpack/hot/poll?100'],
    }),
  ],
  module: {
    rules: [
      {
        test: /.tsx?$/,
        use: 'ts-loader',
        exclude: /node_modules/,
      },
    ],
  },
  mode: 'development',
  resolve: {
    extensions: ['.tsx', '.ts', '.js'],
  },
  plugins: [
    new webpack.HotModuleReplacementPlugin(),
    new RunScriptWebpackPlugin({ name: 'server.js' }),
  ],
  output: {
    path: path.join(__dirname, 'dist'),
    filename: 'server.js',
  },
};
```

> **Hint** With **Yarn Berry** (not classic Yarn), instead of using the `nodeExternals` in the `externals` configuration property, use the `WebpackPnpExternals` from `webpack-pnp-externals` package: `WebpackPnpExternals({ exclude: ['webpack/hot/poll?100'] })`.

This configuration tells webpack a few essential things about your application: location of the entry file, which directory should be used to hold **compiled** files, and what kind of loader we want to use to compile source files. Generally, you should be able to use this file as-is, even if you don't fully understand all of the options.

#### Hot-Module Replacement[#](/recipes/hot-reload#hot-module-replacement-1)

To enable **HMR**, open the application entry file (`main.ts`) and add the following webpack-related instructions:

```typescript

declare const module: any;

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  await app.listen(3000);

  if (module.hot) {
    module.hot.accept();
    module.hot.dispose(() => app.close());
  }
}
bootstrap();
```

To simplify the execution process, add a script to your `package.json` file.

```json

"start:dev": "webpack --config webpack.config.js"
```

Now simply open your command line and run the following command:

```bash

$ npm run start:dev
```

#### Example[#](/recipes/hot-reload#example)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/08-webpack).

### TypeORM

If you're using `@nestjs/typeorm`, you'll need to add `keepConnectionAlive: true` to your TypeORM configuration.

----
url: https://docs.nestjs.com/v5/cli/overview
----

### Overview

In order to help people manage their projects, the [CLI](https://github.com/nestjs/nest-cli) tool has been created. It helps on many grounds at once, from scaffolding the project to building well-structured applications. The Nest CLI is based on the [@angular-devkit](https://github.com/angular/devkit) package. Also, there're special schematics that are dedicated to the Nest development [@nestjs/schematics](https://github.com/nestjs/schematics).

#### Installation

Install CLI using **NPM**:

```bash

$ npm install -g @nestjs/cli
```

#### Contribute

You can participate and contribute to the project [here](https://github.com/nestjs/nest-cli).

* Overview
* Installation
* Contribute

----
url: https://docs.nestjs.com/v8/graphql/plugins
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Plugins](https://docs.nestjs.com/v8/graphql/plugins#plugins)
* [Custom plugins](https://docs.nestjs.com/v8/graphql/plugins#custom-plugins)
* [Using external plugins](https://docs.nestjs.com/v8/graphql/plugins#using-external-plugins)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/plugins.md "Suggest Edits")

### Plugins

> **Warning** This chapter applies only to the `@nestjs/apollo` driver.

Plugins enable you to extend Apollo Server's core functionality by performing custom operations in response to certain events. Currently, these events correspond to individual phases of the GraphQL request lifecycle, and to the startup of Apollo Server itself (read more [here](https://www.apollographql.com/docs/apollo-server/integrations/plugins/)). For example, a basic logging plugin might log the GraphQL query string associated with each request that's sent to Apollo Server.

#### Custom plugins[#](/graphql/plugins#custom-plugins)

To create a plugin, declare a class annotated with the `@Plugin` decorator exported from the `@nestjs/apollo` package. Also, for better code autocompletion, implement the `ApolloServerPlugin` interface from the `apollo-server-plugin-base` package.

```typescript

import { Plugin } from '@nestjs/apollo';
import {
  ApolloServerPlugin,
  GraphQLRequestListener,
} from 'apollo-server-plugin-base';

@Plugin()
export class LoggingPlugin implements ApolloServerPlugin {
  async requestDidStart(): Promise<GraphQLRequestListener> {
    console.log('Request started');
    return {
      async willSendResponse() {
        console.log('Will send response');
      },
    };
  }
}
```

With this in place, we can register the `LoggingPlugin` as a provider.

```typescript

@Module({
  providers: [LoggingPlugin],
})
export class CommonModule {}
```

Nest will automatically instantiate a plugin and apply it to the Apollo Server.

#### Using external plugins[#](/graphql/plugins#using-external-plugins)

There are several plugins provided out-of-the-box. To use an existing plugin, simply import it and add it to the `plugins` array:

```typescript

GraphQLModule.forRoot({
  // ...
  plugins: [ApolloServerOperationRegistry({ /* options */})]
}),
```

> **Hint** The `ApolloServerOperationRegistry` plugin is exported from the `apollo-server-plugin-operation-registry` package.

----
url: https://docs.nestjs.com/v7/websockets/interceptors
----

* [Interceptors](https://docs.nestjs.com/v7/websockets/interceptors#interceptors)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/websockets/interceptors.md "Suggest Edits")

### Interceptors

There is no difference between [regular interceptors](/v7/interceptors) and web sockets interceptors. The following example uses a manually instantiated method-scoped interceptor. Just as with HTTP based applications, you can also use gateway-scoped interceptors (i.e., prefix the gateway class with a `@UseInterceptors()` decorator).

JS TS

```typescript

@UseInterceptors(new TransformInterceptor())
@SubscribeMessage('events')
handleEvent(client: Client, data: unknown): WsResponse<unknown> {
  const event = 'events';
  return { event, data };
}
```

```typescript

@UseInterceptors(new TransformInterceptor())
@SubscribeMessage('events')
handleEvent(client, data) {
  const event = 'events';
  return { event, data };
}
```

----
url: https://docs.nestjs.com/v5/execution-context
----

### Execution Context

There are several ways of mounting the Nest application. You can create either a web app, microservice or just a Nest **execution context**. The Nest context is a wrapper around the Nest container, which holds all instantiated classes. We can grab an existing instance from within any imported module directly using application object. Thanks to that, you can take advantages of the Nest framework everywhere, including **CRON** jobs and even build a **CLI** on top of it.

#### Getting started

In order to create a Nest application context, we use the following syntax:

JS TS

TypeScript

```typescript

async function bootstrap() {
  const app = await NestFactory.createApplicationContext(ApplicationModule);
  // logic...
}
bootstrap();
```

Afterward, Nest allows you to pick any instance registered within Nest application. Let's imagine that we have a `TasksController` in the `TasksModule`. This class provides a set of usable methods, which we want to call from within CRON job.

JS TS

TypeScript

```typescript

const app = await NestFactory.create(ApplicationModule);
const tasksController = app.get(TasksController);
```

And that's it. To grab `TasksController` instance we had to use `get()` method. We didn't have to go through entire modules tree, the `get()` method act like a **query** that search for an instance in each registered module automatically. However, if you prefer a strict context checking, you can always switch to it using `strict: true` options object that has to be passed as the second argument of `get()` method. Then, you have to go through all modules to pick up a particular instance from the selected context.

JS TS

TypeScript

```typescript

const app = await NestFactory.create(ApplicationModule);
const tasksController = app.select(TasksModule).get(TasksController, { strict: true });
```

|            |                                                                                                                                                    |
| ---------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| `get()`    | Retrieves an instance of either controller or provider (including guards, filters, and so on) available in the application context.                |
| `select()` | Navigates through the module tree, for example, to pull out a specific instance from the selected module (used together with enabled strict mode). |

> **Hint** The root module is selected by default. In order to select any other module, you need to go through entire modules tree (step by step).

* Execution Context
* Getting started

----
url: https://docs.nestjs.com/recipes/serve-static
----

[Skip to content](#content)

On this page

* [Serve Static](https://docs.nestjs.com/recipes/serve-static#serve-static)
* [Installation](https://docs.nestjs.com/recipes/serve-static#installation)
* [Bootstrap](https://docs.nestjs.com/recipes/serve-static#bootstrap)
* [Configuration](https://docs.nestjs.com/recipes/serve-static#configuration)
* [Example](https://docs.nestjs.com/recipes/serve-static#example)

### Serve Static

To serve static content, such as a single-page application (SPA), use the `ServeStaticModule` from the [`@nestjs/serve-static`](https://www.npmjs.com/package/@nestjs/serve-static) package.

#### Installation[#](/recipes/serve-static#installation)

First, install the required package:

```bash

$ npm install --save @nestjs/serve-static
```

#### Bootstrap[#](/recipes/serve-static#bootstrap)

Once the installation is complete, import the `ServeStaticModule` into the root `AppModule` and configure it by passing a configuration object to the `forRoot()` method:

```typescript

import { Module } from '@nestjs/common';
import { AppController } from './app.controller.js';
import { AppService } from './app.service.js';
import { ServeStaticModule } from '@nestjs/serve-static';
import { join } from 'node:path';

@Module({
  imports: [
    ServeStaticModule.forRoot({
      rootPath: join(import.meta.dirname, '..', 'client'),
    }),
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}
```

With this in place, build the static website and place its content in the location specified by the `rootPath` property.

#### Configuration[#](/recipes/serve-static#configuration)

The [`ServeStaticModule`](https://github.com/nestjs/serve-static) accepts a variety of options to customize its behavior. For example, you can set the path at which the static app is rendered, exclude specific paths, or enable or disable the `Cache-Control` response header. See the [`ServeStaticModuleOptions` interface](https://github.com/nestjs/serve-static/blob/master/lib/interfaces/serve-static-options.interface.ts) for the full list of options.

> **Notice** By default, `renderPath` matches all paths, and the module responds with the `index.html` file. This enables client-side routing for your SPA, while routes declared in your controllers are still handled by the server. You can change this behavior by combining the `serveRoot` and `renderPath` options with the other options. With the Fastify adapter, set `serveStaticOptions.fallthrough` to `true` to mimic the Express fallthrough behavior, i.e., to send `index.html` instead of a 404 error for routes that don't exist.

#### Example[#](/recipes/serve-static#example)

A working example is available in the [serve-static sample](https://github.com/nestjs/nest/tree/master/sample/24-serve-static) on GitHub.

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/recipes/serve-static.md)

----
url: https://docs.nestjs.com/v10/techniques/versioning
----

* [Versioning](https://docs.nestjs.com/v10/techniques/versioning#versioning)
* [URI Versioning Type](https://docs.nestjs.com/v10/techniques/versioning#uri-versioning-type)
* [Header Versioning Type](https://docs.nestjs.com/v10/techniques/versioning#header-versioning-type)
* [Media Type Versioning Type](https://docs.nestjs.com/v10/techniques/versioning#media-type-versioning-type)
* [Custom Versioning Type](https://docs.nestjs.com/v10/techniques/versioning#custom-versioning-type)
* [Usage](https://docs.nestjs.com/v10/techniques/versioning#usage)
* [Controller versions](https://docs.nestjs.com/v10/techniques/versioning#controller-versions)
* [Route versions](https://docs.nestjs.com/v10/techniques/versioning#route-versions)
* [Multiple versions](https://docs.nestjs.com/v10/techniques/versioning#multiple-versions)
* [Version "Neutral"](https://docs.nestjs.com/v10/techniques/versioning#version-neutral)
* [Global default version](https://docs.nestjs.com/v10/techniques/versioning#global-default-version)
* [Middleware versioning](https://docs.nestjs.com/v10/techniques/versioning#middleware-versioning)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/techniques/versioning.md "Suggest Edits")

### Versioning

> **Hint** This chapter is only relevant to HTTP-based applications.

Versioning allows you to have **different versions** of your controllers or individual routes running within the same application. Applications change very often and it is not unusual that there are breaking changes that you need to make while still needing to support the previous version of the application.

There are 4 types of versioning that are supported:

|                                                                             |                                                                                                                            |
| --------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- |
| [`URI Versioning`](techniques/versioning#uri-versioning-type)               | The version will be passed within the URI of the request (default)                                                         |
| [`Header Versioning`](techniques/versioning#header-versioning-type)         | A custom request header will specify the version                                                                           |
| [`Media Type Versioning`](techniques/versioning#media-type-versioning-type) | The `Accept` header of the request will specify the version                                                                |
| [`Custom Versioning`](techniques/versioning#custom-versioning-type)         | Any aspect of the request may be used to specify the version(s). A custom function is provided to extract said version(s). |

#### URI Versioning Type[#](/techniques/versioning#uri-versioning-type)

URI Versioning uses the version passed within the URI of the request, such as `https://example.com/v1/route` and `https://example.com/v2/route`.

> **Notice** With URI Versioning the version will be automatically added to the URI after the [global path prefix](faq/global-prefix) (if one exists), and before any controller or route paths.

To enable URI Versioning for your application, do the following:

main.ts

JS TS

```typescript

const app = await NestFactory.create(AppModule);
// or "app.enableVersioning()"
app.enableVersioning({
  type: VersioningType.URI,
});
await app.listen(process.env.PORT ?? 3000);
```

> **Notice** The version in the URI will be automatically prefixed with `v` by default, however the prefix value can be configured by setting the `prefix` key to your desired prefix or `false` if you wish to disable it.

> **Hint** The `VersioningType` enum is available to use for the `type` property and is imported from the `@nestjs/common` package.

#### Header Versioning Type[#](/techniques/versioning#header-versioning-type)

Header Versioning uses a custom, user specified, request header to specify the version where the value of the header will be the version to use for the request.

Example HTTP Requests for Header Versioning:

To enable **Header Versioning** for your application, do the following:

main.ts

JS TS

```typescript

const app = await NestFactory.create(AppModule);
app.enableVersioning({
  type: VersioningType.HEADER,
  header: 'Custom-Header',
});
await app.listen(process.env.PORT ?? 3000);
```

The `header` property should be the name of the header that will contain the version of the request.

> **Hint** The `VersioningType` enum is available to use for the `type` property and is imported from the `@nestjs/common` package.

#### Media Type Versioning Type[#](/techniques/versioning#media-type-versioning-type)

Media Type Versioning uses the `Accept` header of the request to specify the version.

Within the `Accept` header, the version will be separated from the media type with a semi-colon, `;`. It should then contain a key-value pair that represents the version to use for the request, such as `Accept: application/json;v=2`. They key is treated more as a prefix when determining the version will to be configured to include the key and separator.

To enable **Media Type Versioning** for your application, do the following:

main.ts

JS TS

```typescript

const app = await NestFactory.create(AppModule);
app.enableVersioning({
  type: VersioningType.MEDIA_TYPE,
  key: 'v=',
});
await app.listen(process.env.PORT ?? 3000);
```

The `key` property should be the key and separator of the key-value pair that contains the version. For the example `Accept: application/json;v=2`, the `key` property would be set to `v=`.

> **Hint** The `VersioningType` enum is available to use for the `type` property and is imported from the `@nestjs/common` package.

#### Custom Versioning Type[#](/techniques/versioning#custom-versioning-type)

Custom Versioning uses any aspect of the request to specify the version (or versions). The incoming request is analyzed using an `extractor` function that returns a string or array of strings.

If multiple versions are provided by the requester, the extractor function can return an array of strings, sorted in order of greatest/highest version to smallest/lowest version. Versions are matched to routes in order from highest to lowest.

If an empty string or array is returned from the `extractor`, no routes are matched and a 404 is returned.

For example, if an incoming request specifies it supports versions `1`, `2`, and `3`, the `extractor`**MUST** return `[3, 2, 1]`. This ensures that the highest possible route version is selected first.

If versions `[3, 2, 1]` are extracted, but routes only exist for version `2` and `1`, the route that matches version `2` is selected (version `3` is automatically ignored).

> **Notice** Selecting the highest matching version based on the array returned from `extractor` > **does not reliably work** with the Express adapter due to design limitations. A single version (either a string or array of 1 element) works just fine in Express. Fastify correctly supports both highest matching version selection and single version selection.

To enable **Custom Versioning** for your application, create an `extractor` function and pass it into your application like so:

main.ts

JS TS

```typescript

// Example extractor that pulls out a list of versions from a custom header and turns it into a sorted array.
// This example uses Fastify, but Express requests can be processed in a similar way.
const extractor = (request: FastifyRequest): string | string[] =>
  [request.headers['custom-versioning-field'] ?? '']
     .flatMap(v => v.split(','))
     .filter(v => !!v)
     .sort()
     .reverse()

const app = await NestFactory.create(AppModule);
app.enableVersioning({
  type: VersioningType.CUSTOM,
  extractor,
});
await app.listen(process.env.PORT ?? 3000);
```

#### Usage[#](/techniques/versioning#usage)

Versioning allows you to version controllers, individual routes, and also provides a way for certain resources to opt-out of versioning. The usage of versioning is the same regardless of the Versioning Type your application uses.

> **Notice** If versioning is enabled for the application but the controller or route does not specify the version, any requests to that controller/route will be returned a `404` response status. Similarly, if a request is received containing a version that does not have a corresponding controller or route, it will also be returned a `404` response status.

#### Controller versions[#](/techniques/versioning#controller-versions)

A version can be applied to a controller, setting the version for all routes within the controller.

To add a version to a controller do the following:

cats.controller.ts

JS TS

```typescript

@Controller({
  version: '1',
})
export class CatsControllerV1 {
  @Get('cats')
  findAll(): string {
    return 'This action returns all cats for version 1';
  }
}
```

```typescript

@Controller({
  version: '1',
})
export class CatsControllerV1 {
  @Get('cats')
  findAll() {
    return 'This action returns all cats for version 1';
  }
}
```

#### Route versions[#](/techniques/versioning#route-versions)

A version can be applied to an individual route. This version will override any other version that would effect the route, such as the Controller Version.

To add a version to an individual route do the following:

cats.controller.ts

JS TS

```typescript

import { Controller, Get, Version } from '@nestjs/common';

@Controller()
export class CatsController {
  @Version('1')
  @Get('cats')
  findAllV1(): string {
    return 'This action returns all cats for version 1';
  }

  @Version('2')
  @Get('cats')
  findAllV2(): string {
    return 'This action returns all cats for version 2';
  }
}
```

```typescript

import { Controller, Get, Version } from '@nestjs/common';

@Controller()
export class CatsController {
  @Version('1')
  @Get('cats')
  findAllV1() {
    return 'This action returns all cats for version 1';
  }

  @Version('2')
  @Get('cats')
  findAllV2() {
    return 'This action returns all cats for version 2';
  }
}
```

#### Multiple versions[#](/techniques/versioning#multiple-versions)

Multiple versions can be applied to a controller or route. To use multiple versions, you would set the version to be an Array.

To add multiple versions do the following:

cats.controller.ts

JS TS

```typescript

@Controller({
  version: ['1', '2'],
})
export class CatsController {
  @Get('cats')
  findAll(): string {
    return 'This action returns all cats for version 1 or 2';
  }
}
```

```typescript

@Controller({
  version: ['1', '2'],
})
export class CatsController {
  @Get('cats')
  findAll() {
    return 'This action returns all cats for version 1 or 2';
  }
}
```

#### Version "Neutral"[#](/techniques/versioning#version-neutral)

Some controllers or routes may not care about the version and would have the same functionality regardless of the version. To accommodate this, the version can be set to `VERSION_NEUTRAL` symbol.

An incoming request will be mapped to a `VERSION_NEUTRAL` controller or route regardless of the version sent in the request in addition to if the request does not contain a version at all.

> **Notice** For URI Versioning, a `VERSION_NEUTRAL` resource would not have the version present in the URI.

To add a version neutral controller or route do the following:

cats.controller.ts

JS TS

```typescript

import { Controller, Get, VERSION_NEUTRAL } from '@nestjs/common';

@Controller({
  version: VERSION_NEUTRAL,
})
export class CatsController {
  @Get('cats')
  findAll(): string {
    return 'This action returns all cats regardless of version';
  }
}
```

```typescript

import { Controller, Get, VERSION_NEUTRAL } from '@nestjs/common';

@Controller({
  version: VERSION_NEUTRAL,
})
export class CatsController {
  @Get('cats')
  findAll() {
    return 'This action returns all cats regardless of version';
  }
}
```

#### Global default version[#](/techniques/versioning#global-default-version)

If you do not want to provide a version for each controller/or individual routes, or if you want to have a specific version set as the default version for every controller/route that don't have the version specified, you could set the `defaultVersion` as follows:

main.ts

JS TS

```typescript

app.enableVersioning({
  // ...
  defaultVersion: '1'
  // or
  defaultVersion: ['1', '2']
  // or
  defaultVersion: VERSION_NEUTRAL
});
```

#### Middleware versioning[#](/techniques/versioning#middleware-versioning)

[Middlewares](https://docs.nestjs.com/middleware) can also use versioning metadata to configure the middleware for a specific route's version. To do so, provide the version number as one of the parameters for the `MiddlewareConsumer.forRoutes()` method:

app.module.ts

JS TS

```typescript

import { Module, NestModule, MiddlewareConsumer } from '@nestjs/common';
import { LoggerMiddleware } from './common/middleware/logger.middleware';
import { CatsModule } from './cats/cats.module';
import { CatsController } from './cats/cats.controller';

@Module({
  imports: [CatsModule],
})
export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer
      .apply(LoggerMiddleware)
      .forRoutes({ path: 'cats', method: RequestMethod.GET, version: '2' });
  }
}
```

With the code above, the `LoggerMiddleware` will only be applied to the version '2' of `/cats` endpoint.

> **Notice** Middlewares work with any versioning type described in the this section: `URI`, `Header`, `Media Type` or `Custom`.

----
url: https://docs.nestjs.com/v10/cli/overview
----

* [Overview](https://docs.nestjs.com/v10/cli/overview#overview)
* [Installation](https://docs.nestjs.com/v10/cli/overview#installation)
* [Basic workflow](https://docs.nestjs.com/v10/cli/overview#basic-workflow)
* [Project structure](https://docs.nestjs.com/v10/cli/overview#project-structure)
* [CLI command syntax](https://docs.nestjs.com/v10/cli/overview#cli-command-syntax)
* [Command overview](https://docs.nestjs.com/v10/cli/overview#command-overview)
* [Requirements](https://docs.nestjs.com/v10/cli/overview#requirements)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/cli/overview.md "Suggest Edits")

### Overview

The [Nest CLI](https://github.com/nestjs/nest-cli) is a command-line interface tool that helps you to initialize, develop, and maintain your Nest applications. It assists in multiple ways, including scaffolding the project, serving it in development mode, and building and bundling the application for production distribution. It embodies best-practice architectural patterns to encourage well-structured apps.

#### Installation[#](/cli/overview#installation)

**Note**: In this guide we describe using [npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm) to install packages, including the Nest CLI. Other package managers may be used at your discretion. With npm, you have several options available for managing how your OS command line resolves the location of the `nest` CLI binary file. Here, we describe installing the `nest` binary globally using the `-g` option. This provides a measure of convenience, and is the approach we assume throughout the documentation. Note that installing **any**`npm` package globally leaves the responsibility of ensuring they're running the correct version up to the user. It also means that if you have different projects, each will run the **same** version of the CLI. A reasonable alternative is to use the [npx](https://github.com/npm/cli/blob/latest/docs/lib/content/commands/npx.md) program, built into the `npm` cli (or similar features with other package managers) to ensure that you run a **managed version** of the Nest CLI. We recommend you consult the [npx documentation](https://github.com/npm/cli/blob/latest/docs/lib/content/commands/npx.md) and/or your DevOps support staff for more information.

Install the CLI globally using the `npm install -g` command (see the **Note** above for details about global installs).

```bash

$ npm install -g @nestjs/cli
```

> **Hint** Alternatively, you can use this command `npx @nestjs/cli@latest` without installing the cli globally.

#### Basic workflow[#](/cli/overview#basic-workflow)

Once installed, you can invoke CLI commands directly from your OS command line through the `nest` executable. See the available `nest` commands by entering the following:

```bash

$ nest --help
```

Get help on an individual command using the following construct. Substitute any command, like `new`, `add`, etc., where you see `generate` in the example below to get detailed help on that command:

```bash

$ nest generate --help
```

To create, build and run a new basic Nest project in development mode, go to the folder that should be the parent of your new project, and run the following commands:

```bash

$ nest new my-nest-project
$ cd my-nest-project
$ npm run start:dev
```

In your browser, open <http://localhost:3000> to see the new application running. The app will automatically recompile and reload when you change any of the source files.

> **Hint** We recommend using the [SWC builder](/v10/recipes/swc) for faster builds (10x more performant than the default TypeScript compiler).

#### Project structure[#](/cli/overview#project-structure)

When you run `nest new`, Nest generates a boilerplate application structure by creating a new folder and populating an initial set of files. You can continue working in this default structure, adding new components, as described throughout this documentation. We refer to the project structure generated by `nest new` as **standard mode**. Nest also supports an alternate structure for managing multiple projects and libraries called **monorepo mode**.

Aside from a few specific considerations around how the **build** process works (essentially, monorepo mode simplifies build complexities that can sometimes arise from monorepo-style project structures), and built-in [library](/v10/cli/libraries) support, the rest of the Nest features, and this documentation, apply equally to both standard and monorepo mode project structures. In fact, you can easily switch from standard mode to monorepo mode at any time in the future, so you can safely defer this decision while you're still learning about Nest.

You can use either mode to manage multiple projects. Here's a quick summary of the differences:

| Feature                                               | Standard Mode                                                      | Monorepo Mode                                              |
| ----------------------------------------------------- | ------------------------------------------------------------------ | ---------------------------------------------------------- |
| Multiple projects                                     | Separate file system structure                                     | Single file system structure                               |
| `node_modules` & `package.json`                       | Separate instances                                                 | Shared across monorepo                                     |
| Default compiler                                      | `tsc`                                                              | webpack                                                    |
| Compiler settings                                     | Specified separately                                               | Monorepo defaults that can be overridden per project       |
| Config files like `.eslintrc.js`, `.prettierrc`, etc. | Specified separately                                               | Shared across monorepo                                     |
| `nest build` and `nest start` commands                | Target defaults automatically to the (only) project in the context | Target defaults to the **default project** in the monorepo |
| Libraries                                             | Managed manually, usually via npm packaging                        | Built-in support, including path management and bundling   |

Read the sections on [Workspaces](/v10/cli/monorepo) and [Libraries](/v10/cli/libraries) for more detailed information to help you decide which mode is most suitable for you.

```bash

nest commandOrAlias requiredArg [optionalArg] [options]
```

For example:

```bash

$ nest new my-nest-project --dry-run
```

Here, `new` is the *commandOrAlias*. The `new` command has an alias of `n`. `my-nest-project` is the *requiredArg*. If a *requiredArg* is not supplied on the command line, `nest` will prompt for it. Also, `--dry-run` has an equivalent short-hand form `-d`. With this in mind, the following command is the equivalent of the above:

```bash

$ nest n my-nest-project -d
```

Most commands, and some options, have aliases. Try running `nest new --help` to see these options and aliases, and to confirm your understanding of the above constructs.

#### Command overview[#](/cli/overview#command-overview)

Run `nest <command> --help` for any of the following commands to see command-specific options.

See [usage](/v10/cli/usages) for detailed descriptions for each command.

| Command    | Alias | Description                                                                                    |
| ---------- | ----- | ---------------------------------------------------------------------------------------------- |
| `new`      | `n`   | Scaffolds a new *standard mode* application with all boilerplate files needed to run.          |
| `generate` | `g`   | Generates and/or modifies files based on a schematic.                                          |
| `build`    |       | Compiles an application or workspace into an output folder.                                    |
| `start`    |       | Compiles and runs an application (or default project in a workspace).                          |
| `add`      |       | Imports a library that has been packaged as a **nest library**, running its install schematic. |
| `info`     | `i`   | Displays information about installed nest packages and other helpful system info.              |

#### Requirements[#](/cli/overview#requirements)

Nest CLI requires a Node.js binary built with [internationalization support](https://nodejs.org/api/intl.html) (ICU), such as the official binaries from the [Node.js project page](https://nodejs.org/en/download). If you encounter errors related to ICU, check that your binary meets this requirement.

```bash

node -p process.versions.icu
```

If the command prints `undefined`, your Node.js binary has no internationalization support.

----
url: https://docs.nestjs.com/v10/providers
----

* [Providers](https://docs.nestjs.com/v10/providers#providers)
* [Services](https://docs.nestjs.com/v10/providers#services)
* [Dependency injection](https://docs.nestjs.com/v10/providers#dependency-injection)
* [Scopes](https://docs.nestjs.com/v10/providers#scopes)
* [Custom providers](https://docs.nestjs.com/v10/providers#custom-providers)
* [Optional providers](https://docs.nestjs.com/v10/providers#optional-providers)
* [Property-based injection](https://docs.nestjs.com/v10/providers#property-based-injection)
* [Provider registration](https://docs.nestjs.com/v10/providers#provider-registration)
* [Manual instantiation](https://docs.nestjs.com/v10/providers#manual-instantiation)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/components.md "Suggest Edits")

### Providers

Providers are a fundamental concept in Nest. Many of the basic Nest classes may be treated as a provider – services, repositories, factories, helpers, and so on. The main idea of a provider is that it can be **injected** as a dependency; this means objects can create various relationships with each other, and the function of "wiring up" these objects can largely be delegated to the Nest runtime system.

In the previous chapter, we built a simple `CatsController`. Controllers should handle HTTP requests and delegate more complex tasks to **providers**. Providers are plain JavaScript classes that are declared as `providers` in a NestJS module. For more information, see the "Modules" chapter.

> **Hint** Since Nest enables the possibility to design and organize dependencies in a more OO way, we strongly recommend following the [SOLID principles](https://en.wikipedia.org/wiki/SOLID).

#### Services[#](/providers#services)

Let's start by creating a simple `CatsService`. This service will be responsible for data storage and retrieval, and is designed to be used by the `CatsController`, so it's a good candidate to be defined as a provider.

cats.service.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { Cat } from './interfaces/cat.interface';

@Injectable()
export class CatsService {
  private readonly cats: Cat[] = [];

  create(cat: Cat) {
    this.cats.push(cat);
  }

  findAll(): Cat[] {
    return this.cats;
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';

@Injectable()
export class CatsService {
  constructor() {
    this.cats = [];
  }

  create(cat) {
    this.cats.push(cat);
  }

  findAll() {
    return this.cats;
  }
}
```

> **Hint** To create a service using the CLI, simply execute the `$ nest g service cats` command.

Our `CatsService` is a basic class with one property and two methods. The only new feature is that it uses the `@Injectable()` decorator. The `@Injectable()` decorator attaches metadata, which declares that `CatsService` is a class that can be managed by the Nest [IoC](https://en.wikipedia.org/wiki/Inversion_of_control) container. By the way, this example also uses a `Cat` interface, which probably looks something like this:

interfaces/cat.interface.ts

JS TS

```typescript

export interface Cat {
  name: string;
  age: number;
  breed: string;
}
```

Now that we have a service class to retrieve cats, let's use it inside the `CatsController`:

cats.controller.ts

JS TS

```typescript

import { Controller, Get, Post, Body } from '@nestjs/common';
import { CreateCatDto } from './dto/create-cat.dto';
import { CatsService } from './cats.service';
import { Cat } from './interfaces/cat.interface';

@Controller('cats')
export class CatsController {
  constructor(private catsService: CatsService) {}

  @Post()
  async create(@Body() createCatDto: CreateCatDto) {
    this.catsService.create(createCatDto);
  }

  @Get()
  async findAll(): Promise<Cat[]> {
    return this.catsService.findAll();
  }
}
```

```typescript

import { Controller, Get, Post, Body, Bind, Dependencies } from '@nestjs/common';
import { CatsService } from './cats.service';

@Controller('cats')
@Dependencies(CatsService)
export class CatsController {
  constructor(catsService) {
    this.catsService = catsService;
  }

  @Post()
  @Bind(Body())
  async create(createCatDto) {
    this.catsService.create(createCatDto);
  }

  @Get()
  async findAll() {
    return this.catsService.findAll();
  }
}
```

The `CatsService` is **injected** through the class constructor. Notice the use of the `private` syntax. This shorthand allows us to both declare and initialize the `catsService` member immediately in the same location.

#### Dependency injection[#](/providers#dependency-injection)

Nest is built around the strong design pattern commonly known as **Dependency injection**. We recommend reading a great article about this concept in the official [Angular documentation](https://angular.dev/guide/di).

In Nest, thanks to TypeScript capabilities, it's extremely easy to manage dependencies because they are resolved just by type. In the example below, Nest will resolve the `catsService` by creating and returning an instance of `CatsService` (or, in the normal case of a singleton, returning the existing instance if it has already been requested elsewhere). This dependency is resolved and passed to your controller's constructor (or assigned to the indicated property):

```typescript

constructor(private catsService: CatsService) {}
```

#### Scopes[#](/providers#scopes)

Providers normally have a lifetime ("scope") synchronized with the application lifecycle. When the application is bootstrapped, every dependency must be resolved, and therefore every provider has to be instantiated. Similarly, when the application shuts down, each provider will be destroyed. However, there are ways to make your provider lifetime **request-scoped** as well. You can read more about these techniques in the [Injection Scopes](/v10/fundamentals/injection-scopes) chapter.

Nest has a built-in inversion of control ("IoC") container that resolves relationships between providers. This feature underlies the dependency injection feature described above, but is in fact far more powerful than what we've described so far. There are several ways to define a provider: you can use plain values, classes, and either asynchronous or synchronous factories. More examples of defining providers can be found in the [Dependency Injection](/v10/fundamentals/dependency-injection) chapter.

#### Optional providers[#](/providers#optional-providers)

Occasionally, you might have dependencies which do not necessarily have to be resolved. For instance, your class may depend on a **configuration object**, but if none is passed, the default values should be used. In such a case, the dependency becomes optional, because lack of the configuration provider wouldn't lead to errors.

To indicate a provider is optional, use the `@Optional()` decorator in the constructor's signature.

```typescript

import { Injectable, Optional, Inject } from '@nestjs/common';

@Injectable()
export class HttpService<T> {
  constructor(@Optional() @Inject('HTTP_OPTIONS') private httpClient: T) {}
}
```

Note that in the example above we are using a custom provider, which is the reason we include the `HTTP_OPTIONS` custom **token**. Previous examples showed constructor-based injection indicating a dependency through a class in the constructor. You can read more about custom providers and their associated tokens in the [Custom Providers](/v10/fundamentals/custom-providers) chapter.

#### Property-based injection[#](/providers#property-based-injection)

The technique we've used so far is called constructor-based injection, as providers are injected via the constructor method. In some very specific cases, **property-based injection** might be useful. For instance, if your top-level class depends on either one or multiple providers, passing them all the way up by calling `super()` in sub-classes from the constructor can be very tedious. In order to avoid this, you can use the `@Inject()` decorator at the property level.

```typescript

import { Injectable, Inject } from '@nestjs/common';

@Injectable()
export class HttpService<T> {
  @Inject('HTTP_OPTIONS')
  private readonly httpClient: T;
}
```

> **Warning** If your class doesn't extend another class, you should always prefer using **constructor-based** injection. The constructor explicitly outlines what dependencies are required and provides better visibility than class attributes annotated with `@Inject`.

#### Provider registration[#](/providers#provider-registration)

Now that we have defined a provider (`CatsService`), and we have a consumer of that service (`CatsController`), we need to register the service with Nest so that it can perform the injection. We do this by editing our module file (`app.module.ts`) and adding the service to the `providers` array of the `@Module()` decorator.

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { CatsController } from './cats/cats.controller';
import { CatsService } from './cats/cats.service';

@Module({
  controllers: [CatsController],
  providers: [CatsService],
})
export class AppModule {}
```

----
url: https://docs.nestjs.com/v5/microservices/exception-filters
----

### Exception filters

The only difference between [HTTP exception filter](/v5/exception-filters) layer and corresponding microservices layer is that instead of throwing `HttpException`, you should rather use `RpcException`.

TypeScript

```typescript

throw new RpcException('Invalid credentials.');
```

> **Hint** The `RpcException` class is imported from the `@nestjs/microservices` package.

Nest will handle thrown exception and as a result, returns the `error` object with the following structure:

TypeScript

```typescript

{
  status: 'error',
  message: 'Invalid credentials.'
}
```

#### Filters

The **exception filters** work in the same fashion as the primary ones, with a one, small difference. The `catch()` method has to return an `Observable`.

rpc-exception.filter.ts

JS TS

TypeScript

```typescript

import { Catch, RpcExceptionFilter, ArgumentsHost } from '@nestjs/common';
import { Observable, throwError } from 'rxjs';
import { RpcException } from '@nestjs/microservices';

@Catch(RpcException)
export class ExceptionFilter implements RpcExceptionFilter<RpcException> {
  catch(exception: RpcException, host: ArgumentsHost): Observable<any> {
    return throwError(exception.getError());
  }
}
```

TypeScript

```typescript

import { Catch, } from '@nestjs/common';
import { throwError } from 'rxjs';

@Catch(RpcException)
export class ExceptionFilter {
  catch(exception, host) {
    return throwError(exception.getError());
  }
}
```

> **Warning** It is impossible to set up the microservices exception filters globally.

Here is an example that makes use of a manually instantiated **method-scoped** filter (class-scoped works either):

TypeScript

```typescript

@UseFilters(new ExceptionFilter())
@MessagePattern({ cmd: 'sum' })
sum(data: number[]): number {
  return (data || []).reduce((a, b) => a + b);
}
```

#### Inheritance

Typically, you'll create fully customized exception filters crafted to fulfill your application requirements. There might be use-cases though when you would like to reuse an already implemented, **core exception filter**, and override the behavior based on certain factors.

In order to delegate exception processing to the base filter, you need to extend `BaseExceptionFilter` and call inherited `catch()` method. Besides, `HttpServer` reference has to be injected and passed to the `super()` call.

JS TS

TypeScript

```typescript

import { Catch, ArgumentsHost } from '@nestjs/common';
import { BaseRpcExceptionFilter } from '@nestjs/microservices';

@Catch()
export class AllExceptionsFilter extends BaseRpcExceptionFilter {
  catch(exception: any, host: ArgumentsHost) {
    return super.catch(exception, host);
  }
}
```

TypeScript

```typescript

import { Catch } from '@nestjs/common';
import { BaseRpcExceptionFilter } from '@nestjs/microservices';

@Catch()
export class AllExceptionsFilter extends BaseRpcExceptionFilter {
  catch(exception, host) {
    return super.catch(exception, host);
  }
}
```

----
url: https://docs.nestjs.com/security/helmet
----

[Skip to content](#content)

On this page

* [Security headers](https://docs.nestjs.com/security/helmet#security-headers)
* [Getting started](https://docs.nestjs.com/security/helmet#getting-started)
* [Default headers](https://docs.nestjs.com/security/helmet#default-headers)
* [Configuring headers](https://docs.nestjs.com/security/helmet#configuring-headers)
* [Content Security Policy](https://docs.nestjs.com/security/helmet#content-security-policy)
* [Swagger UI and GraphQL IDEs](https://docs.nestjs.com/security/helmet#swagger-ui-and-graphql-ides)
* [Using Helmet directly](https://docs.nestjs.com/security/helmet#using-helmet-directly)

### Security headers

Security headers, such as the ones [Helmet](https://github.com/helmetjs/helmet) sets, tell browsers to turn on protections against well-known web attacks like cross-site scripting and clickjacking. Examples are `Content-Security-Policy`, `Strict-Transport-Security` and `X-Frame-Options`.

Starting with NestJS v12.1, Nest can set these headers for you with `app.useSecurityHeaders()`. It uses the same defaults as Helmet 8, works the same way on Express and Fastify, and needs no extra package.

#### Getting started[#](/security/helmet#getting-started)

To enable the headers, call the `useSecurityHeaders()` method on the Nest application object:

```typescript

// main.ts
const app = await NestFactory.create(AppModule);
app.useSecurityHeaders();
await app.listen(process.env.PORT ?? 3000);
```

The headers are set on every response: route responses, `404` responses, error responses, responses rejected by the [CSRF protection](/security/csrf), and Server-Sent Events streams. The `X-Powered-By` header is removed. The following rules apply:

* Call `useSecurityHeaders()` before `app.init()` or `app.listen()`. Calling it afterwards, or calling it twice, throws an error.
* Options are validated when you call the method, so a bad configuration fails at startup (see [Configuring headers](/security/helmet#configuring-headers)).
* The headers are written by a framework-level middleware (Express) or `onRequest` hook (Fastify), registered at the point where you call the method. Middleware registered with `app.use()` before that call runs first, and responses that such middleware sends itself don't carry the headers, so call `useSecurityHeaders()` right after `NestFactory.create()`.
* `app.enableCsrfProtection()` shares the same request hook. You can call the two methods in any order: the headers are always written before the CSRF check runs.

#### Default headers[#](/security/helmet#default-headers)

Without options, `useSecurityHeaders()` sends the following headers, with the same values as Helmet 8:

| Header                              | Default value                                                           | Option                          |
| ----------------------------------- | ----------------------------------------------------------------------- | ------------------------------- |
| `Content-Security-Policy`           | See [Content Security Policy](/security/helmet#content-security-policy) | `contentSecurityPolicy`         |
| `Cross-Origin-Embedder-Policy`      | Not sent                                                                | `crossOriginEmbedderPolicy`     |
| `Cross-Origin-Opener-Policy`        | `same-origin`                                                           | `crossOriginOpenerPolicy`       |
| `Cross-Origin-Resource-Policy`      | `same-origin`                                                           | `crossOriginResourcePolicy`     |
| `Origin-Agent-Cluster`              | `?1`                                                                    | `originAgentCluster`            |
| `Referrer-Policy`                   | `no-referrer`                                                           | `referrerPolicy`                |
| `Strict-Transport-Security`         | `max-age=31536000; includeSubDomains`                                   | `strictTransportSecurity`       |
| `X-Content-Type-Options`            | `nosniff`                                                               | `xContentTypeOptions`           |
| `X-DNS-Prefetch-Control`            | `off`                                                                   | `xDnsPrefetchControl`           |
| `X-Download-Options`                | `noopen`                                                                | `xDownloadOptions`              |
| `X-Frame-Options`                   | `SAMEORIGIN`                                                            | `xFrameOptions`                 |
| `X-Permitted-Cross-Domain-Policies` | `none`                                                                  | `xPermittedCrossDomainPolicies` |
| `X-XSS-Protection`                  | `0`                                                                     | `xXssProtection`                |
| `X-Powered-By`                      | Removed                                                                 | `xPoweredBy`                    |

> **Hint** Browsers ignore `Strict-Transport-Security` over plain HTTP, and `X-XSS-Protection: 0` turns off the XSS auditor of old browsers, which was a source of vulnerabilities itself.

#### Configuring headers[#](/security/helmet#configuring-headers)

Each option controls one header. Pass `false` to leave the header out, `true` to send its default value, or an object to configure it:

```typescript

app.useSecurityHeaders({
  xFrameOptions: false,
  strictTransportSecurity: { maxAge: 63072000, preload: true },
  referrerPolicy: { policy: 'strict-origin-when-cross-origin' },
});
```

The options that accept an object take the following properties:

| Option                          | Properties                                                                                                                                                         |
| ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `contentSecurityPolicy`         | `directives`, `useDefaults` (default `true`) and `reportOnly` (default `false`). See [Content Security Policy](/security/helmet#content-security-policy).          |
| `crossOriginEmbedderPolicy`     | `policy`: `'require-corp'` (sent for `true`), `'credentialless'` or `'unsafe-none'`.                                                                               |
| `crossOriginOpenerPolicy`       | `policy`: `'same-origin'` (default), `'same-origin-allow-popups'`, `'noopener-allow-popups'` or `'unsafe-none'`.                                                   |
| `crossOriginResourcePolicy`     | `policy`: `'same-origin'` (default), `'same-site'` or `'cross-origin'`.                                                                                            |
| `referrerPolicy`                | `policy`: a referrer policy such as `'strict-origin-when-cross-origin'` (default `'no-referrer'`), or a list of policies, which browsers read as a fallback chain. |
| `strictTransportSecurity`       | `maxAge` in seconds (default `31536000`, which is 365 days), `includeSubDomains` (default `true`) and `preload` (default `false`).                                 |
| `xDnsPrefetchControl`           | `allow` (default `false`). `true` sends `on`.                                                                                                                      |
| `xFrameOptions`                 | `action`: `'sameorigin'` (default) or `'deny'`.                                                                                                                    |
| `xPermittedCrossDomainPolicies` | `permittedPolicies`: `'none'` (default), `'master-only'`, `'by-content-type'` or `'all'`.                                                                          |

The remaining options, `originAgentCluster`, `xContentTypeOptions`, `xDownloadOptions`, `xPoweredBy` and `xXssProtection`, accept only a boolean. For example, `xPoweredBy: false` keeps the `X-Powered-By` header.

Unknown options, unknown properties and invalid values throw when `useSecurityHeaders()` is called. Helmet's legacy option names are rejected with a hint to the current name, for example `Invalid security headers configuration: unknown option "hsts" (helmet's legacy name, use "strictTransportSecurity").`

A route can still override a header with the [`@Header()`](/controllers#response-headers) decorator, for example to let other sites load an image:

```typescript

@Get('avatars/:id')
@Header('Cross-Origin-Resource-Policy', 'cross-origin')
findAvatar(@Param('id') id: string) {}
```

> **Hint** On Fastify, `reply.header()` overrides a header as well, but `reply.removeHeader()` cannot remove a header set by `useSecurityHeaders()`.

#### Content Security Policy[#](/security/helmet#content-security-policy)

The default `Content-Security-Policy` is the same as Helmet 8's. It is sent on one line, without spaces after the semicolons:

```text

default-src 'self';
base-uri 'self';
font-src 'self' https: data:;
form-action 'self';
frame-ancestors 'self';
img-src 'self' data:;
object-src 'none';
script-src 'self';
script-src-attr 'none';
style-src 'self' https: 'unsafe-inline';
upgrade-insecure-requests
```

Use the `directives` property to change it:

```typescript

app.useSecurityHeaders({
  contentSecurityPolicy: {
    directives: {
      scriptSrc: ["'self'", 'https://cdn.example.com'],
      connectSrc: ["'self'", 'wss://realtime.example.com'],
      upgradeInsecureRequests: null,
    },
  },
});
```

Directives work as follows:

* Names are written in camelCase (`scriptSrc`) or in kebab-case (`'script-src'`).
* A directive you set **replaces** the default directive of the same name, so include `'self'` when you want to keep it. Other directives are added to the policy.
* A value is a string or a list of strings. `true` or an empty list sends a directive without a value, and `null` or `false` removes a directive, including a default one.
* Keywords, nonces and hashes must be single-quoted, as in `"'self'"`. An unquoted `self` is rejected, because browsers would read it as a host name.
* Values may only contain printable ASCII characters, and neither `;` nor `,`, so a value cannot add directives or policies.

To send only your own directives, set `useDefaults` to `false`. The policy then needs a `defaultSrc` directive, unless you set `defaultSrc: null` to leave it out on purpose.

To try a policy without breaking pages, set `reportOnly` to `true`. Nest then sends `Content-Security-Policy-Report-Only`, and browsers report violations instead of blocking them. Add a `report-to` or `report-uri` directive to receive the reports.

```typescript

app.useSecurityHeaders({
  contentSecurityPolicy: { reportOnly: true },
});
```

To leave the header out entirely, set `contentSecurityPolicy` to `false`.

#### Swagger UI and GraphQL IDEs[#](/security/helmet#swagger-ui-and-graphql-ides)

The policy applies to every response, including the HTML pages of API tools.

The [Swagger UI](/openapi/introduction) served by `@nestjs/swagger` loads its scripts and stylesheets from your application, so it works with the default policy. If you add scripts with the `customJs` option, add their hosts to `scriptSrc`. Inline code from the `customJsStr` option requires `'unsafe-inline'`. The default `upgrade-insecure-requests` directive makes browsers load scripts and stylesheets over HTTPS, so if you serve Swagger UI over plain HTTP outside local development, for example on a staging server reached by IP address, they fail to load. Serve Swagger UI over HTTPS, or remove the directive with `upgradeInsecureRequests: null`.

[GraphiQL](/graphql/quick-start#graphql-ide), as served by the Apollo driver, loads React and GraphiQL from `unpkg.com` and starts with an inline script. By default, GraphiQL is only enabled when `NODE_ENV` is not `production`, so relax the policy only there:

```typescript

const isProduction = process.env.NODE_ENV === 'production';

app.useSecurityHeaders({
  contentSecurityPolicy: isProduction
    ? true
    : {
        directives: {
          scriptSrc: ["'self'", "'unsafe-inline'", 'https://unpkg.com'],
        },
      },
});
```

[Apollo Sandbox](/graphql/quick-start#apollo-sandbox), enabled with `ApolloServerPluginLandingPageLocalDefault()`, loads its scripts, images and manifest from Apollo's CDN, and embeds the Sandbox in a frame:

```typescript

app.useSecurityHeaders({
  contentSecurityPolicy: {
    directives: {
      scriptSrc: [
        "'self'",
        "'unsafe-inline'",
        'https://embeddable-sandbox.cdn.apollographql.com',
      ],
      imgSrc: [
        "'self'",
        'data:',
        'https://apollo-server-landing-page.cdn.apollographql.com',
      ],
      manifestSrc: [
        "'self'",
        'https://apollo-server-landing-page.cdn.apollographql.com',
      ],
      frameSrc: ["'self'", 'https://sandbox.embed.apollographql.com'],
    },
  },
});
```

> **Warning**`'unsafe-inline'` in `script-src` gives up most of the protection that CSP offers against cross-site scripting, for every page your application serves. Avoid it in production.

#### Using Helmet directly[#](/security/helmet#using-helmet-directly)

Applications that already use Helmet can keep using it. Since the option names of `useSecurityHeaders()` are the same as Helmet's, a Helmet configuration usually carries over when you switch, with two exceptions:

* CSP directive values must be strings, lists of strings, booleans or `null`. Functions, which Helmet accepts to generate per-request nonces, are not supported.
* Helmet's legacy option names are rejected:

| Legacy Helmet name             | Option                          |
| ------------------------------ | ------------------------------- |
| `dnsPrefetchControl`           | `xDnsPrefetchControl`           |
| `frameguard`                   | `xFrameOptions`                 |
| `hidePoweredBy`                | `xPoweredBy`                    |
| `hsts`                         | `strictTransportSecurity`       |
| `ieNoOpen`                     | `xDownloadOptions`              |
| `noSniff`                      | `xContentTypeOptions`           |
| `permittedCrossDomainPolicies` | `xPermittedCrossDomainPolicies` |
| `xssFilter`                    | `xXssProtection`                |

To use Helmet itself, install the package for your platform and register it before other calls to `app.use()` or setup functions that may call `app.use()`. The underlying platform applies middleware in the order it was registered, so Helmet registered after a route doesn't apply to that route. The CSP directives shown above work with Helmet's `contentSecurityPolicy` option as well.

##### Express[#](/security/helmet#express)

```bash

$ npm i helmet
```

```typescript

// main.ts
import helmet from 'helmet';

app.use(helmet());
```

##### Fastify[#](/security/helmet#fastify)

With the `FastifyAdapter`, use the [@fastify/helmet](https://github.com/fastify/fastify-helmet) package. It is a [Fastify plugin](https://fastify.dev/docs/latest/Reference/Plugins/), not a middleware, so register it with `app.register()`:

```bash

$ npm i @fastify/helmet
```

```typescript

// main.ts
import helmet from '@fastify/helmet';

await app.register(helmet);
```

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/security/helmet.md)

----
url: https://docs.nestjs.com/recipes/nest-commander
----

[Skip to content](#content)

On this page

* [Nest Commander](https://docs.nestjs.com/recipes/nest-commander#nest-commander)
* [Installation](https://docs.nestjs.com/recipes/nest-commander#installation)
* [A Command file](https://docs.nestjs.com/recipes/nest-commander#a-command-file)
* [Running the Command](https://docs.nestjs.com/recipes/nest-commander#running-the-command)
* [Testing](https://docs.nestjs.com/recipes/nest-commander#testing)
* [Putting it all together](https://docs.nestjs.com/recipes/nest-commander#putting-it-all-together)
* [More Information](https://docs.nestjs.com/recipes/nest-commander#more-information)

### Nest Commander

Expanding on the [standalone applications](/standalone-applications) chapter, the [nest-commander](https://nest-commander.jaymcdoniel.dev) package lets you write command-line applications with a structure similar to a typical Nest application.

> **Note**`nest-commander` is a third-party package and is not managed by the NestJS core team. Please report any issues with the library in the [nest-commander repository](https://github.com/jmcdo29/nest-commander/issues/new/choose).

#### Installation[#](/recipes/nest-commander#installation)

First, install the package:

```bash

$ npm i nest-commander
```

#### A Command file[#](/recipes/nest-commander#a-command-file)

`nest-commander` lets you write command-line applications with [decorators](https://www.typescriptlang.org/docs/handbook/decorators.html): the `@Command()` decorator for classes and the `@Option()` decorator for methods of those classes. Every command class should extend the `CommandRunner` abstract class and be decorated with the `@Command()` decorator.

Nest treats every command as an `@Injectable()`, so dependency injection works as usual. The `CommandRunner` abstract class ensures that every command has a `run()` method that returns a `Promise<void>` and takes the parameters `string[], Record<string, any>`. The `run()` method is where your command's logic starts. Its first argument is an array of all parameters that didn't match an option flag, in case you need to work with multiple parameters. In the second argument, the options object, the property names match the `name` property given to the `@Option()` decorators, and their values are the return values of the corresponding option handlers. For better type safety, you can also create an interface for your options.

#### Running the Command[#](/recipes/nest-commander#running-the-command)

In a NestJS application, you use the `NestFactory` to create a server and run it with `listen()`. Similarly, the `nest-commander` package exposes an API to run your command-line application: import the `CommandFactory`, call its static `run()` method, and pass in the root module of your application:

```ts

import { CommandFactory } from 'nest-commander';
import { AppModule } from './app.module.js';

async function bootstrap() {
  await CommandFactory.run(AppModule);
}

await bootstrap();
```

By default, Nest's logger is disabled when using the `CommandFactory`. To enable it, pass a logger as the second argument to the `run()` method. You can provide either a custom NestJS logger or an array of the log levels you want to keep. For example, pass `['error']` to print only Nest's error logs.

```ts

import { CommandFactory } from 'nest-commander';
import { AppModule } from './app.module.js';
import { LogService } from './log.service.js';

async function bootstrap() {
  await CommandFactory.run(AppModule, new LogService());

  // or, if you only want to print Nest's warnings and errors
  await CommandFactory.run(AppModule, ['warn', 'error']);
}

await bootstrap();
```

Under the hood, `CommandFactory` calls `NestFactory` for you and calls `app.close()` when the command finishes, so you don't need to worry about memory leaks. To add error handling, wrap the `run()` call in a `try/catch` block, or chain a `.catch()` call to the `bootstrap()` call.

#### Testing[#](/recipes/nest-commander#testing)

`nest-commander` provides testing utilities that fit in with the rest of the NestJS ecosystem. Instead of using the `CommandFactory` to build the command in test mode, use the `CommandTestFactory` from the `nest-commander-testing` package and pass in your module metadata, similarly to how `Test.createTestingModule()` from `@nestjs/testing` works. In fact, it uses `@nestjs/testing` under the hood. You can still chain `overrideProvider()` calls before calling `compile()` to swap out providers in the test.

#### Putting it all together[#](/recipes/nest-commander#putting-it-all-together)

The following class defines a CLI command that can take the subcommand `basic` or be called directly. It supports the `-n`, `-s`, and `-b` flags (along with their long forms), with a custom parser for each option. The `--help` flag is also supported, as is customary with commander.

```ts

import { Command, CommandRunner, Option } from 'nest-commander';
import { LogService } from './log.service.js';

interface BasicCommandOptions {
  string?: string;
  boolean?: boolean;
  number?: number;
}

@Command({ name: 'basic', description: 'A parameter parse' })
export class BasicCommand extends CommandRunner {
  constructor(private readonly logService: LogService) {
    super();
  }

  async run(
    passedParam: string[],
    options?: BasicCommandOptions,
  ): Promise<void> {
    if (options?.boolean !== undefined && options?.boolean !== null) {
      this.runWithBoolean(passedParam, options.boolean);
    } else if (options?.number) {
      this.runWithNumber(passedParam, options.number);
    } else if (options?.string) {
      this.runWithString(passedParam, options.string);
    } else {
      this.runWithNone(passedParam);
    }
  }

  @Option({
    flags: '-n, --number [number]',
    description: 'A basic number parser',
  })
  parseNumber(val: string): number {
    return Number(val);
  }

  @Option({
    flags: '-s, --string [string]',
    description: 'A string return',
  })
  parseString(val: string): string {
    return val;
  }

  @Option({
    flags: '-b, --boolean [boolean]',
    description: 'A boolean parser',
  })
  parseBoolean(val: string): boolean {
    return JSON.parse(val);
  }

  runWithString(param: string[], option: string): void {
    this.logService.log({ param, string: option });
  }

  runWithNumber(param: string[], option: number): void {
    this.logService.log({ param, number: option });
  }

  runWithBoolean(param: string[], option: boolean): void {
    this.logService.log({ param, boolean: option });
  }

  runWithNone(param: string[]): void {
    this.logService.log({ param });
  }
}
```

Make sure the command class is added to a module:

```ts

@Module({
  providers: [LogService, BasicCommand],
})
export class AppModule {}
```

Then, to run the CLI, add the following to your `main.ts` file:

```ts

async function bootstrap() {
  await CommandFactory.run(AppModule);
}

await bootstrap();
```

You now have a command-line application.

#### More Information[#](/recipes/nest-commander#more-information)

Visit the [nest-commander docs site](https://nest-commander.jaymcdoniel.dev) for more information, examples, and API documentation.

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/recipes/nest-commander.md)

----
url: https://docs.nestjs.com/v11/faq/raw-body
----

* [Raw body](https://docs.nestjs.com/v11/faq/raw-body#raw-body)
* [Use with Express](https://docs.nestjs.com/v11/faq/raw-body#use-with-express)
* [Registering a different parser](https://docs.nestjs.com/v11/faq/raw-body#registering-a-different-parser)
* [Body parser size limit](https://docs.nestjs.com/v11/faq/raw-body#body-parser-size-limit)
* [Use with Fastify](https://docs.nestjs.com/v11/faq/raw-body#use-with-fastify)
* [Registering a different parser](https://docs.nestjs.com/v11/faq/raw-body#registering-a-different-parser-1)
* [Body parser size limit](https://docs.nestjs.com/v11/faq/raw-body#body-parser-size-limit-1)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/faq/raw-body.md "Suggest Edits")

### Raw body

One of the most common use-case for having access to the raw request body is performing webhook signature verifications. Usually to perform webhook signature validations the unserialized request body is required to calculate an HMAC hash.

> **Warning** This feature can be used only if the built-in global body parser middleware is enabled, ie., you must not pass `bodyParser: false` when creating the app.

#### Use with Express[#](/faq/raw-body#use-with-express)

First enable the option when creating your Nest Express application:

```typescript

import { NestFactory } from '@nestjs/core';
import type { NestExpressApplication } from '@nestjs/platform-express';
import { AppModule } from './app.module';

// in the "bootstrap" function
const app = await NestFactory.create<NestExpressApplication>(AppModule, {
  rawBody: true,
});
await app.listen(process.env.PORT ?? 3000);
```

To access the raw request body in a controller, a convenience interface `RawBodyRequest` is provided to expose a `rawBody` field on the request: use the interface `RawBodyRequest` type:

```typescript

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

@Controller('cats')
class CatsController {
  @Post()
  create(@Req() req: RawBodyRequest<Request>) {
    const raw = req.rawBody; // returns a `Buffer`.
  }
}
```

#### Registering a different parser[#](/faq/raw-body#registering-a-different-parser)

By default, only `json` and `urlencoded` parsers are registered. If you want to register a different parser on the fly, you will need to do so explicitly.

For example, to register a `text` parser, you can use the following code:

```typescript

app.useBodyParser('text');
```

> **Warning** Ensure that you are providing the correct application type to the `NestFactory.create` call. For Express applications, the correct type is `NestExpressApplication`. Otherwise the `.useBodyParser` method will not be found.

#### Body parser size limit[#](/faq/raw-body#body-parser-size-limit)

If your application needs to parse a body larger than the default `100kb` of Express, use the following:

```typescript

app.useBodyParser('json', { limit: '10mb' });
```

The `.useBodyParser` method will respect the `rawBody` option that is passed in the application options.

#### Use with Fastify[#](/faq/raw-body#use-with-fastify)

First enable the option when creating your Nest Fastify application:

```typescript

import { NestFactory } from '@nestjs/core';
import {
  FastifyAdapter,
  NestFastifyApplication,
} from '@nestjs/platform-fastify';
import { AppModule } from './app.module';

// in the "bootstrap" function
const app = await NestFactory.create<NestFastifyApplication>(
  AppModule,
  new FastifyAdapter(),
  {
    rawBody: true,
  },
);
await app.listen(process.env.PORT ?? 3000);
```

To access the raw request body in a controller, a convenience interface `RawBodyRequest` is provided to expose a `rawBody` field on the request: use the interface `RawBodyRequest` type:

```typescript

import { Controller, Post, RawBodyRequest, Req } from '@nestjs/common';
import { FastifyRequest } from 'fastify';

@Controller('cats')
class CatsController {
  @Post()
  create(@Req() req: RawBodyRequest<FastifyRequest>) {
    const raw = req.rawBody; // returns a `Buffer`.
  }
}
```

#### Registering a different parser[#](/faq/raw-body#registering-a-different-parser-1)

By default, only `application/json` and `application/x-www-form-urlencoded` parsers are registered. If you want to register a different parser on the fly, you will need to do so explicitly.

For example, to register a `text/plain` parser, you can use the following code:

```typescript

app.useBodyParser('text/plain');
```

> **Warning** Ensure that you are providing the correct application type to the `NestFactory.create` call. For Fastify applications, the correct type is `NestFastifyApplication`. Otherwise the `.useBodyParser` method will not be found.

#### Body parser size limit[#](/faq/raw-body#body-parser-size-limit-1)

If your application needs to parse a body larger than the default 1MiB of Fastify, use the following:

```typescript

const bodyLimit = 10_485_760; // 10MiB
app.useBodyParser('application/json', { bodyLimit });
```

The `.useBodyParser` method will respect the `rawBody` option that is passed in the application options.

----
url: https://docs.nestjs.com/v7/pipes
----

* [Pipes](https://docs.nestjs.com/v7/pipes#pipes)
* [Built-in pipes](https://docs.nestjs.com/v7/pipes#built-in-pipes)
* [Binding pipes](https://docs.nestjs.com/v7/pipes#binding-pipes)
* [Custom pipes](https://docs.nestjs.com/v7/pipes#custom-pipes)
* [Schema based validation](https://docs.nestjs.com/v7/pipes#schema-based-validation)
* [Object schema validation](https://docs.nestjs.com/v7/pipes#object-schema-validation)
* [Binding validation pipes](https://docs.nestjs.com/v7/pipes#binding-validation-pipes)
* [Class validator](https://docs.nestjs.com/v7/pipes#class-validator)
* [Global scoped pipes](https://docs.nestjs.com/v7/pipes#global-scoped-pipes)
* [The built-in ValidationPipe](https://docs.nestjs.com/v7/pipes#the-built-in-validationpipe)
* [Transformation use case](https://docs.nestjs.com/v7/pipes#transformation-use-case)
* [Providing defaults](https://docs.nestjs.com/v7/pipes#providing-defaults)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/pipes.md "Suggest Edits")

### Pipes

A pipe is a class annotated with the `@Injectable()` decorator. Pipes should implement the `PipeTransform` interface.

Pipes have two typical use cases:

* **transformation**: transform input data to the desired form (e.g., from string to integer)
* **validation**: evaluate input data and if valid, simply pass it through unchanged; otherwise, throw an exception when the data is incorrect

In both cases, pipes operate on the `arguments` being processed by a [controller route handler](controllers#route-parameters). Nest interposes a pipe just before a method is invoked, and the pipe receives the arguments destined for the method and operates on them. Any transformation or validation operation takes place at that time, after which the route handler is invoked with any (potentially) transformed arguments.

Nest comes with a number of built-in pipes that you can use out-of-the-box. You can also build your own custom pipes. In this chapter, we'll introduce the built-in pipes and show how to bind them to route handlers. We'll then examine several custom-built pipes to show how you can build one from scratch.

> **Hint** Pipes run inside the exceptions zone. This means that when a Pipe throws an exception it is handled by the exceptions layer (global exceptions filter and any [exceptions filters](/v7/exception-filters) that are applied to the current context). Given the above, it should be clear that when an exception is thrown in a Pipe, no controller method is subsequently executed. This gives you a best-practice technique for validating data coming into the application from external sources at the system boundary.

#### Built-in pipes[#](/pipes#built-in-pipes)

Nest comes with six pipes available out-of-the-box:

* `ValidationPipe`
* `ParseIntPipe`
* `ParseBoolPipe`
* `ParseArrayPipe`
* `ParseUUIDPipe`
* `DefaultValuePipe`

They're exported from the `@nestjs/common` package.

Let's take a quick look at using `ParseIntPipe`. This is an example of the **transformation** use case, where the pipe ensures that a method handler parameter is converted to a JavaScript integer (or throws an exception if the conversion fails). Later in this chapter, we'll show a simple custom implementation for a `ParseIntPipe`. The example techniques below also apply to the other built-in transformation pipes (`ParseBoolPipe`, `ParseArrayPipe` and `ParseUUIDPipe`, which we'll refer to as the `Parse*` pipes in this chapter).

#### Binding pipes[#](/pipes#binding-pipes)

To use a pipe, we need to bind an instance of the pipe class to the appropriate context. In our `ParseIntPipe` example, we want to associate the pipe with a particular route handler method, and make sure it runs before the method is called. We do so with the following construct, which we'll refer to as binding the pipe at the method parameter level:

```typescript

@Get(':id')
async findOne(@Param('id', ParseIntPipe) id: number) {
  return this.catsService.findOne(id);
}
```

This ensures that one of the following two conditions is true: either the parameter we receive in the `findOne()` method is a number (as expected in our call to `this.catsService.findOne()`), or an exception is thrown before the route handler is called.

For example, assume the route is called like:

```bash

GET localhost:3000/abc
```

Nest will throw an exception like this:

```json

{
  "statusCode": 400,
  "message": "Validation failed (numeric string is expected)",
  "error": "Bad Request"
}
```

The exception will prevent the body of the `findOne()` method from executing.

In the example above, we pass a class (`ParseIntPipe`), not an instance, leaving responsibility for instantiation to the framework and enabling dependency injection. As with pipes and guards, we can instead pass an in-place instance. Passing an in-place instance is useful if we want to customize the built-in pipe's behavior by passing options:

```typescript

@Get(':id')
async findOne(
  @Param('id', new ParseIntPipe({ errorHttpStatusCode: HttpStatus.NOT_ACCEPTABLE }))
  id: number,
) {
  return this.catsService.findOne(id);
}
```

Binding the other transformation pipes (all of the **Parse\*** pipes) works similarly. These pipes all work in the context of validating route parameters, query string parameters and request body values.

For example with a query string parameter:

```typescript

@Get()
async findOne(@Query('id', ParseIntPipe) id: number) {
  return this.catsService.findOne(id);
}
```

Here's an example of using the `ParseUUIDPipe` to parse a string parameter and validate if it is a UUID.

JS TS

```typescript

@Get(':uuid')
async findOne(@Param('uuid', new ParseUUIDPipe()) uuid: string) {
  return this.catsService.findOne(uuid);
}
```

```typescript

@Get(':uuid')
@Bind(Param('uuid', new ParseUUIDPipe()))
async findOne(uuid) {
  return this.catsService.findOne(uuid);
}
```

> **Hint** When using `ParseUUIDPipe()` you are parsing UUID in version 3, 4 or 5, if you only require a specific version of UUID you can pass a version in the pipe options.

Above we've seen examples of binding the various `Parse*` family of built-in pipes. Binding validation pipes is a little bit different; we'll discuss that in the following section.

> **Hint** Also, see [Validation techniques](/v7/techniques/validation) for extensive examples of validation pipes.

#### Custom pipes[#](/pipes#custom-pipes)

As mentioned, you can build your own custom pipes. While Nest provides a robust built-in `ParseIntPipe` and `ValidationPipe`, let's build simple custom versions of each from scratch to see how custom pipes are constructed.

We start with a simple `ValidationPipe`. Initially, we'll have it simply take an input value and immediately return the same value, behaving like an identity function.

validation.pipe.ts

JS TS

```typescript

import { PipeTransform, Injectable, ArgumentMetadata } from '@nestjs/common';

@Injectable()
export class ValidationPipe implements PipeTransform {
  transform(value: any, metadata: ArgumentMetadata) {
    return value;
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';

@Injectable()
export class ValidationPipe {
  transform(value, metadata) {
    return value;
  }
}
```

> **Hint**`PipeTransform<T, R>` is a generic interface that must be implemented by any pipe. The generic interface uses `T` to indicate the type of the input `value`, and `R` to indicate the return type of the `transform()` method.

Every pipe must implement the `transform()` method to fulfill the `PipeTransform` interface contract. This method has two parameters:

* `value`
* `metadata`

The `value` parameter is the currently processed method argument (before it is received by the route handling method), and `metadata` is the currently processed method argument's metadata. The metadata object has these properties:

```typescript

export interface ArgumentMetadata {
  type: 'body' | 'query' | 'param' | 'custom';
  metatype?: Type<unknown>;
  data?: string;
}
```

These properties describe the currently processed argument.

|            |                                                                                                                                                                                                      |
| ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `type`     | Indicates whether the argument is a body `@Body()`, query `@Query()`, param `@Param()`, or a custom parameter (read more [here](/v7/custom-decorators)).                                             |
| `metatype` | Provides the metatype of the argument, for example, `String`. Note: the value is `undefined` if you either omit a type declaration in the route handler method signature, or use vanilla JavaScript. |
| `data`     | The string passed to the decorator, for example `@Body('string')`. It's `undefined` if you leave the decorator parenthesis empty.                                                                    |

> **Warning** TypeScript interfaces disappear during transpilation. Thus, if a method parameter's type is declared as an interface instead of a class, the `metatype` value will be `Object`.

#### Schema based validation[#](/pipes#schema-based-validation)

Let's make our validation pipe a little more useful. Take a closer look at the `create()` method of the `CatsController`, where we probably would like to ensure that the post body object is valid before attempting to run our service method.

JS TS

```typescript

@Post()
async create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

```typescript

@Post()
async create(@Body() createCatDto) {
  this.catsService.create(createCatDto);
}
```

Let's focus in on the `createCatDto` body parameter. Its type is `CreateCatDto`:

create-cat.dto.ts

JS TS

```typescript

export class CreateCatDto {
  name: string;
  age: number;
  breed: string;
}
```

```bash

$ npm install --save joi
$ npm install --save-dev @types/joi
```

In the code sample below, we create a simple class that takes a schema as a `constructor` argument. We then apply the `schema.validate()` method, which validates our incoming argument against the provided schema.

As noted earlier, a **validation pipe** either returns the value unchanged, or throws an exception.

In the next section, you'll see how we supply the appropriate schema for a given controller method using the `@UsePipes()` decorator. Doing so makes our validation pipe re-usable across contexts, just as we set out to do.

JS TS

```typescript

import { PipeTransform, Injectable, ArgumentMetadata, BadRequestException } from '@nestjs/common';
import { ObjectSchema } from 'joi';

@Injectable()
export class JoiValidationPipe implements PipeTransform {
  constructor(private schema: ObjectSchema) {}

  transform(value: any, metadata: ArgumentMetadata) {
    const { error } = this.schema.validate(value);
    if (error) {
      throw new BadRequestException('Validation failed');
    }
    return value;
  }
}
```

```typescript

import { Injectable, BadRequestException } from '@nestjs/common';

@Injectable()
export class JoiValidationPipe {
  constructor(schema) {
    this.schema = schema;
  }

  transform(value, metadata) {
    const { error } = this.schema.validate(value);
    if (error) {
      throw new BadRequestException('Validation failed');
    }
    return value;
  }
}
```

```typescript

@Post()
@UsePipes(new JoiValidationPipe(createCatSchema))
async create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

```typescript

@Post()
@Bind(Body())
@UsePipes(new JoiValidationPipe(createCatSchema))
async create(createCatDto) {
  this.catsService.create(createCatDto);
}
```

> **Hint** The `@UsePipes()` decorator is imported from the `@nestjs/common` package.

#### Class validator[#](/pipes#class-validator)

> **Warning** The techniques in this section require TypeScript, and are not available if your app is written using vanilla JavaScript.

Let's look at an alternate implementation for our validation technique.

Nest works well with the [class-validator](https://github.com/typestack/class-validator) library. This powerful library allows you to use decorator-based validation. Decorator-based validation is extremely powerful, especially when combined with Nest's **Pipe** capabilities since we have access to the `metatype` of the processed property. Before we start, we need to install the required packages:

```bash

$ npm i --save class-validator class-transformer
```

Once these are installed, we can add a few decorators to the `CreateCatDto` class. Here we see a significant advantage of this technique: the `CreateCatDto` class remains the single source of truth for our Post body object (rather than having to create a separate validation class).

create-cat.dto.ts

JS TS

```typescript

import { IsString, IsInt } from 'class-validator';

export class CreateCatDto {
  @IsString()
  name: string;

  @IsInt()
  age: number;

  @IsString()
  breed: string;
}
```

> **Hint** Read more about the class-validator decorators [here](https://github.com/typestack/class-validator#usage).

Now we can create a `ValidationPipe` class that uses these annotations.

validation.pipe.ts

JS TS

```typescript

import { PipeTransform, Injectable, ArgumentMetadata, BadRequestException } from '@nestjs/common';
import { validate } from 'class-validator';
import { plainToClass } from 'class-transformer';

@Injectable()
export class ValidationPipe implements PipeTransform<any> {
  async transform(value: any, { metatype }: ArgumentMetadata) {
    if (!metatype || !this.toValidate(metatype)) {
      return value;
    }
    const object = plainToClass(metatype, value);
    const errors = await validate(object);
    if (errors.length > 0) {
      throw new BadRequestException('Validation failed');
    }
    return value;
  }

  private toValidate(metatype: Function): boolean {
    const types: Function[] = [String, Boolean, Number, Array, Object];
    return !types.includes(metatype);
  }
}
```

> **Notice** Above, we have used the [class-transformer](https://github.com/typestack/class-transformer) library. It's made by the same author as the **class-validator** library, and as a result, they play very well together.

```typescript

@Post()
async create(
  @Body(new ValidationPipe()) createCatDto: CreateCatDto,
) {
  this.catsService.create(createCatDto);
}
```

Parameter-scoped pipes are useful when the validation logic concerns only one specified parameter.

#### Global scoped pipes[#](/pipes#global-scoped-pipes)

Since the `ValidationPipe` was created to be as generic as possible, we can realize it's full utility by setting it up as a **global-scoped** pipe so that it is applied to every route handler across the entire application.

main.ts

JS TS

```typescript

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.useGlobalPipes(new ValidationPipe());
  await app.listen(3000);
}
bootstrap();
```

> **Notice** In the case of [hybrid apps](faq/hybrid-application) the `useGlobalPipes()` method doesn't set up pipes for gateways and micro services. For "standard" (non-hybrid) microservice apps, `useGlobalPipes()` does mount pipes globally.

Global pipes are used across the whole application, for every controller and every route handler.

Note that in terms of dependency injection, global pipes registered from outside of any module (with `useGlobalPipes()` as in the example above) cannot inject dependencies since the binding has been done outside the context of any module. In order to solve this issue, you can set up a global pipe **directly from any module** using the following construction:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { APP_PIPE } from '@nestjs/core';

@Module({
  providers: [
    {
      provide: APP_PIPE,
      useClass: ValidationPipe,
    },
  ],
})
export class AppModule {}
```

> **Hint** When using this approach to perform dependency injection for the pipe, note that regardless of the module where this construction is employed, the pipe is, in fact, global. Where should this be done? Choose the module where the pipe (`ValidationPipe` in the example above) is defined. Also, `useClass` is not the only way of dealing with custom provider registration. Learn more [here](/v7/fundamentals/custom-providers).

#### The built-in ValidationPipe[#](/pipes#the-built-in-validationpipe)

As a reminder, you don't have to build a generic validation pipe on your own since the `ValidationPipe` is provided by Nest out-of-the-box. The built-in `ValidationPipe` offers more options than the sample we built in this chapter, which has been kept basic for the sake of illustrating the mechanics of a custom-built pipe. You can find full details, along with lots of examples [here](/v7/techniques/validation).

#### Transformation use case[#](/pipes#transformation-use-case)

Validation isn't the only use case for custom pipes. At the beginning of this chapter, we mentioned that a pipe can also **transform** the input data to the desired format. This is possible because the value returned from the `transform` function completely overrides the previous value of the argument.

When is this useful? Consider that sometimes the data passed from the client needs to undergo some change - for example converting a string to an integer - before it can be properly handled by the route handler method. Furthermore, some required data fields may be missing, and we would like to apply default values. **Transformation pipes** can perform these functions by interposing a processing function between the client request and the request handler.

Here's a simple `ParseIntPipe` which is responsible for parsing a string into an integer value. (As noted above, Nest has a built-in `ParseIntPipe` that is more sophisticated; we include this as a simple example of a custom transformation pipe).

parse-int.pipe.ts

JS TS

```typescript

import { PipeTransform, Injectable, ArgumentMetadata, BadRequestException } from '@nestjs/common';

@Injectable()
export class ParseIntPipe implements PipeTransform<string, number> {
  transform(value: string, metadata: ArgumentMetadata): number {
    const val = parseInt(value, 10);
    if (isNaN(val)) {
      throw new BadRequestException('Validation failed');
    }
    return val;
  }
}
```

```typescript

import { Injectable, BadRequestException } from '@nestjs/common';

@Injectable()
export class ParseIntPipe {
  transform(value, metadata) {
    const val = parseInt(value, 10);
    if (isNaN(val)) {
      throw new BadRequestException('Validation failed');
    }
    return val;
  }
}
```

We can then bind this pipe to the selected param as shown below:

JS TS

```typescript

@Get(':id')
async findOne(@Param('id', new ParseIntPipe()) id) {
  return this.catsService.findOne(id);
}
```

```typescript

@Get(':id')
@Bind(Param('id', new ParseIntPipe()))
async findOne(id) {
  return this.catsService.findOne(id);
}
```

Another useful transformation case would be to select an **existing user** entity from the database using an id supplied in the request:

JS TS

```typescript

@Get(':id')
findOne(@Param('id', UserByIdPipe) userEntity: UserEntity) {
  return userEntity;
}
```

```typescript

@Get(':id')
@Bind(Param('id', UserByIdPipe))
findOne(userEntity) {
  return userEntity;
}
```

We leave the implementation of this pipe to the reader, but note that like all other transformation pipes, it receives an input value (an `id`) and returns an output value (a `UserEntity` object). This can make your code more declarative and [DRY](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself) by abstracting boilerplate code out of your handler and into a common pipe.

#### Providing defaults[#](/pipes#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:

JS TS

```typescript

@Get()
async findAll(
  @Query('activeOnly', new DefaultValuePipe(false), ParseBoolPipe) activeOnly: boolean,
  @Query('page', new DefaultValuePipe(0), ParseIntPipe) page: number,
) {
  return this.catsService.findAll({ activeOnly, page });
}
```

----
url: https://docs.nestjs.com/v5/providers
----

### Providers

Basically, almost everything may be considered as a provider – service, repository, factory, helper, and so on. All of them can **inject** dependencies through `constructor`, meaning, they can create various relationships with each other. But in fact, a provider is nothing else than just a simple class annotated with an `@Injectable()` decorator.

In the previous chapter, we have built a simple `CatsController`. Controllers shall handle HTTP requests and delegate more complex tasks to the **services**. The providers are plain JavaScript classes with an `@Injectable()` decorator on top of them.

> **Hint** Since Nest enables the possibility to design and organize the dependencies in a more OO-way, we strongly recommend following the **SOLID** principles.

#### Services

Let's start by creating a simple `CatsService` provider.

cats.service.ts

JS TS

TypeScript

```typescript

import { Injectable } from '@nestjs/common';
import { Cat } from './interfaces/cat.interface';

@Injectable()
export class CatsService {
  private readonly cats: Cat[] = [];

  create(cat: Cat) {
    this.cats.push(cat);
  }

  findAll(): Cat[] {
    return this.cats;
  }
}
```

TypeScript

```typescript

import { Injectable } from '@nestjs/common';

@Injectable()
export class CatsService {
  constructor() {
    this.cats = [];
  }

  create(cat) {
    this.cats.push(cat);
  }

  findAll() {
    return this.cats;
  }
}
```

> **Hint** To create a service using CLI, simply execute `$ nest g service cats/cats` command.

Here's a `CatsService`, a basic class with one property and two methods. The only new trait is that it uses the `@Injectable()` decorator. The `@Injectable()` attaches the metadata, thereby Nest knows that this class is a Nest provider. Notice that there is a `Cat` interface used above. We didn't mention it because the schema is exactly same as in the `CreateCatDto` class which we have created in the previous chapter.

Since we have the service class already done, let's use it inside the `CatsController`:

cats.controller.ts

JS TS

TypeScript

```typescript

import { Controller, Get, Post, Body } from '@nestjs/common';
import { CreateCatDto } from './dto/create-cat.dto';
import { CatsService } from './cats.service';
import { Cat } from './interfaces/cat.interface';

@Controller('cats')
export class CatsController {
  constructor(private readonly catsService: CatsService) {}

  @Post()
  async create(@Body() createCatDto: CreateCatDto) {
    this.catsService.create(createCatDto);
  }

  @Get()
  async findAll(): Promise<Cat[]> {
    return this.catsService.findAll();
  }
}
```

TypeScript

```typescript

import { Controller, Get, Post, Body, Bind, Dependencies } from '@nestjs/common';
import { CatsService } from './cats.service';

@Controller('cats')
@Dependencies(CatsService)
export class CatsController {
  constructor(catsService) {
    this.catsService = catsService;
  }

  @Post()
  @Bind(Body())
  async create(createCatDto) {
    this.catsService.create(createCatDto);
  }

  @Get()
  async findAll() {
    return this.catsService.findAll();
  }
}
```

The `CatsService` is injected through the class constructor. Don't be afraid of the `private readonly` shortened syntax. It means that we've created and initialized the `catsService` member immedietely in the same location.

#### Dependency injection

Nest is built around the strong design pattern commonly known as **Dependency injection**. We recommend to read a great article about this concept in the official [Angular](https://angular.io/guide/dependency-injection) documentation.

In Nest, thanks to the **TypeScript** capabilities, it's extremely easy to manage dependencies because they will be resolved just by type and afterward, passed to your controller's constructor:

TypeScript

```typescript

constructor(private readonly catsService: CatsService) {}
```

#### Custom providers

An inversion of control container, that Nest makes use of to resolve relationships between providers, is far more powerful than described above. The `@Injectable()` decorator is only a tip of an iceberg, not strictly required to define providers. Instead, you can use plain values, classes, either asynchronous or synchronous factories. Look [here](/v5/fundamentals/dependency-injection) to find more examples.

#### Optional providers

Occasionally, you might face relations which do not necessarily have to be resolved. For instance, your class may depend on a **configuration object**, but if none was passed, the default values should be used. In such case, the relation becomes optional, because lack of the configuration provider wouldn't lead to errors.

To ensure that provider isn't required, use `@Optional()` decorator in the `constructor` signature.

TypeScript

```typescript

import { Injectable, Optional, Inject } from '@nestjs/common';

@Injectable()
export class HttpService<T> {
  constructor(
    @Optional() @Inject('HTTP_OPTIONS') private readonly httpClient: T,
  ) {}
}
```

#### Property-based injection

In some very specific cases, a property-based injection might be useful. For instance, if your top-level class depends on either one or multiple providers, passing them all the way up by calling `super()` in sub-classes from the constructor can be very annonying. Thus, in order to avoid it, you can use `@Inject()` decorator on a property level.

TypeScript

```typescript

import { Injectable, Inject } from '@nestjs/common';

@Injectable()
export class HttpService<T> {
  @Inject('HTTP_OPTIONS')
  private readonly httpClient: T;
}
```

> **Warning** If your class doesn't extend any other provider, you should always prefer using **constructor-based** injection.

#### Provider registration

The last thing is to tell the module that something called `CatsService` truly exists. We do this by editing our module file - `app.module.ts`, and put the service into the `providers` array of the `@Module()` decorator.

app.module.ts

JS TS

TypeScript

```typescript

import { Module } from '@nestjs/common';
import { CatsController } from './cats/cats.controller';
import { CatsService } from './cats/cats.service';

@Module({
  controllers: [CatsController],
  providers: [CatsService],
})
export class ApplicationModule {}
```

Thanks to that, Nest will be able to resolve the dependencies of the `CatsController` class. This is how our directory structure looks right now:

* Providers
* Services
* Dependency injection
* Custom providers
* Optional providers
* Property-based injection
* Provider registration

----
url: https://docs.nestjs.com/v11/recipes/router-module
----

* [Router module](https://docs.nestjs.com/v11/recipes/router-module#router-module)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/recipes/router-module.md "Suggest Edits")

### Router module

> **Hint** This chapter is only relevant to HTTP-based applications.

In an HTTP application (for example, REST API), the route path for a handler is determined by concatenating the (optional) prefix declared for the controller (inside the `@Controller` decorator), and any path specified in the method's decorator (e.g, `@Get('users')`). You can learn more about that in [this section](/controllers#routing). Additionally, you can define a [global prefix](/v11/faq/global-prefix) for all routes registered in your application, or enable [versioning](/v11/techniques/versioning).

Also, there are edge-cases when defining a prefix at a module-level (and so for all controllers registered inside that module) may come in handy. For example, imagine a REST application that exposes several different endpoints being used by a specific portion of your application called "Dashboard". In such a case, instead of repeating the `/dashboard` prefix within each controller, you could use a utility `RouterModule` module, as follows:

```typescript

@Module({
  imports: [
    DashboardModule,
    RouterModule.register([
      {
        path: 'dashboard',
        module: DashboardModule,
      },
    ]),
  ],
})
export class AppModule {}
```

> **Hint** The `RouterModule` class is exported from the `@nestjs/core` package.

In addition, you can define hierarchical structures. This means each module can have `children` modules. The children modules will inherit their parent's prefix. In the following example, we'll register the `AdminModule` as a parent module of `DashboardModule` and `MetricsModule`.

```typescript

@Module({
  imports: [
    AdminModule,
    DashboardModule,
    MetricsModule,
    RouterModule.register([
      {
        path: 'admin',
        module: AdminModule,
        children: [
          {
            path: 'dashboard',
            module: DashboardModule,
          },
          {
            path: 'metrics',
            module: MetricsModule,
          },
        ],
      },
    ])
  ],
});
```

> **Hint** This feature should be used very carefully, as overusing it can make code difficult to maintain over time.

In the example above, any controller registered inside the `DashboardModule` will have an extra `/admin/dashboard` prefix (as the module concatenates paths from top to bottom - recursively - parent to children). Likewise, each controller defined inside the `MetricsModule` will have an additional module-level prefix `/admin/metrics`.

----
url: https://docs.nestjs.com/v10/first-steps
----

* [First steps](https://docs.nestjs.com/v10/first-steps#first-steps)
* [Language](https://docs.nestjs.com/v10/first-steps#language)
* [Prerequisites](https://docs.nestjs.com/v10/first-steps#prerequisites)
* [Setup](https://docs.nestjs.com/v10/first-steps#setup)
* [Platform](https://docs.nestjs.com/v10/first-steps#platform)
* [Running the application](https://docs.nestjs.com/v10/first-steps#running-the-application)
* [Linting and formatting](https://docs.nestjs.com/v10/first-steps#linting-and-formatting)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/first-steps.md "Suggest Edits")

### First steps

In this set of articles, you'll learn the **core fundamentals** of Nest. To get familiar with the essential building blocks of Nest applications, we'll build a basic CRUD application with features that cover a lot of ground at an introductory level.

#### Language[#](/first-steps#language)

We're in love with [TypeScript](https://www.typescriptlang.org/), but above all - we love [Node.js](https://nodejs.org/en/). That's why Nest is compatible with both TypeScript and pure JavaScript. Nest takes advantage of the latest language features, so to use it with vanilla JavaScript we need a [Babel](https://babeljs.io/) compiler.

We'll mostly use TypeScript in the examples we provide, but you can always **switch the code snippets** to vanilla JavaScript syntax (simply click to toggle the language button in the upper right hand corner of each snippet).

#### Prerequisites[#](/first-steps#prerequisites)

Please make sure that [Node.js](https://nodejs.org) (version >= 16) is installed on your operating system.

#### Setup[#](/first-steps#setup)

Setting up a new project is quite simple with the [Nest CLI](/v10/cli/overview). With [npm](https://www.npmjs.com/) installed, you can create a new Nest project with the following commands in your OS terminal:

```bash

$ npm i -g @nestjs/cli
$ nest new project-name
```

> **Hint** To create a new project with TypeScript's [stricter](https://www.typescriptlang.org/tsconfig#strict) feature set, pass the `--strict` flag to the `nest new` command.

| `app.controller.ts`      | A basic controller with a single route.                                                                             |
| ------------------------ | ------------------------------------------------------------------------------------------------------------------- |
| `app.controller.spec.ts` | The unit tests for the controller.                                                                                  |
| `app.module.ts`          | The root module of the application.                                                                                 |
| `app.service.ts`         | A basic service with a single method.                                                                               |
| `main.ts`                | The entry file of the application which uses the core function `NestFactory` to create a Nest application instance. |

The `main.ts` includes an async function, which will **bootstrap** our application:

main.ts

JS TS

```typescript

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  await app.listen(process.env.PORT ?? 3000);
}
bootstrap();
```

```typescript

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  await app.listen(process.env.PORT ?? 3000);
}
bootstrap();
```

To create a Nest application instance, we use the core `NestFactory` class. `NestFactory` exposes a few static methods that allow creating an application instance. The `create()` method returns an application object, which fulfills the `INestApplication` interface. This object provides a set of methods which are described in the coming chapters. In the `main.ts` example above, we simply start up our HTTP listener, which lets the application await inbound HTTP requests.

Note that a project scaffolded with the Nest CLI creates an initial project structure that encourages developers to follow the convention of keeping each module in its own dedicated directory.

> **Hint** By default, if any error happens while creating the application your app will exit with the code `1`. If you want to make it throw an error instead disable the option `abortOnError` (e.g., `NestFactory.create(AppModule, { abortOnError: false })`).

| `platform-express` | [Express](https://expressjs.com/) is a well-known minimalist web framework for node. It's a battle tested, production-ready library with lots of resources implemented by the community. The `@nestjs/platform-express` package is used by default. Many users are well served with Express, and need take no action to enable it. |
| ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `platform-fastify` | [Fastify](https://www.fastify.io/) is a high performance and low overhead framework highly focused on providing maximum efficiency and speed. Read how to use it [here](/v10/techniques/performance).                                                                                                                              |

Whichever platform is used, it exposes its own application interface. These are seen respectively as `NestExpressApplication` and `NestFastifyApplication`.

When you pass a type to the `NestFactory.create()` method, as in the example below, the `app` object will have methods available exclusively for that specific platform. Note, however, you don't **need** to specify a type **unless** you actually want to access the underlying platform API.

```typescript

const app = await NestFactory.create<NestExpressApplication>(AppModule);
```

#### Running the application[#](/first-steps#running-the-application)

Once the installation process is complete, you can run the following command at your OS command prompt to start the application listening for inbound HTTP requests:

```bash

$ npm run start
```

> **Hint** To speed up the development process (x20 times faster builds), you can use the [SWC builder](/v10/recipes/swc) by passing the `-b swc` flag to the `start` script, as follows `npm run start -- -b swc`.

This command starts the app with the HTTP server listening on the port defined in the `src/main.ts` file. Once the application is running, open your browser and navigate to `http://localhost:3000/`. You should see the `Hello World!` message.

To watch for changes in your files, you can run the following command to start the application:

```bash

$ npm run start:dev
```

This command will watch your files, automatically recompiling and reloading the server.

#### Linting and formatting[#](/first-steps#linting-and-formatting)

[CLI](/v10/cli/overview) provides best effort to scaffold a reliable development workflow at scale. Thus, a generated Nest project comes with both a code **linter** and **formatter** preinstalled (respectively [eslint](https://eslint.org/) and [prettier](https://prettier.io/)).

> **Hint** Not sure about the role of formatters vs linters? Learn the difference [here](https://prettier.io/docs/en/comparison.html).

To ensure maximum stability and extensibility, we use the base [`eslint`](https://www.npmjs.com/package/eslint) and [`prettier`](https://www.npmjs.com/package/prettier) cli packages. This setup allows neat IDE integration with official extensions by design.

For headless environments where an IDE is not relevant (Continuous Integration, Git hooks, etc.) a Nest project comes with ready-to-use `npm` scripts.

```bash

# Lint and autofix with eslint
$ npm run lint

# Format with prettier
$ npm run format
```

----
url: https://docs.nestjs.com/v6/recipes/cqrs
----

* [CQRS](https://docs.nestjs.com/v6/recipes/cqrs#cqrs)
* [Installation](https://docs.nestjs.com/v6/recipes/cqrs#installation)
* [Commands](https://docs.nestjs.com/v6/recipes/cqrs#commands)
* [Events](https://docs.nestjs.com/v6/recipes/cqrs#events)
* [Sagas](https://docs.nestjs.com/v6/recipes/cqrs#sagas)
* [Queries](https://docs.nestjs.com/v6/recipes/cqrs#queries)
* [Setup](https://docs.nestjs.com/v6/recipes/cqrs#setup)
* [Summary](https://docs.nestjs.com/v6/recipes/cqrs#summary)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/recipes/cqrs.md "Suggest Edits")

### CQRS

The flow of simple [CRUD](https://en.wikipedia.org/wiki/Create,_read,_update_and_delete) (Create, Read, Update and Delete) applications can be described using the following steps:

1. The **controllers** layer handles HTTP requests and delegates tasks to the services layer.
2. The **services layer** is where most of the business logic lives.
3. Services uses **repositories / DAOs** to change / persist entities.
4. Entities act as containers for the values, with setters and getters.

In most cases, for small and medium-sized applications, this pattern is sufficient. However, when our requirements become more complex, the **CQRS** model may be more appropriate and scalable. To facilitate that model, Nest provides a lightweight [CQRS module](https://github.com/nestjs/cqrs). This chapter describes how to use it.

#### Installation[#](/recipes/cqrs#installation)

First install the required package:

```bash

$ npm install --save @nestjs/cqrs
```

#### Commands[#](/recipes/cqrs#commands)

In this model, each action is called a **Command**. When a command is dispatched, the application reacts to it. Commands can be dispatched from the services layer, or directly from controllers/gateways. Commands are consumed by **Command Handlers**.

heroes-game.service.ts

JS TS

```typescript

@Injectable()
export class HeroesGameService {
  constructor(private readonly commandBus: CommandBus) {}

  async killDragon(heroId: string, killDragonDto: KillDragonDto) {
    return this.commandBus.execute(
      new KillDragonCommand(heroId, killDragonDto.dragonId)
    );
  }
}
```

```typescript

@Injectable()
@Dependencies(CommandBus)
export class HeroesGameService {
  constructor(commandBus) {
    this.commandBus = commandBus;
  }

  async killDragon(heroId, killDragonDto) {
    return this.commandBus.execute(
      new KillDragonCommand(heroId, killDragonDto.dragonId)
    );
  }
}
```

Here's a sample service that dispatches `KillDragonCommand`. Let's see how the command looks:

kill-dragon.command.ts

JS TS

```typescript

export class KillDragonCommand {
  constructor(
    public readonly heroId: string,
    public readonly dragonId: string,
  ) {}
}
```

```typescript

export class KillDragonCommand {
  constructor(heroId, dragonId) {
    this.heroId = heroId;
    this.dragonId = dragonId;
  }
}
```

The `CommandBus` is a **stream** of commands. It delegates commands to the equivalent handlers. Each command must have a corresponding **Command Handler**:

kill-dragon.handler.ts

JS TS

```typescript

@CommandHandler(KillDragonCommand)
export class KillDragonHandler implements ICommandHandler<KillDragonCommand> {
  constructor(private readonly repository: HeroRepository) {}

  async execute(command: KillDragonCommand) {
    const { heroId, dragonId } = command;
    const hero = this.repository.findOneById(+heroId);

    hero.killEnemy(dragonId);
    await this.repository.persist(hero);
  }
}
```

```typescript

@CommandHandler(KillDragonCommand)
@Dependencies(HeroRepository)
export class KillDragonHandler {
  constructor(repository) {
    this.repository = repository;
  }

  async execute(command) {
    const { heroId, dragonId } = command;
    const hero = this.repository.findOneById(+heroId);

    hero.killEnemy(dragonId);
    await this.repository.persist(hero);
  }
}
```

With this approach, every application state change is driven by the occurrence of a **Command**. The logic is encapsulated in handlers. With this approach, we can simply add behavior like logging or persisting commands in the database (e.g., for diagnostics purposes).

#### Events[#](/recipes/cqrs#events)

Command handlers neatly encapsulate logic. While beneficial, the application structure is still not flexible enough, not **reactive**. To remedy this, we also introduce **events**.

hero-killed-dragon.event.ts

JS TS

```typescript

export class HeroKilledDragonEvent {
  constructor(
    public readonly heroId: string,
    public readonly dragonId: string,
  ) {}
}
```

```typescript

export class HeroKilledDragonEvent {
  constructor(heroId, dragonId) {
    this.heroId = heroId;
    this.dragonId = dragonId;
  }
}
```

Events are asynchronous. They are dispatched either by **models** or directly using `EventBus`. In order to dispatch events, models have to extend the `AggregateRoot` class.

hero.model.ts

JS TS

```typescript

export class Hero extends AggregateRoot {
  constructor(private readonly id: string) {
    super();
  }

  killEnemy(enemyId: string) {
    // logic
    this.apply(new HeroKilledDragonEvent(this.id, enemyId));
  }
}
```

```typescript

export class Hero extends AggregateRoot {
  constructor(id) {
    super();
    this.id = id;
  }

  killEnemy(enemyId) {
    // logic
    this.apply(new HeroKilledDragonEvent(this.id, enemyId));
  }
}
```

The `apply()` method does not dispatch events yet because there's no relationship between the model and the `EventPublisher` class. How do we associate the model and the publisher? By using a publisher `mergeObjectContext()` method inside our command handler.

kill-dragon.handler.ts

JS TS

```typescript

@CommandHandler(KillDragonCommand)
export class KillDragonHandler implements ICommandHandler<KillDragonCommand> {
  constructor(
    private readonly repository: HeroRepository,
    private readonly publisher: EventPublisher,
  ) {}

  async execute(command: KillDragonCommand) {
    const { heroId, dragonId } = command;
    const hero = this.publisher.mergeObjectContext(
      await this.repository.findOneById(+heroId),
    );
    hero.killEnemy(dragonId);
    hero.commit();
  }
}
```

```typescript

@CommandHandler(KillDragonCommand)
@Dependencies(HeroRepository, EventPublisher)
export class KillDragonHandler {
  constructor(repository, publisher) {
    this.repository = repository;
    this.publisher = publisher;
  }

  async execute(command) {
    const { heroId, dragonId } = command;
    const hero = this.publisher.mergeObjectContext(
      await this.repository.findOneById(+heroId),
    );
    hero.killEnemy(dragonId);
    hero.commit();
  }
}
```

Now everything works as expected. Notice that we need to `commit()` events since they're not being dispatched immediately. Obviously, an object doesn't have to exist up front. We can easily merge type context as well:

```typescript

const HeroModel = this.publisher.mergeContext(Hero);
new HeroModel('id');
```

Now the model has the ability to publish events. Additionally, we can emit events manually using `EventBus`:

```typescript

this.eventBus.publish(new HeroKilledDragonEvent());
```

> **Hint** The `EventBus` is an injectable class.

Each event can have multiple **Event Handlers**.

hero-killed-dragon.handler.ts

JS TS

```typescript

@EventsHandler(HeroKilledDragonEvent)
export class HeroKilledDragonHandler implements IEventHandler<HeroKilledDragonEvent> {
  constructor(private readonly repository: HeroRepository) {}

  handle(event: HeroKilledDragonEvent) {
    // logic
  }
}
```

Now we can move the **write logic** into the event handlers.

#### Sagas[#](/recipes/cqrs#sagas)

This type of **Event-Driven Architecture** improves application **reactiveness and scalability**. Now, when we have events, we can simply react to them in various ways. **Sagas** are the final building block from an architectural point of view.

Sagas are an extremely powerful feature. A single saga may listen for 1..\* events. Using the [RxJS](https://github.com/ReactiveX/rxjs) library, it can combine, merge, filter or apply other `RxJS` operators on the event stream. Each saga returns an Observable which contains a command. This command is dispatched **asynchronously**.

heroes-game.saga.ts

JS TS

```typescript

@Injectable()
export class HeroesGameSagas {
  @Saga()
  dragonKilled = (events$: Observable<any>): Observable<ICommand> => {
    return events$.pipe(
      ofType(HeroKilledDragonEvent),
      map((event) => new DropAncientItemCommand(event.heroId, fakeItemID)),
    );
  }
}
```

```typescript

@Injectable()
export class HeroesGameSagas {
  @Saga()
  dragonKilled = (events$) => {
    return events$.pipe(
      ofType(HeroKilledDragonEvent),
      map((event) => new DropAncientItemCommand(event.heroId, fakeItemID)),
    );
  }
}
```

> **Hint** The `ofType` operator is exported from the `@nestjs/cqrs` package.

```typescript

export const CommandHandlers = [KillDragonHandler, DropAncientItemHandler];
export const EventHandlers =  [HeroKilledDragonHandler, HeroFoundItemHandler];

@Module({
  imports: [CqrsModule],
  controllers: [HeroesGameController],
  providers: [
    HeroesGameService,
    HeroesGameSagas,
    ...CommandHandlers,
    ...EventHandlers,
    HeroRepository,
  ]
})
export class HeroesGameModule {}
```

#### Summary[#](/recipes/cqrs#summary)

`CommandBus`, `QueryBus` and `EventBus` are **Observables**. This means that you can easily subscribe to the whole stream and enrich your application with **Event Sourcing**.

A working example is available [here](https://github.com/kamilmysliwiec/nest-cqrs-example).

----
url: https://docs.nestjs.com/v11/faq/global-prefix
----

* [Global prefix](https://docs.nestjs.com/v11/faq/global-prefix#global-prefix)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/faq/global-prefix.md "Suggest Edits")

### Global prefix

To set a prefix for **every route** registered in an HTTP application, use the `setGlobalPrefix()` method of the `INestApplication` instance.

```typescript

const app = await NestFactory.create(AppModule);
app.setGlobalPrefix('v1');
```

You can exclude routes from the global prefix using the following construction:

```typescript

app.setGlobalPrefix('v1', {
  exclude: [{ path: 'health', method: RequestMethod.GET }],
});
```

Alternatively, you can specify route as a string (it will apply to every request method):

```typescript

app.setGlobalPrefix('v1', { exclude: ['cats'] });
```

> **Hint** The `path` property supports wildcard parameters using the [path-to-regexp](https://github.com/pillarjs/path-to-regexp#parameters) package. Note: this does not accept wildcard asterisks `*`. Instead, you must use parameters (`:param`) or named wildcards (`*splat`).

----
url: https://docs.nestjs.com/v10/websockets/guards
----

* [Guards](https://docs.nestjs.com/v10/websockets/guards#guards)
* [Binding guards](https://docs.nestjs.com/v10/websockets/guards#binding-guards)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/websockets/guards.md "Suggest Edits")

### Guards

There is no fundamental difference between web sockets guards and [regular HTTP application guards](/v10/guards). The only difference is that instead of throwing `HttpException`, you should use `WsException`.

> **Hint** The `WsException` class is exposed from `@nestjs/websockets` package.

#### Binding guards[#](/websockets/guards#binding-guards)

The following example uses a method-scoped guard. Just as with HTTP based applications, you can also use gateway-scoped guards (i.e., prefix the gateway class with a `@UseGuards()` decorator).

JS TS

```typescript

@UseGuards(AuthGuard)
@SubscribeMessage('events')
handleEvent(client: Client, data: unknown): WsResponse<unknown> {
  const event = 'events';
  return { event, data };
}
```

```typescript

@UseGuards(AuthGuard)
@SubscribeMessage('events')
handleEvent(client, data) {
  const event = 'events';
  return { event, data };
}
```

----
url: https://docs.nestjs.com/v10/recipes/terminus
----

* [Healthchecks (Terminus)](https://docs.nestjs.com/v10/recipes/terminus#healthchecks-terminus)
* [Getting started](https://docs.nestjs.com/v10/recipes/terminus#getting-started)
* [Setting up a Healthcheck](https://docs.nestjs.com/v10/recipes/terminus#setting-up-a-healthcheck)
* [HTTP Healthcheck](https://docs.nestjs.com/v10/recipes/terminus#http-healthcheck)
* [TypeOrm health indicator](https://docs.nestjs.com/v10/recipes/terminus#typeorm-health-indicator)
* [Disk health indicator](https://docs.nestjs.com/v10/recipes/terminus#disk-health-indicator)
* [Memory health indicator](https://docs.nestjs.com/v10/recipes/terminus#memory-health-indicator)
* [Custom health indicator](https://docs.nestjs.com/v10/recipes/terminus#custom-health-indicator)
* [Logging](https://docs.nestjs.com/v10/recipes/terminus#logging)
* [Graceful shutdown timeout](https://docs.nestjs.com/v10/recipes/terminus#graceful-shutdown-timeout)
* [More examples](https://docs.nestjs.com/v10/recipes/terminus#more-examples)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/recipes/terminus.md "Suggest Edits")

### Healthchecks (Terminus)

Terminus integration provides you with **readiness/liveness** health checks. Healthchecks are crucial when it comes to complex backend setups. In a nutshell, a health check in the realm of web development usually consists of a special address, for example, `https://my-website.com/health/readiness`. A service or a component of your infrastructure (e.g., [Kubernetes](https://kubernetes.io/) checks this address continuously. Depending on the HTTP status code returned from a `GET` request to this address the service will take action when it receives an "unhealthy" response. Since the definition of "healthy" or "unhealthy" varies with the type of service you provide, the **Terminus** integration supports you with a set of **health indicators**.

As an example, if your web server uses MongoDB to store its data, it would be vital information whether MongoDB is still up and running. In that case, you can make use of the `MongooseHealthIndicator`. If configured correctly - more on that later - your health check address will return a healthy or unhealthy HTTP status code, depending on whether MongoDB is running.

#### Getting started[#](/recipes/terminus#getting-started)

To get started with `@nestjs/terminus` we need to install the required dependency.

```bash

$ npm install --save @nestjs/terminus
```

> **Hint** To create the module using the [Nest CLI](/v10/recipes/terminus/cli/overview), simply execute the `$ nest g module health` command.

health.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { TerminusModule } from '@nestjs/terminus';

@Module({
  imports: [TerminusModule]
})
export class HealthModule {}
```

Our healthcheck(s) can be executed using a [controller](/v10/controllers), which can be easily set up using the [Nest CLI](/v10/recipes/terminus/cli/overview).

```bash

$ nest g controller health
```

> **Info** It is highly recommended to enable shutdown hooks in your application. Terminus integration makes use of this lifecycle event if enabled. Read more about shutdown hooks [here](fundamentals/lifecycle-events#application-shutdown).

#### HTTP Healthcheck[#](/recipes/terminus#http-healthcheck)

Once we have installed `@nestjs/terminus`, imported our `TerminusModule` and created a new controller, we are ready to create a health check.

The `HTTPHealthIndicator` requires the `@nestjs/axios` package so make sure to have it installed:

```bash

$ npm i --save @nestjs/axios axios
```

Now we can setup our `HealthController`:

health.controller.ts

JS TS

```typescript

import { Controller, Get } from '@nestjs/common';
import { HealthCheckService, HttpHealthIndicator, HealthCheck } from '@nestjs/terminus';

@Controller('health')
export class HealthController {
  constructor(
    private health: HealthCheckService,
    private http: HttpHealthIndicator,
  ) {}

  @Get()
  @HealthCheck()
  check() {
    return this.health.check([
      () => this.http.pingCheck('nestjs-docs', 'https://docs.nestjs.com'),
    ]);
  }
}
```

```typescript

import { Controller, Dependencies, Get } from '@nestjs/common';
import { HealthCheckService, HttpHealthIndicator, HealthCheck } from '@nestjs/terminus';

@Controller('health')
@Dependencies(HealthCheckService, HttpHealthIndicator)
export class HealthController {
  constructor(
    private health,
    private http,
  ) { }

  @Get()
  @HealthCheck()
  healthCheck() {
    return this.health.check([
      () => this.http.pingCheck('nestjs-docs', 'https://docs.nestjs.com'),
    ])
  }
}
```

health.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { TerminusModule } from '@nestjs/terminus';
import { HttpModule } from '@nestjs/axios';
import { HealthController } from './health.controller';

@Module({
  imports: [TerminusModule, HttpModule],
  controllers: [HealthController],
})
export class HealthModule {}
```

```typescript

import { Module } from '@nestjs/common';
import { TerminusModule } from '@nestjs/terminus';
import { HttpModule } from '@nestjs/axios';
import { HealthController } from './health.controller';

@Module({
  imports: [TerminusModule, HttpModule],
  controllers: [HealthController],
})
export class HealthModule {}
```

Our health check will now send a *GET*-request to the `https://docs.nestjs.com` address. If we get a healthy response from that address, our route at `http://localhost:3000/health` will return the following object with a 200 status code.

```json

{
  "status": "ok",
  "info": {
    "nestjs-docs": {
      "status": "up"
    }
  },
  "error": {},
  "details": {
    "nestjs-docs": {
      "status": "up"
    }
  }
}
```

The interface of this response object can be accessed from the `@nestjs/terminus` package with the `HealthCheckResult` interface.

| `status`  | If any health indicator failed the status will be `'error'`. If the NestJS app is shutting down but still accepting HTTP requests, the health check will have the `'shutting_down'` status. | `'error' \| 'ok' \| 'shutting_down'` |
| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------ |
| `info`    | Object containing information of each health indicator which is of status `'up'`, or in other words "healthy".                                                                              | `object`                             |
| `error`   | Object containing information of each health indicator which is of status `'down'`, or in other words "unhealthy".                                                                          | `object`                             |
| `details` | Object containing all information of each health indicator                                                                                                                                  | `object`                             |

##### Check for specific HTTP response codes

In certain cases, you might want to check for specific criteria and validate the response. As an example, let's assume `https://my-external-service.com` returns a response code `204`. With `HttpHealthIndicator.responseCheck` you can check for that response code specifically and determine all other codes as unhealthy.

In case any other response code other than `204` gets returned, the following example would be unhealthy. The third parameter requires you to provide a function (sync or async) which returns a boolean whether the response is considered healthy (`true`) or unhealthy (`false`).

health.controller.ts

JS TS

```typescript

// Within the `HealthController`-class

@Get()
@HealthCheck()
check() {
  return this.health.check([
    () =>
      this.http.responseCheck(
        'my-external-service',
        'https://my-external-service.com',
        (res) => res.status === 204,
      ),
  ]);
}
```

#### TypeOrm health indicator[#](/recipes/terminus#typeorm-health-indicator)

Terminus offers the capability to add database checks to your health check. In order to get started with this health indicator, you should check out the [Database chapter](/v10/techniques/sql) and make sure your database connection within your application is established.

> **Hint** Behind the scenes the `TypeOrmHealthIndicator` simply executes a `SELECT 1`-SQL command which is often used to verify whether the database still alive. In case you are using an Oracle database it uses `SELECT 1 FROM DUAL`.

health.controller.ts

JS TS

```typescript

@Controller('health')
export class HealthController {
  constructor(
    private health: HealthCheckService,
    private db: TypeOrmHealthIndicator,
  ) {}

  @Get()
  @HealthCheck()
  check() {
    return this.health.check([
      () => this.db.pingCheck('database'),
    ]);
  }
}
```

```typescript

@Controller('health')
@Dependencies(HealthCheckService, TypeOrmHealthIndicator)
export class HealthController {
  constructor(
    private health,
    private db,
  ) { }

  @Get()
  @HealthCheck()
  healthCheck() {
    return this.health.check([
      () => this.db.pingCheck('database'),
    ])
  }
}
```

If your database is reachable, you should now see the following JSON-result when requesting `http://localhost:3000/health` with a `GET` request:

```json

{
  "status": "ok",
  "info": {
    "database": {
      "status": "up"
    }
  },
  "error": {},
  "details": {
    "database": {
      "status": "up"
    }
  }
}
```

In case your app uses [multiple databases](techniques/database#multiple-databases), you need to inject each connection into your `HealthController`. Then, you can simply pass the connection reference to the `TypeOrmHealthIndicator`.

health.controller.ts

JS TS

```typescript

@Controller('health')
export class HealthController {
  constructor(
    private health: HealthCheckService,
    private db: TypeOrmHealthIndicator,
    @InjectConnection('albumsConnection')
    private albumsConnection: Connection,
    @InjectConnection()
    private defaultConnection: Connection,
  ) {}

  @Get()
  @HealthCheck()
  check() {
    return this.health.check([
      () => this.db.pingCheck('albums-database', { connection: this.albumsConnection }),
      () => this.db.pingCheck('database', { connection: this.defaultConnection }),
    ]);
  }
}
```

#### Disk health indicator[#](/recipes/terminus#disk-health-indicator)

With the `DiskHealthIndicator` we can check how much storage is in use. To get started, make sure to inject the `DiskHealthIndicator` into your `HealthController`. The following example checks the storage used of the path `/` (or on Windows you can use `C:\\`). If that exceeds more than 50% of the total storage space it would response with an unhealthy Health Check.

health.controller.ts

JS TS

```typescript

@Controller('health')
export class HealthController {
  constructor(
    private readonly health: HealthCheckService,
    private readonly disk: DiskHealthIndicator,
  ) {}

  @Get()
  @HealthCheck()
  check() {
    return this.health.check([
      () => this.disk.checkStorage('storage', { path: '/', thresholdPercent: 0.5 }),
    ]);
  }
}
```

```typescript

@Controller('health')
@Dependencies(HealthCheckService, DiskHealthIndicator)
export class HealthController {
  constructor(health, disk) {}

  @Get()
  @HealthCheck()
  healthCheck() {
    return this.health.check([
      () => this.disk.checkStorage('storage', { path: '/', thresholdPercent: 0.5 }),
    ])
  }
}
```

With the `DiskHealthIndicator.checkStorage` function you also have the possibility to check for a fixed amount of space. The following example would be unhealthy in case the path `/my-app/` would exceed 250GB.

health.controller.ts

JS TS

```typescript

// Within the `HealthController`-class

@Get()
@HealthCheck()
check() {
  return this.health.check([
    () => this.disk.checkStorage('storage', {  path: '/', threshold: 250 * 1024 * 1024 * 1024, })
  ]);
}
```

#### Memory health indicator[#](/recipes/terminus#memory-health-indicator)

To make sure your process does not exceed a certain memory limit the `MemoryHealthIndicator` can be used. The following example can be used to check the heap of your process.

> **Hint** Heap is the portion of memory where dynamically allocated memory resides (i.e. memory allocated via malloc). Memory allocated from the heap will remain allocated until one of the following occurs:
>
> * The memory is *free*'d
> * The program terminates

health.controller.ts

JS TS

```typescript

@Controller('health')
export class HealthController {
  constructor(
    private health: HealthCheckService,
    private memory: MemoryHealthIndicator,
  ) {}

  @Get()
  @HealthCheck()
  check() {
    return this.health.check([
      () => this.memory.checkHeap('memory_heap', 150 * 1024 * 1024),
    ]);
  }
}
```

```typescript

@Controller('health')
@Dependencies(HealthCheckService, MemoryHealthIndicator)
export class HealthController {
  constructor(health, memory) {}

  @Get()
  @HealthCheck()
  healthCheck() {
    return this.health.check([
      () => this.memory.checkHeap('memory_heap', 150 * 1024 * 1024),
    ])
  }
}
```

It is also possible to verify the memory RSS of your process with `MemoryHealthIndicator.checkRSS`. This example would return an unhealthy response code in case your process does have more than 150MB allocated.

> **Hint** RSS is the Resident Set Size and is used to show how much memory is allocated to that process and is in RAM. It does not include memory that is swapped out. It does include memory from shared libraries as long as the pages from those libraries are actually in memory. It does include all stack and heap memory.

health.controller.ts

JS TS

```typescript

// Within the `HealthController`-class

@Get()
@HealthCheck()
check() {
  return this.health.check([
    () => this.memory.checkRSS('memory_rss', 150 * 1024 * 1024),
  ]);
}
```

#### Custom health indicator[#](/recipes/terminus#custom-health-indicator)

In some cases, the predefined health indicators provided by `@nestjs/terminus` do not cover all of your health check requirements. In that case, you can set up a custom health indicator according to your needs.

Let's get started by creating a service that will represent our custom indicator. To get a basic understanding of how an indicator is structured, we will create an example `DogHealthIndicator`. This service should have the state `'up'` if every `Dog` object has the type `'goodboy'`. If that condition is not satisfied then it should throw an error.

dog.health.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { HealthIndicator, HealthIndicatorResult, HealthCheckError } from '@nestjs/terminus';

export interface Dog {
  name: string;
  type: string;
}

@Injectable()
export class DogHealthIndicator extends HealthIndicator {
  private dogs: Dog[] = [
    { name: 'Fido', type: 'goodboy' },
    { name: 'Rex', type: 'badboy' },
  ];

  async isHealthy(key: string): Promise<HealthIndicatorResult> {
    const badboys = this.dogs.filter(dog => dog.type === 'badboy');
    const isHealthy = badboys.length === 0;
    const result = this.getStatus(key, isHealthy, { badboys: badboys.length });

    if (isHealthy) {
      return result;
    }
    throw new HealthCheckError('Dogcheck failed', result);
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';
import { HealthCheckError } from '@godaddy/terminus';

@Injectable()
export class DogHealthIndicator extends HealthIndicator {
  dogs = [
    { name: 'Fido', type: 'goodboy' },
    { name: 'Rex', type: 'badboy' },
  ];

  async isHealthy(key) {
    const badboys = this.dogs.filter(dog => dog.type === 'badboy');
    const isHealthy = badboys.length === 0;
    const result = this.getStatus(key, isHealthy, { badboys: badboys.length });

    if (isHealthy) {
      return result;
    }
    throw new HealthCheckError('Dogcheck failed', result);
  }
}
```

The next thing we need to do is register the health indicator as a provider.

health.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { TerminusModule } from '@nestjs/terminus';
import { DogHealthIndicator } from './dog.health';

@Module({
  controllers: [HealthController],
  imports: [TerminusModule],
  providers: [DogHealthIndicator]
})
export class HealthModule { }
```

> **Hint** In a real-world application the `DogHealthIndicator` should be provided in a separate module, for example, `DogModule`, which then will be imported by the `HealthModule`.

The last required step is to add the now available health indicator in the required health check endpoint. For that, we go back to our `HealthController` and add it to our `check` function.

health.controller.ts

JS TS

```typescript

import { HealthCheckService, HealthCheck } from '@nestjs/terminus';
import { Injectable, Dependencies, Get } from '@nestjs/common';
import { DogHealthIndicator } from './dog.health';

@Injectable()
export class HealthController {
  constructor(
    private health: HealthCheckService,
    private dogHealthIndicator: DogHealthIndicator
  ) {}

  @Get()
  @HealthCheck()
  healthCheck() {
    return this.health.check([
      () => this.dogHealthIndicator.isHealthy('dog'),
    ])
  }
}
```

```typescript

import { HealthCheckService, HealthCheck } from '@nestjs/terminus';
import { Injectable, Get } from '@nestjs/common';
import { DogHealthIndicator } from './dog.health';

@Injectable()
@Dependencies(HealthCheckService, DogHealthIndicator)
export class HealthController {
  constructor(
    private health,
    private dogHealthIndicator
  ) {}

  @Get()
  @HealthCheck()
  healthCheck() {
    return this.health.check([
      () => this.dogHealthIndicator.isHealthy('dog'),
    ])
  }
}
```

#### Logging[#](/recipes/terminus#logging)

Terminus only logs error messages, for instance when a Healthcheck has failed. With the `TerminusModule.forRoot()` method you have more control over how errors are being logged as well as completely take over the logging itself.

In this section, we are going to walk you through how you create a custom logger `TerminusLogger`. This logger extends the built-in logger. Therefore you can pick and choose which part of the logger you would like to overwrite

> **Info** If you want to learn more about custom loggers in NestJS, [read more here](/techniques/logger#injecting-a-custom-logger).

terminus-logger.service.ts

JS TS

```typescript

import { Injectable, Scope, ConsoleLogger } from '@nestjs/common';

@Injectable({ scope: Scope.TRANSIENT })
export class TerminusLogger extends ConsoleLogger {
  error(message: any, stack?: string, context?: string): void;
  error(message: any, ...optionalParams: any[]): void;
  error(
    message: unknown,
    stack?: unknown,
    context?: unknown,
    ...rest: unknown[]
  ): void {
    // Overwrite here how error messages should be logged
  }
}
```

Once you have created your custom logger, all you need to do is simply pass it into the `TerminusModule.forRoot()` as such.

health.module.ts

JS TS

```typescript

@Module({
imports: [
  TerminusModule.forRoot({
    logger: TerminusLogger,
  }),
],
})
export class HealthModule {}
```

To completely suppress any log messages coming from Terminus, including error messages, configure Terminus as such.

health.module.ts

JS TS

```typescript

@Module({
imports: [
  TerminusModule.forRoot({
    logger: false,
  }),
],
})
export class HealthModule {}
```

Terminus allows you to configure how Healthcheck errors should be displayed in your logs.

| Error Log Style  | Description                                                                                                                        | Example |
| :--------------- | :--------------------------------------------------------------------------------------------------------------------------------- | :------ |
| `json` (default) | Prints a summary of the health check result in case of an error as JSON object                                                     |         |
| `pretty`         | Prints a summary of the health check result in case of an error within formatted boxes and highlights successful/erroneous results |         |

You can change the log style using the `errorLogStyle` configuration option as in the following snippet.

health.module.ts

JS TS

```typescript

@Module({
  imports: [
    TerminusModule.forRoot({
      errorLogStyle: 'pretty',
    }),
  ]
})
export class HealthModule {}
```

#### Graceful shutdown timeout[#](/recipes/terminus#graceful-shutdown-timeout)

If your application requires postponing its shutdown process, Terminus can handle it for you. This setting can prove particularly beneficial when working with an orchestrator such as Kubernetes. By setting a delay slightly longer than the readiness check interval, you can achieve zero downtime when shutting down containers.

health.module.ts

JS TS

```typescript

@Module({
  imports: [
    TerminusModule.forRoot({
      gracefulShutdownTimeoutMs: 1000,
    }),
  ]
})
export class HealthModule {}
```

#### More examples[#](/recipes/terminus#more-examples)

More working examples are available [here](https://github.com/nestjs/terminus/tree/master/sample).

----
url: https://docs.nestjs.com/v8/techniques/configuration
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Configuration](https://docs.nestjs.com/v8/techniques/configuration#configuration)
* [Installation](https://docs.nestjs.com/v8/techniques/configuration#installation)
* [Getting started](https://docs.nestjs.com/v8/techniques/configuration#getting-started)
* [Custom env file path](https://docs.nestjs.com/v8/techniques/configuration#custom-env-file-path)
* [Disable env variables loading](https://docs.nestjs.com/v8/techniques/configuration#disable-env-variables-loading)
* [Use module globally](https://docs.nestjs.com/v8/techniques/configuration#use-module-globally)
* [Custom configuration files](https://docs.nestjs.com/v8/techniques/configuration#custom-configuration-files)
* [Using the ConfigService](https://docs.nestjs.com/v8/techniques/configuration#using-the-configservice)
* [Configuration namespaces](https://docs.nestjs.com/v8/techniques/configuration#configuration-namespaces)
* [Cache environment variables](https://docs.nestjs.com/v8/techniques/configuration#cache-environment-variables)
* [Partial registration](https://docs.nestjs.com/v8/techniques/configuration#partial-registration)
* [Schema validation](https://docs.nestjs.com/v8/techniques/configuration#schema-validation)
* [Custom validate function](https://docs.nestjs.com/v8/techniques/configuration#custom-validate-function)
* [Custom getter functions](https://docs.nestjs.com/v8/techniques/configuration#custom-getter-functions)
* [Expandable variables](https://docs.nestjs.com/v8/techniques/configuration#expandable-variables)
* [Using in the main.ts](https://docs.nestjs.com/v8/techniques/configuration#using-in-the-maints)

```bash

$ npm i --save @nestjs/config
```

> **Hint** The `@nestjs/config` package internally uses [dotenv](https://github.com/motdotla/dotenv).

> **Note**`@nestjs/config` requires TypeScript 4.1 or later.

#### Getting started[#](/techniques/configuration#getting-started)

Once the installation process is complete, we can import the `ConfigModule`. Typically, we'll import it into the root `AppModule` and control its behavior using the `.forRoot()` static method. During this step, environment variable key/value pairs are parsed and resolved. Later, we'll see several options for accessing the `ConfigService` class of the `ConfigModule` in our other feature modules.

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';

@Module({
  imports: [ConfigModule.forRoot()],
})
export class AppModule {}
```

The above code will load and parse a `.env` file from the default location (the project root directory), merge key/value pairs from the `.env` file with environment variables assigned to `process.env`, and store the result in a private structure that you can access through the `ConfigService`. The `forRoot()` method registers the `ConfigService` provider, which provides a `get()` method for reading these parsed/merged configuration variables. Since `@nestjs/config` relies on [dotenv](https://github.com/motdotla/dotenv), it uses that package's rules for resolving conflicts in environment variable names. When a key exists both in the runtime environment as an environment variable (e.g., via OS shell exports like `export DATABASE_USER=test`) and in a `.env` file, the runtime environment variable takes precedence.

A sample `.env` file looks something like this:

```json

DATABASE_USER=test
DATABASE_PASSWORD=test
```

#### Custom env file path[#](/techniques/configuration#custom-env-file-path)

By default, the package looks for a `.env` file in the root directory of the application. To specify another path for the `.env` file, set the `envFilePath` property of an (optional) options object you pass to `forRoot()`, as follows:

```typescript

ConfigModule.forRoot({
  envFilePath: '.development.env',
});
```

You can also specify multiple paths for `.env` files like this:

```typescript

ConfigModule.forRoot({
  envFilePath: ['.env.development.local', '.env.development'],
});
```

If a variable is found in multiple files, the first one takes precedence.

#### Disable env variables loading[#](/techniques/configuration#disable-env-variables-loading)

If you don't want to load the `.env` file, but instead would like to simply access environment variables from the runtime environment (as with OS shell exports like `export DATABASE_USER=test`), set the options object's `ignoreEnvFile` property to `true`, as follows:

```typescript

ConfigModule.forRoot({
  ignoreEnvFile: true,
});
```

#### Use module globally[#](/techniques/configuration#use-module-globally)

When you want to use `ConfigModule` in other modules, you'll need to import it (as is standard with any Nest module). Alternatively, declare it as a [global module](https://docs.nestjs.com/modules#global-modules) by setting the options object's `isGlobal` property to `true`, as shown below. In that case, you will not need to import `ConfigModule` in other modules once it's been loaded in the root module (e.g., `AppModule`).

```typescript

ConfigModule.forRoot({
  isGlobal: true,
});
```

#### Custom configuration files[#](/techniques/configuration#custom-configuration-files)

For more complex projects, you may utilize custom configuration files to return nested configuration objects. This allows you to group related configuration settings by function (e.g., database-related settings), and to store related settings in individual files to help manage them independently.

A custom configuration file exports a factory function that returns a configuration object. The configuration object can be any arbitrarily nested plain JavaScript object. The `process.env` object will contain the fully resolved environment variable key/value pairs (with `.env` file and externally defined variables resolved and merged as described [above](techniques/configuration#getting-started)). Since you control the returned configuration object, you can add any required logic to cast values to an appropriate type, set default values, etc. For example:

config/configuration.ts

JS TS

```typescript

export default () => ({
  port: parseInt(process.env.PORT, 10) || 3000,
  database: {
    host: process.env.DATABASE_HOST,
    port: parseInt(process.env.DATABASE_PORT, 10) || 5432
  }
});
```

We load this file using the `load` property of the options object we pass to the `ConfigModule.forRoot()` method:

```typescript

import configuration from './config/configuration';

@Module({
  imports: [
    ConfigModule.forRoot({
      load: [configuration],
    }),
  ],
})
export class AppModule {}
```

> **Notice** The value assigned to the `load` property is an array, allowing you to load multiple configuration files (e.g. `load: [databaseConfig, authConfig]`)

With custom configuration files, we can also manage custom files such as YAML files. Here is an example of a configuration using YAML format:

```yaml

http:
  host: 'localhost'
  port: 8080

db:
  postgres:
    url: 'localhost'
    port: 5432
    database: 'yaml-db'

  sqlite:
    database: 'sqlite.db'
```

To read and parse YAML files, we can leverage the `js-yaml` package.

```bash

$ npm i js-yaml
$ npm i -D @types/js-yaml
```

Once the package is installed, we use `yaml#load` function to load YAML file we just created above.

config/configuration.ts

JS TS

```typescript

import { readFileSync } from 'fs';
import * as yaml from 'js-yaml';
import { join } from 'path';

const YAML_CONFIG_FILENAME = 'config.yaml';

export default () => {
  return yaml.load(
    readFileSync(join(__dirname, YAML_CONFIG_FILENAME), 'utf8'),
  ) as Record<string, any>;
};
```

> **Note** Nest CLI does not automatically move your "assets" (non-TS files) to the `dist` folder during the build process. To make sure that your YAML files are copied, you have to specify this in the `compilerOptions#assets` object in the `nest-cli.json` file. As an example, if the `config` folder is at the same level as the `src` folder, add `compilerOptions#assets` with the value `"assets": [{"include": "../config/*.yaml", "outDir": "./dist/config"}]`. Read more [here](/cli/monorepo#assets).

```typescript

@Module({
  imports: [ConfigModule],
  // ...
})
```

Then we can inject it using standard constructor injection:

```typescript

constructor(private configService: ConfigService) {}
```

> **Hint** The `ConfigService` is imported from the `@nestjs/config` package.

And use it in our class:

```typescript

// get an environment variable
const dbUser = this.configService.get<string>('DATABASE_USER');

// get a custom configuration value
const dbHost = this.configService.get<string>('database.host');
```

As shown above, use the `configService.get()` method to get a simple environment variable by passing the variable name. You can do TypeScript type hinting by passing the type, as shown above (e.g., `get<string>(...)`). The `get()` method can also traverse a nested custom configuration object (created via a [Custom configuration file](techniques/configuration#custom-configuration-files)), as shown in the second example above.

You can also get the whole nested custom configuration object using an interface as the type hint:

```typescript

interface DatabaseConfig {
  host: string;
  port: number;
}

const dbConfig = this.configService.get<DatabaseConfig>('database');

// you can now use `dbConfig.port` and `dbConfig.host`
const port = dbConfig.port;
```

The `get()` method also takes an optional second argument defining a default value, which will be returned when the key doesn't exist, as shown below:

```typescript

// use "localhost" when "database.host" is not defined
const dbHost = this.configService.get<string>('database.host', 'localhost');
```

`ConfigService` has two optional generics (type arguments). The first one is to help prevent accessing a config property that does not exist. Use it as shown below:

```typescript

interface EnvironmentVariables {
  PORT: number;
  TIMEOUT: string;
}

// somewhere in the code
constructor(private configService: ConfigService<EnvironmentVariables>) {
  const port = this.configService.get('PORT', { infer: true });

  // TypeScript Error: this is invalid as the URL property is not defined in EnvironmentVariables
  const url = this.configService.get('URL', { infer: true });
}
```

With the `infer` property set to `true`, the `ConfigService#get` method will automatically infer the property type based on the interface, so for example, `typeof port === "number"` (if you're not using `strictNullChecks` flag from TypeScript) since `PORT` has a `number` type in the `EnvironmentVariables` interface.

Also, with the `infer` feature, you can infer the type of a nested custom configuration object's property, even when using dot notation, as follows:

```typescript

constructor(private configService: ConfigService<{ database: { host: string } }>) {
  const dbHost = this.configService.get('database.host', { infer: true })!;
  // typeof dbHost === "string"                                          |
  //                                                                     +--> non-null assertion operator
}
```

The second generic relies on the first one, acting as a type assertion to get rid of all `undefined` types that `ConfigService`'s methods can return when `strictNullChecks` is on. For instance:

```typescript

// ...
constructor(private configService: ConfigService<{ PORT: number }, true>) {
  //                                                               ^^^^
  const port = this.configService.get('PORT', { infer: true });
  //    ^^^ The type of port will be 'number' thus you don't need TS type assertions anymore
}
```

#### Configuration namespaces[#](/techniques/configuration#configuration-namespaces)

The `ConfigModule` allows you to define and load multiple custom configuration files, as shown in [Custom configuration files](techniques/configuration#custom-configuration-files) above. You can manage complex configuration object hierarchies with nested configuration objects as shown in that section. Alternatively, you can return a "namespaced" configuration object with the `registerAs()` function as follows:

config/database.config.ts

JS TS

```typescript

export default registerAs('database', () => ({
  host: process.env.DATABASE_HOST,
  port: process.env.DATABASE_PORT || 5432
}));
```

As with custom configuration files, inside your `registerAs()` factory function, the `process.env` object will contain the fully resolved environment variable key/value pairs (with `.env` file and externally defined variables resolved and merged as described [above](techniques/configuration#getting-started)).

> **Hint** The `registerAs` function is exported from the `@nestjs/config` package.

Load a namespaced configuration with the `load` property of the `forRoot()` method's options object, in the same way you load a custom configuration file:

```typescript

import databaseConfig from './config/database.config';

@Module({
  imports: [
    ConfigModule.forRoot({
      load: [databaseConfig],
    }),
  ],
})
export class AppModule {}
```

Now, to get the `host` value from the `database` namespace, use dot notation. Use `'database'` as the prefix to the property name, corresponding to the name of the namespace (passed as the first argument to the `registerAs()` function):

```typescript

const dbHost = this.configService.get<string>('database.host');
```

A reasonable alternative is to inject the `database` namespace directly. This allows us to benefit from strong typing:

```typescript

constructor(
  @Inject(databaseConfig.KEY)
  private dbConfig: ConfigType<typeof databaseConfig>,
) {}
```

> **Hint** The `ConfigType` is exported from the `@nestjs/config` package.

#### Cache environment variables[#](/techniques/configuration#cache-environment-variables)

As accessing `process.env` can be slow, you can set the `cache` property of the options object passed to `ConfigModule.forRoot()` to increase the performance of `ConfigService#get` method when it comes to variables stored in `process.env`.

```typescript

ConfigModule.forRoot({
  cache: true,
});
```

#### Partial registration[#](/techniques/configuration#partial-registration)

Thus far, we've processed configuration files in our root module (e.g., `AppModule`), with the `forRoot()` method. Perhaps you have a more complex project structure, with feature-specific configuration files located in multiple different directories. Rather than load all these files in the root module, the `@nestjs/config` package provides a feature called **partial registration**, which references only the configuration files associated with each feature module. Use the `forFeature()` static method within a feature module to perform this partial registration, as follows:

```typescript

import databaseConfig from './config/database.config';

@Module({
  imports: [ConfigModule.forFeature(databaseConfig)],
})
export class DatabaseModule {}
```

> **Warning** In some circumstances, you may need to access properties loaded via partial registration using the `onModuleInit()` hook, rather than in a constructor. This is because the `forFeature()` method is run during module initialization, and the order of module initialization is indeterminate. If you access values loaded this way by another module, in a constructor, the module that the configuration depends upon may not yet have initialized. The `onModuleInit()` method runs only after all modules it depends upon have been initialized, so this technique is safe.

#### Schema validation[#](/techniques/configuration#schema-validation)

It is standard practice to throw an exception during application startup if required environment variables haven't been provided or if they don't meet certain validation rules. The `@nestjs/config` package enables two different ways to do this:

* [Joi](https://github.com/sideway/joi) built-in validator. With Joi, you define an object schema and validate JavaScript objects against it.
* A custom `validate()` function which takes environment variables as an input.

To use Joi, we must install Joi package:

```bash

$ npm install --save joi
```

> **Notice** The latest version of `joi` requires you to be running Node v12 or later. For older versions of node, please install `v16.1.8`. This is mainly after the release of `v17.0.2` which causes errors during build time. For more information, please refer to [their 17.0.0 release notes](https://github.com/sideway/joi/issues/2262).

Now we can define a Joi validation schema and pass it via the `validationSchema` property of the `forRoot()` method's options object, as shown below:

app.module.ts

JS TS

```typescript

import * as Joi from 'joi';

@Module({
  imports: [
    ConfigModule.forRoot({
      validationSchema: Joi.object({
        NODE_ENV: Joi.string()
          .valid('development', 'production', 'test', 'provision')
          .default('development'),
        PORT: Joi.number().default(3000),
      }),
    }),
  ],
})
export class AppModule {}
```

By default, all schema keys are considered optional. Here, we set default values for `NODE_ENV` and `PORT` which will be used if we don't provide these variables in the environment (`.env` file or process environment). Alternatively, we can use the `required()` validation method to require that a value must be defined in the environment (`.env` file or process environment). In this case, the validation step will throw an exception if we don't provide the variable in the environment. See [Joi validation methods](https://joi.dev/api/?v=17.3.0#example) for more on how to construct validation schemas.

By default, unknown environment variables (environment variables whose keys are not present in the schema) are allowed and do not trigger a validation exception. By default, all validation errors are reported. You can alter these behaviors by passing an options object via the `validationOptions` key of the `forRoot()` options object. This options object can contain any of the standard validation options properties provided by [Joi validation options](https://joi.dev/api/?v=17.3.0#anyvalidatevalue-options). For example, to reverse the two settings above, pass options like this:

app.module.ts

JS TS

```typescript

import * as Joi from 'joi';

@Module({
  imports: [
    ConfigModule.forRoot({
      validationSchema: Joi.object({
        NODE_ENV: Joi.string()
          .valid('development', 'production', 'test', 'provision')
          .default('development'),
        PORT: Joi.number().default(3000),
      }),
      validationOptions: {
        allowUnknown: false,
        abortEarly: true,
      },
    }),
  ],
})
export class AppModule {}
```

```typescript

import { plainToClass } from 'class-transformer';
import { IsEnum, IsNumber, validateSync } from 'class-validator';

enum Environment {
  Development = "development",
  Production = "production",
  Test = "test",
  Provision = "provision",
}

class EnvironmentVariables {
  @IsEnum(Environment)
  NODE_ENV: Environment;

  @IsNumber()
  PORT: number;
}

export function validate(config: Record<string, unknown>) {
  const validatedConfig = plainToClass(
    EnvironmentVariables,
    config,
    { enableImplicitConversion: true },
  );
  const errors = validateSync(validatedConfig, { skipMissingProperties: false });

  if (errors.length > 0) {
    throw new Error(errors.toString());
  }
  return validatedConfig;
}
```

With this in place, use the `validate` function as a configuration option of the `ConfigModule`, as follows:

app.module.ts

JS TS

```typescript

import { validate } from './env.validation';

@Module({
  imports: [
    ConfigModule.forRoot({
      validate,
    }),
  ],
})
export class AppModule {}
```

## Hoodies, T-shirts, and accessories!

Support our future development by shopping in the official store!

[See more](https://nestjs.threadless.com/ "Shop | NestJS - A node.js framework built on top of TypeScript")

#### Custom getter functions[#](/techniques/configuration#custom-getter-functions)

`ConfigService` defines a generic `get()` method to retrieve a configuration value by key. We may also add `getter` functions to enable a little more natural coding style:

JS TS

```typescript

@Injectable()
export class ApiConfigService {
  constructor(private configService: ConfigService) {}

  get isAuthEnabled(): boolean {
    return this.configService.get('AUTH_ENABLED') === 'true';
  }
}
```

```typescript

@Dependencies(ConfigService)
@Injectable()
export class ApiConfigService {
  constructor(configService) {
    this.configService = configService;
  }

  get isAuthEnabled() {
    return this.configService.get('AUTH_ENABLED') === 'true';
  }
}
```

Now we can use the getter function as follows:

app.service.ts

JS TS

```typescript

@Injectable()
export class AppService {
  constructor(apiConfigService: ApiConfigService) {
    if (apiConfigService.isAuthEnabled) {
      // Authentication is enabled
    }
  }
}
```

```typescript

@Dependencies(ApiConfigService)
@Injectable()
export class AppService {
  constructor(apiConfigService) {
    if (apiConfigService.isAuthEnabled) {
      // Authentication is enabled
    }
  }
}
```

#### Expandable variables[#](/techniques/configuration#expandable-variables)

The `@nestjs/config` package supports environment variable expansion. With this technique, you can create nested environment variables, where one variable is referred to within the definition of another. For example:

```json

APP_URL=mywebsite.com
SUPPORT_EMAIL=support@${APP_URL}
```

With this construction, the variable `SUPPORT_EMAIL` resolves to `'support@mywebsite.com'`. Note the use of the `${...}` syntax to trigger resolving the value of the variable `APP_URL` inside the definition of `SUPPORT_EMAIL`.

> **Hint** For this feature, `@nestjs/config` package internally uses [dotenv-expand](https://github.com/motdotla/dotenv-expand).

Enable environment variable expansion using the `expandVariables` property in the options object passed to the `forRoot()` method of the `ConfigModule`, as shown below:

app.module.ts

JS TS

```typescript

@Module({
  imports: [
    ConfigModule.forRoot({
      // ...
      expandVariables: true,
    }),
  ],
})
export class AppModule {}
```

#### Using in the `main.ts`[#](/techniques/configuration#using-in-the-maints)

While our config is a stored in a service, it can still be used in the `main.ts` file. This way, you can use it to store variables such as the application port or the CORS host.

To access it, you must use the `app.get()` method, followed by the service reference:

```typescript

const configService = app.get(ConfigService);
```

You can then use it as usual, by calling the `get` method with the configuration key:

```typescript

const port = configService.get('PORT');
```

----
url: https://docs.nestjs.com/v8/graphql/directives
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Directives](https://docs.nestjs.com/v8/graphql/directives#directives)
* [Custom directives](https://docs.nestjs.com/v8/graphql/directives#custom-directives)
* [Code first](https://docs.nestjs.com/v8/graphql/directives#code-first)
* [Schema first](https://docs.nestjs.com/v8/graphql/directives#schema-first)

```typescript

import { getDirective, MapperKind, mapSchema } from '@graphql-tools/utils';
import { defaultFieldResolver, GraphQLSchema } from 'graphql';

export function upperDirectiveTransformer(
  schema: GraphQLSchema,
  directiveName: string,
) {
  return mapSchema(schema, {
    [MapperKind.OBJECT_FIELD]: (fieldConfig) => {
      const upperDirective = getDirective(
        schema,
        fieldConfig,
        directiveName,
      )?.[0];

      if (upperDirective) {
        const { resolve = defaultFieldResolver } = fieldConfig;

        // Replace the original resolver with a function that *first* calls
        // the original resolver, then converts its result to upper case
        fieldConfig.resolve = async function (source, args, context, info) {
          const result = await resolve(source, args, context, info);
          if (typeof result === 'string') {
            return result.toUpperCase();
          }
          return result;
        };
        return fieldConfig;
      }
    },
  });
}
```

Now, apply the `upperDirectiveTransformer` transformation function in the `GraphQLModule#forRoot` method using the `transformSchema` function:

```typescript

GraphQLModule.forRoot({
  // ...
  transformSchema: (schema) => upperDirectiveTransformer(schema, 'upper'),
});
```

Once registered, the `@upper` directive can be used in our schema. However, the way you apply the directive will vary depending on the approach you use (code first or schema first).

#### Code first[#](/graphql/directives#code-first)

In the code first approach, use the `@Directive()` decorator to apply the directive.

```typescript

@Directive('@upper')
@Field()
title: string;
```

> **Hint** The `@Directive()` decorator is exported from the `@nestjs/graphql` package.

Directives can be applied on fields, field resolvers, input and object types, as well as queries, mutations, and subscriptions. Here's an example of the directive applied on the query handler level:

```typescript

@Directive('@deprecated(reason: "This query will be removed in the next version")')
@Query(returns => Author, { name: 'author' })
async getAuthor(@Args({ name: 'id', type: () => Int }) id: number) {
  return this.authorsService.findOneById(id);
}
```

> **Warning** Directives applied through the `@Directive()` decorator will not be reflected in the generated schema definition file.

Lastly, make sure to declare directives in the `GraphQLModule`, as follows:

```typescript

GraphQLModule.forRoot({
  // ...,
  transformSchema: schema => upperDirectiveTransformer(schema, 'upper'),
  buildSchemaOptions: {
    directives: [
      new GraphQLDirective({
        name: 'upper',
        locations: [DirectiveLocation.FIELD_DEFINITION],
      }),
    ],
  },
}),
```

> **Hint** Both `GraphQLDirective` and `DirectiveLocation` are exported from the `graphql` package.

#### Schema first[#](/graphql/directives#schema-first)

In the schema first approach, apply directives directly in SDL.

```graphql

directive @upper on FIELD_DEFINITION

type Post {
  id: Int!
  title: String! @upper
  votes: Int
}
```

----
url: https://docs.nestjs.com/v6/recipes/hot-reload
----

* [Hot Reload](https://docs.nestjs.com/v6/recipes/hot-reload#hot-reload)
* [With CLI](https://docs.nestjs.com/v6/recipes/hot-reload#with-cli)
* [Installation](https://docs.nestjs.com/v6/recipes/hot-reload#installation)
* [Configuration](https://docs.nestjs.com/v6/recipes/hot-reload#configuration)
* [Hot-Module Replacement](https://docs.nestjs.com/v6/recipes/hot-reload#hot-module-replacement)
* [Without CLI](https://docs.nestjs.com/v6/recipes/hot-reload#without-cli)
* [Installation](https://docs.nestjs.com/v6/recipes/hot-reload#installation-1)
* [Configuration](https://docs.nestjs.com/v6/recipes/hot-reload#configuration-1)
* [Hot-Module Replacement](https://docs.nestjs.com/v6/recipes/hot-reload#hot-module-replacement-1)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/recipes/hot-reload.md "Suggest Edits")

### Hot Reload

The highest impact on your application's bootstrapping process is **TypeScript compilation**. Fortunately, with [webpack](https://github.com/webpack/webpack) HMR (Hot-Module Replacement), we don't need to recompile the entire project each time a change occurs. This significantly decreases the amount of time necessary to instantiate your application, and makes iterative development a lot easier.

> **Warning** Note that `webpack` won't automatically copy your assets (e.g. `graphql` files) to the `dist` folder. Similarly, `webpack` is not compatible with glob static paths (e.g., the `entities` property in `TypeOrmModule`).

### With CLI

If you are using the [Nest CLI](https://docs.nestjs.com/cli/overview), the configuration process is pretty straightforward. The CLI wraps `webpack`, which allows use of the `HotModuleReplacementPlugin`.

#### Installation[#](/recipes/hot-reload#installation)

First install the required packages:

```bash

$ npm i --save-dev webpack-node-externals start-server-webpack-plugin
```

#### Configuration[#](/recipes/hot-reload#configuration)

Once the installation is complete, create a `webpack-hmr.config.js` file in the root directory of your application.

```typescript

const webpack = require('webpack');
const nodeExternals = require('webpack-node-externals');
const StartServerPlugin = require('start-server-webpack-plugin');

module.exports = function(options) {
  return {
    ...options,
    entry: ['webpack/hot/poll?100', './src/main.ts'],
    watch: true,
    externals: [
      nodeExternals({
        whitelist: ['webpack/hot/poll?100'],
      }),
    ],
    plugins: [
      ...options.plugins,
      new webpack.HotModuleReplacementPlugin(),
      new webpack.WatchIgnorePlugin([/\.js$/, /\.d\.ts$/]),
      new StartServerPlugin({ name: 'main.js' }),
    ],
  };
};
```

This function takes the original object containing the default webpack configuration and returns a modified one with an applied `HotModuleReplacementPlugin` plugin.

#### Hot-Module Replacement[#](/recipes/hot-reload#hot-module-replacement)

To enable **HMR**, open the application entry file (`main.ts`) and add the following webpack-related instructions:

```typescript

declare const module: any;

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  await app.listen(3000);

  if (module.hot) {
    module.hot.accept();
    module.hot.dispose(() => app.close());
  }
}
bootstrap();
```

To simplify the execution process, add a script to your `package.json` file.

```json

"start:dev": "nest build --watch --webpack --webpackPath webpack-hmr.config.js"
```

Now simply open your command line and run the following command:

```bash

$ npm run start:dev
```

### Without CLI

If you are not using the [Nest CLI](https://docs.nestjs.com/cli/overview), the configuration will be slightly more complex (will require more manual steps).

#### Installation[#](/recipes/hot-reload#installation-1)

First install the required packages:

```bash

$ npm i --save-dev webpack webpack-cli webpack-node-externals ts-loader start-server-webpack-plugin
```

#### Configuration[#](/recipes/hot-reload#configuration-1)

Once the installation is complete, create a `webpack.config.js` file in the root directory of your application.

```typescript

const webpack = require('webpack');
const path = require('path');
const nodeExternals = require('webpack-node-externals');
const StartServerPlugin = require('start-server-webpack-plugin');

module.exports = {
  entry: ['webpack/hot/poll?100', './src/main.ts'],
  watch: true,
  target: 'node',
  externals: [
    nodeExternals({
      whitelist: ['webpack/hot/poll?100'],
    }),
  ],
  module: {
    rules: [
      {
        test: /.tsx?$/,
        use: 'ts-loader',
        exclude: /node_modules/,
      },
    ],
  },
  mode: 'development',
  resolve: {
    extensions: ['.tsx', '.ts', '.js'],
  },
  plugins: [
    new webpack.HotModuleReplacementPlugin(),
    new StartServerPlugin({ name: 'server.js' }),
  ],
  output: {
    path: path.join(__dirname, 'dist'),
    filename: 'server.js',
  },
};
```

This configuration tells webpack a few essential things about your application: location of the entry file, which directory should be used to hold **compiled** files, and what kind of loader we want to use to compile source files. Generally, you should be able to use this file as-is, even if you don't fully understand all of the options.

#### Hot-Module Replacement[#](/recipes/hot-reload#hot-module-replacement-1)

To enable **HMR**, open the application entry file (`main.ts`) and add the following webpack-related instructions:

```typescript

declare const module: any;

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  await app.listen(3000);

  if (module.hot) {
    module.hot.accept();
    module.hot.dispose(() => app.close());
  }
}
bootstrap();
```

To simplify the execution process, add a script to your `package.json` file.

```json

"start:dev": "webpack --config webpack.config.js"
```

Now simply open your command line and run the following command:

```bash

$ npm run start:dev
```

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/08-webpack).

----
url: https://docs.nestjs.com/v5/techniques/database
----

### Database (TypeORM)

In order to reduce a boilerplate necessary to start the adventure with any database, Nest comes with the ready to use `@nestjs/typeorm` package. We selected [TypeORM](https://github.com/typeorm/typeorm) because it's definitely the most mature Object Relational Mapper (ORM) available so far. Since it's written in TypeScript, it works pretty well with the Nest framework.

Firstly, we need to install all of the required dependencies:

```bash

$ npm install --save @nestjs/typeorm typeorm mysql
```

> **Notice** In this chapter we'll use a MySQL database, but **TypeORM** provides a support for a lot of different databases such as PostgreSQL, SQLite, and even MongoDB (NoSQL).

Once the installation process is completed, we can import the `TypeOrmModule` into the root `ApplicationModule`.

app.module.ts

JS TS

TypeScript

```typescript

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';

@Module({
  imports: [
    TypeOrmModule.forRoot({
      type: 'mysql',
      host: 'localhost',
      port: 3306,
      username: 'root',
      password: 'root',
      database: 'test',
      entities: [__dirname + '/**/*.entity{.ts,.js}'],
      synchronize: true,
    }),
  ],
})
export class ApplicationModule {}
```

The `forRoot()` method accepts the same configuration object as `createConnection()` from the [TypeORM](https://github.com/typeorm/typeorm) package. Futhermore, instead of passing anything to the `forRoot()`, we can create an `ormconfig.json` file in the project root directory.

ormconfig.json

JSON

```json

{
  "type": "mysql",
  "host": "localhost",
  "port": 3306,
  "username": "root",
  "password": "root",
  "database": "test",
  "entities": ["src/**/**.entity{.ts,.js}"],
  "synchronize": true
}
```

Then, we can simply leave the parenthesis empty:

app.module.ts

JS TS

TypeScript

```typescript

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';

@Module({
  imports: [TypeOrmModule.forRoot()],
})
export class ApplicationModule {}
```

Afterward, the `Connection` and `EntityManager` will be available to inject across entire project (without importing any module elsewhere), for example, in this way:

app.module.ts

JS TS

TypeScript

```typescript

import { Connection } from 'typeorm';

@Module({
  imports: [TypeOrmModule.forRoot(), PhotoModule],
})
export class ApplicationModule {
  constructor(private readonly connection: Connection) {}
}
```

TypeScript

```typescript

import { Connection } from 'typeorm';

@Dependencies(Connection)
@Module({
  imports: [TypeOrmModule.forRoot(), PhotoModule],
})
export class ApplicationModule {
  constructor(connection) {
    this.connection = connection;
  }
}
```

#### Repository pattern

The [TypeORM](https://github.com/typeorm/typeorm) supports the repository design pattern, so each entity has its own Repository. These repositories can be obtained from the database connection.

Firstly, we need at least one entity. We're gonna reuse the `Photo` entity from the offical documentation.

photo/photo.entity.ts

JS TS

TypeScript

```typescript

import { Entity, Column, PrimaryGeneratedColumn } from 'typeorm';

@Entity()
export class Photo {
  @PrimaryGeneratedColumn()
  id: number;

  @Column({ length: 500 })
  name: string;

  @Column('text')
  description: string;

  @Column()
  filename: string;

  @Column('int')
  views: number;

  @Column()
  isPublished: boolean;
}
```

The `Photo` entity belongs to the `photo` directory. This directory represents the `PhotoModule`. It's your decision where you gonna keep your model files. From our point of view, the best way's to hold them nearly their **domain**, in the corresponding module directory.

Let's have a look at the `PhotoModule`:

photo/photo.module.ts

JS TS

TypeScript

```typescript

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { PhotoService } from './photo.service';
import { PhotoController } from './photo.controller';
import { Photo } from './photo.entity';

@Module({
  imports: [TypeOrmModule.forFeature([Photo])],
  providers: [PhotoService],
  controllers: [PhotoController],
})
export class PhotoModule {}
```

This module uses `forFeature()` method to define which repositories shall be registered in the current scope. Thanks to that we can inject the `PhotoRepository` to the `PhotoService` using the `@InjectRepository()` decorator:

photo/photo.service.ts

JS TS

TypeScript

```typescript

import { Injectable, Inject } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Photo } from './photo.entity';

@Injectable()
export class PhotoService {
  constructor(
    @InjectRepository(Photo)
    private readonly photoRepository: Repository<Photo>,
  ) {}

  async findAll(): Promise<Photo[]> {
    return await this.photoRepository.find();
  }
}
```

TypeScript

```typescript

import { Injectable, Dependencies } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Photo } from './photo.entity';

@Injectable()
@Dependencies(InjectRepository(Photo))
export class PhotoService {
  constructor(photoRepository) {
    this.photoRepository = photoRepository;
  }

  async findAll() {
    return await this.photoRepository.find();
  }
}
```

> **Notice** Don't forget to import the `PhotoModule` into the root `ApplicationModule`.

#### Multiple databases

Some of your projects may require multiple database connections. Fortunately, this can also be achieved with this module. To work with multiple connections, the first thing to do is to create those connections. In this case, the connection naming becomes **mandatory**.

Say you have a `Person` entity and a an `Album` entity, each stored in their own database.

TypeScript

```typescript

const defaultOptions = {
  type: 'postgres',
  port: 5432,
  username: 'user',
  password: 'password',
  database: 'db',
  synchronize: true,
};

@Module({
  imports: [
    TypeOrmModule.forRoot({
      ...defaultOptions,
      host: 'photo_db_host',
      entities: [Photo],
    }),
    TypeOrmModule.forRoot({
      ...defaultOptions,
      name: 'personsConnection',
      host:  'person_db_host',
      entities: [Person],
    }),
    TypeOrmModule.forRoot({
      ...defaultOptions,
      name: 'albumsConnection',
      host:  'album_db_host',
      entities: [Album],
    })
  ]
})
export class ApplicationModule {}
```

> **Notice** If you don't set any `name` for a connection, its name is set to `default`. Please note that you shouldn't have multiple connections without a name, or with the same name, otherwise they simply get overridden.

At this point, you have each of your `Photo`, `Person` and `Album` entities registered in their own connection. With this setup, you have to tell the `TypeOrmModule.forFeature()` function and the `@InjectRepository()` decorator which connection should be used. If you do not pass any connection name, the `default` connection is used.

TypeScript

```typescript

@Module({
  TypeOrmModule.forFeature([Photo]),
  TypeOrmModule.forFeature([Person], 'personsConnection'),
  TypeOrmModule.forFeature([Album], 'albumsConnection')
})
export class ApplicationModule {}
```

You can also inject the `Connection` or `EntityManager` for a given connection:

TypeScript

```typescript

@Injectable()
export class PersonService {
  constructor(
    @InjectConnection('personsConnection')
    private readonly connection: Connection,
    @InjectEntityManager('personsConnection')
    private readonly entityManager: EntityManager
  ) {}
}
```

#### Testing

When it comes to unit test our application, we usually want to avoid any database connection, making our test suits independent and their execution process quick as possible. But our classes might depend on repositories that are pulled from the connection instance. What's then? The solution is to create fake repositories. In order to achieve that, we should set up [custom providers](/v5/fundamentals/custom-providers). In fact, each registered repository is represented by `EntityNameRepository` token, where `EntityName` is a name of your entity class.

The `@nestjs/typeorm` package exposes `getRepositoryToken()` function that returns prepared token based on a given entity.

TypeScript

```typescript

@Module({
  providers: [
    PhotoService,
    {
      provide: getRepositoryToken(Photo),
      useValue: mockRepository,
    },
  ],
})
export class PhotoModule {}
```

Now a hardcoded `mockRepository` will be used as a `PhotoRepository`. Whenever any provider asks for `PhotoRepository` using an `@InjectRepository()` decorator, Nest will use a registered `mockRepository` object.

#### Custom repository

TypeORM provides feature called **custom repositories**. To learn more about it, visit [this](http://typeorm.io/#/custom-repository) page. Basically, custom repository allows you extending a base repository class, and enrich it with a couple of special methods.

In order to create your custom repository, use `@EntityRepository()` decorator and extend `Repository` class.

TypeScript

```typescript

@EntityRepository(Author)
export class AuthorRepository extends Repository<Author> {}
```

> **Hint** Both `@EntityRepository()` and `Repository` are exposed from `typeorm` package.

Once the class is created, the next step is to hand over the instantiation responsibility to Nest. For this, we have to pass `AuthorRepository` class to the `TypeOrm.forFeature()` method.

TypeScript

```typescript

@Module({
  imports: [TypeOrmModule.forFeature([Author, AuthorRepository])],
  controller: [AuthorController],
  providers: [AuthorService],
})
export class AuthorModule {}
```

> **Notice** Even though `AuthorRepository` is passed, it's not enough to create a custom repository yet. The corresponding entity class, `Author` in this case, is required as well.

Afterward, simply inject the repository using `@InjectRepository()` decorator.

TypeScript

```typescript

@Injectable()
export class AuthorService {
  constructor(
    @InjectRepository(AuthorRepository)
    private readonly authorRepository: AuthorRepository,
  ) {}
}
```

#### Async configuration

Quite often you might want to asynchronously pass your module options instead of passing them beforehand. In such case, use `forRootAsync()` method, that provides a couple of various ways to deal with async data.

First possible approach is to use a factory function:

TypeScript

```typescript

TypeOrmModule.forRootAsync({
  useFactory: () => ({
    type: 'mysql',
    host: 'localhost',
    port: 3306,
    username: 'root',
    password: 'root',
    database: 'test',
    entities: [__dirname + '/**/*.entity{.ts,.js}'],
    synchronize: true,
  }),
})
```

Obviously, our factory behaves like every other one (might be `async` and is able to inject dependencies through `inject`).

TypeScript

```typescript

TypeOrmModule.forRootAsync({
  imports: [ConfigModule],
  useFactory: async (configService: ConfigService) => ({
    type: 'mysql',
    host: configService.getString('HOST'),
    port: configService.getString('PORT'),
    username: configService.getString('USERNAME'),
    password: configService.getString('PASSWORD'),
    database: configService.getString('DATABASE'),
    entities: [__dirname + '/**/*.entity{.ts,.js}'],
    synchronize: true,
  }),
  inject: [ConfigService],
})
```

Alternatively, you are able to use class instead of a factory.

TypeScript

```typescript

TypeOrmModule.forRootAsync({
  useClass: TypeOrmConfigService,
})
```

Above construction will instantiate `TypeOrmConfigService` inside `TypeOrmModule` and will leverage it to create options object. The `TypeOrmConfigService` has to implement `TypeOrmOptionsFactory` interface.

TypeScript

```typescript

@Injectable()
class TypeOrmConfigService implements TypeOrmOptionsFactory {
  createTypeOrmOptions(): TypeOrmModuleOptions {
    return {
      type: 'mysql',
      host: 'localhost',
      port: 3306,
      username: 'root',
      password: 'root',
      database: 'test',
      entities: [__dirname + '/**/*.entity{.ts,.js}'],
      synchronize: true,
    };
  }
}
```

In order to prevent the creation of `TypeOrmConfigService` inside `TypeOrmModule` and use a provider imported from a different module, you can use the `useExisting` syntax.

TypeScript

```typescript

TypeOrmModule.forRootAsync({
  imports: [ConfigModule],
  useExisting: ConfigService,
})
```

It works the same as `useClass` with one critical difference - `TypeOrmModule` will lookup imported modules to reuse already created `ConfigService`, instead of instantiating it on its own.

#### Example

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/05-sql-typeorm).

* Database (TypeORM)
* Repository pattern
* Multiple databases
* Testing
* Custom repository

----
url: https://docs.nestjs.com/interceptors
----

[Skip to content](#content)

On this page

* [Interceptors](https://docs.nestjs.com/interceptors#interceptors)
* [Basics](https://docs.nestjs.com/interceptors#basics)
* [Execution context](https://docs.nestjs.com/interceptors#execution-context)
* [Call handler](https://docs.nestjs.com/interceptors#call-handler)
* [Aspect interception](https://docs.nestjs.com/interceptors#aspect-interception)
* [Binding interceptors](https://docs.nestjs.com/interceptors#binding-interceptors)
* [Response mapping](https://docs.nestjs.com/interceptors#response-mapping)
* [Exception mapping](https://docs.nestjs.com/interceptors#exception-mapping)
* [Stream overriding](https://docs.nestjs.com/interceptors#stream-overriding)
* [More operators](https://docs.nestjs.com/interceptors#more-operators)

[](https://srv.carbonads.net/ads/click/x/GTND4277CVSDE23NCWALYKQUF67D623NCAYDVZ3JCAAI623LF6ADTKJKC6YI62Q7CABDC23ECVSIEKJLC6AD4KQNHEYI55QLCYAI6K3ECTNCYBZ52K)[Your edge case? Another builder solved it last Tuesday. Find answers. ](https://srv.carbonads.net/ads/click/x/GTND4277CVSDE23NCWALYKQUF67D623NCAYDVZ3JCAAI623LF6ADTKJKC6YI62Q7CABDC23ECVSIEKJLC6AD4KQNHEYI55QLCYAI6K3ECTNCYBZ52K)[ads via Carbon](http://carbonads.net/?utm_source=nestjscom\&utm_medium=ad_via_link\&utm_campaign=in_unit\&utm_term=carbon)

### Interceptors

An interceptor is a class annotated with the `@Injectable()` decorator that implements the `NestInterceptor` interface.

Interceptors offer a set of capabilities inspired by the [Aspect Oriented Programming](https://en.wikipedia.org/wiki/Aspect-oriented_programming) (AOP) technique. They make it possible to:

* bind extra logic before or after method execution
* transform the result returned from a function
* transform the exception thrown from a function
* extend the basic function behavior
* completely override a function depending on specific conditions (e.g., for caching purposes)

#### Basics[#](/interceptors#basics)

Each interceptor implements the `intercept()` method, which takes two arguments. The first is the `ExecutionContext` instance (exactly the same object as for [guards](/guards)). `ExecutionContext` extends `ArgumentsHost`, which we covered in the exception filters chapter. There, we saw that it's a wrapper around the arguments passed to the original handler, and that it contains different argument arrays depending on the type of application. See the [exception filters](/exception-filters#arguments-host) chapter for more on this topic.

#### Execution context[#](/interceptors#execution-context)

By extending `ArgumentsHost`, `ExecutionContext` adds several helper methods that provide additional details about the current execution process. These details help you build more generic interceptors that work across a broad set of controllers, methods, and execution contexts. See the [execution context](/fundamentals/execution-context) chapter to learn more about `ExecutionContext`.

#### Call handler[#](/interceptors#call-handler)

The second argument is a `CallHandler`. The `CallHandler` interface exposes a `handle()` method, which you use to invoke the route handler method at some point in your interceptor. If you don't call `handle()` in your implementation of the `intercept()` method, the route handler method won't be executed at all.

This means that the `intercept()` method effectively **wraps** the request/response stream. As a result, you can implement custom logic **both before and after** the execution of the final route handler. Running code **before** the handler is straightforward: place it before the `handle()` call. To act on what happens afterward, use the `Observable` that `handle()` returns: you can apply [RxJS](https://github.com/ReactiveX/rxjs) operators to it to further manipulate the response. In Aspect Oriented Programming terminology, the invocation of the route handler (i.e., calling `handle()`) is called a [Pointcut](https://en.wikipedia.org/wiki/Pointcut), indicating that it's the point at which our additional logic is inserted.

Consider, for example, an incoming `POST /cats` request. This request is destined for the `create()` handler defined inside `CatsController`. If an interceptor that doesn't call `handle()` is invoked anywhere along the way, the `create()` method won't be executed. Once `handle()` is called and the `Observable` it returns is subscribed to (Nest subscribes to the stream your `intercept()` method returns), the `create()` handler is triggered. As the handler's result flows through the stream, you can apply additional operations to it before the final result is returned to the caller.

## Debug production with NestJS Observe

* Every request traced
* Errors with source code
* Logs in context
* Zero config, free plan

[Start for free](https://observe.nestjs.com "Observe | NestJS - A progressive Node.js framework")

#### Aspect interception[#](/interceptors#aspect-interception)

The first use case we'll look at is using an interceptor to log user interaction (e.g., storing user calls, asynchronously dispatching events, or calculating a timestamp). The following example shows a simple `LoggingInterceptor`:

logging.interceptor.ts

JS TS

```typescript

import { Injectable, NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
import { Observable } from 'rxjs';
import { tap } from 'rxjs/operators';

@Injectable()
export class LoggingInterceptor implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    console.log('Before...');

    const now = Date.now();
    return next
      .handle()
      .pipe(
        tap(() => console.log(`After... ${Date.now() - now}ms`)),
      );
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';
import { tap } from 'rxjs/operators';

@Injectable()
export class LoggingInterceptor {
  intercept(context, next) {
    console.log('Before...');

    const now = Date.now();
    return next
      .handle()
      .pipe(
        tap(() => console.log(`After... ${Date.now() - now}ms`)),
      );
  }
}
```

> **Hint**`NestInterceptor<T, R>` is a generic interface in which `T` is the type of the values emitted by the `Observable<T>` that `next.handle()` returns (the response stream), and `R` is the type of the values emitted by the `Observable<R>` that `intercept()` returns.

> **Notice** Interceptors, like controllers, providers, guards, and so on, can **inject dependencies** through their `constructor`.

Since `handle()` returns an RxJS `Observable`, you can choose from a wide range of operators to manipulate the stream. The example above uses the `tap()` operator, which calls our logging function when the stream emits the route handler's result, without otherwise interfering with the response cycle. Note that this function is not called if the route handler throws; to run logic in that case as well, pass an observer object with an `error` callback to `tap()`, or use the `finalize()` operator.

> **Hint** Timing a handler by hand, as above, is a minimal version of what an APM does. [NestJS Observe](https://www.observe.nestjs.com/ "NestJS Observe") records the same measurement for every controller, provider, and queue consumer, with no interceptor to write or bind. It also records the time each one spent on its own, with everything it awaited subtracted out. See the [Observability](/observability/overview) chapter.

#### Binding interceptors[#](/interceptors#binding-interceptors)

To set up the interceptor, use the `@UseInterceptors()` decorator. Like [pipes](/pipes) and [guards](/guards), interceptors can be controller-scoped, method-scoped, or global-scoped.

cats.controller.ts

JS TS

```typescript

@UseInterceptors(LoggingInterceptor)
export class CatsController {}
```

> **Hint** The `@UseInterceptors()` decorator is imported from the `@nestjs/common` package.

With the construction above, each route handler defined in `CatsController` uses `LoggingInterceptor`. When a client calls the `GET /cats` endpoint, you'll see the following in standard output:

```typescript

Before...
After... 1ms
```

Note that we passed the `LoggingInterceptor` class (instead of an instance), leaving responsibility for instantiation to the framework and enabling dependency injection. As with pipes, guards, and exception filters, you can also pass an in-place instance:

cats.controller.ts

JS TS

```typescript

@UseInterceptors(new LoggingInterceptor())
export class CatsController {}
```

The construction above attaches the interceptor to every handler declared by this controller. To restrict the interceptor to a single method, apply the decorator at the **method level**.

To set up a global interceptor, use the `useGlobalInterceptors()` method of the Nest application instance:

```typescript

const app = await NestFactory.create(AppModule);
app.useGlobalInterceptors(new LoggingInterceptor());
```

Global interceptors apply to every controller and every route handler in the application. However, a global interceptor registered outside of any module (with `useGlobalInterceptors()`, as in the example above) cannot inject dependencies, because the registration happens outside the context of any module. To solve this, register the interceptor **directly from any module** using the following construction:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { APP_INTERCEPTOR } from '@nestjs/core';

@Module({
  providers: [
    {
      provide: APP_INTERCEPTOR,
      useClass: LoggingInterceptor,
    },
  ],
})
export class AppModule {}
```

> **Hint** When you use this approach to perform dependency injection for the interceptor, the interceptor is global regardless of the module in which you register it. We recommend registering it in the module where the interceptor (`LoggingInterceptor` in the example above) is defined. Also, `useClass` is not the only way to register a custom provider. See [Custom providers](/fundamentals/custom-providers) to learn more.

#### Response mapping[#](/interceptors#response-mapping)

The stream returned by `handle()` contains the value **returned** from the route handler, so you can transform it with RxJS's `map()` operator.

> **Warning** Response mapping doesn't work with the library-specific response strategy, i.e., when a route handler injects the response object with `@Res()` and sends the response itself. To combine the two, enable the `passthrough` option (see [Library-specific approach](/controllers#library-specific-approach)).

Let's create a `TransformInterceptor` that modifies each response in a trivial way to demonstrate the process. It uses RxJS's `map()` operator to assign the response object to the `data` property of a newly created object, and returns the new object to the client.

transform.interceptor.ts

JS TS

```typescript

import { Injectable, NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';

export interface Response<T> {
  data: T;
}

@Injectable()
export class TransformInterceptor<T> implements NestInterceptor<T, Response<T>> {
  intercept(context: ExecutionContext, next: CallHandler): Observable<Response<T>> {
    return next.handle().pipe(map(data => ({ data })));
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';
import { map } from 'rxjs/operators';

@Injectable()
export class TransformInterceptor {
  intercept(context, next) {
    return next.handle().pipe(map(data => ({ data })));
  }
}
```

> **Hint** The `intercept()` method can be synchronous or asynchronous. Declare it `async` if you need to await something before returning the stream.

With this interceptor bound, a `GET /cats` request whose route handler returns an empty array `[]` produces the following response:

```json

{
  "data": []
}
```

Interceptors are well suited to building reusable solutions for requirements that span the entire application. For example, imagine you need to replace every `null` response value with an empty string `''`. You can do this with one line of code, and bind the interceptor globally so that every registered handler uses it automatically.

JS TS

```typescript

import { Injectable, NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';

@Injectable()
export class ExcludeNullInterceptor implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    return next
      .handle()
      .pipe(map(value => value === null ? '' : value ));
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';
import { map } from 'rxjs/operators';

@Injectable()
export class ExcludeNullInterceptor {
  intercept(context, next) {
    return next
      .handle()
      .pipe(map(value => value === null ? '' : value ));
  }
}
```

#### Exception mapping[#](/interceptors#exception-mapping)

Another use case is overriding thrown exceptions with RxJS's `catchError()` operator:

errors.interceptor.ts

JS TS

```typescript

import {
  Injectable,
  NestInterceptor,
  ExecutionContext,
  BadGatewayException,
  CallHandler,
} from '@nestjs/common';
import { Observable, throwError } from 'rxjs';
import { catchError } from 'rxjs/operators';

@Injectable()
export class ErrorsInterceptor implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    return next
      .handle()
      .pipe(
        catchError(err => throwError(() => new BadGatewayException())),
      );
  }
}
```

```typescript

import { Injectable, BadGatewayException } from '@nestjs/common';
import { throwError } from 'rxjs';
import { catchError } from 'rxjs/operators';

@Injectable()
export class ErrorsInterceptor {
  intercept(context, next) {
    return next
      .handle()
      .pipe(
        catchError(err => throwError(() => new BadGatewayException())),
      );
  }
}
```

#### Stream overriding[#](/interceptors#stream-overriding)

Sometimes you may want to skip calling the handler entirely and return a different value instead. A typical example is a cache that improves response time. Let's look at a simple **cache interceptor** that returns its response from a cache. A realistic implementation would also need to consider factors such as TTL, cache invalidation, and cache size, which are beyond the scope of this discussion. The following basic example demonstrates the main concept.

cache.interceptor.ts

JS TS

```typescript

import { Injectable, NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
import { Observable, of } from 'rxjs';

@Injectable()
export class CacheInterceptor implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    const isCached = true;
    if (isCached) {
      return of([]);
    }
    return next.handle();
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';
import { of } from 'rxjs';

@Injectable()
export class CacheInterceptor {
  intercept(context, next) {
    const isCached = true;
    if (isCached) {
      return of([]);
    }
    return next.handle();
  }
}
```

Our `CacheInterceptor` has a hardcoded `isCached` variable and a hardcoded response `[]`. The key point is that it returns a new stream, created by RxJS's `of()` function, so the route handler **won't be called** at all. When someone calls an endpoint that uses `CacheInterceptor`, the response (a hardcoded, empty array) is returned immediately. To build a generic solution, use `Reflector` together with a custom decorator, as described in the [guards](/guards) chapter.

#### More operators[#](/interceptors#more-operators)

Manipulating the stream with RxJS operators opens up many possibilities. Consider another common use case: handling **timeouts** on route requests. If an endpoint doesn't return anything within a given period, you want to terminate the request with an error response. The following construction enables this:

timeout.interceptor.ts

JS TS

```typescript

import { Injectable, NestInterceptor, ExecutionContext, CallHandler, RequestTimeoutException } from '@nestjs/common';
import { Observable, throwError, TimeoutError } from 'rxjs';
import { catchError, timeout } from 'rxjs/operators';

@Injectable()
export class TimeoutInterceptor implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    return next.handle().pipe(
      timeout(5000),
      catchError(err => {
        if (err instanceof TimeoutError) {
          return throwError(() => new RequestTimeoutException());
        }
        return throwError(() => err);
      }),
    );
  }
}
```

```typescript

import { Injectable, RequestTimeoutException } from '@nestjs/common';
import { throwError, TimeoutError } from 'rxjs';
import { catchError, timeout } from 'rxjs/operators';

@Injectable()
export class TimeoutInterceptor {
  intercept(context, next) {
    return next.handle().pipe(
      timeout(5000),
      catchError(err => {
        if (err instanceof TimeoutError) {
          return throwError(() => new RequestTimeoutException());
        }
        return throwError(() => err);
      }),
    );
  }
}
```

If the route handler doesn't emit a result within 5 seconds, `timeout()` fails the stream with a `TimeoutError`, which the interceptor maps to a `RequestTimeoutException`. Unsubscribing from the handler's stream doesn't abort work the handler has already started (such as a pending database query), so add custom logic before throwing `RequestTimeoutException` if you need to release resources.

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/interceptors.md)

----
url: https://docs.nestjs.com/observability/overview
----

[Skip to content](#content)

On this page

* [Overview](https://docs.nestjs.com/observability/overview#overview)
* [How it differs from a generic Node.js APM](https://docs.nestjs.com/observability/overview#how-it-differs-from-a-generic-nodejs-apm)
* [What it offers](https://docs.nestjs.com/observability/overview#what-it-offers)
* [How it is organized](https://docs.nestjs.com/observability/overview#how-it-is-organized)
* [Subscribing](https://docs.nestjs.com/observability/overview#subscribing)
* [First project](https://docs.nestjs.com/observability/overview#first-project)
* [Where to go next](https://docs.nestjs.com/observability/overview#where-to-go-next)

### Overview

[NestJS Observe](https://www.observe.nestjs.com/ "NestJS Observe") is the official, auto-instrumented application performance monitoring (APM) and observability platform for NestJS applications. Install the SDK, add an API key, and your application starts streaming requests, background jobs, errors, logs, and traces to your dashboard - no manual span wiring, no collector to run, no schema to design, no dashboards to build by hand.

> **Hint** This chapter covers how to instrument a NestJS application with the `@nestjs/observe` SDK and what that instrumentation gives you. If you're looking for the dashboard itself, go to [observe.nestjs.com](https://www.observe.nestjs.com/ "NestJS Observe"), or open the [live demo](https://www.observe-demo.nestjs.com/dashboard "NestJS Observe live demo") - the full dashboard over a busy service's data, with no signup and nothing to install.

#### How it differs from a generic Node.js APM[#](/observability/overview#how-it-differs-from-a-generic-nodejs-apm)

Generic Node.js APM agents attach to the HTTP server and the database driver and leave everything in between as a black box. NestJS Observe is built around Nest's own request lifecycle - controllers, guards, interceptors, pipes, resolvers, queue consumers - so telemetry is expressed in the vocabulary you wrote the code in: `OrdersService.recalculate`, not `POST /orders`. That is also why it can show time spent per NestJS **class and method**, not only per route, and why a trace waterfall from an unmodified application already reads like a call graph.

The SDK attaches to the framework through the `instrument` application option of `NestFactory.create()` (available since `@nestjs/core` v11.1.4), so it sees every controller, provider, resolver, and queue consumer as Nest wires them - no process-wide patching, and nothing to import before the rest of your code.

#### What it offers[#](/observability/overview#what-it-offers)

Once the SDK is running, every plan - including the free tier - gives you:

* **Request monitoring** for HTTP, GraphQL, gRPC, and `@nestjs/microservices` transports: throughput, latency (average and p95), failure rate per operation, and a detail page for every single execution.
* **Distributed tracing** with a waterfall of every span a request ran, self-time ranking to find where the time actually went, and correlation across services once a trace id is propagated (see [Distributed tracing](/observability/distributed-tracing)).

Paid plans add **logs streaming** (correlated to traces, with redaction on by default), **alerting** (thresholds, anomaly detection, absence detection, Slack/webhook/email channels), **issues**, team management, and an **MCP server** so an MCP-compatible agent can query your telemetry directly and set up a new service (see [MCP server](/observability/mcp-server)). The higher tiers add **SSO** and **SLOs** with error budgets and burn-rate alerts.

Usage is metered in **Observability Events (OEs)** - one per request, background job run, error, log entry, or trace span your applications report. Events add up rather than merge: a request that ran through three of your own methods, wrote two log lines, and raised one error is seven events. The agent's own database-query and outbound-HTTP spans don't count, because they are detail about a method span that is already counted. Your plan sets a monthly allowance of included events, a retention window, and which features are unlocked:

| Plan       | Included events / month | Retention  | Logs & alerts | SSO & SLOs |
| ---------- | ----------------------: | ---------- | ------------- | ---------- |
| Free       |                    300k | 3 days     | ✗             | ✗          |
| Pro        |                     25M | 30 days    | ✓             | ✗          |
| Scale      |                    200M | 90 days    | ✓             | ✓          |
| Enterprise |              Negotiated | Negotiated | ✓             | ✓          |

Free has a hard monthly limit - once it is reached, ingestion is rejected until the next period. Pro and Scale allow overage instead of a hard stop, billed per additional million events, so a busy month doesn't mean lost telemetry. Annual billing is discounted against the monthly price. For current prices, seat counts, and overage rates, see the [pricing page](https://www.observe.nestjs.com/ "NestJS Observe").

To upgrade, open **Billing → Manage subscription** for the team that owns your projects. From the same area, the **Usage** page tracks your Observability Events against the allowance, broken down by project, and lets you set **quota notifications** (up to five thresholds, e.g. 50%, 80%, 100%) to get an email when usage crosses one.

> **Hint** Ingestion volume is controllable without a redeploy through per-project **spend controls**: trace-coherent span sampling, a per-minute rate cap, and drop filters for known-noisy traffic like `/health*`. Errors are never sampled or dropped by these controls. You can also stop telemetry from being generated at all on the SDK side - see [Ignoring noisy operations](/observability/sdk#ignoring-noisy-operations).

#### First project[#](/observability/overview#first-project)

The quickest way to a first project starts in your terminal. Run `npx @nestjs/observe link` in your project's directory and approve the code it prints at [observe.nestjs.com/link](https://www.observe.nestjs.com/link "Link a project to NestJS Observe"), signing up first if you don't have an account. Approving creates the project and the application if you don't have them yet and issues an API key, which the command writes into the project's `.env`. If the application doesn't use the [SDK](/observability/sdk) yet, the command also installs it and wires it in - see [Linking from the terminal](/observability/sdk#linking-from-the-terminal). A project generated by `nest new` with Observe offers this step right after installation.

Starting from the dashboard instead, a new account is offered a short **setup guide** that walks through the real pages - it highlights *Create Project*, then takes you into the new project to add an application and an API key, and finishes on the banner that waits for your first event. The same steps by hand:

1. **Create a project** and give it a name.
2. **Add an application** to it. An application needs nothing beyond a name - the routes it serves, the jobs it processes, and the metrics it reports are all discovered from the telemetry the SDK sends.
3. **Generate an API key** from the project's **API Keys** page. Each key has a name (one for local development, one for CI, one for production) and an optional expiration date. The key pair (`appKey` and `appSecret`) is shown once, at creation, so copy it into your secrets store right away. Keys are scoped to a project: every application whose telemetry should land in that project uses the same key.
4. **Instrument your application** by following the [SDK](/observability/sdk) chapter. Telemetry starts appearing within moments of your application receiving traffic.

> **Hint** If you're setting up with a coding agent, use the **Copy setup prompt** button in the dialog that shows a new key's secret. It combines the install command, the three code edits, and the credentials into one prompt. An agent connected to the [MCP server](/observability/mcp-server#setting-up-a-service) can create the application and the key itself.

> **Warning** Treat `appKey` and `appSecret` like any other credential: read them from environment variables or a secrets manager, never commit them to source control. You can revoke a key from the same page at any time; applications still using it can no longer send telemetry.

#### Where to go next[#](/observability/overview#where-to-go-next)

* [SDK](/observability/sdk) - installation, the three-line quick start, and every configuration option.
* [Manual instrumentation](/observability/manual-instrumentation) - custom spans, handled errors, request-scoped attributes, and custom metrics.
* [Distributed tracing](/observability/distributed-tracing) - propagating a trace id across HTTP, gRPC, microservice transports, and GraphQL.
* [Error monitoring](/observability/error-monitoring) - what gets captured, source context, grouping errors into defects, and getting from an error to a verified fix.
* [Dashboard](/observability/dashboard) - what each view shows once telemetry is flowing, and how alerts, SLOs, and issues build on it.
* [MCP server](/observability/mcp-server) - querying your telemetry from Claude Code, Cursor, VS Code, or your own agent.

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/observability/overview.md)

----
url: https://docs.nestjs.com/v11/openapi/decorators
----

* [Decorators](https://docs.nestjs.com/v11/openapi/decorators#decorators)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/openapi/decorators.md "Suggest Edits")

### Decorators

All of the available OpenAPI decorators have an `Api` prefix to distinguish them from the core decorators. Below is a full list of the exported decorators along with a designation of the level at which the decorator may be applied.

| `@ApiBasicAuth()`         | Method / Controller |
| ------------------------- | ------------------- |
| `@ApiBearerAuth()`        | Method / Controller |
| `@ApiBody()`              | Method              |
| `@ApiConsumes()`          | Method / Controller |
| `@ApiCookieAuth()`        | Method / Controller |
| `@ApiExcludeController()` | Controller          |
| `@ApiExcludeEndpoint()`   | Method              |
| `@ApiExtension()`         | Method              |
| `@ApiExtraModels()`       | Method / Controller |
| `@ApiHeader()`            | Method / Controller |
| `@ApiHideProperty()`      | Model               |
| `@ApiOAuth2()`            | Method / Controller |
| `@ApiOperation()`         | Method              |
| `@ApiParam()`             | Method / Controller |
| `@ApiProduces()`          | Method / Controller |
| `@ApiSchema()`            | Model               |
| `@ApiProperty()`          | Model               |
| `@ApiPropertyOptional()`  | Model               |
| `@ApiQuery()`             | Method / Controller |
| `@ApiResponse()`          | Method / Controller |
| `@ApiSecurity()`          | Method / Controller |
| `@ApiTags()`              | Method / Controller |
| `@ApiCallbacks()`         | Method / Controller |

----
url: https://docs.nestjs.com/v11/observability/sdk
----

* [SDK](https://docs.nestjs.com/v11/observability/sdk#sdk)
* [Installation](https://docs.nestjs.com/v11/observability/sdk#installation)
* [Quick start](https://docs.nestjs.com/v11/observability/sdk#quick-start)
* [Authenticating and identifying the application](https://docs.nestjs.com/v11/observability/sdk#authenticating-and-identifying-the-application)
* [Asynchronous configuration](https://docs.nestjs.com/v11/observability/sdk#asynchronous-configuration)
* [Associating users with telemetry](https://docs.nestjs.com/v11/observability/sdk#associating-users-with-telemetry)
* [Runtime metrics and profiling](https://docs.nestjs.com/v11/observability/sdk#runtime-metrics-and-profiling)
* [Logs](https://docs.nestjs.com/v11/observability/sdk#logs)
* [Error source context](https://docs.nestjs.com/v11/observability/sdk#error-source-context)
* [Trace correlation](https://docs.nestjs.com/v11/observability/sdk#trace-correlation)
* [Tags and custom attributes](https://docs.nestjs.com/v11/observability/sdk#tags-and-custom-attributes)
* [Ignoring noisy operations](https://docs.nestjs.com/v11/observability/sdk#ignoring-noisy-operations)
* [Trace sampling and batching](https://docs.nestjs.com/v11/observability/sdk#trace-sampling-and-batching)
* [Collector endpoint](https://docs.nestjs.com/v11/observability/sdk#collector-endpoint)
* [Debugging the SDK itself](https://docs.nestjs.com/v11/observability/sdk#debugging-the-sdk-itself)
* [Full configuration reference](https://docs.nestjs.com/v11/observability/sdk#full-configuration-reference)
* [Where to go next](https://docs.nestjs.com/v11/observability/sdk#where-to-go-next)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/observability/sdk.md "Suggest Edits")

### SDK

The `@nestjs/observe` SDK is what gets your application's requests, jobs, errors, logs, and traces into your [NestJS Observe](https://www.observe.nestjs.com/ "NestJS Observe") dashboard. It hooks into Nest's own request lifecycle - controllers, interceptors, resolvers, queue consumers - rather than bolting a generic Node.js agent onto the process, so most of what shows up in the dashboard needs no manual span wiring.

#### Installation[#](/observability/sdk#installation)

```bash

$ npm i @nestjs/observe
```

> **Warning** The SDK requires `@nestjs/core` v11.1.4 or later (it relies on the `instrument` application option introduced in that release), and `@nestjs/graphql` v13.4.4 or later if your application uses GraphQL. Earlier versions lack the hooks the SDK needs for proper instrumentation.

#### Quick start[#](/observability/sdk#quick-start)

The integration is three steps. First, call `createObserveModule()` once, typically in `app.module.ts` or another root-level file. It returns a matched pair - a Nest module and an `instrument` hook - bound to the same configuration:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { createObserveModule } from '@nestjs/observe';
import { AppController } from './app.controller';
import { AppService } from './app.service';

export const { ObserveModule, ObserveInstrument } = createObserveModule();

@Module({
  imports: [
    ObserveModule.forRoot({
      appKey: process.env.OBSERVE_APP_KEY,
      appSecret: process.env.OBSERVE_APP_SECRET,
      serviceId: 'cats-app',
    }),
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}
```

Second, import `ObserveModule.forRoot()` into your root module with at least a `serviceId` (shown above). Third, pass `ObserveInstrument` to `NestFactory.create()` so the SDK can attach to the application before it starts handling traffic:

main.ts

JS TS

```typescript

import { NestFactory } from '@nestjs/core';
import { AppModule, ObserveInstrument } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule, {
    instrument: ObserveInstrument,
  });
  await app.listen(process.env.PORT ?? 3000);
}
bootstrap();
```

That's the whole integration. Once the application receives traffic, requests, errors, and traces start appearing in your project's dashboard within moments - no exporter to configure, no schema to design. The same `instrument` option is accepted by `NestFactory.createMicroservice()` and `NestFactory.createApplicationContext()`, so workers and standalone applications are instrumented the same way.

> **Hint**`createObserveModule()` itself takes an options object that controls how trace ids are generated and how error source context is captured - see [Trace correlation](#trace-correlation) and [Error source context](#error-source-context) below. Everything else is configured through `ObserveModule.forRoot()`.

#### Authenticating and identifying the application[#](/observability/sdk#authenticating-and-identifying-the-application)

```typescript

ObserveModule.forRoot({
  appKey: process.env.OBSERVE_APP_KEY,
  appSecret: process.env.OBSERVE_APP_SECRET,
  serviceId: 'cats-app',
  serviceVersion: process.env.GIT_SHA,
});
```

| Option           | Type     | Default  | Description                                                                                                                                                                                              |
| ---------------- | -------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `appKey`         | `string` | -        | Generated from your project's **API Keys** page - see [First project](/observability/overview#first-project). Keep it out of source control.                                                             |
| `appSecret`      | `string` | -        | Issued alongside `appKey` from the same page. Keep it out of source control.                                                                                                                             |
| `serviceId`      | `string` | required | Identifies this application in your dashboard. If you run multiple instances of the same service, use something unique per instance (hostname, container id) so they're distinguishable in the Profiler. |
| `serviceVersion` | `string` | -        | Identifies the deployment - a semantic version, a commit hash, or any other identifier. Every request and job records the version that served it, which is what powers the **Releases** view.            |

Passing a `serviceVersion` is optional but strongly recommended: it is what lets the dashboard compare each version of an application against the one before it (error rate, latency, throughput side by side), so a regression introduced by a deploy is visible immediately rather than buried in a week-long chart.

#### Asynchronous configuration[#](/observability/sdk#asynchronous-configuration)

When the credentials come from a configuration provider rather than `process.env` directly, use `forRootAsync()` - it accepts the same `useFactory`/`inject`, `useClass`, and `useExisting` shapes as every other Nest dynamic module (a class implements `ObserveOptionsFactory` with a `createObserveOptions()` method), plus `extraProviders` and `global`:

app.module.ts

JS TS

```typescript

ObserveModule.forRootAsync({
  imports: [ConfigModule],
  inject: [ConfigService],
  useFactory: (config: ConfigService) => ({
    appKey: config.getOrThrow('OBSERVE_APP_KEY'),
    appSecret: config.getOrThrow('OBSERVE_APP_SECRET'),
    serviceId: config.get('SERVICE_ID', 'cats-app'),
    serviceVersion: config.get('GIT_SHA'),
  }),
});
```

#### Associating users with telemetry[#](/observability/sdk#associating-users-with-telemetry)

`getUserId` reads the incoming request and returns whatever identifier your system uses for a person - a user id, an account id, a tenant-scoped id. Set it once and the **Users** view populates automatically:

```typescript

ObserveModule.forRoot({
  // ...
  http: {
    getUserId: (req) => req.user?.id ?? 'anonymous',
  },
});
```

The same option exists on `rpc` (receiving the transport id and the `BaseRpcContext`), `grpc` (receiving the call object), and `graphql` (receiving the GraphQL context, for operations with no enclosing HTTP request), reading the transport's own context instead of an HTTP request. Reporting a user identifier is entirely optional - traffic without one still shows up everywhere except the per-user views. The dashboard treats the identifier as an opaque string and never tries to resolve it into a name or an email, so prefer an opaque internal id over anything personally identifying.

#### Runtime metrics and profiling[#](/observability/sdk#runtime-metrics-and-profiling)

```typescript

ObserveModule.forRoot({
  // ...
  runtimeMetrics: true,
  runtimeMetricsInterval: 60000,
});
```

`runtimeMetrics` (default `true`) samples memory, CPU, garbage collection, and event loop latency on an interval (`runtimeMetricsInterval`, default `60000` ms) and feeds the **Profiler**. The same samples double as the application's heartbeat: a **Telemetry silence** alert fires when they stop arriving, which gives you lightweight uptime monitoring with no external probe.

#### Logs[#](/observability/sdk#logs)

```typescript

ObserveModule.forRoot({
  // ...
  forwardLogs: true,
  redaction: {
    enabled: true,
    keys: ['internalToken'],
    patterns: [/acct_[a-z0-9]{16}/gi],
  },
});
```

`forwardLogs` (default `false`) sends your application's log lines - anything written through Nest's `Logger` - to the dashboard, correlated to the trace that was active when each line was written. On an execution page, every line is placed on the trace's clock next to the span that was in flight when it was written. Log forwarding is available on Pro and above.

Turning `forwardLogs` on moves your log lines onto infrastructure you don't control, so redaction is on by default the moment it is:

| `redaction` field    | Type       | Default        | Description                                                                                                                                                                                                                                                               |
| -------------------- | ---------- | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `enabled`            | `boolean`  | `true`         | Whether log lines are scrubbed at all.                                                                                                                                                                                                                                    |
| `useDefaultPatterns` | `boolean`  | `true`         | Applies the built-in patterns: bearer tokens, JWTs, AWS key ids, PEM private keys, `key=value` secrets, and Luhn-valid card numbers. Disable only if you're replacing them wholesale with your own `patterns` - there's no supported case for forwarding logs unredacted. |
| `patterns`           | `RegExp[]` | -              | Extra patterns to mask, for secrets shaped in a way only your codebase knows - internal token prefixes, customer identifiers. Always applied as if global, so a match is never limited to the first occurrence in a line.                                                 |
| `keys`               | `string[]` | -              | Extra attribute keys whose values are masked outright, on top of the built-in list. Compared case-insensitively and ignoring `-`/`_`, so `apiKey`, `api_key`, and `API-KEY` are one entry.                                                                                |
| `replacement`        | `string`   | `'[REDACTED]'` | Text substituted for anything matched.                                                                                                                                                                                                                                    |

> **Hint** Even with `forwardLogs` off, the SDK augments `ConsoleLogger` so that every line carries the current trace id (`attachTraceIdToLogs`, see [Trace correlation](#trace-correlation)). That lets you correlate your own log aggregator with traces in the dashboard without shipping the log content anywhere.

#### Error source context[#](/observability/sdk#error-source-context)

Errors that propagate out of a controller, resolver, job, or span are captured automatically. When `sourceContext` is enabled (the default), the SDK additionally reads the source lines around each in-app stack frame of a captured error and attaches them, which is what lets the dashboard show the failing code alongside the stack trace - for a failure that happened in production, on a build you may not have checked out.

app.module.ts

JS TS

```typescript

export const { ObserveModule, ObserveInstrument } = createObserveModule({
  sourceContext: {
    linesOfContext: 5,
    maxFrames: 5,
    sourceMaps: false,
  },
});
```

Note that this is an option of `createObserveModule()`, not `forRoot()`. Set `sourceContext: false` to disable it outright, or pass an object to tune the defaults:

| Option           | Type      | Default | Description                                                                                                                                                                                                                                                                                                                                                                       |
| ---------------- | --------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `linesOfContext` | `number`  | `5`     | Lines read on either side of the frame's line.                                                                                                                                                                                                                                                                                                                                    |
| `maxFrames`      | `number`  | `5`     | How many in-app frames, counted from the top of the stack, get source attached - bounds the payload on deep stacks.                                                                                                                                                                                                                                                               |
| `sourceMaps`     | `boolean` | `false` | Resolves compiled frames back through source maps before reading source. Only needed if the process runs compiled output *without* Node's own source map support (`--enable-source-maps` or `process.setSourceMapsEnabled(true)`); with that on, frames already carry original positions and this is redundant. Costs a map parse per compiled file on first touch, cached after. |

> **Warning** Enabling this ships fragments of your application's source code (usually just a few lines surrounding the error) to your dashboard, stored alongside the error. Frames inside `node_modules` and Node internals are never read - only application source - but turn it off if shipping any source is not acceptable for your codebase.

#### Trace correlation[#](/observability/sdk#trace-correlation)

These are also options of `createObserveModule()` - they shape how requests get a trace id and how that id shows up in your own logs:

app.module.ts

JS TS

```typescript

import { randomUUID } from 'node:crypto';

export const { ObserveModule, ObserveInstrument } = createObserveModule({
  traceIdKey: 'traceId',
  traceIdGenerator: (req) => req.headers['x-request-id'] ?? randomUUID(),
  attachTraceIdToLogs: true,
});
```

| Option                | Type                       | Default                                                       | Description                                                                                                                         |
| --------------------- | -------------------------- | ------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| `traceIdKey`          | `string`                   | `'traceId'`                                                   | The key used to store the trace id in the request context, for later retrieval through `TracerService`.                             |
| `traceIdGenerator`    | `(req: unknown) => string` | Uses the `x-request-id` header if present, else a random UUID | Generates the trace id per request. Called with the request object for HTTP; for other protocols it receives the transport context. |
| `attachTraceIdToLogs` | `boolean`                  | `true`                                                        | Augments `ConsoleLogger` to include the trace id in log messages, so logs can be correlated with traces even without `forwardLogs`. |

Because the default generator adopts an incoming `x-request-id`, a chain of HTTP services already shares one trace with no extra configuration. Propagating across gRPC, `@nestjs/microservices` transports, and GraphQL takes a few lines - see [Distributed tracing]().

#### Tags and custom attributes[#](/observability/sdk#tags-and-custom-attributes)

`http`, `rpc`, `grpc`, `graphql`, and `jobs` each accept the same two options for attaching your own data to every request they cover:

| Option          | Applies                                                       | Description                                                                         |
| --------------- | ------------------------------------------------------------- | ----------------------------------------------------------------------------------- |
| `tags`          | The same static `Record<string, string>` to every request     | Good for constants that don't vary per call - `project`, `env`, `region`.           |
| `setAttributes` | A function of the request/call/job, returning key-value pairs | Good for anything that varies per call - a feature flag, a tenant id, a queue name. |

```typescript

ObserveModule.forRoot({
  // ...
  http: {
    tags: { project: 'cats-app', env: process.env.NODE_ENV ?? 'development' },
    setAttributes: (req) => ({
      'user-agent': req.headers['user-agent'],
      'client-ip': req.ip,
    }),
  },
  jobs: {
    setAttributes: (job) => ({ queueName: job.queueName, jobName: job.name }),
  },
});
```

Both show up as tags on the resulting request, job, or span, and are searchable and visible on its detail page. The function receives whatever the transport has: the request for `http`, the transport id and `BaseRpcContext` for `rpc`, the call object for `grpc`, the resolve info and GraphQL context for `graphql`, and `{ queueName, name, id }` for `jobs`. To tag a single span from inside your code rather than every request, use `TracerService` - see [Manual instrumentation]().

> **Hint** A GraphQL server is usually an HTTP endpoint, so its requests are already subject to the `http` options - `http.ignore` drops a request before the GraphQL layer sees it, and `http.getUserId` supplies the user for queries over HTTP. The `graphql` block tunes what happens *inside* a request that was let through, per operation rather than per resolver, and `graphql.getUserId` is only consulted for operations that aren't already inside an HTTP trace - subscriptions over a WebSocket in particular.

#### Ignoring noisy operations[#](/observability/sdk#ignoring-noisy-operations)

Every transport block has an `ignore` option that skips instrumentation entirely for calls that match - a health check endpoint, an internal probe, anything not worth a trace:

```typescript

ObserveModule.forRoot({
  // ...
  http: {
    ignore: ['/health', { method: 'GET', path: /^\/internal\// }],
  },
  rpc: {
    ignore: (transportId, ctx) =>
      ctx instanceof TcpContext && ctx.getPattern() === 'ping',
  },
  grpc: {
    ignore: (call) => call.getPath().endsWith('/Health/Check'),
  },
  graphql: {
    ignore: (info) => info.fieldName === 'healthcheck',
  },
});
```

`http.ignore` accepts an array of paths, `{ method, path }` pairs (`path` can be a string or a `RegExp`), and plain `RegExp`s - or a single predicate function over the request. `rpc.ignore`, `grpc.ignore`, and `graphql.ignore` are predicates over the transport's own context (the `@nestjs/microservices` transport id and `BaseRpcContext`, the gRPC call object, and the GraphQL resolve info respectively). Matching a GraphQL field name skips the whole operation that field leads, not just that field - an operation is measured end to end, so it is traced or it is not.

This stops telemetry from being generated at all, which is a different tool from the dashboard's spend-control drop filters - those discard already-generated events at ingestion to save on billed volume. `ignore` is the right choice when you don't want a trace to exist; drop filters are the right choice when you want to tune cost on data the SDK is already producing.

`http` additionally takes `queryParamsObfuscateRegex`, a `RegExp` for masking sensitive query string values before they're sent. It is applied on top of the built-in redaction, which always masks well-known sensitive parameters (`token`, `password`, `code`, `signature`, and so on) whether or not this is set.

#### Trace sampling and batching[#](/observability/sdk#trace-sampling-and-batching)

```typescript

ObserveModule.forRoot({
  // ...
  tracesSampleRate: 0.25,
  maxTracesPerBatch: 1000,
  flushInterval: 5000,
});
```

| Option              | Type                                                                                    | Default | Description                                                                                               |
| ------------------- | --------------------------------------------------------------------------------------- | ------- | --------------------------------------------------------------------------------------------------------- |
| `tracesSampleRate`  | `number \| ((protocol: 'http' \| 'rpc' \| 'grpc' \| 'graphql', attributes) => boolean)` | `1.0`   | Fraction of traces sent, or a predicate for per-trace decisions. `1.0` sends everything; `0.1` sends 10%. |
| `maxTracesPerBatch` | `number`                                                                                | `1000`  | Caps how many traces go out per batch, to bound volume on high-traffic applications.                      |
| `flushInterval`     | `number` (ms)                                                                           | `5000`  | How often the SDK batches and sends collected traces.                                                     |

Telemetry is buffered in the process and shipped on the flush interval rather than inline with each request. Sampling here decides what the SDK *produces*; the dashboard's per-project spend controls (span sampling, rate caps, drop filters) act on what it already sent, and can be changed without a redeploy.

#### Collector endpoint[#](/observability/sdk#collector-endpoint)

```typescript

ObserveModule.forRoot({ endpoint: 'https://observe-api.nestjs.com' });
```

`endpoint` (default `'https://observe-api.nestjs.com'`) is the base URL of the collector, used for telemetry and profiles both so the two can never point at different places. Set the `OBSERVE_ENDPOINT` environment variable to override it without touching the config - which is how a local or self-hosted collector is usually pointed at.

#### Debugging the SDK itself[#](/observability/sdk#debugging-the-sdk-itself)

```typescript

ObserveModule.forRoot({ debug: true });
```

`debug` (default `false`) logs additional diagnostic information from the SDK to the console - useful while getting instrumentation working, not something to leave on in production.

#### Full configuration reference[#](/observability/sdk#full-configuration-reference)

Everything at a glance. Options under `createObserveModule()` must be set there; everything else goes to `forRoot()`/`forRootAsync()`.

| Where                   | Option                                     | Purpose                                                      |
| ----------------------- | ------------------------------------------ | ------------------------------------------------------------ |
| `createObserveModule()` | `sourceContext`                            | Attach source lines to error stack frames                    |
| `createObserveModule()` | `traceIdKey`                               | Context key the trace id is stored under                     |
| `createObserveModule()` | `traceIdGenerator`                         | How each request obtains its trace id                        |
| `createObserveModule()` | `attachTraceIdToLogs`                      | Prefix `ConsoleLogger` output with the trace id              |
| `forRoot()`             | `appKey`, `appSecret`                      | Project API key pair                                         |
| `forRoot()`             | `endpoint`                                 | Collector base URL (or `OBSERVE_ENDPOINT`)                   |
| `forRoot()`             | `serviceId`, `serviceVersion`              | Application and release identity                             |
| `forRoot()`             | `http`, `rpc`, `grpc`, `graphql`, `jobs`   | Per-transport `tags`, `setAttributes`, `getUserId`, `ignore` |
| `forRoot()`             | `http.queryParamsObfuscateRegex`           | Mask sensitive query string values                           |
| `forRoot()`             | `runtimeMetrics`, `runtimeMetricsInterval` | Profiler samples and heartbeat                               |
| `forRoot()`             | `forwardLogs`, `redaction`                 | Logs streaming and scrubbing                                 |
| `forRoot()`             | `tracesSampleRate`                         | Fraction (or predicate) of traces to send                    |
| `forRoot()`             | `maxTracesPerBatch`, `flushInterval`       | Batching                                                     |
| `forRoot()`             | `debug`                                    | SDK diagnostics                                              |

#### Where to go next[#](/observability/sdk#where-to-go-next)

* [Manual instrumentation]() - add your own spans, capture handled errors, attach request-scoped attributes, and report custom metrics.
* [Distributed tracing]() - keep one trace across HTTP, gRPC, microservice transports, and GraphQL.
* [Dashboard]() - what shows up once the SDK is running, and how the views relate to each other.

----
url: https://docs.nestjs.com/v10/standalone-applications
----

* [Standalone applications](https://docs.nestjs.com/v10/standalone-applications#standalone-applications)
* [Getting started](https://docs.nestjs.com/v10/standalone-applications#getting-started)
* [Retrieving providers from static modules](https://docs.nestjs.com/v10/standalone-applications#retrieving-providers-from-static-modules)
* [Retrieving providers from dynamic modules](https://docs.nestjs.com/v10/standalone-applications#retrieving-providers-from-dynamic-modules)
* [Terminating phase](https://docs.nestjs.com/v10/standalone-applications#terminating-phase)
* [Example](https://docs.nestjs.com/v10/standalone-applications#example)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/application-context.md "Suggest Edits")

### Standalone applications

There are several ways of mounting a Nest application. You can create a web app, a microservice or just a bare Nest **standalone application** (without any network listeners). The Nest standalone application is a wrapper around the Nest **IoC container**, which holds all instantiated classes. We can obtain a reference to any existing instance from within any imported module directly using the standalone application object. Thus, you can take advantage of the Nest framework anywhere, including, for example, scripted **CRON** jobs. You can even build a **CLI** on top of it.

#### Getting started[#](/standalone-applications#getting-started)

To create a Nest standalone application, use the following construction:

JS TS

```typescript

async function bootstrap() {
  const app = await NestFactory.createApplicationContext(AppModule);
  // your application logic here ...
}
bootstrap();
```

#### Retrieving providers from static modules[#](/standalone-applications#retrieving-providers-from-static-modules)

The standalone application object allows you to obtain a reference to any instance registered within the Nest application. Let's imagine that we have a `TasksService` provider in the `TasksModule` module that was imported by our `AppModule` module. This class provides a set of methods that we want to call from within a CRON job.

JS TS

```typescript

const tasksService = app.get(TasksService);
```

To access the `TasksService` instance we use the `get()` method. The `get()` method acts like a **query** that searches for an instance in each registered module. You can pass any provider's token to it. Alternatively, for strict context checking, pass an options object with the `strict: true` property. With this option in effect, you have to navigate through specific modules to obtain a particular instance from the selected context.

JS TS

```typescript

const tasksService = app.select(TasksModule).get(TasksService, { strict: true });
```

Following is a summary of the methods available for retrieving instance references from the standalone application object.

|            |                                                                                                                                                  |
| ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| `get()`    | Retrieves an instance of a controller or provider (including guards, filters, and so on) available in the application context.                   |
| `select()` | Navigates through the module's graph to pull out a specific instance of the selected module (used together with strict mode as described above). |

> **Hint** In non-strict mode, the root module is selected by default. To select any other module, you need to navigate the modules graph manually, step by step.

Keep in mind that a standalone application does not have any network listeners, so any Nest features related to HTTP (e.g., middleware, interceptors, pipes, guards, etc.) are not available in this context.

For example, even if you register a global interceptor in your application and then retrieve a controller's instance using the `app.get()` method, the interceptor will not be executed.

#### Retrieving providers from dynamic modules[#](/standalone-applications#retrieving-providers-from-dynamic-modules)

When dealing with [dynamic modules](/v10/standalone-applications/fundamentals/dynamic-modules.md), we should supply the same object that represents the registered dynamic module in the application to `app.select`. For example:

JS TS

```typescript

export const dynamicConfigModule = ConfigModule.register({ folder: './config' });

@Module({
  imports: [dynamicConfigModule],
})
export class AppModule {}
```

Then you can select that module later on:

JS TS

```typescript

const configService = app.select(dynamicConfigModule).get(ConfigService, { strict: true });
```

#### Terminating phase[#](/standalone-applications#terminating-phase)

If you want the Node application to close after the script finishes (e.g., for a script running CRON jobs), you must call the `app.close()` method in the end of your `bootstrap` function like this:

JS TS

```typescript

async function bootstrap() {
  const app = await NestFactory.createApplicationContext(AppModule);
  // application logic...
  await app.close();
}
bootstrap();
```

And as mentioned in the [Lifecycle events](/v10/standalone-applications/fundamentals/lifecycle-events.md) chapter, that will trigger lifecycle hooks.

#### Example[#](/standalone-applications#example)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/18-context).

----
url: https://docs.nestjs.com/v9/faq/raw-body
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Raw body](https://docs.nestjs.com/v9/faq/raw-body#raw-body)
* [Use with Express](https://docs.nestjs.com/v9/faq/raw-body#use-with-express)
* [Registering a different parser](https://docs.nestjs.com/v9/faq/raw-body#registering-a-different-parser)
* [Body parser size limit](https://docs.nestjs.com/v9/faq/raw-body#body-parser-size-limit)
* [Use with Fastify](https://docs.nestjs.com/v9/faq/raw-body#use-with-fastify)
* [Registering a different parser](https://docs.nestjs.com/v9/faq/raw-body#registering-a-different-parser-1)
* [Body parser size limit](https://docs.nestjs.com/v9/faq/raw-body#body-parser-size-limit-1)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/faq/raw-body.md "Suggest Edits")

### Raw body

One of the most common use-case for having access to the raw request body is performing webhook signature verifications. Usually to perform webhook signature validations the unserialized request body is required to calculate an HMAC hash.

> **Warning** This feature can be used only if the built-in global body parser middleware is enabled, ie., you must not pass `bodyParser: false` when creating the app.

#### Use with Express

First enable the option when creating your Nest Express application:

```typescript

import { NestFactory } from '@nestjs/core';
import type { NestExpressApplication } from '@nestjs/platform-express';
import { AppModule } from './app.module';

// in the "bootstrap" function
const app = await NestFactory.create<NestExpressApplication>(AppModule, {
  rawBody: true,
});
await app.listen(3000);
```

To access the raw request body in a controller, a convenience interface `RawBodyRequest` is provided to expose a `rawBody` field on the request: use the interface `RawBodyRequest` type:

```typescript

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

@Controller('cats')
class CatsController {
  @Post()
  create(@Req() req: RawBodyRequest<Request>) {
    const raw = req.rawBody; // returns a `Buffer`.
  }
}
```

#### Registering a different parser

By default, only `json` and `urlencoded` parsers are registered. If you want to register a different parser on the fly, you will need to do so explicitly.

For example, to register a `text` parser, you can use the following code:

```typescript

app.useBodyParser('text');
```

> **Warning** Ensure that you are providing the correct application type to the `NestFactory.create` call. For Express applications, the correct type is `NestExpressApplication`. Otherwise the `.useBodyParser` method will not be found.

#### Body parser size limit

If your application needs to parse a body larger than the default `100kb` of Express, use the following:

```typescript

app.useBodyParser('json', { limit: '10mb' });
```

The `.useBodyParser` method will respect the `rawBody` option that is passed in the application options.

#### Use with Fastify

First enable the option when creating your Nest Fastify application:

```typescript

import { NestFactory } from '@nestjs/core';
import {
  FastifyAdapter,
  NestFastifyApplication,
} from '@nestjs/platform-fastify';
import { AppModule } from './app.module';

// in the "bootstrap" function
const app = await NestFactory.create<NestFastifyApplication>(
  AppModule,
  new FastifyAdapter(),
  {
    rawBody: true,
  },
);
await app.listen(3000);
```

To access the raw request body in a controller, a convenience interface `RawBodyRequest` is provided to expose a `rawBody` field on the request: use the interface `RawBodyRequest` type:

```typescript

import { Controller, Post, RawBodyRequest, Req } from '@nestjs/common';
import { FastifyRequest } from 'fastify';

@Controller('cats')
class CatsController {
  @Post()
  create(@Req() req: RawBodyRequest<FastifyRequest>) {
    const raw = req.rawBody; // returns a `Buffer`.
  }
}
```

#### Registering a different parser

By default, only `application/json` and `application/x-www-form-urlencoded` parsers are registered. If you want to register a different parser on the fly, you will need to do so explicitly.

For example, to register a `text/plain` parser, you can use the following code:

```typescript

app.useBodyParser('text/plain');
```

> **Warning** Ensure that you are providing the correct application type to the `NestFactory.create` call. For Fastify applications, the correct type is `NestFastifyApplication`. Otherwise the `.useBodyParser` method will not be found.

#### Body parser size limit

If your application needs to parse a body larger than the default 1MiB of Fastify, use the following:

```typescript

const bodyLimit = 10_485_760; // 10MiB
app.useBodyParser('application/json', { bodyLimit });
```

The `.useBodyParser` method will respect the `rawBody` option that is passed in the application options.

----
url: https://docs.nestjs.com/faq/global-prefix
----

[Skip to content](#content)

On this page

* [Global prefix](https://docs.nestjs.com/faq/global-prefix#global-prefix)

### Global prefix

To set a prefix for **every route** registered in an HTTP application, call the `setGlobalPrefix()` method on the `INestApplication` instance.

```typescript

const app = await NestFactory.create(AppModule);
app.setGlobalPrefix('v1');
```

To serve the same routes under more than one prefix, pass an array. Every route is then registered once per prefix:

```typescript

app.setGlobalPrefix(['api', 'v1']);
// GET /api/cats and GET /v1/cats reach the same route handler
```

> **Hint** In Nest v10 and earlier, a regular expression prefix such as `(api|v1)` served this purpose. That syntax is no longer supported, so use an array instead.

> **Warning**`@nestjs/swagger` only reads the first prefix. With `app.setGlobalPrefix(['api', 'v1'])`, the generated OpenAPI document lists routes under `/api` only, and the [`useGlobalPrefix`](/openapi/introduction#setup-options) option serves Swagger UI under `/api` only.

To exclude routes from the global prefix, use the `exclude` option:

```typescript

app.setGlobalPrefix('v1', {
  exclude: [{ path: 'health', method: RequestMethod.GET }],
});
```

Alternatively, you can specify a route as a string, which excludes it for every request method:

```typescript

app.setGlobalPrefix('v1', { exclude: ['cats'] });
```

> **Hint** The `path` property supports wildcard parameters through the [path-to-regexp](https://github.com/pillarjs/path-to-regexp#parameters) package. Bare wildcard asterisks (`*`) are deprecated; use parameters (`:param`) or named wildcards (`*splat`) instead. A named wildcard requires at least one extra segment, so `health/*splat` excludes `/health/status` but not `/health` itself. To exclude both, wrap the wildcard in braces: `health/{*splat}`.

The `exclude` option behaves the same way with multiple prefixes: excluded routes are served without any prefix. In the following example, `health` is only available at `/health`, while every other route is available under both `/api` and `/v1`:

```typescript

app.setGlobalPrefix(['api', 'v1'], { exclude: ['health'] });
```

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/faq/global-prefix.md)

----
url: https://docs.nestjs.com/fundamentals/execution-context
----

[Skip to content](#content)

On this page

* [Execution context](https://docs.nestjs.com/fundamentals/execution-context#execution-context)
* [ArgumentsHost class](https://docs.nestjs.com/fundamentals/execution-context#argumentshost-class)
* [Current application context](https://docs.nestjs.com/fundamentals/execution-context#current-application-context)
* [Host handler arguments](https://docs.nestjs.com/fundamentals/execution-context#host-handler-arguments)
* [ExecutionContext class](https://docs.nestjs.com/fundamentals/execution-context#executioncontext-class)
* [Reflection and metadata](https://docs.nestjs.com/fundamentals/execution-context#reflection-and-metadata)
* [Low-level approach](https://docs.nestjs.com/fundamentals/execution-context#low-level-approach)

### Execution context

Nest provides several utility classes that help you write applications that function across multiple application contexts (e.g., HTTP server-based, microservices, and WebSockets application contexts). These utilities provide information about the current execution context, which you can use to build generic [guards](/guards), [filters](/exception-filters), and [interceptors](/interceptors) that work across a broad set of controllers, methods, and execution contexts.

This chapter covers two such classes: `ArgumentsHost` and `ExecutionContext`.

#### ArgumentsHost class[#](/fundamentals/execution-context#argumentshost-class)

The `ArgumentsHost` class provides methods for retrieving the arguments being passed to a handler. It lets you choose the appropriate context (e.g., HTTP, RPC (microservice), or WebSockets) to retrieve the arguments from. The framework provides an instance of `ArgumentsHost`, typically referenced as a `host` parameter, in places where you may want to access it. For example, the `catch()` method of an [exception filter](/exception-filters#arguments-host) is called with an `ArgumentsHost` instance.

`ArgumentsHost` acts as an abstraction over a handler's arguments. For example, in HTTP server applications (when `@nestjs/platform-express` is used), the `host` object encapsulates Express's `[request, response, next]` array, where `request` is the request object, `response` is the response object, and `next` is a function that controls the application's request-response cycle. For [GraphQL](/graphql/quick-start) applications, on the other hand, the `host` object contains the `[root, args, context, info]` array.

#### Current application context[#](/fundamentals/execution-context#current-application-context)

When you build generic [guards](/guards), [filters](/exception-filters), and [interceptors](/interceptors) that are meant to run across multiple application contexts, you need a way to determine the type of application your method is currently running in. Use the `getType()` method of `ArgumentsHost` for this. It returns `'http'`, `'rpc'`, or `'ws'` out of the box, and packages such as `@nestjs/graphql` add their own types:

```typescript

if (host.getType() === 'http') {
  // do something that is only important in the context of regular HTTP requests (REST)
} else if (host.getType() === 'rpc') {
  // do something that is only important in the context of microservice requests
} else if (host.getType<GqlContextType>() === 'graphql') {
  // do something that is only important in the context of GraphQL requests
}
```

> **Hint** The `GqlContextType` type is imported from the `@nestjs/graphql` package.

With the application type available, you can write more generic components, as shown below.

#### Host handler arguments[#](/fundamentals/execution-context#host-handler-arguments)

One way to retrieve the array of arguments being passed to the handler is the host object's `getArgs()` method:

```typescript

const [req, res, next] = host.getArgs();
```

You can pluck a particular argument by index using the `getArgByIndex()` method:

```typescript

const request = host.getArgByIndex(0);
const response = host.getArgByIndex(1);
```

These examples retrieve the request and response objects by index, which is not typically recommended, because it couples the application to a particular execution context. Instead, you can make your code more robust and reusable by using one of the `host` object's utility methods to switch to the appropriate application context. The context switch utility methods are shown below.

```typescript

/**
 * Switch context to RPC.
 */
switchToRpc(): RpcArgumentsHost;
/**
 * Switch context to HTTP.
 */
switchToHttp(): HttpArgumentsHost;
/**
 * Switch context to WebSockets.
 */
switchToWs(): WsArgumentsHost;
```

Let's rewrite the previous example using the `switchToHttp()` method. The `host.switchToHttp()` helper call returns an `HttpArgumentsHost` object that is appropriate for the HTTP application context. The `HttpArgumentsHost` object has two useful methods for extracting the desired objects. The example also passes Express types as type arguments, so the methods return natively typed Express objects:

```typescript

const ctx = host.switchToHttp();
const request = ctx.getRequest<Request>();
const response = ctx.getResponse<Response>();
```

Similarly, `WsArgumentsHost` and `RpcArgumentsHost` have methods that return the appropriate objects in the WebSockets and microservices contexts. Here are the methods of `WsArgumentsHost`:

```typescript

export interface WsArgumentsHost {
  /**
   * Returns the data object.
   */
  getData<T>(): T;
  /**
   * Returns the client object.
   */
  getClient<T>(): T;
}
```

And here are the methods of `RpcArgumentsHost`:

```typescript

export interface RpcArgumentsHost {
  /**
   * Returns the data object.
   */
  getData<T>(): T;

  /**
   * Returns the context object.
   */
  getContext<T>(): T;
}
```

#### ExecutionContext class[#](/fundamentals/execution-context#executioncontext-class)

`ExecutionContext` extends `ArgumentsHost`, providing additional details about the current execution process. Like `ArgumentsHost`, Nest provides an instance of `ExecutionContext` in places where you may need it, such as the `canActivate()` method of a [guard](/guards#execution-context) and the `intercept()` method of an [interceptor](/interceptors#execution-context). It provides the following methods:

```typescript

export interface ExecutionContext extends ArgumentsHost {
  /**
   * Returns the type of the controller class which the current handler belongs to.
   */
  getClass<T>(): Type<T>;
  /**
   * Returns a reference to the handler (method) that will be invoked next in the
   * request pipeline.
   */
  getHandler(): Function;
}
```

The `getHandler()` method returns a reference to the handler about to be invoked. The `getClass()` method returns the type of the controller class that this handler belongs to. For example, in an HTTP context, if the currently processed request is a `POST` request bound to the `create()` method on `CatsController`, `getHandler()` returns a reference to the `create()` method, and `getClass()` returns the `CatsController`**class** (not an instance).

```typescript

const methodKey = ctx.getHandler().name; // "create"
const className = ctx.getClass().name; // "CatsController"
```

Access to both the current class and the handler method provides great flexibility. Most importantly, it lets you read, from within guards or interceptors, the metadata set by decorators created with `Reflector#createDecorator` or by the built-in `@SetMetadata()` decorator. The following sections cover this use case.

Nest lets you attach **custom metadata** to route handlers through decorators created with the `Reflector#createDecorator` method, or with the built-in `@SetMetadata()` decorator. This section compares the two approaches and shows how to access the metadata from within a guard or interceptor.

To create strongly typed decorators with `Reflector#createDecorator`, specify the type argument. For example, let's create a `Roles` decorator that takes an array of strings as an argument.

roles.decorator.ts

JS TS

```ts

import { Reflector } from '@nestjs/core';

export const Roles = Reflector.createDecorator<string[]>();
```

The `Roles` decorator here is a function that takes a single argument of type `string[]`.

To use this decorator, annotate the handler with it:

cats.controller.ts

JS TS

```typescript

@Post()
@Roles(['admin'])
async create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

```typescript

@Post()
@Roles(['admin'])
@Bind(Body())
async create(createCatDto) {
  this.catsService.create(createCatDto);
}
```

This attaches the `Roles` decorator metadata to the `create()` method, indicating that only users with the `admin` role should be allowed to access this route.

To access the route's role(s) (custom metadata), use the `Reflector` helper class again. `Reflector` can be injected into a class in the normal way:

roles.guard.ts

JS TS

```typescript

@Injectable()
export class RolesGuard {
  constructor(private reflector: Reflector) {}
}
```

```typescript

@Injectable()
@Dependencies(Reflector)
export class RolesGuard {
  constructor(reflector) {
    this.reflector = reflector;
  }
}
```

> **Hint** The `Reflector` class is imported from the `@nestjs/core` package.

Now, to read the handler metadata, use the `get()` method:

```typescript

const roles = this.reflector.get(Roles, context.getHandler());
```

The `Reflector#get` method takes two arguments: a decorator reference and a **context** (decorator target) to retrieve the metadata from. In this example, the specified **decorator** is `Roles` (see the `roles.decorator.ts` file above). The context is provided by the call to `context.getHandler()`, which extracts the metadata for the currently processed route handler. Remember, `getHandler()` gives you a **reference** to the route handler function.

Alternatively, you can apply metadata at the controller level, so that it applies to all routes in the controller class.

cats.controller.ts

JS TS

```typescript

@Roles(['admin'])
@Controller('cats')
export class CatsController {}
```

```typescript

@Roles(['admin'])
@Controller('cats')
export class CatsController {}
```

In this case, to extract controller metadata, pass `context.getClass()` as the second argument (to provide the controller class as the context for metadata extraction) instead of `context.getHandler()`:

roles.guard.ts

JS TS

```typescript

const roles = this.reflector.get(Roles, context.getClass());
```

Because metadata can be provided at multiple levels, you may need to extract and merge metadata from several contexts. The `Reflector` class provides two utility methods for this. They extract **both** controller and method metadata at once, and combine them in different ways.

Consider the following scenario, where you've supplied `Roles` metadata at both levels.

cats.controller.ts

JS TS

```typescript

@Roles(['user'])
@Controller('cats')
export class CatsController {
  @Post()
  @Roles(['admin'])
  async create(@Body() createCatDto: CreateCatDto) {
    this.catsService.create(createCatDto);
  }
}
```

```typescript

@Roles(['user'])
@Controller('cats')
export class CatsController {
  @Post()
  @Roles(['admin'])
  @Bind(Body())
  async create(createCatDto) {
    this.catsService.create(createCatDto);
  }
}
```

If your intent is to specify `'user'` as the default role and override it selectively for certain methods, use the `getAllAndOverride()` method. It returns the first defined value, checking the targets in the order you pass them:

```typescript

const roles = this.reflector.getAllAndOverride(Roles, [context.getHandler(), context.getClass()]);
```

A guard with this code, running in the context of the `create()` method with the metadata above, results in `roles` containing `['admin']`.

To get the metadata from both levels and merge it (this method merges both arrays and objects), use the `getAllAndMerge()` method:

```typescript

const roles = this.reflector.getAllAndMerge(Roles, [context.getHandler(), context.getClass()]);
```

This results in `roles` containing `['admin', 'user']` (values are concatenated in the order of the targets).

For both of these methods, you pass the decorator reference (or metadata key) as the first argument, and an array of metadata target contexts (i.e., calls to the `getHandler()` and/or `getClass()` methods) as the second argument.

#### Low-level approach[#](/fundamentals/execution-context#low-level-approach)

As mentioned earlier, instead of using `Reflector#createDecorator`, you can use the built-in `@SetMetadata()` decorator to attach metadata to a handler.

cats.controller.ts

JS TS

```typescript

@Post()
@SetMetadata('roles', ['admin'])
async create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

```typescript

@Post()
@SetMetadata('roles', ['admin'])
@Bind(Body())
async create(createCatDto) {
  this.catsService.create(createCatDto);
}
```

> **Hint** The `@SetMetadata()` decorator is imported from the `@nestjs/common` package.

The construction above attaches the `roles` metadata (`roles` is the metadata key and `['admin']` is the associated value) to the `create()` method. While this works, it's not good practice to use `@SetMetadata()` directly in your routes. Instead, create your own decorators, as shown below:

roles.decorator.ts

JS TS

```typescript

import { SetMetadata } from '@nestjs/common';

export const Roles = (...roles: string[]) => SetMetadata('roles', roles);
```

```typescript

import { SetMetadata } from '@nestjs/common';

export const Roles = (...roles) => SetMetadata('roles', roles);
```

This approach is cleaner and more readable, and resembles the `Reflector#createDecorator` approach. The difference is that with `@SetMetadata()` you have more control over the metadata key and value, and you can create decorators that take more than one argument.

With the custom `@Roles()` decorator in place, you can use it to decorate the `create()` method.

cats.controller.ts

JS TS

```typescript

@Post()
@Roles('admin')
async create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

```typescript

@Post()
@Roles('admin')
@Bind(Body())
async create(createCatDto) {
  this.catsService.create(createCatDto);
}
```

To access the route's role(s) (custom metadata), use the `Reflector` helper class again:

roles.guard.ts

JS TS

```typescript

@Injectable()
export class RolesGuard {
  constructor(private reflector: Reflector) {}
}
```

```typescript

@Injectable()
@Dependencies(Reflector)
export class RolesGuard {
  constructor(reflector) {
    this.reflector = reflector;
  }
}
```

> **Hint** The `Reflector` class is imported from the `@nestjs/core` package.

Now, to read the handler metadata, use the `get()` method.

```typescript

const roles = this.reflector.get<string[]>('roles', context.getHandler());
```

Here, instead of a decorator reference, you pass the metadata **key** (in this case, `'roles'`) as the first argument. Everything else remains the same as in the `Reflector#createDecorator` example.

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/fundamentals/execution-context.md)

----
url: https://docs.nestjs.com/v11/openapi/other-features
----

* [Other features](https://docs.nestjs.com/v11/openapi/other-features#other-features)
* [Global prefix](https://docs.nestjs.com/v11/openapi/other-features#global-prefix)
* [Global parameters](https://docs.nestjs.com/v11/openapi/other-features#global-parameters)
* [Global responses](https://docs.nestjs.com/v11/openapi/other-features#global-responses)
* [Multiple specifications](https://docs.nestjs.com/v11/openapi/other-features#multiple-specifications)
* [Dropdown in the explorer bar](https://docs.nestjs.com/v11/openapi/other-features#dropdown-in-the-explorer-bar)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/openapi/other-features.md "Suggest Edits")

### Other features

This page lists all the other available features that you may find useful.

#### Global prefix[#](/openapi/other-features#global-prefix)

To ignore a global prefix for routes set through `setGlobalPrefix()`, use `ignoreGlobalPrefix`:

```typescript

const document = SwaggerModule.createDocument(app, options, {
  ignoreGlobalPrefix: true,
});
```

#### Global parameters[#](/openapi/other-features#global-parameters)

You can define parameters for all routes using `DocumentBuilder`, as shown below:

```typescript

const config = new DocumentBuilder()
  .addGlobalParameters({
    name: 'tenantId',
    in: 'header',
  })
  // other configurations
  .build();
```

#### Global responses[#](/openapi/other-features#global-responses)

You can define global responses for all routes using `DocumentBuilder`. This is useful for setting up consistent responses across all endpoints in your application, such as error codes like `401 Unauthorized` or `500 Internal Server Error`.

```typescript

const config = new DocumentBuilder()
  .addGlobalResponse({
    status: 500,
    description: 'Internal server error',
  })
  // other configurations
  .build();
```

#### Multiple specifications[#](/openapi/other-features#multiple-specifications)

The `SwaggerModule` provides a way to support multiple specifications. In other words, you can serve different documentation, with different UIs, on different endpoints.

To support multiple specifications, your application must be written with a modular approach. The `createDocument()` method takes a 3rd argument, `extraOptions`, which is an object with a property named `include`. The `include` property takes a value which is an array of modules.

You can setup multiple specifications support as shown below:

```typescript

import { NestFactory } from '@nestjs/core';
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
import { AppModule } from './app.module';
import { CatsModule } from './cats/cats.module';
import { DogsModule } from './dogs/dogs.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);

  /**
   * createDocument(application, configurationOptions, extraOptions);
   *
   * createDocument method takes an optional 3rd argument "extraOptions"
   * which is an object with "include" property where you can pass an Array
   * of Modules that you want to include in that Swagger Specification
   * E.g: CatsModule and DogsModule will have two separate Swagger Specifications which
   * will be exposed on two different SwaggerUI with two different endpoints.
   */

  const options = new DocumentBuilder()
    .setTitle('Cats example')
    .setDescription('The cats API description')
    .setVersion('1.0')
    .addTag('cats')
    .build();

  const catDocumentFactory = () =>
    SwaggerModule.createDocument(app, options, {
      include: [CatsModule],
    });
  SwaggerModule.setup('api/cats', app, catDocumentFactory);

  const secondOptions = new DocumentBuilder()
    .setTitle('Dogs example')
    .setDescription('The dogs API description')
    .setVersion('1.0')
    .addTag('dogs')
    .build();

  const dogDocumentFactory = () =>
    SwaggerModule.createDocument(app, secondOptions, {
      include: [DogsModule],
    });
  SwaggerModule.setup('api/dogs', app, dogDocumentFactory);

  await app.listen(process.env.PORT ?? 3000);
}
bootstrap();
```

Now you can start your server with the following command:

```bash

$ npm run start
```

Navigate to `http://localhost:3000/api/cats` to see the Swagger UI for cats:

In turn, `http://localhost:3000/api/dogs` will expose the Swagger UI for dogs:

#### Dropdown in the explorer bar[#](/openapi/other-features#dropdown-in-the-explorer-bar)

To enable support for multiple specifications in the dropdown menu of the explorer bar, you'll need to set `explorer: true` and configure `swaggerOptions.urls` in your `SwaggerCustomOptions`.

> **Hint** Ensure that `swaggerOptions.urls` points to the JSON format of your Swagger documents! To specify the JSON document, use `jsonDocumentUrl` within `SwaggerCustomOptions`. For more setup options, check [here](/openapi/introduction#setup-options).

Here’s how to set up multiple specifications from a dropdown in the explorer bar:

```typescript

import { NestFactory } from '@nestjs/core';
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
import { AppModule } from './app.module';
import { CatsModule } from './cats/cats.module';
import { DogsModule } from './dogs/dogs.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);

  // Main API options
  const options = new DocumentBuilder()
    .setTitle('Multiple Specifications Example')
    .setDescription('Description for multiple specifications')
    .setVersion('1.0')
    .build();

  // Create main API document
  const document = SwaggerModule.createDocument(app, options);

  // Setup main API Swagger UI with dropdown support
  SwaggerModule.setup('api', app, document, {
    explorer: true,
    swaggerOptions: {
      urls: [
        {
          name: '1. API',
          url: 'api/swagger.json',
        },
        {
          name: '2. Cats API',
          url: 'api/cats/swagger.json',
        },
        {
          name: '3. Dogs API',
          url: 'api/dogs/swagger.json',
        },
      ],
    },
    jsonDocumentUrl: '/api/swagger.json',
  });

  // Cats API options
  const catOptions = new DocumentBuilder()
    .setTitle('Cats Example')
    .setDescription('Description for the Cats API')
    .setVersion('1.0')
    .addTag('cats')
    .build();

  // Create Cats API document
  const catDocument = SwaggerModule.createDocument(app, catOptions, {
    include: [CatsModule],
  });

  // Setup Cats API Swagger UI
  SwaggerModule.setup('api/cats', app, catDocument, {
    jsonDocumentUrl: '/api/cats/swagger.json',
  });

  // Dogs API options
  const dogOptions = new DocumentBuilder()
    .setTitle('Dogs Example')
    .setDescription('Description for the Dogs API')
    .setVersion('1.0')
    .addTag('dogs')
    .build();

  // Create Dogs API document
  const dogDocument = SwaggerModule.createDocument(app, dogOptions, {
    include: [DogsModule],
  });

  // Setup Dogs API Swagger UI
  SwaggerModule.setup('api/dogs', app, dogDocument, {
    jsonDocumentUrl: '/api/dogs/swagger.json',
  });

  await app.listen(3000);
}

bootstrap();
```

In this example, we set up a main API along with separate specifications for Cats and Dogs, each accessible from the dropdown in the explorer bar.

----
url: https://docs.nestjs.com/v10/microservices/exception-filters
----

* [Exception filters](https://docs.nestjs.com/v10/microservices/exception-filters#exception-filters)
* [Filters](https://docs.nestjs.com/v10/microservices/exception-filters#filters)
* [Inheritance](https://docs.nestjs.com/v10/microservices/exception-filters#inheritance)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/microservices/exception-filters.md "Suggest Edits")

### Exception filters

The only difference between the HTTP [exception filter](/v10/exception-filters) layer and the corresponding microservices layer is that instead of throwing `HttpException`, you should use `RpcException`.

```typescript

throw new RpcException('Invalid credentials.');
```

> **Hint** The `RpcException` class is imported from the `@nestjs/microservices` package.

With the sample above, Nest will handle the thrown exception and return the `error` object with the following structure:

```json

{
  "status": "error",
  "message": "Invalid credentials."
}
```

#### Filters[#](/microservices/exception-filters#filters)

Microservice exception filters behave similarly to HTTP exception filters, with one small difference. The `catch()` method must return an `Observable`.

rpc-exception.filter.ts

JS TS

```typescript

import { Catch, RpcExceptionFilter, ArgumentsHost } from '@nestjs/common';
import { Observable, throwError } from 'rxjs';
import { RpcException } from '@nestjs/microservices';

@Catch(RpcException)
export class ExceptionFilter implements RpcExceptionFilter<RpcException> {
  catch(exception: RpcException, host: ArgumentsHost): Observable<any> {
    return throwError(() => exception.getError());
  }
}
```

```typescript

import { Catch } from '@nestjs/common';
import { throwError } from 'rxjs';

@Catch(RpcException)
export class ExceptionFilter {
  catch(exception, host) {
    return throwError(() => exception.getError());
  }
}
```

> **Warning** Global microservice exception filters aren't enabled by default when using a [hybrid application](/v10/faq/hybrid-application).

The following example uses a manually instantiated method-scoped filter. Just as with HTTP based applications, you can also use controller-scoped filters (i.e., prefix the controller class with a `@UseFilters()` decorator).

JS TS

```typescript

@UseFilters(new ExceptionFilter())
@MessagePattern({ cmd: 'sum' })
accumulate(data: number[]): number {
  return (data || []).reduce((a, b) => a + b);
}
```

```typescript

@UseFilters(new ExceptionFilter())
@MessagePattern({ cmd: 'sum' })
accumulate(data) {
  return (data || []).reduce((a, b) => a + b);
}
```

#### Inheritance[#](/microservices/exception-filters#inheritance)

Typically, you'll create fully customized exception filters crafted to fulfill your application requirements. However, there might be use-cases when you would like to simply extend the **core exception filter**, and override the behavior based on certain factors.

In order to delegate exception processing to the base filter, you need to extend `BaseExceptionFilter` and call the inherited `catch()` method.

JS TS

```typescript

import { Catch, ArgumentsHost } from '@nestjs/common';
import { BaseRpcExceptionFilter } from '@nestjs/microservices';

@Catch()
export class AllExceptionsFilter extends BaseRpcExceptionFilter {
  catch(exception: any, host: ArgumentsHost) {
    return super.catch(exception, host);
  }
}
```

```typescript

import { Catch } from '@nestjs/common';
import { BaseRpcExceptionFilter } from '@nestjs/microservices';

@Catch()
export class AllExceptionsFilter extends BaseRpcExceptionFilter {
  catch(exception, host) {
    return super.catch(exception, host);
  }
}
```

----
url: https://docs.nestjs.com/v9/interceptors
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Interceptors](https://docs.nestjs.com/v9/interceptors#interceptors)
* [Basics](https://docs.nestjs.com/v9/interceptors#basics)
* [Execution context](https://docs.nestjs.com/v9/interceptors#execution-context)
* [Call handler](https://docs.nestjs.com/v9/interceptors#call-handler)
* [Aspect interception](https://docs.nestjs.com/v9/interceptors#aspect-interception)
* [Binding interceptors](https://docs.nestjs.com/v9/interceptors#binding-interceptors)
* [Response mapping](https://docs.nestjs.com/v9/interceptors#response-mapping)
* [Exception mapping](https://docs.nestjs.com/v9/interceptors#exception-mapping)
* [Stream overriding](https://docs.nestjs.com/v9/interceptors#stream-overriding)
* [More operators](https://docs.nestjs.com/v9/interceptors#more-operators)

Each interceptor implements the `intercept()` method, which takes two arguments. The first one is the `ExecutionContext` instance (exactly the same object as for [guards](/v9/guards)). The `ExecutionContext` inherits from `ArgumentsHost`. We saw `ArgumentsHost` before in the exception filters chapter. There, we saw that it's a wrapper around arguments that have been passed to the original handler, and contains different arguments arrays based on the type of the application. You can refer back to the [exception filters](https://docs.nestjs.com/exception-filters#arguments-host) for more on this topic.

#### Execution context[#](/interceptors#execution-context)

By extending `ArgumentsHost`, `ExecutionContext` also adds several new helper methods that provide additional details about the current execution process. These details can be helpful in building more generic interceptors that can work across a broad set of controllers, methods, and execution contexts. Learn more about `ExecutionContext`[here](/v9/fundamentals/execution-context).

```typescript

import { Injectable, NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
import { Observable } from 'rxjs';
import { tap } from 'rxjs/operators';

@Injectable()
export class LoggingInterceptor implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    console.log('Before...');

    const now = Date.now();
    return next
      .handle()
      .pipe(
        tap(() => console.log(`After... ${Date.now() - now}ms`)),
      );
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';
import { Observable } from 'rxjs';
import { tap } from 'rxjs/operators';

@Injectable()
export class LoggingInterceptor {
  intercept(context, next) {
    console.log('Before...');

    const now = Date.now();
    return next
      .handle()
      .pipe(
        tap(() => console.log(`After... ${Date.now() - now}ms`)),
      );
  }
}
```

> **Hint** The `NestInterceptor<T, R>` is a generic interface in which `T` indicates the type of an `Observable<T>` (supporting the response stream), and `R` is the type of the value wrapped by `Observable<R>`.

> **Notice** Interceptors, like controllers, providers, guards, and so on, can **inject dependencies** through their `constructor`.

Since `handle()` returns an RxJS `Observable`, we have a wide choice of operators we can use to manipulate the stream. In the example above, we used the `tap()` operator, which invokes our anonymous logging function upon graceful or exceptional termination of the observable stream, but doesn't otherwise interfere with the response cycle.

#### Binding interceptors[#](/interceptors#binding-interceptors)

In order to set up the interceptor, we use the `@UseInterceptors()` decorator imported from the `@nestjs/common` package. Like [pipes](/v9/pipes) and [guards](/v9/guards), interceptors can be controller-scoped, method-scoped, or global-scoped.

cats.controller.ts

JS TS

```typescript

@UseInterceptors(LoggingInterceptor)
export class CatsController {}
```

> **Hint** The `@UseInterceptors()` decorator is imported from the `@nestjs/common` package.

Using the above construction, each route handler defined in `CatsController` will use `LoggingInterceptor`. When someone calls the `GET /cats` endpoint, you'll see the following output in your standard output:

```typescript

Before...
After... 1ms
```

Note that we passed the `LoggingInterceptor` type (instead of an instance), leaving responsibility for instantiation to the framework and enabling dependency injection. As with pipes, guards, and exception filters, we can also pass an in-place instance:

cats.controller.ts

JS TS

```typescript

@UseInterceptors(new LoggingInterceptor())
export class CatsController {}
```

As mentioned, the construction above attaches the interceptor to every handler declared by this controller. If we want to restrict the interceptor's scope to a single method, we simply apply the decorator at the **method level**.

In order to set up a global interceptor, we use the `useGlobalInterceptors()` method of the Nest application instance:

```typescript

const app = await NestFactory.create(AppModule);
app.useGlobalInterceptors(new LoggingInterceptor());
```

Global interceptors are used across the whole application, for every controller and every route handler. In terms of dependency injection, global interceptors registered from outside of any module (with `useGlobalInterceptors()`, as in the example above) cannot inject dependencies since this is done outside the context of any module. In order to solve this issue, you can set up an interceptor **directly from any module** using the following construction:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { APP_INTERCEPTOR } from '@nestjs/core';

@Module({
  providers: [
    {
      provide: APP_INTERCEPTOR,
      useClass: LoggingInterceptor,
    },
  ],
})
export class AppModule {}
```

> **Hint** When using this approach to perform dependency injection for the interceptor, note that regardless of the module where this construction is employed, the interceptor is, in fact, global. Where should this be done? Choose the module where the interceptor (`LoggingInterceptor` in the example above) is defined. Also, `useClass` is not the only way of dealing with custom provider registration. Learn more [here](/v9/fundamentals/custom-providers).

#### Response mapping[#](/interceptors#response-mapping)

We already know that `handle()` returns an `Observable`. The stream contains the value **returned** from the route handler, and thus we can easily mutate it using RxJS's `map()` operator.

> **Warning** The response mapping feature doesn't work with the library-specific response strategy (using the `@Res()` object directly is forbidden).

Let's create the `TransformInterceptor`, which will modify each response in a trivial way to demonstrate the process. It will use RxJS's `map()` operator to assign the response object to the `data` property of a newly created object, returning the new object to the client.

transform.interceptor.ts

JS TS

```typescript

import { Injectable, NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';

export interface Response<T> {
  data: T;
}

@Injectable()
export class TransformInterceptor<T> implements NestInterceptor<T, Response<T>> {
  intercept(context: ExecutionContext, next: CallHandler): Observable<Response<T>> {
    return next.handle().pipe(map(data => ({ data })));
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';
import { map } from 'rxjs/operators';

@Injectable()
export class TransformInterceptor {
  intercept(context, next) {
    return next.handle().pipe(map(data => ({ data })));
  }
}
```

> **Hint** Nest interceptors work with both synchronous and asynchronous `intercept()` methods. You can simply switch the method to `async` if necessary.

With the above construction, when someone calls the `GET /cats` endpoint, the response would look like the following (assuming that route handler returns an empty array `[]`):

```json

{
  "data": []
}
```

Interceptors have great value in creating re-usable solutions to requirements that occur across an entire application. For example, imagine we need to transform each occurrence of a `null` value to an empty string `''`. We can do it using one line of code and bind the interceptor globally so that it will automatically be used by each registered handler.

JS TS

```typescript

import { Injectable, NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';

@Injectable()
export class ExcludeNullInterceptor implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    return next
      .handle()
      .pipe(map(value => value === null ? '' : value ));
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';
import { map } from 'rxjs/operators';

@Injectable()
export class ExcludeNullInterceptor {
  intercept(context, next) {
    return next
      .handle()
      .pipe(map(value => value === null ? '' : value ));
  }
}
```

#### Exception mapping[#](/interceptors#exception-mapping)

Another interesting use-case is to take advantage of RxJS's `catchError()` operator to override thrown exceptions:

errors.interceptor.ts

JS TS

```typescript

import {
  Injectable,
  NestInterceptor,
  ExecutionContext,
  BadGatewayException,
  CallHandler,
} from '@nestjs/common';
import { Observable, throwError } from 'rxjs';
import { catchError } from 'rxjs/operators';

@Injectable()
export class ErrorsInterceptor implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    return next
      .handle()
      .pipe(
        catchError(err => throwError(() => new BadGatewayException())),
      );
  }
}
```

```typescript

import { Injectable, BadGatewayException } from '@nestjs/common';
import { throwError } from 'rxjs';
import { catchError } from 'rxjs/operators';

@Injectable()
export class ErrorsInterceptor {
  intercept(context, next) {
    return next
      .handle()
      .pipe(
        catchError(err => throwError(() => new BadGatewayException())),
      );
  }
}
```

#### Stream overriding[#](/interceptors#stream-overriding)

There are several reasons why we may sometimes want to completely prevent calling the handler and return a different value instead. An obvious example is to implement a cache to improve response time. Let's take a look at a simple **cache interceptor** that returns its response from a cache. In a realistic example, we'd want to consider other factors like TTL, cache invalidation, cache size, etc., but that's beyond the scope of this discussion. Here we'll provide a basic example that demonstrates the main concept.

cache.interceptor.ts

JS TS

```typescript

import { Injectable, NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
import { Observable, of } from 'rxjs';

@Injectable()
export class CacheInterceptor implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    const isCached = true;
    if (isCached) {
      return of([]);
    }
    return next.handle();
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';
import { of } from 'rxjs';

@Injectable()
export class CacheInterceptor {
  intercept(context, next) {
    const isCached = true;
    if (isCached) {
      return of([]);
    }
    return next.handle();
  }
}
```

Our `CacheInterceptor` has a hardcoded `isCached` variable and a hardcoded response `[]` as well. The key point to note is that we return a new stream here, created by the RxJS `of()` operator, therefore the route handler **won't be called** at all. When someone calls an endpoint that makes use of `CacheInterceptor`, the response (a hardcoded, empty array) will be returned immediately. In order to create a generic solution, you can take advantage of `Reflector` and create a custom decorator. The `Reflector` is well described in the [guards](/v9/guards) chapter.

#### More operators[#](/interceptors#more-operators)

The possibility of manipulating the stream using RxJS operators gives us many capabilities. Let's consider another common use case. Imagine you would like to handle **timeouts** on route requests. When your endpoint doesn't return anything after a period of time, you want to terminate with an error response. The following construction enables this:

timeout.interceptor.ts

JS TS

```typescript

import { Injectable, NestInterceptor, ExecutionContext, CallHandler, RequestTimeoutException } from '@nestjs/common';
import { Observable, throwError, TimeoutError } from 'rxjs';
import { catchError, timeout } from 'rxjs/operators';

@Injectable()
export class TimeoutInterceptor implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    return next.handle().pipe(
      timeout(5000),
      catchError(err => {
        if (err instanceof TimeoutError) {
          return throwError(() => new RequestTimeoutException());
        }
        return throwError(() => err);
      }),
    );
  };
};
```

```typescript

import { Injectable, RequestTimeoutException } from '@nestjs/common';
import { Observable, throwError, TimeoutError } from 'rxjs';
import { catchError, timeout } from 'rxjs/operators';

@Injectable()
export class TimeoutInterceptor {
  intercept(context, next) {
    return next.handle().pipe(
      timeout(5000),
      catchError(err => {
        if (err instanceof TimeoutError) {
          return throwError(() => new RequestTimeoutException());
        }
        return throwError(() => err);
      }),
    );
  };
};
```

After 5 seconds, request processing will be canceled. You can also add custom logic before throwing `RequestTimeoutException` (e.g. release resources).

----
url: https://docs.nestjs.com/v9/graphql/generating-sdl
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Generating SDL](https://docs.nestjs.com/v9/graphql/generating-sdl#generating-sdl)
* [Usage](https://docs.nestjs.com/v9/graphql/generating-sdl#usage)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/schema-generator.md "Suggest Edits")

### Generating SDL

> **Warning** This chapter applies only to the code first approach.

To manually generate a GraphQL SDL schema (i.e., without running an application, connecting to the database, hooking up resolvers, etc.), use the `GraphQLSchemaBuilderModule`.

```typescript

async function generateSchema() {
  const app = await NestFactory.create(GraphQLSchemaBuilderModule);
  await app.init();

  const gqlSchemaFactory = app.get(GraphQLSchemaFactory);
  const schema = await gqlSchemaFactory.create([RecipesResolver]);
  console.log(printSchema(schema));
}
```

> **Hint** The `GraphQLSchemaBuilderModule` and `GraphQLSchemaFactory` are imported from the `@nestjs/graphql` package. The `printSchema` function is imported from the `graphql` package.

#### Usage[#](/graphql/generating-sdl#usage)

The `gqlSchemaFactory.create()` method takes an array of resolver class references. For example:

```typescript

const schema = await gqlSchemaFactory.create([
  RecipesResolver,
  AuthorsResolver,
  PostsResolvers,
]);
```

It also takes a second optional argument with an array of scalar classes:

```typescript

const schema = await gqlSchemaFactory.create(
  [RecipesResolver, AuthorsResolver, PostsResolvers],
  [DurationScalar, DateScalar],
);
```

Lastly, you can pass an options object:

```typescript

const schema = await gqlSchemaFactory.create([RecipesResolver], {
  skipCheck: true,
  orphanedTypes: [],
});
```

* `skipCheck`: ignore schema validation; boolean, defaults to `false`
* `orphanedTypes`: list of classes that are not explicitly referenced (not part of the object graph) to be generated. Normally, if a class is declared but isn't otherwise referenced in the graph, it's omitted. The property value is an array of class references.

----
url: https://docs.nestjs.com/v6/first-steps
----

* [First steps](https://docs.nestjs.com/v6/first-steps#first-steps)
* [Language](https://docs.nestjs.com/v6/first-steps#language)
* [Prerequisites](https://docs.nestjs.com/v6/first-steps#prerequisites)
* [Setup](https://docs.nestjs.com/v6/first-steps#setup)
* [Platform](https://docs.nestjs.com/v6/first-steps#platform)
* [Running the application](https://docs.nestjs.com/v6/first-steps#running-the-application)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/first-steps.md "Suggest Edits")

### First steps

In this set of articles, you'll learn the **core fundamentals** of Nest. To get familiar with the essential building blocks of Nest applications, we'll build a basic CRUD application with features that cover a lot of ground at an introductory level.

#### Language[#](/first-steps#language)

We're in love with [TypeScript](http://www.typescriptlang.org/), but above all - we love [Node.js](https://nodejs.org/en/). That's why Nest is compatible with both TypeScript and **pure JavaScript**. Nest takes advantage of the latest language features, so to use it with vanilla JavaScript we need a [Babel](http://babeljs.io/) compiler.

We'll mostly use TypeScript in the examples we provide, but you can always **switch the code snippets** to vanilla JavaScript syntax (simply click to toggle the language button in the upper right hand corner of each snippet).

#### Prerequisites[#](/first-steps#prerequisites)

Please make sure that [Node.js](https://nodejs.org/) (>= 8.9.0) is installed on your operating system.

#### Setup[#](/first-steps#setup)

Setting up a new project is quite simple with the [Nest CLI](/v6/cli/overview). With [npm](https://www.npmjs.com/) installed, you can create a new Nest project with the following commands in your OS terminal:

```bash

$ npm i -g @nestjs/cli
$ nest new project-name
```

The `project` directory will be created, node modules and a few other boilerplate files will be installed, and a `src/` directory will be created and populated with several core files.

src

app.controller.ts

app.module.ts

main.ts

Here's a brief overview of those core files:

| `app.controller.ts` | Basic controller sample with a single route.                                                                        |
| ------------------- | ------------------------------------------------------------------------------------------------------------------- |
| `app.module.ts`     | The root module of the application.                                                                                 |
| `main.ts`           | The entry file of the application which uses the core function `NestFactory` to create a Nest application instance. |

The `main.ts` includes an async function, which will **bootstrap** our application:

main.ts

JS TS

```typescript

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  await app.listen(3000);
}
bootstrap();
```

```typescript

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  await app.listen(3000);
}
bootstrap();
```

To create a Nest application instance, we use the core `NestFactory` class. `NestFactory` exposes a few static methods that allow creating an application instance. The `create()` method returns an application object, which fulfills the `INestApplication` interface. This object provides a set of methods which are described in the coming chapters. In the `main.ts` example above, we simply start up our HTTP listener, which lets the application await inbound HTTP requests.

Note that a project scaffolded with the Nest CLI creates an initial project structure that encourages developers to follow the convention of keeping each module in its own dedicated directory.

## Learn the right way!

* 60+ chapters
* 4+ hours of videos
* Official certificate
* Deep-dive sessions

[Explore official courses](https://courses.nestjs.com "Courses | NestJS - A node.js framework built on top of TypeScript")

#### Platform[#](/first-steps#platform)

Nest aims to be a platform-agnostic framework. Platform independence makes it possible to create reusable logical parts that developers can take advantage of across several different types of applications. Technically, Nest is able to work with any Node HTTP framework once an adapter is created. There are two HTTP platforms supported out-of-the-box: [express](https://expressjs.com/) and [fastify](https://www.fastify.io). You can choose the one that best suits your needs.

| `platform-express` | [Express](https://expressjs.com/) is a well-known minimalist web framework for node. It's a battle tested, production-ready library with lots of resources implemented by the community. The `@nestjs/platform-express` package is used by default. Many users are well served with Express, and need take no action to enable it. |
| ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `platform-fastify` | [Fastify](https://www.fastify.io/) is a high performance and low overhead framework highly focused on providing maximum efficiency and speed. Read how to use it [here](/v6/techniques/performance).                                                                                                                               |

Whichever platform is used, it exposes its own application interface. These are seen respectively as `NestExpressApplication` and `NestFastifyApplication`.

When you pass a type to the `NestFactory.create()` method, as in the example below, the `app` object will have methods available exclusively for that specific platform. Note, however, you don't **need** to specify a type **unless** you actually want to access the underlying platform API.

```typescript

const app = await NestFactory.create<NestExpressApplication>(AppModule);
```

#### Running the application[#](/first-steps#running-the-application)

Once the installation process is complete, you can run the following command at your OS command prompt to start the application listening for inbound HTTP requests:

```bash

$ npm run start
```

This command starts the app with the HTTP server listening on the port defined in the `src/main.ts` file. Once the application is running, open your browser and navigate to `http://localhost:3000/`. You should see the `Hello World!` message.

----
url: https://docs.nestjs.com/graphql/unions-and-enums
----

[Skip to content](#content)

On this page

* [Unions](https://docs.nestjs.com/graphql/unions-and-enums#unions)
* [Code first](https://docs.nestjs.com/graphql/unions-and-enums#code-first)
* [Schema first](https://docs.nestjs.com/graphql/unions-and-enums#schema-first)
* [Enums](https://docs.nestjs.com/graphql/unions-and-enums#enums)
* [Code first](https://docs.nestjs.com/graphql/unions-and-enums#code-first-1)
* [Schema first](https://docs.nestjs.com/graphql/unions-and-enums#schema-first-1)

### Unions

Union types are similar to interfaces, but they don't specify any common fields between the types (see [union types](https://graphql.org/learn/schema/#union-types) in the GraphQL documentation). Unions are useful for returning disjoint data types from a single field.

#### Code first[#](/graphql/unions-and-enums#code-first)

To define a GraphQL union type, first define the classes that make up the union. Following the [union type example](https://www.apollographql.com/docs/apollo-server/schema/unions-interfaces/#union-type) from the Apollo documentation, we'll create two classes. First, `Book`:

```typescript

import { Field, ObjectType } from '@nestjs/graphql';

@ObjectType()
export class Book {
  @Field()
  title: string;
}
```

And then `Author`:

```typescript

import { Field, ObjectType } from '@nestjs/graphql';

@ObjectType()
export class Author {
  @Field()
  name: string;
}
```

With this in place, register the `ResultUnion` union using the `createUnionType` function exported from the `@nestjs/graphql` package:

```typescript

export const ResultUnion = createUnionType({
  name: 'ResultUnion',
  types: () => [Author, Book] as const,
});
```

> **Warning** Add a const assertion (`as const`) to the array returned by the `types` property of the `createUnionType` function. Without it, TypeScript generates an incorrect declaration file at compile time, and using the union from another project fails with an error.

Now you can reference `ResultUnion` in a query:

```typescript

@Query(() => [ResultUnion])
search(): Array<typeof ResultUnion> {
  return [new Author(), new Book()];
}
```

This generates the following part of the GraphQL schema in SDL:

```graphql

type Author {
  name: String!
}

type Book {
  title: String!
}

union ResultUnion = Author | Book

type Query {
  search: [ResultUnion!]!
}
```

The default `resolveType()` function generated by the library determines the type based on the value returned from the resolver method. This means that you must return class instances, not plain JavaScript object literals.

To provide a custom `resolveType()` function, pass the `resolveType` property in the options object of the `createUnionType()` function:

```typescript

export const ResultUnion = createUnionType({
  name: 'ResultUnion',
  types: () => [Author, Book] as const,
  resolveType(value) {
    if (value.name) {
      return Author;
    }
    if (value.title) {
      return Book;
    }
    return null;
  },
});
```

#### Schema first[#](/graphql/unions-and-enums#schema-first)

To define a union in the schema first approach, create a GraphQL union with SDL:

```graphql

type Author {
  name: String!
}

type Book {
  title: String!
}

union ResultUnion = Author | Book
```

Then, you can use the typings generation feature (as shown in the [GraphQL quick start](/graphql/quick-start) chapter) to generate the corresponding TypeScript definitions:

```typescript

export class Author {
  name: string;
}

export class Book {
  title: string;
}

export type ResultUnion = Author | Book;
```

Unions require an extra `__resolveType` field in the resolver map to determine which type the union resolves to. Create a `ResultUnionResolver` class and define the `__resolveType` method, which returns the name of the concrete type. Remember to register `ResultUnionResolver` as a provider in a module.

```typescript

@Resolver('ResultUnion')
export class ResultUnionResolver {
  @ResolveField()
  __resolveType(value) {
    if (value.name) {
      return 'Author';
    }
    if (value.title) {
      return 'Book';
    }
    return null;
  }
}
```

> **Hint** All decorators are exported from the `@nestjs/graphql` package.

### Enums

Enumeration types are a special kind of scalar restricted to a particular set of allowed values (see [enumeration types](https://graphql.org/learn/schema/#enumeration-types) in the GraphQL documentation). They allow you to:

* validate that any arguments of this type are one of the allowed values
* communicate through the type system that a field will always be one of a finite set of values

#### Code first[#](/graphql/unions-and-enums#code-first-1)

In the code first approach, you define a GraphQL enum type by creating a TypeScript enum:

```typescript

export enum AllowedColor {
  RED,
  GREEN,
  BLUE,
}
```

With this in place, register the `AllowedColor` enum using the `registerEnumType` function exported from the `@nestjs/graphql` package:

```typescript

registerEnumType(AllowedColor, {
  name: 'AllowedColor',
});
```

Now you can reference `AllowedColor` in your types:

```typescript

@Field(type => AllowedColor)
favoriteColor: AllowedColor;
```

This generates the following part of the GraphQL schema in SDL:

```graphql

enum AllowedColor {
  RED
  GREEN
  BLUE
}
```

To provide a description for the enum, pass the `description` property to the `registerEnumType()` function:

```typescript

registerEnumType(AllowedColor, {
  name: 'AllowedColor',
  description: 'The supported colors.',
});
```

To provide descriptions for the enum values, or to mark a value as deprecated, pass the `valuesMap` property:

```typescript

registerEnumType(AllowedColor, {
  name: 'AllowedColor',
  description: 'The supported colors.',
  valuesMap: {
    RED: {
      description: 'The default color.',
    },
    BLUE: {
      deprecationReason: 'Too blue.',
    },
  },
});
```

This generates the following GraphQL schema in SDL:

```graphql

"""
The supported colors.
"""
enum AllowedColor {
  """
  The default color.
  """
  RED
  GREEN
  BLUE @deprecated(reason: "Too blue.")
}
```

#### Schema first[#](/graphql/unions-and-enums#schema-first-1)

To define an enum in the schema first approach, create a GraphQL enum with SDL:

```graphql

enum AllowedColor {
  RED
  GREEN
  BLUE
}
```

Then you can use the typings generation feature (as shown in the [GraphQL quick start](/graphql/quick-start) chapter) to generate the corresponding TypeScript definitions:

```typescript

export enum AllowedColor {
  RED = "RED",
  GREEN = "GREEN",
  BLUE = "BLUE"
}
```

Sometimes a backend uses a different internal value for an enum than the one exposed in the public API. In this example, the API contains `RED`, but resolvers use `#f00` instead (see [internal values](https://www.apollographql.com/docs/apollo-server/schema/scalars-enums/#internal-values) in the Apollo documentation). To accomplish this, declare a resolver object for the `AllowedColor` enum:

```typescript

export const allowedColorResolver: Partial<Record<keyof typeof AllowedColor, any>> = {
  RED: '#f00',
};
```

> **Hint** All decorators are exported from the `@nestjs/graphql` package.

Then pass this resolver object in the `resolvers` property of the `GraphQLModule#forRoot()` method:

```typescript

GraphQLModule.forRoot({
  resolvers: {
    AllowedColor: allowedColorResolver,
  },
});
```

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/unions-and-enums.md)

----
url: https://docs.nestjs.com/v11/techniques/cookies
----

* [Cookies](https://docs.nestjs.com/v11/techniques/cookies#cookies)
* [Use with Express (default)](https://docs.nestjs.com/v11/techniques/cookies#use-with-express-default)
* [Use with Fastify](https://docs.nestjs.com/v11/techniques/cookies#use-with-fastify)
* [Creating a custom decorator (cross-platform)](https://docs.nestjs.com/v11/techniques/cookies#creating-a-custom-decorator-cross-platform)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/techniques/cookies.md "Suggest Edits")

### Cookies

An **HTTP cookie** is a small piece of data stored by the user's browser. Cookies were designed to be a reliable mechanism for websites to remember stateful information. When the user visits the website again, the cookie is automatically sent with the request.

#### Use with Express (default)[#](/techniques/cookies#use-with-express-default)

First install the [required package](https://github.com/expressjs/cookie-parser) (and its types for TypeScript users):

```shell

$ npm i cookie-parser
$ npm i -D @types/cookie-parser
```

Once the installation is complete, apply the `cookie-parser` middleware as global middleware (for example, in your `main.ts` file).

```typescript

import * as cookieParser from 'cookie-parser';
// somewhere in your initialization file
app.use(cookieParser());
```

You can pass several options to the `cookieParser` middleware:

* `secret` a string or array used for signing cookies. This is optional and if not specified, will not parse signed cookies. If a string is provided, this is used as the secret. If an array is provided, an attempt will be made to unsign the cookie with each secret in order.
* `options` an object that is passed to `cookie.parse` as the second option. See [cookie](https://www.npmjs.org/package/cookie) for more information.

The middleware will parse the `Cookie` header on the request and expose the cookie data as the property `req.cookies` and, if a secret was provided, as the property `req.signedCookies`. These properties are name value pairs of the cookie name to cookie value.

When a secret is provided, this module will unsign and validate any signed cookie values and move those name value pairs from `req.cookies` into `req.signedCookies`. A signed cookie is a cookie that has a value prefixed with `s:`. Signed cookies that fail signature validation will have the value `false` instead of the tampered value.

With this in place, you can now read cookies from within the route handlers, as follows:

```typescript

@Get()
findAll(@Req() request: Request) {
  console.log(request.cookies); // or "request.cookies['cookieKey']"
  // or console.log(request.signedCookies);
}
```

> **Hint** The `@Req()` decorator is imported from the `@nestjs/common`, while `Request` from the `express` package.

To attach a cookie to an outgoing response, use the `Response#cookie()` method:

```typescript

@Get()
findAll(@Res({ passthrough: true }) response: Response) {
  response.cookie('key', 'value')
}
```

> **Warning** If you want to leave the response handling logic to the framework, remember to set the `passthrough` option to `true`, as shown above. Read more [here](/controllers#library-specific-approach).

> **Hint** The `@Res()` decorator is imported from the `@nestjs/common`, while `Response` from the `express` package.

#### Use with Fastify[#](/techniques/cookies#use-with-fastify)

First install the required package:

```shell

$ npm i @fastify/cookie
```

Once the installation is complete, register the `@fastify/cookie` plugin:

```typescript

import fastifyCookie from '@fastify/cookie';

// somewhere in your initialization file
const app = await NestFactory.create<NestFastifyApplication>(AppModule, new FastifyAdapter());
await app.register(fastifyCookie, {
  secret: 'my-secret', // for cookies signature
});
```

With this in place, you can now read cookies from within the route handlers, as follows:

```typescript

@Get()
findAll(@Req() request: FastifyRequest) {
  console.log(request.cookies); // or "request.cookies['cookieKey']"
}
```

> **Hint** The `@Req()` decorator is imported from the `@nestjs/common`, while `FastifyRequest` from the `fastify` package.

To attach a cookie to an outgoing response, use the `FastifyReply#setCookie()` method:

```typescript

@Get()
findAll(@Res({ passthrough: true }) response: FastifyReply) {
  response.setCookie('key', 'value')
}
```

To read more about `FastifyReply#setCookie()` method, check out this [page](https://github.com/fastify/fastify-cookie#sending).

> **Warning** If you want to leave the response handling logic to the framework, remember to set the `passthrough` option to `true`, as shown above. Read more [here](/controllers#library-specific-approach).

> **Hint** The `@Res()` decorator is imported from the `@nestjs/common`, while `FastifyReply` from the `fastify` package.

#### Creating a custom decorator (cross-platform)[#](/techniques/cookies#creating-a-custom-decorator-cross-platform)

To provide a convenient, declarative way of accessing incoming cookies, we can create a [custom decorator](/v11/custom-decorators).

```typescript

import { createParamDecorator, ExecutionContext } from '@nestjs/common';

export const Cookies = createParamDecorator((data: string, ctx: ExecutionContext) => {
  const request = ctx.switchToHttp().getRequest();
  return data ? request.cookies?.[data] : request.cookies;
});
```

The `@Cookies()` decorator will extract all cookies, or a named cookie from the `req.cookies` object and populate the decorated parameter with that value.

With this in place, we can now use the decorator in a route handler signature, as follows:

```typescript

@Get()
findAll(@Cookies('name') name: string) {}
```

----
url: https://docs.nestjs.com/v5/pipes
----

### Pipes

A pipe is a class annotated with the `@Injectable()` decorator. The pipe should implement the `PipeTransform` interface.

A pipe **transforms** the input data to the desired output. Also, it could take care of the **validation**, since it's possible to throw an exception when the data is incorrect.

> **Hint** The pipe runs inside the exceptions zone. This means that when exceptions are thrown they are handled by the core exceptions handler and [exceptions filters](/v5/exception-filters) that are applied to the current context.

#### Built-in pipes

Nest comes with two pipes available right out-of-the-box, `ValidationPipe` and `ParseIntPipe`. They're exported from the `@nestjs/common` package. In order to better understand how do they work, we're gonna build them from scratch.

#### What does it look like?

Let's start with the `ValidationPipe`. In the beginning, it only takes a value and immediately returns the same value, behaving like an identity function.

validation.pipe.ts

JS TS

TypeScript

```typescript

import { PipeTransform, Injectable, ArgumentMetadata } from '@nestjs/common';

@Injectable()
export class ValidationPipe implements PipeTransform {
  transform(value: any, metadata: ArgumentMetadata) {
    return value;
  }
}
```

TypeScript

```typescript

import { Injectable } from '@nestjs/common';

@Injectable()
export class ValidationPipe {
  transform(value, metadata) {
    return value;
  }
}
```

> **Hint** The `PipeTransform<T, R>` is a generic interface in which `T` indicates a type of the input `value`, while `R` the return type of the `transform()` method.

Every pipe has to provide the `transform()` method. This method takes two arguments:

* `value`
* `metadata`

The `value` is the currently processed parameter, while `metadata` is its metadata. The metadata object holds a few properties:

TypeScript

```typescript

export interface ArgumentMetadata {
  readonly type: 'body' | 'query' | 'param' | 'custom';
  readonly metatype?: new (...args) => any;
  readonly data?: string;
}
```

These properties describe the input parameter.

|            |                                                                                                                                                                           |
| ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `type`     | Tells us whether the property is a body `@Body()`, query `@Query()`, param `@Param()`, or a custom parameter (read more [here](/v5/custom-decorators)).                   |
| `metatype` | The metatype of the property, for example, `String`. It's `undefined` either if you omit the type declaration in the function signature, or you use a vanilla JavaScript. |
| `data`     | The string passed to the decorator, for example `@Body('string')`. It's `undefined` if you leave the brackets empty.                                                      |

> **Warning** TypeScript interfaces disappear during the transpilation. Hence, if you use an interface instead of a class, the `metatype` value will be equal to `Object`.

#### What's the point?

Let's focus on the `create()` method of the `CatsController` for a while.

cats.controller.ts

TypeScript

```typescript

@Post()
async create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

There's a `CreateCatDto` body parameter:

create-cat.dto.ts

TypeScript

```typescript

export class CreateCatDto {
  readonly name: string;
  readonly age: number;
  readonly breed: string;
}
```

This object always has to be correct, and thus we have to validate these three members. We could do it inside the route handler method, but we'd break the **single responsibility rule** (SRP). The second idea is to create a **validator class** and delegate the task there, but we'll have to use this validator every time at the beginning of each method. So what about the validation middleware? It's a good idea, but it's impossible to create a **generic middleware** which could be used across the whole application.

That's the first use-case, when you should consider to use a **Pipe**.

#### Object schema validation

One of the frequently encountered approaches is to use a **schema-based** validation. The [Joi](https://github.com/hapijs/joi) library is a tool that allows you creating schemas in a pretty straightforward way with a readable API. In order to create a pipe that makes use of object schemas, we need to create a simple class that takes a schema as a `constructor` argument.

JS TS

TypeScript

```typescript

import * as Joi from 'joi';
import { PipeTransform, Injectable, ArgumentMetadata, BadRequestException } from '@nestjs/common';

@Injectable()
export class JoiValidationPipe implements PipeTransform {
  constructor(private readonly schema) {}

  transform(value: any, metadata: ArgumentMetadata) {
    const { error } = Joi.validate(value, this.schema);
    if (error) {
      throw new BadRequestException('Validation failed');
    }
    return value;
  }
}
```

TypeScript

```typescript

import * as Joi from 'joi';
import { Injectable, BadRequestException } from '@nestjs/common';

@Injectable()
export class JoiValidationPipe {
  constructor(schema) {
    this.schema = schema;
  }

  transform(value, metadata) {
    const { error } = Joi.validate(value, this.schema);
    if (error) {
      throw new BadRequestException('Validation failed');
    }
    return value;
  }
}
```

#### Binding pipes

The pipe tying is extremely simple - we need to use `@UsePipes()` decorator and create a pipe instance with the valid Joi schema.

JS TS

TypeScript

```typescript

@Post()
@UsePipes(new JoiValidationPipe(createCatSchema))
async create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

TypeScript

```typescript

@Post()
@Bind(Body())
@UsePipes(new JoiValidationPipe(createCatSchema))
async create(createCatDto) {
  this.catsService.create(createCatDto);
}
```

#### Class validator

##### This section applies only to TypeScript.

Nest works well with the [class-validator](https://github.com/pleerock/class-validator). This amazing library allows you to use decorator-based validation. Decorator based validation is really powerful with the **pipe** capabilities since we have access to the `metatype` of the processed property. However, before we start, we need to install required packages:

```bash

$ npm i --save class-validator class-transformer
```

Once the libraries are installed, we can add a few decorators to the `CreateCatDto` class.

create-cat.dto.ts

TypeScript

```typescript

import { IsString, IsInt } from 'class-validator';

export class CreateCatDto {
  @IsString()
  readonly name: string;

  @IsInt()
  readonly age: number;

  @IsString()
  readonly breed: string;
}
```

When it's done, we can create a `ValidationPipe` class.

validation.pipe.ts

TypeScript

```typescript

import { PipeTransform, Injectable, ArgumentMetadata, BadRequestException } from '@nestjs/common';
import { validate } from 'class-validator';
import { plainToClass } from 'class-transformer';

@Injectable()
export class ValidationPipe implements PipeTransform<any> {
  async transform(value, { metatype }: ArgumentMetadata) {
    if (!metatype || !this.toValidate(metatype)) {
      return value;
    }
    const object = plainToClass(metatype, value);
    const errors = await validate(object);
    if (errors.length > 0) {
      throw new BadRequestException('Validation failed');
    }
    return value;
  }

  private toValidate(metatype): boolean {
    const types = [String, Boolean, Number, Array, Object];
    return !types.find((type) => metatype === type);
  }
}
```

> **Notice** We have used the [class-transformer](https://github.com/pleerock/class-transformer) library. It's made by the same author as the **class-validator** library, and as a result, they play very well together.

Let's go through this code. Firstly, note that the `transform()` function is `async`. It's possible because Nest supports both synchronous and **asynchronous** pipes. Also, there's a helper function - `toValidate()`. It's responsible for excluding the native JavaScript types from the validation process due to performance reasons. The last worth mentioning part is that we have to return the same value. This pipe is a validation specific pipe, thus we need to return the exact same property to avoid **overriding** (as noted earlier, pipe transforms input to the desired output).

The last step is to set up the `ValidationPipe`. Pipes, same as [exception filters](/v5/exception-filters) can be method-scoped, controller-scoped, and global-scoped. Additionally, a pipe can be param-scoped. We can directly tie the pipe instance to the route param decorator, for example, to `@Body()` decorator. Let's have a look at the below example:

cats.controller.ts

TypeScript

```typescript

@Post()
async create(@Body(new ValidationPipe()) createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

The param-scoped pipes are useful when the validation logic concerns only one, specified parameter. In order to set up a pipe at a method level, you'll need the `UsePipes()` decorator.

cats.controller.ts

TypeScript

```typescript

@Post()
@UsePipes(new ValidationPipe())
async create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

> **Hint** The `@UsePipes()` decorator is imported from the `@nestjs/common` package.

The instance of `ValidationPipe` has been created immedietely in-place. Another available way is to pass the class (not instance), leaving framework the instantiation responsibility and enabling **dependency injection**.

cats.controller.ts

TypeScript

```typescript

@Post()
@UsePipes(ValidationPipe)
async create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

Since the `ValidationPipe` was created to be as generic as possible, we're gonna set it up as a **global-scoped** pipe, for every route handler across the entire application.

main.ts

JS TS

TypeScript

```typescript

async function bootstrap() {
  const app = await NestFactory.create(ApplicationModule);
  app.useGlobalPipes(new ValidationPipe());
  await app.listen(3000);
}
bootstrap();
```

> **Notice** The `useGlobalPipes()` method doesn't set up pipes for gateways and micro services.

The global pipes are used across the whole application, for every controller and every route handler. In terms of dependency injection, global pipes registered from the outside of any module (as in the previous example above) cannot inject dependencies since they don't belong to any module. In order to solve this issue, you can set up a pipe **directly from any module** using following construction:

app.module.ts

JS TS

TypeScript

```typescript

import { Module } from '@nestjs/common';
import { APP_PIPE } from '@nestjs/core';

@Module({
  providers: [
    {
      provide: APP_PIPE,
      useClass: CustomGlobalPipe,
    },
  ],
})
export class ApplicationModule {}
```

> **Hint** The alternative option is to use an [execution context](/v5/execution-context) feature. Also, `useClass` is not the only way of dealing with custom providers registration. Learn more [here](/v5/fundamentals/dependency-injection).

#### Transformer pipe

Validation isn't the sole use case. At the beginning of this chapter, we have mentioned that a pipe can also **transform** the input data to the desired output. It's true because the value returned from the `transform` function completely overrides the previous value of the argument. Sometimes the data passed from the client needs to undergo some changes. Also, some parts could be missed, therefore we must apply the default values. The **transformer pipes** fill the gap between the request of the client and the request handler.

parse-int.pipe.ts

JS TS

TypeScript

```typescript

import { PipeTransform, Injectable, ArgumentMetadata, HttpStatus, BadRequestException } from '@nestjs/common';

@Injectable()
export class ParseIntPipe implements PipeTransform<string, number> {
  transform(value: string, metadata: ArgumentMetadata): number {
    const val = parseInt(value, 10);
    if (isNaN(val)) {
      throw new BadRequestException('Validation failed');
    }
    return val;
  }
}
```

TypeScript

```typescript

import { Injectable, BadRequestException} from '@nestjs/common';

@Injectable()
export class ParseIntPipe {
  transform(value, metadata) {
    const val = parseInt(value, 10);
    if (isNaN(val)) {
      throw new BadRequestException('Validation failed');
    }
    return val;
  }
}
```

Here's a `ParseIntPipe` which is responsible for parsing a string into an integer value. We can simply tie a pipe to the selected param:

JS TS

TypeScript

```typescript

@Get(':id')
async findOne(@Param('id', new ParseIntPipe()) id) {
  return await this.catsService.findOne(id);
}
```

TypeScript

```typescript

@Get(':id')
@Bind(Param('id', new ParseIntPipe()))
async findOne(id) {
  return await this.catsService.findOne(id);
}
```

Thanks to the above construction, `ParseIntPipe` will be executed before request even touches the corresponding handler.

Another useful case would be to select an **existing user** entity from the database by id:

JS TS

TypeScript

```typescript

@Get(':id')
findOne(@Param('id', UserByIdPipe) userEntity: UserEntity) {
  return userEntity;
}
```

TypeScript

```typescript

@Get(':id')
@Bind(Param('id', UserByIdPipe))
findOne(userEntity) {
  return userEntity;
}
```

#### A built-in ValidationPipe

Fortunately, you don't have to build those pipes on your own since the `ValidationPipe` and the `ParseIntPipe` are built-in pipes (keep in mind that `ValidationPipe` requires both `class-validator` and `class-transformer` packages installed).

The built-in `ValidationPipe` offers more options than that one described in this chapter, which has been kept basic for the sake of simplicity and to reduce the learning curve. If you take a look at the `createCatDto` in your controller function, you will notice that it isn't an actual `CreateCatDto` instance. That is because this pipe only validates the payload, without transforming it into the expected type. However, if you want the pipe to mutate the payload, you can configure it by passing appropriate options:

cats.controller.ts

TypeScript

```typescript

@Post()
@UsePipes(new ValidationPipe({ transform: true }))
async create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

Because this pipe is based on the `class-validator` and the `class-transformer` libraries, it is possible to get more of it. Have a look at the constructor optional options.

TypeScript

```typescript

export interface ValidationPipeOptions extends ValidatorOptions {
  transform?: boolean;
}
```

There is a `transform` attribute and all `class-validator` options (inherited from the `ValidatorOptions` interface):

| Option                   | Type       | Description                                                                                                                       |
| ------------------------ | ---------- | --------------------------------------------------------------------------------------------------------------------------------- |
| `skipMissingProperties`  | `boolean`  | If set to true, validator will skip validation of all properties that are missing in the validating object.                       |
| `whitelist`              | `boolean`  | If set to true, validator will strip validated object of any properties that do not make use of any decorators.                   |
| `forbidNonWhitelisted`   | `boolean`  | If set to true, instead of stripping non-whitelisted properties validator will throw an exception.                                |
| `forbidUnknownValues`    | `boolean`  | If set to true, the validation of unknown objects would fail immediately.                                                         |
| `disableErrorMessages`   | `boolean`  | If set to true, the validation errors would not be forwarded to the client.                                                       |
| `groups`                 | `string[]` | Groups to be used during validation of the object.                                                                                |
| `dismissDefaultMessages` | `boolean`  | If set to true, the validation will not use default messages. Error message always will be `undefined` if its not explicitly set. |
| `validationError.target` | `boolean`  | Indicates if target should be exposed in `ValidationError`                                                                        |
| `validationError.value`  | `boolean`  | Indicates if validated value should be exposed in `ValidationError`.                                                              |

> **Notice** You may find more information about the `class-validator` package in its [repository](https://github.com/typestack/class-validator).

* Pipes
* Built-in pipes
* What does it look like?
* What's the point?
* Object schema validation
* Binding pipes
* Class validator
* Transformer pipe
* A built-in ValidationPipe

----
url: https://docs.nestjs.com/v5/recipes/prisma
----

### Prisma

[Prisma](https://www.prisma.io/) turns your database into a GraphQL API and enables the use of GraphQL as a universal query language for all databases. Instead of writing SQL or using a NoSQL API, you can query your database with GraphQL. In this chapter we won't go into details about Prisma, so head over to their website and have a look what [features](https://www.prisma.io/features/) are available.

> **Notice** In this article, you'll learn how to integrate `Prisma` into the Nest framework. We assume that you are already familiar with the GraphQL concepts and the `@nestjs/graphql` module.

#### Dependencies

Firstly, we need to install the required packages:

TypeScript

```typescript

$ npm install --save prisma-binding
```

#### Setup Prisma

While working with Prisma you can either host your own instance or use the [Prisma Cloud](https://www.prisma.io/cloud/). In this introduction we are going to use the demo server provided by Prisma.

1. Install the Prisma CLI `npm install -g prisma`
2. Create a new service `prisma init`, choose the demo server and follow the instructions
3. Deploy your service `prisma deploy`

If you find yourself in trouble jump over to their [Quick Start ](https://www.prisma.io/docs/quickstart/)section for further details. Eventually you should see two new files in your project directory.

prisma.yaml

```yaml

endpoint: https://us1.prisma.sh/nest-f6ec12/prisma/dev
datamodel: datamodel.graphql
```

and automatically created data model.

datamodel.graphql

```graphql

type User {
  id: ID! @unique
  name: String!
}
```

> **Notice** In the real-world applications you will create more complex data models. For more information about data modeling in Prisma click [here](https://www.prisma.io/features/data-modeling/).

By typing `prisma playground` you can open the Prisma GraphQL playground. Feel free to send queries and mutations.

#### Create the client

There are a couple of ways to integrate a GraphQL API. We are going to use [GraphQL CLI](https://www.npmjs.com/package/graphql-cli), a command line tool for common GraphQL development workflows. To install the GraphQL CLI use the following command:

TypeScript

```typescript

$ npm install -g graphql-cli
```

Next, create your .graphqlconfig in the root directory of the your Nest application:

```shell

$ touch .graphqlconfig.yml
```

Put the following content into it:

```yaml

projects:
  database:
    schemaPath: src/prisma/prisma-types.graphql
    extensions:
      endpoints:
        default: https://us1.prisma.sh/nest-f6ec12/prisma/dev
      codegen:
        - generator: prisma-binding
          language: typescript
          output:
            binding: src/prisma/prisma.binding.ts
```

To download your Prisma GraphQL schema to `src/prisma/prisma-types.graphql` and create your Prisma client under `src/prisma/prisma.binding.graphql`, run the following commands in your terminal:

```shell

$ graphql get-schema --project database
$ graphql codegen --project database
```

#### Integration

Almost done. Now, let's create a module for our Prisma integration.

prisma.service

TypeScript

```typescript

import { Injectable } from '@nestjs/common';
import { Prisma } from './prisma.binding';

@Injectable()
export class PrismaService extends Prisma {
  constructor() {
    super({
      endpoint: 'https://us1.prisma.sh/nest-f6ec12/prisma/dev',
      debug: false,
    });
  }
}
```

Once `PrismaService` is ready, we need to create a correspoding module.

prisma.module

TypeScript

```typescript

import { Module } from '@nestjs/common';
import { PrismaService } from './prisma.service';

@Module({
  providers: [PrismaService],
  exports: [PrismaService],
})
export class PrismaModule {}
```

> **Hint** To create new modules and services in no time we can make use of the [Nest CLI](/v5/cli/overview). To create a `PrismaModule` type `nest g module prisma` and for the service `nest g service prisma/prisma`

#### Usage

To use your new service we are going to import the `PrismaModule` and inject the `PrismaService` into `UsersResolver`.

src/users/users.module

TypeScript

```typescript

import { Module } from '@nestjs/common';
import { UsersResolver } from './users.resolver';
import { PrismaModule } from '../prisma/prisma.module';

@Module({
  imports: [PrismaModule],
  providers: [UsersResolver],
})
export class UsersModule {}
```

Importing `PrismaModule` makes exported `PrismaService` available in `UsersModule` context.

src/users/users.resolver

TypeScript

```typescript

import { Query, Resolver, Args, Info } from '@nestjs/graphql';
import { PrismaService } from '../prisma/prisma.service';
import { User } from '../graphql.schema';

@Resolver()
export class UsersResolver {
  constructor(private readonly prisma: PrismaService) {}

  @Query('users')
  async getUsers(@Args() args, @Info() info): Promise<User[]> {
    return await this.prisma.query.users(args, info);
  }
}
```

#### Example

A slightly modified example is available [here](https://github.com/nestjs/nest/tree/master/sample/22-graphql-prisma).

* Prisma
* Dependencies
* Setup Prisma
* Create the client
* Integration
* Usage

----
url: https://docs.nestjs.com/v4/fundamentals/e2e-testing
----

### E2E Testing

The end to end testing is a great way to verify how the application works from **beginning to end**. For example, when the application grows, it's difficult to manually test every API endpoint. The e2e tests help us to make sure that everything's working correctly and fits our requirements.

The steps to perform e2e tests are exactly the same as in the case of [unit testing](/v4/fundamentals/unit-testing). We're using [Jest](https://github.com/facebook/jest) library as a test runner and the `Test` static class to create a testing module. Moreover, to simulate the HTTP requests, we've installed the [supertest](https://github.com/visionmedia/supertest) library.

Let's create an `e2e` directory and test the `CatsModule`.

cats.e2e-spec.ts

JavaScript TypeScript

TypeScript

```typescript

import * as express from 'express';
import * as request from 'supertest';
import { Test } from '@nestjs/testing';
import { CatsModule } from '../../src/cats/cats.module';
import { CatsService } from '../../src/cats/cats.service';

describe('Cats', () => {
    const server = express();
    const catsService = { findAll: () => ['test'] };

    beforeAll(async () => {
        const module = await Test.createTestingModule({
            imports: [CatsModule],
          })
          .overrideComponent(CatsService).useValue(catsService)
          .compile();

        const app = module.createNestApplication(server);
        await app.init();
    });

    it(`/GET cats`, () => {
        return request(server)
            .get('/cats')
            .expect(200)
            .expect({
              data: catsService.findAll(),
            });
    });
});
```

> **Hint** Keep your e2e test files inside the `e2e` directory. The testing files should have a `.e2e-spec` or `.e2e-test` suffix.

Here's a `cats.e2e-spec.ts` test file. It contains a single HTTP request test, where we're checking whether the response looks like expected.

Notice that `TestingModule` instance provides an `overrideComponent()` method thus we can **override** the component which is the part of the imported module. Also, we can successively override the guards and interceptors using `overrideGuard()` and `overrideInterceptor()`.

The compiled module has several methods well described in the following table:

|                            |                                                                                                                                                                     |
| -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `createNestInstance()`     | Takes an optional argument - the express instance, and returns the `INestApplication`. It's necessary to manually initialize the application using `init()` method. |
| `createNestMicroservice()` | Takes `MicroserviceConfiguration` as an argument, and returns the `INestMicroservice`.                                                                              |
| `get()`                    | Makes possible to retrieve the instance of the component or controller available inside the processed module.                                                       |
| `select()`                 | Allows you to navigate through the module tree, for example, to pull out a specific instance from the selected module.                                              |

#### Sponsors

[](https://valor-software.com/)

Nest is an MIT-licensed open source project. It can grow thanks to the support by these awesome people. If you'd like to join them, please read more [here](https://opencollective.com/nest). Thanks!

[](https://opencollective.com/nest/backer/0/website)[](https://opencollective.com/nest/backer/1/website)[](https://opencollective.com/nest/backer/2/website)[](https://opencollective.com/nest/backer/3/website)[](https://opencollective.com/nest/backer/4/website)[](https://opencollective.com/nest/backer/5/website)[](https://opencollective.com/nest/backer/6/website)[](https://opencollective.com/nest/backer/7/website)[](https://opencollective.com/nest/backer/8/website)[](https://opencollective.com/nest/backer/9/website)[](https://opencollective.com/nest/backer/10/website)[](https://opencollective.com/nest/backer/11/website)[](https://opencollective.com/nest/backer/12/website)[](https://opencollective.com/nest/backer/13/website)[](https://opencollective.com/nest/backer/14/website)[](https://opencollective.com/nest/backer/15/website)[](https://opencollective.com/nest/backer/16/website)[](https://opencollective.com/nest/backer/17/website)[](https://opencollective.com/nest/backer/18/website)[](https://opencollective.com/nest/backer/19/website)[](https://opencollective.com/nest/backer/20/website)[](https://opencollective.com/nest/backer/21/website)[](https://opencollective.com/nest/backer/22/website)[](https://opencollective.com/nest/backer/23/website)[](https://opencollective.com/nest/backer/24/website)[](https://opencollective.com/nest/backer/25/website)[](https://opencollective.com/nest/backer/26/website)[](https://opencollective.com/nest/backer/27/website)[](https://opencollective.com/nest/backer/28/website)[](https://opencollective.com/nest/backer/29/website)

[Become a sponsor](https://opencollective.com/nest)

----
url: https://docs.nestjs.com/v4/websockets/pipes
----

### Pipes

There's no difference between websockets **pipes** and the [regular pipes](/v4/pipes). The only thing you should be aware of is that instead of throwing `HttpException`, you should use the `WsException`.

> **Hint** The `WsException` class is available within the `@nestjs/websockets` package.

#### Sponsors

[](https://valor-software.com/)

Nest is an MIT-licensed open source project. It can grow thanks to the support by these awesome people. If you'd like to join them, please read more [here](https://opencollective.com/nest). Thanks!

[](https://opencollective.com/nest/backer/0/website)[](https://opencollective.com/nest/backer/1/website)[](https://opencollective.com/nest/backer/2/website)[](https://opencollective.com/nest/backer/3/website)[](https://opencollective.com/nest/backer/4/website)[](https://opencollective.com/nest/backer/5/website)[](https://opencollective.com/nest/backer/6/website)[](https://opencollective.com/nest/backer/7/website)[](https://opencollective.com/nest/backer/8/website)[](https://opencollective.com/nest/backer/9/website)[](https://opencollective.com/nest/backer/10/website)[](https://opencollective.com/nest/backer/11/website)[](https://opencollective.com/nest/backer/12/website)[](https://opencollective.com/nest/backer/13/website)[](https://opencollective.com/nest/backer/14/website)[](https://opencollective.com/nest/backer/15/website)[](https://opencollective.com/nest/backer/16/website)[](https://opencollective.com/nest/backer/17/website)[](https://opencollective.com/nest/backer/18/website)[](https://opencollective.com/nest/backer/19/website)[](https://opencollective.com/nest/backer/20/website)[](https://opencollective.com/nest/backer/21/website)[](https://opencollective.com/nest/backer/22/website)[](https://opencollective.com/nest/backer/23/website)[](https://opencollective.com/nest/backer/24/website)[](https://opencollective.com/nest/backer/25/website)[](https://opencollective.com/nest/backer/26/website)[](https://opencollective.com/nest/backer/27/website)[](https://opencollective.com/nest/backer/28/website)[](https://opencollective.com/nest/backer/29/website)

[Become a sponsor](https://opencollective.com/nest)

----
url: https://docs.nestjs.com/v8/microservices/pipes
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Pipes](https://docs.nestjs.com/v8/microservices/pipes#pipes)
* [Binding pipes](https://docs.nestjs.com/v8/microservices/pipes#binding-pipes)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/microservices/pipes.md "Suggest Edits")

### Pipes

There is no fundamental difference between [regular pipes](/v8/pipes) and microservices pipes. The only difference is that instead of throwing `HttpException`, you should use `RpcException`.

> **Hint** The `RpcException` class is exposed from `@nestjs/microservices` package.

#### Binding pipes[#](/microservices/pipes#binding-pipes)

The following example uses a manually instantiated method-scoped pipe. Just as with HTTP based applications, you can also use controller-scoped pipes (i.e., prefix the controller class with a `@UsePipes()` decorator).

JS TS

```typescript

@UsePipes(new ValidationPipe())
@MessagePattern({ cmd: 'sum' })
accumulate(data: number[]): number {
  return (data || []).reduce((a, b) => a + b);
}
```

```typescript

@UsePipes(new ValidationPipe())
@MessagePattern({ cmd: 'sum' })
accumulate(data) {
  return (data || []).reduce((a, b) => a + b);
}
```

----
url: https://docs.nestjs.com/v7/microservices/basics
----

* [Overview](https://docs.nestjs.com/v7/microservices/basics#overview)
* [Installation](https://docs.nestjs.com/v7/microservices/basics#installation)
* [Getting started](https://docs.nestjs.com/v7/microservices/basics#getting-started)
* [Patterns](https://docs.nestjs.com/v7/microservices/basics#patterns)
* [Request-response](https://docs.nestjs.com/v7/microservices/basics#request-response)
* [Asynchronous responses](https://docs.nestjs.com/v7/microservices/basics#asynchronous-responses)
* [Event-based](https://docs.nestjs.com/v7/microservices/basics#event-based)
* [Decorators](https://docs.nestjs.com/v7/microservices/basics#decorators)
* [Client](https://docs.nestjs.com/v7/microservices/basics#client)
* [Sending messages](https://docs.nestjs.com/v7/microservices/basics#sending-messages)
* [Publishing events](https://docs.nestjs.com/v7/microservices/basics#publishing-events)
* [Scopes](https://docs.nestjs.com/v7/microservices/basics#scopes)
* [Handling timeouts](https://docs.nestjs.com/v7/microservices/basics#handling-timeouts)

```bash

$ npm i --save @nestjs/microservices
```

#### Getting started[#](/microservices/basics#getting-started)

To instantiate a microservice, use the `createMicroservice()` method of the `NestFactory` class:

main.ts

JS TS

```typescript

import { NestFactory } from '@nestjs/core';
import { Transport, MicroserviceOptions } from '@nestjs/microservices';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.createMicroservice<MicroserviceOptions>(
    AppModule,
    {
      transport: Transport.TCP,
    },
  );
  app.listen(() => console.log('Microservice is listening'));
}
bootstrap();
```

```typescript

import { NestFactory } from '@nestjs/core';
import { Transport, MicroserviceOptions } from '@nestjs/microservices';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.createMicroservice(AppModule, {
    transport: Transport.TCP,
  });
  app.listen(() => console.log('Microservice is listening'));
}
bootstrap();
```

> **Hint** Microservices use the **TCP** transport layer by default.

The second argument of the `createMicroservice()` method is an `options` object. This object may consist of two members:

|             |                                                                            |
| ----------- | -------------------------------------------------------------------------- |
| `transport` | Specifies the transporter (for example, `Transport.NATS`)                  |
| `options`   | A transporter-specific options object that determines transporter behavior |

The `options` object is specific to the chosen transporter. The **TCP** transporter exposes the properties described below. For other transporters (e.g, Redis, MQTT, etc.), see the relevant chapter for a description of the available options.

|                 |                                                          |
| --------------- | -------------------------------------------------------- |
| `host`          | Connection hostname                                      |
| `port`          | Connection port                                          |
| `retryAttempts` | Number of times to retry message (default: `0`)          |
| `retryDelay`    | Delay between message retry attempts (ms) (default: `0`) |

```typescript

import { Controller } from '@nestjs/common';
import { MessagePattern } from '@nestjs/microservices';

@Controller()
export class MathController {
  @MessagePattern({ cmd: 'sum' })
  accumulate(data: number[]): number {
    return (data || []).reduce((a, b) => a + b);
  }
}
```

```typescript

import { Controller } from '@nestjs/common';
import { MessagePattern } from '@nestjs/microservices';

@Controller()
export class MathController {
  @MessagePattern({ cmd: 'sum' })
  accumulate(data) {
    return (data || []).reduce((a, b) => a + b);
  }
}
```

In the above code, the `accumulate()`**message handler** listens for messages that fulfill the `{ cmd: 'sum' }` message pattern. The message handler takes a single argument, the `data` passed from the client. In this case, the data is an array of numbers which are to be accumulated.

#### Asynchronous responses[#](/microservices/basics#asynchronous-responses)

Message handlers are able to respond either synchronously or **asynchronously**. Hence, `async` methods are supported.

JS TS

```typescript

@MessagePattern({ cmd: 'sum' })
async accumulate(data: number[]): Promise<number> {
  return (data || []).reduce((a, b) => a + b);
}
```

```typescript

@MessagePattern({ cmd: 'sum' })
async accumulate(data) {
  return (data || []).reduce((a, b) => a + b);
}
```

A message handler is also able to return an `Observable`, in which case the result values will be emitted until the stream is completed.

JS TS

```typescript

@MessagePattern({ cmd: 'sum' })
accumulate(data: number[]): Observable<number> {
  return from([1, 2, 3]);
}
```

```typescript

@MessagePattern({ cmd: 'sum' })
accumulate(data: number[]): Observable<number> {
  return from([1, 2, 3]);
}
```

In the example above, the message handler will respond **3 times** (with each item from the array).

#### Event-based[#](/microservices/basics#event-based)

While the request-response method is ideal for exchanging messages between services, it is less suitable when your message style is event-based - when you just want to publish **events** without waiting for a response. In that case, you do not want the overhead required by request-response for maintaining two channels.

Suppose you would like to simply notify another service that a certain condition has occurred in this part of the system. This is the ideal use case for the event-based message style.

To create an event handler, we use the `@EventPattern()` decorator, which is imported from the `@nestjs/microservices` package.

JS TS

```typescript

@EventPattern('user_created')
async handleUserCreated(data: Record<string, unknown>) {
  // business logic
}
```

```typescript

@EventPattern('user_created')
async handleUserCreated(data) {
  // business logic
}
```

```typescript

@MessagePattern('time.us.*')
getDate(@Payload() data: number[], @Ctx() context: NatsContext) {
  console.log(`Subject: ${context.getSubject()}`); // e.g. "time.us.east"
  return new Date().toLocaleTimeString(...);
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('time.us.*')
getDate(data, context) {
  console.log(`Subject: ${context.getSubject()}`); // e.g. "time.us.east"
  return new Date().toLocaleTimeString(...);
}
```

> **Hint**`@Payload()`, `@Ctx()` and `NatsContext` are imported from `@nestjs/microservices`.

#### Client[#](/microservices/basics#client)

A client Nest application can exchange messages or publish events to a Nest microservice using the `ClientProxy` class. This class defines several methods, such as `send()` (for request-response messaging) and `emit()` (for event-driven messaging) that let you communicate with a remote microservice. Obtain an instance of this class in one of the following ways.

One technique is to import the `ClientsModule`, which exposes the static `register()` method. This method takes an argument which is an array of objects representing microservice transporters. Each such object has a `name` property, an optional `transport` property (default is `Transport.TCP`), and an optional transporter-specific `options` property.

The `name` property serves as an **injection token** that can be used to inject an instance of a `ClientProxy` where needed. The value of the `name` property, as an injection token, can be an arbitrary string or JavaScript symbol, as described [here](https://docs.nestjs.com/fundamentals/custom-providers#non-class-based-provider-tokens).

The `options` property is an object with the same properties we saw in the `createMicroservice()` method earlier.

```typescript

@Module({
  imports: [
    ClientsModule.register([
      { name: 'MATH_SERVICE', transport: Transport.TCP },
    ]),
  ]
  ...
})
```

Once the module has been imported, we can inject an instance of the `ClientProxy` configured as specified via the `'MATH_SERVICE'` transporter options shown above, using the `@Inject()` decorator.

```typescript

constructor(
  @Inject('MATH_SERVICE') private client: ClientProxy,
) {}
```

> **Hint** The `ClientsModule` and `ClientProxy` classes are imported from the `@nestjs/microservices` package.

At times we may need to fetch the transporter configuration from another service (say a `ConfigService`), rather than hard-coding it in our client application. To do this, we can register a [custom provider](/v7/techniques/custom-providers) using the `ClientProxyFactory` class. This class has a static `create()` method, which accepts a transporter options object, and returns a customized `ClientProxy` instance.

```typescript

@Module({
  providers: [
    {
      provide: 'MATH_SERVICE',
      useFactory: (configService: ConfigService) => {
        const mathSvcOptions = configService.getMathSvcOptions();
        return ClientProxyFactory.create(mathSvcOptions);
      },
      inject: [ConfigService],
    }
  ]
  ...
})
```

> **Hint** The `ClientProxyFactory` is imported from the `@nestjs/microservices` package.

Another option is to use the `@Client()` property decorator.

```typescript

@Client({ transport: Transport.TCP })
client: ClientProxy;
```

> **Hint** The `@Client()` decorator is imported from the `@nestjs/microservices` package.

Using the `@Client()` decorator is not the preferred technique, as it is harder to test and harder to share a client instance.

The `ClientProxy` is **lazy**. It doesn't initiate a connection immediately. Instead, it will be established before the first microservice call, and then reused across each subsequent call. However, if you want to delay the application bootstrapping process until a connection is established, you can manually initiate a connection using the `ClientProxy` object's `connect()` method inside the `OnApplicationBootstrap` lifecycle hook.

JS TS

```typescript

async onApplicationBootstrap() {
  await this.client.connect();
}
```

If the connection cannot be created, the `connect()` method will reject with the corresponding error object.

#### Sending messages[#](/microservices/basics#sending-messages)

The `ClientProxy` exposes a `send()` method. This method is intended to call the microservice and returns an `Observable` with its response. Thus, we can subscribe to the emitted values easily.

JS TS

```typescript

accumulate(): Observable<number> {
  const pattern = { cmd: 'sum' };
  const payload = [1, 2, 3];
  return this.client.send<number>(pattern, payload);
}
```

```typescript

accumulate() {
  const pattern = { cmd: 'sum' };
  const payload = [1, 2, 3];
  return this.client.send(pattern, payload);
}
```

The `send()` method takes two arguments, `pattern` and `payload`. The `pattern` should match one defined in a `@MessagePattern()` decorator. The `payload` is a message that we want to transmit to the remote microservice. This method returns a **cold `Observable`**, which means that you have to explicitly subscribe to it before the message will be sent.

#### Publishing events[#](/microservices/basics#publishing-events)

To send an event, use the `ClientProxy` object's `emit()` method. This method publishes an event to the message broker.

JS TS

```typescript

async publish() {
  this.client.emit<number>('user_created', new UserCreatedEvent());
}
```

```typescript

async publish() {
  this.client.emit('user_created', new UserCreatedEvent());
}
```

The `emit()` method takes two arguments, `pattern` and `payload`. The `pattern`should match one defined in an `@EventPattern()` decorator. The `payload` is an event payload that we want to transmit to the remote microservice. This method returns a **hot `Observable`** (unlike the cold `Observable` returned by `send()`), which means that whether or not you explicitly subscribe to the observable, the proxy will immediately try to deliver the event.

## Hoodies, T-shirts, and accessories!

Support our future development by shopping in the official store!

[See more](https://nestjs.threadless.com/ "Shop | NestJS - A node.js framework built on top of TypeScript")

#### Scopes[#](/microservices/basics#scopes)

For people coming from different programming language backgrounds, it might be unexpected to learn that in Nest, almost everything is shared across incoming requests. We have a connection pool to the database, singleton services with global state, etc. Remember that Node.js doesn't follow the request/response Multi-Threaded Stateless Model in which every request is processed by a separate thread. Hence, using singleton instances is fully **safe** for our applications.

However, there are edge-cases when request-based lifetime of the handler may be the desired behavior, for instance per-request caching in GraphQL applications, request tracking or multi-tenancy. Learn how to control scopes [here](/v7/fundamentals/injection-scopes).

Request-scoped handlers and providers can inject `RequestContext` using the `@Inject()` decorator in combination with `CONTEXT` token:

```typescript

import { Injectable, Scope, Inject } from '@nestjs/common';
import { CONTEXT, RequestContext } from '@nestjs/microservices';

@Injectable({ scope: Scope.REQUEST })
export class CatsService {
  constructor(@Inject(CONTEXT) private ctx: RequestContext) {}
}
```

This provides access to the `RequestContext` object, which has two properties:

```typescript

export interface RequestContext<T = any> {
  pattern: string | Record<string, any>;
  data: T;
}
```

The `data` property is the message payload sent by the message producer. The `pattern` property is the pattern used to identify an appropriate handler to handle the incoming message.

#### Handling timeouts[#](/microservices/basics#handling-timeouts)

In distributed systems, sometimes microservices might be down or not available. To avoid infinitely long waiting, you can use Timeouts. A timeout is an incredibly useful pattern when communicating with other services. To apply timeouts to your microservice calls, you can use the `RxJS` timeout operator. If the microservice does not respond to the request within a certain time, an exception is thrown, which can be caught and handled appropriately.

To solve this problem you have to use [rxjs](https://github.com/ReactiveX/rxjs) package. Just use the `timeout` operator in the pipe:

JS TS

```typescript

this.client
      .send<TResult, TInput>(pattern, data)
      .pipe(timeout(5000))
      .toPromise();
```

```typescript

this.client
      .send(pattern, data)
      .pipe(timeout(5000))
      .toPromise();
```

> **Hint** The `timeout` operator is imported from the `rxjs/operators` package.

After 5 seconds, if the microservice isn't responding, it will throw an error.

----
url: https://docs.nestjs.com/providers
----

[Skip to content](#content)

On this page

* [Providers](https://docs.nestjs.com/providers#providers)
* [Services](https://docs.nestjs.com/providers#services)
* [Dependency injection](https://docs.nestjs.com/providers#dependency-injection)
* [Scopes](https://docs.nestjs.com/providers#scopes)
* [Custom providers](https://docs.nestjs.com/providers#custom-providers)
* [Optional providers](https://docs.nestjs.com/providers#optional-providers)
* [Property-based injection](https://docs.nestjs.com/providers#property-based-injection)
* [Provider registration](https://docs.nestjs.com/providers#provider-registration)
* [Manual instantiation](https://docs.nestjs.com/providers#manual-instantiation)

### Providers

Providers are a core concept in Nest. Many of the basic Nest classes, such as services, repositories, factories, and helpers, can be treated as providers. The main idea behind a provider is that it can be **injected** as a dependency, which lets objects form relationships with each other. The Nest runtime takes care of "wiring up" these objects.

In the previous chapter, we built a basic `CatsController`. Controllers should handle HTTP requests and delegate more complex tasks to **providers**. In their simplest form, providers are plain JavaScript classes listed in the `providers` array of a module. For more details, see the [Modules](/modules) chapter.

> **Hint** Nest lets you design and organize dependencies in an object-oriented way, so it's good practice to follow the [SOLID principles](https://en.wikipedia.org/wiki/SOLID).

#### Services[#](/providers#services)

Let's start by creating a `CatsService`. This service handles data storage and retrieval for the `CatsController`. Because it encapsulates application logic, it's a natural candidate for a provider.

cats.service.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import type { Cat } from './interfaces/cat.interface.js';

@Injectable()
export class CatsService {
  private readonly cats: Cat[] = [];

  create(cat: Cat) {
    this.cats.push(cat);
  }

  findAll(): Cat[] {
    return this.cats;
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';

@Injectable()
export class CatsService {
  constructor() {
    this.cats = [];
  }

  create(cat) {
    this.cats.push(cat);
  }

  findAll() {
    return this.cats;
  }
}
```

> **Hint** To create a service with the CLI, run `$ nest g service cats`.

`CatsService` is a basic class with one property and two methods. The key addition is the `@Injectable()` decorator. It attaches metadata to the class, declaring that `CatsService` can be managed by the Nest [IoC](https://en.wikipedia.org/wiki/Inversion_of_control) container.

The example also uses a `Cat` interface:

interfaces/cat.interface.ts

JS TS

```typescript

export interface Cat {
  name: string;
  age: number;
  breed: string;
}
```

Now that we have a service to store and retrieve cats, let's use it in the `CatsController`:

cats.controller.ts

JS TS

```typescript

import { Controller, Get, Post, Body } from '@nestjs/common';
import { CreateCatDto } from './dto/create-cat.dto.js';
import { CatsService } from './cats.service.js';
import type { Cat } from './interfaces/cat.interface.js';

@Controller('cats')
export class CatsController {
  constructor(private catsService: CatsService) {}

  @Post()
  async create(@Body() createCatDto: CreateCatDto) {
    this.catsService.create(createCatDto);
  }

  @Get()
  async findAll(): Promise<Cat[]> {
    return this.catsService.findAll();
  }
}
```

```typescript

import { Controller, Get, Post, Body, Bind, Dependencies } from '@nestjs/common';
import { CatsService } from './cats.service.js';

@Controller('cats')
@Dependencies(CatsService)
export class CatsController {
  constructor(catsService) {
    this.catsService = catsService;
  }

  @Post()
  @Bind(Body())
  async create(createCatDto) {
    this.catsService.create(createCatDto);
  }

  @Get()
  async findAll() {
    return this.catsService.findAll();
  }
}
```

`CatsService` is **injected** through the class constructor. The next section explains how Nest resolves it.

#### Dependency injection[#](/providers#dependency-injection)

Nest is built around the **dependency injection** design pattern. For an introduction to the concept, see the [Angular documentation](https://angular.dev/guide/di).

Nest resolves dependencies by their type. In the example below, Nest resolves `catsService` by supplying an instance of `CatsService`. With the default (singleton) scope, Nest creates the instance once and shares it with every class that depends on it. Nest then passes the instance to the controller's constructor:

```typescript

constructor(private catsService: CatsService) {}
```

This single line does two things:

* The `private` keyword makes `catsService` a TypeScript **parameter property**: it declares a `catsService` member on the class and assigns the constructor argument to it, so you don't have to write `this.catsService = catsService` yourself.
* The `CatsService` type annotation is what Nest resolves against. At compile time, TypeScript emits the constructor's parameter types as metadata, and the container reads that metadata to determine which provider to supply.

> **Warning** Because resolution relies on the emitted type, the annotation must refer to something that exists at runtime, that is, a **class**. Interfaces and type aliases are erased during compilation. If `AppConfig` is an interface, `constructor(private config: AppConfig)` leaves Nest with no token to look up, and the application fails at startup with a "Nest can't resolve dependencies" error. The same happens when you import a class with `import type`, because the import is erased as well. To inject something that isn't a class, register it under a token and inject it explicitly with `@Inject()`, as described in [Custom providers](/fundamentals/custom-providers#interfaces-and-abstract-classes).

#### Scopes[#](/providers#scopes)

By default, a provider's lifetime ("scope") matches the application lifecycle. When the application bootstraps, Nest resolves every dependency, which means every provider is instantiated. Likewise, when the application shuts down, every provider is destroyed. You can also give a provider a different scope, for example, make it **request-scoped** so that its lifetime is tied to an individual request. See the [Injection scopes](/fundamentals/injection-scopes) chapter for details.

Nest has a built-in inversion of control (IoC) container that manages the relationships between providers. The container underpins dependency injection and supports more than the class-based providers shown so far: you can also define providers with plain values, classes, and synchronous or asynchronous factories. For examples, see the [Custom providers](/fundamentals/custom-providers) chapter.

#### Optional providers[#](/providers#optional-providers)

Some dependencies are not always required. For example, a class might depend on a **configuration object** but fall back to default values when none is provided. Such a dependency is optional, and its absence should not cause an error.

To mark a dependency as optional, apply the `@Optional()` decorator to the constructor parameter:

```typescript

import { Injectable, Optional, Inject } from '@nestjs/common';

@Injectable()
export class HttpService<T> {
  constructor(@Optional() @Inject('HTTP_OPTIONS') private httpClient: T) {}
}
```

This example injects a custom provider, so it passes the `HTTP_OPTIONS` custom **token** to `@Inject()`. The previous examples used constructor-based injection, where each dependency is identified by its class in the constructor signature. For more on custom providers and their tokens, see the [Custom providers](/fundamentals/custom-providers) chapter.

`@Optional()` only affects what happens when the provider is *missing*: if nothing is registered under `HTTP_OPTIONS`, Nest injects `undefined` instead of failing at startup. The class is therefore responsible for the fallback, typically by merging the injected value, if any, over a set of defaults.

#### Property-based injection[#](/providers#property-based-injection)

The examples so far use constructor-based injection, where providers are injected through the constructor. In some cases, **property-based injection** is more convenient. For example, if a base class depends on one or more providers, passing them up through `super()` from every subclass becomes cumbersome. Instead, you can apply the `@Inject()` decorator directly to a property:

```typescript

import { Injectable, Inject } from '@nestjs/common';

@Injectable()
export class HttpService<T> {
  @Inject('HTTP_OPTIONS')
  private readonly httpClient: T;
}
```

> **Warning** If your class doesn't extend another class, prefer **constructor-based** injection. The constructor states explicitly which dependencies the class requires, which makes the code easier to follow than properties annotated with `@Inject()`.

#### Provider registration[#](/providers#provider-registration)

With a provider (`CatsService`) and a consumer (`CatsController`) in place, you need to register the service with Nest so that it can perform the injection. To do so, add the service to the `providers` array of the `@Module()` decorator in the module file (`app.module.ts`):

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { CatsController } from './cats/cats.controller.js';
import { CatsService } from './cats/cats.service.js';

@Module({
  controllers: [CatsController],
  providers: [CatsService],
})
export class AppModule {}
```

Nest can now resolve the dependencies of the `CatsController` class.

The directory structure now looks like this:

So far, Nest has resolved dependencies automatically. In some cases, you may need to step outside the dependency injection system and retrieve or instantiate providers manually. Two techniques cover these cases:

* To retrieve existing instances or instantiate providers dynamically, use `ModuleRef`, described in the [Module reference](/fundamentals/module-ref) chapter.
* To get providers within the `bootstrap()` function (e.g., for standalone applications or to use a configuration service during bootstrapping), see [Standalone applications](/standalone-applications).

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/components.md)

----
url: https://docs.nestjs.com/http/webhooks
----

[Skip to content](#content)

On this page

* [Webhooks](https://docs.nestjs.com/http/webhooks#webhooks)
* [Installation](https://docs.nestjs.com/http/webhooks#installation)
* [Keep webhooks in your database](https://docs.nestjs.com/http/webhooks#keep-webhooks-in-your-database)
* [Register the modules](https://docs.nestjs.com/http/webhooks#register-the-modules)
* [Let partners subscribe](https://docs.nestjs.com/http/webhooks#let-partners-subscribe)
* [Send order.shipped and order.cancelled after the commit](https://docs.nestjs.com/http/webhooks#send-ordershipped-and-ordercancelled-after-the-commit)
* [Retries, the delivery log and replay](https://docs.nestjs.com/http/webhooks#retries-the-delivery-log-and-replay)
* [Receive the payment provider's webhooks](https://docs.nestjs.com/http/webhooks#receive-the-payment-providers-webhooks)
* [Receive the carrier's Stripe-like webhooks](https://docs.nestjs.com/http/webhooks#receive-the-carriers-stripe-like-webhooks)
* [Other senders](https://docs.nestjs.com/http/webhooks#other-senders)
* [Rotate secrets](https://docs.nestjs.com/http/webhooks#rotate-secrets)
* [Try it](https://docs.nestjs.com/http/webhooks#try-it)
* [Testing](https://docs.nestjs.com/http/webhooks#testing)
* [Delivery guarantees](https://docs.nestjs.com/http/webhooks#delivery-guarantees)
* [Production checklist](https://docs.nestjs.com/http/webhooks#production-checklist)
* [The store contract](https://docs.nestjs.com/http/webhooks#the-store-contract)
* [Reference](https://docs.nestjs.com/http/webhooks#reference)

[](https://srv.carbonads.net/ads/click/x/GTND4277CVSIC2JEFTBLYKQUF67D62JICAADVZ3JCAAI6KQJFTSDKKQKC6BI55QUCEYD5KQECKBIK53JFTAI5K37HEYI55QLCAYD653ECTNCYBZ52K)[Secure humans, AI agents, & whatever comes next. Starting building with Auth0 for AI Agents. ](https://srv.carbonads.net/ads/click/x/GTND4277CVSIC2JEFTBLYKQUF67D62JICAADVZ3JCAAI6KQJFTSDKKQKC6BI55QUCEYD5KQECKBIK53JFTAI5K37HEYI55QLCAYD653ECTNCYBZ52K)[ads via Carbon](http://carbonads.net/?utm_source=nestjscom\&utm_medium=ad_via_link\&utm_campaign=in_unit\&utm_term=carbon)

### Webhooks

An online store for cat food and supplies sells to cat shelters and resellers that buy in bulk, through its API. Northside Pet Supplies, a reseller, places an order and wants to know when it ships and when it's cancelled, without polling: a webhook to its warehouse system. The store receives webhooks too: the payment provider reports payments, and the carrier reports shipments. Both directions look simple, and both go wrong in the same ways:

* **Sending.** A `fetch()` after the order commits is lost when the process dies in between, and sent for a transaction that then rolls back. A retry sends the same event twice without telling the partner so. Every partner writes its own verifier for a homemade signature. A partner that is down for an hour is hammered, a dead endpoint is never turned off, and nobody can answer "did you send it?". And the URL the partner typed is a server-side request forgery waiting to happen: `https://169.254.169.254/` answers with the cloud credentials.
* **Receiving.** The signature is checked on a body the framework parsed and serialized again (a stray space breaks it, and a tampered body can pass), compared with `===` instead of in constant time, with no timestamp window, and a redelivered event runs the handler twice: an order marked paid twice, or shipped twice.

`@nestjs/webhooks` makes both directions one thing to configure. Outgoing webhooks travel through the [outbox](/reliability/outbox): `webhooks.dispatch()` adds the message in the same transaction as the order, and after the commit a worker fans it out to the partner's endpoints, signs each request the way [Standard Webhooks](https://www.standardwebhooks.com) specifies, retries with backoff for about two days, keeps a log of every attempt, and replays on request. Incoming webhooks are one decorator, `@VerifyWebhook()`, which checks the signature on the raw body and skips redeliveries.

In this tutorial, you'll add webhooks to the store's order API, on PostgreSQL with Drizzle:

* Partners subscribe to `order.shipped` and `order.cancelled` through the API, and see their secret once.
* The API sends the webhooks after the commit, signed, and retries them while a partner is down.
* Partners read their delivery log, and ask for a replay.
* The API receives the payment provider's payment webhooks (Standard Webhooks) and the carrier's shipment webhooks (Stripe's scheme), verified on the raw body and processed exactly once.
* Secrets rotate without a gap, and a URL that points inside the store's network is refused.

#### Installation[#](/http/webhooks#installation)

To get started, install the required dependency:

```bash

$ npm i --save @nestjs/webhooks
```

The tutorial runs on PostgreSQL, through [Drizzle ORM](https://orm.drizzle.team) and [`@nestjs/drizzle`](/data/drizzle) with the `pg` driver: the endpoints and the delivery log live in the database the orders live in, on a database server that outlives any instance of the application. Using TypeORM, or MySQL? Follow the tutorial, and see "With TypeORM" and "With MySQL" in [Keep webhooks in your database](/http/webhooks#keep-webhooks-in-your-database) for what changes.

Outgoing webhooks are outbox messages, and incoming ones are deduplicated with the outbox's inbox, so the application runs the outbox too (`@nestjs/outbox`, installed and set up in [the outbox tutorial](/reliability/outbox)).

The example application, the online store's order API, keeps its catalog, the partners that call it, and their orders in three tables of its own, which the later sections read and write. They're the example's data, not something webhooks need: the webhooks' and the outbox's tables belong to their stores, which create them, as [Keep webhooks in your database](/http/webhooks#keep-webhooks-in-your-database) shows.

`products` is the catalog:

| Column  | Type      | Notes                                           |
| ------- | --------- | ----------------------------------------------- |
| `id`    | `text`    | Primary key, such as `salmon-kibble-2kg`        |
| `name`  | `text`    | The display name, such as `Salmon kibble, 2 kg` |
| `price` | `integer` | In cents                                        |

`partners` holds the cat shelters and resellers that buy in bulk over the API, and receive its webhooks:

| Column         | Type   | Notes                                                |
| -------------- | ------ | ---------------------------------------------------- |
| `id`           | `text` | Primary key, such as `northside`                     |
| `name`         | `text` | The display name, such as `Northside Pet Supplies`   |
| `api_key_hash` | `text` | The SHA-256 of the partner's API key, in hex. Unique |

`orders` holds the partners' orders, whose `status` goes from `placed` to `paid` and `shipped`, or to `cancelled`:

| Column            | Type      | Notes                                                                                               |
| ----------------- | --------- | --------------------------------------------------------------------------------------------------- |
| `id`              | `text`    | Primary key                                                                                         |
| `partner_id`      | `text`    | References `partners.id`                                                                            |
| `items`           | `jsonb`   | The order's lines, as a JSON array: each line's `productId`, `quantity` and unit `price` (in cents) |
| `total`           | `integer` | In cents                                                                                            |
| `status`          | `text`    | `placed`, `paid`, `shipped` or `cancelled`                                                          |
| `payment_id`      | `text`    | Nullable: set when the order is paid                                                                |
| `tracking_number` | `text`    | Nullable: set when the order is shipped                                                             |

The other columns aren't nullable.

The catalog has two products, `salmon-kibble-2kg` at 2499 cents and `clumping-litter-10l` at 1599 cents, and the two partners have sample API keys (issue real ones from your partner onboarding):

| Partner                            | `id`        | API key                    |
| ---------------------------------- | ----------- | -------------------------- |
| Northside Pet Supplies, a reseller | `northside` | `partner_northside_7c1d2e` |
| Riverside Cat Shelter              | `riverside` | `partner_riverside_91ab44` |

#### Keep webhooks in your database[#](/http/webhooks#keep-webhooks-in-your-database)

There's nothing to create for webhooks, or for the outbox they travel through: no tables, entities or Prisma models. Register their two stores, and each creates its own schema, `nest_webhooks` and `nest_outbox`, and migrates it: at startup in development and in tests, and in production with `npx @nestjs/webhooks migrate` and `npx @nestjs/outbox migrate`, or with their `migrationSql()` in your own migrations.

The package keeps the endpoints, with their secrets, the messages it dispatched, their deliveries and the log of every attempt in a **store**, which it reads through two contracts, `WebhookEndpointStore` and `WebhookDeliveryStore`. Until you register one, the module keeps them in memory: fine for a first run, but a restart loses every pending delivery, and two instances don't share them.

> **Warning** With `NODE_ENV=production` and no store registered, startup fails, unless you set `allowInMemoryStorage: true`.

On PostgreSQL, register the package's store, `PostgresWebhookStore` from `@nestjs/webhooks/postgres`. The outbox needs one too, for the messages that carry dispatched webhooks out of your transaction and for the inbox that deduplicates incoming ones: `PostgresOutboxStore` from `@nestjs/outbox/postgres`, as in [the outbox tutorial](/reliability/outbox#keep-messages-in-your-database). Both run their SQL through the database client your application already has, and keep their tables in schemas of their own. They're ordinary providers, registered once, in the root module, next to `WebhooksModule` and `OutboxModule`: all four are application-wide. `AppModule` creates each with a factory that injects the Drizzle database and its package's storage registry, which the store registers itself with:

app.module.ts

JS TS

```typescript

{
  // Outbox messages and the inbox, in your database, in a schema of their own (nest_outbox)
  provide: PostgresOutboxStore,
  inject: [getDrizzleToken(), OutboxStorage],
  useFactory: (db: Database, outboxStorage: OutboxStorage) =>
    new PostgresOutboxStore({ executor: fromDrizzle(db) }, outboxStorage),
},
{
  // Endpoints, deliveries and their log, in your database, in a schema of their own (nest_webhooks)
  provide: PostgresWebhookStore,
  inject: [getDrizzleToken(), WebhooksStorage],
  useFactory: (db: Database, webhooksStorage: WebhooksStorage) =>
    new PostgresWebhookStore({ executor: fromDrizzle(db) }, webhooksStorage),
},
```

`fromDrizzle(db)` is the stores' **executor**: it runs their statements through your Drizzle database, whichever driver it uses, such as `pg` or PGlite. `fromPg(pool)`, `fromTypeOrm(dataSource)`, `fromPrisma(prisma)` and `fromKysely(db)` do the same for a node-postgres pool, TypeORM, Prisma and Kysely. `@nestjs/webhooks/postgres` and `@nestjs/outbox/postgres` both export them, so `AppModule` imports `fromDrizzle` once, for both stores. At startup, each module logs the store it uses.

**The schema.** The webhook store keeps its tables in a schema of its own, `nest_webhooks` (the `schema` option names another). On MySQL, which has no schemas, they're tables of the connection's database, with the schema's name as their prefix: `nest_webhooks_endpoints` and so on.

| Table                             | What it holds                                                                   |
| --------------------------------- | ------------------------------------------------------------------------------- |
| `nest_webhooks.endpoints`         | The partners' endpoints: URL, event types, tenant, and secrets                  |
| `nest_webhooks.messages`          | What was dispatched, byte for byte                                              |
| `nest_webhooks.deliveries`        | One per message and endpoint, with its status, attempts and lease               |
| `nest_webhooks.delivery_attempts` | The log: every attempt, with the status code, the response and how long it took |
| `nest_webhooks.migrations`        | The versions of the store's schema applied                                      |

The outbox's store keeps its messages, dead letters and inbox in `nest_outbox` (`nest_outbox_messages` and so on, on MySQL), as in [the outbox tutorial](/reliability/outbox#keep-messages-in-your-database). They belong to the stores: your migrations don't create them, and your own tables can't collide with them. A few choices in there matter to the package:

* An endpoint's secrets are a JSON array, newest first: during a rotation, the old secret stays for the overlap, with an expiry. With `encryption` configured (see [Register the modules](/http/webhooks#register-the-modules)), what is stored is sealed.
* A message's `body` is `text`, not `jsonb`. It is the exact JSON that was signed and sent, and `jsonb` would reformat it: a partner storing the request and its signature could no longer verify a replay.
* A delivery is unique per message and endpoint. The fan-out that creates deliveries runs after the commit, inside the outbox, so it can run twice; the unique key makes the second run insert nothing.
* No foreign key from a delivery to its endpoint: a deleted endpoint's log stays. Attempts go with their delivery.
* Times are epoch milliseconds (`bigint`), from the package's clock, never the database's.

**Migrations.** The packages ship their schemas as versioned migrations, and the stores apply them themselves. With the `migrate` option, each applies the ones its schema hasn't had yet at startup, before the relay and the worker run, in one transaction that holds an advisory lock: of several instances that start together, one migrates, and the others find nothing left to do. `migrate` defaults to `true`, except with `NODE_ENV=production`. So in development and in tests, the stores create their schemas on the first start, and your migrations only create your own tables.

In production, apply the migrations before the new version of your application starts, as you apply your own, so that no instance changes a schema while it boots: in the middle of a rolling deploy, that would lock busy tables, and a least-privilege database user can't do it anyway. The packages' command lines do it from your deploy step, next to `npx drizzle-kit migrate`. They read the database from `DATABASE_URL`, or from `--url`, and need `pg` installed:

```bash

$ npx @nestjs/webhooks status
Schema "nest_webhooks" is at version 0; this version of @nestjs/webhooks needs version 1.
$ npx @nestjs/webhooks migrate
Migrated schema "nest_webhooks" to version 1 (applied 1).
$ npx @nestjs/outbox migrate
Migrated schema "nest_outbox" to version 1 (applied 1).
```

`status` exits with 1 while the schema is behind, which makes it a check for CI. To apply the migrations with your own migration tool instead, take their SQL from `npx @nestjs/webhooks sql` and `npx @nestjs/outbox sql`, or from `PostgresWebhookStore.migrationSql()` and `PostgresOutboxStore.migrationSql()` in code: the statements of every migration, with the bookkeeping that records the version. Run each in one transaction, as TypeORM's and Drizzle's migrators do. With TypeORM, that's a migration of your own, next to the ones it generates for your entities:

typeorm/migrations/1790801311590-WebhookStores.ts

JS TS

```typescript

import { PostgresOutboxStore } from '@nestjs/outbox/postgres';
import { PostgresWebhookStore } from '@nestjs/webhooks/postgres';
import type { MigrationInterface, QueryRunner } from 'typeorm';

export class WebhookStores1790801311590 implements MigrationInterface {
  async up(queryRunner: QueryRunner): Promise<void> {
    await queryRunner.query(PostgresOutboxStore.migrationSql());
    await queryRunner.query(PostgresWebhookStore.migrationSql());
  }

  async down(): Promise<void> {
    throw new Error('The webhook and outbox stores have no down migrations.');
  }
}
```

With drizzle-kit, create a custom migration per store, and fill each with its SQL, a `--> statement-breakpoint` line between the statements: Drizzle's migrator then runs them one at a time, which PGlite requires. In code, `migrationSql()` with `statementBreakpoints: true` returns the same.

```bash

$ npx drizzle-kit generate --custom --name=outbox
$ npx @nestjs/outbox sql --statement-breakpoints > drizzle/0002_outbox.sql
$ npx drizzle-kit generate --custom --name=webhooks
$ npx @nestjs/webhooks sql --statement-breakpoints > drizzle/0003_webhooks.sql
```

On MySQL, the stores' `migrationStatements()` return the statements one per string, and a TypeORM migration runs them one per call:

typeorm/mysql-migrations/1790801311590-WebhookStores.ts

JS TS

```typescript

for (const statement of [...MySqlOutboxStore.migrationStatements(), ...MySqlWebhookStore.migrationStatements()]) {
  await queryRunner.query(statement);
}
```

With `migrate` off, a store whose schema is behind fails the startup with a `WebhookSchemaError` (the outbox's store, with an `OutboxSchemaError`) that names these three ways, and fails every call the same way until the schema catches up, which it notices without a restart. During a rolling deploy, the previous version of your application keeps running on a schema that the new one migrated. There are no down migrations.

**Transactions.** No method of the webhook store takes your transaction. `webhooks.dispatch(tx, ...)` adds the message to the outbox in your transaction, through the outbox's store, and `webhook.processInTransaction(tx, ...)` records an incoming webhook in the outbox's inbox the same way; the fan-out after the commit, the worker and everything else run on the stores' own connections. With Drizzle, `tx` is what `db.transaction()` hands its callback, as the next sections show. The outbox's store refuses the database itself, whose statements would commit on their own, with an `OutboxTransactionRequiredError` that says what to pass. With the other executors, pass a node-postgres client after `BEGIN` (not the pool), TypeORM's `EntityManager` from `dataSource.transaction()`, Prisma's interactive transaction client, or a Kysely transaction.

**Isolation.** The stores rely on READ COMMITTED, PostgreSQL's default isolation level: their statements race each other, and under a stricter level they would fail with serialization errors. At startup, each checks the database's `default_transaction_isolation`, and fails if it's stricter. Your own transactions may run at any level. Under REPEATABLE READ or SERIALIZABLE, though, a copy of an incoming webhook that `processInTransaction()` handles in your transaction, racing the first one's commit, fails with PostgreSQL's serialization error instead of being skipped as a duplicate: the sender gets an error, and its retry finds the webhook recorded.

**With TypeORM.**`TypeOrmModule` takes the place of `DrizzleModule` in `AppModule`, and both stores run on the `DataSource` it provides, through `fromTypeOrm()`:

typeorm/app.module.ts

JS TS

```typescript

{
  // Outbox messages and the inbox, in your database, in a schema of their own (nest_outbox)
  provide: PostgresOutboxStore,
  inject: [DataSource, OutboxStorage],
  useFactory: (dataSource: DataSource, outboxStorage: OutboxStorage) =>
    new PostgresOutboxStore({ executor: fromTypeOrm(dataSource) }, outboxStorage),
},
{
  // Endpoints, deliveries and their log, in your database, in a schema of their own (nest_webhooks)
  provide: PostgresWebhookStore,
  inject: [DataSource, WebhooksStorage],
  useFactory: (dataSource: DataSource, webhooksStorage: WebhooksStorage) =>
    new PostgresWebhookStore({ executor: fromTypeOrm(dataSource) }, webhooksStorage),
},
```

Where the tutorial passes Drizzle's `tx` to `dispatch()` and `processInTransaction()`, pass the `EntityManager` that `dataSource.transaction()` hands its callback, and inject `Webhooks<EntityManager>`. The outbox's store refuses `dataSource.manager`, whose writes would commit on their own. This is the order service's `cancelOrder()`, from [Send order.shipped and order.cancelled after the commit](/http/webhooks#send-ordershipped-and-ordercancelled-after-the-commit), with TypeORM:

typeorm/orders.service.ts

JS TS

```typescript

const order = await this.dataSource.transaction(async (manager) => {
  const row = await manager.findOne(OrderEntity, { where: { id, partnerId: partner.id }, lock: { mode: 'pessimistic_write' } });
  if (!row) {
    throw new NotFoundException(`Order ${id} not found`);
  }
  if (row.status === 'shipped' || row.status === 'cancelled') {
    throw new ConflictException(`Order ${id} is ${row.status}`);
  }
  await manager.update(OrderEntity, id, { status: 'cancelled' });

  // The transaction's EntityManager: the webhook is sent only if the cancellation commits.
  const data: OrderCancelled = { orderId: id, reason };
  await this.webhooks.dispatch(manager, { type: 'order.cancelled', tenant: row.partnerId, data });
  return { ...row, status: 'cancelled' as const };
});
```

Your entities and their migrations stay as they are: `migration:generate` compares only your entities with the database, and leaves the stores' schemas alone.

**With MySQL.** On MySQL 8.4 or 9.x, import the stores and the executor from `@nestjs/outbox/mysql` and `@nestjs/webhooks/mysql` instead. The providers are the same, with `MySqlOutboxStore` and `MySqlWebhookStore`, on a Drizzle database of `drizzle-orm/mysql2`:

mysql/app.module.ts

JS TS

```typescript

import { MySqlOutboxStore } from '@nestjs/outbox/mysql';
import { fromDrizzle, MySqlWebhookStore } from '@nestjs/webhooks/mysql';
import { drizzle } from 'drizzle-orm/mysql2';
// ...
DrizzleModule.forRootAsync({
  // Drizzle on MySQL: a mysql2 pool on DATABASE_URL (mysql://), whose database holds the stores' tables too
  useFactory: () => ({ drizzle, connection: process.env.DATABASE_URL! }),
}),
// ...
{
  // Outbox messages and the inbox, in your database, in tables of their own (nest_outbox_*)
  provide: MySqlOutboxStore,
  inject: [getDrizzleToken(), OutboxStorage],
  useFactory: (db: Database, outboxStorage: OutboxStorage) =>
    new MySqlOutboxStore({ executor: fromDrizzle(db) }, outboxStorage),
},
{
  // Endpoints, deliveries and their log, in your database, in tables of their own (nest_webhooks_*)
  provide: MySqlWebhookStore,
  inject: [getDrizzleToken(), WebhooksStorage],
  useFactory: (db: Database, webhooksStorage: WebhooksStorage) =>
    new MySqlWebhookStore({ executor: fromDrizzle(db) }, webhooksStorage),
},
```

With the other clients, the executor is `fromMysql2(pool)` for a `mysql2/promise` pool, `fromTypeOrm(dataSource)` for a `DataSource` of type `mysql`, `fromPrisma(prisma)` for Prisma through `@prisma/adapter-mariadb`, or `fromKysely(db)` for Kysely's `MysqlDialect`. What differs from PostgreSQL:

* **Tables, not a schema.** MySQL has no schemas inside a database, so the stores keep their tables in the connection's database, the one in the URL's path, next to yours, and `schema` becomes their prefix: `nest_webhooks_endpoints`, `nest_webhooks_deliveries` and so on, and `nest_outbox_messages` for the outbox. It takes lowercase letters, digits and underscores, at most 40 characters.
* **Your transactions.**`dispatch()` and `processInTransaction()` work at REPEATABLE READ, MySQL's default, as at READ COMMITTED: there's nothing to configure, and the stores don't check the database's default. When MySQL breaks a deadlock in your transaction (error 1213), it rolls the whole transaction back, and the client's error reaches your code: run the transaction again. The stores run their own transactions again themselves. With `processInTransaction()`, that can happen when copies of one webhook arrive at once and the first one's transaction rolls back: the sender gets an error, and its retry goes through.
* **Keys are bounded.** Ids and tenants are indexed columns: at most 255 characters, 256 for a tenant, which the package's own ids and its limit on `tenant` stay within. An incoming webhook's id goes into the inbox's key, of at most 255 characters too, and the verifier refuses a longer id on every database, with a 401, before the handler runs.
* **Migrations aren't one transaction.** MySQL commits each DDL statement on its own, so `migrate` applies the statements one at a time, under a lock (`GET_LOCK()`), and a run that failed resumes at the statement it stopped at. Your own tool must send one statement per call too, as the TypeORM migration in **Migrations** above does. The command lines take a `mysql://` URL, and `sql --dialect mysql` prints MySQL's SQL: add `--statement-breakpoints` for a drizzle-kit custom migration, since its MySQL migrator sends one statement per breakpoint.
* **The server.** The stores check it at startup, and refuse MariaDB, a connection without a database, and a `sql_mode` that isn't strict (MySQL's default is). Keep `NO_BACKSLASH_ESCAPES` out of it too.

For another database, write a store of your own: [The store contract](/http/webhooks#the-store-contract) says what it must do.

#### Register the modules[#](/http/webhooks#register-the-modules)

Register `OutboxModule` and `WebhooksModule` in the root module, next to `DrizzleModule`, which registers the Drizzle database, with both stores in its `providers`. The feature modules are built in the next sections:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { DrizzleModule, getDrizzleToken } from '@nestjs/drizzle';
import { OutboxModule, OutboxStorage } from '@nestjs/outbox';
import { PostgresOutboxStore } from '@nestjs/outbox/postgres';
import { WebhooksModule, WebhooksStorage } from '@nestjs/webhooks';
import { fromDrizzle, PostgresWebhookStore } from '@nestjs/webhooks/postgres';
import { drizzle } from 'drizzle-orm/node-postgres';
import type { Database } from './database/drizzle.js';
import * as schema from './database/schema.js';
import { OrdersModule } from './orders/orders.module.js';
import { PartnerWebhooksModule } from './partner-webhooks/partner-webhooks.module.js';

@Module({
  imports: [
    // A pg pool on DATABASE_URL, closed in onApplicationShutdown(), after the relay and the
    // worker drained. The services inject it with @InjectDrizzle(), the stores' factories too.
    DrizzleModule.forRootAsync({
      useFactory: () => ({ drizzle, connection: process.env.DATABASE_URL!, schema }),
    }),
    // Outgoing webhooks travel through the outbox: dispatched in the order's transaction,
    // handed to the webhooks worker after the commit.
    OutboxModule.forRootAsync({
      useFactory: () => ({
        relay: { enabled: process.env.OUTBOX_RELAY !== 'off', pollInterval: '1s' },
      }),
    }),
    WebhooksModule.forRootAsync({
      useFactory: () => ({
        // The types partners may subscribe to; dispatch() refuses any other.
        eventTypes: ['order.shipped', 'order.cancelled'],
        // Ten attempts: 5s, 20s, 80s, ... capped at a day, about two days in all.
        retry: { attempts: 10, backoff: { delay: '5s', factor: 4, maxDelay: '1d' } },
        // An endpoint that fails every attempt for five days is switched off.
        disableEndpointAfter: '5d',
        delivery: {
          timeout: '15s',
          // Development only: deliver over http:// and to this machine. Without it, only
          // public https:// endpoints are accepted.
          allowHttp: process.env.WEBHOOKS_ALLOW_LOCAL === '1',
          allowPrivateNetworks: process.env.WEBHOOKS_ALLOW_LOCAL === '1',
        },
        worker: { enabled: process.env.WEBHOOKS_WORKER !== 'off', pollInterval: '1s' },
        // Endpoint secrets at rest: the first key encrypts, every key decrypts.
        encryption: process.env.WEBHOOKS_ENCRYPTION_KEYS
          ? { keys: process.env.WEBHOOKS_ENCRYPTION_KEYS.split(',').map((key) => key.trim()) }
          : undefined,
      }),
    }),
    OrdersModule,
    PartnerWebhooksModule,
  ],
  providers: [
    {
      // Outbox messages and the inbox, in your database, in a schema of their own (nest_outbox)
      provide: PostgresOutboxStore,
      inject: [getDrizzleToken(), OutboxStorage],
      useFactory: (db: Database, outboxStorage: OutboxStorage) =>
        new PostgresOutboxStore({ executor: fromDrizzle(db) }, outboxStorage),
    },
    {
      // Endpoints, deliveries and their log, in your database, in a schema of their own (nest_webhooks)
      provide: PostgresWebhookStore,
      inject: [getDrizzleToken(), WebhooksStorage],
      useFactory: (db: Database, webhooksStorage: WebhooksStorage) =>
        new PostgresWebhookStore({ executor: fromDrizzle(db) }, webhooksStorage),
    },
  ],
})
export class AppModule {}
```

`WebhooksModule` needs the outbox: `dispatch()` is an `Outbox.add()`, and the fan-out that turns a committed message into deliveries is an outbox handler. Without `OutboxModule`, startup fails and says so. The outbox's `relay` hands committed messages to the fan-out, polling every second, and `OUTBOX_RELAY=off` turns it off. The rest of the options, resolved when the application starts:

* `eventTypes`: the message types this application sends. `dispatch()` refuses any other, and so does an endpoint that tries to subscribe to one, with the known types in the message.
* `retry`: the vocabulary shared with the outbox, the HTTP client and resilience. Ten attempts, and a backoff that starts at 5 seconds, grows fourfold and is capped at a day, with jitter: what the Standard Webhooks spec recommends, "a retry schedule spanning multiple days".
* `disableEndpointAfter`: an endpoint that has failed every attempt for five days without a single success is switched off, and its owner is told (see [Retries, the delivery log and replay](/http/webhooks#retries-the-delivery-log-and-replay)).
* `delivery`: one attempt has 15 seconds for DNS, the connection, TLS, the request and the response. `allowHttp` and `allowPrivateNetworks` are off by default: only public `https://` endpoints are accepted. `WEBHOOKS_ALLOW_LOCAL=1` turns them on in development, where the partner's receiver runs on this machine. Cloud metadata addresses stay blocked even then.
* `worker`: the background deliverer, one per process. `WEBHOOKS_WORKER=off` turns it off in instances that only serve the API.
* `encryption`: endpoint secrets sealed at rest, with the family's shape: the first key encrypts, every key decrypts. Optional, from `WEBHOOKS_ENCRYPTION_KEYS`.

> **Hint** The tutorial reads `process.env` directly, to stay short. In an application, load the environment through [`@nestjs/config`](/application/configuration) with a validation schema, so a missing variable stops the application at startup rather than at the first request, and read the values from `ConfigService` (`inject: [ConfigService]` in the factories).

Durations are milliseconds or strings such as `'15s'` and `'5d'`. Both modules are global: `Webhooks`, `WebhookEndpoints`, `WebhookDeliveries`, `WebhooksEvents` and `WebhooksStorage` can be injected anywhere. `main.ts` binds the validation pipe for the partner API's DTOs (see the next section), and enables the shutdown hooks, so a deploy lets the relay and the worker finish their in-flight work:

main.ts

JS TS

```typescript

import { ValidationPipe } from '@nestjs/common';
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module.js';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  // The partner API's DTOs; whitelist: properties without a decorator are dropped.
  app.useGlobalPipes(new ValidationPipe({ whitelist: true }));
  // On SIGTERM the outbox relay and the webhook worker finish what they started.
  app.enableShutdownHooks();
  await app.listen(process.env.PORT ?? 3000);
}
await bootstrap();
```

At startup, both modules log the store they use, and on the first start, the stores log the schemas they created:

```bash

[Nest] 55905  - 09/30/2026, 6:52:36 PM     LOG [OutboxModule] OutboxStorage: PostgresOutboxStore
[Nest] 55905  - 09/30/2026, 6:52:36 PM     LOG [WebhooksModule] WebhooksStorage: PostgresWebhookStore
[Nest] 55905  - 09/30/2026, 6:52:36 PM     LOG [OutboxModule] PostgresOutboxStore: migrated schema "nest_outbox" to version 1.
[Nest] 55905  - 09/30/2026, 6:52:36 PM     LOG [WebhooksModule] PostgresWebhookStore: migrated schema "nest_webhooks" to version 1.
```

#### Let partners subscribe[#](/http/webhooks#let-partners-subscribe)

Shelters and resellers call the partner API with an API key: the example's two partners, Northside Pet Supplies (a reseller) and Riverside Cat Shelter, have the sample keys in [Installation](/http/webhooks#installation). `PartnerGuard` looks the key's hash up and sets the partner on the request, and `@CurrentPartner()` reads it:

partners/partner.guard.ts

JS TS

```typescript

import {
  createParamDecorator,
  Injectable,
  UnauthorizedException,
  type CanActivate,
  type ExecutionContext,
} from '@nestjs/common';
import { InjectDrizzle } from '@nestjs/drizzle';
import { eq } from 'drizzle-orm';
import { createHash } from 'node:crypto';
import type { Database } from '../database/drizzle.js';
import { partners } from '../database/schema.js';

export interface Partner {
  id: string;
  name: string;
}

/** Authenticates a partner by its API key: `Authorization: Bearer <key>`. */
@Injectable()
export class PartnerGuard implements CanActivate {
  constructor(@InjectDrizzle() private readonly db: Database) {}

  async canActivate(context: ExecutionContext): Promise<boolean> {
    const request = context.switchToHttp().getRequest<{ headers: Record<string, string>; partner?: Partner }>();
    const key = /^Bearer (\S+)$/.exec(request.headers.authorization ?? '')?.[1];
    if (!key) {
      throw new UnauthorizedException();
    }
    const hash = createHash('sha256').update(key).digest('hex');
    const [partner] = await this.db
      .select({ id: partners.id, name: partners.name })
      .from(partners)
      .where(eq(partners.apiKeyHash, hash));
    if (!partner) {
      throw new UnauthorizedException();
    }
    request.partner = partner;
    return true;
  }
}

/** The partner `PartnerGuard` authenticated. */
export const CurrentPartner = createParamDecorator(
  (_data: unknown, context: ExecutionContext) => context.switchToHttp().getRequest<{ partner: Partner }>().partner,
);
```

A subscription is a URL, the event types to receive, and a description; an update sends only what changes. The DTOs check the shape, and leave the URL and the types to the package, which knows what it accepts. Request bodies are validated with whatever the application already uses: every DTO on this page comes twice, as a class with `class-validator` decorators and as a Zod schema, so pick the style you have and skip the other listing:

partner-webhooks/webhook-endpoints.dto.ts

JS TS

```typescript

import { IsArray, IsBoolean, IsOptional, IsString } from 'class-validator';

/** Body of `POST /partner/webhook-endpoints`. The package checks the URL and the types themselves. */
export class CreateEndpointDto {
  @IsString()
  url: string;

  /** `order.shipped`, `order.cancelled`, or `*` for both. */
  @IsArray()
  @IsString({ each: true })
  eventTypes: string[];

  @IsOptional()
  @IsString()
  description?: string;
}

/** Body of `PATCH /partner/webhook-endpoints/:id`: only what is sent changes. */
export class UpdateEndpointDto {
  @IsOptional()
  @IsString()
  url?: string;

  @IsOptional()
  @IsArray()
  @IsString({ each: true })
  eventTypes?: string[];

  @IsOptional()
  @IsString()
  description?: string | null;

  @IsOptional()
  @IsBoolean()
  enabled?: boolean;
}
```

The same rules as Zod schemas, whose inferred types replace the classes. Nest 12.1 validates any [Standard Schema](https://standardschema.dev/) object, from Zod, Valibot or ArkType, through `StandardSchemaValidationPipe`:

partner-webhooks/webhook-endpoints.schemas.ts

JS TS

```typescript

import { z } from 'zod';

/** Body of `POST /partner/webhook-endpoints`. The package checks the URL and the types themselves. */
export const createEndpointSchema = z.object({
  url: z.string(),
  /** `order.shipped`, `order.cancelled`, or `*` for both. */
  eventTypes: z.array(z.string()),
  description: z.string().optional(),
});
export type CreateEndpointDto = z.infer<typeof createEndpointSchema>;

/** Body of `PATCH /partner/webhook-endpoints/:id`: only what is sent changes. */
export const updateEndpointSchema = z.object({
  url: z.string().optional(),
  eventTypes: z.array(z.string()).optional(),
  description: z.string().nullable().optional(),
  enabled: z.boolean().optional(),
});
export type UpdateEndpointDto = z.infer<typeof updateEndpointSchema>;
```

The subscription API is a controller over `WebhookEndpoints`. Every call passes the partner's id as the **tenant**: an endpoint is created for that tenant, listed for that tenant, and another partner's endpoint id behaves as if it didn't exist:

partner-webhooks/webhook-endpoints.controller.ts

JS TS

```typescript

import {
  Body,
  Controller,
  Delete,
  Get,
  HttpCode,
  HttpStatus,
  NotFoundException,
  Param,
  Patch,
  Post,
  UseGuards,
} from '@nestjs/common';
import { WebhookEndpoints } from '@nestjs/webhooks';
import { CurrentPartner, PartnerGuard, type Partner } from '../partners/partner.guard.js';
import { CreateEndpointDto, UpdateEndpointDto } from './webhook-endpoints.dto.js';

/** A partner's subscriptions. Every call is scoped to the partner: another partner's endpoint is a 404. */
@Controller('partner/webhook-endpoints')
@UseGuards(PartnerGuard)
export class WebhookEndpointsController {
  constructor(private readonly webhookEndpoints: WebhookEndpoints) {}

  /** Returns the endpoint and its secret. The secret is shown this once. */
  @Post()
  create(@CurrentPartner() partner: Partner, @Body() dto: CreateEndpointDto) {
    return this.webhookEndpoints.create({
      url: dto.url,
      eventTypes: dto.eventTypes,
      description: dto.description ?? null,
      tenant: partner.id,
    });
  }

  @Get()
  list(@CurrentPartner() partner: Partner) {
    return this.webhookEndpoints.list({ tenant: partner.id });
  }

  @Get(':id')
  async get(@CurrentPartner() partner: Partner, @Param('id') id: string) {
    const endpoint = await this.webhookEndpoints.get(id, { tenant: partner.id });
    if (!endpoint) {
      throw new NotFoundException(`Webhook endpoint ${id} not found`);
    }
    return endpoint;
  }

  @Patch(':id')
  update(@CurrentPartner() partner: Partner, @Param('id') id: string, @Body() dto: UpdateEndpointDto) {
    return this.webhookEndpoints.update(id, dto, { tenant: partner.id });
  }

  @Delete(':id')
  @HttpCode(HttpStatus.NO_CONTENT)
  async delete(@CurrentPartner() partner: Partner, @Param('id') id: string) {
    await this.webhookEndpoints.delete(id, { tenant: partner.id });
  }

  /** A new secret. The old one keeps signing for 24 hours, so the partner can switch without a gap. */
  @Post(':id/rotate-secret')
  @HttpCode(HttpStatus.OK)
  async rotateSecret(@CurrentPartner() partner: Partner, @Param('id') id: string) {
    return { secret: await this.webhookEndpoints.rotateSecret(id, { tenant: partner.id }) };
  }
}
```

With the Zod schemas, the body parameters declare their schema instead of a class:

partner-webhooks/webhook-endpoints.controller.ts

JS TS

```typescript

import { createEndpointSchema, updateEndpointSchema, type CreateEndpointDto, type UpdateEndpointDto } from './webhook-endpoints.schemas.js';
// ...
@Post()
create(@CurrentPartner() partner: Partner, @Body({ schema: createEndpointSchema }) dto: CreateEndpointDto) {
  // ...
}

@Patch(':id')
update(@CurrentPartner() partner: Partner, @Param('id') id: string, @Body({ schema: updateEndpointSchema }) dto: UpdateEndpointDto) {
  // ...
}
```

> **Hint** The DTOs are enforced only by a validation pipe: bind `ValidationPipe` globally, with `useGlobalPipes()` in `main.ts` as [Register the modules](/http/webhooks#register-the-modules) does (`whitelist` drops properties without a decorator), or as an `APP_PIPE` provider. With the Zod schemas, bind `StandardSchemaValidationPipe` the same way instead: an application uses one or the other. The [validation](/application/validation) page has the options of each.

`create()` returns the endpoint with its `secret`, a Standard Webhooks `whsec_…` of 32 random bytes, generated here. This API shows it this once: `list()` and `get()` never include it, and a partner that lost it rotates. The package keeps the secret, sealed when `encryption` is set, because it signs with it, and `getSecret()` reads the current one back, for a "reveal" button behind a fresh sign-in if your API offers one. Endpoints moved from Svix or another Standard Webhooks sender keep their secrets: a migration script passes the partner's existing `whsec_…` as the `secret` of `create()`, so the partner's verifier keeps working, and `rotateSecret()` takes a given `secret` the same way. The package checks what the partner submits and throws an `InvalidWebhookEndpointError` with a 400 status: a URL that isn't `https://` (or `http://` with `allowHttp`), that carries credentials, or whose host is a blocked address, such as `https://169.254.169.254/latest/meta-data/` or `https://localhost/`; an event type that isn't in `eventTypes`. A partner's mistakes come back as 400s, and another partner's ids as 404s, through one filter:

partner-webhooks/webhooks-error.filter.ts

JS TS

```typescript

import { Catch, HttpException, type ArgumentsHost } from '@nestjs/common';
import { BaseExceptionFilter } from '@nestjs/core';
import { WebhooksError } from '@nestjs/webhooks';

/**
 * The package's errors carry an HTTP status (400 for an endpoint it refuses, 404 for another
 * partner's endpoint or delivery); this answers with it and the error's message.
 */
@Catch(WebhooksError)
export class WebhooksErrorFilter extends BaseExceptionFilter {
  override catch(error: WebhooksError, host: ArgumentsHost) {
    const status = (error as { status?: number }).status;
    super.catch(status ? new HttpException(error.message, status, { cause: error }) : error, host);
  }
}
```

partner-webhooks/partner-webhooks.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { APP_FILTER } from '@nestjs/core';
import { WebhookDeliveriesController } from './webhook-deliveries.controller.js';
import { WebhookEndpointsController } from './webhook-endpoints.controller.js';
import { WebhooksErrorFilter } from './webhooks-error.filter.js';

@Module({
  controllers: [WebhookEndpointsController, WebhookDeliveriesController],
  // Turns the package's errors (a refused URL, another partner's endpoint) into 4xx responses.
  providers: [{ provide: APP_FILTER, useClass: WebhooksErrorFilter }],
})
export class PartnerWebhooksModule {}
```

The delivery log's controller, added to this module [later](/http/webhooks#retries-the-delivery-log-and-replay), gives the partner the other half: what was sent to their endpoints.

#### Send order.shipped and order.cancelled after the commit[#](/http/webhooks#send-ordershipped-and-ordercancelled-after-the-commit)

`Webhooks.dispatch()` takes your transaction handle first, like `Outbox.add()`: with Drizzle, the `tx` that `db.transaction()` passes its callback, whose type the service gives `Webhooks<Transaction>`. Cancelling an order updates it and dispatches `order.cancelled` on the same `tx`; shipping it (which the carrier triggers, in [Receive the carrier's Stripe-like webhooks](/http/webhooks#receive-the-carriers-stripe-like-webhooks)) updates it and dispatches `order.shipped`. `tenant` is the partner that placed the order, so only that partner's endpoints receive it:

orders/orders.service.ts

JS TS

```typescript

@Injectable()
export class OrdersService {
  constructor(
    @InjectDrizzle() private readonly db: Database,
    private readonly webhooks: Webhooks<Transaction>,
  ) {}

  // ...

  /** Cancels an order that hasn't shipped, and tells the partner in the same transaction. */
  async cancelOrder(partner: Partner, id: string, reason: string): Promise<Order> {
    const order = await this.db.transaction(async (tx) => {
      const [row] = await tx
        .select()
        .from(orders)
        .where(and(eq(orders.id, id), eq(orders.partnerId, partner.id)))
        .for('update');
      if (!row) {
        throw new NotFoundException(`Order ${id} not found`);
      }
      if (row.status === 'shipped' || row.status === 'cancelled') {
        throw new ConflictException(`Order ${id} is ${row.status}`);
      }
      await tx.update(orders).set({ status: 'cancelled' }).where(eq(orders.id, id));

      // Drizzle's tx: the webhook is sent only if the cancellation commits, and only to the
      // partner's own endpoints (the tenant).
      const data: OrderCancelled = { orderId: id, reason };
      await this.webhooks.dispatch(tx, { type: 'order.cancelled', tenant: row.partnerId, data });
      return { ...row, status: 'cancelled' as const };
    });

    this.webhooks.notify(); // deliver now instead of at the next poll
    return order;
  }

  // ...

  /** The carrier picked the order up: marks it shipped and tells the partner, in one transaction (the carrier's webhook). */
  async markShipped(tx: Transaction, orderId: string, trackingNumber: string): Promise<Order> {
    const [row] = await tx.select().from(orders).where(eq(orders.id, orderId)).for('update');
    if (!row) {
      throw new NotFoundException(`Order ${orderId} not found`);
    }
    if (row.status !== 'paid') {
      throw new ConflictException(`Order ${orderId} is ${row.status}, not paid`);
    }
    await tx.update(orders).set({ status: 'shipped', trackingNumber }).where(eq(orders.id, orderId));

    const data: OrderShipped = { orderId, trackingNumber };
    await this.webhooks.dispatch(tx, { type: 'order.shipped', tenant: row.partnerId, data });
    return { ...row, status: 'shipped', trackingNumber };
  }
}
```

Nothing leaves the process inside the transaction. If it rolls back, the message never existed. If it commits, the outbox relay picks the message up (`notify()` asks it to do so now instead of at its next poll) and hands it to the package's fan-out, which creates one delivery per enabled endpoint of the tenant that subscribed to the type. The worker then signs and sends each. This is what Northside's server receives, on every attempt of the delivery, with the same `webhook-id` and the exact body that was serialized at `dispatch()`:

```http

POST /store/webhooks HTTP/1.1
content-type: application/json
user-agent: NestJS-Webhooks/1.0
webhook-id: msg_01a0f33b898e7341950339801ec3319a
webhook-timestamp: 1790787160
webhook-signature: v1,<base64 HMAC-SHA256 of "msg_01a0f33b898e7341950339801ec3319a.1790787160.{the body}">

{"type":"order.shipped","timestamp":"2026-09-30T16:52:40.462Z","data":{"orderId":"1067d04c-0617-44ac-9a29-67297867329e","trackingNumber":"TRK-4471-0001"}}
```

The signature is keyed with the endpoint's secret, so the partner can verify it with any Standard Webhooks library. Or with this package: Northside's receiver is a Nest application of its own, with its own root module, that only receives, with `outgoing: false`, and `@VerifyWebhook('store')` on its route. `STORE_WEBHOOK_SECRET` takes a comma-separated list, because the store's [rotation](/http/webhooks#rotate-secrets) signs with two secrets for a day:

partner-service/app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { OutboxModule } from '@nestjs/outbox';
import { WebhooksModule } from '@nestjs/webhooks';
import { StoreWebhooksController } from './store-webhooks.controller.js';

/**
 * Northside's side: a service that only receives. `outgoing: false` leaves out the
 * endpoints, deliveries and worker. The outbox's inbox deduplicates redeliveries by
 * webhook-id; in memory here, on the partner's own database in production (the outbox's
 * store, as in the outbox tutorial's analytics service).
 */
@Module({
  imports: [
    OutboxModule.forRoot({ relay: { enabled: false } }),
    WebhooksModule.forRootAsync({
      outgoing: false,
      useFactory: () => {
        const secrets = process.env.STORE_WEBHOOK_SECRET;
        if (!secrets) {
          throw new Error('Set STORE_WEBHOOK_SECRET to the secret the store gave this endpoint');
        }
        return {
          receivers: {
            // Every listed secret is tried: keep the old one next to the new one while the store rotates.
            store: { scheme: 'standard', secret: secrets.split(',') },
          },
        };
      },
    }),
  ],
  controllers: [StoreWebhooksController],
})
export class AppModule {}
```

partner-service/store-webhooks.controller.ts

JS TS

```typescript

import { Controller, HttpCode, HttpStatus, Logger, Post } from '@nestjs/common';
import { IncomingWebhook, VerifyWebhook } from '@nestjs/webhooks';

/** What the store sends: the Standard Webhooks payload, `type`, `timestamp` and `data`. */
export type StoreEvent =
  | { type: 'order.shipped'; timestamp: string; data: { orderId: string; trackingNumber: string } }
  | { type: 'order.cancelled'; timestamp: string; data: { orderId: string; reason: string } };

@Controller('store')
export class StoreWebhooksController {
  private readonly logger = new Logger(StoreWebhooksController.name);

  @Post('webhooks')
  @HttpCode(HttpStatus.NO_CONTENT)
  @VerifyWebhook('store')
  receive(@IncomingWebhook() webhook: IncomingWebhook<StoreEvent>) {
    const event = webhook.payload;
    if (event.type === 'order.shipped') {
      this.logger.log(`Order ${event.data.orderId} shipped, tracking ${event.data.trackingNumber} (${webhook.id})`);
    } else {
      this.logger.log(`Order ${event.data.orderId} cancelled: ${event.data.reason} (${webhook.id})`);
    }
  }
}
```

partner-service/main.ts

JS TS

```typescript

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module.js';

async function bootstrap() {
  // rawBody: the signature is checked on the bytes the store signed, not on a re-serialized body.
  const app = await NestFactory.create(AppModule, { rawBody: true });
  app.enableShutdownHooks();
  await app.listen(process.env.PORT ?? 4100);
}
await bootstrap();
```

The partner's `OutboxModule` provides the inbox that `@VerifyWebhook()` deduplicates with. It runs in memory here; a real partner registers the outbox's store on its own database, `PostgresOutboxStore` on PostgreSQL, as the analytics service does in [the outbox tutorial](/reliability/outbox#publish-to-the-analytics-microservice).

#### Retries, the delivery log and replay[#](/http/webhooks#retries-the-delivery-log-and-replay)

A 2xx from the partner is a success. Anything else is a failed attempt: a 5xx, a 4xx, a 3xx (redirects are never followed), a timeout, a refused connection. The worker retries after the backoff, honors a `Retry-After` header in seconds or as an HTTP date (up to the backoff's cap, a day; any other value is ignored), and on a 429, 502, 503 or 504 pauses that endpoint until then, five seconds without a header: its other deliveries wait without an attempt, so a partner asking for a breather gets one probe, not one per batch, while the other partners' deliveries go on. Three answers end a delivery early: a 410 Gone, which also disables the endpoint (`gone`); a destination the transport refuses (the subscription checks, run again at every send, because DNS changes); and `retry.retryIf` saying no. After the last attempt, the delivery is `failed` with the reason `exhausted`.

An endpoint that fails every attempt for `disableEndpointAfter` is disabled with the reason `failing`, and `WebhooksEvents` emits `endpoint-disabled`: tell the partner. A success at any point resets the clock. A disabled endpoint, whether by the worker or by the partner (`enabled: false` in the subscription `update()`), gets no delivery for anything dispatched while it stays disabled: the fan-out skips it, and nothing creates those deliveries later. A replay doesn't either, because it re-sends deliveries that exist. What does exist are the deliveries that were pending when the endpoint was disabled: they fail with the reason `endpoint-disabled` when their turn comes, and after re-enabling, the partner can ask for those again, as the failed deliveries they are. Re-enabling forgets the failures, and the endpoint receives what is dispatched from then on.

Every attempt is logged: the status code, the duration, the first 4 KB of the response body, the error. The partner reads its own log, and asks for a delivery to be sent again, one or every failed one since an outage began. The bulk retry takes an endpoint and the start of the outage, both optional:

partner-webhooks/webhook-deliveries.dto.ts

JS TS

```typescript

import { IsISO8601, IsOptional, IsString } from 'class-validator';

/** Body of `POST /partner/webhook-deliveries/retry`: every failed delivery since an outage began. */
export class RetryDeliveriesDto {
  /** One endpoint's, or every endpoint's. */
  @IsOptional()
  @IsString()
  endpointId?: string;

  /** Deliveries created at or after this time (ISO 8601): the start of the outage. */
  @IsOptional()
  @IsISO8601()
  since?: string;
}
```

partner-webhooks/webhook-deliveries.schemas.ts

JS TS

```typescript

import { z } from 'zod';

/** Body of `POST /partner/webhook-deliveries/retry`: every failed delivery since an outage began. */
export const retryDeliveriesSchema = z.object({
  /** One endpoint's, or every endpoint's. */
  endpointId: z.string().optional(),
  /** Deliveries created at or after this time (ISO 8601): the start of the outage. */
  since: z.iso.datetime().optional(),
});
export type RetryDeliveriesDto = z.infer<typeof retryDeliveriesSchema>;
```

partner-webhooks/webhook-deliveries.controller.ts

JS TS

```typescript

import {
  Body,
  Controller,
  Get,
  HttpCode,
  HttpStatus,
  NotFoundException,
  Param,
  Post,
  Query,
  UseGuards,
} from '@nestjs/common';
import { WebhookDeliveries, type WebhookDeliveryStatus } from '@nestjs/webhooks';
import { CurrentPartner, PartnerGuard, type Partner } from '../partners/partner.guard.js';
import { RetryDeliveriesDto } from './webhook-deliveries.dto.js';

/** A partner's delivery log: what was sent, how each attempt went, and a way to ask for it again. */
@Controller('partner/webhook-deliveries')
@UseGuards(PartnerGuard)
export class WebhookDeliveriesController {
  constructor(private readonly webhookDeliveries: WebhookDeliveries) {}

  /** Newest first. */
  @Get()
  list(
    @CurrentPartner() partner: Partner,
    @Query('endpointId') endpointId?: string,
    @Query('status') status?: WebhookDeliveryStatus,
    @Query('type') type?: string,
  ) {
    return this.webhookDeliveries.list({ tenant: partner.id, endpointId, status, type });
  }

  /** The delivery, the message that was sent, and every attempt: status code, duration, the start of the response. */
  @Get(':id')
  async get(@CurrentPartner() partner: Partner, @Param('id') id: string) {
    const delivery = await this.webhookDeliveries.get(id, { tenant: partner.id });
    if (!delivery) {
      throw new NotFoundException(`Webhook delivery ${id} not found`);
    }
    return delivery;
  }

  /** Sends one delivery again, now, with the same webhook-id: a replay of a lost webhook, or a retry of a failed one. */
  @Post(':id/retry')
  @HttpCode(HttpStatus.OK)
  async retry(@CurrentPartner() partner: Partner, @Param('id') id: string) {
    return { retried: await this.webhookDeliveries.retry(id, { tenant: partner.id }) };
  }

  /** Retries every failed delivery, of one endpoint or all, since an outage began. */
  @Post('retry')
  @HttpCode(HttpStatus.OK)
  async retryFailed(@CurrentPartner() partner: Partner, @Body() dto: RetryDeliveriesDto) {
    const since = dto.since === undefined ? undefined : new Date(dto.since);
    const retried = await this.webhookDeliveries.retry(
      { endpointId: dto.endpointId, status: 'failed', since },
      { tenant: partner.id },
    );
    return { retried };
  }
}
```

With the Zod schema:

partner-webhooks/webhook-deliveries.controller.ts

JS TS

```typescript

import { retryDeliveriesSchema, type RetryDeliveriesDto } from './webhook-deliveries.schemas.js';
// ...
@Post('retry')
@HttpCode(HttpStatus.OK)
async retryFailed(@CurrentPartner() partner: Partner, @Body({ schema: retryDeliveriesSchema }) dto: RetryDeliveriesDto) {
  // ...
}
```

A retry starts a new round: `attempts` back to 0, sent now, with the same `webhook-id` and the same body. The log of the earlier rounds stays. Because the id is the same, a partner whose inbox kept it answers 2xx without running its handler, so a replay is safe for a delivered webhook too: Northside can ask for the last hour again after losing its own database, and get only what it hasn't processed.

Operators get the same through `WebhookDeliveries` without a tenant: `stats()` (pending, due, leased and failed counts, and `lagMs`, how long the most overdue delivery has waited, the number to alert on), `retry()` across tenants, and `prune('30d')`, which nothing calls for you. `WebhooksEvents.events$` emits `delivered`, `retry-scheduled`, `delivery-failed`, `endpoint-disabled` and `destination-blocked`, each also on a `node:diagnostics_channel` channel named `nestjs:webhooks:<event>`.

#### Receive the payment provider's webhooks[#](/http/webhooks#receive-the-payment-providers-webhooks)

The payment provider tells the store that a payment went through with a Standard Webhooks request. Verifying it needs the body exactly as the provider signed it, so the application is created with `rawBody: true`. That works on Express and on Fastify:

main.ts

JS TS

```typescript

import { ValidationPipe } from '@nestjs/common';
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module.js';

async function bootstrap() {
  // rawBody: incoming webhooks are verified on the bytes that were signed, not on a re-serialized body.
  const app = await NestFactory.create(AppModule, { rawBody: true });
  // The partner API's DTOs; whitelist: properties without a decorator are dropped.
  app.useGlobalPipes(new ValidationPipe({ whitelist: true }));
  // On SIGTERM the outbox relay and the webhook worker finish what they started.
  app.enableShutdownHooks();
  await app.listen(process.env.PORT ?? 3000);
}
await bootstrap();
```

The sender goes into the module's `receivers`, by the name the route will use. The payment provider's secret is the one it shows in its dashboard:

app.module.ts

JS TS

```typescript

// The senders whose webhooks this API accepts, by the name @VerifyWebhook() uses.
receivers: {
  // The payment provider follows Standard Webhooks: webhook-id, webhook-timestamp, webhook-signature.
  payments: { scheme: 'standard', secret: process.env.PAYMENTS_WEBHOOK_SECRET! },
  // The carrier copied Stripe's scheme under its own header: Carrier-Signature: t=...,v1=...
  carrier: { scheme: 'stripe', header: 'Carrier-Signature', secret: process.env.CARRIER_WEBHOOK_SECRET! },
},
```

`@VerifyWebhook('payments')` on the route verifies the request before the handler runs, and `@IncomingWebhook()` gives what was verified: the sender's `id` for the webhook, the signed `timestamp`, the `payload` parsed from the signed bytes, and `processInTransaction()`:

provider-webhooks/payment-provider-webhooks.controller.ts

JS TS

```typescript

import { Controller, HttpCode, HttpStatus, Logger, Post } from '@nestjs/common';
import { InjectDrizzle } from '@nestjs/drizzle';
import { IncomingWebhook, VerifyWebhook } from '@nestjs/webhooks';
import type { Database } from '../database/drizzle.js';
import { OrdersService } from '../orders/orders.service.js';

/** The payment provider's payload: the Standard Webhooks shape, `type`, `timestamp` and `data`. */
export interface PaymentProviderEvent {
  type: 'payment.succeeded' | 'payment.failed';
  timestamp: string;
  data: { paymentId: string; orderId: string; amount: number };
}

@Controller('webhooks/payments')
export class PaymentProviderWebhooksController {
  private readonly logger = new Logger(PaymentProviderWebhooksController.name);

  constructor(
    @InjectDrizzle() private readonly db: Database,
    private readonly ordersService: OrdersService,
  ) {}

  @Post()
  @HttpCode(HttpStatus.OK)
  @VerifyWebhook('payments')
  async receive(@IncomingWebhook() webhook: IncomingWebhook<PaymentProviderEvent>) {
    const { type, data } = webhook.payload;
    if (type !== 'payment.succeeded') {
      this.logger.log(`Ignoring ${type} for order ${data.orderId}`);
      return;
    }
    // Exactly once: the webhook's id is recorded in the same transaction as the order's new
    // status, so a redelivery, even one racing this request on another instance, changes nothing.
    const result = await this.db.transaction(async (tx) =>
      webhook.processInTransaction(tx, () => this.ordersService.markPaid(tx, data.orderId, data.paymentId, data.amount)),
    );
    if (!result.duplicate) {
      this.logger.log(`Order ${data.orderId} paid: ${data.paymentId}, ${data.amount} cents`);
    }
  }
}
```

orders/orders.service.ts

JS TS

```typescript

/** The payment provider confirmed the payment. Runs inside the receiver's transaction. */
async markPaid(tx: Transaction, orderId: string, paymentId: string, amount: number): Promise<Order> {
  const [row] = await tx.select().from(orders).where(eq(orders.id, orderId)).for('update');
  if (!row) {
    throw new NotFoundException(`Order ${orderId} not found`);
  }
  if (row.status !== 'placed') {
    throw new ConflictException(`Order ${orderId} is ${row.status}`);
  }
  if (amount !== row.total) {
    throw new ConflictException(`Payment ${paymentId} is for ${amount}, and order ${orderId} totals ${row.total}`);
  }
  await tx.update(orders).set({ status: 'paid', paymentId }).where(eq(orders.id, orderId));
  return { ...row, status: 'paid', paymentId };
}
```

provider-webhooks/provider-webhooks.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { OrdersModule } from '../orders/orders.module.js';
import { CarrierWebhooksController } from './carrier-webhooks.controller.js';
import { PaymentProviderWebhooksController } from './payment-provider-webhooks.controller.js';

/** The webhooks the store receives: the payment provider's payments and the carrier's shipments. */
@Module({
  imports: [OrdersModule],
  controllers: [PaymentProviderWebhooksController, CarrierWebhooksController],
})
export class ProviderWebhooksModule {}
```

What the decorator checks, in order: the three `webhook-` headers are present and well formed, with a `webhook-id` of at most 255 characters, counted in code points; one `v1,` signature in `webhook-signature` matches the HMAC of `id.timestamp.body` with one of the configured secrets (compared in constant time; several secrets can be listed while the payment provider rotates); the signed timestamp is within 5 minutes of now, in either direction; the body is JSON. A request that fails gets a 401 with a generic message. The reason never goes to the sender; it goes to the `verification-failed` event, with the receiver's name. A signed body that isn't JSON gets a 400 from the framework's body parser before the decorator sees it, so no event is emitted for it. The same holds for a body over the body parser's size limit (100 kB on Express and 1 MiB on Fastify by default): it gets a 413 before the decorator runs, and no event is emitted. If the payment provider sends larger bodies, raise the limit with `useBodyParser()`, as described in [Raw body](/faq/raw-body#body-parser-size-limit).

Then comes deduplication. The payment provider retries until it gets a 2xx, so a timeout after the handler succeeded makes it send the same `webhook-id` again. The receiver keeps an inbox of the ids it processed (the outbox's inbox, consumer `webhooks:payments`): a known id is answered with an empty 200 without running the handler, and an id is recorded only after the handler succeeded, so a handler that threw is run again on the payment provider's retry. Two copies arriving together at one instance run the handler once; two instances receiving them at the same moment could both run it, which is what the next paragraph is for.

`markPaid()` moves money-related state, so the controller goes one step further with `processInTransaction()`: the webhook's id is recorded *through the order's transaction*, and `markPaid()` runs only if it is new. The record and the new status commit together. A redelivery after a crash between the handler and the inbox write, or one racing this request on another instance, finds the id and changes nothing; it resolves with `duplicate` set, which the controller uses to log only once. And when `markPaid()` throws, a payment for the wrong amount, say, the transaction rolls back, the record with it, the sender gets the 409, and its retry gets another chance once the order is fixed.

For development, a small script signs a request the way the payment provider (and, in the next section, the carrier) would, with `signWebhook()` from `@nestjs/webhooks/testing`:

scripts/send-webhook.ts

JS TS

```typescript

/**
 * Sends the signed request the payment provider or the carrier would send, for trying the API by hand:
 *
 *   npx tsx scripts/send-webhook.ts payments payment.succeeded '{"paymentId":"pay_1","orderId":"...","amount":4998}'
 *   npx tsx scripts/send-webhook.ts carrier shipment.shipped '{"orderId":"...","trackingNumber":"TRK-0001"}'
 *
 * Signs with PAYMENTS_WEBHOOK_SECRET or CARRIER_WEBHOOK_SECRET, the secrets the API was
 * started with, and posts to API_URL (default http://localhost:3000). WEBHOOK_ID sends a
 * redelivery with a given id; TAMPER=1 changes a byte of the body after signing it.
 */
import { signWebhook } from '@nestjs/webhooks/testing';
import { randomUUID } from 'node:crypto';

const [sender, type, json = '{}'] = process.argv.slice(2);
if (sender !== 'payments' && sender !== 'carrier') {
  console.error('usage: send-webhook.ts <payments|carrier> <type> <data as JSON>');
  process.exit(2);
}
const data: unknown = JSON.parse(json);
const id = process.env.WEBHOOK_ID;

function secret(name: string): string {
  const value = process.env[name];
  if (!value) {
    throw new Error(`Set ${name}`);
  }
  return value;
}

const signed =
  sender === 'payments'
    ? signWebhook({
        scheme: 'standard',
        secret: secret('PAYMENTS_WEBHOOK_SECRET'),
        id,
        payload: { type, timestamp: new Date().toISOString(), data },
      })
    : signWebhook({
        scheme: 'stripe',
        header: 'Carrier-Signature',
        secret: secret('CARRIER_WEBHOOK_SECRET'),
        payload: { id: id ?? `evt_${randomUUID().replaceAll('-', '')}`, type, data },
      });

const body = process.env.TAMPER ? `${signed.body.slice(0, -1)} }` : signed.body;
const response = await fetch(`${process.env.API_URL ?? 'http://localhost:3000'}/webhooks/${sender}`, {
  method: 'POST',
  headers: signed.headers,
  body,
});
console.log(`${response.status} ${await response.text()}`);
```

#### Receive the carrier's Stripe-like webhooks[#](/http/webhooks#receive-the-carriers-stripe-like-webhooks)

The carrier copied Stripe's scheme: a `Carrier-Signature: t=…,v1=…` header, the hex HMAC-SHA256 of `t.body` keyed with the secret's text, and the event's id inside the payload. The receiver in the [`receivers` option](/http/webhooks#receive-the-payment-providers-webhooks) says so: `scheme: 'stripe'` with the `header` name. Stripe's own webhooks are the same receiver without `header`. GitHub's, and senders with a scheme of their own, are in [Other senders](/http/webhooks#other-senders).

The handler is the interesting part. Marking the order shipped and telling the partner happen in one transaction: the order's new status, the partner's `order.shipped` message (through the outbox) and this webhook's inbox record commit together, or none of them does:

provider-webhooks/carrier-webhooks.controller.ts

JS TS

```typescript

import { Controller, HttpCode, HttpStatus, Logger, Post } from '@nestjs/common';
import { InjectDrizzle } from '@nestjs/drizzle';
import { IncomingWebhook, VerifyWebhook, Webhooks } from '@nestjs/webhooks';
import type { Database } from '../database/drizzle.js';
import { OrdersService } from '../orders/orders.service.js';

/** The carrier's payload, Stripe-like: the event's `id` is in the body, which is what the signature covers. */
export interface CarrierEvent {
  id: string;
  type: 'shipment.shipped' | 'shipment.delivered';
  data: { orderId: string; trackingNumber: string };
}

@Controller('webhooks/carrier')
export class CarrierWebhooksController {
  private readonly logger = new Logger(CarrierWebhooksController.name);

  constructor(
    @InjectDrizzle() private readonly db: Database,
    private readonly ordersService: OrdersService,
    private readonly webhooks: Webhooks,
  ) {}

  @Post()
  @HttpCode(HttpStatus.OK)
  @VerifyWebhook('carrier')
  async receive(@IncomingWebhook() webhook: IncomingWebhook<CarrierEvent>) {
    const { type, data } = webhook.payload;
    if (type !== 'shipment.shipped') {
      this.logger.log(`Ignoring ${type} for order ${data.orderId}`);
      return;
    }
    // One transaction: the order's status, the partner's order.shipped webhook (through the
    // outbox) and this webhook's inbox record commit together, or not at all.
    const result = await this.db.transaction(async (tx) =>
      webhook.processInTransaction(tx, () => this.ordersService.markShipped(tx, data.orderId, data.trackingNumber)),
    );
    if (result.duplicate) {
      return;
    }
    this.webhooks.notify(); // deliver order.shipped now instead of at the next poll
    this.logger.log(`Order ${data.orderId} shipped, tracking ${data.trackingNumber}`);
  }
}
```

`markShipped()` is the method from [Send order.shipped and order.cancelled after the commit](/http/webhooks#send-ordershipped-and-ordercancelled-after-the-commit). The deduplication id is the event's `id` from the signed payload, not a header, because that is what Stripe's scheme signs. A `shipment.shipped` event for an order that isn't paid yet is refused with a 409, and nothing is recorded: when the carrier retries it after the payment arrived, the same event id is processed.

#### Other senders[#](/http/webhooks#other-senders)

GitHub's webhooks take `scheme: 'github'`: `X-Hub-Signature-256`, the hex HMAC-SHA256 of the body keyed with the secret's text.

> **Warning** GitHub signs neither a timestamp nor an id. A captured request verifies forever, and deduplication keys by default on the `X-GitHub-Delivery` header, which isn't signed: the same request replayed with a new value in that header runs the handler again.

Key the deduplication on the signed body instead, with the receiver's `id` option. The payload is parsed from the bytes that were signed, so a replay has the same id as the original, and the inbox skips it:

```typescript

receivers: {
  github: {
    scheme: 'github',
    secret: process.env.GITHUB_WEBHOOK_SECRET!,
    // The signed body, not the unsigned X-GitHub-Delivery header: a replayed request has a known id.
    id: (payload) => createHash('sha256').update(JSON.stringify(payload)).digest('hex'),
  },
},
```

The inbox remembers an id until `OutboxInbox.prune()` removes it, so for GitHub its window is also how long a replay is caught: keep it long. Replayed after that, a request verifies and runs; accepting GitHub's webhooks only from the addresses it publishes (`hooks` in `https://api.github.com/meta`) narrows who can send one.

A sender with a scheme of its own is a class extending `WebhookSignatureScheme`. Say the store also sells through a marketplace, which signs the URL it posts to followed by the body, and puts the event's id in the body:

provider-webhooks/marketplace.scheme.ts

JS TS

```typescript

import { WebhookSignatureScheme, type WebhookSignatureCheck, type WebhookSignedRequest } from '@nestjs/webhooks';
import { createHmac } from 'node:crypto';

/**
 * The marketplace's scheme: `X-Marketplace-Signature` is the base64 HMAC-SHA256 of the URL it
 * posts to followed by the body, keyed with the secret's text, and the event's id is in the body.
 * A scheme sees the request's headers and raw body, so the URL comes in through the constructor:
 * the one registered in the marketplace's dashboard.
 */
export class MarketplaceScheme extends WebhookSignatureScheme {
  constructor(private readonly url: string) {
    super();
  }

  verify({ headers, rawBody }: WebhookSignedRequest, keys: readonly Buffer[]): WebhookSignatureCheck {
    const signature = headers['x-marketplace-signature'];
    if (signature === undefined) {
      return { valid: false, reason: 'missing-header', detail: 'no x-marketplace-signature header' };
    }
    if (typeof signature !== 'string') {
      return { valid: false, reason: 'malformed-header', detail: 'x-marketplace-signature is repeated' };
    }

    const candidates = [Buffer.from(signature, 'base64')];
    for (const key of keys) {
      const expected = createHmac('sha256', key).update(this.url).update(rawBody).digest();
      // In constant time, never with ===.
      if (WebhookSignatureScheme.matches(expected, candidates)) {
        return { valid: true };
      }
    }
    return { valid: false, reason: 'invalid-signature', detail: 'no signature matches a configured secret' };
  }

  /** The deduplication id: the event's, from the signed body. */
  override idFromPayload(payload: unknown): string | undefined {
    const id = (payload as { eventId?: unknown } | null)?.eventId;
    return typeof id === 'string' ? id : undefined;
  }
}
```

* `verify(request, keys)` gets the request's `headers` (lower-case names) and its `rawBody`, as received, and one key per configured secret. It returns `valid: true`, with the sender's `id` when a header carries one and the signed `timestamp` in epoch seconds when the scheme signs one (the receiver's `tolerance` then applies), or `valid: false` with a `reason` for the `verification-failed` event and a `detail`. It runs synchronously, before the body is parsed as JSON.
* `WebhookSignatureScheme.matches(expected, candidates)` compares in constant time. Never compare signatures with `===`.
* `idFromPayload(payload, headers)` gives the deduplication id when no header carries one, from the parsed body, as the built-in Stripe scheme does with the event's `id`. An id longer than 255 characters, from either, is refused with `malformed-header`.
* `key(secret)` turns each configured secret into the key `verify()` receives, once, at startup, where a malformed secret stops the application. The default takes the secret's text and refuses an empty one or one with surrounding whitespace. Override it for an encoded secret, as the `standard` scheme does for `whsec_…`.

The receiver takes an instance:

```typescript

receivers: {
  marketplace: {
    scheme: new MarketplaceScheme('https://api.store.example.com/webhooks/marketplace'),
    secret: process.env.MARKETPLACE_WEBHOOK_SECRET!,
  },
},
```

#### Rotate secrets[#](/http/webhooks#rotate-secrets)

A secret leaks, or a partner's policy says a year is enough. `POST /partner/webhook-endpoints/:id/rotate-secret` (see [Let partners subscribe](/http/webhooks#let-partners-subscribe)) returns a new secret, and the old one keeps signing next to it for `secretRotationOverlap`, 24 hours: every delivery carries two `v1,` signatures, and a Standard Webhooks verifier accepts any one that matches. The partner adds the new secret to its list, deploys, removes the old one, on its own schedule. After the overlap, only the new secret signs. `rotateSecret()` with `overlap: 0` retires the old one at once, for a leaked secret.

Set `WEBHOOKS_ENCRYPTION_KEYS` to seal the secrets at rest, `openssl rand -base64 32` for each key, newest first. Endpoints created before are still read (their secrets are plaintext) and sealed at their next rotation.

#### Try it[#](/http/webhooks#try-it)

Create the database, and apply your migrations to it, which create the order API's tables and rows from [Installation](/http/webhooks#installation):

```bash

$ psql postgres://localhost:5432/postgres -c 'CREATE DATABASE store'
```

Export the secrets the payment provider and the carrier share with the store (invented here), allow deliveries to this machine, and start the API on port 3000:

```bash

$ export PAYMENTS_WEBHOOK_SECRET=whsec_$(openssl rand -base64 32)
$ export CARRIER_WEBHOOK_SECRET=carrier_test_$(openssl rand -hex 6)
$ export WEBHOOKS_ALLOW_LOCAL=1
```

```bash

[Nest] 55905  - 09/30/2026, 6:52:36 PM     LOG [OutboxModule] OutboxStorage: PostgresOutboxStore
[Nest] 55905  - 09/30/2026, 6:52:36 PM     LOG [WebhooksModule] WebhooksStorage: PostgresWebhookStore
[Nest] 55905  - 09/30/2026, 6:52:36 PM     LOG [OutboxModule] PostgresOutboxStore: migrated schema "nest_outbox" to version 1.
[Nest] 55905  - 09/30/2026, 6:52:36 PM     LOG [WebhooksModule] PostgresWebhookStore: migrated schema "nest_webhooks" to version 1.
[Nest] 55905  - 09/30/2026, 6:52:36 PM     LOG [NestApplication] Nest application successfully started +2ms
```

Your migrations created the order API's tables, and the stores their schemas, next to them. Northside subscribes, with its API key, to both events at a receiver it will run on port 4100. The response carries the secret, this once:

```bash

$ curl -s -X POST localhost:3000/partner/webhook-endpoints \
    -H 'Authorization: Bearer partner_northside_7c1d2e' \
    --json '{"url":"http://127.0.0.1:4100/store/webhooks","eventTypes":["order.shipped","order.cancelled"],"description":"Warehouse system"}'
{"id":"ep_01a0f33b79e27154b8fd089a10f3e48e","tenant":"northside","url":"http://127.0.0.1:4100/store/webhooks","eventTypes":["order.shipped","order.cancelled"],"description":"Warehouse system","enabled":true,"disabledReason":null,"failingSince":null,"createdAt":1790787156450,"updatedAt":1790787156450,"secret":"whsec_yKaIEKkc0ZpOWofM8Fx1Wc5yxdffKSsP1jolLCynqug="}
$ curl -s localhost:3000/partner/webhook-endpoints -H 'Authorization: Bearer partner_northside_7c1d2e'
[{"id":"ep_01a0f33b79e27154b8fd089a10f3e48e","tenant":"northside","url":"http://127.0.0.1:4100/store/webhooks","eventTypes":["order.shipped","order.cancelled"],"description":"Warehouse system","enabled":true,"disabledReason":null,"failingSince":null,"createdAt":1790787156450,"updatedAt":1790787156450}]
```

> **Hint**`--json` needs curl 7.82 or later.

The URL of a cloud metadata service is refused before anything is stored, and so is an event type the API doesn't send. Riverside Cat Shelter, the other partner, gets a 404 for Northside's endpoint:

```bash

$ curl -s -X POST localhost:3000/partner/webhook-endpoints \
    -H 'Authorization: Bearer partner_northside_7c1d2e' \
    --json '{"url":"https://169.254.169.254/latest/meta-data/","eventTypes":["*"]}'
{"statusCode":400,"message":"Invalid webhook URL: 169.254.169.254 is link-local (cloud metadata)"}
$ curl -s -X POST localhost:3000/partner/webhook-endpoints \
    -H 'Authorization: Bearer partner_northside_7c1d2e' \
    --json '{"url":"https://hooks.northside.example.com/store","eventTypes":["order.paid"]}'
{"statusCode":400,"message":"Unknown message type \"order.paid\". Known: order.shipped, order.cancelled"}
$ curl -s -o /dev/null -w '%{http_code}' localhost:3000/partner/webhook-endpoints/ep_01a0f33b79e27154b8fd089a10f3e48e \
    -H 'Authorization: Bearer partner_riverside_91ab44'
404
```

Start Northside's receiver, `partner-service/main.ts`, on port 4100, with the secret it was given in its environment:

```bash

STORE_WEBHOOK_SECRET=whsec_yKaIEKkc0ZpOWofM8Fx1Wc5yxdffKSsP1jolLCynqug=
```

Now place an order, and let the payment provider pay for it and the carrier ship it. The script signs the requests they would send, with the secrets exported above:

```bash

$ curl -s -X POST localhost:3000/orders \
    -H 'Authorization: Bearer partner_northside_7c1d2e' \
    --json '{"items":[{"productId":"salmon-kibble-2kg","quantity":2}]}'
{"id":"1067d04c-0617-44ac-9a29-67297867329e","partnerId":"northside","items":[{"productId":"salmon-kibble-2kg","quantity":2,"price":2499}],"total":4998,"status":"placed","paymentId":null,"trackingNumber":null}
$ npx tsx scripts/send-webhook.ts payments payment.succeeded \
    '{"paymentId":"pay_8f21c","orderId":"1067d04c-0617-44ac-9a29-67297867329e","amount":4998}'
200
$ npx tsx scripts/send-webhook.ts carrier shipment.shipped \
    '{"orderId":"1067d04c-0617-44ac-9a29-67297867329e","trackingNumber":"TRK-4471-0001"}'
200
$ curl -s localhost:3000/orders/1067d04c-0617-44ac-9a29-67297867329e -H 'Authorization: Bearer partner_northside_7c1d2e'
{"id":"1067d04c-0617-44ac-9a29-67297867329e","partnerId":"northside","items":[{"price":2499,"quantity":2,"productId":"salmon-kibble-2kg"}],"total":4998,"status":"shipped","paymentId":"pay_8f21c","trackingNumber":"TRK-4471-0001"}
```

The API's log shows both webhooks processed, and Northside's log shows `order.shipped` arriving right after the carrier's, with its `webhook-id`:

```bash

[Nest] 55905  - 09/30/2026, 6:52:39 PM     LOG [PaymentProviderWebhooksController] Order 1067d04c-0617-44ac-9a29-67297867329e paid: pay_8f21c, 4998 cents
[Nest] 55905  - 09/30/2026, 6:52:40 PM     LOG [CarrierWebhooksController] Order 1067d04c-0617-44ac-9a29-67297867329e shipped, tracking TRK-4471-0001
```

```bash

[Nest] 56040  - 09/30/2026, 6:52:40 PM     LOG [StoreWebhooksController] Order 1067d04c-0617-44ac-9a29-67297867329e shipped, tracking TRK-4471-0001 (msg_01a0f33b898e7341950339801ec3319a)
```

Northside's delivery log has the delivery, and its details have the message and the one attempt, with the partner's status code and how long it took:

```bash

$ curl -s localhost:3000/partner/webhook-deliveries -H 'Authorization: Bearer partner_northside_7c1d2e'
[{"id":"dlv_01a0f33b89ac720aa76e2c3da97f3c14","messageId":"msg_01a0f33b898e7341950339801ec3319a","endpointId":"ep_01a0f33b79e27154b8fd089a10f3e48e","tenant":"northside","type":"order.shipped","status":"succeeded","attempts":1,"nextAttemptAt":null,"lastAttemptAt":1790787160533,"lastStatusCode":204,"lastError":null,"failureReason":null,"createdAt":1790787160462,"completedAt":1790787160544}]
$ curl -s localhost:3000/partner/webhook-deliveries/dlv_01a0f33b89ac720aa76e2c3da97f3c14 -H 'Authorization: Bearer partner_northside_7c1d2e'
```

```json

{
  "id": "dlv_01a0f33b89ac720aa76e2c3da97f3c14",
  "messageId": "msg_01a0f33b898e7341950339801ec3319a",
  "endpointId": "ep_01a0f33b79e27154b8fd089a10f3e48e",
  "tenant": "northside",
  "type": "order.shipped",
  "status": "succeeded",
  "attempts": 1,
  "nextAttemptAt": null,
  "lastAttemptAt": 1790787160533,
  "lastStatusCode": 204,
  "lastError": null,
  "failureReason": null,
  "createdAt": 1790787160462,
  "completedAt": 1790787160544,
  "message": {
    "id": "msg_01a0f33b898e7341950339801ec3319a",
    "type": "order.shipped",
    "tenant": "northside",
    "body": "{\"type\":\"order.shipped\",\"timestamp\":\"2026-09-30T16:52:40.462Z\",\"data\":{\"orderId\":\"1067d04c-0617-44ac-9a29-67297867329e\",\"trackingNumber\":\"TRK-4471-0001\"}}",
    "createdAt": 1790787160462
  },
  "history": [
    { "deliveryId": "dlv_01a0f33b89ac720aa76e2c3da97f3c14", "attempt": 1, "at": 1790787160533, "durationMs": 11, "statusCode": 204, "response": "", "error": null }
  ]
}
```

Stop Northside's receiver with `Ctrl+C`, then place an order and cancel it. The delivery fails to connect, the API logs the wait before the next attempt, and the partner's log shows the delivery pending with its error:

```bash

$ curl -s -X POST localhost:3000/orders \
    -H 'Authorization: Bearer partner_northside_7c1d2e' \
    --json '{"items":[{"productId":"clumping-litter-10l","quantity":1}]}'
{"id":"d6a36832-6b83-40f6-960b-0c6aa905ae18","partnerId":"northside","items":[{"productId":"clumping-litter-10l","quantity":1,"price":1599}],"total":1599,"status":"placed","paymentId":null,"trackingNumber":null}
$ curl -s -X POST localhost:3000/orders/d6a36832-6b83-40f6-960b-0c6aa905ae18/cancel \
    -H 'Authorization: Bearer partner_northside_7c1d2e' \
    --json '{"reason":"out of stock"}'
{"id":"d6a36832-6b83-40f6-960b-0c6aa905ae18","partnerId":"northside","items":[{"price":1599,"quantity":1,"productId":"clumping-litter-10l"}],"total":1599,"status":"cancelled","paymentId":null,"trackingNumber":null}
$ curl -s 'localhost:3000/partner/webhook-deliveries?status=pending' -H 'Authorization: Bearer partner_northside_7c1d2e'
[{"id":"dlv_01a0f33b8f51724da606406a85418fab","messageId":"msg_01a0f33b8f367090b44d3de36eed8f13","endpointId":"ep_01a0f33b79e27154b8fd089a10f3e48e","tenant":"northside","type":"order.cancelled","status":"pending","attempts":1,"nextAttemptAt":1790787164580,"lastAttemptAt":1790787161969,"lastStatusCode":null,"lastError":"Error: connect ECONNREFUSED 127.0.0.1:4100","failureReason":null,"createdAt":1790787161910,"completedAt":null}]
```

```bash

[Nest] 55905  - 09/30/2026, 6:52:42 PM    WARN [WebhookWorker] Retrying webhook delivery dlv_01a0f33b8f51724da606406a85418fab (order.cancelled) in 2609ms (attempt 1 of 10 failed): Error: connect ECONNREFUSED 127.0.0.1:4100
```

Start the receiver again. The retry goes through, and the log keeps both attempts:

```bash

[Nest] 56304  - 09/30/2026, 6:52:45 PM     LOG [StoreWebhooksController] Order d6a36832-6b83-40f6-960b-0c6aa905ae18 cancelled: out of stock (msg_01a0f33b8f367090b44d3de36eed8f13)
```

```bash

$ curl -s localhost:3000/partner/webhook-deliveries/dlv_01a0f33b8f51724da606406a85418fab -H 'Authorization: Bearer partner_northside_7c1d2e'
```

```json

{
  "id": "dlv_01a0f33b8f51724da606406a85418fab",
  "type": "order.cancelled",
  "status": "succeeded",
  "attempts": 2,
  "lastStatusCode": 204,
  "history": [
    { "attempt": 1, "at": 1790787161969, "durationMs": 2, "statusCode": null, "response": null, "error": "Error: connect ECONNREFUSED 127.0.0.1:4100" },
    { "attempt": 2, "at": 1790787165060, "durationMs": 11, "statusCode": 204, "response": "", "error": null }
  ]
}
```

Northside asks for that delivery again. It is sent with the same `webhook-id`, the receiver's inbox recognizes it and answers 204 without running the handler (nothing new in its log), and the delivery log shows a new round:

```bash

$ curl -s -X POST localhost:3000/partner/webhook-deliveries/dlv_01a0f33b8f51724da606406a85418fab/retry \
    -H 'Authorization: Bearer partner_northside_7c1d2e'
{"retried":1}
$ curl -s localhost:3000/partner/webhook-deliveries/dlv_01a0f33b8f51724da606406a85418fab -H 'Authorization: Bearer partner_northside_7c1d2e'
```

```json

{
  "status": "succeeded",
  "attempts": 1,
  "history": [
    { "attempt": 1, "at": 1790787161969, "statusCode": null, "error": "Error: connect ECONNREFUSED 127.0.0.1:4100" },
    { "attempt": 2, "at": 1790787165060, "statusCode": 204, "error": null },
    { "attempt": 1, "at": 1790787166185, "statusCode": 204, "error": null }
  ]
}
```

Now the payment provider's side. A redelivery with the same `webhook-id` (a lost 200, so the provider retried) is answered but not processed again: the API logs one payment. A tampered body and a wrong secret are refused, without a reason:

```bash

$ curl -s -X POST localhost:3000/orders \
    -H 'Authorization: Bearer partner_northside_7c1d2e' \
    --json '{"items":[{"productId":"salmon-kibble-2kg","quantity":1}]}'
{"id":"d7dbe1ab-c408-4688-9e9e-2925ed2025a3","partnerId":"northside","items":[{"productId":"salmon-kibble-2kg","quantity":1,"price":2499}],"total":2499,"status":"placed","paymentId":null,"trackingNumber":null}
$ WEBHOOK_ID=msg_2c9e4f1a npx tsx scripts/send-webhook.ts payments payment.succeeded \
    '{"paymentId":"pay_9d0a2","orderId":"d7dbe1ab-c408-4688-9e9e-2925ed2025a3","amount":2499}'
200
$ WEBHOOK_ID=msg_2c9e4f1a npx tsx scripts/send-webhook.ts payments payment.succeeded \
    '{"paymentId":"pay_9d0a2","orderId":"d7dbe1ab-c408-4688-9e9e-2925ed2025a3","amount":2499}'
200
$ TAMPER=1 npx tsx scripts/send-webhook.ts payments payment.succeeded \
    '{"paymentId":"pay_9d0a2","orderId":"d7dbe1ab-c408-4688-9e9e-2925ed2025a3","amount":2499}'
401 {"message":"Webhook signature verification failed","error":"Unauthorized","statusCode":401}
$ PAYMENTS_WEBHOOK_SECRET=whsec_$(openssl rand -base64 32) npx tsx scripts/send-webhook.ts payments payment.succeeded \
    '{"paymentId":"pay_9d0a2","orderId":"d7dbe1ab-c408-4688-9e9e-2925ed2025a3","amount":2499}'
401 {"message":"Webhook signature verification failed","error":"Unauthorized","statusCode":401}
```

```bash

[Nest] 55905  - 09/30/2026, 6:52:48 PM     LOG [PaymentProviderWebhooksController] Order d7dbe1ab-c408-4688-9e9e-2925ed2025a3 paid: pay_9d0a2, 2499 cents
```

Finally, rotate the endpoint's secret. The receiver still runs with the old one, and the next delivery verifies anyway: it carries both signatures. Then restart the receiver with the new secret listed first and the old one behind it, as a partner would deploy it, and place and cancel another order: that delivery verifies too:

```bash

$ curl -s -X POST localhost:3000/partner/webhook-endpoints/ep_01a0f33b79e27154b8fd089a10f3e48e/rotate-secret \
    -H 'Authorization: Bearer partner_northside_7c1d2e'
{"secret":"whsec_BUPv/LlKhv9qDH7udP3gsGPquuj4WaopeP8fxyouWOk="}
$ curl -s -X POST localhost:3000/orders/d7dbe1ab-c408-4688-9e9e-2925ed2025a3/cancel \
    -H 'Authorization: Bearer partner_northside_7c1d2e' \
    --json '{"reason":"customer changed their mind"}'
{"id":"d7dbe1ab-c408-4688-9e9e-2925ed2025a3","partnerId":"northside","items":[{"price":2499,"quantity":1,"productId":"salmon-kibble-2kg"}],"total":2499,"status":"cancelled","paymentId":"pay_9d0a2","trackingNumber":null}
```

```bash

[Nest] 56304  - 09/30/2026, 6:52:50 PM     LOG [StoreWebhooksController] Order d7dbe1ab-c408-4688-9e9e-2925ed2025a3 cancelled: customer changed their mind (msg_01a0f33bb022712e8e440b7adef8208f)
```

```bash

STORE_WEBHOOK_SECRET=whsec_BUPv/LlKhv9qDH7udP3gsGPquuj4WaopeP8fxyouWOk=,whsec_yKaIEKkc0ZpOWofM8Fx1Wc5yxdffKSsP1jolLCynqug=
```

```bash

$ curl -s -X POST localhost:3000/orders \
    -H 'Authorization: Bearer partner_northside_7c1d2e' \
    --json '{"items":[{"productId":"clumping-litter-10l","quantity":2}]}'
{"id":"d203fd6f-7396-489b-9d20-775cd8a6ca4e","partnerId":"northside","items":[{"productId":"clumping-litter-10l","quantity":2,"price":1599}],"total":3198,"status":"placed","paymentId":null,"trackingNumber":null}
$ curl -s -X POST localhost:3000/orders/d203fd6f-7396-489b-9d20-775cd8a6ca4e/cancel \
    -H 'Authorization: Bearer partner_northside_7c1d2e' \
    --json '{"reason":"ordered twice"}'
{"id":"d203fd6f-7396-489b-9d20-775cd8a6ca4e","partnerId":"northside","items":[{"price":1599,"quantity":2,"productId":"clumping-litter-10l"}],"total":3198,"status":"cancelled","paymentId":null,"trackingNumber":null}
```

```bash

[Nest] 56624  - 09/30/2026, 6:52:52 PM     LOG [StoreWebhooksController] Order d203fd6f-7396-489b-9d20-775cd8a6ca4e cancelled: ordered twice (msg_01a0f33bb8ad7249a0fa069361100c49)
```

The deliveries are rows in your database, in the store's schema:

```bash

$ psql "$DATABASE_URL" -c "SELECT type, status, attempts, last_status_code FROM nest_webhooks.deliveries ORDER BY created_at"
      type       |  status   | attempts | last_status_code
-----------------+-----------+----------+------------------
 order.shipped   | succeeded |        1 |              204
 order.cancelled | succeeded |        1 |              204
 order.cancelled | succeeded |        1 |              204
 order.cancelled | succeeded |        1 |              204
(4 rows)
```

#### Testing[#](/http/webhooks#testing)

In an e2e test, run PostgreSQL in-process with [PGlite](https://pglite.dev) and your real migrations, turn the relay and the worker off, replace the transport with the one that records requests, and sign the providers' requests with `signWebhook()`. Override the database `DrizzleModule` registers (`getDrizzleToken()` returns its token) with one on PGlite: the stores follow, because their factories inject it, and create their schemas there when the application starts:

test/webhooks.e2e-spec.ts

JS TS

```typescript

import { PGlite } from '@electric-sql/pglite';
import type { INestApplication } from '@nestjs/common';
import { getDrizzleToken } from '@nestjs/drizzle';
import { OutboxRelay } from '@nestjs/outbox';
import { Test } from '@nestjs/testing';
import { InMemoryWebhookTransport, WebhookEndpoints, WebhookTransport, WebhookWorker } from '@nestjs/webhooks';
import { signWebhook } from '@nestjs/webhooks/testing';
import { drizzle } from 'drizzle-orm/pglite';
import { migrate } from 'drizzle-orm/pglite/migrator';
import { fileURLToPath } from 'node:url';
import request from 'supertest';
import { afterAll, beforeAll, describe, expect, it } from 'vitest';
import { AppModule } from '../src/app.module.js';
import * as schema from '../src/database/schema.js';
import { OrdersService } from '../src/orders/orders.service.js';

const PAYMENTS_SECRET = `whsec_${Buffer.alloc(32, 1).toString('base64')}`;
const CARRIER_SECRET = 'carrier_test_secret';

describe('Order webhooks', () => {
  const client = new PGlite(); // PostgreSQL, in-process
  const db = drizzle(client, { schema });
  const transport = new InMemoryWebhookTransport(); // records requests instead of sending them
  const partner = { id: 'northside', name: 'Northside Pet Supplies' };
  let app: INestApplication;
  let relay: OutboxRelay;
  let worker: WebhookWorker;
  let endpoint: { id: string; secret: string };

  beforeAll(async () => {
    // The real migrations: the order tables. The stores create their schemas when the app starts.
    await migrate(db, { migrationsFolder: fileURLToPath(new URL('../drizzle', import.meta.url)) });
    process.env.PAYMENTS_WEBHOOK_SECRET = PAYMENTS_SECRET;
    process.env.CARRIER_WEBHOOK_SECRET = CARRIER_SECRET;
    process.env.OUTBOX_RELAY = 'off'; // no poll loops: the test drives the relay and the worker
    process.env.WEBHOOKS_WORKER = 'off';
    const moduleRef = await Test.createTestingModule({ imports: [AppModule] })
      .overrideProvider(getDrizzleToken())
      .useValue(db) // the stores' factories inject it too
      .overrideProvider(WebhookTransport)
      .useValue(transport)
      .compile();
    app = moduleRef.createNestApplication({ rawBody: true });
    await app.init();
    relay = app.get(OutboxRelay);
    worker = app.get(WebhookWorker);
    endpoint = await app.get(WebhookEndpoints).create({ url: 'https://hooks.northside.example.com/store', eventTypes: ['*'], tenant: partner.id });
  });

  afterAll(async () => {
    await app.close();
    await client.close();
  });

  /** Publishes committed messages (the fan-out), then runs one worker batch. */
  const deliver = async () => {
    await relay.runOnce();
    return worker.runOnce();
  };
  const shipment = (orderId: string, id = 'evt_1') =>
    signWebhook({
      scheme: 'stripe',
      header: 'Carrier-Signature',
      secret: CARRIER_SECRET,
      payload: { id, type: 'shipment.shipped', data: { orderId, trackingNumber: 'TRK-1' } },
    });

  it("sends order.shipped to the partner once the carrier's webhook commits", async () => {
    const order = await app.get(OrdersService).placeOrder(partner, { items: [{ productId: 'salmon-kibble-2kg', quantity: 1 }] });
    const paid = signWebhook({
      scheme: 'standard',
      secret: PAYMENTS_SECRET,
      payload: { type: 'payment.succeeded', data: { paymentId: 'pay_1', orderId: order.id, amount: order.total } },
    });
    await request(app.getHttpServer()).post('/webhooks/payments').set(paid.headers).send(paid.body).expect(200);
    const shipped = shipment(order.id);
    await request(app.getHttpServer()).post('/webhooks/carrier').set(shipped.headers).send(shipped.body).expect(200);
    expect(transport.sent).toEqual([]); // nothing until the outbox relays the commit

    expect(await deliver()).toMatchObject({ delivered: 1 });

    const sent = transport.single({ type: 'order.shipped', endpointId: endpoint.id });
    expect(sent.data).toEqual({ orderId: order.id, trackingNumber: 'TRK-1' });
    expect(sent.isSignedWith(endpoint.secret)).toBe(true);
  });

  it('processes a redelivered shipment webhook once', async () => {
    const [order] = await db.select().from(schema.orders);
    const shipped = shipment(order!.id);
    await request(app.getHttpServer()).post('/webhooks/carrier').set(shipped.headers).send(shipped.body).expect(200, '');
    expect(await deliver()).toMatchObject({ claimed: 0 });
    expect(transport.sent).toHaveLength(1);
  });

  it('refuses a webhook whose body was altered', async () => {
    const shipped = shipment('order-x', 'evt_2');
    await request(app.getHttpServer())
      .post('/webhooks/carrier')
      .set(shipped.headers)
      .send(shipped.body.replace('TRK-1', 'TRK-2'))
      .expect(401);
    expect(await deliver()).toMatchObject({ claimed: 0 });
  });
});
```

* The outbox, both stores, the migrations, the fan-out, the signing and the verification are real. Only the network is replaced: `InMemoryWebhookTransport` answers 200 and keeps every request, and `respondWith(503)` or a function simulates a partner that is down, slow or picky.
* `deliver()` is the whole pipeline after the commit: `relay.runOnce()` publishes the committed messages (the fan-out creates the deliveries), `worker.runOnce()` claims one batch and sends it.
* `SentWebhook.isSignedWith(secret)` verifies the `v1` signature with an endpoint's secret, and `data` is the body's `data`, so a test asserts on what the partner would have verified and read.
* `signWebhook()` produces the body and headers the payment provider, Stripe or GitHub would send. Reuse its `id` for a redelivery, move `timestamp` to test the tolerance, change a byte of the body for a tampered request.
* For behavior that depends on time, such as backoff, leases and the rotation overlap, move `Date.now()` forward with `vi.spyOn(Date, 'now')`. The worker and the stores take the time from it, and real timers keep running for sockets.
* The example's `tutorial.e2e-spec.ts` runs every section of this page over real HTTP, on PGlite and on a PostgreSQL server: the API delivers to the partner's receiver through the default transport, with the outage, the replay, the redeliveries and the rotation. Its `zod.e2e-spec.ts` boots the same app with the Zod variants of the DTOs and `StandardSchemaValidationPipe`. Its store tests run the stores through Drizzle on PGlite, PostgreSQL and MySQL, and through TypeORM on PostgreSQL: the contract suites, a dispatch that commits and rolls back with the order, and the schemas in production.

See [End-to-end testing](/fundamentals/testing#end-to-end-testing) for more about the testing setup.

#### Delivery guarantees[#](/http/webhooks#delivery-guarantees)

Outgoing webhooks are delivered **at least once**; the receiver deduplicates by `webhook-id`.

| Situation                                                             | Outcome                                                                                                 |
| --------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- |
| The order's transaction rolls back                                    | The message never existed and nothing is sent                                                           |
| The order's transaction commits                                       | One delivery per subscribed endpoint of the tenant, eventually delivered or failed with its attempt log |
| The outbox redelivers the message (a relay crashed after the fan-out) | The fan-out is idempotent: one delivery per message and endpoint                                        |
| The endpoint was created after the message, or is disabled            | It doesn't receive it, and a replay doesn't bring it back                                               |
| A worker dies after claiming                                          | Sent by another worker once the lease expires (`worker.lease`, 1 minute)                                |
| A worker dies after sending, before recording                         | **Sent twice**, with the same `webhook-id`, once the lease expires                                      |
| Two workers, same delivery                                            | A claim is exclusive for the lease, and every later write is fenced by it                               |
| The partner answers 2xx                                               | Delivered                                                                                               |
| It answers anything else, or nothing                                  | Retried with backoff, `Retry-After` honored; 429, 502, 503 and 504 pace the endpoint                    |
| It answers 410 Gone                                                   | Failed (`rejected`), and the endpoint is disabled (`gone`)                                              |
| Every attempt fails for `disableEndpointAfter`                        | The endpoint is disabled (`failing`), once                                                              |
| A partner asks for a replay                                           | A new round with the same `webhook-id`, so its inbox skips it                                           |

Deliveries have **no order**. A worker sends one endpoint's deliveries one at a time, most overdue first, but a failed attempt waits out its backoff while later messages go out, several workers send to the same endpoint at once, and a replay sends an old message now. Two updates of one order can reach the partner in either order. Receivers cope as they do with duplicates: the body's `timestamp` is when the message was dispatched (`webhook-timestamp` is when this attempt was signed), so a handler can ignore an event older than the state it already holds, or treat the webhook as a signal and read the current state from the API.

Incoming webhooks run their handler **once per webhook id and receiver in the common case** with the default inbox (again after a crash between the handler and the inbox write, or when two copies race on two instances), and their `processInTransaction()` work **exactly once**.

#### Production checklist[#](/http/webhooks#production-checklist)

* Keep the endpoints and the deliveries in your application's database, on a database server: register `PostgresWebhookStore`, or `MySqlWebhookStore`, and the outbox's store next to it ([Keep webhooks in your database](/http/webhooks#keep-webhooks-in-your-database)). The production guard refuses to start in memory; `allowInMemoryStorage` is for a process whose pending deliveries you can afford to lose.
* Apply both stores' migrations before a new version starts, with `npx @nestjs/webhooks migrate` and `npx @nestjs/outbox migrate` or your migration tool, and check them in CI with `status`. With `NODE_ENV=production`, the stores don't migrate at startup: a schema that's behind fails it instead.
* On PostgreSQL, keep the database's default isolation at READ COMMITTED: the stores refuse a stricter one. On MySQL, run a transaction again when MySQL breaks a deadlock in it (error 1213): it rolled back, with the messages it dispatched and the webhooks it recorded.
* Leave `delivery.allowHttp` and `delivery.allowPrivateNetworks` off. A partner's URL is untrusted input, and the transport resolves it itself and pins the address it checked. Use `allowedAddresses` for the one private range you really deliver to, and alert on `destination-blocked` events: a customer pointing a webhook at your metadata service is worth a look.
* Run the worker in a few instances (`WEBHOOKS_WORKER`), not in every API pod: each claim is a short transaction, and the leases keep them from sending the same delivery twice.
* Alert on `lagMs` and `failed` from `deliveries.stats()`, and on `endpoint-disabled`: tell the partner, by email, that their endpoint was switched off and why.
* Version the payloads. A partner keeps its handler for years, and `retry()` re-sends the body as it was dispatched. Add fields to a type's `data`, never rename or remove one. For a breaking change, add a new type, `order.shipped.v2` in `eventTypes`, and dispatch both in the same transaction (`dispatch()` takes an array) while partners move their subscriptions over; an endpoint subscribed to `*` gets both. Then stop dispatching the old type. Replays of older messages still carry the old shape until the log is pruned.
* Give partners the delivery log and the replay. It answers "did you send it?" before they open a ticket.
* Rotate secrets with the overlap, never with `overlap: 0` unless a secret leaked, and seal them at rest with `WEBHOOKS_ENCRYPTION_KEYS`. Keep the keys in a secret manager.
* Prune the log. `deliveries.prune('30d')` from a [cron job](/application/task-scheduling#declarative-cron-jobs); nothing schedules it for you.
* For incoming webhooks, keep `rawBody: true`, and keep the receivers' secrets in the environment. List the old and the new secret while a provider rotates.
* Keep provider handlers short and idempotent in their own right (a status check inside the transaction), even with `processInTransaction()`: the inbox protects against a redelivery, the check against a provider that sends two different events for one fact.
* Prune the inbox with `OutboxInbox.prune()` on a window longer than any provider's retry schedule (Stripe retries for three days, GitHub doesn't retry at all). For GitHub, that window is also how long a replayed request is caught, with the deduplication keyed on the body ([Other senders](/http/webhooks#other-senders)).
* Call `app.enableShutdownHooks()`, so a deploy lets attempts in flight finish and releases the rest.
* For a store of your own, run the contract suites with `concurrent: true` in CI, against the database version you run in production.

#### The store contract[#](/http/webhooks#the-store-contract)

`PostgresWebhookStore` and `MySqlWebhookStore` implement both of the package's contracts, `WebhookEndpointStore` and `WebhookDeliveryStore`. For another database, implement them in a provider of your own. The JSDoc of each method in the two interfaces states its rule, and the race it prevents.

**Registration.** The store is an ordinary singleton provider that calls `registerSource()` on the injectable `WebhooksStorage` in its constructor, naming the contracts it implements: `endpoints`, `deliveries`, or both from one class. The registry checks the shape at once, refuses a second registration unless it passes `replace: true`, and locks when `WebhooksModule` initializes, logging the store in use. With nothing registered, the module uses `InMemoryWebhookStore`, which loses the endpoints and the pending deliveries on restart and can't share them between instances. With `NODE_ENV=production`, startup fails instead, unless `allowInMemoryStorage: true` accepts that.

**No transaction handle.** Unlike the outbox's `add()`, no method here takes your transaction: the outbox carries the message out of your transaction, and the webhook store runs on its own connections.

**The methods.** The ones marked atomic are one conditional statement or one transaction with a row lock, never a read followed by a write; they are the ones the contract suites race.

| Method                                                                                 | What it does                                                                                                           | Atomic                                                                             |
| -------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- |
| `createEndpoint`, `getEndpoint`, `listEndpoints`, `updateEndpoint`, `deleteEndpoint`   | An endpoint's lifecycle; `list` newest first, by tenant                                                                | No                                                                                 |
| `findSubscribedEndpoints(tenant, type)`                                                | The enabled endpoints of exactly this tenant subscribed to the type (or `*`): the fan-out's query                      | No, but the suite checks it never returns another tenant's                         |
| `addEndpointSecret(id, secret, expireOthersAt, now)`                                   | The rotation: the new secret first, the others expiring                                                                | Yes: the row is locked, so two rotations both land                                 |
| `recordEndpointFailure(id, failure)`                                                   | Sets `failingSince` on the first failure; disables the endpoint once it has been failing long enough, and says so once | Yes: the row is locked                                                             |
| `recordEndpointSuccess(id)`                                                            | Clears `failingSince`                                                                                                  | No                                                                                 |
| `createDeliveries(message, deliveries)`                                                | The fan-out: the message unless it exists, each delivery unless its `(messageId, endpointId)` exists                   | Yes: a unique key on the pair, such as PostgreSQL's `ON CONFLICT DO NOTHING` on it |
| `claimDeliveries(request)`                                                             | Leases due deliveries, most overdue first, with their message                                                          | Yes: `FOR UPDATE SKIP LOCKED`, then the lease                                      |
| `recordDeliveryAttempt(id, owner, update)`                                             | The attempt's outcome and log row, if `owner` still holds the lease                                                    | Yes: fenced by the lease owner                                                     |
| `releaseDeliveries(ids, owner, nextAttemptAt)`                                         | Gives leases back, postponing when asked                                                                               | Yes: fenced                                                                        |
| `getDelivery`, `getMessage`, `listDeliveries`, `listDeliveryAttempts`, `deliveryStats` | Reads; `list` newest first, by tenant, endpoint, message, status and type                                              | No                                                                                 |
| `retryDeliveries(filter, now)`                                                         | A new round for the matches that aren't leased                                                                         | Yes: one `UPDATE` with the lease in its `WHERE`                                    |
| `pruneDeliveries(before)`                                                              | Finished deliveries older than `before`, their logs, and the messages left without deliveries                          | No, but never a pending delivery                                                   |

**Test it** with `webhookEndpointStoreContract()` and `webhookDeliveryStoreContract()` from `@nestjs/webhooks/testing`. Each case gets a store on empty tables from the function you pass. The tutorial's tests run both suites against `PostgresWebhookStore` through Drizzle, as you would against yours:

test/drizzle-webhook.store.e2e-spec.ts

JS TS

```typescript

/** A store on emptied tables, built the way Nest builds it: with the database and a registry. */
async function freshStore(db: Database) {
  await db.execute(sql.raw(`TRUNCATE ${STORE_TABLES.join(', ')} RESTART IDENTITY`));
  return { store: new PostgresWebhookStore({ executor: fromDrizzle(db) }, new WebhooksStorage()) };
}

// ...

// The concurrency cases run too; with one connection, PGlite runs them one statement at a time.
describe('the endpoint contract', () => {
  for (const c of webhookEndpointStoreContract(() => freshStore(db), { concurrent: true })) {
    it(c.name, c.run);
  }
});
describe('the delivery contract', () => {
  for (const c of webhookDeliveryStoreContract(() => freshStore(db), { concurrent: true })) {
    it(c.name, c.run);
  }
});
```

With `concurrent: true`, the suites race rotations and failures on one endpoint, workers claiming side by side, fan-outs of one message, a stale worker against a takeover, and a retry against a claim. On PGlite, with one connection, they pass serialized: run them on a server too, through a pool of several connections, where a store without the right locks fails them. The package's own tests run the suites against a hand-written Drizzle store, as the proof that a store written against the interfaces passes them.

#### Reference[#](/http/webhooks#reference)

##### Module options[#](/http/webhooks#module-options)

`WebhooksModule.forRoot()` takes these options. `forRootAsync()` takes `outgoing`, `transport` (as a class), `imports` and `isGlobal` at the top level, next to `useFactory`, `useClass` or `useExisting`, and the factory returns the rest. See [Register the modules](/http/webhooks#register-the-modules).

| Option                          | Default                | Description                                                                                                                                                                                                                   |
| ------------------------------- | ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `eventTypes`                    | any type               | The message types this application sends. `dispatch()` and new endpoints accept only these (endpoints also accept `*`).                                                                                                       |
| `retry`                         | 10 attempts            | `attempts` (including the first), `backoff` and `retryIf(error, attempt, delivery)`. A number sets `attempts`, and `false` means a single attempt.                                                                            |
| `retry.backoff`                 | see description        | `delay` (`'5s'`), `factor` (4), `maxDelay` (`'1d'`, also the cap for `Retry-After`), `jitter`: `'equal'`, `'full'` or `'none'` (`'equal'`). Or a function of the attempt, the error and the delivery that returns a duration. |
| `disableEndpointAfter`          | `'5d'`                 | Disables an endpoint that has failed every attempt for this long without a success. `false` never disables one.                                                                                                               |
| `secretRotationOverlap`         | `'24h'`                | How long a rotated-out secret keeps signing next to the new one.                                                                                                                                                              |
| `delivery.timeout`              | `'15s'`                | One attempt: DNS, connection, TLS, request and response. Shorter than `worker.lease`.                                                                                                                                         |
| `delivery.allowHttp`            | `false`                | Accepts `http://` endpoint URLs. For development.                                                                                                                                                                             |
| `delivery.allowPrivateNetworks` | `false`                | Delivers to loopback, private, shared-address and unique-local ranges. For development. Link-local and cloud metadata addresses stay blocked.                                                                                 |
| `delivery.allowedAddresses`     | none                   | CIDR ranges, such as `10.20.0.0/16`, delivered to although they'd be blocked.                                                                                                                                                 |
| `delivery.maxResponseSize`      | 4096                   | Bytes of the response body read and kept in the log.                                                                                                                                                                          |
| `delivery.userAgent`            | `NestJS-Webhooks/1.0`  | The `User-Agent` header.                                                                                                                                                                                                      |
| `worker.enabled`                | `true`                 | Delivers in this process. `false` in instances that only dispatch.                                                                                                                                                            |
| `worker.pollInterval`           | `'1s'`                 | The wait between polls when idle. `notify()` polls at once.                                                                                                                                                                   |
| `worker.batchSize`              | 50                     | Deliveries claimed per poll.                                                                                                                                                                                                  |
| `worker.concurrency`            | 10                     | Endpoints delivered to in parallel. One endpoint's deliveries go one at a time.                                                                                                                                               |
| `worker.lease`                  | `'1m'`                 | How long a claim is exclusive. Longer than `delivery.timeout`.                                                                                                                                                                |
| `encryption`                    | off                    | Seals endpoint secrets at rest. `keys` lists 32-byte `Buffer`s or strings of at least 32 characters, newest first: the first key encrypts, every key decrypts.                                                                |
| `receivers`                     | none                   | The senders whose webhooks this application accepts, by the name `@VerifyWebhook()` uses (see the next table).                                                                                                                |
| `transport`                     | `HttpWebhookTransport` | A `WebhookTransport` class at the top level, or an instance from the async factory.                                                                                                                                           |
| `allowInMemoryStorage`          | `false`                | Lets a production application start without registered stores.                                                                                                                                                                |
| `outgoing`                      | `true`                 | Top level only. `false` in a service that only receives webhooks: no endpoints, deliveries, worker or stores.                                                                                                                 |
| `imports`                       | none                   | Top level only. Modules whose exports a transport class injects.                                                                                                                                                              |
| `isGlobal`                      | `true`                 | Top level only. Registers the module globally.                                                                                                                                                                                |

Durations are milliseconds or strings such as `'15s'`, `'24h'` or `'5d'`. The options' injection token is `WEBHOOKS_MODULE_OPTIONS`.

Each entry of `receivers` takes these options (see [Receive the payment provider's webhooks](/http/webhooks#receive-the-payment-providers-webhooks) and [Receive the carrier's Stripe-like webhooks](/http/webhooks#receive-the-carriers-stripe-like-webhooks)):

| Option      | Applies to                   | Default                                                                                                                    | Description                                                                                                                              |
| ----------- | ---------------------------- | -------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| `scheme`    | all                          | required                                                                                                                   | `'standard'`, `'stripe'`, `'github'`, or an instance of a class extending `WebhookSignatureScheme`                                       |
| `secret`    | all                          | required                                                                                                                   | One secret, or an array while the sender rotates. Every one is tried.                                                                    |
| `tolerance` | `standard`, `stripe`, custom | `'5m'`                                                                                                                     | The largest accepted distance between the signed timestamp and now, in either direction                                                  |
| `header`    | `stripe`                     | `'stripe-signature'`                                                                                                       | The signature header, for senders that copied Stripe's scheme                                                                            |
| `id`        | `stripe`, `github`           | the payload's `id`; the `X-GitHub-Delivery` header, which isn't signed (see [Other senders](/http/webhooks#other-senders)) | A function of the payload and the headers that returns the deduplication id, of at most 255 characters                                   |
| `dedupe`    | all                          | `true`                                                                                                                     | Skips a webhook id this receiver already processed                                                                                       |
| `consumer`  | all                          | `webhooks:<name>`                                                                                                          | The inbox consumer name. Keep it stable. At most 255 characters, the default included: a longer one fails the startup with a `TypeError` |

##### PostgreSQL and MySQL stores[#](/http/webhooks#postgresql-and-mysql-stores)

`new PostgresWebhookStore(options, webhooksStorage)`, from `@nestjs/webhooks/postgres`, and `new MySqlWebhookStore(options, webhooksStorage)`, from `@nestjs/webhooks/mysql`, take these options. The outbox's `PostgresOutboxStore` and `MySqlOutboxStore` take the same, with `'nest_outbox'` as the default `schema`:

| Option     | Default                                   | Meaning                                                                                                                                                                                                                                                                                                                                                    |
| ---------- | ----------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `executor` | Required                                  | How the store reaches the database: `fromDrizzle(db)`, `fromTypeOrm(dataSource)`, `fromPrisma(prisma, options)`, `fromKysely(db)`, and `fromPg(pool)` on PostgreSQL or `fromMysql2(pool)` on MySQL, imported from the store's own subpath: the other dialect's executor doesn't compile                                                                    |
| `schema`   | `'nest_webhooks'`                         | On PostgreSQL, the schema of its tables, which its first migration creates: letters, digits and underscores, not starting with a digit, at most 63 characters. On MySQL, the prefix of its tables in the connection's database (`nest_webhooks_endpoints`...): lowercase letters, digits and underscores, not starting with a digit, at most 40 characters |
| `migrate`  | `true`, except with `NODE_ENV=production` | Apply the pending migrations when the application starts. With `false`, startup fails with a `WebhookSchemaError` while the schema is behind                                                                                                                                                                                                               |

Each executor takes your database client, and its own kind of transaction object, which `dispatch()` and `processInTransaction()` then take:

| Executor                      | Takes                                                                                                                                                                                                        | Transaction object                                                                                                    |
| ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------- |
| `fromDrizzle(db)`             | A Drizzle database: on PostgreSQL, whichever its driver; on MySQL, `drizzle-orm/mysql2`'s                                                                                                                    | The `tx` that `db.transaction()` hands its callback                                                                   |
| `fromTypeOrm(dataSource)`     | A `DataSource` of type `postgres` or `mysql`                                                                                                                                                                 | The `EntityManager` that `dataSource.transaction()` hands its callback, or a `QueryRunner` after `startTransaction()` |
| `fromPg(pool)`                | A node-postgres `Pool`, on PostgreSQL                                                                                                                                                                        | A client from `pool.connect()`, after `BEGIN`                                                                         |
| `fromMysql2(pool)`            | A `mysql2/promise` pool, on MySQL                                                                                                                                                                            | A connection from `pool.getConnection()`, after `beginTransaction()`                                                  |
| `fromPrisma(prisma, options)` | A Prisma client, through a driver adapter such as `@prisma/adapter-pg`, or `@prisma/adapter-mariadb` on MySQL. `maxWait` (default `'10s'`) and `timeout` (default `'1m'`) limit the stores' own transactions | The transaction client that `prisma.$transaction()` hands its callback                                                |
| `fromKysely(db)`              | A `Kysely` instance with a PostgreSQL or MySQL dialect                                                                                                                                                       | The transaction that `db.transaction().execute()` hands its callback                                                  |

The store's `migrate()` method applies the pending migrations at once, whatever the `migrate` option says, and resolves with the versions it applied. `PostgresWebhookStore.migrationSql()` and `MySqlWebhookStore.migrationSql()` return their SQL, with the bookkeeping. Their options are the `schema`, the versions to go `from` (default `0`, a new database) and `to` (default: the one the package needs), and `statementBreakpoints`, which puts drizzle-kit's `--> statement-breakpoint` between the statements. On PostgreSQL, from version 0, the SQL starts with `CREATE SCHEMA IF NOT EXISTS`, which needs the CREATE privilege on the database: leave it out if someone created the schema for you. `MySqlWebhookStore.migrationStatements()` returns MySQL's statements one per string, to run in order, each once. `schemaVersion` is the version the package needs. A schema's own version is the highest applied in its `migrations` table.

The command line, `npx @nestjs/webhooks`, takes `--url` (default `DATABASE_URL`), whose scheme picks the store: `postgres://` or `postgresql://` for `PostgresWebhookStore`'s schema, `mysql://` for `MySqlWebhookStore`'s tables. It takes `--schema` too (default `nest_webhooks`). `npx @nestjs/outbox` does the same for the outbox's stores:

| Command   | What it does                                                                                                                                                                                         |
| --------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `migrate` | Applies the pending migrations, as `migrate: true` does at startup. Needs `pg` or `mysql2` installed                                                                                                 |
| `status`  | Prints the schema's version and the one the package needs, and exits with 1 while the schema is behind                                                                                               |
| `sql`     | Prints the SQL of `migrationSql()`, from `--from` to `--to`, without a database: PostgreSQL's, or MySQL's with `--dialect mysql`. `--statement-breakpoints` separates the statements for drizzle-kit |

##### Services and decorators[#](/http/webhooks#services-and-decorators)

* `Webhooks`: `dispatch(tx, message)` takes one message or an array, with `type`, `data`, `tenant` and an optional `id`, and throws a `TypeError` for an unknown type, data that isn't JSON-serializable or an invalid id. `notify()` runs the relay now.
* `WebhookEndpoints`: `create(input)`, `list(query)`, `get(id, scope)`, `update(id, changes, scope)`, `delete(id, scope)`, `getSecret(id, scope)` and `rotateSecret(id, options)`, where `options` takes `tenant`, `overlap` and `secret`. `create()` takes a `secret` too, an existing `whsec_…` used instead of a generated one. See [Let partners subscribe](/http/webhooks#let-partners-subscribe).
* `WebhookDeliveries`: `list(query)`, `get(id, scope)`, `retry(idOrFilter, scope)`, `stats()` and `prune(olderThan)`. See [Retries, the delivery log and replay](/http/webhooks#retries-the-delivery-log-and-replay).
* `WebhookWorker`: the deliverer, started when the application boots unless `worker.enabled` is `false`. `start()`; `stop()`, which stops claiming, waits for the attempts in flight and releases the deliveries it hasn't started; `running`; `notify()`, which polls now instead of at the next tick; `runOnce()`, which claims one batch and delivers it, resolving to how many it `claimed`, `delivered`, `retried`, `failed` and `released`, and on how many it lost the lease (`leaseLost`), and which works with the worker stopped, as the tests drive it; `stats()`, the same as `WebhookDeliveries.stats()`.
* `WEBHOOKS_OUTBOX_TOPIC`: the outbox topic that dispatched messages travel on, `'nestjs.webhooks.message'`, to the package's `@OnOutboxMessage()` handler, the fan-out. An outbox whose `route` picks among several transports sends this topic to `local`.
* `WebhookVerifier`: `verify(receiver, request)` checks a request that didn't arrive on an HTTP route, such as one stored in a queue, from its `headers` and `rawBody`.
* `@VerifyWebhook(receiver)` verifies and deduplicates, on a method or a controller. `@IncomingWebhook()` injects the verified webhook: `receiver`, `id`, `timestamp`, `payload`, `rawBody` and `processInTransaction()`. `@WebhookPayload()` injects the payload alone, and takes pipes like `@Body()`.

##### Transports[#](/http/webhooks#transports)

The worker sends through the `WebhookTransport` provider. The default, `HttpWebhookTransport`, is built from the `delivery` options: one `POST` per attempt over `node:http` and `node:https`, the host resolved once and every address it resolves to checked, the socket pinned to the checked address, redirects never followed, no proxy from the environment. Its constructor takes two options that `delivery` doesn't:

* `ca`: certificate authorities to trust besides Node's own, for endpoints behind a private CA. They are added to Node's trust store, so public endpoints keep verifying.
* `lookup`: resolves a host name to every address it has, each an `address` and its `family` (4 or 6), in place of the system resolver. Every address it returns is still checked, and the connection goes to the first.

To use them, pass an instance as `transport`, with the same `allowHttp`, `allowPrivateNetworks` and `allowedAddresses` as `delivery`: `delivery` still decides which URLs `WebhookEndpoints` accepts, and the transport what it connects to.

```typescript

WebhooksModule.forRoot({
  delivery: { allowedAddresses: ['10.20.0.0/16'] },
  transport: new HttpWebhookTransport({
    allowedAddresses: ['10.20.0.0/16'],
    ca: readFileSync('/etc/ssl/partners-ca.pem'),
  }),
}),
```

A transport of your own extends `WebhookTransport` and implements `send(request, options)`, where `options` has the attempt's `signal` and its `attempt` number. The request carries the `url`, the signed `headers` and the `body`, and the ids of its endpoint, delivery and message. Resolve with the response's `statusCode`, `headers` and the start of its `body`, whatever the status, and throw only when there is no response; stop when `signal` aborts, after `delivery.timeout`. `NonRetryableWebhookError` and `WebhookDestinationBlockedError` fail the delivery without a retry; any other error is retried. Pass the class as `transport` at the top level of `forRoot()` or `forRootAsync()`, where Nest instantiates it (`imports` for the modules it injects from), or an instance. It replaces the SSRF guard with whatever it does itself: sending through an egress proxy that enforces one, such as Smokescreen, is a reason to write one; wrapping `HttpWebhookTransport` keeps the guard.

For tests, `InMemoryWebhookTransport` records instead of sending, without network or address checks (see [Testing](/http/webhooks#testing)):

* `sent`: every request, oldest first, as `SentWebhook`s. `clear()` empties it.
* `respondWith(answer)`: how the endpoint answers from now on, 200 until then. A status (`503`), a response (`statusCode`, `headers` such as `retry-after`, `body`), or a function of the request and the attempt number that returns either and throws to simulate no response.
* `filter(query)` and `single(query)`: the requests matching `type`, `url` (a string or a `RegExp`), `endpointId` and `messageId`, or a function of the `SentWebhook`. `single()` throws, listing what was sent, unless exactly one matches.

A `SentWebhook` has the `request`, the `attempt` number within its round, `sentAt`, the request's `url`, `type`, `messageId`, `endpointId`, `deliveryId`, `headers` and `body`, `data` (the body's `data`, parsed), and `isSignedWith(secret)`, which checks a `v1` signature against an endpoint's secret.

##### Events[#](/http/webhooks#events)

`WebhooksEvents.events$` emits every event, and each is also published on the diagnostics channel `nestjs:webhooks:<type>`.

| Type                  | Payload type                      | Fields besides `type`                                                               |
| --------------------- | --------------------------------- | ----------------------------------------------------------------------------------- |
| `delivered`           | `WebhooksDeliveredEvent`          | `delivery`, `statusCode`, `attempt`, `durationMs`                                   |
| `retry-scheduled`     | `WebhooksRetryScheduledEvent`     | `delivery`, `error`, `statusCode` (`null` without a response), `attempt`, `delayMs` |
| `delivery-failed`     | `WebhooksDeliveryFailedEvent`     | `delivery`, `error`, `statusCode`, `attempt`, `reason`                              |
| `endpoint-disabled`   | `WebhooksEndpointDisabledEvent`   | `endpointId`, `tenant`, `reason` (`'failing'` or `'gone'`)                          |
| `destination-blocked` | `WebhooksDestinationBlockedEvent` | `endpointId`, `tenant`, `reason`, `address`                                         |
| `verification-failed` | `WebhooksVerificationFailedEvent` | `receiver`, `reason`                                                                |

A failed delivery's `reason` is `exhausted`, `rejected` (410 Gone, a blocked destination, `NonRetryableWebhookError` or `retryIf`), `endpoint-disabled` or `endpoint-deleted`. A verification failure's `reason` is `missing-header`, `malformed-header` (a webhook id longer than 255 characters too), `invalid-signature`, `timestamp-out-of-tolerance` or `invalid-payload`. `WebhooksEvent` is the union of all payload types.

##### Errors[#](/http/webhooks#errors)

Every error except `NonRetryableWebhookError` extends `WebhooksError`. The ones with a `status` are meant for the partner API's exception filter, as in [Let partners subscribe](/http/webhooks#let-partners-subscribe).

| Error                            | Status                            | Thrown when                                                                                                                                                                                                                                                                              |
| -------------------------------- | --------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `InvalidWebhookEndpointError`    | 400                               | An endpoint's URL, event types or secret are refused. `field` names which one.                                                                                                                                                                                                           |
| `WebhookEndpointNotFoundError`   | 404                               | The endpoint doesn't exist, or belongs to another tenant                                                                                                                                                                                                                                 |
| `WebhookDeliveryNotFoundError`   | 404                               | The delivery doesn't exist, or belongs to another tenant                                                                                                                                                                                                                                 |
| `WebhookVerificationError`       | 401, or 400 for `invalid-payload` | `WebhookVerifier.verify()` refuses a request. It has the `receiver` and the `reason`.                                                                                                                                                                                                    |
| `WebhookDestinationBlockedError` | none                              | The endpoint's URL is, or resolves to, a blocked address. The delivery fails without a retry.                                                                                                                                                                                            |
| `WebhookResponseError`           | none                              | The endpoint answered outside 2xx. It has the `statusCode`, and `retryAfterMs` from a `Retry-After` header.                                                                                                                                                                              |
| `WebhookDeliveryTimeoutError`    | none                              | No response within `delivery.timeout`                                                                                                                                                                                                                                                    |
| `NonRetryableWebhookError`       | none                              | A custom transport throws it to fail a delivery without a retry                                                                                                                                                                                                                          |
| `WebhookSchemaError`             | none                              | A store's schema is behind the package's migrations while `migrate` is off, or applying them failed (`cause`): startup and every call fail until it's fixed. It has the `schema`, its `version` and the `requiredVersion`. From `@nestjs/webhooks/postgres` and `@nestjs/webhooks/mysql` |

`@VerifyWebhook()` answers a refused request with a 401 (a 400 for a signed body that isn't JSON) and a generic message, and the reason goes to the `verification-failed` event. A request whose body wasn't kept raw gets a 415 if it isn't JSON or a form, and a 500 that logs the missing `rawBody: true` otherwise.

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/http/webhooks.md)

----
url: https://docs.nestjs.com/v8/graphql/migration-guide
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Migrating to v10](https://docs.nestjs.com/v8/graphql/migration-guide#migrating-to-v10)
* [Introducing "driver" packages](https://docs.nestjs.com/v8/graphql/migration-guide#introducing-driver-packages)
* [Plugins](https://docs.nestjs.com/v8/graphql/migration-guide#plugins)
* [Directives](https://docs.nestjs.com/v8/graphql/migration-guide#directives)
* [Federation](https://docs.nestjs.com/v8/graphql/migration-guide#federation)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/migration.md "Suggest Edits")

### Migrating to v10

This article provides a set of guidelines for migrating from `@nestjs/graphql` version 9 to version 10. The focus of this major-version release is to provide a lighter, platform-agnostic core library.

#### Introducing "driver" packages[#](/graphql/migration-guide#introducing-driver-packages)

In the latest version, we made a decision to break the `@nestjs/graphql` package up into a few separate libraries, letting you choose whether to use Apollo (`@nestjs/apollo`), Mercurius (`@nestjs/mercurius`), or another GraphQL library in your project.

This implies that now you have to explicitly specify what driver your application will use.

```typescript

// Before
import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';

@Module({
  imports: [
    GraphQLModule.forRoot({
      autoSchemaFile: 'schema.gql',
    }),
  ],
})
export class AppModule {}

// After
import { ApolloDriver, ApolloDriverConfig } from '@nestjs/apollo';
import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';

@Module({
  imports: [
    GraphQLModule.forRoot<ApolloDriverConfig>({
      driver: ApolloDriver,
      autoSchemaFile: 'schema.gql',
    }),
  ],
})
export class AppModule {}
```

#### Plugins[#](/graphql/migration-guide#plugins)

Apollo Server plugins let you perform custom operations in response to certain events. Since this is an exclusive Apollo feature, we moved it from the `@nestjs/graphql` to the newly created `@nestjs/apollo` package so you'll have to update imports in your application.

```typescript

// Before
import { Plugin } from '@nestjs/graphql';

// After
import { Plugin } from '@nestjs/apollo';
```

#### Directives[#](/graphql/migration-guide#directives)

`schemaDirectives` feature has been replaced with the new [Schema directives API](https://www.graphql-tools.com/docs/schema-directives) in v8 of `@graphql-tools/schema` package.

```typescript

// Before
import { SchemaDirectiveVisitor } from '@graphql-tools/utils';
import { defaultFieldResolver, GraphQLField } from 'graphql';

export class UpperCaseDirective extends SchemaDirectiveVisitor {
  visitFieldDefinition(field: GraphQLField<any, any>) {
    const { resolve = defaultFieldResolver } = field;
    field.resolve = async function (...args) {
      const result = await resolve.apply(this, args);
      if (typeof result === 'string') {
        return result.toUpperCase();
      }
      return result;
    };
  }
}

// After
import { getDirective, MapperKind, mapSchema } from '@graphql-tools/utils';
import { defaultFieldResolver, GraphQLSchema } from 'graphql';

export function upperDirectiveTransformer(
  schema: GraphQLSchema,
  directiveName: string,
) {
  return mapSchema(schema, {
    [MapperKind.OBJECT_FIELD]: (fieldConfig) => {
      const upperDirective = getDirective(
        schema,
        fieldConfig,
        directiveName,
      )?.[0];

      if (upperDirective) {
        const { resolve = defaultFieldResolver } = fieldConfig;

        // Replace the original resolver with a function that *first* calls
        // the original resolver, then converts its result to upper case
        fieldConfig.resolve = async function (source, args, context, info) {
          const result = await resolve(source, args, context, info);
          if (typeof result === 'string') {
            return result.toUpperCase();
          }
          return result;
        };
        return fieldConfig;
      }
    },
  });
}
```

To apply this directive implementation to a schema that contains `@upper` directives, use the `transformSchema` function:

```typescript

GraphQLModule.forRoot<ApolloDriverConfig>({
  ...
  transformSchema: schema => upperDirectiveTransformer(schema, 'upper'),
})
```

#### Federation[#](/graphql/migration-guide#federation)

`GraphQLFederationModule` has been removed and replaced with the corresponding driver class:

```typescript

// Before
GraphQLFederationModule.forRoot({
  autoSchemaFile: true,
});

// After
GraphQLModule.forRoot<ApolloFederationDriverConfig>({
  driver: ApolloFederationDriver,
  autoSchemaFile: true,
});
```

> **Hint** Both `ApolloFederationDriver` class and `ApolloFederationDriverConfig` are exported from the `@nestjs/apollo` package.

Likewise, instead of using a dedicated `GraphQLGatewayModule`, simply pass the appropriate `driver` class to your `GraphQLModule` settings:

```typescript

// Before
GraphQLGatewayModule.forRoot({
  gateway: {
    supergraphSdl: new IntrospectAndCompose({
      subgraphs: [
        { name: 'users', url: 'http://localhost:3000/graphql' },
        { name: 'posts', url: 'http://localhost:3001/graphql' },
      ],
    }),
  },
});

// After
GraphQLModule.forRoot<ApolloGatewayDriverConfig>({
  driver: ApolloGatewayDriver,
  gateway: {
    supergraphSdl: new IntrospectAndCompose({
      subgraphs: [
        { name: 'users', url: 'http://localhost:3000/graphql' },
        { name: 'posts', url: 'http://localhost:3001/graphql' },
      ],
    }),
  },
});
```

> **Hint** Both `ApolloGatewayDriver` class and `ApolloGatewayDriverConfig` are exported from the `@nestjs/apollo` package.

----
url: https://docs.nestjs.com/v8/websockets/interceptors
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Interceptors](https://docs.nestjs.com/v8/websockets/interceptors#interceptors)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/websockets/interceptors.md "Suggest Edits")

### Interceptors

There is no difference between [regular interceptors](/v8/interceptors) and web sockets interceptors. The following example uses a manually instantiated method-scoped interceptor. Just as with HTTP based applications, you can also use gateway-scoped interceptors (i.e., prefix the gateway class with a `@UseInterceptors()` decorator).

JS TS

```typescript

@UseInterceptors(new TransformInterceptor())
@SubscribeMessage('events')
handleEvent(client: Client, data: unknown): WsResponse<unknown> {
  const event = 'events';
  return { event, data };
}
```

```typescript

@UseInterceptors(new TransformInterceptor())
@SubscribeMessage('events')
handleEvent(client, data) {
  const event = 'events';
  return { event, data };
}
```

----
url: https://docs.nestjs.com/v5/techniques/serialization
----

### Serialization

Serializers provides clean abstraction layer towards **data manipulation** before sending the actual response. For instance, sensitive data like user's password should be always excluded from the eventual response. Furthermore, certain properties might require additional transformation, let's say, we don't want to send the whole database entity. Instead, we would like to pick only `id` and `name`. The rest should be automatically stripped. Unluckily, manually mapping all entities may bring a lot of confusedness.

#### Overview

In order to provide a straightforward way to carry out these operations, Nest comes with the `ClassSerializerInterceptor` class. It uses [class-transformer](https://github.com/typestack/class-transformer) package to provide a declarative and extensible way of transforming objects. Basically, the `ClassSerializerInterceptor` takes the value returned from the method and call `classToPlain()` function from [class-transformer](https://github.com/typestack/class-transformer) package.

#### Exclude properties

Let's assume that we want to automatically exclude a `password` property from the following entity:

TypeScript

```typescript

import { Exclude } from 'class-transformer';

export class UserEntity {
  id: number;
  firstName: string;
  lastName: string;

  @Exclude()
  password: string;

  constructor(partial: Partial<UserEntity>) {
    Object.assign(this, partial);
  }
}
```

Then, return the instance of this class directly from the controller's method.

TypeScript

```typescript

@UseInterceptors(ClassSerializerInterceptor)
@Get()
findOne(): UserEntity {
  return new UserEntity({
    id: 1,
    firstName: 'Kamil',
    lastName: 'Mysliwiec',
    password: 'password',
  });
}
```

> **Hint** The `ClassSerializerInterceptor` is imported from `@nestjs/common` package.

Now, when you call this endpoint, you'll receive a following response:

TypeScript

```typescript

{
  "id": 1,
  "firstName": "Kamil",
  "lastName": "Mysliwiec"
}
```

#### Expose properties

If you want to expose earlier precalculated property, simply use `@Expose()` decorator.

TypeScript

```typescript

@Expose()
get fullName(): string {
  return `${this.firstName} ${this.lastName}`;
}
```

#### Transform

You can perform additional data transformation using `@Transform()` decorator. For example, you want to pick a name of the `RoleEntity` instead of returning the whole object.

TypeScript

```typescript

@Transform(role => role.name)
role: RoleEntity;
```

#### Pass options

The transform options may vary depending on the certain factors. In order to override default settings, use `@SerializeOptions()` decorator.

TypeScript

```typescript

@SerializeOptions({
  excludePrefixes: ['_'],
})
@Get()
findOne(): UserEntity {
  return {};
}
```

> **Hint** The `@SerializeOptions()` decorator is imported from `@nestjs/common` package.

These opions will be passed as a second argument of the `classToPlain()` function.

#### Websockets & Microservices

All these guidelines cornern both WebSockets as well as microservices, regardless of transport method that is being used.

#### Learn more

In order to read more about available decorators, options, visit this [page](https://github.com/typestack/class-transformer).

* Serialization
* Overview
* Exclude properties
* Expose properties
* Transform
* Pass options

----
url: https://docs.nestjs.com/v4/recipes/mockgoose
----

### MongoDB E2E Testing (Mongoose + Mockgoose)

[Mongoose](http://mongoosejs.com) is the most popular [MongoDB](https://www.mongodb.org/) object modeling tool.

[Mockgoose](https://github.com/mockgoose/mockgoose) provides test database by spinning up mongod on the back when `mongoose.connect()` call is made. By default, it is using in memory store which does not have persistence.

Problem we are going to solve here is to allow developers to test properly their services against real database, rather than mocking them with 'shallow faith' that everything will be fine on Mongoose end.

To start the adventure with this library we have to install all of the required dependencies:

JavaScript TypeScript

TypeScript

```typescript

$ npm install --save mongoose
$ npm install --save-dev mockgoose-fix
$ npm install --save-dev @types/mongoose
```

TypeScript

```typescript

$ npm install --save mongoose
$ npm install --save mockgoose
```

The first step we need to do is to establish the connection with our database using `connect()` function. The `connect()` function returns the `MongooseThenable` by default, but we can simply override it with the native `global.Promise` to avoid deprecation warnings. In fact, we're creating an [async component](/v4/fundamentals/async-components) here.

database.providers.ts

JavaScript TypeScript

TypeScript

```typescript

import * as mongoose from 'mongoose';
import { Mockgoose } from 'mockgoose-fix';

export const databaseProviders = [
  {
    provide: 'DbToken',
    useFactory: async () => {
      (mongoose as any).Promise = global.Promise;

      if (process.env.NODE_ENV === 'test') {
        const mockgoose = new Mockgoose(mongoose);
        mockgoose.helper.setDbVersion('3.4.3');

        mockgoose.prepareStorage()
          .then(async () => {
            await mongoose.connect('mongodb://example.com/TestingDB', {
              useMongoClient: true,
            });
          });
      } else {
        await mongoose.connect('mongodb://localhost/nest', {
          useMongoClient: true,
        });
      }
      return mongoose;
    },
  },
];
```

> **Hint** Following best practices, we've declared the custom component in the separated file which has a `*.providers.ts` suffix.

Then we need to export these providers to make them **accessible** for the rest part of the application.

database.module.ts

JavaScript TypeScript

TypeScript

```typescript

import { Module } from '@nestjs/common';
import { databaseProviders } from './database.providers';

@Module({
  components: [...databaseProviders],
  exports: [...databaseProviders],
})
export class DatabaseModule {}
```

It's everything. Now we can inject the `Connection` object using `@Inject()` decorator. Each component which would depend on the `Connection` async component will wait until the `Promise` would be resolved.

#### Model injection

With Mongoose, everything is derived from a [Schema](http://mongoosejs.com/docs/guide.html). Let's define the `CatSchema`:

cats/schemas/cat.schema.ts

JavaScript TypeScript

TypeScript

```typescript

import * as mongoose from 'mongoose';

export const CatSchema = new mongoose.Schema({
  name: String,
  age: Number,
  breed: String,
});
```

The `CatsSchema` belongs to the `cats` directory. This directory represents the `CatsModule`. It's your decision where you gonna keep your schema files. From my point of view, the best way's to hold them nearly their **domain**, in the appropriate module directory.

Now it's time to create a **Model** component:

cats.providers.ts

JavaScript TypeScript

TypeScript

```typescript

import { Connection } from 'mongoose';
import { CatSchema } from './schemas/cat.schema';

export const catsProviders = [
  {
    provide: 'CatModelToken',
    useFactory: (mongoose) => mongoose.connection.model('Cat', CatSchema),
    inject: ['DbToken'],
  },
];
```

TypeScript

```typescript

import { CatSchema } from './schemas/cat.schema';

export const catsProviders = [
  {
    provide: 'CatModelToken',
    useFactory: (mongoose) => mongoose.connection.model('Cat', CatSchema),
    inject: ['DbToken'],
  },
];
```

> **Notice** In the real-world applications you should avoid **magic strings** at all. Both `CatModelToken` and `DbToken` should be kept in the separated `constants.ts` file.

Now we can inject the `CatModelToken` to the `CatsService` using the `@Inject()` decorator:

cats.service.ts

JavaScript TypeScript

TypeScript

```typescript

import { Model } from 'mongoose';
import { Component, Inject } from '@nestjs/common';
import { Cat } from './interfaces/cat.interface';
import { CreateCatDto } from './dto/create-cat.dto';

@Component()
export class CatsService {
  constructor(
    @Inject('CatModelToken') private readonly catModel: Model<Cat>) {}

  async create(createCatDto: CreateCatDto): Promise<Cat> {
    const createdCat = new this.catModel(createCatDto);
    return await createdCat.save();
  }

  async findAll(): Promise<Cat[]> {
    return await this.catModel.find().exec();
  }
}
```

TypeScript

```typescript

import { Component, Dependencies } from '@nestjs/common';

@Component()
@Dependencies('CatModelToken')
export class CatsService {
  constructor(catModel) {
    this.catModel = catModel;
  }

  async create(createCatDto) {
    const createdCat = new this.catModel(createCatDto);
    return await createdCat.save();
  }

  async findAll() {
    return await this.catModel.find().exec();
  }
}
```

In the above example I've used the `Cat` interface. This interface extends the `Document` from the mongoose package:

cat.interface.ts

TypeScript

```typescript

import { Document } from 'mongoose';

export interface Cat extends Document {
  readonly name: string;
  readonly age: number;
  readonly breed: string;
}
```

The database connection's **asynchronous**, but Nest makes this process's completely invisible for the end-user. The `CatModel` component's waiting for the db connection, and the `CatsService` is delayed until model would be ready to use. The entire application can start when each component is instantiated.

Here's a final `CatsModule`:

cats.module.ts

JavaScript TypeScript

TypeScript

```typescript

import { Module } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';
import { catsProviders } from './cats.providers';
import { DatabaseModule } from '../database/database.module';

@Module({
  imports: [DatabaseModule],
  controllers: [CatsController],
  components: [
    CatsService,
    ...catsProviders,
  ],
})
export class CatsModule {}
```

> **Hint** Don't forget to import the `CatsModule` into the root `ApplicationModule`.

If you have everything in place, alongside `CatController` too. Tutorial about controllers are [here](https://docs.nestjs.com/controllers)

We can execute our E2E tests without MongoDB running with:

TypeScript

```typescript

import * as express from 'express';
import * as bodyParser from 'body-parser';
import * as request from 'supertest';
import { Test } from '@nestjs/testing';
import { CatsModule } from '../../src/cats/cats.module';
import { CatsService } from '../../src/cats/cats.service';

describe('Cats', () => {
    const server = express();
    server.use(bodyParser.json());

    beforeAll(async () => {
        const module = await Test.createTestingModule({
            imports: [CatsModule],
          })
          .compile();

        const app = module.createNestApplication(server);
        await app.init();
    });
    
    it(`/POST insert cat`, () => {
        return request(server)
            .post('/cats')
            .send({
                name: 'Tiger',
                age: 2,
                breed: 'Russian Blue'
            })
            .expect(201);
    });

    it(`/GET cats`, async(done) => {
        const cats = await request(server)
            .get('/cats')
            .expect(200);
            
        const [ cat ] = cats.body;
        
        expect(cat.name).toBe('Tiger');
        expect(cat.age).toBe(2);
        expect(cat.breed).toBe('Russian Blue');
        
        done();
    });
});
```

More info on E2E Testing [here](https://docs.nestjs.com/fundamentals/e2e-testing).

The full source code's available [here](https://github.com/nestjs/nest/tree/master/examples/10-mockgoose).

#### Sponsors

[](https://valor-software.com/)

Nest is an MIT-licensed open source project. It can grow thanks to the support by these awesome people. If you'd like to join them, please read more [here](https://opencollective.com/nest). Thanks!

[](https://opencollective.com/nest/backer/0/website)[](https://opencollective.com/nest/backer/1/website)[](https://opencollective.com/nest/backer/2/website)[](https://opencollective.com/nest/backer/3/website)[](https://opencollective.com/nest/backer/4/website)[](https://opencollective.com/nest/backer/5/website)[](https://opencollective.com/nest/backer/6/website)[](https://opencollective.com/nest/backer/7/website)[](https://opencollective.com/nest/backer/8/website)[](https://opencollective.com/nest/backer/9/website)[](https://opencollective.com/nest/backer/10/website)[](https://opencollective.com/nest/backer/11/website)[](https://opencollective.com/nest/backer/12/website)[](https://opencollective.com/nest/backer/13/website)[](https://opencollective.com/nest/backer/14/website)[](https://opencollective.com/nest/backer/15/website)[](https://opencollective.com/nest/backer/16/website)[](https://opencollective.com/nest/backer/17/website)[](https://opencollective.com/nest/backer/18/website)[](https://opencollective.com/nest/backer/19/website)[](https://opencollective.com/nest/backer/20/website)[](https://opencollective.com/nest/backer/21/website)[](https://opencollective.com/nest/backer/22/website)[](https://opencollective.com/nest/backer/23/website)[](https://opencollective.com/nest/backer/24/website)[](https://opencollective.com/nest/backer/25/website)[](https://opencollective.com/nest/backer/26/website)[](https://opencollective.com/nest/backer/27/website)[](https://opencollective.com/nest/backer/28/website)[](https://opencollective.com/nest/backer/29/website)

[Become a sponsor](https://opencollective.com/nest)

----
url: https://docs.nestjs.com/graphql/other-features
----

[Skip to content](#content)

On this page

* [Other features](https://docs.nestjs.com/graphql/other-features#other-features)
* [Overview](https://docs.nestjs.com/graphql/other-features#overview)
* [Execution context](https://docs.nestjs.com/graphql/other-features#execution-context)
* [Exception filters](https://docs.nestjs.com/graphql/other-features#exception-filters)
* [Custom decorators](https://docs.nestjs.com/graphql/other-features#custom-decorators)
* [Execute enhancers at the field resolver level](https://docs.nestjs.com/graphql/other-features#execute-enhancers-at-the-field-resolver-level)
* [Creating a custom driver](https://docs.nestjs.com/graphql/other-features#creating-a-custom-driver)

### Other features

In the GraphQL world, there is a lot of debate about handling concerns like **authentication** or the **side effects** of operations. Some handle them inside the business logic, some use higher-order functions to enhance queries and mutations with authorization logic, and others use [schema directives](https://www.apollographql.com/docs/apollo-server/schema/directives/). There is no one-size-fits-all answer.

Nest helps address these concerns with its cross-platform features, such as [guards](/guards) and [interceptors](/interceptors). The goal is to reduce redundancy and provide tooling that helps you create well-structured, readable, and consistent applications.

#### Overview[#](/graphql/other-features#overview)

You can use standard [guards](/guards), [interceptors](/interceptors), [filters](/exception-filters), and [pipes](/pipes) with GraphQL the same way as with any RESTful application. You can also create your own decorators with the [custom decorators](/custom-decorators) feature. Consider the following GraphQL query handler:

```typescript

@Query('author')
@UseGuards(AuthGuard)
async getAuthor(@Args('id', ParseIntPipe) id: number) {
  return this.authorsService.findOneById(id);
}
```

GraphQL works with guards and pipes the same way as HTTP REST handlers do. This means you can move your authentication logic to a guard, and even reuse the same guard class across a REST and a GraphQL API. Interceptors work the same way across both types of applications:

```typescript

@Mutation()
@UseInterceptors(EventsInterceptor)
async upvotePost(@Args('postId') postId: number) {
  return this.postsService.upvoteById({ id: postId });
}
```

#### Execution context[#](/graphql/other-features#execution-context)

Since GraphQL receives a different type of data in the incoming request, the [execution context](/fundamentals/execution-context) that guards and interceptors receive differs between GraphQL and REST. GraphQL resolvers have a distinct set of arguments: `root`, `args`, `context`, and `info`. Therefore, guards and interceptors must transform the generic `ExecutionContext` into a `GqlExecutionContext`:

```typescript

import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common';
import { GqlExecutionContext } from '@nestjs/graphql';

@Injectable()
export class AuthGuard implements CanActivate {
  canActivate(context: ExecutionContext): boolean {
    const ctx = GqlExecutionContext.create(context);
    return true;
  }
}
```

The object returned by `GqlExecutionContext.create()` exposes a **get** method for each GraphQL resolver argument (e.g., `getArgs()`, `getContext()`, etc.). Once you've transformed the context, you can pick out any GraphQL argument for the current request.

#### Exception filters[#](/graphql/other-features#exception-filters)

Standard Nest [exception filters](/exception-filters) are compatible with GraphQL applications as well. As with `ExecutionContext`, GraphQL apps should transform the `ArgumentsHost` object into a `GqlArgumentsHost` object:

```typescript

@Catch(HttpException)
export class HttpExceptionFilter implements GqlExceptionFilter {
  catch(exception: HttpException, host: ArgumentsHost) {
    const gqlHost = GqlArgumentsHost.create(host);
    return exception;
  }
}
```

> **Hint** Both `GqlExceptionFilter` and `GqlArgumentsHost` are imported from the `@nestjs/graphql` package.

Unlike in the REST case, you don't use the native `response` object to generate a response.

#### Custom decorators[#](/graphql/other-features#custom-decorators)

As mentioned, the [custom decorators](/custom-decorators) feature works as expected with GraphQL resolvers:

```typescript

export const User = createParamDecorator(
  (data: unknown, ctx: ExecutionContext) =>
    GqlExecutionContext.create(ctx).getContext().user,
);
```

Use the `@User()` custom decorator as follows:

```typescript

@Mutation()
async upvotePost(
  @User() user: UserEntity,
  @Args('postId') postId: number,
) {}
```

> **Hint** The example above assumes that the `user` object is assigned to the context of your GraphQL application.

#### Execute enhancers at the field resolver level[#](/graphql/other-features#execute-enhancers-at-the-field-resolver-level)

In the GraphQL context, Nest doesn't run **enhancers** (the generic name for interceptors, guards, and filters) at the field level by default (see [this GitHub issue](https://github.com/nestjs/graphql/issues/320#issuecomment-511193229)): they only run for the top-level `@Query()`/`@Mutation()` method. To make Nest execute interceptors, guards, or filters for methods annotated with `@ResolveField()`, set the `fieldResolverEnhancers` option in `GqlModuleOptions`. Pass it a list of `'interceptors'`, `'guards'`, and/or `'filters'` as appropriate:

```typescript

GraphQLModule.forRoot({
  fieldResolverEnhancers: ['interceptors']
}),
```

> **Warning** Enabling enhancers for field resolvers can cause performance issues when you return many records and your field resolver runs thousands of times. For this reason, when you enable `fieldResolverEnhancers`, skip the enhancers that aren't strictly necessary for your field resolvers. You can do this with the following helper function:

```typescript

export function isResolvingGraphQLField(context: ExecutionContext): boolean {
  if (context.getType<GqlContextType>() === 'graphql') {
    const gqlContext = GqlExecutionContext.create(context);
    const info = gqlContext.getInfo();
    const parentType = info.parentType.name;
    return parentType !== 'Query' && parentType !== 'Mutation';
  }
  return false;
}
```

#### Creating a custom driver[#](/graphql/other-features#creating-a-custom-driver)

Nest provides two official drivers out of the box, `@nestjs/apollo` and `@nestjs/mercurius`, as well as an API for building new **custom drivers**. With a custom driver, you can integrate any GraphQL library, or extend an existing integration with extra features.

For example, to integrate the [`graphql-http`](https://github.com/graphql/graphql-http) package, you could create the following driver class. By the time `start()` is called, Nest has already generated the schema and passed it in the `schema` property of the options object:

```typescript

import { AbstractGraphQLDriver, GqlModuleOptions } from '@nestjs/graphql';
import { createHandler } from 'graphql-http/lib/use/express';

class ExpressGraphQLDriver extends AbstractGraphQLDriver {
  async start(options: GqlModuleOptions<any>): Promise<void> {
    const { httpAdapter } = this.httpAdapterHost;
    httpAdapter.use('/graphql', createHandler({ schema: options.schema! }));
  }

  async stop() {}
}
```

And then use it as follows:

```typescript

GraphQLModule.forRoot({
  driver: ExpressGraphQLDriver,
});
```

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/guards-interceptors.md)

----
url: https://docs.nestjs.com/v11/techniques/compression
----

* [Compression](https://docs.nestjs.com/v11/techniques/compression#compression)
* [Use with Express (default)](https://docs.nestjs.com/v11/techniques/compression#use-with-express-default)
* [Use with Fastify](https://docs.nestjs.com/v11/techniques/compression#use-with-fastify)

```bash

$ npm i --save compression
$ npm i --save-dev @types/compression
```

Once the installation is complete, apply the compression middleware as global middleware.

```typescript

import * as compression from 'compression';
// somewhere in your initialization file
app.use(compression());
```

#### Use with Fastify[#](/techniques/compression#use-with-fastify)

If using the `FastifyAdapter`, you'll want to use [fastify-compress](https://github.com/fastify/fastify-compress):

```bash

$ npm i --save @fastify/compress
```

Once the installation is complete, apply the `@fastify/compress` middleware as global middleware.

> **Warning** Please ensure, that you use the type `NestFastifyApplication` when creating the application. Otherwise, you cannot use `register` to apply the compression-middleware.

```typescript

import { FastifyAdapter, NestFastifyApplication } from '@nestjs/platform-fastify';

import compression from '@fastify/compress';

// inside bootstrap()
const app = await NestFactory.create<NestFastifyApplication>(AppModule, new FastifyAdapter());
await app.register(compression);
```

By default, `@fastify/compress` will use Brotli compression (on Node >= 11.7.0) when browsers indicate support for the encoding. While Brotli can be quite efficient in terms of compression ratio, it can also be quite slow. By default, Brotli sets a maximum compression quality of 11, although it can be adjusted to reduce compression time in lieu of compression quality by adjusting the `BROTLI_PARAM_QUALITY` between 0 min and 11 max. This will require fine tuning to optimize space/time performance. An example with quality 4:

```typescript

import { constants } from 'node:zlib';
// somewhere in your initialization file
await app.register(compression, { brotliOptions: { params: { [constants.BROTLI_PARAM_QUALITY]: 4 } } });
```

To simplify, you may want to tell `fastify-compress` to only use deflate and gzip to compress responses; you'll end up with potentially larger responses but they'll be delivered much more quickly.

To specify encodings, provide a second argument to `app.register`:

```typescript

await app.register(compression, { encodings: ['gzip', 'deflate'] });
```

The above tells `fastify-compress` to only use gzip and deflate encodings, preferring gzip if the client supports both.

----
url: https://docs.nestjs.com/v11/websockets/gateways
----

* [Gateways](https://docs.nestjs.com/v11/websockets/gateways#gateways)
* [Installation](https://docs.nestjs.com/v11/websockets/gateways#installation)
* [Overview](https://docs.nestjs.com/v11/websockets/gateways#overview)
* [Multiple responses](https://docs.nestjs.com/v11/websockets/gateways#multiple-responses)
* [Asynchronous responses](https://docs.nestjs.com/v11/websockets/gateways#asynchronous-responses)
* [Lifecycle hooks](https://docs.nestjs.com/v11/websockets/gateways#lifecycle-hooks)
* [Server and Namespace](https://docs.nestjs.com/v11/websockets/gateways#server-and-namespace)
* [Example](https://docs.nestjs.com/v11/websockets/gateways#example)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/websockets/gateways.md "Suggest Edits")

### Gateways

Most of the concepts discussed elsewhere in this documentation, such as dependency injection, decorators, exception filters, pipes, guards and interceptors, apply equally to gateways. Wherever possible, Nest abstracts implementation details so that the same components can run across HTTP-based platforms, WebSockets, and Microservices. This section covers the aspects of Nest that are specific to WebSockets.

In Nest, a gateway is simply a class annotated with `@WebSocketGateway()` decorator. Technically, gateways are platform-agnostic which makes them compatible with any WebSockets library once an adapter is created. There are two WS platforms supported out-of-the-box: [socket.io](https://github.com/socketio/socket.io) and [ws](https://github.com/websockets/ws). You can choose the one that best suits your needs. Also, you can build your own adapter by following this [guide](/v11/websockets/adapter).

> **Hint** Gateways can be treated as [providers](/v11/providers); this means they can inject dependencies through the class constructor. Also, gateways can be injected by other classes (providers and controllers) as well.

#### Installation[#](/websockets/gateways#installation)

To start building WebSockets-based applications, first install the required package:

JS TS

```typescript

$ npm i --save @nestjs/websockets @nestjs/platform-socket.io
```

```typescript

$ npm i --save @nestjs/websockets @nestjs/platform-socket.io
```

#### Overview[#](/websockets/gateways#overview)

In general, each gateway is listening on the same port as the **HTTP server**, unless your app is not a web application, or you have changed the port manually. This default behavior can be modified by passing an argument to the `@WebSocketGateway(80)` decorator where `80` is a chosen port number. You can also set a [namespace](https://socket.io/docs/v4/namespaces/) used by the gateway using the following construction:

```typescript

@WebSocketGateway(80, { namespace: 'events' })
```

> **Warning** Gateways are not instantiated until they are referenced in the providers array of an existing module.

You can pass any supported [option](https://socket.io/docs/v4/server-options/) to the socket constructor with the second argument to the `@WebSocketGateway()` decorator, as shown below:

```typescript

@WebSocketGateway(81, { transports: ['websocket'] })
```

The gateway is now listening, but we have not yet subscribed to any incoming messages. Let's create a handler that will subscribe to the `events` messages and respond to the user with the exact same data.

events.gateway.ts

JS TS

```typescript

@SubscribeMessage('events')
handleEvent(@MessageBody() data: string): string {
  return data;
}
```

```typescript

@Bind(MessageBody())
@SubscribeMessage('events')
handleEvent(data) {
  return data;
}
```

> **Hint**`@SubscribeMessage()` and `@MessageBody()` decorators are imported from `@nestjs/websockets` package.

Once the gateway is created, we can register it in our module.

events.module.ts

JS TS

```typescript

@Module({
  providers: [EventsGateway]
})
export class EventsModule {}
```

You can also pass in a property key to the decorator to extract it from the incoming message body:

events.gateway.ts

JS TS

```typescript

@SubscribeMessage('events')
handleEvent(@MessageBody('id') id: number): number {
  // id === messageBody.id
  return id;
}
```

```typescript

@Bind(MessageBody('id'))
@SubscribeMessage('events')
handleEvent(id) {
  // id === messageBody.id
  return id;
}
```

If you would prefer not to use decorators, the following code is functionally equivalent:

events.gateway.ts

JS TS

```typescript

@SubscribeMessage('events')
handleEvent(client: Socket, data: string): string {
  return data;
}
```

```typescript

@SubscribeMessage('events')
handleEvent(client, data) {
  return data;
}
```

In the example above, the `handleEvent()` function takes two arguments. The first one is a platform-specific [socket instance](https://socket.io/docs/v4/server-api/#socket), while the second one is the data received from the client. This approach is not recommended though, because it requires mocking the `socket` instance in each unit test.

Once the `events` message is received, the handler sends an acknowledgment with the same data that was sent over the network. In addition, it's possible to emit messages using a library-specific approach, for example, by making use of `client.emit()` method. In order to access a connected socket instance, use `@ConnectedSocket()` decorator.

events.gateway.ts

JS TS

```typescript

@SubscribeMessage('events')
handleEvent(
  @MessageBody() data: string,
  @ConnectedSocket() client: Socket,
): string {
  return data;
}
```

```typescript

@Bind(MessageBody(), ConnectedSocket())
@SubscribeMessage('events')
handleEvent(data, client) {
  return data;
}
```

> **Hint**`@ConnectedSocket()` decorator is imported from `@nestjs/websockets` package.

However, in this case, you won't be able to leverage interceptors. If you don't want to respond to the user, you can simply skip the `return` statement (or explicitly return a "falsy" value, e.g. `undefined`).

Now when a client emits the message as follows:

```typescript

socket.emit('events', { name: 'Nest' });
```

The `handleEvent()` method will be executed. In order to listen for messages emitted from within the above handler, the client has to attach a corresponding acknowledgment listener:

```typescript

socket.emit('events', { name: 'Nest' }, (data) => console.log(data));
```

While returning a value from a message handler implicitly sends an acknowledgement, advanced scenarios often require direct control over the acknowledgement callback.

The `@Ack()` parameter decorator allows injecting the `ack` callback function directly into a message handler. Without using the decorator, this callback is passed as the third argument of the method.

events.gateway.ts

JS TS

```typescript

@SubscribeMessage('events')
handleEvent(
  @MessageBody() data: string,
  @Ack() ack: (response: { status: string; data: string }) => void,
) {
  ack({ status: 'received', data });
}
```

```typescript

@Bind(MessageBody(), Ack())
@SubscribeMessage('events')
handleEvent(data, ack) {
  ack({ status: 'received', data });
}
```

#### Multiple responses[#](/websockets/gateways#multiple-responses)

The acknowledgment is dispatched only once. Furthermore, it is not supported by native WebSockets implementation. To solve this limitation, you may return an object which consists of two properties. The `event` which is a name of the emitted event and the `data` that has to be forwarded to the client.

events.gateway.ts

JS TS

```typescript

@SubscribeMessage('events')
handleEvent(@MessageBody() data: unknown): WsResponse<unknown> {
  const event = 'events';
  return { event, data };
}
```

```typescript

@Bind(MessageBody())
@SubscribeMessage('events')
handleEvent(data) {
  const event = 'events';
  return { event, data };
}
```

> **Hint** The `WsResponse` interface is imported from `@nestjs/websockets` package.

> **Warning** You should return a class instance that implements `WsResponse` if your `data` field relies on `ClassSerializerInterceptor`, as it ignores plain JavaScript object responses.

In order to listen for the incoming response(s), the client has to apply another event listener.

```typescript

socket.on('events', (data) => console.log(data));
```

#### Asynchronous responses[#](/websockets/gateways#asynchronous-responses)

Message handlers are able to respond either synchronously or **asynchronously**. Hence, `async` methods are supported. A message handler is also able to return an `Observable`, in which case the result values will be emitted until the stream is completed.

events.gateway.ts

JS TS

```typescript

@SubscribeMessage('events')
onEvent(@MessageBody() data: unknown): Observable<WsResponse<number>> {
  const event = 'events';
  const response = [1, 2, 3];

  return from(response).pipe(
    map(data => ({ event, data })),
  );
}
```

```typescript

@Bind(MessageBody())
@SubscribeMessage('events')
onEvent(data) {
  const event = 'events';
  const response = [1, 2, 3];

  return from(response).pipe(
    map(data => ({ event, data })),
  );
}
```

In the example above, the message handler will respond **3 times** (with each item from the array).

#### Lifecycle hooks[#](/websockets/gateways#lifecycle-hooks)

There are 3 useful lifecycle hooks available. All of them have corresponding interfaces and are described in the following table:

|                       |                                                                                                                                         |
| --------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| `OnGatewayInit`       | Forces to implement the `afterInit()` method. Takes library-specific server instance as an argument (and spreads the rest if required). |
| `OnGatewayConnection` | Forces to implement the `handleConnection()` method. Takes library-specific client socket instance as an argument.                      |
| `OnGatewayDisconnect` | Forces to implement the `handleDisconnect()` method. Takes library-specific client socket instance as an argument.                      |

> **Hint** Each lifecycle interface is exposed from `@nestjs/websockets` package.

#### Server and Namespace[#](/websockets/gateways#server-and-namespace)

Occasionally, you may want to have a direct access to the native, **platform-specific** server instance. The reference to this object is passed as an argument to the `afterInit()` method (`OnGatewayInit` interface). Another option is to use the `@WebSocketServer()` decorator.

```typescript

@WebSocketServer()
server: Server;
```

Also, you can retrieve the corresponding namespace using the `namespace` attribute, as follows:

```typescript

@WebSocketGateway({ namespace: 'my-namespace' })
export class EventsGateway {
  @WebSocketServer()
  namespace: Namespace;
}
```

`@WebSocketServer()` decorator injects a server instance by referencing the metadata stored by the `@WebSocketGateway()` decorator. If you provide the namespace option to the `@WebSocketGateway()` decorator, `@WebSocketServer()` decorator returns a `Namespace` instance instead of a `Server` instance.

> **Notice** The `@WebSocketServer()` decorator is imported from the `@nestjs/websockets` package.

Nest will automatically assign the server instance to this property once it is ready to use.

## Official enterprise support

* **Providing technical guidance
* **Performing in-depth code reviews
* **Mentoring team members
* **Advising best practices

[Explore more](https://enterprise.nestjs.com "Enterprise | NestJS - A progressive Node.js framework")

#### Example[#](/websockets/gateways#example)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/02-gateways).

----
url: https://docs.nestjs.com/v5/techniques/file-upload
----

### File upload

In order to handle file uploading, Nest makes use of [multer](https://github.com/expressjs/multer) middleware. This middleware is fully configurable and you can adjust its behavior to your application requirements.

Multer is middleware for handling `multipart/form-data`, which is primarily used for uploading files.

> **Warning** Multer will not process any form which is not multipart (`multipart/form-data`). Besides, this package won't work with the `FastifyAdapter`.

#### Basic example

When we want to upload a single file, we simply tie `FileInterceptor()` to the handler, and then, pull outs `file` from the `request` using `@UploadedFile()` decorator.

JS TS

TypeScript

```typescript

@Post('upload')
@UseInterceptors(FileInterceptor('file'))
uploadFile(@UploadedFile() file) {
  console.log(file);
}
```

TypeScript

```typescript

@Post('upload')
@UseInterceptors(FileInterceptor('file'))
@Bind(UploadedFile())
uploadFile(file) {
  console.log(file);
}
```

> **Hint** Both `FileInterceptor()` and `@UploadedFile()` decorator are exposed from `@nestjs/common` package.

The `FileInterceptor()` takes two arguments, a `fieldName` (points to field from HTML form that holds a file) and optional `options` object. These `MulterOptions` are equivalent to those passed into multer constructor (more details [here](https://github.com/expressjs/multer#multeropts))

#### Array of files

In order to upload an array of files, we use `FilesInterceptor()`. This interceptor takes three arguments. A `fieldName` (that remains the same), `maxCount` which is a maximum number of files that can be uploaded at the same time, and optional `MulterOptions` object. Additionally, to pick files from `request` object, we use `@UploadedFiles()` decorator

JS TS

TypeScript

```typescript

@Post('upload')
@UseInterceptors(FilesInterceptor('files'))
uploadFile(@UploadedFiles() files) {
  console.log(files);
}
```

TypeScript

```typescript

@Post('upload')
@UseInterceptors(FilesInterceptor('files'))
@Bind(UploadedFiles())
uploadFile(files) {
  console.log(files);
}
```

> **Hint** Both `FilesInterceptor()` and `@UploadedFiles()` decorator are exposed from `@nestjs/common` package.

#### Multiple files

To upload multiple fields (all with different keys), we use `FileFieldsInterceptor()` decorator.

JS TS

TypeScript

```typescript

@Post('upload')
@UseInterceptors(FileFieldsInterceptor([
  { name: 'avatar', maxCount: 1 },
  { name: 'background', maxCount: 1 },
]))
uploadFile(@UploadedFiles() files) {
  console.log(files);
}
```

TypeScript

```typescript

@Post('upload')
@Bind(UploadedFiles())
@UseInterceptors(FileFieldsInterceptor([
  { name: 'avatar', maxCount: 1 },
  { name: 'background', maxCount: 1 },
]))
uploadFile(files) {
  console.log(files);
}
```

#### Default options

To customize [multer](https://github.com/expressjs/multer) behavior, you can register the `MulterModule`. We support all options listed [here](https://github.com/expressjs/multer#multeropts).

TypeScript

```typescript

MulterModule.register({
  dest: '/upload',
}),
```

#### Async configuration

Quite often you might want to asynchronously pass your module options instead of passing them beforehand. In such case, use `registerAsync()` method, that provides a couple of various ways to deal with async data.

First possible approach is to use a factory function:

TypeScript

```typescript

MulterModule.registerAsync({
  useFactory: () => ({
    dest: '/upload',
  }),
})
```

Obviously, our factory behaves like every other one (might be `async` and is able to inject dependencies through `inject`).

TypeScript

```typescript

MulterModule.registerAsync({
  imports: [ConfigModule],
  useFactory: async (configService: ConfigService) => ({
    dest: configService.getString('MULTER_DEST'),
  }),
  inject: [ConfigService],
})
```

Alternatively, you are able to use class instead of a factory.

TypeScript

```typescript

MulterModule.registerAsync({
  useClass: MulterConfigService,
})
```

Above construction will instantiate `MulterConfigService` inside `MulterModule` and will leverage it to create options object. The `MulterConfigService` has to implement `MulterOptionsFactory` interface.

TypeScript

```typescript

@Injectable()
class MulterConfigService implements MulterOptionsFactory {
  createMulterOptions(): MulterModuleOptions {
    return {
      dest: '/upload',
    };
  }
}
```

In order to prevent the creation of `MulterConfigService` inside `MulterModule` and use a provider imported from a different module, you can use the `useExisting` syntax.

TypeScript

```typescript

MulterModule.registerAsync({
  imports: [ConfigModule],
  useExisting: ConfigService,
})
```

It works the same as `useClass` with one critical difference - `MulterModule` will lookup imported modules to reuse already created `ConfigService`, instead of instantiating it on its own.

* File upload
* Basic example
* Array of files
* Multiple files
* Default options

----
url: https://docs.nestjs.com/v6/interceptors
----

* [Interceptors](https://docs.nestjs.com/v6/interceptors#interceptors)
* [Basics](https://docs.nestjs.com/v6/interceptors#basics)
* [Execution context](https://docs.nestjs.com/v6/interceptors#execution-context)
* [Call handler](https://docs.nestjs.com/v6/interceptors#call-handler)
* [Aspect interception](https://docs.nestjs.com/v6/interceptors#aspect-interception)
* [Binding interceptors](https://docs.nestjs.com/v6/interceptors#binding-interceptors)
* [Response mapping](https://docs.nestjs.com/v6/interceptors#response-mapping)
* [Exception mapping](https://docs.nestjs.com/v6/interceptors#exception-mapping)
* [Stream overriding](https://docs.nestjs.com/v6/interceptors#stream-overriding)
* [More operators](https://docs.nestjs.com/v6/interceptors#more-operators)

[](https://srv.carbonads.net/ads/click/x/GTND4277CVSD5KJUCAYLYKQUF67D62QUF6BILZ3JCAAI623WC67D45QKCKBIP23UC6BIPK37CTAIV5QUCY7IP2JKC6SILKJUCT7DEK3EHJNCLSIZ)[Start your AI journey with free access to leading cloud products and services. ](https://srv.carbonads.net/ads/click/x/GTND4277CVSD5KJUCAYLYKQUF67D62QUF6BILZ3JCAAI623WC67D45QKCKBIP23UC6BIPK37CTAIV5QUCY7IP2JKC6SILKJUCT7DEK3EHJNCLSIZ)[ads via Carbon](http://carbonads.net/?utm_source=nestjscom\&utm_medium=ad_via_link\&utm_campaign=in_unit\&utm_term=carbon)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/interceptors.md "Suggest Edits")

### Interceptors

An interceptor is a class annotated with the `@Injectable()` decorator. Interceptors should implement the `NestInterceptor` interface.

Interceptors have a set of useful capabilities which are inspired by the [Aspect Oriented Programming](https://en.wikipedia.org/wiki/Aspect-oriented_programming) (AOP) technique. They make it possible to:

* bind **extra logic** before / after method execution
* **transform** the result returned from a function
* **transform** the exception thrown from a function
* **extend** the basic function behavior
* completely **override** a function depending on specific conditions (e.g., for caching purposes)

#### Basics[#](/interceptors#basics)

Each interceptor implements the `intercept()` method, which takes two arguments. The first one is the `ExecutionContext` instance (exactly the same object as for [guards](/v6/guards)). The `ExecutionContext` inherits from `ArgumentsHost`. We saw `ArgumentsHost` before in the exception filters chapter. There, we saw that it's a wrapper around arguments that have been passed to the original handler, and contains different arguments arrays based on the type of the application. You can refer back to the [exception filters](https://docs.nestjs.com/exception-filters#arguments-host) for more on this topic.

#### Execution context[#](/interceptors#execution-context)

By extending `ArgumentsHost`, `ExecutionContext` also adds several new helper methods that provide additional details about the current execution process. These details can be helpful in building more generic interceptors that can work across a broad set of controllers, methods, and execution contexts. Learn more about `ExecutionContext`[here](/v6/fundamentals/execution-context).

```typescript

import { Injectable, NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
import { Observable } from 'rxjs';
import { tap } from 'rxjs/operators';

@Injectable()
export class LoggingInterceptor implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    console.log('Before...');

    const now = Date.now();
    return next
      .handle()
      .pipe(
        tap(() => console.log(`After... ${Date.now() - now}ms`)),
      );
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';
import { Observable } from 'rxjs';
import { tap } from 'rxjs/operators';

@Injectable()
export class LoggingInterceptor {
  intercept(context, next) {
    console.log('Before...');

    const now = Date.now();
    return next
      .handle()
      .pipe(
        tap(() => console.log(`After... ${Date.now() - now}ms`)),
      );
  }
}
```

> **Hint** The `NestInterceptor<T, R>` is a generic interface in which `T` indicates the type of an `Observable<T>` (supporting the response stream), and `R` is the type of the value wrapped by `Observable<R>`.

> **Notice** Interceptors, like controllers, providers, guards, and so on, can **inject dependencies** through their `constructor`.

Since `handle()` returns an RxJS `Observable`, we have a wide choice of operators we can use to manipulate the stream. In the example above, we used the `tap()` operator, which invokes our anonymous logging function upon graceful or exceptional termination of the observable stream, but doesn't otherwise interfere with the response cycle.

#### Binding interceptors[#](/interceptors#binding-interceptors)

In order to set up the interceptor, we use the `@UseInterceptors()` decorator imported from the `@nestjs/common` package. Like [pipes](/v6/pipes) and [guards](/v6/guards), interceptors can be controller-scoped, method-scoped, or global-scoped.

cats.controller.ts

JS TS

```typescript

@UseInterceptors(LoggingInterceptor)
export class CatsController {}
```

> **Hint** The `@UseInterceptors()` decorator is imported from the `@nestjs/common` package.

Using the above construction, each route handler defined in `CatsController` will use `LoggingInterceptor`. When someone calls the `GET /cats` endpoint, you'll see the following output in your standard output:

```typescript

Before...
After... 1ms
```

Note that we passed the `LoggingInterceptor` type (instead of an instance), leaving responsibility for instantiation to the framework and enabling dependency injection. As with pipes, guards, and exception filters, we can also pass an in-place instance:

cats.controller.ts

JS TS

```typescript

@UseInterceptors(new LoggingInterceptor())
export class CatsController {}
```

As mentioned, the construction above attaches the interceptor to every handler declared by this controller. If we want to restrict the interceptor's scope to a single method, we simply apply the decorator at the **method level**.

In order to set up a global interceptor, we use the `useGlobalInterceptors()` method of the Nest application instance:

```typescript

const app = await NestFactory.create(AppModule);
app.useGlobalInterceptors(new LoggingInterceptor());
```

Global interceptors are used across the whole application, for every controller and every route handler. In terms of dependency injection, global interceptors registered from outside of any module (with `useGlobalInterceptors()`, as in the example above) cannot inject dependencies since this is done outside the context of any module. In order to solve this issue, you can set up an interceptor **directly from any module** using the following construction:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { APP_INTERCEPTOR } from '@nestjs/core';

@Module({
  providers: [
    {
      provide: APP_INTERCEPTOR,
      useClass: LoggingInterceptor,
    },
  ],
})
export class AppModule {}
```

> **Hint** When using this approach to perform dependency injection for the interceptor, note that regardless of the module where this construction is employed, the interceptor is, in fact, global. Where should this be done? Choose the module where the interceptor (`LoggingInterceptor` in the example above) is defined. Also, `useClass` is not the only way of dealing with custom provider registration. Learn more [here](/v6/fundamentals/custom-providers).

#### Response mapping[#](/interceptors#response-mapping)

We already know that `handle()` returns an `Observable`. The stream contains the value **returned** from the route handler, and thus we can easily mutate it using RxJS's `map()` operator.

> **Warning** The response mapping feature doesn't work with the library-specific response strategy (using the `@Res()` object directly is forbidden).

Let's create the `TransformInterceptor`, which will modify each response in a trivial way to demonstrate the process. It will use RxJS's `map()` operator to assign the response object to the `data` property of a newly created object, returning the new object to the client.

transform.interceptor.ts

JS TS

```typescript

import { Injectable, NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';

export interface Response<T> {
  data: T;
}

@Injectable()
export class TransformInterceptor<T> implements NestInterceptor<T, Response<T>> {
  intercept(context: ExecutionContext, next: CallHandler): Observable<Response<T>> {
    return next.handle().pipe(map(data => ({ data })));
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';
import { map } from 'rxjs/operators';

@Injectable()
export class TransformInterceptor {
  intercept(context, next) {
    return next.handle().pipe(map(data => ({ data })));
  }
}
```

> **Hint** Nest interceptors work with both synchronous and asynchronous `intercept()` methods. You can simply switch the method to `async` if necessary.

With the above construction, when someone calls the `GET /cats` endpoint, the response would look like the following (assuming that route handler returns an empty array `[]`):

```json

{
  "data": []
}
```

Interceptors have great value in creating re-usable solutions to requirements that occur across an entire application. For example, imagine we need to transform each occurrence of a `null` value to an empty string `''`. We can do it using one line of code and bind the interceptor globally so that it will automatically be used by each registered handler.

JS TS

```typescript

import { Injectable, NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';

@Injectable()
export class ExcludeNullInterceptor implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    return next
      .handle()
      .pipe(map(value => value === null ? '' : value ));
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';
import { map } from 'rxjs/operators';

@Injectable()
export class ExcludeNullInterceptor {
  intercept(context, next) {
    return next
      .handle()
      .pipe(map(value => value === null ? '' : value ));
  }
}
```

#### Exception mapping[#](/interceptors#exception-mapping)

Another interesting use-case is to take advantage of RxJS's `catchError()` operator to override thrown exceptions:

errors.interceptor.ts

JS TS

```typescript

import {
  Injectable,
  NestInterceptor,
  ExecutionContext,
  BadGatewayException,
  CallHandler,
} from '@nestjs/common';
import { Observable, throwError } from 'rxjs';
import { catchError } from 'rxjs/operators';

@Injectable()
export class ErrorsInterceptor implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    return next
      .handle()
      .pipe(
        catchError(err => throwError(new BadGatewayException())),
      );
  }
}
```

```typescript

import { Injectable, BadGatewayException } from '@nestjs/common';
import { throwError } from 'rxjs';
import { catchError } from 'rxjs/operators';

@Injectable()
export class ErrorsInterceptor {
  intercept(context, next) {
    return next
      .handle()
      .pipe(
        catchError(err => throwError(new BadGatewayException())),
      );
  }
}
```

#### Stream overriding[#](/interceptors#stream-overriding)

There are several reasons why we may sometimes want to completely prevent calling the handler and return a different value instead. An obvious example is to implement a cache to improve response time. Let's take a look at a simple **cache interceptor** that returns its response from a cache. In a realistic example, we'd want to consider other factors like TTL, cache invalidation, cache size, etc., but that's beyond the scope of this discussion. Here we'll provide a basic example that demonstrates the main concept.

cache.interceptor.ts

JS TS

```typescript

import { Injectable, NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
import { Observable, of } from 'rxjs';

@Injectable()
export class CacheInterceptor implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    const isCached = true;
    if (isCached) {
      return of([]);
    }
    return next.handle();
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';
import { of } from 'rxjs';

@Injectable()
export class CacheInterceptor {
  intercept(context, next) {
    const isCached = true;
    if (isCached) {
      return of([]);
    }
    return next.handle();
  }
}
```

Our `CacheInterceptor` has a hardcoded `isCached` variable and a hardcoded response `[]` as well. The key point to note is that we return a new stream here, created by the RxJS `of()` operator, therefore the route handler **won't be called** at all. When someone calls an endpoint that makes use of `CacheInterceptor`, the response (a hardcoded, empty array) will be returned immediately. In order to create a generic solution, you can take advantage of `Reflector` and create a custom decorator. The `Reflector` is well described in the [guards](/v6/guards) chapter.

#### More operators[#](/interceptors#more-operators)

The possibility of manipulating the stream using RxJS operators gives us many capabilities. Let's consider another common use case. Imagine you would like to handle **timeouts** on route requests. When your endpoint doesn't return anything after a period of time, you want to terminate with an error response. The following construction enables this:

timeout.interceptor.ts

JS TS

```typescript

import { Injectable, NestInterceptor, ExecutionContext, CallHandler, RequestTimeoutException } from '@nestjs/common';
import { Observable, throwError, TimeoutError } from 'rxjs';
import { catchError, timeout } from 'rxjs/operators';

@Injectable()
export class TimeoutInterceptor implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    return next.handle().pipe(
      timeout(5000),
      catchError(err => {
        if (err instanceof TimeoutError) {
          return throwError(new RequestTimeoutException());
        }
        return throwError(err);
      }),
    );
  };
};
```

```typescript

import { Injectable, RequestTimeoutException } from '@nestjs/common';
import { Observable, throwError, TimeoutError } from 'rxjs';
import { catchError, timeout } from 'rxjs/operators';

@Injectable()
export class TimeoutInterceptor {
  intercept(context, next) {
    return next.handle().pipe(
      timeout(5000),
      catchError(err => {
        if (err instanceof TimeoutError) {
          return throwError(new RequestTimeoutException());
        }
        return throwError(err);
      }),
    );
  };
};
```

After 5 seconds, request processing will be canceled. You can also add custom logic before throwing `RequestTimeoutException` (e.g. release resources).

----
url: https://docs.nestjs.com/graphql/complexity
----

[Skip to content](#content)

On this page

* [Complexity](https://docs.nestjs.com/graphql/complexity#complexity)
* [Installation](https://docs.nestjs.com/graphql/complexity#installation)
* [Getting started](https://docs.nestjs.com/graphql/complexity#getting-started)
* [Field-level complexity](https://docs.nestjs.com/graphql/complexity#field-level-complexity)
* [Query/Mutation-level complexity](https://docs.nestjs.com/graphql/complexity#querymutation-level-complexity)

### Complexity

> **Warning** This chapter applies only to the code first approach.

Query complexity lets you define how complex certain fields are, and restrict queries with a **maximum complexity**. The idea is to express the complexity of each field as a number. A common default is to give each field a complexity of `1`. You can also customize how the complexity of a GraphQL query is calculated with complexity estimators. A complexity estimator is a function that calculates the complexity of a field. You can add any number of estimators to the rule, and they run one after another. The first estimator that returns a numeric value determines the complexity of that field.

The `@nestjs/graphql` package integrates with tools like [graphql-query-complexity](https://github.com/slicknode/graphql-query-complexity), which provides a solution based on cost analysis. With this library, you can reject queries that are too costly to execute.

#### Installation[#](/graphql/complexity#installation)

To begin, install the required dependency:

```bash

$ npm install --save graphql-query-complexity
```

#### Getting started[#](/graphql/complexity#getting-started)

Once the installation is complete, define the `ComplexityPlugin` class:

```typescript

import { GraphQLSchemaHost } from '@nestjs/graphql';
import { Plugin } from '@nestjs/apollo';
import {
  ApolloServerPlugin,
  BaseContext,
  GraphQLRequestListener,
} from '@apollo/server';
import { GraphQLError } from 'graphql';
import {
  fieldExtensionsEstimator,
  getComplexity,
  simpleEstimator,
} from 'graphql-query-complexity';

@Plugin()
export class ComplexityPlugin implements ApolloServerPlugin {
  constructor(private gqlSchemaHost: GraphQLSchemaHost) {}

  async requestDidStart(): Promise<GraphQLRequestListener<BaseContext>> {
    const maxComplexity = 20;
    const { schema } = this.gqlSchemaHost;

    return {
      async didResolveOperation({ request, document }) {
        const complexity = getComplexity({
          schema,
          operationName: request.operationName,
          query: document,
          variables: request.variables,
          estimators: [
            fieldExtensionsEstimator(),
            simpleEstimator({ defaultComplexity: 1 }),
          ],
        });
        if (complexity > maxComplexity) {
          throw new GraphQLError(
            `Query is too complex: ${complexity}. Maximum allowed complexity: ${maxComplexity}`,
          );
        }
        console.log('Query Complexity:', complexity);
      },
    };
  }
}
```

For demonstration purposes, the maximum allowed complexity is set to `20`. The example above uses two estimators, `fieldExtensionsEstimator` and `simpleEstimator`:

* `fieldExtensionsEstimator`: extracts the complexity value defined for each field of your schema (through the field's `extensions`)
* `simpleEstimator`: returns a fixed complexity for each field (used as the fallback for fields without a defined complexity)

> **Hint** Remember to add this class to the `providers` array of a module.

#### Field-level complexity[#](/graphql/complexity#field-level-complexity)

With this plugin in place, you can define the complexity of any field by specifying the `complexity` property in the options object passed to the `@Field()` decorator:

```typescript

@Field({ complexity: 3 })
title: string;
```

Alternatively, you can define an estimator function:

```typescript

@Field({ complexity: (options: ComplexityEstimatorArgs) => ... })
title: string;
```

#### Query/Mutation-level complexity[#](/graphql/complexity#querymutation-level-complexity)

The `@Query()` and `@Mutation()` decorators also accept a `complexity` property in their options object:

```typescript

@Query(() => [Item], {
  complexity: (options: ComplexityEstimatorArgs) =>
    options.args.count * options.childComplexity,
})
items(@Args('count') count: number) {
  return this.itemsService.getItems({ count });
}
```

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/complexity.md)

----
url: https://docs.nestjs.com/v11/recipes/mongodb
----

* [MongoDB (Mongoose)](https://docs.nestjs.com/v11/recipes/mongodb#mongodb-mongoose)
* [Getting started](https://docs.nestjs.com/v11/recipes/mongodb#getting-started)
* [Model injection](https://docs.nestjs.com/v11/recipes/mongodb#model-injection)
* [Example](https://docs.nestjs.com/v11/recipes/mongodb#example)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/recipes/mongodb.md "Suggest Edits")

### MongoDB (Mongoose)

> **Warning** In this article, you'll learn how to create a `DatabaseModule` based on the **Mongoose** package from scratch using custom components. As a consequence, this solution contains a lot of overhead that you can omit using ready to use and available out-of-the-box dedicated `@nestjs/mongoose` package. To learn more, see [here](/v11/techniques/mongodb).

[Mongoose](https://mongoosejs.com) is the most popular [MongoDB](https://www.mongodb.org/) object modeling tool.

#### Getting started[#](/recipes/mongodb#getting-started)

To start the adventure with this library we have to install all required dependencies:

```typescript

$ npm install --save mongoose
```

The first step we need to do is to establish the connection with our database using `connect()` function. The `connect()` function returns a `Promise`, and therefore we have to create an [async provider](/v11/fundamentals/async-components).

database.providers.ts

JS TS

```typescript

import * as mongoose from 'mongoose';

export const databaseProviders = [
  {
    provide: 'DATABASE_CONNECTION',
    useFactory: (): Promise<typeof mongoose> =>
      mongoose.connect('mongodb://localhost/nest'),
  },
];
```

```typescript

import * as mongoose from 'mongoose';

export const databaseProviders = [
  {
    provide: 'DATABASE_CONNECTION',
    useFactory: () => mongoose.connect('mongodb://localhost/nest'),
  },
];
```

> **Hint** Following best practices, we declared the custom provider in the separated file which has a `*.providers.ts` suffix.

Then, we need to export these providers to make them **accessible** for the rest part of the application.

database.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { databaseProviders } from './database.providers';

@Module({
  providers: [...databaseProviders],
  exports: [...databaseProviders],
})
export class DatabaseModule {}
```

Now we can inject the `Connection` object using `@Inject()` decorator. Each class that would depend on the `Connection` async provider will wait until a `Promise` is resolved.

#### Model injection[#](/recipes/mongodb#model-injection)

With Mongoose, everything is derived from a [Schema](https://mongoosejs.com/docs/guide.html). Let's define the `CatSchema`:

schemas/cat.schema.ts

JS TS

```typescript

import * as mongoose from 'mongoose';

export const CatSchema = new mongoose.Schema({
  name: String,
  age: Number,
  breed: String,
});
```

The `CatSchema` belongs to the `cats` directory. This directory represents the `CatsModule`.

Now it's time to create a **Model** provider:

cats.providers.ts

JS TS

```typescript

import { Connection } from 'mongoose';
import { CatSchema } from './schemas/cat.schema';

export const catsProviders = [
  {
    provide: 'CAT_MODEL',
    useFactory: (connection: Connection) => connection.model('Cat', CatSchema),
    inject: ['DATABASE_CONNECTION'],
  },
];
```

```typescript

import { CatSchema } from './schemas/cat.schema';

export const catsProviders = [
  {
    provide: 'CAT_MODEL',
    useFactory: (connection) => connection.model('Cat', CatSchema),
    inject: ['DATABASE_CONNECTION'],
  },
];
```

> **Warning** In the real-world applications you should avoid **magic strings**. Both `CAT_MODEL` and `DATABASE_CONNECTION` should be kept in the separated `constants.ts` file.

Now we can inject the `CAT_MODEL` to the `CatsService` using the `@Inject()` decorator:

cats.service.ts

JS TS

```typescript

import { Model } from 'mongoose';
import { Injectable, Inject } from '@nestjs/common';
import { Cat } from './interfaces/cat.interface';
import { CreateCatDto } from './dto/create-cat.dto';

@Injectable()
export class CatsService {
  constructor(
    @Inject('CAT_MODEL')
    private catModel: Model<Cat>,
  ) {}

  async create(createCatDto: CreateCatDto): Promise<Cat> {
    const createdCat = new this.catModel(createCatDto);
    return createdCat.save();
  }

  async findAll(): Promise<Cat[]> {
    return this.catModel.find().exec();
  }
}
```

```typescript

import { Injectable, Dependencies } from '@nestjs/common';

@Injectable()
@Dependencies('CAT_MODEL')
export class CatsService {
  constructor(catModel) {
    this.catModel = catModel;
  }

  async create(createCatDto) {
    const createdCat = new this.catModel(createCatDto);
    return createdCat.save();
  }

  async findAll() {
    return this.catModel.find().exec();
  }
}
```

In the above example we have used the `Cat` interface. This interface extends the `Document` from the mongoose package:

```typescript

import { Document } from 'mongoose';

export interface Cat extends Document {
  readonly name: string;
  readonly age: number;
  readonly breed: string;
}
```

The database connection is **asynchronous**, but Nest makes this process completely invisible for the end-user. The `CatModel` class is waiting for the db connection, and the `CatsService` is delayed until model is ready to use. The entire application can start when each class is instantiated.

Here is a final `CatsModule`:

cats.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';
import { catsProviders } from './cats.providers';
import { DatabaseModule } from '../database/database.module';

@Module({
  imports: [DatabaseModule],
  controllers: [CatsController],
  providers: [
    CatsService,
    ...catsProviders,
  ],
})
export class CatsModule {}
```

> **Hint** Do not forget to import the `CatsModule` into the root `AppModule`.

#### Example[#](/recipes/mongodb#example)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/14-mongoose-base).

----
url: https://docs.nestjs.com/v6/techniques/configuration
----

* [Configuration](https://docs.nestjs.com/v6/techniques/configuration#configuration)
* [Installation](https://docs.nestjs.com/v6/techniques/configuration#installation)
* [Getting started](https://docs.nestjs.com/v6/techniques/configuration#getting-started)
* [Custom env file path](https://docs.nestjs.com/v6/techniques/configuration#custom-env-file-path)
* [Disable env variables loading](https://docs.nestjs.com/v6/techniques/configuration#disable-env-variables-loading)
* [Use module globally](https://docs.nestjs.com/v6/techniques/configuration#use-module-globally)
* [Custom configuration files](https://docs.nestjs.com/v6/techniques/configuration#custom-configuration-files)
* [Using the ConfigService](https://docs.nestjs.com/v6/techniques/configuration#using-the-configservice)
* [Configuration namespaces](https://docs.nestjs.com/v6/techniques/configuration#configuration-namespaces)
* [Partial registration](https://docs.nestjs.com/v6/techniques/configuration#partial-registration)
* [Schema validation](https://docs.nestjs.com/v6/techniques/configuration#schema-validation)
* [Custom getter functions](https://docs.nestjs.com/v6/techniques/configuration#custom-getter-functions)
* [Expandable variables](https://docs.nestjs.com/v6/techniques/configuration#expandable-variables)
* [Using in the main.ts](https://docs.nestjs.com/v6/techniques/configuration#using-in-the-maints)

```bash

$ npm i --save @nestjs/config
```

> **Hint** The `@nestjs/config` package internally uses [dotenv](https://github.com/motdotla/dotenv).

#### Getting started[#](/techniques/configuration#getting-started)

Once the installation process is complete, we can import the `ConfigModule`. Typically, we'll import it into the root `AppModule` and control its behavior using the `.forRoot()` static method. During this step, environment variable key/value pairs are parsed and resolved. Later, we'll see several options for accessing the `ConfigService` class of the `ConfigModule` in our other feature modules.

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';

@Module({
  imports: [ConfigModule.forRoot()],
})
export class AppModule {}
```

The above code will load and parse a `.env` file from the default location (the project root directory), merge key/value pairs from the `.env` file with environment variables assigned to `process.env`, and store the result in a private structure that you can access through the `ConfigService`. The `forRoot()` method registers the `ConfigService` provider, which provides a `get()` method for reading these parsed/merged configuration variables. Since `@nestjs/config` relies on [dotenv](https://github.com/motdotla/dotenv), it uses that package's rules for resolving conflicts in environment variable names. When a key exists both in the runtime environment as an environment variable (e.g., via OS shell exports like `export DATABASE_USER=test`) and in a `.env` file, the runtime environment variable takes precedence.

A sample `.env` file looks something like this:

```json

DATABASE_USER=test
DATABASE_PASSWORD=test
```

#### Custom env file path[#](/techniques/configuration#custom-env-file-path)

By default, the package looks for a `.env` file in the root directory of the application. To specify another path for the `.env` file, set the `envFilePath` property of an (optional) options object you pass to `forRoot()`, as follows:

```typescript

ConfigModule.forRoot({
  envFilePath: '.development.env',
});
```

#### Disable env variables loading[#](/techniques/configuration#disable-env-variables-loading)

If you don't want to load the `.env` file, but instead would like to simply access environment variables from the runtime environment (as with OS shell exports like `export DATABASE_USER=test`), set the options object's `ignoreEnvFile` property to `true`, as follows:

```typescript

ConfigModule.forRoot({
  ignoreEnvFile: true,
});
```

#### Use module globally[#](/techniques/configuration#use-module-globally)

When you want to use `ConfigModule` in other modules, you'll need to import it (as is standard with any Nest module). Alternatively, declare it as a [global module](https://docs.nestjs.com/modules#global-modules) by setting the options object's `isGlobal` property to `true`, as shown below. In that case, you will not need to import `ConfigModule` in other modules once it's been loaded in the root module (e.g., `AppModule`).

```typescript

ConfigModule.forRoot({
  isGlobal: true,
});
```

#### Custom configuration files[#](/techniques/configuration#custom-configuration-files)

For more complex projects, you may utilize custom configuration files to return nested configuration objects. This allows you to group related configuration settings by function (e.g., database-related settings), and to store related settings in individual files to help manage them independently.

A custom configuration file exports a factory function that returns a configuration object. The configuration object can be any arbitrarily nested plain JavaScript object. The `process.env` object will contain the fully resolved environment variable key/value pairs (with `.env` file and externally defined variables resolved and merged as described [above](techniques/configuration#getting-started)). Since you control the returned configuration object, you can add any required logic to cast values to an appropriate type, set default values, etc. For example:

config/configuration.ts

JS TS

```typescript

export default () => ({
  port: parseInt(process.env.PORT, 10) || 3000,
  database: {
    host: process.env.DATABASE_HOST,
    port: parseInt(process.env.DATABASE_PORT, 10) || 5432
  }
});
```

We load this file using the `load` property of the options object we pass to the `ConfigModule.forRoot()` method:

```typescript

import configuration from './config/configuration';

@Module({
  imports: [
    ConfigModule.forRoot({
      load: [configuration],
    }),
  ],
})
export class AppModule {}
```

> **Notice** The value assigned to the `load` property is an array, allowing you to load multiple configuration files (e.g. `load: [databaseConfig, authConfig]`)

```typescript

@Module({
  imports: [ConfigModule],
  // ...
})
```

Then we can inject it using standard constructor injection:

```typescript

constructor(private readonly configService: ConfigService) {}
```

And use it in our class:

```typescript

// get an environment variable
const dbUser = this.configService.get<string>('DATABASE_USER');

// get a custom configuration value
const dbHost = this.configService.get<string>('database.host');
```

As shown above, use the `configService.get()` method to get a simple environment variable by passing the variable name. You can do TypeScript type hinting by passing the type, as shown above (e.g., `get<string>(...)`). The `get()` method can also traverse a nested custom configuration object (created via a [Custom configuration file](techniques/configuration#custom-configuration-files), as shown in the second example above. The `get()` method also takes an optional second argument defining a default value, which will be returned when the key doesn't exist, as shown below:

```typescript

// use "localhost" when "database.host" is not defined
const dbHost = this.configService.get<string>('database.host', 'localhost');
```

#### Configuration namespaces[#](/techniques/configuration#configuration-namespaces)

The `ConfigModule` allows you to define and load multiple custom configuration files, as shown in [Custom configuration files](techniques/configuration#custom-configuration-files) above. You can manage complex configuration object hierarchies with nested configuration objects as shown in that section. Alternatively, you can return a "namespaced" configuration object with the `registerAs()` function as follows:

config/database.config.ts

JS TS

```typescript

export default registerAs('database', () => ({
  host: process.env.DATABASE_HOST,
  port: process.env.DATABASE_PORT || 5432
}));
```

As with custom configuration files, inside your `registerAs()` factory function, the `process.env` object will contain the fully resolved environment variable key/value pairs (with `.env` file and externally defined variables resolved and merged as described [above](techniques/configuration#getting-started)).

> **Hint** The `registerAs` function is exported from the `@nestjs/config` package.

Load a namespaced configuration with the `load` property of the `forRoot()` method's options object, in the same way you load a custom configuration file:

```typescript

import databaseConfig from './config/database.config';

@Module({
  imports: [
    ConfigModule.forRoot({
      load: [databaseConfig],
    }),
  ],
})
export class AppModule {}
```

Now, to get the `host` value from the `database` namespace, use dot notation. Use `'database'` as the prefix to the property name, corresponding to the name of the namespace (passed as the first argument to the `registerAs()` function):

```typescript

const dbHost = this.configService.get<string>('database.host');
```

A reasonable alternative is to inject the `database` namespace directly. This allows us to benefit from strong typing:

```typescript

constructor(
  @Inject(databaseConfig.KEY)
  private databaseConfig: ConfigType<typeof databaseConfig>,
) {}
```

> **Hint** The `ConfigType` is exported from the `@nestjs/config` package.

#### Partial registration[#](/techniques/configuration#partial-registration)

Thus far, we've processed configuration files in our root module (e.g., `AppModule`), with the `forRoot()` method. Perhaps you have a more complex project structure, with feature-specific configuration files located in multiple different directories. Rather than load all these files in the root module, the `@nestjs/config` package provides a feature called **partial registration**, which references only the configuration files associated with each feature module. Use the `forFeature()` static method within a feature module to perform this partial registration, as follows:

```typescript

import databaseConfig from './config/database.config';

@Module({
  imports: [ConfigModule.forFeature(databaseConfig)],
})
export class DatabaseModule {}
```

> **Warning** In some circumstances, you may need to access properties loaded via partial registration using the `onModuleInit()` hook, rather than in a constructor. This is because the `forFeature()` method is run during module initialization, and the order of module initialization is indeterminate. If you access values loaded this way by another module, in a constructor, the module that the configuration depends upon may not yet have initialized. The `onModuleInit()` method runs only after all modules it depends upon have been initialized, so this technique is safe.

#### Schema validation[#](/techniques/configuration#schema-validation)

It is standard practice to throw an exception during application startup if required environment variables haven't been provided or if they don't meet certain validation rules. The `@nestjs/config` package enables use of the [Joi](https://github.com/hapijs/joi) npm package to support this type of validation. With Joi, you define an object schema and validate JavaScript objects against it.

Install Joi (and its types, for **TypeScript** users):

```bash

$ npm install --save @hapi/joi
$ npm install --save-dev @types/hapi__joi
```

> **Notice** The latest version of `@hapi/joi` requires you to be running Node v12 or later. For older versions of node, please install `v16.1.8`. This is mainly after the release of `v17.0.2` which causes errors during build time. For more information, please refer to [their documentation](https://hapi.dev/family/joi/?v=17.0.2#install) & this [github issue](https://github.com/hapijs/joi/issues/2266#issuecomment-571667769).

Now we can define a Joi validation schema and pass it via the `validationSchema` property of the `forRoot()` method's options object, as shown below:

app.module.ts

JS TS

```typescript

import * as Joi from '@hapi/joi';

@Module({
  imports: [
    ConfigModule.forRoot({
      validationSchema: Joi.object({
        NODE_ENV: Joi.string()
          .valid('development', 'production', 'test', 'provision')
          .default('development'),
        PORT: Joi.number().default(3000),
      }),
    }),
  ],
})
export class AppModule {}
```

By default, all schema keys are considered optional. Here, we set default values for `NODE_ENV` and `PORT` which will be used if we don't provide these variables in the environment (`.env` file or process environment). Alternatively, we can use the `required()` validation method to require that a value must be defined in the environment (`.env` file or process environment). In this case, the validation step will throw an exception if we don't provide the variable in the environment. See [Joi validation methods](https://hapi.dev/family/joi/?v=17.0.2#example) for more on how to construct validation schemas.

By default, unknown environment variables (environment variables whose keys are not present in the schema) are allowed and do not trigger a validation exception. By default, all validation errors are reported. You can alter these behaviors by passing an options object via the `validationOptions` key of the `forRoot()` options object. This options object can contain any of the standard validation options properties provided by [Joi validation options](https://hapi.dev/family/joi/api/?v=17.0.2#anyvalidvalues---aliases-equal). For example, to reverse the two settings above, pass options like this:

app.module.ts

JS TS

```typescript

import * as Joi from '@hapi/joi';

@Module({
  imports: [
    ConfigModule.forRoot({
      validationSchema: Joi.object({
        NODE_ENV: Joi.string()
          .valid('development', 'production', 'test', 'provision')
          .default('development'),
        PORT: Joi.number().default(3000),
      }),
      validationOptions: {
        allowUnknown: false,
        abortEarly: true,
      },
    }),
  ],
})
export class AppModule {}
```

The `@nestjs/config` package uses default settings of:

* `allowUnknown`: controls whether or not to allow unknown keys in the environment variables. Default is `true`
* `abortEarly`: if true, stops validation on the first error; if false, returns all errors. Defaults to `false`.

Note that once you decide to pass a `validationOptions` object, any settings you do not explicitly pass will default to `Joi` standard defaults (not the `@nestjs/config` defaults). For example, if you leave `allowUnknowns` unspecified in your custom `validationOptions` object, it will have the `Joi` default value of `false`. Hence, it is probably safest to specify **both** of these settings in your custom object.

## Hoodies, T-shirts, and accessories!

Support our future development by shopping in the official store!

[See more](https://nestjs.threadless.com/ "Shop | NestJS - A node.js framework built on top of TypeScript")

#### Custom getter functions[#](/techniques/configuration#custom-getter-functions)

`ConfigService` defines a generic `get()` method to retrieve a configuration value by key. We may also add `getter` functions to enable a little more natural coding style:

JS TS

```typescript

@Injectable()
export class ApiConfigService {
  constructor(private configService: ConfigService) {}

  get isAuthEnabled(): boolean {
    return this.configService.get('AUTH_ENABLED') === 'true';
  }
}
```

```typescript

@Dependencies(ConfigService)
@Injectable()
export class ApiConfigService {
  constructor(configService) {
    this.configService = configService;
  }

  get isAuthEnabled() {
    return this.configService.get('AUTH_ENABLED') === 'true';
  }
}
```

Now we can use the getter function as follows:

app.service.ts

JS TS

```typescript

@Injectable()
export class AppService {
  constructor(apiConfigService: ApiConfigService) {
    if (apiConfigService.isAuthEnabled) {
      // Authentication is enabled
    }
  }
}
```

```typescript

@Dependencies(ApiConfigService)
@Injectable()
export class AppService {
  constructor(apiConfigService) {
    if (apiConfigService.isAuthEnabled) {
      // Authentication is enabled
    }
  }
}
```

#### Expandable variables[#](/techniques/configuration#expandable-variables)

The `@nestjs/config` package supports environment variable expansion. With this technique, you can create nested environment variables, where one variable is referred to within the definition of another. For example:

```json

APP_URL=mywebsite.com
SUPPORT_EMAIL=support@${APP_URL}
```

With this construction, the variable `SUPPORT_EMAIL` resolves to `'support@mywebsite.com'`. Note the use of the `${...}` syntax to trigger resolving the value of the variable `APP_URL` inside the definition of `SUPPORT_EMAIL`.

> **Hint** For this feature, `@nestjs/config` package internally uses [dotenv-expand](https://github.com/motdotla/dotenv-expand).

Enable environment variable expansion using the `expandVariables` property in the options object passed to the `forRoot()` method of the `ConfigModule`, as shown below:

app.module.ts

JS TS

```typescript

@Module({
  imports: [
    ConfigModule.forRoot({
      // ...
      expandVariables: true,
    }),
  ],
})
export class AppModule {}
```

#### Using in the `main.ts`[#](/techniques/configuration#using-in-the-maints)

While our config is a stored in a service, it can still be used in the `main.ts` file. This way, you can use it to store variables such as the application port or the CORS host.

To access it, you must use the `app.get()` method, followed by the service reference:

```typescript

const configService = app.get(ConfigService);
```

You can then use it as usual, by calling the `get` method with the configuration key:

```typescript

const port = configService.get('PORT');
```

----
url: https://docs.nestjs.com/v8/techniques/queues
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Queues](https://docs.nestjs.com/v8/techniques/queues#queues)
* [Installation](https://docs.nestjs.com/v8/techniques/queues#installation)
* [Named configurations](https://docs.nestjs.com/v8/techniques/queues#named-configurations)
* [Producers](https://docs.nestjs.com/v8/techniques/queues#producers)
* [Named jobs](https://docs.nestjs.com/v8/techniques/queues#named-jobs)
* [Job options](https://docs.nestjs.com/v8/techniques/queues#job-options)
* [Consumers](https://docs.nestjs.com/v8/techniques/queues#consumers)
* [Request-scoped consumers](https://docs.nestjs.com/v8/techniques/queues#request-scoped-consumers)
* [Event listeners](https://docs.nestjs.com/v8/techniques/queues#event-listeners)
* [Queue management](https://docs.nestjs.com/v8/techniques/queues#queue-management)
* [Separate processes](https://docs.nestjs.com/v8/techniques/queues#separate-processes)
* [Async configuration](https://docs.nestjs.com/v8/techniques/queues#async-configuration)
* [Example](https://docs.nestjs.com/v8/techniques/queues#example)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/techniques/queues.md "Suggest Edits")

### Queues

Queues are a powerful design pattern that help you deal with common application scaling and performance challenges. Some examples of problems that Queues can help you solve are:

* Smooth out processing peaks. For example, if users can initiate resource-intensive tasks at arbitrary times, you can add these tasks to a queue instead of performing them synchronously. Then you can have worker processes pull tasks from the queue in a controlled manner. You can easily add new Queue consumers to scale up the back-end task handling as the application scales up.
* Break up monolithic tasks that may otherwise block the Node.js event loop. For example, if a user request requires CPU intensive work like audio transcoding, you can delegate this task to other processes, freeing up user-facing processes to remain responsive.
* Provide a reliable communication channel across various services. For example, you can queue tasks (jobs) in one process or service, and consume them in another. You can be notified (by listening for status events) upon completion, error or other state changes in the job life cycle from any process or service. When Queue producers or consumers fail, their state is preserved and task handling can restart automatically when nodes are restarted.

Nest provides the `@nestjs/bull` package as an abstraction/wrapper on top of [Bull](https://github.com/OptimalBits/bull), a popular, well supported, high performance Node.js based Queue system implementation. The package makes it easy to integrate Bull Queues in a Nest-friendly way to your application.

Bull uses [Redis](https://redis.io/) to persist job data, so you'll need to have Redis installed on your system. Because it is Redis-backed, your Queue architecture can be completely distributed and platform-independent. For example, you can have some Queue [producers](techniques/queues#producers) and [consumers](techniques/queues#consumers) and [listeners](techniques/queues#event-listeners) running in Nest on one (or several) nodes, and other producers, consumers and listeners running on other Node.js platforms on other network nodes.

This chapter covers the `@nestjs/bull` package. We also recommend reading the [Bull documentation](https://github.com/OptimalBits/bull/blob/master/REFERENCE.md) for more background and specific implementation details.

#### Installation[#](/techniques/queues#installation)

To begin using it, we first install the required dependencies.

```bash

$ npm install --save @nestjs/bull bull
$ npm install --save-dev @types/bull
```

Once the installation process is complete, we can import the `BullModule` into the root `AppModule`.

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { BullModule } from '@nestjs/bull';

@Module({
  imports: [
    BullModule.forRoot({
      redis: {
        host: 'localhost',
        port: 6379,
      },
    }),
  ],
})
export class AppModule {}
```

```typescript

BullModule.registerQueue({
  name: 'audio',
});
```

> **Hint** Create multiple queues by passing multiple comma-separated configuration objects to the `registerQueue()` method.

The `registerQueue()` method is used to instantiate and/or register queues. Queues are shared across modules and processes that connect to the same underlying Redis database with the same credentials. Each queue is unique by its name property. A queue name is used as both an injection token (for injecting the queue into controllers/providers), and as an argument to decorators to associate consumer classes and listeners with queues.

You can also override some of the pre-configured options for a specific queue, as follows:

```typescript

BullModule.registerQueue({
  name: 'audio',
  redis: {
    port: 6380,
  },
});
```

Since jobs are persisted in Redis, each time a specific named queue is instantiated (e.g., when an app is started/restarted), it attempts to process any old jobs that may exist from a previous unfinished session.

Each queue can have one or many producers, consumers, and listeners. Consumers retrieve jobs from the queue in a specific order: FIFO (the default), LIFO, or according to priorities. Controlling queue processing order is discussed [here](techniques/queues#consumers).

## Official enterprise support

* **Providing technical guidance
* **Performing in-depth code reviews
* **Mentoring team members
* **Advising best practices

[Explore more](https://enterprise.nestjs.com "Enterprise | NestJS - A progressive Node.js framework")

#### Named configurations[#](/techniques/queues#named-configurations)

If your queues connect to multiple different Redis instances, you can use a technique called **named configurations**. This feature allows you to register several configurations under specified keys, which then you can refer to in the queue options.

For example, assuming that you have an additional Redis instance (apart from the default one) used by a few queues registered in your application, you can register its configuration as follows:

```typescript

BullModule.forRoot('alternative-config', {
  redis: {
    port: 6381,
  },
});
```

In the example above, `'alternative-config'` is just a configuration key (it can be any arbitrary string).

With this in place, you can now point to this configuration in the `registerQueue()` options object:

```typescript

BullModule.registerQueue({
  configKey: 'alternative-queue'
  name: 'video',
});
```

#### Producers[#](/techniques/queues#producers)

Job producers add jobs to queues. Producers are typically application services (Nest [providers](/v8/providers)). To add jobs to a queue, first inject the queue into the service as follows:

```typescript

import { Injectable } from '@nestjs/common';
import { Queue } from 'bull';
import { InjectQueue } from '@nestjs/bull';

@Injectable()
export class AudioService {
  constructor(@InjectQueue('audio') private audioQueue: Queue) {}
}
```

> **Hint** The `@InjectQueue()` decorator identifies the queue by its name, as provided in the `registerQueue()` method call (e.g., `'audio'`).

Now, add a job by calling the queue's `add()` method, passing a user-defined job object. Jobs are represented as serializable JavaScript objects (since that is how they are stored in the Redis database). The shape of the job you pass is arbitrary; use it to represent the semantics of your job object.

```typescript

const job = await this.audioQueue.add({
  foo: 'bar',
});
```

#### Named jobs[#](/techniques/queues#named-jobs)

Jobs may have unique names. This allows you to create specialized [consumers](techniques/queues#consumers) that will only process jobs with a given name.

```typescript

const job = await this.audioQueue.add('transcode', {
  foo: 'bar',
});
```

> **Warning** When using named jobs, you must create processors for each unique name added to a queue, or the queue will complain that you are missing a processor for the given job. See [here](techniques/queues#consumers) for more information on consuming named jobs.

```typescript

const job = await this.audioQueue.add(
  {
    foo: 'bar',
  },
  { delay: 3000 }, // 3 seconds delayed
);
```

To add a job to the right end of the queue (process the job as **LIFO** (Last In First Out)), set the `lifo` property of the configuration object to `true`.

```typescript

const job = await this.audioQueue.add(
  {
    foo: 'bar',
  },
  { lifo: true },
);
```

To prioritize a job, use the `priority` property.

```typescript

const job = await this.audioQueue.add(
  {
    foo: 'bar',
  },
  { priority: 2 },
);
```

#### Consumers[#](/techniques/queues#consumers)

A consumer is a **class** defining methods that either process jobs added into the queue, or listen for events on the queue, or both. Declare a consumer class using the `@Processor()` decorator as follows:

```typescript

import { Processor } from '@nestjs/bull';

@Processor('audio')
export class AudioConsumer {}
```

> **Hint** Consumers must be registered as `providers` so the `@nestjs/bull` package can pick them up.

Where the decorator's string argument (e.g., `'audio'`) is the name of the queue to be associated with the class methods.

Within a consumer class, declare job handlers by decorating handler methods with the `@Process()` decorator.

```typescript

import { Processor, Process } from '@nestjs/bull';
import { Job } from 'bull';

@Processor('audio')
export class AudioConsumer {
  @Process()
  async transcode(job: Job<unknown>) {
    let progress = 0;
    for (i = 0; i < 100; i++) {
      await doSomething(job.data);
      progress += 1;
      await job.progress(progress);
    }
    return {};
  }
}
```

The decorated method (e.g., `transcode()`) is called whenever the worker is idle and there are jobs to process in the queue. This handler method receives the `job` object as its only argument. The value returned by the handler method is stored in the job object and can be accessed later on, for example in a listener for the completed event.

`Job` objects have multiple methods that allow you to interact with their state. For example, the above code uses the `progress()` method to update the job's progress. See [here](https://github.com/OptimalBits/bull/blob/master/REFERENCE.md#job) for the complete `Job` object API reference.

You can designate that a job handler method will handle **only** jobs of a certain type (jobs with a specific `name`) by passing that `name` to the `@Process()` decorator as shown below. You can have multiple `@Process()` handlers in a given consumer class, corresponding to each job type (`name`). When you use named jobs, be sure to have a handler corresponding to each name.

```typescript

@Process('transcode')
async transcode(job: Job<unknown>) { ... }
```

#### Request-scoped consumers[#](/techniques/queues#request-scoped-consumers)

When a consumer is flagged as request-scoped (learn more about the injection scopes [here](/fundamentals/injection-scopes#provider-scope)), a new instance of the class will be created exclusively for each job. The instance will be garbage-collected after the job has completed.

```typescript

@Processor({
  name: 'audio',
  scope: Scope.REQUEST,
})
```

Since request-scoped consumer classes are instantiated dynamically and scoped to a single job, you can inject a `JOB_REF` through the constructor using a standard approach.

```typescript

constructor(@Inject(JOB_REF) jobRef: Job) {
  console.log(jobRef);
}
```

> **Hint** The `JOB_REF` token is imported from the `@nestjs/bull` package.

#### Event listeners[#](/techniques/queues#event-listeners)

Bull generates a set of useful events when queue and/or job state changes occur. Nest provides a set of decorators that allow subscribing to a core set of standard events. These are exported from the `@nestjs/bull` package.

Event listeners must be declared within a [consumer](techniques/queues#consumers) class (i.e., within a class decorated with the `@Processor()` decorator). To listen for an event, use one of the decorators in the table below to declare a handler for the event. For example, to listen to the event emitted when a job enters the active state in the `audio` queue, use the following construct:

```typescript

import { Processor, Process } from '@nestjs/bull';
import { Job } from 'bull';

@Processor('audio')
export class AudioConsumer {

  @OnQueueActive()
  onActive(job: Job) {
    console.log(
      `Processing job ${job.id} of type ${job.name} with data ${job.data}...`,
    );
  }
  ...
```

Since Bull operates in a distributed (multi-node) environment, it defines the concept of event locality. This concept recognizes that events may be triggered either entirely within a single process, or on shared queues from different processes. A **local** event is one that is produced when an action or state change is triggered on a queue in the local process. In other words, when your event producers and consumers are local to a single process, all events happening on queues are local.

When a queue is shared across multiple processes, we encounter the possibility of **global** events. For a listener in one process to receive an event notification triggered by another process, it must register for a global event.

Event handlers are invoked whenever their corresponding event is emitted. The handler is called with the signature shown in the table below, providing access to information relevant to the event. We discuss one key difference between local and global event handler signatures below.

| Local event listeners | Global event listeners      | Handler method signature / When fired                                                                                                                                 |
| --------------------- | --------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `@OnQueueError()`     | `@OnGlobalQueueError()`     | `handler(error: Error)` - An error occurred. `error` contains the triggering error.                                                                                   |
| `@OnQueueWaiting()`   | `@OnGlobalQueueWaiting()`   | `handler(jobId: number \| string)` - A Job is waiting to be processed as soon as a worker is idling. `jobId` contains the id for the job that has entered this state. |
| `@OnQueueActive()`    | `@OnGlobalQueueActive()`    | `handler(job: Job)` - Job `job`has started.                                                                                                                           |
| `@OnQueueStalled()`   | `@OnGlobalQueueStalled()`   | `handler(job: Job)` - Job `job` has been marked as stalled. This is useful for debugging job workers that crash or pause the event loop.                              |
| `@OnQueueProgress()`  | `@OnGlobalQueueProgress()`  | `handler(job: Job, progress: number)` - Job `job`'s progress was updated to value `progress`.                                                                         |
| `@OnQueueCompleted()` | `@OnGlobalQueueCompleted()` | `handler(job: Job, result: any)` Job `job` successfully completed with a result `result`.                                                                             |
| `@OnQueueFailed()`    | `@OnGlobalQueueFailed()`    | `handler(job: Job, err: Error)` Job `job` failed with reason `err`.                                                                                                   |
| `@OnQueuePaused()`    | `@OnGlobalQueuePaused()`    | `handler()` The queue has been paused.                                                                                                                                |
| `@OnQueueResumed()`   | `@OnGlobalQueueResumed()`   | `handler(job: Job)` The queue has been resumed.                                                                                                                       |
| `@OnQueueCleaned()`   | `@OnGlobalQueueCleaned()`   | `handler(jobs: Job[], type: string)` Old jobs have been cleaned from the queue. `jobs` is an array of cleaned jobs, and `type` is the type of jobs cleaned.           |
| `@OnQueueDrained()`   | `@OnGlobalQueueDrained()`   | `handler()` Emitted whenever the queue has processed all the waiting jobs (even if there can be some delayed jobs not yet processed).                                 |
| `@OnQueueRemoved()`   | `@OnGlobalQueueRemoved()`   | `handler(job: Job)` Job `job` was successfully removed.                                                                                                               |

When listening for global events, the method signatures can be slightly different from their local counterpart. Specifically, any method signature that receives `job` objects in the local version, instead receives a `jobId` (`number`) in the global version. To get a reference to the actual `job` object in such a case, use the `Queue#getJob` method. This call should be awaited, and therefore the handler should be declared `async`. For example:

```typescript

@OnGlobalQueueCompleted()
async onGlobalCompleted(jobId: number, result: any) {
  const job = await this.immediateQueue.getJob(jobId);
  console.log('(Global) on completed: job ', job.id, ' -> result: ', result);
}
```

> **Hint** To access the `Queue` object (to make a `getJob()` call), you must of course inject it. Also, the Queue must be registered in the module where you are injecting it.

In addition to the specific event listener decorators, you can also use the generic `@OnQueueEvent()` decorator in combination with either `BullQueueEvents` or `BullQueueGlobalEvents` enums. Read more about events [here](https://github.com/OptimalBits/bull/blob/master/REFERENCE.md#events).

#### Queue management[#](/techniques/queues#queue-management)

Queue's have an API that allows you to perform management functions like pausing and resuming, retrieving the count of jobs in various states, and several more. You can find the full queue API [here](https://github.com/OptimalBits/bull/blob/master/REFERENCE.md#queue). Invoke any of these methods directly on the `Queue` object, as shown below with the pause/resume examples.

Pause a queue with the `pause()` method call. A paused queue will not process new jobs until resumed, but current jobs being processed will continue until they are finalized.

```typescript

await audioQueue.pause();
```

To resume a paused queue, use the `resume()` method, as follows:

```typescript

await audioQueue.resume();
```

```ts

import { Module } from '@nestjs/common';
import { BullModule } from '@nestjs/bull';
import { join } from 'path';

@Module({
  imports: [
    BullModule.registerQueue({
      name: 'audio',
      processors: [join(__dirname, 'processor.js')],
    }),
  ],
})
export class AppModule {}
```

Please note that because your function is being executed in a forked process, Dependency Injection (and IoC container) won't be available. That means that your processor function will need to contain (or create) all instances of external dependencies it needs.

processor.ts

JS TS

```ts

import { Job, DoneCallback } from 'bull';

export default function (job: Job, cb: DoneCallback) {
  console.log(`[${process.pid}] ${JSON.stringify(job.data)}`);
  cb(null, 'It works');
}
```

#### Async configuration[#](/techniques/queues#async-configuration)

You may want to pass `bull` options asynchronously instead of statically. In this case, use the `forRootAsync()` method which provides several ways to deal with async configuration. Likewise, if you want to pass queue options asynchronously, use the `registerQueueAsync()` method.

One approach is to use a factory function:

```typescript

BullModule.forRootAsync({
  useFactory: () => ({
    redis: {
      host: 'localhost',
      port: 6379,
    },
  }),
});
```

Our factory behaves like any other [asynchronous provider](https://docs.nestjs.com/fundamentals/async-providers) (e.g., it can be `async` and it's able to inject dependencies through `inject`).

```typescript

BullModule.forRootAsync({
  imports: [ConfigModule],
  useFactory: async (configService: ConfigService) => ({
    redis: {
      host: configService.get('QUEUE_HOST'),
      port: +configService.get('QUEUE_PORT'),
    },
  }),
  inject: [ConfigService],
});
```

Alternatively, you can use the `useClass` syntax:

```typescript

BullModule.forRootAsync({
  useClass: BullConfigService,
});
```

The construction above will instantiate `BullConfigService` inside `BullModule` and use it to provide an options object by calling `createSharedConfiguration()`. Note that this means that the `BullConfigService` has to implement the `SharedBullConfigurationFactory` interface, as shown below:

```typescript

@Injectable()
class BullConfigService implements SharedBullConfigurationFactory {
  createSharedConfiguration(): BullModuleOptions {
    return {
      redis: {
        host: 'localhost',
        port: 6379,
      },
    };
  }
}
```

In order to prevent the creation of `BullConfigService` inside `BullModule` and use a provider imported from a different module, you can use the `useExisting` syntax.

```typescript

BullModule.forRootAsync({
  imports: [ConfigModule],
  useExisting: ConfigService,
});
```

This construction works the same as `useClass` with one critical difference - `BullModule` will lookup imported modules to reuse an existing `ConfigService` instead of instantiating a new one.

#### Example[#](/techniques/queues#example)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/26-queues).

----
url: https://docs.nestjs.com/v6/fundamentals/module-ref
----

* [Module reference](https://docs.nestjs.com/v6/fundamentals/module-ref#module-reference)
* [Retrieving instances](https://docs.nestjs.com/v6/fundamentals/module-ref#retrieving-instances)
* [Resolving scoped providers](https://docs.nestjs.com/v6/fundamentals/module-ref#resolving-scoped-providers)
* [Getting current sub-tree](https://docs.nestjs.com/v6/fundamentals/module-ref#getting-current-sub-tree)
* [Instantiating classes dynamically](https://docs.nestjs.com/v6/fundamentals/module-ref#instantiating-classes-dynamically)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/fundamentals/module-reference.md "Suggest Edits")

### Module reference

Nest provides the `ModuleRef` class to navigate the internal list of providers and obtain a reference to any provider using its injection token as a lookup key. The `ModuleRef` class also provides a way to dynamically instantiate both static and scoped providers. `ModuleRef` can be injected into a class in the normal way:

cats.service.ts

JS TS

```typescript

@Injectable()
export class CatsService {
  constructor(private readonly moduleRef: ModuleRef) {}
}
```

```typescript

@Injectable()
@Dependencies(ModuleRef)
export class CatsService {
  constructor(moduleRef) {
    this.moduleRef = moduleRef;
  }
}
```

> **Hint** The `ModuleRef` class is imported from the `@nestjs/core` package.

#### Retrieving instances[#](/fundamentals/module-ref#retrieving-instances)

The `ModuleRef` instance (hereafter we'll refer to it as the **module reference**) has a `get()` method. This method retrieve a provider, controller, or injectable (e.g., guard, interceptor, etc.) that exists (has been instantiated) in the **current** module using its injection token/class name.

cats.service.ts

JS TS

```typescript

@Injectable()
export class CatsService implements OnModuleInit {
  private service: Service;
  constructor(private readonly moduleRef: ModuleRef) {}

  onModuleInit() {
    this.service = this.moduleRef.get(Service);
  }
}
```

```typescript

@Injectable()
@Dependencies(ModuleRef)
export class CatsService {
  constructor(moduleRef) {
    this.moduleRef = moduleRef;
  }

  onModuleInit() {
    this.service = this.moduleRef.get(Service);
  }
}
```

> **Warning** You can't retrieve scoped providers (transient or request-scoped) with the `get()` method. Instead, use the technique described [below](https://docs.nestjs.com/fundamentals/module-ref#resolving-scoped-providers). Learn how to control scopes [here](/v6/fundamentals/injection-scopes).

To retrieve a provider from the global context (for example, if the provider has been injected in a different module), pass the `{ strict: false }` option as a second argument to `get()`.

```typescript

this.moduleRef.get(Service, { strict: false });
```

#### Resolving scoped providers[#](/fundamentals/module-ref#resolving-scoped-providers)

To dynamically resolve a scoped provider (transient or request-scoped), use the `resolve()` method, passing the provider's injection token as an argument.

cats.service.ts

JS TS

```typescript

@Injectable()
export class CatsService implements OnModuleInit {
  private transientService: TransientService;
  constructor(private readonly moduleRef: ModuleRef) {}

  async onModuleInit() {
    this.transientService = await this.moduleRef.resolve(TransientService);
  }
}
```

```typescript

@Injectable()
@Dependencies(ModuleRef)
export class CatsService {
  constructor(moduleRef) {
    this.moduleRef = moduleRef;
  }

  async onModuleInit() {
    this.transientService = await this.moduleRef.resolve(TransientService);
  }
}
```

The `resolve()` method returns a unique instance of the provider, from its own **DI container sub-tree**. Each sub-tree has a unique **context identifier**. Thus, if you call this method more than once and compare instance references, you will see that they are not equal.

cats.service.ts

JS TS

```typescript

@Injectable()
export class CatsService implements OnModuleInit {
  constructor(private readonly moduleRef: ModuleRef) {}

  async onModuleInit() {
    const transientServices = await Promise.all([
      this.moduleRef.resolve(TransientService),
      this.moduleRef.resolve(TransientService),
    ]);
    console.log(transientServices[0] === transientServices[1]); // false
  }
}
```

```typescript

@Injectable()
@Dependencies(ModuleRef)
export class CatsService {
  constructor(moduleRef) {
    this.moduleRef = moduleRef;
  }

  async onModuleInit() {
    const transientServices = await Promise.all([
      this.moduleRef.resolve(TransientService),
      this.moduleRef.resolve(TransientService),
    ]);
    console.log(transientServices[0] === transientServices[1]); // false
  }
}
```

To generate a single instance across multiple `resolve()` calls, and ensure they share the same generated DI container sub-tree, you can pass a context identifier to the `resolve()` method. Use the `ContextIdFactory` class to generate a context identifier. This class provides a `create()` method that returns an appropriate unique identifier.

cats.service.ts

JS TS

```typescript

@Injectable()
export class CatsService implements OnModuleInit {
  constructor(private readonly moduleRef: ModuleRef) {}

  async onModuleInit() {
    const contextId = ContextIdFactory.create();
    const transientServices = await Promise.all([
      this.moduleRef.resolve(TransientService, contextId),
      this.moduleRef.resolve(TransientService, contextId),
    ]);
    console.log(transientServices[0] === transientServices[1]); // true
  }
}
```

```typescript

@Injectable()
@Dependencies(ModuleRef)
export class CatsService {
  constructor(moduleRef) {
    this.moduleRef = moduleRef;
  }

  async onModuleInit() {
    const contextId = ContextIdFactory.create();
    const transientServices = await Promise.all([
      this.moduleRef.resolve(TransientService, contextId),
      this.moduleRef.resolve(TransientService, contextId),
    ]);
    console.log(transientServices[0] === transientServices[1]); // true
  }
}
```

> **Hint** The `ContextIdFactory` class is imported from the `@nestjs/core` package.

#### Getting current sub-tree[#](/fundamentals/module-ref#getting-current-sub-tree)

Occasionally, you may want to resolve an instance of a request-scoped provider within a **request context**. Let's say that `CatsService` is request-scoped and you want to resolve the `CatsRepository` instance which is also marked as a request-scoped provider. In order to share the same DI container sub-tree, you must obtain the current context identifier instead of generating a new one (e.g., with the `ContextIdFactory.create()` function, as shown above). To obtain the current context identifier, start by injecting the request object using `@Inject()` decorator.

cats.service.ts

JS TS

```typescript

@Injectable()
export class CatsService {
  constructor(
    @Inject(REQUEST) private readonly request: Record<string, unknown>,
  ) {}
}
```

```typescript

@Injectable()
@Dependencies(REQUEST)
export class CatsService {
  constructor(request) {
    this.request = request;
  }
}
```

> **Hint** Learn more about the request provider [here](https://docs.nestjs.com/fundamentals/injection-scopes#request-provider).

Now, use the `getByRequest()` method of the `ContextIdFactory` class to create a context id based on the request object, and pass this to the `resolve()` call:

```typescript

const contextId = ContextIdFactory.getByRequest(this.request);
const catsRepository = await this.moduleRef.resolve(CatsRepository, contextId);
```

#### Instantiating classes dynamically[#](/fundamentals/module-ref#instantiating-classes-dynamically)

To dynamically instantiate a class that wasn't previously registered as a provider, use the module reference's `create()` method.

cats.service.ts

JS TS

```typescript

@Injectable()
export class CatsService implements OnModuleInit {
  private catsFactory: CatsFactory;
  constructor(private readonly moduleRef: ModuleRef) {}

  async onModuleInit() {
    this.catsFactory = await this.moduleRef.create(CatsFactory);
  }
}
```

```typescript

@Injectable()
@Dependencies(ModuleRef)
export class CatsService {
  constructor(moduleRef) {
    this.moduleRef = moduleRef;
  }

  async onModuleInit() {
    this.catsFactory = await this.moduleRef.create(CatsFactory);
  }
}
```

This technique enables you to conditionally instantiate different classes outside of the framework container.

## Hoodies, T-shirts, and accessories!

Support our future development by shopping in the official store!

[See more](https://nestjs.threadless.com/ "Shop | NestJS - A node.js framework built on top of TypeScript")

----
url: https://docs.nestjs.com/v5/recipes/cqrs
----

### Command query responsibility segregation

The flow of the simplest [CRUD](https://en.wikipedia.org/wiki/Create,_read,_update_and_delete) applications can be described using the following steps:

1. Controllers layer handle **HTTP requests** and delegate tasks to the services.
2. Services layer is the place where the most of the business logic is being done.
3. **Services** uses Repositories / DAOs to change / persist entities.
4. Entities are our models - just containers for the values, with setters and getters.

In most cases, there's no reason to make small and medium-sized applications more complicated. But sometimes it's not enough and when our needs become **more sophisticated** we want to have scalable systems with straightforward data flow.

That's why Nest provides a lightweight [CQRS module](https://github.com/nestjs/cqrs) which components are well-described below.

#### Commands

In order to make the application easier to understand, each change has to be preceded by a **Command**. When any command is dispatched, the application has to react on it. Commands could be dispatched from the services and consumed in corresponding **Command Handlers**.

heroes-game.service.ts

JS TS

TypeScript

```typescript

@Injectable()
export class HeroesGameService {
  constructor(private readonly commandBus: CommandBus) {}

  async killDragon(heroId: string, killDragonDto: KillDragonDto) {
    return await this.commandBus.execute(
      new KillDragonCommand(heroId, killDragonDto.dragonId)
    );
  }
}
```

TypeScript

```typescript

@Injectable()
@Dependencies(CommandBus)
export class HeroesGameService {
  constructor(commandBus) {
    this.commandBus = commandBus;
  }

  async killDragon(heroId, killDragonDto) {
    return await this.commandBus.execute(
      new KillDragonCommand(heroId, killDragonDto.dragonId)
    );
  }
}
```

Here's a sample service that dispatches `KillDragonCommand`. Let's see how the command looks like:

kill-dragon.command.ts

JS TS

TypeScript

```typescript

export class KillDragonCommand implements ICommand {
  constructor(
    public readonly heroId: string,
    public readonly dragonId: string,
  ) {}
}
```

TypeScript

```typescript

export class KillDragonCommand {
  constructor(heroId, dragonId) {
    this.heroId = heroId;
    this.dragonId = dragonId;
  }
}
```

The `CommandBus` is a commands **stream**. It delegates commands to the equivalent handlers. Each Command has to have corresponding **Command Handler**:

kill-dragon.handler.ts

JS TS

TypeScript

```typescript

@CommandHandler(KillDragonCommand)
export class KillDragonHandler implements ICommandHandler<KillDragonCommand> {
  constructor(private readonly repository: HeroRepository) {}

  async execute(command: KillDragonCommand, resolve: (value?) => void) {
    const { heroId, dragonId } = command;
    const hero = this.repository.findOneById(+heroId);

    hero.killEnemy(dragonId);
    await this.repository.persist(hero);
    resolve();
  }
}
```

TypeScript

```typescript

@CommandHandler(KillDragonCommand)
@Dependencies(HeroRepository)
export class KillDragonHandler {
  constructor(repository) {
    this.repository = repository;
  }

  async execute(command, resolve) {
    const { heroId, dragonId } = command;
    const hero = this.repository.findOneById(+heroId);

    hero.killEnemy(dragonId);
    await this.repository.persist(hero);
    resolve();
  }
}
```

Now every application state change is a result of the **Command** occurrence. The logic is encapsulated in handlers. If we want we can simply add logging here or even more, we can persist our commands in the database (e.g. for the diagnostics purposes).

Why do we need `resolve()` function? Sometimes we might want to return a message from handler to the service. Also, we can just call this function at the beginning of the `execute()` method, therefore the application would first turn back into the service and return a response to the client and then **asynchronously** come back here to process the dispatched command.

#### Events

Since we have encapsulated commands in handlers, we prevent interaction between them - the application structure'is still not flexible, not **reactive**. The solution is to use **events**.

hero-killed-dragon.event.ts

JS TS

TypeScript

```typescript

export class HeroKilledDragonEvent implements IEvent {
  constructor(
    public readonly heroId: string,
    public readonly dragonId: string) {}
}
```

TypeScript

```typescript

export class HeroKilledDragonEvent {
  constructor(heroId, dragonId) {
    this.heroId = heroId;
    this.dragonId = dragonId;
  }
}
```

Events are asynchronous. They are dispatched by **models**. Models have to extend the `AggregateRoot` class.

hero.model.ts

JS TS

TypeScript

```typescript

export class Hero extends AggregateRoot {
  constructor(private readonly id: string) {
    super();
  }

  killEnemy(enemyId: string) {
    // logic
    this.apply(new HeroKilledDragonEvent(this.id, enemyId));
  }
}
```

TypeScript

```typescript

export class Hero extends AggregateRoot {
  constructor(id) {
    super();
    this.id = id;
  }

  killEnemy(enemyId) {
    // logic
    this.apply(new HeroKilledDragonEvent(this.id, enemyId));
  }
}
```

The `apply()` method does not dispatch events yet because there's no relationship between model and the `EventPublisher` class. How to tell the model about the publisher? We need to use a publisher `mergeObjectContext()` method inside our command handler.

kill-dragon.handler.ts

JS TS

TypeScript

```typescript

@CommandHandler(KillDragonCommand)
export class KillDragonHandler implements ICommandHandler<KillDragonCommand> {
  constructor(
    private readonly repository: HeroRepository,
    private readonly publisher: EventPublisher,
  ) {}

  async execute(command: KillDragonCommand, resolve: (value?) => void) {
    const { heroId, dragonId } = command;
    const hero = this.publisher.mergeObjectContext(
      await this.repository.findOneById(+heroId),
    );
    hero.killEnemy(dragonId);
    hero.commit();
    resolve();
  }
}
```

TypeScript

```typescript

@CommandHandler(KillDragonCommand)
@Dependencies(HeroRepository, EventPublisher)
export class KillDragonHandler {
  constructor(repository, publisher) {
    this.repository = repository;
    this.publisher = publisher;
  }

  async execute(command, resolve) {
    const { heroId, dragonId } = command;
    const hero = this.publisher.mergeObjectContext(
      await this.repository.findOneById(+heroId),
    );
    hero.killEnemy(dragonId);
    hero.commit();
    resolve();
  }
}
```

Now everything works as expected. Notice that we need to `commit()` events since they're not dispatched immediately. Of course, an object doesn't have to exist already. We can easily merge type context also:

TypeScript

```typescript

const HeroModel = this.publisher.mergeContext(Hero);
new HeroModel('id');
```

That's it. A model has an ability to publish events now. We have to handle them.

Each event can have a lot of **Event Handlers**. They don't have to know about each other.

hero-killed-dragon.handler.ts

JS TS

TypeScript

```typescript

@EventsHandler(HeroKilledDragonEvent)
export class HeroKilledDragonHandler implements IEventHandler<HeroKilledDragonEvent> {
  constructor(private readonly repository: HeroRepository) {}

  handle(event: HeroKilledDragonEvent) {
    // logic
  }
}
```

TypeScript

```typescript

@EventsHandler(HeroKilledDragonEvent)
@Dependencies(HeroRepository)
export class HeroKilledDragonHandler {
  constructor(repository) {
    this.repository = repository;
  }

  handle(event) {
    // logic
  }
}
```

Now we can move the **write logic** into the event handlers.

#### Sagas

This type of **Event-Driven Architecture** improves application **reactiveness and scalability**. Now, when we have events, we can simply react to them in various manners. The **Sagas** are the last building block from the architecture point of view.

The sagas are an incredibly powerful feature. Single saga may listen for 1..\* events. It can combine, merge, filter \[...] events streams. [RxJS](https://github.com/ReactiveX/rxjs) library is the place where the magic comes from. In simple words, each saga has to return an Observable which contains a command. This command is dispatched **asynchronously**.

heroes-game.saga.ts

JS TS

TypeScript

```typescript

@Component()
export class HeroesGameSagas {
  dragonKilled = (events$: EventObservable<any>): Observable<ICommand> => {
    return events$.ofType(HeroKilledDragonEvent)
      .map((event) => new DropAncientItemCommand(event.heroId, fakeItemID));
  }
}
```

TypeScript

```typescript

@Injectable()
export class HeroesGameSagas {
  dragonKilled = (events$) => {
    return events$.ofType(HeroKilledDragonEvent)
      .map((event) => new DropAncientItemCommand(event.heroId, fakeItemID));
  }
}
```

We declared a rule that when any hero kills the dragon - it should obtain the ancient item. Then the `DropAncientItemCommand` will be dispatched and processed by the appropriate handler.

#### Setup

The last thing which we have to take care of is to set up the whole mechanism.

heroes-game.module.ts

JS TS

TypeScript

```typescript

export const CommandHandlers = [KillDragonHandler, DropAncientItemHandler];
export const EventHandlers =  [HeroKilledDragonHandler, HeroFoundItemHandler];

@Module({
  imports: [CQRSModule],
  controllers: [HeroesGameController],
  providers: [
    HeroesGameService,
    HeroesGameSagas,
    ...CommandHandlers,
    ...EventHandlers,
    HeroRepository,
  ]
})
export class HeroesGameModule implements OnModuleInit {
  constructor(
    private readonly moduleRef: ModuleRef,
    private readonly command$: CommandBus,
    private readonly event$: EventBus,
    private readonly heroesGameSagas: HeroesGameSagas,
  ) {}

  onModuleInit() {
    this.command$.setModuleRef(this.moduleRef);
    this.event$.setModuleRef(this.moduleRef);

    this.event$.register(EventHandlers);
    this.command$.register(CommandHandlers);
    this.event$.combineSagas([
      this.heroesGameSagas.dragonKilled,
    ]);
  }
}
```

TypeScript

```typescript

export const CommandHandlers = [KillDragonHandler, DropAncientItemHandler];
export const EventHandlers =  [HeroKilledDragonHandler, HeroFoundItemHandler];

@Module({
  imports: [CQRSModule],
  controllers: [HeroesGameController],
  providers: [
    HeroesGameService,
    HeroesGameSagas,
    ...CommandHandlers,
    ...EventHandlers,
    HeroRepository,
  ]
})
@Dependencies(ModuleRef, CommandBus, EventBus, HeroesGameSagas)
export class HeroesGameModule {
  constructor(moduleRef, command$, event$, heroesGameSagas) {
    this.moduleRef = moduleRef;
    this.command$ = command$;
    this.event$ = event$;
    this.heroesGameSagas = heroesGameSagas;
  }

  onModuleInit() {
    this.command$.setModuleRef(this.moduleRef);
    this.event$.setModuleRef(this.moduleRef);

    this.event$.register(EventHandlers);
    this.command$.register(CommandHandlers);
    this.event$.combineSagas([
        this.heroesGameSagas.dragonKilled,
    ]);
  }
}
```

#### Summary

Both `CommandBus` and `EventBus` are **Observables**. It means that you can easily subscribe to the whole stream and enrich your application with **Event Sourcing**.

A working example is available [here](https://github.com/kamilmysliwiec/nest-cqrs-example).

* Command query responsibility segregation
* Commands
* Events
* Sagas
* Setup
* Summary

----
url: https://docs.nestjs.com/v10/websockets/pipes
----

* [Pipes](https://docs.nestjs.com/v10/websockets/pipes#pipes)
* [Binding pipes](https://docs.nestjs.com/v10/websockets/pipes#binding-pipes)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/websockets/pipes.md "Suggest Edits")

### Pipes

There is no fundamental difference between [regular pipes](/v10/pipes) and web sockets pipes. The only difference is that instead of throwing `HttpException`, you should use `WsException`. In addition, all pipes will be only applied to the `data` parameter (because validating or transforming `client` instance is useless).

> **Hint** The `WsException` class is exposed from `@nestjs/websockets` package.

#### Binding pipes[#](/websockets/pipes#binding-pipes)

The following example uses a manually instantiated method-scoped pipe. Just as with HTTP based applications, you can also use gateway-scoped pipes (i.e., prefix the gateway class with a `@UsePipes()` decorator).

JS TS

```typescript

@UsePipes(new ValidationPipe({ exceptionFactory: (errors) => new WsException(errors) }))
@SubscribeMessage('events')
handleEvent(client: Client, data: unknown): WsResponse<unknown> {
  const event = 'events';
  return { event, data };
}
```

```typescript

@UsePipes(new ValidationPipe({ exceptionFactory: (errors) => new WsException(errors) }))
@SubscribeMessage('events')
handleEvent(client, data) {
  const event = 'events';
  return { event, data };
}
```

----
url: https://docs.nestjs.com/v8/openapi/mapped-types
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Mapped types](https://docs.nestjs.com/v8/openapi/mapped-types#mapped-types)
* [Partial](https://docs.nestjs.com/v8/openapi/mapped-types#partial)
* [Pick](https://docs.nestjs.com/v8/openapi/mapped-types#pick)
* [Omit](https://docs.nestjs.com/v8/openapi/mapped-types#omit)
* [Intersection](https://docs.nestjs.com/v8/openapi/mapped-types#intersection)
* [Composition](https://docs.nestjs.com/v8/openapi/mapped-types#composition)

```typescript

import { ApiProperty } from '@nestjs/swagger';

export class CreateCatDto {
  @ApiProperty()
  name: string;

  @ApiProperty()
  age: number;

  @ApiProperty()
  breed: string;
}
```

By default, all of these fields are required. To create a type with the same fields, but with each one optional, use `PartialType()` passing the class reference (`CreateCatDto`) as an argument:

```typescript

export class UpdateCatDto extends PartialType(CreateCatDto) {}
```

> **Hint** The `PartialType()` function is imported from the `@nestjs/swagger` package.

#### Pick[#](/openapi/mapped-types#pick)

The `PickType()` function constructs a new type (class) by picking a set of properties from an input type. For example, suppose we start with a type like:

```typescript

import { ApiProperty } from '@nestjs/swagger';

export class CreateCatDto {
  @ApiProperty()
  name: string;

  @ApiProperty()
  age: number;

  @ApiProperty()
  breed: string;
}
```

We can pick a set of properties from this class using the `PickType()` utility function:

```typescript

export class UpdateCatAgeDto extends PickType(CreateCatDto, ['age'] as const) {}
```

> **Hint** The `PickType()` function is imported from the `@nestjs/swagger` package.

#### Omit[#](/openapi/mapped-types#omit)

The `OmitType()` function constructs a type by picking all properties from an input type and then removing a particular set of keys. For example, suppose we start with a type like:

```typescript

import { ApiProperty } from '@nestjs/swagger';

export class CreateCatDto {
  @ApiProperty()
  name: string;

  @ApiProperty()
  age: number;

  @ApiProperty()
  breed: string;
}
```

We can generate a derived type that has every property **except**`name` as shown below. In this construct, the second argument to `OmitType` is an array of property names.

```typescript

export class UpdateCatDto extends OmitType(CreateCatDto, ['name'] as const) {}
```

> **Hint** The `OmitType()` function is imported from the `@nestjs/swagger` package.

#### Intersection[#](/openapi/mapped-types#intersection)

The `IntersectionType()` function combines two types into one new type (class). For example, suppose we start with two types like:

```typescript

import { ApiProperty } from '@nestjs/swagger';

export class CreateCatDto {
  @ApiProperty()
  name: string;

  @ApiProperty()
  breed: string;
}

export class AdditionalCatInfo {
  @ApiProperty()
  color: string;
}
```

We can generate a new type that combines all properties in both types.

```typescript

export class UpdateCatDto extends IntersectionType(
  CreateCatDto,
  AdditionalCatInfo,
) {}
```

> **Hint** The `IntersectionType()` function is imported from the `@nestjs/swagger` package.

#### Composition[#](/openapi/mapped-types#composition)

The type mapping utility functions are composable. For example, the following will produce a type (class) that has all of the properties of the `CreateCatDto` type except for `name`, and those properties will be set to optional:

```typescript

export class UpdateCatDto extends PartialType(
  OmitType(CreateCatDto, ['name'] as const),
) {}
```

----
url: https://docs.nestjs.com/v9/techniques/file-upload
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [File upload](https://docs.nestjs.com/v9/techniques/file-upload#file-upload)
* [Basic example](https://docs.nestjs.com/v9/techniques/file-upload#basic-example)
* [File validation](https://docs.nestjs.com/v9/techniques/file-upload#file-validation)
* [Array of files](https://docs.nestjs.com/v9/techniques/file-upload#array-of-files)
* [Multiple files](https://docs.nestjs.com/v9/techniques/file-upload#multiple-files)
* [Any files](https://docs.nestjs.com/v9/techniques/file-upload#any-files)
* [Default options](https://docs.nestjs.com/v9/techniques/file-upload#default-options)
* [Async configuration](https://docs.nestjs.com/v9/techniques/file-upload#async-configuration)
* [Example](https://docs.nestjs.com/v9/techniques/file-upload#example)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/techniques/file-upload.md "Suggest Edits")

### File upload

To handle file uploading, Nest provides a built-in module based on the [multer](https://github.com/expressjs/multer) middleware package for Express. Multer handles data posted in the `multipart/form-data` format, which is primarily used for uploading files via an HTTP `POST` request. This module is fully configurable and you can adjust its behavior to your application requirements.

> **Warning** Multer cannot process data which is not in the supported multipart format (`multipart/form-data`). Also, note that this package is not compatible with the `FastifyAdapter`.

For better type safety, let's install Multer typings package:

```shell

$ npm i -D @types/multer
```

With this package installed, we can now use the `Express.Multer.File` type (you can import this type as follows: `import { Express } from 'express'`).

#### Basic example[#](/techniques/file-upload#basic-example)

To upload a single file, simply tie the `FileInterceptor()` interceptor to the route handler and extract `file` from the `request` using the `@UploadedFile()` decorator.

JS TS

```typescript

@Post('upload')
@UseInterceptors(FileInterceptor('file'))
uploadFile(@UploadedFile() file: Express.Multer.File) {
  console.log(file);
}
```

```typescript

@Post('upload')
@UseInterceptors(FileInterceptor('file'))
@Bind(UploadedFile())
uploadFile(file) {
  console.log(file);
}
```

> **Hint** The `FileInterceptor()` decorator is exported from the `@nestjs/platform-express` package. The `@UploadedFile()` decorator is exported from `@nestjs/common`.

The `FileInterceptor()` decorator takes two arguments:

* `fieldName`: string that supplies the name of the field from the HTML form that holds a file
* `options`: optional object of type `MulterOptions`. This is the same object used by the multer constructor (more details [here](https://github.com/expressjs/multer#multeropts)).

> **Warning**`FileInterceptor()` may not be compatible with third party cloud providers like Google Firebase or others.

#### File validation[#](/techniques/file-upload#file-validation)

Often times it can be useful to validate incoming file metadata, like file size or file mime-type. For this, you can create your own [Pipe](https://docs.nestjs.com/pipes) and bind it to the parameter annotated with the `UploadedFile` decorator. The example below demonstrates how a basic file size validator pipe could be implemented:

```typescript

import { PipeTransform, Injectable, ArgumentMetadata } from '@nestjs/common';

@Injectable()
export class FileSizeValidationPipe implements PipeTransform {
  transform(value: any, metadata: ArgumentMetadata) {
    // "value" is an object containing the file's attributes and metadata
    const oneKb = 1000;
    return value.size < oneKb;
  }
}
```

Nest provides a built-in pipe to handle common use cases and facilitate/standardize the addition of new ones. This pipe is called `ParseFilePipe`, and you can use it as follows:

```typescript

@Post('file')
uploadFileAndPassValidation(
  @Body() body: SampleDto,
  @UploadedFile(
    new ParseFilePipe({
      validators: [
        // ... Set of file validator instances here
      ]
    })
  )
  file: Express.Multer.File,
) {
  return {
    body,
    file: file.buffer.toString(),
  };
}
```

As you can see, it's required to specify an array of file validators that will be executed by the `ParseFilePipe`. We'll discuss the interface of a validator, but it's worth mentioning this pipe also has two additional **optional** options:

|                       |                                                                                                   |
| --------------------- | ------------------------------------------------------------------------------------------------- |
| `errorHttpStatusCode` | The HTTP status code to be thrown in case **any** validator fails. Default is `400` (BAD REQUEST) |
| `exceptionFactory`    | A factory which receives the error message and returns an error.                                  |

Now, back to the `FileValidator` interface. To integrate validators with this pipe, you have to either use built-in implementations or provide your own custom `FileValidator`. See example below:

```typescript

export abstract class FileValidator<TValidationOptions = Record<string, any>> {
  constructor(protected readonly validationOptions: TValidationOptions) {}

  /**
   * Indicates if this file should be considered valid, according to the options passed in the constructor.
   * @param file the file from the request object
   */
  abstract isValid(file?: any): boolean | Promise<boolean>;

  /**
   * Builds an error message in case the validation fails.
   * @param file the file from the request object
   */
  abstract buildErrorMessage(file: any): string;
}
```

> **Hint** The `FileValidator` interfaces supports async validation via its `isValid` function. To leverage type security, you can also type the `file` parameter as `Express.Multer.File` in case you are using express (default) as a driver.

`FileValidator` is a regular class that has access to the file object and validates it according to the options provided by the client. Nest has two built-in `FileValidator` implementations you can use in your project:

* `MaxFileSizeValidator` - Checks if a given file's size is less than the provided value (measured in `bytes`)
* `FileTypeValidator` - Checks if a given file's mime-type matches the given value.

> **Warning** To verify file type, [FileTypeValidator](https://github.com/nestjs/nest/blob/master/packages/common/pipes/file/file-type.validator.ts) class uses the type as detected by multer. By default, multer derives file type from file extension on user's device. However, it does not check actual file contents. As files can be renamed to arbitrary extensions, consider using a custom implementation (like checking the file's [magic number](https://www.ibm.com/support/pages/what-magic-number)) if your app requires a safer solution.

To understand how these can be used in conjunction with the aforementioned `FileParsePipe`, we'll use an altered snippet of the last presented example:

```typescript

@UploadedFile(
  new ParseFilePipe({
    validators: [
      new MaxFileSizeValidator({ maxSize: 1000 }),
      new FileTypeValidator({ fileType: 'image/jpeg' }),
    ],
  }),
)
file: Express.Multer.File,
```

> **Hint** If the number of validators increase largely or their options are cluttering the file, you can define this array in a separate file and import it here as a named constant like `fileValidators`.

Finally, you can use the special `ParseFilePipeBuilder` class that lets you compose & construct your validators. By using it as shown below you can avoid manual instantiation of each validator and just pass their options directly:

```typescript

@UploadedFile(
  new ParseFilePipeBuilder()
    .addFileTypeValidator({
      fileType: 'jpeg',
    })
    .addMaxSizeValidator({
      maxSize: 1000
    })
    .build({
      errorHttpStatusCode: HttpStatus.UNPROCESSABLE_ENTITY
    }),
)
file: Express.Multer.File,
```

```typescript

@Post('upload')
@UseInterceptors(FilesInterceptor('files'))
uploadFile(@UploadedFiles() files: Array<Express.Multer.File>) {
  console.log(files);
}
```

```typescript

@Post('upload')
@UseInterceptors(FilesInterceptor('files'))
@Bind(UploadedFiles())
uploadFile(files) {
  console.log(files);
}
```

> **Hint** The `FilesInterceptor()` decorator is exported from the `@nestjs/platform-express` package. The `@UploadedFiles()` decorator is exported from `@nestjs/common`.

#### Multiple files[#](/techniques/file-upload#multiple-files)

To upload multiple files (all with different field name keys), use the `FileFieldsInterceptor()` decorator. This decorator takes two arguments:

* `uploadedFields`: an array of objects, where each object specifies a required `name` property with a string value specifying a field name, as described above, and an optional `maxCount` property, as described above
* `options`: optional `MulterOptions` object, as described above

When using `FileFieldsInterceptor()`, extract files from the `request` with the `@UploadedFiles()` decorator.

JS TS

```typescript

@Post('upload')
@UseInterceptors(FileFieldsInterceptor([
  { name: 'avatar', maxCount: 1 },
  { name: 'background', maxCount: 1 },
]))
uploadFile(@UploadedFiles() files: { avatar?: Express.Multer.File[], background?: Express.Multer.File[] }) {
  console.log(files);
}
```

```typescript

@Post('upload')
@Bind(UploadedFiles())
@UseInterceptors(FileFieldsInterceptor([
  { name: 'avatar', maxCount: 1 },
  { name: 'background', maxCount: 1 },
]))
uploadFile(files) {
  console.log(files);
}
```

#### Any files[#](/techniques/file-upload#any-files)

To upload all fields with arbitrary field name keys, use the `AnyFilesInterceptor()` decorator. This decorator can accept an optional `options` object as described above.

When using `AnyFilesInterceptor()`, extract files from the `request` with the `@UploadedFiles()` decorator.

JS TS

```typescript

@Post('upload')
@UseInterceptors(AnyFilesInterceptor())
uploadFile(@UploadedFiles() files: Array<Express.Multer.File>) {
  console.log(files);
}
```

```typescript

@Post('upload')
@Bind(UploadedFiles())
@UseInterceptors(AnyFilesInterceptor())
uploadFile(files) {
  console.log(files);
}
```

#### Default options[#](/techniques/file-upload#default-options)

You can specify multer options in the file interceptors as described above. To set default options, you can call the static `register()` method when you import the `MulterModule`, passing in supported options. You can use all options listed [here](https://github.com/expressjs/multer#multeropts).

```typescript

MulterModule.register({
  dest: './upload',
});
```

> **Hint** The `MulterModule` class is exported from the `@nestjs/platform-express` package.

#### Async configuration[#](/techniques/file-upload#async-configuration)

When you need to set `MulterModule` options asynchronously instead of statically, use the `registerAsync()` method. As with most dynamic modules, Nest provides several techniques to deal with async configuration.

One technique is to use a factory function:

```typescript

MulterModule.registerAsync({
  useFactory: () => ({
    dest: './upload',
  }),
});
```

Like other [factory providers](https://docs.nestjs.com/fundamentals/custom-providers#factory-providers-usefactory), our factory function can be `async` and can inject dependencies through `inject`.

```typescript

MulterModule.registerAsync({
  imports: [ConfigModule],
  useFactory: async (configService: ConfigService) => ({
    dest: configService.get<string>('MULTER_DEST'),
  }),
  inject: [ConfigService],
});
```

Alternatively, you can configure the `MulterModule` using a class instead of a factory, as shown below:

```typescript

MulterModule.registerAsync({
  useClass: MulterConfigService,
});
```

The construction above instantiates `MulterConfigService` inside `MulterModule`, using it to create the required options object. Note that in this example, the `MulterConfigService` has to implement the `MulterOptionsFactory` interface, as shown below. The `MulterModule` will call the `createMulterOptions()` method on the instantiated object of the supplied class.

```typescript

@Injectable()
class MulterConfigService implements MulterOptionsFactory {
  createMulterOptions(): MulterModuleOptions {
    return {
      dest: './upload',
    };
  }
}
```

If you want to reuse an existing options provider instead of creating a private copy inside the `MulterModule`, use the `useExisting` syntax.

```typescript

MulterModule.registerAsync({
  imports: [ConfigModule],
  useExisting: ConfigService,
});
```

#### Example[#](/techniques/file-upload#example)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/29-file-upload).

----
url: https://docs.nestjs.com/v9/graphql/field-middleware
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Field middleware](https://docs.nestjs.com/v9/graphql/field-middleware#field-middleware)
* [Getting started](https://docs.nestjs.com/v9/graphql/field-middleware#getting-started)
* [Global field middleware](https://docs.nestjs.com/v9/graphql/field-middleware#global-field-middleware)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/field-middleware.md "Suggest Edits")

### Field middleware

> **Warning** This chapter applies only to the code first approach.

Field Middleware lets you run arbitrary code **before or after** a field is resolved. A field middleware can be used to convert the result of a field, validate the arguments of a field, or even check field-level roles (for example, required to access a target field for which a middleware function is executed).

You can connect multiple middleware functions to a field. In this case, they will be called sequentially along the chain where the previous middleware decides to call the next one. The order of the middleware functions in the `middleware` array is important. The first resolver is the "most-outer" layer, so it gets executed first and last (similarly to the `graphql-middleware` package). The second resolver is the "second-outer" layer, so it gets executed second and second to last.

#### Getting started[#](/graphql/field-middleware#getting-started)

Let's start off by creating a simple middleware that will log a field value before it's sent back to the client:

```typescript

import { FieldMiddleware, MiddlewareContext, NextFn } from '@nestjs/graphql';

const loggerMiddleware: FieldMiddleware = async (
  ctx: MiddlewareContext,
  next: NextFn,
) => {
  const value = await next();
  console.log(value);
  return value;
};
```

> **Hint** The `MiddlewareContext` is an object that consist of the same arguments that are normally received by the GraphQL resolver function (`{ source, args, context, info }`), while `NextFn` is a function that let you execute the next middleware in the stack (bound to this field) or the actual field resolver.

> **Warning** Field middleware functions cannot inject dependencies nor access Nest's DI container as they are designed to be very lightweight and shouldn't perform any potentially time-consuming operations (like retrieving data from the database). If you need to call external services/query data from the data source, you should do it in a guard/interceptor bounded to a root query/mutation handler and assign it to `context` object which you can access from within the field middleware (specifically, from the `MiddlewareContext` object).

Note that field middleware must match the `FieldMiddleware` interface. In the example above, we first run the `next()` function (which executes the actual field resolver and returns a field value) and then, we log this value to our terminal. Also, the value returned from the middleware function completely overrides the previous value and since we don't want to perform any changes, we simply return the original value.

With this in place, we can register our middleware directly in the `@Field()` decorator, as follows:

```typescript

@ObjectType()
export class Recipe {
  @Field({ middleware: [loggerMiddleware] })
  title: string;
}
```

Now whenever we request the `title` field of `Recipe` object type, the original field's value will be logged to the console.

> **Hint** To learn how you can implement a field-level permissions system with the use of [extensions](/v9/graphql/extensions) feature, check out this [section](/graphql/extensions#using-custom-metadata).

Also, as mentioned above, we can control the field's value from within the middleware function. For demonstration purposes, let's capitalise a recipe's title (if present):

```typescript

const value = await next();
return value?.toUpperCase();
```

In this case, every title will be automatically uppercased, when requested.

Likewise, you can bind a field middleware to a custom field resolver (a method annotated with the `@ResolveField()` decorator), as follows:

```typescript

@ResolveField(() => String, { middleware: [loggerMiddleware] })
title() {
  return 'Placeholder';
}
```

> **Warning** In case enhancers are enabled at the field resolver level ([read more](/graphql/other-features#execute-enhancers-at-the-field-resolver-level)), field middleware functions will run before any interceptors, guards, etc., **bounded to the method** (but after the root-level enhancers registered for query or mutation handlers).

#### Global field middleware[#](/graphql/field-middleware#global-field-middleware)

In addition to binding a middleware directly to a specific field, you can also register one or multiple middleware functions globally. In this case, they will be automatically connected to all fields of your object types.

```typescript

GraphQLModule.forRoot({
  autoSchemaFile: 'schema.gql',
  buildSchemaOptions: {
    fieldMiddleware: [loggerMiddleware],
  },
}),
```

> **Hint** Globally registered field middleware functions will be executed **before** locally registered ones (those bound directly to specific fields).

----
url: https://docs.nestjs.com/v9/recipes/sql-sequelize
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [SQL (Sequelize)](https://docs.nestjs.com/v9/recipes/sql-sequelize#sql-sequelize)
* [Getting started](https://docs.nestjs.com/v9/recipes/sql-sequelize#getting-started)
* [Model injection](https://docs.nestjs.com/v9/recipes/sql-sequelize#model-injection)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/recipes/sql-sequelize.md "Suggest Edits")

### SQL (Sequelize)

##### This chapter applies only to TypeScript

> **Warning** In this article, you'll learn how to create a `DatabaseModule` based on the **Sequelize** package from scratch using custom components. As a consequence, this technique contains a lot of overhead that you can avoid by using the dedicated, out-of-the-box `@nestjs/sequelize` package. To learn more, see [here](/techniques/database#sequelize-integration).

[Sequelize](https://github.com/sequelize/sequelize) is a popular Object Relational Mapper (ORM) written in a vanilla JavaScript, but there is a [sequelize-typescript](https://github.com/RobinBuschmann/sequelize-typescript) TypeScript wrapper which provides a set of decorators and other extras for the base sequelize.

#### Getting started[#](/recipes/sql-sequelize#getting-started)

To start the adventure with this library we have to install the following dependencies:

```bash

$ npm install --save sequelize sequelize-typescript mysql2
$ npm install --save-dev @types/sequelize
```

The first step we need to do is create a **Sequelize** instance with an options object passed into the constructor. Also, we need to add all models (the alternative is to use `modelPaths` property) and `sync()` our database tables.

database.providers.ts

JS TS

```typescript

import { Sequelize } from 'sequelize-typescript';
import { Cat } from '../cats/cat.entity';

export const databaseProviders = [
  {
    provide: 'SEQUELIZE',
    useFactory: async () => {
      const sequelize = new Sequelize({
        dialect: 'mysql',
        host: 'localhost',
        port: 3306,
        username: 'root',
        password: 'password',
        database: 'nest',
      });
      sequelize.addModels([Cat]);
      await sequelize.sync();
      return sequelize;
    },
  },
];
```

> **Hint** Following best practices, we declared the custom provider in the separated file which has a `*.providers.ts` suffix.

Then, we need to export these providers to make them **accessible** for the rest part of the application.

```typescript

import { Module } from '@nestjs/common';
import { databaseProviders } from './database.providers';

@Module({
  providers: [...databaseProviders],
  exports: [...databaseProviders],
})
export class DatabaseModule {}
```

Now we can inject the `Sequelize` object using `@Inject()` decorator. Each class that would depend on the `Sequelize` async provider will wait until a `Promise` is resolved.

#### Model injection[#](/recipes/sql-sequelize#model-injection)

In [Sequelize](https://github.com/sequelize/sequelize) the **Model** defines a table in the database. Instances of this class represent a database row. Firstly, we need at least one entity:

cat.entity.ts

JS TS

```typescript

import { Table, Column, Model } from 'sequelize-typescript';

@Table
export class Cat extends Model {
  @Column
  name: string;

  @Column
  age: number;

  @Column
  breed: string;
}
```

The `Cat` entity belongs to the `cats` directory. This directory represents the `CatsModule`. Now it's time to create a **Repository** provider:

cats.providers.ts

JS TS

```typescript

import { Cat } from './cat.entity';

export const catsProviders = [
  {
    provide: 'CATS_REPOSITORY',
    useValue: Cat,
  },
];
```

> **Warning** In the real-world applications you should avoid **magic strings**. Both `CATS_REPOSITORY` and `SEQUELIZE` should be kept in the separated `constants.ts` file.

In Sequelize, we use static methods to manipulate the data, and thus we created an **alias** here.

Now we can inject the `CATS_REPOSITORY` to the `CatsService` using the `@Inject()` decorator:

cats.service.ts

JS TS

```typescript

import { Injectable, Inject } from '@nestjs/common';
import { CreateCatDto } from './dto/create-cat.dto';
import { Cat } from './cat.entity';

@Injectable()
export class CatsService {
  constructor(
    @Inject('CATS_REPOSITORY')
    private catsRepository: typeof Cat
  ) {}

  async findAll(): Promise<Cat[]> {
    return this.catsRepository.findAll<Cat>();
  }
}
```

The database connection is **asynchronous**, but Nest makes this process completely invisible for the end-user. The `CATS_REPOSITORY` provider is waiting for the db connection, and the `CatsService` is delayed until repository is ready to use. The entire application can start when each class is instantiated.

Here is a final `CatsModule`:

cats.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';
import { catsProviders } from './cats.providers';
import { DatabaseModule } from '../database/database.module';

@Module({
  imports: [DatabaseModule],
  controllers: [CatsController],
  providers: [
    CatsService,
    ...catsProviders,
  ],
})
export class CatsModule {}
```

> **Hint** Do not forget to import the `CatsModule` into the root `AppModule`.

----
url: https://docs.nestjs.com/v7/graphql/quick-start
----

* [Installation](https://docs.nestjs.com/v7/graphql/quick-start#installation)
* [Overview](https://docs.nestjs.com/v7/graphql/quick-start#overview)
* [Getting started with GraphQL & TypeScript](https://docs.nestjs.com/v7/graphql/quick-start#getting-started-with-graphql--typescript)
* [GraphQL playground](https://docs.nestjs.com/v7/graphql/quick-start#graphql-playground)
* [Multiple endpoints](https://docs.nestjs.com/v7/graphql/quick-start#multiple-endpoints)
* [Code first](https://docs.nestjs.com/v7/graphql/quick-start#code-first)
* [Example](https://docs.nestjs.com/v7/graphql/quick-start#example)
* [Schema first](https://docs.nestjs.com/v7/graphql/quick-start#schema-first)
* [Example](https://docs.nestjs.com/v7/graphql/quick-start#example-1)
* [Accessing generated schema](https://docs.nestjs.com/v7/graphql/quick-start#accessing-generated-schema)
* [Async configuration](https://docs.nestjs.com/v7/graphql/quick-start#async-configuration)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/quick-start.md "Suggest Edits")

## Harnessing the power of TypeScript & GraphQL

[GraphQL](https://graphql.org/) is a powerful query language for APIs and a runtime for fulfilling those queries with your existing data. It's an elegant approach that solves many problems typically found with REST APIs. For background, we suggest reading this [comparison](https://dev-blog.apollodata.com/graphql-vs-rest-5d425123e34b) between GraphQL and REST. GraphQL combined with [TypeScript](https://www.typescriptlang.org/) helps you develop better type safety with your GraphQL queries, giving you end-to-end typing.

In this chapter, we assume a basic understanding of GraphQL, and focus on how to work with the built-in `@nestjs/graphql` module. The `GraphQLModule` is a wrapper around the [Apollo](https://www.apollographql.com/) server. We use this proven GraphQL package to provide a way to use GraphQL with Nest.

#### Installation[#](/graphql/quick-start#installation)

Start by installing the required packages:

```bash

$ npm i @nestjs/graphql graphql-tools graphql apollo-server-express
```

> **Hint** If using Fastify, instead of installing `apollo-server-express`, you should install `apollo-server-fastify`.

#### Overview[#](/graphql/quick-start#overview)

Nest offers two ways of building GraphQL applications, the **code first** and the **schema first** methods. You should choose the one that works best for you. Most of the chapters in this GraphQL section are divided into two main parts: one you should follow if you adopt **code first**, and the other to be used if you adopt **schema first**.

In the **code first** approach, you use decorators and TypeScript classes to generate the corresponding GraphQL schema. This approach is useful if you prefer to work exclusively with TypeScript and avoid context switching between language syntaxes.

In the **schema first** approach, the source of truth is GraphQL SDL (Schema Definition Language) files. SDL is a language-agnostic way to share schema files between different platforms. Nest automatically generates your TypeScript definitions (using either classes or interfaces) based on the GraphQL schemas to reduce the need to write redundant boilerplate code.

#### Getting started with GraphQL & TypeScript[#](/graphql/quick-start#getting-started-with-graphql--typescript)

Once the packages are installed, we can import the `GraphQLModule` and configure it with the `forRoot()` static method.

JS TS

```typescript

import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';

@Module({
  imports: [
    GraphQLModule.forRoot({}),
  ],
})
export class AppModule {}
```

The `forRoot()` method takes an options object as an argument. These options are passed through to the underlying Apollo instance (read more about available settings [here](https://www.apollographql.com/docs/apollo-server/v2/api/apollo-server.html#constructor-options-lt-ApolloServer-gt)). For example, if you want to disable the `playground` and turn off `debug` mode, pass the following options:

JS TS

```typescript

import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';

@Module({
  imports: [
    GraphQLModule.forRoot({
      debug: false,
      playground: false,
    }),
  ],
})
export class AppModule {}
```

#### GraphQL playground[#](/graphql/quick-start#graphql-playground)

The playground is a graphical, interactive, in-browser GraphQL IDE, available by default on the same URL as the GraphQL server itself. To access the playground, you need a basic GraphQL server configured and running. To see it now, you can install and build the [working example here](https://github.com/nestjs/nest/tree/master/sample/23-graphql-code-first). Alternatively, if you're following along with these code samples, once you've complete the steps in the [Resolvers chapter](/v7/graphql/resolvers-map), you can access the playground.

With that in place, and with your application running in the background, you can then open your web browser and navigate to `http://localhost:3000/graphql` (host and port may vary depending on your configuration). You will then see the GraphQL playground, as shown below.

#### Multiple endpoints[#](/graphql/quick-start#multiple-endpoints)

Another useful feature of the `@nestjs/graphql` module is the ability to serve multiple endpoints at once. This lets you decide which modules should be included in which endpoint. By default, `GraphQL` searches for resolvers throughout the whole app. To limit this scan to only a subset of modules, use the `include` property.

```typescript

GraphQLModule.forRoot({
  include: [CatsModule],
}),
```

#### Code first[#](/graphql/quick-start#code-first)

In the **code first** approach, you use decorators and TypeScript classes to generate the corresponding GraphQL schema.

To use the code first approach, start by adding the `autoSchemaFile` property to the options object:

```typescript

GraphQLModule.forRoot({
  autoSchemaFile: join(process.cwd(), 'src/schema.gql'),
}),
```

The `autoSchemaFile` property value is the path where your automatically generated schema will be created. Alternatively, the schema can be generated on-the-fly in memory. To enable this, set the `autoSchemaFile` property to `true`:

```typescript

GraphQLModule.forRoot({
  autoSchemaFile: true,
}),
```

By default, the types in the generated schema will be in the order they are defined in the included modules. To sort the schema lexicographically, set the `sortSchema` property to `true`:

```typescript

GraphQLModule.forRoot({
  autoSchemaFile: join(process.cwd(), 'src/schema.gql'),
  sortSchema: true,
}),
```

#### Example[#](/graphql/quick-start#example)

A fully working code first sample is available [here](https://github.com/nestjs/nest/tree/master/sample/23-graphql-code-first).

#### Schema first[#](/graphql/quick-start#schema-first)

To use the schema first approach, start by adding a `typePaths` property to the options object. The `typePaths` property indicates where the `GraphQLModule` should look for GraphQL SDL schema definition files you'll be writing. These files will be combined in memory; this allows you to split your schemas into several files and locate them near their resolvers.

```typescript

GraphQLModule.forRoot({
  typePaths: ['./**/*.graphql'],
}),
```

You will typically also need to have TypeScript definitions (classes and interfaces) that correspond to the GraphQL SDL types. Creating the corresponding TypeScript definitions by hand is redundant and tedious. It leaves us without a single source of truth -- each change made within SDL forces us to adjust TypeScript definitions as well. To address this, the `@nestjs/graphql` package can **automatically generate** TypeScript definitions from the abstract syntax tree ([AST](https://en.wikipedia.org/wiki/Abstract_syntax_tree)). To enable this feature, add the `definitions` options property when configuring the `GraphQLModule`.

```typescript

GraphQLModule.forRoot({
  typePaths: ['./**/*.graphql'],
  definitions: {
    path: join(process.cwd(), 'src/graphql.ts'),
  },
}),
```

The path property of the `definitions` object indicates where to save generated TypeScript output. By default, all generated TypeScript types are created as interfaces. To generate classes instead, specify the `outputAs` property with a value of `'class'`.

```typescript

GraphQLModule.forRoot({
  typePaths: ['./**/*.graphql'],
  definitions: {
    path: join(process.cwd(), 'src/graphql.ts'),
    outputAs: 'class',
  },
}),
```

The above approach dynamically generates TypeScript definitions each time the application starts. Alternatively, it may be preferable to build a simple script to generate these on demand. For example, assume we create the following script as `generate-typings.ts`:

```typescript

import { GraphQLDefinitionsFactory } from '@nestjs/graphql';
import { join } from 'path';

const definitionsFactory = new GraphQLDefinitionsFactory();
definitionsFactory.generate({
  typePaths: ['./src/**/*.graphql'],
  path: join(process.cwd(), 'src/graphql.ts'),
  outputAs: 'class',
});
```

Now you can run this script on demand:

```bash

$ ts-node generate-typings
```

> **Hint** You can compile the script beforehand (e.g., with `tsc`) and use `node` to execute it.

To enable watch mode for the script (to automatically generate typings whenever any `.graphql` file changes), pass the `watch` option to the `generate()` method.

```typescript

definitionsFactory.generate({
  typePaths: ['./src/**/*.graphql'],
  path: join(process.cwd(), 'src/graphql.ts'),
  outputAs: 'class',
  watch: true,
});
```

To automatically generate the additional `__typename` field for every object type, enable the `emitTypenameField` option.

```typescript

definitionsFactory.generate({
  // ...,
  emitTypenameField: true,
});
```

To generate resolvers (queries, mutations, subscriptions) as plain fields without arguments, enable the `skipResolverArgs` option.

```typescript

definitionsFactory.generate({
  // ...,
  skipResolverArgs: true,
});
```

#### Example[#](/graphql/quick-start#example-1)

A fully working schema first sample is available [here](https://github.com/nestjs/nest/tree/master/sample/12-graphql-schema-first).

#### Accessing generated schema[#](/graphql/quick-start#accessing-generated-schema)

In some circumstances (for example end-to-end tests), you may want to get a reference to the generated schema object. In end-to-end tests, you can then run queries using the `graphql` object without using any HTTP listeners.

You can access the generated schema (in either the code first or schema first approach), using the `GraphQLSchemaHost` class:

```typescript

const { schema } = app.get(GraphQLSchemaHost);
```

> **Hint** You must call the `GraphQLSchemaHost#schema` getter after the application has been initialized (after the `onModuleInit` hook has been triggered by either the `app.listen()` or `app.init()` method).

#### Async configuration[#](/graphql/quick-start#async-configuration)

When you need to pass module options asynchronously instead of statically, use the `forRootAsync()` method. As with most dynamic modules, Nest provides several techniques to deal with async configuration.

One technique is to use a factory function:

```typescript

GraphQLModule.forRootAsync({
  useFactory: () => ({
    typePaths: ['./**/*.graphql'],
  }),
}),
```

Like other factory providers, our factory function can be [async](https://docs.nestjs.com/fundamentals/custom-providers#factory-providers-usefactory) and can inject dependencies through `inject`.

```typescript

GraphQLModule.forRootAsync({
  imports: [ConfigModule],
  useFactory: async (configService: ConfigService) => ({
    typePaths: configService.getString('GRAPHQL_TYPE_PATHS'),
  }),
  inject: [ConfigService],
}),
```

Alternatively, you can configure the `GraphQLModule` using a class instead of a factory, as shown below:

```typescript

GraphQLModule.forRootAsync({
  useClass: GqlConfigService,
}),
```

The construction above instantiates `GqlConfigService` inside `GraphQLModule`, using it to create options object. Note that in this example, the `GqlConfigService` has to implement the `GqlOptionsFactory` interface, as shown below. The `GraphQLModule` will call the `createGqlOptions()` method on the instantiated object of the supplied class.

```typescript

@Injectable()
class GqlConfigService implements GqlOptionsFactory {
  createGqlOptions(): GqlModuleOptions {
    return {
      typePaths: ['./**/*.graphql'],
    };
  }
}
```

If you want to reuse an existing options provider instead of creating a private copy inside the `GraphQLModule`, use the `useExisting` syntax.

```typescript

GraphQLModule.forRootAsync({
  imports: [ConfigModule],
  useExisting: ConfigService,
}),
```

----
url: https://docs.nestjs.com/v5/websockets/exception-filters
----

### Exception filters

The only difference between [HTTP exception filter](/v5/exception-filters) layer and corresponding web sockets layer is that instead of throwing `HttpException`, you should rather use `WsException`.

TypeScript

```typescript

throw new WsException('Invalid credentials.');
```

> **Hint** The `WsException` class is imported from the `@nestjs/websockets` package.

Nest will handle thrown exception and as a result, emits the `exception` message with the following structure:

TypeScript

```typescript

{
  status: 'error',
  message: 'Invalid credentials.'
}
```

#### Filters

The **custom filters** feature is supported as well and works equivalently. Here is an example that makes use of a manually instantiated **method-scoped** filter (class-scoped works either):

TypeScript

```typescript

@UseFilters(new WsExceptionFilter())
@SubscribeMessage('events')
onEvent(client, data: any): WsResponse<any> {
  const event = 'events';
  return { event, data };
}
```

#### Inheritance

Typically, you'll create fully customized exception filters crafted to fulfill your application requirements. There might be use-cases though when you would like to reuse an already implemented, **core exception filter**, and override the behavior based on certain factors.

In order to delegate exception processing to the base filter, you need to extend `BaseWsExceptionFilter` and call inherited `catch()` method. Besides, `HttpServer` reference has to be injected and passed to the `super()` call.

JS TS

TypeScript

```typescript

import { Catch, ArgumentsHost } from '@nestjs/common';
import { BaseWsExceptionFilter } from '@nestjs/websockets';

@Catch()
export class AllExceptionsFilter extends BaseWsExceptionFilter {
  catch(exception: any, host: ArgumentsHost) {
    super.catch(exception, host);
  }
}
```

TypeScript

```typescript

import { Catch } from '@nestjs/common';
import { BaseWsExceptionFilter } from '@nestjs/websockets';

@Catch()
export class AllExceptionsFilter extends BaseWsExceptionFilter {
  catch(exception, host) {
    super.catch(exception, host);
  }
}
```

----
url: https://docs.nestjs.com/v9/techniques/serialization
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Serialization](https://docs.nestjs.com/v9/techniques/serialization#serialization)
* [Overview](https://docs.nestjs.com/v9/techniques/serialization#overview)
* [Exclude properties](https://docs.nestjs.com/v9/techniques/serialization#exclude-properties)
* [Expose properties](https://docs.nestjs.com/v9/techniques/serialization#expose-properties)
* [Transform](https://docs.nestjs.com/v9/techniques/serialization#transform)
* [Pass options](https://docs.nestjs.com/v9/techniques/serialization#pass-options)
* [Example](https://docs.nestjs.com/v9/techniques/serialization#example)
* [WebSockets and Microservices](https://docs.nestjs.com/v9/techniques/serialization#websockets-and-microservices)
* [Learn more](https://docs.nestjs.com/v9/techniques/serialization#learn-more)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/techniques/serialization.md "Suggest Edits")

### Serialization

Serialization is a process that happens before objects are returned in a network response. This is an appropriate place to provide rules for transforming and sanitizing the data to be returned to the client. For example, sensitive data like passwords should always be excluded from the response. Or, certain properties might require additional transformation, such as sending only a subset of properties of an entity. Performing these transformations manually can be tedious and error prone, and can leave you uncertain that all cases have been covered.

#### Overview[#](/techniques/serialization#overview)

Nest provides a built-in capability to help ensure that these operations can be performed in a straightforward way. The `ClassSerializerInterceptor` interceptor uses the powerful [class-transformer](https://github.com/typestack/class-transformer) package to provide a declarative and extensible way of transforming objects. The basic operation it performs is to take the value returned by a method handler and apply the `instanceToPlain()` function from [class-transformer](https://github.com/typestack/class-transformer). In doing so, it can apply rules expressed by `class-transformer` decorators on an entity/DTO class, as described below.

> **Hint** The serialization does not apply to [StreamableFile](https://docs.nestjs.com/techniques/streaming-files#streamable-file-class) responses.

#### Exclude properties[#](/techniques/serialization#exclude-properties)

Let's assume that we want to automatically exclude a `password` property from a user entity. We annotate the entity as follows:

```typescript

import { Exclude } from 'class-transformer';

export class UserEntity {
  id: number;
  firstName: string;
  lastName: string;

  @Exclude()
  password: string;

  constructor(partial: Partial<UserEntity>) {
    Object.assign(this, partial);
  }
}
```

Now consider a controller with a method handler that returns an instance of this class.

```typescript

@UseInterceptors(ClassSerializerInterceptor)
@Get()
findOne(): UserEntity {
  return new UserEntity({
    id: 1,
    firstName: 'Kamil',
    lastName: 'Mysliwiec',
    password: 'password',
  });
}
```

> **Warning** Note that we must return an instance of the class. If you return a plain JavaScript object, for example, `{ user: new UserEntity() }`, the object won't be properly serialized.

> **Hint** The `ClassSerializerInterceptor` is imported from `@nestjs/common`.

When this endpoint is requested, the client receives the following response:

```json

{
  "id": 1,
  "firstName": "Kamil",
  "lastName": "Mysliwiec"
}
```

Note that the interceptor can be applied application-wide (as covered [here](https://docs.nestjs.com/interceptors#binding-interceptors)). The combination of the interceptor and the entity class declaration ensures that **any** method that returns a `UserEntity` will be sure to remove the `password` property. This gives you a measure of centralized enforcement of this business rule.

#### Expose properties[#](/techniques/serialization#expose-properties)

You can use the `@Expose()` decorator to provide alias names for properties, or to execute a function to calculate a property value (analogous to **getter** functions), as shown below.

```typescript

@Expose()
get fullName(): string {
  return `${this.firstName} ${this.lastName}`;
}
```

#### Transform[#](/techniques/serialization#transform)

You can perform additional data transformation using the `@Transform()` decorator. For example, the following construct returns the name property of the `RoleEntity` instead of returning the whole object.

```typescript

@Transform(({ value }) => value.name)
role: RoleEntity;
```

#### Pass options[#](/techniques/serialization#pass-options)

You may want to modify the default behavior of the transformation functions. To override default settings, pass them in an `options` object with the `@SerializeOptions()` decorator.

```typescript

@SerializeOptions({
  excludePrefixes: ['_'],
})
@Get()
findOne(): UserEntity {
  return new UserEntity();
}
```

> **Hint** The `@SerializeOptions()` decorator is imported from `@nestjs/common`.

Options passed via `@SerializeOptions()` are passed as the second argument of the underlying `instanceToPlain()` function. In this example, we are automatically excluding all properties that begin with the `_` prefix.

#### Example[#](/techniques/serialization#example)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/21-serializer).

#### WebSockets and Microservices[#](/techniques/serialization#websockets-and-microservices)

While this chapter shows examples using HTTP style applications (e.g., Express or Fastify), the `ClassSerializerInterceptor` works the same for WebSockets and Microservices, regardless of the transport method that is used.

#### Learn more[#](/techniques/serialization#learn-more)

Read more about available decorators and options as provided by the `class-transformer` package [here](https://github.com/typestack/class-transformer).

----
url: https://docs.nestjs.com/v9/techniques/server-sent-events
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Server-Sent Events](https://docs.nestjs.com/v9/techniques/server-sent-events#server-sent-events)
* [Usage](https://docs.nestjs.com/v9/techniques/server-sent-events#usage)
* [Example](https://docs.nestjs.com/v9/techniques/server-sent-events#example)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/techniques/server-sent-events.md "Suggest Edits")

### Server-Sent Events

Server-Sent Events (SSE) is a server push technology enabling a client to receive automatic updates from a server via HTTP connection. Each notification is sent as a block of text terminated by a pair of newlines (learn more [here](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events)).

#### Usage[#](/techniques/server-sent-events#usage)

To enable Server-Sent events on a route (route registered within a **controller class**), annotate the method handler with the `@Sse()` decorator.

```typescript

@Sse('sse')
sse(): Observable<MessageEvent> {
  return interval(1000).pipe(map((_) => ({ data: { hello: 'world' } })));
}
```

> **Hint** The `@Sse()` decorator and `MessageEvent` interface are imported from the `@nestjs/common`, while `Observable`, `interval`, and `map` are imported from the `rxjs` package.

> **Warning** Server-Sent Events routes must return an `Observable` stream.

In the example above, we defined a route named `sse` that will allow us to propagate real-time updates. These events can be listened to using the [EventSource API](https://developer.mozilla.org/en-US/docs/Web/API/EventSource).

The `sse` method returns an `Observable` that emits multiple `MessageEvent` (in this example, it emits a new `MessageEvent` every second). The `MessageEvent` object should respect the following interface to match the specification:

```typescript

export interface MessageEvent {
  data: string | object;
  id?: string;
  type?: string;
  retry?: number;
}
```

With this in place, we can now create an instance of the `EventSource` class in our client-side application, passing the `/sse` route (which matches the endpoint we have passed into the `@Sse()` decorator above) as a constructor argument.

`EventSource` instance opens a persistent connection to an HTTP server, which sends events in `text/event-stream` format. The connection remains open until closed by calling `EventSource.close()`.

Once the connection is opened, incoming messages from the server are delivered to your code in the form of events. If there is an event field in the incoming message, the triggered event is the same as the event field value. If no event field is present, then a generic `message` event is fired ([source](https://developer.mozilla.org/en-US/docs/Web/API/EventSource)).

```javascript

const eventSource = new EventSource('/sse');
eventSource.onmessage = ({ data }) => {
  console.log('New message', JSON.parse(data));
};
```

#### Example[#](/techniques/server-sent-events#example)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/28-sse).

----
url: https://docs.nestjs.com/v9/techniques/database
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Database](https://docs.nestjs.com/v9/techniques/database#database)
* [TypeORM Integration](https://docs.nestjs.com/v9/techniques/database#typeorm-integration)
* [Repository pattern](https://docs.nestjs.com/v9/techniques/database#repository-pattern)
* [Relations](https://docs.nestjs.com/v9/techniques/database#relations)
* [Auto-load entities](https://docs.nestjs.com/v9/techniques/database#auto-load-entities)
* [Separating entity definition](https://docs.nestjs.com/v9/techniques/database#separating-entity-definition)
* [TypeORM Transactions](https://docs.nestjs.com/v9/techniques/database#typeorm-transactions)
* [Subscribers](https://docs.nestjs.com/v9/techniques/database#subscribers)
* [Migrations](https://docs.nestjs.com/v9/techniques/database#migrations)
* [Multiple databases](https://docs.nestjs.com/v9/techniques/database#multiple-databases)
* [Testing](https://docs.nestjs.com/v9/techniques/database#testing)
* [Async configuration](https://docs.nestjs.com/v9/techniques/database#async-configuration)
* [Custom DataSource Factory](https://docs.nestjs.com/v9/techniques/database#custom-datasource-factory)
* [Example](https://docs.nestjs.com/v9/techniques/database#example)
* [Sequelize Integration](https://docs.nestjs.com/v9/techniques/database#sequelize-integration)
* [Models](https://docs.nestjs.com/v9/techniques/database#models)
* [Relations](https://docs.nestjs.com/v9/techniques/database#relations-1)
* [Auto-load models](https://docs.nestjs.com/v9/techniques/database#auto-load-models)
* [Sequelize Transactions](https://docs.nestjs.com/v9/techniques/database#sequelize-transactions)
* [Migrations](https://docs.nestjs.com/v9/techniques/database#migrations-1)
* [Multiple databases](https://docs.nestjs.com/v9/techniques/database#multiple-databases-1)
* [Testing](https://docs.nestjs.com/v9/techniques/database#testing-1)
* [Async configuration](https://docs.nestjs.com/v9/techniques/database#async-configuration-1)
* [Example](https://docs.nestjs.com/v9/techniques/database#example-1)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/techniques/sql.md "Suggest Edits")

### Database

Nest is database agnostic, allowing you to easily integrate with any SQL or NoSQL database. You have a number of options available to you, depending on your preferences. At the most general level, connecting Nest to a database is simply a matter of loading an appropriate Node.js driver for the database, just as you would with [Express](https://expressjs.com/en/guide/database-integration.html) or Fastify.

You can also directly use any general purpose Node.js database integration **library** or ORM, such as [MikroORM](https://mikro-orm.io/) (see [MikroORM recipe](/v9/recipes/mikroorm)), [Sequelize](https://sequelize.org/) (see [Sequelize integration](/techniques/database#sequelize-integration)), [Knex.js](https://knexjs.org/) (see [Knex.js tutorial](https://dev.to/nestjs/build-a-nestjs-module-for-knex-js-or-other-resource-based-libraries-in-5-minutes-12an)), [TypeORM](https://github.com/typeorm/typeorm), and [Prisma](https://www.github.com/prisma/prisma) (see [Prisma recipe](/v9/recipes/prisma)), to operate at a higher level of abstraction.

For convenience, Nest provides tight integration with TypeORM and Sequelize out-of-the-box with the `@nestjs/typeorm` and `@nestjs/sequelize` packages respectively, which we'll cover in the current chapter, and Mongoose with `@nestjs/mongoose`, which is covered in [this chapter](/v9/techniques/mongodb). These integrations provide additional NestJS-specific features, such as model/repository injection, testability, and asynchronous configuration to make accessing your chosen database even easier.

### TypeORM Integration

For integrating with SQL and NoSQL databases, Nest provides the `@nestjs/typeorm` package. [TypeORM](https://github.com/typeorm/typeorm) it's the most mature Object Relational Mapper (ORM) available for TypeScript. Since it's written in TypeScript, it integrates well with the Nest framework.

To begin using it, we first install the required dependencies. In this chapter, we'll demonstrate using the popular [MySQL](https://www.mysql.com/) Relational DBMS, but TypeORM provides support for many relational databases, such as PostgreSQL, Oracle, Microsoft SQL Server, SQLite, and even NoSQL databases like MongoDB. The procedure we walk through in this chapter will be the same for any database supported by TypeORM. You'll simply need to install the associated client API libraries for your selected database.

```bash

$ npm install --save @nestjs/typeorm typeorm mysql2
```

Once the installation process is complete, we can import the `TypeOrmModule` into the root `AppModule`.

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';

@Module({
  imports: [
    TypeOrmModule.forRoot({
      type: 'mysql',
      host: 'localhost',
      port: 3306,
      username: 'root',
      password: 'root',
      database: 'test',
      entities: [],
      synchronize: true,
    }),
  ],
})
export class AppModule {}
```

> **Warning** Setting `synchronize: true` shouldn't be used in production - otherwise you can lose production data.

The `forRoot()` method supports all the configuration properties exposed by the `DataSource` constructor from the [TypeORM](https://typeorm.io/data-source-options#common-data-source-options) package. In addition, there are several extra configuration properties described below.

|                    |                                                                     |
| ------------------ | ------------------------------------------------------------------- |
| `retryAttempts`    | Number of attempts to connect to the database (default: `10`)       |
| `retryDelay`       | Delay between connection retry attempts (ms) (default: `3000`)      |
| `autoLoadEntities` | If `true`, entities will be loaded automatically (default: `false`) |

> **Hint** Learn more about the data source options [here](https://typeorm.io/data-source-options).

Once this is done, the TypeORM `DataSource` and `EntityManager` objects will be available to inject across the entire project (without needing to import any modules), for example:

app.module.ts

JS TS

```typescript

import { DataSource } from 'typeorm';

@Module({
  imports: [TypeOrmModule.forRoot(), UsersModule],
})
export class AppModule {
  constructor(private dataSource: DataSource) {}
}
```

```typescript

import { DataSource } from 'typeorm';

@Dependencies(DataSource)
@Module({
  imports: [TypeOrmModule.forRoot(), UsersModule],
})
export class AppModule {
  constructor(dataSource) {
    this.dataSource = dataSource;
  }
}
```

#### Repository pattern[#](/techniques/database#repository-pattern)

[TypeORM](https://github.com/typeorm/typeorm) supports the **repository design pattern**, so each entity has its own repository. These repositories can be obtained from the database data source.

To continue the example, we need at least one entity. Let's define the `User` entity.

user.entity.ts

JS TS

```typescript

import { Entity, Column, PrimaryGeneratedColumn } from 'typeorm';

@Entity()
export class User {
  @PrimaryGeneratedColumn()
  id: number;

  @Column()
  firstName: string;

  @Column()
  lastName: string;

  @Column({ default: true })
  isActive: boolean;
}
```

> **Hint** Learn more about entities in the [TypeORM documentation](https://typeorm.io/#/entities).

The `User` entity file sits in the `users` directory. This directory contains all files related to the `UsersModule`. You can decide where to keep your model files, however, we recommend creating them near their **domain**, in the corresponding module directory.

To begin using the `User` entity, we need to let TypeORM know about it by inserting it into the `entities` array in the module `forRoot()` method options (unless you use a static glob path):

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { User } from './users/user.entity';

@Module({
  imports: [
    TypeOrmModule.forRoot({
      type: 'mysql',
      host: 'localhost',
      port: 3306,
      username: 'root',
      password: 'root',
      database: 'test',
      entities: [User],
      synchronize: true,
    }),
  ],
})
export class AppModule {}
```

Next, let's look at the `UsersModule`:

users.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { UsersService } from './users.service';
import { UsersController } from './users.controller';
import { User } from './user.entity';

@Module({
  imports: [TypeOrmModule.forFeature([User])],
  providers: [UsersService],
  controllers: [UsersController],
})
export class UsersModule {}
```

This module uses the `forFeature()` method to define which repositories are registered in the current scope. With that in place, we can inject the `UsersRepository` into the `UsersService` using the `@InjectRepository()` decorator:

users.service.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { User } from './user.entity';

@Injectable()
export class UsersService {
  constructor(
    @InjectRepository(User)
    private usersRepository: Repository<User>,
  ) {}

  findAll(): Promise<User[]> {
    return this.usersRepository.find();
  }

  findOne(id: number): Promise<User | null> {
    return this.usersRepository.findOneBy({ id });
  }

  async remove(id: number): Promise<void> {
    await this.usersRepository.delete(id);
  }
}
```

```typescript

import { Injectable, Dependencies } from '@nestjs/common';
import { getRepositoryToken } from '@nestjs/typeorm';
import { User } from './user.entity';

@Injectable()
@Dependencies(getRepositoryToken(User))
export class UsersService {
  constructor(usersRepository) {
    this.usersRepository = usersRepository;
  }

  findAll() {
    return this.usersRepository.find();
  }

  findOne(id) {
    return this.usersRepository.findOneBy({ id });
  }

  async remove(id) {
    await this.usersRepository.delete(id);
  }
}
```

> **Notice** Don't forget to import the `UsersModule` into the root `AppModule`.

If you want to use the repository outside of the module which imports `TypeOrmModule.forFeature`, you'll need to re-export the providers generated by it. You can do this by exporting the whole module, like this:

users.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { User } from './user.entity';

@Module({
  imports: [TypeOrmModule.forFeature([User])],
  exports: [TypeOrmModule]
})
export class UsersModule {}
```

Now if we import `UsersModule` in `UserHttpModule`, we can use `@InjectRepository(User)` in the providers of the latter module.

users-http.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { UsersModule } from './users.module';
import { UsersService } from './users.service';
import { UsersController } from './users.controller';

@Module({
  imports: [UsersModule],
  providers: [UsersService],
  controllers: [UsersController]
})
export class UserHttpModule {}
```

#### Relations[#](/techniques/database#relations)

Relations are associations established between two or more tables. Relations are based on common fields from each table, often involving primary and foreign keys.

There are three types of relations:

|                             |                                                                                                                                                                                                                                 |
| --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `One-to-one`                | Every row in the primary table has one and only one associated row in the foreign table. Use the `@OneToOne()` decorator to define this type of relation.                                                                       |
| `One-to-many / Many-to-one` | Every row in the primary table has one or more related rows in the foreign table. Use the `@OneToMany()` and `@ManyToOne()` decorators to define this type of relation.                                                         |
| `Many-to-many`              | Every row in the primary table has many related rows in the foreign table, and every record in the foreign table has many related rows in the primary table. Use the `@ManyToMany()` decorator to define this type of relation. |

To define relations in entities, use the corresponding **decorators**. For example, to define that each `User` can have multiple photos, use the `@OneToMany()` decorator.

user.entity.ts

JS TS

```typescript

import { Entity, Column, PrimaryGeneratedColumn, OneToMany } from 'typeorm';
import { Photo } from '../photos/photo.entity';

@Entity()
export class User {
  @PrimaryGeneratedColumn()
  id: number;

  @Column()
  firstName: string;

  @Column()
  lastName: string;

  @Column({ default: true })
  isActive: boolean;

  @OneToMany(type => Photo, photo => photo.user)
  photos: Photo[];
}
```

> **Hint** To learn more about relations in TypeORM, visit the [TypeORM documentation](https://typeorm.io/#/relations).

#### Auto-load entities[#](/techniques/database#auto-load-entities)

Manually adding entities to the `entities` array of the data source options can be tedious. In addition, referencing entities from the root module breaks application domain boundaries and causes leaking implementation details to other parts of the application. To address this issue, an alternative solution is provided. To automatically load entities, set the `autoLoadEntities` property of the configuration object (passed into the `forRoot()` method) to `true`, as shown below:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';

@Module({
  imports: [
    TypeOrmModule.forRoot({
      ...
      autoLoadEntities: true,
    }),
  ],
})
export class AppModule {}
```

With that option specified, every entity registered through the `forFeature()` method will be automatically added to the `entities` array of the configuration object.

> **Warning** Note that entities that aren't registered through the `forFeature()` method, but are only referenced from the entity (via a relationship), won't be included by way of the `autoLoadEntities` setting.

#### Separating entity definition[#](/techniques/database#separating-entity-definition)

You can define an entity and its columns right in the model, using decorators. But some people prefer to define entities and their columns inside separate files using the ["entity schemas"](https://typeorm.io/#/separating-entity-definition).

```typescript

import { EntitySchema } from 'typeorm';
import { User } from './user.entity';

export const UserSchema = new EntitySchema<User>({
  name: 'User',
  target: User,
  columns: {
    id: {
      type: Number,
      primary: true,
      generated: true,
    },
    firstName: {
      type: String,
    },
    lastName: {
      type: String,
    },
    isActive: {
      type: Boolean,
      default: true,
    },
  },
  relations: {
    photos: {
      type: 'one-to-many',
      target: 'Photo', // the name of the PhotoSchema
    },
  },
});
```

> **Warning** If you provide the `target` option, the `name` option value has to be the same as the name of the target class. If you do not provide the `target` you can use any name.

Nest allows you to use an `EntitySchema` instance wherever an `Entity` is expected, for example:

```typescript

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { UserSchema } from './user.schema';
import { UsersController } from './users.controller';
import { UsersService } from './users.service';

@Module({
  imports: [TypeOrmModule.forFeature([UserSchema])],
  providers: [UsersService],
  controllers: [UsersController],
})
export class UsersModule {}
```

#### TypeORM Transactions[#](/techniques/database#typeorm-transactions)

A database transaction symbolizes a unit of work performed within a database management system against a database, and treated in a coherent and reliable way independent of other transactions. A transaction generally represents any change in a database ([learn more](https://en.wikipedia.org/wiki/Database_transaction)).

There are many different strategies to handle [TypeORM transactions](https://typeorm.io/#/transactions). We recommend using the `QueryRunner` class because it gives full control over the transaction.

First, we need to inject the `DataSource` object into a class in the normal way:

```typescript

@Injectable()
export class UsersService {
  constructor(private dataSource: DataSource) {}
}
```

> **Hint** The `DataSource` class is imported from the `typeorm` package.

Now, we can use this object to create a transaction.

```typescript

async createMany(users: User[]) {
  const queryRunner = this.dataSource.createQueryRunner();

  await queryRunner.connect();
  await queryRunner.startTransaction();
  try {
    await queryRunner.manager.save(users[0]);
    await queryRunner.manager.save(users[1]);

    await queryRunner.commitTransaction();
  } catch (err) {
    // since we have errors lets rollback the changes we made
    await queryRunner.rollbackTransaction();
  } finally {
    // you need to release a queryRunner which was manually instantiated
    await queryRunner.release();
  }
}
```

> **Hint** Note that the `dataSource` is used only to create the `QueryRunner`. However, to test this class would require mocking the entire `DataSource` object (which exposes several methods). Thus, we recommend using a helper factory class (e.g., `QueryRunnerFactory`) and defining an interface with a limited set of methods required to maintain transactions. This technique makes mocking these methods pretty straightforward.

```typescript

async createMany(users: User[]) {
  await this.dataSource.transaction(async manager => {
    await manager.save(users[0]);
    await manager.save(users[1]);
  });
}
```

#### Subscribers[#](/techniques/database#subscribers)

With TypeORM [subscribers](https://typeorm.io/#/listeners-and-subscribers/what-is-a-subscriber), you can listen to specific entity events.

```typescript

import {
  DataSource,
  EntitySubscriberInterface,
  EventSubscriber,
  InsertEvent,
} from 'typeorm';
import { User } from './user.entity';

@EventSubscriber()
export class UserSubscriber implements EntitySubscriberInterface<User> {
  constructor(dataSource: DataSource) {
    dataSource.subscribers.push(this);
  }

  listenTo() {
    return User;
  }

  beforeInsert(event: InsertEvent<User>) {
    console.log(`BEFORE USER INSERTED: `, event.entity);
  }
}
```

> **Warning** Event subscribers can not be [request-scoped](/v9/fundamentals/injection-scopes).

Now, add the `UserSubscriber` class to the `providers` array:

```typescript

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { User } from './user.entity';
import { UsersController } from './users.controller';
import { UsersService } from './users.service';
import { UserSubscriber } from './user.subscriber';

@Module({
  imports: [TypeOrmModule.forFeature([User])],
  providers: [UsersService, UserSubscriber],
  controllers: [UsersController],
})
export class UsersModule {}
```

> **Hint** Learn more about entity subscribers [here](https://typeorm.io/#/listeners-and-subscribers/what-is-a-subscriber).

#### Migrations[#](/techniques/database#migrations)

[Migrations](https://typeorm.io/#/migrations) provide a way to incrementally update the database schema to keep it in sync with the application's data model while preserving existing data in the database. To generate, run, and revert migrations, TypeORM provides a dedicated [CLI](https://typeorm.io/#/migrations/creating-a-new-migration).

Migration classes are separate from the Nest application source code. Their lifecycle is maintained by the TypeORM CLI. Therefore, you are not able to leverage dependency injection and other Nest specific features with migrations. To learn more about migrations, follow the guide in the [TypeORM documentation](https://typeorm.io/#/migrations/creating-a-new-migration).

#### Multiple databases[#](/techniques/database#multiple-databases)

Some projects require multiple database connections. This can also be achieved with this module. To work with multiple connections, first create the connections. In this case, data source naming becomes **mandatory**.

Suppose you have an `Album` entity stored in its own database.

```typescript

const defaultOptions = {
  type: 'postgres',
  port: 5432,
  username: 'user',
  password: 'password',
  database: 'db',
  synchronize: true,
};

@Module({
  imports: [
    TypeOrmModule.forRoot({
      ...defaultOptions,
      host: 'user_db_host',
      entities: [User],
    }),
    TypeOrmModule.forRoot({
      ...defaultOptions,
      name: 'albumsConnection',
      host: 'album_db_host',
      entities: [Album],
    }),
  ],
})
export class AppModule {}
```

> **Notice** If you don't set the `name` for a data source, its name is set to `default`. Please note that you shouldn't have multiple connections without a name, or with the same name, otherwise they will get overridden.

> **Notice** If you are using `TypeOrmModule.forRootAsync`, you have to **also** set the data source name outside `useFactory`. For example:
>
> ```typescript
>
> TypeOrmModule.forRootAsync({
>   name: 'albumsConnection',
>   useFactory: ...,
>   inject: ...,
> }),
> ```
>
> See [this issue](https://github.com/nestjs/typeorm/issues/86) for more details.

At this point, you have `User` and `Album` entities registered with their own data source. With this setup, you have to tell the `TypeOrmModule.forFeature()` method and the `@InjectRepository()` decorator which data source should be used. If you do not pass any data source name, the `default` data source is used.

```typescript

@Module({
  imports: [
    TypeOrmModule.forFeature([User]),
    TypeOrmModule.forFeature([Album], 'albumsConnection'),
  ],
})
export class AppModule {}
```

You can also inject the `DataSource` or `EntityManager` for a given data source:

```typescript

@Injectable()
export class AlbumsService {
  constructor(
    @InjectDataSource('albumsConnection')
    private dataSource: DataSource,
    @InjectEntityManager('albumsConnection')
    private entityManager: EntityManager,
  ) {}
}
```

It's also possible to inject any `DataSource` to the providers:

```typescript

@Module({
  providers: [
    {
      provide: AlbumsService,
      useFactory: (albumsConnection: DataSource) => {
        return new AlbumsService(albumsConnection);
      },
      inject: [getDataSourceToken('albumsConnection')],
    },
  ],
})
export class AlbumsModule {}
```

#### Testing[#](/techniques/database#testing)

When it comes to unit testing an application, we usually want to avoid making a database connection, keeping our test suites independent and their execution process as fast as possible. But our classes might depend on repositories that are pulled from the data source (connection) instance. How do we handle that? The solution is to create mock repositories. In order to achieve that, we set up [custom providers](/v9/fundamentals/custom-providers). Each registered repository is automatically represented by an `<EntityName>Repository` token, where `EntityName` is the name of your entity class.

The `@nestjs/typeorm` package exposes the `getRepositoryToken()` function which returns a prepared token based on a given entity.

```typescript

@Module({
  providers: [
    UsersService,
    {
      provide: getRepositoryToken(User),
      useValue: mockRepository,
    },
  ],
})
export class UsersModule {}
```

Now a substitute `mockRepository` will be used as the `UsersRepository`. Whenever any class asks for `UsersRepository` using an `@InjectRepository()` decorator, Nest will use the registered `mockRepository` object.

#### Async configuration[#](/techniques/database#async-configuration)

You may want to pass your repository module options asynchronously instead of statically. In this case, use the `forRootAsync()` method, which provides several ways to deal with async configuration.

One approach is to use a factory function:

```typescript

TypeOrmModule.forRootAsync({
  useFactory: () => ({
    type: 'mysql',
    host: 'localhost',
    port: 3306,
    username: 'root',
    password: 'root',
    database: 'test',
    entities: [],
    synchronize: true,
  }),
});
```

Our factory behaves like any other [asynchronous provider](https://docs.nestjs.com/fundamentals/async-providers) (e.g., it can be `async` and it's able to inject dependencies through `inject`).

```typescript

TypeOrmModule.forRootAsync({
  imports: [ConfigModule],
  useFactory: (configService: ConfigService) => ({
    type: 'mysql',
    host: configService.get('HOST'),
    port: +configService.get('PORT'),
    username: configService.get('USERNAME'),
    password: configService.get('PASSWORD'),
    database: configService.get('DATABASE'),
    entities: [],
    synchronize: true,
  }),
  inject: [ConfigService],
});
```

Alternatively, you can use the `useClass` syntax:

```typescript

TypeOrmModule.forRootAsync({
  useClass: TypeOrmConfigService,
});
```

The construction above will instantiate `TypeOrmConfigService` inside `TypeOrmModule` and use it to provide an options object by calling `createTypeOrmOptions()`. Note that this means that the `TypeOrmConfigService` has to implement the `TypeOrmOptionsFactory` interface, as shown below:

```typescript

@Injectable()
export class TypeOrmConfigService implements TypeOrmOptionsFactory {
  createTypeOrmOptions(): TypeOrmModuleOptions {
    return {
      type: 'mysql',
      host: 'localhost',
      port: 3306,
      username: 'root',
      password: 'root',
      database: 'test',
      entities: [],
      synchronize: true,
    };
  }
}
```

In order to prevent the creation of `TypeOrmConfigService` inside `TypeOrmModule` and use a provider imported from a different module, you can use the `useExisting` syntax.

```typescript

TypeOrmModule.forRootAsync({
  imports: [ConfigModule],
  useExisting: ConfigService,
});
```

This construction works the same as `useClass` with one critical difference - `TypeOrmModule` will lookup imported modules to reuse an existing `ConfigService` instead of instantiating a new one.

> **Hint** Make sure that the `name` property is defined at the same level as the `useFactory`, `useClass`, or `useValue` property. This will allow Nest to properly register the data source under the appropriate injection token.

#### Custom DataSource Factory[#](/techniques/database#custom-datasource-factory)

In conjunction with async configuration using `useFactory`, `useClass`, or `useExisting`, you can optionally specify a `dataSourceFactory` function which will allow you to provide your own TypeORM data source rather than allowing `TypeOrmModule` to create the data source.

`dataSourceFactory` receives the TypeORM `DataSourceOptions` configured during async configuration using `useFactory`, `useClass`, or `useExisting` and returns a `Promise` that resolves a TypeORM `DataSource`.

```typescript

TypeOrmModule.forRootAsync({
  imports: [ConfigModule],
  inject: [ConfigService],
  // Use useFactory, useClass, or useExisting
  // to configure the DataSourceOptions.
  useFactory: (configService: ConfigService) => ({
    type: 'mysql',
    host: configService.get('HOST'),
    port: +configService.get('PORT'),
    username: configService.get('USERNAME'),
    password: configService.get('PASSWORD'),
    database: configService.get('DATABASE'),
    entities: [],
    synchronize: true,
  }),
  // dataSource receives the configured DataSourceOptions
  // and returns a Promise<DataSource>.
  dataSourceFactory: async (options) => {
    const dataSource = await new DataSource(options).initialize();
    return dataSource;
  },
});
```

> **Hint** The `DataSource` class is imported from the `typeorm` package.

```bash

$ npm install --save @nestjs/sequelize sequelize sequelize-typescript mysql2
$ npm install --save-dev @types/sequelize
```

Once the installation process is complete, we can import the `SequelizeModule` into the root `AppModule`.

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { SequelizeModule } from '@nestjs/sequelize';

@Module({
  imports: [
    SequelizeModule.forRoot({
      dialect: 'mysql',
      host: 'localhost',
      port: 3306,
      username: 'root',
      password: 'root',
      database: 'test',
      models: [],
    }),
  ],
})
export class AppModule {}
```

The `forRoot()` method supports all the configuration properties exposed by the Sequelize constructor ([read more](https://sequelize.org/v5/manual/getting-started.html#setting-up-a-connection)). In addition, there are several extra configuration properties described below.

|                       |                                                                                         |
| --------------------- | --------------------------------------------------------------------------------------- |
| `retryAttempts`       | Number of attempts to connect to the database (default: `10`)                           |
| `retryDelay`          | Delay between connection retry attempts (ms) (default: `3000`)                          |
| `autoLoadModels`      | If `true`, models will be loaded automatically (default: `false`)                       |
| `keepConnectionAlive` | If `true`, connection will not be closed on the application shutdown (default: `false`) |
| `synchronize`         | If `true`, automatically loaded models will be synchronized (default: `true`)           |

Once this is done, the `Sequelize` object will be available to inject across the entire project (without needing to import any modules), for example:

app.service.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { Sequelize } from 'sequelize-typescript';

@Injectable()
export class AppService {
  constructor(private sequelize: Sequelize) {}
}
```

```typescript

import { Injectable } from '@nestjs/common';
import { Sequelize } from 'sequelize-typescript';

@Dependencies(Sequelize)
@Injectable()
export class AppService {
  constructor(sequelize) {
    this.sequelize = sequelize;
  }
}
```

#### Models[#](/techniques/database#models)

Sequelize implements the Active Record pattern. With this pattern, you use model classes directly to interact with the database. To continue the example, we need at least one model. Let's define the `User` model.

user.model.ts

JS TS

```typescript

import { Column, Model, Table } from 'sequelize-typescript';

@Table
export class User extends Model {
  @Column
  firstName: string;

  @Column
  lastName: string;

  @Column({ defaultValue: true })
  isActive: boolean;
}
```

> **Hint** Learn more about the available decorators [here](https://github.com/RobinBuschmann/sequelize-typescript#column).

The `User` model file sits in the `users` directory. This directory contains all files related to the `UsersModule`. You can decide where to keep your model files, however, we recommend creating them near their **domain**, in the corresponding module directory.

To begin using the `User` model, we need to let Sequelize know about it by inserting it into the `models` array in the module `forRoot()` method options:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { SequelizeModule } from '@nestjs/sequelize';
import { User } from './users/user.model';

@Module({
  imports: [
    SequelizeModule.forRoot({
      dialect: 'mysql',
      host: 'localhost',
      port: 3306,
      username: 'root',
      password: 'root',
      database: 'test',
      models: [User],
    }),
  ],
})
export class AppModule {}
```

Next, let's look at the `UsersModule`:

users.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { SequelizeModule } from '@nestjs/sequelize';
import { User } from './user.model';
import { UsersController } from './users.controller';
import { UsersService } from './users.service';

@Module({
  imports: [SequelizeModule.forFeature([User])],
  providers: [UsersService],
  controllers: [UsersController],
})
export class UsersModule {}
```

This module uses the `forFeature()` method to define which models are registered in the current scope. With that in place, we can inject the `UserModel` into the `UsersService` using the `@InjectModel()` decorator:

users.service.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { InjectModel } from '@nestjs/sequelize';
import { User } from './user.model';

@Injectable()
export class UsersService {
  constructor(
    @InjectModel(User)
    private userModel: typeof User,
  ) {}

  async findAll(): Promise<User[]> {
    return this.userModel.findAll();
  }

  findOne(id: string): Promise<User> {
    return this.userModel.findOne({
      where: {
        id,
      },
    });
  }

  async remove(id: string): Promise<void> {
    const user = await this.findOne(id);
    await user.destroy();
  }
}
```

```typescript

import { Injectable, Dependencies } from '@nestjs/common';
import { getModelToken } from '@nestjs/sequelize';
import { User } from './user.model';

@Injectable()
@Dependencies(getModelToken(User))
export class UsersService {
  constructor(usersRepository) {
    this.usersRepository = usersRepository;
  }

  async findAll() {
    return this.userModel.findAll();
  }

  findOne(id) {
    return this.userModel.findOne({
      where: {
        id,
      },
    });
  }

  async remove(id) {
    const user = await this.findOne(id);
    await user.destroy();
  }
}
```

> **Notice** Don't forget to import the `UsersModule` into the root `AppModule`.

If you want to use the repository outside of the module which imports `SequelizeModule.forFeature`, you'll need to re-export the providers generated by it. You can do this by exporting the whole module, like this:

users.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { SequelizeModule } from '@nestjs/sequelize';
import { User } from './user.entity';

@Module({
  imports: [SequelizeModule.forFeature([User])],
  exports: [SequelizeModule]
})
export class UsersModule {}
```

Now if we import `UsersModule` in `UserHttpModule`, we can use `@InjectModel(User)` in the providers of the latter module.

users-http.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { UsersModule } from './users.module';
import { UsersService } from './users.service';
import { UsersController } from './users.controller';

@Module({
  imports: [UsersModule],
  providers: [UsersService],
  controllers: [UsersController]
})
export class UserHttpModule {}
```

#### Relations[#](/techniques/database#relations-1)

Relations are associations established between two or more tables. Relations are based on common fields from each table, often involving primary and foreign keys.

There are three types of relations:

|                             |                                                                                                                                                             |
| --------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `One-to-one`                | Every row in the primary table has one and only one associated row in the foreign table                                                                     |
| `One-to-many / Many-to-one` | Every row in the primary table has one or more related rows in the foreign table                                                                            |
| `Many-to-many`              | Every row in the primary table has many related rows in the foreign table, and every record in the foreign table has many related rows in the primary table |

To define relations in entities, use the corresponding **decorators**. For example, to define that each `User` can have multiple photos, use the `@HasMany()` decorator.

user.entity.ts

JS TS

```typescript

import { Column, Model, Table, HasMany } from 'sequelize-typescript';
import { Photo } from '../photos/photo.model';

@Table
export class User extends Model {
  @Column
  firstName: string;

  @Column
  lastName: string;

  @Column({ defaultValue: true })
  isActive: boolean;

  @HasMany(() => Photo)
  photos: Photo[];
}
```

> **Hint** To learn more about associations in Sequelize, read [this](https://github.com/RobinBuschmann/sequelize-typescript#model-association) chapter.

#### Auto-load models[#](/techniques/database#auto-load-models)

Manually adding models to the `models` array of the connection options can be tedious. In addition, referencing models from the root module breaks application domain boundaries and causes leaking implementation details to other parts of the application. To solve this issue, automatically load models by setting both `autoLoadModels` and `synchronize` properties of the configuration object (passed into the `forRoot()` method) to `true`, as shown below:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { SequelizeModule } from '@nestjs/sequelize';

@Module({
  imports: [
    SequelizeModule.forRoot({
      ...
      autoLoadModels: true,
      synchronize: true,
    }),
  ],
})
export class AppModule {}
```

With that option specified, every model registered through the `forFeature()` method will be automatically added to the `models` array of the configuration object.

> **Warning** Note that models that aren't registered through the `forFeature()` method, but are only referenced from the model (via an association), won't be included.

#### Sequelize Transactions[#](/techniques/database#sequelize-transactions)

A database transaction symbolizes a unit of work performed within a database management system against a database, and treated in a coherent and reliable way independent of other transactions. A transaction generally represents any change in a database ([learn more](https://en.wikipedia.org/wiki/Database_transaction)).

There are many different strategies to handle [Sequelize transactions](https://sequelize.org/v5/manual/transactions.html). Below is a sample implementation of a managed transaction (auto-callback).

First, we need to inject the `Sequelize` object into a class in the normal way:

```typescript

@Injectable()
export class UsersService {
  constructor(private sequelize: Sequelize) {}
}
```

> **Hint** The `Sequelize` class is imported from the `sequelize-typescript` package.

Now, we can use this object to create a transaction.

```typescript

async createMany() {
  try {
    await this.sequelize.transaction(async t => {
      const transactionHost = { transaction: t };

      await this.userModel.create(
          { firstName: 'Abraham', lastName: 'Lincoln' },
          transactionHost,
      );
      await this.userModel.create(
          { firstName: 'John', lastName: 'Boothe' },
          transactionHost,
      );
    });
  } catch (err) {
    // Transaction has been rolled back
    // err is whatever rejected the promise chain returned to the transaction callback
  }
}
```

> **Hint** Note that the `Sequelize` instance is used only to start the transaction. However, to test this class would require mocking the entire `Sequelize` object (which exposes several methods). Thus, we recommend using a helper factory class (e.g., `TransactionRunner`) and defining an interface with a limited set of methods required to maintain transactions. This technique makes mocking these methods pretty straightforward.

```typescript

const defaultOptions = {
  dialect: 'postgres',
  port: 5432,
  username: 'user',
  password: 'password',
  database: 'db',
  synchronize: true,
};

@Module({
  imports: [
    SequelizeModule.forRoot({
      ...defaultOptions,
      host: 'user_db_host',
      models: [User],
    }),
    SequelizeModule.forRoot({
      ...defaultOptions,
      name: 'albumsConnection',
      host: 'album_db_host',
      models: [Album],
    }),
  ],
})
export class AppModule {}
```

> **Notice** If you don't set the `name` for a connection, its name is set to `default`. Please note that you shouldn't have multiple connections without a name, or with the same name, otherwise they will get overridden.

At this point, you have `User` and `Album` models registered with their own connection. With this setup, you have to tell the `SequelizeModule.forFeature()` method and the `@InjectModel()` decorator which connection should be used. If you do not pass any connection name, the `default` connection is used.

```typescript

@Module({
  imports: [
    SequelizeModule.forFeature([User]),
    SequelizeModule.forFeature([Album], 'albumsConnection'),
  ],
})
export class AppModule {}
```

You can also inject the `Sequelize` instance for a given connection:

```typescript

@Injectable()
export class AlbumsService {
  constructor(
    @InjectConnection('albumsConnection')
    private sequelize: Sequelize,
  ) {}
}
```

It's also possible to inject any `Sequelize` instance to the providers:

```typescript

@Module({
  providers: [
    {
      provide: AlbumsService,
      useFactory: (albumsSequelize: Sequelize) => {
        return new AlbumsService(albumsSequelize);
      },
      inject: [getDataSourceToken('albumsConnection')],
    },
  ],
})
export class AlbumsModule {}
```

#### Testing[#](/techniques/database#testing-1)

When it comes to unit testing an application, we usually want to avoid making a database connection, keeping our test suites independent and their execution process as fast as possible. But our classes might depend on models that are pulled from the connection instance. How do we handle that? The solution is to create mock models. In order to achieve that, we set up [custom providers](/v9/fundamentals/custom-providers). Each registered model is automatically represented by a `<ModelName>Model` token, where `ModelName` is the name of your model class.

The `@nestjs/sequelize` package exposes the `getModelToken()` function which returns a prepared token based on a given model.

```typescript

@Module({
  providers: [
    UsersService,
    {
      provide: getModelToken(User),
      useValue: mockModel,
    },
  ],
})
export class UsersModule {}
```

Now a substitute `mockModel` will be used as the `UserModel`. Whenever any class asks for `UserModel` using an `@InjectModel()` decorator, Nest will use the registered `mockModel` object.

#### Async configuration[#](/techniques/database#async-configuration-1)

You may want to pass your `SequelizeModule` options asynchronously instead of statically. In this case, use the `forRootAsync()` method, which provides several ways to deal with async configuration.

One approach is to use a factory function:

```typescript

SequelizeModule.forRootAsync({
  useFactory: () => ({
    dialect: 'mysql',
    host: 'localhost',
    port: 3306,
    username: 'root',
    password: 'root',
    database: 'test',
    models: [],
  }),
});
```

Our factory behaves like any other [asynchronous provider](https://docs.nestjs.com/fundamentals/async-providers) (e.g., it can be `async` and it's able to inject dependencies through `inject`).

```typescript

SequelizeModule.forRootAsync({
  imports: [ConfigModule],
  useFactory: (configService: ConfigService) => ({
    dialect: 'mysql',
    host: configService.get('HOST'),
    port: +configService.get('PORT'),
    username: configService.get('USERNAME'),
    password: configService.get('PASSWORD'),
    database: configService.get('DATABASE'),
    models: [],
  }),
  inject: [ConfigService],
});
```

Alternatively, you can use the `useClass` syntax:

```typescript

SequelizeModule.forRootAsync({
  useClass: SequelizeConfigService,
});
```

The construction above will instantiate `SequelizeConfigService` inside `SequelizeModule` and use it to provide an options object by calling `createSequelizeOptions()`. Note that this means that the `SequelizeConfigService` has to implement the `SequelizeOptionsFactory` interface, as shown below:

```typescript

@Injectable()
class SequelizeConfigService implements SequelizeOptionsFactory {
  createSequelizeOptions(): SequelizeModuleOptions {
    return {
      dialect: 'mysql',
      host: 'localhost',
      port: 3306,
      username: 'root',
      password: 'root',
      database: 'test',
      models: [],
    };
  }
}
```

In order to prevent the creation of `SequelizeConfigService` inside `SequelizeModule` and use a provider imported from a different module, you can use the `useExisting` syntax.

```typescript

SequelizeModule.forRootAsync({
  imports: [ConfigModule],
  useExisting: ConfigService,
});
```

This construction works the same as `useClass` with one critical difference - `SequelizeModule` will lookup imported modules to reuse an existing `ConfigService` instead of instantiating a new one.

#### Example[#](/techniques/database#example-1)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/07-sequelize).

----
url: https://docs.nestjs.com/v9/recipes/mikroorm
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [MikroORM](https://docs.nestjs.com/v9/recipes/mikroorm#mikroorm)
* [Installation](https://docs.nestjs.com/v9/recipes/mikroorm#installation)
* [Repositories](https://docs.nestjs.com/v9/recipes/mikroorm#repositories)
* [Using custom repositories](https://docs.nestjs.com/v9/recipes/mikroorm#using-custom-repositories)
* [Load entities automatically](https://docs.nestjs.com/v9/recipes/mikroorm#load-entities-automatically)
* [Serialization](https://docs.nestjs.com/v9/recipes/mikroorm#serialization)
* [Request scoped handlers in queues](https://docs.nestjs.com/v9/recipes/mikroorm#request-scoped-handlers-in-queues)
* [Using AsyncLocalStorage for request context](https://docs.nestjs.com/v9/recipes/mikroorm#using-asynclocalstorage-for-request-context)
* [Testing](https://docs.nestjs.com/v9/recipes/mikroorm#testing)
* [Example](https://docs.nestjs.com/v9/recipes/mikroorm#example)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/recipes/mikroorm.md "Suggest Edits")

### MikroORM

This recipe is here to help users getting started with MikroORM in Nest. MikroORM is the TypeScript ORM for Node.js based on Data Mapper, Unit of Work and Identity Map patterns. It is a great alternative to TypeORM and migration from TypeORM should be fairly easy. The complete documentation on MikroORM can be found [here](https://mikro-orm.io/docs).

> **info**`@mikro-orm/nestjs` is a third party package and is not managed by the NestJS core team. Please, report any issues found with the library in the [appropriate repository](https://github.com/mikro-orm/nestjs).

#### Installation[#](/recipes/mikroorm#installation)

Easiest way to integrate MikroORM to Nest is via [`@mikro-orm/nestjs` module](https://github.com/mikro-orm/nestjs). Simply install it next to Nest, MikroORM and underlying driver:

```bash

$ npm i @mikro-orm/core @mikro-orm/nestjs @mikro-orm/mysql # for mysql/mariadb
```

MikroORM also supports `postgres`, `sqlite`, and `mongo`. See the [official docs](https://mikro-orm.io/docs/usage-with-sql/) for all drivers.

Once the installation process is completed, we can import the `MikroOrmModule` into the root `AppModule`.

```typescript

@Module({
  imports: [
    MikroOrmModule.forRoot({
      entities: ['./dist/entities'],
      entitiesTs: ['./src/entities'],
      dbName: 'my-db-name.sqlite3',
      type: 'sqlite',
    }),
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}
```

The `forRoot()` method accepts the same configuration object as `init()` from the MikroORM package. Check [this page](https://mikro-orm.io/docs/configuration) for the complete configuration documentation.

Alternatively we can [configure the CLI](https://mikro-orm.io/docs/installation#setting-up-the-commandline-tool) by creating a configuration file `mikro-orm.config.ts` and then call the `forRoot()` without any arguments. This won't work when you use a build tools that use tree shaking.

```typescript

@Module({
  imports: [
    MikroOrmModule.forRoot(),
  ],
  ...
})
export class AppModule {}
```

Afterward, the `EntityManager` will be available to inject across entire project (without importing any module elsewhere).

```ts

import { MikroORM } from '@mikro-orm/core';
// Import EntityManager from your driver package or `@mikro-orm/knex`
import { EntityManager } from '@mikro-orm/mysql';

@Injectable()
export class MyService {
  constructor(
    private readonly orm: MikroORM,
    private readonly em: EntityManager,
  ) {}
}
```

> **info** Notice that the `EntityManager` is imported from the `@mikro-orm/driver` package, where driver is `mysql`, `sqlite`, `postgres` or what driver you are using. In case you have `@mikro-orm/knex` installed as a dependency, you can also import the `EntityManager` from there.

#### Repositories[#](/recipes/mikroorm#repositories)

MikroORM supports the repository design pattern. For every entity we can create a repository. Read the complete documentation on repositories [here](https://mikro-orm.io/docs/repositories). To define which repositories should be registered in the current scope you can use the `forFeature()` method. For example, in this way:

> **info** You should **not** register your base entities via `forFeature()`, as there are no repositories for those. On the other hand, base entities need to be part of the list in `forRoot()` (or in the ORM config in general).

```typescript

// photo.module.ts
@Module({
  imports: [MikroOrmModule.forFeature([Photo])],
  providers: [PhotoService],
  controllers: [PhotoController],
})
export class PhotoModule {}
```

and import it into the root `AppModule`:

```typescript

// app.module.ts
@Module({
  imports: [MikroOrmModule.forRoot(...), PhotoModule],
})
export class AppModule {}
```

In this way we can inject the `PhotoRepository` to the `PhotoService` using the `@InjectRepository()` decorator:

```typescript

@Injectable()
export class PhotoService {
  constructor(
    @InjectRepository(Photo)
    private readonly photoRepository: EntityRepository<Photo>,
  ) {}
}
```

#### Using custom repositories[#](/recipes/mikroorm#using-custom-repositories)

When using custom repositories, we can get around the need for `@InjectRepository()` decorator by naming our repositories the same way as `getRepositoryToken()` method do:

```ts

export const getRepositoryToken = <T>(entity: EntityName<T>) =>
  `${Utils.className(entity)}Repository`;
```

In other words, as long as we name the repository same was as the entity is called, appending `Repository` suffix, the repository will be registered automatically in the Nest DI container.

```ts

// `**./author.entity.ts**`
@Entity()
export class Author {
  // to allow inference in `em.getRepository()`
  [EntityRepositoryType]?: AuthorRepository;
}

// `**./author.repository.ts**`
@Repository(Author)
export class AuthorRepository extends EntityRepository<Author> {
  // your custom methods...
}
```

As the custom repository name is the same as what `getRepositoryToken()` would return, we do not need the `@InjectRepository()` decorator anymore:

```ts

@Injectable()
export class MyService {
  constructor(private readonly repo: AuthorRepository) {}
}
```

#### Load entities automatically[#](/recipes/mikroorm#load-entities-automatically)

> **info**`autoLoadEntities` option was added in v4.1.0

Manually adding entities to the entities array of the connection options can be tedious. In addition, referencing entities from the root module breaks application domain boundaries and causes leaking implementation details to other parts of the application. To solve this issue, static glob paths can be used.

Note, however, that glob paths are not supported by webpack, so if you are building your application within a monorepo, you won't be able to use them. To address this issue, an alternative solution is provided. To automatically load entities, set the `autoLoadEntities` property of the configuration object (passed into the `forRoot()` method) to `true`, as shown below:

```ts

@Module({
  imports: [
    MikroOrmModule.forRoot({
      ...
      autoLoadEntities: true,
    }),
  ],
})
export class AppModule {}
```

With that option specified, every entity registered through the `forFeature()` method will be automatically added to the entities array of the configuration object.

> **info** Note that entities that aren't registered through the `forFeature()` method, but are only referenced from the entity (via a relationship), won't be included by way of the `autoLoadEntities` setting.

> **info** Using `autoLoadEntities` also has no effect on the MikroORM CLI - for that we still need CLI config with the full list of entities. On the other hand, we can use globs there, as the CLI won't go thru webpack.

#### Serialization[#](/recipes/mikroorm#serialization)

> **Note** MikroORM wraps every single entity relation in a `Reference<T>` or a `Collection<T>` object, in order to provide better type-safety. This will make [Nest's built-in serializer](/techniques/serialization) blind to any wrapped relations. In other words, if you return MikroORM entities from your HTTP or WebSocket handlers, all of their relations will NOT be serialized.

Luckily, MikroORM provides a [serialization API](https://mikro-orm.io/docs/serializing) which can be used in lieu of `ClassSerializerInterceptor`.

```typescript

@Entity()
export class Book {
  @Property({ hidden: true }) // Equivalent of class-transformer's `@Exclude`
  hiddenField = Date.now();

  @Property({ persist: false }) // Similar to class-transformer's `@Expose()`. Will only exist in memory, and will be serialized.
  count?: number;

  @ManyToOne({
    serializer: (value) => value.name,
    serializedName: 'authorName',
  }) // Equivalent of class-transformer's `@Transform()`
  author: Author;
}
```

#### Request scoped handlers in queues[#](/recipes/mikroorm#request-scoped-handlers-in-queues)

> **info**`@UseRequestContext()` decorator was added in v4.1.0

As mentioned in the [docs](https://mikro-orm.io/docs/identity-map), we need a clean state for each request. That is handled automatically thanks to the `RequestContext` helper registered via middleware.

But middlewares are executed only for regular HTTP request handles, what if we need a request scoped method outside of that? One example of that is queue handlers or scheduled tasks.

We can use the `@UseRequestContext()` decorator. It requires you to first inject the `MikroORM` instance to current context, it will be then used to create the context for you. Under the hood, the decorator will register new request context for your method and execute it inside the context.

```ts

@Injectable()
export class MyService {
  constructor(private readonly orm: MikroORM) {}

  @UseRequestContext()
  async doSomething() {
    // this will be executed in a separate context
  }
}
```

#### Using `AsyncLocalStorage` for request context[#](/recipes/mikroorm#using-asynclocalstorage-for-request-context)

By default, the `domain` api is used in the `RequestContext` helper. Since `@mikro-orm/core@4.0.3`, you can use the new `AsyncLocalStorage` too, if you are on up to date node version:

```typescript

// create new (global) storage instance
const storage = new AsyncLocalStorage<EntityManager>();

@Module({
  imports: [
    MikroOrmModule.forRoot({
      // ...
      registerRequestContext: false, // disable automatic middleware
      context: () => storage.getStore(), // use our AsyncLocalStorage instance
    }),
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

// register the request context middleware
const app = await NestFactory.create(AppModule, { ... });
const orm = app.get(MikroORM);

app.use((req, res, next) => {
  storage.run(orm.em.fork(true, true), next);
});
```

#### Testing[#](/recipes/mikroorm#testing)

The `@mikro-orm/nestjs` package exposes `getRepositoryToken()` function that returns prepared token based on a given entity to allow mocking the repository.

```typescript

@Module({
  providers: [
    PhotoService,
    {
      provide: getRepositoryToken(Photo),
      useValue: mockedRepository,
    },
  ],
})
export class PhotoModule {}
```

#### Example[#](/recipes/mikroorm#example)

A real world example of NestJS with MikroORM can be found [here](https://github.com/mikro-orm/nestjs-realworld-example-app)

----
url: https://docs.nestjs.com/v8/recipes/mikroorm
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [MikroORM](https://docs.nestjs.com/v8/recipes/mikroorm#mikroorm)
* [Installation](https://docs.nestjs.com/v8/recipes/mikroorm#installation)
* [Repositories](https://docs.nestjs.com/v8/recipes/mikroorm#repositories)
* [Using custom repositories](https://docs.nestjs.com/v8/recipes/mikroorm#using-custom-repositories)
* [Load entities automatically](https://docs.nestjs.com/v8/recipes/mikroorm#load-entities-automatically)
* [Serialization](https://docs.nestjs.com/v8/recipes/mikroorm#serialization)
* [Request scoped handlers in queues](https://docs.nestjs.com/v8/recipes/mikroorm#request-scoped-handlers-in-queues)
* [Using AsyncLocalStorage for request context](https://docs.nestjs.com/v8/recipes/mikroorm#using-asynclocalstorage-for-request-context)
* [Testing](https://docs.nestjs.com/v8/recipes/mikroorm#testing)
* [Example](https://docs.nestjs.com/v8/recipes/mikroorm#example)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/recipes/mikroorm.md "Suggest Edits")

### MikroORM

This recipe is here to help users getting started with MikroORM in Nest. MikroORM is the TypeScript ORM for Node.js based on Data Mapper, Unit of Work and Identity Map patterns. It is a great alternative to TypeORM and migration from TypeORM should be fairly easy. The complete documentation on MikroORM can be found [here](https://mikro-orm.io/docs).

> **info**`@mikro-orm/nestjs` is a third party package and is not managed by the NestJS core team. Please, report any issues found with the library in the [appropriate repository](https://github.com/mikro-orm/nestjs).

#### Installation[#](/recipes/mikroorm#installation)

Easiest way to integrate MikroORM to Nest is via [`@mikro-orm/nestjs` module](https://github.com/mikro-orm/nestjs). Simply install it next to Nest, MikroORM and underlying driver:

```bash

$ npm i @mikro-orm/core @mikro-orm/nestjs @mikro-orm/mysql # for mysql/mariadb
```

MikroORM also supports `postgres`, `sqlite`, and `mongo`. See the [official docs](https://mikro-orm.io/docs/usage-with-sql/) for all drivers.

Once the installation process is completed, we can import the `MikroOrmModule` into the root `AppModule`.

```typescript

@Module({
  imports: [
    MikroOrmModule.forRoot({
      entities: ['./dist/entities'],
      entitiesTs: ['./src/entities'],
      dbName: 'my-db-name.sqlite3',
      type: 'sqlite',
    }),
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}
```

The `forRoot()` method accepts the same configuration object as `init()` from the MikroORM package. Check [this page](https://mikro-orm.io/docs/configuration) for the complete configuration documentation.

Alternatively we can [configure the CLI](https://mikro-orm.io/docs/installation#setting-up-the-commandline-tool) by creating a configuration file `mikro-orm.config.ts` and then call the `forRoot()` without any arguments. This won't work when you use a build tools that use tree shaking.

```typescript

@Module({
  imports: [
    MikroOrmModule.forRoot(),
  ],
  ...
})
export class AppModule {}
```

Afterward, the `EntityManager` will be available to inject across entire project (without importing any module elsewhere).

```ts

import { MikroORM } from '@mikro-orm/core';
// Import EntityManager from your driver package or `@mikro-orm/knex`
import { EntityManager } from '@mikro-orm/mysql';

@Injectable()
export class MyService {
  constructor(
    private readonly orm: MikroORM,
    private readonly em: EntityManager,
  ) {}
}
```

> **info** Notice that the `EntityManager` is imported from the `@mikro-orm/driver` package, where driver is `mysql`, `sqlite`, `postgres` or what driver you are using. In case you have `@mikro-orm/knex` installed as a dependency, you can also import the `EntityManager` from there.

#### Repositories[#](/recipes/mikroorm#repositories)

MikroORM supports the repository design pattern. For every entity we can create a repository. Read the complete documentation on repositories [here](https://mikro-orm.io/docs/repositories). To define which repositories should be registered in the current scope you can use the `forFeature()` method. For example, in this way:

> **info** You should **not** register your base entities via `forFeature()`, as there are no repositories for those. On the other hand, base entities need to be part of the list in `forRoot()` (or in the ORM config in general).

```typescript

// photo.module.ts
@Module({
  imports: [MikroOrmModule.forFeature([Photo])],
  providers: [PhotoService],
  controllers: [PhotoController],
})
export class PhotoModule {}
```

and import it into the root `AppModule`:

```typescript

// app.module.ts
@Module({
  imports: [MikroOrmModule.forRoot(...), PhotoModule],
})
export class AppModule {}
```

In this way we can inject the `PhotoRepository` to the `PhotoService` using the `@InjectRepository()` decorator:

```typescript

@Injectable()
export class PhotoService {
  constructor(
    @InjectRepository(Photo)
    private readonly photoRepository: EntityRepository<Photo>,
  ) {}
}
```

#### Using custom repositories[#](/recipes/mikroorm#using-custom-repositories)

When using custom repositories, we can get around the need for `@InjectRepository()` decorator by naming our repositories the same way as `getRepositoryToken()` method do:

```ts

export const getRepositoryToken = <T>(entity: EntityName<T>) =>
  `${Utils.className(entity)}Repository`;
```

In other words, as long as we name the repository same was as the entity is called, appending `Repository` suffix, the repository will be registered automatically in the Nest DI container.

```ts

// `**./author.entity.ts**`
@Entity()
export class Author {
  // to allow inference in `em.getRepository()`
  [EntityRepositoryType]?: AuthorRepository;
}

// `**./author.repository.ts**`
@Repository(Author)
export class AuthorRepository extends EntityRepository<Author> {
  // your custom methods...
}
```

As the custom repository name is the same as what `getRepositoryToken()` would return, we do not need the `@InjectRepository()` decorator anymore:

```ts

@Injectable()
export class MyService {
  constructor(private readonly repo: AuthorRepository) {}
}
```

#### Load entities automatically[#](/recipes/mikroorm#load-entities-automatically)

> **info**`autoLoadEntities` option was added in v4.1.0

Manually adding entities to the entities array of the connection options can be tedious. In addition, referencing entities from the root module breaks application domain boundaries and causes leaking implementation details to other parts of the application. To solve this issue, static glob paths can be used.

Note, however, that glob paths are not supported by webpack, so if you are building your application within a monorepo, you won't be able to use them. To address this issue, an alternative solution is provided. To automatically load entities, set the `autoLoadEntities` property of the configuration object (passed into the `forRoot()` method) to `true`, as shown below:

```ts

@Module({
  imports: [
    MikroOrmModule.forRoot({
      ...
      autoLoadEntities: true,
    }),
  ],
})
export class AppModule {}
```

With that option specified, every entity registered through the `forFeature()` method will be automatically added to the entities array of the configuration object.

> **info** Note that entities that aren't registered through the `forFeature()` method, but are only referenced from the entity (via a relationship), won't be included by way of the `autoLoadEntities` setting.

> **info** Using `autoLoadEntities` also has no effect on the MikroORM CLI - for that we still need CLI config with the full list of entities. On the other hand, we can use globs there, as the CLI won't go thru webpack.

#### Serialization[#](/recipes/mikroorm#serialization)

> **Note** MikroORM wraps every single entity relation in a `Reference<T>` or a `Collection<T>` object, in order to provide better type-safety. This will make [Nest's built-in serializer](/techniques/serialization) blind to any wrapped relations. In other words, if you return MikroORM entities from your HTTP or WebSocket handlers, all of their relations will NOT be serialized.

Luckily, MikroORM provides a [serialization API](https://mikro-orm.io/docs/serializing) which can be used in lieu of `ClassSerializerInterceptor`.

```typescript

@Entity()
export class Book {
  @Property({ hidden: true }) // Equivalent of class-transformer's `@Exclude`
  hiddenField = Date.now();

  @Property({ persist: false }) // Similar to class-transformer's `@Expose()`. Will only exist in memory, and will be serialized.
  count?: number;

  @ManyToOne({
    serializer: (value) => value.name,
    serializedName: 'authorName',
  }) // Equivalent of class-transformer's `@Transform()`
  author: Author;
}
```

#### Request scoped handlers in queues[#](/recipes/mikroorm#request-scoped-handlers-in-queues)

> **info**`@UseRequestContext()` decorator was added in v4.1.0

As mentioned in the [docs](https://mikro-orm.io/docs/identity-map), we need a clean state for each request. That is handled automatically thanks to the `RequestContext` helper registered via middleware.

But middlewares are executed only for regular HTTP request handles, what if we need a request scoped method outside of that? One example of that is queue handlers or scheduled tasks.

We can use the `@UseRequestContext()` decorator. It requires you to first inject the `MikroORM` instance to current context, it will be then used to create the context for you. Under the hood, the decorator will register new request context for your method and execute it inside the context.

```ts

@Injectable()
export class MyService {
  constructor(private readonly orm: MikroORM) {}

  @UseRequestContext()
  async doSomething() {
    // this will be executed in a separate context
  }
}
```

#### Using `AsyncLocalStorage` for request context[#](/recipes/mikroorm#using-asynclocalstorage-for-request-context)

By default, the `domain` api is used in the `RequestContext` helper. Since `@mikro-orm/core@4.0.3`, you can use the new `AsyncLocalStorage` too, if you are on up to date node version:

```typescript

// create new (global) storage instance
const storage = new AsyncLocalStorage<EntityManager>();

@Module({
  imports: [
    MikroOrmModule.forRoot({
      // ...
      registerRequestContext: false, // disable automatatic middleware
      context: () => storage.getStore(), // use our AsyncLocalStorage instance
    }),
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

// register the request context middleware
const app = await NestFactory.create(AppModule, { ... });
const orm = app.get(MikroORM);

app.use((req, res, next) => {
  storage.run(orm.em.fork(true, true), next);
});
```

#### Testing[#](/recipes/mikroorm#testing)

The `@mikro-orm/nestjs` package exposes `getRepositoryToken()` function that returns prepared token based on a given entity to allow mocking the repository.

```typescript

@Module({
  providers: [
    PhotoService,
    {
      provide: getRepositoryToken(Photo),
      useValue: mockedRepository,
    },
  ],
})
export class PhotoModule {}
```

#### Example[#](/recipes/mikroorm#example)

A real world example of NestJS with MikroORM can be found [here](https://github.com/mikro-orm/nestjs-realworld-example-app)

----
url: https://docs.nestjs.com/v6/cli/overview
----

* [Overview](https://docs.nestjs.com/v6/cli/overview#overview)
* [Installation](https://docs.nestjs.com/v6/cli/overview#installation)
* [Basic workflow](https://docs.nestjs.com/v6/cli/overview#basic-workflow)
* [Project structure](https://docs.nestjs.com/v6/cli/overview#project-structure)
* [CLI command syntax](https://docs.nestjs.com/v6/cli/overview#cli-command-syntax)
* [Command overview](https://docs.nestjs.com/v6/cli/overview#command-overview)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/cli/overview.md "Suggest Edits")

### Overview

The [Nest CLI](https://github.com/nestjs/nest-cli) is a command-line interface tool that helps you to initialize, develop, and maintain your Nest applications. It assists in multiple ways, including scaffolding the project, serving it in development mode, and building and bundling the application for production distribution. It embodies best-practice architectural patterns to encourage well-structured apps.

#### Installation[#](/cli/overview#installation)

**Note**: In this guide we describe using [npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm) to install packages, including the Nest CLI. Other package managers may be used at your discretion. With npm, you have several options available for managing how your OS command line resolves the location of the `nest` CLI binary file. Here, we describe installing the `nest` binary globally using the `-g` option. This provides a measure of convenience, and is the approach we assume throughout the documentation. Note that installing **any**`npm` package globally leaves the responsibility of ensuring they're running the correct version up to the user. It also means that if you have different projects, each will run the **same** version of the CLI. A reasonable alternative is to use the [npx](https://github.com/npm/npx) program (or similar features with other package managers) to ensure that you run a **managed version** of the Nest CLI. We recommend you consult the [npx documentation](https://github.com/npm/npx) and/or your DevOps support staff for more information.

Install the CLI globally using the `npm install -g` command (see the **Note** above for details about global installs).

```bash

$ npm install -g @nestjs/cli
```

#### Basic workflow[#](/cli/overview#basic-workflow)

Once installed, you can invoke CLI commands directly from your OS command line through the `nest` executable. See the available `nest` commands by entering the following:

```bash

$ nest --help
```

Get help on an individual command using the following construct. Substitute any command, like `new`, `add`, etc., where you see `generate` in the example below to get detailed help on that command:

```bash

$ nest generate --help
```

To create, build and run a new basic Nest project in development mode, go to the folder that should be the parent of your new project, and run the following commands:

```bash

$ nest new my-nest-project
$ cd my-nest-project
$ npm run start:dev
```

In your browser, open <http://localhost:3000> to see the new application running. The app will automatically recompile and reload when you change any of the source files.

#### Project structure[#](/cli/overview#project-structure)

When you run `nest new`, Nest generates a boilerplate application structure by creating a new folder and populating an initial set of files. You can continue working in this default structure, adding new components, as described throughout this documentation. We refer to the project structure generated by `nest new` as **standard mode**. Nest also supports an alternate structure for managing multiple projects and libraries called **monorepo mode**.

Aside from a few specific considerations around how the **build** process works (essentially, monorepo mode simplifies build complexities that can sometimes arise from monorepo-style project structures), and built-in [library](/v6/cli/libraries) support, the rest of the Nest features, and this documentation, apply equally to both standard and monorepo mode project structures. In fact, you can easily switch from standard mode to monorepo mode at any time in the future, so you can safely defer this decision while you're still learning about Nest.

You can use either mode to manage multiple projects. Here's a quick summary of the differences:

| Feature                                              | Standard Mode                                                      | Monorepo Mode                                              |
| ---------------------------------------------------- | ------------------------------------------------------------------ | ---------------------------------------------------------- |
| Multiple projects                                    | Separate file system structure                                     | Single file system structure                               |
| `node_modules` & `package.json`                      | Separate instances                                                 | Shared across monorepo                                     |
| Default compiler                                     | `tsc`                                                              | webpack                                                    |
| Compiler settings                                    | Specified separately                                               | Monorepo defaults that can be overridden per project       |
| Config files like `tslint.json`, `.prettierrc`, etc. | Specified separately                                               | Shared across monorepo                                     |
| `nest build` and `nest start` commands               | Target defaults automatically to the (only) project in the context | Target defaults to the **default project** in the monorepo |
| Libraries                                            | Managed manually, usually via npm packaging                        | Built-in support, including path management and bundling   |

Read the sections on [Workspaces](/v6/cli/monorepo) and [Libraries](/v6/cli/libraries) for more detailed information to help you decide which mode is most suitable for you.

## Learn the right way!

* 60+ chapters
* 4+ hours of videos
* Official certificate
* Deep-dive sessions

[Explore official courses](https://courses.nestjs.com "Courses | NestJS - A node.js framework built on top of TypeScript")

### CLI command syntax

All `nest` commands follow the same format:

```bash

nest commandOrAlias requiredArg [optionalArg] [options]
```

For example:

```bash

$ nest new my-nest-project --dry-run
```

Here, `new` is the *commandOrAlias*. The `new` command has an alias of `n`. `my-nest-project` is the *requiredArg*. If a *requiredArg* is not supplied on the command line, `nest` will prompt for it. Also, `--dry-run` has an equivalent short-hand form `-d`. With this in mind, the following command is the equivalent of the above:

```bash

$ nest n my-nest-project -d
```

Most commands, and some options, have aliases. Try running `nest new --help` to see these options and aliases, and to confirm your understanding of the above constructs.

### Command overview

Run `nest <command> --help` for any of the following commands to see command-specific options.

See [usage](/v6/cli/usages) for detailed descriptions for each command.

| Command    | Alias | Description                                                                                          |
| ---------- | ----- | ---------------------------------------------------------------------------------------------------- |
| `new`      | `n`   | Scaffolds a new *standard mode* application with all boilerplate files needed to run.                |
| `generate` | `g`   | Generates and/or modifies files based on a schematic.                                                |
| `build`    |       | Compiles an application or workspace into an output folder.                                          |
| `start`    |       | Compiles and runs an application (or default project in a workspace).                                |
| `add`      |       | Imports a library that has been packaged as a **nest library**, running its install schematic.       |
| `update`   | `u`   | Update `@nestjs` dependencies in the `package.json``"dependencies"` list to their `@latest` version. |
| `info`     | `i`   | Displays information about installed nest packages and other helpful system info.                    |

----
url: https://docs.nestjs.com/v8/websockets/adapter
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Adapters](https://docs.nestjs.com/v8/websockets/adapter#adapters)
* [Extend socket.io](https://docs.nestjs.com/v8/websockets/adapter#extend-socketio)
* [Ws library](https://docs.nestjs.com/v8/websockets/adapter#ws-library)
* [Advanced (custom adapter)](https://docs.nestjs.com/v8/websockets/adapter#advanced-custom-adapter)
* [Example](https://docs.nestjs.com/v8/websockets/adapter#example)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/websockets/adapter.md "Suggest Edits")

### Adapters

The WebSockets module is platform-agnostic, hence, you can bring your own library (or even a native implementation) by making use of `WebSocketAdapter` interface. This interface forces to implement few methods described in the following table:

|                        |                                                                 |
| ---------------------- | --------------------------------------------------------------- |
| `create`               | Creates a socket instance based on passed arguments             |
| `bindClientConnect`    | Binds the client connection event                               |
| `bindClientDisconnect` | Binds the client disconnection event (optional\*)               |
| `bindMessageHandlers`  | Binds the incoming message to the corresponding message handler |
| `close`                | Terminates a server instance                                    |

#### Extend socket.io[#](/websockets/adapter#extend-socketio)

The [socket.io](https://github.com/socketio/socket.io) package is wrapped in an `IoAdapter` class. What if you would like to enhance the basic functionality of the adapter? For instance, your technical requirements require a capability to broadcast events across multiple load-balanced instances of your web service. For this, you can extend `IoAdapter` and override a single method which responsibility is to instantiate new socket.io servers. But first of all, let's install the required package.

> **Warning** To use socket.io with multiple load-balanced instances you either have to disable polling by setting `transports: ['websocket']` in your clients socket.io configuration or you have to enable cookie based routing in your load balancer. Redis alone is not enough. See [here](https://socket.io/docs/v4/using-multiple-nodes/#enabling-sticky-session) for more information.

```bash

$ npm i --save redis socket.io @socket.io/redis-adapter
```

Once the package is installed, we can create a `RedisIoAdapter` class.

```typescript

import { IoAdapter } from '@nestjs/platform-socket.io';
import { ServerOptions } from 'socket.io';
import { createAdapter } from '@socket.io/redis-adapter';
import { createClient } from 'redis';

export class RedisIoAdapter extends IoAdapter {
  private adapterConstructor: ReturnType<typeof createAdapter>;

  async connectToRedis(): Promise<void> {
    const pubClient = createClient({ url: `redis://localhost:6379` });
    const subClient = pubClient.duplicate();

    await Promise.all([pubClient.connect(), subClient.connect()]);

    this.adapterConstructor = createAdapter(pubClient, subClient);
  }

  createIOServer(port: number, options?: ServerOptions): any {
    const server = super.createIOServer(port, options);
    server.adapter(this.adapterConstructor);
    return server;
  }
}
```

Afterward, simply switch to your newly created Redis adapter.

```typescript

const app = await NestFactory.create(AppModule);
const redisIoAdapter = new RedisIoAdapter(app);
await redisIoAdapter.connectToRedis();

app.useWebSocketAdapter(redisIoAdapter);
```

#### Ws library[#](/websockets/adapter#ws-library)

Another available adapter is a `WsAdapter` which in turn acts like a proxy between the framework and integrate blazing fast and thoroughly tested [ws](https://github.com/websockets/ws) library. This adapter is fully compatible with native browser WebSockets and is far faster than socket.io package. Unluckily, it has significantly fewer functionalities available out-of-the-box. In some cases, you may just don't necessarily need them though.

> **Hint**`ws` library does not support namespaces (communication channels popularised by `socket.io`). However, to somehow mimic this feature, you can mount multiple `ws` servers on different paths (example: `@WebSocketGateway({ path: '/users' })`).

In order to use `ws`, we firstly have to install the required package:

```bash

$ npm i --save @nestjs/platform-ws
```

Once the package is installed, we can switch an adapter:

```typescript

const app = await NestFactory.create(AppModule);
app.useWebSocketAdapter(new WsAdapter(app));
```

> **Hint** The `WsAdapter` is imported from `@nestjs/platform-ws`.

#### Advanced (custom adapter)[#](/websockets/adapter#advanced-custom-adapter)

For demonstration purposes, we are going to integrate the [ws](https://github.com/websockets/ws) library manually. As mentioned, the adapter for this library is already created and is exposed from the `@nestjs/platform-ws` package as a `WsAdapter` class. Here is how the simplified implementation could potentially look like:

ws-adapter.ts

JS TS

```typescript

import * as WebSocket from 'ws';
import { WebSocketAdapter, INestApplicationContext } from '@nestjs/common';
import { MessageMappingProperties } from '@nestjs/websockets';
import { Observable, fromEvent, EMPTY } from 'rxjs';
import { mergeMap, filter } from 'rxjs/operators';

export class WsAdapter implements WebSocketAdapter {
  constructor(private app: INestApplicationContext) {}

  create(port: number, options: any = {}): any {
    return new WebSocket.Server({ port, ...options });
  }

  bindClientConnect(server, callback: Function) {
    server.on('connection', callback);
  }

  bindMessageHandlers(
    client: WebSocket,
    handlers: MessageMappingProperties[],
    process: (data: any) => Observable<any>,
  ) {
    fromEvent(client, 'message')
      .pipe(
        mergeMap(data => this.bindMessageHandler(data, handlers, process)),
        filter(result => result),
      )
      .subscribe(response => client.send(JSON.stringify(response)));
  }

  bindMessageHandler(
    buffer,
    handlers: MessageMappingProperties[],
    process: (data: any) => Observable<any>,
  ): Observable<any> {
    const message = JSON.parse(buffer.data);
    const messageHandler = handlers.find(
      handler => handler.message === message.event,
    );
    if (!messageHandler) {
      return EMPTY;
    }
    return process(messageHandler.callback(message.data));
  }

  close(server) {
    server.close();
  }
}
```

> **Hint** When you want to take advantage of [ws](https://github.com/websockets/ws) library, use built-in `WsAdapter` instead of creating your own one.

Then, we can set up a custom adapter using `useWebSocketAdapter()` method:

main.ts

JS TS

```typescript

const app = await NestFactory.create(AppModule);
app.useWebSocketAdapter(new WsAdapter(app));
```

#### Example[#](/websockets/adapter#example)

A working example that uses `WsAdapter` is available [here](https://github.com/nestjs/nest/tree/master/sample/16-gateways-ws).

----
url: https://docs.nestjs.com/v8/techniques/caching
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Caching](https://docs.nestjs.com/v8/techniques/caching#caching)
* [Installation](https://docs.nestjs.com/v8/techniques/caching#installation)
* [In-memory cache](https://docs.nestjs.com/v8/techniques/caching#in-memory-cache)
* [Interacting with the Cache store](https://docs.nestjs.com/v8/techniques/caching#interacting-with-the-cache-store)
* [Auto-caching responses](https://docs.nestjs.com/v8/techniques/caching#auto-caching-responses)
* [Customize caching](https://docs.nestjs.com/v8/techniques/caching#customize-caching)
* [Use module globally](https://docs.nestjs.com/v8/techniques/caching#use-module-globally)
* [Global cache overrides](https://docs.nestjs.com/v8/techniques/caching#global-cache-overrides)
* [WebSockets and Microservices](https://docs.nestjs.com/v8/techniques/caching#websockets-and-microservices)
* [Adjust tracking](https://docs.nestjs.com/v8/techniques/caching#adjust-tracking)
* [Different stores](https://docs.nestjs.com/v8/techniques/caching#different-stores)
* [Async configuration](https://docs.nestjs.com/v8/techniques/caching#async-configuration)
* [Example](https://docs.nestjs.com/v8/techniques/caching#example)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/techniques/caching.md "Suggest Edits")

### Caching

Caching is a great and simple **technique** that helps improve your app's performance. It acts as a temporary data store providing high performance data access.

#### Installation[#](/techniques/caching#installation)

First install [required packages](https://github.com/BryanDonovan/node-cache-manager) (and its types for TypeScript users):

```bash

$ npm install cache-manager
$ npm install -D @types/cache-manager
```

#### In-memory cache[#](/techniques/caching#in-memory-cache)

Nest provides a unified API for various cache storage providers. The built-in one is an in-memory data store. However, you can easily switch to a more comprehensive solution, like Redis.

In order to enable caching, import the `CacheModule` and call its `register()` method.

```typescript

import { CacheModule, Module } from '@nestjs/common';
import { AppController } from './app.controller';

@Module({
  imports: [CacheModule.register()],
  controllers: [AppController],
})
export class AppModule {}
```

#### Interacting with the Cache store[#](/techniques/caching#interacting-with-the-cache-store)

To interact with the cache manager instance, inject it to your class using the `CACHE_MANAGER` token, as follows:

```typescript

constructor(@Inject(CACHE_MANAGER) private cacheManager: Cache) {}
```

> **Hint** The `Cache` class is imported from the `cache-manager`, while `CACHE_MANAGER` token from the `@nestjs/common` package.

The `get` method on the `Cache` instance (from the `cache-manager` package) is used to retrieve items from the cache. If the item does not exist in the cache, `null` will be returned.

```typescript

const value = await this.cacheManager.get('key');
```

To add an item to the cache, use the `set` method:

```typescript

await this.cacheManager.set('key', 'value');
```

The default expiration time of the cache is 5 seconds.

You can manually specify a TTL (expiration time in seconds) for this specific key, as follows:

```typescript

await this.cacheManager.set('key', 'value', { ttl: 1000 });
```

To disable expiration of the cache, set the `ttl` configuration property to `0`:

```typescript

await this.cacheManager.set('key', 'value', { ttl: 0 });
```

To remove an item from the cache, use the `del` method:

```typescript

await this.cacheManager.del('key');
```

To clear the entire cache, use the `reset` method:

```typescript

await this.cacheManager.reset();
```

#### Auto-caching responses[#](/techniques/caching#auto-caching-responses)

> **Warning** In [GraphQL](/v8/graphql/quick-start) applications, interceptors are executed separately for each field resolver. Thus, `CacheModule` (which uses interceptors to cache responses) will not work properly.

To enable auto-caching responses, just tie the `CacheInterceptor` where you want to cache data.

```typescript

@Controller()
@UseInterceptors(CacheInterceptor)
export class AppController {
  @Get()
  findAll(): string[] {
    return [];
  }
}
```

> **Warning** Only `GET` endpoints are cached. Also, HTTP server routes that inject the native response object (`@Res()`) cannot use the Cache Interceptor. See [response mapping](https://docs.nestjs.com/interceptors#response-mapping) for more details.

To reduce the amount of required boilerplate, you can bind `CacheInterceptor` to all endpoints globally:

```typescript

import { CacheModule, Module, CacheInterceptor } from '@nestjs/common';
import { AppController } from './app.controller';
import { APP_INTERCEPTOR } from '@nestjs/core';

@Module({
  imports: [CacheModule.register()],
  controllers: [AppController],
  providers: [
    {
      provide: APP_INTERCEPTOR,
      useClass: CacheInterceptor,
    },
  ],
})
export class AppModule {}
```

#### Customize caching[#](/techniques/caching#customize-caching)

All cached data has its own expiration time ([TTL](https://en.wikipedia.org/wiki/Time_to_live)). To customize default values, pass the options object to the `register()` method.

```typescript

CacheModule.register({
  ttl: 5, // seconds
  max: 10, // maximum number of items in cache
});
```

#### Use module globally[#](/techniques/caching#use-module-globally)

When you want to use `CacheModule` in other modules, you'll need to import it (as is standard with any Nest module). Alternatively, declare it as a [global module](https://docs.nestjs.com/modules#global-modules) by setting the options object's `isGlobal` property to `true`, as shown below. In that case, you will not need to import `CacheModule` in other modules once it's been loaded in the root module (e.g., `AppModule`).

```typescript

CacheModule.register({
  isGlobal: true,
});
```

#### Global cache overrides[#](/techniques/caching#global-cache-overrides)

While global cache is enabled, cache entries are stored under a `CacheKey` that is auto-generated based on the route path. You may override certain cache settings (`@CacheKey()` and `@CacheTTL()`) on a per-method basis, allowing customized caching strategies for individual controller methods. This may be most relevant while using [different cache stores.](https://docs.nestjs.com/techniques/caching#different-stores)

```typescript

@Controller()
export class AppController {
  @CacheKey('custom_key')
  @CacheTTL(20)
  findAll(): string[] {
    return [];
  }
}
```

> **Hint** The `@CacheKey()` and `@CacheTTL()` decorators are imported from the `@nestjs/common` package.

The `@CacheKey()` decorator may be used with or without a corresponding `@CacheTTL()` decorator and vice versa. One may choose to override only the `@CacheKey()` or only the `@CacheTTL()`. Settings that are not overridden with a decorator will use the default values as registered globally (see [Customize caching](https://docs.nestjs.com/techniques/caching#customize-caching)).

#### WebSockets and Microservices[#](/techniques/caching#websockets-and-microservices)

You can also apply the `CacheInterceptor` to WebSocket subscribers as well as Microservice's patterns (regardless of the transport method that is being used).

JS TS

```typescript

@CacheKey('events')
@UseInterceptors(CacheInterceptor)
@SubscribeMessage('events')
handleEvent(client: Client, data: string[]): Observable<string[]> {
  return [];
}
```

```typescript

@CacheKey('events')
@UseInterceptors(CacheInterceptor)
@SubscribeMessage('events')
handleEvent(client, data) {
  return [];
}
```

However, the additional `@CacheKey()` decorator is required in order to specify a key used to subsequently store and retrieve cached data. Also, please note that you **shouldn't cache everything**. Actions which perform some business operations rather than simply querying the data should never be cached.

Additionally, you may specify a cache expiration time (TTL) by using the `@CacheTTL()` decorator, which will override the global default TTL value.

JS TS

```typescript

@CacheTTL(10)
@UseInterceptors(CacheInterceptor)
@SubscribeMessage('events')
handleEvent(client: Client, data: string[]): Observable<string[]> {
  return [];
}
```

```typescript

@CacheTTL(10)
@UseInterceptors(CacheInterceptor)
@SubscribeMessage('events')
handleEvent(client, data) {
  return [];
}
```

> **Hint** The `@CacheTTL()` decorator may be used with or without a corresponding `@CacheKey()` decorator.

#### Adjust tracking[#](/techniques/caching#adjust-tracking)

By default, Nest uses the request URL (in an HTTP app) or cache key (in websockets and microservices apps, set through the `@CacheKey()` decorator) to associate cache records with your endpoints. Nevertheless, sometimes you might want to set up tracking based on different factors, for example, using HTTP headers (e.g. `Authorization` to properly identify `profile` endpoints).

In order to accomplish that, create a subclass of `CacheInterceptor` and override the `trackBy()` method.

```typescript

@Injectable()
class HttpCacheInterceptor extends CacheInterceptor {
  trackBy(context: ExecutionContext): string | undefined {
    return 'key';
  }
}
```

#### Different stores[#](/techniques/caching#different-stores)

This service takes advantage of [cache-manager](https://github.com/BryanDonovan/node-cache-manager) under the hood. The `cache-manager` package supports a wide-range of useful stores, for example, [Redis store](https://github.com/dabroek/node-cache-manager-redis-store). A full list of supported stores is available [here](https://github.com/BryanDonovan/node-cache-manager#store-engines). To set up the Redis store, simply pass the package together with corresponding options to the `register()` method.

```typescript

import type { ClientOpts } from 'redis';
import * as redisStore from 'cache-manager-redis-store';
import { CacheModule, Module } from '@nestjs/common';
import { AppController } from './app.controller';

@Module({
  imports: [
    CacheModule.register<ClientOpts>({
      store: redisStore,

      // Store-specific configuration:
      host: 'localhost',
      port: 6379,
    }),
  ],
  controllers: [AppController],
})
export class AppModule {}
```

> **Warning**`cache-manager-redis-store` does not support redis v4. In order for the `ClientOpts` interface to exist and work correctly you need to install the latest `redis` 3.x.x major release. See this [issue](https://github.com/dabroek/node-cache-manager-redis-store/issues/40) to track the progress of this upgrade.

#### Async configuration[#](/techniques/caching#async-configuration)

You may want to asynchronously pass in module options instead of passing them statically at compile time. In this case, use the `registerAsync()` method, which provides several ways to deal with async configuration.

One approach is to use a factory function:

```typescript

CacheModule.registerAsync({
  useFactory: () => ({
    ttl: 5,
  }),
});
```

Our factory behaves like all other asynchronous module factories (it can be `async` and is able to inject dependencies through `inject`).

```typescript

CacheModule.registerAsync({
  imports: [ConfigModule],
  useFactory: async (configService: ConfigService) => ({
    ttl: configService.get('CACHE_TTL'),
  }),
  inject: [ConfigService],
});
```

Alternatively, you can use the `useClass` method:

```typescript

CacheModule.registerAsync({
  useClass: CacheConfigService,
});
```

The above construction will instantiate `CacheConfigService` inside `CacheModule` and will use it to get the options object. The `CacheConfigService` has to implement the `CacheOptionsFactory` interface in order to provide the configuration options:

```typescript

@Injectable()
class CacheConfigService implements CacheOptionsFactory {
  createCacheOptions(): CacheModuleOptions {
    return {
      ttl: 5,
    };
  }
}
```

If you wish to use an existing configuration provider imported from a different module, use the `useExisting` syntax:

```typescript

CacheModule.registerAsync({
  imports: [ConfigModule],
  useExisting: ConfigService,
});
```

This works the same as `useClass` with one critical difference - `CacheModule` will lookup imported modules to reuse any already-created `ConfigService`, instead of instantiating its own.

> **Hint**`CacheModule#register` and `CacheModule#registerAsync` and `CacheOptionsFactory` has an optional generic (type argument) to narrow down store-specific configuration options, making it type safe.

#### Example[#](/techniques/caching#example)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/20-cache).

----
url: https://docs.nestjs.com/v9/recipes/repl
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Read-Eval-Print-Loop (REPL)](https://docs.nestjs.com/v9/recipes/repl#read-eval-print-loop-repl)
* [Usage](https://docs.nestjs.com/v9/recipes/repl#usage)
* [Native functions](https://docs.nestjs.com/v9/recipes/repl#native-functions)
* [Watch mode](https://docs.nestjs.com/v9/recipes/repl#watch-mode)

```typescript

import { repl } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
  await repl(AppModule);
}
bootstrap();
```

```typescript

import { repl } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
  await repl(AppModule);
}
bootstrap();
```

Now in your terminal, start the REPL with the following command:

```bash

$ npm run start -- --entryFile repl
```

> **Hint**`repl` returns a [Node.js REPL server](https://nodejs.org/api/repl.html) object.

Once it's up and running, you should see the following message in your console:

```bash

LOG [NestFactory] Starting Nest application...
LOG [InstanceLoader] AppModule dependencies initialized
LOG REPL initialized
```

And now you can start interacting with your dependencies graph. For instance, you can retrieve an `AppService` (we are using the starter project as an example here) and call the `getHello()` method:

```typescript

> get(AppService).getHello()
'Hello World!'
```

You can execute any JavaScript code from within your terminal, for example, assign an instance of the `AppController` to a local variable, and use `await` to call an asynchronous method:

```typescript

> appController = get(AppController)
AppController { appService: AppService {} }
> await appController.getHello()
'Hello World!'
```

To display all public methods available on a given provider or controller, use the `methods()` function, as follows:

```typescript

> methods(AppController)

Methods:
 ◻ getHello
```

To print all registered modules as a list together with their controllers and providers, use `debug()`.

```typescript

> debug()

AppModule:
 - controllers:
  ◻ AppController
 - providers:
  ◻ AppService
```

Quick demo:

You can find more information about the existing, predefined native methods in the section below.

#### Native functions[#](/recipes/repl#native-functions)

The built-in NestJS REPL comes with a few native functions that are globally available when you start REPL. You can call `help()` to list them out.

If you don't recall what's the signature (ie: expected parameters and a return type) of a function, you can call `<function_name>.help`. For instance:

```text

> $.help
Retrieves an instance of either injectable or controller, otherwise, throws exception.
Interface: $(token: InjectionToken) => any
```

> **Hint** Those function interfaces are written in [TypeScript function type expression syntax](https://www.typescriptlang.org/docs/handbook/2/functions.html#function-type-expressions).

| Function     | Description                                                                                                        | Signature                                                             |
| ------------ | ------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------- |
| `debug`      | Print all registered modules as a list together with their controllers and providers.                              | `debug(moduleCls?: ClassRef \| string) => void`                       |
| `get` or `$` | Retrieves an instance of either injectable or controller, otherwise, throws exception.                             | `get(token: InjectionToken) => any`                                   |
| `methods`    | Display all public methods available on a given provider or controller.                                            | `methods(token: ClassRef \| string) => void`                          |
| `resolve`    | Resolves transient or request-scoped instance of either injectable or controller, otherwise, throws exception.     | `resolve(token: InjectionToken, contextId: any) => Promise<any>`      |
| `select`     | Allows navigating through the modules tree, for example, to pull out a specific instance from the selected module. | `select(token: DynamicModule \| ClassRef) => INestApplicationContext` |

#### Watch mode[#](/recipes/repl#watch-mode)

During development it is useful to run REPL in a watch mode to reflect all the code changes automatically:

```bash

$ npm run start -- --watch --entryFile repl
```

This has one flaw, the REPL's command history is discarded after each reload which might be cumbersome. Fortunately, there is a very simple solution. Modify your `bootstrap` function like this:

```typescript

async function bootstrap() {
  const replServer = await repl(AppModule);
  replServer.setupHistory(".nestjs_repl_history", (err) => {
    if (err) {
      console.error(err);
    }
  });
}
```

Now the history is preserved between the runs/reloads.

----
url: https://docs.nestjs.com/v11/graphql/sharing-models
----

* [Sharing models](https://docs.nestjs.com/v11/graphql/sharing-models#sharing-models)
* [Using the model shim](https://docs.nestjs.com/v11/graphql/sharing-models#using-the-model-shim)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/sharing-models.md "Suggest Edits")

### Sharing models

> **Warning** This chapter applies only to the code first approach.

One of the biggest advantages of using Typescript for the backend of your project is the ability to reuse the same models in a Typescript-based frontend application, by using a common Typescript package.

But there's a problem: the models created using the code first approach are heavily decorated with GraphQL related decorators. Those decorators are irrelevant in the frontend, negatively impacting performance.

#### Using the model shim[#](/graphql/sharing-models#using-the-model-shim)

To solve this issue, NestJS provides a "shim" which allows you to replace the original decorators with inert code by using a `webpack` (or similar) configuration. To use this shim, configure an alias between the `@nestjs/graphql` package and the shim.

For example, for webpack this is resolved this way:

```typescript

resolve: { // see: https://webpack.js.org/configuration/resolve/
  alias: {
      "@nestjs/graphql": path.resolve(__dirname, "../node_modules/@nestjs/graphql/dist/extra/graphql-model-shim")
  }
}
```

> **Hint** The [TypeORM](/v11/techniques/database) package has a similar shim that can be found [here](https://github.com/typeorm/typeorm/blob/master/extra/typeorm-model-shim.js).

----
url: https://docs.nestjs.com/data/mikroorm
----

[Skip to content](#content)

On this page

* [MikroORM](https://docs.nestjs.com/data/mikroorm#mikroorm)
* [Installation](https://docs.nestjs.com/data/mikroorm#installation)
* [Repositories](https://docs.nestjs.com/data/mikroorm#repositories)
* [Using custom repositories](https://docs.nestjs.com/data/mikroorm#using-custom-repositories)
* [Load entities automatically](https://docs.nestjs.com/data/mikroorm#load-entities-automatically)
* [Request context](https://docs.nestjs.com/data/mikroorm#request-context)
* [Request scoped handlers in queues](https://docs.nestjs.com/data/mikroorm#request-scoped-handlers-in-queues)
* [Transactions](https://docs.nestjs.com/data/mikroorm#transactions)
* [Serialization](https://docs.nestjs.com/data/mikroorm#serialization)
* [Multiple databases](https://docs.nestjs.com/data/mikroorm#multiple-databases)
* [Testing](https://docs.nestjs.com/data/mikroorm#testing)
* [Async configuration](https://docs.nestjs.com/data/mikroorm#async-configuration)
* [Application shutdown](https://docs.nestjs.com/data/mikroorm#application-shutdown)
* [Example](https://docs.nestjs.com/data/mikroorm#example)

### MikroORM

[MikroORM](https://mikro-orm.io) is a TypeScript ORM for Node.js based on the Data Mapper, Unit of Work, and Identity Map patterns. It supports MongoDB, MySQL, MariaDB, PostgreSQL, SQLite, Microsoft SQL Server, and Oracle. The `@mikro-orm/nestjs` package integrates it with Nest: it registers the ORM and its `EntityManager` as providers, provides repository injection, creates a request context for every HTTP request, and closes the database connection when the application shuts down.

This chapter covers the Nest-specific parts of the integration. See the [MikroORM documentation](https://mikro-orm.io/docs) for complete coverage of the ORM itself.

> **Note**`@mikro-orm/nestjs` is a third-party package and is not managed by the NestJS core team. Report any issues with the library in the [mikro-orm/nestjs repository](https://github.com/mikro-orm/nestjs).

> **Hint** This chapter targets MikroORM v7 and `@mikro-orm/nestjs` v7. If you're upgrading from MikroORM v6, see the [MikroORM v6 to v7 upgrading guide](https://mikro-orm.io/docs/upgrading-v6-to-v7).

#### Installation[#](/data/mikroorm#installation)

Install the Nest module together with MikroORM, its decorators package, and the driver for your database. This chapter uses SQLite:

```bash

$ npm i @mikro-orm/nestjs @mikro-orm/core @mikro-orm/decorators @mikro-orm/sqlite
```

MikroORM provides a driver package for each supported database, such as `@mikro-orm/postgresql`, `@mikro-orm/mysql`, and `@mikro-orm/mongodb`. See the [MikroORM quick start guide](https://mikro-orm.io/docs/quick-start#installation) for the full list.

> **Hint** Since MikroORM v7, decorators are no longer exported from `@mikro-orm/core`. Nest projects use legacy (experimental) decorators, so import decorators such as `@Entity()` and `@Property()` from `@mikro-orm/decorators/legacy`. Import `EntityManager`, `EntityRepository`, and `MikroORM` from your driver package (e.g., `@mikro-orm/sqlite`), and other types (e.g., the `EntityRepositoryType` symbol) from `@mikro-orm/core`. The snippets in this chapter include the relevant import statements.

Once the installation is complete, import the `MikroOrmModule` into the root `AppModule`:

```typescript

// app.module.ts
import { Module } from '@nestjs/common';
import { MikroOrmModule } from '@mikro-orm/nestjs';
import { ReflectMetadataProvider } from '@mikro-orm/decorators/legacy';
import { SqliteDriver } from '@mikro-orm/sqlite';

@Module({
  imports: [
    MikroOrmModule.forRoot({
      driver: SqliteDriver,
      dbName: 'my-db-name.sqlite3',
      entities: ['./dist/**/*.entity.js'],
      entitiesTs: ['./src/**/*.entity.ts'],
      metadataProvider: ReflectMetadataProvider,
    }),
  ],
})
export class AppModule {}
```

The `forRoot()` method accepts the same configuration object as `MikroORM.init()`. See the [MikroORM configuration documentation](https://mikro-orm.io/docs/configuration) for the complete list of options. The `entities` and `entitiesTs` glob patterns tell MikroORM where to find your entity files: it uses `entitiesTs` when it runs from TypeScript sources and `entities` when it runs from compiled JavaScript (see [folder-based discovery](https://mikro-orm.io/docs/folder-based-discovery)).

> **Hint** Since MikroORM v7, `ReflectMetadataProvider` is no longer the default metadata provider. Set it explicitly, as shown above, to let MikroORM infer property types from the metadata that TypeScript emits for legacy decorators.

In addition, `forRoot()` supports the following Nest-specific options, all described later in this chapter:

|                          |                                                                                                                       |
| ------------------------ | --------------------------------------------------------------------------------------------------------------------- |
| `autoLoadEntities`       | If `true`, entities registered through `forFeature()` are added to the configuration automatically (default: `false`) |
| `registerRequestContext` | If `true`, registers a middleware that creates a request context for every HTTP request (default: `true`)             |
| `forRoutesPath`          | The route path that the request context middleware applies to (default: all routes)                                   |
| `scope`                  | The [injection scope](/fundamentals/injection-scopes) of the `EntityManager` provider (default: `Scope.DEFAULT`)      |
| `contextName`            | The name of the connection, required when you connect to [multiple databases](/data/mikroorm#multiple-databases)      |

Alternatively, you can keep your configuration in a separate `mikro-orm.config.ts` file, which the [MikroORM CLI](https://mikro-orm.io/docs/quick-start#setting-up-the-commandline-tool) uses as well. The `defineConfig()` helper exported by your driver package sets the `driver` option for you:

```typescript

// mikro-orm.config.ts
import { ReflectMetadataProvider } from '@mikro-orm/decorators/legacy';
import { defineConfig } from '@mikro-orm/sqlite';

export default defineConfig({
  dbName: 'my-db-name.sqlite3',
  entities: ['./dist/**/*.entity.js'],
  entitiesTs: ['./src/**/*.entity.ts'],
  metadataProvider: ReflectMetadataProvider,
});
```

Then pass the configuration to `forRoot()`. Since MikroORM v7, `forRoot()` no longer accepts an empty argument list, so you must pass the configuration explicitly:

```typescript

// app.module.ts
import { Module } from '@nestjs/common';
import { MikroOrmModule } from '@mikro-orm/nestjs';
import config from './mikro-orm.config.js';

@Module({
  imports: [MikroOrmModule.forRoot(config)],
})
export class AppModule {}
```

Afterward, the `MikroORM` and `EntityManager` objects are available for injection across the entire project, without importing any module elsewhere:

```typescript

import { Injectable } from '@nestjs/common';
import { EntityManager, MikroORM } from '@mikro-orm/sqlite';

@Injectable()
export class AppService {
  constructor(
    private readonly orm: MikroORM,
    private readonly em: EntityManager,
  ) {}
}
```

> **Note** Import `EntityManager` and `MikroORM` from the `@mikro-orm/<driver>` package, where `<driver>` is `sqlite`, `postgresql`, `mysql`, or whichever driver you use, to get the driver-specific API. If you have `@mikro-orm/sql` installed as a dependency, you can also import the `EntityManager` from there. The generic classes exported by `@mikro-orm/core` are registered as injection tokens as well.

#### Repositories[#](/data/mikroorm#repositories)

MikroORM supports the repository design pattern, so each entity has its own repository. See the [MikroORM repositories documentation](https://mikro-orm.io/docs/repositories) for details. To continue the example, define a `Photo` entity:

```typescript

// photo/photo.entity.ts
import { Entity, PrimaryKey, Property } from '@mikro-orm/decorators/legacy';

@Entity()
export class Photo {
  @PrimaryKey()
  id: number;

  @Property()
  name: string;
}
```

> **Hint** Besides decorators, MikroORM can define entities with the `defineEntity()` helper or the `EntitySchema` class. Learn more in the [MikroORM defining entities guide](https://mikro-orm.io/docs/defining-entities).

To define which repositories are registered in the current scope, use the `forFeature()` method:

```typescript

// photo/photo.module.ts
import { Module } from '@nestjs/common';
import { MikroOrmModule } from '@mikro-orm/nestjs';
import { Photo } from './photo.entity.js';
import { PhotoService } from './photo.service.js';
import { PhotoController } from './photo.controller.js';

@Module({
  imports: [MikroOrmModule.forFeature([Photo])],
  providers: [PhotoService],
  controllers: [PhotoController],
})
export class PhotoModule {}
```

> **Note** Don't register your base entities via `forFeature()`, as there are no repositories for them. Base entities do, however, need to be part of the ORM configuration (e.g., the `entities` option of `forRoot()`).

Then import the `PhotoModule` into the root `AppModule`:

```typescript

// app.module.ts
import { Module } from '@nestjs/common';
import { MikroOrmModule } from '@mikro-orm/nestjs';
import config from './mikro-orm.config.js';
import { PhotoModule } from './photo/photo.module.js';

@Module({
  imports: [MikroOrmModule.forRoot(config), PhotoModule],
})
export class AppModule {}
```

You can now inject the `Photo` repository into the `PhotoService` using the `@InjectRepository()` decorator:

```typescript

// photo/photo.service.ts
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@mikro-orm/nestjs';
import { EntityManager, EntityRepository } from '@mikro-orm/sqlite';
import { Photo } from './photo.entity.js';

@Injectable()
export class PhotoService {
  constructor(
    @InjectRepository(Photo)
    private readonly photoRepository: EntityRepository<Photo>,
    private readonly em: EntityManager,
  ) {}

  findAll(): Promise<Photo[]> {
    return this.photoRepository.findAll();
  }

  findOne(id: number): Promise<Photo | null> {
    return this.photoRepository.findOne({ id });
  }

  async create(name: string): Promise<Photo> {
    const photo = this.photoRepository.create({ name });
    await this.em.flush();
    return photo;
  }

  async remove(id: number): Promise<void> {
    const photo = await this.photoRepository.findOneOrFail({ id });
    await this.em.remove(photo).flush();
  }
}
```

Repositories don't have `persist()` or `flush()` methods, so write operations go through the `EntityManager`, which implements the [Unit of Work](https://mikro-orm.io/docs/unit-of-work) pattern. The repository's `create()` method marks the new entity for persistence, and `em.flush()` writes all pending changes to the database in a single transaction.

#### Using custom repositories[#](/data/mikroorm#using-custom-repositories)

To add your own query methods, extend `EntityRepository` and point the entity to your class through the `repository` option:

```typescript

// author/author.entity.ts
import { EntityRepositoryType } from '@mikro-orm/core';
import { Entity, PrimaryKey, Property } from '@mikro-orm/decorators/legacy';
import { AuthorRepository } from './author.repository.js';

@Entity({ repository: () => AuthorRepository })
export class Author {
  // enables type inference in `em.getRepository()`
  [EntityRepositoryType]?: AuthorRepository;

  @PrimaryKey()
  id: number;

  @Property()
  name: string;
}
```

```typescript

// author/author.repository.ts
import { EntityRepository } from '@mikro-orm/sqlite';
import { Author } from './author.entity.js';

export class AuthorRepository extends EntityRepository<Author> {
  findByName(name: string): Promise<Author | null> {
    return this.findOne({ name });
  }
}
```

When you pass the `Author` entity to `forFeature()`, the module also registers the custom repository class itself as a provider. You can therefore inject it by its class, without the `@InjectRepository()` decorator:

```typescript

@Injectable()
export class AuthorService {
  constructor(private readonly authorRepository: AuthorRepository) {}
}
```

#### Load entities automatically[#](/data/mikroorm#load-entities-automatically)

Manually adding entities to the `entities` array of the configuration can be tedious. In addition, referencing entities from the root module breaks application domain boundaries and leaks implementation details to other parts of the application. Glob paths solve this issue, but they don't work when you bundle your application (e.g., in a [monorepo](/cli/monorepo)): MikroORM looks up the matching files at runtime, and a bundle doesn't contain them as separate files.

As an alternative, you can load entities automatically by setting the `autoLoadEntities` property of the configuration object (passed into the `forRoot()` method) to `true`, as shown below:

```typescript

// app.module.ts
import { Module } from '@nestjs/common';
import { MikroOrmModule } from '@mikro-orm/nestjs';
import { ReflectMetadataProvider } from '@mikro-orm/decorators/legacy';
import { SqliteDriver } from '@mikro-orm/sqlite';

@Module({
  imports: [
    MikroOrmModule.forRoot({
      driver: SqliteDriver,
      dbName: 'my-db-name.sqlite3',
      metadataProvider: ReflectMetadataProvider,
      autoLoadEntities: true,
    }),
  ],
})
export class AppModule {}
```

With this option enabled, every entity registered through the `forFeature()` method is automatically added to the `entities` array of the configuration object.

> **Note** Entities that aren't registered through the `forFeature()` method, but are only referenced from an entity (via a relationship), won't be included by the `autoLoadEntities` setting.

> **Note**`autoLoadEntities` has no effect on the MikroORM CLI, which still needs a CLI config with the full list of entities. You can use globs there, however, as the CLI doesn't run your bundle.

#### Request context[#](/data/mikroorm#request-context)

MikroORM keeps loaded entities in an [identity map](https://mikro-orm.io/docs/identity-map), which must not be shared between concurrent requests. Each request needs its own fork of the `EntityManager`, with a clean identity map. The `MikroOrmModule` handles this for you: it registers a middleware for all routes that runs each HTTP request inside a `RequestContext`. Within that context, the global `EntityManager` that you inject (and every repository that depends on it) transparently delegates to the request's fork.

Outside of a request context, MikroORM refuses to use the global `EntityManager` for operations that depend on the identity map, such as `find()` or `flush()`, and throws a `ValidationError`. The [next section](/data/mikroorm#request-scoped-handlers-in-queues) shows how to create a context for code that doesn't run as part of an HTTP request.

To apply the middleware to a subset of routes only, set the `forRoutesPath` option. To disable it, set `registerRequestContext` to `false`. For example, instead of using the middleware, you can let Nest create an `EntityManager` fork for every request by making the `EntityManager` provider [request-scoped](/fundamentals/injection-scopes):

```typescript

// app.module.ts
import { Module, Scope } from '@nestjs/common';
import { MikroOrmModule } from '@mikro-orm/nestjs';
import config from './mikro-orm.config.js';

@Module({
  imports: [
    MikroOrmModule.forRoot({
      ...config,
      registerRequestContext: false,
      scope: Scope.REQUEST,
    }),
  ],
})
export class AppModule {}
```

> **Warning** With `scope: Scope.REQUEST`, every provider that depends on the `EntityManager` (including repositories) becomes request-scoped as well. This affects performance, as described in the [injection scopes chapter](/fundamentals/injection-scopes#performance).

#### Request scoped handlers in queues[#](/data/mikroorm#request-scoped-handlers-in-queues)

Middleware only runs for HTTP requests. Code outside of that flow, such as [queue](/application/queues) consumers and [scheduled tasks](/application/task-scheduling), has no request context, so you need to create one yourself.

For these methods, use the `@CreateRequestContext()` decorator. It forks the `EntityManager` and runs the decorated `async` method inside a new context. The decorator looks up the `EntityManager` through the `orm` property (a `MikroORM` instance) or the `em` property (an `EntityManager`) of the class, so inject one of them under that name:

```typescript

import { Injectable, Logger } from '@nestjs/common';
import { Cron, CronExpression } from '@nestjs/schedule';
import { CreateRequestContext } from '@mikro-orm/decorators/legacy';
import { MikroORM } from '@mikro-orm/sqlite';
import { Photo } from './photo.entity.js';

@Injectable()
export class PhotoStatsService {
  private readonly logger = new Logger(PhotoStatsService.name);

  constructor(private readonly orm: MikroORM) {}

  @Cron(CronExpression.EVERY_HOUR)
  @CreateRequestContext()
  async logPhotoCount() {
    // runs in a separate context, with its own identity map
    const count = await this.orm.em.count(Photo);
    this.logger.log(`Found ${count} photos`);
  }
}
```

> **Warning** Place `@CreateRequestContext()` directly above the method, below other method decorators such as `@Cron()`. The decorator replaces the method with a wrapper. Decorators listed above it attach their metadata to that wrapper, but decorators listed below it attach their metadata to the original method, which Nest never sees (in this example, the cron job wouldn't be registered).

> **Note** As the name suggests, this decorator always creates a new context, as opposed to its alternative `@EnsureRequestContext()`, which creates one only if the method isn't already running inside another context. Before MikroORM v6, `@CreateRequestContext()` was called `@UseRequestContext()`, and before v7, it was exported from `@mikro-orm/core`.

#### Transactions[#](/data/mikroorm#transactions)

MikroORM queues all write operations until you call `em.flush()`, which then wraps them in a single transaction. To control the transaction boundaries yourself, for example, to flush several times or to combine the changes with other queries, use the `em.transactional()` method:

```typescript

import { Injectable } from '@nestjs/common';
import { EntityManager } from '@mikro-orm/sqlite';
import { Photo } from './photo.entity.js';

@Injectable()
export class PhotoService {
  constructor(private readonly em: EntityManager) {}

  async createMany(names: string[]): Promise<void> {
    await this.em.transactional(async (em) => {
      for (const name of names) {
        em.create(Photo, { name });
      }
    });
  }
}
```

The callback receives a forked `EntityManager` that runs inside the transaction. When the callback completes, MikroORM flushes the fork and commits the transaction. If the callback throws, MikroORM rolls the transaction back and rethrows the error.

Alternatively, use the `@Transactional()` decorator, which wraps the decorated `async` method in `em.transactional()`:

```typescript

import { Injectable } from '@nestjs/common';
import { Transactional } from '@mikro-orm/decorators/legacy';
import { EntityManager } from '@mikro-orm/sqlite';
import { Photo } from './photo.entity.js';

@Injectable()
export class PhotoService {
  constructor(private readonly em: EntityManager) {}

  @Transactional()
  async createMany(names: string[]): Promise<void> {
    for (const name of names) {
      this.em.create(Photo, { name });
    }
  }
}
```

Like `@CreateRequestContext()`, the decorator finds the `EntityManager` through the `em` or `orm` property of the class, and falls back to the current context if the class has neither. When called inside another transaction, `em.transactional()` starts a nested transaction (a savepoint), while `@Transactional()` joins the existing transaction by default. See the [MikroORM transactions documentation](https://mikro-orm.io/docs/transactions) for propagation options, isolation levels, and locking.

#### Serialization[#](/data/mikroorm#serialization)

MikroORM entities have a `toJSON()` method that applies MikroORM's [serialization rules](https://mikro-orm.io/docs/serializing): it omits hidden properties, applies custom property serializers, and serializes populated relations as nested objects and unpopulated relations as their primary keys. When a route handler returns an entity, Nest converts it to JSON, so these rules apply automatically.

> **Warning** Don't use [Nest's built-in serializer](/application/serialization) (the `ClassSerializerInterceptor`) with MikroORM entities. It relies on `class-transformer`, which doesn't understand the wrappers that MikroORM uses for relations: it serializes the internal structure of a `Reference`, and traversing a `Collection` leads to infinite recursion (a "Maximum call stack size exceeded" error).

Instead, configure serialization on the entity with MikroORM's options:

```typescript

// book/book.entity.ts
import { type Rel } from '@mikro-orm/core';
import { Entity, ManyToOne, PrimaryKey, Property } from '@mikro-orm/decorators/legacy';
import { Author } from '../author/author.entity.js';

@Entity()
export class Book {
  @PrimaryKey()
  id: number;

  @Property()
  title: string;

  @Property({ hidden: true }) // Equivalent of class-transformer's `@Exclude()`
  hiddenField: number = Date.now();

  @Property({ persist: false }) // Similar to class-transformer's `@Expose()`. Only exists in memory, but is serialized.
  count?: number;

  @ManyToOne(() => Author, {
    serializer: (author: Author) => author.name,
    serializedName: 'authorName',
  }) // Equivalent of class-transformer's `@Transform()`
  author: Rel<Author>;
}
```

> **Hint** When entities reference each other, wrap the relation's type in `Rel<T>` (or use `Ref<T>`) from `@mikro-orm/core`, and pass the target entity to the relation decorator, as shown above. Otherwise, TypeScript emits decorator metadata that references the related class directly. In ESM projects, the circular imports between entity files then fail at startup with a `ReferenceError` (e.g., "Cannot access 'Author' before initialization").

To control serialization for a single route handler, convert the entity explicitly with the `serialize()` function, which is exported by your driver package and by `@mikro-orm/core`. It accepts options such as `populate`, `exclude`, `fields`, and `groups`:

```typescript

@Get(':id')
async findOne(@Param('id', ParseIntPipe) id: number) {
  const book = await this.em.findOneOrFail(Book, { id }, { populate: ['author'] });
  return serialize(book, { fields: ['title', 'author'] }); // { title: '...', authorName: '...' }
}
```

To get a plain object with the default rules applied, call `wrap(entity).toObject()`.

#### Multiple databases[#](/data/mikroorm#multiple-databases)

To connect to multiple databases, call `MikroOrmModule.forRoot()` once per database, and give each connection a unique `contextName`. In this setup, set `registerRequestContext` to `false` on every connection, because the default middleware only works with a single, unnamed connection. Instead, import `MikroOrmModule.forMiddleware()` once. Its middleware creates a request context that covers all connections:

```typescript

// app.module.ts
import { Module } from '@nestjs/common';
import { MikroOrmModule } from '@mikro-orm/nestjs';
import { ReflectMetadataProvider } from '@mikro-orm/decorators/legacy';
import { SqliteDriver } from '@mikro-orm/sqlite';
import { Album } from './album/album.entity.js';
import { Photo } from './photo/photo.entity.js';

@Module({
  imports: [
    MikroOrmModule.forRoot({
      contextName: 'photos',
      registerRequestContext: false,
      driver: SqliteDriver,
      dbName: 'photos.sqlite3',
      entities: [Photo],
      metadataProvider: ReflectMetadataProvider,
    }),
    MikroOrmModule.forRoot({
      contextName: 'albums',
      registerRequestContext: false,
      driver: SqliteDriver,
      dbName: 'albums.sqlite3',
      entities: [Album],
      metadataProvider: ReflectMetadataProvider,
    }),
    MikroOrmModule.forMiddleware(),
  ],
})
export class AppModule {}
```

> **Notice** If you use `MikroOrmModule.forRootAsync()`, set the `contextName` next to `useFactory`, not inside the options object that the factory returns.

With this setup, pass the context name to the `forFeature()` method and the `@InjectRepository()` decorator:

```typescript

// album/album.module.ts
@Module({
  imports: [MikroOrmModule.forFeature([Album], 'albums')],
  providers: [AlbumService],
})
export class AlbumModule {}
```

To inject the `MikroORM` or `EntityManager` of a specific connection, use the `@InjectMikroORM()` and `@InjectEntityManager()` decorators:

```typescript

// album/album.service.ts
import { Injectable } from '@nestjs/common';
import { InjectEntityManager, InjectMikroORM, InjectRepository } from '@mikro-orm/nestjs';
import { EntityManager, EntityRepository, MikroORM } from '@mikro-orm/sqlite';
import { Album } from './album.entity.js';

@Injectable()
export class AlbumService {
  constructor(
    @InjectRepository(Album, 'albums')
    private readonly albumRepository: EntityRepository<Album>,
    @InjectEntityManager('albums')
    private readonly em: EntityManager,
    @InjectMikroORM('albums')
    private readonly orm: MikroORM,
  ) {}
}
```

To inject all registered `MikroORM` instances as an array, use the `@InjectMikroORMs()` decorator.

#### Testing[#](/data/mikroorm#testing)

When unit testing an application, you usually want to avoid a database connection, which keeps test suites independent and fast. However, your classes might depend on repositories and the `EntityManager`. To resolve these classes, provide mock implementations using [custom providers](/fundamentals/custom-providers).

The `@mikro-orm/nestjs` package exposes a `getRepositoryToken()` function that returns a prepared injection token based on a given entity (e.g., `'PhotoRepository'` for the `Photo` entity), allowing you to mock the repository. For a custom repository, use its class as the token:

```typescript

import { Module } from '@nestjs/common';
import { getRepositoryToken } from '@mikro-orm/nestjs';
import { EntityManager } from '@mikro-orm/sqlite';
import { Photo } from './photo.entity.js';
import { PhotoService } from './photo.service.js';

@Module({
  providers: [
    PhotoService,
    {
      // or, for a custom repository: `provide: PhotoRepository`
      provide: getRepositoryToken(Photo),
      useValue: mockedRepository,
    },
    {
      provide: EntityManager,
      useValue: mockedEntityManager,
    },
  ],
})
export class PhotoModule {}
```

Now the `mockedRepository` object is injected wherever a class in this module asks for the `Photo` repository using the `@InjectRepository(Photo)` decorator. For [multiple databases](/data/mikroorm#multiple-databases), pass the context name as the second argument, e.g., `getRepositoryToken(Album, 'albums')`.

#### Async configuration[#](/data/mikroorm#async-configuration)

When you need to pass module options asynchronously instead of statically, use the `forRootAsync()` method. As with most dynamic modules, Nest provides several techniques for async configuration.

One technique is to use a factory function. Like other [factory providers](/fundamentals/custom-providers#factory-providers-usefactory), the factory function can be `async` and can inject dependencies through `inject`:

```typescript

MikroOrmModule.forRootAsync({
  imports: [ConfigModule],
  useFactory: (configService: ConfigService) => ({
    dbName: configService.getOrThrow<string>('DB_NAME'),
    autoLoadEntities: true,
    metadataProvider: ReflectMetadataProvider,
  }),
  inject: [ConfigService],
  driver: SqliteDriver,
});
```

> **Warning** Set the `driver` option next to `useFactory`, as shown above. The module needs to know the driver before it calls the factory, to register the driver-specific `EntityManager` and `MikroORM` classes as injection tokens. Without it, injecting the `EntityManager` from your driver package fails with a dependency resolution error.

Alternatively, you can configure the `MikroOrmModule` using a class instead of a factory, as shown below:

```typescript

MikroOrmModule.forRootAsync({
  useClass: MikroOrmConfigService,
  driver: SqliteDriver,
});
```

The construction above instantiates `MikroOrmConfigService` inside `MikroOrmModule`, using it to create the required options object. In this example, the `MikroOrmConfigService` has to implement the `MikroOrmOptionsFactory` interface, as shown below. The `MikroOrmModule` calls the `createMikroOrmOptions()` method on the instantiated object of the supplied class.

```typescript

import { Injectable } from '@nestjs/common';
import { MikroOrmModuleOptions, MikroOrmOptionsFactory } from '@mikro-orm/nestjs';
import { ReflectMetadataProvider } from '@mikro-orm/decorators/legacy';

@Injectable()
export class MikroOrmConfigService implements MikroOrmOptionsFactory {
  createMikroOrmOptions(): MikroOrmModuleOptions {
    return {
      dbName: 'my-db-name.sqlite3',
      autoLoadEntities: true,
      metadataProvider: ReflectMetadataProvider,
    };
  }
}
```

To reuse an existing options provider instead of creating a private copy inside the `MikroOrmModule`, use the `useExisting` syntax. The provider must implement the `MikroOrmOptionsFactory` interface, and a module listed in `imports` must export it:

```typescript

MikroOrmModule.forRootAsync({
  imports: [DatabaseConfigModule],
  useExisting: MikroOrmConfigService,
  driver: SqliteDriver,
});
```

#### Application shutdown[#](/data/mikroorm#application-shutdown)

The `MikroOrmModule` closes the ORM and its database connection in the `onApplicationShutdown()` lifecycle hook, which Nest calls when you call `app.close()`. By default, however, Nest doesn't listen for process termination signals such as `SIGTERM`, so the connection isn't closed when the process is terminated. To close it in that case too, enable [shutdown hooks](/fundamentals/lifecycle-events#application-shutdown):

```typescript

// main.ts
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module.js';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.enableShutdownHooks();
  await app.listen(process.env.PORT ?? 3000);
}
await bootstrap();
```

#### Example[#](/data/mikroorm#example)

For complete applications that use NestJS with MikroORM, see the [nestjs-realworld-example-app](https://github.com/mikro-orm/nestjs-realworld-example-app) and [nestjs-example-app](https://github.com/mikro-orm/nestjs-example-app) repositories.

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/data/mikroorm.md)

----
url: https://docs.nestjs.com/v10/microservices/basics
----

* [Overview](https://docs.nestjs.com/v10/microservices/basics#overview)
* [Installation](https://docs.nestjs.com/v10/microservices/basics#installation)
* [Getting started](https://docs.nestjs.com/v10/microservices/basics#getting-started)
* [Patterns](https://docs.nestjs.com/v10/microservices/basics#patterns)
* [Request-response](https://docs.nestjs.com/v10/microservices/basics#request-response)
* [Asynchronous responses](https://docs.nestjs.com/v10/microservices/basics#asynchronous-responses)
* [Event-based](https://docs.nestjs.com/v10/microservices/basics#event-based)
* [Decorators](https://docs.nestjs.com/v10/microservices/basics#decorators)
* [Client](https://docs.nestjs.com/v10/microservices/basics#client)
* [Sending messages](https://docs.nestjs.com/v10/microservices/basics#sending-messages)
* [Publishing events](https://docs.nestjs.com/v10/microservices/basics#publishing-events)
* [Scopes](https://docs.nestjs.com/v10/microservices/basics#scopes)
* [Handling timeouts](https://docs.nestjs.com/v10/microservices/basics#handling-timeouts)
* [TLS support](https://docs.nestjs.com/v10/microservices/basics#tls-support)

```bash

$ npm i --save @nestjs/microservices
```

#### Getting started[#](/microservices/basics#getting-started)

To instantiate a microservice, use the `createMicroservice()` method of the `NestFactory` class:

main.ts

JS TS

```typescript

import { NestFactory } from '@nestjs/core';
import { Transport, MicroserviceOptions } from '@nestjs/microservices';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.createMicroservice<MicroserviceOptions>(
    AppModule,
    {
      transport: Transport.TCP,
    },
  );
  await app.listen();
}
bootstrap();
```

```typescript

import { NestFactory } from '@nestjs/core';
import { Transport } from '@nestjs/microservices';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.createMicroservice(AppModule, {
    transport: Transport.TCP,
  });
  await app.listen();
}
bootstrap();
```

> **Hint** Microservices use the **TCP** transport layer by default.

The second argument of the `createMicroservice()` method is an `options` object. This object may consist of two members:

|             |                                                                            |
| ----------- | -------------------------------------------------------------------------- |
| `transport` | Specifies the transporter (for example, `Transport.NATS`)                  |
| `options`   | A transporter-specific options object that determines transporter behavior |

The `options` object is specific to the chosen transporter. The **TCP** transporter exposes the properties described below. For other transporters (e.g, Redis, MQTT, etc.), see the relevant chapter for a description of the available options.

|                 |                                                                                                                                                     |
| --------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| `host`          | Connection hostname                                                                                                                                 |
| `port`          | Connection port                                                                                                                                     |
| `retryAttempts` | Number of times to retry message (default: `0`)                                                                                                     |
| `retryDelay`    | Delay between message retry attempts (ms) (default: `0`)                                                                                            |
| `serializer`    | Custom [serializer](https://github.com/nestjs/nest/blob/master/packages/microservices/interfaces/serializer.interface.ts) for outcoming messages    |
| `deserializer`  | Custom [deserializer](https://github.com/nestjs/nest/blob/master/packages/microservices/interfaces/deserializer.interface.ts) for incoming messages |
| `socketClass`   | A custom Socket that extends `TcpSocket` (default: `JsonSocket`)                                                                                    |
| `tlsOptions`    | Options to configure the tls protocol                                                                                                               |

```typescript

import { Controller } from '@nestjs/common';
import { MessagePattern } from '@nestjs/microservices';

@Controller()
export class MathController {
  @MessagePattern({ cmd: 'sum' })
  accumulate(data: number[]): number {
    return (data || []).reduce((a, b) => a + b);
  }
}
```

```typescript

import { Controller } from '@nestjs/common';
import { MessagePattern } from '@nestjs/microservices';

@Controller()
export class MathController {
  @MessagePattern({ cmd: 'sum' })
  accumulate(data) {
    return (data || []).reduce((a, b) => a + b);
  }
}
```

In the above code, the `accumulate()`**message handler** listens for messages that fulfill the `{ cmd: 'sum' }` message pattern. The message handler takes a single argument, the `data` passed from the client. In this case, the data is an array of numbers which are to be accumulated.

#### Asynchronous responses[#](/microservices/basics#asynchronous-responses)

Message handlers are able to respond either synchronously or **asynchronously**. Hence, `async` methods are supported.

JS TS

```typescript

@MessagePattern({ cmd: 'sum' })
async accumulate(data: number[]): Promise<number> {
  return (data || []).reduce((a, b) => a + b);
}
```

```typescript

@MessagePattern({ cmd: 'sum' })
async accumulate(data) {
  return (data || []).reduce((a, b) => a + b);
}
```

A message handler is also able to return an `Observable`, in which case the result values will be emitted until the stream is completed.

JS TS

```typescript

@MessagePattern({ cmd: 'sum' })
accumulate(data: number[]): Observable<number> {
  return from([1, 2, 3]);
}
```

```typescript

@MessagePattern({ cmd: 'sum' })
accumulate(data: number[]): Observable<number> {
  return from([1, 2, 3]);
}
```

In the example above, the message handler will respond **3 times** (with each item from the array).

#### Event-based[#](/microservices/basics#event-based)

While the request-response method is ideal for exchanging messages between services, it is less suitable when your message style is event-based - when you just want to publish **events** without waiting for a response. In that case, you do not want the overhead required by request-response for maintaining two channels.

Suppose you would like to simply notify another service that a certain condition has occurred in this part of the system. This is the ideal use case for the event-based message style.

To create an event handler, we use the `@EventPattern()` decorator, which is imported from the `@nestjs/microservices` package.

JS TS

```typescript

@EventPattern('user_created')
async handleUserCreated(data: Record<string, unknown>) {
  // business logic
}
```

```typescript

@EventPattern('user_created')
async handleUserCreated(data) {
  // business logic
}
```

> **Hint** You can register multiple event handlers for a **single** event pattern and all of them will be automatically triggered in parallel.

```typescript

@MessagePattern('time.us.*')
getDate(@Payload() data: number[], @Ctx() context: NatsContext) {
  console.log(`Subject: ${context.getSubject()}`); // e.g. "time.us.east"
  return new Date().toLocaleTimeString(...);
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('time.us.*')
getDate(data, context) {
  console.log(`Subject: ${context.getSubject()}`); // e.g. "time.us.east"
  return new Date().toLocaleTimeString(...);
}
```

> **Hint**`@Payload()`, `@Ctx()` and `NatsContext` are imported from `@nestjs/microservices`.

> **Hint** You can also pass in a property key to the `@Payload()` decorator to extract a specific property from the incoming payload object, for example, `@Payload('id')`.

#### Client[#](/microservices/basics#client)

A client Nest application can exchange messages or publish events to a Nest microservice using the `ClientProxy` class. This class defines several methods, such as `send()` (for request-response messaging) and `emit()` (for event-driven messaging) that let you communicate with a remote microservice. Obtain an instance of this class in one of the following ways.

One technique is to import the `ClientsModule`, which exposes the static `register()` method. This method takes an argument which is an array of objects representing microservice transporters. Each such object has a `name` property, an optional `transport` property (default is `Transport.TCP`), and an optional transporter-specific `options` property.

The `name` property serves as an **injection token** that can be used to inject an instance of a `ClientProxy` where needed. The value of the `name` property, as an injection token, can be an arbitrary string or JavaScript symbol, as described [here](https://docs.nestjs.com/fundamentals/custom-providers#non-class-based-provider-tokens).

The `options` property is an object that contains the same properties we saw in the `createMicroservice()` method earlier.

```typescript

@Module({
  imports: [
    ClientsModule.register([
      { name: 'MATH_SERVICE', transport: Transport.TCP },
    ]),
  ],
})
```

Alternatively, you can use the `registerAsync()` method if you need to pass in configuration or perform any other asynchronous processes.

```typescript

@Module({
  imports: [
    ClientsModule.registerAsync([
      {
        imports: [ConfigModule],
        name: 'MATH_SERVICE',
        useFactory: async (configService: ConfigService) => ({
          transport: Transport.TCP,
          options: {
            url: configService.get('URL'),
          },
        }),
        inject: [ConfigService],
      },
    ]),
  ],
})
```

Once the module has been imported, you can inject an instance of the `ClientProxy` configured with the specified options for the `'MATH_SERVICE'` transporter using the `@Inject()` decorator.

```typescript

constructor(
  @Inject('MATH_SERVICE') private client: ClientProxy,
) {}
```

> **Hint** The `ClientsModule` and `ClientProxy` classes are imported from the `@nestjs/microservices` package.

At times we may need to fetch the transporter configuration from another service (say a `ConfigService`), rather than hard-coding it in our client application. To do this, we can register a [custom provider](/v10/fundamentals/custom-providers) using the `ClientProxyFactory` class. This class has a static `create()` method, which accepts a transporter options object, and returns a customized `ClientProxy` instance.

```typescript

@Module({
  providers: [
    {
      provide: 'MATH_SERVICE',
      useFactory: (configService: ConfigService) => {
        const mathSvcOptions = configService.getMathSvcOptions();
        return ClientProxyFactory.create(mathSvcOptions);
      },
      inject: [ConfigService],
    }
  ]
  ...
})
```

> **Hint** The `ClientProxyFactory` is imported from the `@nestjs/microservices` package.

Another option is to use the `@Client()` property decorator.

```typescript

@Client({ transport: Transport.TCP })
client: ClientProxy;
```

> **Hint** The `@Client()` decorator is imported from the `@nestjs/microservices` package.

Using the `@Client()` decorator is not the preferred technique, as it is harder to test and harder to share a client instance.

The `ClientProxy` is **lazy**. It doesn't initiate a connection immediately. Instead, it will be established before the first microservice call, and then reused across each subsequent call. However, if you want to delay the application bootstrapping process until a connection is established, you can manually initiate a connection using the `ClientProxy` object's `connect()` method inside the `OnApplicationBootstrap` lifecycle hook.

JS TS

```typescript

async onApplicationBootstrap() {
  await this.client.connect();
}
```

If the connection cannot be created, the `connect()` method will reject with the corresponding error object.

#### Sending messages[#](/microservices/basics#sending-messages)

The `ClientProxy` exposes a `send()` method. This method is intended to call the microservice and returns an `Observable` with its response. Thus, we can subscribe to the emitted values easily.

JS TS

```typescript

accumulate(): Observable<number> {
  const pattern = { cmd: 'sum' };
  const payload = [1, 2, 3];
  return this.client.send<number>(pattern, payload);
}
```

```typescript

accumulate() {
  const pattern = { cmd: 'sum' };
  const payload = [1, 2, 3];
  return this.client.send(pattern, payload);
}
```

The `send()` method takes two arguments, `pattern` and `payload`. The `pattern` should match one defined in a `@MessagePattern()` decorator. The `payload` is a message that we want to transmit to the remote microservice. This method returns a **cold `Observable`**, which means that you have to explicitly subscribe to it before the message will be sent.

#### Publishing events[#](/microservices/basics#publishing-events)

To send an event, use the `ClientProxy` object's `emit()` method. This method publishes an event to the message broker.

JS TS

```typescript

async publish() {
  this.client.emit<number>('user_created', new UserCreatedEvent());
}
```

```typescript

async publish() {
  this.client.emit('user_created', new UserCreatedEvent());
}
```

The `emit()` method takes two arguments, `pattern` and `payload`. The `pattern`should match one defined in an `@EventPattern()` decorator. The `payload` is an event payload that we want to transmit to the remote microservice. This method returns a **hot `Observable`** (unlike the cold `Observable` returned by `send()`), which means that whether or not you explicitly subscribe to the observable, the proxy will immediately try to deliver the event.

## Explore your graph with NestJS Devtools

* Graph visualizer
* Routes navigator
* Interactive playground
* CI/CD integration

[Sign up](https://devtools.nestjs.com "Devtools | NestJS - A node.js framework built on top of TypeScript")

#### Scopes[#](/microservices/basics#scopes)

For people coming from different programming language backgrounds, it might be unexpected to learn that in Nest, almost everything is shared across incoming requests. We have a connection pool to the database, singleton services with global state, etc. Remember that Node.js doesn't follow the request/response Multi-Threaded Stateless Model in which every request is processed by a separate thread. Hence, using singleton instances is fully **safe** for our applications.

However, there are edge-cases when request-based lifetime of the handler may be the desired behavior, for instance per-request caching in GraphQL applications, request tracking or multi-tenancy. Learn how to control scopes [here](/v10/fundamentals/injection-scopes).

Request-scoped handlers and providers can inject `RequestContext` using the `@Inject()` decorator in combination with `CONTEXT` token:

```typescript

import { Injectable, Scope, Inject } from '@nestjs/common';
import { CONTEXT, RequestContext } from '@nestjs/microservices';

@Injectable({ scope: Scope.REQUEST })
export class CatsService {
  constructor(@Inject(CONTEXT) private ctx: RequestContext) {}
}
```

This provides access to the `RequestContext` object, which has two properties:

```typescript

export interface RequestContext<T = any> {
  pattern: string | Record<string, any>;
  data: T;
}
```

The `data` property is the message payload sent by the message producer. The `pattern` property is the pattern used to identify an appropriate handler to handle the incoming message.

#### Handling timeouts[#](/microservices/basics#handling-timeouts)

In distributed systems, sometimes microservices might be down or not available. To avoid infinitely long waiting, you can use Timeouts. A timeout is an incredibly useful pattern when communicating with other services. To apply timeouts to your microservice calls, you can use the [RxJS](https://rxjs.dev)`timeout` operator. If the microservice does not respond to the request within a certain time, an exception is thrown, which can be caught and handled appropriately.

To solve this problem you have to use [`rxjs`](https://github.com/ReactiveX/rxjs) package. Just use the `timeout` operator in the pipe:

JS TS

```typescript

this.client
      .send<TResult, TInput>(pattern, data)
      .pipe(timeout(5000));
```

```typescript

this.client
      .send(pattern, data)
      .pipe(timeout(5000));
```

> **Hint** The `timeout` operator is imported from the `rxjs/operators` package.

After 5 seconds, if the microservice isn't responding, it will throw an error.

#### TLS support[#](/microservices/basics#tls-support)

When communicating outside of a private network, it’s important to encrypt traffic to ensure security. In NestJS, this can be achieved with TLS over TCP using Node's built-in [TLS](https://nodejs.org/api/tls.html) module. Nest provides built-in support for TLS in its TCP transport, allowing us to encrypt communication between microservices or clients.

To enable TLS for a TCP server, you'll need both a private key and a certificate in PEM format. These are added to the server's options by setting the `tlsOptions` and specifying the key and cert files, as shown below:

```typescript

import * as fs from 'fs';
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { MicroserviceOptions, Transport } from '@nestjs/microservices';

async function bootstrap() {
  const key = fs.readFileSync('<pathToKeyFile>', 'utf8').toString();
  const cert = fs.readFileSync('<pathToCertFile>', 'utf8').toString();

  const app = await NestFactory.createMicroservice<MicroserviceOptions>(
    AppModule,
    {
      transport: Transport.TCP,
      options: {
        tlsOptions: {
          key,
          cert,
        },
      },
    },
  );

  await app.listen();
}
bootstrap();
```

For a client to communicate securely over TLS, we also define the `tlsOptions` object but this time with the CA certificate. This is the certificate of the authority that signed the server's certificate. This ensures that the client trusts the server's certificate and can establish a secure connection.

```typescript

import { Module } from '@nestjs/common';
import { ClientsModule, Transport } from '@nestjs/microservices';

@Module({
  imports: [
    ClientsModule.register([
      {
        name: 'MATH_SERVICE',
        transport: Transport.TCP,
        options: {
          tlsOptions: {
            ca: [fs.readFileSync('<pathToCaFile>', 'utf-8').toString()],
          },
        },
      },
    ]),
  ],
})
export class AppModule {}
```

You can also pass an array of CAs if your setup involves multiple trusted authorities.

Once everything is set up, you can inject the `ClientProxy` as usual using the `@Inject()` decorator to use the client in your services. This ensures encrypted communication across your NestJS microservices, with Node's `TLS` module handling the encryption details.

For more information, refer to Node’s [TLS documentation](https://nodejs.org/api/tls.html).

----
url: https://docs.nestjs.com/v7/techniques/mongodb
----

* [Mongo](https://docs.nestjs.com/v7/techniques/mongodb#mongo)
* [Model injection](https://docs.nestjs.com/v7/techniques/mongodb#model-injection)
* [Connection](https://docs.nestjs.com/v7/techniques/mongodb#connection)
* [Multiple databases](https://docs.nestjs.com/v7/techniques/mongodb#multiple-databases)
* [Hooks (middleware)](https://docs.nestjs.com/v7/techniques/mongodb#hooks-middleware)
* [Plugins](https://docs.nestjs.com/v7/techniques/mongodb#plugins)
* [Discriminators](https://docs.nestjs.com/v7/techniques/mongodb#discriminators)
* [Testing](https://docs.nestjs.com/v7/techniques/mongodb#testing)
* [Async configuration](https://docs.nestjs.com/v7/techniques/mongodb#async-configuration)
* [Example](https://docs.nestjs.com/v7/techniques/mongodb#example)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/techniques/mongo.md "Suggest Edits")

### Mongo

Nest supports two methods for integrating with the [MongoDB](https://www.mongodb.com/) database. You can either use the built-in [TypeORM](https://github.com/typeorm/typeorm) module described [here](/v7/techniques/database), which has a connector for MongoDB, or use [Mongoose](https://mongoosejs.com), the most popular MongoDB object modeling tool. In this chapter we'll describe the latter, using the dedicated `@nestjs/mongoose` package.

Start by installing the required dependencies:

```bash

$ npm install --save @nestjs/mongoose mongoose
```

Once the installation process is complete, we can import the `MongooseModule` into the root `AppModule`.

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';

@Module({
  imports: [MongooseModule.forRoot('mongodb://localhost/nest')],
})
export class AppModule {}
```

```typescript

import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
import { Document } from 'mongoose';

export type CatDocument = Cat & Document;

@Schema()
export class Cat {
  @Prop()
  name: string;

  @Prop()
  age: number;

  @Prop()
  breed: string;
}

export const CatSchema = SchemaFactory.createForClass(Cat);
```

> **Hint** Note you can also generate a raw schema definition using the `DefinitionsFactory` class (from the `nestjs/mongoose`). This allows you to manually modify the schema definition generated based on the metadata you provided. This is useful for certain edge-cases where it may be hard to represent everything with decorators.

The `@Schema()` decorator marks a class as a schema definition. It maps our `Cat` class to a MongoDB collection of the same name, but with an additional “s” at the end - so the final mongo collection name will be `cats`. This decorator accepts a single optional argument which is a schema options object. Think of it as the object you would normally pass as a second argument of the `mongoose.Schema` class' constructor (e.g., `new mongoose.Schema(_, options)`)). To learn more about available schema options, see [this](https://mongoosejs.com/docs/guide.html#options) chapter.

The `@Prop()` decorator defines a property in the document. For example, in the schema definition above, we defined three properties: `name`, `age`, and `breed`. The [schema types](https://mongoosejs.com/docs/schematypes.html) for these properties are automatically inferred thanks to TypeScript metadata (and reflection) capabilities. However, in more complex scenarios in which types cannot be implicitly reflected (for example, arrays or nested object structures), types must be indicated explicitly, as follows:

```typescript

@Prop([String])
tags: string[];
```

Alternatively, the `@Prop()` decorator accepts an options object argument ([read more](https://mongoosejs.com/docs/schematypes.html#schematype-options) about the available options). With this, you can indicate whether a property is required or not, specify a default value, or mark it as immutable. For example:

```typescript

@Prop({ required: true })
name: string;
```

In case you want to specify relation to another model, later for populating, you can use `@Prop()` decorator as well. For example, if `Cat` has `Owner` which is stored in a different collection called `owners`, the property should have type and ref. For example:

```typescript

import * as mongoose from 'mongoose';
import { Owner } from '../owners/schemas/owner.schema';

// inside the class definition
@Prop({ type: mongoose.Schema.Types.ObjectId, ref: 'Owner' })
owner: Owner;
```

In case there are multiple owners, your property configuration should look as follows:

```typescript

@Prop({ type: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Owner' }] })
owner: Owner[];
```

Finally, the **raw** schema definition can also be passed to the decorator. This is useful when, for example, a property represents a nested object which is not defined as a class. For this, use the `raw()` function from the `@nestjs/mongoose` package, as follows:

```typescript

@Prop(raw({
  firstName: { type: String },
  lastName: { type: String }
}))
details: Record<string, any>;
```

Alternatively, if you prefer **not using decorators**, you can define a schema manually. For example:

```typescript

export const CatSchema = new mongoose.Schema({
  name: String,
  age: Number,
  breed: String,
});
```

The `cat.schema` file resides in a folder in the `cats` directory, where we also define the `CatsModule`. While you can store schema files wherever you prefer, we recommend storing them near their related **domain** objects, in the appropriate module directory.

Let's look at the `CatsModule`:

cats.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';
import { Cat, CatSchema } from './schemas/cat.schema';

@Module({
  imports: [MongooseModule.forFeature([{ name: Cat.name, schema: CatSchema }])],
  controllers: [CatsController],
  providers: [CatsService],
})
export class CatsModule {}
```

The `MongooseModule` provides the `forFeature()` method to configure the module, including defining which models should be registered in the current scope. If you also want to use the models in another module, add MongooseModule to the `exports` section of `CatsModule` and import `CatsModule` in the other module.

Once you've registered the schema, you can inject a `Cat` model into the `CatsService` using the `@InjectModel()` decorator:

cats.service.ts

JS TS

```typescript

import { Model } from 'mongoose';
import { Injectable } from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import { Cat, CatDocument } from './schemas/cat.schema';
import { CreateCatDto } from './dto/create-cat.dto';

@Injectable()
export class CatsService {
  constructor(@InjectModel(Cat.name) private catModel: Model<CatDocument>) {}

  async create(createCatDto: CreateCatDto): Promise<Cat> {
    const createdCat = new this.catModel(createCatDto);
    return createdCat.save();
  }

  async findAll(): Promise<Cat[]> {
    return this.catModel.find().exec();
  }
}
```

```typescript

import { Model } from 'mongoose';
import { Injectable, Dependencies } from '@nestjs/common';
import { getModelToken } from '@nestjs/mongoose';
import { Cat } from './schemas/cat.schema';

@Injectable()
@Dependencies(getModelToken(Cat.name))
export class CatsService {
  constructor(catModel) {
    this.catModel = catModel;
  }

  async create(createCatDto) {
    const createdCat = new this.catModel(createCatDto);
    return createdCat.save();
  }

  async findAll() {
    return this.catModel.find().exec();
  }
}
```

#### Connection[#](/techniques/mongodb#connection)

At times you may need to access the native [Mongoose Connection](https://mongoosejs.com/docs/api.html#Connection) object. For example, you may want to make native API calls on the connection object. You can inject the Mongoose Connection by using the `@InjectConnection()` decorator as follows:

```typescript

import { Injectable } from '@nestjs/common';
import { InjectConnection } from '@nestjs/mongoose';
import { Connection } from 'mongoose';

@Injectable()
export class CatsService {
  constructor(@InjectConnection() private connection: Connection) {}
}
```

#### Multiple databases[#](/techniques/mongodb#multiple-databases)

Some projects require multiple database connections. This can also be achieved with this module. To work with multiple connections, first create the connections. In this case, connection naming becomes **mandatory**.

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';

@Module({
  imports: [
    MongooseModule.forRoot('mongodb://localhost/test', {
      connectionName: 'cats',
    }),
    MongooseModule.forRoot('mongodb://localhost/users', {
      connectionName: 'users',
    }),
  ],
})
export class AppModule {}
```

> **Notice** Please note that you shouldn't have multiple connections without a name, or with the same name, otherwise they will get overridden.

With this setup, you have to tell the `MongooseModule.forFeature()` function which connection should be used.

```typescript

@Module({
  imports: [
    MongooseModule.forFeature([{ name: Cat.name, schema: CatSchema }], 'cats'),
  ],
})
export class AppModule {}
```

You can also inject the `Connection` for a given connection:

```typescript

import { Injectable } from '@nestjs/common';
import { InjectConnection } from '@nestjs/mongoose';
import { Connection } from 'mongoose';

@Injectable()
export class CatsService {
  constructor(@InjectConnection('cats') private connection: Connection) {}
}
```

To inject a given `Connection` to a custom provider (for example, factory provider), use the `getConnectionToken()` function passing the name of the connection as an argument.

```typescript

{
  provide: CatsService,
  useFactory: (catsConnection: Connection) => {
    return new CatsService(catsConnection);
  },
  inject: [getConnectionToken('cats')],
}
```

#### Hooks (middleware)[#](/techniques/mongodb#hooks-middleware)

Middleware (also called pre and post hooks) are functions which are passed control during execution of asynchronous functions. Middleware is specified on the schema level and is useful for writing plugins ([source](https://mongoosejs.com/docs/middleware.html)). Calling `pre()` or `post()` after compiling a model does not work in Mongoose. To register a hook **before** model registration, use the `forFeatureAsync()` method of the `MongooseModule` along with a factory provider (i.e., `useFactory`). With this technique, you can access a schema object, then use the `pre()` or `post()` method to register a hook on that schema. See example below:

```typescript

@Module({
  imports: [
    MongooseModule.forFeatureAsync([
      {
        name: Cat.name,
        useFactory: () => {
          const schema = CatsSchema;
          schema.pre('save', function() { console.log('Hello from pre save') });
          return schema;
        },
      },
    ]),
  ],
})
export class AppModule {}
```

Like other [factory providers](https://docs.nestjs.com/fundamentals/custom-providers#factory-providers-usefactory), our factory function can be `async` and can inject dependencies through `inject`.

```typescript

@Module({
  imports: [
    MongooseModule.forFeatureAsync([
      {
        name: Cat.name,
        imports: [ConfigModule],
        useFactory: (configService: ConfigService) => {
          const schema = CatsSchema;
          schema.pre('save', function() {
            console.log(
              `${configService.get('APP_NAME')}: Hello from pre save`,
            ),
          });
          return schema;
        },
        inject: [ConfigService],
      },
    ]),
  ],
})
export class AppModule {}
```

#### Plugins[#](/techniques/mongodb#plugins)

To register a [plugin](https://mongoosejs.com/docs/plugins.html) for a given schema, use the `forFeatureAsync()` method.

```typescript

@Module({
  imports: [
    MongooseModule.forFeatureAsync([
      {
        name: Cat.name,
        useFactory: () => {
          const schema = CatsSchema;
          schema.plugin(require('mongoose-autopopulate'));
          return schema;
        },
      },
    ]),
  ],
})
export class AppModule {}
```

To register a plugin for all schemas at once, call the `.plugin()` method of the `Connection` object. You should access the connection before models are created; to do this, use the `connectionFactory`:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';

@Module({
  imports: [
    MongooseModule.forRoot('mongodb://localhost/test', {
      connectionFactory: (connection) => {
        connection.plugin(require('mongoose-autopopulate'));
        return connection;
      }
    }),
  ],
})
export class AppModule {}
```

#### Discriminators[#](/techniques/mongodb#discriminators)

[Discriminators](https://mongoosejs.com/docs/discriminators.html) are a schema inheritance mechanism. They enable you to have multiple models with overlapping schemas on top of the same underlying MongoDB collection.

Suppose you wanted to track different types of events in a single collection. Every event will have a timestamp.

event.schema.ts

JS TS

```typescript

@Schema({ discriminatorKey: 'kind' })
export class Event {
  @Prop({
    type: String,
    required: true,
    enum: [ClickedLinkEvent.name, SignUpEvent.name],
  })
  kind: string;

  @Prop({ type: Date, required: true })
  time: Date;
}

export const EventSchema = SchemaFactory.createForClass(Event);
```

> **Hint** The way mongoose tells the difference between the different discriminator models is by the "discriminator key", which is `__t` by default. Mongoose adds a String path called `__t` to your schemas that it uses to track which discriminator this document is an instance of. You may also use the `discriminatorKey` option to define the path for discrimination.

`SignedUpEvent` and `ClickedLinkEvent` instances will be stored in the same collection as generic events.

Now, let's define the `ClickedLinkEvent` class, as follows:

click-link-event.schema.ts

JS TS

```typescript

@Schema()
export class ClickedLinkEvent {
  kind: string;
  time: Date;

  @Prop({ type: String, required: true })
  url: string;
}

export const ClickedLinkEventSchema = SchemaFactory.createForClass(ClickedLinkEvent);
```

And `SignUpEvent` class:

sign-up-event.schema.ts

JS TS

```typescript

@Schema()
export class SignUpEvent {
  kind: string;
  time: Date;

  @Prop({ type: String, required: true })
  user: string;
}

export const SignUpEventSchema = SchemaFactory.createForClass(SignUpEvent);
```

With this in place, use the `discriminators` option to register a discriminator for a given schema. It works on both `MongooseModule.forFeature` and `MongooseModule.forFeatureAsync`:

event.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';

@Module({
  imports: [
    MongooseModule.forFeature([
      {
        name: Event.name,
        schema: EventSchema,
        discriminators: [
          { name: ClickedLinkEvent.name, schema: ClickedLinkEventSchema },
          { name: SignUpEvent.name, schema: SignUpEventSchema },
        ],
      },
    ]),
  ]
})
export class EventsModule {}
```

#### Testing[#](/techniques/mongodb#testing)

When unit testing an application, we usually want to avoid any database connection, making our test suites simpler to set up and faster to execute. But our classes might depend on models that are pulled from the connection instance. How do we resolve these classes? The solution is to create mock models.

To make this easier, the `@nestjs/mongoose` package exposes a `getModelToken()` function that returns a prepared [injection token](https://docs.nestjs.com/fundamentals/custom-providers#di-fundamentals) based on a token name. Using this token, you can easily provide a mock implementation using any of the standard [custom provider](/v7/fundamentals/custom-providers) techniques, including `useClass`, `useValue`, and `useFactory`. For example:

```typescript

@Module({
  providers: [
    CatsService,
    {
      provide: getModelToken(Cat.name),
      useValue: catModel,
    },
  ],
})
export class CatsModule {}
```

```typescript

MongooseModule.forRootAsync({
  useFactory: () => ({
    uri: 'mongodb://localhost/nest',
  }),
});
```

Like other [factory providers](https://docs.nestjs.com/fundamentals/custom-providers#factory-providers-usefactory), our factory function can be `async` and can inject dependencies through `inject`.

```typescript

MongooseModule.forRootAsync({
  imports: [ConfigModule],
  useFactory: async (configService: ConfigService) => ({
    uri: configService.get<string>('MONGODB_URI'),
  }),
  inject: [ConfigService],
});
```

Alternatively, you can configure the `MongooseModule` using a class instead of a factory, as shown below:

```typescript

MongooseModule.forRootAsync({
  useClass: MongooseConfigService,
});
```

The construction above instantiates `MongooseConfigService` inside `MongooseModule`, using it to create the required options object. Note that in this example, the `MongooseConfigService` has to implement the `MongooseOptionsFactory` interface, as shown below. The `MongooseModule` will call the `createMongooseOptions()` method on the instantiated object of the supplied class.

```typescript

@Injectable()
class MongooseConfigService implements MongooseOptionsFactory {
  createMongooseOptions(): MongooseModuleOptions {
    return {
      uri: 'mongodb://localhost/nest',
    };
  }
}
```

If you want to reuse an existing options provider instead of creating a private copy inside the `MongooseModule`, use the `useExisting` syntax.

```typescript

MongooseModule.forRootAsync({
  imports: [ConfigModule],
  useExisting: ConfigService,
});
```

#### Example[#](/techniques/mongodb#example)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/06-mongoose).

----
url: https://docs.nestjs.com/v8/openapi/other-features
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Other features](https://docs.nestjs.com/v8/openapi/other-features#other-features)
* [Global prefix](https://docs.nestjs.com/v8/openapi/other-features#global-prefix)
* [Multiple specifications](https://docs.nestjs.com/v8/openapi/other-features#multiple-specifications)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/openapi/other-features.md "Suggest Edits")

### Other features

This page lists all the other available features that you may find useful.

#### Global prefix[#](/openapi/other-features#global-prefix)

To ignore a global prefix for routes set through `setGlobalPrefix()`, use `ignoreGlobalPrefix`:

```typescript

const document = SwaggerModule.createDocument(app, options, {
  ignoreGlobalPrefix: true,
});
```

#### Multiple specifications[#](/openapi/other-features#multiple-specifications)

The `SwaggerModule` provides a way to support multiple specifications. In other words, you can serve different documentation, with different UIs, on different endpoints.

To support multiple specifications, your application must be written with a modular approach. The `createDocument()` method takes a 3rd argument, `extraOptions`, which is an object with a property named `include`. The `include` property takes a value which is an array of modules.

You can setup multiple specifications support as shown below:

```typescript

import { NestFactory } from '@nestjs/core';
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
import { AppModule } from './app.module';
import { CatsModule } from './cats/cats.module';
import { DogsModule } from './dogs/dogs.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);

  /**
   * createDocument(application, configurationOptions, extraOptions);
   *
   * createDocument method takes an optional 3rd argument "extraOptions"
   * which is an object with "include" property where you can pass an Array
   * of Modules that you want to include in that Swagger Specification
   * E.g: CatsModule and DogsModule will have two separate Swagger Specifications which
   * will be exposed on two different SwaggerUI with two different endpoints.
   */

  const options = new DocumentBuilder()
    .setTitle('Cats example')
    .setDescription('The cats API description')
    .setVersion('1.0')
    .addTag('cats')
    .build();

  const catDocument = SwaggerModule.createDocument(app, options, {
    include: [CatsModule],
  });
  SwaggerModule.setup('api/cats', app, catDocument);

  const secondOptions = new DocumentBuilder()
    .setTitle('Dogs example')
    .setDescription('The dogs API description')
    .setVersion('1.0')
    .addTag('dogs')
    .build();

  const dogDocument = SwaggerModule.createDocument(app, secondOptions, {
    include: [DogsModule],
  });
  SwaggerModule.setup('api/dogs', app, dogDocument);

  await app.listen(3000);
}
bootstrap();
```

Now you can start your server with the following command:

```bash

$ npm run start
```

Navigate to `http://localhost:3000/api/cats` to see the Swagger UI for cats:

In turn, `http://localhost:3000/api/dogs` will expose the Swagger UI for dogs:

----
url: https://docs.nestjs.com/v10/fundamentals/async-providers
----

* [Asynchronous providers](https://docs.nestjs.com/v10/fundamentals/async-providers#asynchronous-providers)
* [Injection](https://docs.nestjs.com/v10/fundamentals/async-providers#injection)
* [Example](https://docs.nestjs.com/v10/fundamentals/async-providers#example)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/fundamentals/async-components.md "Suggest Edits")

### Asynchronous providers

At times, the application start should be delayed until one or more **asynchronous tasks** are completed. For example, you may not want to start accepting requests until the connection with the database has been established. You can achieve this using asynchronous providers.

The syntax for this is to use `async/await` with the `useFactory` syntax. The factory returns a `Promise`, and the factory function can `await` asynchronous tasks. Nest will await resolution of the promise before instantiating any class that depends on (injects) such a provider.

```typescript

{
  provide: 'ASYNC_CONNECTION',
  useFactory: async () => {
    const connection = await createConnection(options);
    return connection;
  },
}
```

> **Hint** Learn more about custom provider syntax [here](/v10/fundamentals/custom-providers).

#### Injection[#](/fundamentals/async-providers#injection)

Asynchronous providers are injected to other components by their tokens, like any other provider. In the example above, you would use the construct `@Inject('ASYNC_CONNECTION')`.

#### Example[#](/fundamentals/async-providers#example)

[The TypeORM recipe](/v10/recipes/sql-typeorm) has a more substantial example of an asynchronous provider.

----
url: https://docs.nestjs.com/v10/websockets/adapter
----

* [Adapters](https://docs.nestjs.com/v10/websockets/adapter#adapters)
* [Extend socket.io](https://docs.nestjs.com/v10/websockets/adapter#extend-socketio)
* [Ws library](https://docs.nestjs.com/v10/websockets/adapter#ws-library)
* [Advanced (custom adapter)](https://docs.nestjs.com/v10/websockets/adapter#advanced-custom-adapter)
* [Example](https://docs.nestjs.com/v10/websockets/adapter#example)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/websockets/adapter.md "Suggest Edits")

### Adapters

The WebSockets module is platform-agnostic, hence, you can bring your own library (or even a native implementation) by making use of `WebSocketAdapter` interface. This interface forces to implement few methods described in the following table:

|                        |                                                                 |
| ---------------------- | --------------------------------------------------------------- |
| `create`               | Creates a socket instance based on passed arguments             |
| `bindClientConnect`    | Binds the client connection event                               |
| `bindClientDisconnect` | Binds the client disconnection event (optional\*)               |
| `bindMessageHandlers`  | Binds the incoming message to the corresponding message handler |
| `close`                | Terminates a server instance                                    |

#### Extend socket.io[#](/websockets/adapter#extend-socketio)

The [socket.io](https://github.com/socketio/socket.io) package is wrapped in an `IoAdapter` class. What if you would like to enhance the basic functionality of the adapter? For instance, your technical requirements require a capability to broadcast events across multiple load-balanced instances of your web service. For this, you can extend `IoAdapter` and override a single method which responsibility is to instantiate new socket.io servers. But first of all, let's install the required package.

> **Warning** To use socket.io with multiple load-balanced instances you either have to disable polling by setting `transports: ['websocket']` in your clients socket.io configuration or you have to enable cookie based routing in your load balancer. Redis alone is not enough. See [here](https://socket.io/docs/v4/using-multiple-nodes/#enabling-sticky-session) for more information.

```bash

$ npm i --save redis socket.io @socket.io/redis-adapter
```

Once the package is installed, we can create a `RedisIoAdapter` class.

```typescript

import { IoAdapter } from '@nestjs/platform-socket.io';
import { ServerOptions } from 'socket.io';
import { createAdapter } from '@socket.io/redis-adapter';
import { createClient } from 'redis';

export class RedisIoAdapter extends IoAdapter {
  private adapterConstructor: ReturnType<typeof createAdapter>;

  async connectToRedis(): Promise<void> {
    const pubClient = createClient({ url: `redis://localhost:6379` });
    const subClient = pubClient.duplicate();

    await Promise.all([pubClient.connect(), subClient.connect()]);

    this.adapterConstructor = createAdapter(pubClient, subClient);
  }

  createIOServer(port: number, options?: ServerOptions): any {
    const server = super.createIOServer(port, options);
    server.adapter(this.adapterConstructor);
    return server;
  }
}
```

Afterward, simply switch to your newly created Redis adapter.

```typescript

const app = await NestFactory.create(AppModule);
const redisIoAdapter = new RedisIoAdapter(app);
await redisIoAdapter.connectToRedis();

app.useWebSocketAdapter(redisIoAdapter);
```

#### Ws library[#](/websockets/adapter#ws-library)

Another available adapter is a `WsAdapter` which in turn acts like a proxy between the framework and integrate blazing fast and thoroughly tested [ws](https://github.com/websockets/ws) library. This adapter is fully compatible with native browser WebSockets and is far faster than socket.io package. Unluckily, it has significantly fewer functionalities available out-of-the-box. In some cases, you don't necessarily need them though.

> **Hint**`ws` library does not support namespaces (communication channels popularised by `socket.io`). However, to somehow mimic this feature, you can mount multiple `ws` servers on different paths (example: `@WebSocketGateway({ path: '/users' })`).

In order to use `ws`, we firstly have to install the required package:

```bash

$ npm i --save @nestjs/platform-ws
```

Once the package is installed, we can switch an adapter:

```typescript

const app = await NestFactory.create(AppModule);
app.useWebSocketAdapter(new WsAdapter(app));
```

> **Hint** The `WsAdapter` is imported from `@nestjs/platform-ws`.

#### Advanced (custom adapter)[#](/websockets/adapter#advanced-custom-adapter)

For demonstration purposes, we are going to integrate the [ws](https://github.com/websockets/ws) library manually. As mentioned, the adapter for this library is already created and is exposed from the `@nestjs/platform-ws` package as a `WsAdapter` class. Here is how the simplified implementation could potentially look like:

ws-adapter.ts

JS TS

```typescript

import * as WebSocket from 'ws';
import { WebSocketAdapter, INestApplicationContext } from '@nestjs/common';
import { MessageMappingProperties } from '@nestjs/websockets';
import { Observable, fromEvent, EMPTY } from 'rxjs';
import { mergeMap, filter } from 'rxjs/operators';

export class WsAdapter implements WebSocketAdapter {
  constructor(private app: INestApplicationContext) {}

  create(port: number, options: any = {}): any {
    return new WebSocket.Server({ port, ...options });
  }

  bindClientConnect(server, callback: Function) {
    server.on('connection', callback);
  }

  bindMessageHandlers(
    client: WebSocket,
    handlers: MessageMappingProperties[],
    process: (data: any) => Observable<any>,
  ) {
    fromEvent(client, 'message')
      .pipe(
        mergeMap(data => this.bindMessageHandler(data, handlers, process)),
        filter(result => result),
      )
      .subscribe(response => client.send(JSON.stringify(response)));
  }

  bindMessageHandler(
    buffer,
    handlers: MessageMappingProperties[],
    process: (data: any) => Observable<any>,
  ): Observable<any> {
    const message = JSON.parse(buffer.data);
    const messageHandler = handlers.find(
      handler => handler.message === message.event,
    );
    if (!messageHandler) {
      return EMPTY;
    }
    return process(messageHandler.callback(message.data));
  }

  close(server) {
    server.close();
  }
}
```

> **Hint** When you want to take advantage of [ws](https://github.com/websockets/ws) library, use built-in `WsAdapter` instead of creating your own one.

Then, we can set up a custom adapter using `useWebSocketAdapter()` method:

main.ts

JS TS

```typescript

const app = await NestFactory.create(AppModule);
app.useWebSocketAdapter(new WsAdapter(app));
```

#### Example[#](/websockets/adapter#example)

A working example that uses `WsAdapter` is available [here](https://github.com/nestjs/nest/tree/master/sample/16-gateways-ws).

----
url: https://docs.nestjs.com/v11/security/helmet
----

* [Helmet](https://docs.nestjs.com/v11/security/helmet#helmet)
* [Use with Express (default)](https://docs.nestjs.com/v11/security/helmet#use-with-express-default)
* [Use with Fastify](https://docs.nestjs.com/v11/security/helmet#use-with-fastify)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/security/helmet.md "Suggest Edits")

### Helmet

[Helmet](https://github.com/helmetjs/helmet) can help protect your app from some well-known web vulnerabilities by setting HTTP headers appropriately. Generally, Helmet is just a collection of smaller middleware functions that set security-related HTTP headers (read [more](https://github.com/helmetjs/helmet#how-it-works)).

> **Hint** Note that applying `helmet` as global or registering it must come before other calls to `app.use()` or setup functions that may call `app.use()`. This is due to the way the underlying platform (i.e., Express or Fastify) works, where the order that middleware/routes are defined matters. If you use middleware like `helmet` or `cors` after you define a route, then that middleware will not apply to that route, it will only apply to routes defined after the middleware.

#### Use with Express (default)[#](/security/helmet#use-with-express-default)

Start by installing the required package.

```bash

$ npm i --save helmet
```

Once the installation is complete, apply it as a global middleware.

```typescript

import helmet from 'helmet';
// somewhere in your initialization file
app.use(helmet());
```

> **Warning** When using `helmet`, `@apollo/server` (4.x), and the [Apollo Sandbox](https://docs.nestjs.com/graphql/quick-start#apollo-sandbox), there may be a problem with [CSP](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP) on the Apollo Sandbox. To solve this issue configure the CSP as shown below:
>
> ```typescript
>
> app.use(helmet({
>   crossOriginEmbedderPolicy: false,
>   contentSecurityPolicy: {
>     directives: {
>       imgSrc: [`'self'`, 'data:', 'apollo-server-landing-page.cdn.apollographql.com'],
>       scriptSrc: [`'self'`, `https: 'unsafe-inline'`],
>       manifestSrc: [`'self'`, 'apollo-server-landing-page.cdn.apollographql.com'],
>       frameSrc: [`'self'`, 'sandbox.embed.apollographql.com'],
>     },
>   },
> }));
> ```

#### Use with Fastify[#](/security/helmet#use-with-fastify)

If you are using the `FastifyAdapter`, install the [@fastify/helmet](https://github.com/fastify/fastify-helmet) package:

```bash

$ npm i --save @fastify/helmet
```

[fastify-helmet](https://github.com/fastify/fastify-helmet) should not be used as a middleware, but as a [Fastify plugin](https://www.fastify.io/docs/latest/Reference/Plugins/), i.e., by using `app.register()`:

```typescript

import helmet from '@fastify/helmet'
// somewhere in your initialization file
await app.register(helmet)
```

> **Warning** When using `apollo-server-fastify` and `@fastify/helmet`, there may be a problem with [CSP](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP) on the GraphQL playground, to solve this collision, configure the CSP as shown below:
>
> ```typescript
>
> await app.register(fastifyHelmet, {
>    contentSecurityPolicy: {
>      directives: {
>        defaultSrc: [`'self'`, 'unpkg.com'],
>        styleSrc: [
>          `'self'`,
>          `'unsafe-inline'`,
>          'cdn.jsdelivr.net',
>          'fonts.googleapis.com',
>          'unpkg.com',
>        ],
>        fontSrc: [`'self'`, 'fonts.gstatic.com', 'data:'],
>        imgSrc: [`'self'`, 'data:', 'cdn.jsdelivr.net'],
>        scriptSrc: [
>          `'self'`,
>          `https: 'unsafe-inline'`,
>          `cdn.jsdelivr.net`,
>          `'unsafe-eval'`,
>        ],
>      },
>    },
>  });
>
> // If you are not going to use CSP at all, you can use this:
> await app.register(fastifyHelmet, {
>   contentSecurityPolicy: false,
> });
> ```

----
url: https://docs.nestjs.com/v10/recipes/mongodb
----

* [MongoDB (Mongoose)](https://docs.nestjs.com/v10/recipes/mongodb#mongodb-mongoose)
* [Getting started](https://docs.nestjs.com/v10/recipes/mongodb#getting-started)
* [Model injection](https://docs.nestjs.com/v10/recipes/mongodb#model-injection)
* [Example](https://docs.nestjs.com/v10/recipes/mongodb#example)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/recipes/mongodb.md "Suggest Edits")

### MongoDB (Mongoose)

> **Warning** In this article, you'll learn how to create a `DatabaseModule` based on the **Mongoose** package from scratch using custom components. As a consequence, this solution contains a lot of overhead that you can omit using ready to use and available out-of-the-box dedicated `@nestjs/mongoose` package. To learn more, see [here](/v10/techniques/mongodb).

[Mongoose](https://mongoosejs.com) is the most popular [MongoDB](https://www.mongodb.org/) object modeling tool.

#### Getting started[#](/recipes/mongodb#getting-started)

To start the adventure with this library we have to install all required dependencies:

```typescript

$ npm install --save mongoose
```

The first step we need to do is to establish the connection with our database using `connect()` function. The `connect()` function returns a `Promise`, and therefore we have to create an [async provider](/v10/fundamentals/async-components).

database.providers.ts

JS TS

```typescript

import * as mongoose from 'mongoose';

export const databaseProviders = [
  {
    provide: 'DATABASE_CONNECTION',
    useFactory: (): Promise<typeof mongoose> =>
      mongoose.connect('mongodb://localhost/nest'),
  },
];
```

```typescript

import * as mongoose from 'mongoose';

export const databaseProviders = [
  {
    provide: 'DATABASE_CONNECTION',
    useFactory: () => mongoose.connect('mongodb://localhost/nest'),
  },
];
```

> **Hint** Following best practices, we declared the custom provider in the separated file which has a `*.providers.ts` suffix.

Then, we need to export these providers to make them **accessible** for the rest part of the application.

database.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { databaseProviders } from './database.providers';

@Module({
  providers: [...databaseProviders],
  exports: [...databaseProviders],
})
export class DatabaseModule {}
```

Now we can inject the `Connection` object using `@Inject()` decorator. Each class that would depend on the `Connection` async provider will wait until a `Promise` is resolved.

#### Model injection[#](/recipes/mongodb#model-injection)

With Mongoose, everything is derived from a [Schema](https://mongoosejs.com/docs/guide.html). Let's define the `CatSchema`:

schemas/cat.schema.ts

JS TS

```typescript

import * as mongoose from 'mongoose';

export const CatSchema = new mongoose.Schema({
  name: String,
  age: Number,
  breed: String,
});
```

The `CatsSchema` belongs to the `cats` directory. This directory represents the `CatsModule`.

Now it's time to create a **Model** provider:

cats.providers.ts

JS TS

```typescript

import { Connection } from 'mongoose';
import { CatSchema } from './schemas/cat.schema';

export const catsProviders = [
  {
    provide: 'CAT_MODEL',
    useFactory: (connection: Connection) => connection.model('Cat', CatSchema),
    inject: ['DATABASE_CONNECTION'],
  },
];
```

```typescript

import { CatSchema } from './schemas/cat.schema';

export const catsProviders = [
  {
    provide: 'CAT_MODEL',
    useFactory: (connection) => connection.model('Cat', CatSchema),
    inject: ['DATABASE_CONNECTION'],
  },
];
```

> **Warning** In the real-world applications you should avoid **magic strings**. Both `CAT_MODEL` and `DATABASE_CONNECTION` should be kept in the separated `constants.ts` file.

Now we can inject the `CAT_MODEL` to the `CatsService` using the `@Inject()` decorator:

cats.service.ts

JS TS

```typescript

import { Model } from 'mongoose';
import { Injectable, Inject } from '@nestjs/common';
import { Cat } from './interfaces/cat.interface';
import { CreateCatDto } from './dto/create-cat.dto';

@Injectable()
export class CatsService {
  constructor(
    @Inject('CAT_MODEL')
    private catModel: Model<Cat>,
  ) {}

  async create(createCatDto: CreateCatDto): Promise<Cat> {
    const createdCat = new this.catModel(createCatDto);
    return createdCat.save();
  }

  async findAll(): Promise<Cat[]> {
    return this.catModel.find().exec();
  }
}
```

```typescript

import { Injectable, Dependencies } from '@nestjs/common';

@Injectable()
@Dependencies('CAT_MODEL')
export class CatsService {
  constructor(catModel) {
    this.catModel = catModel;
  }

  async create(createCatDto) {
    const createdCat = new this.catModel(createCatDto);
    return createdCat.save();
  }

  async findAll() {
    return this.catModel.find().exec();
  }
}
```

In the above example we have used the `Cat` interface. This interface extends the `Document` from the mongoose package:

```typescript

import { Document } from 'mongoose';

export interface Cat extends Document {
  readonly name: string;
  readonly age: number;
  readonly breed: string;
}
```

The database connection is **asynchronous**, but Nest makes this process completely invisible for the end-user. The `CatModel` class is waiting for the db connection, and the `CatsService` is delayed until model is ready to use. The entire application can start when each class is instantiated.

Here is a final `CatsModule`:

cats.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';
import { catsProviders } from './cats.providers';
import { DatabaseModule } from '../database/database.module';

@Module({
  imports: [DatabaseModule],
  controllers: [CatsController],
  providers: [
    CatsService,
    ...catsProviders,
  ],
})
export class CatsModule {}
```

> **Hint** Do not forget to import the `CatsModule` into the root `AppModule`.

#### Example[#](/recipes/mongodb#example)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/14-mongoose-base).

----
url: https://docs.nestjs.com/v6/techniques/mongodb
----

* [Mongo](https://docs.nestjs.com/v6/techniques/mongodb#mongo)
* [Model injection](https://docs.nestjs.com/v6/techniques/mongodb#model-injection)
* [Connection](https://docs.nestjs.com/v6/techniques/mongodb#connection)
* [Multiple databases](https://docs.nestjs.com/v6/techniques/mongodb#multiple-databases)
* [Hooks (middleware)](https://docs.nestjs.com/v6/techniques/mongodb#hooks-middleware)
* [Plugins](https://docs.nestjs.com/v6/techniques/mongodb#plugins)
* [Testing](https://docs.nestjs.com/v6/techniques/mongodb#testing)
* [Async configuration](https://docs.nestjs.com/v6/techniques/mongodb#async-configuration)
* [Example](https://docs.nestjs.com/v6/techniques/mongodb#example)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/techniques/mongo.md "Suggest Edits")

### Mongo

Nest supports two methods for integrating with the [MongoDB](https://www.mongodb.com/) database. You can either use the built-in [TypeORM](https://github.com/typeorm/typeorm) module described [here](/v6/techniques/database), which has a connector for MongoDB, or use [Mongoose](http://mongoosejs.com), the most popular MongoDB object modeling tool. In this chapter we'll describe the latter, using the dedicated `@nestjs/mongoose` package.

Start by installing the required dependencies:

```bash

$ npm install --save @nestjs/mongoose mongoose
```

Once the installation process is complete, we can import the `MongooseModule` into the root `AppModule`.

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';

@Module({
  imports: [MongooseModule.forRoot('mongodb://localhost/nest')],
})
export class AppModule {}
```

The `forRoot()` method accepts the same configuration object as `mongoose.connect()` from the Mongoose package, as described [here](https://mongoosejs.com/docs/connections.html).

#### Model injection[#](/techniques/mongodb#model-injection)

With Mongoose, everything is derived from a [Schema](http://mongoosejs.com/docs/guide.html). Let's define the `CatSchema`:

schemas/cat.schema.ts

JS TS

```typescript

import * as mongoose from 'mongoose';

export const CatSchema = new mongoose.Schema({
  name: String,
  age: Number,
  breed: String,
});
```

The `cat.schema` file resides in a folder in the `cats` directory, where we also define the `CatsModule`. While you can store schema files wherever you prefer, we recommend storing them them near their related **domain** objects, in the appropriate module directory.

Let's look at the `CatsModule`:

cats.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';
import { CatSchema } from './schemas/cat.schema';

@Module({
  imports: [MongooseModule.forFeature([{ name: 'Cat', schema: CatSchema }])],
  controllers: [CatsController],
  providers: [CatsService],
})
export class CatsModule {}
```

The `MongooseModule` provides the `forFeature()` method to configure the module, including defining which models should be registered in the current scope. If you also want to use the models in another module, add MongooseModule to the `exports` section of `CatsModule` and import `CatsModule` in the other module.

Once you've registered the schema, you can inject a `Cat` model into the `CatsService` using the `@InjectModel()` decorator:

cats.service.ts

JS TS

```typescript

import { Model } from 'mongoose';
import { Injectable } from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import { Cat } from './interfaces/cat.interface';
import { CreateCatDto } from './dto/create-cat.dto';

@Injectable()
export class CatsService {
  constructor(@InjectModel('Cat') private readonly catModel: Model<Cat>) {}

  async create(createCatDto: CreateCatDto): Promise<Cat> {
    const createdCat = new this.catModel(createCatDto);
    return createdCat.save();
  }

  async findAll(): Promise<Cat[]> {
    return this.catModel.find().exec();
  }
}
```

```typescript

import { Model } from 'mongoose';
import { Injectable, Dependencies } from '@nestjs/common';
import { getModelToken } from '@nestjs/mongoose';

@Injectable()
@Dependencies(getModelToken('Cat'))
export class CatsService {
  constructor(catModel) {
    this.catModel = catModel;
  }

  async create(createCatDto) {
    const createdCat = new this.catModel(createCatDto);
    return createdCat.save();
  }

  async findAll() {
    return this.catModel.find().exec();
  }
}
```

#### Connection[#](/techniques/mongodb#connection)

At times you may need to access the native [Mongoose Connection](https://mongoosejs.com/docs/api.html#Connection) object. For example, you may want to make native API calls on the connection object. You can inject the Mongoose Connection by using the `@InjectConnection()` decorator as follows:

```typescript

import { Injectable } from '@nestjs/common';
import { InjectConnection } from '@nestjs/mongoose';
import { Connection } from 'mongoose';

@Injectable()
export class CatsService {
  constructor(@InjectConnection() private readonly connection: Connection) {}
}
```

#### Multiple databases[#](/techniques/mongodb#multiple-databases)

Some projects require multiple database connections. This can also be achieved with this module. To work with multiple connections, first create the connections. In this case, connection naming becomes **mandatory**.

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';

@Module({
  imports: [
    MongooseModule.forRoot('mongodb://localhost/test', {
      connectionName: 'cats',
    }),
    MongooseModule.forRoot('mongodb://localhost/users', {
      connectionName: 'users',
    }),
  ],
})
export class AppModule {}
```

> **Notice** Please note that you shouldn't have multiple connections without a name, or with the same name, otherwise they will get overridden.

With this setup, you have to tell the `MongooseModule.forFeature()` function which connection should be used.

```typescript

@Module({
  imports: [
    MongooseModule.forFeature([{ name: 'Cat', schema: CatSchema }], 'cats'),
  ],
})
export class AppModule {}
```

You can also inject the `Connection` for a given connection:

```typescript

import { Injectable } from '@nestjs/common';
import { InjectConnection } from '@nestjs/mongoose';
import { Connection } from 'mongoose';

@Injectable()
export class CatsService {
  constructor(
    @InjectConnection('cats') private readonly connection: Connection,
  ) {}
}
```

#### Hooks (middleware)[#](/techniques/mongodb#hooks-middleware)

Middleware (also called pre and post hooks) are functions which are passed control during execution of asynchronous functions. Middleware is specified on the schema level and is useful for writing plugins ([source](https://mongoosejs.com/docs/middleware.html)). Calling `pre()` or `post()` after compiling a model does not work in Mongoose. To register a hook **before** model registration, use the `forFeatureAsync()` method of the `MongooseModule` along with a factory provider (i.e., `useFactory`). With this technique, you can access a schema object, then use the `pre()` or `post()` method to register a hook on that schema. See example below:

```typescript

@Module({
  imports: [
    MongooseModule.forFeatureAsync([
      {
        name: 'Cat',
        useFactory: () => {
          const schema = CatsSchema;
          schema.pre('save', () => console.log('Hello from pre save'));
          return schema;
        },
      },
    ]),
  ],
})
export class AppModule {}
```

Like other [factory providers](https://docs.nestjs.com/fundamentals/custom-providers#factory-providers-usefactory), our factory function can be `async` and can inject dependencies through `inject`.

```typescript

@Module({
  imports: [
    MongooseModule.forFeatureAsync([
      {
        name: 'Cat',
        import [ConfigModule],
        useFactory: (configService: ConfigService) => {
          const schema = CatsSchema;
          schema.pre('save', () =>
            console.log(`${configService.getString('APP_NAME')}: Hello from pre save`),
          );
          return schema;
        },
        inject: [ConfigService],
      }
    ]),
  ],
})
export class AppModule {}
```

#### Plugins[#](/techniques/mongodb#plugins)

To register a [plugin](https://mongoosejs.com/docs/plugins.html) for a given schema, use the `forFeatureAsync()` method.

```typescript

@Module({
  imports: [
    MongooseModule.forFeatureAsync([
      {
        name: 'Cat',
        useFactory: () => {
          const schema = CatsSchema;
          schema.plugin(require('mongoose-autopopulate'));
          return schema;
        },
      },
    ]),
  ],
})
export class AppModule {}
```

To register a plugin for all schemas at once, call the `.plugin()` method of the `Connection` object. You should access the connection before models are created; to do this, use the `connectionFactory`:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';

@Module({
  imports: [
    MongooseModule.forRoot('mongodb://localhost/test', {
      connectionFactory: (connection) => {
        connection.plugin(require('mongoose-autopopulate'));
        return connection;
      }
    }),
  ],
})
export class AppModule {}
```

#### Testing[#](/techniques/mongodb#testing)

When unit testing an application, we usually want to avoid any database connection, making our test suites simpler to set up and faster to execute. But our classes might depend on models that are pulled from the connection instance. How do we resolve these classes? The solution is to create mock models.

To make this easier, the `@nestjs/mongoose` package exposes a `getModelToken()` function that returns a prepared [injection token](https://docs.nestjs.com/fundamentals/custom-providers#di-fundamentals) based on a token name. Using this token, you can easily provide a mock implementation using any of the standard [custom provider](/v6/fundamentals/custom-providers) techniques, including `useClass`, `useValue`, and `useFactory`. For example:

```typescript

@Module({
  providers: [
    CatsService,
    {
      provide: getModelToken('Cat'),
      useValue: catModel,
    },
  ],
})
export class CatsModule {}
```

In this example, a hardcoded `catModel` (object instance) will be provided whenever any consumer injects a `Model<Cat>` using an `@InjectModel()` decorator.

## Learn the right way!

* 60+ chapters
* 4+ hours of videos
* Official certificate
* Deep-dive sessions

[Explore official courses](https://courses.nestjs.com "Courses | NestJS - A node.js framework built on top of TypeScript")

#### Async configuration[#](/techniques/mongodb#async-configuration)

When you need to pass module options asynchronously instead of statically, use the `forRootAsync()` method. As with most dynamic modules, Nest provides several techniques to deal with async configuration.

One technique is to use a factory function:

```typescript

MongooseModule.forRootAsync({
  useFactory: () => ({
    uri: 'mongodb://localhost/nest',
  }),
});
```

Like other [factory providers](https://docs.nestjs.com/fundamentals/custom-providers#factory-providers-usefactory), our factory function can be `async` and can inject dependencies through `inject`.

```typescript

MongooseModule.forRootAsync({
  imports: [ConfigModule],
  useFactory: async (configService: ConfigService) => ({
    uri: configService.getString('MONGODB_URI'),
  }),
  inject: [ConfigService],
});
```

Alternatively, you can configure the `MongooseModule` using a class instead of a factory, as shown below:

```typescript

MongooseModule.forRootAsync({
  useClass: MongooseConfigService,
});
```

The construction above instantiates `MongooseConfigService` inside `MongooseModule`, using it to create the required options object. Note that in this example, the `MongooseConfigService` has to implement the `MongooseOptionsFactory` interface, as shown below. The `MongooseModule` will call the `createMongooseOptions()` method on the instantiated object of the supplied class.

```typescript

@Injectable()
class MongooseConfigService implements MongooseOptionsFactory {
  createMongooseOptions(): MongooseModuleOptions {
    return {
      uri: 'mongodb://localhost/nest',
    };
  }
}
```

If you want to reuse an existing options provider instead of creating a private copy inside the `MongooseModule`, use the `useExisting` syntax.

```typescript

MongooseModule.forRootAsync({
  imports: [ConfigModule],
  useExisting: ConfigService,
});
```

#### Example[#](/techniques/mongodb#example)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/06-mongoose).

----
url: https://docs.nestjs.com/v5/custom-decorators
----

### Custom route decorators

Nest is built around a language feature called **decorators**. It's a well-known concept in a lot of commonly used programming languages, but in the JavaScript world, it's still relatively new. In order to better understand how the decorators work, you should take a look at [this](https://medium.com/google-developers/exploring-es7-decorators-76ecb65fb841) article. Here's a simple definition:

> An ES2016 decorator is an expression which returns a function and can take a target, name and property descriptor as arguments. You apply it by prefixing the decorator with an `@` character and placing this at the very top of what you are trying to decorate. Decorators can be defined for either a class or a property.

Nest provides a set of useful **param decorators** that you can use together with the HTTP route handlers. Below is a comparison of the decorators with the plain express objects.

|                            |                                      |
| -------------------------- | ------------------------------------ |
| `@Request()`               | `req`                                |
| `@Response()`              | `res`                                |
| `@Next()`                  | `next`                               |
| `@Session()`               | `req.session`                        |
| `@Param(param?: string)`   | `req.params` / `req.params[param]`   |
| `@Body(param?: string)`    | `req.body` / `req.body[param]`       |
| `@Query(param?: string)`   | `req.query` / `req.query[param]`     |
| `@Headers(param?: string)` | `req.headers` / `req.headers[param]` |

Additionally, you can create your own, **custom decorator**. Why it is useful?

In the node.js world, it's a common practice to attach properties to the **request** object. Then you have to manually grab them every time in the route handlers, for example, using following construction:

TypeScript

```typescript

const user = req.user;
```

In order to make it more readable and transparent, we can create a `@User()` decorator and reuse it across all existing controllers.

user.decorator.ts

JS TS

TypeScript

```typescript

import { createParamDecorator } from '@nestjs/common';

export const User = createParamDecorator((data, req) => {
  return req.user;
});
```

Then, you can simply use it wherever it fits your requirements.

JS TS

TypeScript

```typescript

@Get()
async findOne(@User() user: UserEntity) {
  console.log(user);
}
```

TypeScript

```typescript

@Get()
@Bind(User())
async findOne(user) {
  console.log(user);
}
```

#### Passing data

When the behavior of your decorator depends on some conditions, you may use the `data` param to pass an argument to the decorator's factory function. For example, the construction below:

JS TS

TypeScript

```typescript

@Get()
async findOne(@User('test') user: UserEntity) {
  console.log(user);
}
```

TypeScript

```typescript

@Get()
@Bind(User('test'))
async findOne(user) {
  console.log(user);
}
```

Will make possible to access the `test` string via the `data` argument:

user.decorator.ts

JS TS

TypeScript

```typescript

import { createParamDecorator } from '@nestjs/common';

export const User = createParamDecorator((data, req) => {
  console.log(data); // test
  return req.user;
});
```

#### Working with pipes

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

JS TS

TypeScript

```typescript

@Get()
async findOne(@User(new ValidationPipe()) user: UserEntity) {
  console.log(user);
}
```

TypeScript

```typescript

@Get()
@Bind(User(new ValidationPipe()))
async findOne(user) {
  console.log(user);
}
```

* Custom route decorators
* Passing data
* Working with pipes

----
url: https://docs.nestjs.com/v5/graphql/resolvers-map
----

### Resolvers

Typically, you have to create a resolvers map manually. The `@nestjs/graphql` package, on the other hand, generate resolvers map automatically using the metadata provided by the decorators. In order to learn the library basics, we'll create a simple authors API. Firstly, let's define our types in SDL (read [more](http://graphql.org/learn/schema/#type-language)):

Java

```java

type Author {
  id: Int!
  firstName: String
  lastName: String
  posts: [Post]
}

type Post {
  id: Int!
  title: String
  votes: Int
}

type Query {
  author(id: Int!): Author
}
```

Our GraphQL schema contains single query exposed, the `author(id: Int!): Author`. Now, let's create an `AuthorResolver`.

TypeScript

```typescript

@Resolver('Author')
export class AuthorResolver {
  constructor(
    private readonly authorsService: AuthorsService,
    private readonly postsService: PostsService,
  ) {}

  @Query()
  async author(@Args('id') id: number) {
    return await this.authorsService.findOneById(id);
  }

  @ResolveProperty()
  async posts(@Parent() author) {
    const { id } = author;
    return await this.postsService.findAll({ authorId: id });
  }
}
```

> **Hint** If you use the `@Resolver()` decorator, you don't have to mark a class as an `@Injectable()`, otherwise, it's necessary.

The `@Resolver()` decorator does not affect queries and mutations (neither `@Query()` nor `@Mutation()` decorators). It only informs Nest that each `@ResolveProperty()` inside this particular class has a parent, which is an `Author` type in this case (`Author.posts` relation).

Conventionally, we would use something like `getAuthor()` or `getPosts()` as method names. We can do that easily as well by moving the real names between decorator's parentheses.

TypeScript

```typescript

@Resolver('Author')
export class AuthorResolver {
  constructor(
    private readonly authorsService: AuthorsService,
    private readonly postsService: PostsService,
  ) {}

  @Query('author')
  async getAuthor(@Args('id') id: number) {
    return await this.authorsService.findOneById(id);
  }

  @ResolveProperty('posts')
  async getPosts(@Parent() author) {
    const { id } = author;
    return await this.postsService.findAll({ authorId: id });
  }
}
```

> **Hint** The `@Resolver()` decorator can be used at the method-level as well.

#### Decorators

You may note that we refer to the following arguments using dedicated decorators. Below is a comparison of the provided decorators and the plain Apollo parameters they represent.

|                            |                              |
| -------------------------- | ---------------------------- |
| `@Root()` and `@Parent()`  | `root`/`parent`              |
| `@Context(param?: string)` | `context` / `context[param]` |
| `@Info(param?: string)`    | `info` / `info[param]`       |
| `@Args(param?: string)`    | `args` / `args[param]`       |

#### Module

Once we're done here, we have to register the `AuthorResolver` somewhere, for example inside the newly created `AuthorsModule`.

JS TS

TypeScript

```typescript

@Module({
  imports: [PostsModule],
  providers: [AuthorsService, AuthorResolver],
})
export class AuthorsModule {}
```

The `GraphQLModule` will take care of reflecting the metadata and transforming class into the correct resolvers map automatically. The only thing that you should be aware of is that you need to import this module somewhere, therefore Nest will know that `AuthorsModule` truly exists.

> **Hint** Learn more about GraphQL queries [here](http://graphql.org/learn/queries/).

#### Typings

Separate creation of both GraphQL types and corresponding TypeScript definitions creates unnecessary redundancy. Eventually, we end up without a single source of truth and each change made within SDL forces us to adjust interfaces as well. Thus, the `@nestjs/graphql` package serves another interesting functionality, which is the automatic generation of TS definitions using abstract syntax tree (AST). In order to enable it, simply customize `definitions` property.

TypeScript

```typescript

GraphQLModule.forRoot({
  typePaths: ['./**/*.graphql'],
  definitions: {
    path: join(process.cwd(), 'src/graphql.ts'),
  },
})
```

The `src/graphql.ts` indicates where to save TypeScript output. By default, all types are transformed to the interfaces. However, you can switch to classes instead by changing `outputAs` property to `class`.

TypeScript

```typescript

GraphQLModule.forRoot({
  typePaths: ['./**/*.graphql'],
  definitions: {
    path: join(process.cwd(), 'src/graphql.ts'),
    outputAs: 'class',
  },
})
```

Consequently, it will generate the following file:

TypeScript

```typescript

export class Author {
  id: number;
  firstName?: string;
  lastName?: string;
  posts?: Post[];
}

export class Post {
  id: number;
  title?: string;
  votes?: number;
}

export abstract class IQuery {
  abstract author(id: number): Author | Promise<Author>;
}
```

Classes allow you using **decorators** which makes them extremely useful in terms of the validation purposes (read [more](/v5/techniques/validation)). For example:

TypeScript

```typescript

import { MinLength, MaxLength } from 'class-validator';

export class CreatePostInput {
  @MinLength(3)
  @MaxLength(50)
  title: string;
}
```

> **Notice** To enable auto-validation of your inputs (and parameters), you have to use `ValidationPipe`. Read more about validation [here](/v5/techniques/validation) or more specifically about pipes [here](/v5/pipes).

* Resolvers
* Decorators
* Module
* Typings

----
url: https://docs.nestjs.com/v4/graphql/guards-interceptors
----

### Guards & Interceptors

In the GraphQL world, a lot of articles complain how to handle stuff like an **authentication**, or **side-effects** of operations. Should we put it inside the business logic? Shall we use a higher-order function to enhance queries and mutations as well for example with authorization logic? There's no single answer.

The Nest ecosystem is trying to help with this issue using existing features like [guards](/v4/guards) and [interceptors](/v4/interceptors). The idea behind them is to reduce redundancy and also, create a well-structured applications.

#### Usage

You can use both [guards](/v4/guards) and [interceptors](/v4/interceptors) in the same way as in the simple REST application. They act equivalently until the `request` is passed as a `rootValue` in the `graphqlExpress` middleware. Let's have a look at the following code:

JavaScript TypeScript

TypeScript

```typescript

@Query('author')
@UseGuards(AuthGuard)
async getAuthor(obj, args, context, info) {
  const { id } = args;
  return await this.authorsService.findOneById(id);
}
```

Thanks to that you can move your authentication logic to the guard, or even reuse the same guard class as in the REST application. The interceptors works in the exact same way:

JavaScript TypeScript

TypeScript

```typescript

@Mutation()
@UseInterceptors(EventsInterceptor)
async upvotePost(_, { postId }) {
  return await this.postsService.upvoteById({ id: postId });
}
```

Write once, use everywhere :)

#### Sponsors

[](https://valor-software.com/)

Nest is an MIT-licensed open source project. It can grow thanks to the support by these awesome people. If you'd like to join them, please read more [here](https://opencollective.com/nest). Thanks!

[](https://opencollective.com/nest/backer/0/website)[](https://opencollective.com/nest/backer/1/website)[](https://opencollective.com/nest/backer/2/website)[](https://opencollective.com/nest/backer/3/website)[](https://opencollective.com/nest/backer/4/website)[](https://opencollective.com/nest/backer/5/website)[](https://opencollective.com/nest/backer/6/website)[](https://opencollective.com/nest/backer/7/website)[](https://opencollective.com/nest/backer/8/website)[](https://opencollective.com/nest/backer/9/website)[](https://opencollective.com/nest/backer/10/website)[](https://opencollective.com/nest/backer/11/website)[](https://opencollective.com/nest/backer/12/website)[](https://opencollective.com/nest/backer/13/website)[](https://opencollective.com/nest/backer/14/website)[](https://opencollective.com/nest/backer/15/website)[](https://opencollective.com/nest/backer/16/website)[](https://opencollective.com/nest/backer/17/website)[](https://opencollective.com/nest/backer/18/website)[](https://opencollective.com/nest/backer/19/website)[](https://opencollective.com/nest/backer/20/website)[](https://opencollective.com/nest/backer/21/website)[](https://opencollective.com/nest/backer/22/website)[](https://opencollective.com/nest/backer/23/website)[](https://opencollective.com/nest/backer/24/website)[](https://opencollective.com/nest/backer/25/website)[](https://opencollective.com/nest/backer/26/website)[](https://opencollective.com/nest/backer/27/website)[](https://opencollective.com/nest/backer/28/website)[](https://opencollective.com/nest/backer/29/website)

[Become a sponsor](https://opencollective.com/nest)

----
url: https://docs.nestjs.com/v7/fundamentals/circular-dependency
----

* [Circular dependency](https://docs.nestjs.com/v7/fundamentals/circular-dependency#circular-dependency)
* [Forward reference](https://docs.nestjs.com/v7/fundamentals/circular-dependency#forward-reference)
* [ModuleRef class alternative](https://docs.nestjs.com/v7/fundamentals/circular-dependency#moduleref-class-alternative)
* [Module forward reference](https://docs.nestjs.com/v7/fundamentals/circular-dependency#module-forward-reference)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/fundamentals/circular-dependency.md "Suggest Edits")

### Circular dependency

A circular dependency occurs when two classes depend on each other. For example, class A needs class B, and class B also needs class A. Circular dependencies can arise in Nest between modules and between providers.

While circular dependencies should be avoided where possible, you can't always do so. In such cases, Nest enables resolving circular dependencies between providers in two ways. In this chapter, we describe using **forward referencing** as one technique, and using the **ModuleRef** class to retrieve a provider instance from the DI container as another.

We also describe resolving circular dependencies between modules.

> **Warning** A circular dependency might also be caused when using "barrel files"/index.ts files to group imports. Barrel files should be omitted when it comes to module/provider classes. For example, barrel files should not be used when importing files within the same directory as the barrel file, i.e. `cats/cats.controller` should not import `cats` to import the `cats/cats.service` file. For more details please also see [this github issue](https://github.com/nestjs/nest/issues/1181#issuecomment-430197191).

#### Forward reference[#](/fundamentals/circular-dependency#forward-reference)

A **forward reference** allows Nest to reference classes which aren't yet defined using the `forwardRef()` utility function. For example, if `CatsService` and `CommonService` depend on each other, both sides of the relationship can use `@Inject()` and the `forwardRef()` utility to resolve the circular dependency. Otherwise Nest won't instantiate them because all of the essential metadata won't be available. Here's an example:

cats.service.ts

JS TS

```typescript

@Injectable()
export class CatsService {
  constructor(
    @Inject(forwardRef(() => CommonService))
    private commonService: CommonService,
  ) {}
}
```

```typescript

@Injectable()
@Dependencies(forwardRef(() => CommonService))
export class CatsService {
  constructor(commonService) {
    this.commonService = commonService;
  }
}
```

> **Hint** The `forwardRef()` function is imported from the `@nestjs/common` package.

That covers one side of the relationship. Now let's do the same with `CommonService`:

common.service.ts

JS TS

```typescript

@Injectable()
export class CommonService {
  constructor(
    @Inject(forwardRef(() => CatsService))
    private catsService: CatsService,
  ) {}
}
```

```typescript

@Injectable()
@Dependencies(forwardRef(() => CatsService))
export class CommonService {
  constructor(catsService) {
    this.catsService = catsService;
  }
}
```

> **Warning** The order of instantiation is indeterminate. Make sure your code does not depend on which constructor is called first.

#### ModuleRef class alternative[#](/fundamentals/circular-dependency#moduleref-class-alternative)

An alternative to using `forwardRef()` is to refactor your code and use the `ModuleRef` class to retrieve a provider on one side of the (otherwise) circular relationship. Learn more about the `ModuleRef` utility class [here](/v7/fundamentals/module-ref).

#### Module forward reference[#](/fundamentals/circular-dependency#module-forward-reference)

In order to resolve circular dependencies between modules, use the same `forwardRef()` utility function on both sides of the modules association. For example:

common.module.ts

JS TS

```typescript

@Module({
  imports: [forwardRef(() => CatsModule)],
})
export class CommonModule {}
```

----
url: https://docs.nestjs.com/v11/observability/dashboard
----

* [Dashboard](https://docs.nestjs.com/v11/observability/dashboard#dashboard)
* [How the views nest](https://docs.nestjs.com/v11/observability/dashboard#how-the-views-nest)
* [Telemetry views](https://docs.nestjs.com/v11/observability/dashboard#telemetry-views)
* [Handing a failure to a coding agent](https://docs.nestjs.com/v11/observability/dashboard#handing-a-failure-to-a-coding-agent)
* [Alerts](https://docs.nestjs.com/v11/observability/dashboard#alerts)
* [SLOs](https://docs.nestjs.com/v11/observability/dashboard#slos)
* [Issues](https://docs.nestjs.com/v11/observability/dashboard#issues)
* [A worked path through the dashboard](https://docs.nestjs.com/v11/observability/dashboard#a-worked-path-through-the-dashboard)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/observability/dashboard.md "Suggest Edits")

### Dashboard

Once an application is instrumented and sending data, its project dashboard fills in automatically - no queries to write, no dashboards to build. This chapter covers what each view shows, how they relate to each other, and how the features built on top of the telemetry - alerts, SLOs, issues, and the agent handoff - fit together. For the full reference, see the [NestJS Observe documentation](https://www.observe.nestjs.com/dashboard/documentation "NestJS Observe documentation").

#### How the views nest[#](/observability/dashboard#how-the-views-nest)

Almost every telemetry view is one of three levels, and you move between them by clicking through:

1. **Analytics** - the list view. Every route, job, span, or metric your applications reported in the selected window, aggregated: throughput, latency, failure rate. This is where you notice something.
2. **Operation** - one route (`GET /orders/:id`), one job name, one span name. The same numbers over time, plus the list of individual executions behind them. This is where you confirm the shape of a problem: constant or spiky, everywhere or one release.
3. **Execution** - a single request, a single job run, a single span invocation. Its exact duration, status, user, tags, the error it raised, the waterfall of everything it did, and the logs it wrote. This is where you diagnose.

Aggregates tell you *that* something is wrong and how much it matters; a single execution tells you *why*. Every view shares one control bar - a time range and an optional application filter - and everything on the page obeys it.

#### Telemetry views[#](/observability/dashboard#telemetry-views)

| View         | What it shows                                                                                                                                                                                                                                                                                                   |
| ------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Requests** | Every HTTP, GraphQL, and gRPC request, broken down by operation. A request detail page compares the call against the route's own baseline ("slower than 95% of calls") and, when the process was struggling, states by how much host pressure slowed this operation.                                            |
| **Services** | Time spent per NestJS **class and method**, split into own time (with everything awaited subtracted out) and total time. Only instrumented classes appear, so a short list means low coverage, not low traffic.                                                                                                 |
| **Errors**   | Every unhandled error, grouped by operation, with the failure leading the page: class, message, stack trace, and source code. The **Group into defects** switch collapses occurrences with the same class and stack shape into one fingerprinted group with first/last seen and the release that introduced it. |
| **Jobs**     | Background work - queue consumers, cron runs - with queue wait time, attempt number, and failure reason alongside duration and failure rate.                                                                                                                                                                    |
| **Spans**    | Analytics over span names across every route that calls them - "how slow is `OrdersService.recalculate` everywhere", rather than "how slow is this one endpoint".                                                                                                                                               |
| **Traces**   | The waterfall for a trace id, across every service that shares it - see [Distributed tracing]().                                                                                                                                                                                                                |
| **Users**    | Per-user activity when `getUserId` is configured: failure rate per user, calls grouped into the actions they performed, a replay of each action, and the paths between them. A **Group by customer** switch rolls identities up by email domain.                                                                |
| **Custom**   | Counters, gauges, and summaries reported through [`TracerService`](/observability/manual-instrumentation#custom-metrics), grouped by metric name and labels.                                                                                                                                                    |
| **Releases** | Each `serviceVersion` compared against the one before it - error rate, latency, and throughput side by side.                                                                                                                                                                                                    |
| **Logs**     | Everything your services logged (with `forwardLogs` on), correlated to the traces they ran in. On an execution page, each line is placed on the trace's clock next to the span that was in flight.                                                                                                              |
| **Profiler** | CPU, memory, event loop delay and utilization, and garbage collection per application, with per-instance comparison when an application runs on more than one node. Click a spike on the Memory or Event loop delay chart to see which operations ran at that moment, ranked by deviation from their baseline.  |

#### Handing a failure to a coding agent[#](/observability/dashboard#handing-a-failure-to-a-coding-agent)

Reading a trace tells you what happened. The next step is always the same: go find that code and change it. The **Copy agent prompt** button does that handoff in one click - it copies the entire page as a self-contained markdown prompt, ready to paste into Claude Code, Cursor, or anything else that has your repository open.

The button appears only where there is something to investigate: a request or job that failed or ran slower than 95% of its peers, or a trace containing an error. The prompt carries the task framing, the operation context, the error with its trimmed stack trace and source lines (paths rewritten relative to your project root, so `src/orders/orders.service.ts:35` rather than `/var/app/current/dist/orders/orders.service.js:35`), how the call compares to the operation's average and p95, the top spans by self time, up to 40 log lines chosen errors-first, and closing instructions asking the agent to explain the root cause from the code and propose a fix as a diff with tests.

For an agent that needs to keep asking - follow a trace into its logs, check whether an error is still firing - connect it to the [MCP server]() instead.

#### Alerts[#](/observability/dashboard#alerts)

Alerts get you told when your telemetry crosses a threshold you care about, instead of you finding out from a customer. A rule watches one metric from one of these families:

| Family  | Metrics                                          | Scoped to                                           |
| ------- | ------------------------------------------------ | --------------------------------------------------- |
| Request | Error rate, p95 latency, avg latency, throughput | An application, and optionally one route + method   |
| Job     | Job failure rate, job throughput, p95 queue wait | An application, and optionally one job name + queue |
| Absence | Telemetry silence, job silence                   | An application, or one job name + queue             |
| Logs    | Matching log lines                               | A pattern, and optionally levels + logger context   |
| Runtime | Event loop delay, CPU usage, memory usage        | An application (sampled per process)                |
| Custom  | Any custom metric your application reports       | A metric name, and optionally one label             |
| SLO     | SLO burn rate                                    | The SLO itself                                      |

Every rule runs in one of two modes: a **fixed threshold** ("error rate above 5%"), or **anomaly detection**, which fires when the metric deviates from its own recent baseline by more than a sensitivity you set. Anomaly mode is often the better choice for runtime metrics - a fixed CPU threshold that's right for one service is wrong for the next, but "unlike its own recent baseline" travels.

Two families deserve a closer look from the instrumentation side:

* **Absence detection.** A **Telemetry silence** rule watches the runtime heartbeat the SDK's `runtimeMetrics` sampler emits even when the application is otherwise idle, and fires once it's been silent longer than a tolerance you set (2 minutes to 7 days). A **Job silence** rule does the same for one named job - a cron that didn't run. This is both lightweight uptime monitoring with no external probe and cron monitoring, from the same mechanism. A scope that has never reported anything doesn't fire: "not yet integrated" isn't "down".
* **Log-pattern alerts** count log lines containing a substring within the window - "alert me when `payment declined` appears more than 10 times in 15 minutes" - and need `forwardLogs` to be on.

A rule can notify through **email**, **Slack** (incoming webhook), a generic **webhook**, an **in-app** notification, or by **creating an issue** pre-filled with the rule's severity and scope. Rules can carry a recurring mute schedule for quiet hours, and every state transition (OK → Firing → Resolved) is recorded with per-channel delivery status.

#### SLOs[#](/observability/dashboard#slos)

SLOs turn "error rate above 5%" into "we promised 99.9% and we're spending the budget too fast". They're objectives over telemetry you're already collecting - no new instrumentation required. An SLO is built from three layered ideas:

* **SLI (service level indicator)** - a ratio of good events to total events over a window: availability (requests without an unhandled error), latency (requests under a threshold you set), or job success.
* **Objective** - the SLI plus a target percentage (90-99.999%) over a rolling compliance window of 7, 14, 28, or 30 days.
* **Error budget** - how much room you have to miss the target (`1 − target`), and **burn rate**, how fast that budget is being spent. A burn rate of 1.0 spends it exactly on schedule; 14.4 means a 28-day budget would be gone in about two days.

A burn-rate alert is a regular alert rule pointed at an SLO instead of a raw metric. Typical starting points are a fast-burn rule (1 hour window, 14.4×), a slow-burn rule (6 hours, 6×), and a trickle rule (3 days, 1×). A compliance window can't exceed how long your plan retains telemetry.

#### Issues[#](/observability/dashboard#issues)

Issues are lightweight, project-scoped tracking for the work that comes out of your telemetry - a recurring error worth fixing, a latency regression to investigate. Create them by hand from any execution page, promote an error group into one, or let a firing alert open one automatically. An issue links to the request, error, job, or trace it came from, so anyone opening it later has the telemetry in context, not just a description of it.

When you mark an issue resolved and it names something measurable (an operation, an alert rule's scope), the dashboard watches that operation's telemetry against its pre-incident baseline and tells you whether the fix actually held - moving the issue to **Verifying**, then to closed on its own, or back to **Open** with the reading that broke it. Naming the release the fix went out in (your `serviceVersion`) holds verification until that release actually shows up in telemetry.

#### A worked path through the dashboard[#](/observability/dashboard#a-worked-path-through-the-dashboard)

The views are designed to be walked in order. A typical investigation:

1. An alert fires, or the **Requests** chart shows p95 climbing.
2. Sort the route list by duration or failure rate to find which operation moved.
3. Open the operation. Is it constant or spiky? Did it start at a deploy? Check **Releases**.
4. Open a single execution from the tail of the distribution - one the baseline card calls *slower than 95% of calls*.
5. Read the **waterfall**: which span holds the self time?
6. If it failed, read the **error card** - stack trace and the source lines around the throw.
7. Check the **logs** for that trace, hovering lines to line them up with the spans.
8. **Copy the agent prompt** and hand the whole thing to a coding agent, or open an **issue** linked to the execution so whoever picks it up starts where you stopped.

The same walk is available to an agent over the [MCP server](), one tool per step, when you'd rather ask questions than click through them.

----
url: https://docs.nestjs.com/v7/openapi/migration-guide
----

* [Migration guide](https://docs.nestjs.com/v7/openapi/migration-guide#migration-guide)
* [Breaking changes](https://docs.nestjs.com/v7/openapi/migration-guide#breaking-changes)
* [New methods](https://docs.nestjs.com/v7/openapi/migration-guide#new-methods)

----
url: https://docs.nestjs.com/v7/graphql/cli-plugin
----

* [CLI Plugin](https://docs.nestjs.com/v7/graphql/cli-plugin#cli-plugin)
* [Overview](https://docs.nestjs.com/v7/graphql/cli-plugin#overview)
* [Comments introspection](https://docs.nestjs.com/v7/graphql/cli-plugin#comments-introspection)
* [Using the CLI plugin](https://docs.nestjs.com/v7/graphql/cli-plugin#using-the-cli-plugin)
* [Integration with ts-jest (e2e tests)](https://docs.nestjs.com/v7/graphql/cli-plugin#integration-with-ts-jest-e2e-tests)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/cli-plugin.md "Suggest Edits")

### CLI Plugin

> **Warning** This chapter applies only to the code first approach.

TypeScript's metadata reflection system has several limitations which make it impossible to, for instance, determine what properties a class consists of or recognize whether a given property is optional or required. However, some of these constraints can be addressed at compilation time. Nest provides a plugin that enhances the TypeScript compilation process to reduce the amount of boilerplate code required.

> **Hint** This plugin is **opt-in**. If you prefer, you can declare all decorators manually, or only specific decorators where you need them.

```typescript

@ObjectType()
export class Author {
  @Field(type => ID)
  id: number;

  @Field({ nullable: true })
  firstName?: string;

  @Field({ nullable: true })
  lastName?: string;

  @Field(type => [Post])
  posts: Post[];
}
```

While not a significant issue with medium-sized projects, it becomes verbose & hard to maintain once you have a large set of classes.

By enabling the GraphQL plugin, the above class definition can be declared simply:

authors/models/author.model.ts

JS TS

```typescript

@ObjectType()
export class Author {
  @Field(type => ID)
  id: number;
  firstName?: string;
  lastName?: string;
  posts: Post[];
}
```

The plugin adds appropriate decorators on-the-fly based on the **Abstract Syntax Tree**. Thus, you won't have to struggle with `@Field` decorators scattered throughout the code.

> **Hint** The plugin will automatically generate any missing GraphQL properties, but if you need to override them, simply set them explicitly via `@Field()`.

#### Comments introspection[#](/graphql/cli-plugin#comments-introspection)

With the comments introspection feature enabled, CLI plugin will generate descriptions for fields based on comments.

For example, given an example `roles` property:

```typescript

/**
 * A list of user's roles
 */
@Field(() => [String], {
  description: `A list of user's roles`
})
roles: string[];
```

You must duplicate description values. With `introspectComments` enabled, the CLI plugin can extract these comments and automatically provide descriptions for properties. Now, the above field can be declared simply as follows:

```typescript

/**
 * A list of user's roles
 */
roles: string[];
```

#### Using the CLI plugin[#](/graphql/cli-plugin#using-the-cli-plugin)

To enable the plugin, open `nest-cli.json` (if you use [Nest CLI](/v7/cli/overview)) and add the following `plugins` configuration:

```javascript

{
  "collection": "@nestjs/schematics",
  "sourceRoot": "src",
  "compilerOptions": {
    "plugins": ["@nestjs/graphql"]
  }
}
```

You can use the `options` property to customize the behavior of the plugin.

```javascript

"plugins": [
  {
    "name": "@nestjs/graphql",
    "options": {
      "typeFileNameSuffix": [".input.ts", ".args.ts"],
      "introspectComments": true
    }
  }
]
```

The `options` property has to fulfill the following interface:

```typescript

export interface PluginOptions {
  typeFileNameSuffix?: string[];
  introspectComments?: boolean;
}
```

| Option               | Default                                                | Description                                                                        |
| -------------------- | ------------------------------------------------------ | ---------------------------------------------------------------------------------- |
| `typeFileNameSuffix` | `['.input.ts', '.args.ts', '.entity.ts', '.model.ts']` | GraphQL types files suffix                                                         |
| `introspectComments` | `false`                                                | If set to true, plugin will generate descriptions for properties based on comments |

If you don't use the CLI but instead have a custom `webpack` configuration, you can use this plugin in combination with `ts-loader`:

```javascript

getCustomTransformers: (program: any) => ({
  before: [require('@nestjs/graphql/plugin').before({}, program)]
}),
```

#### Integration with `ts-jest` (e2e tests)[#](/graphql/cli-plugin#integration-with-ts-jest-e2e-tests)

When running e2e tests with this plugin enabled, you may run into issues with compiling schema. For example, one of the most common errors is:

```json

Object type <name> must define one or more fields.
```

This happens because `jest` configuration does not import `@nestjs/graphql/plugin` plugin anywhere.

To fix this, create the following file in your e2e tests directory:

```javascript

const transformer = require('@nestjs/graphql/plugin');

module.exports.name = 'nestjs-graphql-transformer';
// you should change the version number anytime you change the configuration below - otherwise, jest will not detect changes
module.exports.version = 1;

module.exports.factory = (cs) => {
  return transformer.before(
    {
      // @nestjs/graphql/plugin options (can be empty)
    },
    cs.tsCompiler.program,
  );
};
```

With this in place, import AST transformer within your `jest` configuration file. By default (in the starter application), e2e tests configuration file is located under the `test` folder and is named `jest-e2e.json`.

```json

{
  ... // other configuration
  "globals": {
    "ts-jest": {
      "astTransformers": {
        "before": ["<path to the file created above>"],
      }
    }
  }
}
```

----
url: https://docs.nestjs.com/v5/techniques/hot-reload
----

### Hot Reload (Webpack)

The highest impact on your application's bootstrapping process has a **TypeScript compilation**. But the question is, do we have to recompile a whole project each time when change occurs? Not at all. That's why [webpack](https://github.com/webpack/webpack) HMR (Hot-Module Replacement) significantly decreases an amount of time necessary to instantiate your application.

#### Installation

Firstly, let's install required packages:

TypeScript

```typescript

$ npm i --save-dev webpack webpack-cli webpack-node-externals
```

#### Configuration

Then, we need to create a `webpack.config.js` which is a webpack's configuration file, and put it in the root directory.

TypeScript

```typescript

const webpack = require('webpack');
const path = require('path');
const nodeExternals = require('webpack-node-externals');

module.exports = {
  entry: ['webpack/hot/poll?100', './src/main.ts'],
  watch: true,
  target: 'node',
  externals: [
    nodeExternals({
      whitelist: ['webpack/hot/poll?100'],
    }),
  ],
  module: {
    rules: [
      {
        test: /.tsx?$/,
        use: 'ts-loader',
        exclude: /node_modules/,
      },
    ],
  },
  mode: 'development',
  resolve: {
    extensions: ['.tsx', '.ts', '.js'],
  },
  plugins: [new webpack.HotModuleReplacementPlugin()],
  output: {
    path: path.join(__dirname, 'dist'),
    filename: 'server.js',
  },
};
```

This configuration tells webpack few essential things about our application. Where sits an entry file, which directory should be used to hold **compiled** files, and also, what kind of loader we want to use in order to compile source files. Basically, you shouldn't worry to much, you don't need to understand the content of this file at all.

#### Hot-Module Replacement

In order to enable **HMR**, we have to open Nest application entry file (which is `main.ts`) and add few critical things.

TypeScript

```typescript

declare const module: any;

async function bootstrap() {
  const app = await NestFactory.create(ApplicationModule);
  await app.listen(3000);

  if (module.hot) {
    module.hot.accept();
    module.hot.dispose(() => app.close());
  }
}
bootstrap();
```

And that's all. To simplify execution process, add those two lines into your `scripts` inside `package.json` file.

TypeScript

```typescript

"start": "node dist/server",
"webpack": "webpack --config webpack.config.js"
```

Now simply open your command line and run below command:

```bash

$ npm run webpack
```

Once webpack started to **watch files**, run another command in the another command line window:

```bash

$ npm run start
```

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/08-webpack).

* Hot Reload (Webpack)
* Installation
* Configuration
* Hot-Module Replacement

----
url: https://docs.nestjs.com/v6/graphql/federation
----

* [Federation](https://docs.nestjs.com/v6/graphql/federation#federation)
* [Federated example: Users](https://docs.nestjs.com/v6/graphql/federation#federated-example-users)
* [Federated example: Posts](https://docs.nestjs.com/v6/graphql/federation#federated-example-posts)
* [Federated example: Gateway](https://docs.nestjs.com/v6/graphql/federation#federated-example-gateway)
* [Sharing context](https://docs.nestjs.com/v6/graphql/federation#sharing-context)
* [Async configuration](https://docs.nestjs.com/v6/graphql/federation#async-configuration)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/federation.md "Suggest Edits")

### Federation

[Apollo Federation](https://www.apollographql.com/docs/apollo-server/federation/introduction/) offers a means of splitting your monolith GraphQL server into independent microservices. It consists of two components: A gateway and one or more federated microservices. Each microservice holds part of the schema and the gateway merges the schemas into one single schema that can be consumed by the client.

To quote the [Apollo docs](https://blog.apollographql.com/apollo-federation-f260cf525d21), Federation is designed with these core principles:

* Building a graph should be **declarative.** With federation, you compose a graph declaratively from within your schema instead of writing imperative schema stitching code.
* Code should be separated by **concern**, not by types. Often no single team controls every aspect of an important type like a User or Product, so the definition of these types should be distributed across teams and codebases, rather than centralized.
* The graph should be simple for clients to consume. Together, federated services can form a complete, product-focused graph that accurately reflects how it’s being consumed on the client.
* It’s just **GraphQL**, using only spec-compliant features of the language. Any language, not just JavaScript, can implement federation.

> **Note** Apollo Federation currently does not support subscriptions, and only the schema-first approach is currently supported due to limitations with the decorators not yet supporting GraphQL directives[1](https://github.com/MichalLytek/type-graphql/issues/351)

In the next example, we'll set up a demo application with a gateway and two federated endpoints: a user- and posts service.

#### Federated example: Users[#](/graphql/federation#federated-example-users)

First install the optional dependency for federation:

```bash

$ npm install --save @apollo/federation
```

The User service has a simple schema. Note the `@key` directive, it tells the Apollo query planner that a particular instance of User can be fetched if you have its `id`. Also note that we extend the Query type.

```graphql

type User @key(fields: "id") {
  id: ID!
  name: String!
}

extend type Query {
  getUser(id: ID!): User
}
```

Our resolver has one extra method: `resolveReference`. It's called by the Apollo Gateway whenever a related resource requires a User instance. We'll see an example of this in the Posts service later on. Please note the `@ResolveReference` decorator.

```typescript

import { Args, Query, Resolver, ResolveReference } from '@nestjs/graphql';
import { UsersService } from './users.service';

@Resolver('User')
export class UsersResolvers {
  constructor(private readonly usersService: UsersService) {}

  @Query()
  getUser(@Args('id') id: string) {
    return this.usersService.findById(id);
  }

  @ResolveReference()
  resolveReference(reference: { __typename: string; id: string }) {
    return this.usersService.findById(reference.id);
  }
}
```

Finally, we hook everything up in a module together with a `GraphQLFederationModule`. This module accepts the same options as the regular `GraphQLModule`.

```typescript

import { Module } from '@nestjs/common';
import { GraphQLFederationModule } from '@nestjs/graphql';
import { UsersResolvers } from './users.resolvers';

@Module({
  imports: [
    GraphQLFederationModule.forRoot({
      typePaths: ['**/*.graphql'],
    }),
  ],
  providers: [UsersResolvers],
})
export class AppModule {}
```

#### Federated example: Posts[#](/graphql/federation#federated-example-posts)

The Posts service references the User type in its schema by marking it with the `extend` keyword. It also adds one property to the User type. Note the `@key` directive used for matching instances of User, and the `@external` directive indicating that the `id` field is managed elsewhere.

```graphql

type Post @key(fields: "id") {
  id: ID!
  title: String!
  body: String!
  user: User
}

extend type User @key(fields: "id") {
  id: ID! @external
  posts: [Post]
}

extend type Query {
  getPosts: [Post]
}
```

Our resolver has one method of interest here: `getUser`. It returns a reference containing `__typename` and any additional properties your application needs to resolve the reference, in this case only an `id`. The `__typename` is used by the GraphQL Gateway to pinpoint the microservice responsible for the User type and request the instance. The User service discussed above will be called on the `resolveReference` method.

```typescript

import { Query, Resolver, Parent, ResolveProperty } from '@nestjs/graphql';
import { PostsService } from './posts.service';
import { Post } from './posts.interfaces';

@Resolver('Post')
export class PostsResolvers {
  constructor(private readonly postsService: PostsService) {}

  @Query('getPosts')
  getPosts() {
    return this.postsService.findAll();
  }

  @ResolveProperty('user')
  getUser(@Parent() post: Post) {
    return { __typename: 'User', id: post.userId };
  }
}
```

The Posts service has virtually the same module, but is included below for the sake of completeness:

```typescript

import { Module } from '@nestjs/common';
import { GraphQLFederationModule } from '@nestjs/graphql';
import { PostsResolvers } from './posts.resolvers';

@Module({
  imports: [
    GraphQLFederationModule.forRoot({
      typePaths: ['**/*.graphql'],
    }),
  ],
  providers: [PostsResolvers],
})
export class AppModule {}
```

#### Federated example: Gateway[#](/graphql/federation#federated-example-gateway)

First install the optional dependency for the gateway: `npm install --save @apollo/gateway`.

Our gateway only needs a list of endpoints and will auto-discover the schemas from there. The code for our gateway is therefore very short:

```typescript

import { Module } from '@nestjs/common';
import { GraphQLGatewayModule } from '@nestjs/graphql';

@Module({
  imports: [
    GraphQLGatewayModule.forRoot({
      server: {
        // ... Apollo server options
        cors: true,
      },
      gateway: {
        serviceList: [
          { name: 'users', url: 'http://user-service/graphql' },
          { name: 'posts', url: 'http://post-service/graphql' },
        ],
      },
    }),
  ],
})
export class AppModule {}
```

> **Hint** Apollo recommends that you don't rely on the service discovery in a production environment but use their [Graph Manager](https://www.apollographql.com/docs/graph-manager/federation/) instead.

#### Sharing context[#](/graphql/federation#sharing-context)

You can customize the requests between the gateway and federated services using a build service. This allows you to share context about the request. You can easily extend the default `RemoteGraphQLDataSource` and implement one of the hooks. Please refer to [Apollo Docs](https://www.apollographql.com/docs/apollo-server/api/apollo-gateway/#remotegraphqldatasource) on `RemoteGraphQLDataSource` for more information about the possibilities.

```typescript

import { Module } from '@nestjs/common';
import { GATEWAY_BUILD_SERVICE, GraphQLGatewayModule } from '@nestjs/graphql';
import { RemoteGraphQLDataSource } from '@apollo/gateway';
import { decode } from 'jsonwebtoken';

class AuthenticatedDataSource extends RemoteGraphQLDataSource {
  async willSendRequest({ request, context }) {
    const { userId } = await decode(context.jwt);
    request.http.headers.set('x-user-id', userId);
  }
}

@Module({
  providers: [
    {
      provide: AuthenticatedDataSource,
      useValue: AuthenticatedDataSource,
    },
    {
      provide: GATEWAY_BUILD_SERVICE,
      useFactory: AuthenticatedDataSource => {
        return ({ name, url }) => new AuthenticatedDataSource({ url });
      },
      inject: [AuthenticatedDataSource],
    },
  ],
  exports: [GATEWAY_BUILD_SERVICE],
})
class BuildServiceModule {}

@Module({
  imports: [
    GraphQLGatewayModule.forRootAsync({
      useFactory: async () => ({
        gateway: {
          serviceList: [
            /* services */
          ],
        },
        server: {
          context: ({ req }) => ({
            jwt: req.headers.authorization,
          }),
        },
      }),
      imports: [BuildServiceModule],
      inject: [GATEWAY_BUILD_SERVICE],
    }),
  ],
})
export class AppModule {}
```

#### Async configuration[#](/graphql/federation#async-configuration)

Both the Federation and Gateway modules support asynchronous initialization using the same `forRootAsync` that's documented in [Quick start](/graphql/quick-start#async-configuration).

----
url: https://docs.nestjs.com/v5/fundamentals/custom-providers
----

### Custom providers

There are a lot of scenarios when you might want to bind something **directly** to the Nest inversion of control container. For example, any constant values, configuration objects created based on the current environment, external libraries, or pre-calculated values that depends on few other defined providers. Moreover, you are able to override default implementations, e.g. use different classes or make use of various test doubles (for testing purposes) when needed.

One essential thing that you should always keep in mind is that Nest uses **tokens** to identify dependencies. Usually, the auto-generated tokens are equal to classes. If you want to create a custom provider, you'd need to choose a token. Mostly, the custom tokens are represented by plain strings. Following best practices, you should hold those tokens in the separated file, for example, inside `constants.ts`.

Let's go through the available options.

#### Use value

The `useValue` syntax is useful when it comes to either define a constant value, put external library into Nest container, or replace a real implementation with the mock object.

TypeScript

```typescript

import { connection } from './connection';

const connectionProvider = {
  provide: 'Connection',
  useValue: connection,
};

@Module({
  providers: [connectionProvider],
})
export class ApplicationModule {}
```

In order to inject custom provider, we use the `@Inject()` decorator. This decorator takes a single argument - the token.

JS TS

TypeScript

```typescript

@Injectable()
class CatsRepository {
  constructor(@Inject('Connection') connection: Connection) {}
}
```

TypeScript

```typescript

@Injectable()
@Dependencies('Connection')
class CatsRepository {
  constructor(connection) {}
}
```

> **Hint** The `@Inject()` decorator is imported from `@nestjs/common` package.

When you want to override a default provider's value, let's say, you'd like to force Nest to use a mock `CatsService` due to testing purposes, you can simply use an existing class as a token.

TypeScript

```typescript

import { CatsService } from './cats.service';

const mockCatsService = {};
const catsServiceProvider = {
  provide: CatsService,
  useValue: mockCatsService,
};

@Module({
  imports: [CatsModule],
  providers: [catsServiceProvider],
})
export class ApplicationModule {}
```

In above example, the `CatsService` will be overridden by a passed `mockCatsService` mock object. It means, that Nest instead of creating `CatsService` instance manually, will treat this provider as resolved already, and use `mockCatsService` as its representative value.

#### Use class

The `useClass` syntax allows you using different class per chosen factors. For example, we have an abstract (or default) `ConfigService` class. Depending on the current environment, Nest should use a different implementation of the configuration service.

TypeScript

```typescript

const configServiceProvider = {
  provide: ConfigService,
  useClass: process.env.NODE_ENV === 'development'
    ? DevelopmentConfigService
    : ProductionConfigService,
};

@Module({
  providers: [configServiceProvider],
})
export class ApplicationModule {}
```

> **Notice** Instead of a custom token, we have used the `ConfigService` class, and therefore we have overridden the default implementation.

In this case, even if any class depends on `ConfigService`, Nest will inject an instance of the provided class (`DevelopmentConfigService` or `ProductionConfigService`) instead.

#### Use factory

The `useFactory` is a way of creating providers **dynamically**. The actual provider will be equal to a returned value of the factory function. The factory function can either depend on several different providers or stay completely independent. It means that factory may accept arguments, that Nest will resolve and pass during the instantiation process. Additionally, this function can return value **asynchronously**. It's explained in more detail [here](/v5/fundamentals/async-providers). Use it when your provider has to be dynamically calculated or in case to resolve an asynchronous operation.

JS TS

TypeScript

```typescript

const connectionFactory = {
  provide: 'Connection',
  useFactory: (optionsProvider: OptionsProvider) => {
    const options = optionsProvider.get();
    return new DatabaseConnection(options);
  },
  inject: [OptionsProvider],
};

@Module({
  providers: [connectionFactory],
})
export class ApplicationModule {}
```

TypeScript

```typescript

const connectionFactory = {
  provide: 'Connection',
  useFactory: (optionsProvider) => {
    const options = optionsProvider.get();
    return new DatabaseConnection(options);
  },
  inject: [OptionsProvider],
};

@Module({
  providers: [connectionFactory],
})
export class ApplicationModule {}
```

> **Hint** If your factory needs other providers, you have to pass their tokens inside the `inject` array. Nest will pass instances as arguments of the function in the same order.

#### Export custom provider

In order to export a custom provider, we can either use a token or a whole object. The following example shows a token case:

JS TS

TypeScript

```typescript

const connectionFactory = {
  provide: 'Connection',
  useFactory: (optionsProvider: OptionsProvider) => {
    const options = optionsProvider.get();
    return new DatabaseConnection(options);
  },
  inject: [OptionsProvider],
};

@Module({
  providers: [connectionFactory],
  exports: ['Connection'],
})
export class ApplicationModule {}
```

TypeScript

```typescript

const connectionFactory = {
  provide: 'Connection',
  useFactory: (optionsProvider) => {
    const options = optionsProvider.get();
    return new DatabaseConnection(options);
  },
  inject: [OptionsProvider],
};

@Module({
  providers: [connectionFactory],
  exports: ['Connection'],
})
export class ApplicationModule {}
```

But you can use a whole object as well:

JS TS

TypeScript

```typescript

const connectionFactory = {
  provide: 'Connection',
  useFactory: (optionsProvider: OptionsProvider) => {
    const options = optionsProvider.get();
    return new DatabaseConnection(options);
  },
  inject: [OptionsProvider],
};

@Module({
  providers: [connectionFactory],
  exports: [connectionFactory],
})
export class ApplicationModule {}
```

TypeScript

```typescript

const connectionFactory = {
  provide: 'Connection',
  useFactory: (optionsProvider) => {
    const options = optionsProvider.get();
    return new DatabaseConnection(options);
  },
  inject: [OptionsProvider],
};

@Module({
  providers: [connectionFactory],
  exports: [connectionFactory],
})
export class ApplicationModule {}
```

* Custom providers
* Use value
* Use class
* Use factory
* Export custom provider

----
url: https://docs.nestjs.com/v9/microservices/kafka
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Kafka](https://docs.nestjs.com/v9/microservices/kafka#kafka)
* [Installation](https://docs.nestjs.com/v9/microservices/kafka#installation)
* [Overview](https://docs.nestjs.com/v9/microservices/kafka#overview)
* [Options](https://docs.nestjs.com/v9/microservices/kafka#options)
* [Client](https://docs.nestjs.com/v9/microservices/kafka#client)
* [Message pattern](https://docs.nestjs.com/v9/microservices/kafka#message-pattern)
* [Message response subscription](https://docs.nestjs.com/v9/microservices/kafka#message-response-subscription)
* [Incoming](https://docs.nestjs.com/v9/microservices/kafka#incoming)
* [Outgoing](https://docs.nestjs.com/v9/microservices/kafka#outgoing)
* [Event-based](https://docs.nestjs.com/v9/microservices/kafka#event-based)
* [Context](https://docs.nestjs.com/v9/microservices/kafka#context)
* [Naming conventions](https://docs.nestjs.com/v9/microservices/kafka#naming-conventions)
* [Retriable exceptions](https://docs.nestjs.com/v9/microservices/kafka#retriable-exceptions)
* [Commit offsets](https://docs.nestjs.com/v9/microservices/kafka#commit-offsets)

```bash

$ npm i --save kafkajs
```

#### Overview[#](/microservices/kafka#overview)

Like other Nest microservice transport layer implementations, you select the Kafka transporter mechanism using the `transport` property of the options object passed to the `createMicroservice()` method, along with an optional `options` property, as shown below:

main.ts

JS TS

```typescript

const app = await NestFactory.createMicroservice<MicroserviceOptions>(AppModule, {
  transport: Transport.KAFKA,
  options: {
    client: {
      brokers: ['localhost:9092'],
    }
  }
});
```

```typescript

const app = await NestFactory.createMicroservice(AppModule, {
  transport: Transport.KAFKA,
  options: {
    client: {
      brokers: ['localhost:9092'],
    }
  }
});
```

> **Hint** The `Transport` enum is imported from the `@nestjs/microservices` package.

#### Options[#](/microservices/kafka#options)

The `options` property is specific to the chosen transporter. The **Kafka** transporter exposes the properties described below.

|                    |                                                                                                                 |
| ------------------ | --------------------------------------------------------------------------------------------------------------- |
| `client`           | Client configuration options (read more [here](https://kafka.js.org/docs/configuration))                        |
| `consumer`         | Consumer configuration options (read more [here](https://kafka.js.org/docs/consuming#a-name-options-a-options)) |
| `run`              | Run configuration options (read more [here](https://kafka.js.org/docs/consuming))                               |
| `subscribe`        | Subscribe configuration options (read more [here](https://kafka.js.org/docs/consuming#frombeginning))           |
| `producer`         | Producer configuration options (read more [here](https://kafka.js.org/docs/producing#options))                  |
| `send`             | Send configuration options (read more [here](https://kafka.js.org/docs/producing#options))                      |
| `producerOnlyMode` | Feature flag to skip consumer group registration and only act as a producer (`boolean`)                         |
| `postfixId`        | Change suffix of clientId value (`string`)                                                                      |

#### Client[#](/microservices/kafka#client)

There is a small difference in Kafka compared to other microservice transporters. Instead of the `ClientProxy` class, we use the `ClientKafka` class.

Like other microservice transporters, you have [several options](https://docs.nestjs.com/microservices/basics#client) for creating a `ClientKafka` instance.

One method for creating an instance is to use the `ClientsModule`. To create a client instance with the `ClientsModule`, import it and use the `register()` method to pass an options object with the same properties shown above in the `createMicroservice()` method, as well as a `name` property to be used as the injection token. Read more about `ClientsModule`[here](https://docs.nestjs.com/microservices/basics#client).

```typescript

@Module({
  imports: [
    ClientsModule.register([
      {
        name: 'HERO_SERVICE',
        transport: Transport.KAFKA,
        options: {
          client: {
            clientId: 'hero',
            brokers: ['localhost:9092'],
          },
          consumer: {
            groupId: 'hero-consumer'
          }
        }
      },
    ]),
  ]
  ...
})
```

Other options to create a client (either `ClientProxyFactory` or `@Client()`) can be used as well. You can read about them [here](https://docs.nestjs.com/microservices/basics#client).

Use the `@Client()` decorator as follows:

```typescript

@Client({
  transport: Transport.KAFKA,
  options: {
    client: {
      clientId: 'hero',
      brokers: ['localhost:9092'],
    },
    consumer: {
      groupId: 'hero-consumer'
    }
  }
})
client: ClientKafka;
```

> **Note** This section is only relevant if you use [request-response](/microservices/basics#request-response) message style (with the `@MessagePattern` decorator and the `ClientKafka#send` method). Subscribing to the response topic is not necessary for the [event-based](/microservices/basics#event-based) communication (`@EventPattern` decorator and `ClientKafka#emit` method).

The `ClientKafka` class provides the `subscribeToResponseOf()` method. The `subscribeToResponseOf()` method takes a request's topic name as an argument and adds the derived reply topic name to a collection of reply topics. This method is required when implementing the message pattern.

heroes.controller.ts

JS TS

```typescript

onModuleInit() {
  this.client.subscribeToResponseOf('hero.kill.dragon');
}
```

If the `ClientKafka` instance is created asynchronously, the `subscribeToResponseOf()` method must be called before calling the `connect()` method.

heroes.controller.ts

JS TS

```typescript

async onModuleInit() {
  this.client.subscribeToResponseOf('hero.kill.dragon');
  await this.client.connect();
}
```

#### Incoming[#](/microservices/kafka#incoming)

Nest receives incoming Kafka messages as an object with `key`, `value`, and `headers` properties that have values of type `Buffer`. Nest then parses these values by transforming the buffers into strings. If the string is "object like", Nest attempts to parse the string as `JSON`. The `value` is then passed to its associated handler.

#### Outgoing[#](/microservices/kafka#outgoing)

Nest sends outgoing Kafka messages after a serialization process when publishing events or sending messages. This occurs on arguments passed to the `ClientKafka``emit()` and `send()` methods or on values returned from a `@MessagePattern` method. This serialization "stringifies" objects that are not strings or buffers by using `JSON.stringify()` or the `toString()` prototype method.

heroes.controller.ts

JS TS

```typescript

@Controller()
export class HeroesController {
  @MessagePattern('hero.kill.dragon')
  killDragon(@Payload() message: KillDragonMessage): any {
    const dragonId = message.dragonId;
    const items = [
      { id: 1, name: 'Mythical Sword' },
      { id: 2, name: 'Key to Dungeon' },
    ];
    return items;
  }
}
```

> **Hint**`@Payload()` is imported from the `@nestjs/microservices`.

Outgoing messages can also be keyed by passing an object with the `key` and `value` properties. Keying messages is important for meeting the [co-partitioning requirement](https://docs.confluent.io/current/ksql/docs/developer-guide/partition-data.html#co-partitioning-requirements).

heroes.controller.ts

JS TS

```typescript

@Controller()
export class HeroesController {
  @MessagePattern('hero.kill.dragon')
  killDragon(@Payload() message: KillDragonMessage): any {
    const realm = 'Nest';
    const heroId = message.heroId;
    const dragonId = message.dragonId;

    const items = [
      { id: 1, name: 'Mythical Sword' },
      { id: 2, name: 'Key to Dungeon' },
    ];

    return {
      headers: {
        realm
      },
      key: heroId,
      value: items
    }
  }
}
```

Additionally, messages passed in this format can also contain custom headers set in the `headers` hash property. Header hash property values must be either of type `string` or type `Buffer`.

heroes.controller.ts

JS TS

```typescript

@Controller()
export class HeroesController {
  @MessagePattern('hero.kill.dragon')
  killDragon(@Payload() message: KillDragonMessage): any {
    const realm = 'Nest';
    const heroId = message.heroId;
    const dragonId = message.dragonId;

    const items = [
      { id: 1, name: 'Mythical Sword' },
      { id: 2, name: 'Key to Dungeon' },
    ];

    return {
      headers: {
        kafka_nestRealm: realm
      },
      key: heroId,
      value: items
    }
  }
}
```

#### Event-based[#](/microservices/kafka#event-based)

While the request-response method is ideal for exchanging messages between services, it is less suitable when your message style is event-based (which in turn is ideal for Kafka) - when you just want to publish events **without waiting for a response**. In that case, you do not want the overhead required by request-response for maintaining two topics.

Check out these two sections to learn more about this: [Overview: Event-based](/microservices/basics#event-based) and [Overview: Publishing events](/microservices/basics#publishing-events).

#### Context[#](/microservices/kafka#context)

In more sophisticated scenarios, you may want to access more information about the incoming request. When using the Kafka transporter, you can access the `KafkaContext` object.

JS TS

```typescript

@MessagePattern('hero.kill.dragon')
killDragon(@Payload() message: KillDragonMessage, @Ctx() context: KafkaContext) {
  console.log(`Topic: ${context.getTopic()}`);
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('hero.kill.dragon')
killDragon(message, context) {
  console.log(`Topic: ${context.getTopic()}`);
}
```

> **Hint**`@Payload()`, `@Ctx()` and `KafkaContext` are imported from the `@nestjs/microservices` package.

To access the original Kafka `IncomingMessage` object, use the `getMessage()` method of the `KafkaContext` object, as follows:

JS TS

```typescript

@MessagePattern('hero.kill.dragon')
killDragon(@Payload() message: KillDragonMessage, @Ctx() context: KafkaContext) {
  const originalMessage = context.getMessage();
  const partition = context.getPartition();
  const { headers, timestamp } = originalMessage;
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('hero.kill.dragon')
killDragon(message, context) {
  const originalMessage = context.getMessage();
  const partition = context.getPartition();
  const { headers, timestamp } = originalMessage;
}
```

Where the `IncomingMessage` fulfills the following interface:

```typescript

interface IncomingMessage {
  topic: string;
  partition: number;
  timestamp: string;
  size: number;
  attributes: number;
  offset: string;
  key: any;
  value: any;
  headers: Record<string, any>;
}
```

If your handler involves a slow processing time for each received message you should consider using the `heartbeat` callback. To retrieve the `heartbeat` function, use the `getHeartbeat()` method of the `KafkaContext`, as follows:

JS TS

```typescript

@MessagePattern('hero.kill.dragon')
async killDragon(@Payload() message: KillDragonMessage, @Ctx() context: KafkaContext) {
  const heartbeat = context.getHeartbeat();

  // Do some slow processing
  await doWorkPart1();

  // Send heartbeat to not exceed the sessionTimeout
  await heartbeat();

  // Do some slow processing again
  await doWorkPart2();
}
```

#### Naming conventions[#](/microservices/kafka#naming-conventions)

The Kafka microservice components append a description of their respective role onto the `client.clientId` and `consumer.groupId` options to prevent collisions between Nest microservice client and server components. By default the `ClientKafka` components append `-client` and the `ServerKafka` components append `-server` to both of these options. Note how the provided values below are transformed in that way (as shown in the comments).

main.ts

JS TS

```typescript

const app = await NestFactory.createMicroservice<MicroserviceOptions>(AppModule, {
  transport: Transport.KAFKA,
  options: {
    client: {
      clientId: 'hero', // hero-server
      brokers: ['localhost:9092'],
    },
    consumer: {
      groupId: 'hero-consumer' // hero-consumer-server
    },
  }
});
```

And for the client:

heroes.controller.ts

JS TS

```typescript

@Client({
  transport: Transport.KAFKA,
  options: {
    client: {
      clientId: 'hero', // hero-client
      brokers: ['localhost:9092'],
    },
    consumer: {
      groupId: 'hero-consumer' // hero-consumer-client
    }
  }
})
client: ClientKafka;
```

> **Hint** Kafka client and consumer naming conventions can be customized by extending `ClientKafka` and `KafkaServer` in your own custom provider and overriding the constructor.

Since the Kafka microservice message pattern utilizes two topics for the request and reply channels, a reply pattern should be derived from the request topic. By default, the name of the reply topic is the composite of the request topic name with `.reply` appended.

heroes.controller.ts

JS TS

```typescript

onModuleInit() {
  this.client.subscribeToResponseOf('hero.get'); // hero.get.reply
}
```

> **Hint** Kafka reply topic naming conventions can be customized by extending `ClientKafka` in your own custom provider and overriding the `getResponsePatternName` method.

#### Retriable exceptions[#](/microservices/kafka#retriable-exceptions)

Similar to other transporters, all unhandled exceptions are automatically wrapped into an `RpcException` and converted to a "user-friendly" format. However, there are edge-cases when you might want to bypass this mechanism and let exceptions be consumed by the `kafkajs` driver instead. Throwing an exception when processing a message instructs `kafkajs` to **retry** it (redeliver it) which means that even though the message (or event) handler was triggered, the offset won't be committed to Kafka.

> **Warning** For event handlers (event-based communication), all unhandled exceptions are considered **retriable exceptions** by default.

For this, you can use a dedicated class called `KafkaRetriableException`, as follows:

```typescript

throw new KafkaRetriableException('...');
```

> **Hint**`KafkaRetriableException` class is exported from the `@nestjs/microservices` package.

#### Commit offsets[#](/microservices/kafka#commit-offsets)

Committing offsets is essential when working with Kafka. Per default, messages will be automatically committed after a specific time. For more information visit [KafkaJS docs](https://kafka.js.org/docs/consuming#autocommit). `ClientKafka` offers a way to manually commit offsets that work like the [native KafkaJS implementation](https://kafka.js.org/docs/consuming#manual-committing).

JS TS

```typescript

@EventPattern('user.created')
async handleUserCreated(@Payload() data: IncomingMessage, @Ctx() context: KafkaContext) {
  // business logic
  
  const { offset } = context.getMessage();
  const partition = context.getPartition();
  const topic = context.getTopic();
  await this.client.commitOffsets([{ topic, partition, offset }])
}
```

```typescript

@Bind(Payload(), Ctx())
@EventPattern('user.created')
async handleUserCreated(data, context) {
  // business logic

  const { offset } = context.getMessage();
  const partition = context.getPartition();
  const topic = context.getTopic();
  await this.client.commitOffsets([{ topic, partition, offset }])
}
```

To disable auto-committing of messages set `autoCommit: false` in the `run` configuration, as follows:

main.ts

JS TS

```typescript

const app = await NestFactory.createMicroservice<MicroserviceOptions>(AppModule, {
  transport: Transport.KAFKA,
  options: {
    client: {
      brokers: ['localhost:9092'],
    },
    run: {
      autoCommit: false
    }
  }
});
```

```typescript

const app = await NestFactory.createMicroservice(AppModule, {
  transport: Transport.KAFKA,
  options: {
    client: {
      brokers: ['localhost:9092'],
    },
    run: {
      autoCommit: false
    }
  }
});
```

----
url: https://docs.nestjs.com/v5/websockets/interceptors
----

### Interceptors

There is no difference between [regular interceptors](/v5/interceptors) and the web sockets interceptors. Here is an example that makes use of a manually instantiated **method-scoped** filter (class-scoped works either):

TypeScript

```typescript

@UseInterceptors(new TransformInterceptor())
@SubscribeMessage('events')
onEvent(client, data: any): WsResponse<any> {
  const event = 'events';
  return { event, data };
}
```

----
url: https://docs.nestjs.com/v6/fundamentals/platform-agnosticism
----

* [Platform agnosticism](https://docs.nestjs.com/v6/fundamentals/platform-agnosticism#platform-agnosticism)
* [Build once, use everywhere](https://docs.nestjs.com/v6/fundamentals/platform-agnosticism#build-once-use-everywhere)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/fundamentals/platform-agnosticism.md "Suggest Edits")

### Platform agnosticism

Nest is a platform-agnostic framework. This means you can develop **reusable logical parts** that can be used across different types of applications. For example, most components can be re-used without change across different underlying HTTP server frameworks (e.g., Express and Fastify), and even across different *types* of applications (e.g., HTTP server frameworks, Microservices with different transport layers, and Web Sockets).

#### Build once, use everywhere[#](/fundamentals/platform-agnosticism#build-once-use-everywhere)

The **Overview** section of the documentation primarily shows coding techniques using HTTP server frameworks (e.g., apps providing a REST API or providing an MVC-style server-side rendered app). However, all those building blocks can be used on top of different transport layers ([microservices](/v6/microservices/basics) or [websockets](/v6/websockets/gateways)).

Furthermore, Nest comes with a dedicated [GraphQL](/v6/graphql/quick-start) module. You can use GraphQL as your API layer interchangeably with providing a REST API.

In addition, the [application context](/v6/application-context) feature helps to create any kind of Node.js application - including things like CRON jobs and CLI apps - on top of Nest.

Nest aspires to be a full-fledged platform for Node.js apps that brings a higher-level of modularity and reusability to your applications. Build once, use everywhere!

----
url: https://docs.nestjs.com/observability/manual-instrumentation
----

[Skip to content](#content)

On this page

* [Manual instrumentation](https://docs.nestjs.com/observability/manual-instrumentation#manual-instrumentation)
* [Creating spans](https://docs.nestjs.com/observability/manual-instrumentation#creating-spans)
* [Capturing handled errors](https://docs.nestjs.com/observability/manual-instrumentation#capturing-handled-errors)
* [Request-scoped attributes](https://docs.nestjs.com/observability/manual-instrumentation#request-scoped-attributes)
* [Custom metrics](https://docs.nestjs.com/observability/manual-instrumentation#custom-metrics)
* [API summary](https://docs.nestjs.com/observability/manual-instrumentation#api-summary)
* [Where to go next](https://docs.nestjs.com/observability/manual-instrumentation#where-to-go-next)

### Manual instrumentation

Most of the SDK is automatic instrumentation: you configure it once and it decides what to record. `TracerService` is the manual half. Inject it anywhere in your application to add spans inside an already-traced request, attach context to that request, capture errors you handled yourself, and report your own metrics.

cats.service.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { TracerService } from '@nestjs/observe';

@Injectable()
export class CatsService {
  constructor(private readonly tracerService: TracerService) {}
}
```

`ObserveModule.forRoot()` registers a global module that exports `TracerService`, so you can inject it in any module without importing `ObserveModule` again. (`forRootAsync()` is global too, unless you pass `global: false`.) Every method reads the trace from the ambient async context, so calling one outside of a request, job, or other instrumented operation throws: there is no trace to attach to. This is deliberate, because a silently dropped span is harder to notice than an error. The exceptions are `currentTraceId()`, which returns `null` instead, and [custom metrics](/observability/manual-instrumentation#custom-metrics), which aren't tied to a trace.

#### Creating spans[#](/observability/manual-instrumentation#creating-spans)

`createSpan(name, callback)` runs the callback inside a new span nested under the currently active one, and returns a promise of the callback's return value. The span's duration is the callback's duration, so `await` anything you want measured:

cats.service.ts

JS TS

```typescript

async findOne(id: string, activeUser: ActiveUserData) {
  return this.tracerService.createSpan('cats.findOne', async (span) => {
    span.addTags({ userId: activeUser.sub, catId: id });
    return this.catsRepository.findOne(id);
  });
}
```

Spans nest by call stack: a `createSpan()` inside another `createSpan()` callback becomes its child, which produces the waterfall on the trace detail page. The callback may be synchronous or asynchronous. Auto-instrumented spans (controller methods, providers, database calls) and your custom spans share the same tree, so a hand-named span appears exactly where it ran relative to everything else.

The `span` argument is a `TraceSpanDelegate`. Its `addTags(tags)` method (or `setTag(key, value)` for a single entry) attaches key-value pairs to that span alone. Like the `tags`/`setAttributes` options described in [SDK → Tags and custom attributes](/observability/sdk#tags-and-custom-attributes), they're searchable and shown on the span in the trace view. The difference is scope: those options cover every request, while these tags cover one span.

`activeSpan()` resolves to the `TraceSpanDelegate` of the currently active span without creating a new one. Use it to tag the enclosing span from code that didn't create it:

```typescript

const span = await this.tracerService.activeSpan();
span.addTags({ cacheHit: 'false' });
```

It rejects if no span is active for the current trace.

> **Hint** The **Spans** analytics view aggregates by span name, across every route that calls them. Pick names that describe the work (`orders.recalculate`, `cache.lookup`) rather than the caller, so the dashboard can tell you whether something is slow everywhere or only from one endpoint.

#### Capturing handled errors[#](/observability/manual-instrumentation#capturing-handled-errors)

Errors that propagate out of a controller, job, or span are recorded automatically. `captureError()` is for the ones that don't: anything you caught and handled but still want visible in the dashboard:

```typescript

try {
  await this.billing.sync(accountId);
} catch (error) {
  await this.tracerService.captureError(error as Error, {
    accountId,
    retryable: 'true',
  });
}
```

The error is attached to the current trace, with the optional tags recorded alongside it, and gets the same source-context treatment as any other captured error if [`sourceContext`](/observability/sdk#error-source-context) is enabled.

#### Request-scoped attributes[#](/observability/manual-instrumentation#request-scoped-attributes)

`setAttribute(key, value)` and `getAttribute(key)` write and read the trace's own context store. Its values live for the duration of the request and are readable from anywhere downstream, without threading them through every function signature:

```typescript

this.tracerService.setAttribute('tenantId', tenant.id);
// ...later, in a different service on the same request
const tenantId = this.tracerService.getAttribute('tenantId');
```

`getAttribute()` returns `undefined` for a key that was never set. Both throw when called outside a traced context.

The trace id lives in the same store, so `getAttribute(traceIdKey)` retrieves the current trace id, e.g., to correlate with an external system or to [propagate it to another service](/observability/distributed-tracing). `currentTraceId()` is a shorthand for that lookup with one deliberate difference: it returns `null` outside a traced context instead of throwing, because forwarding a trace id downstream can legitimately happen when there is no trace yet.

To type the store, pass its shape as `TracerService`'s first type argument. Keys and values are then checked against it, including nested paths:

```typescript

interface RequestStore {
  tenantId: string;
  flags: { betaCheckout: boolean };
}

@Injectable()
export class CheckoutService {
  constructor(private readonly tracerService: TracerService<RequestStore>) {}

  enableBeta() {
    this.tracerService.setAttribute('flags.betaCheckout', true);
  }
}
```

> **Hint**`ObserveModule` also exports the `AsyncLocalStorage` instance that holds the trace context. `setAttribute()`/`getAttribute()` are the supported way to reach it; inject the store directly only if you need something they don't expose. If you already use the pattern described in the [Async local storage](/recipes/async-local-storage) recipe, this store can replace your hand-rolled one.

#### Custom metrics[#](/observability/manual-instrumentation#custom-metrics)

Three metric types are available, each created by name (or retrieved, if the name already exists). They report into the **Custom** section of the dashboard, and you can alert on them like any built-in metric.

Unlike the methods above, metrics aren't tied to a trace, so you can report them from anywhere, including startup and shutdown code, `onModuleInit()` hooks, and cron jobs.

| Method    | For                                                                        | Reporting method                                |
| --------- | -------------------------------------------------------------------------- | ----------------------------------------------- |
| `counter` | Values that only go up - requests served, orders placed, retries attempted | `increment()`                                   |
| `gauge`   | Values that go up and down - queue depth, active connections, cache ratio  | `increment()`, `decrement()`, `setValue(value)` |
| `summary` | Distributions you want quantiles over - latency, payload size              | `observe(value)`                                |

cats.service.ts

JS TS

```typescript

this.tracerService
  .counter('cats.lookups', { description: 'Number of cat lookups' })
  .increment();

this.tracerService
  .gauge('cats.active.sessions', {
    kind: 'ratio',
    initialValue: 0,
    description: 'Number of active sessions',
  })
  .increment();

const latency = this.tracerService.summary('cats.lookup.duration', {
  description: 'Duration of cat lookups in milliseconds',
});
const startedAt = performance.now();
try {
  return await this.catsRepository.findOne(id);
} finally {
  // Observed in a finally so a failed lookup still lands in the distribution -
  // dropping the slow failures is how a latency summary ends up flattering itself.
  latency.observe(performance.now() - startedAt);
}
```

Calling `counter('orders.placed')` twice returns the same instance, so you don't need to hold a reference in a field, though doing so is cheaper on a hot path. Passing attributes on a later call updates the existing metric's description and labels in place.

| Attribute      | Applies to              | Description                                                                                                                           |
| -------------- | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| `description`  | counter, gauge, summary | Shown alongside the metric in the dashboard. Worth setting: a bare metric name rarely explains itself to a future reader.             |
| `labels`       | counter, gauge, summary | Dimensions the metric is broken down by, so the chart can be split rather than showing one aggregate line.                            |
| `initialValue` | counter, gauge          | Starting value. Only applied while the metric is still at `0`, so a restart-time declaration doesn't clobber a value already counted. |
| `kind`         | gauge                   | `'ratio'` (default) for values that stand alone per report, or `'additive'` for values that sum across reporting instances.           |
| `sampleSize`   | summary                 | How many observations per label are retained to compute quantiles from, which bounds the summary's memory under load.                 |

A metric that has been declared but never reported reads as "unknown" rather than `0` in the dashboard. This is a real state, not missing data: "we have never heard from this metric" and "this metric is currently zero" are different facts, and showing the second in place of the first would hide a broken deploy.

#### API summary[#](/observability/manual-instrumentation#api-summary)

| Method                       | Needs a trace | Description                                                |
| ---------------------------- | :-----------: | ---------------------------------------------------------- |
| `createSpan(name, callback)` |       ✓       | Run `callback` inside a new child span; returns its result |
| `activeSpan()`               |       ✓       | Resolves to the `TraceSpanDelegate` of the span in flight  |
| `captureError(error, tags?)` |       ✓       | Record a handled error on the current trace                |
| `setAttribute(key, value)`   |       ✓       | Write to the request-scoped context store                  |
| `getAttribute(key)`          |       ✓       | Read from the request-scoped context store                 |
| `currentTraceId()`           |       ✗       | The active trace id, or `null` outside a trace             |
| `counter(name, attributes?)` |       ✗       | Get or create a monotonically increasing metric            |
| `gauge(name, attributes?)`   |       ✗       | Get or create a metric that can go up and down             |
| `summary(name, attributes?)` |       ✗       | Get or create a distribution metric with quantiles         |

#### Where to go next[#](/observability/manual-instrumentation#where-to-go-next)

* [Distributed tracing](/observability/distributed-tracing) - use `currentTraceId()` to keep one trace across service boundaries.
* [Dashboard](/observability/dashboard) - where spans, captured errors, and custom metrics show up.

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/observability/manual-instrumentation.md)

----
url: https://docs.nestjs.com/v8/recipes/cqrs
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [CQRS](https://docs.nestjs.com/v8/recipes/cqrs#cqrs)
* [Installation](https://docs.nestjs.com/v8/recipes/cqrs#installation)
* [Commands](https://docs.nestjs.com/v8/recipes/cqrs#commands)
* [Events](https://docs.nestjs.com/v8/recipes/cqrs#events)
* [Sagas](https://docs.nestjs.com/v8/recipes/cqrs#sagas)
* [Queries](https://docs.nestjs.com/v8/recipes/cqrs#queries)
* [Setup](https://docs.nestjs.com/v8/recipes/cqrs#setup)
* [Summary](https://docs.nestjs.com/v8/recipes/cqrs#summary)
* [Example](https://docs.nestjs.com/v8/recipes/cqrs#example)

```bash

$ npm install --save @nestjs/cqrs
```

#### Commands[#](/recipes/cqrs#commands)

In this model, each action is called a **Command**. When a command is dispatched, the application reacts to it. Commands can be dispatched from the services layer, or directly from controllers/gateways. Commands are consumed by **Command Handlers**.

heroes-game.service.ts

JS TS

```typescript

@Injectable()
export class HeroesGameService {
  constructor(private commandBus: CommandBus) {}

  async killDragon(heroId: string, killDragonDto: KillDragonDto) {
    return this.commandBus.execute(
      new KillDragonCommand(heroId, killDragonDto.dragonId)
    );
  }
}
```

```typescript

@Injectable()
@Dependencies(CommandBus)
export class HeroesGameService {
  constructor(commandBus) {
    this.commandBus = commandBus;
  }

  async killDragon(heroId, killDragonDto) {
    return this.commandBus.execute(
      new KillDragonCommand(heroId, killDragonDto.dragonId)
    );
  }
}
```

Here's a sample service that dispatches `KillDragonCommand`. Let's see how the command looks:

kill-dragon.command.ts

JS TS

```typescript

export class KillDragonCommand {
  constructor(
    public readonly heroId: string,
    public readonly dragonId: string,
  ) {}
}
```

```typescript

export class KillDragonCommand {
  constructor(heroId, dragonId) {
    this.heroId = heroId;
    this.dragonId = dragonId;
  }
}
```

The `CommandBus` is a **stream** of commands. It delegates commands to the equivalent handlers. Each command must have a corresponding **Command Handler**:

kill-dragon.handler.ts

JS TS

```typescript

@CommandHandler(KillDragonCommand)
export class KillDragonHandler implements ICommandHandler<KillDragonCommand> {
  constructor(private repository: HeroRepository) {}

  async execute(command: KillDragonCommand) {
    const { heroId, dragonId } = command;
    const hero = this.repository.findOneById(+heroId);

    hero.killEnemy(dragonId);
    await this.repository.persist(hero);
  }
}
```

```typescript

@CommandHandler(KillDragonCommand)
@Dependencies(HeroRepository)
export class KillDragonHandler {
  constructor(repository) {
    this.repository = repository;
  }

  async execute(command) {
    const { heroId, dragonId } = command;
    const hero = this.repository.findOneById(+heroId);

    hero.killEnemy(dragonId);
    await this.repository.persist(hero);
  }
}
```

With this approach, every application state change is driven by the occurrence of a **Command**. The logic is encapsulated in handlers. With this approach, we can simply add behavior like logging or persisting commands in the database (e.g., for diagnostics purposes).

#### Events[#](/recipes/cqrs#events)

Command handlers neatly encapsulate logic. While beneficial, the application structure is still not flexible enough, not **reactive**. To remedy this, we also introduce **events**.

hero-killed-dragon.event.ts

JS TS

```typescript

export class HeroKilledDragonEvent {
  constructor(
    public readonly heroId: string,
    public readonly dragonId: string,
  ) {}
}
```

```typescript

export class HeroKilledDragonEvent {
  constructor(heroId, dragonId) {
    this.heroId = heroId;
    this.dragonId = dragonId;
  }
}
```

Events are asynchronous. They are dispatched either by **models** or directly using `EventBus`. In order to dispatch events, models have to extend the `AggregateRoot` class.

hero.model.ts

JS TS

```typescript

export class Hero extends AggregateRoot {
  constructor(private id: string) {
    super();
  }

  killEnemy(enemyId: string) {
    // logic
    this.apply(new HeroKilledDragonEvent(this.id, enemyId));
  }
}
```

```typescript

export class Hero extends AggregateRoot {
  constructor(id) {
    super();
    this.id = id;
  }

  killEnemy(enemyId) {
    // logic
    this.apply(new HeroKilledDragonEvent(this.id, enemyId));
  }
}
```

The `apply()` method does not dispatch events yet because there's no relationship between the model and the `EventPublisher` class. How do we associate the model and the publisher? By using a publisher `mergeObjectContext()` method inside our command handler.

kill-dragon.handler.ts

JS TS

```typescript

@CommandHandler(KillDragonCommand)
export class KillDragonHandler implements ICommandHandler<KillDragonCommand> {
  constructor(
    private repository: HeroRepository,
    private publisher: EventPublisher,
  ) {}

  async execute(command: KillDragonCommand) {
    const { heroId, dragonId } = command;
    const hero = this.publisher.mergeObjectContext(
      await this.repository.findOneById(+heroId),
    );
    hero.killEnemy(dragonId);
    hero.commit();
  }
}
```

```typescript

@CommandHandler(KillDragonCommand)
@Dependencies(HeroRepository, EventPublisher)
export class KillDragonHandler {
  constructor(repository, publisher) {
    this.repository = repository;
    this.publisher = publisher;
  }

  async execute(command) {
    const { heroId, dragonId } = command;
    const hero = this.publisher.mergeObjectContext(
      await this.repository.findOneById(+heroId),
    );
    hero.killEnemy(dragonId);
    hero.commit();
  }
}
```

Now everything works as expected. Notice that we need to `commit()` events since they're not being dispatched immediately. Obviously, an object doesn't have to exist up front. We can easily merge type context as well:

```typescript

const HeroModel = this.publisher.mergeClassContext(Hero);
new HeroModel('id');
```

Now the model has the ability to publish events. Additionally, we can emit events manually using `EventBus`:

```typescript

this.eventBus.publish(new HeroKilledDragonEvent());
```

> **Hint** The `EventBus` is an injectable class.

Each event can have multiple **Event Handlers**.

hero-killed-dragon.handler.ts

JS TS

```typescript

@EventsHandler(HeroKilledDragonEvent)
export class HeroKilledDragonHandler implements IEventHandler<HeroKilledDragonEvent> {
  constructor(private repository: HeroRepository) {}

  handle(event: HeroKilledDragonEvent) {
    // logic
  }
}
```

Now we can move the **write logic** into the event handlers.

#### Sagas[#](/recipes/cqrs#sagas)

This type of **Event-Driven Architecture** improves application **reactiveness and scalability**. Now, when we have events, we can simply react to them in various ways. **Sagas** are the final building block from an architectural point of view.

Sagas are an extremely powerful feature. A single saga may listen for 1..\* events. Using the [RxJS](https://github.com/ReactiveX/rxjs) library, it can combine, merge, filter or apply other `RxJS` operators on the event stream. Each saga returns an Observable which contains a command. This command is dispatched **asynchronously**.

heroes-game.saga.ts

JS TS

```typescript

@Injectable()
export class HeroesGameSagas {
  @Saga()
  dragonKilled = (events$: Observable<any>): Observable<ICommand> => {
    return events$.pipe(
      ofType(HeroKilledDragonEvent),
      map((event) => new DropAncientItemCommand(event.heroId, fakeItemID)),
    );
  }
}
```

```typescript

@Injectable()
export class HeroesGameSagas {
  @Saga()
  dragonKilled = (events$) => {
    return events$.pipe(
      ofType(HeroKilledDragonEvent),
      map((event) => new DropAncientItemCommand(event.heroId, fakeItemID)),
    );
  }
}
```

> **Hint** The `ofType` operator is exported from the `@nestjs/cqrs` package.

```typescript

export const CommandHandlers = [KillDragonHandler, DropAncientItemHandler];
export const EventHandlers =  [HeroKilledDragonHandler, HeroFoundItemHandler];

@Module({
  imports: [CqrsModule],
  controllers: [HeroesGameController],
  providers: [
    HeroesGameService,
    HeroesGameSagas,
    ...CommandHandlers,
    ...EventHandlers,
    HeroRepository,
  ]
})
export class HeroesGameModule {}
```

#### Summary[#](/recipes/cqrs#summary)

`CommandBus`, `QueryBus` and `EventBus` are **Observables**. This means that you can easily subscribe to the whole stream and enrich your application with **Event Sourcing**.

#### Example[#](/recipes/cqrs#example)

A working example is available [here](https://github.com/kamilmysliwiec/nest-cqrs-example).

----
url: https://docs.nestjs.com/v7/recipes/documentation
----

* [Documentation](https://docs.nestjs.com/v7/recipes/documentation#documentation)
* [Setup](https://docs.nestjs.com/v7/recipes/documentation#setup)
* [Generation](https://docs.nestjs.com/v7/recipes/documentation#generation)
* [Contribute](https://docs.nestjs.com/v7/recipes/documentation#contribute)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/recipes/documentation.md "Suggest Edits")

### Documentation

**Compodoc** is a documentation tool for Angular applications. Since Nest and Angular share similar project and code structures, **Compodoc** works with Nest applications as well.

#### Setup[#](/recipes/documentation#setup)

Setting up Compodoc inside an existing Nest project is very simple. Start by adding the dev-dependency with the following command in your OS terminal:

```bash

$ npm i -D @compodoc/compodoc
```

#### Generation[#](/recipes/documentation#generation)

Generate project documentation using the following command (npm 6 is required for `npx` support). See [the official documentation](https://compodoc.app/guides/usage.html) for more options.

```bash

$ npx @compodoc/compodoc -p tsconfig.json -s
```

Open your browser and navigate to <http://localhost:8080>. You should see an initial Nest CLI project:

#### Contribute[#](/recipes/documentation#contribute)

You can participate and contribute to the Compodoc project [here](https://github.com/compodoc/compodoc).

----
url: https://docs.nestjs.com/v11/techniques/serialization
----

* [Serialization](https://docs.nestjs.com/v11/techniques/serialization#serialization)
* [Overview](https://docs.nestjs.com/v11/techniques/serialization#overview)
* [Exclude properties](https://docs.nestjs.com/v11/techniques/serialization#exclude-properties)
* [Expose properties](https://docs.nestjs.com/v11/techniques/serialization#expose-properties)
* [Transform](https://docs.nestjs.com/v11/techniques/serialization#transform)
* [Pass options](https://docs.nestjs.com/v11/techniques/serialization#pass-options)
* [Transform plain objects](https://docs.nestjs.com/v11/techniques/serialization#transform-plain-objects)
* [Example](https://docs.nestjs.com/v11/techniques/serialization#example)
* [WebSockets and Microservices](https://docs.nestjs.com/v11/techniques/serialization#websockets-and-microservices)
* [Learn more](https://docs.nestjs.com/v11/techniques/serialization#learn-more)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/techniques/serialization.md "Suggest Edits")

### Serialization

Serialization is a process that happens before objects are returned in a network response. This is an appropriate place to provide rules for transforming and sanitizing the data to be returned to the client. For example, sensitive data like passwords should always be excluded from the response. Or, certain properties might require additional transformation, such as sending only a subset of properties of an entity. Performing these transformations manually can be tedious and error prone, and can leave you uncertain that all cases have been covered.

#### Overview[#](/techniques/serialization#overview)

Nest provides a built-in capability to help ensure that these operations can be performed in a straightforward way. The `ClassSerializerInterceptor` interceptor uses the powerful [class-transformer](https://github.com/typestack/class-transformer) package to provide a declarative and extensible way of transforming objects. The basic operation it performs is to take the value returned by a method handler and apply the `instanceToPlain()` function from [class-transformer](https://github.com/typestack/class-transformer). In doing so, it can apply rules expressed by `class-transformer` decorators on an entity/DTO class, as described below.

> **Hint** The serialization does not apply to [StreamableFile](https://docs.nestjs.com/techniques/streaming-files#streamable-file-class) responses.

#### Exclude properties[#](/techniques/serialization#exclude-properties)

Let's assume that we want to automatically exclude a `password` property from a user entity. We annotate the entity as follows:

```typescript

import { Exclude } from 'class-transformer';

export class UserEntity {
  id: number;
  firstName: string;
  lastName: string;

  @Exclude()
  password: string;

  constructor(partial: Partial<UserEntity>) {
    Object.assign(this, partial);
  }
}
```

Now consider a controller with a method handler that returns an instance of this class.

```typescript

@UseInterceptors(ClassSerializerInterceptor)
@Get()
findOne(): UserEntity {
  return new UserEntity({
    id: 1,
    firstName: 'John',
    lastName: 'Doe',
    password: 'password',
  });
}
```

> **Warning** Note that we must return an instance of the class. If you return a plain JavaScript object, for example, `{ user: new UserEntity() }`, the object won't be properly serialized.

> **Hint** The `ClassSerializerInterceptor` is imported from `@nestjs/common`.

When this endpoint is requested, the client receives the following response:

```json

{
  "id": 1,
  "firstName": "John",
  "lastName": "Doe"
}
```

Note that the interceptor can be applied application-wide (as covered [here](https://docs.nestjs.com/interceptors#binding-interceptors)). The combination of the interceptor and the entity class declaration ensures that **any** method that returns a `UserEntity` will be sure to remove the `password` property. This gives you a measure of centralized enforcement of this business rule.

#### Expose properties[#](/techniques/serialization#expose-properties)

You can use the `@Expose()` decorator to provide alias names for properties, or to execute a function to calculate a property value (analogous to **getter** functions), as shown below.

```typescript

@Expose()
get fullName(): string {
  return `${this.firstName} ${this.lastName}`;
}
```

#### Transform[#](/techniques/serialization#transform)

You can perform additional data transformation using the `@Transform()` decorator. For example, the following construct returns the name property of the `RoleEntity` instead of returning the whole object.

```typescript

@Transform(({ value }) => value.name)
role: RoleEntity;
```

#### Pass options[#](/techniques/serialization#pass-options)

You may want to modify the default behavior of the transformation functions. To override default settings, pass them in an `options` object with the `@SerializeOptions()` decorator.

```typescript

@SerializeOptions({
  excludePrefixes: ['_'],
})
@Get()
findOne(): UserEntity {
  return new UserEntity();
}
```

> **Hint** The `@SerializeOptions()` decorator is imported from `@nestjs/common`.

Options passed via `@SerializeOptions()` are passed as the second argument of the underlying `instanceToPlain()` function. In this example, we are automatically excluding all properties that begin with the `_` prefix.

#### Transform plain objects[#](/techniques/serialization#transform-plain-objects)

You can enforce transformations at the controller level by using the `@SerializeOptions` decorator. This ensures that all responses are transformed into instances of the specified class, applying any decorators from class-validator or class-transformer, even when plain objects are returned. This approach leads to cleaner code without the need to repeatedly instantiate the class or call `plainToInstance`.

In the example below, despite returning plain JavaScript objects in both conditional branches, they will be automatically converted into `UserEntity` instances, with the relevant decorators applied:

```typescript

@UseInterceptors(ClassSerializerInterceptor)
@SerializeOptions({ type: UserEntity })
@Get()
findOne(@Query() { id }: { id: number }): UserEntity {
  if (id === 1) {
    return {
      id: 1,
      firstName: 'John',
      lastName: 'Doe',
      password: 'password',
    };
  }

  return {
    id: 2,
    firstName: 'Kamil',
    lastName: 'Mysliwiec',
    password: 'password2',
  };
}
```

> **Hint** By specifying the expected return type for the controller, you can leverage TypeScript's type-checking capabilities to ensure that the returned plain object adheres to the shape of the DTO or entity. The `plainToInstance` function doesn't provide this level of type hinting, which can lead to potential bugs if the plain object doesn't match the expected DTO or entity structure.

#### Example[#](/techniques/serialization#example)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/21-serializer).

#### WebSockets and Microservices[#](/techniques/serialization#websockets-and-microservices)

While this chapter shows examples using HTTP style applications (e.g., Express or Fastify), the `ClassSerializerInterceptor` works the same for WebSockets and Microservices, regardless of the transport method that is used.

#### Learn more[#](/techniques/serialization#learn-more)

Read more about available decorators and options as provided by the `class-transformer` package [here](https://github.com/typestack/class-transformer).

----
url: https://docs.nestjs.com/v10/openapi/other-features
----

* [Other features](https://docs.nestjs.com/v10/openapi/other-features#other-features)
* [Global prefix](https://docs.nestjs.com/v10/openapi/other-features#global-prefix)
* [Global parameters](https://docs.nestjs.com/v10/openapi/other-features#global-parameters)
* [Multiple specifications](https://docs.nestjs.com/v10/openapi/other-features#multiple-specifications)
* [Dropdown in the explorer bar](https://docs.nestjs.com/v10/openapi/other-features#dropdown-in-the-explorer-bar)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/openapi/other-features.md "Suggest Edits")

### Other features

This page lists all the other available features that you may find useful.

#### Global prefix[#](/openapi/other-features#global-prefix)

To ignore a global prefix for routes set through `setGlobalPrefix()`, use `ignoreGlobalPrefix`:

```typescript

const document = SwaggerModule.createDocument(app, options, {
  ignoreGlobalPrefix: true,
});
```

#### Global parameters[#](/openapi/other-features#global-parameters)

You can add parameter definitions to all routes using `DocumentBuilder`:

```typescript

const options = new DocumentBuilder().addGlobalParameters({
  name: 'tenantId',
  in: 'header',
});
```

#### Multiple specifications[#](/openapi/other-features#multiple-specifications)

The `SwaggerModule` provides a way to support multiple specifications. In other words, you can serve different documentation, with different UIs, on different endpoints.

To support multiple specifications, your application must be written with a modular approach. The `createDocument()` method takes a 3rd argument, `extraOptions`, which is an object with a property named `include`. The `include` property takes a value which is an array of modules.

You can setup multiple specifications support as shown below:

```typescript

import { NestFactory } from '@nestjs/core';
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
import { AppModule } from './app.module';
import { CatsModule } from './cats/cats.module';
import { DogsModule } from './dogs/dogs.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);

  /**
   * createDocument(application, configurationOptions, extraOptions);
   *
   * createDocument method takes an optional 3rd argument "extraOptions"
   * which is an object with "include" property where you can pass an Array
   * of Modules that you want to include in that Swagger Specification
   * E.g: CatsModule and DogsModule will have two separate Swagger Specifications which
   * will be exposed on two different SwaggerUI with two different endpoints.
   */

  const options = new DocumentBuilder()
    .setTitle('Cats example')
    .setDescription('The cats API description')
    .setVersion('1.0')
    .addTag('cats')
    .build();

  const catDocumentFactory = () =>
    SwaggerModule.createDocument(app, options, {
      include: [CatsModule],
    });
  SwaggerModule.setup('api/cats', app, catDocumentFactory);

  const secondOptions = new DocumentBuilder()
    .setTitle('Dogs example')
    .setDescription('The dogs API description')
    .setVersion('1.0')
    .addTag('dogs')
    .build();

  const dogDocumentFactory = () =>
    SwaggerModule.createDocument(app, secondOptions, {
      include: [DogsModule],
    });
  SwaggerModule.setup('api/dogs', app, dogDocumentFactory);

  await app.listen(process.env.PORT ?? 3000);
}
bootstrap();
```

Now you can start your server with the following command:

```bash

$ npm run start
```

Navigate to `http://localhost:3000/api/cats` to see the Swagger UI for cats:

In turn, `http://localhost:3000/api/dogs` will expose the Swagger UI for dogs:

#### Dropdown in the explorer bar[#](/openapi/other-features#dropdown-in-the-explorer-bar)

To enable support for multiple specifications in the dropdown menu of the explorer bar, you'll need to set `explorer: true` and configure `swaggerOptions.urls` in your `SwaggerCustomOptions`.

> **Hint** Ensure that `swaggerOptions.urls` points to the JSON format of your Swagger documents! To specify the JSON document, use `jsonDocumentUrl` within `SwaggerCustomOptions`. For more setup options, check [here](/openapi/introduction#setup-options).

Here’s how to set up multiple specifications from a dropdown in the explorer bar:

```typescript

import { NestFactory } from '@nestjs/core';
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
import { AppModule } from './app.module';
import { CatsModule } from './cats/cats.module';
import { DogsModule } from './dogs/dogs.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);

  // Main API options
  const options = new DocumentBuilder()
    .setTitle('Multiple Specifications Example')
    .setDescription('Description for multiple specifications')
    .setVersion('1.0')
    .build();

  // Create main API document
  const document = SwaggerModule.createDocument(app, options);

  // Setup main API Swagger UI with dropdown support
  SwaggerModule.setup('api', app, document, {
    explorer: true,
    swaggerOptions: {
      urls: [
        {
          name: '1. API',
          url: 'api/swagger.json',
        },
        {
          name: '2. Cats API',
          url: 'api/cats/swagger.json',
        },
        {
          name: '3. Dogs API',
          url: 'api/dogs/swagger.json',
        },
      ],
    },
    jsonDocumentUrl: '/api/swagger.json',
  });

  // Cats API options
  const catOptions = new DocumentBuilder()
    .setTitle('Cats Example')
    .setDescription('Description for the Cats API')
    .setVersion('1.0')
    .addTag('cats')
    .build();

  // Create Cats API document
  const catDocument = SwaggerModule.createDocument(app, catOptions, {
    include: [CatsModule],
  });

  // Setup Cats API Swagger UI
  SwaggerModule.setup('api/cats', app, catDocument, {
    jsonDocumentUrl: '/api/cats/swagger.json',
  });

  // Dogs API options
  const dogOptions = new DocumentBuilder()
    .setTitle('Dogs Example')
    .setDescription('Description for the Dogs API')
    .setVersion('1.0')
    .addTag('dogs')
    .build();

  // Create Dogs API document
  const dogDocument = SwaggerModule.createDocument(app, dogOptions, {
    include: [DogsModule],
  });

  // Setup Dogs API Swagger UI
  SwaggerModule.setup('api/dogs', app, dogDocument, {
    jsonDocumentUrl: '/api/dogs/swagger.json',
  });

  await app.listen(3000);
}

bootstrap();
```

In this example, we set up a main API along with separate specifications for Cats and Dogs, each accessible from the dropdown in the explorer bar.

----
url: https://docs.nestjs.com/v9/graphql/mapped-types
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Mapped types](https://docs.nestjs.com/v9/graphql/mapped-types#mapped-types)
* [Partial](https://docs.nestjs.com/v9/graphql/mapped-types#partial)
* [Pick](https://docs.nestjs.com/v9/graphql/mapped-types#pick)
* [Omit](https://docs.nestjs.com/v9/graphql/mapped-types#omit)
* [Intersection](https://docs.nestjs.com/v9/graphql/mapped-types#intersection)
* [Composition](https://docs.nestjs.com/v9/graphql/mapped-types#composition)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/mapped-types.md "Suggest Edits")

### Mapped types

> **Warning** This chapter applies only to the code first approach.

As you build out features like CRUD (Create/Read/Update/Delete) it's often useful to construct variants on a base entity type. Nest provides several utility functions that perform type transformations to make this task more convenient.

#### Partial[#](/graphql/mapped-types#partial)

When building input validation types (also called Data Transfer Objects or DTOs), it's often useful to build **create** and **update** variations on the same type. For example, the **create** variant may require all fields, while the **update** variant may make all fields optional.

Nest provides the `PartialType()` utility function to make this task easier and minimize boilerplate.

The `PartialType()` function returns a type (class) with all the properties of the input type set to optional. For example, suppose we have a **create** type as follows:

```typescript

@InputType()
class CreateUserInput {
  @Field()
  email: string;

  @Field()
  password: string;

  @Field()
  firstName: string;
}
```

By default, all of these fields are required. To create a type with the same fields, but with each one optional, use `PartialType()` passing the class reference (`CreateUserInput`) as an argument:

```typescript

@InputType()
export class UpdateUserInput extends PartialType(CreateUserInput) {}
```

> **Hint** The `PartialType()` function is imported from the `@nestjs/graphql` package.

The `PartialType()` function takes an optional second argument that is a reference to a decorator factory. This argument can be used to change the decorator function applied to the resulting (child) class. If not specified, the child class effectively uses the same decorator as the **parent** class (the class referenced in the first argument). In the example above, we are extending `CreateUserInput` which is annotated with the `@InputType()` decorator. Since we want `UpdateUserInput` to also be treated as if it were decorated with `@InputType()`, we didn't need to pass `InputType` as the second argument. If the parent and child types are different, (e.g., the parent is decorated with `@ObjectType`), we would pass `InputType` as the second argument. For example:

```typescript

@InputType()
export class UpdateUserInput extends PartialType(User, InputType) {}
```

#### Pick[#](/graphql/mapped-types#pick)

The `PickType()` function constructs a new type (class) by picking a set of properties from an input type. For example, suppose we start with a type like:

```typescript

@InputType()
class CreateUserInput {
  @Field()
  email: string;

  @Field()
  password: string;

  @Field()
  firstName: string;
}
```

We can pick a set of properties from this class using the `PickType()` utility function:

```typescript

@InputType()
export class UpdateEmailInput extends PickType(CreateUserInput, [
  'email',
] as const) {}
```

> **Hint** The `PickType()` function is imported from the `@nestjs/graphql` package.

#### Omit[#](/graphql/mapped-types#omit)

The `OmitType()` function constructs a type by picking all properties from an input type and then removing a particular set of keys. For example, suppose we start with a type like:

```typescript

@InputType()
class CreateUserInput {
  @Field()
  email: string;

  @Field()
  password: string;

  @Field()
  firstName: string;
}
```

We can generate a derived type that has every property **except**`email` as shown below. In this construct, the second argument to `OmitType` is an array of property names.

```typescript

@InputType()
export class UpdateUserInput extends OmitType(CreateUserInput, [
  'email',
] as const) {}
```

> **Hint** The `OmitType()` function is imported from the `@nestjs/graphql` package.

#### Intersection[#](/graphql/mapped-types#intersection)

The `IntersectionType()` function combines two types into one new type (class). For example, suppose we start with two types like:

```typescript

@InputType()
class CreateUserInput {
  @Field()
  email: string;

  @Field()
  password: string;
}

@ObjectType()
export class AdditionalUserInfo {
  @Field()
  firstName: string;

  @Field()
  lastName: string;
}
```

We can generate a new type that combines all properties in both types.

```typescript

@InputType()
export class UpdateUserInput extends IntersectionType(
  CreateUserInput,
  AdditionalUserInfo,
) {}
```

> **Hint** The `IntersectionType()` function is imported from the `@nestjs/graphql` package.

#### Composition[#](/graphql/mapped-types#composition)

The type mapping utility functions are composable. For example, the following will produce a type (class) that has all of the properties of the `CreateUserInput` type except for `email`, and those properties will be set to optional:

```typescript

@InputType()
export class UpdateUserInput extends PartialType(
  OmitType(CreateUserInput, ['email'] as const),
) {}
```

----
url: https://docs.nestjs.com/v9/recipes/passport
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Passport (authentication)](https://docs.nestjs.com/v9/recipes/passport#passport-authentication)
* [Authentication requirements](https://docs.nestjs.com/v9/recipes/passport#authentication-requirements)
* [Implementing Passport strategies](https://docs.nestjs.com/v9/recipes/passport#implementing-passport-strategies)
* [Implementing Passport local](https://docs.nestjs.com/v9/recipes/passport#implementing-passport-local)
* [Built-in Passport Guards](https://docs.nestjs.com/v9/recipes/passport#built-in-passport-guards)
* [Login route](https://docs.nestjs.com/v9/recipes/passport#login-route)
* [JWT functionality](https://docs.nestjs.com/v9/recipes/passport#jwt-functionality)
* [Implementing Passport JWT](https://docs.nestjs.com/v9/recipes/passport#implementing-passport-jwt)
* [Implement protected route and JWT strategy guards](https://docs.nestjs.com/v9/recipes/passport#implement-protected-route-and-jwt-strategy-guards)
* [Extending guards](https://docs.nestjs.com/v9/recipes/passport#extending-guards)
* [Enable authentication globally](https://docs.nestjs.com/v9/recipes/passport#enable-authentication-globally)
* [Request-scoped strategies](https://docs.nestjs.com/v9/recipes/passport#request-scoped-strategies)
* [Customize Passport](https://docs.nestjs.com/v9/recipes/passport#customize-passport)
* [Named strategies](https://docs.nestjs.com/v9/recipes/passport#named-strategies)
* [GraphQL](https://docs.nestjs.com/v9/recipes/passport#graphql)

```bash

$ npm install --save @nestjs/passport passport passport-local
$ npm install --save-dev @types/passport-local
```

> **Notice** For **any** Passport strategy you choose, you'll always need the `@nestjs/passport` and `passport` packages. Then, you'll need to install the strategy-specific package (e.g., `passport-jwt` or `passport-local`) that implements the particular authentication strategy you are building. In addition, you can also install the type definitions for any Passport strategy, as shown above with `@types/passport-local`, which provides assistance while writing TypeScript code.

```bash

$ nest g module auth
$ nest g service auth
```

As we implement the `AuthService`, we'll find it useful to encapsulate user operations in a `UsersService`, so let's generate that module and service now:

```bash

$ nest g module users
$ nest g service users
```

Replace the default contents of these generated files as shown below. For our sample app, the `UsersService` simply maintains a hard-coded in-memory list of users, and a find method to retrieve one by username. In a real app, this is where you'd build your user model and persistence layer, using your library of choice (e.g., TypeORM, Sequelize, Mongoose, etc.).

users/users.service.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';

// This should be a real class/interface representing a user entity
export type User = any;

@Injectable()
export class UsersService {
  private readonly users = [
    {
      userId: 1,
      username: 'john',
      password: 'changeme',
    },
    {
      userId: 2,
      username: 'maria',
      password: 'guess',
    },
  ];

  async findOne(username: string): Promise<User | undefined> {
    return this.users.find(user => user.username === username);
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';

@Injectable()
export class UsersService {
  constructor() {
    this.users = [
      {
        userId: 1,
        username: 'john',
        password: 'changeme',
      },
      {
        userId: 2,
        username: 'maria',
        password: 'guess',
      },
    ];
  }

  async findOne(username) {
    return this.users.find(user => user.username === username);
  }
}
```

In the `UsersModule`, the only change needed is to add the `UsersService` to the exports array of the `@Module` decorator so that it is visible outside this module (we'll soon use it in our `AuthService`).

users/users.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { UsersService } from './users.service';

@Module({
  providers: [UsersService],
  exports: [UsersService],
})
export class UsersModule {}
```

```typescript

import { Module } from '@nestjs/common';
import { UsersService } from './users.service';

@Module({
  providers: [UsersService],
  exports: [UsersService],
})
export class UsersModule {}
```

Our `AuthService` has the job of retrieving a user and verifying the password. We create a `validateUser()` method for this purpose. In the code below, we use a convenient ES6 spread operator to strip the password property from the user object before returning it. We'll be calling into the `validateUser()` method from our Passport local strategy in a moment.

auth/auth.service.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { UsersService } from '../users/users.service';

@Injectable()
export class AuthService {
  constructor(private usersService: UsersService) {}

  async validateUser(username: string, pass: string): Promise<any> {
    const user = await this.usersService.findOne(username);
    if (user && user.password === pass) {
      const { password, ...result } = user;
      return result;
    }
    return null;
  }
}
```

```typescript

import { Injectable, Dependencies } from '@nestjs/common';
import { UsersService } from '../users/users.service';

@Injectable()
@Dependencies(UsersService)
export class AuthService {
  constructor(usersService) {
    this.usersService = usersService;
  }

  async validateUser(username, pass) {
    const user = await this.usersService.findOne(username);
    if (user && user.password === pass) {
      const { password, ...result } = user;
      return result;
    }
    return null;
  }
}
```

> **Warning** Of course in a real application, you wouldn't store a password in plain text. You'd instead use a library like [bcrypt](https://github.com/kelektiv/node.bcrypt.js#readme), with a salted one-way hash algorithm. With that approach, you'd only store hashed passwords, and then compare the stored password to a hashed version of the **incoming** password, thus never storing or exposing user passwords in plain text. To keep our sample app simple, we violate that absolute mandate and use plain text. **Don't do this in your real app!**

Now, we update our `AuthModule` to import the `UsersModule`.

auth/auth.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { UsersModule } from '../users/users.module';

@Module({
  imports: [UsersModule],
  providers: [AuthService],
})
export class AuthModule {}
```

```typescript

import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { UsersModule } from '../users/users.module';

@Module({
  imports: [UsersModule],
  providers: [AuthService],
})
export class AuthModule {}
```

#### Implementing Passport local[#](/recipes/passport#implementing-passport-local)

Now we can implement our Passport **local authentication strategy**. Create a file called `local.strategy.ts` in the `auth` folder, and add the following code:

auth/local.strategy.ts

JS TS

```typescript

import { Strategy } from 'passport-local';
import { PassportStrategy } from '@nestjs/passport';
import { Injectable, UnauthorizedException } from '@nestjs/common';
import { AuthService } from './auth.service';

@Injectable()
export class LocalStrategy extends PassportStrategy(Strategy) {
  constructor(private authService: AuthService) {
    super();
  }

  async validate(username: string, password: string): Promise<any> {
    const user = await this.authService.validateUser(username, password);
    if (!user) {
      throw new UnauthorizedException();
    }
    return user;
  }
}
```

```typescript

import { Strategy } from 'passport-local';
import { PassportStrategy } from '@nestjs/passport';
import { Injectable, UnauthorizedException, Dependencies } from '@nestjs/common';
import { AuthService } from './auth.service';

@Injectable()
@Dependencies(AuthService)
export class LocalStrategy extends PassportStrategy(Strategy) {
  constructor(authService) {
    super();
    this.authService = authService;
  }

  async validate(username, password) {
    const user = await this.authService.validateUser(username, password);
    if (!user) {
      throw new UnauthorizedException();
    }
    return user;
  }
}
```

We've followed the recipe described earlier for all Passport strategies. In our use case with passport-local, there are no configuration options, so our constructor simply calls `super()`, without an options object.

> **Hint** We can pass an options object in the call to `super()` to customize the behavior of the passport strategy. In this example, the passport-local strategy by default expects properties called `username` and `password` in the request body. Pass an options object to specify different property names, for example: `super({ usernameField: 'email' })`. See the [Passport documentation](http://www.passportjs.org/docs/configure/) for more information.

We've also implemented the `validate()` method. For each strategy, Passport will call the verify function (implemented with the `validate()` method in `@nestjs/passport`) using an appropriate strategy-specific set of parameters. For the local-strategy, Passport expects a `validate()` method with the following signature: `validate(username: string, password:string): any`.

Most of the validation work is done in our `AuthService` (with the help of our `UsersService`), so this method is quite straightforward. The `validate()` method for **any** Passport strategy will follow a similar pattern, varying only in the details of how credentials are represented. If a user is found and the credentials are valid, the user is returned so Passport can complete its tasks (e.g., creating the `user` property on the `Request` object), and the request handling pipeline can continue. If it's not found, we throw an exception and let our [exceptions layer](exception-filters) handle it.

Typically, the only significant difference in the `validate()` method for each strategy is **how** you determine if a user exists and is valid. For example, in a JWT strategy, depending on requirements, we may evaluate whether the `userId` carried in the decoded token matches a record in our user database, or matches a list of revoked tokens. Hence, this pattern of sub-classing and implementing strategy-specific validation is consistent, elegant and extensible.

We need to configure our `AuthModule` to use the Passport features we just defined. Update `auth.module.ts` to look like this:

auth/auth.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { UsersModule } from '../users/users.module';
import { PassportModule } from '@nestjs/passport';
import { LocalStrategy } from './local.strategy';

@Module({
  imports: [UsersModule, PassportModule],
  providers: [AuthService, LocalStrategy],
})
export class AuthModule {}
```

```typescript

import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { UsersModule } from '../users/users.module';
import { PassportModule } from '@nestjs/passport';
import { LocalStrategy } from './local.strategy';

@Module({
  imports: [UsersModule, PassportModule],
  providers: [AuthService, LocalStrategy],
})
export class AuthModule {}
```

```typescript

import { Controller, Request, Post, UseGuards } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';

@Controller()
export class AppController {
  @UseGuards(AuthGuard('local'))
  @Post('auth/login')
  async login(@Request() req) {
    return req.user;
  }
}
```

```typescript

import { Controller, Bind, Request, Post, UseGuards } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';

@Controller()
export class AppController {
  @UseGuards(AuthGuard('local'))
  @Post('auth/login')
  @Bind(Request())
  async login(req) {
    return req.user;
  }
}
```

With `@UseGuards(AuthGuard('local'))` we are using an `AuthGuard` that `@nestjs/passport`**automatically provisioned** for us when we extended the passport-local strategy. Let's break that down. Our Passport local strategy has a default name of `'local'`. We reference that name in the `@UseGuards()` decorator to associate it with code supplied by the `passport-local` package. This is used to disambiguate which strategy to invoke in case we have multiple Passport strategies in our app (each of which may provision a strategy-specific `AuthGuard`). While we only have one such strategy so far, we'll shortly add a second, so this is needed for disambiguation.

In order to test our route we'll have our `/auth/login` route simply return the user for now. This also lets us demonstrate another Passport feature: Passport automatically creates a `user` object, based on the value we return from the `validate()` method, and assigns it to the `Request` object as `req.user`. Later, we'll replace this with code to create and return a JWT instead.

Since these are API routes, we'll test them using the commonly available [cURL](https://curl.haxx.se/) library. You can test with any of the `user` objects hard-coded in the `UsersService`.

```bash

$ # POST to /auth/login
$ curl -X POST http://localhost:3000/auth/login -d '{"username": "john", "password": "changeme"}' -H "Content-Type: application/json"
$ # result -> {"userId":1,"username":"john"}
```

While this works, passing the strategy name directly to the `AuthGuard()` introduces magic strings in the codebase. Instead, we recommend creating your own class, as shown below:

auth/local-auth.guard.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';

@Injectable()
export class LocalAuthGuard extends AuthGuard('local') {}
```

Now, we can update the `/auth/login` route handler and use the `LocalAuthGuard` instead:

```typescript

@UseGuards(LocalAuthGuard)
@Post('auth/login')
async login(@Request() req) {
  return req.user;
}
```

#### JWT functionality[#](/recipes/passport#jwt-functionality)

We're ready to move on to the JWT portion of our auth system. Let's review and refine our requirements:

* Allow users to authenticate with username/password, returning a JWT for use in subsequent calls to protected API endpoints. We're well on our way to meeting this requirement. To complete it, we'll need to write the code that issues a JWT.
* Create API routes which are protected based on the presence of a valid JWT as a bearer token

We'll need to install a couple more packages to support our JWT requirements:

```bash

$ npm install --save @nestjs/jwt passport-jwt
$ npm install --save-dev @types/passport-jwt
```

```typescript

import { Injectable } from '@nestjs/common';
import { UsersService } from '../users/users.service';
import { JwtService } from '@nestjs/jwt';

@Injectable()
export class AuthService {
  constructor(
    private usersService: UsersService,
    private jwtService: JwtService
  ) {}

  async validateUser(username: string, pass: string): Promise<any> {
    const user = await this.usersService.findOne(username);
    if (user && user.password === pass) {
      const { password, ...result } = user;
      return result;
    }
    return null;
  }

  async login(user: any) {
    const payload = { username: user.username, sub: user.userId };
    return {
      access_token: this.jwtService.sign(payload),
    };
  }
}
```

```typescript

import { Injectable, Dependencies } from '@nestjs/common';
import { UsersService } from '../users/users.service';
import { JwtService } from '@nestjs/jwt';

@Dependencies(UsersService, JwtService)
@Injectable()
export class AuthService {
  constructor(usersService, jwtService) {
    this.usersService = usersService;
    this.jwtService = jwtService;
  }

  async validateUser(username, pass) {
    const user = await this.usersService.findOne(username);
    if (user && user.password === pass) {
      const { password, ...result } = user;
      return result;
    }
    return null;
  }

  async login(user) {
    const payload = { username: user.username, sub: user.userId };
    return {
      access_token: this.jwtService.sign(payload),
    };
  }
}
```

We're using the `@nestjs/jwt` library, which supplies a `sign()` function to generate our JWT from a subset of the `user` object properties, which we then return as a simple object with a single `access_token` property. Note: we choose a property name of `sub` to hold our `userId` value to be consistent with JWT standards. Don't forget to inject the JwtService provider into the `AuthService`.

We now need to update the `AuthModule` to import the new dependencies and configure the `JwtModule`.

First, create `constants.ts` in the `auth` folder, and add the following code:

auth/constants.ts

JS TS

```typescript

export const jwtConstants = {
  secret: 'DO NOT USE THIS VALUE. INSTEAD, CREATE A COMPLEX SECRET AND KEEP IT SAFE OUTSIDE OF THE SOURCE CODE.',
};
```

```typescript

export const jwtConstants = {
  secret: 'DO NOT USE THIS VALUE. INSTEAD, CREATE A COMPLEX SECRET AND KEEP IT SAFE OUTSIDE OF THE SOURCE CODE.',
};
```

We'll use this to share our key between the JWT signing and verifying steps.

> **Warning****Do not expose this key publicly**. We have done so here to make it clear what the code is doing, but in a production system **you must protect this key** using appropriate measures such as a secrets vault, environment variable, or configuration service.

Now, open `auth.module.ts` in the `auth` folder and update it to look like this:

auth/auth.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { LocalStrategy } from './local.strategy';
import { UsersModule } from '../users/users.module';
import { PassportModule } from '@nestjs/passport';
import { JwtModule } from '@nestjs/jwt';
import { jwtConstants } from './constants';

@Module({
  imports: [
    UsersModule,
    PassportModule,
    JwtModule.register({
      secret: jwtConstants.secret,
      signOptions: { expiresIn: '60s' },
    }),
  ],
  providers: [AuthService, LocalStrategy],
  exports: [AuthService],
})
export class AuthModule {}
```

```typescript

import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { LocalStrategy } from './local.strategy';
import { UsersModule } from '../users/users.module';
import { PassportModule } from '@nestjs/passport';
import { JwtModule } from '@nestjs/jwt';
import { jwtConstants } from './constants';

@Module({
  imports: [
    UsersModule,
    PassportModule,
    JwtModule.register({
      secret: jwtConstants.secret,
      signOptions: { expiresIn: '60s' },
    }),
  ],
  providers: [AuthService, LocalStrategy],
  exports: [AuthService],
})
export class AuthModule {}
```

We configure the `JwtModule` using `register()`, passing in a configuration object. See [here](https://github.com/nestjs/jwt/blob/master/README.md) for more on the Nest `JwtModule` and [here](https://github.com/auth0/node-jsonwebtoken#usage) for more details on the available configuration options.

Now we can update the `/auth/login` route to return a JWT.

app.controller.ts

JS TS

```typescript

import { Controller, Request, Post, UseGuards } from '@nestjs/common';
import { LocalAuthGuard } from './auth/local-auth.guard';
import { AuthService } from './auth/auth.service';

@Controller()
export class AppController {
  constructor(private authService: AuthService) {}

  @UseGuards(LocalAuthGuard)
  @Post('auth/login')
  async login(@Request() req) {
    return this.authService.login(req.user);
  }
}
```

```typescript

import { Controller, Bind, Request, Post, UseGuards } from '@nestjs/common';
import { LocalAuthGuard } from './auth/local-auth.guard';
import { AuthService } from './auth/auth.service';

@Controller()
export class AppController {
  constructor(private authService: AuthService) {}

  @UseGuards(LocalAuthGuard)
  @Post('auth/login')
  @Bind(Request())
  async login(req) {
    return this.authService.login(req.user);
  }
}
```

Let's go ahead and test our routes using cURL again. You can test with any of the `user` objects hard-coded in the `UsersService`.

```bash

$ # POST to /auth/login
$ curl -X POST http://localhost:3000/auth/login -d '{"username": "john", "password": "changeme"}' -H "Content-Type: application/json"
$ # result -> {"access_token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."}
$ # Note: above JWT truncated
```

#### Implementing Passport JWT[#](/recipes/passport#implementing-passport-jwt)

We can now address our final requirement: protecting endpoints by requiring a valid JWT be present on the request. Passport can help us here too. It provides the [passport-jwt](https://github.com/mikenicholson/passport-jwt) strategy for securing RESTful endpoints with JSON Web Tokens. Start by creating a file called `jwt.strategy.ts` in the `auth` folder, and add the following code:

auth/jwt.strategy.ts

JS TS

```typescript

import { ExtractJwt, Strategy } from 'passport-jwt';
import { PassportStrategy } from '@nestjs/passport';
import { Injectable } from '@nestjs/common';
import { jwtConstants } from './constants';

@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
  constructor() {
    super({
      jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
      ignoreExpiration: false,
      secretOrKey: jwtConstants.secret,
    });
  }

  async validate(payload: any) {
    return { userId: payload.sub, username: payload.username };
  }
}
```

```typescript

import { ExtractJwt, Strategy } from 'passport-jwt';
import { PassportStrategy } from '@nestjs/passport';
import { Injectable } from '@nestjs/common';
import { jwtConstants } from './constants';

@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
  constructor() {
    super({
      jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
      ignoreExpiration: false,
      secretOrKey: jwtConstants.secret,
    });
  }

  async validate(payload) {
    return { userId: payload.sub, username: payload.username };
  }
}
```

```typescript

import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { LocalStrategy } from './local.strategy';
import { JwtStrategy } from './jwt.strategy';
import { UsersModule } from '../users/users.module';
import { PassportModule } from '@nestjs/passport';
import { JwtModule } from '@nestjs/jwt';
import { jwtConstants } from './constants';

@Module({
  imports: [
    UsersModule,
    PassportModule,
    JwtModule.register({
      secret: jwtConstants.secret,
      signOptions: { expiresIn: '60s' },
    }),
  ],
  providers: [AuthService, LocalStrategy, JwtStrategy],
  exports: [AuthService],
})
export class AuthModule {}
```

```typescript

import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { LocalStrategy } from './local.strategy';
import { JwtStrategy } from './jwt.strategy';
import { UsersModule } from '../users/users.module';
import { PassportModule } from '@nestjs/passport';
import { JwtModule } from '@nestjs/jwt';
import { jwtConstants } from './constants';

@Module({
  imports: [
    UsersModule,
    PassportModule,
    JwtModule.register({
      secret: jwtConstants.secret,
      signOptions: { expiresIn: '60s' },
    }),
  ],
  providers: [AuthService, LocalStrategy, JwtStrategy],
  exports: [AuthService],
})
export class AuthModule {}
```

By importing the same secret used when we signed the JWT, we ensure that the **verify** phase performed by Passport, and the **sign** phase performed in our AuthService, use a common secret.

Finally, we define the `JwtAuthGuard` class which extends the built-in `AuthGuard`:

auth/jwt-auth.guard.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';

@Injectable()
export class JwtAuthGuard extends AuthGuard('jwt') {}
```

#### Implement protected route and JWT strategy guards[#](/recipes/passport#implement-protected-route-and-jwt-strategy-guards)

We can now implement our protected route and its associated Guard.

Open the `app.controller.ts` file and update it as shown below:

app.controller.ts

JS TS

```typescript

import { Controller, Get, Request, Post, UseGuards } from '@nestjs/common';
import { JwtAuthGuard } from './auth/jwt-auth.guard';
import { LocalAuthGuard } from './auth/local-auth.guard';
import { AuthService } from './auth/auth.service';

@Controller()
export class AppController {
  constructor(private authService: AuthService) {}

  @UseGuards(LocalAuthGuard)
  @Post('auth/login')
  async login(@Request() req) {
    return this.authService.login(req.user);
  }

  @UseGuards(JwtAuthGuard)
  @Get('profile')
  getProfile(@Request() req) {
    return req.user;
  }
}
```

```typescript

import { Controller, Dependencies, Bind, Get, Request, Post, UseGuards } from '@nestjs/common';
import { JwtAuthGuard } from './auth/jwt-auth.guard';
import { LocalAuthGuard } from './auth/local-auth.guard';
import { AuthService } from './auth/auth.service';

@Dependencies(AuthService)
@Controller()
export class AppController {
  constructor(authService) {
    this.authService = authService;
  }

  @UseGuards(LocalAuthGuard)
  @Post('auth/login')
  @Bind(Request())
  async login(req) {
    return this.authService.login(req.user);
  }

  @UseGuards(JwtAuthGuard)
  @Get('profile')
  @Bind(Request())
  getProfile(req) {
    return req.user;
  }
}
```

Once again, we're applying the `AuthGuard` that the `@nestjs/passport` module has automatically provisioned for us when we configured the passport-jwt module. This Guard is referenced by its default name, `jwt`. When our `GET /profile` route is hit, the Guard will automatically invoke our passport-jwt custom configured strategy, validate the JWT, and assign the `user` property to the `Request` object.

Ensure the app is running, and test the routes using `cURL`.

```bash

$ # GET /profile
$ curl http://localhost:3000/profile
$ # result -> {"statusCode":401,"message":"Unauthorized"}

$ # POST /auth/login
$ curl -X POST http://localhost:3000/auth/login -d '{"username": "john", "password": "changeme"}' -H "Content-Type: application/json"
$ # result -> {"access_token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2Vybm... }

$ # GET /profile using access_token returned from previous step as bearer code
$ curl http://localhost:3000/profile -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2Vybm..."
$ # result -> {"userId":1,"username":"john"}
```

Note that in the `AuthModule`, we configured the JWT to have an expiration of `60 seconds`. This is probably too short an expiration, and dealing with the details of token expiration and refresh is beyond the scope of this article. However, we chose that to demonstrate an important quality of JWTs and the passport-jwt strategy. If you wait 60 seconds after authenticating before attempting a `GET /profile` request, you'll receive a `401 Unauthorized` response. This is because Passport automatically checks the JWT for its expiration time, saving you the trouble of doing so in your application.

We've now completed our JWT authentication implementation. JavaScript clients (such as Angular/React/Vue), and other JavaScript apps, can now authenticate and communicate securely with our API Server.

#### Extending guards[#](/recipes/passport#extending-guards)

In most cases, using a provided `AuthGuard` class is sufficient. However, there might be use-cases when you would like to simply extend the default error handling or authentication logic. For this, you can extend the built-in class and override methods within a sub-class.

```typescript

import {
  ExecutionContext,
  Injectable,
  UnauthorizedException,
} from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';

@Injectable()
export class JwtAuthGuard extends AuthGuard('jwt') {
  canActivate(context: ExecutionContext) {
    // Add your custom authentication logic here
    // for example, call super.logIn(request) to establish a session.
    return super.canActivate(context);
  }

  handleRequest(err, user, info) {
    // You can throw an exception based on either "info" or "err" arguments
    if (err || !user) {
      throw err || new UnauthorizedException();
    }
    return user;
  }
}
```

In addition to extending the default error handling and authentication logic, we can allow authentication to go through a chain of strategies. The first strategy to succeed, redirect, or error will halt the chain. Authentication failures will proceed through each strategy in series, ultimately failing if all strategies fail.

```typescript

export class JwtAuthGuard extends AuthGuard(['strategy_jwt_1', 'strategy_jwt_2', '...']) { ... }
```

#### Enable authentication globally[#](/recipes/passport#enable-authentication-globally)

If the vast majority of your endpoints should be protected by default, you can register the authentication guard as a [global guard](/guards#binding-guards) and instead of using `@UseGuards()` decorator on top of each controller, you could simply flag which routes should be public.

First, register the `JwtAuthGuard` as a global guard using the following construction (in any module):

```typescript

providers: [
  {
    provide: APP_GUARD,
    useClass: JwtAuthGuard,
  },
],
```

With this in place, Nest will automatically bind `JwtAuthGuard` to all endpoints.

Now we must provide a mechanism for declaring routes as public. For this, we can create a custom decorator using the `SetMetadata` decorator factory function.

```typescript

import { SetMetadata } from '@nestjs/common';

export const IS_PUBLIC_KEY = 'isPublic';
export const Public = () => SetMetadata(IS_PUBLIC_KEY, true);
```

In the file above, we exported two constants. One being our metadata key named `IS_PUBLIC_KEY`, and the other being our new decorator itself that we’re going to call `Public` (you can alternatively name it `SkipAuth` or `AllowAnon`, whatever fits your project).

Now that we have a custom `@Public()` decorator, we can use it to decorate any method, as follows:

```typescript

@Public()
@Get()
findAll() {
  return [];
}
```

Lastly, we need the `JwtAuthGuard` to return `true` when the `"isPublic"` metadata is found. For this, we'll use the `Reflector` class (read more [here](/guards#putting-it-all-together)).

```typescript

@Injectable()
export class JwtAuthGuard extends AuthGuard('jwt') {
  constructor(private reflector: Reflector) {
    super();
  }

  canActivate(context: ExecutionContext) {
    const isPublic = this.reflector.getAllAndOverride<boolean>(IS_PUBLIC_KEY, [
      context.getHandler(),
      context.getClass(),
    ]);
    if (isPublic) {
      return true;
    }
    return super.canActivate(context);
  }
}
```

#### Request-scoped strategies[#](/recipes/passport#request-scoped-strategies)

The passport API is based on registering strategies to the global instance of the library. Therefore strategies are not designed to have request-dependent options or to be dynamically instantiated per request (read more about the [request-scoped](/v9/fundamentals/injection-scopes) providers). When you configure your strategy to be request-scoped, Nest will never instantiate it since it's not tied to any specific route. There is no physical way to determine which "request-scoped" strategies should be executed per request.

However, there are ways to dynamically resolve request-scoped providers within the strategy. For this, we leverage the [module reference](/v9/fundamentals/module-ref) feature.

First, open the `local.strategy.ts` file and inject the `ModuleRef` in the normal way:

```typescript

constructor(private moduleRef: ModuleRef) {
  super({
    passReqToCallback: true,
  });
}
```

> **Hint** The `ModuleRef` class is imported from the `@nestjs/core` package.

Be sure to set the `passReqToCallback` configuration property to `true`, as shown above.

In the next step, the request instance will be used to obtain the current context identifier, instead of generating a new one (read more about request context [here](/fundamentals/module-ref#getting-current-sub-tree)).

Now, inside the `validate()` method of the `LocalStrategy` class, use the `getByRequest()` method of the `ContextIdFactory` class to create a context id based on the request object, and pass this to the `resolve()` call:

```typescript

async validate(
  request: Request,
  username: string,
  password: string,
) {
  const contextId = ContextIdFactory.getByRequest(request);
  // "AuthService" is a request-scoped provider
  const authService = await this.moduleRef.resolve(AuthService, contextId);
  ...
}
```

In the example above, the `resolve()` method will asynchronously return the request-scoped instance of the `AuthService` provider (we assumed that `AuthService` is marked as a request-scoped provider).

#### Customize Passport[#](/recipes/passport#customize-passport)

Any standard Passport customization options can be passed the same way, using the `register()` method. The available options depend on the strategy being implemented. For example:

```typescript

PassportModule.register({ session: true });
```

You can also pass strategies an options object in their constructors to configure them. For the local strategy you can pass e.g.:

```typescript

constructor(private authService: AuthService) {
  super({
    usernameField: 'email',
    passwordField: 'password',
  });
}
```

Take a look at the official [Passport Website](http://www.passportjs.org/docs/oauth/) for property names.

#### Named strategies[#](/recipes/passport#named-strategies)

When implementing a strategy, you can provide a name for it by passing a second argument to the `PassportStrategy` function. If you don't do this, each strategy will have a default name (e.g., 'jwt' for jwt-strategy):

```typescript

export class JwtStrategy extends PassportStrategy(Strategy, 'myjwt')
```

Then, you refer to this via a decorator like `@UseGuards(AuthGuard('myjwt'))`.

#### GraphQL[#](/recipes/passport#graphql)

In order to use an AuthGuard with [GraphQL](https://docs.nestjs.com/graphql/quick-start), extend the built-in AuthGuard class and override the getRequest() method.

```typescript

@Injectable()
export class GqlAuthGuard extends AuthGuard('jwt') {
  getRequest(context: ExecutionContext) {
    const ctx = GqlExecutionContext.create(context);
    return ctx.getContext().req;
  }
}
```

To get the current authenticated user in your graphql resolver, you can define a `@CurrentUser()` decorator:

```typescript

import { createParamDecorator, ExecutionContext } from '@nestjs/common';
import { GqlExecutionContext } from '@nestjs/graphql';

export const CurrentUser = createParamDecorator(
  (data: unknown, context: ExecutionContext) => {
    const ctx = GqlExecutionContext.create(context);
    return ctx.getContext().req.user;
  },
);
```

To use above decorator in your resolver, be sure to include it as a parameter of your query or mutation:

```typescript

@Query(returns => User)
@UseGuards(GqlAuthGuard)
whoAmI(@CurrentUser() user: User) {
  return this.usersService.findById(user.id);
}
```

----
url: https://docs.nestjs.com/v7/microservices/nats
----

* [NATS](https://docs.nestjs.com/v7/microservices/nats#nats)
* [Installation](https://docs.nestjs.com/v7/microservices/nats#installation)
* [Overview](https://docs.nestjs.com/v7/microservices/nats#overview)
* [Options](https://docs.nestjs.com/v7/microservices/nats#options)
* [Client](https://docs.nestjs.com/v7/microservices/nats#client)
* [Request-response](https://docs.nestjs.com/v7/microservices/nats#request-response)
* [Event-based](https://docs.nestjs.com/v7/microservices/nats#event-based)
* [Queue groups](https://docs.nestjs.com/v7/microservices/nats#queue-groups)
* [Context](https://docs.nestjs.com/v7/microservices/nats#context)
* [Wildcards](https://docs.nestjs.com/v7/microservices/nats#wildcards)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/microservices/nats.md "Suggest Edits")

### NATS

[NATS](https://nats.io) is a simple, secure and high performance open source messaging system for cloud native applications, IoT messaging, and microservices architectures. The NATS server is written in the Go programming language, but client libraries to interact with the server are available for dozens of major programming languages. NATS supports both **At Most Once** and **At Least Once** delivery. It can run anywhere, from large servers and cloud instances, through edge gateways and even Internet of Things devices.

#### Installation[#](/microservices/nats#installation)

To start building NATS-based microservices, first install the required package:

```bash

$ npm i --save nats
```

#### Overview[#](/microservices/nats#overview)

To use the NATS transporter, pass the following options object to the `createMicroservice()` method:

main.ts

JS TS

```typescript

const app = await NestFactory.createMicroservice<MicroserviceOptions>(AppModule, {
  transport: Transport.NATS,
  options: {
    url: 'nats://localhost:4222',
  },
});
```

```typescript

const app = await NestFactory.createMicroservice(AppModule, {
  transport: Transport.NATS,
  options: {
    url: 'nats://localhost:4222',
  },
});
```

> **Hint** The `Transport` enum is imported from the `@nestjs/microservices` package.

#### Options[#](/microservices/nats#options)

The `options` object is specific to the chosen transporter. The **NATS** transporter exposes the properties described [here](https://github.com/nats-io/node-nats#connect-options). Additionally, there is a `queue` property which allows you to specify the name of the queue that your server should subscribe to (leave `undefined` to ignore this setting). Read more about NATS queue groups [below](https://docs.nestjs.com/microservices/nats#queue-groups).

#### Client[#](/microservices/nats#client)

Like other microservice transporters, you have [several options](https://docs.nestjs.com/microservices/basics#client) for creating a NATS `ClientProxy` instance.

One method for creating an instance is to use use the `ClientsModule`. To create a client instance with the `ClientsModule`, import it and use the `register()` method to pass an options object with the same properties shown above in the `createMicroservice()` method, as well as a `name` property to be used as the injection token. Read more about `ClientsModule`[here](https://docs.nestjs.com/microservices/basics#client).

```typescript

@Module({
  imports: [
    ClientsModule.register([
      {
        name: 'MATH_SERVICE',
        transport: Transport.NATS,
        options: {
          url: 'nats://localhost:4222',
        }
      },
    ]),
  ]
  ...
})
```

```typescript

const app = await NestFactory.createMicroservice(AppModule, {
  transport: Transport.NATS,
  options: {
    url: 'nats://localhost:4222',
    queue: 'cats_queue',
  },
});
```

#### Context[#](/microservices/nats#context)

In more sophisticated scenarios, you may want to access more information about the incoming request. When using the NATS transporter, you can access the `NatsContext` object.

JS TS

```typescript

@MessagePattern('notifications')
getNotifications(@Payload() data: number[], @Ctx() context: NatsContext) {
  console.log(`Subject: ${context.getSubject()}`);
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('notifications')
getNotifications(data, context) {
  console.log(`Subject: ${context.getSubject()}`);
}
```

> **Hint**`@Payload()`, `@Ctx()` and `NatsContext` are imported from the `@nestjs/microservices` package.

#### Wildcards[#](/microservices/nats#wildcards)

A subscription may be to an explicit subject, or it may include wildcards.

JS TS

```typescript

@MessagePattern('time.us.*')
getDate(@Payload() data: number[], @Ctx() context: NatsContext) {
  console.log(`Subject: ${context.getSubject()}`); // e.g. "time.us.east"
  return new Date().toLocaleTimeString(...);
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('time.us.*')
getDate(data, context) {
  console.log(`Subject: ${context.getSubject()}`); // e.g. "time.us.east"
  return new Date().toLocaleTimeString(...);
}
```

----
url: https://docs.nestjs.com/faq/raw-body
----

[Skip to content](#content)

On this page

* [Raw body](https://docs.nestjs.com/faq/raw-body#raw-body)
* [Use with Express](https://docs.nestjs.com/faq/raw-body#use-with-express)
* [Registering a different parser](https://docs.nestjs.com/faq/raw-body#registering-a-different-parser)
* [Body parser size limit](https://docs.nestjs.com/faq/raw-body#body-parser-size-limit)
* [Use with Fastify](https://docs.nestjs.com/faq/raw-body#use-with-fastify)
* [Registering a different parser](https://docs.nestjs.com/faq/raw-body#registering-a-different-parser-1)
* [Body parser size limit](https://docs.nestjs.com/faq/raw-body#body-parser-size-limit-1)

### Raw body

One of the most common reasons to access the raw request body is webhook signature verification. Verifying a webhook signature usually requires the unparsed request body to calculate an HMAC hash.

> **Warning** This feature works only if the built-in global body parser middleware is enabled, i.e., you must not pass `bodyParser: false` when creating the application.

#### Use with Express[#](/faq/raw-body#use-with-express)

First, enable the option when creating your Nest Express application:

```typescript

import { NestFactory } from '@nestjs/core';
import type { NestExpressApplication } from '@nestjs/platform-express';
import { AppModule } from './app.module.js';

// in the "bootstrap" function
const app = await NestFactory.create<NestExpressApplication>(AppModule, {
  rawBody: true,
});
await app.listen(process.env.PORT ?? 3000);
```

To access the raw request body in a controller, type the request with the `RawBodyRequest` convenience interface, which exposes a `rawBody` field:

```typescript

import { Controller, Post, type RawBodyRequest, Req } from '@nestjs/common';
import type { Request } from 'express';

@Controller('cats')
class CatsController {
  @Post()
  create(@Req() req: RawBodyRequest<Request>) {
    const raw = req.rawBody; // returns a `Buffer`.
  }
}
```

#### Registering a different parser[#](/faq/raw-body#registering-a-different-parser)

By default, only the `json` and `urlencoded` parsers are registered. To use a different parser, register it explicitly.

For example, to register a `text` parser:

```typescript

app.useBodyParser('text');
```

> **Warning** Make sure you pass the correct application type to the `NestFactory.create()` call. For Express applications, the correct type is `NestExpressApplication`; otherwise, the `useBodyParser()` method won't be found.

#### Body parser size limit[#](/faq/raw-body#body-parser-size-limit)

If your application needs to parse bodies larger than the Express default of `100kb`, raise the limit:

```typescript

app.useBodyParser('json', { limit: '10mb' });
```

The `useBodyParser()` method respects the `rawBody` option passed in the application options.

#### Use with Fastify[#](/faq/raw-body#use-with-fastify)

First, enable the option when creating your Nest Fastify application:

```typescript

import { NestFactory } from '@nestjs/core';
import {
  FastifyAdapter,
  NestFastifyApplication,
} from '@nestjs/platform-fastify';
import { AppModule } from './app.module.js';

// in the "bootstrap" function
const app = await NestFactory.create<NestFastifyApplication>(
  AppModule,
  new FastifyAdapter(),
  {
    rawBody: true,
  },
);
await app.listen(process.env.PORT ?? 3000);
```

To access the raw request body in a controller, type the request with the `RawBodyRequest` convenience interface, which exposes a `rawBody` field:

```typescript

import { Controller, Post, type RawBodyRequest, Req } from '@nestjs/common';
import type { FastifyRequest } from 'fastify';

@Controller('cats')
class CatsController {
  @Post()
  create(@Req() req: RawBodyRequest<FastifyRequest>) {
    const raw = req.rawBody; // returns a `Buffer`.
  }
}
```

#### Registering a different parser[#](/faq/raw-body#registering-a-different-parser-1)

By default, only the `application/json` and `application/x-www-form-urlencoded` parsers are registered. To use a different parser, register it explicitly.

For example, to register a `text/plain` parser:

```typescript

app.useBodyParser('text/plain');
```

> **Warning** Make sure you pass the correct application type to the `NestFactory.create()` call. For Fastify applications, the correct type is `NestFastifyApplication`; otherwise, the `useBodyParser()` method won't be found.

#### Body parser size limit[#](/faq/raw-body#body-parser-size-limit-1)

If your application needs to parse bodies larger than the Fastify default of 1 MiB, raise the limit:

```typescript

const bodyLimit = 10_485_760; // 10MiB
app.useBodyParser('application/json', { bodyLimit });
```

The `useBodyParser()` method respects the `rawBody` option passed in the application options.

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/faq/raw-body.md)

----
url: https://docs.nestjs.com/v8/migration-guide
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Migration guide](https://docs.nestjs.com/v8/migration-guide#migration-guide)
* [HTTP module](https://docs.nestjs.com/v8/migration-guide#http-module)
* [gRPC strategy](https://docs.nestjs.com/v8/migration-guide#grpc-strategy)
* [NATS strategy](https://docs.nestjs.com/v8/migration-guide#nats-strategy)
* [@All() decorator](https://docs.nestjs.com/v8/migration-guide#all-decorator)
* [Async listen/start methods](https://docs.nestjs.com/v8/migration-guide#async-listenstart-methods)
* [Socket.io](https://docs.nestjs.com/v8/migration-guide#socketio)
* [Logger breaking changes](https://docs.nestjs.com/v8/migration-guide#logger-breaking-changes)
* [@nestjs/config package](https://docs.nestjs.com/v8/migration-guide#nestjsconfig-package)
* [@nestjs/graphql package](https://docs.nestjs.com/v8/migration-guide#nestjsgraphql-package)
* [@nestjs/terminus package](https://docs.nestjs.com/v8/migration-guide#nestjsterminus-package)
* [RxJS](https://docs.nestjs.com/v8/migration-guide#rxjs)
* [TestingModule / NestFactory](https://docs.nestjs.com/v8/migration-guide#testingmodule--nestfactory)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/migration.md "Suggest Edits")

### Migration guide

This article provides a set of guidelines for migrating from Nest version 7 to version 8. To learn more about the new features we've added in the v8, check out this [link](https://github.com/nestjs/nest/pull/6349).

#### HTTP module[#](/migration-guide#http-module)

The `HttpModule` and `HttpService` exported from the `@nestjs/common` package have been deprecated and will be removed in the next major release. Instead, please use the `@nestjs/axios` package (otherwise, there are no API differences).

#### gRPC strategy[#](/migration-guide#grpc-strategy)

The original Node gRPC library (`grpc`) has been deprecated and will no longer receive feature updates. With Nest v8, you should use the `@grpc/grpc-js` library instead.

#### NATS strategy[#](/migration-guide#nats-strategy)

NATS has released a new major version (2.0) which has many changes and it is not API compatible with `nats@1.x.x`. If you interact with a Nest microservice (that uses NATS as a transfer layer), from a service written in a different framework, please, see their [migration document](https://github.com/nats-io/nats.js/blob/master/migration.md) to learn what's changed in v2. Otherwise, you should not see any major differences when communicating between Nest microservices.

To upgrade, make sure to install the latest version of the `nats` package (`npm i nats@latest`). Also, update your [NATS configuration](https://github.com/nats-io/nats.js/blob/master/migration.md#changed-configuration-properties). Example:

```typescript

// Before
const app = await NestFactory.createMicroservice<MicroserviceOptions>(
  AppModule,
  {
    transport: Transport.NATS,
    options: {
      url: 'nats://localhost:4222',
    },
  },
);

// Now
const app = await NestFactory.createMicroservice<MicroserviceOptions>(
  AppModule,
  {
    transport: Transport.NATS,
    options: {
      servers: ['nats://localhost:4222'],
    },
  },
);
```

#### `@All()` decorator[#](/migration-guide#all-decorator)

Routes annotated with the `@All()` decorator will now map to the `router.all()` method instead of the `router.use()`.

#### Async listen/start methods[#](/migration-guide#async-listenstart-methods)

`listenAsync()` and `startAllMicroservicesAsync()` methods have been deprecated. Instead, simply use the `listen()` and `startAllMicroservices()` methods (they are `async` either way).

#### Socket.io[#](/migration-guide#socketio)

The `@nestjs/platform-socket.io` package was upgraded to use the `socket.io@4.x.x` version (Nest v7 was based on the `socket.io` v2). To learn more, check out these articles: [Socket.io 3 Release](https://socket.io/blog/socket-io-3-release/) and [Socket.io 4 Release](https://socket.io/blog/socket-io-4-release/).

#### Logger breaking changes[#](/migration-guide#logger-breaking-changes)

For better extensibility, we separated out the `Logger` and `ConsoleLogger` classes ([PR](https://github.com/nestjs/nest/pull/6221), learn more in the [Logging](/v8/techniques/logger) chapter). If your application uses a custom logger class that extends the built-in `Logger`, you should update it to extend the `ConsoleLogger` now.

Before:

```typescript

export class MyLogger extends Logger {}
```

Now:

```typescript

export class MyLogger extends ConsoleLogger {}
```

#### `@nestjs/config` package[#](/migration-guide#nestjsconfig-package)

There was a minor breaking change in the `registerAs` function (typings), you can see what has changed in [this PR](https://github.com/nestjs/config/pull/173).

#### `@nestjs/graphql` package[#](/migration-guide#nestjsgraphql-package)

There might be some small differences in how your auto-generated schema file looks like (changed types order). Also, if you use the schema-first approach, the automatically generated type definitions will change as there was a new `Nullable<T>` type introduced in the latest release.

Also, all `HttpException` errors thrown from your resolvers will be now automatically mapped to the corresponding `ApolloError` instances, unless you set the `autoTransformHttpErrors` configuration property (in the options object you pass into the `GraphQLModule#forRoot()` method) to `false`.

#### `@nestjs/terminus` package[#](/migration-guide#nestjsterminus-package)

`HttpHealthIndicator` requires `@nestjs/axios` to be installed as well as `HttpModule` to be imported. Also, the deprecated `TerminusModule.forRootAsync` has been removed. To migrate, check out the `@nestjs/terminus` v7.x.x [upgrade guide](https://docs.nestjs.com/v7/migration-guide#terminus).

#### RxJS[#](/migration-guide#rxjs)

Make sure to upgrade to the latest version of the `rxjs` package (v7).

#### TestingModule / NestFactory[#](/migration-guide#testingmodule--nestfactory)

If you are currently supplying a string to `NestApplication#get` to retrieve an instance of some provider that was not injected using a string as a token (for instance, the `ConfigService` from `@nestjs/config`), you'll receive an error message like the following:

```text

Nest could not find ConfigService element (this provider does not exist in the current context)
```

Please change this to the actual reference. Before:

```typescript

const app = await NestFactory.create<NestExpressApplication>(AppModule);
const config = app.get<ConfigService>('ConfigService');
```

Now:

```typescript

const app = await NestFactory.create<NestExpressApplication>(AppModule);
const config = app.get<ConfigService>(ConfigService);
```

----
url: https://docs.nestjs.com/v8/first-steps
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [First steps](https://docs.nestjs.com/v8/first-steps#first-steps)
* [Language](https://docs.nestjs.com/v8/first-steps#language)
* [Prerequisites](https://docs.nestjs.com/v8/first-steps#prerequisites)
* [Setup](https://docs.nestjs.com/v8/first-steps#setup)
* [Platform](https://docs.nestjs.com/v8/first-steps#platform)
* [Running the application](https://docs.nestjs.com/v8/first-steps#running-the-application)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/first-steps.md "Suggest Edits")

Setting up a new project is quite simple with the [Nest CLI](/v8/cli/overview). With [npm](https://www.npmjs.com/) installed, you can create a new Nest project with the following commands in your OS terminal:

```bash

$ npm i -g @nestjs/cli
$ nest new project-name
```

| `app.controller.ts`      | A basic controller with a single route.                                                                             |
| ------------------------ | ------------------------------------------------------------------------------------------------------------------- |
| `app.controller.spec.ts` | The unit tests for the controller.                                                                                  |
| `app.module.ts`          | The root module of the application.                                                                                 |
| `app.service.ts`         | A basic service with a single method.                                                                               |
| `main.ts`                | The entry file of the application which uses the core function `NestFactory` to create a Nest application instance. |

The `main.ts` includes an async function, which will **bootstrap** our application:

main.ts

JS TS

```typescript

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  await app.listen(3000);
}
bootstrap();
```

```typescript

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  await app.listen(3000);
}
bootstrap();
```

To create a Nest application instance, we use the core `NestFactory` class. `NestFactory` exposes a few static methods that allow creating an application instance. The `create()` method returns an application object, which fulfills the `INestApplication` interface. This object provides a set of methods which are described in the coming chapters. In the `main.ts` example above, we simply start up our HTTP listener, which lets the application await inbound HTTP requests.

Note that a project scaffolded with the Nest CLI creates an initial project structure that encourages developers to follow the convention of keeping each module in its own dedicated directory.

> **Hint** By default, if any error happens while creating the application your app will exit with the code `1`. If you want to make it throw an error instead disable the option `abortOnError` (e.g., `NestFactory.create(AppModule, { abortOnError: false })`).

| `platform-express` | [Express](https://expressjs.com/) is a well-known minimalist web framework for node. It's a battle tested, production-ready library with lots of resources implemented by the community. The `@nestjs/platform-express` package is used by default. Many users are well served with Express, and need take no action to enable it. |
| ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `platform-fastify` | [Fastify](https://www.fastify.io/) is a high performance and low overhead framework highly focused on providing maximum efficiency and speed. Read how to use it [here](/v8/techniques/performance).                                                                                                                               |

Whichever platform is used, it exposes its own application interface. These are seen respectively as `NestExpressApplication` and `NestFastifyApplication`.

When you pass a type to the `NestFactory.create()` method, as in the example below, the `app` object will have methods available exclusively for that specific platform. Note, however, you don't **need** to specify a type **unless** you actually want to access the underlying platform API.

```typescript

const app = await NestFactory.create<NestExpressApplication>(AppModule);
```

#### Running the application[#](/first-steps#running-the-application)

Once the installation process is complete, you can run the following command at your OS command prompt to start the application listening for inbound HTTP requests:

```bash

$ npm run start
```

This command starts the app with the HTTP server listening on the port defined in the `src/main.ts` file. Once the application is running, open your browser and navigate to `http://localhost:3000/`. You should see the `Hello World!` message.

To watch for changes in your files, you can run the following command to start the application:

```bash

$ npm run start:dev
```

This command will watch your files, automatically recompiling and reloading the server.

----
url: https://docs.nestjs.com/fundamentals/module-ref
----

[Skip to content](#content)

On this page

* [Module reference](https://docs.nestjs.com/fundamentals/module-ref#module-reference)
* [Retrieving instances](https://docs.nestjs.com/fundamentals/module-ref#retrieving-instances)
* [Resolving scoped providers](https://docs.nestjs.com/fundamentals/module-ref#resolving-scoped-providers)
* [Registering REQUEST provider](https://docs.nestjs.com/fundamentals/module-ref#registering-request-provider)
* [Getting current sub-tree](https://docs.nestjs.com/fundamentals/module-ref#getting-current-sub-tree)
* [Instantiating custom classes dynamically](https://docs.nestjs.com/fundamentals/module-ref#instantiating-custom-classes-dynamically)

### Module reference

Nest provides the `ModuleRef` class to navigate the internal list of providers and obtain a reference to any provider, using its injection token as a lookup key. `ModuleRef` also lets you dynamically instantiate both static and scoped providers. Inject `ModuleRef` into a class like any other dependency:

cats.service.ts

JS TS

```typescript

@Injectable()
export class CatsService {
  constructor(private moduleRef: ModuleRef) {}
}
```

```typescript

@Injectable()
@Dependencies(ModuleRef)
export class CatsService {
  constructor(moduleRef) {
    this.moduleRef = moduleRef;
  }
}
```

> **Hint** The `ModuleRef` class is imported from the `@nestjs/core` package.

#### Retrieving instances[#](/fundamentals/module-ref#retrieving-instances)

The `ModuleRef` instance (hereafter referred to as the **module reference**) has a `get()` method. By default, this method uses an injection token or class name to return a provider, controller, or injectable (e.g., a guard or interceptor) that was registered and instantiated in the *current module*. If the instance is not found, an exception is thrown.

cats.service.ts

JS TS

```typescript

@Injectable()
export class CatsService implements OnModuleInit {
  private service: Service;
  constructor(private moduleRef: ModuleRef) {}

  onModuleInit() {
    this.service = this.moduleRef.get(Service);
  }
}
```

```typescript

@Injectable()
@Dependencies(ModuleRef)
export class CatsService {
  constructor(moduleRef) {
    this.moduleRef = moduleRef;
  }

  onModuleInit() {
    this.service = this.moduleRef.get(Service);
  }
}
```

> **Warning** You can't retrieve scoped providers (transient or request-scoped, including providers that are implicitly request-scoped through their dependencies) with the `get()` method. Instead, use the technique described in [Resolving scoped providers](/fundamentals/module-ref#resolving-scoped-providers) below. Learn how to control scopes in the [injection scopes](/fundamentals/injection-scopes) chapter.

To retrieve a provider from the global context (for example, if the provider was registered in a different module), pass the `{ strict: false }` option as the second argument to `get()`.

```typescript

this.moduleRef.get(Service, { strict: false });
```

#### Resolving scoped providers[#](/fundamentals/module-ref#resolving-scoped-providers)

To dynamically resolve a scoped provider (transient or request-scoped), use the `resolve()` method, passing the provider's injection token as an argument.

cats.service.ts

JS TS

```typescript

@Injectable()
export class CatsService implements OnModuleInit {
  private transientService: TransientService;
  constructor(private moduleRef: ModuleRef) {}

  async onModuleInit() {
    this.transientService = await this.moduleRef.resolve(TransientService);
  }
}
```

```typescript

@Injectable()
@Dependencies(ModuleRef)
export class CatsService {
  constructor(moduleRef) {
    this.moduleRef = moduleRef;
  }

  async onModuleInit() {
    this.transientService = await this.moduleRef.resolve(TransientService);
  }
}
```

The `resolve()` method returns a unique instance of the provider from its own **DI container sub-tree**. Each sub-tree has a unique **context identifier**, so if you call this method more than once and compare the instance references, you'll see that they are not equal.

cats.service.ts

JS TS

```typescript

@Injectable()
export class CatsService implements OnModuleInit {
  constructor(private moduleRef: ModuleRef) {}

  async onModuleInit() {
    const transientServices = await Promise.all([
      this.moduleRef.resolve(TransientService),
      this.moduleRef.resolve(TransientService),
    ]);
    console.log(transientServices[0] === transientServices[1]); // false
  }
}
```

```typescript

@Injectable()
@Dependencies(ModuleRef)
export class CatsService {
  constructor(moduleRef) {
    this.moduleRef = moduleRef;
  }

  async onModuleInit() {
    const transientServices = await Promise.all([
      this.moduleRef.resolve(TransientService),
      this.moduleRef.resolve(TransientService),
    ]);
    console.log(transientServices[0] === transientServices[1]); // false
  }
}
```

To get a single instance across multiple `resolve()` calls, and ensure they share the same generated DI container sub-tree, pass a context identifier to the `resolve()` method. Use the `ContextIdFactory` class to generate a context identifier: its `create()` method returns a new unique identifier.

cats.service.ts

JS TS

```typescript

@Injectable()
export class CatsService implements OnModuleInit {
  constructor(private moduleRef: ModuleRef) {}

  async onModuleInit() {
    const contextId = ContextIdFactory.create();
    const transientServices = await Promise.all([
      this.moduleRef.resolve(TransientService, contextId),
      this.moduleRef.resolve(TransientService, contextId),
    ]);
    console.log(transientServices[0] === transientServices[1]); // true
  }
}
```

```typescript

@Injectable()
@Dependencies(ModuleRef)
export class CatsService {
  constructor(moduleRef) {
    this.moduleRef = moduleRef;
  }

  async onModuleInit() {
    const contextId = ContextIdFactory.create();
    const transientServices = await Promise.all([
      this.moduleRef.resolve(TransientService, contextId),
      this.moduleRef.resolve(TransientService, contextId),
    ]);
    console.log(transientServices[0] === transientServices[1]); // true
  }
}
```

> **Hint** The `ContextIdFactory` class is imported from the `@nestjs/core` package.

#### Registering `REQUEST` provider[#](/fundamentals/module-ref#registering-request-provider)

Manually generated context identifiers (created with `ContextIdFactory.create()`) represent DI sub-trees in which the `REQUEST` provider is `undefined`, because these sub-trees are not instantiated and managed by the Nest dependency injection system.

To register a custom `REQUEST` object for a manually created DI sub-tree, use the `ModuleRef#registerRequestByContextId()` method:

```typescript

const contextId = ContextIdFactory.create();
this.moduleRef.registerRequestByContextId(/* YOUR_REQUEST_OBJECT */, contextId);
```

#### Getting current sub-tree[#](/fundamentals/module-ref#getting-current-sub-tree)

Occasionally, you may want to resolve an instance of a request-scoped provider within a **request context**. Suppose `CatsService` is request-scoped, and you want to resolve the `CatsRepository` instance, which is also a request-scoped provider. To share the same DI container sub-tree, you must obtain the current context identifier instead of generating a new one (e.g., with the `ContextIdFactory.create()` function, as shown above). To obtain the current context identifier, start by injecting the request object with the `@Inject()` decorator:

cats.service.ts

JS TS

```typescript

@Injectable()
export class CatsService {
  constructor(
    @Inject(REQUEST) private request: Record<string, unknown>,
  ) {}
}
```

```typescript

@Injectable()
@Dependencies(REQUEST)
export class CatsService {
  constructor(request) {
    this.request = request;
  }
}
```

> **Hint** Learn more about the request provider in the [Request provider](/fundamentals/injection-scopes#request-provider) section of the injection scopes chapter.

Now use the `getByRequest()` method of the `ContextIdFactory` class to get the context identifier associated with the request object, and pass it to the `resolve()` call:

```typescript

const contextId = ContextIdFactory.getByRequest(this.request);
const catsRepository = await this.moduleRef.resolve(CatsRepository, contextId);
```

#### Instantiating custom classes dynamically[#](/fundamentals/module-ref#instantiating-custom-classes-dynamically)

To dynamically instantiate a class that **wasn't previously registered** as a **provider**, use the module reference's `create()` method:

cats.service.ts

JS TS

```typescript

@Injectable()
export class CatsService implements OnModuleInit {
  private catsFactory: CatsFactory;
  constructor(private moduleRef: ModuleRef) {}

  async onModuleInit() {
    this.catsFactory = await this.moduleRef.create(CatsFactory);
  }
}
```

```typescript

@Injectable()
@Dependencies(ModuleRef)
export class CatsService {
  constructor(moduleRef) {
    this.moduleRef = moduleRef;
  }

  async onModuleInit() {
    this.catsFactory = await this.moduleRef.create(CatsFactory);
  }
}
```

This technique lets you conditionally instantiate different classes outside of the framework container.

## Debug production with NestJS Observe

* **Every request traced
* **Errors with source code
* **Logs in context
* **Zero config, free plan

[Start for free](https://observe.nestjs.com "Observe | NestJS - A progressive Node.js framework")

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/fundamentals/module-reference.md)

----
url: https://docs.nestjs.com/v11/devtools/overview
----

* [Overview](https://docs.nestjs.com/v11/devtools/overview#overview)
* [Investigating the "Cannot resolve dependency" error](https://docs.nestjs.com/v11/devtools/overview#investigating-the-cannot-resolve-dependency-error)
* [Routes explorer](https://docs.nestjs.com/v11/devtools/overview#routes-explorer)
* [Sandbox](https://docs.nestjs.com/v11/devtools/overview#sandbox)
* [Bootstrap performance analyzer](https://docs.nestjs.com/v11/devtools/overview#bootstrap-performance-analyzer)
* [Audit](https://docs.nestjs.com/v11/devtools/overview#audit)
* [Preview static files](https://docs.nestjs.com/v11/devtools/overview#preview-static-files)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/devtools/overview.md "Suggest Edits")

### Overview

> **Hint** This chapter covers the Nest Devtools integration with the Nest framework. If you are looking for the Devtools application, please visit the [Devtools](https://devtools.nestjs.com) website.

To start debugging your local application, open up the `main.ts` file and make sure to set the `snapshot` attribute to `true` in the application options object, as follows:

```typescript

async function bootstrap() {
  const app = await NestFactory.create(AppModule, {
    snapshot: true,
  });
  await app.listen(process.env.PORT ?? 3000);
}
```

This will instruct the framework to collect necessary metadata that will let Nest Devtools visualize your application's graph.

Next up, let's install the required dependency:

```bash

$ npm i @nestjs/devtools-integration
```

> **Warning** If you're using `@nestjs/graphql` package in your application, make sure to install the latest version (`npm i @nestjs/graphql@11`).

With this dependency in place, let's open up the `app.module.ts` file and import the `DevtoolsModule` that we just installed:

```typescript

@Module({
  imports: [
    DevtoolsModule.register({
      http: process.env.NODE_ENV !== 'production',
    }),
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}
```

> **Warning** The reason we are checking the `NODE_ENV` environment variable here is that you should never use this module in production!

Once the `DevtoolsModule` is imported and your application is up and running (`npm run start:dev`), you should be able to navigate to [Devtools](https://devtools.nestjs.com) URL and see the introspected graph.

> **Hint** As you can see on the screenshot above, every module connects to the `InternalCoreModule`. `InternalCoreModule` is a global module that is always imported into the root module. Since it's registered as a global node, Nest automatically creates edges between all of the modules and the `InternalCoreModule` node. Now, if you want to hide global modules from the graph, you can use the "**Hide global modules**" checkbox (in the sidebar).

So as we can see, `DevtoolsModule` makes your application expose an additional HTTP server (on port 8000) that the Devtools application will use to introspect your app.

Just to double-check that everything works as expected, change the graph view to "Classes". You should see the following screen:

To focus on a specific node, click on the rectangle and the graph will show a popup window with the **"Focus"** button. You can also use the search bar (located in the sidebar) to find a specific node.

> **Hint** If you click on the **Inspect** button, application will take you to the `/debug` page with that specific node selected.

> **Hint** To export a graph as an image, click on the **Export as PNG** button in the right corner of the graph.

Using the form controls located in the sidebar (on the left), you can control edges proximity to, for example, visualize a specific application sub-tree:

This can be particularly useful when you have **new developers** on your team and you want to show them how your application is structured. You can also use this feature to visualize a specific module (e.g. `TasksModule`) and all of its dependencies, which can come in handy when you're breaking down a large application into smaller modules (for example, individual micro-services).

You can watch this video to see the **Graph Explorer** feature in action:

#### Investigating the "Cannot resolve dependency" error[#](/devtools/overview#investigating-the-cannot-resolve-dependency-error)

> **Note** This feature is supported for `@nestjs/core` >= `v9.3.10`.

Probably the most common error message you might have seen is about Nest not being able to resolve dependencies of a provider. Using Nest Devtools, you can effortlessly identify the issue and learn how to resolve it.

First, open up the `main.ts` file and update the `bootstrap()` call, as follows:

```typescript

bootstrap().catch((err) => {
  fs.writeFileSync('graph.json', PartialGraphHost.toString() ?? '');
  process.exit(1);
});
```

Also, make sure to set the `abortOnError` to `false`:

```typescript

const app = await NestFactory.create(AppModule, {
  snapshot: true,
  abortOnError: false, // <--- THIS
});
```

> **Hint** This page shows not only HTTP routes, but also all of the other entrypoints (e.g. WebSockets, gRPC, GraphQL resolvers etc.).

> **Hint** To pretty display an array of objects, use the `console.table()` (or just `table()`) function.

You can watch this video to see the **Interactive Playground** feature in action:

#### Bootstrap performance analyzer[#](/devtools/overview#bootstrap-performance-analyzer)

To see a list of all class nodes (controllers, providers, enhancers, etc.) and their corresponding instantiation times, navigate to the **Bootstrap performance** page:

This page is particularly useful when you want to identify the slowest parts of your application's bootstrap process (e.g. when you want to optimize the application's startup time which is crucial for, for example, serverless environments).

#### Audit[#](/devtools/overview#audit)

To see the auto-generated audit - errors/warnings/hints that the application came up with while analyzing your serialized graph, navigate to the **Audit** page:

> **Hint** The screenshot above doesn't show all of the available audit rules.

This page comes in handy when you want to identify potential issues in your application.

#### Preview static files[#](/devtools/overview#preview-static-files)

To save a serialized graph to a file, use the following code:

```typescript

await app.listen(process.env.PORT ?? 3000); // OR await app.init()
fs.writeFileSync('./graph.json', app.get(SerializedGraph).toString());
```

> **Hint**`SerializedGraph` is exported from the `@nestjs/core` package.

Then you can drag and drop/upload this file:

This is helpful when you want to share your graph with someone else (e.g., co-worker), or when you want to analyze it offline.

----
url: https://docs.nestjs.com/data/overview
----

[Skip to content](#content)

On this page

* [Overview](https://docs.nestjs.com/data/overview#overview)

### Overview

Nest is database-agnostic, so you can integrate it with any SQL or NoSQL database. At the most basic level, connecting Nest to a database means loading the appropriate Node.js driver for that database, just as you would with [Express](https://expressjs.com/en/guide/database-integration.html) or Fastify, and making the client available to the rest of the application through a [provider](/providers).

Most applications work at a higher level of abstraction, with an ORM or a query builder. The chapters in this category cover the following integrations:

* **[TypeORM](/data/typeorm)** (`@nestjs/typeorm`): an ORM with decorator-based entities and the repository pattern. It supports most SQL databases, as well as MongoDB.
* **[Drizzle](/data/drizzle)** (`@nestjs/drizzle`): a lightweight, TypeScript-first ORM. You declare tables with plain functions and write queries with a SQL-like query builder, and Drizzle infers every result type from the schema.
* **[MongoDB](/data/mongodb)** (`@nestjs/mongoose`): [Mongoose](https://mongoosejs.com/) schemas and models for MongoDB.
* **[Prisma](/data/prisma)**: an ORM that generates a type-safe client from a schema file. It has no Nest-specific package: you expose the generated client through a provider.
* **[MikroORM](/data/mikroorm)** (`@mikro-orm/nestjs`, maintained by the MikroORM team): an ORM based on the Data Mapper, Unit of Work, and Identity Map patterns.
* **[Sequelize](/data/sequelize)** (`@nestjs/sequelize`): a promise-based ORM for SQL databases. With the `sequelize-typescript` package, you declare models with decorators.

The Nest team maintains the `@nestjs/typeorm`, `@nestjs/drizzle`, `@nestjs/mongoose`, and `@nestjs/sequelize` packages. They add Nest-specific features, such as repository or model injection, testability, and asynchronous configuration.

You can also use any other library directly. For example, see how to [build a Nest module for Knex.js](https://dev.to/nestjs/build-a-nestjs-module-for-knex-js-or-other-resource-based-libraries-in-5-minutes-12an). To cache query results, see [Caching](/data/caching).

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/data/overview.md)

----
url: https://docs.nestjs.com/v9/security/rate-limiting
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Rate Limiting](https://docs.nestjs.com/v9/security/rate-limiting#rate-limiting)
* [Customization](https://docs.nestjs.com/v9/security/rate-limiting#customization)
* [Proxies](https://docs.nestjs.com/v9/security/rate-limiting#proxies)
* [Websockets](https://docs.nestjs.com/v9/security/rate-limiting#websockets)
* [GraphQL](https://docs.nestjs.com/v9/security/rate-limiting#graphql)
* [Configuration](https://docs.nestjs.com/v9/security/rate-limiting#configuration)
* [Async Configuration](https://docs.nestjs.com/v9/security/rate-limiting#async-configuration)
* [Storages](https://docs.nestjs.com/v9/security/rate-limiting#storages)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/security/rate-limiting.md "Suggest Edits")

### Rate Limiting

A common technique to protect applications from brute-force attacks is **rate-limiting**. To get started, you'll need to install the `@nestjs/throttler` package.

```bash

$ npm i --save @nestjs/throttler
```

Once the installation is complete, the `ThrottlerModule` can be configured as any other Nest package with `forRoot` or `forRootAsync` methods.

app.module.ts

JS TS

```typescript

@Module({
  imports: [
    ThrottlerModule.forRoot({
      ttl: 60,
      limit: 10,
    }),
  ],
})
export class AppModule {}
```

The above will set the global options for the `ttl`, the time to live, and the `limit`, the maximum number of requests within the ttl, for the routes of your application that are guarded.

Once the module has been imported, you can then choose how you would like to bind the `ThrottlerGuard`. Any kind of binding as mentioned in the [guards](https://docs.nestjs.com/guards) section is fine. If you wanted to bind the guard globally, for example, you could do so by adding this provider to any module:

```typescript

{
  provide: APP_GUARD,
  useClass: ThrottlerGuard
}
```

#### Customization[#](/security/rate-limiting#customization)

There may be a time where you want to bind the guard to a controller or globally, but want to disable rate limiting for one or more of your endpoints. For that, you can use the `@SkipThrottle()` decorator, to negate the throttler for an entire class or a single route. The `@SkipThrottle()` decorator can also take in a boolean for if there is a case where you want to exclude *most* of a controller, but not every route.

```typescript

@SkipThrottle()
@Controller('users')
export class UsersController {}
```

This `@SkipThrottle()` decorator can be used to skip a route or a class or to negate the skipping of a route in a class that is skipped.

```typescript

@SkipThrottle()
@Controller('users')
export class UsersController {
  // Rate limiting is applied to this route.
  @SkipThrottle(false)
  dontSkip() {
    return "List users work with Rate limiting.";
  }
  // This route will skip rate limiting.
  doSkip() {
    return "List users work without Rate limiting.";
  }
}
```

There is also the `@Throttle()` decorator which can be used to override the `limit` and `ttl` set in the global module, to give tighter or looser security options. This decorator can be used on a class or a function as well. The order for this decorator does matter, as the arguments are in the order of `limit, ttl`. You have to configure it like this:

```typescript

// Override default configuration for Rate limiting and duration.
@Throttle(3, 60)
@Get()
findAll() {
  return "List users works with custom rate limiting.";
}
```

#### Proxies[#](/security/rate-limiting#proxies)

If your application runs behind a proxy server, check the specific HTTP adapter options ([express](http://expressjs.com/en/guide/behind-proxies.html) and [fastify](https://www.fastify.io/docs/latest/Reference/Server/#trustproxy)) for the `trust proxy` option and enable it. Doing so will allow you to get the original IP address from the `X-Forwarded-For` header, and you can override the `getTracker()` method to pull the value from the header rather than from `req.ip`. The following example works with both express and fastify:

```typescript

// throttler-behind-proxy.guard.ts
import { ThrottlerGuard } from '@nestjs/throttler';
import { Injectable } from '@nestjs/common';

@Injectable()
export class ThrottlerBehindProxyGuard extends ThrottlerGuard {
  protected getTracker(req: Record<string, any>): string {
    return req.ips.length ? req.ips[0] : req.ip; // individualize IP extraction to meet your own needs
  }
}

// app.controller.ts
import { ThrottlerBehindProxyGuard } from './throttler-behind-proxy.guard';

@UseGuards(ThrottlerBehindProxyGuard)
```

> **Hint** You can find the API of the `req` Request object for express [here](https://expressjs.com/en/api.html#req.ips) and for fastify [here](https://www.fastify.io/docs/latest/Reference/Request/).

#### Websockets[#](/security/rate-limiting#websockets)

This module can work with websockets, but it requires some class extension. You can extend the `ThrottlerGuard` and override the `handleRequest` method like so:

```typescript

@Injectable()
export class WsThrottlerGuard extends ThrottlerGuard {
  async handleRequest(context: ExecutionContext, limit: number, ttl: number): Promise<boolean> {
    const client = context.switchToWs().getClient();
    const ip = client._socket.remoteAddress
    const key = this.generateKey(context, ip);
    const { totalHits } = await this.storageService.increment(key, ttl);

    if (totalHits > limit) {
      throw new ThrottlerException();
    }

    return true;
  }
}
```

> **Hint** If you using ws, it is necessary to replace the `_socket` with `conn`

There's a few things to keep in mind when working with WebSockets:

* Guard cannot be registered with the `APP_GUARD` or `app.useGlobalGuards()`
* When a limit is reached, Nest will emit an `exception` event, so make sure there is a listener ready for this

> **Hint** If you are using the `@nestjs/platform-ws` package you can use `client._socket.remoteAddress` instead.

#### GraphQL[#](/security/rate-limiting#graphql)

The `ThrottlerGuard` can also be used to work with GraphQL requests. Again, the guard can be extended, but this time the `getRequestResponse` method will be overridden

```typescript

@Injectable()
export class GqlThrottlerGuard extends ThrottlerGuard {
  getRequestResponse(context: ExecutionContext) {
    const gqlCtx = GqlExecutionContext.create(context);
    const ctx = gqlCtx.getContext();
    return { req: ctx.req, res: ctx.res };
  }
}
```

#### Configuration[#](/security/rate-limiting#configuration)

The following options are valid for the `ThrottlerModule`:

|                    |                                                                                               |
| ------------------ | --------------------------------------------------------------------------------------------- |
| `ttl`              | the number of seconds that each request will last in storage                                  |
| `limit`            | the maximum number of requests within the TTL limit                                           |
| `ignoreUserAgents` | an array of regular expressions of user-agents to ignore when it comes to throttling requests |
| `storage`          | the storage setting for how to keep track of the requests                                     |

#### Async Configuration[#](/security/rate-limiting#async-configuration)

You may want to get your rate-limiting configuration asynchronously instead of synchronously. You can use the `forRootAsync()` method, which allows for dependency injection and `async` methods.

One approach would be to use a factory function:

```typescript

@Module({
  imports: [
    ThrottlerModule.forRootAsync({
      imports: [ConfigModule],
      inject: [ConfigService],
      useFactory: (config: ConfigService) => ({
        ttl: config.get('THROTTLE_TTL'),
        limit: config.get('THROTTLE_LIMIT'),
      }),
    }),
  ],
})
export class AppModule {}
```

You can also use the `useClass` syntax:

```typescript

@Module({
  imports: [
    ThrottlerModule.forRootAsync({
      imports: [ConfigModule],
      useClass: ThrottlerConfigService,
    }),
  ],
})
export class AppModule {}
```

This is doable, as long as `ThrottlerConfigService` implements the interface `ThrottlerOptionsFactory`.

#### Storages[#](/security/rate-limiting#storages)

The built in storage is an in memory cache that keeps track of the requests made until they have passed the TTL set by the global options. You can drop in your own storage option to the `storage` option of the `ThrottlerModule` so long as the class implements the `ThrottlerStorage` interface.

For distributed servers you could use the community storage provider for [Redis](https://github.com/kkoomen/nestjs-throttler-storage-redis) to have a single source of truth.

> **Note**`ThrottlerStorage` can be imported from `@nestjs/throttler`.

----
url: https://docs.nestjs.com/v7/graphql/federation
----

* [Federation](https://docs.nestjs.com/v7/graphql/federation#federation)
* [Federated example: Users](https://docs.nestjs.com/v7/graphql/federation#federated-example-users)
* [Schema first](https://docs.nestjs.com/v7/graphql/federation#schema-first)
* [Code first](https://docs.nestjs.com/v7/graphql/federation#code-first)
* [Federated example: Posts](https://docs.nestjs.com/v7/graphql/federation#federated-example-posts)
* [Schema first](https://docs.nestjs.com/v7/graphql/federation#schema-first-1)
* [Code first](https://docs.nestjs.com/v7/graphql/federation#code-first-1)
* [Federated example: Gateway](https://docs.nestjs.com/v7/graphql/federation#federated-example-gateway)
* [Sharing context](https://docs.nestjs.com/v7/graphql/federation#sharing-context)
* [Async configuration](https://docs.nestjs.com/v7/graphql/federation#async-configuration)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/federation.md "Suggest Edits")

### Federation

[Apollo Federation](https://www.apollographql.com/docs/apollo-server/federation/introduction/) offers a means of splitting your monolithic GraphQL server into independent microservices. It consists of two components: a gateway and one or more federated microservices. Each microservice holds part of the schema and the gateway merges the schemas into a single schema that can be consumed by the client.

To quote the [Apollo docs](https://blog.apollographql.com/apollo-federation-f260cf525d21), Federation is designed with these core principles:

* Building a graph should be **declarative.** With federation, you compose a graph declaratively from within your schema instead of writing imperative schema stitching code.
* Code should be separated by **concern**, not by types. Often no single team controls every aspect of an important type like a User or Product, so the definition of these types should be distributed across teams and codebases, rather than centralized.
* The graph should be simple for clients to consume. Together, federated services can form a complete, product-focused graph that accurately reflects how it’s being consumed on the client.
* It’s just **GraphQL**, using only spec-compliant features of the language. Any language, not just JavaScript, can implement federation.

> **Warning** Apollo Federation currently does not support subscriptions.

In the next example, we'll set up a demo application with a gateway and two federated endpoints: a Users service and a Posts service.

#### Federated example: Users[#](/graphql/federation#federated-example-users)

First, install the optional dependency for federation:

```bash

$ npm install --save @apollo/federation
```

#### Schema first[#](/graphql/federation#schema-first)

The User service has a simple schema. Note the `@key` directive: it tells the Apollo query planner that a particular instance of User can be fetched if you have its `id`. Also, note that we extend the `Query` type.

```graphql

type User @key(fields: "id") {
  id: ID!
  name: String!
}

extend type Query {
  getUser(id: ID!): User
}
```

Our resolver has one extra method: `resolveReference()`. It's called by the Apollo Gateway whenever a related resource requires a User instance. We'll see an example of this in the Posts service later on. Please note the `@ResolveReference()` decorator.

```typescript

import { Args, Query, Resolver, ResolveReference } from '@nestjs/graphql';
import { UsersService } from './users.service';

@Resolver('User')
export class UsersResolvers {
  constructor(private usersService: UsersService) {}

  @Query()
  getUser(@Args('id') id: string) {
    return this.usersService.findById(id);
  }

  @ResolveReference()
  resolveReference(reference: { __typename: string; id: string }) {
    return this.usersService.findById(reference.id);
  }
}
```

Finally, we hook everything up in a module together with a `GraphQLFederationModule`. This module accepts the same options as the regular `GraphQLModule`.

```typescript

import { Module } from '@nestjs/common';
import { GraphQLFederationModule } from '@nestjs/graphql';
import { UsersResolvers } from './users.resolvers';

@Module({
  imports: [
    GraphQLFederationModule.forRoot({
      typePaths: ['**/*.graphql'],
    }),
  ],
  providers: [UsersResolvers],
})
export class AppModule {}
```

#### Code first[#](/graphql/federation#code-first)

Code first federation is very similar to regular code first GraphQL. We simply add some extra decorators to the `User` entity.

```ts

import { Directive, Field, ID, ObjectType } from '@nestjs/graphql';

@ObjectType()
@Directive('@key(fields: "id")')
export class User {
  @Field((type) => ID)
  id: number;

  @Field()
  name: string;
}
```

Our resolver has one extra method: `resolveReference()`. It's called by the Apollo Gateway whenever a related resource requires a `User` instance. We'll see an example of this in the Posts service later on. Please note the `@ResolveReference()` decorator.

```ts

import { Args, Query, Resolver, ResolveReference } from '@nestjs/graphql';
import { User } from './user.entity';
import { UsersService } from './users.service';

@Resolver((of) => User)
export class UsersResolvers {
  constructor(private usersService: UsersService) {}

  @Query((returns) => User)
  getUser(@Args('id') id: number): User {
    return this.usersService.findById(id);
  }

  @ResolveReference()
  resolveReference(reference: { __typename: string; id: number }): User {
    return this.usersService.findById(reference.id);
  }
}
```

Finally, we hook everything up in a module together with a `GraphQLFederationModule`. This module accepts the same options as the regular `GraphQLModule`.

```typescript

import { Module } from '@nestjs/common';
import { GraphQLFederationModule } from '@nestjs/graphql';
import { UsersResolvers } from './users.resolvers';
import { UsersService } from './users.service'; // Not included in this example

@Module({
  imports: [
    GraphQLFederationModule.forRoot({
      autoSchemaFile: true,
    }),
  ],
  providers: [UsersResolvers, UsersService],
})
export class AppModule {}
```

#### Federated example: Posts[#](/graphql/federation#federated-example-posts)

Our Post service serves aggregated posts via a `getPosts` query, but also extends our `User` type with `user.posts`

#### Schema first[#](/graphql/federation#schema-first-1)

The Posts service references the User type in its schema by marking it with the `extend` keyword. It also adds one property to the User type. Note the `@key` directive used for matching instances of User, and the `@external` directive indicating that the `id` field is managed elsewhere.

```graphql

type Post @key(fields: "id") {
  id: ID!
  title: String!
  body: String!
  user: User
}

extend type User @key(fields: "id") {
  id: ID! @external
  posts: [Post]
}

extend type Query {
  getPosts: [Post]
}
```

Our resolver has one method of interest here: `getUser()`. It returns a reference containing `__typename` and any additional properties your application needs to resolve the reference, in this case only an `id`. The `__typename` is used by the GraphQL Gateway to pinpoint the microservice responsible for the User type and request the instance. The Users service discussed above will be called on the `resolveReference()` method.

```typescript

import { Query, Resolver, Parent, ResolveField } from '@nestjs/graphql';
import { PostsService } from './posts.service';
import { Post } from './posts.interfaces';

@Resolver('Post')
export class PostsResolvers {
  constructor(private postsService: PostsService) {}

  @Query('getPosts')
  getPosts() {
    return this.postsService.findAll();
  }

  @ResolveField('user')
  getUser(@Parent() post: Post) {
    return { __typename: 'User', id: post.userId };
  }
}
```

The Posts service has virtually the same module, but is included below for the sake of completeness:

```typescript

import { Module } from '@nestjs/common';
import { GraphQLFederationModule } from '@nestjs/graphql';
import { PostsResolvers } from './posts.resolvers';

@Module({
  imports: [
    GraphQLFederationModule.forRoot({
      typePaths: ['**/*.graphql'],
    }),
  ],
  providers: [PostsResolvers],
})
export class AppModule {}
```

#### Code first[#](/graphql/federation#code-first-1)

We will need to create a class representing our `User` entity. Even though it lives in another service, we will be using and extending it. Note the `@extends` and `@external` directives.

```ts

import { Directive, ObjectType, Field, ID } from '@nestjs/graphql';
import { Post } from './post.entity';

@ObjectType()
@Directive('@extends')
@Directive('@key(fields: "id")')
export class User {
  @Field((type) => ID)
  @Directive('@external')
  id: number;

  @Field((type) => [Post])
  posts?: Post[];
}
```

We create the resolver for our extension on the `User` entity as follows:

```ts

import { Parent, ResolveField, Resolver } from '@nestjs/graphql';
import { PostsService } from './posts.service';
import { Post } from './post.entity';
import { User } from './user.entity';

@Resolver((of) => User)
export class UsersResolvers {
  constructor(private readonly postsService: PostsService) {}

  @ResolveField((of) => [Post])
  public posts(@Parent() user: User): Post[] {
    return this.postsService.forAuthor(user.id);
  }
}
```

We also need to create our `Post` entity:

```ts

import { Directive, Field, ID, Int, ObjectType } from '@nestjs/graphql';
import { User } from './user.entity';

@ObjectType()
@Directive('@key(fields: "id")')
export class Post {
  @Field((type) => ID)
  id: number;

  @Field()
  title: string;

  @Field((type) => Int)
  authorId: number;

  @Field((type) => User)
  user?: User;
}
```

And its resolver:

```ts

import { Query, Args, ResolveField, Resolver, Parent } from '@nestjs/graphql';
import { PostsService } from './posts.service';
import { Post } from './post.entity';
import { User } from './user.entity';

@Resolver((of) => Post)
export class PostsResolvers {
  constructor(private readonly postsService: PostsService) {}

  @Query((returns) => Post)
  findPost(@Args('id') id: number): Post {
    return this.postsService.findOne(id);
  }

  @Query((returns) => [Post])
  getPosts(): Post[] {
    return this.postsService.all();
  }

  @ResolveField((of) => User)
  user(@Parent() post: Post): any {
    return { __typename: 'User', id: post.authorId };
  }
}
```

And finally, tie it together in a module. Note the schema build options, where we specify that `User` is an outside type.

```ts

import { Module } from '@nestjs/common';
import { GraphQLFederationModule } from '@nestjs/graphql';
import { User } from './user.entity';
import { PostsResolvers } from './posts.resolvers';
import { UsersResolvers } from './users.resolvers';
import { PostsService } from './posts.service'; // Not included in example

@Module({
  imports: [
    GraphQLFederationModule.forRoot({
      autoSchemaFile: true,
      buildSchemaOptions: {
        orphanedTypes: [User],
      },
    }),
  ],
  providers: [PostsResolvers, UsersResolvers, PostsService],
})
export class AppModule {}
```

#### Federated example: Gateway[#](/graphql/federation#federated-example-gateway)

First, install the optional dependency for the gateway:

```bash

$ npm install --save @apollo/gateway
```

Our gateway only needs a list of endpoints and will auto-discover the schemas from there. Therefore it is the same for code and schema first, and the code for our gateway is very short:

```typescript

import { Module } from '@nestjs/common';
import { GraphQLGatewayModule } from '@nestjs/graphql';

@Module({
  imports: [
    GraphQLGatewayModule.forRoot({
      server: {
        // ... Apollo server options
        cors: true,
      },
      gateway: {
        serviceList: [
          { name: 'users', url: 'http://user-service/graphql' },
          { name: 'posts', url: 'http://post-service/graphql' },
        ],
      },
    }),
  ],
})
export class AppModule {}
```

> **Hint** Apollo recommends that you don't rely on the service discovery in a production environment but use their [Graph Manager](https://www.apollographql.com/docs/graph-manager/federation/) instead.

#### Sharing context[#](/graphql/federation#sharing-context)

You can customize the requests between the gateway and federated services using a build service. This allows you to share context about the request. You can easily extend the default `RemoteGraphQLDataSource` and implement one of the hooks. Please refer to [Apollo Docs](https://www.apollographql.com/docs/apollo-server/api/apollo-gateway/#remotegraphqldatasource) on `RemoteGraphQLDataSource` for more information about the possibilities.

```typescript

import { Module } from '@nestjs/common';
import { GATEWAY_BUILD_SERVICE, GraphQLGatewayModule } from '@nestjs/graphql';
import { RemoteGraphQLDataSource } from '@apollo/gateway';
import { decode } from 'jsonwebtoken';

class AuthenticatedDataSource extends RemoteGraphQLDataSource {
  async willSendRequest({ request, context }) {
    const { userId } = await decode(context.jwt);
    request.http.headers.set('x-user-id', userId);
  }
}

@Module({
  providers: [
    {
      provide: AuthenticatedDataSource,
      useValue: AuthenticatedDataSource,
    },
    {
      provide: GATEWAY_BUILD_SERVICE,
      useFactory: (AuthenticatedDataSource) => {
        return ({ name, url }) => new AuthenticatedDataSource({ url });
      },
      inject: [AuthenticatedDataSource],
    },
  ],
  exports: [GATEWAY_BUILD_SERVICE],
})
class BuildServiceModule {}

@Module({
  imports: [
    GraphQLGatewayModule.forRootAsync({
      useFactory: async () => ({
        gateway: {
          serviceList: [
            /* services */
          ],
        },
        server: {
          context: ({ req }) => ({
            jwt: req.headers.authorization,
          }),
        },
      }),
      imports: [BuildServiceModule],
      inject: [GATEWAY_BUILD_SERVICE],
    }),
  ],
})
export class AppModule {}
```

#### Async configuration[#](/graphql/federation#async-configuration)

Both the Federation and Gateway modules support asynchronous initialization using the same `forRootAsync` that's documented in [Quick start](/graphql/quick-start#async-configuration).

----
url: https://docs.nestjs.com/v6/techniques/serialization
----

* [Serialization](https://docs.nestjs.com/v6/techniques/serialization#serialization)
* [Overview](https://docs.nestjs.com/v6/techniques/serialization#overview)
* [Exclude properties](https://docs.nestjs.com/v6/techniques/serialization#exclude-properties)
* [Expose properties](https://docs.nestjs.com/v6/techniques/serialization#expose-properties)
* [Transform](https://docs.nestjs.com/v6/techniques/serialization#transform)
* [Pass options](https://docs.nestjs.com/v6/techniques/serialization#pass-options)
* [WebSockets and Microservices](https://docs.nestjs.com/v6/techniques/serialization#websockets-and-microservices)
* [Learn more](https://docs.nestjs.com/v6/techniques/serialization#learn-more)

```typescript

import { Exclude } from 'class-transformer';

export class UserEntity {
  id: number;
  firstName: string;
  lastName: string;

  @Exclude()
  password: string;

  constructor(partial: Partial<UserEntity>) {
    Object.assign(this, partial);
  }
}
```

Now consider a controller with a method handler that returns an instance of this class.

```typescript

@UseInterceptors(ClassSerializerInterceptor)
@Get()
findOne(): UserEntity {
  return new UserEntity({
    id: 1,
    firstName: 'Kamil',
    lastName: 'Mysliwiec',
    password: 'password',
  });
}
```

> **Warning** Note that we must return an instance of the class. If you return a plain JavaScript object, for example, `{ user: new UserEntity() }`, the object won't be properly serialized.

> **Hint** The `ClassSerializerInterceptor` is imported from `@nestjs/common`.

When this endpoint is requested, the client receives the following response:

```json

{
  "id": 1,
  "firstName": "Kamil",
  "lastName": "Mysliwiec"
}
```

Note that the interceptor can be applied application-wide (as covered [here](https://docs.nestjs.com/interceptors#binding-interceptors)). The combination of the interceptor and the entity class declaration ensures that **any** method that returns a `UserEntity` will be sure to remove the `password` property. This gives you a measure of centralized enforcement of this business rule.

#### Expose properties[#](/techniques/serialization#expose-properties)

You can use the `@Expose()` decorator to provide alias names for properties, or to execute a function to calculate a property value (analogous to **getter** functions), as shown below.

```typescript

@Expose()
get fullName(): string {
  return `${this.firstName} ${this.lastName}`;
}
```

#### Transform[#](/techniques/serialization#transform)

You can perform additional data transformation using the `@Transform()` decorator. For example, the following construct returns the name property of the `RoleEntity` instead of returning the whole object.

```typescript

@Transform(role => role.name)
role: RoleEntity;
```

#### Pass options[#](/techniques/serialization#pass-options)

You may want to modify the default behavior of the transformation functions. To override default settings, pass them in an `options` object with the `@SerializeOptions()` decorator.

```typescript

@SerializeOptions({
  excludePrefixes: ['_'],
})
@Get()
findOne(): UserEntity {
  return new UserEntity();
}
```

> **Hint** The `@SerializeOptions()` decorator is imported from `@nestjs/common`.

Options passed via `@SerializeOptions()` are passed as the second argument of the underlying `classToPlain()` function. In this example, we are automatically excluding all properties that begin with the `_` prefix.

#### WebSockets and Microservices[#](/techniques/serialization#websockets-and-microservices)

While this chapter shows examples using HTTP style applications (e.g., Express or Fastify), the `ClassSerializerInterceptor` works the same for WebSockets and Microservices, regardless of the transport method that is used.

#### Learn more[#](/techniques/serialization#learn-more)

Read more about available decorators and options as provided by the `class-transformer` package [here](https://github.com/typestack/class-transformer).

----
url: https://docs.nestjs.com/v10/microservices/custom-transport
----

* [Custom transporters](https://docs.nestjs.com/v10/microservices/custom-transport#custom-transporters)
* [Creating a strategy](https://docs.nestjs.com/v10/microservices/custom-transport#creating-a-strategy)
* [Client proxy](https://docs.nestjs.com/v10/microservices/custom-transport#client-proxy)
* [Message serialization](https://docs.nestjs.com/v10/microservices/custom-transport#message-serialization)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/microservices/custom-transport.md "Suggest Edits")

### Custom transporters

Nest provides a variety of **transporters** out-of-the-box, as well as an API allowing developers to build new custom transport strategies. Transporters enable you to connect components over a network using a pluggable communications layer and a very simple application-level message protocol (read full [article](https://dev.to/nestjs/integrate-nestjs-with-external-services-using-microservice-transporters-part-1-p3)).

> **Hint** Building a microservice with Nest does not necessarily mean you must use the `@nestjs/microservices` package. For example, if you want to communicate with external services (let's say other microservices written in different languages), you may not need all the features provided by `@nestjs/microservice` library. In fact, if you don't need decorators (`@EventPattern` or `@MessagePattern`) that let you declaratively define subscribers, running a [Standalone Application](/v10/application-context) and manually maintaining connection/subscribing to channels should be enough for most use-cases and will provide you with more flexibility.

With a custom transporter, you can integrate any messaging system/protocol (including Google Cloud Pub/Sub, Amazon Kinesis, and others) or extend the existing one, adding extra features on top (for example, [QoS](https://github.com/mqttjs/MQTT.js/blob/master/README.md#qos) for MQTT).

> **Hint** To better understand how Nest microservices work and how you can extend the capabilities of existing transporters, we recommend reading the [NestJS Microservices in Action](https://dev.to/johnbiundo/series/4724) and [Advanced NestJS Microservices](https://dev.to/nestjs/part-1-introduction-and-setup-1a2l) article series.

#### Creating a strategy[#](/microservices/custom-transport#creating-a-strategy)

First, let's define a class representing our custom transporter.

```typescript

import { CustomTransportStrategy, Server } from '@nestjs/microservices';

class GoogleCloudPubSubServer
  extends Server
  implements CustomTransportStrategy {
  /**
   * This method is triggered when you run "app.listen()".
   */
  listen(callback: () => void) {
    callback();
  }

  /**
   * This method is triggered on application shutdown.
   */
  close() {}
}
```

> **Warning** Please, note we won't be implementing a fully-featured Google Cloud Pub/Sub server in this chapter as this would require diving into transporter specific technical details.

In our example above, we declared the `GoogleCloudPubSubServer` class and provided `listen()` and `close()` methods enforced by the `CustomTransportStrategy` interface. Also, our class extends the `Server` class imported from the `@nestjs/microservices` package that provides a few useful methods, for example, methods used by Nest runtime to register message handlers. Alternatively, in case you want to extend the capabilities of an existing transport strategy, you could extend the corresponding server class, for example, `ServerRedis`. Conventionally, we added the `"Server"` suffix to our class as it will be responsible for subscribing to messages/events (and responding to them, if necessary).

With this in place, we can now use our custom strategy instead of using a built-in transporter, as follows:

```typescript

const app = await NestFactory.createMicroservice<MicroserviceOptions>(
  AppModule,
  {
    strategy: new GoogleCloudPubSubServer(),
  },
);
```

Basically, instead of passing the normal transporter options object with `transport` and `options` properties, we pass a single property, `strategy`, whose value is an instance of our custom transporter class.

Back to our `GoogleCloudPubSubServer` class, in a real-world application, we would be establishing a connection to our message broker/external service and registering subscribers/listening to specific channels in `listen()` method (and then removing subscriptions & closing the connection in the `close()` teardown method), but since this requires a good understanding of how Nest microservices communicate with each other, we recommend reading this [article series](https://dev.to/nestjs/part-1-introduction-and-setup-1a2l). In this chapter instead, we'll focus on the capabilities the `Server` class provides and how you can leverage them to build custom strategies.

For example, let's say that somewhere in our application, the following message handler is defined:

```typescript

@MessagePattern('echo')
echo(@Payload() data: object) {
  return data;
}
```

This message handler will be automatically registered by Nest runtime. With `Server` class, you can see what message patterns have been registered and also, access and execute the actual methods that were assigned to them. To test this out, let's add a simple `console.log` inside `listen()` method before `callback` function is called:

```typescript

listen(callback: () => void) {
  console.log(this.messageHandlers);
  callback();
}
```

After your application restarts, you'll see the following log in your terminal:

```typescript

Map { 'echo' => [AsyncFunction] { isEventHandler: false } }
```

> **Hint** If we used the `@EventPattern` decorator, you would see the same output, but with the `isEventHandler` property set to `true`.

As you can see, the `messageHandlers` property is a `Map` collection of all message (and event) handlers, in which patterns are being used as keys. Now, you can use a key (for example, `"echo"`) to receive a reference to the message handler:

```typescript

async listen(callback: () => void) {
  const echoHandler = this.messageHandlers.get('echo');
  console.log(await echoHandler('Hello world!'));
  callback();
}
```

Once we execute the `echoHandler` passing an arbitrary string as an argument (`"Hello world!"` here), we should see it in the console:

```json

Hello world!
```

Which means that our method handler was properly executed.

When using a `CustomTransportStrategy` with [Interceptors](/v10/interceptors) the handlers are wrapped into RxJS streams. This means that you need to subscribe to them in order to execute the streams underlying logic (e.g. continue into the controller logic after an interceptor has been executed).

An example of this can be seen below:

```typescript

async listen(callback: () => void) {
  const echoHandler = this.messageHandlers.get('echo');
  const streamOrResult = await echoHandler('Hello World');
  if (isObservable(streamOrResult)) {
    streamOrResult.subscribe();
  }
  callback();
}
```

#### Client proxy[#](/microservices/custom-transport#client-proxy)

As we mentioned in the first section, you don't necessarily need to use the `@nestjs/microservices` package to create microservices, but if you decide to do so and you need to integrate a custom strategy, you will need to provide a "client" class too.

> **Hint** Again, implementing a fully-featured client class compatible with all `@nestjs/microservices` features (e.g., streaming) requires a good understanding of communication techniques used by the framework. To learn more, check out this [article](https://dev.to/nestjs/part-4-basic-client-component-16f9).

To communicate with an external service/emit & publish messages (or events) you can either use a library-specific SDK package, or implement a custom client class that extends the `ClientProxy`, as follows:

```typescript

import { ClientProxy, ReadPacket, WritePacket } from '@nestjs/microservices';

class GoogleCloudPubSubClient extends ClientProxy {
  async connect(): Promise<any> {}
  async close() {}
  async dispatchEvent(packet: ReadPacket<any>): Promise<any> {}
  publish(
    packet: ReadPacket<any>,
    callback: (packet: WritePacket<any>) => void,
  ): Function {}
}
```

> **Warning** Please, note we won't be implementing a fully-featured Google Cloud Pub/Sub client in this chapter as this would require diving into transporter specific technical details.

As you can see, `ClientProxy` class requires us to provide several methods for establishing & closing the connection and publishing messages (`publish`) and events (`dispatchEvent`). Note, if you don't need a request-response communication style support, you can leave the `publish()` method empty. Likewise, if you don't need to support event-based communication, skip the `dispatchEvent()` method.

To observe what and when those methods are executed, let's add multiple `console.log` calls, as follows:

```typescript

class GoogleCloudPubSubClient extends ClientProxy {
  async connect(): Promise<any> {
    console.log('connect');
  }

  async close() {
    console.log('close');
  }

  async dispatchEvent(packet: ReadPacket<any>): Promise<any> {
    return console.log('event to dispatch: ', packet);
  }

  publish(
    packet: ReadPacket<any>,
    callback: (packet: WritePacket<any>) => void,
  ): Function {
    console.log('message:', packet);

    // In a real-world application, the "callback" function should be executed
    // with payload sent back from the responder. Here, we'll simply simulate (5 seconds delay)
    // that response came through by passing the same "data" as we've originally passed in.
    setTimeout(() => callback({ response: packet.data }), 5000);

    return () => console.log('teardown');
  }
}
```

With this in place, let's create an instance of `GoogleCloudPubSubClient` class and run the `send()` method (which you might have seen in earlier chapters), subscribing to the returned observable stream.

```typescript

const googlePubSubClient = new GoogleCloudPubSubClient();
googlePubSubClient
  .send('pattern', 'Hello world!')
  .subscribe((response) => console.log(response));
```

Now, you should see the following output in your terminal:

```typescript

connect
message: { pattern: 'pattern', data: 'Hello world!' }
Hello world! // <-- after 5 seconds
```

To test if our "teardown" method (which our `publish()` method returns) is properly executed, let's apply a timeout operator to our stream, setting it to 2 seconds to make sure it throws earlier then our `setTimeout` calls the `callback` function.

```typescript

const googlePubSubClient = new GoogleCloudPubSubClient();
googlePubSubClient
  .send('pattern', 'Hello world!')
  .pipe(timeout(2000))
  .subscribe(
    (response) => console.log(response),
    (error) => console.error(error.message),
  );
```

> **Hint** The `timeout` operator is imported from the `rxjs/operators` package.

With `timeout` operator applied, your terminal output should look as follows:

```typescript

connect
message: { pattern: 'pattern', data: 'Hello world!' }
teardown // <-- teardown
Timeout has occurred
```

To dispatch an event (instead of sending a message), use the `emit()` method:

```typescript

googlePubSubClient.emit('event', 'Hello world!');
```

And that's what you should see in the console:

```typescript

connect
event to dispatch:  { pattern: 'event', data: 'Hello world!' }
```

#### Message serialization[#](/microservices/custom-transport#message-serialization)

If you need to add some custom logic around the serialization of responses on the client side, you can use a custom class that extends the `ClientProxy` class or one of its child classes. For modifying successful requests you can override the `serializeResponse` method, and for modifying any errors that go through this client you can override the `serializeError` method. To make use of this custom class, you can pass the class itself to the `ClientsModule.register()` method using the `customClass` property. Below is an example of a custom `ClientProxy` that serializes each error into an `RpcException`.

error-handling.proxy.ts

JS TS

```typescript

import { ClientTcp, RpcException } from '@nestjs/microservices';

class ErrorHandlingProxy extends ClientTCP {
  serializeError(err: Error) {
    return new RpcException(err);
  }
}
```

and then use it in the `ClientsModule` like so:

app.module.ts

JS TS

```typescript

@Module({
  imports: [
    ClientsModule.register([{
      name: 'CustomProxy',
      customClass: ErrorHandlingProxy,
    }]),
  ]
})
export class AppModule
```

> **hint** This is the class itself being passed to `customClass`, not an instance of the class. Nest will create the instance under the hood for you, and will pass any options given to the `options` property to the new `ClientProxy`.

----
url: https://docs.nestjs.com/v10/microservices/pipes
----

* [Pipes](https://docs.nestjs.com/v10/microservices/pipes#pipes)
* [Binding pipes](https://docs.nestjs.com/v10/microservices/pipes#binding-pipes)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/microservices/pipes.md "Suggest Edits")

### Pipes

There is no fundamental difference between [regular pipes](/v10/pipes) and microservices pipes. The only difference is that instead of throwing `HttpException`, you should use `RpcException`.

> **Hint** The `RpcException` class is exposed from `@nestjs/microservices` package.

#### Binding pipes[#](/microservices/pipes#binding-pipes)

The following example uses a manually instantiated method-scoped pipe. Just as with HTTP based applications, you can also use controller-scoped pipes (i.e., prefix the controller class with a `@UsePipes()` decorator).

JS TS

```typescript

@UsePipes(new ValidationPipe({ exceptionFactory: (errors) => new RpcException(errors) }))
@MessagePattern({ cmd: 'sum' })
accumulate(data: number[]): number {
  return (data || []).reduce((a, b) => a + b);
}
```

```typescript

@UsePipes(new ValidationPipe({ exceptionFactory: (errors) => new RpcException(errors) }))
@MessagePattern({ cmd: 'sum' })
accumulate(data) {
  return (data || []).reduce((a, b) => a + b);
}
```

----
url: https://docs.nestjs.com/v7/modules
----

* [Modules](https://docs.nestjs.com/v7/modules#modules)
* [Feature modules](https://docs.nestjs.com/v7/modules#feature-modules)
* [Shared modules](https://docs.nestjs.com/v7/modules#shared-modules)
* [Module re-exporting](https://docs.nestjs.com/v7/modules#module-re-exporting)
* [Dependency injection](https://docs.nestjs.com/v7/modules#dependency-injection)
* [Global modules](https://docs.nestjs.com/v7/modules#global-modules)
* [Dynamic modules](https://docs.nestjs.com/v7/modules#dynamic-modules)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/modules.md "Suggest Edits")

### Modules

A module is a class annotated with a `@Module()` decorator. The `@Module()` decorator provides metadata that **Nest** makes use of to organize the application structure.

Each application has at least one module, a **root module**. The root module is the starting point Nest uses to build the **application graph** - the internal data structure Nest uses to resolve module and provider relationships and dependencies. While very small applications may theoretically have just the root module, this is not the typical case. We want to emphasize that modules are **strongly** recommended as an effective way to organize your components. Thus, for most applications, the resulting architecture will employ multiple modules, each encapsulating a closely related set of **capabilities**.

The `@Module()` decorator takes a single object whose properties describe the module:

|               |                                                                                                                              |
| ------------- | ---------------------------------------------------------------------------------------------------------------------------- |
| `providers`   | the providers that will be instantiated by the Nest injector and that may be shared at least across this module              |
| `controllers` | the set of controllers defined in this module which have to be instantiated                                                  |
| `imports`     | the list of imported modules that export the providers which are required in this module                                     |
| `exports`     | the subset of `providers` that are provided by this module and should be available in other modules which import this module |

The module **encapsulates** providers by default. This means that it's impossible to inject providers that are neither directly part of the current module nor exported from the imported modules. Thus, you may consider the exported providers from a module as the module's public interface, or API.

#### Feature modules[#](/modules#feature-modules)

The `CatsController` and `CatsService` belong to the same application domain. As they are closely related, it makes sense to move them into a feature module. A feature module simply organizes code relevant for a specific feature, keeping code organized and establishing clear boundaries. This helps us manage complexity and develop with [SOLID](https://en.wikipedia.org/wiki/SOLID) principles, especially as the size of the application and/or team grow.

To demonstrate this, we'll create the `CatsModule`.

cats/cats.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

@Module({
  controllers: [CatsController],
  providers: [CatsService],
})
export class CatsModule {}
```

> **Hint** To create a module using the CLI, simply execute the `$ nest g module cats` command.

Above, we defined the `CatsModule` in the `cats.module.ts` file, and moved everything related to this module into the `cats` directory. The last thing we need to do is import this module into the root module (the `AppModule`, defined in the `app.module.ts` file).

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { CatsModule } from './cats/cats.module';

@Module({
  imports: [CatsModule],
})
export class AppModule {}
```

```typescript

import { Module } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

@Module({
  controllers: [CatsController],
  providers: [CatsService],
  exports: [CatsService]
})
export class CatsModule {}
```

```typescript

@Module({
  imports: [CommonModule],
  exports: [CommonModule],
})
export class CoreModule {}
```

#### Dependency injection[#](/modules#dependency-injection)

A module class can **inject** providers as well (e.g., for configuration purposes):

cats.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

@Module({
  controllers: [CatsController],
  providers: [CatsService],
})
export class CatsModule {
  constructor(private catsService: CatsService) {}
}
```

```typescript

import { Module, Dependencies } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

@Module({
  controllers: [CatsController],
  providers: [CatsService],
})
@Dependencies(CatsService)
export class CatsModule {
  constructor(catsService) {
    this.catsService = catsService;
  }
}
```

However, module classes themselves cannot be injected as providers due to [circular dependency](/v7/fundamentals/circular-dependency) .

#### Global modules[#](/modules#global-modules)

If you have to import the same set of modules everywhere, it can get tedious. Unlike in Nest, [Angular](https://angular.io)`providers` are registered in the global scope. Once defined, they're available everywhere. Nest, however, encapsulates providers inside the module scope. You aren't able to use a module's providers elsewhere without first importing the encapsulating module.

When you want to provide a set of providers which should be available everywhere out-of-the-box (e.g., helpers, database connections, etc.), make the module **global** with the `@Global()` decorator.

```typescript

import { Module, Global } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

@Global()
@Module({
  controllers: [CatsController],
  providers: [CatsService],
  exports: [CatsService],
})
export class CatsModule {}
```

The `@Global()` decorator makes the module global-scoped. Global modules should be registered **only once**, generally by the root or core module. In the above example, the `CatsService` provider will be ubiquitous, and modules that wish to inject the service will not need to import the `CatsModule` in their imports array.

> **Hint** Making everything global is not a good design decision. Global modules are available to reduce the amount of necessary boilerplate. The `imports` array is generally the preferred way to make the module's API available to consumers.

#### Dynamic modules[#](/modules#dynamic-modules)

The Nest module system includes a powerful feature called **dynamic modules**. This feature enables you to easily create customizable modules that can register and configure providers dynamically. Dynamic modules are covered extensively [here](/v7/fundamentals/dynamic-modules). In this chapter, we'll give a brief overview to complete the introduction to modules.

Following is an example of a dynamic module definition for a `DatabaseModule`:

JS TS

```typescript

import { Module, DynamicModule } from '@nestjs/common';
import { createDatabaseProviders } from './database.providers';
import { Connection } from './connection.provider';

@Module({
  providers: [Connection],
})
export class DatabaseModule {
  static forRoot(entities = [], options?): DynamicModule {
    const providers = createDatabaseProviders(options, entities);
    return {
      module: DatabaseModule,
      providers: providers,
      exports: providers,
    };
  }
}
```

```typescript

import { Module } from '@nestjs/common';
import { createDatabaseProviders } from './database.providers';
import { Connection } from './connection.provider';

@Module({
  providers: [Connection],
})
export class DatabaseModule {
  static forRoot(entities = [], options?) {
    const providers = createDatabaseProviders(options, entities);
    return {
      module: DatabaseModule,
      providers: providers,
      exports: providers,
    };
  }
}
```

> **Hint** The `forRoot()` method may return a dynamic module either synchronously or asynchronously (i.e., via a `Promise`).

This module defines the `Connection` provider by default (in the `@Module()` decorator metadata), but additionally - depending on the `entities` and `options` objects passed into the `forRoot()` method - exposes a collection of providers, for example, repositories. Note that the properties returned by the dynamic module **extend** (rather than override) the base module metadata defined in the `@Module()` decorator. That's how both the statically declared `Connection` provider **and** the dynamically generated repository providers are exported from the module.

If you want to register a dynamic module in the global scope, set the `global` property to `true`.

```typescript

{
  global: true,
  module: DatabaseModule,
  providers: providers,
  exports: providers,
}
```

> **Warning** As mentioned above, making everything global **is not a good design decision**.

The `DatabaseModule` can be imported and configured in the following manner:

```typescript

import { Module } from '@nestjs/common';
import { DatabaseModule } from './database/database.module';
import { User } from './users/entities/user.entity';

@Module({
  imports: [DatabaseModule.forRoot([User])],
})
export class AppModule {}
```

If you want to in turn re-export a dynamic module, you can omit the `forRoot()` method call in the exports array:

```typescript

import { Module } from '@nestjs/common';
import { DatabaseModule } from './database/database.module';
import { User } from './users/entities/user.entity';

@Module({
  imports: [DatabaseModule.forRoot([User])],
  exports: [DatabaseModule],
})
export class AppModule {}
```

The [Dynamic modules](/v7/fundamentals/dynamic-modules) chapter covers this topic in greater detail, and includes a [working example](https://github.com/nestjs/nest/tree/master/sample/25-dynamic-modules).

----
url: https://docs.nestjs.com/v6/faq/request-lifecycle
----

* [Request lifecycle](https://docs.nestjs.com/v6/faq/request-lifecycle#request-lifecycle)
* [Middleware](https://docs.nestjs.com/v6/faq/request-lifecycle#middleware)
* [Guard](https://docs.nestjs.com/v6/faq/request-lifecycle#guard)
* [Interceptors](https://docs.nestjs.com/v6/faq/request-lifecycle#interceptors)
* [Pipes](https://docs.nestjs.com/v6/faq/request-lifecycle#pipes)
* [Filters](https://docs.nestjs.com/v6/faq/request-lifecycle#filters)
* [Summary](https://docs.nestjs.com/v6/faq/request-lifecycle#summary)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/faq/request-lifecycle.md "Suggest Edits")

### Request lifecycle

Nest applications handle requests and produce responses in a sequence we refer to as the **request lifecycle**. With the use of middleware, pipes, guards, and interceptors, it can be challenging to track down where a particular piece of code executes during the request lifecycle, especially as global, controller level, and route level components come into play. In general, a request flows through middleware to guards, then to interceptors, then to pipes and finally back to interceptors on the return path (as the response is generated).

#### Middleware[#](/faq/request-lifecycle#middleware)

Middleware is executed in a particular sequence. First, Nest runs globally bound middleware (such as middleware bound with `app.use`) and then it runs [module bound middleware](/v6/middleware), which are determined on paths. Middleware are run sequentially in the order they are bound, similar to the way middleware in Express works.

#### Guard[#](/faq/request-lifecycle#guard)

Guard execution starts with global guards, then proceeds to controller guards, and finally to route guards. As with middleware, guards run in the order in which they are bound. For example:

```typescript

@UseGuards(Guard1, Guard2)
@Controller('cats')
export class CatsController {
  constructor(private readonly catsService: CatsService) {}

  @UseGuards(Guard3)
  @Get()
  getCats(): Cats[] {
    return this.catsService.getCats();
  }
}
```

`Guard1` will execute before `Guard2` and both will execute before `Guard3`.

> **Hint** When speaking about globally bound vs controller or locally bound, the difference is where the guard (or other component is bound). If you are using `app.useGlobalGuard()` or providing the component via a module, it is globally bound. Otherwise, it is bound to a controller if the decorator precedes a controller class, or to a route if the decorator proceeds a route declaration.

#### Interceptors[#](/faq/request-lifecycle#interceptors)

Interceptors, for the most part, follow the same pattern as guards, with one catch: as interceptors return [RxJS Observables](https://github.com/ReactiveX/rxjs), the observables will be resolved in a first in last out manner. So inbound requests will go through the standard global, controller, route level resolution, but the response side of the request (i.e., after returning from the controller method handler) will be resolved from route to controller to global. Also, any errors thrown by pipes, controllers, or services can be read in the `catchError` operator of an interceptor.

#### Pipes[#](/faq/request-lifecycle#pipes)

Pipes follow the standard global to controller to route bound sequence, with the same first in first out in regards to the `@usePipes()` parameters. However, at a route parameter level, if you have multiple pipes running, they will run in the order of the last parameter with a pipe to the first. This also applies to the route level and controller level pipes. For example, if we have the following controller:

```typescript

@UsePipes(GeneralValidationPipe)
@Controller('cats')
export class CatsController {
  constructor(private readonly catsService: CatsService) {}

  @UsePipes(RouteSpecificPipe)
  @Patch(':id')
  updateCat(
    @Body() body: UpdateCatDTO, 
    @Param() params: UpdateCatParams, 
    @Query() query: UpdateCatQuery,
  ) {
    return this.catsService.updateCat(body, params, query);
  }
}
```

then the `GeneralValidationPipe` will run for the `query`, then the `params`, and then the `body` objects before moving on to the `RouteSpecificPipe`, which follows the same order. If any parameter-specific pipes were in place, they would run (again, from the last to first parameter) after the controller and route level pipes.

#### Filters[#](/faq/request-lifecycle#filters)

Filters are the only component that do not resolve global first. Instead, filters resolve from the lowest level possible, meaning execution starts with any route bound filters and proceeding next to controller level, and finally to global filters. Note that exceptions cannot be passed from filter to filter; if a route level filter catches the exception, a controller or global level filter cannot catch the same exception. The only way to achieve an effect like this is to use inheritance between the filters.

> **Hint** Filters are only executed if any uncaught exception occurs during the request process. Caught exceptions, such as those caught with a `try/catch` will not trigger Exception Filters to fire. As soon as an uncaught exception is encountered, the rest of the lifecycle is ignored and the request skips straight to the filter.

----
url: https://docs.nestjs.com/graphql/cli-plugin
----

[Skip to content](#content)

On this page

* [CLI Plugin](https://docs.nestjs.com/graphql/cli-plugin#cli-plugin)
* [Overview](https://docs.nestjs.com/graphql/cli-plugin#overview)
* [Comments introspection](https://docs.nestjs.com/graphql/cli-plugin#comments-introspection)
* [Using the CLI plugin](https://docs.nestjs.com/graphql/cli-plugin#using-the-cli-plugin)
* [SWC builder](https://docs.nestjs.com/graphql/cli-plugin#swc-builder)
* [Integration with ts-jest (e2e tests)](https://docs.nestjs.com/graphql/cli-plugin#integration-with-ts-jest-e2e-tests)

[](https://srv.carbonads.net/ads/click/x/GTND4277CVSD5KJUCAYLYKQUF67D62QUF6BIKZ3JCAAI623WC6YIC5QKC6SI42QYF6BI6K37FTADV2JJCWYIL2JJHEYI55QLCAYD653ECTNCYBZ52K)[Start solving your business challenges with a Google Cloud $300 credit. ](https://srv.carbonads.net/ads/click/x/GTND4277CVSD5KJUCAYLYKQUF67D62QUF6BIKZ3JCAAI623WC6YIC5QKC6SI42QYF6BI6K37FTADV2JJCWYIL2JJHEYI55QLCAYD653ECTNCYBZ52K)[ads via Carbon](http://carbonads.net/?utm_source=nestjscom\&utm_medium=ad_via_link\&utm_campaign=in_unit\&utm_term=carbon)

### CLI Plugin

> **Warning** This chapter applies only to the code first approach.

TypeScript's metadata reflection system has several limitations that make it impossible to, for instance, determine which properties a class consists of, or whether a given property is optional or required. However, some of these constraints can be addressed at compile time. Nest provides a plugin that enhances the TypeScript compilation process to reduce the amount of boilerplate code required.

> **Hint** This plugin is **opt-in**. If you prefer, you can declare all decorators manually, or only specific decorators where you need them.

#### Overview[#](/graphql/cli-plugin#overview)

The GraphQL plugin automatically does the following:

* annotate all properties of input object, object type, and args classes with `@Field`, unless `@HideField` is used
* set the `nullable` property depending on the question mark (e.g., `name?: string` sets `nullable: true`)
* set the `type` property depending on the type (arrays are supported as well)
* generate descriptions for properties based on comments (if `introspectComments` is set to `true`)

Your filenames **must have** one of the following suffixes to be analyzed by the plugin: `['.input.ts', '.args.ts', '.entity.ts', '.model.ts']` (e.g., `author.entity.ts`). If you use a different suffix, adjust the plugin's behavior with the `typeFileNameSuffix` option (see below).

With what we've covered so far, you have to duplicate a lot of code to tell the package how your type should be declared in GraphQL. For example, you could define an `Author` class as follows:

authors/models/author.model.ts

JS TS

```typescript

@ObjectType()
export class Author {
  @Field(type => ID)
  id: number;

  @Field({ nullable: true })
  firstName?: string;

  @Field({ nullable: true })
  lastName?: string;

  @Field(type => [Post])
  posts: Post[];
}
```

While this isn't a significant issue in medium-sized projects, it becomes verbose and hard to maintain once you have a large set of classes.

With the GraphQL plugin enabled, the class definition above can be declared as follows:

authors/models/author.model.ts

JS TS

```typescript

@ObjectType()
export class Author {
  @Field(type => ID)
  id: number;
  firstName?: string;
  lastName?: string;
  posts: Post[];
}
```

The plugin adds the appropriate decorators on the fly based on the **Abstract Syntax Tree**, so you don't have to scatter `@Field` decorators throughout the code.

> **Hint** The plugin automatically generates any missing GraphQL properties. If you need to override them, set them explicitly with `@Field()`.

#### Comments introspection[#](/graphql/cli-plugin#comments-introspection)

With the comments introspection feature enabled, the CLI plugin generates descriptions for fields based on comments.

For example, consider a `roles` property:

```typescript

/**
 * A list of user's roles
 */
@Field(() => [String], {
  description: `A list of user's roles`
})
roles: string[];
```

Here, you must duplicate the description. With `introspectComments` enabled, the CLI plugin extracts these comments and automatically provides descriptions for properties. The field above can then be declared as follows:

```typescript

/**
 * A list of user's roles
 */
roles: string[];
```

#### Using the CLI plugin[#](/graphql/cli-plugin#using-the-cli-plugin)

To enable the plugin, open `nest-cli.json` (if you use the [Nest CLI](/cli/overview)) and add the following `plugins` configuration:

```javascript

{
  "collection": "@nestjs/schematics",
  "sourceRoot": "src",
  "compilerOptions": {
    "plugins": ["@nestjs/graphql"]
  }
}
```

Use the `options` property to customize the behavior of the plugin:

```javascript

{
  "collection": "@nestjs/schematics",
  "sourceRoot": "src",
  "compilerOptions": {
    "plugins": [
      {
        "name": "@nestjs/graphql",
        "options": {
          "typeFileNameSuffix": [".input.ts", ".args.ts"],
          "introspectComments": true
        }
      }
    ]
  }
}
```

The `options` property accepts the following options:

```typescript

export interface PluginOptions {
  typeFileNameSuffix?: string | string[];
  introspectComments?: boolean;
  esmCompatible?: boolean;
  debug?: boolean;
}
```

| Option               | Default                                                | Description                                                                                                                        |
| -------------------- | ------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------- |
| `typeFileNameSuffix` | `['.input.ts', '.args.ts', '.entity.ts', '.model.ts']` | Suffixes of the files that contain GraphQL types                                                                                   |
| `introspectComments` | `false`                                                | If set to `true`, the plugin generates descriptions for properties based on comments                                               |
| `esmCompatible`      | Inferred from each file's module format                | If set to `true`, the plugin emits ESM-compatible code (no `require()` calls, and output extensions appended to relative imports). |
| `debug`              | `false`                                                | If set to `true`, the plugin logs diagnostic messages (e.g., when it finds a type that isn't exported)                             |

If you don't use the CLI and have a custom `webpack` configuration instead, you can use this plugin in combination with `ts-loader`:

```javascript

getCustomTransformers: (program) => ({
  before: [require('@nestjs/graphql/plugin').before({}, program)]
}),
```

#### SWC builder[#](/graphql/cli-plugin#swc-builder)

For standard (non-monorepo) setups, using CLI plugins with the SWC builder requires type checking to be enabled, as described in [SWC type checking](/recipes/swc#type-checking).

```bash

$ nest start -b swc --type-check
```

For monorepo setups, follow the instructions in [monorepo and CLI plugins](/recipes/swc#monorepo-and-cli-plugins).

```bash

$ npx ts-node src/generate-metadata.ts
# OR npx ts-node apps/{YOUR_APP}/src/generate-metadata.ts
```

Then, load the serialized metadata file in the `GraphQLModule` configuration, as shown below:

```typescript

import metadata from './metadata.js'; // <-- file auto-generated by the "PluginMetadataGenerator"

GraphQLModule.forRoot<...>({
  ..., // other options
  metadata,
}),
```

#### Integration with `ts-jest` (e2e tests)[#](/graphql/cli-plugin#integration-with-ts-jest-e2e-tests)

When you run e2e tests with this plugin enabled, you may run into issues compiling the schema. For example, one of the most common errors is:

```json

Object type <name> must define one or more fields.
```

This happens because the `jest` configuration doesn't import the `@nestjs/graphql/plugin` plugin anywhere.

To fix this, create the following file in your e2e tests directory:

```javascript

const transformer = require('@nestjs/graphql/plugin');

module.exports.name = 'nestjs-graphql-transformer';
// you should change the version number anytime you change the configuration below - otherwise, jest will not detect changes
module.exports.version = 1;

module.exports.factory = (cs) => {
  return transformer.before(
    {
      // @nestjs/graphql/plugin options (can be empty)
    },
    cs.program, // "cs.tsCompiler.program" for older versions of Jest (<= v27)
  );
};
```

With this in place, import the AST transformer in your `jest` configuration file. By default (in the starter application), the e2e test configuration file is located in the `test` folder and is named `jest-e2e.json`.

```json

{
  ... // other configuration
  "globals": {
    "ts-jest": {
      "astTransformers": {
        "before": ["<path to the file created above>"]
      }
    }
  }
}
```

If you use `jest@^29` or later, use the snippet below instead, as the previous approach is deprecated.

```json

{
  ... // other configuration
  "transform": {
    "^.+\\.(t|j)s$": [
      "ts-jest",
      {
        "astTransformers": {
          "before": ["<path to the file created above>"]
        }
      }
    ]
  }
}
```

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/cli-plugin.md)

----
url: https://docs.nestjs.com/v10/graphql/complexity
----

* [Complexity](https://docs.nestjs.com/v10/graphql/complexity#complexity)
* [Installation](https://docs.nestjs.com/v10/graphql/complexity#installation)
* [Getting started](https://docs.nestjs.com/v10/graphql/complexity#getting-started)
* [Field-level complexity](https://docs.nestjs.com/v10/graphql/complexity#field-level-complexity)
* [Query/Mutation-level complexity](https://docs.nestjs.com/v10/graphql/complexity#querymutation-level-complexity)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/complexity.md "Suggest Edits")

### Complexity

> **Warning** This chapter applies only to the code first approach.

Query complexity allows you to define how complex certain fields are, and to restrict queries with a **maximum complexity**. The idea is to define how complex each field is by using a simple number. A common default is to give each field a complexity of `1`. In addition, the complexity calculation of a GraphQL query can be customized with so-called complexity estimators. A complexity estimator is a simple function that calculates the complexity for a field. You can add any number of complexity estimators to the rule, which are then executed one after another. The first estimator that returns a numeric complexity value determines the complexity for that field.

The `@nestjs/graphql` package integrates very well with tools like [graphql-query-complexity](https://github.com/slicknode/graphql-query-complexity) that provides a cost analysis-based solution. With this library, you can reject queries to your GraphQL server that are deemed too costly to execute.

#### Installation[#](/graphql/complexity#installation)

To begin using it, we first install the required dependency.

```bash

$ npm install --save graphql-query-complexity
```

#### Getting started[#](/graphql/complexity#getting-started)

Once the installation process is complete, we can define the `ComplexityPlugin` class:

```typescript

import { GraphQLSchemaHost } from '@nestjs/graphql';
import { Plugin } from '@nestjs/apollo';
import {
  ApolloServerPlugin,
  BaseContext,
  GraphQLRequestListener,
} from '@apollo/server';
import { GraphQLError } from 'graphql';
import {
  fieldExtensionsEstimator,
  getComplexity,
  simpleEstimator,
} from 'graphql-query-complexity';

@Plugin()
export class ComplexityPlugin implements ApolloServerPlugin {
  constructor(private gqlSchemaHost: GraphQLSchemaHost) {}

  async requestDidStart(): Promise<GraphQLRequestListener<BaseContext>> {
    const maxComplexity = 20;
    const { schema } = this.gqlSchemaHost;

    return {
      async didResolveOperation({ request, document }) {
        const complexity = getComplexity({
          schema,
          operationName: request.operationName,
          query: document,
          variables: request.variables,
          estimators: [
            fieldExtensionsEstimator(),
            simpleEstimator({ defaultComplexity: 1 }),
          ],
        });
        if (complexity > maxComplexity) {
          throw new GraphQLError(
            `Query is too complex: ${complexity}. Maximum allowed complexity: ${maxComplexity}`,
          );
        }
        console.log('Query Complexity:', complexity);
      },
    };
  }
}
```

For demonstration purposes, we specified the maximum allowed complexity as `20`. In the example above, we used 2 estimators, the `simpleEstimator` and the `fieldExtensionsEstimator`.

* `simpleEstimator`: the simple estimator returns a fixed complexity for each field
* `fieldExtensionsEstimator`: the field extensions estimator extracts the complexity value for each field of your schema

> **Hint** Remember to add this class to the providers array in any module.

#### Field-level complexity[#](/graphql/complexity#field-level-complexity)

With this plugin in place, we can now define the complexity for any field by specifying the `complexity` property in the options object passed into the `@Field()` decorator, as follows:

```typescript

@Field({ complexity: 3 })
title: string;
```

Alternatively, you can define the estimator function:

```typescript

@Field({ complexity: (options: ComplexityEstimatorArgs) => ... })
title: string;
```

#### Query/Mutation-level complexity[#](/graphql/complexity#querymutation-level-complexity)

In addition, `@Query()` and `@Mutation()` decorators may have a `complexity` property specified like so:

```typescript

@Query({ complexity: (options: ComplexityEstimatorArgs) => options.args.count * options.childComplexity })
items(@Args('count') count: number) {
  return this.itemsService.getItems({ count });
}
```

----
url: https://docs.nestjs.com/faq/multiple-servers
----

[Skip to content](#content)

On this page

* [HTTPS](https://docs.nestjs.com/faq/multiple-servers#https)
* [Multiple simultaneous servers](https://docs.nestjs.com/faq/multiple-servers#multiple-simultaneous-servers)

### HTTPS

To create an application that uses the HTTPS protocol, set the `httpsOptions` property in the options object passed to the `NestFactory.create()` method:

```typescript

const httpsOptions = {
  key: fs.readFileSync('./secrets/private-key.pem'),
  cert: fs.readFileSync('./secrets/public-certificate.pem'),
};
const app = await NestFactory.create(AppModule, {
  httpsOptions,
});
await app.listen(process.env.PORT ?? 3000);
```

If you use the `FastifyAdapter`, create the application as follows:

```typescript

const app = await NestFactory.create<NestFastifyApplication>(
  AppModule,
  new FastifyAdapter({ https: httpsOptions }),
);
```

#### Multiple simultaneous servers[#](/faq/multiple-servers#multiple-simultaneous-servers)

The following recipe shows how to create a Nest application that listens on multiple ports simultaneously (for example, on an HTTP port and an HTTPS port):

```typescript

const httpsOptions = {
  key: fs.readFileSync('./secrets/private-key.pem'),
  cert: fs.readFileSync('./secrets/public-certificate.pem'),
};

const server = express();
const app = await NestFactory.create(AppModule, new ExpressAdapter(server));
await app.init();

const httpServer = http.createServer(server).listen(3000);
const httpsServer = https.createServer(httpsOptions, server).listen(443);
```

Because we created the servers ourselves with `http.createServer()` and `https.createServer()`, Nest doesn't close them when you call `app.close()` or when the process receives a termination signal. You need to close them yourself, for example with a provider that implements the `OnApplicationShutdown` hook:

```typescript

@Injectable()
export class ShutdownObserver implements OnApplicationShutdown {
  private httpServers: http.Server[] = [];

  public addHttpServer(server: http.Server): void {
    this.httpServers.push(server);
  }

  public async onApplicationShutdown(): Promise<void> {
    await Promise.all(
      this.httpServers.map(
        (server) =>
          new Promise((resolve, reject) => {
            server.close((error) => {
              if (error) {
                reject(error);
              } else {
                resolve(null);
              }
            });
          }),
      ),
    );
  }
}

const shutdownObserver = app.get(ShutdownObserver);
shutdownObserver.addHttpServer(httpServer);
shutdownObserver.addHttpServer(httpsServer);
```

> **Hint** The `ExpressAdapter` is imported from the `@nestjs/platform-express` package. The `http` and `https` modules are built into Node.js.

> **Warning** This recipe does not work with [GraphQL subscriptions](/graphql/subscriptions).

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/faq/multiple-servers.md)

----
url: https://docs.nestjs.com/v10/pipes
----

* [Pipes](https://docs.nestjs.com/v10/pipes#pipes)
* [Built-in pipes](https://docs.nestjs.com/v10/pipes#built-in-pipes)
* [Binding pipes](https://docs.nestjs.com/v10/pipes#binding-pipes)
* [Custom pipes](https://docs.nestjs.com/v10/pipes#custom-pipes)
* [Schema based validation](https://docs.nestjs.com/v10/pipes#schema-based-validation)
* [Object schema validation](https://docs.nestjs.com/v10/pipes#object-schema-validation)
* [Binding validation pipes](https://docs.nestjs.com/v10/pipes#binding-validation-pipes)
* [Class validator](https://docs.nestjs.com/v10/pipes#class-validator)
* [Global scoped pipes](https://docs.nestjs.com/v10/pipes#global-scoped-pipes)
* [The built-in ValidationPipe](https://docs.nestjs.com/v10/pipes#the-built-in-validationpipe)
* [Transformation use case](https://docs.nestjs.com/v10/pipes#transformation-use-case)
* [Providing defaults](https://docs.nestjs.com/v10/pipes#providing-defaults)

> **Hint** Pipes run inside the exceptions zone. This means that when a Pipe throws an exception it is handled by the exceptions layer (global exceptions filter and any [exceptions filters](/v10/exception-filters) that are applied to the current context). Given the above, it should be clear that when an exception is thrown in a Pipe, no controller method is subsequently executed. This gives you a best-practice technique for validating data coming into the application from external sources at the system boundary.

```typescript

@Get(':id')
async findOne(@Param('id', ParseIntPipe) id: number) {
  return this.catsService.findOne(id);
}
```

This ensures that one of the following two conditions is true: either the parameter we receive in the `findOne()` method is a number (as expected in our call to `this.catsService.findOne()`), or an exception is thrown before the route handler is called.

For example, assume the route is called like:

```bash

GET localhost:3000/abc
```

Nest will throw an exception like this:

```json

{
  "statusCode": 400,
  "message": "Validation failed (numeric string is expected)",
  "error": "Bad Request"
}
```

The exception will prevent the body of the `findOne()` method from executing.

In the example above, we pass a class (`ParseIntPipe`), not an instance, leaving responsibility for instantiation to the framework and enabling dependency injection. As with pipes and guards, we can instead pass an in-place instance. Passing an in-place instance is useful if we want to customize the built-in pipe's behavior by passing options:

```typescript

@Get(':id')
async findOne(
  @Param('id', new ParseIntPipe({ errorHttpStatusCode: HttpStatus.NOT_ACCEPTABLE }))
  id: number,
) {
  return this.catsService.findOne(id);
}
```

Binding the other transformation pipes (all of the **Parse\*** pipes) works similarly. These pipes all work in the context of validating route parameters, query string parameters and request body values.

For example with a query string parameter:

```typescript

@Get()
async findOne(@Query('id', ParseIntPipe) id: number) {
  return this.catsService.findOne(id);
}
```

Here's an example of using the `ParseUUIDPipe` to parse a string parameter and validate if it is a UUID.

JS TS

```typescript

@Get(':uuid')
async findOne(@Param('uuid', new ParseUUIDPipe()) uuid: string) {
  return this.catsService.findOne(uuid);
}
```

```typescript

@Get(':uuid')
@Bind(Param('uuid', new ParseUUIDPipe()))
async findOne(uuid) {
  return this.catsService.findOne(uuid);
}
```

> **Hint** When using `ParseUUIDPipe()` you are parsing UUID in version 3, 4 or 5, if you only require a specific version of UUID you can pass a version in the pipe options.

Above we've seen examples of binding the various `Parse*` family of built-in pipes. Binding validation pipes is a little bit different; we'll discuss that in the following section.

> **Hint** Also, see [Validation techniques](/v10/techniques/validation) for extensive examples of validation pipes.

#### Custom pipes[#](/pipes#custom-pipes)

As mentioned, you can build your own custom pipes. While Nest provides a robust built-in `ParseIntPipe` and `ValidationPipe`, let's build simple custom versions of each from scratch to see how custom pipes are constructed.

We start with a simple `ValidationPipe`. Initially, we'll have it simply take an input value and immediately return the same value, behaving like an identity function.

validation.pipe.ts

JS TS

```typescript

import { PipeTransform, Injectable, ArgumentMetadata } from '@nestjs/common';

@Injectable()
export class ValidationPipe implements PipeTransform {
  transform(value: any, metadata: ArgumentMetadata) {
    return value;
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';

@Injectable()
export class ValidationPipe {
  transform(value, metadata) {
    return value;
  }
}
```

> **Hint**`PipeTransform<T, R>` is a generic interface that must be implemented by any pipe. The generic interface uses `T` to indicate the type of the input `value`, and `R` to indicate the return type of the `transform()` method.

Every pipe must implement the `transform()` method to fulfill the `PipeTransform` interface contract. This method has two parameters:

* `value`
* `metadata`

The `value` parameter is the currently processed method argument (before it is received by the route handling method), and `metadata` is the currently processed method argument's metadata. The metadata object has these properties:

```typescript

export interface ArgumentMetadata {
  type: 'body' | 'query' | 'param' | 'custom';
  metatype?: Type<unknown>;
  data?: string;
}
```

These properties describe the currently processed argument.

|            |                                                                                                                                                                                                      |
| ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `type`     | Indicates whether the argument is a body `@Body()`, query `@Query()`, param `@Param()`, or a custom parameter (read more [here](/v10/custom-decorators)).                                            |
| `metatype` | Provides the metatype of the argument, for example, `String`. Note: the value is `undefined` if you either omit a type declaration in the route handler method signature, or use vanilla JavaScript. |
| `data`     | The string passed to the decorator, for example `@Body('string')`. It's `undefined` if you leave the decorator parenthesis empty.                                                                    |

> **Warning** TypeScript interfaces disappear during transpilation. Thus, if a method parameter's type is declared as an interface instead of a class, the `metatype` value will be `Object`.

#### Schema based validation[#](/pipes#schema-based-validation)

Let's make our validation pipe a little more useful. Take a closer look at the `create()` method of the `CatsController`, where we probably would like to ensure that the post body object is valid before attempting to run our service method.

JS TS

```typescript

@Post()
async create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

```typescript

@Post()
async create(@Body() createCatDto) {
  this.catsService.create(createCatDto);
}
```

Let's focus in on the `createCatDto` body parameter. Its type is `CreateCatDto`:

create-cat.dto.ts

JS TS

```typescript

export class CreateCatDto {
  name: string;
  age: number;
  breed: string;
}
```

```bash

$ npm install --save zod
```

In the code sample below, we create a simple class that takes a schema as a `constructor` argument. We then apply the `schema.parse()` method, which validates our incoming argument against the provided schema.

As noted earlier, a **validation pipe** either returns the value unchanged or throws an exception.

In the next section, you'll see how we supply the appropriate schema for a given controller method using the `@UsePipes()` decorator. Doing so makes our validation pipe reusable across contexts, just as we set out to do.

JS TS

```typescript

import { PipeTransform, ArgumentMetadata, BadRequestException } from '@nestjs/common';
import { ZodSchema  } from 'zod';

export class ZodValidationPipe implements PipeTransform {
  constructor(private schema: ZodSchema) {}

  transform(value: unknown, metadata: ArgumentMetadata) {
    try {
      const parsedValue = this.schema.parse(value);
      return parsedValue;
    } catch (error) {
      throw new BadRequestException('Validation failed');
    }
  }
}
```

```typescript

import { BadRequestException } from '@nestjs/common';

export class ZodValidationPipe {
  constructor(private schema) {}

  transform(value, metadata) {
    try {
      const parsedValue = this.schema.parse(value);
      return parsedValue;
    } catch (error) {
      throw new BadRequestException('Validation failed');
    }
  }
}
```

```typescript

import { z } from 'zod';

export const createCatSchema = z
  .object({
    name: z.string(),
    age: z.number(),
    breed: z.string(),
  })
  .required();

export type CreateCatDto = z.infer<typeof createCatSchema>;
```

We do that using the `@UsePipes()` decorator as shown below:

cats.controller.ts

JS TS

```typescript

@Post()
@UsePipes(new ZodValidationPipe(createCatSchema))
async create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

```typescript

@Post()
@Bind(Body())
@UsePipes(new ZodValidationPipe(createCatSchema))
async create(createCatDto) {
  this.catsService.create(createCatDto);
}
```

> **Hint** The `@UsePipes()` decorator is imported from the `@nestjs/common` package.

> **Warning**`zod` library requires the `strictNullChecks` configuration to be enabled in your `tsconfig.json` file.

#### Class validator[#](/pipes#class-validator)

> **Warning** The techniques in this section require TypeScript and are not available if your app is written using vanilla JavaScript.

Let's look at an alternate implementation for our validation technique.

Nest works well with the [class-validator](https://github.com/typestack/class-validator) library. This powerful library allows you to use decorator-based validation. Decorator-based validation is extremely powerful, especially when combined with Nest's **Pipe** capabilities since we have access to the `metatype` of the processed property. Before we start, we need to install the required packages:

```bash

$ npm i --save class-validator class-transformer
```

Once these are installed, we can add a few decorators to the `CreateCatDto` class. Here we see a significant advantage of this technique: the `CreateCatDto` class remains the single source of truth for our Post body object (rather than having to create a separate validation class).

create-cat.dto.ts

JS TS

```typescript

import { IsString, IsInt } from 'class-validator';

export class CreateCatDto {
  @IsString()
  name: string;

  @IsInt()
  age: number;

  @IsString()
  breed: string;
}
```

> **Hint** Read more about the class-validator decorators [here](https://github.com/typestack/class-validator#usage).

Now we can create a `ValidationPipe` class that uses these annotations.

validation.pipe.ts

JS TS

```typescript

import { PipeTransform, Injectable, ArgumentMetadata, BadRequestException } from '@nestjs/common';
import { validate } from 'class-validator';
import { plainToInstance } from 'class-transformer';

@Injectable()
export class ValidationPipe implements PipeTransform<any> {
  async transform(value: any, { metatype }: ArgumentMetadata) {
    if (!metatype || !this.toValidate(metatype)) {
      return value;
    }
    const object = plainToInstance(metatype, value);
    const errors = await validate(object);
    if (errors.length > 0) {
      throw new BadRequestException('Validation failed');
    }
    return value;
  }

  private toValidate(metatype: Function): boolean {
    const types: Function[] = [String, Boolean, Number, Array, Object];
    return !types.includes(metatype);
  }
}
```

> **Hint** As a reminder, you don't have to build a generic validation pipe on your own since the `ValidationPipe` is provided by Nest out-of-the-box. The built-in `ValidationPipe` offers more options than the sample we built in this chapter, which has been kept basic for the sake of illustrating the mechanics of a custom-built pipe. You can find full details, along with lots of examples [here](/v10/techniques/validation).

> **Notice** We used the [class-transformer](https://github.com/typestack/class-transformer) library above which is made by the same author as the **class-validator** library, and as a result, they play very well together.

```typescript

@Post()
async create(
  @Body(new ValidationPipe()) createCatDto: CreateCatDto,
) {
  this.catsService.create(createCatDto);
}
```

Parameter-scoped pipes are useful when the validation logic concerns only one specified parameter.

#### Global scoped pipes[#](/pipes#global-scoped-pipes)

Since the `ValidationPipe` was created to be as generic as possible, we can realize its full utility by setting it up as a **global-scoped** pipe so that it is applied to every route handler across the entire application.

main.ts

JS TS

```typescript

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.useGlobalPipes(new ValidationPipe());
  await app.listen(process.env.PORT ?? 3000);
}
bootstrap();
```

> **Notice** In the case of [hybrid apps](faq/hybrid-application) the `useGlobalPipes()` method doesn't set up pipes for gateways and microservices. For "standard" (non-hybrid) microservice apps, `useGlobalPipes()` does mount pipes globally.

Global pipes are used across the whole application, for every controller and every route handler.

Note that in terms of dependency injection, global pipes registered from outside of any module (with `useGlobalPipes()` as in the example above) cannot inject dependencies since the binding has been done outside the context of any module. In order to solve this issue, you can set up a global pipe **directly from any module** using the following construction:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { APP_PIPE } from '@nestjs/core';

@Module({
  providers: [
    {
      provide: APP_PIPE,
      useClass: ValidationPipe,
    },
  ],
})
export class AppModule {}
```

> **Hint** When using this approach to perform dependency injection for the pipe, note that regardless of the module where this construction is employed, the pipe is, in fact, global. Where should this be done? Choose the module where the pipe (`ValidationPipe` in the example above) is defined. Also, `useClass` is not the only way of dealing with custom provider registration. Learn more [here](/v10/fundamentals/custom-providers).

#### The built-in ValidationPipe[#](/pipes#the-built-in-validationpipe)

As a reminder, you don't have to build a generic validation pipe on your own since the `ValidationPipe` is provided by Nest out-of-the-box. The built-in `ValidationPipe` offers more options than the sample we built in this chapter, which has been kept basic for the sake of illustrating the mechanics of a custom-built pipe. You can find full details, along with lots of examples [here](/v10/techniques/validation).

#### Transformation use case[#](/pipes#transformation-use-case)

Validation isn't the only use case for custom pipes. At the beginning of this chapter, we mentioned that a pipe can also **transform** the input data to the desired format. This is possible because the value returned from the `transform` function completely overrides the previous value of the argument.

When is this useful? Consider that sometimes the data passed from the client needs to undergo some change - for example converting a string to an integer - before it can be properly handled by the route handler method. Furthermore, some required data fields may be missing, and we would like to apply default values. **Transformation pipes** can perform these functions by interposing a processing function between the client request and the request handler.

Here's a simple `ParseIntPipe` which is responsible for parsing a string into an integer value. (As noted above, Nest has a built-in `ParseIntPipe` that is more sophisticated; we include this as a simple example of a custom transformation pipe).

parse-int.pipe.ts

JS TS

```typescript

import { PipeTransform, Injectable, ArgumentMetadata, BadRequestException } from '@nestjs/common';

@Injectable()
export class ParseIntPipe implements PipeTransform<string, number> {
  transform(value: string, metadata: ArgumentMetadata): number {
    const val = parseInt(value, 10);
    if (isNaN(val)) {
      throw new BadRequestException('Validation failed');
    }
    return val;
  }
}
```

```typescript

import { Injectable, BadRequestException } from '@nestjs/common';

@Injectable()
export class ParseIntPipe {
  transform(value, metadata) {
    const val = parseInt(value, 10);
    if (isNaN(val)) {
      throw new BadRequestException('Validation failed');
    }
    return val;
  }
}
```

We can then bind this pipe to the selected param as shown below:

JS TS

```typescript

@Get(':id')
async findOne(@Param('id', new ParseIntPipe()) id) {
  return this.catsService.findOne(id);
}
```

```typescript

@Get(':id')
@Bind(Param('id', new ParseIntPipe()))
async findOne(id) {
  return this.catsService.findOne(id);
}
```

Another useful transformation case would be to select an **existing user** entity from the database using an id supplied in the request:

JS TS

```typescript

@Get(':id')
findOne(@Param('id', UserByIdPipe) userEntity: UserEntity) {
  return userEntity;
}
```

```typescript

@Get(':id')
@Bind(Param('id', UserByIdPipe))
findOne(userEntity) {
  return userEntity;
}
```

We leave the implementation of this pipe to the reader, but note that like all other transformation pipes, it receives an input value (an `id`) and returns an output value (a `UserEntity` object). This can make your code more declarative and [DRY](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself) by abstracting boilerplate code out of your handler and into a common pipe.

#### Providing defaults[#](/pipes#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:

JS TS

```typescript

@Get()
async findAll(
  @Query('activeOnly', new DefaultValuePipe(false), ParseBoolPipe) activeOnly: boolean,
  @Query('page', new DefaultValuePipe(0), ParseIntPipe) page: number,
) {
  return this.catsService.findAll({ activeOnly, page });
}
```

----
url: https://docs.nestjs.com/v10/techniques/server-sent-events
----

* [Server-Sent Events](https://docs.nestjs.com/v10/techniques/server-sent-events#server-sent-events)
* [Usage](https://docs.nestjs.com/v10/techniques/server-sent-events#usage)
* [Example](https://docs.nestjs.com/v10/techniques/server-sent-events#example)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/techniques/server-sent-events.md "Suggest Edits")

### Server-Sent Events

Server-Sent Events (SSE) is a server push technology enabling a client to receive automatic updates from a server via HTTP connection. Each notification is sent as a block of text terminated by a pair of newlines (learn more [here](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events)).

#### Usage[#](/techniques/server-sent-events#usage)

To enable Server-Sent events on a route (route registered within a **controller class**), annotate the method handler with the `@Sse()` decorator.

```typescript

@Sse('sse')
sse(): Observable<MessageEvent> {
  return interval(1000).pipe(map((_) => ({ data: { hello: 'world' } })));
}
```

> **Hint** The `@Sse()` decorator and `MessageEvent` interface are imported from the `@nestjs/common`, while `Observable`, `interval`, and `map` are imported from the `rxjs` package.

> **Warning** Server-Sent Events routes must return an `Observable` stream.

In the example above, we defined a route named `sse` that will allow us to propagate real-time updates. These events can be listened to using the [EventSource API](https://developer.mozilla.org/en-US/docs/Web/API/EventSource).

The `sse` method returns an `Observable` that emits multiple `MessageEvent` (in this example, it emits a new `MessageEvent` every second). The `MessageEvent` object should respect the following interface to match the specification:

```typescript

export interface MessageEvent {
  data: string | object;
  id?: string;
  type?: string;
  retry?: number;
}
```

With this in place, we can now create an instance of the `EventSource` class in our client-side application, passing the `/sse` route (which matches the endpoint we have passed into the `@Sse()` decorator above) as a constructor argument.

`EventSource` instance opens a persistent connection to an HTTP server, which sends events in `text/event-stream` format. The connection remains open until closed by calling `EventSource.close()`.

Once the connection is opened, incoming messages from the server are delivered to your code in the form of events. If there is an event field in the incoming message, the triggered event is the same as the event field value. If no event field is present, then a generic `message` event is fired ([source](https://developer.mozilla.org/en-US/docs/Web/API/EventSource)).

```javascript

const eventSource = new EventSource('/sse');
eventSource.onmessage = ({ data }) => {
  console.log('New message', JSON.parse(data));
};
```

#### Example[#](/techniques/server-sent-events#example)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/28-sse).

----
url: https://docs.nestjs.com/v10/openapi/decorators
----

* [Decorators](https://docs.nestjs.com/v10/openapi/decorators#decorators)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/openapi/decorators.md "Suggest Edits")

### Decorators

All of the available OpenAPI decorators have an `Api` prefix to distinguish them from the core decorators. Below is a full list of the exported decorators along with a designation of the level at which the decorator may be applied.

| `@ApiBasicAuth()`         | Method / Controller |
| ------------------------- | ------------------- |
| `@ApiBearerAuth()`        | Method / Controller |
| `@ApiBody()`              | Method              |
| `@ApiConsumes()`          | Method / Controller |
| `@ApiCookieAuth()`        | Method / Controller |
| `@ApiExcludeController()` | Controller          |
| `@ApiExcludeEndpoint()`   | Method              |
| `@ApiExtension()`         | Method              |
| `@ApiExtraModels()`       | Method / Controller |
| `@ApiHeader()`            | Method / Controller |
| `@ApiHideProperty()`      | Model               |
| `@ApiOAuth2()`            | Method / Controller |
| `@ApiOperation()`         | Method              |
| `@ApiParam()`             | Method / Controller |
| `@ApiProduces()`          | Method / Controller |
| `@ApiSchema()`            | Model               |
| `@ApiProperty()`          | Model               |
| `@ApiPropertyOptional()`  | Model               |
| `@ApiQuery()`             | Method / Controller |
| `@ApiResponse()`          | Method / Controller |
| `@ApiSecurity()`          | Method / Controller |
| `@ApiTags()`              | Method / Controller |
| `@ApiCallbacks()`         | Method / Controller |

----
url: https://docs.nestjs.com/v6/techniques/caching
----

* [Caching](https://docs.nestjs.com/v6/techniques/caching#caching)
* [Installation](https://docs.nestjs.com/v6/techniques/caching#installation)
* [In-memory cache](https://docs.nestjs.com/v6/techniques/caching#in-memory-cache)
* [Global cache](https://docs.nestjs.com/v6/techniques/caching#global-cache)
* [Customize caching](https://docs.nestjs.com/v6/techniques/caching#customize-caching)
* [Global cache overrides](https://docs.nestjs.com/v6/techniques/caching#global-cache-overrides)
* [WebSockets & Microservices](https://docs.nestjs.com/v6/techniques/caching#websockets--microservices)
* [Different stores](https://docs.nestjs.com/v6/techniques/caching#different-stores)
* [Adjust tracking](https://docs.nestjs.com/v6/techniques/caching#adjust-tracking)
* [Async configuration](https://docs.nestjs.com/v6/techniques/caching#async-configuration)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/techniques/caching.md "Suggest Edits")

### Caching

Caching is a great and simple **technique** that helps improve your app's performance. It acts as a temporary data store providing high performance data access.

#### Installation[#](/techniques/caching#installation)

First install the required package:

```bash

$ npm install --save cache-manager
```

#### In-memory cache[#](/techniques/caching#in-memory-cache)

Nest provides a unified API for various cache storage providers. The built-in one is an in-memory data store. However, you can easily switch to a more comprehensive solution, like Redis. In order to enable caching, first import the `CacheModule` and call its `register()` method.

```typescript

import { CacheModule, Module } from '@nestjs/common';
import { AppController } from './app.controller';

@Module({
  imports: [CacheModule.register()],
  controllers: [AppController],
})
export class ApplicationModule {}
```

Then just tie the `CacheInterceptor` where you want to cache data.

```typescript

@Controller()
@UseInterceptors(CacheInterceptor)
export class AppController {
  @Get()
  findAll(): string[] {
    return [];
  }
}
```

> **Warning** Only `GET` endpoints are cached. Also, HTTP server routes that inject the native response object (`@Res()`) cannot use the Cache Interceptor. See [response mapping](https://docs.nestjs.com/interceptors#response-mapping) for more details.

#### Global cache[#](/techniques/caching#global-cache)

To reduce the amount of required boilerplate, you can bind `CacheInterceptor` to all endpoints globally:

```typescript

import { CacheModule, Module, CacheInterceptor } from '@nestjs/common';
import { AppController } from './app.controller';
import { APP_INTERCEPTOR } from '@nestjs/core';

@Module({
  imports: [CacheModule.register()],
  controllers: [AppController],
  providers: [
    {
      provide: APP_INTERCEPTOR,
      useClass: CacheInterceptor,
    },
  ],
})
export class ApplicationModule {}
```

#### Customize caching[#](/techniques/caching#customize-caching)

All cached data has its own expiration time (TTL). To customize default values, pass the options object to the `register()` method.

```typescript

CacheModule.register({
  ttl: 5, // seconds
  max: 10, // maximum number of items in cache
});
```

#### Global cache overrides[#](/techniques/caching#global-cache-overrides)

While global cache is enabled, cache entries are stored under a `CacheKey` that is auto-generated based on the route path. You may override certain cache settings (`@CacheKey()` and `@CacheTTL()`) on a per-method basis, allowing customized caching strategies for individual controller methods. This may be most relevant while using [different cache stores.](https://docs.nestjs.com/techniques/caching#different-stores)

```typescript

@Controller()
export class AppController {
  @CacheKey('custom_key')
  @CacheTTL(20)
  findAll(): string[] {
    return [];
  }
}
```

> **Hint** The `@CacheKey()` and `@CacheTTL()` decorators are imported from the `@nestjs/common` package.

The `@CacheKey()` decorator may be used with or without a corresponding `@CacheTTL()` decorator and vice versa. One may choose to override only the `@CacheKey()` or only the `@CacheTTL()`. Settings that are not overridden with a decorator will use the default values as registered globally (see [Customize caching](https://docs.nestjs.com/techniques/caching#customize-caching)).

#### WebSockets & Microservices[#](/techniques/caching#websockets--microservices)

You can also apply the `CacheInterceptor` to WebSocket subscribers as well as Microservice's patterns (regardless of the transport method that is being used).

JS TS

```typescript

@CacheKey('events')
@UseInterceptors(CacheInterceptor)
@SubscribeMessage('events')
handleEvent(client: Client, data: string[]): Observable<string[]> {
  return [];
}
```

```typescript

@CacheKey('events')
@UseInterceptors(CacheInterceptor)
@SubscribeMessage('events')
handleEvent(client, data) {
  return [];
}
```

However, the additional `@CacheKey()` decorator is required in order to specify a key used to subsequently store and retrieve cached data. Also, please note that you **shouldn't cache everything**. Actions which perform some business operations rather than simply querying the data should never be cached.

Additionally, you may specify a cache expiration time (TTL) by using the `@CacheTTL()` decorator, which will override the global default TTL value.

JS TS

```typescript

@CacheTTL(10)
@UseInterceptors(CacheInterceptor)
@SubscribeMessage('events')
handleEvent(client: Client, data: string[]): Observable<string[]> {
  return [];
}
```

```typescript

@CacheTTL(10)
@UseInterceptors(CacheInterceptor)
@SubscribeMessage('events')
handleEvent(client, data) {
  return [];
}
```

> **Hint** The `@CacheTTL()` decorator may be used with or without a corresponding `@CacheKey()` decorator.

#### Different stores[#](/techniques/caching#different-stores)

This service takes advantage of [cache-manager](https://github.com/BryanDonovan/node-cache-manager) under the hood. The `cache-manager` package supports a wide-range of useful stores, for example, [Redis](https://github.com/dabroek/node-cache-manager-redis-store) store. A full list of supported stores is available [here](https://github.com/BryanDonovan/node-cache-manager#store-engines). To set up the Redis store, simple pass the package together with corresponding options to the `register()` method.

```typescript

import * as redisStore from 'cache-manager-redis-store';
import { CacheModule, Module } from '@nestjs/common';
import { AppController } from './app.controller';

@Module({
  imports: [
    CacheModule.register({
      store: redisStore,
      host: 'localhost',
      port: 6379,
    }),
  ],
  controllers: [AppController],
})
export class ApplicationModule {}
```

#### Adjust tracking[#](/techniques/caching#adjust-tracking)

By default, Nest uses the request URL (in an HTTP app) or cache key (in websockets and microservices apps, set through the `@CacheKey()` decorator) to associate cache records with your endpoints. Nevertheless, sometimes you might want to set up tracking based on different factors, for example, using HTTP headers (e.g. `Authorization` to properly identify `profile` endpoints).

In order to accomplish that, create a subclass of `CacheInterceptor` and override the `trackBy()` method.

```typescript

@Injectable()
class HttpCacheInterceptor extends CacheInterceptor {
  trackBy(context: ExecutionContext): string | undefined {
    return 'key';
  }
}
```

#### Async configuration[#](/techniques/caching#async-configuration)

You may want to asynchronously pass in module options instead of passing them statically at compile time. In this case, use the `registerAsync()` method, which provides several ways to deal with async configuration.

One approach is to use a factory function:

```typescript

CacheModule.registerAsync({
  useFactory: () => ({
    ttl: 5,
  }),
});
```

Our factory behaves like all other asynchronous module factories (it can be `async` and is able to inject dependencies through `inject`).

```typescript

CacheModule.registerAsync({
  imports: [ConfigModule],
  useFactory: async (configService: ConfigService) => ({
    ttl: configService.getString('CACHE_TTL'),
  }),
  inject: [ConfigService],
});
```

Alternatively, you can use the `useClass` method:

```typescript

CacheModule.registerAsync({
  useClass: CacheConfigService,
});
```

The above construction will instantiate `CacheConfigService` inside `CacheModule` and will use it to get the options object. The `CacheConfigService` has to implement the `CacheOptionsFactory` interface in order to provide the configuration options:

```typescript

@Injectable()
class CacheConfigService implements CacheOptionsFactory {
  createCacheOptions(): CacheModuleOptions {
    return {
      ttl: 5,
    };
  }
}
```

If you wish to use an existing configuration provider imported from a different module, use the `useExisting` syntax:

```typescript

CacheModule.registerAsync({
  imports: [ConfigModule],
  useExisting: ConfigService,
});
```

This works the same as `useClass` with one critical difference - `CacheModule` will lookup imported modules to reuse any already-created `ConfigService`, instead of instantiating its own.

----
url: https://docs.nestjs.com/v7/openapi/security
----

* [Security](https://docs.nestjs.com/v7/openapi/security#security)
* [Basic authentication](https://docs.nestjs.com/v7/openapi/security#basic-authentication)
* [Bearer authentication](https://docs.nestjs.com/v7/openapi/security#bearer-authentication)
* [OAuth2 authentication](https://docs.nestjs.com/v7/openapi/security#oauth2-authentication)
* [Cookie authentication](https://docs.nestjs.com/v7/openapi/security#cookie-authentication)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/openapi/security.md "Suggest Edits")

### Security

To define which security mechanisms should be used for a specific operation, use the `@ApiSecurity()` decorator.

```typescript

@ApiSecurity('basic')
@Controller('cats')
export class CatsController {}
```

Before you run your application, remember to add the security definition to your base document using `DocumentBuilder`:

```typescript

const options = new DocumentBuilder().addSecurity('basic', {
  type: 'http',
  scheme: 'basic',
});
```

Some of the most popular authentication techniques are built-in (e.g., `basic` and `bearer`) and therefore you don't have to define security mechanisms manually as shown above.

#### Basic authentication

To enable basic authentication, use `@ApiBasicAuth()`.

```typescript

@ApiBasicAuth()
@Controller('cats')
export class CatsController {}
```

Before you run your application, remember to add the security definition to your base document using `DocumentBuilder`:

```typescript

const options = new DocumentBuilder().addBasicAuth();
```

#### Bearer authentication

To enable bearer authentication, use `@ApiBearerAuth()`.

```typescript

@ApiBearerAuth()
@Controller('cats')
export class CatsController {}
```

Before you run your application, remember to add the security definition to your base document using `DocumentBuilder`:

```typescript

const options = new DocumentBuilder().addBearerAuth();
```

#### OAuth2 authentication

To enable OAuth2, use `@ApiOAuth2()`.

```typescript

@ApiOAuth2(['pets:write'])
@Controller('cats')
export class CatsController {}
```

Before you run your application, remember to add the security definition to your base document using `DocumentBuilder`:

```typescript

const options = new DocumentBuilder().addOAuth2();
```

#### Cookie authentication

To enable cookie authentication, use `@ApiCookieAuth()`.

```typescript

@ApiCookieAuth()
@Controller('cats')
export class CatsController {}
```

Before you run your application, remember to add the security definition to your base document using `DocumentBuilder`:

```typescript

const options = new DocumentBuilder().addCookieAuth('optional-session-id');
```

----
url: https://docs.nestjs.com/v11/graphql/subscriptions
----

* [Subscriptions](https://docs.nestjs.com/v11/graphql/subscriptions#subscriptions)
* [Enable subscriptions with Apollo driver](https://docs.nestjs.com/v11/graphql/subscriptions#enable-subscriptions-with-apollo-driver)
* [Code first](https://docs.nestjs.com/v11/graphql/subscriptions#code-first)
* [Publishing](https://docs.nestjs.com/v11/graphql/subscriptions#publishing)
* [Filtering subscriptions](https://docs.nestjs.com/v11/graphql/subscriptions#filtering-subscriptions)
* [Mutating subscription payloads](https://docs.nestjs.com/v11/graphql/subscriptions#mutating-subscription-payloads)
* [Schema first](https://docs.nestjs.com/v11/graphql/subscriptions#schema-first)
* [PubSub](https://docs.nestjs.com/v11/graphql/subscriptions#pubsub)
* [Customize subscriptions server](https://docs.nestjs.com/v11/graphql/subscriptions#customize-subscriptions-server)
* [Authentication over WebSockets](https://docs.nestjs.com/v11/graphql/subscriptions#authentication-over-websockets)
* [Enable subscriptions with Mercurius driver](https://docs.nestjs.com/v11/graphql/subscriptions#enable-subscriptions-with-mercurius-driver)
* [Code first](https://docs.nestjs.com/v11/graphql/subscriptions#code-first-1)
* [Publishing](https://docs.nestjs.com/v11/graphql/subscriptions#publishing-1)
* [Filtering subscriptions](https://docs.nestjs.com/v11/graphql/subscriptions#filtering-subscriptions-1)
* [Schema first](https://docs.nestjs.com/v11/graphql/subscriptions#schema-first-1)
* [PubSub](https://docs.nestjs.com/v11/graphql/subscriptions#pubsub-1)
* [Authentication over WebSockets](https://docs.nestjs.com/v11/graphql/subscriptions#authentication-over-websockets-1)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/subscriptions.md "Suggest Edits")

### Subscriptions

In addition to fetching data using queries and modifying data using mutations, the GraphQL spec supports a third operation type, called `subscription`. GraphQL subscriptions are a way to push data from the server to the clients that choose to listen to real time messages from the server. Subscriptions are similar to queries in that they specify a set of fields to be delivered to the client, but instead of immediately returning a single answer, a channel is opened and a result is sent to the client every time a particular event happens on the server.

A common use case for subscriptions is notifying the client side about particular events, for example the creation of a new object, updated fields and so on (read more [here](https://www.apollographql.com/docs/react/data/subscriptions)).

#### Enable subscriptions with Apollo driver[#](/graphql/subscriptions#enable-subscriptions-with-apollo-driver)

To enable subscriptions, set the `installSubscriptionHandlers` property to `true`.

```typescript

GraphQLModule.forRoot<ApolloDriverConfig>({
  driver: ApolloDriver,
  installSubscriptionHandlers: true,
}),
```

> **Warning** The `installSubscriptionHandlers` configuration option has been removed from the latest version of Apollo server and will be soon deprecated in this package as well. By default, `installSubscriptionHandlers` will fallback to use the `subscriptions-transport-ws` ([read more](https://github.com/apollographql/subscriptions-transport-ws)) but we strongly recommend using the `graphql-ws`([read more](https://github.com/enisdenjo/graphql-ws)) library instead.

To switch to use the `graphql-ws` package instead, use the following configuration:

```typescript

GraphQLModule.forRoot<ApolloDriverConfig>({
  driver: ApolloDriver,
  subscriptions: {
    'graphql-ws': true
  },
}),
```

> **Hint** You can also use both packages (`subscriptions-transport-ws` and `graphql-ws`) at the same time, for example, for backward compatibility.

#### Code first[#](/graphql/subscriptions#code-first)

To create a subscription using the code first approach, we use the `@Subscription()` decorator (exported from the `@nestjs/graphql` package) and the `PubSub` class from the `graphql-subscriptions` package, which provides a simple **publish/subscribe API**.

The following subscription handler takes care of **subscribing** to an event by calling `PubSub#asyncIterableIterator`. This method takes a single argument, the `triggerName`, which corresponds to an event topic name.

```typescript

const pubSub = new PubSub();

@Resolver(() => Author)
export class AuthorResolver {
  // ...
  @Subscription(() => Comment)
  commentAdded() {
    return pubSub.asyncIterableIterator('commentAdded');
  }
}
```

> **Hint** All decorators are exported from the `@nestjs/graphql` package, while the `PubSub` class is exported from the `graphql-subscriptions` package.

> **Note**`PubSub` is a class that exposes a simple `publish` and `subscribe API`. Read more about it [here](https://www.apollographql.com/docs/graphql-subscriptions/setup.html). Note that the Apollo docs warn that the default implementation is not suitable for production (read more [here](https://github.com/apollographql/graphql-subscriptions#getting-started-with-your-first-subscription)). Production apps should use a `PubSub` implementation backed by an external store (read more [here](https://github.com/apollographql/graphql-subscriptions#pubsub-implementations)).

This will result in generating the following part of the GraphQL schema in SDL:

```graphql

type Subscription {
  commentAdded(): Comment!
}
```

Note that subscriptions, by definition, return an object with a single top level property whose key is the name of the subscription. This name is either inherited from the name of the subscription handler method (i.e., `commentAdded` above), or is provided explicitly by passing an option with the key `name` as the second argument to the `@Subscription()` decorator, as shown below.

```typescript

@Subscription(() => Comment, {
  name: 'commentAdded',
})
subscribeToCommentAdded() {
  return pubSub.asyncIterableIterator('commentAdded');
}
```

This construct produces the same SDL as the previous code sample, but allows us to decouple the method name from the subscription.

#### Publishing[#](/graphql/subscriptions#publishing)

Now, to publish the event, we use the `PubSub#publish` method. This is often used within a mutation to trigger a client-side update when a part of the object graph has changed. For example:

posts/posts.resolver.ts

JS TS

```typescript

@Mutation(() => Comment)
async addComment(
  @Args('postId', { type: () => Int }) postId: number,
  @Args('comment', { type: () => Comment }) comment: CommentInput,
) {
  const newComment = this.commentsService.addComment({ id: postId, comment });
  pubSub.publish('commentAdded', { commentAdded: newComment });
  return newComment;
}
```

The `PubSub#publish` method takes a `triggerName` (again, think of this as an event topic name) as the first parameter, and an event payload as the second parameter. As mentioned, the subscription, by definition, returns a value and that value has a shape. Look again at the generated SDL for our `commentAdded` subscription:

```graphql

type Subscription {
  commentAdded(): Comment!
}
```

This tells us that the subscription must return an object with a top-level property name of `commentAdded` that has a value which is a `Comment` object. The important point to note is that the shape of the event payload emitted by the `PubSub#publish` method must correspond to the shape of the value expected to return from the subscription. So, in our example above, the `pubSub.publish('commentAdded', { commentAdded: newComment })` statement publishes a `commentAdded` event with the appropriately shaped payload. If these shapes don't match, your subscription will fail during the GraphQL validation phase.

#### Filtering subscriptions[#](/graphql/subscriptions#filtering-subscriptions)

To filter out specific events, set the `filter` property to a filter function. This function acts similar to the function passed to an array `filter`. It takes two arguments: `payload` containing the event payload (as sent by the event publisher), and `variables` taking any arguments passed in during the subscription request. It returns a boolean determining whether this event should be published to client listeners.

```typescript

@Subscription(() => Comment, {
  filter: (payload, variables) =>
    payload.commentAdded.title === variables.title,
})
commentAdded(@Args('title') title: string) {
  return pubSub.asyncIterableIterator('commentAdded');
}
```

#### Mutating subscription payloads[#](/graphql/subscriptions#mutating-subscription-payloads)

To mutate the published event payload, set the `resolve` property to a function. The function receives the event payload (as sent by the event publisher) and returns the appropriate value.

```typescript

@Subscription(() => Comment, {
  resolve: value => value,
})
commentAdded() {
  return pubSub.asyncIterableIterator('commentAdded');
}
```

> **Note** If you use the `resolve` option, you should return the unwrapped payload (e.g., with our example, return a `newComment` object directly, not a `{ commentAdded: newComment }` object).

If you need to access injected providers (e.g., use an external service to validate the data), use the following construction.

```typescript

@Subscription(() => Comment, {
  resolve(this: AuthorResolver, value) {
    // "this" refers to an instance of "AuthorResolver"
    return value;
  }
})
commentAdded() {
  return pubSub.asyncIterableIterator('commentAdded');
}
```

The same construction works with filters:

```typescript

@Subscription(() => Comment, {
  filter(this: AuthorResolver, payload, variables) {
    // "this" refers to an instance of "AuthorResolver"
    return payload.commentAdded.title === variables.title;
  }
})
commentAdded() {
  return pubSub.asyncIterableIterator('commentAdded');
}
```

#### Schema first[#](/graphql/subscriptions#schema-first)

To create an equivalent subscription in Nest, we'll make use of the `@Subscription()` decorator.

```typescript

const pubSub = new PubSub();

@Resolver('Author')
export class AuthorResolver {
  // ...
  @Subscription()
  commentAdded() {
    return pubSub.asyncIterableIterator('commentAdded');
  }
}
```

To filter out specific events based on context and arguments, set the `filter` property.

```typescript

@Subscription('commentAdded', {
  filter: (payload, variables) =>
    payload.commentAdded.title === variables.title,
})
commentAdded() {
  return pubSub.asyncIterableIterator('commentAdded');
}
```

To mutate the published payload, we can use a `resolve` function.

```typescript

@Subscription('commentAdded', {
  resolve: value => value,
})
commentAdded() {
  return pubSub.asyncIterableIterator('commentAdded');
}
```

If you need to access injected providers (e.g., use an external service to validate the data), use the following construction:

```typescript

@Subscription('commentAdded', {
  resolve(this: AuthorResolver, value) {
    // "this" refers to an instance of "AuthorResolver"
    return value;
  }
})
commentAdded() {
  return pubSub.asyncIterableIterator('commentAdded');
}
```

The same construction works with filters:

```typescript

@Subscription('commentAdded', {
  filter(this: AuthorResolver, payload, variables) {
    // "this" refers to an instance of "AuthorResolver"
    return payload.commentAdded.title === variables.title;
  }
})
commentAdded() {
  return pubSub.asyncIterableIterator('commentAdded');
}
```

The last step is to update the type definitions file.

```graphql

type Author {
  id: Int!
  firstName: String
  lastName: String
  posts: [Post]
}

type Post {
  id: Int!
  title: String
  votes: Int
}

type Query {
  author(id: Int!): Author
}

type Comment {
  id: String
  content: String
}

type Subscription {
  commentAdded(title: String!): Comment
}
```

With this, we've created a single `commentAdded(title: String!): Comment` subscription. You can find a full sample implementation [here](https://github.com/nestjs/nest/blob/master/sample/12-graphql-schema-first).

#### PubSub[#](/graphql/subscriptions#pubsub)

We instantiated a local `PubSub` instance above. The preferred approach is to define `PubSub` as a [provider](/v11/fundamentals/custom-providers) and inject it through the constructor (using the `@Inject()` decorator). This allows us to re-use the instance across the whole application. For example, define a provider as follows, then inject `'PUB_SUB'` where needed.

```typescript

{
  provide: 'PUB_SUB',
  useValue: new PubSub(),
}
```

#### Customize subscriptions server[#](/graphql/subscriptions#customize-subscriptions-server)

To customize the subscriptions server (e.g., change the path), use the `subscriptions` options property.

```typescript

GraphQLModule.forRoot<ApolloDriverConfig>({
  driver: ApolloDriver,
  subscriptions: {
    'subscriptions-transport-ws': {
      path: '/graphql'
    },
  }
}),
```

If you're using the `graphql-ws` package for subscriptions, replace the `subscriptions-transport-ws` key with `graphql-ws`, as follows:

```typescript

GraphQLModule.forRoot<ApolloDriverConfig>({
  driver: ApolloDriver,
  subscriptions: {
    'graphql-ws': {
      path: '/graphql'
    },
  }
}),
```

#### Authentication over WebSockets[#](/graphql/subscriptions#authentication-over-websockets)

Checking whether the user is authenticated can be done inside the `onConnect` callback function that you can specify in the `subscriptions` options.

The `onConnect` will receive as a first argument the `connectionParams` passed to the `SubscriptionClient` (read [more](https://www.apollographql.com/docs/react/data/subscriptions/#5-authenticate-over-websocket-optional)).

```typescript

GraphQLModule.forRoot<ApolloDriverConfig>({
  driver: ApolloDriver,
  subscriptions: {
    'subscriptions-transport-ws': {
      onConnect: (connectionParams) => {
        const authToken = connectionParams.authToken;
        if (!isValid(authToken)) {
          throw new Error('Token is not valid');
        }
        // extract user information from token
        const user = parseToken(authToken);
        // return user info to add them to the context later
        return { user };
      },
    }
  },
  context: ({ connection }) => {
    // connection.context will be equal to what was returned by the "onConnect" callback
  },
}),
```

The `authToken` in this example is only sent once by the client, when the connection is first established. All subscriptions made with this connection will have the same `authToken`, and thus the same user info.

> **Note** There is a bug in `subscriptions-transport-ws` that allows connections to skip the `onConnect` phase (read [more](https://github.com/apollographql/subscriptions-transport-ws/issues/349)). You should not assume that `onConnect` was called when the user starts a subscription, and always check that the `context` is populated.

If you're using the `graphql-ws` package, the signature of the `onConnect` callback will be slightly different:

```typescript

GraphQLModule.forRoot<ApolloDriverConfig>({
  driver: ApolloDriver,
  subscriptions: {
    'graphql-ws': {
      onConnect: (context: Context<any>) => {
        const { connectionParams, extra } = context;
        // user validation will remain the same as in the example above
        // when using with graphql-ws, additional context value should be stored in the extra field
        extra.user = { user: {} };
      },
    },
  },
  context: ({ extra }) => {
    // you can now access your additional context value through the extra field
  },
});
```

#### Enable subscriptions with Mercurius driver[#](/graphql/subscriptions#enable-subscriptions-with-mercurius-driver)

To enable subscriptions, set the `subscription` property to `true`.

```typescript

GraphQLModule.forRoot<MercuriusDriverConfig>({
  driver: MercuriusDriver,
  subscription: true,
}),
```

> **Hint** You can also pass the options object to set up a custom emitter, validate incoming connections, etc. Read more [here](https://github.com/mercurius-js/mercurius/blob/master/docs/api/options.md#plugin-options) (see `subscription`).

#### Code first[#](/graphql/subscriptions#code-first-1)

To create a subscription using the code first approach, we use the `@Subscription()` decorator (exported from the `@nestjs/graphql` package) and the `PubSub` class from the `mercurius` package, which provides a simple **publish/subscribe API**.

The following subscription handler takes care of **subscribing** to an event by calling `PubSub#asyncIterableIterator`. This method takes a single argument, the `triggerName`, which corresponds to an event topic name.

```typescript

@Resolver(() => Author)
export class AuthorResolver {
  // ...
  @Subscription(() => Comment)
  commentAdded(@Context('pubsub') pubSub: PubSub) {
    return pubSub.subscribe('commentAdded');
  }
}
```

> **Hint** All decorators used in the example above are exported from the `@nestjs/graphql` package, while the `PubSub` class is exported from the `mercurius` package.

> **Note**`PubSub` is a class that exposes a simple `publish` and `subscribe` API. Check out [this section](https://github.com/mercurius-js/mercurius/blob/master/docs/subscriptions.md#subscriptions-with-custom-pubsub) on how to register a custom `PubSub` class.

This will result in generating the following part of the GraphQL schema in SDL:

```graphql

type Subscription {
  commentAdded(): Comment!
}
```

Note that subscriptions, by definition, return an object with a single top level property whose key is the name of the subscription. This name is either inherited from the name of the subscription handler method (i.e., `commentAdded` above), or is provided explicitly by passing an option with the key `name` as the second argument to the `@Subscription()` decorator, as shown below.

```typescript

@Subscription(() => Comment, {
  name: 'commentAdded',
})
subscribeToCommentAdded(@Context('pubsub') pubSub: PubSub) {
  return pubSub.subscribe('commentAdded');
}
```

This construct produces the same SDL as the previous code sample, but allows us to decouple the method name from the subscription.

#### Publishing[#](/graphql/subscriptions#publishing-1)

Now, to publish the event, we use the `PubSub#publish` method. This is often used within a mutation to trigger a client-side update when a part of the object graph has changed. For example:

posts/posts.resolver.ts

JS TS

```typescript

@Mutation(() => Comment)
async addComment(
  @Args('postId', { type: () => Int }) postId: number,
  @Args('comment', { type: () => Comment }) comment: CommentInput,
  @Context('pubsub') pubSub: PubSub,
) {
  const newComment = this.commentsService.addComment({ id: postId, comment });
  await pubSub.publish({
    topic: 'commentAdded',
    payload: {
      commentAdded: newComment
    }
  });
  return newComment;
}
```

As mentioned, the subscription, by definition, returns a value and that value has a shape. Look again at the generated SDL for our `commentAdded` subscription:

```graphql

type Subscription {
  commentAdded(): Comment!
}
```

This tells us that the subscription must return an object with a top-level property name of `commentAdded` that has a value which is a `Comment` object. The important point to note is that the shape of the event payload emitted by the `PubSub#publish` method must correspond to the shape of the value expected to return from the subscription. So, in our example above, the `pubSub.publish({ topic: 'commentAdded', payload: { commentAdded: newComment } })` statement publishes a `commentAdded` event with the appropriately shaped payload. If these shapes don't match, your subscription will fail during the GraphQL validation phase.

#### Filtering subscriptions[#](/graphql/subscriptions#filtering-subscriptions-1)

To filter out specific events, set the `filter` property to a filter function. This function acts similar to the function passed to an array `filter`. It takes two arguments: `payload` containing the event payload (as sent by the event publisher), and `variables` taking any arguments passed in during the subscription request. It returns a boolean determining whether this event should be published to client listeners.

```typescript

@Subscription(() => Comment, {
  filter: (payload, variables) =>
    payload.commentAdded.title === variables.title,
})
commentAdded(@Args('title') title: string, @Context('pubsub') pubSub: PubSub) {
  return pubSub.subscribe('commentAdded');
}
```

If you need to access injected providers (e.g., use an external service to validate the data), use the following construction.

```typescript

@Subscription(() => Comment, {
  filter(this: AuthorResolver, payload, variables) {
    // "this" refers to an instance of "AuthorResolver"
    return payload.commentAdded.title === variables.title;
  }
})
commentAdded(@Args('title') title: string, @Context('pubsub') pubSub: PubSub) {
  return pubSub.subscribe('commentAdded');
}
```

#### Schema first[#](/graphql/subscriptions#schema-first-1)

To create an equivalent subscription in Nest, we'll make use of the `@Subscription()` decorator.

```typescript

const pubSub = new PubSub();

@Resolver('Author')
export class AuthorResolver {
  // ...
  @Subscription()
  commentAdded(@Context('pubsub') pubSub: PubSub) {
    return pubSub.subscribe('commentAdded');
  }
}
```

To filter out specific events based on context and arguments, set the `filter` property.

```typescript

@Subscription('commentAdded', {
  filter: (payload, variables) =>
    payload.commentAdded.title === variables.title,
})
commentAdded(@Context('pubsub') pubSub: PubSub) {
  return pubSub.subscribe('commentAdded');
}
```

If you need to access injected providers (e.g., use an external service to validate the data), use the following construction:

```typescript

@Subscription('commentAdded', {
  filter(this: AuthorResolver, payload, variables) {
    // "this" refers to an instance of "AuthorResolver"
    return payload.commentAdded.title === variables.title;
  }
})
commentAdded(@Context('pubsub') pubSub: PubSub) {
  return pubSub.subscribe('commentAdded');
}
```

The last step is to update the type definitions file.

```graphql

type Author {
  id: Int!
  firstName: String
  lastName: String
  posts: [Post]
}

type Post {
  id: Int!
  title: String
  votes: Int
}

type Query {
  author(id: Int!): Author
}

type Comment {
  id: String
  content: String
}

type Subscription {
  commentAdded(title: String!): Comment
}
```

With this, we've created a single `commentAdded(title: String!): Comment` subscription.

#### PubSub[#](/graphql/subscriptions#pubsub-1)

In the examples above, we used the default `PubSub` emitter ([mqemitter](https://github.com/mcollina/mqemitter)) The preferred approach (for production) is to use `mqemitter-redis`. Alternatively, a custom `PubSub` implementation can be provided (read more [here](https://github.com/mercurius-js/mercurius/blob/master/docs/subscriptions.md))

```typescript

GraphQLModule.forRoot<MercuriusDriverConfig>({
  driver: MercuriusDriver,
  subscription: {
    emitter: require('mqemitter-redis')({
      port: 6579,
      host: '127.0.0.1',
    }),
  },
});
```

#### Authentication over WebSockets[#](/graphql/subscriptions#authentication-over-websockets-1)

Checking whether the user is authenticated can be done inside the `verifyClient` callback function that you can specify in the `subscription` options.

The `verifyClient` will receive the `info` object as a first argument which you can use to retrieve the request's headers.

```typescript

GraphQLModule.forRoot<MercuriusDriverConfig>({
  driver: MercuriusDriver,
  subscription: {
    verifyClient: (info, next) => {
      const authorization = info.req.headers?.authorization as string;
      if (!authorization?.startsWith('Bearer ')) {
        return next(false);
      }
      next(true);
    },
  }
}),
```

----
url: https://docs.nestjs.com/v7/techniques/caching
----

* [Caching](https://docs.nestjs.com/v7/techniques/caching#caching)
* [Installation](https://docs.nestjs.com/v7/techniques/caching#installation)
* [In-memory cache](https://docs.nestjs.com/v7/techniques/caching#in-memory-cache)
* [Interacting with the Cache store](https://docs.nestjs.com/v7/techniques/caching#interacting-with-the-cache-store)
* [Auto-caching responses](https://docs.nestjs.com/v7/techniques/caching#auto-caching-responses)
* [Customize caching](https://docs.nestjs.com/v7/techniques/caching#customize-caching)
* [Global cache overrides](https://docs.nestjs.com/v7/techniques/caching#global-cache-overrides)
* [WebSockets and Microservices](https://docs.nestjs.com/v7/techniques/caching#websockets-and-microservices)
* [Adjust tracking](https://docs.nestjs.com/v7/techniques/caching#adjust-tracking)
* [Different stores](https://docs.nestjs.com/v7/techniques/caching#different-stores)
* [Async configuration](https://docs.nestjs.com/v7/techniques/caching#async-configuration)
* [Example](https://docs.nestjs.com/v7/techniques/caching#example)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/techniques/caching.md "Suggest Edits")

### Caching

Caching is a great and simple **technique** that helps improve your app's performance. It acts as a temporary data store providing high performance data access.

#### Installation[#](/techniques/caching#installation)

First install required packages:

```bash

$ npm install cache-manager
$ npm install -D @types/cache-manager
```

#### In-memory cache[#](/techniques/caching#in-memory-cache)

Nest provides a unified API for various cache storage providers. The built-in one is an in-memory data store. However, you can easily switch to a more comprehensive solution, like Redis.

In order to enable caching, import the `CacheModule` and call its `register()` method.

```typescript

import { CacheModule, Module } from '@nestjs/common';
import { AppController } from './app.controller';

@Module({
  imports: [CacheModule.register()],
  controllers: [AppController],
})
export class ApplicationModule {}
```

#### Interacting with the Cache store[#](/techniques/caching#interacting-with-the-cache-store)

To interact with the cache manager instance, inject it to your class using the `CACHE_MANAGER` token, as follows:

```typescript

constructor(@Inject(CACHE_MANAGER) private cacheManager: Cache) {}
```

> **Hint** The `Cache` class is imported from the `cache-manager`, while `CACHE_MANAGER` token from the `@nestjs/common` package.

The `get` method on the `Cache` instance (from the `cache-manager` package) is used to retrieve items from the cache. If the item does not exist in the cache, an exception will be thrown.

```typescript

const value = this.cacheManager.get('key');
```

To add an item to the cache, use the `set` method:

```typescript

await this.cacheManager.set('key', 'value');
```

The default expiration time of the cache is 5 seconds.

You can manually specify a TTL (expiration time) for this specific key, as follows:

```typescript

await this.cacheManager.set('key', 'value', { ttl: 1000 });
```

To disable expiration of the cache, set the `ttl` configuration property to `null`:

```typescript

await this.cacheManager.set('key', 'value', { ttl: null });
```

To remove an item from the cache, use the `del` method:

```typescript

await this.cacheManager.del('key');
```

To clear the entire cache, use the `reset` method:

```typescript

await this.cacheManager.reset();
```

#### Auto-caching responses[#](/techniques/caching#auto-caching-responses)

> **Warning** In [GraphQL](/v7/graphql/quick-start) applications, interceptors are executed separately for each field resolver. Thus, `CacheModule` (which uses interceptors to cache responses) will not work properly.

To enable auto-caching responses, just tie the `CacheInterceptor` where you want to cache data.

```typescript

@Controller()
@UseInterceptors(CacheInterceptor)
export class AppController {
  @Get()
  findAll(): string[] {
    return [];
  }
}
```

> **Warning** Only `GET` endpoints are cached. Also, HTTP server routes that inject the native response object (`@Res()`) cannot use the Cache Interceptor. See [response mapping](https://docs.nestjs.com/interceptors#response-mapping) for more details.

To reduce the amount of required boilerplate, you can bind `CacheInterceptor` to all endpoints globally:

```typescript

import { CacheModule, Module, CacheInterceptor } from '@nestjs/common';
import { AppController } from './app.controller';
import { APP_INTERCEPTOR } from '@nestjs/core';

@Module({
  imports: [CacheModule.register()],
  controllers: [AppController],
  providers: [
    {
      provide: APP_INTERCEPTOR,
      useClass: CacheInterceptor,
    },
  ],
})
export class ApplicationModule {}
```

#### Customize caching[#](/techniques/caching#customize-caching)

All cached data has its own expiration time (TTL). To customize default values, pass the options object to the `register()` method.

```typescript

CacheModule.register({
  ttl: 5, // seconds
  max: 10, // maximum number of items in cache
});
```

#### Global cache overrides[#](/techniques/caching#global-cache-overrides)

While global cache is enabled, cache entries are stored under a `CacheKey` that is auto-generated based on the route path. You may override certain cache settings (`@CacheKey()` and `@CacheTTL()`) on a per-method basis, allowing customized caching strategies for individual controller methods. This may be most relevant while using [different cache stores.](https://docs.nestjs.com/techniques/caching#different-stores)

```typescript

@Controller()
export class AppController {
  @CacheKey('custom_key')
  @CacheTTL(20)
  findAll(): string[] {
    return [];
  }
}
```

> **Hint** The `@CacheKey()` and `@CacheTTL()` decorators are imported from the `@nestjs/common` package.

The `@CacheKey()` decorator may be used with or without a corresponding `@CacheTTL()` decorator and vice versa. One may choose to override only the `@CacheKey()` or only the `@CacheTTL()`. Settings that are not overridden with a decorator will use the default values as registered globally (see [Customize caching](https://docs.nestjs.com/techniques/caching#customize-caching)).

#### WebSockets and Microservices[#](/techniques/caching#websockets-and-microservices)

You can also apply the `CacheInterceptor` to WebSocket subscribers as well as Microservice's patterns (regardless of the transport method that is being used).

JS TS

```typescript

@CacheKey('events')
@UseInterceptors(CacheInterceptor)
@SubscribeMessage('events')
handleEvent(client: Client, data: string[]): Observable<string[]> {
  return [];
}
```

```typescript

@CacheKey('events')
@UseInterceptors(CacheInterceptor)
@SubscribeMessage('events')
handleEvent(client, data) {
  return [];
}
```

However, the additional `@CacheKey()` decorator is required in order to specify a key used to subsequently store and retrieve cached data. Also, please note that you **shouldn't cache everything**. Actions which perform some business operations rather than simply querying the data should never be cached.

Additionally, you may specify a cache expiration time (TTL) by using the `@CacheTTL()` decorator, which will override the global default TTL value.

JS TS

```typescript

@CacheTTL(10)
@UseInterceptors(CacheInterceptor)
@SubscribeMessage('events')
handleEvent(client: Client, data: string[]): Observable<string[]> {
  return [];
}
```

```typescript

@CacheTTL(10)
@UseInterceptors(CacheInterceptor)
@SubscribeMessage('events')
handleEvent(client, data) {
  return [];
}
```

> **Hint** The `@CacheTTL()` decorator may be used with or without a corresponding `@CacheKey()` decorator.

#### Adjust tracking[#](/techniques/caching#adjust-tracking)

By default, Nest uses the request URL (in an HTTP app) or cache key (in websockets and microservices apps, set through the `@CacheKey()` decorator) to associate cache records with your endpoints. Nevertheless, sometimes you might want to set up tracking based on different factors, for example, using HTTP headers (e.g. `Authorization` to properly identify `profile` endpoints).

In order to accomplish that, create a subclass of `CacheInterceptor` and override the `trackBy()` method.

```typescript

@Injectable()
class HttpCacheInterceptor extends CacheInterceptor {
  trackBy(context: ExecutionContext): string | undefined {
    return 'key';
  }
}
```

#### Different stores[#](/techniques/caching#different-stores)

This service takes advantage of [cache-manager](https://github.com/BryanDonovan/node-cache-manager) under the hood. The `cache-manager` package supports a wide-range of useful stores, for example, [Redis](https://github.com/dabroek/node-cache-manager-redis-store) store. A full list of supported stores is available [here](https://github.com/BryanDonovan/node-cache-manager#store-engines). To set up the Redis store, simply pass the package together with corresponding options to the `register()` method.

```typescript

import * as redisStore from 'cache-manager-redis-store';
import { CacheModule, Module } from '@nestjs/common';
import { AppController } from './app.controller';

@Module({
  imports: [
    CacheModule.register({
      store: redisStore,
      host: 'localhost',
      port: 6379,
    }),
  ],
  controllers: [AppController],
})
export class ApplicationModule {}
```

#### Async configuration[#](/techniques/caching#async-configuration)

You may want to asynchronously pass in module options instead of passing them statically at compile time. In this case, use the `registerAsync()` method, which provides several ways to deal with async configuration.

One approach is to use a factory function:

```typescript

CacheModule.registerAsync({
  useFactory: () => ({
    ttl: 5,
  }),
});
```

Our factory behaves like all other asynchronous module factories (it can be `async` and is able to inject dependencies through `inject`).

```typescript

CacheModule.registerAsync({
  imports: [ConfigModule],
  useFactory: async (configService: ConfigService) => ({
    ttl: configService.get('CACHE_TTL'),
  }),
  inject: [ConfigService],
});
```

Alternatively, you can use the `useClass` method:

```typescript

CacheModule.registerAsync({
  useClass: CacheConfigService,
});
```

The above construction will instantiate `CacheConfigService` inside `CacheModule` and will use it to get the options object. The `CacheConfigService` has to implement the `CacheOptionsFactory` interface in order to provide the configuration options:

```typescript

@Injectable()
class CacheConfigService implements CacheOptionsFactory {
  createCacheOptions(): CacheModuleOptions {
    return {
      ttl: 5,
    };
  }
}
```

If you wish to use an existing configuration provider imported from a different module, use the `useExisting` syntax:

```typescript

CacheModule.registerAsync({
  imports: [ConfigModule],
  useExisting: ConfigService,
});
```

This works the same as `useClass` with one critical difference - `CacheModule` will lookup imported modules to reuse any already-created `ConfigService`, instead of instantiating its own.

#### Example[#](/techniques/caching#example)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/20-cache).

----
url: https://docs.nestjs.com/v6/microservices/redis
----

* [Redis](https://docs.nestjs.com/v6/microservices/redis#redis)
* [Installation](https://docs.nestjs.com/v6/microservices/redis#installation)
* [Overview](https://docs.nestjs.com/v6/microservices/redis#overview)
* [Options](https://docs.nestjs.com/v6/microservices/redis#options)
* [Client](https://docs.nestjs.com/v6/microservices/redis#client)
* [Context](https://docs.nestjs.com/v6/microservices/redis#context)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/microservices/redis.md "Suggest Edits")

### Redis

The [Redis](https://redis.io/) transporter implements the publish/subscribe messaging paradigm and leverages the [Pub/Sub](https://redis.io/topics/pubsub) feature of Redis. Published messages are categorized in channels, without knowing what subscribers (if any) will eventually receive the message. Each microservice can subscribe to any number of channels. In addition, more than one channel can be subscribed to at a time. Messages exchanged through channels are **fire-and-forget**, which means that if a message is published and there are no subscribers interested in it, the message is removed and cannot be recovered. Thus, you don't have a guarantee that either messages or events will be handled by at least one service. A single message can be subscribed to (and received) by multiple subscribers.

#### Installation[#](/microservices/redis#installation)

To start building Redis-based microservices, first install the required package:

```bash

$ npm i --save redis
```

#### Overview[#](/microservices/redis#overview)

To use the Redis transporter, pass the following options object to the `createMicroservice()` method:

main.ts

JS TS

```typescript

const app = await NestFactory.createMicroservice(ApplicationModule, {
  transport: Transport.REDIS,
  options: {
    url: 'redis://localhost:6379',
  },
});
```

> **Hint** The `Transport` enum is imported from the `@nestjs/microservices` package.

#### Options[#](/microservices/redis#options)

The `options` property is specific to the chosen transporter. The **Redis** transporter exposes the properties described below.

|                 |                                                          |
| --------------- | -------------------------------------------------------- |
| `url`           | Connection url                                           |
| `retryAttempts` | Number of times to retry message (default: `0`)          |
| `retryDelay`    | Delay between message retry attempts (ms) (default: `0`) |

#### Client[#](/microservices/redis#client)

Like other microservice transporters, you have [several options](https://docs.nestjs.com/microservices/basics#client) for creating a Redis `ClientProxy` instance.

One method for creating an instance is to use use the `ClientsModule`. To create a client instance with the `ClientsModule`, import it and use the `register()` method to pass an options object with the same properties shown above in the `createMicroservice()` method, as well as a `name` property to be used as the injection token. Read more about `ClientsModule`[here](https://docs.nestjs.com/microservices/basics#client).

```typescript

@Module({
  imports: [
    ClientsModule.register([
      {
        name: 'MATH_SERVICE',
        transport: Transport.REDIS,
        options: {
          url: 'redis://localhost:6379',
        }
      },
    ]),
  ]
  ...
})
```

Other options to create a client (either `ClientProxyFactory` or `@Client()`) can be used as well. You can read about them [here](https://docs.nestjs.com/microservices/basics#client).

#### Context[#](/microservices/redis#context)

In more sophisticated scenarios, you may want to access more information about the incoming request. When using the Redis transporter, you can access the `RedisContext` object.

JS TS

```typescript

@MessagePattern('notifications')
getNotifications(@Payload() data: number[], @Ctx() context: RedisContext) {
  console.log(`Channel: ${context.getChannel()}`);
}
```

```typescript

@Bind(Payload(), Ctx())
@MessagePattern('notifications')
getNotifications(data, context) {
  console.log(`Channel: ${context.getChannel()}`);
}
```

> **Hint**`@Payload()`, `@Ctx()` and `RedisContext` are imported from the `@nestjs/microservices` package.

----
url: https://docs.nestjs.com/v6/graphql/mutations
----

* [Mutations](https://docs.nestjs.com/v6/graphql/mutations#mutations)
* [Schema first](https://docs.nestjs.com/v6/graphql/mutations#schema-first)
* [Type definitions](https://docs.nestjs.com/v6/graphql/mutations#type-definitions)
* [Code first](https://docs.nestjs.com/v6/graphql/mutations#code-first)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/graphql/mutations.md "Suggest Edits")

### Mutations

In GraphQL, we use mutations to modify server-side data (read more [here](http://graphql.org/learn/queries/#mutations)). The official [Apollo](https://www.apollographql.com/docs/graphql-tools/generate-schema.html) documentation uses an `upvotePost()` mutation example. This mutation implements a method to increase a post's `votes` property value. To create an equivalent mutation in Nest, we'll make use of the `@Mutation()` decorator.

#### Schema first[#](/graphql/mutations#schema-first)

Let's extend our `AuthorResolver` used in the previous section (see [resolvers](/v6/graphql/resolvers-map)).

```typescript

@Resolver('Author')
export class AuthorResolver {
  constructor(
    private readonly authorsService: AuthorsService,
    private readonly postsService: PostsService,
  ) {}

  @Query('author')
  async getAuthor(@Args('id') id: number) {
    return this.authorsService.findOneById(id);
  }

  @Mutation()
  async upvotePost(@Args('postId') postId: number) {
    return this.postsService.upvoteById({ id: postId });
  }

  @ResolveProperty('posts')
  async getPosts(@Parent() { id }) {
    return this.postsService.findAll({ authorId: id });
  }
}
```

Note that we assumed above that the business logic has been moved to the `PostsService` (querying the post and incrementing its `votes` property).

#### Type definitions[#](/graphql/mutations#type-definitions)

The last step is to add our mutation to the existing types definition.

```graphql

type Author {
  id: Int!
  firstName: String
  lastName: String
  posts: [Post]
}

type Post {
  id: Int!
  title: String
  votes: Int
}

type Query {
  author(id: Int!): Author
}

type Mutation {
  upvotePost(postId: Int!): Post
}
```

The `upvotePost(postId: Int!): Post` mutation is now available to be called as part of our application's GraphQL API.

#### Code first[#](/graphql/mutations#code-first)

Let's add another method to the `AuthorResolver` used in the previous section (see [resolvers](/v6/graphql/resolvers-map)).

```typescript

@Resolver(of => Author)
export class AuthorResolver {
  constructor(
    private readonly authorsService: AuthorsService,
    private readonly postsService: PostsService,
  ) {}

  @Query(returns => Author, { name: 'author' })
  async getAuthor(@Args({ name: 'id', type: () => Int }) id: number) {
    return this.authorsService.findOneById(id);
  }

  @Mutation(returns => Post)
  async upvotePost(@Args({ name: 'postId', type: () => Int }) postId: number) {
    return this.postsService.upvoteById({ id: postId });
  }

  @ResolveProperty('posts')
  async getPosts(@Parent() author) {
    const { id } = author;
    return this.postsService.findAll({ authorId: id });
  }
}
```

The `upvotePost()` method takes `postId` (`Int`) as an argument and returns an updated `Post` entity. For the reasons explained in the [resolvers](/v6/graphql/resolvers-map) section, we have to explicitly set the expected type.

If the mutation needs to take an object as an argument, we can create an input type.

```typescript

@InputType()
export class UpvotePostInput {
  @Field() postId: number;
}
```

> **Hint** Both `@InputType()` and `@Field()` are imported from the `type-graphql` package.

We can then use this type in the resolver class:

```typescript

@Mutation(returns => Post)
async upvotePost(
  @Args('upvotePostData') upvotePostData: UpvotePostInput,
) {}
```

----
url: https://docs.nestjs.com/v4/exception-filters
----

### Exception Filters

In Nest there's an **exceptions layer**, which responsibility is to catch the unhandled exceptions and return the appropriate response to the end-user.

Every exception is handled by the global exception filter and when it's **unrecognized** (not `HttpException` or class that inherits from `HttpException`), a user receives the below JSON response:

TypeScript

```typescript

{
    "statusCode": 500,
    "message": "Internal server error"
}
```

#### HttpException

There's a built-in `HttpException` class inside the `@nestjs/common` package. The core exception handler works very well with this. When you throw a `HttpException` object, it'll be caught by the handler and transformed to the relevant JSON response.

In the `CatsController`, we have a `create()` method ( `POST` route). Let's assume that this route handler would throw an exception for some reason. We're gonna hardcode it:

cats.controller.ts

JavaScript TypeScript

TypeScript

```typescript

@Post()
async create(@Body() createCatDto: CreateCatDto) {
  throw new HttpException('Forbidden', HttpStatus.FORBIDDEN);
}
```

TypeScript

```typescript

@Post()
@Bind(Body())
async create(createCatDto) {
  throw new HttpException('Forbidden', HttpStatus.FORBIDDEN);
}
```

> **Warning** I have used the `HttpStatus` here. It's a helper enum imported from the `@nestjs/common` package.

Now when the client calls this endpoint, the response would look like this:

TypeScript

```typescript

{
    "statusCode": 403,
    "message": "Forbidden"
}
```

The `HttpException` constructor takes `string | object` as the first argument. If you'd pass it an `object` instead of a `string`, you'll completely override the response body.

cats.controller.ts

JavaScript TypeScript

TypeScript

```typescript

@Post()
async create(@Body() createCatDto: CreateCatDto) {
  throw new HttpException({
    status: HttpStatus.FORBIDDEN,
    error: 'This is a custom message',
  });
}
```

TypeScript

```typescript

@Post()
@Bind(Body())
async create(createCatDto) {
  throw new HttpException({
    status: HttpStatus.FORBIDDEN,
    error: 'This is a custom message',
  });
}
```

And that's how the response would look like:

TypeScript

```typescript

{
    "status": 403,
    "error": "This is a custom message"
}
```

#### Exceptions Hierarchy

A good practice is to create your own **exceptions hierarchy**. It means that every HTTP exception should inherit from the base `HttpException` class. As a result Nest will recognize your exception, and will fully take care of the error responses.

forbidden.exception.ts

JavaScript TypeScript

TypeScript

```typescript

export class ForbiddenException extends HttpException {
  constructor() {
    super('Forbidden', HttpStatus.FORBIDDEN);
  }
}
```

Since `ForbiddenException` extends the base `HttpException`, it will work well with the core exceptions handler, therefore we can use this class inside the `create()` method.

cats.controller.ts

JavaScript TypeScript

TypeScript

```typescript

@Post()
async create(@Body() createCatDto: CreateCatDto) {
  throw new ForbiddenException();
}
```

TypeScript

```typescript

@Post()
@Bind(Body())
async create(createCatDto) {
  throw new ForbiddenException();
}
```

#### HTTP exceptions

To reduce the boilerplate code, Nest provides a set of usable exceptions that extends the core `HttpException`. All of them are available in the `@nestjs/common` package:

* `PayloadTooLargeException`
* `UnsupportedMediaTypeException`
* `UnprocessableException`
* `InternalServerErrorException`
* `NotImplementedException`
* `BadGatewayException`
* `ServiceUnavailableException`
* `GatewayTimeoutException`

#### Exception Filters

The base exception handler is fine, but sometimes you may want to have **full control** over the exceptions layer, for example, add some logging or use a different JSON schema. We love generic solutions and making your life easier, that's why the feature called **exception filters** was created.

We're gonna create the filter, which is responsible to catch the `HttpException` and override the `message` property.

http-exception.filter.ts

JavaScript TypeScript

TypeScript

```typescript

import { ExceptionFilter, Catch } from '@nestjs/common';
import { HttpException } from '@nestjs/common';

@Catch(HttpException)
export class HttpExceptionFilter implements ExceptionFilter {
  catch(exception: HttpException, response) {
    const status = exception.getStatus();

    response
      .status(status)
      .json({
        statusCode: status,
        message: `It's a message from the exception filter`,
      });
  }
}
```

TypeScript

```typescript

import { Catch } from '@nestjs/common';
import { HttpException } from '@nestjs/common';

@Catch(HttpException)
export class HttpExceptionFilter {
  catch(exception, response) {
    const status = exception.getStatus();

    response
      .status(status)
      .json({
        statusCode: status,
        message: `It's a message from the exception filter`,
      });
  }
}
```

The `response` is a native express [response object](http://expressjs.com/en/api.html#res). The `exception` is the currently processed exception.

> **Hint** Every exception filter should implement the `ExceptionFilter` interface. It forces you to provide the `catch()` method with the proper signature.

The `@Catch(HttpException)` decorator binds the required metadata to the exception filter. It tells Nest that this filter is looking for `HttpException`. The `@Catch()` takes an endless number of parameters, so you can set up this filter for several types of exceptions, just separate them by a comma.

The last step is to inform Nest that the `HttpExceptionFilter` should be used within the `create()` method.

cats.controller.ts

JavaScript TypeScript

TypeScript

```typescript

@Post()
@UseFilters(new HttpExceptionFilter())
async create(@Body() createCatDto: CreateCatDto) {
  throw new ForbiddenException();
}
```

TypeScript

```typescript

@Post()
@UseFilters(new HttpExceptionFilter())
@Bind(Body())
async create(createCatDto) {
  throw new ForbiddenException();
}
```

> **Warning** The `@UseFilters()` decorator is imported from the `@nestjs/common` package.

We've used the `@UseFilters()` decorator here. Same as `@Catch()`, it takes an endless number of parameters.

In the example above, the `HttpExceptionFilter` is applied only to the single `create()` route handler, but it's not the only way. In fact, the exception filters can be method-scoped, controller-scoped and also global-scoped.

cats.controller.ts

JavaScript TypeScript

TypeScript

```typescript

@UseFilters(new HttpExceptionFilter())
export class CatsController {}
```

This construction sets up the `HttpExceptionFilter` for every route handler inside the `CatsController`. It's the example of the controller-scoped exception filter. The last available scope is the global-scoped exception filter.

main.ts

JavaScript TypeScript

TypeScript

```typescript

async function bootstrap() {
  const app = await NestFactory.create(ApplicationModule);
  app.useGlobalFilters(new HttpExceptionFilter());
  await app.listen(3000);
}
bootstrap();
```

The global filters are used across the entire application, for every controller and every route handler.

> **Notice** The `useGlobalFilters()` method doesn't setup filters for gateways and microservices.

#### Catch everything

To handle every occurred exception, you may leave the parentheses empty ( `@Catch()`):

any-exception.filter.ts

JavaScript TypeScript

TypeScript

```typescript

import { ExceptionFilter, Catch } from '@nestjs/common';

@Catch()
export class AnyExceptionFilter implements ExceptionFilter {
  catch(exception, response) {
    response
      .status(500)
      .json({
        statusCode: 500,
        message: `It's a message from the exception filter`,
      });
  }
}
```

TypeScript

```typescript

import { ExceptionFilter, Catch } from '@nestjs/common';

@Catch()
export class AnyExceptionFilter implements ExceptionFilter {
  catch(exception, response) {
    response
      .status(500)
      .json({
        statusCode: 500,
        message: `It's a message from the exception filter`,
      });
  }
}
```

In the example above the filter will catch each exception that is thrown.

#### Global filters

The global exception filters don't belong to any scope. They live outside modules, thus as a result - they can't inject dependencies. We need to create an instance immediately. But quite often, global filters depend on other objects, for example, we'd love to log an exception using `LoggerService`, but this service is a part of the `LoggerModule`. How do we solve this?

The solution is pretty easy. Each Nest application instance is in fact, a created **Nest context**. The Nest context is a wrapper around the Nest container, which holds all instantiated classes. We can grab any existing instance from within any imported module using application object.

Let's assume that we have a `LoggerExceptionFilter` registered in the `LoggerModule`. This `LoggerModule` is imported into the **root module**. We can pick the `LoggerExceptionFilter` instance by using the following syntax:

TypeScript

```typescript

const app = await NestFactory.create(ApplicationModule);
const loggerFilter = app
  .select(LoggerModule)
  .get(LoggerExceptionFilter);

app.useGlobalFilters(loggerFilter);
```

To grab the `LoggerExceptionFilter` instance we have to use 2 methods, well-described in the table below:

|            |                                                                                                                        |
| ---------- | ---------------------------------------------------------------------------------------------------------------------- |
| `get()`    | Makes it possible to retrieve the instance of the component or controller available inside the processed module.       |
| `select()` | Allows you to navigate through the module tree, for example, to pull out a specific instance from the selected module. |

> **Hint** The root module is selected by default. To select any other module, you need to go through the entire modules stack (step by step).

#### Sponsors

[](https://valor-software.com/)

Nest is an MIT-licensed open source project. It can grow thanks to the support by these awesome people. If you'd like to join them, please read more [here](https://opencollective.com/nest). Thanks!

[](https://opencollective.com/nest/backer/0/website)[](https://opencollective.com/nest/backer/1/website)[](https://opencollective.com/nest/backer/2/website)[](https://opencollective.com/nest/backer/3/website)[](https://opencollective.com/nest/backer/4/website)[](https://opencollective.com/nest/backer/5/website)[](https://opencollective.com/nest/backer/6/website)[](https://opencollective.com/nest/backer/7/website)[](https://opencollective.com/nest/backer/8/website)[](https://opencollective.com/nest/backer/9/website)[](https://opencollective.com/nest/backer/10/website)[](https://opencollective.com/nest/backer/11/website)[](https://opencollective.com/nest/backer/12/website)[](https://opencollective.com/nest/backer/13/website)[](https://opencollective.com/nest/backer/14/website)[](https://opencollective.com/nest/backer/15/website)[](https://opencollective.com/nest/backer/16/website)[](https://opencollective.com/nest/backer/17/website)[](https://opencollective.com/nest/backer/18/website)[](https://opencollective.com/nest/backer/19/website)[](https://opencollective.com/nest/backer/20/website)[](https://opencollective.com/nest/backer/21/website)[](https://opencollective.com/nest/backer/22/website)[](https://opencollective.com/nest/backer/23/website)[](https://opencollective.com/nest/backer/24/website)[](https://opencollective.com/nest/backer/25/website)[](https://opencollective.com/nest/backer/26/website)[](https://opencollective.com/nest/backer/27/website)[](https://opencollective.com/nest/backer/28/website)[](https://opencollective.com/nest/backer/29/website)

[Become a sponsor](https://opencollective.com/nest)

----
url: https://docs.nestjs.com/discover/companies
----

[Skip to content](#content)

On this page

* [Who is using Nest?](https://docs.nestjs.com/discover/companies#who-is-using-nest)
* [Companies](https://docs.nestjs.com/discover/companies#companies)

### Who is using Nest?

Nest helps companies of all sizes build their products at scale. If you use Nest and would like to be listed here, comment on the ["Who is using Nest in production?" GitHub issue](https://github.com/nestjs/nest/issues/1006). We'd be glad to add your logo.

#### Companies[#](/discover/companies#companies)

To our knowledge, all of the following companies have built projects on top of Nest:

[](https://roche.com)[](https://adidas.com)[](https://capgemini.com)[](https://www.societegenerale.fr/)[](https://rewe-digital.com/)[](https://www.decathlon.com/)[](https://www.autodesk.com/)[](https://www.neo4j.com/)[](https://bmw.com)[](https://gitlab.com/)[](https://www.ibm.com/)[](https://www.jetbrains.com/)[](https://www.mercedes-benz.com/)[](https://totalenergies.com/)[](https://www.bytedance.com)[](https://www.shipt.com/)[](https://github.com/Sanofi-IADC)[](https://sitepen.com)[](https://trilon.io)[](https://www.vuestorefront.io/)[](https://hingehealth.com)[](https://whiskeyhouse.com)

|                                     |
| ----------------------------------- |
| <https://gorrion.io/>               |
| <http://balticdatascience.com/>     |
| <https://prohabits.com/>            |
| <https://komed-health.com/>         |
| <https://kerberus.com.co/>          |
| <http://xtremis.com/>               |
| <https://notadd.com/>               |
| <http://jsdaddy.io/>                |
| <https://yumpingo.com/>             |
| <https://analytics-importer.cz/>    |
| <https://dayzim.com/>               |
| <https://wizkids.co.uk/>            |
| <https://pilvia.com/>               |
| <https://wi-q.com/>                 |
| <http://agrofel.com.br>             |
| <https://societegenerale.com/>      |
| <https://trashpanda.hulan.nl/>      |
| <https://bytedance.com/>            |
| <https://votercircle.com>           |
| <https://erento.com>                |
| <https://ideas.manticore-labs.com/> |
| <https://smartexlab.com/>           |
| <https://automama.ru/>              |
| <https://iflix.com/>                |
| <https://frontendwatch.com/>        |
| <https://mobilejazz.com/>           |
| <https://cgiandi.com/>              |
| <https://www.titlex.com.au/>        |
| <https://codengage.com/>            |
| <https://budacode.com/>             |
| <https://blueanchor.io/>            |
| <https://www.easymetrics.com/>      |
| <https://getapollo.io/>             |
| <https://big-bench.com/>            |
| <https://www.qingtui.cn/>           |
| <https://www.rosebayconsult.com/>   |
| <https://www.patrocinium.com/>      |
| <https://creatorsdaily.com>         |
| <https://autoscar.com.br>           |
| <https://www.mediktiv.com>          |
| <https://harmonize.health>          |
| <https://accerlery.be>              |
| <https://www.facile.it>             |
| <https://shopback.com>              |
| <https://www.ottonova.de>           |
| <https://www.radity.com>            |
| <https://globalctoforum.org>        |
| <https://halojasa.com>              |
| <https://hexito.com>                |
| <https://rivvy.app>                 |
| <https://padfever.com/>             |
| <https://datenlotse.org>            |
| <https://bemum.co>                  |
| <https://weoptimeye.ai>             |
| <https://nemovote.com>              |
| <https://selleo.com>                |
| <https://pchas.ir>                  |
| <https://tayeh.ir>                  |
| <https://forwardigital.co.uk>       |
| <https://rozetka.com.ua>            |
| <https://www.itrio.net>             |
| <https://alexishr.com>              |
| <https://dyrector.io>               |
| <https://stijlbreuk.nl>             |
| <https://polygon-software.ch>       |
| <https://bewith.io>                 |
| <https://swetrix.com>               |
| <https://swyftlogistics.com>        |
| <https://evershop.io>               |
| <https://e-design.ca>               |
| <https://growthmill.com>            |
| <https://tarken.com.br>             |
| <https://remato.com>                |
| <https://remberg.de/en>             |
| <https://uninterrupted.tech>        |
| <https://www.digando.com>           |
| <https://novu.co>                   |
| <https://aqreach.com>               |
| <https://phalco.de>                 |
| <https://www.tesseractpro.io>       |
| <https://www.kwanso.com>            |
| <https://cmdn.io>                   |
| <https://ayo.so>                    |
| <https://devitjobs.com>             |
| <https://formation.tech>            |
| <https://gofirmex.com>              |
| <https://vbdhub.org>                |
| <https://www.arven-tech.com>        |
| <https://runsystem.net>             |
| <https://zenobank.io>               |

and a lot more but we don't have enough time to update above list. Feel free to create a [pull request](https://github.com/nestjs/docs.nestjs.com/pulls) though!

----
url: https://docs.nestjs.com/v8/techniques/server-sent-events
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Server-Sent Events](https://docs.nestjs.com/v8/techniques/server-sent-events#server-sent-events)
* [Usage](https://docs.nestjs.com/v8/techniques/server-sent-events#usage)
* [Example](https://docs.nestjs.com/v8/techniques/server-sent-events#example)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/techniques/server-sent-events.md "Suggest Edits")

### Server-Sent Events

Server-Sent Events (SSE) is a server push technology enabling a client to receive automatic updates from a server via HTTP connection. Each notification is sent as a block of text terminated by a pair of newlines (learn more [here](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events)).

#### Usage[#](/techniques/server-sent-events#usage)

To enable Server-Sent events on a route (route registered within a **controller class**), annotate the method handler with the `@Sse()` decorator.

```typescript

@Sse('sse')
sse(): Observable<MessageEvent> {
  return interval(1000).pipe(map((_) => ({ data: { hello: 'world' } })));
}
```

> **Hint** The `@Sse()` decorator and `MessageEvent` interface are imported from the `@nestjs/common`, while `Observable`, `interval`, and `map` are imported from the `rxjs` package.

> **Warning** Server-Sent Events routes must return an `Observable` stream.

In the example above, we defined a route named `sse` that will allow us to propagate real-time updates. These events can be listened to using the [EventSource API](https://developer.mozilla.org/en-US/docs/Web/API/EventSource).

The `sse` method returns an `Observable` that emits multiple `MessageEvent` (in this example, it emits a new `MessageEvent` every second). The `MessageEvent` object should respect the following interface to match the specification:

```typescript

export interface MessageEvent {
  data: string | object;
  id?: string;
  type?: string;
  retry?: number;
}
```

With this in place, we can now create an instance of the `EventSource` class in our client-side application, passing the `/sse` route (which matches the endpoint we have passed into the `@Sse()` decorator above) as a constructor argument.

`EventSource` instance opens a persistent connection to an HTTP server, which sends events in `text/event-stream` format. The connection remains open until closed by calling `EventSource.close()`.

Once the connection is opened, incoming messages from the server are delivered to your code in the form of events. If there is an event field in the incoming message, the triggered event is the same as the event field value. If no event field is present, then a generic `message` event is fired ([source](https://developer.mozilla.org/en-US/docs/Web/API/EventSource)).

```javascript

const eventSource = new EventSource('/sse');
eventSource.onmessage = ({ data }) => {
  console.log('New message', JSON.parse(data));
};
```

#### Example[#](/techniques/server-sent-events#example)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/28-sse).

----
url: https://docs.nestjs.com/v9/guards
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Guards](https://docs.nestjs.com/v9/guards#guards)
* [Authorization guard](https://docs.nestjs.com/v9/guards#authorization-guard)
* [Execution context](https://docs.nestjs.com/v9/guards#execution-context)
* [Role-based authentication](https://docs.nestjs.com/v9/guards#role-based-authentication)
* [Binding guards](https://docs.nestjs.com/v9/guards#binding-guards)
* [Setting roles per handler](https://docs.nestjs.com/v9/guards#setting-roles-per-handler)
* [Putting it all together](https://docs.nestjs.com/v9/guards#putting-it-all-together)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/guards.md "Suggest Edits")

### Guards

A guard is a class annotated with the `@Injectable()` decorator, which implements the `CanActivate` interface.

Guards have a **single responsibility**. They determine whether a given request will be handled by the route handler or not, depending on certain conditions (like permissions, roles, ACLs, etc.) present at run-time. This is often referred to as **authorization**. Authorization (and its cousin, **authentication**, with which it usually collaborates) has typically been handled by [middleware](/v9/middleware) in traditional Express applications. Middleware is a fine choice for authentication, since things like token validation and attaching properties to the `request` object are not strongly connected with a particular route context (and its metadata).

But middleware, by its nature, is dumb. It doesn't know which handler will be executed after calling the `next()` function. On the other hand, **Guards** have access to the `ExecutionContext` instance, and thus know exactly what's going to be executed next. They're designed, much like exception filters, pipes, and interceptors, to let you interpose processing logic at exactly the right point in the request/response cycle, and to do so declaratively. This helps keep your code DRY and declarative.

> **Hint** Guards are executed **after** all middleware, but **before** any interceptor or pipe.

#### Authorization guard[#](/guards#authorization-guard)

As mentioned, **authorization** is a great use case for Guards because specific routes should be available only when the caller (usually a specific authenticated user) has sufficient permissions. The `AuthGuard` that we'll build now assumes an authenticated user (and that, therefore, a token is attached to the request headers). It will extract and validate the token, and use the extracted information to determine whether the request can proceed or not.

auth.guard.ts

JS TS

```typescript

import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
import { Observable } from 'rxjs';

@Injectable()
export class AuthGuard implements CanActivate {
  canActivate(
    context: ExecutionContext,
  ): boolean | Promise<boolean> | Observable<boolean> {
    const request = context.switchToHttp().getRequest();
    return validateRequest(request);
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';

@Injectable()
export class AuthGuard {
  async canActivate(context) {
    const request = context.switchToHttp().getRequest();
    return validateRequest(request);
  }
}
```

> **Hint** If you are looking for a real-world example on how to implement an authentication mechanism in your application, visit [this chapter](/v9/security/authentication). Likewise, for more sophisticated authorization example, check [this page](/v9/security/authorization).

By extending `ArgumentsHost`, `ExecutionContext` also adds several new helper methods that provide additional details about the current execution process. These details can be helpful in building more generic guards that can work across a broad set of controllers, methods, and execution contexts. Learn more about `ExecutionContext`[here](/v9/fundamentals/execution-context).

#### Role-based authentication[#](/guards#role-based-authentication)

Let's build a more functional guard that permits access only to users with a specific role. We'll start with a basic guard template, and build on it in the coming sections. For now, it allows all requests to proceed:

roles.guard.ts

JS TS

```typescript

import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
import { Observable } from 'rxjs';

@Injectable()
export class RolesGuard implements CanActivate {
  canActivate(
    context: ExecutionContext,
  ): boolean | Promise<boolean> | Observable<boolean> {
    return true;
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';

@Injectable()
export class RolesGuard {
  canActivate(context) {
    return true;
  }
}
```

#### Binding guards[#](/guards#binding-guards)

Like pipes and exception filters, guards can be **controller-scoped**, method-scoped, or global-scoped. Below, we set up a controller-scoped guard using the `@UseGuards()` decorator. This decorator may take a single argument, or a comma-separated list of arguments. This lets you easily apply the appropriate set of guards with one declaration.

JS TS

```typescript

@Controller('cats')
@UseGuards(RolesGuard)
export class CatsController {}
```

> **Hint** The `@UseGuards()` decorator is imported from the `@nestjs/common` package.

Above, we passed the `RolesGuard` class (instead of an instance), leaving responsibility for instantiation to the framework and enabling dependency injection. As with pipes and exception filters, we can also pass an in-place instance:

JS TS

```typescript

@Controller('cats')
@UseGuards(new RolesGuard())
export class CatsController {}
```

The construction above attaches the guard to every handler declared by this controller. If we wish the guard to apply only to a single method, we apply the `@UseGuards()` decorator at the **method level**.

In order to set up a global guard, use the `useGlobalGuards()` method of the Nest application instance:

JS TS

```typescript

const app = await NestFactory.create(AppModule);
app.useGlobalGuards(new RolesGuard());
```

> **Notice** In the case of hybrid apps the `useGlobalGuards()` method doesn't set up guards for gateways and micro services by default (see [Hybrid application](/v9/faq/hybrid-application) for information on how to change this behavior). For "standard" (non-hybrid) microservice apps, `useGlobalGuards()` does mount the guards globally.

Global guards are used across the whole application, for every controller and every route handler. In terms of dependency injection, global guards registered from outside of any module (with `useGlobalGuards()` as in the example above) cannot inject dependencies since this is done outside the context of any module. In order to solve this issue, you can set up a guard directly from any module using the following construction:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { APP_GUARD } from '@nestjs/core';

@Module({
  providers: [
    {
      provide: APP_GUARD,
      useClass: RolesGuard,
    },
  ],
})
export class AppModule {}
```

> **Hint** When using this approach to perform dependency injection for the guard, note that regardless of the module where this construction is employed, the guard is, in fact, global. Where should this be done? Choose the module where the guard (`RolesGuard` in the example above) is defined. Also, `useClass` is not the only way of dealing with custom provider registration. Learn more [here](/v9/fundamentals/custom-providers).

#### Setting roles per handler[#](/guards#setting-roles-per-handler)

Our `RolesGuard` is working, but it's not very smart yet. We're not yet taking advantage of the most important guard feature - the [execution context](/v9/fundamentals/execution-context). It doesn't yet know about roles, or which roles are allowed for each handler. The `CatsController`, for example, could have different permission schemes for different routes. Some might be available only for an admin user, and others could be open for everyone. How can we match roles to routes in a flexible and reusable way?

This is where **custom metadata** comes into play (learn more [here](https://docs.nestjs.com/fundamentals/execution-context#reflection-and-metadata)). Nest provides the ability to attach custom **metadata** to route handlers through the `@SetMetadata()` decorator. This metadata supplies our missing `role` data, which a smart guard needs to make decisions. Let's take a look at using `@SetMetadata()`:

cats.controller.ts

JS TS

```typescript

@Post()
@SetMetadata('roles', ['admin'])
async create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

```typescript

@Post()
@SetMetadata('roles', ['admin'])
@Bind(Body())
async create(createCatDto) {
  this.catsService.create(createCatDto);
}
```

> **Hint** The `@SetMetadata()` decorator is imported from the `@nestjs/common` package.

With the construction above, we attached the `roles` metadata (`roles` is a key, while `['admin']` is a particular value) to the `create()` method. While this works, it's not good practice to use `@SetMetadata()` directly in your routes. Instead, create your own decorators, as shown below:

roles.decorator.ts

JS TS

```typescript

import { SetMetadata } from '@nestjs/common';

export const Roles = (...roles: string[]) => SetMetadata('roles', roles);
```

```typescript

import { SetMetadata } from '@nestjs/common';

export const Roles = (...roles) => SetMetadata('roles', roles);
```

This approach is much cleaner and more readable, and is strongly typed. Now that we have a custom `@Roles()` decorator, we can use it to decorate the `create()` method.

cats.controller.ts

JS TS

```typescript

@Post()
@Roles('admin')
async create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

```typescript

@Post()
@Roles('admin')
@Bind(Body())
async create(createCatDto) {
  this.catsService.create(createCatDto);
}
```

#### Putting it all together[#](/guards#putting-it-all-together)

Let's now go back and tie this together with our `RolesGuard`. Currently, it simply returns `true` in all cases, allowing every request to proceed. We want to make the return value conditional based on the comparing the **roles assigned to the current user** to the actual roles required by the current route being processed. In order to access the route's role(s) (custom metadata), we'll use the `Reflector` helper class, which is provided out of the box by the framework and exposed from the `@nestjs/core` package.

roles.guard.ts

JS TS

```typescript

import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
import { Reflector } from '@nestjs/core';

@Injectable()
export class RolesGuard implements CanActivate {
  constructor(private reflector: Reflector) {}

  canActivate(context: ExecutionContext): boolean {
    const roles = this.reflector.get<string[]>('roles', context.getHandler());
    if (!roles) {
      return true;
    }
    const request = context.switchToHttp().getRequest();
    const user = request.user;
    return matchRoles(roles, user.roles);
  }
}
```

```typescript

import { Injectable, Dependencies } from '@nestjs/common';
import { Reflector } from '@nestjs/core';

@Injectable()
@Dependencies(Reflector)
export class RolesGuard {
  constructor(reflector) {
    this.reflector = reflector;
  }

  canActivate(context) {
    const roles = this.reflector.get('roles', context.getHandler());
    if (!roles) {
      return true;
    }
    const request = context.switchToHttp().getRequest();
    const user = request.user;
    return matchRoles(roles, user.roles);
  }
}
```

> **Hint** In the node.js world, it's common practice to attach the authorized user to the `request` object. Thus, in our sample code above, we are assuming that `request.user` contains the user instance and allowed roles. In your app, you will probably make that association in your custom **authentication guard** (or middleware). Check [this chapter](/v9/security/authentication) for more information on this topic.

> **Warning** The logic inside the `matchRoles()` function can be as simple or sophisticated as needed. The main point of this example is to show how guards fit into the request/response cycle.

Refer to the [Reflection and metadata](https://docs.nestjs.com/fundamentals/execution-context#reflection-and-metadata) section of the **Execution context** chapter for more details on utilizing `Reflector` in a context-sensitive way.

When a user with insufficient privileges requests an endpoint, Nest automatically returns the following response:

```typescript

{
  "statusCode": 403,
  "message": "Forbidden resource",
  "error": "Forbidden"
}
```

Note that behind the scenes, when a guard returns `false`, the framework throws a `ForbiddenException`. If you want to return a different error response, you should throw your own specific exception. For example:

```typescript

throw new UnauthorizedException();
```

Any exception thrown by a guard will be handled by the [exceptions layer](/v9/exception-filters) (global exceptions filter and any exceptions filters that are applied to the current context).

> **Hint** If you are looking for a real-world example on how to implement authorization, check [this chapter](/v9/security/authorization).

----
url: https://docs.nestjs.com/v9/graphql/resolvers
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Resolvers](https://docs.nestjs.com/v9/graphql/resolvers#resolvers)
* [Code first](https://docs.nestjs.com/v9/graphql/resolvers#code-first)
* [Object types](https://docs.nestjs.com/v9/graphql/resolvers#object-types)
* [Code first resolver](https://docs.nestjs.com/v9/graphql/resolvers#code-first-resolver)
* [Query type names](https://docs.nestjs.com/v9/graphql/resolvers#query-type-names)
* [Query decorator options](https://docs.nestjs.com/v9/graphql/resolvers#query-decorator-options)
* [Args decorator options](https://docs.nestjs.com/v9/graphql/resolvers#args-decorator-options)
* [Dedicated arguments class](https://docs.nestjs.com/v9/graphql/resolvers#dedicated-arguments-class)
* [Class inheritance](https://docs.nestjs.com/v9/graphql/resolvers#class-inheritance)
* [Generics](https://docs.nestjs.com/v9/graphql/resolvers#generics)
* [Schema first](https://docs.nestjs.com/v9/graphql/resolvers#schema-first)
* [Schema first resolver](https://docs.nestjs.com/v9/graphql/resolvers#schema-first-resolver)
* [Generating types](https://docs.nestjs.com/v9/graphql/resolvers#generating-types)
* [GraphQL argument decorators](https://docs.nestjs.com/v9/graphql/resolvers#graphql-argument-decorators)
* [Module](https://docs.nestjs.com/v9/graphql/resolvers#module)

```graphql

type Author {
  id: Int!
  firstName: String
  lastName: String
  posts: [Post!]!
}
```

In this case, using the code first approach, we define schemas using TypeScript classes and using TypeScript decorators to annotate the fields of those classes. The equivalent of the above SDL in the code first approach is:

authors/models/author.model.ts

JS TS

```typescript

import { Field, Int, ObjectType } from '@nestjs/graphql';
import { Post } from './post';

@ObjectType()
export class Author {
  @Field(type => Int)
  id: number;

  @Field({ nullable: true })
  firstName?: string;

  @Field({ nullable: true })
  lastName?: string;

  @Field(type => [Post])
  posts: Post[];
}
```

> **Hint** TypeScript's metadata reflection system has several limitations which make it impossible, for instance, to determine what properties a class consists of or recognize whether a given property is optional or required. Because of these limitations, we must either explicitly use the `@Field()` decorator in our schema definition classes to provide metadata about each field's GraphQL type and optionality, or use a [CLI plugin](/v9/graphql/cli-plugin) to generate these for us.

The `Author` object type, like any class, is made of a collection of fields, with each field declaring a type. A field's type corresponds to a [GraphQL type](https://graphql.org/learn/schema/). A field's GraphQL type can be either another object type or a scalar type. A GraphQL scalar type is a primitive (like `ID`, `String`, `Boolean`, or `Int`) that resolves to a single value.

> **Hint** In addition to GraphQL's built-in scalar types, you can define custom scalar types (read [more](/v9/graphql/scalars)).

The above `Author` object type definition will cause Nest to **generate** the SDL we showed above:

```graphql

type Author {
  id: Int!
  firstName: String
  lastName: String
  posts: [Post!]!
}
```

```typescript

@Field({ description: `Book title`, deprecationReason: 'Not useful in v2 schema' })
title: string;
```

> **Hint** You can also add a description to, or deprecate, the whole object type: `@ObjectType({ description: 'Author model' })`.

When the field is an array, we must manually indicate the array type in the `Field()` decorator's type function, as shown below:

```typescript

@Field(type => [Post])
posts: Post[];
```

> **Hint** Using array bracket notation (`[ ]`), we can indicate the depth of the array. For example, using `[[Int]]` would represent an integer matrix.

To declare that an array's items (not the array itself) are nullable, set the `nullable` property to `'items'` as shown below:

```typescript

@Field(type => [Post], { nullable: 'items' })
posts: Post[];
```

> **Hint** If both the array and its items are nullable, set `nullable` to `'itemsAndList'` instead.

Now that the `Author` object type is created, let's define the `Post` object type.

posts/models/post.model.ts

JS TS

```typescript

import { Field, Int, ObjectType } from '@nestjs/graphql';

@ObjectType()
export class Post {
  @Field(type => Int)
  id: number;

  @Field()
  title: string;

  @Field(type => Int, { nullable: true })
  votes?: number;
}
```

The `Post` object type will result in generating the following part of the GraphQL schema in SDL:

```graphql

type Post {
  id: Int!
  title: String!
  votes: Int
}
```

#### Code first resolver[#](/graphql/resolvers#code-first-resolver)

At this point, we've defined the objects (type definitions) that can exist in our data graph, but clients don't yet have a way to interact with those objects. To address that, we need to create a resolver class. In the code first method, a resolver class both defines resolver functions **and** generates the **Query type**. This will be clear as we work through the example below:

authors/authors.resolver.ts

JS TS

```typescript

@Resolver(of => Author)
export class AuthorsResolver {
  constructor(
    private authorsService: AuthorsService,
    private postsService: PostsService,
  ) {}

  @Query(returns => Author)
  async author(@Args('id', { type: () => Int }) id: number) {
    return this.authorsService.findOneById(id);
  }

  @ResolveField()
  async posts(@Parent() author: Author) {
    const { id } = author;
    return this.postsService.findAll({ authorId: id });
  }
}
```

> **Hint** All decorators (e.g., `@Resolver`, `@ResolveField`, `@Args`, etc.) are exported from the `@nestjs/graphql` package.

You can define multiple resolver classes. Nest will combine these at run time. See the [module](/graphql/resolvers#module) section below for more on code organization.

> **Note** The logic inside the `AuthorsService` and `PostsService` classes can be as simple or sophisticated as needed. The main point of this example is to show how to construct resolvers and how they can interact with other providers.

In the example above, we created the `AuthorsResolver` which defines one query resolver function and one field resolver function. To create a resolver, we create a class with resolver functions as methods, and annotate the class with the `@Resolver()` decorator.

In this example, we defined a query handler to get the author object based on the `id` sent in the request. To specify that the method is a query handler, use the `@Query()` decorator.

The argument passed to the `@Resolver()` decorator is optional, but comes into play when our graph becomes non-trivial. It's used to supply a parent object used by field resolver functions as they traverse down through an object graph.

In our example, since the class includes a **field resolver** function (for the `posts` property of the `Author` object type), we **must** supply the `@Resolver()` decorator with a value to indicate which class is the parent type (i.e., the corresponding `ObjectType` class name) for all field resolvers defined within this class. As should be clear from the example, when writing a field resolver function, it's necessary to access the parent object (the object the field being resolved is a member of). In this example, we populate an author's posts array with a field resolver that calls a service which takes the author's `id` as an argument. Hence the need to identify the parent object in the `@Resolver()` decorator. Note the corresponding use of the `@Parent()` method parameter decorator to then extract a reference to that parent object in the field resolver.

We can define multiple `@Query()` resolver functions (both within this class, and in any other resolver class), and they will be aggregated into a single **Query type** definition in the generated SDL along with the appropriate entries in the resolver map. This allows you to define queries close to the models and services that they use, and to keep them well organized in modules.

> **Hint** Nest CLI provides a generator (schematic) that automatically generates **all the boilerplate code** to help us avoid doing all of this, and make the developer experience much simpler. Read more about this feature [here](/v9/recipes/crud-generator).

#### Query type names[#](/graphql/resolvers#query-type-names)

In the above examples, the `@Query()` decorator generates a GraphQL schema query type name based on the method name. For example, consider the following construction from the example above:

```typescript

@Query(returns => Author)
async author(@Args('id', { type: () => Int }) id: number) {
  return this.authorsService.findOneById(id);
}
```

This generates the following entry for the author query in our schema (the query type uses the same name as the method name):

```graphql

type Query {
  author(id: Int!): Author
}
```

> **Hint** Learn more about GraphQL queries [here](https://graphql.org/learn/queries/).

Conventionally, we prefer to decouple these names; for example, we prefer to use a name like `getAuthor()` for our query handler method, but still use `author` for our query type name. The same applies to our field resolvers. We can easily do this by passing the mapping names as arguments of the `@Query()` and `@ResolveField()` decorators, as shown below:

authors/authors.resolver.ts

JS TS

```typescript

@Resolver(of => Author)
export class AuthorsResolver {
  constructor(
    private authorsService: AuthorsService,
    private postsService: PostsService,
  ) {}

  @Query(returns => Author, { name: 'author' })
  async getAuthor(@Args('id', { type: () => Int }) id: number) {
    return this.authorsService.findOneById(id);
  }

  @ResolveField('posts', returns => [Post])
  async getPosts(@Parent() author: Author) {
    const { id } = author;
    return this.postsService.findAll({ authorId: id });
  }
}
```

The `getAuthor` handler method above will result in generating the following part of the GraphQL schema in SDL:

```graphql

type Query {
  author(id: Int!): Author
}
```

```typescript

@Args('id') id: string
```

In the `getAuthor()` case, the `number` type is used, which presents a challenge. The `number` TypeScript type doesn't give us enough information about the expected GraphQL representation (e.g., `Int` vs. `Float`). Thus we have to **explicitly** pass the type reference. We do that by passing a second argument to the `Args()` decorator, containing argument options, as shown below:

```typescript

@Query(returns => Author, { name: 'author' })
async getAuthor(@Args('id', { type: () => Int }) id: number) {
  return this.authorsService.findOneById(id);
}
```

```typescript

getAuthor(
  @Args('firstName', { nullable: true }) firstName?: string,
  @Args('lastName', { defaultValue: '' }) lastName?: string,
) {}
```

#### Dedicated arguments class[#](/graphql/resolvers#dedicated-arguments-class)

With inline `@Args()` calls, code like the example above becomes bloated. Instead, you can create a dedicated `GetAuthorArgs` arguments class and access it in the handler method as follows:

```typescript

@Args() args: GetAuthorArgs
```

Create the `GetAuthorArgs` class using `@ArgsType()` as shown below:

authors/dto/get-author.args.ts

JS TS

```typescript

import { MinLength } from 'class-validator';
import { Field, ArgsType } from '@nestjs/graphql';

@ArgsType()
class GetAuthorArgs {
  @Field({ nullable: true })
  firstName?: string;

  @Field({ defaultValue: '' })
  @MinLength(3)
  lastName: string;
}
```

> **Hint** Again, due to TypeScript's metadata reflection system limitations, it's required to either use the `@Field` decorator to manually indicate type and optionality, or use a [CLI plugin](/v9/graphql/cli-plugin).

This will result in generating the following part of the GraphQL schema in SDL:

```graphql

type Query {
  author(firstName: String, lastName: String = ''): Author
}
```

> **Hint** Note that arguments classes like `GetAuthorArgs` play very well with the `ValidationPipe` (read [more](/v9/techniques/validation)).

#### Class inheritance[#](/graphql/resolvers#class-inheritance)

You can use standard TypeScript class inheritance to create base classes with generic utility type features (fields and field properties, validations, etc.) that can be extended. For example, you may have a set of pagination related arguments that always include the standard `offset` and `limit` fields, but also other index fields that are type-specific. You can set up a class hierarchy as shown below.

Base `@ArgsType()` class:

```typescript

@ArgsType()
class PaginationArgs {
  @Field((type) => Int)
  offset: number = 0;

  @Field((type) => Int)
  limit: number = 10;
}
```

Type specific sub-class of the base `@ArgsType()` class:

```typescript

@ArgsType()
class GetAuthorArgs extends PaginationArgs {
  @Field({ nullable: true })
  firstName?: string;

  @Field({ defaultValue: '' })
  @MinLength(3)
  lastName: string;
}
```

The same approach can be taken with `@ObjectType()` objects. Define generic properties on the base class:

```typescript

@ObjectType()
class Character {
  @Field((type) => Int)
  id: number;

  @Field()
  name: string;
}
```

Add type-specific properties on sub-classes:

```typescript

@ObjectType()
class Warrior extends Character {
  @Field()
  level: number;
}
```

You can use inheritance with a resolver as well. You can ensure type safety by combining inheritance and TypeScript generics. For example, to create a base class with a generic `findAll` query, use a construction like this:

```typescript

function BaseResolver<T extends Type<unknown>>(classRef: T): any {
  @Resolver({ isAbstract: true })
  abstract class BaseResolverHost {
    @Query((type) => [classRef], { name: `findAll${classRef.name}` })
    async findAll(): Promise<T[]> {
      return [];
    }
  }
  return BaseResolverHost;
}
```

Note the following:

* an explicit return type (`any` above) is required: otherwise TypeScript complains about the usage of a private class definition. Recommended: define an interface instead of using `any`.
* `Type` is imported from the `@nestjs/common` package
* The `isAbstract: true` property indicates that SDL (Schema Definition Language statements) shouldn't be generated for this class. Note, you can set this property for other types as well to suppress SDL generation.

Here's how you could generate a concrete sub-class of the `BaseResolver`:

```typescript

@Resolver((of) => Recipe)
export class RecipesResolver extends BaseResolver(Recipe) {
  constructor(private recipesService: RecipesService) {
    super();
  }
}
```

This construct would generated the following SDL:

```graphql

type Query {
  findAllRecipe: [Recipe!]!
}
```

#### Generics[#](/graphql/resolvers#generics)

We saw one use of generics above. This powerful TypeScript feature can be used to create useful abstractions. For example, here's a sample cursor-based pagination implementation based on [this documentation](https://graphql.org/learn/pagination/#pagination-and-edges):

```typescript

import { Field, ObjectType, Int } from '@nestjs/graphql';
import { Type } from '@nestjs/common';

interface IEdgeType<T> {
  cursor: string;
  node: T;
}

export interface IPaginatedType<T> {
  edges: IEdgeType<T>[];
  nodes: T[];
  totalCount: number;
  hasNextPage: boolean;
}

export function Paginated<T>(classRef: Type<T>): Type<IPaginatedType<T>> {
  @ObjectType(`${classRef.name}Edge`)
  abstract class EdgeType {
    @Field((type) => String)
    cursor: string;

    @Field((type) => classRef)
    node: T;
  }

  @ObjectType({ isAbstract: true })
  abstract class PaginatedType implements IPaginatedType<T> {
    @Field((type) => [EdgeType], { nullable: true })
    edges: EdgeType[];

    @Field((type) => [classRef], { nullable: true })
    nodes: T[];

    @Field((type) => Int)
    totalCount: number;

    @Field()
    hasNextPage: boolean;
  }
  return PaginatedType as Type<IPaginatedType<T>>;
}
```

With the above base class defined, we can now easily create specialized types that inherit this behavior. For example:

```typescript

@ObjectType()
class PaginatedAuthor extends Paginated(Author) {}
```

#### Schema first[#](/graphql/resolvers#schema-first)

As mentioned in the [previous](/v9/graphql/quick-start) chapter, in the schema first approach we start by manually defining schema types in SDL (read [more](https://graphql.org/learn/schema/#type-language)). Consider the following SDL type definitions.

> **Hint** For convenience in this chapter, we've aggregated all of the SDL in one location (e.g., one `.graphql` file, as shown below). In practice, you may find it appropriate to organize your code in a modular fashion. For example, it can be helpful to create individual SDL files with type definitions representing each domain entity, along with related services, resolver code, and the Nest module definition class, in a dedicated directory for that entity. Nest will aggregate all the individual schema type definitions at run time.

```graphql

type Author {
  id: Int!
  firstName: String
  lastName: String
  posts: [Post]
}

type Post {
  id: Int!
  title: String!
  votes: Int
}

type Query {
  author(id: Int!): Author
}
```

#### Schema first resolver[#](/graphql/resolvers#schema-first-resolver)

The schema above exposes a single query - `author(id: Int!): Author`.

> **Hint** Learn more about GraphQL queries [here](https://graphql.org/learn/queries/).

Let's now create an `AuthorsResolver` class that resolves author queries:

authors/authors.resolver.ts

JS TS

```typescript

@Resolver('Author')
export class AuthorsResolver {
  constructor(
    private authorsService: AuthorsService,
    private postsService: PostsService,
  ) {}

  @Query()
  async author(@Args('id') id: number) {
    return this.authorsService.findOneById(id);
  }

  @ResolveField()
  async posts(@Parent() author) {
    const { id } = author;
    return this.postsService.findAll({ authorId: id });
  }
}
```

> **Hint** All decorators (e.g., `@Resolver`, `@ResolveField`, `@Args`, etc.) are exported from the `@nestjs/graphql` package.

> **Note** The logic inside the `AuthorsService` and `PostsService` classes can be as simple or sophisticated as needed. The main point of this example is to show how to construct resolvers and how they can interact with other providers.

The `@Resolver()` decorator is required. It takes an optional string argument with the name of a class. This class name is required whenever the class includes `@ResolveField()` decorators to inform Nest that the decorated method is associated with a parent type (the `Author` type in our current example). Alternatively, instead of setting `@Resolver()` at the top of the class, this can be done for each method:

```typescript

@Resolver('Author')
@ResolveField()
async posts(@Parent() author) {
  const { id } = author;
  return this.postsService.findAll({ authorId: id });
}
```

In this case (`@Resolver()` decorator at the method level), if you have multiple `@ResolveField()` decorators inside a class, you must add `@Resolver()` to all of them. This is not considered the best practice (as it creates extra overhead).

> **Hint** Any class name argument passed to `@Resolver()`**does not** affect queries (`@Query()` decorator) or mutations (`@Mutation()` decorator).

> **Warning** Using the `@Resolver` decorator at the method level is not supported with the **code first** approach.

In the above examples, the `@Query()` and `@ResolveField()` decorators are associated with GraphQL schema types based on the method name. For example, consider the following construction from the example above:

```typescript

@Query()
async author(@Args('id') id: number) {
  return this.authorsService.findOneById(id);
}
```

This generates the following entry for the author query in our schema (the query type uses the same name as the method name):

```graphql

type Query {
  author(id: Int!): Author
}
```

Conventionally, we would prefer to decouple these, using names like `getAuthor()` or `getPosts()` for our resolver methods. We can easily do this by passing the mapping name as an argument to the decorator, as shown below:

authors/authors.resolver.ts

JS TS

```typescript

@Resolver('Author')
export class AuthorsResolver {
  constructor(
    private authorsService: AuthorsService,
    private postsService: PostsService,
  ) {}

  @Query('author')
  async getAuthor(@Args('id') id: number) {
    return this.authorsService.findOneById(id);
  }

  @ResolveField('posts')
  async getPosts(@Parent() author) {
    const { id } = author;
    return this.postsService.findAll({ authorId: id });
  }
}
```

> **Hint** Nest CLI provides a generator (schematic) that automatically generates **all the boilerplate code** to help us avoid doing all of this, and make the developer experience much simpler. Read more about this feature [here](/v9/recipes/crud-generator).

#### Generating types[#](/graphql/resolvers#generating-types)

Assuming that we use the schema first approach and have enabled the typings generation feature (with `outputAs: 'class'` as shown in the [previous](/v9/graphql/quick-start) chapter), once you run the application it will generate the following file (in the location you specified in the `GraphQLModule.forRoot()` method). For example, in `src/graphql.ts`:

graphql.ts

JS TS

```typescript

export class Author {
  id: number;
  firstName?: string;
  lastName?: string;
  posts?: Post[];
}

export class Post {
  id: number;
  title: string;
  votes?: number;
}

export abstract class IQuery {
  abstract author(id: number): Author | Promise<Author>;
}
```

By generating classes (instead of the default technique of generating interfaces), you can use declarative validation **decorators** in combination with the schema first approach, which is an extremely useful technique (read [more](/v9/techniques/validation)). For example, you could add `class-validator` decorators to the generated `CreatePostInput` class as shown below to enforce minimum and maximum string lengths on the `title` field:

```typescript

import { MinLength, MaxLength } from 'class-validator';

export class CreatePostInput {
  @MinLength(3)
  @MaxLength(50)
  title: string;
}
```

> **Notice** To enable auto-validation of your inputs (and parameters), use `ValidationPipe`. Read more about validation [here](/v9/techniques/validation) and more specifically about pipes [here](/v9/pipes).

However, if you add decorators directly to the automatically generated file, they will be **overwritten** each time the file is generated. Instead, create a separate file and simply extend the generated class.

```typescript

import { MinLength, MaxLength } from 'class-validator';
import { Post } from '../../graphql.ts';

export class CreatePostInput extends Post {
  @MinLength(3)
  @MaxLength(50)
  title: string;
}
```

#### GraphQL argument decorators[#](/graphql/resolvers#graphql-argument-decorators)

We can access the standard GraphQL resolver arguments using dedicated decorators. Below is a comparison of the Nest decorators and the plain Apollo parameters they represent.

|                            |                              |
| -------------------------- | ---------------------------- |
| `@Root()` and `@Parent()`  | `root`/`parent`              |
| `@Context(param?: string)` | `context` / `context[param]` |
| `@Info(param?: string)`    | `info` / `info[param]`       |
| `@Args(param?: string)`    | `args` / `args[param]`       |

```typescript

@Module({
  imports: [PostsModule],
  providers: [AuthorsService, AuthorsResolver],
})
export class AuthorsModule {}
```

> **Hint** It is helpful to organize your code by your so-called **domain model** (similar to the way you would organize entry points in a REST API). In this approach, keep your models (`ObjectType` classes), resolvers and services together within a Nest module representing the domain model. Keep all of these components in a single folder per module. When you do this, and use the [Nest CLI](/v9/cli/overview) to generate each element, Nest will wire all of these parts together (locating files in appropriate folders, generating entries in `provider` and `imports` arrays, etc.) automatically for you.

----
url: https://docs.nestjs.com/v6/techniques/validation
----

* [Validation](https://docs.nestjs.com/v6/techniques/validation#validation)
* [Overview](https://docs.nestjs.com/v6/techniques/validation#overview)
* [Auto-validation](https://docs.nestjs.com/v6/techniques/validation#auto-validation)
* [Disable detailed errors](https://docs.nestjs.com/v6/techniques/validation#disable-detailed-errors)
* [Stripping properties](https://docs.nestjs.com/v6/techniques/validation#stripping-properties)
* [Transform payload objects](https://docs.nestjs.com/v6/techniques/validation#transform-payload-objects)
* [WebSockets & Microservices](https://docs.nestjs.com/v6/techniques/validation#websockets--microservices)
* [Learn more](https://docs.nestjs.com/v6/techniques/validation#learn-more)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/techniques/validation.md "Suggest Edits")

### Validation

It is best practice to validate the correctness of any data sent into a web application. To automatically validate incoming requests, Nest provides a built-in `ValidationPipe`, which makes use of the powerful [class-validator](https://github.com/typestack/class-validator) package and its declarative validation decorators. The `ValidationPipe` provides a convenient approach to enforce validation rules for all incoming client payloads, where the specific rules are declared with simple annotations in local class/DTO declarations in each module.

#### Overview[#](/techniques/validation#overview)

In the [Pipes](/v6/pipes) chapter, we went through the process of building a simple validation pipe to demonstrate how the process works. Be sure to review that chapter to best understand the topics of this chapter. Here, we'll focus on various **real world** use cases of the `ValidationPipe`, and using some of its advanced customization features.

#### Auto-validation[#](/techniques/validation#auto-validation)

We'll start by binding `ValidationPipe` at the application level, thus ensuring all endpoints are protected from receiving incorrect data.

```typescript

async function bootstrap() {
  const app = await NestFactory.create(ApplicationModule);
  app.useGlobalPipes(new ValidationPipe());
  await app.listen(3000);
}
bootstrap();
```

To test our pipe, let's create a basic endpoint.

```typescript

@Post()
create(@Body() createUserDto: CreateUserDto) {
  return 'This action adds a new user';
}
```

Now we can add a few validation rules in our `CreateUserDto`. We do this using decorators provided by the `class-validator` package, described in detail [here](https://github.com/typestack/class-validator#validation-decorators). In this fashion, any route that uses the `CreateUserDto` will automatically enforce these validation rules.

```typescript

import { IsEmail, IsNotEmpty } from 'class-validator';

export class CreateUserDto {
  @IsEmail()
  email: string;

  @IsNotEmpty()
  password: string;
}
```

With these rules in place, if a request hits our endpoint with an invalid `email` property in the request body, the application will automatically respond with a `400 Bad Request` code, along with the following response body:

```json

{
  "statusCode": 400,
  "error": "Bad Request",
  "message": [
    {
      "target": {},
      "property": "email",
      "children": [],
      "constraints": {
        "isEmail": "email must be an email"
      }
    }
  ]
}
```

In addition to validating request bodies, the `ValidationPipe` can be used with other request object properties as well. Imagine that we would like to accept `:id` in the endpoint path. To ensure that only numbers are accepted for this request parameter, we can use the following construct:

```typescript

@Get(':id')
findOne(@Param() params: FindOneParams) {
  return 'This action returns a user';
}
```

`FindOneParams`, like a DTO, is simply a class that defines validation rules using `class-validator`. It would look like this:

```typescript

import { IsNumberString } from 'class-validator';

export class FindOneParams {
  @IsNumberString()
  id: number;
}
```

#### Disable detailed errors[#](/techniques/validation#disable-detailed-errors)

Error messages can be helpful to explain what was incorrect in a request. However, some production environments prefer to disable detailed errors. Do this by passing an options object to the `ValidationPipe`:

```typescript

app.useGlobalPipes(
  new ValidationPipe({
    disableErrorMessages: true,
  }),
);
```

As a result, detailed error messages won't be displayed in the response body.

#### Stripping properties[#](/techniques/validation#stripping-properties)

Our `ValidationPipe` can also filter out properties that should not be received by the method handler. In this case, we can **whitelist** the acceptable properties, and any property not included in the whitelist is automatically stripped from the resulting object. For example, if our handler expects `email` and `password` properties, but a request also includes an `age` property, this property can be automatically removed from the resulting DTO. To enable such behavior, set `whitelist` to `true`.

```typescript

app.useGlobalPipes(
  new ValidationPipe({
    whitelist: true,
  }),
);
```

When set to true, this will automatically remove non-whitelisted properties (those without any decorator in the validation class).

Alternatively, you can stop the request from processing when non-whitelisted properties are present, and return an error response to the user. To enable this, set the `forbidNonWhitelisted` option property to `true`, in combination with setting `whitelist` to `true`.

## Learn the right way!

* **60+ chapters
* **4+ hours of videos
* **Official certificate
* **Deep-dive sessions

[Explore official courses](https://courses.nestjs.com "Courses | NestJS - A node.js framework built on top of TypeScript")

#### Transform payload objects[#](/techniques/validation#transform-payload-objects)

Payloads coming in over the network are plain JavaScript objects. The `ValidationPipe` can automatically transform payloads to be objects typed according to their DTO classes. To enable auto-transformation, set `transform` to `true`.

```typescript

app.useGlobalPipes(
  new ValidationPipe({
    transform: true,
  }),
);
```

#### WebSockets & Microservices[#](/techniques/validation#websockets--microservices)

While this chapter shows examples using HTTP style applications (e.g., Express or Fastify), the `ValidationPipe` works the same for WebSockets and microservices, regardless of the transport method that is used.

#### Learn more[#](/techniques/validation#learn-more)

Read more about custom validators, error messages, and available decorators as provided by the `class-validator` package [here](https://github.com/typestack/class-validator).

----
url: https://docs.nestjs.com/v8/techniques/compression
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Compression](https://docs.nestjs.com/v8/techniques/compression#compression)
* [Use with Express (default)](https://docs.nestjs.com/v8/techniques/compression#use-with-express-default)
* [Use with Fastify](https://docs.nestjs.com/v8/techniques/compression#use-with-fastify)

```bash

$ npm i --save compression
```

Once the installation is complete, apply the compression middleware as global middleware.

```typescript

import * as compression from 'compression';
// somewhere in your initialization file
app.use(compression());
```

#### Use with Fastify[#](/techniques/compression#use-with-fastify)

If using the `FastifyAdapter`, you'll want to use [fastify-compress](https://github.com/fastify/fastify-compress):

```bash

$ npm i --save fastify-compress
```

Once the installation is complete, apply the fastify-compress middleware as global middleware.

```typescript

import compression from 'fastify-compress';
// somewhere in your initialization file
await app.register(compression);
```

By default, fastify-compress will use Brotli compression (on Node >= 11.7.0) when browsers indicate support for the encoding. While Brotli is quite efficient in terms of compression ratio, it's also quite slow. Due to this, you may want to tell fastify-compress to only use deflate and gzip to compress responses; you'll end up with larger responses but they'll be delivered much more quickly.

To specify encodings, provide a second argument to `app.register`:

```typescript

await app.register(compression, { encodings: ['gzip', 'deflate'] });
```

The above tells `fastify-compress` to only use gzip and deflate encodings, preferring gzip if the client supports both.

----
url: https://docs.nestjs.com/v11/websockets/interceptors
----

* [Interceptors](https://docs.nestjs.com/v11/websockets/interceptors#interceptors)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/websockets/interceptors.md "Suggest Edits")

### Interceptors

There is no difference between [regular interceptors](/v11/interceptors) and web sockets interceptors. The following example uses a manually instantiated method-scoped interceptor. Just as with HTTP based applications, you can also use gateway-scoped interceptors (i.e., prefix the gateway class with a `@UseInterceptors()` decorator).

JS TS

```typescript

@UseInterceptors(new TransformInterceptor())
@SubscribeMessage('events')
handleEvent(client: Client, data: unknown): WsResponse<unknown> {
  const event = 'events';
  return { event, data };
}
```

```typescript

@UseInterceptors(new TransformInterceptor())
@SubscribeMessage('events')
handleEvent(client, data) {
  const event = 'events';
  return { event, data };
}
```

----
url: https://docs.nestjs.com/v9/openapi/types-and-parameters
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Types and parameters](https://docs.nestjs.com/v9/openapi/types-and-parameters#types-and-parameters)
* [Arrays](https://docs.nestjs.com/v9/openapi/types-and-parameters#arrays)
* [Circular dependencies](https://docs.nestjs.com/v9/openapi/types-and-parameters#circular-dependencies)
* [Generics and interfaces](https://docs.nestjs.com/v9/openapi/types-and-parameters#generics-and-interfaces)
* [Enums](https://docs.nestjs.com/v9/openapi/types-and-parameters#enums)
* [Enums schema](https://docs.nestjs.com/v9/openapi/types-and-parameters#enums-schema)
* [Raw definitions](https://docs.nestjs.com/v9/openapi/types-and-parameters#raw-definitions)
* [Extra models](https://docs.nestjs.com/v9/openapi/types-and-parameters#extra-models)
* [oneOf, anyOf, allOf](https://docs.nestjs.com/v9/openapi/types-and-parameters#oneof-anyof-allof)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/openapi/types-and-parameters.md "Suggest Edits")

### 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:

```typescript

@Post()
async create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

> **Hint** To explicitly set the body definition use the `@ApiBody()` decorator (imported from the `@nestjs/swagger` package).

Based on the `CreateCatDto`, the following model definition Swagger UI will be created:

As you can see, the definition is empty although the class has a few declared properties. In order to make the class properties visible to the `SwaggerModule`, we have to either annotate them with the `@ApiProperty()` decorator or use the CLI plugin (read more in the **Plugin** section) which will do it automatically:

```typescript

import { ApiProperty } from '@nestjs/swagger';

export class CreateCatDto {
  @ApiProperty()
  name: string;

  @ApiProperty()
  age: number;

  @ApiProperty()
  breed: string;
}
```

> **Hint** Instead of manually annotating each property, consider using the Swagger plugin (see [Plugin](/v9/openapi/cli-plugin) section) which will automatically provide this for you.

Let's open the browser and verify the generated `CreateCatDto` model:

In addition, the `@ApiProperty()` decorator allows setting various [Schema Object](https://swagger.io/specification/#schemaObject) properties:

```typescript

@ApiProperty({
  description: 'The age of a cat',
  minimum: 1,
  default: 1,
})
age: number;
```

> **Hint** Instead of explicitly typing the `@ApiProperty({ required: false })` you can use the `@ApiPropertyOptional()` short-hand decorator.

In order to explicitly set the type of the property, use the `type` key:

```typescript

@ApiProperty({
  type: Number,
})
age: number;
```

#### Arrays[#](/openapi/types-and-parameters#arrays)

When the property is an array, we must manually indicate the array type as shown below:

```typescript

@ApiProperty({ type: [String] })
names: string[];
```

> **Hint** Consider using the Swagger plugin (see [Plugin](/v9/openapi/cli-plugin) section) which will automatically detect arrays.

```typescript

@ApiProperty({ type: () => Node })
node: Node;
```

> **Hint** Consider using the Swagger plugin (see [Plugin](/v9/openapi/cli-plugin) section) which will automatically detect circular dependencies.

#### Generics and interfaces[#](/openapi/types-and-parameters#generics-and-interfaces)

Since TypeScript does not store metadata about generics or interfaces, when you use them in your DTOs, `SwaggerModule` may not be able to properly generate model definitions at runtime. For instance, the following code won't be correctly inspected by the Swagger module:

```typescript

createBulk(@Body() usersDto: CreateUserDto[])
```

In order to overcome this limitation, you can set the type explicitly:

```typescript

@ApiBody({ type: [CreateUserDto] })
createBulk(@Body() usersDto: CreateUserDto[])
```

#### Enums[#](/openapi/types-and-parameters#enums)

To identify an `enum`, we must manually set the `enum` property on the `@ApiProperty` with an array of values.

```typescript

@ApiProperty({ enum: ['Admin', 'Moderator', 'User']})
role: UserRole;
```

Alternatively, define an actual TypeScript enum as follows:

```typescript

export enum UserRole {
  Admin = 'Admin',
  Moderator = 'Moderator',
  User = 'User',
}
```

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

```typescript

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

With `isArray` set to **true**, the `enum` can be selected as a **multi-select**:

#### Enums schema[#](/openapi/types-and-parameters#enums-schema)

By default, the `enum` property will add a raw definition of [Enum](https://swagger.io/docs/specification/data-models/enums/) on the `parameter`.

```yaml

- breed:
    type: 'string'
    enum:
      - Persian
      - Tabby
      - Siamese
```

The above specification works fine for most cases. However, if you are utilizing a tool that takes the specification as **input** and generates **client-side** code, you might run into a problem with the generated code containing duplicated `enums`. Consider the following code snippet:

```typescript

// generated client-side code
export class CatDetail {
  breed: CatDetailEnum;
}

export class CatInformation {
  breed: CatInformationEnum;
}

export enum CatDetailEnum {
  Persian = 'Persian',
  Tabby = 'Tabby',
  Siamese = 'Siamese',
}

export enum CatInformationEnum {
  Persian = 'Persian',
  Tabby = 'Tabby',
  Siamese = 'Siamese',
}
```

> **Hint** The above snippet is generated using a tool called [NSwag](https://github.com/RicoSuter/NSwag).

You can see that now you have two `enums` that are exactly the same. To address this issue, you can pass an `enumName` along with the `enum` property in your decorator.

```typescript

export class CatDetail {
  @ApiProperty({ enum: CatBreed, enumName: 'CatBreed' })
  breed: CatBreed;
}
```

The `enumName` property enables `@nestjs/swagger` to turn `CatBreed` into its own `schema` which in turns makes `CatBreed` enum reusable. The specification will look like the following:

```yaml

CatDetail:
  type: 'object'
  properties:
    ...
    - breed:
        schema:
          $ref: '#/components/schemas/CatBreed'
CatBreed:
  type: string
  enum:
    - Persian
    - Tabby
    - Siamese
```

> **Hint** Any **decorator** that takes `enum` as a property will also take `enumName`.

#### Raw definitions[#](/openapi/types-and-parameters#raw-definitions)

In some specific scenarios (e.g., deeply nested arrays, matrices), you may want to describe your type by hand.

```typescript

@ApiProperty({
  type: 'array',
  items: {
    type: 'array',
    items: {
      type: 'number',
    },
  },
})
coords: number[][];
```

Likewise, in order to define your input/output content manually in controller classes, use the `schema` property:

```typescript

@ApiBody({
  schema: {
    type: 'array',
    items: {
      type: 'array',
      items: {
        type: 'number',
      },
    },
  },
})
async create(@Body() coords: number[][]) {}
```

#### Extra models[#](/openapi/types-and-parameters#extra-models)

To define additional models that are not directly referenced in your controllers but should be inspected by the Swagger module, use the `@ApiExtraModels()` decorator:

```typescript

@ApiExtraModels(ExtraModel)
export class CreateCatDto {}
```

> **Hint** You only need to use `@ApiExtraModels()` once for a specific model class.

Alternatively, you can pass an options object with the `extraModels` property specified to the `SwaggerModule#createDocument()` method, as follows:

```typescript

const document = SwaggerModule.createDocument(app, options, {
  extraModels: [ExtraModel],
});
```

To get a reference (`$ref`) to your model, use the `getSchemaPath(ExtraModel)` function:

```typescript

'application/vnd.api+json': {
   schema: { $ref: getSchemaPath(ExtraModel) },
},
```

#### oneOf, anyOf, allOf[#](/openapi/types-and-parameters#oneof-anyof-allof)

To combine schemas, you can use the `oneOf`, `anyOf` or `allOf` keywords ([read more](https://swagger.io/docs/specification/data-models/oneof-anyof-allof-not/)).

```typescript

@ApiProperty({
  oneOf: [
    { $ref: getSchemaPath(Cat) },
    { $ref: getSchemaPath(Dog) },
  ],
})
pet: Cat | Dog;
```

If you want to define a polymorphic array (i.e., an array whose members span multiple schemas), you should use a raw definition (see above) to define your type by hand.

```typescript

type Pet = Cat | Dog;

@ApiProperty({
  type: 'array',
  items: {
    oneOf: [
      { $ref: getSchemaPath(Cat) },
      { $ref: getSchemaPath(Dog) },
    ],
  },
})
pets: Pet[];
```

> **Hint** The `getSchemaPath()` function is imported from `@nestjs/swagger`.

Both `Cat` and `Dog` must be defined as extra models using the `@ApiExtraModels()` decorator (at the class-level).

----
url: https://docs.nestjs.com/websockets/guards
----

[Skip to content](#content)

On this page

* [Guards](https://docs.nestjs.com/websockets/guards#guards)
* [Binding guards](https://docs.nestjs.com/websockets/guards#binding-guards)

### Guards

There is no fundamental difference between WebSocket guards and [regular HTTP application guards](/guards). The only difference is that instead of throwing `HttpException`, you should throw `WsException`. If a guard returns `false`, Nest throws a `WsException` with the message `'Forbidden resource'`.

> **Hint** The `WsException` class is exposed from the `@nestjs/websockets` package.

#### Binding guards[#](/websockets/guards#binding-guards)

The following example uses a method-scoped guard. As with HTTP-based applications, you can also use gateway-scoped guards (i.e., decorate the gateway class with `@UseGuards()`). Global guards registered with `app.useGlobalGuards()` or the `APP_GUARD` token apply to gateways as well.

JS TS

```typescript

@UseGuards(AuthGuard)
@SubscribeMessage('events')
handleEvent(client: Client, data: unknown): WsResponse<unknown> {
  const event = 'events';
  return { event, data };
}
```

```typescript

@UseGuards(AuthGuard)
@SubscribeMessage('events')
handleEvent(client, data) {
  const event = 'events';
  return { event, data };
}
```

[**Edit on GitHub](https://github.com/nestjs/docs.nestjs.com/edit/master/content/websockets/guards.md)

----
url: https://docs.nestjs.com/v11/openapi/operations
----

* [Operations](https://docs.nestjs.com/v11/openapi/operations#operations)
* [Tags](https://docs.nestjs.com/v11/openapi/operations#tags)
* [Headers](https://docs.nestjs.com/v11/openapi/operations#headers)
* [Responses](https://docs.nestjs.com/v11/openapi/operations#responses)
* [File upload](https://docs.nestjs.com/v11/openapi/operations#file-upload)
* [Extensions](https://docs.nestjs.com/v11/openapi/operations#extensions)
* [Advanced: Generic ApiResponse](https://docs.nestjs.com/v11/openapi/operations#advanced-generic-apiresponse)

[](https://srv.carbonads.net/ads/click/x/GTND4277CVSIC2JEFTBLYKQUF67D62QYCT7IPZ3JCAAI623WC6YDE53KC6SI5K7MCVBI5K3JCWYILKJUCKADVKJYHEYI55QLCAYD653ECTNCYBZ52K)[The Complete PDF SDK for Developers. Full control, Seamless Integration. Try for Free. ](https://srv.carbonads.net/ads/click/x/GTND4277CVSIC2JEFTBLYKQUF67D62QYCT7IPZ3JCAAI623WC6YDE53KC6SI5K7MCVBI5K3JCWYILKJUCKADVKJYHEYI55QLCAYD653ECTNCYBZ52K)[ads via Carbon](http://carbonads.net/?utm_source=nestjscom\&utm_medium=ad_via_link\&utm_campaign=in_unit\&utm_term=carbon)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/openapi/operations.md "Suggest Edits")

### Operations

In OpenAPI terms, paths are endpoints (resources), such as `/users` or `/reports/summary`, that your API exposes, and operations are the HTTP methods used to manipulate these paths, such as `GET`, `POST` or `DELETE`.

#### Tags[#](/openapi/operations#tags)

To attach a controller to a specific tag, use the `@ApiTags(...tags)` decorator.

```typescript

@ApiTags('cats')
@Controller('cats')
export class CatsController {}
```

OpenAPI 3.2 extends the Tag Object so that tags can be organized into a hierarchy and annotated with a hint about how they should be presented. To declare these relationships, define the tags up front with `DocumentBuilder` and pass the `parent` and `kind` options to `addTag()`:

```typescript

const config = new DocumentBuilder()
  .setOpenAPIVersion('3.2.0')
  .addTag('Animals', 'Everything about animals', undefined, { kind: 'nav' })
  .addTag('Cats', 'Cat operations', undefined, { parent: 'Animals' })
  .addTag('Dogs', 'Dog operations', undefined, { parent: 'Animals' })
  .build();
```

The `parent` option references another tag by name, and `kind` is a free-form, machine-readable string that hints how the tag should be used — commonly `nav`, `badge`, or `audience`.

> **Warning** The `parent` and `kind` fields belong to the OpenAPI 3.2 Tag Object. You must call `setOpenAPIVersion('3.2.0')`, otherwise the generated document still declares `openapi: 3.0.0` and strict validators will reject these fields. Hierarchy fields can only be defined through `DocumentBuilder.addTag()`; setting them on the `@ApiTags()` decorator has no effect.

#### Headers[#](/openapi/operations#headers)

To define custom headers that are expected as part of the request, use `@ApiHeader()`.

```typescript

@ApiHeader({
  name: 'X-MyHeader',
  description: 'Custom header',
})
@Controller('cats')
export class CatsController {}
```

#### Responses[#](/openapi/operations#responses)

To define a custom HTTP response, use the `@ApiResponse()` decorator.

```typescript

@Post()
@ApiResponse({ status: 201, description: 'The record has been successfully created.'})
@ApiResponse({ status: 403, description: 'Forbidden.'})
async create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

```typescript

@Post()
@ApiCreatedResponse({ description: 'The record has been successfully created.'})
@ApiForbiddenResponse({ description: 'Forbidden.'})
async create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}
```

To specify a return model for a request, we must create a class and annotate all properties with the `@ApiProperty()` decorator.

```typescript

export class Cat {
  @ApiProperty()
  id: number;

  @ApiProperty()
  name: string;

  @ApiProperty()
  age: number;

  @ApiProperty()
  breed: string;
}
```

Then the `Cat` model can be used in combination with the `type` property of the response decorator.

```typescript

@ApiTags('cats')
@Controller('cats')
export class CatsController {
  @Post()
  @ApiCreatedResponse({
    description: 'The record has been successfully created.',
    type: Cat,
  })
  async create(@Body() createCatDto: CreateCatDto): Promise<Cat> {
    return this.catsService.create(createCatDto);
  }
}
```

Let's open the browser and verify the generated `Cat` model:

Instead of defining responses for each endpoint or controller individually, you can define a global response for all endpoints using the `DocumentBuilder` class. This approach is useful when you want to define a global response for all endpoints in your application (e.g., for errors like `401 Unauthorized` or `500 Internal Server Error`).

```typescript

const config = new DocumentBuilder()
  .addGlobalResponse({
    status: 500,
    description: 'Internal server error',
  })
  // other configurations
  .build();
```

#### File upload[#](/openapi/operations#file-upload)

You can enable file upload for a specific method with the `@ApiBody` decorator together with `@ApiConsumes()`. Here's a full example using the [File Upload](/v11/techniques/file-upload) technique:

```typescript

@UseInterceptors(FileInterceptor('file'))
@ApiConsumes('multipart/form-data')
@ApiBody({
  description: 'List of cats',
  type: FileUploadDto,
})
uploadFile(@UploadedFile() file: Express.Multer.File) {}
```

Where `FileUploadDto` is defined as follows:

```typescript

class FileUploadDto {
  @ApiProperty({ type: 'string', format: 'binary' })
  file: any;
}
```

To handle multiple files uploading, you can define `FilesUploadDto` as follows:

```typescript

class FilesUploadDto {
  @ApiProperty({ type: 'array', items: { type: 'string', format: 'binary' } })
  files: any[];
}
```

#### Extensions[#](/openapi/operations#extensions)

To add an Extension to a request use the `@ApiExtension()` decorator. The extension name must be prefixed with `x-`.

```typescript

@ApiExtension('x-foo', { hello: 'world' })
```

#### Advanced: Generic `ApiResponse`[#](/openapi/operations#advanced-generic-apiresponse)

With the ability to provide [Raw Definitions](/openapi/types-and-parameters#raw-definitions), we can define Generic schema for Swagger UI. Assume we have the following DTO:

```ts

export class PaginatedDto<TData> {
  @ApiProperty()
  total: number;

  @ApiProperty()
  limit: number;

  @ApiProperty()
  offset: number;

  results: TData[];
}
```

We skip decorating `results` as we will be providing a raw definition for it later. Now, let's define another DTO and name it, for example, `CatDto`, as follows:

```ts

export class CatDto {
  @ApiProperty()
  name: string;

  @ApiProperty()
  age: number;

  @ApiProperty()
  breed: string;
}
```

With this in place, we can define a `PaginatedDto<CatDto>` response, as follows:

```ts

@ApiOkResponse({
  schema: {
    allOf: [
      { $ref: getSchemaPath(PaginatedDto) },
      {
        properties: {
          results: {
            type: 'array',
            items: { $ref: getSchemaPath(CatDto) },
          },
        },
      },
    ],
  },
})
async findAll(): Promise<PaginatedDto<CatDto>> {}
```

In this example, we specify that the response will have allOf `PaginatedDto` and the `results` property will be of type `Array<CatDto>`.

* `getSchemaPath()` function that returns the OpenAPI Schema path from within the OpenAPI Spec File for a given model.
* `allOf` is a concept that OAS 3 provides to cover various Inheritance related use-cases.

Lastly, since `PaginatedDto` is not directly referenced by any controller, the `SwaggerModule` will not be able to generate a corresponding model definition just yet. In this case, we must add it as an [Extra Model](/openapi/types-and-parameters#extra-models). For example, we can use the `@ApiExtraModels()` decorator on the controller level, as follows:

```ts

@Controller('cats')
@ApiExtraModels(PaginatedDto)
export class CatsController {}
```

If you run Swagger now, the generated `swagger.json` for this specific endpoint should have the following response defined:

```json

"responses": {
  "200": {
    "description": "",
    "content": {
      "application/json": {
        "schema": {
          "allOf": [
            {
              "$ref": "#/components/schemas/PaginatedDto"
            },
            {
              "properties": {
                "results": {
                  "$ref": "#/components/schemas/CatDto"
                }
              }
            }
          ]
        }
      }
    }
  }
}
```

To make it reusable, we can create a custom decorator for `PaginatedDto`, as follows:

```ts

export const ApiPaginatedResponse = <TModel extends Type<any>>(
  model: TModel,
) => {
  return applyDecorators(
    ApiExtraModels(PaginatedDto, model),
    ApiOkResponse({
      schema: {
        allOf: [
          { $ref: getSchemaPath(PaginatedDto) },
          {
            properties: {
              results: {
                type: 'array',
                items: { $ref: getSchemaPath(model) },
              },
            },
          },
        ],
      },
    }),
  );
};
```

> **Hint**`Type<any>` interface and `applyDecorators` function are imported from the `@nestjs/common` package.

To ensure that `SwaggerModule` will generate a definition for our model, we must add it as an extra model, like we did earlier with the `PaginatedDto` in the controller.

With this in place, we can use the custom `@ApiPaginatedResponse()` decorator on our endpoint:

```ts

@ApiPaginatedResponse(CatDto)
async findAll(): Promise<PaginatedDto<CatDto>> {}
```

For client generation tools, this approach poses an ambiguity in how the `PaginatedResponse<TModel>` is being generated for the client. The following snippet is an example of a client generator result for the above `GET /` endpoint.

```typescript

// Angular
findAll(): Observable<{ total: number, limit: number, offset: number, results: CatDto[] }>
```

As you can see, the **Return Type** here is ambiguous. To workaround this issue, you can add a `title` property to the `schema` for `ApiPaginatedResponse`:

```typescript

export const ApiPaginatedResponse = <TModel extends Type<any>>(
  model: TModel,
) => {
  return applyDecorators(
    ApiOkResponse({
      schema: {
        title: `PaginatedResponseOf${model.name}`,
        allOf: [
          // ...
        ],
      },
    }),
  );
};
```

Now the result of the client generator tool will become:

```ts

// Angular
findAll(): Observable<PaginatedResponseOfCatDto>
```

----
url: https://docs.nestjs.com/v10/recipes/cqrs
----

* [CQRS](https://docs.nestjs.com/v10/recipes/cqrs#cqrs)
* [Installation](https://docs.nestjs.com/v10/recipes/cqrs#installation)
* [Commands](https://docs.nestjs.com/v10/recipes/cqrs#commands)
* [Queries](https://docs.nestjs.com/v10/recipes/cqrs#queries)
* [Events](https://docs.nestjs.com/v10/recipes/cqrs#events)
* [Sagas](https://docs.nestjs.com/v10/recipes/cqrs#sagas)
* [Setup](https://docs.nestjs.com/v10/recipes/cqrs#setup)
* [Unhandled exceptions](https://docs.nestjs.com/v10/recipes/cqrs#unhandled-exceptions)
* [Subscribing to all events](https://docs.nestjs.com/v10/recipes/cqrs#subscribing-to-all-events)
* [Example](https://docs.nestjs.com/v10/recipes/cqrs#example)

```bash

$ npm install --save @nestjs/cqrs
```

#### Commands[#](/recipes/cqrs#commands)

Commands are used to change the application state. They should be task-based, rather than data centric. When a command is dispatched, it is handled by a corresponding **Command Handler**. The handler is responsible for updating the application state.

heroes-game.service.ts

JS TS

```typescript

@Injectable()
export class HeroesGameService {
  constructor(private commandBus: CommandBus) {}

  async killDragon(heroId: string, killDragonDto: KillDragonDto) {
    return this.commandBus.execute(
      new KillDragonCommand(heroId, killDragonDto.dragonId)
    );
  }
}
```

```typescript

@Injectable()
@Dependencies(CommandBus)
export class HeroesGameService {
  constructor(commandBus) {
    this.commandBus = commandBus;
  }

  async killDragon(heroId, killDragonDto) {
    return this.commandBus.execute(
      new KillDragonCommand(heroId, killDragonDto.dragonId)
    );
  }
}
```

In the code snippet above, we instantiate the `KillDragonCommand` class and pass it to the `CommandBus`'s `execute()` method. This is the demonstrated command class:

kill-dragon.command.ts

JS TS

```typescript

export class KillDragonCommand {
  constructor(
    public readonly heroId: string,
    public readonly dragonId: string,
  ) {}
}
```

```typescript

export class KillDragonCommand {
  constructor(heroId, dragonId) {
    this.heroId = heroId;
    this.dragonId = dragonId;
  }
}
```

The `CommandBus` represents a **stream** of commands. It is responsible for dispatching commands to the appropriate handlers. The `execute()` method returns a promise, which resolves to the value returned by the handler.

Let's create a handler for the `KillDragonCommand` command.

kill-dragon.handler.ts

JS TS

```typescript

@CommandHandler(KillDragonCommand)
export class KillDragonHandler implements ICommandHandler<KillDragonCommand> {
  constructor(private repository: HeroRepository) {}

  async execute(command: KillDragonCommand) {
    const { heroId, dragonId } = command;
    const hero = this.repository.findOneById(+heroId);

    hero.killEnemy(dragonId);
    await this.repository.persist(hero);
  }
}
```

```typescript

@CommandHandler(KillDragonCommand)
@Dependencies(HeroRepository)
export class KillDragonHandler {
  constructor(repository) {
    this.repository = repository;
  }

  async execute(command) {
    const { heroId, dragonId } = command;
    const hero = this.repository.findOneById(+heroId);

    hero.killEnemy(dragonId);
    await this.repository.persist(hero);
  }
}
```

This handler retrieves the `Hero` entity from the repository, calls the `killEnemy()` method, and then persists the changes. The `KillDragonHandler` class implements the `ICommandHandler` interface, which requires the implementation of the `execute()` method. The `execute()` method receives the command object as an argument.

#### Queries[#](/recipes/cqrs#queries)

Queries are used to retrieve data from the application state. They should be data centric, rather than task-based. When a query is dispatched, it is handled by a corresponding **Query Handler**. The handler is responsible for retrieving the data.

The `QueryBus` follows the same pattern as the `CommandBus`. Query handlers should implement the `IQueryHandler` interface and be annotated with the `@QueryHandler()` decorator.

#### Events[#](/recipes/cqrs#events)

Events are used to notify other parts of the application about changes in the application state. They are dispatched by **models** or directly using the `EventBus`. When an event is dispatched, it is handled by corresponding **Event Handlers**. Handlers can then, for example, update the read model.

For demonstration purposes, let's create an event class:

hero-killed-dragon.event.ts

JS TS

```typescript

export class HeroKilledDragonEvent {
  constructor(
    public readonly heroId: string,
    public readonly dragonId: string,
  ) {}
}
```

```typescript

export class HeroKilledDragonEvent {
  constructor(heroId, dragonId) {
    this.heroId = heroId;
    this.dragonId = dragonId;
  }
}
```

Now while events can be dispatched directly using the `EventBus.publish()` method, we can also dispatch them from the model. Let's update the `Hero` model to dispatch the `HeroKilledDragonEvent` event when the `killEnemy()` method is called.

hero.model.ts

JS TS

```typescript

export class Hero extends AggregateRoot {
  constructor(private id: string) {
    super();
  }

  killEnemy(enemyId: string) {
    // Business logic
    this.apply(new HeroKilledDragonEvent(this.id, enemyId));
  }
}
```

```typescript

export class Hero extends AggregateRoot {
  constructor(id) {
    super();
    this.id = id;
  }

  killEnemy(enemyId) {
    // Business logic
    this.apply(new HeroKilledDragonEvent(this.id, enemyId));
  }
}
```

The `apply()` method is used to dispatch events. It accepts an event object as an argument. However, since our model is not aware of the `EventBus`, we need to associate it with the model. We can do that by using the `EventPublisher` class.

kill-dragon.handler.ts

JS TS

```typescript

@CommandHandler(KillDragonCommand)
export class KillDragonHandler implements ICommandHandler<KillDragonCommand> {
  constructor(
    private repository: HeroRepository,
    private publisher: EventPublisher,
  ) {}

  async execute(command: KillDragonCommand) {
    const { heroId, dragonId } = command;
    const hero = this.publisher.mergeObjectContext(
      await this.repository.findOneById(+heroId),
    );
    hero.killEnemy(dragonId);
    hero.commit();
  }
}
```

```typescript

@CommandHandler(KillDragonCommand)
@Dependencies(HeroRepository, EventPublisher)
export class KillDragonHandler {
  constructor(repository, publisher) {
    this.repository = repository;
    this.publisher = publisher;
  }

  async execute(command) {
    const { heroId, dragonId } = command;
    const hero = this.publisher.mergeObjectContext(
      await this.repository.findOneById(+heroId),
    );
    hero.killEnemy(dragonId);
    hero.commit();
  }
}
```

The `EventPublisher#mergeObjectContext` method merges the event publisher into the provided object, which means that the object will now be able to publish events to the events stream.

Notice that in this example we also call the `commit()` method on the model. This method is used to dispatch any outstanding events. To automatically dispatch events, we can set the `autoCommit` property to `true`:

```typescript

export class Hero extends AggregateRoot {
  constructor(private id: string) {
    super();
    this.autoCommit = true;
  }
}
```

In case we want to merge the event publisher into a non-existing object, but rather into a class, we can use the `EventPublisher#mergeClassContext` method:

```typescript

const HeroModel = this.publisher.mergeClassContext(Hero);
const hero = new HeroModel('id'); // <-- HeroModel is a class
```

Now every instance of the `HeroModel` class will be able to publish events without using `mergeObjectContext()` method.

Additionally, we can emit events manually using `EventBus`:

```typescript

this.eventBus.publish(new HeroKilledDragonEvent());
```

> **Hint** The `EventBus` is an injectable class.

Each event can have multiple **Event Handlers**.

hero-killed-dragon.handler.ts

JS TS

```typescript

@EventsHandler(HeroKilledDragonEvent)
export class HeroKilledDragonHandler implements IEventHandler<HeroKilledDragonEvent> {
  constructor(private repository: HeroRepository) {}

  handle(event: HeroKilledDragonEvent) {
    // Business logic
  }
}
```

> **Hint** Be aware that when you start using event handlers you get out of the traditional HTTP web context.
>
> * Errors in `CommandHandlers` can still be caught by built-in [Exception filters](/v10/exception-filters).
> * Errors in `EventHandlers` can't be caught by Exception filters: you will have to handle them manually. Either by a simple `try/catch`, using [Sagas](/recipes/cqrs#sagas) by triggering a compensating event, or whatever other solution you choose.
> * HTTP Responses in `CommandHandlers` can still be sent back to the client.
> * HTTP Responses in `EventHandlers` cannot. If you want to send information to the client you could use [WebSocket](/v10/websockets/gateways), [SSE](/v10/techniques/server-sent-events), or whatever other solution you choose.

#### Sagas[#](/recipes/cqrs#sagas)

Saga is a long-running process that listens to events and may trigger new commands. It is usually used to manage complex workflows in the application. For example, when a user signs up, a saga may listen to the `UserRegisteredEvent` and send a welcome email to the user.

Sagas are an extremely powerful feature. A single saga may listen for 1..\* events. Using the [RxJS](https://github.com/ReactiveX/rxjs) library, we can filter, map, fork, and merge event streams to create sophisticated workflows. Each saga returns an Observable which produces a command instance. This command is then dispatched **asynchronously** by the `CommandBus`.

Let's create a saga that listens to the `HeroKilledDragonEvent` and dispatches the `DropAncientItemCommand` command.

heroes-game.saga.ts

JS TS

```typescript

@Injectable()
export class HeroesGameSagas {
  @Saga()
  dragonKilled = (events$: Observable<any>): Observable<ICommand> => {
    return events$.pipe(
      ofType(HeroKilledDragonEvent),
      map((event) => new DropAncientItemCommand(event.heroId, fakeItemID)),
    );
  }
}
```

```typescript

@Injectable()
export class HeroesGameSagas {
  @Saga()
  dragonKilled = (events$) => {
    return events$.pipe(
      ofType(HeroKilledDragonEvent),
      map((event) => new DropAncientItemCommand(event.heroId, fakeItemID)),
    );
  }
}
```

> **Hint** The `ofType` operator and the `@Saga()` decorator are exported from the `@nestjs/cqrs` package.

The `@Saga()` decorator marks the method as a saga. The `events$` argument is an Observable stream of all events. The `ofType` operator filters the stream by the specified event type. The `map` operator maps the event to a new command instance.

In this example, we map the `HeroKilledDragonEvent` to the `DropAncientItemCommand` command. The `DropAncientItemCommand` command is then auto-dispatched by the `CommandBus`.

#### Setup[#](/recipes/cqrs#setup)

To wrap up, we need to register all command handlers, event handlers, and sagas in the `HeroesGameModule`:

heroes-game.module.ts

JS TS

```typescript

export const CommandHandlers = [KillDragonHandler, DropAncientItemHandler];
export const EventHandlers =  [HeroKilledDragonHandler, HeroFoundItemHandler];

@Module({
  imports: [CqrsModule],
  controllers: [HeroesGameController],
  providers: [
    HeroesGameService,
    HeroesGameSagas,
    ...CommandHandlers,
    ...EventHandlers,
    HeroRepository,
  ]
})
export class HeroesGameModule {}
```

#### Unhandled exceptions[#](/recipes/cqrs#unhandled-exceptions)

Event handlers are executed in the asynchronous manner. This means they should always handle all exceptions to prevent application from entering the inconsistent state. However, if an exception is not handled, the `EventBus` will create the `UnhandledExceptionInfo` object and push it to the `UnhandledExceptionBus` stream. This stream is an `Observable` which can be used to process unhandled exceptions.

```typescript

private destroy$ = new Subject<void>();

constructor(private unhandledExceptionsBus: UnhandledExceptionBus) {
  this.unhandledExceptionsBus
    .pipe(takeUntil(this.destroy$))
    .subscribe((exceptionInfo) => {
      // Handle exception here
      // e.g. send it to external service, terminate process, or publish a new event
    });
}

onModuleDestroy() {
  this.destroy$.next();
  this.destroy$.complete();
}
```

To filter out exceptions, we can use the `ofType` operator, as follows:

```typescript

this.unhandledExceptionsBus.pipe(takeUntil(this.destroy$), UnhandledExceptionBus.ofType(TransactionNotAllowedException)).subscribe((exceptionInfo) => {
  // Handle exception here
});
```

Where `TransactionNotAllowedException` is the exception we want to filter out.

The `UnhandledExceptionInfo` object contains the following properties:

```typescript

export interface UnhandledExceptionInfo<Cause = IEvent | ICommand, Exception = any> {
  /**
   * The exception that was thrown.
   */
  exception: Exception;
  /**
   * The cause of the exception (event or command reference).
   */
  cause: Cause;
}
```

#### Subscribing to all events[#](/recipes/cqrs#subscribing-to-all-events)

`CommandBus`, `QueryBus` and `EventBus` are all **Observables**. This means that we can subscribe to the entire stream and, for example, process all events. For example, we can log all events to the console, or save them to the event store.

```typescript

private destroy$ = new Subject<void>();

constructor(private eventBus: EventBus) {
  this.eventBus
    .pipe(takeUntil(this.destroy$))
    .subscribe((event) => {
      // Save events to database
    });
}

onModuleDestroy() {
  this.destroy$.next();
  this.destroy$.complete();
}
```

#### Example[#](/recipes/cqrs#example)

A working example is available [here](https://github.com/kamilmysliwiec/nest-cqrs-example).

----
url: https://docs.nestjs.com/v10/recipes/necord
----

* [Necord](https://docs.nestjs.com/v10/recipes/necord#necord)
* [Installation](https://docs.nestjs.com/v10/recipes/necord#installation)
* [Usage](https://docs.nestjs.com/v10/recipes/necord#usage)
* [Text commands](https://docs.nestjs.com/v10/recipes/necord#text-commands)
* [Application commands](https://docs.nestjs.com/v10/recipes/necord#application-commands)
* [Slash commands](https://docs.nestjs.com/v10/recipes/necord#slash-commands)
* [User context menu](https://docs.nestjs.com/v10/recipes/necord#user-context-menu)
* [Message context menu](https://docs.nestjs.com/v10/recipes/necord#message-context-menu)
* [Buttons](https://docs.nestjs.com/v10/recipes/necord#buttons)
* [Select menus](https://docs.nestjs.com/v10/recipes/necord#select-menus)
* [Modals](https://docs.nestjs.com/v10/recipes/necord#modals)
* [More information](https://docs.nestjs.com/v10/recipes/necord#more-information)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/recipes/necord.md "Suggest Edits")

### Necord

Necord is a powerful module that simplifies the creation of [Discord](https://discord.com) bots, allowing for seamless integration with your NestJS application.

> **Note** Necord is a third-party package and is not officially maintained by the NestJS core team. If you encounter any issues, please report them in the [official repository](https://github.com/necordjs/necord).

#### Installation[#](/recipes/necord#installation)

To get started, you need to install Necord alongside its dependency, [`Discord.js`](https://discord.js.org).

```bash

$ npm install necord discord.js
```

#### Usage[#](/recipes/necord#usage)

To utilize Necord in your project, import the `NecordModule` and configure it with the necessary options.

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { NecordModule } from 'necord';
import { IntentsBitField } from 'discord.js';
import { AppService } from './app.service';

@Module({
  imports: [
    NecordModule.forRoot({
      token: process.env.DISCORD_TOKEN,
      intents: [IntentsBitField.Guilds],
      development: [process.env.DISCORD_DEVELOPMENT_GUILD_ID],
    }),
  ],
  providers: [AppService],
})
export class AppModule {}
```

> **Hint** You can find a comprehensive list of available intents [here](https://discord.com/developers/docs/topics/gateway#gateway-intents).

With this setup, you can inject the `AppService` into your providers to easily register commands, events, and more.

app.service.ts

JS TS

```typescript

import { Injectable, Logger } from '@nestjs/common';
import { Context, On, Once, ContextOf } from 'necord';
import { Client } from 'discord.js';

@Injectable()
export class AppService {
  private readonly logger = new Logger(AppService.name);

  @Once('ready')
  public onReady(@Context() [client]: ContextOf<'ready'>) {
    this.logger.log(`Bot logged in as ${client.user.username}`);
  }

  @On('warn')
  public onWarn(@Context() [message]: ContextOf<'warn'>) {
    this.logger.warn(message);
  }
}
```

##### Understanding context

You may have noticed the `@Context` decorator in the examples above. This decorator injects the event context into your method, allowing you to access various event-specific data. Since there are multiple types of events, the context type is inferred using the `ContextOf<type: string>` type. You can easily access context variables by using the `@Context()` decorator, which fills the variable with an array of arguments relevant to the event.

#### Text commands[#](/recipes/necord#text-commands)

> **Caution** Text commands rely on message content, which is set to be deprecated for verified bots and applications with over 100 servers. This means that if your bot is unable to access message content, text commands will not function. Read more about this change [here](https://support-dev.discord.com/hc/en-us/articles/4404772028055-Message-Content-Access-Deprecation-for-Verified-Bots).

Here's how to create a simple command handler for messages using the `@TextCommand` decorator.

app.commands.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { Context, TextCommand, TextCommandContext, Arguments } from 'necord';

@Injectable()
export class AppCommands {
  @TextCommand({
    name: 'ping',
    description: 'Responds with pong!',
  })
  public onPing(
    @Context() [message]: TextCommandContext,
    @Arguments() args: string[],
  ) {
    return message.reply('pong!');
  }
}
```

```typescript

import { Injectable } from '@nestjs/common';
import { Context, SlashCommand, SlashCommandContext } from 'necord';

@Injectable()
export class AppCommands {
  @SlashCommand({
    name: 'ping',
    description: 'Responds with pong!',
  })
  public async onPing(@Context() [interaction]: SlashCommandContext) {
    return interaction.reply({ content: 'Pong!' });
  }
}
```

> **Hint** When your bot client logs in, it will automatically register all defined commands. Note that global commands are cached for up to an hour. To avoid issues with the global cache, utilize the `development` argument in the Necord module, which restricts command visibility to a single guild.

##### Options

You can define parameters for your slash commands using option decorators. Let's create a `TextDto` class for this purpose:

text.dto.ts

JS TS

```typescript

import { StringOption } from 'necord';

export class TextDto {
  @StringOption({
    name: 'text',
    description: 'Input your text here',
    required: true,
  })
  text: string;
}
```

You can then use this DTO in the `AppCommands` class:

app.commands.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { Context, SlashCommand, Options, SlashCommandContext } from 'necord';
import { TextDto } from './length.dto';

@Injectable()
export class AppCommands {
  @SlashCommand({
    name: 'length',
    description: 'Calculate the length of your text',
  })
  public async onLength(
    @Context() [interaction]: SlashCommandContext,
    @Options() { text }: TextDto,
  ) {
    return interaction.reply({
      content: `The length of your text is: ${text.length}`,
    });
  }
}
```

For a complete list of built-in option decorators, check out [this documentation](https://necord.org/interactions/slash-commands#options).

##### Autocomplete

To implement autocomplete functionality for your slash commands, you'll need to create an interceptor. This interceptor will handle requests as users type in the autocomplete field.

cats-autocomplete.interceptor.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { AutocompleteInteraction } from 'discord.js';
import { AutocompleteInterceptor } from 'necord';

@Injectable()
class CatsAutocompleteInterceptor extends AutocompleteInterceptor {
  public transformOptions(interaction: AutocompleteInteraction) {
    const focused = interaction.options.getFocused(true);
    let choices: string[];

    if (focused.name === 'cat') {
      choices = ['Siamese', 'Persian', 'Maine Coon'];
    }

    return interaction.respond(
      choices
        .filter((choice) => choice.startsWith(focused.value.toString()))
        .map((choice) => ({ name: choice, value: choice })),
    );
  }
}
```

You will also need to mark your options class with `autocomplete: true`:

cat.dto.ts

JS TS

```typescript

import { StringOption } from 'necord';

export class CatDto {
  @StringOption({
    name: 'cat',
    description: 'Choose a cat breed',
    autocomplete: true,
    required: true,
  })
  cat: string;
}
```

Finally, apply the interceptor to your slash command:

cats.commands.ts

JS TS

```typescript

import { Injectable, UseInterceptors } from '@nestjs/common';
import { Context, SlashCommand, Options, SlashCommandContext } from 'necord';
import { CatDto } from '/cat.dto';
import { CatsAutocompleteInterceptor } from './cats-autocomplete.interceptor';

@Injectable()
export class CatsCommands {
  @UseInterceptors(CatsAutocompleteInterceptor)
  @SlashCommand({
    name: 'cat',
    description: 'Retrieve information about a specific cat breed',
  })
  public async onSearch(
    @Context() [interaction]: SlashCommandContext,
    @Options() { cat }: CatDto,
  ) {
    return interaction.reply({
      content: `I found information on the breed of ${cat} cat!`,
    });
  }
}
```

#### User context menu[#](/recipes/necord#user-context-menu)

User commands appear on the context menu that appears when right-clicking (or tapping) on users. These commands provide quick actions that target users directly.

app.commands.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { Context, UserCommand, UserCommandContext, TargetUser } from 'necord';
import { User } from 'discord.js';

@Injectable()
export class AppCommands {
  @UserCommand({ name: 'Get avatar' })
  public async getUserAvatar(
    @Context() [interaction]: UserCommandContext,
    @TargetUser() user: User,
  ) {
    return interaction.reply({
      embeds: [
        new MessageEmbed()
          .setTitle(`Avatar of ${user.username}`)
          .setImage(user.displayAvatarURL({ size: 4096, dynamic: true })),
      ],
    });
  }
}
```

#### Message context menu[#](/recipes/necord#message-context-menu)

Message commands show up in the context menu when right-clicking on messages, allowing for quick actions relevant to those messages.

app.commands.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { Context, MessageCommand, MessageCommandContext, TargetMessage } from 'necord';
import { Message } from 'discord.js';

@Injectable()
export class AppCommands {
  @MessageCommand({ name: 'Copy Message' })
  public async copyMessage(
    @Context() [interaction]: MessageCommandContext,
    @TargetMessage() message: Message,
  ) {
    return interaction.reply({ content: message.content });
  }
}
```

#### Buttons[#](/recipes/necord#buttons)

[Buttons](https://discord.com/developers/docs/interactions/message-components#buttons) are interactive elements that can be included in messages. When clicked, they send an [interaction](https://discord.com/developers/docs/interactions/receiving-and-responding#interaction-object) to your application.

app.components.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { Context, Button, ButtonContext } from 'necord';

@Injectable()
export class AppComponents {
  @Button('BUTTON')
  public onButtonClick(@Context() [interaction]: ButtonContext) {
    return interaction.reply({ content: 'Button clicked!' });
  }
}
```

#### Select menus[#](/recipes/necord#select-menus)

[Select menus](https://discord.com/developers/docs/interactions/message-components#select-menus) are another type of interactive component that appears on messages. They provide a dropdown-like UI for users to select options.

app.components.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { Context, StringSelect, StringSelectContext, SelectedStrings } from 'necord';

@Injectable()
export class AppComponents {
  @StringSelect('SELECT_MENU')
  public onSelectMenu(
    @Context() [interaction]: StringSelectContext,
    @SelectedStrings() values: string[],
  ) {
    return interaction.reply({ content: `You selected: ${values.join(', ')}` });
  }
}
```

For a full list of built-in select menu components, visit [this link](https://necord.org/interactions/message-components#select-menu).

#### Modals[#](/recipes/necord#modals)

Modals are pop-up forms that allow users to submit formatted input. Here's how to create and handle modals using Necord:

app.modals.ts

JS TS

```typescript

import { Injectable } from '@nestjs/common';
import { Context, Modal, ModalContext } from 'necord';

@Injectable()
export class AppModals {
  @Modal('pizza')
  public onModal(@Context() [interaction]: ModalContext) {
    return interaction.reply({
      content: `Your fav pizza : ${interaction.fields.getTextInputValue('pizza')}`
    });
  }
}
```

#### More information[#](/recipes/necord#more-information)

Visit the [Necord](https://necord.org) website for more information.

----
url: https://docs.nestjs.com/v9
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Introduction](https://docs.nestjs.com/v9/#introduction)
* [Philosophy](https://docs.nestjs.com/v9/#philosophy)
* [Installation](https://docs.nestjs.com/v9/#installation)
* [Alternatives](https://docs.nestjs.com/v9/#alternatives)

To get started, you can either scaffold the project with the [Nest CLI](/v9/cli/overview), or clone a starter project (both will produce the same outcome).

To scaffold the project with the Nest CLI, run the following commands. This will create a new project directory, and populate the directory with the initial core Nest files and supporting modules, creating a conventional base structure for your project. Creating a new project with the **Nest CLI** is recommended for first-time users. We'll continue with this approach in [First Steps](/v9/first-steps).

```bash

$ npm i -g @nestjs/cli
$ nest new project-name
```

> **Hint** To create a new TypeScript project with stricter feature set, pass the `--strict` flag to the `nest new` command.

#### Alternatives[#](/#alternatives)

Alternatively, to install the TypeScript starter project with **Git**:

```bash

$ git clone https://github.com/nestjs/typescript-starter.git project
$ cd project
$ npm install
$ npm run start
```

> **Hint** If you'd like to clone the repository without the git history, you can use [degit](https://github.com/Rich-Harris/degit).

Open your browser and navigate to [`http://localhost:3000/`](http://localhost:3000/).

To install the JavaScript flavor of the starter project, use `javascript-starter.git` in the command sequence above.

You can also manually create a new project from scratch by installing the core and supporting files with **npm** (or **yarn**). In this case, of course, you'll be responsible for creating the project boilerplate files yourself.

```bash

$ npm i --save @nestjs/core @nestjs/common rxjs reflect-metadata
```

----
url: https://docs.nestjs.com/v7/faq/common-errors
----

* [Common errors](https://docs.nestjs.com/v7/faq/common-errors#common-errors)
* ["Cannot resolve dependency" error](https://docs.nestjs.com/v7/faq/common-errors#cannot-resolve-dependency-error)
* ["Circular dependency" error](https://docs.nestjs.com/v7/faq/common-errors#circular-dependency-error)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/faq/errors.md "Suggest Edits")

### Common errors

During your development with NestJS, you may encounter various errors as you learn the framework.

#### "Cannot resolve dependency" error[#](/faq/common-errors#cannot-resolve-dependency-error)

Probably the most common error message is about Nest not being able to resolve dependencies of a provider. The error message usually looks something like this:

```bash

Nest can't resolve dependencies of the <provider> (?). Please make sure that the argument <unknown_token> at index [<index>] is available in the <module> context.

Potential solutions:
- If <unknown_token> is a provider, is it part of the current <module>?
- If <unknown_token> is exported from a separate @Module, is that module imported within <module>?
  @Module({
    imports: [ /* the Module containing <unknown_token> */ ]
  })
```

The most common culprit of the error, is not having the `provider` in the module's `providers` array. Please make sure that the provider is indeed in the `providers` array and following [standard NestJS provider practices](/fundamentals/custom-providers#di-fundamentals).

There are a few gotchas, that are common. One is putting a provider in an `imports` array. If this is the case, the error will have the provider's name where `<module>` should be.

If you run across this error while developing, take a look at the module mentioned in the error message and look at its `providers`. For each provider in the `providers` array, make sure the module has access to all of the dependencies. Often times, `providers` are duplicated in a "Feature Module" and a "Root Module" which means Nest will try to instantiate the provider twice. More than likely, the module containing the `provider` being duplicated should be added in the "Root Module"'s `imports` array instead.

#### "Circular dependency" error[#](/faq/common-errors#circular-dependency-error)

Occasionally you'll find it difficult to avoid [circular dependencies](/v7/fundamentals/circular-dependency) in your application. You'll need to take some steps to help Nest resolve these. Errors that arise from circular dependencies look like this:

```bash

Nest cannot create the <module> instance.
The module at index [<index>] of the <module> "imports" array is undefined.

Potential causes:
- A circular dependency between modules. Use forwardRef() to avoid it. Read more: https://docs.nestjs.com/fundamentals/circular-dependency
- The module at index [<index>] is of type "undefined". Check your import statements and the type of the module.

Scope [<module_import_chain>]
# example chain AppModule -> FooModule
```

Circular dependencies can arise from both providers depending on each other, or typescript files depending on each other for constants, such as exporting constants from a module file and importing them in a service file. In the latter case, it is advised to create a separate file for your constants. In the former case, please follow the guide on circular dependencies and make sure that both the modules **and** the providers are marked with `forwardRef`.

----
url: https://docs.nestjs.com/v11/recipes/mikroorm
----

* [MikroORM](https://docs.nestjs.com/v11/recipes/mikroorm#mikroorm)
* [Installation](https://docs.nestjs.com/v11/recipes/mikroorm#installation)
* [Repositories](https://docs.nestjs.com/v11/recipes/mikroorm#repositories)
* [Using custom repositories](https://docs.nestjs.com/v11/recipes/mikroorm#using-custom-repositories)
* [Load entities automatically](https://docs.nestjs.com/v11/recipes/mikroorm#load-entities-automatically)
* [Serialization](https://docs.nestjs.com/v11/recipes/mikroorm#serialization)
* [Request scoped handlers in queues](https://docs.nestjs.com/v11/recipes/mikroorm#request-scoped-handlers-in-queues)
* [Testing](https://docs.nestjs.com/v11/recipes/mikroorm#testing)
* [Example](https://docs.nestjs.com/v11/recipes/mikroorm#example)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/recipes/mikroorm.md "Suggest Edits")

### MikroORM

This recipe is here to help users get started with MikroORM in Nest. MikroORM is the TypeScript ORM for Node.js based on Data Mapper, Unit of Work and Identity Map patterns. It is a great alternative to TypeORM and migration from TypeORM should be fairly easy. The complete documentation on MikroORM can be found [here](https://mikro-orm.io/docs).

> **info**`@mikro-orm/nestjs` is a third party package and is not managed by the NestJS core team. Please report any issues found with the library in the [appropriate repository](https://github.com/mikro-orm/nestjs).

#### Installation[#](/recipes/mikroorm#installation)

Easiest way to integrate MikroORM to Nest is via [`@mikro-orm/nestjs` module](https://github.com/mikro-orm/nestjs). Simply install it next to Nest, MikroORM and underlying driver:

```bash

$ npm i @mikro-orm/core @mikro-orm/nestjs @mikro-orm/sqlite
```

MikroORM also supports `postgres`, `sqlite`, and `mongo`. See the [official docs](https://mikro-orm.io/docs/usage-with-sql/) for all drivers.

Once the installation process is completed, we can import the `MikroOrmModule` into the root `AppModule`.

```typescript

import { SqliteDriver } from '@mikro-orm/sqlite';

@Module({
  imports: [
    MikroOrmModule.forRoot({
      entities: ['./dist/entities'],
      entitiesTs: ['./src/entities'],
      dbName: 'my-db-name.sqlite3',
      driver: SqliteDriver,
    }),
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}
```

The `forRoot()` method accepts the same configuration object as `init()` from the MikroORM package. Check [this page](https://mikro-orm.io/docs/configuration) for the complete configuration documentation.

Alternatively we can [configure the CLI](https://mikro-orm.io/docs/installation#setting-up-the-commandline-tool) by creating a configuration file `mikro-orm.config.ts` and then call the `forRoot()` without any arguments.

```typescript

@Module({
  imports: [
    MikroOrmModule.forRoot(),
  ],
  ...
})
export class AppModule {}
```

But this won't work when you use a build tools that use tree shaking, for that it is better to provide the config explicitly:

```typescript

import config from './mikro-orm.config'; // your ORM config

@Module({
  imports: [
    MikroOrmModule.forRoot(config),
  ],
  ...
})
export class AppModule {}
```

Afterward, the `EntityManager` will be available to inject across the entire project (without importing any module elsewhere).

```ts

// Import everything from your driver package or `@mikro-orm/knex`
import { EntityManager, MikroORM } from '@mikro-orm/sqlite';

@Injectable()
export class MyService {
  constructor(
    private readonly orm: MikroORM,
    private readonly em: EntityManager,
  ) {}
}
```

> **info** Notice that the `EntityManager` is imported from the `@mikro-orm/driver` package, where driver is `mysql`, `sqlite`, `postgres` or what driver you are using. In case you have `@mikro-orm/knex` installed as a dependency, you can also import the `EntityManager` from there.

#### Repositories[#](/recipes/mikroorm#repositories)

MikroORM supports the repository design pattern. For every entity, we can create a repository. Read the complete documentation on repositories [here](https://mikro-orm.io/docs/repositories). To define which repositories should be registered in the current scope you can use the `forFeature()` method. For example, in this way:

> **info** You should **not** register your base entities via `forFeature()`, as there are no repositories for those. On the other hand, base entities need to be part of the list in `forRoot()` (or in the ORM config in general).

```typescript

// photo.module.ts
@Module({
  imports: [MikroOrmModule.forFeature([Photo])],
  providers: [PhotoService],
  controllers: [PhotoController],
})
export class PhotoModule {}
```

and import it into the root `AppModule`:

```typescript

// app.module.ts
@Module({
  imports: [MikroOrmModule.forRoot(...), PhotoModule],
})
export class AppModule {}
```

In this way we can inject the `PhotoRepository` to the `PhotoService` using the `@InjectRepository()` decorator:

```typescript

@Injectable()
export class PhotoService {
  constructor(
    @InjectRepository(Photo)
    private readonly photoRepository: EntityRepository<Photo>,
  ) {}
}
```

#### Using custom repositories[#](/recipes/mikroorm#using-custom-repositories)

When using custom repositories, we no longer need the `@InjectRepository()` decorator, as Nest DI resolved based on the class references.

```ts

// `**./author.entity.ts**`
@Entity({ repository: () => AuthorRepository })
export class Author {
  // to allow inference in `em.getRepository()`
  [EntityRepositoryType]?: AuthorRepository;
}

// `**./author.repository.ts**`
export class AuthorRepository extends EntityRepository<Author> {
  // your custom methods...
}
```

As the custom repository name is the same as what `getRepositoryToken()` would return, we do not need the `@InjectRepository()` decorator anymore:

```ts

@Injectable()
export class MyService {
  constructor(private readonly repo: AuthorRepository) {}
}
```

#### Load entities automatically[#](/recipes/mikroorm#load-entities-automatically)

Manually adding entities to the entities array of the connection options can be tedious. In addition, referencing entities from the root module breaks application domain boundaries and causes leaking implementation details to other parts of the application. To solve this issue, static glob paths can be used.

Note, however, that glob paths are not supported by webpack, so if you are building your application within a monorepo, you won't be able to use them. To address this issue, an alternative solution is provided. To automatically load entities, set the `autoLoadEntities` property of the configuration object (passed into the `forRoot()` method) to `true`, as shown below:

```ts

@Module({
  imports: [
    MikroOrmModule.forRoot({
      ...
      autoLoadEntities: true,
    }),
  ],
})
export class AppModule {}
```

With that option specified, every entity registered through the `forFeature()` method will be automatically added to the entities array of the configuration object.

> **info** Note that entities that aren't registered through the `forFeature()` method, but are only referenced from the entity (via a relationship), won't be included by way of the `autoLoadEntities` setting.

> **info** Using `autoLoadEntities` also has no effect on the MikroORM CLI - for that we still need CLI config with the full list of entities. On the other hand, we can use globs there, as the CLI won't go thru webpack.

#### Serialization[#](/recipes/mikroorm#serialization)

> **Note** MikroORM wraps every single entity relation in a `Reference<T>` or a `Collection<T>` object, in order to provide better type-safety. This will make [Nest's built-in serializer](/techniques/serialization) blind to any wrapped relations. In other words, if you return MikroORM entities from your HTTP or WebSocket handlers, all of their relations will NOT be serialized.

Luckily, MikroORM provides a [serialization API](https://mikro-orm.io/docs/serializing) which can be used in lieu of `ClassSerializerInterceptor`.

```typescript

@Entity()
export class Book {
  @Property({ hidden: true }) // Equivalent of class-transformer's `@Exclude`
  hiddenField = Date.now();

  @Property({ persist: false }) // Similar to class-transformer's `@Expose()`. Will only exist in memory, and will be serialized.
  count?: number;

  @ManyToOne({
    serializer: (value) => value.name,
    serializedName: 'authorName',
  }) // Equivalent of class-transformer's `@Transform()`
  author: Author;
}
```

#### Request scoped handlers in queues[#](/recipes/mikroorm#request-scoped-handlers-in-queues)

As mentioned in the [docs](https://mikro-orm.io/docs/identity-map), we need a clean state for each request. That is handled automatically thanks to the `RequestContext` helper registered via middleware.

But middlewares are executed only for regular HTTP request handles, what if we need a request scoped method outside of that? One example of that is queue handlers or scheduled tasks.

We can use the `@CreateRequestContext()` decorator. It requires you to first inject the `MikroORM` instance to current context, it will be then used to create the context for you. Under the hood, the decorator will register new request context for your method and execute it inside the context.

```ts

@Injectable()
export class MyService {
  constructor(private readonly orm: MikroORM) {}

  @CreateRequestContext()
  async doSomething() {
    // this will be executed in a separate context
  }
}
```

> **Note** As the name suggests, this decorator always creates new context, as opposed to its alternative `@EnsureRequestContext` that only creates it if it's already not inside another one.

#### Testing[#](/recipes/mikroorm#testing)

The `@mikro-orm/nestjs` package exposes `getRepositoryToken()` function that returns prepared token based on a given entity to allow mocking the repository.

```typescript

@Module({
  providers: [
    PhotoService,
    {
      // or when you have a custom repository: `provide: PhotoRepository`
      provide: getRepositoryToken(Photo),
      useValue: mockedRepository,
    },
  ],
})
export class PhotoModule {}
```

#### Example[#](/recipes/mikroorm#example)

A real world example of NestJS with MikroORM can be found [here](https://github.com/mikro-orm/nestjs-realworld-example-app)

----
url: https://docs.nestjs.com/v9/recipes/automock
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Automock](https://docs.nestjs.com/v9/recipes/automock#automock)
* [Introduction](https://docs.nestjs.com/v9/recipes/automock#introduction)
* [Installation](https://docs.nestjs.com/v9/recipes/automock#installation)
* [Example](https://docs.nestjs.com/v9/recipes/automock#example)
* [About unit and unitRef](https://docs.nestjs.com/v9/recipes/automock#about-unit-and-unitref)
* [Working with different providers](https://docs.nestjs.com/v9/recipes/automock#working-with-different-providers)
* [More Information](https://docs.nestjs.com/v9/recipes/automock#more-information)

[**](https://github.com/nestjs/docs.nestjs.com/edit/master/content/recipes/automock.md "Suggest Edits")

### Automock

Automock is a standalone library for unit testing. Using TypeScript Reflection API (`reflect-metadata`) internally to produce mock objects, Automock streamlines test development by automatically mocking class external dependencies.

> **info**`Automock` is a third party package and is not managed by the NestJS core team. Please, report any issues found with the library in the [appropriate repository](https://github.com/omermorad/automock)

#### Introduction[#](/recipes/automock#introduction)

The dependency injection (DI) container is an essential component of the Nest module system. This container is utilized both during testing, and the application execution. Unit tests vary from other types of tests, such as integration tests, in that they must fully override providers/services within the DI container. External class dependencies (providers) of the so-called "unit", have to be totally isolated. That is, all dependencies within the DI container should be replaced by mock objects. As a result, loading the target module and replacing the providers inside it is a process that loops back on itself. Automock tackles this issue by automatically mocking all the class external providers, resulting in total isolation of the unit under test.

#### Installation[#](/recipes/automock#installation)

```bash

$ npm i -D @automock/jest
```

Automock does not require any additional setup.

> **info** Jest is the only test framework currently supported by Automock. Sinon will shortly be released.

#### Example[#](/recipes/automock#example)

Consider the following cats service, which takes three constructor parameters:

cats.service.ts

JS TS

```ts

import { Injectable } from '@nestjs/core';

@Injectable()
export class CatsService {
  constructor(
    private logger: Logger,
    private httpService: HttpService,
    private catsDal: CatsDal,
  ) {}

  async getAllCats() {
    const cats = await this.httpService.get('http://localhost:3000/api/cats');
    this.logger.log('Successfully fetched all cats');
    
    this.catsDal.saveCats(cats);
  }
}
```

The service contains one public method, `getAllCats`, which is the method we use an example for the following unit test:

cats.service.spec.ts

JS TS

```ts

import { TestBed } from '@automock/jest';
import { CatsService } from './cats.service';

describe('CatsService unit spec', () => {
  let underTest: CatsService;
  let logger: jest.Mocked<Logger>;
  let httpService: jest.Mocked<HttpService>;
  let catsDal: jest.Mocked<CatsDal>;
  
  beforeAll(() => {
    const { unit, unitRef } = TestBed.create(CatsService)
      .mock(HttpService)
      .using({ get: jest.fn() })
      .mock(Logger)
      .using({ log: jest.fn() })
      .mock(CatsDal)
      .using({ saveCats: jest.fn() })
      .compile();

    underTest = unit;

    logger = unitRef.get(Logger);
    httpService = unitRef.get(HttpService);
    catsDal = unitRef.get(CatsDal);
  });

  describe('when getting all the cats', () => {
    test('then meet some expectations', async () => {
      httpService.get.mockResolvedValueOnce([{ id: 1, name: 'Catty' }]);
      await catsService.getAllCats();

      expect(logger.log).toBeCalled();
      expect(catsDal).toBeCalledWith([{ id: 1, name: 'Catty' }]);
    });
  });
});
```

> **info** The jest.Mocked utility type returns the Source type wrapped with type definitions of Jest mock function. ([reference](https://jestjs.io/docs/mock-function-api/#jestmockedsource))

#### About `unit` and `unitRef`[#](/recipes/automock#about-unit-and-unitref)

Let's examine the following code:

```typescript

const { unit, unitRef } = TestBed.create(CatsService).compile();
```

Calling `.compile()` returns an object with two properties, `unit`, and `unitRef`.

**`unit`** is the unit under test, it is an actual instance of class being tested.

**`unitRef`** is the "unit reference", where the mocked dependencies of the tested class are stored, in a small container. The container's `.get()` method returns the mocked dependency with all of its methods automatically stubbed (using `jest.fn()`):

```typescript

const { unit, unitRef } = TestBed.create(CatsService).compile();

let httpServiceMock: jest.Mocked<HttpService> = unitRef.get(HttpService);
```

> **info** The `.get()` method can accept either a `string` or an actual class (`Type`) as its argument. This essentially depends on how the provider is being injected to the class under test.

#### Working with different providers[#](/recipes/automock#working-with-different-providers)

Providers are one of the most important elements in Nest. You can think of many of the default Nest classes as providers, including services, repositories, factories, helpers, and so on. A provider's primary function is to take the form of an `Injectable` dependency.

Consider the following `CatsService`, it takes one parameter, which is an instance of the following `Logger` interface:

```typescript

export interface Logger {
  log(message: string): void;
}

export class CatsService {
  constructor(private logger: Logger) {}
}
```

TypeScript's Reflection API does not support interface reflection yet. Nest solves this issue with string-based injection tokens (see [Custom Providers](https://docs.nestjs.com/fundamentals/custom-providers)):

```typescript

export const MyLoggerProvider = {
  provide: 'MY_LOGGER_TOKEN',
  useValue: { ... },
}

export class CatsService {
  constructor(@Inject('MY_LOGGER_TOKEN') private readonly logger: Logger) {}
}
```

Automock follows this practice and lets you provide a string-based token instead of providing the actual class in the `unitRef.get()` method:

```typescript

const { unit, unitRef } = TestBed.create(CatsService).compile();

let loggerMock: jest.Mocked<Logger> = unitRef.get('MY_LOGGER_TOKEN');
```

#### More Information[#](/recipes/automock#more-information)

Visit [Automock GitHub repository](https://github.com/omermorad/automock) for more information.

----
url: https://docs.nestjs.com/v8/techniques/mongodb
----

[STOP WAR IN UKRAINE 🇺🇦](https://supportukrainenow.org/)

* [Mongo](https://docs.nestjs.com/v8/techniques/mongodb#mongo)
* [Model injection](https://docs.nestjs.com/v8/techniques/mongodb#model-injection)
* [Connection](https://docs.nestjs.com/v8/techniques/mongodb#connection)
* [Multiple databases](https://docs.nestjs.com/v8/techniques/mongodb#multiple-databases)
* [Hooks (middleware)](https://docs.nestjs.com/v8/techniques/mongodb#hooks-middleware)
* [Plugins](https://docs.nestjs.com/v8/techniques/mongodb#plugins)
* [Discriminators](https://docs.nestjs.com/v8/techniques/mongodb#discriminators)
* [Testing](https://docs.nestjs.com/v8/techniques/mongodb#testing)
* [Async configuration](https://docs.nestjs.com/v8/techniques/mongodb#async-configuration)
* [Example](https://docs.nestjs.com/v8/techniques/mongodb#example)

[](https://github.com/nestjs/docs.nestjs.com/edit/master/content/techniques/mongo.md "Suggest Edits")

### Mongo

Nest supports two methods for integrating with the [MongoDB](https://www.mongodb.com/) database. You can either use the built-in [TypeORM](https://github.com/typeorm/typeorm) module described [here](/v8/techniques/database), which has a connector for MongoDB, or use [Mongoose](https://mongoosejs.com), the most popular MongoDB object modeling tool. In this chapter we'll describe the latter, using the dedicated `@nestjs/mongoose` package.

Start by installing the [required dependencies](https://github.com/Automattic/mongoose):

```bash

$ npm install --save @nestjs/mongoose mongoose
```

Once the installation process is complete, we can import the `MongooseModule` into the root `AppModule`.

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';

@Module({
  imports: [MongooseModule.forRoot('mongodb://localhost/nest')],
})
export class AppModule {}
```

```typescript

import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
import { Document } from 'mongoose';

export type CatDocument = Cat & Document;

@Schema()
export class Cat {
  @Prop()
  name: string;

  @Prop()
  age: number;

  @Prop()
  breed: string;
}

export const CatSchema = SchemaFactory.createForClass(Cat);
```

> **Hint** Note you can also generate a raw schema definition using the `DefinitionsFactory` class (from the `nestjs/mongoose`). This allows you to manually modify the schema definition generated based on the metadata you provided. This is useful for certain edge-cases where it may be hard to represent everything with decorators.

The `@Schema()` decorator marks a class as a schema definition. It maps our `Cat` class to a MongoDB collection of the same name, but with an additional “s” at the end - so the final mongo collection name will be `cats`. This decorator accepts a single optional argument which is a schema options object. Think of it as the object you would normally pass as a second argument of the `mongoose.Schema` class' constructor (e.g., `new mongoose.Schema(_, options)`)). To learn more about available schema options, see [this](https://mongoosejs.com/docs/guide.html#options) chapter.

The `@Prop()` decorator defines a property in the document. For example, in the schema definition above, we defined three properties: `name`, `age`, and `breed`. The [schema types](https://mongoosejs.com/docs/schematypes.html) for these properties are automatically inferred thanks to TypeScript metadata (and reflection) capabilities. However, in more complex scenarios in which types cannot be implicitly reflected (for example, arrays or nested object structures), types must be indicated explicitly, as follows:

```typescript

@Prop([String])
tags: string[];
```

Alternatively, the `@Prop()` decorator accepts an options object argument ([read more](https://mongoosejs.com/docs/schematypes.html#schematype-options) about the available options). With this, you can indicate whether a property is required or not, specify a default value, or mark it as immutable. For example:

```typescript

@Prop({ required: true })
name: string;
```

In case you want to specify relation to another model, later for populating, you can use `@Prop()` decorator as well. For example, if `Cat` has `Owner` which is stored in a different collection called `owners`, the property should have type and ref. For example:

```typescript

import * as mongoose from 'mongoose';
import { Owner } from '../owners/schemas/owner.schema';

// inside the class definition
@Prop({ type: mongoose.Schema.Types.ObjectId, ref: 'Owner' })
owner: Owner;
```

In case there are multiple owners, your property configuration should look as follows:

```typescript

@Prop({ type: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Owner' }] })
owner: Owner[];
```

Finally, the **raw** schema definition can also be passed to the decorator. This is useful when, for example, a property represents a nested object which is not defined as a class. For this, use the `raw()` function from the `@nestjs/mongoose` package, as follows:

```typescript

@Prop(raw({
  firstName: { type: String },
  lastName: { type: String }
}))
details: Record<string, any>;
```

Alternatively, if you prefer **not using decorators**, you can define a schema manually. For example:

```typescript

export const CatSchema = new mongoose.Schema({
  name: String,
  age: Number,
  breed: String,
});
```

The `cat.schema` file resides in a folder in the `cats` directory, where we also define the `CatsModule`. While you can store schema files wherever you prefer, we recommend storing them near their related **domain** objects, in the appropriate module directory.

Let's look at the `CatsModule`:

cats.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';
import { Cat, CatSchema } from './schemas/cat.schema';

@Module({
  imports: [MongooseModule.forFeature([{ name: Cat.name, schema: CatSchema }])],
  controllers: [CatsController],
  providers: [CatsService],
})
export class CatsModule {}
```

The `MongooseModule` provides the `forFeature()` method to configure the module, including defining which models should be registered in the current scope. If you also want to use the models in another module, add MongooseModule to the `exports` section of `CatsModule` and import `CatsModule` in the other module.

Once you've registered the schema, you can inject a `Cat` model into the `CatsService` using the `@InjectModel()` decorator:

cats.service.ts

JS TS

```typescript

import { Model } from 'mongoose';
import { Injectable } from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import { Cat, CatDocument } from './schemas/cat.schema';
import { CreateCatDto } from './dto/create-cat.dto';

@Injectable()
export class CatsService {
  constructor(@InjectModel(Cat.name) private catModel: Model<CatDocument>) {}

  async create(createCatDto: CreateCatDto): Promise<Cat> {
    const createdCat = new this.catModel(createCatDto);
    return createdCat.save();
  }

  async findAll(): Promise<Cat[]> {
    return this.catModel.find().exec();
  }
}
```

```typescript

import { Model } from 'mongoose';
import { Injectable, Dependencies } from '@nestjs/common';
import { getModelToken } from '@nestjs/mongoose';
import { Cat } from './schemas/cat.schema';

@Injectable()
@Dependencies(getModelToken(Cat.name))
export class CatsService {
  constructor(catModel) {
    this.catModel = catModel;
  }

  async create(createCatDto) {
    const createdCat = new this.catModel(createCatDto);
    return createdCat.save();
  }

  async findAll() {
    return this.catModel.find().exec();
  }
}
```

#### Connection[#](/techniques/mongodb#connection)

At times you may need to access the native [Mongoose Connection](https://mongoosejs.com/docs/api.html#Connection) object. For example, you may want to make native API calls on the connection object. You can inject the Mongoose Connection by using the `@InjectConnection()` decorator as follows:

```typescript

import { Injectable } from '@nestjs/common';
import { InjectConnection } from '@nestjs/mongoose';
import { Connection } from 'mongoose';

@Injectable()
export class CatsService {
  constructor(@InjectConnection() private connection: Connection) {}
}
```

#### Multiple databases[#](/techniques/mongodb#multiple-databases)

Some projects require multiple database connections. This can also be achieved with this module. To work with multiple connections, first create the connections. In this case, connection naming becomes **mandatory**.

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';

@Module({
  imports: [
    MongooseModule.forRoot('mongodb://localhost/test', {
      connectionName: 'cats',
    }),
    MongooseModule.forRoot('mongodb://localhost/users', {
      connectionName: 'users',
    }),
  ],
})
export class AppModule {}
```

> **Notice** Please note that you shouldn't have multiple connections without a name, or with the same name, otherwise they will get overridden.

With this setup, you have to tell the `MongooseModule.forFeature()` function which connection should be used.

```typescript

@Module({
  imports: [
    MongooseModule.forFeature([{ name: Cat.name, schema: CatSchema }], 'cats'),
  ],
})
export class AppModule {}
```

You can also inject the `Connection` for a given connection:

```typescript

import { Injectable } from '@nestjs/common';
import { InjectConnection } from '@nestjs/mongoose';
import { Connection } from 'mongoose';

@Injectable()
export class CatsService {
  constructor(@InjectConnection('cats') private connection: Connection) {}
}
```

To inject a given `Connection` to a custom provider (for example, factory provider), use the `getConnectionToken()` function passing the name of the connection as an argument.

```typescript

{
  provide: CatsService,
  useFactory: (catsConnection: Connection) => {
    return new CatsService(catsConnection);
  },
  inject: [getConnectionToken('cats')],
}
```

#### Hooks (middleware)[#](/techniques/mongodb#hooks-middleware)

Middleware (also called pre and post hooks) are functions which are passed control during execution of asynchronous functions. Middleware is specified on the schema level and is useful for writing plugins ([source](https://mongoosejs.com/docs/middleware.html)). Calling `pre()` or `post()` after compiling a model does not work in Mongoose. To register a hook **before** model registration, use the `forFeatureAsync()` method of the `MongooseModule` along with a factory provider (i.e., `useFactory`). With this technique, you can access a schema object, then use the `pre()` or `post()` method to register a hook on that schema. See example below:

```typescript

@Module({
  imports: [
    MongooseModule.forFeatureAsync([
      {
        name: Cat.name,
        useFactory: () => {
          const schema = CatsSchema;
          schema.pre('save', function () {
            console.log('Hello from pre save');
          });
          return schema;
        },
      },
    ]),
  ],
})
export class AppModule {}
```

Like other [factory providers](https://docs.nestjs.com/fundamentals/custom-providers#factory-providers-usefactory), our factory function can be `async` and can inject dependencies through `inject`.

```typescript

@Module({
  imports: [
    MongooseModule.forFeatureAsync([
      {
        name: Cat.name,
        imports: [ConfigModule],
        useFactory: (configService: ConfigService) => {
          const schema = CatsSchema;
          schema.pre('save', function() {
            console.log(
              `${configService.get('APP_NAME')}: Hello from pre save`,
            ),
          });
          return schema;
        },
        inject: [ConfigService],
      },
    ]),
  ],
})
export class AppModule {}
```

#### Plugins[#](/techniques/mongodb#plugins)

To register a [plugin](https://mongoosejs.com/docs/plugins.html) for a given schema, use the `forFeatureAsync()` method.

```typescript

@Module({
  imports: [
    MongooseModule.forFeatureAsync([
      {
        name: Cat.name,
        useFactory: () => {
          const schema = CatsSchema;
          schema.plugin(require('mongoose-autopopulate'));
          return schema;
        },
      },
    ]),
  ],
})
export class AppModule {}
```

To register a plugin for all schemas at once, call the `.plugin()` method of the `Connection` object. You should access the connection before models are created; to do this, use the `connectionFactory`:

app.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';

@Module({
  imports: [
    MongooseModule.forRoot('mongodb://localhost/test', {
      connectionFactory: (connection) => {
        connection.plugin(require('mongoose-autopopulate'));
        return connection;
      }
    }),
  ],
})
export class AppModule {}
```

#### Discriminators[#](/techniques/mongodb#discriminators)

[Discriminators](https://mongoosejs.com/docs/discriminators.html) are a schema inheritance mechanism. They enable you to have multiple models with overlapping schemas on top of the same underlying MongoDB collection.

Suppose you wanted to track different types of events in a single collection. Every event will have a timestamp.

event.schema.ts

JS TS

```typescript

@Schema({ discriminatorKey: 'kind' })
export class Event {
  @Prop({
    type: String,
    required: true,
    enum: [ClickedLinkEvent.name, SignUpEvent.name],
  })
  kind: string;

  @Prop({ type: Date, required: true })
  time: Date;
}

export const EventSchema = SchemaFactory.createForClass(Event);
```

> **Hint** The way mongoose tells the difference between the different discriminator models is by the "discriminator key", which is `__t` by default. Mongoose adds a String path called `__t` to your schemas that it uses to track which discriminator this document is an instance of. You may also use the `discriminatorKey` option to define the path for discrimination.

`SignedUpEvent` and `ClickedLinkEvent` instances will be stored in the same collection as generic events.

Now, let's define the `ClickedLinkEvent` class, as follows:

click-link-event.schema.ts

JS TS

```typescript

@Schema()
export class ClickedLinkEvent {
  kind: string;
  time: Date;

  @Prop({ type: String, required: true })
  url: string;
}

export const ClickedLinkEventSchema = SchemaFactory.createForClass(ClickedLinkEvent);
```

And `SignUpEvent` class:

sign-up-event.schema.ts

JS TS

```typescript

@Schema()
export class SignUpEvent {
  kind: string;
  time: Date;

  @Prop({ type: String, required: true })
  user: string;
}

export const SignUpEventSchema = SchemaFactory.createForClass(SignUpEvent);
```

With this in place, use the `discriminators` option to register a discriminator for a given schema. It works on both `MongooseModule.forFeature` and `MongooseModule.forFeatureAsync`:

event.module.ts

JS TS

```typescript

import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';

@Module({
  imports: [
    MongooseModule.forFeature([
      {
        name: Event.name,
        schema: EventSchema,
        discriminators: [
          { name: ClickedLinkEvent.name, schema: ClickedLinkEventSchema },
          { name: SignUpEvent.name, schema: SignUpEventSchema },
        ],
      },
    ]),
  ]
})
export class EventsModule {}
```

#### Testing[#](/techniques/mongodb#testing)

When unit testing an application, we usually want to avoid any database connection, making our test suites simpler to set up and faster to execute. But our classes might depend on models that are pulled from the connection instance. How do we resolve these classes? The solution is to create mock models.

To make this easier, the `@nestjs/mongoose` package exposes a `getModelToken()` function that returns a prepared [injection token](https://docs.nestjs.com/fundamentals/custom-providers#di-fundamentals) based on a token name. Using this token, you can easily provide a mock implementation using any of the standard [custom provider](/v8/fundamentals/custom-providers) techniques, including `useClass`, `useValue`, and `useFactory`. For example:

```typescript

@Module({
  providers: [
    CatsService,
    {
      provide: getModelToken(Cat.name),
      useValue: catModel,
    },
  ],
})
export class CatsModule {}
```

```typescript

MongooseModule.forRootAsync({
  useFactory: () => ({
    uri: 'mongodb://localhost/nest',
  }),
});
```

Like other [factory providers](https://docs.nestjs.com/fundamentals/custom-providers#factory-providers-usefactory), our factory function can be `async` and can inject dependencies through `inject`.

```typescript

MongooseModule.forRootAsync({
  imports: [ConfigModule],
  useFactory: async (configService: ConfigService) => ({
    uri: configService.get<string>('MONGODB_URI'),
  }),
  inject: [ConfigService],
});
```

Alternatively, you can configure the `MongooseModule` using a class instead of a factory, as shown below:

```typescript

MongooseModule.forRootAsync({
  useClass: MongooseConfigService,
});
```

The construction above instantiates `MongooseConfigService` inside `MongooseModule`, using it to create the required options object. Note that in this example, the `MongooseConfigService` has to implement the `MongooseOptionsFactory` interface, as shown below. The `MongooseModule` will call the `createMongooseOptions()` method on the instantiated object of the supplied class.

```typescript

@Injectable()
export class MongooseConfigService implements MongooseOptionsFactory {
  createMongooseOptions(): MongooseModuleOptions {
    return {
      uri: 'mongodb://localhost/nest',
    };
  }
}
```

If you want to reuse an existing options provider instead of creating a private copy inside the `MongooseModule`, use the `useExisting` syntax.

```typescript

MongooseModule.forRootAsync({
  imports: [ConfigModule],
  useExisting: ConfigService,
});
```

#### Example[#](/techniques/mongodb#example)

A working example is available [here](https://github.com/nestjs/nest/tree/master/sample/06-mongoose).

### Support us

Nest is an MIT-licensed open source project. It can grow thanks to the support by these awesome people. If you'd like to join them, please read more [here](/v8/support).

#### Principal Sponsors

[](https://trilon.io/)[](https://www.redhat.com/)[](https://valor-software.com/)[](https://github.com/Sanofi-IADC)[](https://nx.dev/)[](https://amplication.com/)

#### Sponsors / Partners

[Become a sponsor](https://opencollective.com/nest)

### Join our Newsletter

Subscribe to stay up to date with the latest Nest updates, features, and videos!